summaryrefslogtreecommitdiffstats
path: root/tests/ui/lint
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/lint')
-rw-r--r--tests/ui/lint/auxiliary/add-impl.rs22
-rw-r--r--tests/ui/lint/auxiliary/external_extern_fn.rs3
-rw-r--r--tests/ui/lint/auxiliary/inherited_stability.rs47
-rw-r--r--tests/ui/lint/auxiliary/lint_output_format.rs20
-rw-r--r--tests/ui/lint/auxiliary/lint_stability.rs188
-rw-r--r--tests/ui/lint/auxiliary/lint_stability_fields.rs66
-rw-r--r--tests/ui/lint/auxiliary/lints-in-foreign-macros.rs14
-rw-r--r--tests/ui/lint/auxiliary/stability-cfg2.rs5
-rw-r--r--tests/ui/lint/auxiliary/stability_cfg1.rs3
-rw-r--r--tests/ui/lint/auxiliary/stability_cfg2.rs5
-rw-r--r--tests/ui/lint/auxiliary/trivial-cast-ice.rs7
-rw-r--r--tests/ui/lint/auxiliary/unaligned_references_external_crate.rs28
-rw-r--r--tests/ui/lint/bad-lint-cap.rs4
-rw-r--r--tests/ui/lint/bad-lint-cap.stderr2
-rw-r--r--tests/ui/lint/bad-lint-cap2.rs8
-rw-r--r--tests/ui/lint/bad-lint-cap2.stderr15
-rw-r--r--tests/ui/lint/bad-lint-cap3.rs9
-rw-r--r--tests/ui/lint/bad-lint-cap3.stderr15
-rw-r--r--tests/ui/lint/bare-trait-objects-path.rs26
-rw-r--r--tests/ui/lint/bare-trait-objects-path.stderr62
-rw-r--r--tests/ui/lint/clashing-extern-fn-recursion.rs119
-rw-r--r--tests/ui/lint/clashing-extern-fn-wasm.rs21
-rw-r--r--tests/ui/lint/clashing-extern-fn.rs417
-rw-r--r--tests/ui/lint/clashing-extern-fn.stderr236
-rw-r--r--tests/ui/lint/cli-lint-override.forbid_warn.stderr11
-rw-r--r--tests/ui/lint/cli-lint-override.force_warn_deny.stderr11
-rw-r--r--tests/ui/lint/cli-lint-override.rs17
-rw-r--r--tests/ui/lint/cli-lint-override.warn_deny.stderr11
-rw-r--r--tests/ui/lint/cli-unknown-force-warn.rs7
-rw-r--r--tests/ui/lint/cli-unknown-force-warn.stderr11
-rw-r--r--tests/ui/lint/command-line-lint-group-allow.rs6
-rw-r--r--tests/ui/lint/command-line-lint-group-deny.rs5
-rw-r--r--tests/ui/lint/command-line-lint-group-deny.stderr10
-rw-r--r--tests/ui/lint/command-line-lint-group-forbid.rs5
-rw-r--r--tests/ui/lint/command-line-lint-group-forbid.stderr10
-rw-r--r--tests/ui/lint/command-line-lint-group-warn.rs7
-rw-r--r--tests/ui/lint/command-line-lint-group-warn.stderr10
-rw-r--r--tests/ui/lint/command-line-register-lint-tool.rs7
-rw-r--r--tests/ui/lint/command-line-register-unknown-lint-tool.rs4
-rw-r--r--tests/ui/lint/command-line-register-unknown-lint-tool.stderr11
-rw-r--r--tests/ui/lint/crate_level_only_lint.rs22
-rw-r--r--tests/ui/lint/crate_level_only_lint.stderr62
-rw-r--r--tests/ui/lint/dead-code/alias-in-pat.rs10
-rw-r--r--tests/ui/lint/dead-code/anon-const-in-pat.rs45
-rw-r--r--tests/ui/lint/dead-code/associated-type.rs19
-rw-r--r--tests/ui/lint/dead-code/basic.rs15
-rw-r--r--tests/ui/lint/dead-code/basic.stderr14
-rw-r--r--tests/ui/lint/dead-code/closure-bang.rs9
-rw-r--r--tests/ui/lint/dead-code/const-and-self.rs54
-rw-r--r--tests/ui/lint/dead-code/const-and-self.stderr19
-rw-r--r--tests/ui/lint/dead-code/empty-unused-enum.rs5
-rw-r--r--tests/ui/lint/dead-code/empty-unused-enum.stderr15
-rw-r--r--tests/ui/lint/dead-code/empty-unused-public-enum.rs6
-rw-r--r--tests/ui/lint/dead-code/enum-variants.rs14
-rw-r--r--tests/ui/lint/dead-code/impl-trait.rs18
-rw-r--r--tests/ui/lint/dead-code/impl-trait.stderr14
-rw-r--r--tests/ui/lint/dead-code/issue-68408-false-positive.rs22
-rw-r--r--tests/ui/lint/dead-code/issue-85071-2.rs22
-rw-r--r--tests/ui/lint/dead-code/issue-85071-2.stderr34
-rw-r--r--tests/ui/lint/dead-code/issue-85071.rs19
-rw-r--r--tests/ui/lint/dead-code/issue-85071.stderr34
-rw-r--r--tests/ui/lint/dead-code/issue-85255.rs50
-rw-r--r--tests/ui/lint/dead-code/issue-85255.stderr74
-rw-r--r--tests/ui/lint/dead-code/leading-underscore.rs31
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-1.rs110
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-1.stderr71
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-2.rs41
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-2.stderr26
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-3.rs90
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-3.stderr50
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-4.rs83
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-4.stderr66
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-5.rs50
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-5.stderr34
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-6.rs20
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-6.stderr32
-rw-r--r--tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs29
-rw-r--r--tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr55
-rw-r--r--tests/ui/lint/dead-code/newline-span.rs19
-rw-r--r--tests/ui/lint/dead-code/newline-span.stderr26
-rw-r--r--tests/ui/lint/dead-code/self-assign.rs52
-rw-r--r--tests/ui/lint/dead-code/self-assign.stderr44
-rw-r--r--tests/ui/lint/dead-code/trait-impl.rs19
-rw-r--r--tests/ui/lint/dead-code/tuple-struct-field.rs37
-rw-r--r--tests/ui/lint/dead-code/tuple-struct-field.stderr33
-rw-r--r--tests/ui/lint/dead-code/type-alias.rs10
-rw-r--r--tests/ui/lint/dead-code/type-alias.stderr14
-rw-r--r--tests/ui/lint/dead-code/type-in-foreign.rs19
-rw-r--r--tests/ui/lint/dead-code/unused-enum.rs12
-rw-r--r--tests/ui/lint/dead-code/unused-enum.stderr27
-rw-r--r--tests/ui/lint/dead-code/unused-struct-variant.rs13
-rw-r--r--tests/ui/lint/dead-code/unused-struct-variant.stderr18
-rw-r--r--tests/ui/lint/dead-code/unused-variant-pub.rs14
-rw-r--r--tests/ui/lint/dead-code/unused-variant.rs12
-rw-r--r--tests/ui/lint/dead-code/unused-variant.stderr17
-rw-r--r--tests/ui/lint/dead-code/with-core-crate.rs18
-rw-r--r--tests/ui/lint/dead-code/with-core-crate.stderr14
-rw-r--r--tests/ui/lint/dead-code/with-impl.rs17
-rw-r--r--tests/ui/lint/deny-overflowing-literals.rs7
-rw-r--r--tests/ui/lint/deny-overflowing-literals.stderr17
-rw-r--r--tests/ui/lint/empty-lint-attributes.rs17
-rw-r--r--tests/ui/lint/enable-unstable-lib-feature.rs13
-rw-r--r--tests/ui/lint/enable-unstable-lib-feature.stderr14
-rw-r--r--tests/ui/lint/expansion-time-include.rs4
-rw-r--r--tests/ui/lint/expansion-time.rs33
-rw-r--r--tests/ui/lint/expansion-time.stderr56
-rw-r--r--tests/ui/lint/expr_attr_paren_order.rs22
-rw-r--r--tests/ui/lint/expr_attr_paren_order.stderr14
-rw-r--r--tests/ui/lint/fn_must_use.rs76
-rw-r--r--tests/ui/lint/fn_must_use.stderr69
-rw-r--r--tests/ui/lint/for_loop_over_fallibles.rs43
-rw-r--r--tests/ui/lint/for_loop_over_fallibles.stderr101
-rw-r--r--tests/ui/lint/forbid-error-capped.rs15
-rw-r--r--tests/ui/lint/forbid-group-group-1.rs13
-rw-r--r--tests/ui/lint/forbid-group-group-1.stderr15
-rw-r--r--tests/ui/lint/forbid-group-group-2.rs26
-rw-r--r--tests/ui/lint/forbid-group-group-2.stderr115
-rw-r--r--tests/ui/lint/forbid-group-member.rs17
-rw-r--r--tests/ui/lint/forbid-group-member.stderr39
-rw-r--r--tests/ui/lint/forbid-member-group.rs11
-rw-r--r--tests/ui/lint/forbid-member-group.stderr21
-rw-r--r--tests/ui/lint/force-warn/allow-warnings.rs11
-rw-r--r--tests/ui/lint/force-warn/allow-warnings.stderr10
-rw-r--r--tests/ui/lint/force-warn/allowed-by-default-lint.rs12
-rw-r--r--tests/ui/lint/force-warn/allowed-by-default-lint.stderr14
-rw-r--r--tests/ui/lint/force-warn/allowed-cli-deny-by-default-lint.rs10
-rw-r--r--tests/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr10
-rw-r--r--tests/ui/lint/force-warn/allowed-deny-by-default-lint.rs11
-rw-r--r--tests/ui/lint/force-warn/allowed-deny-by-default-lint.stderr10
-rw-r--r--tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.rs18
-rw-r--r--tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr42
-rw-r--r--tests/ui/lint/force-warn/allowed-warn-by-default-lint.rs11
-rw-r--r--tests/ui/lint/force-warn/allowed-warn-by-default-lint.stderr10
-rw-r--r--tests/ui/lint/force-warn/cap-lints-allow.rs16
-rw-r--r--tests/ui/lint/force-warn/cap-lints-allow.stderr42
-rw-r--r--tests/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.rs17
-rw-r--r--tests/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr12
-rw-r--r--tests/ui/lint/force-warn/deny-by-default-lint.rs9
-rw-r--r--tests/ui/lint/force-warn/deny-by-default-lint.stderr10
-rw-r--r--tests/ui/lint/force-warn/lint-group-allow-warnings.rs12
-rw-r--r--tests/ui/lint/force-warn/lint-group-allow-warnings.stderr10
-rw-r--r--tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.rs16
-rw-r--r--tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr42
-rw-r--r--tests/ui/lint/force-warn/lint-group-allowed-lint-group.rs18
-rw-r--r--tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr42
-rw-r--r--tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.rs18
-rw-r--r--tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr42
-rw-r--r--tests/ui/lint/force-warn/warn-by-default-lint-two-modules.rs18
-rw-r--r--tests/ui/lint/force-warn/warn-by-default-lint-two-modules.stderr16
-rw-r--r--tests/ui/lint/force-warn/warnings-lint-group.rs5
-rw-r--r--tests/ui/lint/force-warn/warnings-lint-group.stderr7
-rw-r--r--tests/ui/lint/function-item-references.rs169
-rw-r--r--tests/ui/lint/function-item-references.stderr206
-rw-r--r--tests/ui/lint/future-incompat-test.rs10
-rw-r--r--tests/ui/lint/future-incompat-test.stderr9
-rw-r--r--tests/ui/lint/inclusive-range-pattern-syntax.fixed21
-rw-r--r--tests/ui/lint/inclusive-range-pattern-syntax.rs21
-rw-r--r--tests/ui/lint/inclusive-range-pattern-syntax.stderr25
-rw-r--r--tests/ui/lint/inert-attr-macro.rs20
-rw-r--r--tests/ui/lint/inert-attr-macro.stderr44
-rw-r--r--tests/ui/lint/inline-trait-and-foreign-items.rs37
-rw-r--r--tests/ui/lint/inline-trait-and-foreign-items.stderr74
-rw-r--r--tests/ui/lint/invalid_value.rs169
-rw-r--r--tests/ui/lint/invalid_value.stderr676
-rw-r--r--tests/ui/lint/issue-101284.rs15
-rw-r--r--tests/ui/lint/issue-102705.rs22
-rw-r--r--tests/ui/lint/issue-103317.fixed14
-rw-r--r--tests/ui/lint/issue-103317.rs14
-rw-r--r--tests/ui/lint/issue-103317.stderr17
-rw-r--r--tests/ui/lint/issue-103435-extra-parentheses.fixed18
-rw-r--r--tests/ui/lint/issue-103435-extra-parentheses.rs18
-rw-r--r--tests/ui/lint/issue-103435-extra-parentheses.stderr61
-rw-r--r--tests/ui/lint/issue-104392.rs11
-rw-r--r--tests/ui/lint/issue-104392.stderr27
-rw-r--r--tests/ui/lint/issue-104897.rs6
-rw-r--r--tests/ui/lint/issue-104897.stderr43
-rw-r--r--tests/ui/lint/issue-108155.rs15
-rw-r--r--tests/ui/lint/issue-14309.rs39
-rw-r--r--tests/ui/lint/issue-14309.stderr77
-rw-r--r--tests/ui/lint/issue-14837.rs11
-rw-r--r--tests/ui/lint/issue-17718-const-naming.rs8
-rw-r--r--tests/ui/lint/issue-17718-const-naming.stderr23
-rw-r--r--tests/ui/lint/issue-1866.rs29
-rw-r--r--tests/ui/lint/issue-1866.stderr19
-rw-r--r--tests/ui/lint/issue-20343.rs32
-rw-r--r--tests/ui/lint/issue-30302.rs20
-rw-r--r--tests/ui/lint/issue-30302.stderr26
-rw-r--r--tests/ui/lint/issue-31924-non-snake-ffi.rs15
-rw-r--r--tests/ui/lint/issue-34798.rs25
-rw-r--r--tests/ui/lint/issue-35075.rs9
-rw-r--r--tests/ui/lint/issue-35075.stderr25
-rw-r--r--tests/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs27
-rw-r--r--tests/ui/lint/issue-54099-camel-case-underscore-types.rs14
-rw-r--r--tests/ui/lint/issue-57410-1.rs18
-rw-r--r--tests/ui/lint/issue-57410.rs17
-rw-r--r--tests/ui/lint/issue-63364.rs10
-rw-r--r--tests/ui/lint/issue-63364.stderr11
-rw-r--r--tests/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs29
-rw-r--r--tests/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr32
-rw-r--r--tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs50
-rw-r--r--tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr18
-rw-r--r--tests/ui/lint/issue-79546-fuel-ice.rs8
-rw-r--r--tests/ui/lint/issue-79744.rs13
-rw-r--r--tests/ui/lint/issue-79744.stderr12
-rw-r--r--tests/ui/lint/issue-80988.rs14
-rw-r--r--tests/ui/lint/issue-80988.stderr39
-rw-r--r--tests/ui/lint/issue-81218.rs14
-rw-r--r--tests/ui/lint/issue-83477.rs16
-rw-r--r--tests/ui/lint/issue-83477.stderr30
-rw-r--r--tests/ui/lint/issue-86600-lint-twice.rs15
-rw-r--r--tests/ui/lint/issue-86600-lint-twice.stderr12
-rw-r--r--tests/ui/lint/issue-87274-paren-parent.rs9
-rw-r--r--tests/ui/lint/issue-87274-paren-parent.stderr10
-rw-r--r--tests/ui/lint/issue-89469.rs20
-rw-r--r--tests/ui/lint/issue-90614-accept-allow-text-direction-codepoint-in-comment-lint.rs9
-rw-r--r--tests/ui/lint/issue-97094.rs50
-rw-r--r--tests/ui/lint/issue-97094.stderr53
-rw-r--r--tests/ui/lint/issue-99387.rs24
-rw-r--r--tests/ui/lint/known-tool-in-submodule/root.rs10
-rw-r--r--tests/ui/lint/known-tool-in-submodule/submodule.rs4
-rw-r--r--tests/ui/lint/let_underscore/let_underscore_drop.rs14
-rw-r--r--tests/ui/lint/let_underscore/let_underscore_drop.stderr22
-rw-r--r--tests/ui/lint/let_underscore/let_underscore_lock.rs7
-rw-r--r--tests/ui/lint/let_underscore/let_underscore_lock.stderr20
-rw-r--r--tests/ui/lint/lint-attr-everywhere-early.rs176
-rw-r--r--tests/ui/lint/lint-attr-everywhere-early.stderr486
-rw-r--r--tests/ui/lint/lint-attr-everywhere-late.rs197
-rw-r--r--tests/ui/lint/lint-attr-everywhere-late.stderr428
-rw-r--r--tests/ui/lint/lint-attr-non-item-node.rs9
-rw-r--r--tests/ui/lint/lint-attr-non-item-node.stderr16
-rw-r--r--tests/ui/lint/lint-cap.rs8
-rw-r--r--tests/ui/lint/lint-change-warnings.rs21
-rw-r--r--tests/ui/lint/lint-change-warnings.stderr36
-rw-r--r--tests/ui/lint/lint-const-item-mutation.rs66
-rw-r--r--tests/ui/lint/lint-const-item-mutation.stderr118
-rw-r--r--tests/ui/lint/lint-ctypes-66202.rs17
-rw-r--r--tests/ui/lint/lint-ctypes-73249-1.rs21
-rw-r--r--tests/ui/lint/lint-ctypes-73249-2.rs29
-rw-r--r--tests/ui/lint/lint-ctypes-73249-2.stderr15
-rw-r--r--tests/ui/lint/lint-ctypes-73249-3.rs23
-rw-r--r--tests/ui/lint/lint-ctypes-73249-3.stderr15
-rw-r--r--tests/ui/lint/lint-ctypes-73249-4.rs24
-rw-r--r--tests/ui/lint/lint-ctypes-73249-5.rs23
-rw-r--r--tests/ui/lint/lint-ctypes-73249-5.stderr15
-rw-r--r--tests/ui/lint/lint-ctypes-73249.rs21
-rw-r--r--tests/ui/lint/lint-ctypes-73251-1.rs26
-rw-r--r--tests/ui/lint/lint-ctypes-73251-1.stderr15
-rw-r--r--tests/ui/lint/lint-ctypes-73251-2.rs39
-rw-r--r--tests/ui/lint/lint-ctypes-73251-2.stderr15
-rw-r--r--tests/ui/lint/lint-ctypes-73251.rs22
-rw-r--r--tests/ui/lint/lint-ctypes-73747.rs14
-rw-r--r--tests/ui/lint/lint-ctypes-enum.rs92
-rw-r--r--tests/ui/lint/lint-ctypes-enum.stderr92
-rw-r--r--tests/ui/lint/lint-ctypes-fn.rs196
-rw-r--r--tests/ui/lint/lint-ctypes-fn.stderr188
-rw-r--r--tests/ui/lint/lint-ctypes.rs118
-rw-r--r--tests/ui/lint/lint-ctypes.stderr262
-rw-r--r--tests/ui/lint/lint-deref-nullptr.rs38
-rw-r--r--tests/ui/lint/lint-deref-nullptr.stderr68
-rw-r--r--tests/ui/lint/lint-directives-on-use-items-issue-10534.rs24
-rw-r--r--tests/ui/lint/lint-directives-on-use-items-issue-10534.stderr26
-rw-r--r--tests/ui/lint/lint-enum-intrinsics-non-enums.rs67
-rw-r--r--tests/ui/lint/lint-enum-intrinsics-non-enums.stderr95
-rw-r--r--tests/ui/lint/lint-exceeding-bitshifts.noopt.stderr152
-rw-r--r--tests/ui/lint/lint-exceeding-bitshifts.opt.stderr152
-rw-r--r--tests/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr152
-rw-r--r--tests/ui/lint/lint-exceeding-bitshifts.rs79
-rw-r--r--tests/ui/lint/lint-expr-stmt-attrs-for-early-lints.rs14
-rw-r--r--tests/ui/lint/lint-ffi-safety-all-phantom.rs22
-rw-r--r--tests/ui/lint/lint-forbid-attr.rs7
-rw-r--r--tests/ui/lint/lint-forbid-attr.stderr21
-rw-r--r--tests/ui/lint/lint-forbid-cmdline.rs6
-rw-r--r--tests/ui/lint/lint-forbid-cmdline.stderr19
-rw-r--r--tests/ui/lint/lint-forbid-internal-unsafe.rs17
-rw-r--r--tests/ui/lint/lint-forbid-internal-unsafe.stderr22
-rw-r--r--tests/ui/lint/lint-group-nonstandard-style.rs26
-rw-r--r--tests/ui/lint/lint-group-nonstandard-style.stderr57
-rw-r--r--tests/ui/lint/lint-impl-fn.rs33
-rw-r--r--tests/ui/lint/lint-impl-fn.stderr38
-rw-r--r--tests/ui/lint/lint-incoherent-auto-trait-objects.rs19
-rw-r--r--tests/ui/lint/lint-incoherent-auto-trait-objects.stderr81
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-bool.rs28
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-bool.stderr35
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-exchange-weak.rs50
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr83
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-exchange.rs48
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-exchange.stderr83
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-false-positive.rs18
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-fence.rs21
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-fence.stderr19
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.rs49
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr83
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-int.rs130
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-int.stderr163
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-ptr.rs30
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-ptr.stderr35
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-uint.rs129
-rw-r--r--tests/ui/lint/lint-invalid-atomic-ordering-uint.stderr163
-rw-r--r--tests/ui/lint/lint-level-macro-def-mod.rs17
-rw-r--r--tests/ui/lint/lint-level-macro-def.rs17
-rw-r--r--tests/ui/lint/lint-lowercase-static-const-pattern-rename.rs63
-rw-r--r--tests/ui/lint/lint-lowercase-static-const-pattern.rs51
-rw-r--r--tests/ui/lint/lint-lowercase-static-const-pattern.stderr26
-rw-r--r--tests/ui/lint/lint-malformed.rs6
-rw-r--r--tests/ui/lint/lint-malformed.stderr33
-rw-r--r--tests/ui/lint/lint-match-arms.rs18
-rw-r--r--tests/ui/lint/lint-match-arms.stderr14
-rw-r--r--tests/ui/lint/lint-misplaced-attr.rs10
-rw-r--r--tests/ui/lint/lint-misplaced-attr.stderr20
-rw-r--r--tests/ui/lint/lint-missing-copy-implementations-allow.rs35
-rw-r--r--tests/ui/lint/lint-missing-copy-implementations.rs15
-rw-r--r--tests/ui/lint/lint-missing-copy-implementations.stderr16
-rw-r--r--tests/ui/lint/lint-missing-doc.rs203
-rw-r--r--tests/ui/lint/lint-missing-doc.stderr140
-rw-r--r--tests/ui/lint/lint-non-camel-case-types.rs37
-rw-r--r--tests/ui/lint/lint-non-camel-case-types.stderr62
-rw-r--r--tests/ui/lint/lint-non-camel-case-variant.rs10
-rw-r--r--tests/ui/lint/lint-non-camel-case-with-trailing-underscores.rs11
-rw-r--r--tests/ui/lint/lint-non-snake-case-crate-2.rs6
-rw-r--r--tests/ui/lint/lint-non-snake-case-crate-2.stderr11
-rw-r--r--tests/ui/lint/lint-non-snake-case-crate.rs5
-rw-r--r--tests/ui/lint/lint-non-snake-case-crate.stderr14
-rw-r--r--tests/ui/lint/lint-non-snake-case-functions.rs44
-rw-r--r--tests/ui/lint/lint-non-snake-case-functions.stderr62
-rw-r--r--tests/ui/lint/lint-non-snake-case-identifiers-suggestion-reserved.rs19
-rw-r--r--tests/ui/lint/lint-non-snake-case-identifiers-suggestion-reserved.stderr67
-rw-r--r--tests/ui/lint/lint-non-snake-case-lifetimes.rs8
-rw-r--r--tests/ui/lint/lint-non-snake-case-lifetimes.stderr14
-rw-r--r--tests/ui/lint/lint-non-snake-case-modules.rs10
-rw-r--r--tests/ui/lint/lint-non-snake-case-modules.stderr14
-rw-r--r--tests/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs11
-rw-r--r--tests/ui/lint/lint-non-uppercase-associated-const.rs11
-rw-r--r--tests/ui/lint/lint-non-uppercase-associated-const.stderr14
-rw-r--r--tests/ui/lint/lint-non-uppercase-statics.rs11
-rw-r--r--tests/ui/lint/lint-non-uppercase-statics.stderr20
-rw-r--r--tests/ui/lint/lint-nonstandard-style-unicode-1.rs49
-rw-r--r--tests/ui/lint/lint-nonstandard-style-unicode-1.stderr50
-rw-r--r--tests/ui/lint/lint-nonstandard-style-unicode-2.rs29
-rw-r--r--tests/ui/lint/lint-nonstandard-style-unicode-2.stderr20
-rw-r--r--tests/ui/lint/lint-nonstandard-style-unicode-3.rs24
-rw-r--r--tests/ui/lint/lint-nonstandard-style-unicode-3.stderr14
-rw-r--r--tests/ui/lint/lint-output-format-2.rs15
-rw-r--r--tests/ui/lint/lint-output-format-2.stderr16
-rw-r--r--tests/ui/lint/lint-output-format.rs13
-rw-r--r--tests/ui/lint/lint-output-format.stderr35
-rw-r--r--tests/ui/lint/lint-owned-heap-memory.rs12
-rw-r--r--tests/ui/lint/lint-owned-heap-memory.stderr20
-rw-r--r--tests/ui/lint/lint-pre-expansion-extern-module.rs7
-rw-r--r--tests/ui/lint/lint-pre-expansion-extern-module.stderr12
-rw-r--r--tests/ui/lint/lint-pub-unreachable-for-nested-glob.rs28
-rw-r--r--tests/ui/lint/lint-qualification.rs20
-rw-r--r--tests/ui/lint/lint-qualification.stderr14
-rw-r--r--tests/ui/lint/lint-range-endpoint-overflow.rs17
-rw-r--r--tests/ui/lint/lint-range-endpoint-overflow.stderr50
-rw-r--r--tests/ui/lint/lint-removed-allow.rs8
-rw-r--r--tests/ui/lint/lint-removed-allow.stderr14
-rw-r--r--tests/ui/lint/lint-removed-cmdline.rs12
-rw-r--r--tests/ui/lint/lint-removed-cmdline.stderr27
-rw-r--r--tests/ui/lint/lint-removed.rs8
-rw-r--r--tests/ui/lint/lint-removed.stderr22
-rw-r--r--tests/ui/lint/lint-renamed-allow.rs8
-rw-r--r--tests/ui/lint/lint-renamed-allow.stderr15
-rw-r--r--tests/ui/lint/lint-renamed-cmdline.rs8
-rw-r--r--tests/ui/lint/lint-renamed-cmdline.stderr27
-rw-r--r--tests/ui/lint/lint-renamed.rs4
-rw-r--r--tests/ui/lint/lint-renamed.stderr23
-rw-r--r--tests/ui/lint/lint-shorthand-field.fixed70
-rw-r--r--tests/ui/lint/lint-shorthand-field.rs70
-rw-r--r--tests/ui/lint/lint-shorthand-field.stderr38
-rw-r--r--tests/ui/lint/lint-stability-2.rs413
-rw-r--r--tests/ui/lint/lint-stability-2.stderr259
-rw-r--r--tests/ui/lint/lint-stability-deprecated.rs464
-rw-r--r--tests/ui/lint/lint-stability-deprecated.stderr656
-rw-r--r--tests/ui/lint/lint-stability-fields-deprecated.rs344
-rw-r--r--tests/ui/lint/lint-stability-fields-deprecated.stderr380
-rw-r--r--tests/ui/lint/lint-stability-fields.rs293
-rw-r--r--tests/ui/lint/lint-stability-fields.stderr347
-rw-r--r--tests/ui/lint/lint-stability.rs454
-rw-r--r--tests/ui/lint/lint-stability.stderr347
-rw-r--r--tests/ui/lint/lint-stability2.rs13
-rw-r--r--tests/ui/lint/lint-stability2.stderr15
-rw-r--r--tests/ui/lint/lint-stability3.rs14
-rw-r--r--tests/ui/lint/lint-stability3.stderr14
-rw-r--r--tests/ui/lint/lint-strict-provenance-fuzzy-casts.rs7
-rw-r--r--tests/ui/lint/lint-strict-provenance-fuzzy-casts.stderr19
-rw-r--r--tests/ui/lint/lint-strict-provenance-lossy-casts.rs18
-rw-r--r--tests/ui/lint/lint-strict-provenance-lossy-casts.stderr51
-rw-r--r--tests/ui/lint/lint-temporary-cstring-as-param.rs11
-rw-r--r--tests/ui/lint/lint-temporary-cstring-as-param.stderr18
-rw-r--r--tests/ui/lint/lint-temporary-cstring-as-ptr.rs9
-rw-r--r--tests/ui/lint/lint-temporary-cstring-as-ptr.stderr18
-rw-r--r--tests/ui/lint/lint-type-limits.rs27
-rw-r--r--tests/ui/lint/lint-type-limits.stderr58
-rw-r--r--tests/ui/lint/lint-type-limits2.rs15
-rw-r--r--tests/ui/lint/lint-type-limits2.stderr24
-rw-r--r--tests/ui/lint/lint-type-limits3.rs13
-rw-r--r--tests/ui/lint/lint-type-limits3.stderr24
-rw-r--r--tests/ui/lint/lint-type-overflow.rs45
-rw-r--r--tests/ui/lint/lint-type-overflow.stderr167
-rw-r--r--tests/ui/lint/lint-type-overflow2.rs12
-rw-r--r--tests/ui/lint/lint-type-overflow2.stderr48
-rw-r--r--tests/ui/lint/lint-unconditional-recursion.rs194
-rw-r--r--tests/ui/lint/lint-unconditional-recursion.stderr201
-rw-r--r--tests/ui/lint/lint-unexported-no-mangle.rs29
-rw-r--r--tests/ui/lint/lint-unexported-no-mangle.stderr44
-rw-r--r--tests/ui/lint/lint-unknown-feature-default.rs9
-rw-r--r--tests/ui/lint/lint-unknown-feature.rs9
-rw-r--r--tests/ui/lint/lint-unknown-lint-cmdline.rs9
-rw-r--r--tests/ui/lint/lint-unknown-lint-cmdline.stderr21
-rw-r--r--tests/ui/lint/lint-unknown-lint.rs13
-rw-r--r--tests/ui/lint/lint-unknown-lint.stderr26
-rw-r--r--tests/ui/lint/lint-unnecessary-import-braces.rs11
-rw-r--r--tests/ui/lint/lint-unnecessary-import-braces.stderr14
-rw-r--r--tests/ui/lint/lint-unnecessary-parens.fixed81
-rw-r--r--tests/ui/lint/lint-unnecessary-parens.rs81
-rw-r--r--tests/ui/lint/lint-unnecessary-parens.stderr211
-rw-r--r--tests/ui/lint/lint-unsafe-code.rs130
-rw-r--r--tests/ui/lint/lint-unsafe-code.stderr224
-rw-r--r--tests/ui/lint/lint-uppercase-variables.rs41
-rw-r--r--tests/ui/lint/lint-uppercase-variables.stderr90
-rw-r--r--tests/ui/lint/lint_pre_expansion_extern_module_aux.rs3
-rw-r--r--tests/ui/lint/lints-in-foreign-macros.rs21
-rw-r--r--tests/ui/lint/lints-in-foreign-macros.stderr60
-rw-r--r--tests/ui/lint/missing-doc-private-macro.rs43
-rw-r--r--tests/ui/lint/missing-doc-private-macro.stderr20
-rw-r--r--tests/ui/lint/must_not_suspend/boxed.rs25
-rw-r--r--tests/ui/lint/must_not_suspend/boxed.stderr26
-rw-r--r--tests/ui/lint/must_not_suspend/dedup.rs20
-rw-r--r--tests/ui/lint/must_not_suspend/dedup.stderr19
-rw-r--r--tests/ui/lint/must_not_suspend/feature-gate-must_not_suspend.rs9
-rw-r--r--tests/ui/lint/must_not_suspend/feature-gate-must_not_suspend.stderr12
-rw-r--r--tests/ui/lint/must_not_suspend/gated.rs17
-rw-r--r--tests/ui/lint/must_not_suspend/gated.stderr33
-rw-r--r--tests/ui/lint/must_not_suspend/generic.rs20
-rw-r--r--tests/ui/lint/must_not_suspend/handled.rs28
-rw-r--r--tests/ui/lint/must_not_suspend/issue-89562.rs19
-rw-r--r--tests/ui/lint/must_not_suspend/mutex.rs13
-rw-r--r--tests/ui/lint/must_not_suspend/mutex.stderr26
-rw-r--r--tests/ui/lint/must_not_suspend/other_items.rs8
-rw-r--r--tests/ui/lint/must_not_suspend/other_items.stderr10
-rw-r--r--tests/ui/lint/must_not_suspend/ref-drop-tracking.rs30
-rw-r--r--tests/ui/lint/must_not_suspend/ref-drop-tracking.stderr27
-rw-r--r--tests/ui/lint/must_not_suspend/ref.drop_tracking.stderr27
-rw-r--r--tests/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr27
-rw-r--r--tests/ui/lint/must_not_suspend/ref.rs29
-rw-r--r--tests/ui/lint/must_not_suspend/return.rs9
-rw-r--r--tests/ui/lint/must_not_suspend/return.stderr12
-rw-r--r--tests/ui/lint/must_not_suspend/trait.rs28
-rw-r--r--tests/ui/lint/must_not_suspend/trait.stderr37
-rw-r--r--tests/ui/lint/must_not_suspend/tuple-mismatch.rs9
-rw-r--r--tests/ui/lint/must_not_suspend/tuple-mismatch.stderr12
-rw-r--r--tests/ui/lint/must_not_suspend/unit.rs25
-rw-r--r--tests/ui/lint/must_not_suspend/unit.stderr26
-rw-r--r--tests/ui/lint/must_not_suspend/warn.rs26
-rw-r--r--tests/ui/lint/must_not_suspend/warn.stderr26
-rw-r--r--tests/ui/lint/no-coverage.rs55
-rw-r--r--tests/ui/lint/no-coverage.stderr101
-rw-r--r--tests/ui/lint/noop-method-call.rs55
-rw-r--r--tests/ui/lint/noop-method-call.stderr47
-rw-r--r--tests/ui/lint/not_found.rs21
-rw-r--r--tests/ui/lint/not_found.stderr22
-rw-r--r--tests/ui/lint/opaque-ty-ffi-normalization-cycle.rs41
-rw-r--r--tests/ui/lint/opaque-ty-ffi-normalization-cycle.stderr15
-rw-r--r--tests/ui/lint/opaque-ty-ffi-unsafe.rs15
-rw-r--r--tests/ui/lint/opaque-ty-ffi-unsafe.stderr15
-rw-r--r--tests/ui/lint/outer-forbid.rs32
-rw-r--r--tests/ui/lint/outer-forbid.stderr41
-rw-r--r--tests/ui/lint/reasons-erroneous.rs54
-rw-r--r--tests/ui/lint/reasons-erroneous.stderr131
-rw-r--r--tests/ui/lint/reasons-forbidden.rs34
-rw-r--r--tests/ui/lint/reasons-forbidden.stderr31
-rw-r--r--tests/ui/lint/reasons.rs35
-rw-r--r--tests/ui/lint/reasons.stderr36
-rw-r--r--tests/ui/lint/recommend-literal.rs42
-rw-r--r--tests/ui/lint/recommend-literal.stderr96
-rw-r--r--tests/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs12
-rw-r--r--tests/ui/lint/redundant-semicolon/item-stmt-semi.rs6
-rw-r--r--tests/ui/lint/redundant-semicolon/item-stmt-semi.stderr20
-rw-r--r--tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs19
-rw-r--r--tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr21
-rw-r--r--tests/ui/lint/register-tool-lint.rs9
-rw-r--r--tests/ui/lint/register-tool-lint.stderr19
-rw-r--r--tests/ui/lint/renamed-lints-still-apply.rs9
-rw-r--r--tests/ui/lint/renamed-lints-still-apply.stderr29
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/avoid_delayed_good_path_ice.rs8
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/catch_multiple_lint_triggers.rs45
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/crate_level_expect.rs15
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/crate_level_expect.stderr10
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_inside_macro.rs16
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.rs42
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.stderr29
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.rs9
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.stderr12
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_multiple_lints.rs58
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_multiple_lints.stderr52
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.rs53
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr52
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_on_fn_params.rs15
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_on_fn_params.stderr10
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_tool_lint_rfc_2383.rs155
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_tool_lint_rfc_2383.stderr16
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.rs39
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.stderr38
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.rs34
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.stderr51
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_with_reason.rs11
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr11
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.rs48
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr40
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_unfulfilled.rs49
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_unfulfilled.stderr38
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_early_lints.rs23
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_late_lints.rs43
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.rs14
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr47
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.rs14
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.stderr10
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.rs16
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.stdout20
-rw-r--r--tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs16
-rw-r--r--tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr26
-rw-r--r--tests/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables-2.rs19
-rw-r--r--tests/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.rs14
-rw-r--r--tests/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.stderr34
-rw-r--r--tests/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs12
-rw-r--r--tests/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr26
-rw-r--r--tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs13
-rw-r--r--tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr34
-rw-r--r--tests/ui/lint/rustdoc-group.rs5
-rw-r--r--tests/ui/lint/rustdoc-group.stderr10
-rw-r--r--tests/ui/lint/rustdoc-renamed.rs15
-rw-r--r--tests/ui/lint/rustdoc-renamed.stderr14
-rw-r--r--tests/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs4
-rw-r--r--tests/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs9
-rw-r--r--tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.rs51
-rw-r--r--tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr185
-rw-r--r--tests/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs16
-rw-r--r--tests/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr31
-rw-r--r--tests/ui/lint/special-upper-lower-cases.rs23
-rw-r--r--tests/ui/lint/special-upper-lower-cases.stderr32
-rw-r--r--tests/ui/lint/suggestions.fixed66
-rw-r--r--tests/ui/lint/suggestions.rs67
-rw-r--r--tests/ui/lint/suggestions.stderr114
-rw-r--r--tests/ui/lint/test-allow-dead-extern-static-no-warning.rs11
-rw-r--r--tests/ui/lint/test-inner-fn.rs19
-rw-r--r--tests/ui/lint/test-inner-fn.stderr19
-rw-r--r--tests/ui/lint/trivial-cast-ice.rs12
-rw-r--r--tests/ui/lint/trivial-casts-featuring-type-ascription.rs10
-rw-r--r--tests/ui/lint/trivial-casts-featuring-type-ascription.stderr28
-rw-r--r--tests/ui/lint/trivial-casts.rs9
-rw-r--r--tests/ui/lint/trivial-casts.stderr28
-rw-r--r--tests/ui/lint/trivial_casts.rs85
-rw-r--r--tests/ui/lint/trivial_casts.stderr164
-rw-r--r--tests/ui/lint/type-overflow.rs22
-rw-r--r--tests/ui/lint/type-overflow.stderr67
-rw-r--r--tests/ui/lint/unaligned_references.rs103
-rw-r--r--tests/ui/lint/unaligned_references.stderr259
-rw-r--r--tests/ui/lint/unaligned_references_external_macro.rs13
-rw-r--r--tests/ui/lint/unaligned_references_external_macro.stderr61
-rw-r--r--tests/ui/lint/unnecessary-extern-crate.rs71
-rw-r--r--tests/ui/lint/unnecessary-extern-crate.stderr44
-rw-r--r--tests/ui/lint/unreachable-async-fn.rs9
-rw-r--r--tests/ui/lint/unreachable_pub.rs66
-rw-r--r--tests/ui/lint/unreachable_pub.stderr148
-rw-r--r--tests/ui/lint/unsafe_code/auxiliary/forge_unsafe_block.rs16
-rw-r--r--tests/ui/lint/unsafe_code/forge_unsafe_block.rs16
-rw-r--r--tests/ui/lint/unused-borrows.rs33
-rw-r--r--tests/ui/lint/unused-borrows.stderr73
-rw-r--r--tests/ui/lint/unused-braces-while-let-with-mutable-value.rs12
-rw-r--r--tests/ui/lint/unused-qualification-in-derive-expansion.rs16
-rw-r--r--tests/ui/lint/unused/auxiliary/lint_unused_extern_crate.rs1
-rw-r--r--tests/ui/lint/unused/auxiliary/lint_unused_extern_crate2.rs1
-rw-r--r--tests/ui/lint/unused/auxiliary/lint_unused_extern_crate3.rs1
-rw-r--r--tests/ui/lint/unused/auxiliary/lint_unused_extern_crate4.rs1
-rw-r--r--tests/ui/lint/unused/auxiliary/lint_unused_extern_crate5.rs1
-rw-r--r--tests/ui/lint/unused/issue-104397.rs18
-rw-r--r--tests/ui/lint/unused/issue-105061-array-lint.rs11
-rw-r--r--tests/ui/lint/unused/issue-105061-array-lint.stderr56
-rw-r--r--tests/ui/lint/unused/issue-105061-should-lint.rs23
-rw-r--r--tests/ui/lint/unused/issue-105061-should-lint.stderr32
-rw-r--r--tests/ui/lint/unused/issue-105061.rs17
-rw-r--r--tests/ui/lint/unused/issue-105061.stderr20
-rw-r--r--tests/ui/lint/unused/issue-30730.rs5
-rw-r--r--tests/ui/lint/unused/issue-30730.stderr15
-rw-r--r--tests/ui/lint/unused/issue-46576.rs21
-rw-r--r--tests/ui/lint/unused/issue-46576.stderr14
-rw-r--r--tests/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs88
-rw-r--r--tests/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr116
-rw-r--r--tests/ui/lint/unused/issue-54180-unused-ref-field.fixed34
-rw-r--r--tests/ui/lint/unused/issue-54180-unused-ref-field.rs34
-rw-r--r--tests/ui/lint/unused/issue-54180-unused-ref-field.stderr33
-rw-r--r--tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed113
-rw-r--r--tests/ui/lint/unused/issue-54538-unused-parens-lint.rs113
-rw-r--r--tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr295
-rw-r--r--tests/ui/lint/unused/issue-59896.rs9
-rw-r--r--tests/ui/lint/unused/issue-59896.stderr17
-rw-r--r--tests/ui/lint/unused/issue-67691-unused-field-in-or-pattern.rs85
-rw-r--r--tests/ui/lint/unused/issue-67691-unused-field-in-or-pattern.stderr74
-rw-r--r--tests/ui/lint/unused/issue-70041.rs13
-rw-r--r--tests/ui/lint/unused/issue-70041.stderr18
-rw-r--r--tests/ui/lint/unused/issue-71290-unused-paren-binop.rs23
-rw-r--r--tests/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs26
-rw-r--r--tests/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr84
-rw-r--r--tests/ui/lint/unused/issue-81314-unused-span-ident.fixed12
-rw-r--r--tests/ui/lint/unused/issue-81314-unused-span-ident.rs12
-rw-r--r--tests/ui/lint/unused/issue-81314-unused-span-ident.stderr21
-rw-r--r--tests/ui/lint/unused/issue-85913.rs13
-rw-r--r--tests/ui/lint/unused/issue-85913.stderr18
-rw-r--r--tests/ui/lint/unused/issue-88519-unused-paren.rs85
-rw-r--r--tests/ui/lint/unused/issue-90807-unused-paren-error.rs9
-rw-r--r--tests/ui/lint/unused/issue-90807-unused-paren-error.stderr31
-rw-r--r--tests/ui/lint/unused/issue-90807-unused-paren.rs8
-rw-r--r--tests/ui/lint/unused/issue-92751.rs9
-rw-r--r--tests/ui/lint/unused/issue-92751.stderr32
-rw-r--r--tests/ui/lint/unused/lint-unused-extern-crate.rs35
-rw-r--r--tests/ui/lint/unused/lint-unused-extern-crate.stderr20
-rw-r--r--tests/ui/lint/unused/lint-unused-imports.rs90
-rw-r--r--tests/ui/lint/unused/lint-unused-imports.stderr78
-rw-r--r--tests/ui/lint/unused/lint-unused-mut-self.fixed14
-rw-r--r--tests/ui/lint/unused/lint-unused-mut-self.rs14
-rw-r--r--tests/ui/lint/unused/lint-unused-mut-self.stderr24
-rw-r--r--tests/ui/lint/unused/lint-unused-mut-variables.rs207
-rw-r--r--tests/ui/lint/unused/lint-unused-mut-variables.stderr222
-rw-r--r--tests/ui/lint/unused/lint-unused-variables.rs79
-rw-r--r--tests/ui/lint/unused/lint-unused-variables.stderr74
-rw-r--r--tests/ui/lint/unused/must-use-box-from-raw.rs11
-rw-r--r--tests/ui/lint/unused/must-use-box-from-raw.stderr15
-rw-r--r--tests/ui/lint/unused/must-use-ops.rs51
-rw-r--r--tests/ui/lint/unused/must-use-ops.stderr238
-rw-r--r--tests/ui/lint/unused/must_use-array.rs54
-rw-r--r--tests/ui/lint/unused/must_use-array.stderr50
-rw-r--r--tests/ui/lint/unused/must_use-in-stdlib-traits.rs47
-rw-r--r--tests/ui/lint/unused/must_use-in-stdlib-traits.stderr47
-rw-r--r--tests/ui/lint/unused/must_use-trait.rs39
-rw-r--r--tests/ui/lint/unused/must_use-trait.stderr38
-rw-r--r--tests/ui/lint/unused/must_use-tuple.rs17
-rw-r--r--tests/ui/lint/unused/must_use-tuple.stderr47
-rw-r--r--tests/ui/lint/unused/must_use-unit.rs16
-rw-r--r--tests/ui/lint/unused/must_use-unit.stderr20
-rw-r--r--tests/ui/lint/unused/no-unused-parens-return-block.rs9
-rw-r--r--tests/ui/lint/unused/unused-async.rs62
-rw-r--r--tests/ui/lint/unused/unused-async.stderr55
-rw-r--r--tests/ui/lint/unused/unused-attr-duplicate.rs105
-rw-r--r--tests/ui/lint/unused/unused-attr-duplicate.stderr293
-rw-r--r--tests/ui/lint/unused/unused-attr-macro-rules.rs33
-rw-r--r--tests/ui/lint/unused/unused-attr-macro-rules.stderr26
-rw-r--r--tests/ui/lint/unused/unused-closure.rs35
-rw-r--r--tests/ui/lint/unused/unused-closure.stderr65
-rw-r--r--tests/ui/lint/unused/unused-doc-comments-edge-cases.rs46
-rw-r--r--tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr95
-rw-r--r--tests/ui/lint/unused/unused-doc-comments-for-macros.rs17
-rw-r--r--tests/ui/lint/unused/unused-doc-comments-for-macros.stderr31
-rw-r--r--tests/ui/lint/unused/unused-macro-rules-compile-error.rs27
-rw-r--r--tests/ui/lint/unused/unused-macro-rules-compile-error.stderr26
-rw-r--r--tests/ui/lint/unused/unused-macro-rules-decl.rs49
-rw-r--r--tests/ui/lint/unused/unused-macro-rules-decl.stderr26
-rw-r--r--tests/ui/lint/unused/unused-macro-rules-malformed-rule.rs11
-rw-r--r--tests/ui/lint/unused/unused-macro-rules-malformed-rule.stderr8
-rw-r--r--tests/ui/lint/unused/unused-macro-rules.rs47
-rw-r--r--tests/ui/lint/unused/unused-macro-rules.stderr26
-rw-r--r--tests/ui/lint/unused/unused-macro-with-bad-frag-spec.rs9
-rw-r--r--tests/ui/lint/unused/unused-macro-with-bad-frag-spec.stderr10
-rw-r--r--tests/ui/lint/unused/unused-macro-with-follow-violation.rs7
-rw-r--r--tests/ui/lint/unused/unused-macro-with-follow-violation.stderr10
-rw-r--r--tests/ui/lint/unused/unused-macros-decl.rs28
-rw-r--r--tests/ui/lint/unused/unused-macros-decl.stderr32
-rw-r--r--tests/ui/lint/unused/unused-macros-malformed-rule.rs15
-rw-r--r--tests/ui/lint/unused/unused-macros-malformed-rule.stderr26
-rw-r--r--tests/ui/lint/unused/unused-macros.rs31
-rw-r--r--tests/ui/lint/unused/unused-macros.stderr32
-rw-r--r--tests/ui/lint/unused/unused-mut-warning-captured-var.fixed9
-rw-r--r--tests/ui/lint/unused/unused-mut-warning-captured-var.rs9
-rw-r--r--tests/ui/lint/unused/unused-mut-warning-captured-var.stderr16
-rw-r--r--tests/ui/lint/unused/unused-result.rs42
-rw-r--r--tests/ui/lint/unused/unused-result.stderr48
-rw-r--r--tests/ui/lint/unused/unused-supertrait.rs11
-rw-r--r--tests/ui/lint/unused/unused-supertrait.stderr15
-rw-r--r--tests/ui/lint/unused/unused_attributes-must_use.rs131
-rw-r--r--tests/ui/lint/unused/unused_attributes-must_use.stderr187
-rw-r--r--tests/ui/lint/unused/useless-comment.rs45
-rw-r--r--tests/ui/lint/unused/useless-comment.stderr110
-rw-r--r--tests/ui/lint/unused_braces.fixed57
-rw-r--r--tests/ui/lint/unused_braces.rs57
-rw-r--r--tests/ui/lint/unused_braces.stderr84
-rw-r--r--tests/ui/lint/unused_braces_borrow.fixed26
-rw-r--r--tests/ui/lint/unused_braces_borrow.rs26
-rw-r--r--tests/ui/lint/unused_braces_borrow.stderr19
-rw-r--r--tests/ui/lint/unused_braces_macro.rs6
-rw-r--r--tests/ui/lint/unused_import_warning_issue_45268.rs49
-rw-r--r--tests/ui/lint/unused_import_warning_issue_45268.stderr14
-rw-r--r--tests/ui/lint/unused_labels.rs85
-rw-r--r--tests/ui/lint/unused_labels.stderr65
-rw-r--r--tests/ui/lint/unused_parens_json_suggestion.fixed26
-rw-r--r--tests/ui/lint/unused_parens_json_suggestion.rs26
-rw-r--r--tests/ui/lint/unused_parens_json_suggestion.stderr21
-rw-r--r--tests/ui/lint/unused_parens_multibyte_recovery.rs11
-rw-r--r--tests/ui/lint/unused_parens_multibyte_recovery.stderr43
-rw-r--r--tests/ui/lint/unused_parens_remove_json_suggestion.fixed61
-rw-r--r--tests/ui/lint/unused_parens_remove_json_suggestion.rs61
-rw-r--r--tests/ui/lint/unused_parens_remove_json_suggestion.stderr125
-rw-r--r--tests/ui/lint/unused_variables-issue-82488.fixed16
-rw-r--r--tests/ui/lint/unused_variables-issue-82488.rs16
-rw-r--r--tests/ui/lint/unused_variables-issue-82488.stderr14
-rw-r--r--tests/ui/lint/use-redundant.rs27
-rw-r--r--tests/ui/lint/use-redundant.stderr29
-rw-r--r--tests/ui/lint/use_suggestion_json.rs13
-rw-r--r--tests/ui/lint/use_suggestion_json.stderr3
-rw-r--r--tests/ui/lint/warn-ctypes-inhibit.rs15
-rw-r--r--tests/ui/lint/warn-path-statement.rs17
-rw-r--r--tests/ui/lint/warn-path-statement.stderr22
-rw-r--r--tests/ui/lint/warn-unused-inline-on-fn-prototypes.rs13
-rw-r--r--tests/ui/lint/warn-unused-inline-on-fn-prototypes.stderr20
712 files changed, 32007 insertions, 0 deletions
diff --git a/tests/ui/lint/auxiliary/add-impl.rs b/tests/ui/lint/auxiliary/add-impl.rs
new file mode 100644
index 000000000..9d0e3068a
--- /dev/null
+++ b/tests/ui/lint/auxiliary/add-impl.rs
@@ -0,0 +1,22 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_derive(AddImpl)]
+// Unnecessary qualification `bar::foo`
+// https://github.com/rust-lang/rust/issues/71898
+pub fn derive(input: TokenStream) -> TokenStream {
+ "impl B {
+ fn foo(&self) { use bar::foo; bar::foo() }
+ }
+
+ fn foo() {}
+
+ mod bar { pub fn foo() {} }
+ ".parse().unwrap()
+}
diff --git a/tests/ui/lint/auxiliary/external_extern_fn.rs b/tests/ui/lint/auxiliary/external_extern_fn.rs
new file mode 100644
index 000000000..c2a8cadc6
--- /dev/null
+++ b/tests/ui/lint/auxiliary/external_extern_fn.rs
@@ -0,0 +1,3 @@
+extern "C" {
+ pub fn extern_fn(x: u8);
+}
diff --git a/tests/ui/lint/auxiliary/inherited_stability.rs b/tests/ui/lint/auxiliary/inherited_stability.rs
new file mode 100644
index 000000000..62100e5cc
--- /dev/null
+++ b/tests/ui/lint/auxiliary/inherited_stability.rs
@@ -0,0 +1,47 @@
+#![crate_name="inherited_stability"]
+#![crate_type = "lib"]
+#![unstable(feature = "unstable_test_feature", issue = "none")]
+#![feature(staged_api)]
+
+pub fn unstable() {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn stable() {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub mod stable_mod {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub fn unstable() {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn stable() {}
+}
+
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub mod unstable_mod {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn deprecated() {}
+
+ pub fn unstable() {}
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Stable {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ fn unstable(&self);
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn stable(&self);
+}
+
+impl Stable for usize {
+ fn unstable(&self) {}
+ fn stable(&self) {}
+}
+
+pub enum Unstable {
+ UnstableVariant,
+ #[stable(feature = "rust1", since = "1.0.0")]
+ StableVariant
+}
diff --git a/tests/ui/lint/auxiliary/lint_output_format.rs b/tests/ui/lint/auxiliary/lint_output_format.rs
new file mode 100644
index 000000000..4e3547250
--- /dev/null
+++ b/tests/ui/lint/auxiliary/lint_output_format.rs
@@ -0,0 +1,20 @@
+#![crate_name="lint_output_format"]
+#![crate_type = "lib"]
+#![feature(staged_api)]
+#![unstable(feature = "unstable_test_feature", issue = "none")]
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[deprecated(since = "1.0.0", note = "text")]
+pub fn foo() -> usize {
+ 20
+}
+
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub fn bar() -> usize {
+ 40
+}
+
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub fn baz() -> usize {
+ 30
+}
diff --git a/tests/ui/lint/auxiliary/lint_stability.rs b/tests/ui/lint/auxiliary/lint_stability.rs
new file mode 100644
index 000000000..99c29dcdd
--- /dev/null
+++ b/tests/ui/lint/auxiliary/lint_stability.rs
@@ -0,0 +1,188 @@
+#![crate_name="lint_stability"]
+#![crate_type = "lib"]
+#![feature(staged_api)]
+#![feature(associated_type_defaults)]
+#![stable(feature = "lint_stability", since = "1.0.0")]
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[deprecated(since = "1.0.0", note = "text")]
+pub fn deprecated() {}
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[deprecated(since = "1.0.0", note = "text")]
+pub fn deprecated_text() {}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[deprecated(since = "99.99.99", note = "text")]
+pub fn deprecated_future() {}
+
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+#[deprecated(since = "1.0.0", note = "text")]
+pub fn deprecated_unstable() {}
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+#[deprecated(since = "1.0.0", note = "text")]
+pub fn deprecated_unstable_text() {}
+
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub fn unstable() {}
+#[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")]
+pub fn unstable_text() {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn stable() {}
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn stable_text() {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct MethodTester;
+
+impl MethodTester {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn method_deprecated(&self) {}
+ #[stable(feature = "stable_test_feature", since = "1.0.0")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn method_deprecated_text(&self) {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn method_deprecated_unstable(&self) {}
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn method_deprecated_unstable_text(&self) {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub fn method_unstable(&self) {}
+ #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")]
+ pub fn method_unstable_text(&self) {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn method_stable(&self) {}
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn method_stable_text(&self) {}
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+pub trait Trait {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn trait_deprecated(&self) {}
+ #[stable(feature = "stable_test_feature", since = "1.0.0")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn trait_deprecated_text(&self) {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn trait_deprecated_unstable(&self) {}
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn trait_deprecated_unstable_text(&self) {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ fn trait_unstable(&self) {}
+ #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")]
+ fn trait_unstable_text(&self) {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn trait_stable(&self) {}
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn trait_stable_text(&self) {}
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+pub trait TraitWithAssociatedTypes {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ type TypeUnstable = u8;
+ #[stable(feature = "stable_test_feature", since = "1.0.0")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ type TypeDeprecated = u8;
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+impl Trait for MethodTester {}
+
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub trait UnstableTrait { fn dummy(&self) { } }
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[deprecated(since = "1.0.0", note = "text")]
+pub trait DeprecatedTrait {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] fn dummy(&self) { }
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[deprecated(since = "1.0.0", note = "text")]
+pub struct DeprecatedStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize
+}
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+#[deprecated(since = "1.0.0", note = "text")]
+pub struct DeprecatedUnstableStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize
+}
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub struct UnstableStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct StableStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize
+}
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub enum UnstableEnum {}
+#[stable(feature = "rust1", since = "1.0.0")]
+pub enum StableEnum {}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[deprecated(since = "1.0.0", note = "text")]
+pub struct DeprecatedUnitStruct;
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+#[deprecated(since = "1.0.0", note = "text")]
+pub struct DeprecatedUnstableUnitStruct;
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub struct UnstableUnitStruct;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct StableUnitStruct;
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+pub enum Enum {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ DeprecatedVariant,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ DeprecatedUnstableVariant,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ UnstableVariant,
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ StableVariant,
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[deprecated(since = "1.0.0", note = "text")]
+pub struct DeprecatedTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+#[deprecated(since = "1.0.0", note = "text")]
+pub struct DeprecatedUnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub struct UnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct StableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[macro_export]
+macro_rules! macro_test {
+ () => (deprecated());
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[macro_export]
+macro_rules! macro_test_arg {
+ ($func:expr) => ($func);
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[macro_export]
+macro_rules! macro_test_arg_nested {
+ ($func:ident) => (macro_test_arg!($func()));
+}
diff --git a/tests/ui/lint/auxiliary/lint_stability_fields.rs b/tests/ui/lint/auxiliary/lint_stability_fields.rs
new file mode 100644
index 000000000..e72a501e1
--- /dev/null
+++ b/tests/ui/lint/auxiliary/lint_stability_fields.rs
@@ -0,0 +1,66 @@
+#![feature(staged_api)]
+#![stable(feature = "rust1", since = "1.0.0")]
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Stable {
+ pub inherit: u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub override1: u8,
+ #[deprecated(since = "1.0.0", note = "text")]
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub override2: u8,
+ #[stable(feature = "rust2", since = "2.0.0")]
+ pub override3: u8,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Stable2(#[stable(feature = "rust2", since = "2.0.0")] pub u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")] pub u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")] pub u8,
+ pub u8);
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub enum Stable3 {
+ Inherit(u8),
+ InheritOverride(#[stable(feature = "rust2", since = "2.0.0")] u8),
+ #[stable(feature = "rust2", since = "2.0.0")]
+ Override1,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ Override2,
+ #[deprecated(since = "1.0.0", note = "text")]
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ Override3,
+}
+
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub struct Unstable {
+ pub inherit: u8,
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub override1: u8,
+ #[deprecated(since = "1.0.0", note = "text")]
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub override2: u8,
+}
+
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub struct Unstable2(pub u8,
+ #[stable(feature = "rust1", since = "1.0.0")] pub u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")] pub u8);
+
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+#[deprecated(since = "1.0.0", note = "text")]
+pub struct Deprecated {
+ pub inherit: u8,
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub override1: u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub override2: u8,
+}
+
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+#[deprecated(since = "1.0.0", note = "text")]
+pub struct Deprecated2(pub u8,
+ #[stable(feature = "rust1", since = "1.0.0")] pub u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")] pub u8);
diff --git a/tests/ui/lint/auxiliary/lints-in-foreign-macros.rs b/tests/ui/lint/auxiliary/lints-in-foreign-macros.rs
new file mode 100644
index 000000000..b969d9dba
--- /dev/null
+++ b/tests/ui/lint/auxiliary/lints-in-foreign-macros.rs
@@ -0,0 +1,14 @@
+#[macro_export]
+macro_rules! bar {
+ () => {use std::string::ToString;}
+}
+
+#[macro_export]
+macro_rules! baz {
+ ($i:item) => ($i)
+}
+
+#[macro_export]
+macro_rules! baz2 {
+ ($($i:tt)*) => ($($i)*)
+}
diff --git a/tests/ui/lint/auxiliary/stability-cfg2.rs b/tests/ui/lint/auxiliary/stability-cfg2.rs
new file mode 100644
index 000000000..c995038e5
--- /dev/null
+++ b/tests/ui/lint/auxiliary/stability-cfg2.rs
@@ -0,0 +1,5 @@
+// compile-flags:--cfg foo
+
+#![cfg_attr(foo, unstable(feature = "unstable_test_feature", issue = "none"))]
+#![cfg_attr(not(foo), stable(feature = "test_feature", since = "1.0.0"))]
+#![feature(staged_api)]
diff --git a/tests/ui/lint/auxiliary/stability_cfg1.rs b/tests/ui/lint/auxiliary/stability_cfg1.rs
new file mode 100644
index 000000000..2e027cc27
--- /dev/null
+++ b/tests/ui/lint/auxiliary/stability_cfg1.rs
@@ -0,0 +1,3 @@
+#![cfg_attr(foo, experimental)]
+#![cfg_attr(not(foo), stable(feature = "test_feature", since = "1.0.0"))]
+#![feature(staged_api)]
diff --git a/tests/ui/lint/auxiliary/stability_cfg2.rs b/tests/ui/lint/auxiliary/stability_cfg2.rs
new file mode 100644
index 000000000..c995038e5
--- /dev/null
+++ b/tests/ui/lint/auxiliary/stability_cfg2.rs
@@ -0,0 +1,5 @@
+// compile-flags:--cfg foo
+
+#![cfg_attr(foo, unstable(feature = "unstable_test_feature", issue = "none"))]
+#![cfg_attr(not(foo), stable(feature = "test_feature", since = "1.0.0"))]
+#![feature(staged_api)]
diff --git a/tests/ui/lint/auxiliary/trivial-cast-ice.rs b/tests/ui/lint/auxiliary/trivial-cast-ice.rs
new file mode 100644
index 000000000..ab2332d06
--- /dev/null
+++ b/tests/ui/lint/auxiliary/trivial-cast-ice.rs
@@ -0,0 +1,7 @@
+#[macro_export]
+macro_rules! foo {
+ () => {
+ let x: &Option<i32> = &Some(1);
+ let _y = x as *const Option<i32>;
+ }
+}
diff --git a/tests/ui/lint/auxiliary/unaligned_references_external_crate.rs b/tests/ui/lint/auxiliary/unaligned_references_external_crate.rs
new file mode 100644
index 000000000..fb486c6b5
--- /dev/null
+++ b/tests/ui/lint/auxiliary/unaligned_references_external_crate.rs
@@ -0,0 +1,28 @@
+#[macro_export]
+macro_rules! mac {
+ (
+ $(#[$attrs:meta])*
+ pub struct $ident:ident {
+ $(
+ $(#[$pin:ident])?
+ $field_vis:vis $field:ident: $field_ty:ty
+ ),+ $(,)?
+ }
+ ) => {
+ $(#[$attrs])*
+ pub struct $ident {
+ $(
+ $field_vis $field: $field_ty
+ ),+
+ }
+
+ const _: () = {
+ #[deny(unaligned_references)]
+ fn __f(this: &$ident) {
+ $(
+ let _ = &this.$field;
+ )+
+ }
+ };
+ };
+}
diff --git a/tests/ui/lint/bad-lint-cap.rs b/tests/ui/lint/bad-lint-cap.rs
new file mode 100644
index 000000000..e65c8319d
--- /dev/null
+++ b/tests/ui/lint/bad-lint-cap.rs
@@ -0,0 +1,4 @@
+// compile-flags: --cap-lints test
+// error-pattern: unknown lint level: `test`
+
+fn main() {}
diff --git a/tests/ui/lint/bad-lint-cap.stderr b/tests/ui/lint/bad-lint-cap.stderr
new file mode 100644
index 000000000..f284dbf84
--- /dev/null
+++ b/tests/ui/lint/bad-lint-cap.stderr
@@ -0,0 +1,2 @@
+error: unknown lint level: `test`
+
diff --git a/tests/ui/lint/bad-lint-cap2.rs b/tests/ui/lint/bad-lint-cap2.rs
new file mode 100644
index 000000000..8bc8aca20
--- /dev/null
+++ b/tests/ui/lint/bad-lint-cap2.rs
@@ -0,0 +1,8 @@
+// compile-flags: --cap-lints deny
+
+#![warn(unused)]
+#![deny(warnings)]
+
+use std::option; //~ ERROR
+
+fn main() {}
diff --git a/tests/ui/lint/bad-lint-cap2.stderr b/tests/ui/lint/bad-lint-cap2.stderr
new file mode 100644
index 000000000..3f3affe5a
--- /dev/null
+++ b/tests/ui/lint/bad-lint-cap2.stderr
@@ -0,0 +1,15 @@
+error: unused import: `std::option`
+ --> $DIR/bad-lint-cap2.rs:6:5
+ |
+LL | use std::option;
+ | ^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/bad-lint-cap2.rs:4:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(unused_imports)]` implied by `#[deny(warnings)]`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/bad-lint-cap3.rs b/tests/ui/lint/bad-lint-cap3.rs
new file mode 100644
index 000000000..c38105870
--- /dev/null
+++ b/tests/ui/lint/bad-lint-cap3.rs
@@ -0,0 +1,9 @@
+// check-pass
+// compile-flags: --cap-lints warn
+
+#![warn(unused)]
+#![deny(warnings)]
+
+use std::option; //~ WARN
+
+fn main() {}
diff --git a/tests/ui/lint/bad-lint-cap3.stderr b/tests/ui/lint/bad-lint-cap3.stderr
new file mode 100644
index 000000000..0fb65322f
--- /dev/null
+++ b/tests/ui/lint/bad-lint-cap3.stderr
@@ -0,0 +1,15 @@
+warning: unused import: `std::option`
+ --> $DIR/bad-lint-cap3.rs:7:5
+ |
+LL | use std::option;
+ | ^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/bad-lint-cap3.rs:5:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[warn(unused_imports)]` implied by `#[warn(warnings)]`
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/bare-trait-objects-path.rs b/tests/ui/lint/bare-trait-objects-path.rs
new file mode 100644
index 000000000..0e2294715
--- /dev/null
+++ b/tests/ui/lint/bare-trait-objects-path.rs
@@ -0,0 +1,26 @@
+#![feature(associated_type_defaults)]
+
+trait Assoc {
+ fn func() {}
+ const CONST: u8 = 0;
+ type Ty = u8;
+}
+
+trait Dyn {}
+
+impl Assoc for dyn Dyn {}
+
+fn main() {
+ Dyn::func();
+ //~^ WARN trait objects without an explicit `dyn` are deprecated
+ //~| WARN this is accepted in the current edition
+ ::Dyn::func();
+ //~^ WARN trait objects without an explicit `dyn` are deprecated
+ //~| WARN this is accepted in the current edition
+ Dyn::CONST;
+ //~^ WARN trait objects without an explicit `dyn` are deprecated
+ //~| WARN this is accepted in the current edition
+ let _: Dyn::Ty; //~ ERROR ambiguous associated type
+ //~^ WARN trait objects without an explicit `dyn` are deprecated
+ //~| WARN this is accepted in the current edition
+}
diff --git a/tests/ui/lint/bare-trait-objects-path.stderr b/tests/ui/lint/bare-trait-objects-path.stderr
new file mode 100644
index 000000000..a19f4963c
--- /dev/null
+++ b/tests/ui/lint/bare-trait-objects-path.stderr
@@ -0,0 +1,62 @@
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/bare-trait-objects-path.rs:23:12
+ |
+LL | let _: Dyn::Ty;
+ | ^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: `#[warn(bare_trait_objects)]` on by default
+help: use `dyn`
+ |
+LL | let _: <dyn Dyn>::Ty;
+ | ++++ +
+
+error[E0223]: ambiguous associated type
+ --> $DIR/bare-trait-objects-path.rs:23:12
+ |
+LL | let _: Dyn::Ty;
+ | ^^^^^^^ help: use the fully-qualified path: `<dyn Dyn as Assoc>::Ty`
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/bare-trait-objects-path.rs:14:5
+ |
+LL | Dyn::func();
+ | ^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | <dyn Dyn>::func();
+ | ++++ +
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/bare-trait-objects-path.rs:17:5
+ |
+LL | ::Dyn::func();
+ | ^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | <dyn (::Dyn)>::func();
+ | ++++++ ++
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/bare-trait-objects-path.rs:20:5
+ |
+LL | Dyn::CONST;
+ | ^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | <dyn Dyn>::CONST;
+ | ++++ +
+
+error: aborting due to previous error; 4 warnings emitted
+
+For more information about this error, try `rustc --explain E0223`.
diff --git a/tests/ui/lint/clashing-extern-fn-recursion.rs b/tests/ui/lint/clashing-extern-fn-recursion.rs
new file mode 100644
index 000000000..ab0fd0a2e
--- /dev/null
+++ b/tests/ui/lint/clashing-extern-fn-recursion.rs
@@ -0,0 +1,119 @@
+// check-pass
+//
+// This tests checks that clashing_extern_declarations handles types that are recursive through a
+// pointer or ref argument. See #75512.
+
+#![crate_type = "lib"]
+
+mod raw_ptr_recursion {
+ mod a {
+ #[repr(C)]
+ struct Pointy {
+ pointy: *const Pointy,
+ }
+
+ extern "C" {
+ fn run_pointy(pointy: Pointy);
+ }
+ }
+ mod b {
+ #[repr(C)]
+ struct Pointy {
+ pointy: *const Pointy,
+ }
+
+ extern "C" {
+ fn run_pointy(pointy: Pointy);
+ }
+ }
+}
+
+mod raw_ptr_recursion_once_removed {
+ mod a {
+ #[repr(C)]
+ struct Pointy1 {
+ pointy_two: *const Pointy2,
+ }
+
+ #[repr(C)]
+ struct Pointy2 {
+ pointy_one: *const Pointy1,
+ }
+
+ extern "C" {
+ fn run_pointy2(pointy: Pointy2);
+ }
+ }
+
+ mod b {
+ #[repr(C)]
+ struct Pointy1 {
+ pointy_two: *const Pointy2,
+ }
+
+ #[repr(C)]
+ struct Pointy2 {
+ pointy_one: *const Pointy1,
+ }
+
+ extern "C" {
+ fn run_pointy2(pointy: Pointy2);
+ }
+ }
+}
+
+mod ref_recursion {
+ mod a {
+ #[repr(C)]
+ struct Reffy<'a> {
+ reffy: &'a Reffy<'a>,
+ }
+
+ extern "C" {
+ fn reffy_recursion(reffy: Reffy);
+ }
+ }
+ mod b {
+ #[repr(C)]
+ struct Reffy<'a> {
+ reffy: &'a Reffy<'a>,
+ }
+
+ extern "C" {
+ fn reffy_recursion(reffy: Reffy);
+ }
+ }
+}
+
+mod ref_recursion_once_removed {
+ mod a {
+ #[repr(C)]
+ struct Reffy1<'a> {
+ reffy: &'a Reffy2<'a>,
+ }
+
+ struct Reffy2<'a> {
+ reffy: &'a Reffy1<'a>,
+ }
+
+ extern "C" {
+ #[allow(improper_ctypes)]
+ fn reffy_once_removed(reffy: Reffy1);
+ }
+ }
+ mod b {
+ #[repr(C)]
+ struct Reffy1<'a> {
+ reffy: &'a Reffy2<'a>,
+ }
+
+ struct Reffy2<'a> {
+ reffy: &'a Reffy1<'a>,
+ }
+
+ extern "C" {
+ #[allow(improper_ctypes)]
+ fn reffy_once_removed(reffy: Reffy1);
+ }
+ }
+}
diff --git a/tests/ui/lint/clashing-extern-fn-wasm.rs b/tests/ui/lint/clashing-extern-fn-wasm.rs
new file mode 100644
index 000000000..eeb2b8eae
--- /dev/null
+++ b/tests/ui/lint/clashing-extern-fn-wasm.rs
@@ -0,0 +1,21 @@
+// check-pass
+#![crate_type = "lib"]
+
+#[cfg(target_arch = "wasm32")]
+mod wasm_non_clash {
+ mod a {
+ #[link(wasm_import_module = "a")]
+ extern "C" {
+ pub fn foo();
+ }
+ }
+
+ mod b {
+ #[link(wasm_import_module = "b")]
+ extern "C" {
+ pub fn foo() -> usize;
+ // #79581: These declarations shouldn't clash because foreign fn names are mangled
+ // on wasm32.
+ }
+ }
+}
diff --git a/tests/ui/lint/clashing-extern-fn.rs b/tests/ui/lint/clashing-extern-fn.rs
new file mode 100644
index 000000000..809e06026
--- /dev/null
+++ b/tests/ui/lint/clashing-extern-fn.rs
@@ -0,0 +1,417 @@
+// check-pass
+// aux-build:external_extern_fn.rs
+#![crate_type = "lib"]
+#![warn(clashing_extern_declarations)]
+
+mod redeclared_different_signature {
+ mod a {
+ extern "C" {
+ fn clash(x: u8);
+ }
+ }
+ mod b {
+ extern "C" {
+ fn clash(x: u64); //~ WARN `clash` redeclared with a different signature
+ }
+ }
+}
+
+mod redeclared_same_signature {
+ mod a {
+ extern "C" {
+ fn no_clash(x: u8);
+ }
+ }
+ mod b {
+ extern "C" {
+ fn no_clash(x: u8);
+ }
+ }
+}
+
+extern crate external_extern_fn;
+mod extern_no_clash {
+ // Should not clash with external_extern_fn::extern_fn.
+ extern "C" {
+ fn extern_fn(x: u8);
+ }
+}
+
+extern "C" {
+ fn some_other_new_name(x: i16);
+
+ #[link_name = "extern_link_name"]
+ fn some_new_name(x: i16);
+
+ #[link_name = "link_name_same"]
+ fn both_names_different(x: i16);
+}
+
+fn link_name_clash() {
+ extern "C" {
+ fn extern_link_name(x: u32);
+ //~^ WARN `extern_link_name` redeclared with a different signature
+
+ #[link_name = "some_other_new_name"]
+ //~^ WARN `some_other_extern_link_name` redeclares `some_other_new_name` with a different
+ fn some_other_extern_link_name(x: u32);
+
+ #[link_name = "link_name_same"]
+ //~^ WARN `other_both_names_different` redeclares `link_name_same` with a different
+ fn other_both_names_different(x: u32);
+ }
+}
+
+mod a {
+ extern "C" {
+ fn different_mod(x: u8);
+ }
+}
+mod b {
+ extern "C" {
+ fn different_mod(x: u64); //~ WARN `different_mod` redeclared with a different signature
+ }
+}
+
+extern "C" {
+ fn variadic_decl(x: u8, ...);
+}
+
+fn variadic_clash() {
+ extern "C" {
+ fn variadic_decl(x: u8); //~ WARN `variadic_decl` redeclared with a different signature
+ }
+}
+
+#[no_mangle]
+fn no_mangle_name(x: u8) {}
+
+extern "C" {
+ #[link_name = "unique_link_name"]
+ fn link_name_specified(x: u8);
+}
+
+fn tricky_no_clash() {
+ extern "C" {
+ // Shouldn't warn, because the declaration above actually declares a different symbol (and
+ // Rust's name resolution rules around shadowing will handle this gracefully).
+ fn link_name_specified() -> u32;
+
+ // The case of a no_mangle name colliding with an extern decl (see #28179) is related but
+ // shouldn't be reported by ClashingExternDeclarations, because this is an example of
+ // unmangled name clash causing bad behaviour in functions with a defined body.
+ fn no_mangle_name() -> u32;
+ }
+}
+
+mod banana {
+ mod one {
+ #[repr(C)]
+ struct Banana {
+ weight: u32,
+ length: u16,
+ }
+ extern "C" {
+ fn weigh_banana(count: *const Banana) -> u64;
+ }
+ }
+
+ mod two {
+ #[repr(C)]
+ struct Banana {
+ weight: u32,
+ length: u16,
+ } // note: distinct type
+ // This should not trigger the lint because two::Banana is structurally equivalent to
+ // one::Banana.
+ extern "C" {
+ fn weigh_banana(count: *const Banana) -> u64;
+ }
+ }
+
+ mod three {
+ // This _should_ trigger the lint, because repr(packed) should generate a struct that has a
+ // different layout.
+ #[repr(packed)]
+ struct Banana {
+ weight: u32,
+ length: u16,
+ }
+ #[allow(improper_ctypes)]
+ extern "C" {
+ fn weigh_banana(count: *const Banana) -> u64;
+ //~^ WARN `weigh_banana` redeclared with a different signature
+ }
+ }
+}
+
+mod sameish_members {
+ mod a {
+ #[repr(C)]
+ struct Point {
+ x: i16,
+ y: i16,
+ }
+
+ extern "C" {
+ fn draw_point(p: Point);
+ }
+ }
+ mod b {
+ #[repr(C)]
+ struct Point {
+ coordinates: [i16; 2],
+ }
+
+ // It's possible we are overconservative for this case, as accessing the elements of the
+ // coordinates array might end up correctly accessing `.x` and `.y`. However, this may not
+ // always be the case, for every architecture and situation. This is also a really odd
+ // thing to do anyway.
+ extern "C" {
+ fn draw_point(p: Point);
+ //~^ WARN `draw_point` redeclared with a different signature
+ }
+ }
+}
+
+mod same_sized_members_clash {
+ mod a {
+ #[repr(C)]
+ struct Point3 {
+ x: f32,
+ y: f32,
+ z: f32,
+ }
+ extern "C" {
+ fn origin() -> Point3;
+ }
+ }
+ mod b {
+ #[repr(C)]
+ struct Point3 {
+ x: i32,
+ y: i32,
+ z: i32, // NOTE: Incorrectly redeclared as i32
+ }
+ extern "C" {
+ fn origin() -> Point3; //~ WARN `origin` redeclared with a different signature
+ }
+ }
+}
+
+mod transparent {
+ #[repr(transparent)]
+ struct T(usize);
+ mod a {
+ use super::T;
+ extern "C" {
+ fn transparent() -> T;
+ fn transparent_incorrect() -> T;
+ }
+ }
+
+ mod b {
+ extern "C" {
+ // Shouldn't warn here, because repr(transparent) guarantees that T's layout is the
+ // same as just the usize.
+ fn transparent() -> usize;
+
+ // Should warn, because there's a signedness conversion here:
+ fn transparent_incorrect() -> isize;
+ //~^ WARN `transparent_incorrect` redeclared with a different signature
+ }
+ }
+}
+
+mod missing_return_type {
+ mod a {
+ extern "C" {
+ fn missing_return_type() -> usize;
+ }
+ }
+
+ mod b {
+ extern "C" {
+ // This should output a warning because we can't assume that the first declaration is
+ // the correct one -- if this one is the correct one, then calling the usize-returning
+ // version would allow reads into uninitialised memory.
+ fn missing_return_type();
+ //~^ WARN `missing_return_type` redeclared with a different signature
+ }
+ }
+}
+
+mod non_zero_and_non_null {
+ mod a {
+ extern "C" {
+ fn non_zero_usize() -> core::num::NonZeroUsize;
+ fn non_null_ptr() -> core::ptr::NonNull<usize>;
+ }
+ }
+ mod b {
+ extern "C" {
+ // If there's a clash in either of these cases you're either gaining an incorrect
+ // invariant that the value is non-zero, or you're missing out on that invariant. Both
+ // cases are warning for, from both a caller-convenience and optimisation perspective.
+ fn non_zero_usize() -> usize;
+ //~^ WARN `non_zero_usize` redeclared with a different signature
+ fn non_null_ptr() -> *const usize;
+ //~^ WARN `non_null_ptr` redeclared with a different signature
+ }
+ }
+}
+
+// See #75739
+mod non_zero_transparent {
+ mod a1 {
+ use std::num::NonZeroUsize;
+ extern "C" {
+ fn f1() -> NonZeroUsize;
+ }
+ }
+
+ mod b1 {
+ #[repr(transparent)]
+ struct X(NonZeroUsize);
+ use std::num::NonZeroUsize;
+ extern "C" {
+ fn f1() -> X;
+ }
+ }
+
+ mod a2 {
+ use std::num::NonZeroUsize;
+ extern "C" {
+ fn f2() -> NonZeroUsize;
+ }
+ }
+
+ mod b2 {
+ #[repr(transparent)]
+ struct X1(NonZeroUsize);
+
+ #[repr(transparent)]
+ struct X(X1);
+
+ use std::num::NonZeroUsize;
+ extern "C" {
+ // Same case as above, but with two layers of newtyping.
+ fn f2() -> X;
+ }
+ }
+
+ mod a3 {
+ #[repr(transparent)]
+ struct X(core::ptr::NonNull<i32>);
+
+ use std::num::NonZeroUsize;
+ extern "C" {
+ fn f3() -> X;
+ }
+ }
+
+ mod b3 {
+ extern "C" {
+ fn f3() -> core::ptr::NonNull<i32>;
+ }
+ }
+
+ mod a4 {
+ #[repr(transparent)]
+ enum E {
+ X(std::num::NonZeroUsize),
+ }
+ extern "C" {
+ fn f4() -> E;
+ }
+ }
+
+ mod b4 {
+ extern "C" {
+ fn f4() -> std::num::NonZeroUsize;
+ }
+ }
+}
+
+mod null_optimised_enums {
+ mod a {
+ extern "C" {
+ fn option_non_zero_usize() -> usize;
+ fn option_non_zero_isize() -> isize;
+ fn option_non_null_ptr() -> *const usize;
+
+ fn option_non_zero_usize_incorrect() -> usize;
+ fn option_non_null_ptr_incorrect() -> *const usize;
+ }
+ }
+ mod b {
+ extern "C" {
+ // This should be allowed, because these conversions are guaranteed to be FFI-safe (see
+ // #60300)
+ fn option_non_zero_usize() -> Option<core::num::NonZeroUsize>;
+ fn option_non_zero_isize() -> Option<core::num::NonZeroIsize>;
+ fn option_non_null_ptr() -> Option<core::ptr::NonNull<usize>>;
+
+ // However, these should be incorrect (note isize instead of usize)
+ fn option_non_zero_usize_incorrect() -> isize;
+ //~^ WARN `option_non_zero_usize_incorrect` redeclared with a different signature
+ fn option_non_null_ptr_incorrect() -> *const isize;
+ //~^ WARN `option_non_null_ptr_incorrect` redeclared with a different signature
+ }
+ }
+}
+
+#[allow(improper_ctypes)]
+mod unknown_layout {
+ mod a {
+ extern "C" {
+ pub fn generic(l: Link<u32>);
+ }
+ pub struct Link<T> {
+ pub item: T,
+ pub next: *const Link<T>,
+ }
+ }
+
+ mod b {
+ extern "C" {
+ pub fn generic(l: Link<u32>);
+ }
+ pub struct Link<T> {
+ pub item: T,
+ pub next: *const Link<T>,
+ }
+ }
+}
+
+mod hidden_niche {
+ mod a {
+ extern "C" {
+ fn hidden_niche_transparent() -> usize;
+ fn hidden_niche_transparent_no_niche() -> usize;
+ fn hidden_niche_unsafe_cell() -> usize;
+ }
+ }
+ mod b {
+ use std::cell::UnsafeCell;
+ use std::num::NonZeroUsize;
+
+ #[repr(transparent)]
+ struct Transparent { x: NonZeroUsize }
+
+ #[repr(transparent)]
+ struct TransparentNoNiche { y: UnsafeCell<NonZeroUsize> }
+
+ extern "C" {
+ fn hidden_niche_transparent() -> Option<Transparent>;
+
+ fn hidden_niche_transparent_no_niche() -> Option<TransparentNoNiche>;
+ //~^ WARN redeclared with a different signature
+ //~| WARN block uses type `Option<TransparentNoNiche>`, which is not FFI-safe
+
+ fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
+ //~^ WARN redeclared with a different signature
+ //~| WARN block uses type `Option<UnsafeCell<NonZeroUsize>>`, which is not FFI-safe
+ }
+ }
+}
diff --git a/tests/ui/lint/clashing-extern-fn.stderr b/tests/ui/lint/clashing-extern-fn.stderr
new file mode 100644
index 000000000..217eed6c9
--- /dev/null
+++ b/tests/ui/lint/clashing-extern-fn.stderr
@@ -0,0 +1,236 @@
+warning: `clash` redeclared with a different signature
+ --> $DIR/clashing-extern-fn.rs:14:13
+ |
+LL | fn clash(x: u8);
+ | ---------------- `clash` previously declared here
+...
+LL | fn clash(x: u64);
+ | ^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn(u8)`
+ found `unsafe extern "C" fn(u64)`
+note: the lint level is defined here
+ --> $DIR/clashing-extern-fn.rs:4:9
+ |
+LL | #![warn(clashing_extern_declarations)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: `extern_link_name` redeclared with a different signature
+ --> $DIR/clashing-extern-fn.rs:52:9
+ |
+LL | / #[link_name = "extern_link_name"]
+LL | | fn some_new_name(x: i16);
+ | |_____________________________- `extern_link_name` previously declared here
+...
+LL | fn extern_link_name(x: u32);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn(i16)`
+ found `unsafe extern "C" fn(u32)`
+
+warning: `some_other_extern_link_name` redeclares `some_other_new_name` with a different signature
+ --> $DIR/clashing-extern-fn.rs:55:9
+ |
+LL | fn some_other_new_name(x: i16);
+ | ------------------------------- `some_other_new_name` previously declared here
+...
+LL | / #[link_name = "some_other_new_name"]
+LL | |
+LL | | fn some_other_extern_link_name(x: u32);
+ | |_______________________________________________^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn(i16)`
+ found `unsafe extern "C" fn(u32)`
+
+warning: `other_both_names_different` redeclares `link_name_same` with a different signature
+ --> $DIR/clashing-extern-fn.rs:59:9
+ |
+LL | / #[link_name = "link_name_same"]
+LL | | fn both_names_different(x: i16);
+ | |____________________________________- `link_name_same` previously declared here
+...
+LL | / #[link_name = "link_name_same"]
+LL | |
+LL | | fn other_both_names_different(x: u32);
+ | |______________________________________________^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn(i16)`
+ found `unsafe extern "C" fn(u32)`
+
+warning: `different_mod` redeclared with a different signature
+ --> $DIR/clashing-extern-fn.rs:72:9
+ |
+LL | fn different_mod(x: u8);
+ | ------------------------ `different_mod` previously declared here
+...
+LL | fn different_mod(x: u64);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn(u8)`
+ found `unsafe extern "C" fn(u64)`
+
+warning: `variadic_decl` redeclared with a different signature
+ --> $DIR/clashing-extern-fn.rs:82:9
+ |
+LL | fn variadic_decl(x: u8, ...);
+ | ----------------------------- `variadic_decl` previously declared here
+...
+LL | fn variadic_decl(x: u8);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn(u8, ...)`
+ found `unsafe extern "C" fn(u8)`
+
+warning: `weigh_banana` redeclared with a different signature
+ --> $DIR/clashing-extern-fn.rs:142:13
+ |
+LL | fn weigh_banana(count: *const Banana) -> u64;
+ | --------------------------------------------- `weigh_banana` previously declared here
+...
+LL | fn weigh_banana(count: *const Banana) -> u64;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn(*const one::Banana) -> u64`
+ found `unsafe extern "C" fn(*const three::Banana) -> u64`
+
+warning: `draw_point` redeclared with a different signature
+ --> $DIR/clashing-extern-fn.rs:171:13
+ |
+LL | fn draw_point(p: Point);
+ | ------------------------ `draw_point` previously declared here
+...
+LL | fn draw_point(p: Point);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn(sameish_members::a::Point)`
+ found `unsafe extern "C" fn(sameish_members::b::Point)`
+
+warning: `origin` redeclared with a different signature
+ --> $DIR/clashing-extern-fn.rs:197:13
+ |
+LL | fn origin() -> Point3;
+ | ---------------------- `origin` previously declared here
+...
+LL | fn origin() -> Point3;
+ | ^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn() -> same_sized_members_clash::a::Point3`
+ found `unsafe extern "C" fn() -> same_sized_members_clash::b::Point3`
+
+warning: `transparent_incorrect` redeclared with a different signature
+ --> $DIR/clashing-extern-fn.rs:220:13
+ |
+LL | fn transparent_incorrect() -> T;
+ | -------------------------------- `transparent_incorrect` previously declared here
+...
+LL | fn transparent_incorrect() -> isize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn() -> T`
+ found `unsafe extern "C" fn() -> isize`
+
+warning: `missing_return_type` redeclared with a different signature
+ --> $DIR/clashing-extern-fn.rs:238:13
+ |
+LL | fn missing_return_type() -> usize;
+ | ---------------------------------- `missing_return_type` previously declared here
+...
+LL | fn missing_return_type();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn() -> usize`
+ found `unsafe extern "C" fn()`
+
+warning: `non_zero_usize` redeclared with a different signature
+ --> $DIR/clashing-extern-fn.rs:256:13
+ |
+LL | fn non_zero_usize() -> core::num::NonZeroUsize;
+ | ----------------------------------------------- `non_zero_usize` previously declared here
+...
+LL | fn non_zero_usize() -> usize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn() -> NonZeroUsize`
+ found `unsafe extern "C" fn() -> usize`
+
+warning: `non_null_ptr` redeclared with a different signature
+ --> $DIR/clashing-extern-fn.rs:258:13
+ |
+LL | fn non_null_ptr() -> core::ptr::NonNull<usize>;
+ | ----------------------------------------------- `non_null_ptr` previously declared here
+...
+LL | fn non_null_ptr() -> *const usize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn() -> NonNull<usize>`
+ found `unsafe extern "C" fn() -> *const usize`
+
+warning: `option_non_zero_usize_incorrect` redeclared with a different signature
+ --> $DIR/clashing-extern-fn.rs:356:13
+ |
+LL | fn option_non_zero_usize_incorrect() -> usize;
+ | ---------------------------------------------- `option_non_zero_usize_incorrect` previously declared here
+...
+LL | fn option_non_zero_usize_incorrect() -> isize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn() -> usize`
+ found `unsafe extern "C" fn() -> isize`
+
+warning: `option_non_null_ptr_incorrect` redeclared with a different signature
+ --> $DIR/clashing-extern-fn.rs:358:13
+ |
+LL | fn option_non_null_ptr_incorrect() -> *const usize;
+ | --------------------------------------------------- `option_non_null_ptr_incorrect` previously declared here
+...
+LL | fn option_non_null_ptr_incorrect() -> *const isize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn() -> *const usize`
+ found `unsafe extern "C" fn() -> *const isize`
+
+warning: `hidden_niche_transparent_no_niche` redeclared with a different signature
+ --> $DIR/clashing-extern-fn.rs:408:13
+ |
+LL | fn hidden_niche_transparent_no_niche() -> usize;
+ | ------------------------------------------------ `hidden_niche_transparent_no_niche` previously declared here
+...
+LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoNiche>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn() -> usize`
+ found `unsafe extern "C" fn() -> Option<TransparentNoNiche>`
+
+warning: `hidden_niche_unsafe_cell` redeclared with a different signature
+ --> $DIR/clashing-extern-fn.rs:412:13
+ |
+LL | fn hidden_niche_unsafe_cell() -> usize;
+ | --------------------------------------- `hidden_niche_unsafe_cell` previously declared here
+...
+LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn() -> usize`
+ found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZeroUsize>>`
+
+warning: `extern` block uses type `Option<TransparentNoNiche>`, which is not FFI-safe
+ --> $DIR/clashing-extern-fn.rs:408:55
+ |
+LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoNiche>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+ = note: enum has no representation hint
+ = note: `#[warn(improper_ctypes)]` on by default
+
+warning: `extern` block uses type `Option<UnsafeCell<NonZeroUsize>>`, which is not FFI-safe
+ --> $DIR/clashing-extern-fn.rs:412:46
+ |
+LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+ = note: enum has no representation hint
+
+warning: 19 warnings emitted
+
diff --git a/tests/ui/lint/cli-lint-override.forbid_warn.stderr b/tests/ui/lint/cli-lint-override.forbid_warn.stderr
new file mode 100644
index 000000000..d1c66a81c
--- /dev/null
+++ b/tests/ui/lint/cli-lint-override.forbid_warn.stderr
@@ -0,0 +1,11 @@
+error: extern declarations without an explicit ABI are deprecated
+ --> $DIR/cli-lint-override.rs:12:1
+ |
+LL | extern fn foo() {}
+ | ^^^^^^^^^^^^^^^ ABI should be specified here
+ |
+ = help: the default ABI is C
+ = note: requested on the command line with `-F missing-abi`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/cli-lint-override.force_warn_deny.stderr b/tests/ui/lint/cli-lint-override.force_warn_deny.stderr
new file mode 100644
index 000000000..779c24c93
--- /dev/null
+++ b/tests/ui/lint/cli-lint-override.force_warn_deny.stderr
@@ -0,0 +1,11 @@
+warning: extern declarations without an explicit ABI are deprecated
+ --> $DIR/cli-lint-override.rs:12:1
+ |
+LL | extern fn foo() {}
+ | ^^^^^^^^^^^^^^^ ABI should be specified here
+ |
+ = help: the default ABI is C
+ = note: requested on the command line with `--force-warn missing-abi`
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/cli-lint-override.rs b/tests/ui/lint/cli-lint-override.rs
new file mode 100644
index 000000000..a0e853fc3
--- /dev/null
+++ b/tests/ui/lint/cli-lint-override.rs
@@ -0,0 +1,17 @@
+// Tests that subsequent lints specified via the command line override
+// each other, except for ForceWarn and Forbid, which cannot be overridden.
+//
+// revisions: warn_deny forbid_warn force_warn_deny
+//
+//[warn_deny] compile-flags: --warn missing_abi --deny missing_abi
+//[forbid_warn] compile-flags: --warn missing_abi --forbid missing_abi
+//[force_warn_deny] compile-flags: --force-warn missing_abi --allow missing_abi
+//[force_warn_deny] check-pass
+
+
+extern fn foo() {}
+//[warn_deny]~^ ERROR extern declarations without an explicit ABI are deprecated
+//[forbid_warn]~^^ ERROR extern declarations without an explicit ABI are deprecated
+//[force_warn_deny]~^^^ WARN extern declarations without an explicit ABI are deprecated
+
+fn main() {}
diff --git a/tests/ui/lint/cli-lint-override.warn_deny.stderr b/tests/ui/lint/cli-lint-override.warn_deny.stderr
new file mode 100644
index 000000000..f034cfa93
--- /dev/null
+++ b/tests/ui/lint/cli-lint-override.warn_deny.stderr
@@ -0,0 +1,11 @@
+error: extern declarations without an explicit ABI are deprecated
+ --> $DIR/cli-lint-override.rs:12:1
+ |
+LL | extern fn foo() {}
+ | ^^^^^^^^^^^^^^^ ABI should be specified here
+ |
+ = help: the default ABI is C
+ = note: requested on the command line with `-D missing-abi`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/cli-unknown-force-warn.rs b/tests/ui/lint/cli-unknown-force-warn.rs
new file mode 100644
index 000000000..f3dea87a6
--- /dev/null
+++ b/tests/ui/lint/cli-unknown-force-warn.rs
@@ -0,0 +1,7 @@
+// Checks that rustc correctly errors when passed an invalid lint with
+// `--force-warn`. This is a regression test for issue #86958.
+//
+// compile-flags: --force-warn foo-qux
+// error-pattern: unknown lint: `foo_qux`
+
+fn main() {}
diff --git a/tests/ui/lint/cli-unknown-force-warn.stderr b/tests/ui/lint/cli-unknown-force-warn.stderr
new file mode 100644
index 000000000..9ce9f405a
--- /dev/null
+++ b/tests/ui/lint/cli-unknown-force-warn.stderr
@@ -0,0 +1,11 @@
+error[E0602]: unknown lint: `foo_qux`
+ |
+ = note: requested on the command line with `--force-warn foo_qux`
+
+error[E0602]: unknown lint: `foo_qux`
+ |
+ = note: requested on the command line with `--force-warn foo_qux`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0602`.
diff --git a/tests/ui/lint/command-line-lint-group-allow.rs b/tests/ui/lint/command-line-lint-group-allow.rs
new file mode 100644
index 000000000..21c0df028
--- /dev/null
+++ b/tests/ui/lint/command-line-lint-group-allow.rs
@@ -0,0 +1,6 @@
+// compile-flags: -A bad-style
+// check-pass
+
+fn main() {
+ let _InappropriateCamelCasing = true;
+}
diff --git a/tests/ui/lint/command-line-lint-group-deny.rs b/tests/ui/lint/command-line-lint-group-deny.rs
new file mode 100644
index 000000000..da999f33e
--- /dev/null
+++ b/tests/ui/lint/command-line-lint-group-deny.rs
@@ -0,0 +1,5 @@
+// compile-flags: -D bad-style
+
+fn main() {
+ let _InappropriateCamelCasing = true; //~ ERROR should have a snake
+}
diff --git a/tests/ui/lint/command-line-lint-group-deny.stderr b/tests/ui/lint/command-line-lint-group-deny.stderr
new file mode 100644
index 000000000..04c3f6f26
--- /dev/null
+++ b/tests/ui/lint/command-line-lint-group-deny.stderr
@@ -0,0 +1,10 @@
+error: variable `_InappropriateCamelCasing` should have a snake case name
+ --> $DIR/command-line-lint-group-deny.rs:4:9
+ |
+LL | let _InappropriateCamelCasing = true;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `_inappropriate_camel_casing`
+ |
+ = note: `-D non-snake-case` implied by `-D bad-style`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/command-line-lint-group-forbid.rs b/tests/ui/lint/command-line-lint-group-forbid.rs
new file mode 100644
index 000000000..4e5c2aca5
--- /dev/null
+++ b/tests/ui/lint/command-line-lint-group-forbid.rs
@@ -0,0 +1,5 @@
+// compile-flags: -F bad-style
+
+fn main() {
+ let _InappropriateCamelCasing = true; //~ ERROR should have a snake
+}
diff --git a/tests/ui/lint/command-line-lint-group-forbid.stderr b/tests/ui/lint/command-line-lint-group-forbid.stderr
new file mode 100644
index 000000000..736782140
--- /dev/null
+++ b/tests/ui/lint/command-line-lint-group-forbid.stderr
@@ -0,0 +1,10 @@
+error: variable `_InappropriateCamelCasing` should have a snake case name
+ --> $DIR/command-line-lint-group-forbid.rs:4:9
+ |
+LL | let _InappropriateCamelCasing = true;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `_inappropriate_camel_casing`
+ |
+ = note: `-F non-snake-case` implied by `-F bad-style`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/command-line-lint-group-warn.rs b/tests/ui/lint/command-line-lint-group-warn.rs
new file mode 100644
index 000000000..f4536f9c9
--- /dev/null
+++ b/tests/ui/lint/command-line-lint-group-warn.rs
@@ -0,0 +1,7 @@
+// compile-flags: -W bad-style
+// check-pass
+
+fn main() {
+ let _InappropriateCamelCasing = true;
+ //~^ WARNING should have a snake case name
+}
diff --git a/tests/ui/lint/command-line-lint-group-warn.stderr b/tests/ui/lint/command-line-lint-group-warn.stderr
new file mode 100644
index 000000000..e9c80b4ef
--- /dev/null
+++ b/tests/ui/lint/command-line-lint-group-warn.stderr
@@ -0,0 +1,10 @@
+warning: variable `_InappropriateCamelCasing` should have a snake case name
+ --> $DIR/command-line-lint-group-warn.rs:5:9
+ |
+LL | let _InappropriateCamelCasing = true;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `_inappropriate_camel_casing`
+ |
+ = note: `-W non-snake-case` implied by `-W bad-style`
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/command-line-register-lint-tool.rs b/tests/ui/lint/command-line-register-lint-tool.rs
new file mode 100644
index 000000000..d6e95fd3e
--- /dev/null
+++ b/tests/ui/lint/command-line-register-lint-tool.rs
@@ -0,0 +1,7 @@
+// compile-flags: -A known_tool::foo
+// check-pass
+
+#![feature(register_tool)]
+#![register_tool(known_tool)]
+
+fn main() {}
diff --git a/tests/ui/lint/command-line-register-unknown-lint-tool.rs b/tests/ui/lint/command-line-register-unknown-lint-tool.rs
new file mode 100644
index 000000000..59fc02000
--- /dev/null
+++ b/tests/ui/lint/command-line-register-unknown-lint-tool.rs
@@ -0,0 +1,4 @@
+// compile-flags: -A unknown_tool::foo
+// error-pattern: unknown lint tool: `unknown_tool`
+
+fn main() {}
diff --git a/tests/ui/lint/command-line-register-unknown-lint-tool.stderr b/tests/ui/lint/command-line-register-unknown-lint-tool.stderr
new file mode 100644
index 000000000..c9a2aff21
--- /dev/null
+++ b/tests/ui/lint/command-line-register-unknown-lint-tool.stderr
@@ -0,0 +1,11 @@
+error[E0602]: unknown lint tool: `unknown_tool`
+ |
+ = note: requested on the command line with `-A unknown_tool::foo`
+
+error[E0602]: unknown lint tool: `unknown_tool`
+ |
+ = note: requested on the command line with `-A unknown_tool::foo`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0602`.
diff --git a/tests/ui/lint/crate_level_only_lint.rs b/tests/ui/lint/crate_level_only_lint.rs
new file mode 100644
index 000000000..d9673faa2
--- /dev/null
+++ b/tests/ui/lint/crate_level_only_lint.rs
@@ -0,0 +1,22 @@
+#![deny(uncommon_codepoints, unused_attributes)]
+
+mod foo {
+#![allow(uncommon_codepoints)]
+//~^ ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
+//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
+//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
+
+#[allow(uncommon_codepoints)]
+//~^ ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
+//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
+//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
+const BAR: f64 = 0.000001;
+
+}
+
+#[allow(uncommon_codepoints)]
+//~^ ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
+//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
+//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
+fn main() {
+}
diff --git a/tests/ui/lint/crate_level_only_lint.stderr b/tests/ui/lint/crate_level_only_lint.stderr
new file mode 100644
index 000000000..8fb06df2a
--- /dev/null
+++ b/tests/ui/lint/crate_level_only_lint.stderr
@@ -0,0 +1,62 @@
+error: allow(uncommon_codepoints) is ignored unless specified at crate level
+ --> $DIR/crate_level_only_lint.rs:4:10
+ |
+LL | #![allow(uncommon_codepoints)]
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/crate_level_only_lint.rs:1:30
+ |
+LL | #![deny(uncommon_codepoints, unused_attributes)]
+ | ^^^^^^^^^^^^^^^^^
+
+error: allow(uncommon_codepoints) is ignored unless specified at crate level
+ --> $DIR/crate_level_only_lint.rs:9:9
+ |
+LL | #[allow(uncommon_codepoints)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: allow(uncommon_codepoints) is ignored unless specified at crate level
+ --> $DIR/crate_level_only_lint.rs:17:9
+ |
+LL | #[allow(uncommon_codepoints)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: allow(uncommon_codepoints) is ignored unless specified at crate level
+ --> $DIR/crate_level_only_lint.rs:4:10
+ |
+LL | #![allow(uncommon_codepoints)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: allow(uncommon_codepoints) is ignored unless specified at crate level
+ --> $DIR/crate_level_only_lint.rs:9:9
+ |
+LL | #[allow(uncommon_codepoints)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: allow(uncommon_codepoints) is ignored unless specified at crate level
+ --> $DIR/crate_level_only_lint.rs:17:9
+ |
+LL | #[allow(uncommon_codepoints)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: allow(uncommon_codepoints) is ignored unless specified at crate level
+ --> $DIR/crate_level_only_lint.rs:4:10
+ |
+LL | #![allow(uncommon_codepoints)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: allow(uncommon_codepoints) is ignored unless specified at crate level
+ --> $DIR/crate_level_only_lint.rs:9:9
+ |
+LL | #[allow(uncommon_codepoints)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: allow(uncommon_codepoints) is ignored unless specified at crate level
+ --> $DIR/crate_level_only_lint.rs:17:9
+ |
+LL | #[allow(uncommon_codepoints)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 9 previous errors
+
diff --git a/tests/ui/lint/dead-code/alias-in-pat.rs b/tests/ui/lint/dead-code/alias-in-pat.rs
new file mode 100644
index 000000000..69d455f3b
--- /dev/null
+++ b/tests/ui/lint/dead-code/alias-in-pat.rs
@@ -0,0 +1,10 @@
+// run-pass
+
+#![deny(dead_code)]
+
+fn main() {
+ struct Foo<T> { x: T }
+ type Bar = Foo<u32>;
+ let spam = |Bar { x }| x != 0;
+ println!("{}", spam(Foo { x: 10 }));
+}
diff --git a/tests/ui/lint/dead-code/anon-const-in-pat.rs b/tests/ui/lint/dead-code/anon-const-in-pat.rs
new file mode 100644
index 000000000..d3e39c0de
--- /dev/null
+++ b/tests/ui/lint/dead-code/anon-const-in-pat.rs
@@ -0,0 +1,45 @@
+// check-pass
+#![feature(inline_const_pat)]
+#![allow(incomplete_features)]
+#![deny(dead_code)]
+
+const fn one() -> i32 {
+ 1
+}
+
+const fn two() -> i32 {
+ 2
+}
+
+const fn three() -> i32 {
+ 3
+}
+
+fn inline_const() {
+ // rust-lang/rust#78171: dead_code lint triggers even though function is used in const pattern
+ match 1 {
+ const { one() } => {}
+ _ => {}
+ }
+}
+
+fn inline_const_range() {
+ match 1 {
+ 1 ..= const { two() } => {}
+ _ => {}
+ }
+}
+
+struct S<const C: i32>;
+
+fn const_generic_arg() {
+ match S::<3> {
+ S::<{three()}> => {}
+ }
+}
+
+fn main() {
+ inline_const();
+ inline_const_range();
+ const_generic_arg();
+}
diff --git a/tests/ui/lint/dead-code/associated-type.rs b/tests/ui/lint/dead-code/associated-type.rs
new file mode 100644
index 000000000..1cf66e75a
--- /dev/null
+++ b/tests/ui/lint/dead-code/associated-type.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+#![deny(dead_code)]
+
+trait Foo {
+ type Bar;
+}
+
+struct Used;
+
+struct Ex;
+
+impl Foo for Ex {
+ type Bar = Used;
+}
+
+pub fn main() {
+ let _x = Ex;
+}
diff --git a/tests/ui/lint/dead-code/basic.rs b/tests/ui/lint/dead-code/basic.rs
new file mode 100644
index 000000000..3b8ffd58c
--- /dev/null
+++ b/tests/ui/lint/dead-code/basic.rs
@@ -0,0 +1,15 @@
+#![deny(dead_code)]
+#![allow(unreachable_code)]
+
+fn foo() { //~ ERROR function `foo` is never used
+
+ // none of these should have any dead_code exposed to the user
+ panic!();
+
+ panic!("foo");
+
+ panic!("bar {}", "baz")
+}
+
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/basic.stderr b/tests/ui/lint/dead-code/basic.stderr
new file mode 100644
index 000000000..7d068cead
--- /dev/null
+++ b/tests/ui/lint/dead-code/basic.stderr
@@ -0,0 +1,14 @@
+error: function `foo` is never used
+ --> $DIR/basic.rs:4:4
+ |
+LL | fn foo() {
+ | ^^^
+ |
+note: the lint level is defined here
+ --> $DIR/basic.rs:1:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/dead-code/closure-bang.rs b/tests/ui/lint/dead-code/closure-bang.rs
new file mode 100644
index 000000000..8e8636b11
--- /dev/null
+++ b/tests/ui/lint/dead-code/closure-bang.rs
@@ -0,0 +1,9 @@
+// ignore-test FIXME(#20574)
+
+#![deny(unreachable_code)]
+
+fn main() {
+ let x = || panic!();
+ x();
+ println!("Foo bar"); //~ ERROR: unreachable statement
+}
diff --git a/tests/ui/lint/dead-code/const-and-self.rs b/tests/ui/lint/dead-code/const-and-self.rs
new file mode 100644
index 000000000..5c96e4d0e
--- /dev/null
+++ b/tests/ui/lint/dead-code/const-and-self.rs
@@ -0,0 +1,54 @@
+// check-pass
+
+#![warn(dead_code)]
+
+const TLC: usize = 4;
+
+trait Tr { fn doit(&self); }
+
+impl Tr for [usize; TLC] {
+ fn doit(&self) {
+ println!("called 4");
+ }
+}
+
+struct X;
+struct Y;
+struct Z;
+
+trait Foo<T> {
+ type Ty;
+ fn foo() -> Self::Ty;
+}
+
+impl Foo<Y> for X {
+ type Ty = Z;
+ fn foo() -> Self::Ty {
+ unimplemented!()
+ }
+}
+
+enum E {
+ A,
+ B, //~ WARN variants `B` and `C` are never constructed
+ C,
+}
+
+type F = E;
+
+impl E {
+ fn check(&self) -> bool {
+ match self {
+ Self::A => true,
+ Self::B => false,
+ F::C => false,
+ }
+ }
+}
+
+fn main() {
+ let s = [0,1,2,3];
+ s.doit();
+ X::foo();
+ E::A.check();
+}
diff --git a/tests/ui/lint/dead-code/const-and-self.stderr b/tests/ui/lint/dead-code/const-and-self.stderr
new file mode 100644
index 000000000..9d1d7d6ec
--- /dev/null
+++ b/tests/ui/lint/dead-code/const-and-self.stderr
@@ -0,0 +1,19 @@
+warning: variants `B` and `C` are never constructed
+ --> $DIR/const-and-self.rs:33:5
+ |
+LL | enum E {
+ | - variants in this enum
+LL | A,
+LL | B,
+ | ^
+LL | C,
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/const-and-self.rs:3:9
+ |
+LL | #![warn(dead_code)]
+ | ^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/dead-code/empty-unused-enum.rs b/tests/ui/lint/dead-code/empty-unused-enum.rs
new file mode 100644
index 000000000..864501e94
--- /dev/null
+++ b/tests/ui/lint/dead-code/empty-unused-enum.rs
@@ -0,0 +1,5 @@
+#![deny(unused)]
+
+enum E {} //~ ERROR enum `E` is never used
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/empty-unused-enum.stderr b/tests/ui/lint/dead-code/empty-unused-enum.stderr
new file mode 100644
index 000000000..6391f0941
--- /dev/null
+++ b/tests/ui/lint/dead-code/empty-unused-enum.stderr
@@ -0,0 +1,15 @@
+error: enum `E` is never used
+ --> $DIR/empty-unused-enum.rs:3:6
+ |
+LL | enum E {}
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/empty-unused-enum.rs:1:9
+ |
+LL | #![deny(unused)]
+ | ^^^^^^
+ = note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/dead-code/empty-unused-public-enum.rs b/tests/ui/lint/dead-code/empty-unused-public-enum.rs
new file mode 100644
index 000000000..15b04496b
--- /dev/null
+++ b/tests/ui/lint/dead-code/empty-unused-public-enum.rs
@@ -0,0 +1,6 @@
+// build-pass
+#![deny(unused)]
+
+pub enum E {}
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/enum-variants.rs b/tests/ui/lint/dead-code/enum-variants.rs
new file mode 100644
index 000000000..91c97232e
--- /dev/null
+++ b/tests/ui/lint/dead-code/enum-variants.rs
@@ -0,0 +1,14 @@
+// run-pass
+
+#![deny(dead_code)]
+
+enum Foo {
+ A,
+ B,
+}
+
+pub fn main() {
+ match Foo::A {
+ Foo::A | Foo::B => Foo::B
+ };
+}
diff --git a/tests/ui/lint/dead-code/impl-trait.rs b/tests/ui/lint/dead-code/impl-trait.rs
new file mode 100644
index 000000000..757b8f83e
--- /dev/null
+++ b/tests/ui/lint/dead-code/impl-trait.rs
@@ -0,0 +1,18 @@
+#![deny(dead_code)]
+
+trait Trait {
+ type Type;
+}
+
+impl Trait for () {
+ type Type = ();
+}
+
+type Used = ();
+type Unused = (); //~ ERROR type alias `Unused` is never used
+
+fn foo() -> impl Trait<Type = Used> {}
+
+fn main() {
+ foo();
+}
diff --git a/tests/ui/lint/dead-code/impl-trait.stderr b/tests/ui/lint/dead-code/impl-trait.stderr
new file mode 100644
index 000000000..e35e13a9e
--- /dev/null
+++ b/tests/ui/lint/dead-code/impl-trait.stderr
@@ -0,0 +1,14 @@
+error: type alias `Unused` is never used
+ --> $DIR/impl-trait.rs:12:6
+ |
+LL | type Unused = ();
+ | ^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/impl-trait.rs:1:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/dead-code/issue-68408-false-positive.rs b/tests/ui/lint/dead-code/issue-68408-false-positive.rs
new file mode 100644
index 000000000..7ee6b5d72
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-68408-false-positive.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+// Make sure we don't have any false positives here.
+
+#![deny(dead_code)]
+
+enum X {
+ A { _a: () },
+ B { _b: () },
+}
+impl X {
+ fn a() -> X {
+ X::A { _a: () }
+ }
+ fn b() -> Self {
+ Self::B { _b: () }
+ }
+}
+
+fn main() {
+ let (_, _) = (X::a(), X::b());
+}
diff --git a/tests/ui/lint/dead-code/issue-85071-2.rs b/tests/ui/lint/dead-code/issue-85071-2.rs
new file mode 100644
index 000000000..f0639931c
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-85071-2.rs
@@ -0,0 +1,22 @@
+// A slight variation of issue-85071.rs. Here, a method is called instead
+// of a function, and the warning is about an unreachable definition
+// instead of an unreachable expression.
+
+// check-pass
+
+#![warn(unused_variables,unreachable_code)]
+
+enum Foo {}
+
+struct S;
+impl S {
+ fn f(&self) -> Foo {todo!()}
+}
+
+fn main() {
+ let s = S;
+ let x = s.f();
+ //~^ WARNING: unused variable: `x`
+ let _y = x;
+ //~^ WARNING: unreachable definition
+}
diff --git a/tests/ui/lint/dead-code/issue-85071-2.stderr b/tests/ui/lint/dead-code/issue-85071-2.stderr
new file mode 100644
index 000000000..5e963183d
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-85071-2.stderr
@@ -0,0 +1,34 @@
+warning: unreachable definition
+ --> $DIR/issue-85071-2.rs:20:9
+ |
+LL | let x = s.f();
+ | ----- any code following this expression is unreachable
+LL |
+LL | let _y = x;
+ | ^^ unreachable definition
+ |
+note: this expression has type `Foo`, which is uninhabited
+ --> $DIR/issue-85071-2.rs:18:13
+ |
+LL | let x = s.f();
+ | ^^^^^
+note: the lint level is defined here
+ --> $DIR/issue-85071-2.rs:7:26
+ |
+LL | #![warn(unused_variables,unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+warning: unused variable: `x`
+ --> $DIR/issue-85071-2.rs:18:9
+ |
+LL | let x = s.f();
+ | ^ help: if this is intentional, prefix it with an underscore: `_x`
+ |
+note: the lint level is defined here
+ --> $DIR/issue-85071-2.rs:7:9
+ |
+LL | #![warn(unused_variables,unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/lint/dead-code/issue-85071.rs b/tests/ui/lint/dead-code/issue-85071.rs
new file mode 100644
index 000000000..d6969321c
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-85071.rs
@@ -0,0 +1,19 @@
+// Checks that an unreachable code warning is emitted when an expression is
+// preceded by an expression with an uninhabited type. Previously, the
+// variable liveness analysis was "smarter" than the reachability analysis
+// in this regard, which led to confusing "unused variable" warnings
+// without an accompanying explanatory "unreachable expression" warning.
+
+// check-pass
+
+#![warn(unused_variables,unreachable_code)]
+
+enum Foo {}
+fn f() -> Foo {todo!()}
+
+fn main() {
+ let x = f();
+ //~^ WARNING: unused variable: `x`
+ let _ = x;
+ //~^ WARNING: unreachable expression
+}
diff --git a/tests/ui/lint/dead-code/issue-85071.stderr b/tests/ui/lint/dead-code/issue-85071.stderr
new file mode 100644
index 000000000..721fb8148
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-85071.stderr
@@ -0,0 +1,34 @@
+warning: unreachable expression
+ --> $DIR/issue-85071.rs:17:13
+ |
+LL | let x = f();
+ | --- any code following this expression is unreachable
+LL |
+LL | let _ = x;
+ | ^ unreachable expression
+ |
+note: this expression has type `Foo`, which is uninhabited
+ --> $DIR/issue-85071.rs:15:13
+ |
+LL | let x = f();
+ | ^^^
+note: the lint level is defined here
+ --> $DIR/issue-85071.rs:9:26
+ |
+LL | #![warn(unused_variables,unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+warning: unused variable: `x`
+ --> $DIR/issue-85071.rs:15:9
+ |
+LL | let x = f();
+ | ^ help: if this is intentional, prefix it with an underscore: `_x`
+ |
+note: the lint level is defined here
+ --> $DIR/issue-85071.rs:9:9
+ |
+LL | #![warn(unused_variables,unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/lint/dead-code/issue-85255.rs b/tests/ui/lint/dead-code/issue-85255.rs
new file mode 100644
index 000000000..043f68137
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-85255.rs
@@ -0,0 +1,50 @@
+// Unused `pub` fields in non-`pub` structs should also trigger dead code warnings.
+// check-pass
+
+#![warn(dead_code)]
+
+struct Foo {
+ a: i32, //~ WARNING: fields `a` and `b` are never read
+ pub b: i32,
+}
+
+struct Bar;
+
+impl Bar {
+ fn a(&self) -> i32 { 5 } //~ WARNING: associated function `a` is never used
+ pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function `b` is never used
+}
+
+pub(crate) struct Foo1 {
+ a: i32, //~ WARNING: fields `a` and `b` are never read
+ pub b: i32,
+}
+
+pub(crate) struct Bar1;
+
+impl Bar1 {
+ fn a(&self) -> i32 { 5 } //~ WARNING: associated function `a` is never used
+ pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function `b` is never used
+}
+
+pub(crate) struct Foo2 {
+ a: i32, //~ WARNING: fields `a` and `b` are never read
+ pub b: i32,
+}
+
+pub(crate) struct Bar2;
+
+impl Bar2 {
+ fn a(&self) -> i32 { 5 } //~ WARNING: associated function `a` is never used
+ pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function `b` is never used
+}
+
+
+fn main() {
+ let _ = Foo { a: 1, b: 2 };
+ let _ = Bar;
+ let _ = Foo1 { a: 1, b: 2 };
+ let _ = Bar1;
+ let _ = Foo2 { a: 1, b: 2 };
+ let _ = Bar2;
+}
diff --git a/tests/ui/lint/dead-code/issue-85255.stderr b/tests/ui/lint/dead-code/issue-85255.stderr
new file mode 100644
index 000000000..3497b952f
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-85255.stderr
@@ -0,0 +1,74 @@
+warning: fields `a` and `b` are never read
+ --> $DIR/issue-85255.rs:7:5
+ |
+LL | struct Foo {
+ | --- fields in this struct
+LL | a: i32,
+ | ^
+LL | pub b: i32,
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-85255.rs:4:9
+ |
+LL | #![warn(dead_code)]
+ | ^^^^^^^^^
+
+warning: fields `a` and `b` are never read
+ --> $DIR/issue-85255.rs:19:5
+ |
+LL | pub(crate) struct Foo1 {
+ | ---- fields in this struct
+LL | a: i32,
+ | ^
+LL | pub b: i32,
+ | ^
+
+warning: fields `a` and `b` are never read
+ --> $DIR/issue-85255.rs:31:5
+ |
+LL | pub(crate) struct Foo2 {
+ | ---- fields in this struct
+LL | a: i32,
+ | ^
+LL | pub b: i32,
+ | ^
+
+warning: associated function `a` is never used
+ --> $DIR/issue-85255.rs:14:8
+ |
+LL | fn a(&self) -> i32 { 5 }
+ | ^
+
+warning: associated function `b` is never used
+ --> $DIR/issue-85255.rs:15:12
+ |
+LL | pub fn b(&self) -> i32 { 6 }
+ | ^
+
+warning: associated function `a` is never used
+ --> $DIR/issue-85255.rs:26:8
+ |
+LL | fn a(&self) -> i32 { 5 }
+ | ^
+
+warning: associated function `b` is never used
+ --> $DIR/issue-85255.rs:27:12
+ |
+LL | pub fn b(&self) -> i32 { 6 }
+ | ^
+
+warning: associated function `a` is never used
+ --> $DIR/issue-85255.rs:38:8
+ |
+LL | fn a(&self) -> i32 { 5 }
+ | ^
+
+warning: associated function `b` is never used
+ --> $DIR/issue-85255.rs:39:12
+ |
+LL | pub fn b(&self) -> i32 { 6 }
+ | ^
+
+warning: 9 warnings emitted
+
diff --git a/tests/ui/lint/dead-code/leading-underscore.rs b/tests/ui/lint/dead-code/leading-underscore.rs
new file mode 100644
index 000000000..d3582961b
--- /dev/null
+++ b/tests/ui/lint/dead-code/leading-underscore.rs
@@ -0,0 +1,31 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+#![deny(dead_code)]
+
+static _X: usize = 0;
+
+fn _foo() {}
+
+struct _Y {
+ _z: usize,
+}
+
+enum _Z {}
+
+impl _Y {
+ fn _bar() {}
+}
+
+type _A = isize;
+
+mod _bar {
+ fn _qux() {}
+}
+
+extern "C" {
+ #[link_name = "abort"]
+ fn _abort() -> !;
+}
+
+pub fn main() {}
diff --git a/tests/ui/lint/dead-code/lint-dead-code-1.rs b/tests/ui/lint/dead-code/lint-dead-code-1.rs
new file mode 100644
index 000000000..8f5a4c41e
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-1.rs
@@ -0,0 +1,110 @@
+#![no_std]
+#![allow(unused_variables)]
+#![allow(non_camel_case_types)]
+#![allow(non_upper_case_globals)]
+#![deny(dead_code)]
+
+#![crate_type="lib"]
+
+pub use foo2::Bar2;
+
+mod foo {
+ pub struct Bar; //~ ERROR: struct `Bar` is never constructed
+}
+
+mod foo2 {
+ pub struct Bar2;
+}
+
+pub static pub_static: isize = 0;
+static priv_static: isize = 0; //~ ERROR: static `priv_static` is never used
+const used_static: isize = 0;
+pub static used_static2: isize = used_static;
+const USED_STATIC: isize = 0;
+const STATIC_USED_IN_ENUM_DISCRIMINANT: isize = 10;
+
+pub const pub_const: isize = 0;
+const priv_const: isize = 0; //~ ERROR: constant `priv_const` is never used
+const used_const: isize = 0;
+pub const used_const2: isize = used_const;
+const USED_CONST: isize = 1;
+const CONST_USED_IN_ENUM_DISCRIMINANT: isize = 11;
+
+pub type typ = *const UsedStruct4;
+pub struct PubStruct;
+struct PrivStruct; //~ ERROR: struct `PrivStruct` is never constructed
+struct UsedStruct1 {
+ #[allow(dead_code)]
+ x: isize
+}
+struct UsedStruct2(isize);
+struct UsedStruct3;
+pub struct UsedStruct4;
+// this struct is never used directly, but its method is, so we don't want
+// to warn it
+struct SemiUsedStruct;
+impl SemiUsedStruct {
+ fn la_la_la() {}
+}
+struct StructUsedAsField;
+pub struct StructUsedInEnum;
+struct StructUsedInGeneric;
+pub struct PubStruct2 {
+ #[allow(dead_code)]
+ struct_used_as_field: *const StructUsedAsField
+}
+
+pub enum pub_enum { foo1, bar1 }
+pub enum pub_enum2 { a(*const StructUsedInEnum) }
+pub enum pub_enum3 {
+ Foo = STATIC_USED_IN_ENUM_DISCRIMINANT,
+ Bar = CONST_USED_IN_ENUM_DISCRIMINANT,
+}
+
+enum priv_enum { foo2, bar2 } //~ ERROR: enum `priv_enum` is never used
+enum used_enum {
+ foo3,
+ bar3 //~ ERROR variant `bar3` is never constructed
+}
+
+fn f<T>() {}
+
+pub fn pub_fn() {
+ used_fn();
+ let used_struct1 = UsedStruct1 { x: 1 };
+ let used_struct2 = UsedStruct2(1);
+ let used_struct3 = UsedStruct3;
+ let e = used_enum::foo3;
+ SemiUsedStruct::la_la_la();
+
+ let i = 1;
+ match i {
+ USED_STATIC => (),
+ USED_CONST => (),
+ _ => ()
+ }
+ f::<StructUsedInGeneric>();
+}
+fn priv_fn() { //~ ERROR: function `priv_fn` is never used
+ let unused_struct = PrivStruct;
+}
+fn used_fn() {}
+
+fn foo() { //~ ERROR: function `foo` is never used
+ bar();
+ let unused_enum = priv_enum::foo2;
+}
+
+fn bar() { //~ ERROR: function `bar` is never used
+ foo();
+}
+
+fn baz() -> impl Copy { //~ ERROR: function `baz` is never used
+ "I'm unused, too"
+}
+
+// Code with #[allow(dead_code)] should be marked live (and thus anything it
+// calls is marked live)
+#[allow(dead_code)]
+fn g() { h(); }
+fn h() {}
diff --git a/tests/ui/lint/dead-code/lint-dead-code-1.stderr b/tests/ui/lint/dead-code/lint-dead-code-1.stderr
new file mode 100644
index 000000000..eb728b5b9
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-1.stderr
@@ -0,0 +1,71 @@
+error: static `priv_static` is never used
+ --> $DIR/lint-dead-code-1.rs:20:8
+ |
+LL | static priv_static: isize = 0;
+ | ^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-dead-code-1.rs:5:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: constant `priv_const` is never used
+ --> $DIR/lint-dead-code-1.rs:27:7
+ |
+LL | const priv_const: isize = 0;
+ | ^^^^^^^^^^
+
+error: struct `PrivStruct` is never constructed
+ --> $DIR/lint-dead-code-1.rs:35:8
+ |
+LL | struct PrivStruct;
+ | ^^^^^^^^^^
+
+error: enum `priv_enum` is never used
+ --> $DIR/lint-dead-code-1.rs:64:6
+ |
+LL | enum priv_enum { foo2, bar2 }
+ | ^^^^^^^^^
+
+error: variant `bar3` is never constructed
+ --> $DIR/lint-dead-code-1.rs:67:5
+ |
+LL | enum used_enum {
+ | --------- variant in this enum
+LL | foo3,
+LL | bar3
+ | ^^^^
+
+error: function `priv_fn` is never used
+ --> $DIR/lint-dead-code-1.rs:88:4
+ |
+LL | fn priv_fn() {
+ | ^^^^^^^
+
+error: function `foo` is never used
+ --> $DIR/lint-dead-code-1.rs:93:4
+ |
+LL | fn foo() {
+ | ^^^
+
+error: function `bar` is never used
+ --> $DIR/lint-dead-code-1.rs:98:4
+ |
+LL | fn bar() {
+ | ^^^
+
+error: function `baz` is never used
+ --> $DIR/lint-dead-code-1.rs:102:4
+ |
+LL | fn baz() -> impl Copy {
+ | ^^^
+
+error: struct `Bar` is never constructed
+ --> $DIR/lint-dead-code-1.rs:12:16
+ |
+LL | pub struct Bar;
+ | ^^^
+
+error: aborting due to 10 previous errors
+
diff --git a/tests/ui/lint/dead-code/lint-dead-code-2.rs b/tests/ui/lint/dead-code/lint-dead-code-2.rs
new file mode 100644
index 000000000..6bfa4d96f
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-2.rs
@@ -0,0 +1,41 @@
+#![allow(unused_variables)]
+#![deny(dead_code)]
+#![feature(rustc_attrs, start)]
+
+struct Foo;
+
+trait Bar {
+ fn bar1(&self);
+ fn bar2(&self) {
+ self.bar1();
+ }
+}
+
+impl Bar for Foo {
+ fn bar1(&self) {
+ live_fn();
+ }
+}
+
+fn live_fn() {}
+
+fn dead_fn() {} //~ ERROR: function `dead_fn` is never used
+
+#[rustc_main]
+fn dead_fn2() {} //~ ERROR: function `dead_fn2` is never used
+
+fn used_fn() {}
+
+#[start]
+fn start(_: isize, _: *const *const u8) -> isize {
+ used_fn();
+ let foo = Foo;
+ foo.bar2();
+ 0
+}
+
+// this is not main
+fn main() { //~ ERROR: function `main` is never used
+ dead_fn();
+ dead_fn2();
+}
diff --git a/tests/ui/lint/dead-code/lint-dead-code-2.stderr b/tests/ui/lint/dead-code/lint-dead-code-2.stderr
new file mode 100644
index 000000000..85af553c9
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-2.stderr
@@ -0,0 +1,26 @@
+error: function `dead_fn` is never used
+ --> $DIR/lint-dead-code-2.rs:22:4
+ |
+LL | fn dead_fn() {}
+ | ^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-dead-code-2.rs:2:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: function `dead_fn2` is never used
+ --> $DIR/lint-dead-code-2.rs:25:4
+ |
+LL | fn dead_fn2() {}
+ | ^^^^^^^^
+
+error: function `main` is never used
+ --> $DIR/lint-dead-code-2.rs:38:4
+ |
+LL | fn main() {
+ | ^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/dead-code/lint-dead-code-3.rs b/tests/ui/lint/dead-code/lint-dead-code-3.rs
new file mode 100644
index 000000000..293fcdbc5
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-3.rs
@@ -0,0 +1,90 @@
+#![allow(unused_variables)]
+#![allow(non_camel_case_types)]
+#![allow(clashing_extern_declarations)]
+#![deny(dead_code)]
+
+#![crate_type="lib"]
+
+
+pub use extern_foo as x;
+extern "C" {
+ pub fn extern_foo();
+}
+
+struct Foo; //~ ERROR: struct `Foo` is never constructed
+impl Foo {
+ fn foo(&self) { //~ ERROR: associated function `foo` is never used
+ bar()
+ }
+}
+
+fn bar() { //~ ERROR: function `bar` is never used
+ fn baz() {}
+
+ Foo.foo();
+ baz();
+}
+
+// no warning
+struct Foo2;
+impl Foo2 { fn foo2(&self) { bar2() } }
+fn bar2() {
+ fn baz2() {}
+
+ Foo2.foo2();
+ baz2();
+}
+
+pub fn pub_fn() {
+ let foo2_struct = Foo2;
+ foo2_struct.foo2();
+
+ blah::baz();
+}
+
+mod blah {
+ // not warned because it's used in the parameter of `free` and return of
+ // `malloc` below, which are also used.
+ enum c_void {}
+
+ extern "C" {
+ fn free(p: *const c_void);
+ fn malloc(size: usize) -> *const c_void;
+ }
+
+ pub fn baz() {
+ unsafe { free(malloc(4)); }
+ }
+}
+
+enum c_void {} //~ ERROR: enum `c_void` is never used
+extern "C" {
+ fn free(p: *const c_void); //~ ERROR: function `free` is never used
+}
+
+// Check provided method
+mod inner {
+ pub trait Trait {
+ fn f(&self) { f(); }
+ }
+
+ impl Trait for isize {}
+
+ fn f() {}
+}
+
+fn anon_const() -> [(); {
+ fn blah() {} //~ ERROR: function `blah` is never used
+ 1
+}] {
+ [(); {
+ fn blah() {} //~ ERROR: function `blah` is never used
+ 1
+ }]
+}
+
+pub fn foo() {
+ let a: &dyn inner::Trait = &1_isize;
+ a.f();
+ anon_const();
+}
diff --git a/tests/ui/lint/dead-code/lint-dead-code-3.stderr b/tests/ui/lint/dead-code/lint-dead-code-3.stderr
new file mode 100644
index 000000000..26fc13bae
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-3.stderr
@@ -0,0 +1,50 @@
+error: struct `Foo` is never constructed
+ --> $DIR/lint-dead-code-3.rs:14:8
+ |
+LL | struct Foo;
+ | ^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-dead-code-3.rs:4:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: function `bar` is never used
+ --> $DIR/lint-dead-code-3.rs:21:4
+ |
+LL | fn bar() {
+ | ^^^
+
+error: enum `c_void` is never used
+ --> $DIR/lint-dead-code-3.rs:60:6
+ |
+LL | enum c_void {}
+ | ^^^^^^
+
+error: function `blah` is never used
+ --> $DIR/lint-dead-code-3.rs:77:8
+ |
+LL | fn blah() {}
+ | ^^^^
+
+error: function `blah` is never used
+ --> $DIR/lint-dead-code-3.rs:81:12
+ |
+LL | fn blah() {}
+ | ^^^^
+
+error: associated function `foo` is never used
+ --> $DIR/lint-dead-code-3.rs:16:8
+ |
+LL | fn foo(&self) {
+ | ^^^
+
+error: function `free` is never used
+ --> $DIR/lint-dead-code-3.rs:62:8
+ |
+LL | fn free(p: *const c_void);
+ | ^^^^
+
+error: aborting due to 7 previous errors
+
diff --git a/tests/ui/lint/dead-code/lint-dead-code-4.rs b/tests/ui/lint/dead-code/lint-dead-code-4.rs
new file mode 100644
index 000000000..0fc6c6156
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-4.rs
@@ -0,0 +1,83 @@
+#![allow(unused_variables)]
+#![allow(non_camel_case_types)]
+#![deny(dead_code)]
+
+struct Foo {
+ x: usize,
+ b: bool, //~ ERROR: field `b` is never read
+}
+
+fn field_read(f: Foo) -> usize {
+ f.x.pow(2)
+}
+
+enum XYZ {
+ X, //~ ERROR variants `X` and `Y` are never constructed
+ Y {
+ a: String,
+ b: i32,
+ c: i32,
+ },
+ Z
+}
+
+enum ABC { //~ ERROR enum `ABC` is never used
+ A,
+ B {
+ a: String,
+ b: i32,
+ c: i32,
+ },
+ C
+}
+
+// ensure struct variants get warning for their fields
+enum IJK {
+ I, //~ ERROR variants `I` and `K` are never constructed
+ J {
+ a: String,
+ b: i32, //~ ERROR fields `b` and `c` are never read
+ c: i32,
+ },
+ K
+
+}
+
+fn struct_variant_partial_use(b: IJK) -> String {
+ match b {
+ IJK::J { a, b: _, .. } => a,
+ _ => "".to_string()
+ }
+}
+
+fn field_match_in_patterns(b: XYZ) -> String {
+ match b {
+ XYZ::Y { a, b: _, .. } => a,
+ _ => "".to_string()
+ }
+}
+
+struct Bar {
+ x: usize, //~ ERROR: fields `x` and `c` are never read
+ b: bool,
+ c: bool,
+ _guard: ()
+}
+
+#[repr(C)]
+struct Baz {
+ x: u32,
+}
+
+fn field_match_in_let(f: Bar) -> bool {
+ let Bar { b, c: _, .. } = f;
+ b
+}
+
+fn main() {
+ field_read(Foo { x: 1, b: false });
+ field_match_in_patterns(XYZ::Z);
+ struct_variant_partial_use(IJK::J { a: "".into(), b: 1, c: -1 });
+ field_match_in_let(Bar { x: 42, b: true, c: false, _guard: () });
+ let _ = Baz { x: 0 };
+}
diff --git a/tests/ui/lint/dead-code/lint-dead-code-4.stderr b/tests/ui/lint/dead-code/lint-dead-code-4.stderr
new file mode 100644
index 000000000..668c1dacf
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-4.stderr
@@ -0,0 +1,66 @@
+error: field `b` is never read
+ --> $DIR/lint-dead-code-4.rs:7:5
+ |
+LL | struct Foo {
+ | --- field in this struct
+LL | x: usize,
+LL | b: bool,
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-dead-code-4.rs:3:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: variants `X` and `Y` are never constructed
+ --> $DIR/lint-dead-code-4.rs:15:5
+ |
+LL | enum XYZ {
+ | --- variants in this enum
+LL | X,
+ | ^
+LL | Y {
+ | ^
+
+error: enum `ABC` is never used
+ --> $DIR/lint-dead-code-4.rs:24:6
+ |
+LL | enum ABC {
+ | ^^^
+
+error: fields `b` and `c` are never read
+ --> $DIR/lint-dead-code-4.rs:39:9
+ |
+LL | J {
+ | - fields in this variant
+LL | a: String,
+LL | b: i32,
+ | ^
+LL | c: i32,
+ | ^
+
+error: variants `I` and `K` are never constructed
+ --> $DIR/lint-dead-code-4.rs:36:5
+ |
+LL | enum IJK {
+ | --- variants in this enum
+LL | I,
+ | ^
+...
+LL | K
+ | ^
+
+error: fields `x` and `c` are never read
+ --> $DIR/lint-dead-code-4.rs:61:5
+ |
+LL | struct Bar {
+ | --- fields in this struct
+LL | x: usize,
+ | ^
+LL | b: bool,
+LL | c: bool,
+ | ^
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/lint/dead-code/lint-dead-code-5.rs b/tests/ui/lint/dead-code/lint-dead-code-5.rs
new file mode 100644
index 000000000..ed90fb464
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-5.rs
@@ -0,0 +1,50 @@
+#![allow(unused_variables)]
+#![deny(dead_code)]
+
+enum Enum1 {
+ Variant1(isize),
+ Variant2 //~ ERROR: variant `Variant2` is never constructed
+}
+
+enum Enum2 {
+ Variant3(bool),
+ #[allow(dead_code)]
+ Variant4(isize),
+ Variant5 { _x: isize }, //~ ERROR: variants `Variant5` and `Variant6` are never constructed
+ Variant6(isize),
+ _Variant7,
+ Variant8 { _field: bool },
+ Variant9,
+ Variant10(usize)
+}
+
+impl Enum2 {
+ fn new_variant8() -> Enum2 {
+ Self::Variant8 { _field: true }
+ }
+
+ fn new_variant9() -> Enum2 {
+ Self::Variant9
+ }
+
+ fn new_variant10() -> Enum2 {
+ Self::Variant10(10)
+ }
+}
+
+enum Enum3 { //~ ERROR: enum `Enum3` is never used
+ Variant8,
+ Variant9
+}
+
+fn main() {
+ let v = Enum1::Variant1(1);
+ match v {
+ Enum1::Variant1(_) => (),
+ Enum1::Variant2 => ()
+ }
+ let x = Enum2::Variant3(true);
+ let _ = Enum2::new_variant8();
+ let _ = Enum2::new_variant9();
+ let _ = Enum2::new_variant10();
+}
diff --git a/tests/ui/lint/dead-code/lint-dead-code-5.stderr b/tests/ui/lint/dead-code/lint-dead-code-5.stderr
new file mode 100644
index 000000000..eaf43e453
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-5.stderr
@@ -0,0 +1,34 @@
+error: variant `Variant2` is never constructed
+ --> $DIR/lint-dead-code-5.rs:6:5
+ |
+LL | enum Enum1 {
+ | ----- variant in this enum
+LL | Variant1(isize),
+LL | Variant2
+ | ^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-dead-code-5.rs:2:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: variants `Variant5` and `Variant6` are never constructed
+ --> $DIR/lint-dead-code-5.rs:13:5
+ |
+LL | enum Enum2 {
+ | ----- variants in this enum
+...
+LL | Variant5 { _x: isize },
+ | ^^^^^^^^
+LL | Variant6(isize),
+ | ^^^^^^^^
+
+error: enum `Enum3` is never used
+ --> $DIR/lint-dead-code-5.rs:35:6
+ |
+LL | enum Enum3 {
+ | ^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/dead-code/lint-dead-code-6.rs b/tests/ui/lint/dead-code/lint-dead-code-6.rs
new file mode 100644
index 000000000..e3074acf1
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-6.rs
@@ -0,0 +1,20 @@
+#![deny(dead_code)]
+
+struct UnusedStruct; //~ ERROR struct `UnusedStruct` is never constructed
+impl UnusedStruct {
+ fn unused_impl_fn_1() { //~ ERROR associated function `unused_impl_fn_1` is never used
+ println!("blah");
+ }
+
+ fn unused_impl_fn_2(var: i32) { //~ ERROR associated function `unused_impl_fn_2` is never used
+ println!("foo {}", var);
+ }
+
+ fn unused_impl_fn_3( //~ ERROR associated function `unused_impl_fn_3` is never used
+ var: i32,
+ ) {
+ println!("bar {}", var);
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/lint-dead-code-6.stderr b/tests/ui/lint/dead-code/lint-dead-code-6.stderr
new file mode 100644
index 000000000..f9d83308a
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-6.stderr
@@ -0,0 +1,32 @@
+error: struct `UnusedStruct` is never constructed
+ --> $DIR/lint-dead-code-6.rs:3:8
+ |
+LL | struct UnusedStruct;
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-dead-code-6.rs:1:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: associated function `unused_impl_fn_1` is never used
+ --> $DIR/lint-dead-code-6.rs:5:8
+ |
+LL | fn unused_impl_fn_1() {
+ | ^^^^^^^^^^^^^^^^
+
+error: associated function `unused_impl_fn_2` is never used
+ --> $DIR/lint-dead-code-6.rs:9:8
+ |
+LL | fn unused_impl_fn_2(var: i32) {
+ | ^^^^^^^^^^^^^^^^
+
+error: associated function `unused_impl_fn_3` is never used
+ --> $DIR/lint-dead-code-6.rs:13:8
+ |
+LL | fn unused_impl_fn_3(
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs b/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs
new file mode 100644
index 000000000..2003e1e29
--- /dev/null
+++ b/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs
@@ -0,0 +1,29 @@
+#![warn(dead_code)]
+
+struct Bar {
+ #[allow(dead_code)]
+ a: usize,
+ #[forbid(dead_code)]
+ b: usize, //~ ERROR field `b` is never read
+ #[deny(dead_code)]
+ c: usize, //~ ERROR fields `c` and `e` are never read
+ d: usize, //~ WARN fields `d`, `f`, and `g` are never read
+ #[deny(dead_code)]
+ e: usize,
+ f: usize,
+ g: usize,
+ _h: usize,
+}
+
+fn main() {
+ Bar {
+ a: 1,
+ b: 1,
+ c: 1,
+ d: 1,
+ e: 1,
+ f: 1,
+ g: 1,
+ _h: 1,
+ };
+}
diff --git a/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr b/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr
new file mode 100644
index 000000000..0e5c78a71
--- /dev/null
+++ b/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr
@@ -0,0 +1,55 @@
+warning: fields `d`, `f`, and `g` are never read
+ --> $DIR/multiple-dead-codes-in-the-same-struct.rs:10:5
+ |
+LL | struct Bar {
+ | --- fields in this struct
+...
+LL | d: usize,
+ | ^
+...
+LL | f: usize,
+ | ^
+LL | g: usize,
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/multiple-dead-codes-in-the-same-struct.rs:1:9
+ |
+LL | #![warn(dead_code)]
+ | ^^^^^^^^^
+
+error: fields `c` and `e` are never read
+ --> $DIR/multiple-dead-codes-in-the-same-struct.rs:9:5
+ |
+LL | struct Bar {
+ | --- fields in this struct
+...
+LL | c: usize,
+ | ^
+...
+LL | e: usize,
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/multiple-dead-codes-in-the-same-struct.rs:8:12
+ |
+LL | #[deny(dead_code)]
+ | ^^^^^^^^^
+
+error: field `b` is never read
+ --> $DIR/multiple-dead-codes-in-the-same-struct.rs:7:5
+ |
+LL | struct Bar {
+ | --- field in this struct
+...
+LL | b: usize,
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/multiple-dead-codes-in-the-same-struct.rs:6:14
+ |
+LL | #[forbid(dead_code)]
+ | ^^^^^^^^^
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
diff --git a/tests/ui/lint/dead-code/newline-span.rs b/tests/ui/lint/dead-code/newline-span.rs
new file mode 100644
index 000000000..209c3cd93
--- /dev/null
+++ b/tests/ui/lint/dead-code/newline-span.rs
@@ -0,0 +1,19 @@
+#![deny(dead_code)]
+
+fn unused() { //~ error: function `unused` is never used
+ println!("blah");
+}
+
+fn unused2(var: i32) { //~ error: function `unused2` is never used
+ println!("foo {}", var);
+}
+
+fn unused3( //~ error: function `unused3` is never used
+ var: i32,
+) {
+ println!("bar {}", var);
+}
+
+fn main() {
+ println!("Hello world!");
+}
diff --git a/tests/ui/lint/dead-code/newline-span.stderr b/tests/ui/lint/dead-code/newline-span.stderr
new file mode 100644
index 000000000..4eeadccc8
--- /dev/null
+++ b/tests/ui/lint/dead-code/newline-span.stderr
@@ -0,0 +1,26 @@
+error: function `unused` is never used
+ --> $DIR/newline-span.rs:3:4
+ |
+LL | fn unused() {
+ | ^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/newline-span.rs:1:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: function `unused2` is never used
+ --> $DIR/newline-span.rs:7:4
+ |
+LL | fn unused2(var: i32) {
+ | ^^^^^^^
+
+error: function `unused3` is never used
+ --> $DIR/newline-span.rs:11:4
+ |
+LL | fn unused3(
+ | ^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/dead-code/self-assign.rs b/tests/ui/lint/dead-code/self-assign.rs
new file mode 100644
index 000000000..ea7ce98d8
--- /dev/null
+++ b/tests/ui/lint/dead-code/self-assign.rs
@@ -0,0 +1,52 @@
+// Test that dead code warnings are issued for superfluous assignments of
+// fields or variables to themselves (issue #75356).
+
+// ignore-test FIXME(81658, 83171)
+
+// check-pass
+#![allow(unused_assignments)]
+#![warn(dead_code)]
+
+fn main() {
+ let mut x = 0;
+ x = x;
+ //~^ WARNING: useless assignment of variable of type `i32` to itself
+
+ x = (x);
+ //~^ WARNING: useless assignment of variable of type `i32` to itself
+
+ x = {x};
+ // block expressions don't count as self-assignments
+
+
+ struct S<'a> { f: &'a str }
+ let mut s = S { f: "abc" };
+ s = s;
+ //~^ WARNING: useless assignment of variable of type `S` to itself
+
+ s.f = s.f;
+ //~^ WARNING: useless assignment of field of type `&str` to itself
+
+
+ struct N0 { x: Box<i32> }
+ struct N1 { n: N0 }
+ struct N2(N1);
+ struct N3 { n: N2 };
+ let mut n3 = N3 { n: N2(N1 { n: N0 { x: Box::new(42) } }) };
+ n3.n.0.n.x = n3.n.0.n.x;
+ //~^ WARNING: useless assignment of field of type `Box<i32>` to itself
+
+ let mut t = (1, ((2, 3, (4, 5)),));
+ t.1.0.2.1 = t.1.0.2.1;
+ //~^ WARNING: useless assignment of field of type `i32` to itself
+
+
+ let mut y = 0;
+ macro_rules! assign_to_y {
+ ($cur:expr) => {{
+ y = $cur;
+ }};
+ }
+ assign_to_y!(y);
+ // self-assignments in macro expansions are not reported either
+}
diff --git a/tests/ui/lint/dead-code/self-assign.stderr b/tests/ui/lint/dead-code/self-assign.stderr
new file mode 100644
index 000000000..bb79c0ec7
--- /dev/null
+++ b/tests/ui/lint/dead-code/self-assign.stderr
@@ -0,0 +1,44 @@
+warning: useless assignment of variable of type `i32` to itself
+ --> $DIR/self-assign.rs:10:5
+ |
+LL | x = x;
+ | ^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/self-assign.rs:6:9
+ |
+LL | #![warn(dead_code)]
+ | ^^^^^^^^^
+
+warning: useless assignment of variable of type `i32` to itself
+ --> $DIR/self-assign.rs:13:5
+ |
+LL | x = (x);
+ | ^^^^^^^
+
+warning: useless assignment of variable of type `S` to itself
+ --> $DIR/self-assign.rs:22:5
+ |
+LL | s = s;
+ | ^^^^^
+
+warning: useless assignment of field of type `&str` to itself
+ --> $DIR/self-assign.rs:25:5
+ |
+LL | s.f = s.f;
+ | ^^^^^^^^^
+
+warning: useless assignment of field of type `Box<i32>` to itself
+ --> $DIR/self-assign.rs:34:5
+ |
+LL | n3.n.0.n.x = n3.n.0.n.x;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: useless assignment of field of type `i32` to itself
+ --> $DIR/self-assign.rs:38:5
+ |
+LL | t.1.0.2.1 = t.1.0.2.1;
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: 6 warnings emitted
+
diff --git a/tests/ui/lint/dead-code/trait-impl.rs b/tests/ui/lint/dead-code/trait-impl.rs
new file mode 100644
index 000000000..92e389a93
--- /dev/null
+++ b/tests/ui/lint/dead-code/trait-impl.rs
@@ -0,0 +1,19 @@
+// check-pass
+#![deny(dead_code)]
+
+enum Foo {
+ Bar,
+}
+
+fn main() {
+ let p = [0; 0];
+ p.bar();
+}
+
+trait Bar {
+ fn bar(&self) -> usize {
+ 3
+ }
+}
+
+impl Bar for [u32; Foo::Bar as usize] {}
diff --git a/tests/ui/lint/dead-code/tuple-struct-field.rs b/tests/ui/lint/dead-code/tuple-struct-field.rs
new file mode 100644
index 000000000..14fb30be9
--- /dev/null
+++ b/tests/ui/lint/dead-code/tuple-struct-field.rs
@@ -0,0 +1,37 @@
+#![deny(unused_tuple_struct_fields)]
+//~^ NOTE: the lint level is defined here
+
+use std::marker::PhantomData;
+
+const LEN: usize = 4;
+
+struct SingleUnused(i32, [u8; LEN], String);
+//~^ ERROR: field `1` is never read
+//~| NOTE: field in this struct
+//~| HELP: consider changing the field to be of unit type
+
+struct MultipleUnused(i32, f32, String, u8);
+//~^ ERROR: fields `0`, `1`, `2`, and `3` are never read
+//~| NOTE: fields in this struct
+//~| HELP: consider changing the fields to be of unit type
+
+struct GoodUnit(());
+
+struct GoodPhantom(PhantomData<i32>);
+
+struct Void;
+struct GoodVoid(Void);
+
+fn main() {
+ let w = SingleUnused(42, [0, 1, 2, 3], "abc".to_string());
+ let _ = w.0;
+ let _ = w.2;
+
+ let m = MultipleUnused(42, 3.14, "def".to_string(), 4u8);
+
+ let gu = GoodUnit(());
+ let gp = GoodPhantom(PhantomData);
+ let gv = GoodVoid(Void);
+
+ let _ = (gu, gp, gv, m);
+}
diff --git a/tests/ui/lint/dead-code/tuple-struct-field.stderr b/tests/ui/lint/dead-code/tuple-struct-field.stderr
new file mode 100644
index 000000000..b8ad5cbe4
--- /dev/null
+++ b/tests/ui/lint/dead-code/tuple-struct-field.stderr
@@ -0,0 +1,33 @@
+error: field `1` is never read
+ --> $DIR/tuple-struct-field.rs:8:26
+ |
+LL | struct SingleUnused(i32, [u8; LEN], String);
+ | ------------ ^^^^^^^^^
+ | |
+ | field in this struct
+ |
+note: the lint level is defined here
+ --> $DIR/tuple-struct-field.rs:1:9
+ |
+LL | #![deny(unused_tuple_struct_fields)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
+ |
+LL | struct SingleUnused(i32, (), String);
+ | ~~
+
+error: fields `0`, `1`, `2`, and `3` are never read
+ --> $DIR/tuple-struct-field.rs:13:23
+ |
+LL | struct MultipleUnused(i32, f32, String, u8);
+ | -------------- ^^^ ^^^ ^^^^^^ ^^
+ | |
+ | fields in this struct
+ |
+help: consider changing the fields to be of unit type to suppress this warning while preserving the field numbering, or remove the fields
+ |
+LL | struct MultipleUnused((), (), (), ());
+ | ~~ ~~ ~~ ~~
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/dead-code/type-alias.rs b/tests/ui/lint/dead-code/type-alias.rs
new file mode 100644
index 000000000..35a7f125d
--- /dev/null
+++ b/tests/ui/lint/dead-code/type-alias.rs
@@ -0,0 +1,10 @@
+#![deny(dead_code)]
+
+type Used = u8;
+type Unused = u8; //~ ERROR type alias `Unused` is never used
+
+fn id(x: Used) -> Used { x }
+
+fn main() {
+ id(0);
+}
diff --git a/tests/ui/lint/dead-code/type-alias.stderr b/tests/ui/lint/dead-code/type-alias.stderr
new file mode 100644
index 000000000..446447d97
--- /dev/null
+++ b/tests/ui/lint/dead-code/type-alias.stderr
@@ -0,0 +1,14 @@
+error: type alias `Unused` is never used
+ --> $DIR/type-alias.rs:4:6
+ |
+LL | type Unused = u8;
+ | ^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/type-alias.rs:1:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/dead-code/type-in-foreign.rs b/tests/ui/lint/dead-code/type-in-foreign.rs
new file mode 100644
index 000000000..b6c593f31
--- /dev/null
+++ b/tests/ui/lint/dead-code/type-in-foreign.rs
@@ -0,0 +1,19 @@
+// Verify that we do not warn on types that are used by foreign functions.
+// check-pass
+#![deny(dead_code)]
+
+#[repr(C)]
+struct Type(u8);
+
+#[repr(C)]
+struct Param(u8);
+
+extern "C" {
+ #[allow(dead_code)]
+ fn hey(t: Param);
+
+ #[allow(dead_code)]
+ static much: Type;
+}
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/unused-enum.rs b/tests/ui/lint/dead-code/unused-enum.rs
new file mode 100644
index 000000000..20df3e1de
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-enum.rs
@@ -0,0 +1,12 @@
+#![deny(unused)]
+
+struct F; //~ ERROR struct `F` is never constructed
+struct B; //~ ERROR struct `B` is never constructed
+
+enum E {
+ //~^ ERROR enum `E` is never used
+ Foo(F),
+ Bar(B),
+}
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/unused-enum.stderr b/tests/ui/lint/dead-code/unused-enum.stderr
new file mode 100644
index 000000000..d2602dbb3
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-enum.stderr
@@ -0,0 +1,27 @@
+error: struct `F` is never constructed
+ --> $DIR/unused-enum.rs:3:8
+ |
+LL | struct F;
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/unused-enum.rs:1:9
+ |
+LL | #![deny(unused)]
+ | ^^^^^^
+ = note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
+
+error: struct `B` is never constructed
+ --> $DIR/unused-enum.rs:4:8
+ |
+LL | struct B;
+ | ^
+
+error: enum `E` is never used
+ --> $DIR/unused-enum.rs:6:6
+ |
+LL | enum E {
+ | ^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/dead-code/unused-struct-variant.rs b/tests/ui/lint/dead-code/unused-struct-variant.rs
new file mode 100644
index 000000000..a914e0c33
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-struct-variant.rs
@@ -0,0 +1,13 @@
+#![deny(unused)]
+
+struct F;
+struct B;
+
+enum E {
+ Foo(F),
+ Bar(B), //~ ERROR variant `Bar` is never constructed
+}
+
+fn main() {
+ let _ = E::Foo(F);
+}
diff --git a/tests/ui/lint/dead-code/unused-struct-variant.stderr b/tests/ui/lint/dead-code/unused-struct-variant.stderr
new file mode 100644
index 000000000..d26dd3aff
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-struct-variant.stderr
@@ -0,0 +1,18 @@
+error: variant `Bar` is never constructed
+ --> $DIR/unused-struct-variant.rs:8:5
+ |
+LL | enum E {
+ | - variant in this enum
+LL | Foo(F),
+LL | Bar(B),
+ | ^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused-struct-variant.rs:1:9
+ |
+LL | #![deny(unused)]
+ | ^^^^^^
+ = note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/dead-code/unused-variant-pub.rs b/tests/ui/lint/dead-code/unused-variant-pub.rs
new file mode 100644
index 000000000..3a9061340
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-variant-pub.rs
@@ -0,0 +1,14 @@
+// build-pass
+#![deny(unused)]
+
+pub struct F;
+pub struct B;
+
+pub enum E {
+ Foo(F),
+ Bar(B),
+}
+
+fn main() {
+ let _ = E::Foo(F);
+}
diff --git a/tests/ui/lint/dead-code/unused-variant.rs b/tests/ui/lint/dead-code/unused-variant.rs
new file mode 100644
index 000000000..82108fa9c
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-variant.rs
@@ -0,0 +1,12 @@
+#![deny(dead_code)]
+
+#[derive(Clone)]
+enum Enum {
+ Variant1, //~ ERROR: variant `Variant1` is never constructed
+ Variant2,
+}
+
+fn main() {
+ let e = Enum::Variant2;
+ e.clone();
+}
diff --git a/tests/ui/lint/dead-code/unused-variant.stderr b/tests/ui/lint/dead-code/unused-variant.stderr
new file mode 100644
index 000000000..6029bf268
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-variant.stderr
@@ -0,0 +1,17 @@
+error: variant `Variant1` is never constructed
+ --> $DIR/unused-variant.rs:5:5
+ |
+LL | enum Enum {
+ | ---- variant in this enum
+LL | Variant1,
+ | ^^^^^^^^
+ |
+ = note: `Enum` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
+note: the lint level is defined here
+ --> $DIR/unused-variant.rs:1:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/dead-code/with-core-crate.rs b/tests/ui/lint/dead-code/with-core-crate.rs
new file mode 100644
index 000000000..0a94b528f
--- /dev/null
+++ b/tests/ui/lint/dead-code/with-core-crate.rs
@@ -0,0 +1,18 @@
+#![deny(dead_code)]
+#![allow(unreachable_code)]
+
+#[macro_use]
+extern crate core;
+
+fn foo() { //~ ERROR function `foo` is never used
+
+ // none of these should have any dead_code exposed to the user
+ panic!();
+
+ panic!("foo");
+
+ panic!("bar {}", "baz")
+}
+
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/with-core-crate.stderr b/tests/ui/lint/dead-code/with-core-crate.stderr
new file mode 100644
index 000000000..7adcf8848
--- /dev/null
+++ b/tests/ui/lint/dead-code/with-core-crate.stderr
@@ -0,0 +1,14 @@
+error: function `foo` is never used
+ --> $DIR/with-core-crate.rs:7:4
+ |
+LL | fn foo() {
+ | ^^^
+ |
+note: the lint level is defined here
+ --> $DIR/with-core-crate.rs:1:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/dead-code/with-impl.rs b/tests/ui/lint/dead-code/with-impl.rs
new file mode 100644
index 000000000..812fcdd09
--- /dev/null
+++ b/tests/ui/lint/dead-code/with-impl.rs
@@ -0,0 +1,17 @@
+// run-pass
+
+#![deny(dead_code)]
+
+pub struct GenericFoo<T>(#[allow(unused_tuple_struct_fields)] T);
+
+type Foo = GenericFoo<u32>;
+
+impl Foo {
+ fn bar(self) -> u8 {
+ 0
+ }
+}
+
+fn main() {
+ println!("{}", GenericFoo(0).bar());
+}
diff --git a/tests/ui/lint/deny-overflowing-literals.rs b/tests/ui/lint/deny-overflowing-literals.rs
new file mode 100644
index 000000000..21c8ba7d6
--- /dev/null
+++ b/tests/ui/lint/deny-overflowing-literals.rs
@@ -0,0 +1,7 @@
+fn main() {
+ let x: u8 = 256;
+ //~^ error: literal out of range for `u8`
+
+ for _ in 0..256u8 {}
+ //~^ error: range endpoint is out of range for `u8`
+}
diff --git a/tests/ui/lint/deny-overflowing-literals.stderr b/tests/ui/lint/deny-overflowing-literals.stderr
new file mode 100644
index 000000000..beb0ad795
--- /dev/null
+++ b/tests/ui/lint/deny-overflowing-literals.stderr
@@ -0,0 +1,17 @@
+error: literal out of range for `u8`
+ --> $DIR/deny-overflowing-literals.rs:2:17
+ |
+LL | let x: u8 = 256;
+ | ^^^
+ |
+ = note: the literal `256` does not fit into the type `u8` whose range is `0..=255`
+ = note: `#[deny(overflowing_literals)]` on by default
+
+error: range endpoint is out of range for `u8`
+ --> $DIR/deny-overflowing-literals.rs:5:14
+ |
+LL | for _ in 0..256u8 {}
+ | ^^^^^^^^ help: use an inclusive range instead: `0..=255u8`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/empty-lint-attributes.rs b/tests/ui/lint/empty-lint-attributes.rs
new file mode 100644
index 000000000..9a0ec2533
--- /dev/null
+++ b/tests/ui/lint/empty-lint-attributes.rs
@@ -0,0 +1,17 @@
+#![feature(lint_reasons)]
+
+// check-pass
+
+// Empty (and reason-only) lint attributes are legal—although we may want to
+// lint them in the future (Issue #55112).
+
+#![allow()]
+#![warn(reason = "observationalism")]
+
+#[forbid()]
+fn devoir() {}
+
+#[deny(reason = "ultion")]
+fn waldgrave() {}
+
+fn main() {}
diff --git a/tests/ui/lint/enable-unstable-lib-feature.rs b/tests/ui/lint/enable-unstable-lib-feature.rs
new file mode 100644
index 000000000..aa6a973d7
--- /dev/null
+++ b/tests/ui/lint/enable-unstable-lib-feature.rs
@@ -0,0 +1,13 @@
+// Test that enabling an unstable feature disables warnings
+
+// aux-build:stability-cfg2.rs
+
+#![feature(unstable_test_feature)]
+#![deny(non_snake_case)] // To trigger a hard error
+
+// Shouldn't generate a warning about unstable features
+extern crate stability_cfg2;
+
+pub fn BOGUS() { } //~ ERROR
+
+pub fn main() { }
diff --git a/tests/ui/lint/enable-unstable-lib-feature.stderr b/tests/ui/lint/enable-unstable-lib-feature.stderr
new file mode 100644
index 000000000..bb4e928ad
--- /dev/null
+++ b/tests/ui/lint/enable-unstable-lib-feature.stderr
@@ -0,0 +1,14 @@
+error: function `BOGUS` should have a snake case name
+ --> $DIR/enable-unstable-lib-feature.rs:11:8
+ |
+LL | pub fn BOGUS() { }
+ | ^^^^^ help: convert the identifier to snake case: `bogus`
+ |
+note: the lint level is defined here
+ --> $DIR/enable-unstable-lib-feature.rs:6:9
+ |
+LL | #![deny(non_snake_case)] // To trigger a hard error
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/expansion-time-include.rs b/tests/ui/lint/expansion-time-include.rs
new file mode 100644
index 000000000..4ea89d5ad
--- /dev/null
+++ b/tests/ui/lint/expansion-time-include.rs
@@ -0,0 +1,4 @@
+// ignore-test auxiliary file for expansion-time.rs
+
+1
+2
diff --git a/tests/ui/lint/expansion-time.rs b/tests/ui/lint/expansion-time.rs
new file mode 100644
index 000000000..f23c7cb0d
--- /dev/null
+++ b/tests/ui/lint/expansion-time.rs
@@ -0,0 +1,33 @@
+// check-pass
+
+#[warn(meta_variable_misuse)]
+macro_rules! foo {
+ ( $($i:ident)* ) => { $($i)+ }; //~ WARN meta-variable repeats with different Kleene operator
+}
+
+#[warn(missing_fragment_specifier)]
+macro_rules! m { ($i) => {} } //~ WARN missing fragment specifier
+ //~| WARN this was previously accepted
+
+#[warn(soft_unstable)]
+mod benches {
+ #[bench] //~ WARN use of unstable library feature 'test'
+ //~| WARN this was previously accepted
+ fn foo() {}
+}
+
+#[deprecated = "reason"]
+macro_rules! deprecated {
+ () => {}
+}
+
+#[allow(deprecated)]
+mod deprecated {
+ deprecated!(); // No warning
+}
+
+#[warn(incomplete_include)]
+fn main() {
+ // WARN see in the stderr file, the warning points to the included file.
+ include!("expansion-time-include.rs");
+}
diff --git a/tests/ui/lint/expansion-time.stderr b/tests/ui/lint/expansion-time.stderr
new file mode 100644
index 000000000..064ee5fad
--- /dev/null
+++ b/tests/ui/lint/expansion-time.stderr
@@ -0,0 +1,56 @@
+warning: meta-variable repeats with different Kleene operator
+ --> $DIR/expansion-time.rs:5:29
+ |
+LL | ( $($i:ident)* ) => { $($i)+ };
+ | - ^^ - conflicting repetition
+ | |
+ | expected repetition
+ |
+note: the lint level is defined here
+ --> $DIR/expansion-time.rs:3:8
+ |
+LL | #[warn(meta_variable_misuse)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+warning: missing fragment specifier
+ --> $DIR/expansion-time.rs:9:19
+ |
+LL | macro_rules! m { ($i) => {} }
+ | ^^
+ |
+ = 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 #40107 <https://github.com/rust-lang/rust/issues/40107>
+note: the lint level is defined here
+ --> $DIR/expansion-time.rs:8:8
+ |
+LL | #[warn(missing_fragment_specifier)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable
+ --> $DIR/expansion-time.rs:14:7
+ |
+LL | #[bench]
+ | ^^^^^
+ |
+ = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
+note: the lint level is defined here
+ --> $DIR/expansion-time.rs:12:8
+ |
+LL | #[warn(soft_unstable)]
+ | ^^^^^^^^^^^^^
+
+warning: include macro expected single expression in source
+ --> $DIR/expansion-time-include.rs:4:1
+ |
+LL | 2
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/expansion-time.rs:29:8
+ |
+LL | #[warn(incomplete_include)]
+ | ^^^^^^^^^^^^^^^^^^
+
+warning: 4 warnings emitted
+
diff --git a/tests/ui/lint/expr_attr_paren_order.rs b/tests/ui/lint/expr_attr_paren_order.rs
new file mode 100644
index 000000000..e1ec2e951
--- /dev/null
+++ b/tests/ui/lint/expr_attr_paren_order.rs
@@ -0,0 +1,22 @@
+#![feature(stmt_expr_attributes)]
+
+fn main() {
+
+ // Test that attributes on parens get concatenated
+ // in the expected order in the hir folder.
+
+ #[deny(non_snake_case)] #[allow(non_snake_case)] (
+ {
+ let X = 0;
+ let _ = X;
+ }
+ );
+
+ #[allow(non_snake_case)] #[deny(non_snake_case)] (
+ {
+ let X = 0; //~ ERROR snake case name
+ let _ = X;
+ }
+ );
+
+}
diff --git a/tests/ui/lint/expr_attr_paren_order.stderr b/tests/ui/lint/expr_attr_paren_order.stderr
new file mode 100644
index 000000000..42beed10c
--- /dev/null
+++ b/tests/ui/lint/expr_attr_paren_order.stderr
@@ -0,0 +1,14 @@
+error: variable `X` should have a snake case name
+ --> $DIR/expr_attr_paren_order.rs:17:17
+ |
+LL | let X = 0;
+ | ^ help: convert the identifier to snake case (notice the capitalization): `x`
+ |
+note: the lint level is defined here
+ --> $DIR/expr_attr_paren_order.rs:15:37
+ |
+LL | #[allow(non_snake_case)] #[deny(non_snake_case)] (
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/fn_must_use.rs b/tests/ui/lint/fn_must_use.rs
new file mode 100644
index 000000000..b4e9da0fc
--- /dev/null
+++ b/tests/ui/lint/fn_must_use.rs
@@ -0,0 +1,76 @@
+// check-pass
+
+#![warn(unused_must_use)]
+
+#[derive(PartialEq, Eq)]
+struct MyStruct {
+ n: usize,
+}
+
+impl MyStruct {
+ #[must_use]
+ fn need_to_use_this_method_value(&self) -> usize {
+ self.n
+ }
+
+ #[must_use]
+ fn need_to_use_this_associated_function_value() -> isize {
+ -1
+ }
+}
+
+trait EvenNature {
+ #[must_use = "no side effects"]
+ fn is_even(&self) -> bool;
+}
+
+impl EvenNature for MyStruct {
+ fn is_even(&self) -> bool {
+ self.n % 2 == 0
+ }
+}
+
+trait Replaceable {
+ fn replace(&mut self, substitute: usize) -> usize;
+}
+
+impl Replaceable for MyStruct {
+ // ↓ N.b.: `#[must_use]` attribute on a particular trait implementation
+ // method won't work; the attribute should be on the method signature in
+ // the trait's definition.
+ #[must_use]
+ fn replace(&mut self, substitute: usize) -> usize {
+ let previously = self.n;
+ self.n = substitute;
+ previously
+ }
+}
+
+#[must_use = "it's important"]
+fn need_to_use_this_value() -> bool {
+ false
+}
+
+fn main() {
+ need_to_use_this_value(); //~ WARN unused return value
+
+ let mut m = MyStruct { n: 2 };
+ let n = MyStruct { n: 3 };
+
+ m.need_to_use_this_method_value(); //~ WARN unused return value
+ m.is_even(); // trait method!
+ //~^ WARN unused return value
+
+ MyStruct::need_to_use_this_associated_function_value();
+ //~^ WARN unused return value
+
+ m.replace(3); // won't warn (annotation needs to be in trait definition)
+
+ // comparison methods are `must_use`
+ 2.eq(&3); //~ WARN unused return value
+ m.eq(&n); //~ WARN unused return value
+
+ // lint includes comparison operators
+ 2 == 3; //~ WARN unused comparison
+ m == n; //~ WARN unused comparison
+}
diff --git a/tests/ui/lint/fn_must_use.stderr b/tests/ui/lint/fn_must_use.stderr
new file mode 100644
index 000000000..657f23c60
--- /dev/null
+++ b/tests/ui/lint/fn_must_use.stderr
@@ -0,0 +1,69 @@
+warning: unused return value of `need_to_use_this_value` that must be used
+ --> $DIR/fn_must_use.rs:55:5
+ |
+LL | need_to_use_this_value();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: it's important
+note: the lint level is defined here
+ --> $DIR/fn_must_use.rs:3:9
+ |
+LL | #![warn(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+
+warning: unused return value of `MyStruct::need_to_use_this_method_value` that must be used
+ --> $DIR/fn_must_use.rs:60:5
+ |
+LL | m.need_to_use_this_method_value();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused return value of `EvenNature::is_even` that must be used
+ --> $DIR/fn_must_use.rs:61:5
+ |
+LL | m.is_even(); // trait method!
+ | ^^^^^^^^^^^
+ |
+ = note: no side effects
+
+warning: unused return value of `MyStruct::need_to_use_this_associated_function_value` that must be used
+ --> $DIR/fn_must_use.rs:64:5
+ |
+LL | MyStruct::need_to_use_this_associated_function_value();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused return value of `std::cmp::PartialEq::eq` that must be used
+ --> $DIR/fn_must_use.rs:70:5
+ |
+LL | 2.eq(&3);
+ | ^^^^^^^^
+
+warning: unused return value of `std::cmp::PartialEq::eq` that must be used
+ --> $DIR/fn_must_use.rs:71:5
+ |
+LL | m.eq(&n);
+ | ^^^^^^^^
+
+warning: unused comparison that must be used
+ --> $DIR/fn_must_use.rs:74:5
+ |
+LL | 2 == 3;
+ | ^^^^^^ the comparison produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = 2 == 3;
+ | +++++++
+
+warning: unused comparison that must be used
+ --> $DIR/fn_must_use.rs:75:5
+ |
+LL | m == n;
+ | ^^^^^^ the comparison produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = m == n;
+ | +++++++
+
+warning: 8 warnings emitted
+
diff --git a/tests/ui/lint/for_loop_over_fallibles.rs b/tests/ui/lint/for_loop_over_fallibles.rs
new file mode 100644
index 000000000..43d71c2e8
--- /dev/null
+++ b/tests/ui/lint/for_loop_over_fallibles.rs
@@ -0,0 +1,43 @@
+// check-pass
+
+fn main() {
+ // Common
+ for _ in Some(1) {}
+ //~^ WARN for loop over an `Option`. This is more readably written as an `if let` statement
+ //~| HELP to check pattern in a loop use `while let`
+ //~| HELP consider using `if let` to clear intent
+ for _ in Ok::<_, ()>(1) {}
+ //~^ WARN for loop over a `Result`. This is more readably written as an `if let` statement
+ //~| HELP to check pattern in a loop use `while let`
+ //~| HELP consider using `if let` to clear intent
+
+ // `Iterator::next` specific
+ for _ in [0; 0].iter().next() {}
+ //~^ WARN for loop over an `Option`. This is more readably written as an `if let` statement
+ //~| HELP to iterate over `[0; 0].iter()` remove the call to `next`
+ //~| HELP consider using `if let` to clear intent
+
+ // `Result<impl Iterator, _>`, but function doesn't return `Result`
+ for _ in Ok::<_, ()>([0; 0].iter()) {}
+ //~^ WARN for loop over a `Result`. This is more readably written as an `if let` statement
+ //~| HELP to check pattern in a loop use `while let`
+ //~| HELP consider using `if let` to clear intent
+}
+
+fn _returns_result() -> Result<(), ()> {
+ // `Result<impl Iterator, _>`
+ for _ in Ok::<_, ()>([0; 0].iter()) {}
+ //~^ WARN for loop over a `Result`. This is more readably written as an `if let` statement
+ //~| HELP to check pattern in a loop use `while let`
+ //~| HELP consider unwrapping the `Result` with `?` to iterate over its contents
+ //~| HELP consider using `if let` to clear intent
+
+ // `Result<impl IntoIterator>`
+ for _ in Ok::<_, ()>([0; 0]) {}
+ //~^ WARN for loop over a `Result`. This is more readably written as an `if let` statement
+ //~| HELP to check pattern in a loop use `while let`
+ //~| HELP consider unwrapping the `Result` with `?` to iterate over its contents
+ //~| HELP consider using `if let` to clear intent
+
+ Ok(())
+}
diff --git a/tests/ui/lint/for_loop_over_fallibles.stderr b/tests/ui/lint/for_loop_over_fallibles.stderr
new file mode 100644
index 000000000..96efdf85c
--- /dev/null
+++ b/tests/ui/lint/for_loop_over_fallibles.stderr
@@ -0,0 +1,101 @@
+warning: for loop over an `Option`. This is more readably written as an `if let` statement
+ --> $DIR/for_loop_over_fallibles.rs:5:14
+ |
+LL | for _ in Some(1) {}
+ | ^^^^^^^
+ |
+ = note: `#[warn(for_loops_over_fallibles)]` on by default
+help: to check pattern in a loop use `while let`
+ |
+LL | while let Some(_) = Some(1) {}
+ | ~~~~~~~~~~~~~~~ ~~~
+help: consider using `if let` to clear intent
+ |
+LL | if let Some(_) = Some(1) {}
+ | ~~~~~~~~~~~~ ~~~
+
+warning: for loop over a `Result`. This is more readably written as an `if let` statement
+ --> $DIR/for_loop_over_fallibles.rs:9:14
+ |
+LL | for _ in Ok::<_, ()>(1) {}
+ | ^^^^^^^^^^^^^^
+ |
+help: to check pattern in a loop use `while let`
+ |
+LL | while let Ok(_) = Ok::<_, ()>(1) {}
+ | ~~~~~~~~~~~~~ ~~~
+help: consider using `if let` to clear intent
+ |
+LL | if let Ok(_) = Ok::<_, ()>(1) {}
+ | ~~~~~~~~~~ ~~~
+
+warning: for loop over an `Option`. This is more readably written as an `if let` statement
+ --> $DIR/for_loop_over_fallibles.rs:15:14
+ |
+LL | for _ in [0; 0].iter().next() {}
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+help: to iterate over `[0; 0].iter()` remove the call to `next`
+ |
+LL | for _ in [0; 0].iter().by_ref() {}
+ | ~~~~~~~~~
+help: consider using `if let` to clear intent
+ |
+LL | if let Some(_) = [0; 0].iter().next() {}
+ | ~~~~~~~~~~~~ ~~~
+
+warning: for loop over a `Result`. This is more readably written as an `if let` statement
+ --> $DIR/for_loop_over_fallibles.rs:21:14
+ |
+LL | for _ in Ok::<_, ()>([0; 0].iter()) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: to check pattern in a loop use `while let`
+ |
+LL | while let Ok(_) = Ok::<_, ()>([0; 0].iter()) {}
+ | ~~~~~~~~~~~~~ ~~~
+help: consider using `if let` to clear intent
+ |
+LL | if let Ok(_) = Ok::<_, ()>([0; 0].iter()) {}
+ | ~~~~~~~~~~ ~~~
+
+warning: for loop over a `Result`. This is more readably written as an `if let` statement
+ --> $DIR/for_loop_over_fallibles.rs:29:14
+ |
+LL | for _ in Ok::<_, ()>([0; 0].iter()) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: to check pattern in a loop use `while let`
+ |
+LL | while let Ok(_) = Ok::<_, ()>([0; 0].iter()) {}
+ | ~~~~~~~~~~~~~ ~~~
+help: consider unwrapping the `Result` with `?` to iterate over its contents
+ |
+LL | for _ in Ok::<_, ()>([0; 0].iter())? {}
+ | +
+help: consider using `if let` to clear intent
+ |
+LL | if let Ok(_) = Ok::<_, ()>([0; 0].iter()) {}
+ | ~~~~~~~~~~ ~~~
+
+warning: for loop over a `Result`. This is more readably written as an `if let` statement
+ --> $DIR/for_loop_over_fallibles.rs:36:14
+ |
+LL | for _ in Ok::<_, ()>([0; 0]) {}
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+help: to check pattern in a loop use `while let`
+ |
+LL | while let Ok(_) = Ok::<_, ()>([0; 0]) {}
+ | ~~~~~~~~~~~~~ ~~~
+help: consider unwrapping the `Result` with `?` to iterate over its contents
+ |
+LL | for _ in Ok::<_, ()>([0; 0])? {}
+ | +
+help: consider using `if let` to clear intent
+ |
+LL | if let Ok(_) = Ok::<_, ()>([0; 0]) {}
+ | ~~~~~~~~~~ ~~~
+
+warning: 6 warnings emitted
+
diff --git a/tests/ui/lint/forbid-error-capped.rs b/tests/ui/lint/forbid-error-capped.rs
new file mode 100644
index 000000000..b56471a75
--- /dev/null
+++ b/tests/ui/lint/forbid-error-capped.rs
@@ -0,0 +1,15 @@
+// check-pass
+// compile-args: --cap-lints=warn -Fwarnings
+
+// This checks that the forbid attribute checking is ignored when the forbidden
+// lint is capped.
+
+#![forbid(warnings)]
+#![allow(unused)]
+
+#[allow(unused)]
+mod bar {
+ fn bar() {}
+}
+
+fn main() {}
diff --git a/tests/ui/lint/forbid-group-group-1.rs b/tests/ui/lint/forbid-group-group-1.rs
new file mode 100644
index 000000000..80f7db4e5
--- /dev/null
+++ b/tests/ui/lint/forbid-group-group-1.rs
@@ -0,0 +1,13 @@
+// Check what happens when we forbid a smaller group but
+// then allow a superset of that group.
+
+#![forbid(nonstandard_style)]
+
+// FIXME: Arguably this should be an error, but the WARNINGS group is
+// treated in a very special (and rather ad-hoc) way and
+// it fails to trigger.
+#[allow(warnings)]
+fn main() {
+ let A: ();
+ //~^ ERROR should have a snake case name
+}
diff --git a/tests/ui/lint/forbid-group-group-1.stderr b/tests/ui/lint/forbid-group-group-1.stderr
new file mode 100644
index 000000000..fd425e5f7
--- /dev/null
+++ b/tests/ui/lint/forbid-group-group-1.stderr
@@ -0,0 +1,15 @@
+error: variable `A` should have a snake case name
+ --> $DIR/forbid-group-group-1.rs:11:9
+ |
+LL | let A: ();
+ | ^ help: convert the identifier to snake case: `a`
+ |
+note: the lint level is defined here
+ --> $DIR/forbid-group-group-1.rs:4:11
+ |
+LL | #![forbid(nonstandard_style)]
+ | ^^^^^^^^^^^^^^^^^
+ = note: `#[forbid(non_snake_case)]` implied by `#[forbid(nonstandard_style)]`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/forbid-group-group-2.rs b/tests/ui/lint/forbid-group-group-2.rs
new file mode 100644
index 000000000..b12fd72da
--- /dev/null
+++ b/tests/ui/lint/forbid-group-group-2.rs
@@ -0,0 +1,26 @@
+// Check what happens when we forbid a bigger group but
+// then deny a subset of that group.
+
+#![forbid(warnings)]
+#![deny(forbidden_lint_groups)]
+
+#[allow(nonstandard_style)]
+//~^ ERROR incompatible with previous
+//~| WARNING previously accepted by the compiler
+//~| ERROR incompatible with previous
+//~| WARNING previously accepted by the compiler
+//~| ERROR incompatible with previous
+//~| WARNING previously accepted by the compiler
+//~| ERROR incompatible with previous
+//~| WARNING previously accepted by the compiler
+//~| ERROR incompatible with previous
+//~| WARNING previously accepted by the compiler
+//~| ERROR incompatible with previous
+//~| WARNING previously accepted by the compiler
+//~| ERROR incompatible with previous
+//~| WARNING previously accepted by the compiler
+//~| ERROR incompatible with previous
+//~| WARNING previously accepted by the compiler
+//~| ERROR incompatible with previous
+//~| WARNING previously accepted by the compiler
+fn main() {}
diff --git a/tests/ui/lint/forbid-group-group-2.stderr b/tests/ui/lint/forbid-group-group-2.stderr
new file mode 100644
index 000000000..b2e2bcea1
--- /dev/null
+++ b/tests/ui/lint/forbid-group-group-2.stderr
@@ -0,0 +1,115 @@
+error: allow(nonstandard_style) incompatible with previous forbid
+ --> $DIR/forbid-group-group-2.rs:7:9
+ |
+LL | #![forbid(warnings)]
+ | -------- `forbid` level set here
+...
+LL | #[allow(nonstandard_style)]
+ | ^^^^^^^^^^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+note: the lint level is defined here
+ --> $DIR/forbid-group-group-2.rs:5:9
+ |
+LL | #![deny(forbidden_lint_groups)]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: allow(nonstandard_style) incompatible with previous forbid
+ --> $DIR/forbid-group-group-2.rs:7:9
+ |
+LL | #![forbid(warnings)]
+ | -------- `forbid` level set here
+...
+LL | #[allow(nonstandard_style)]
+ | ^^^^^^^^^^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+
+error: allow(nonstandard_style) incompatible with previous forbid
+ --> $DIR/forbid-group-group-2.rs:7:9
+ |
+LL | #![forbid(warnings)]
+ | -------- `forbid` level set here
+...
+LL | #[allow(nonstandard_style)]
+ | ^^^^^^^^^^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+
+error: allow(nonstandard_style) incompatible with previous forbid
+ --> $DIR/forbid-group-group-2.rs:7:9
+ |
+LL | #![forbid(warnings)]
+ | -------- `forbid` level set here
+...
+LL | #[allow(nonstandard_style)]
+ | ^^^^^^^^^^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+
+error: allow(nonstandard_style) incompatible with previous forbid
+ --> $DIR/forbid-group-group-2.rs:7:9
+ |
+LL | #![forbid(warnings)]
+ | -------- `forbid` level set here
+...
+LL | #[allow(nonstandard_style)]
+ | ^^^^^^^^^^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+
+error: allow(nonstandard_style) incompatible with previous forbid
+ --> $DIR/forbid-group-group-2.rs:7:9
+ |
+LL | #![forbid(warnings)]
+ | -------- `forbid` level set here
+...
+LL | #[allow(nonstandard_style)]
+ | ^^^^^^^^^^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+
+error: allow(nonstandard_style) incompatible with previous forbid
+ --> $DIR/forbid-group-group-2.rs:7:9
+ |
+LL | #![forbid(warnings)]
+ | -------- `forbid` level set here
+...
+LL | #[allow(nonstandard_style)]
+ | ^^^^^^^^^^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+
+error: allow(nonstandard_style) incompatible with previous forbid
+ --> $DIR/forbid-group-group-2.rs:7:9
+ |
+LL | #![forbid(warnings)]
+ | -------- `forbid` level set here
+...
+LL | #[allow(nonstandard_style)]
+ | ^^^^^^^^^^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+
+error: allow(nonstandard_style) incompatible with previous forbid
+ --> $DIR/forbid-group-group-2.rs:7:9
+ |
+LL | #![forbid(warnings)]
+ | -------- `forbid` level set here
+...
+LL | #[allow(nonstandard_style)]
+ | ^^^^^^^^^^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+
+error: aborting due to 9 previous errors
+
diff --git a/tests/ui/lint/forbid-group-member.rs b/tests/ui/lint/forbid-group-member.rs
new file mode 100644
index 000000000..664edeaa8
--- /dev/null
+++ b/tests/ui/lint/forbid-group-member.rs
@@ -0,0 +1,17 @@
+// Check what happens when we forbid a group but
+// then allow a member of that group.
+//
+// check-pass
+
+#![forbid(unused)]
+
+#[allow(unused_variables)]
+//~^ WARNING incompatible with previous forbid
+//~| WARNING previously accepted
+//~| WARNING incompatible with previous forbid
+//~| WARNING previously accepted
+//~| WARNING incompatible with previous forbid
+//~| WARNING previously accepted
+fn main() {
+ let a: ();
+}
diff --git a/tests/ui/lint/forbid-group-member.stderr b/tests/ui/lint/forbid-group-member.stderr
new file mode 100644
index 000000000..47336d4d8
--- /dev/null
+++ b/tests/ui/lint/forbid-group-member.stderr
@@ -0,0 +1,39 @@
+warning: allow(unused_variables) incompatible with previous forbid
+ --> $DIR/forbid-group-member.rs:8:9
+ |
+LL | #![forbid(unused)]
+ | ------ `forbid` level set here
+LL |
+LL | #[allow(unused_variables)]
+ | ^^^^^^^^^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+ = note: `#[warn(forbidden_lint_groups)]` on by default
+
+warning: allow(unused_variables) incompatible with previous forbid
+ --> $DIR/forbid-group-member.rs:8:9
+ |
+LL | #![forbid(unused)]
+ | ------ `forbid` level set here
+LL |
+LL | #[allow(unused_variables)]
+ | ^^^^^^^^^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+
+warning: allow(unused_variables) incompatible with previous forbid
+ --> $DIR/forbid-group-member.rs:8:9
+ |
+LL | #![forbid(unused)]
+ | ------ `forbid` level set here
+LL |
+LL | #[allow(unused_variables)]
+ | ^^^^^^^^^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/lint/forbid-member-group.rs b/tests/ui/lint/forbid-member-group.rs
new file mode 100644
index 000000000..e2f76825a
--- /dev/null
+++ b/tests/ui/lint/forbid-member-group.rs
@@ -0,0 +1,11 @@
+// Check what happens when we forbid a member of
+// a group but then allow the group.
+
+#![forbid(unused_variables)]
+
+#[allow(unused)]
+//~^ ERROR incompatible with previous forbid
+//~| ERROR incompatible with previous forbid
+fn main() {
+ let a: ();
+}
diff --git a/tests/ui/lint/forbid-member-group.stderr b/tests/ui/lint/forbid-member-group.stderr
new file mode 100644
index 000000000..e65301778
--- /dev/null
+++ b/tests/ui/lint/forbid-member-group.stderr
@@ -0,0 +1,21 @@
+error[E0453]: allow(unused) incompatible with previous forbid
+ --> $DIR/forbid-member-group.rs:6:9
+ |
+LL | #![forbid(unused_variables)]
+ | ---------------- `forbid` level set here
+LL |
+LL | #[allow(unused)]
+ | ^^^^^^ overruled by previous forbid
+
+error[E0453]: allow(unused) incompatible with previous forbid
+ --> $DIR/forbid-member-group.rs:6:9
+ |
+LL | #![forbid(unused_variables)]
+ | ---------------- `forbid` level set here
+LL |
+LL | #[allow(unused)]
+ | ^^^^^^ overruled by previous forbid
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0453`.
diff --git a/tests/ui/lint/force-warn/allow-warnings.rs b/tests/ui/lint/force-warn/allow-warnings.rs
new file mode 100644
index 000000000..0199381fc
--- /dev/null
+++ b/tests/ui/lint/force-warn/allow-warnings.rs
@@ -0,0 +1,11 @@
+// --force-warn $LINT causes $LINT (which is warn-by-default) to warn
+// despite allowing all warnings in module
+// compile-flags: --force-warn dead_code
+// check-pass
+
+#![allow(warnings)]
+
+fn dead_function() {}
+//~^ WARN function `dead_function` is never used
+
+fn main() {}
diff --git a/tests/ui/lint/force-warn/allow-warnings.stderr b/tests/ui/lint/force-warn/allow-warnings.stderr
new file mode 100644
index 000000000..4de68a079
--- /dev/null
+++ b/tests/ui/lint/force-warn/allow-warnings.stderr
@@ -0,0 +1,10 @@
+warning: function `dead_function` is never used
+ --> $DIR/allow-warnings.rs:8:4
+ |
+LL | fn dead_function() {}
+ | ^^^^^^^^^^^^^
+ |
+ = note: requested on the command line with `--force-warn dead-code`
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/force-warn/allowed-by-default-lint.rs b/tests/ui/lint/force-warn/allowed-by-default-lint.rs
new file mode 100644
index 000000000..b24ab822d
--- /dev/null
+++ b/tests/ui/lint/force-warn/allowed-by-default-lint.rs
@@ -0,0 +1,12 @@
+// --force-warn $LINT causes $LINT (which is allow-by-default) to warn
+// compile-flags: --force-warn elided_lifetimes_in_paths
+// check-pass
+
+struct Foo<'a> {
+ x: &'a u32,
+}
+
+fn foo(x: &Foo) {}
+//~^ WARN hidden lifetime parameters in types are deprecated
+
+fn main() {}
diff --git a/tests/ui/lint/force-warn/allowed-by-default-lint.stderr b/tests/ui/lint/force-warn/allowed-by-default-lint.stderr
new file mode 100644
index 000000000..ac98b5896
--- /dev/null
+++ b/tests/ui/lint/force-warn/allowed-by-default-lint.stderr
@@ -0,0 +1,14 @@
+warning: hidden lifetime parameters in types are deprecated
+ --> $DIR/allowed-by-default-lint.rs:9:12
+ |
+LL | fn foo(x: &Foo) {}
+ | ^^^ expected lifetime parameter
+ |
+ = note: requested on the command line with `--force-warn elided-lifetimes-in-paths`
+help: indicate the anonymous lifetime
+ |
+LL | fn foo(x: &Foo<'_>) {}
+ | ++++
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/force-warn/allowed-cli-deny-by-default-lint.rs b/tests/ui/lint/force-warn/allowed-cli-deny-by-default-lint.rs
new file mode 100644
index 000000000..257df13ef
--- /dev/null
+++ b/tests/ui/lint/force-warn/allowed-cli-deny-by-default-lint.rs
@@ -0,0 +1,10 @@
+// --force-warn $LINT causes $LINT (which is deny-by-default) to warn
+// despite $LINT being allowed on command line
+// compile-flags: -A mutable_transmutes --force-warn mutable_transmutes
+// check-pass
+
+fn main() {
+ unsafe {
+ let y = std::mem::transmute::<&i32, &mut i32>(&5); //~WARN: undefined behavior
+ }
+}
diff --git a/tests/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr b/tests/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr
new file mode 100644
index 000000000..6a1fc76e1
--- /dev/null
+++ b/tests/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr
@@ -0,0 +1,10 @@
+warning: transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell
+ --> $DIR/allowed-cli-deny-by-default-lint.rs:8:17
+ |
+LL | let y = std::mem::transmute::<&i32, &mut i32>(&5);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: requested on the command line with `--force-warn mutable-transmutes`
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/force-warn/allowed-deny-by-default-lint.rs b/tests/ui/lint/force-warn/allowed-deny-by-default-lint.rs
new file mode 100644
index 000000000..0d4b468c2
--- /dev/null
+++ b/tests/ui/lint/force-warn/allowed-deny-by-default-lint.rs
@@ -0,0 +1,11 @@
+// --force-warn $LINT causes $LINT (which is deny-by-default) to warn
+// despite $LINT being allowed in module
+// compile-flags: --force-warn mutable_transmutes
+// check-pass
+
+#![allow(mutable_transmutes)]
+fn main() {
+ unsafe {
+ let y = std::mem::transmute::<&i32, &mut i32>(&5); //~WARN: undefined behavior
+ }
+}
diff --git a/tests/ui/lint/force-warn/allowed-deny-by-default-lint.stderr b/tests/ui/lint/force-warn/allowed-deny-by-default-lint.stderr
new file mode 100644
index 000000000..9ef53d47e
--- /dev/null
+++ b/tests/ui/lint/force-warn/allowed-deny-by-default-lint.stderr
@@ -0,0 +1,10 @@
+warning: transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell
+ --> $DIR/allowed-deny-by-default-lint.rs:9:17
+ |
+LL | let y = std::mem::transmute::<&i32, &mut i32>(&5);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: requested on the command line with `--force-warn mutable-transmutes`
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.rs b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.rs
new file mode 100644
index 000000000..631a8cb2f
--- /dev/null
+++ b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.rs
@@ -0,0 +1,18 @@
+// --force-warn $LINT causes $LINT (which is warn-by-default) to warn
+// despite $LINT_GROUP (which contains $LINT) being allowed
+// compile-flags: --force-warn bare_trait_objects
+// check-pass
+
+#![allow(rust_2018_idioms)]
+
+pub trait SomeTrait {}
+
+pub fn function(_x: Box<SomeTrait>) {}
+//~^ WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+
+fn main() {}
diff --git a/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
new file mode 100644
index 000000000..0f58953a5
--- /dev/null
+++ b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
@@ -0,0 +1,42 @@
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/allowed-group-warn-by-default-lint.rs:10:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: requested on the command line with `--force-warn bare-trait-objects`
+help: use `dyn`
+ |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/allowed-group-warn-by-default-lint.rs:10:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/allowed-group-warn-by-default-lint.rs:10:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/lint/force-warn/allowed-warn-by-default-lint.rs b/tests/ui/lint/force-warn/allowed-warn-by-default-lint.rs
new file mode 100644
index 000000000..06b372867
--- /dev/null
+++ b/tests/ui/lint/force-warn/allowed-warn-by-default-lint.rs
@@ -0,0 +1,11 @@
+// --force-warn $LINT causes $LINT (which is warn-by-default) to warn
+// despite $LINT being allowed in module
+// compile-flags: --force-warn dead_code
+// check-pass
+
+#![allow(dead_code)]
+
+fn dead_function() {}
+//~^ WARN function `dead_function` is never used
+
+fn main() {}
diff --git a/tests/ui/lint/force-warn/allowed-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/allowed-warn-by-default-lint.stderr
new file mode 100644
index 000000000..a6634e212
--- /dev/null
+++ b/tests/ui/lint/force-warn/allowed-warn-by-default-lint.stderr
@@ -0,0 +1,10 @@
+warning: function `dead_function` is never used
+ --> $DIR/allowed-warn-by-default-lint.rs:8:4
+ |
+LL | fn dead_function() {}
+ | ^^^^^^^^^^^^^
+ |
+ = note: requested on the command line with `--force-warn dead-code`
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/force-warn/cap-lints-allow.rs b/tests/ui/lint/force-warn/cap-lints-allow.rs
new file mode 100644
index 000000000..fdba7f410
--- /dev/null
+++ b/tests/ui/lint/force-warn/cap-lints-allow.rs
@@ -0,0 +1,16 @@
+// --force-warn $LINT casuses $LINT to warn despite --cap-lints
+// set to allow
+// compile-flags: --cap-lints allow --force-warn bare_trait_objects
+// check-pass
+
+pub trait SomeTrait {}
+
+pub fn function(_x: Box<SomeTrait>) {}
+//~^ WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+
+fn main() {}
diff --git a/tests/ui/lint/force-warn/cap-lints-allow.stderr b/tests/ui/lint/force-warn/cap-lints-allow.stderr
new file mode 100644
index 000000000..03a32fa6f
--- /dev/null
+++ b/tests/ui/lint/force-warn/cap-lints-allow.stderr
@@ -0,0 +1,42 @@
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/cap-lints-allow.rs:8:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: requested on the command line with `--force-warn bare-trait-objects`
+help: use `dyn`
+ |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/cap-lints-allow.rs:8:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/cap-lints-allow.rs:8:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.rs b/tests/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.rs
new file mode 100644
index 000000000..e65f156bf
--- /dev/null
+++ b/tests/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.rs
@@ -0,0 +1,17 @@
+// --force-warn $LINT_GROUP causes $LINT to warn despite $LINT being
+// allowed in module and cap-lints set to warn
+// compile-flags: --cap-lints warn --force-warn rust-2021-compatibility
+// check-pass
+#![allow(ellipsis_inclusive_range_patterns)]
+
+pub fn f() -> bool {
+ let x = 123;
+ match x {
+ 0...100 => true,
+ //~^ WARN range patterns are deprecated
+ //~| WARN this is accepted in the current edition
+ _ => false,
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr
new file mode 100644
index 000000000..d1b764b34
--- /dev/null
+++ b/tests/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr
@@ -0,0 +1,12 @@
+warning: `...` range patterns are deprecated
+ --> $DIR/cap-lints-warn-allowed-warn-by-default-lint.rs:10:10
+ |
+LL | 0...100 => true,
+ | ^^^ help: use `..=` for an inclusive range
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: `--force-warn ellipsis-inclusive-range-patterns` implied by `--force-warn rust-2021-compatibility`
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/force-warn/deny-by-default-lint.rs b/tests/ui/lint/force-warn/deny-by-default-lint.rs
new file mode 100644
index 000000000..c2e9377e9
--- /dev/null
+++ b/tests/ui/lint/force-warn/deny-by-default-lint.rs
@@ -0,0 +1,9 @@
+// --force-warn $LINT causes $LINT (which is deny-by-default) to warn
+// compile-flags: --force-warn mutable_transmutes
+// check-pass
+
+fn main() {
+ unsafe {
+ let y = std::mem::transmute::<&i32, &mut i32>(&5); //~WARN: undefined behavior
+ }
+}
diff --git a/tests/ui/lint/force-warn/deny-by-default-lint.stderr b/tests/ui/lint/force-warn/deny-by-default-lint.stderr
new file mode 100644
index 000000000..c644d0fe7
--- /dev/null
+++ b/tests/ui/lint/force-warn/deny-by-default-lint.stderr
@@ -0,0 +1,10 @@
+warning: transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell
+ --> $DIR/deny-by-default-lint.rs:7:17
+ |
+LL | let y = std::mem::transmute::<&i32, &mut i32>(&5);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: requested on the command line with `--force-warn mutable-transmutes`
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/force-warn/lint-group-allow-warnings.rs b/tests/ui/lint/force-warn/lint-group-allow-warnings.rs
new file mode 100644
index 000000000..4b95f4d2d
--- /dev/null
+++ b/tests/ui/lint/force-warn/lint-group-allow-warnings.rs
@@ -0,0 +1,12 @@
+// --force-warn $LINT_GROUP causes $LINT in $LINT_GROUP to warn
+// despite all warnings being allowed in module
+// warn-by-default lint to warn
+// compile-flags: --force-warn nonstandard_style
+// check-pass
+
+#![allow(warnings)]
+
+pub fn FUNCTION() {}
+//~^ WARN function `FUNCTION` should have a snake case name
+
+fn main() {}
diff --git a/tests/ui/lint/force-warn/lint-group-allow-warnings.stderr b/tests/ui/lint/force-warn/lint-group-allow-warnings.stderr
new file mode 100644
index 000000000..dc7b1b7b9
--- /dev/null
+++ b/tests/ui/lint/force-warn/lint-group-allow-warnings.stderr
@@ -0,0 +1,10 @@
+warning: function `FUNCTION` should have a snake case name
+ --> $DIR/lint-group-allow-warnings.rs:9:8
+ |
+LL | pub fn FUNCTION() {}
+ | ^^^^^^^^ help: convert the identifier to snake case: `function`
+ |
+ = note: `--force-warn non-snake-case` implied by `--force-warn nonstandard-style`
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.rs b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.rs
new file mode 100644
index 000000000..7ad7462dd
--- /dev/null
+++ b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.rs
@@ -0,0 +1,16 @@
+// --force-warn $LINT_GROUP causes $LINT (which is warn-by-default) to warn
+// despite $LINT being allowed on command line
+// compile-flags: -A bare-trait-objects --force-warn rust-2018-idioms
+// check-pass
+
+pub trait SomeTrait {}
+
+pub fn function(_x: Box<SomeTrait>) {}
+//~^ WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+
+fn main() {}
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
new file mode 100644
index 000000000..e17630fd3
--- /dev/null
+++ b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
@@ -0,0 +1,42 @@
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/lint-group-allowed-cli-warn-by-default-lint.rs:8:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
+help: use `dyn`
+ |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/lint-group-allowed-cli-warn-by-default-lint.rs:8:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/lint-group-allowed-cli-warn-by-default-lint.rs:8:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-lint-group.rs b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.rs
new file mode 100644
index 000000000..ee5a18c38
--- /dev/null
+++ b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.rs
@@ -0,0 +1,18 @@
+// --force-warn $LINT_GROUP causes $LINT to warn despite
+// $LINT_GROUP being allowed in module
+// compile-flags: --force-warn rust_2018_idioms
+// check-pass
+
+#![allow(rust_2018_idioms)]
+
+pub trait SomeTrait {}
+
+pub fn function(_x: Box<SomeTrait>) {}
+//~^ WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+
+fn main() {}
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
new file mode 100644
index 000000000..72198541a
--- /dev/null
+++ b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
@@ -0,0 +1,42 @@
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/lint-group-allowed-lint-group.rs:10:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
+help: use `dyn`
+ |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/lint-group-allowed-lint-group.rs:10:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/lint-group-allowed-lint-group.rs:10:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.rs b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.rs
new file mode 100644
index 000000000..248aece6f
--- /dev/null
+++ b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.rs
@@ -0,0 +1,18 @@
+// --force-warn $LINT_GROUP causes $LINT (which is warn-by-default) to warn
+// despite $LINT being allowed in module
+// compile-flags: --force-warn rust-2018-idioms
+// check-pass
+
+#![allow(bare_trait_objects)]
+
+pub trait SomeTrait {}
+
+pub fn function(_x: Box<SomeTrait>) {}
+//~^ WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+//~| WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+
+fn main() {}
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
new file mode 100644
index 000000000..52c870ac2
--- /dev/null
+++ b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
@@ -0,0 +1,42 @@
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/lint-group-allowed-warn-by-default-lint.rs:10:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
+help: use `dyn`
+ |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/lint-group-allowed-warn-by-default-lint.rs:10:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/lint-group-allowed-warn-by-default-lint.rs:10:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | pub fn function(_x: Box<dyn SomeTrait>) {}
+ | +++
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/lint/force-warn/warn-by-default-lint-two-modules.rs b/tests/ui/lint/force-warn/warn-by-default-lint-two-modules.rs
new file mode 100644
index 000000000..47a480ad7
--- /dev/null
+++ b/tests/ui/lint/force-warn/warn-by-default-lint-two-modules.rs
@@ -0,0 +1,18 @@
+// --force-warn $LINT causes $LINT (which is warn-by-default) to warn
+// despite being allowed in one submodule (but not the other)
+// compile-flags: --force-warn dead_code
+// check-pass
+
+mod one {
+ #![allow(dead_code)]
+
+ fn dead_function() {}
+ //~^ WARN function `dead_function` is never used
+}
+
+mod two {
+ fn dead_function() {}
+ //~^ WARN function `dead_function` is never used
+}
+
+fn main() {}
diff --git a/tests/ui/lint/force-warn/warn-by-default-lint-two-modules.stderr b/tests/ui/lint/force-warn/warn-by-default-lint-two-modules.stderr
new file mode 100644
index 000000000..824bcccc0
--- /dev/null
+++ b/tests/ui/lint/force-warn/warn-by-default-lint-two-modules.stderr
@@ -0,0 +1,16 @@
+warning: function `dead_function` is never used
+ --> $DIR/warn-by-default-lint-two-modules.rs:9:8
+ |
+LL | fn dead_function() {}
+ | ^^^^^^^^^^^^^
+ |
+ = note: requested on the command line with `--force-warn dead-code`
+
+warning: function `dead_function` is never used
+ --> $DIR/warn-by-default-lint-two-modules.rs:14:8
+ |
+LL | fn dead_function() {}
+ | ^^^^^^^^^^^^^
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/lint/force-warn/warnings-lint-group.rs b/tests/ui/lint/force-warn/warnings-lint-group.rs
new file mode 100644
index 000000000..d1d4f5602
--- /dev/null
+++ b/tests/ui/lint/force-warn/warnings-lint-group.rs
@@ -0,0 +1,5 @@
+// --force-warn warnings is an error
+// compile-flags: --force-warn warnings
+// error-pattern: `warnings` lint group is not supported
+
+fn main() {}
diff --git a/tests/ui/lint/force-warn/warnings-lint-group.stderr b/tests/ui/lint/force-warn/warnings-lint-group.stderr
new file mode 100644
index 000000000..1faeed337
--- /dev/null
+++ b/tests/ui/lint/force-warn/warnings-lint-group.stderr
@@ -0,0 +1,7 @@
+error[E0602]: `warnings` lint group is not supported with ´--force-warn´
+
+error[E0602]: `warnings` lint group is not supported with ´--force-warn´
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0602`.
diff --git a/tests/ui/lint/function-item-references.rs b/tests/ui/lint/function-item-references.rs
new file mode 100644
index 000000000..05213f4ed
--- /dev/null
+++ b/tests/ui/lint/function-item-references.rs
@@ -0,0 +1,169 @@
+// check-pass
+#![feature(c_variadic)]
+#![warn(function_item_references)]
+use std::fmt::Pointer;
+use std::fmt::Formatter;
+
+fn nop() { }
+fn foo() -> u32 { 42 }
+fn bar(x: u32) -> u32 { x }
+fn baz(x: u32, y: u32) -> u32 { x + y }
+unsafe fn unsafe_fn() { }
+extern "C" fn c_fn() { }
+unsafe extern "C" fn unsafe_c_fn() { }
+unsafe extern fn variadic(_x: u32, _args: ...) { }
+fn take_generic_ref<'a, T>(_x: &'a T) { }
+fn take_generic_array<T, const N: usize>(_x: [T; N]) { }
+fn multiple_generic<T, U>(_x: T, _y: U) { }
+fn multiple_generic_arrays<T, U, const N: usize, const M: usize>(_x: [T; N], _y: [U; M]) { }
+
+//function references passed to these functions should never lint
+fn call_fn(f: &dyn Fn(u32) -> u32, x: u32) { f(x); }
+fn parameterized_call_fn<F: Fn(u32) -> u32>(f: &F, x: u32) { f(x); }
+
+//function references passed to these functions should lint
+fn print_ptr<F: Pointer>(f: F) { println!("{:p}", f); }
+fn bound_by_ptr_trait<F: Pointer>(_f: F) { }
+fn bound_by_ptr_trait_tuple<F: Pointer, G: Pointer>(_t: (F, G)) { }
+fn implicit_ptr_trait<F>(f: &F) { println!("{:p}", f); }
+
+//case found in tinyvec that triggered a compiler error in an earlier version of the lint checker
+trait HasItem {
+ type Item;
+ fn assoc_item(&self) -> Self::Item;
+}
+fn _format_assoc_item<T: HasItem>(data: T, f: &mut Formatter) -> std::fmt::Result
+ where T::Item: Pointer {
+ //when the arg type bound by `Pointer` is an associated type, we shouldn't attempt to normalize
+ Pointer::fmt(&data.assoc_item(), f)
+}
+
+//simple test to make sure that calls to `Pointer::fmt` aren't double counted
+fn _call_pointer_fmt(f: &mut Formatter) -> std::fmt::Result {
+ let zst_ref = &foo;
+ Pointer::fmt(&zst_ref, f)
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+}
+
+fn main() {
+ //`let` bindings with function references shouldn't lint
+ let _ = &foo;
+ let _ = &mut foo;
+
+ let zst_ref = &foo;
+ let fn_item = foo;
+ let indirect_ref = &fn_item;
+
+ let _mut_zst_ref = &mut foo;
+ let mut mut_fn_item = foo;
+ let _mut_indirect_ref = &mut mut_fn_item;
+
+ let cast_zst_ptr = &foo as *const _;
+ let coerced_zst_ptr: *const _ = &foo;
+
+ let _mut_cast_zst_ptr = &mut foo as *mut _;
+ let _mut_coerced_zst_ptr: *mut _ = &mut foo;
+
+ let _cast_zst_ref = &foo as &dyn Fn() -> u32;
+ let _coerced_zst_ref: &dyn Fn() -> u32 = &foo;
+
+ let _mut_cast_zst_ref = &mut foo as &mut dyn Fn() -> u32;
+ let _mut_coerced_zst_ref: &mut dyn Fn() -> u32 = &mut foo;
+
+ //the suggested way to cast to a function pointer
+ let fn_ptr = foo as fn() -> u32;
+
+ //correct ways to print function pointers
+ println!("{:p}", foo as fn() -> u32);
+ println!("{:p}", fn_ptr);
+
+ //potential ways to incorrectly try printing function pointers
+ println!("{:p}", &foo);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ print!("{:p}", &foo);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ format!("{:p}", &foo);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+
+ println!("{:p}", &foo as *const _);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ println!("{:p}", zst_ref);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ println!("{:p}", cast_zst_ptr);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ println!("{:p}", coerced_zst_ptr);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+
+ println!("{:p}", &fn_item);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ println!("{:p}", indirect_ref);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+
+ println!("{:p}", &nop);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ println!("{:p}", &bar);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ println!("{:p}", &baz);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ println!("{:p}", &unsafe_fn);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ println!("{:p}", &c_fn);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ println!("{:p}", &unsafe_c_fn);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ println!("{:p}", &variadic);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ println!("{:p}", &take_generic_ref::<u32>);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ println!("{:p}", &take_generic_array::<u32, 4>);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ println!("{:p}", &multiple_generic::<u32, f32>);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ println!("{:p}", &multiple_generic_arrays::<u32, f32, 4, 8>);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ println!("{:p}", &std::env::var::<String>);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+
+ println!("{:p} {:p} {:p}", &nop, &foo, &bar);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ //~^^ WARNING taking a reference to a function item does not give a function pointer
+ //~^^^ WARNING taking a reference to a function item does not give a function pointer
+
+ //using a function reference to call a function shouldn't lint
+ (&bar)(1);
+
+ //passing a function reference to an arbitrary function shouldn't lint
+ call_fn(&bar, 1);
+ parameterized_call_fn(&bar, 1);
+ std::mem::size_of_val(&foo);
+
+ unsafe {
+ //potential ways to incorrectly try transmuting function pointers
+ std::mem::transmute::<_, usize>(&foo);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ std::mem::transmute::<_, (usize, usize)>((&foo, &bar));
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ //~^^ WARNING taking a reference to a function item does not give a function pointer
+ std::mem::transmute::<_, usize>(&take_generic_ref::<u32>);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+
+ //the correct way to transmute function pointers
+ std::mem::transmute::<_, usize>(foo as fn() -> u32);
+ std::mem::transmute::<_, (usize, usize)>((foo as fn() -> u32, bar as fn(u32) -> u32));
+ }
+
+ //function references as arguments required to be bound by std::fmt::Pointer should lint
+ print_ptr(&bar);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ bound_by_ptr_trait(&bar);
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ bound_by_ptr_trait_tuple((&foo, &bar));
+ //~^ WARNING taking a reference to a function item does not give a function pointer
+ //~^^ WARNING taking a reference to a function item does not give a function pointer
+ implicit_ptr_trait(&bar); // ignore
+
+ //correct ways to pass function pointers as arguments bound by std::fmt::Pointer
+ print_ptr(bar as fn(u32) -> u32);
+ bound_by_ptr_trait(bar as fn(u32) -> u32);
+ bound_by_ptr_trait_tuple((foo as fn() -> u32, bar as fn(u32) -> u32));
+}
diff --git a/tests/ui/lint/function-item-references.stderr b/tests/ui/lint/function-item-references.stderr
new file mode 100644
index 000000000..a9d18bb6a
--- /dev/null
+++ b/tests/ui/lint/function-item-references.stderr
@@ -0,0 +1,206 @@
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:44:18
+ |
+LL | Pointer::fmt(&zst_ref, f)
+ | ^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _`
+ |
+note: the lint level is defined here
+ --> $DIR/function-item-references.rs:3:9
+ |
+LL | #![warn(function_item_references)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:81:22
+ |
+LL | println!("{:p}", &foo);
+ | ^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:83:20
+ |
+LL | print!("{:p}", &foo);
+ | ^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:85:21
+ |
+LL | format!("{:p}", &foo);
+ | ^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:88:22
+ |
+LL | println!("{:p}", &foo as *const _);
+ | ^^^^^^^^^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:90:22
+ |
+LL | println!("{:p}", zst_ref);
+ | ^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:92:22
+ |
+LL | println!("{:p}", cast_zst_ptr);
+ | ^^^^^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:94:22
+ |
+LL | println!("{:p}", coerced_zst_ptr);
+ | ^^^^^^^^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:97:22
+ |
+LL | println!("{:p}", &fn_item);
+ | ^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:99:22
+ |
+LL | println!("{:p}", indirect_ref);
+ | ^^^^^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:102:22
+ |
+LL | println!("{:p}", &nop);
+ | ^^^^ help: cast `nop` to obtain a function pointer: `nop as fn()`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:104:22
+ |
+LL | println!("{:p}", &bar);
+ | ^^^^ help: cast `bar` to obtain a function pointer: `bar as fn(_) -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:106:22
+ |
+LL | println!("{:p}", &baz);
+ | ^^^^ help: cast `baz` to obtain a function pointer: `baz as fn(_, _) -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:108:22
+ |
+LL | println!("{:p}", &unsafe_fn);
+ | ^^^^^^^^^^ help: cast `unsafe_fn` to obtain a function pointer: `unsafe_fn as unsafe fn()`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:110:22
+ |
+LL | println!("{:p}", &c_fn);
+ | ^^^^^ help: cast `c_fn` to obtain a function pointer: `c_fn as extern "C" fn()`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:112:22
+ |
+LL | println!("{:p}", &unsafe_c_fn);
+ | ^^^^^^^^^^^^ help: cast `unsafe_c_fn` to obtain a function pointer: `unsafe_c_fn as unsafe extern "C" fn()`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:114:22
+ |
+LL | println!("{:p}", &variadic);
+ | ^^^^^^^^^ help: cast `variadic` to obtain a function pointer: `variadic as unsafe extern "C" fn(_, ...)`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:116:22
+ |
+LL | println!("{:p}", &take_generic_ref::<u32>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `take_generic_ref` to obtain a function pointer: `take_generic_ref::<u32> as fn(_)`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:118:22
+ |
+LL | println!("{:p}", &take_generic_array::<u32, 4>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `take_generic_array` to obtain a function pointer: `take_generic_array::<u32, 4> as fn(_)`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:120:22
+ |
+LL | println!("{:p}", &multiple_generic::<u32, f32>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `multiple_generic` to obtain a function pointer: `multiple_generic::<u32, f32> as fn(_, _)`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:122:22
+ |
+LL | println!("{:p}", &multiple_generic_arrays::<u32, f32, 4, 8>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `multiple_generic_arrays` to obtain a function pointer: `multiple_generic_arrays::<u32, f32, 4, 8> as fn(_, _)`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:124:22
+ |
+LL | println!("{:p}", &std::env::var::<String>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `var` to obtain a function pointer: `var::<String> as fn(_) -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:127:32
+ |
+LL | println!("{:p} {:p} {:p}", &nop, &foo, &bar);
+ | ^^^^ help: cast `nop` to obtain a function pointer: `nop as fn()`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:127:38
+ |
+LL | println!("{:p} {:p} {:p}", &nop, &foo, &bar);
+ | ^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:127:44
+ |
+LL | println!("{:p} {:p} {:p}", &nop, &foo, &bar);
+ | ^^^^ help: cast `bar` to obtain a function pointer: `bar as fn(_) -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:142:41
+ |
+LL | std::mem::transmute::<_, usize>(&foo);
+ | ^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:144:50
+ |
+LL | std::mem::transmute::<_, (usize, usize)>((&foo, &bar));
+ | ^^^^^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:144:50
+ |
+LL | std::mem::transmute::<_, (usize, usize)>((&foo, &bar));
+ | ^^^^^^^^^^^^ help: cast `bar` to obtain a function pointer: `bar as fn(_) -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:147:41
+ |
+LL | std::mem::transmute::<_, usize>(&take_generic_ref::<u32>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `take_generic_ref` to obtain a function pointer: `take_generic_ref::<u32> as fn(_)`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:156:15
+ |
+LL | print_ptr(&bar);
+ | ^^^^ help: cast `bar` to obtain a function pointer: `bar as fn(_) -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:158:24
+ |
+LL | bound_by_ptr_trait(&bar);
+ | ^^^^ help: cast `bar` to obtain a function pointer: `bar as fn(_) -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:160:30
+ |
+LL | bound_by_ptr_trait_tuple((&foo, &bar));
+ | ^^^^^^^^^^^^ help: cast `bar` to obtain a function pointer: `bar as fn(_) -> _`
+
+warning: taking a reference to a function item does not give a function pointer
+ --> $DIR/function-item-references.rs:160:30
+ |
+LL | bound_by_ptr_trait_tuple((&foo, &bar));
+ | ^^^^^^^^^^^^ help: cast `foo` to obtain a function pointer: `foo as fn() -> _`
+
+warning: 33 warnings emitted
+
diff --git a/tests/ui/lint/future-incompat-test.rs b/tests/ui/lint/future-incompat-test.rs
new file mode 100644
index 000000000..c5f477cc4
--- /dev/null
+++ b/tests/ui/lint/future-incompat-test.rs
@@ -0,0 +1,10 @@
+// compile-flags: -Zfuture-incompat-test
+// check-pass
+
+// The `-Zfuture-incompat-test flag causes any normal warning to be included
+// in the future-incompatible report. The stderr output here should mention
+// the future incompatible report (as extracted by compiletest).
+
+fn main() {
+ let x = 1;
+}
diff --git a/tests/ui/lint/future-incompat-test.stderr b/tests/ui/lint/future-incompat-test.stderr
new file mode 100644
index 000000000..52674a843
--- /dev/null
+++ b/tests/ui/lint/future-incompat-test.stderr
@@ -0,0 +1,9 @@
+Future incompatibility report: Future breakage diagnostic:
+warning: unused variable: `x`
+ --> $DIR/future-incompat-test.rs:9:9
+ |
+LL | let x = 1;
+ | ^ help: if this is intentional, prefix it with an underscore: `_x`
+ |
+ = note: `-A unused-variables` implied by `-A unused`
+
diff --git a/tests/ui/lint/inclusive-range-pattern-syntax.fixed b/tests/ui/lint/inclusive-range-pattern-syntax.fixed
new file mode 100644
index 000000000..bee5d4ae4
--- /dev/null
+++ b/tests/ui/lint/inclusive-range-pattern-syntax.fixed
@@ -0,0 +1,21 @@
+// check-pass
+// run-rustfix
+
+#![warn(ellipsis_inclusive_range_patterns)]
+
+fn main() {
+ let despondency = 2;
+ match despondency {
+ 1..=2 => {}
+ //~^ WARN `...` range patterns are deprecated
+ //~| WARN this is accepted in the current edition
+ _ => {}
+ }
+
+ match &despondency {
+ &(1..=2) => {}
+ //~^ WARN `...` range patterns are deprecated
+ //~| WARN this is accepted in the current edition
+ _ => {}
+ }
+}
diff --git a/tests/ui/lint/inclusive-range-pattern-syntax.rs b/tests/ui/lint/inclusive-range-pattern-syntax.rs
new file mode 100644
index 000000000..d98c10c26
--- /dev/null
+++ b/tests/ui/lint/inclusive-range-pattern-syntax.rs
@@ -0,0 +1,21 @@
+// check-pass
+// run-rustfix
+
+#![warn(ellipsis_inclusive_range_patterns)]
+
+fn main() {
+ let despondency = 2;
+ match despondency {
+ 1...2 => {}
+ //~^ WARN `...` range patterns are deprecated
+ //~| WARN this is accepted in the current edition
+ _ => {}
+ }
+
+ match &despondency {
+ &1...2 => {}
+ //~^ WARN `...` range patterns are deprecated
+ //~| WARN this is accepted in the current edition
+ _ => {}
+ }
+}
diff --git a/tests/ui/lint/inclusive-range-pattern-syntax.stderr b/tests/ui/lint/inclusive-range-pattern-syntax.stderr
new file mode 100644
index 000000000..ed9fa0d41
--- /dev/null
+++ b/tests/ui/lint/inclusive-range-pattern-syntax.stderr
@@ -0,0 +1,25 @@
+warning: `...` range patterns are deprecated
+ --> $DIR/inclusive-range-pattern-syntax.rs:9:10
+ |
+LL | 1...2 => {}
+ | ^^^ help: use `..=` for an inclusive range
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+note: the lint level is defined here
+ --> $DIR/inclusive-range-pattern-syntax.rs:4:9
+ |
+LL | #![warn(ellipsis_inclusive_range_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: `...` range patterns are deprecated
+ --> $DIR/inclusive-range-pattern-syntax.rs:16:9
+ |
+LL | &1...2 => {}
+ | ^^^^^^ help: use `..=` for an inclusive range: `&(1..=2)`
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/lint/inert-attr-macro.rs b/tests/ui/lint/inert-attr-macro.rs
new file mode 100644
index 000000000..dc0bb8ac2
--- /dev/null
+++ b/tests/ui/lint/inert-attr-macro.rs
@@ -0,0 +1,20 @@
+// check-pass
+
+#![warn(unused)]
+
+macro_rules! foo {
+ () => {}
+}
+
+fn main() {
+ #[inline] foo!(); //~ WARN unused attribute `inline`
+
+ // This does nothing, since `#[allow(warnings)]` is itself
+ // an inert attribute on a macro call
+ #[allow(warnings)] #[inline] foo!(); //~ WARN unused attribute `allow`
+ //~^ WARN unused attribute `inline`
+
+ // This does work, since the attribute is on a parent
+ // of the macro invocation.
+ #[allow(warnings)] { #[inline] foo!(); }
+}
diff --git a/tests/ui/lint/inert-attr-macro.stderr b/tests/ui/lint/inert-attr-macro.stderr
new file mode 100644
index 000000000..5ccb4ffe7
--- /dev/null
+++ b/tests/ui/lint/inert-attr-macro.stderr
@@ -0,0 +1,44 @@
+warning: unused attribute `inline`
+ --> $DIR/inert-attr-macro.rs:10:5
+ |
+LL | #[inline] foo!();
+ | ^^^^^^^^^
+ |
+note: the built-in attribute `inline` will be ignored, since it's applied to the macro invocation `foo`
+ --> $DIR/inert-attr-macro.rs:10:15
+ |
+LL | #[inline] foo!();
+ | ^^^
+note: the lint level is defined here
+ --> $DIR/inert-attr-macro.rs:3:9
+ |
+LL | #![warn(unused)]
+ | ^^^^^^
+ = note: `#[warn(unused_attributes)]` implied by `#[warn(unused)]`
+
+warning: unused attribute `allow`
+ --> $DIR/inert-attr-macro.rs:14:5
+ |
+LL | #[allow(warnings)] #[inline] foo!();
+ | ^^^^^^^^^^^^^^^^^^
+ |
+note: the built-in attribute `allow` will be ignored, since it's applied to the macro invocation `foo`
+ --> $DIR/inert-attr-macro.rs:14:34
+ |
+LL | #[allow(warnings)] #[inline] foo!();
+ | ^^^
+
+warning: unused attribute `inline`
+ --> $DIR/inert-attr-macro.rs:14:24
+ |
+LL | #[allow(warnings)] #[inline] foo!();
+ | ^^^^^^^^^
+ |
+note: the built-in attribute `inline` will be ignored, since it's applied to the macro invocation `foo`
+ --> $DIR/inert-attr-macro.rs:14:34
+ |
+LL | #[allow(warnings)] #[inline] foo!();
+ | ^^^
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/lint/inline-trait-and-foreign-items.rs b/tests/ui/lint/inline-trait-and-foreign-items.rs
new file mode 100644
index 000000000..13dab7ed9
--- /dev/null
+++ b/tests/ui/lint/inline-trait-and-foreign-items.rs
@@ -0,0 +1,37 @@
+#![feature(extern_types)]
+#![feature(type_alias_impl_trait)]
+
+#![warn(unused_attributes)]
+
+trait Trait {
+ #[inline] //~ WARN `#[inline]` is ignored on constants
+ //~^ WARN this was previously accepted
+ const X: u32;
+
+ #[inline] //~ ERROR attribute should be applied to function or closure
+ type T;
+
+ type U;
+}
+
+impl Trait for () {
+ #[inline] //~ WARN `#[inline]` is ignored on constants
+ //~^ WARN this was previously accepted
+ const X: u32 = 0;
+
+ #[inline] //~ ERROR attribute should be applied to function or closure
+ type T = Self;
+
+ #[inline] //~ ERROR attribute should be applied to function or closure
+ type U = impl Trait; //~ ERROR unconstrained opaque type
+}
+
+extern "C" {
+ #[inline] //~ ERROR attribute should be applied to function or closure
+ static X: u32;
+
+ #[inline] //~ ERROR attribute should be applied to function or closure
+ type T;
+}
+
+fn main() {}
diff --git a/tests/ui/lint/inline-trait-and-foreign-items.stderr b/tests/ui/lint/inline-trait-and-foreign-items.stderr
new file mode 100644
index 000000000..2f1fb4c46
--- /dev/null
+++ b/tests/ui/lint/inline-trait-and-foreign-items.stderr
@@ -0,0 +1,74 @@
+warning: `#[inline]` is ignored on constants
+ --> $DIR/inline-trait-and-foreign-items.rs:7:5
+ |
+LL | #[inline]
+ | ^^^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: see issue #65833 <https://github.com/rust-lang/rust/issues/65833> for more information
+note: the lint level is defined here
+ --> $DIR/inline-trait-and-foreign-items.rs:4:9
+ |
+LL | #![warn(unused_attributes)]
+ | ^^^^^^^^^^^^^^^^^
+
+error[E0518]: attribute should be applied to function or closure
+ --> $DIR/inline-trait-and-foreign-items.rs:11:5
+ |
+LL | #[inline]
+ | ^^^^^^^^^
+LL | type T;
+ | ------- not a function or closure
+
+warning: `#[inline]` is ignored on constants
+ --> $DIR/inline-trait-and-foreign-items.rs:18:5
+ |
+LL | #[inline]
+ | ^^^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: see issue #65833 <https://github.com/rust-lang/rust/issues/65833> for more information
+
+error[E0518]: attribute should be applied to function or closure
+ --> $DIR/inline-trait-and-foreign-items.rs:22:5
+ |
+LL | #[inline]
+ | ^^^^^^^^^
+LL | type T = Self;
+ | -------------- not a function or closure
+
+error[E0518]: attribute should be applied to function or closure
+ --> $DIR/inline-trait-and-foreign-items.rs:25:5
+ |
+LL | #[inline]
+ | ^^^^^^^^^
+LL | type U = impl Trait;
+ | -------------------- not a function or closure
+
+error[E0518]: attribute should be applied to function or closure
+ --> $DIR/inline-trait-and-foreign-items.rs:30:5
+ |
+LL | #[inline]
+ | ^^^^^^^^^
+LL | static X: u32;
+ | -------------- not a function or closure
+
+error[E0518]: attribute should be applied to function or closure
+ --> $DIR/inline-trait-and-foreign-items.rs:33:5
+ |
+LL | #[inline]
+ | ^^^^^^^^^
+LL | type T;
+ | ------- not a function or closure
+
+error: unconstrained opaque type
+ --> $DIR/inline-trait-and-foreign-items.rs:26:14
+ |
+LL | type U = impl Trait;
+ | ^^^^^^^^^^
+ |
+ = note: `U` must be used in combination with a concrete type within the same impl
+
+error: aborting due to 6 previous errors; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0518`.
diff --git a/tests/ui/lint/invalid_value.rs b/tests/ui/lint/invalid_value.rs
new file mode 100644
index 000000000..57d8cbe7c
--- /dev/null
+++ b/tests/ui/lint/invalid_value.rs
@@ -0,0 +1,169 @@
+// This test checks that calling `mem::{uninitialized,zeroed}` with certain types results
+// in a lint.
+
+#![feature(never_type, rustc_attrs)]
+#![allow(deprecated)]
+#![deny(invalid_value)]
+
+use std::mem::{self, MaybeUninit};
+use std::ptr::NonNull;
+use std::num::NonZeroU32;
+
+enum Void {}
+
+struct Ref(&'static i32);
+struct RefPair((&'static i32, i32));
+
+struct Wrap<T> { wrapped: T }
+enum WrapEnum<T> { Wrapped(T) }
+
+#[rustc_layout_scalar_valid_range_start(0)]
+#[rustc_layout_scalar_valid_range_end(128)]
+#[repr(transparent)]
+pub(crate) struct NonBig(u64);
+
+/// A two-variant enum, thus needs a tag and may not remain uninitialized.
+enum Fruit {
+ Apple,
+ Banana,
+}
+
+/// Looks like two variants but really only has one.
+enum OneFruit {
+ Apple(!),
+ Banana,
+}
+
+enum OneFruitNonZero {
+ Apple(!),
+ Banana(NonZeroU32),
+}
+
+enum TwoUninhabited {
+ A(!),
+ B(Void),
+}
+
+#[rustc_layout_scalar_valid_range_start(254)]
+#[rustc_layout_scalar_valid_range_end(1)]
+pub(crate) struct WrapAroundRange(u8);
+
+#[allow(unused)]
+fn generic<T: 'static>() {
+ unsafe {
+ let _val: &'static T = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: &'static T = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: Wrap<&'static T> = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: Wrap<&'static T> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+ }
+}
+
+fn main() {
+ unsafe {
+ // Things that cannot even be zero.
+ let _val: ! = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: ! = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: (i32, !) = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: (i32, !) = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: Void = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: Void = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: &'static i32 = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: &'static i32 = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: Ref = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: Ref = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: fn() = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: fn() = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: Wrap<fn()> = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: Wrap<fn()> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: WrapEnum<fn()> = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: WrapEnum<fn()> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: Wrap<(RefPair, i32)> = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: NonNull<i32> = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: NonNull<i32> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: (NonZeroU32, i32) = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: (NonZeroU32, i32) = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: *const dyn Send = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: *const dyn Send = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: [fn(); 2] = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: [fn(); 2] = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: TwoUninhabited = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: TwoUninhabited = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: OneFruitNonZero = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: OneFruitNonZero = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ // Things that can be zero, but not uninit.
+ let _val: bool = mem::zeroed();
+ let _val: bool = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: Wrap<char> = mem::zeroed();
+ let _val: Wrap<char> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: NonBig = mem::zeroed();
+ let _val: NonBig = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: Fruit = mem::zeroed();
+ let _val: Fruit = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: [bool; 2] = mem::zeroed();
+ let _val: [bool; 2] = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: i32 = mem::zeroed();
+ let _val: i32 = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: f32 = mem::zeroed();
+ let _val: f32 = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: *const () = mem::zeroed();
+ let _val: *const () = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: *const [()] = mem::zeroed();
+ let _val: *const [()] = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: WrapAroundRange = mem::zeroed();
+ let _val: WrapAroundRange = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ // Things where 0 is okay due to rustc implementation details,
+ // but that are not guaranteed to keep working.
+ let _val: Result<i32, i32> = mem::zeroed();
+ let _val: Result<i32, i32> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ // Some things that happen to be UB-free due to rustc implementation details,
+ // but are not guaranteed to keep working.
+ let _val: OneFruit = mem::zeroed();
+ let _val: OneFruit = mem::uninitialized();
+
+ // Transmute-from-0
+ let _val: &'static i32 = mem::transmute(0usize); //~ ERROR: does not permit zero-initialization
+ let _val: &'static [i32] = mem::transmute((0usize, 0usize)); //~ ERROR: does not permit zero-initialization
+ let _val: NonZeroU32 = mem::transmute(0); //~ ERROR: does not permit zero-initialization
+
+ // `MaybeUninit` cases
+ let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init(); //~ ERROR: does not permit zero-initialization
+ let _val: NonNull<i32> = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized
+ let _val: bool = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized
+
+ // Some more types that should work just fine.
+ let _val: Option<&'static i32> = mem::zeroed();
+ let _val: Option<fn()> = mem::zeroed();
+ let _val: MaybeUninit<&'static i32> = mem::zeroed();
+ let _val: bool = MaybeUninit::zeroed().assume_init();
+ let _val: [bool; 0] = MaybeUninit::uninit().assume_init();
+ let _val: [!; 0] = MaybeUninit::zeroed().assume_init();
+ }
+}
diff --git a/tests/ui/lint/invalid_value.stderr b/tests/ui/lint/invalid_value.stderr
new file mode 100644
index 000000000..48fd4169d
--- /dev/null
+++ b/tests/ui/lint/invalid_value.stderr
@@ -0,0 +1,676 @@
+error: the type `&T` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:54:32
+ |
+LL | let _val: &'static T = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: references must be non-null
+note: the lint level is defined here
+ --> $DIR/invalid_value.rs:6:9
+ |
+LL | #![deny(invalid_value)]
+ | ^^^^^^^^^^^^^
+
+error: the type `&T` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:55:32
+ |
+LL | let _val: &'static T = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: references must be non-null
+
+error: the type `Wrap<&T>` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:57:38
+ |
+LL | let _val: Wrap<&'static T> = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `Wrap<&T>` must be non-null
+note: because references must be non-null (in this struct field)
+ --> $DIR/invalid_value.rs:17:18
+ |
+LL | struct Wrap<T> { wrapped: T }
+ | ^^^^^^^^^^
+
+error: the type `Wrap<&T>` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:58:38
+ |
+LL | let _val: Wrap<&'static T> = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `Wrap<&T>` must be non-null
+note: because references must be non-null (in this struct field)
+ --> $DIR/invalid_value.rs:17:18
+ |
+LL | struct Wrap<T> { wrapped: T }
+ | ^^^^^^^^^^
+
+error: the type `!` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:65:23
+ |
+LL | let _val: ! = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: the `!` type has no valid value
+
+error: the type `!` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:66:23
+ |
+LL | let _val: ! = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: the `!` type has no valid value
+
+error: the type `(i32, !)` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:68:30
+ |
+LL | let _val: (i32, !) = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: the `!` type has no valid value
+
+error: the type `(i32, !)` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:69:30
+ |
+LL | let _val: (i32, !) = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: integers must be initialized
+
+error: the type `Void` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:71:26
+ |
+LL | let _val: Void = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+note: enums with no inhabited variants have no valid value
+ --> $DIR/invalid_value.rs:12:1
+ |
+LL | enum Void {}
+ | ^^^^^^^^^
+
+error: the type `Void` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:72:26
+ |
+LL | let _val: Void = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+note: enums with no inhabited variants have no valid value
+ --> $DIR/invalid_value.rs:12:1
+ |
+LL | enum Void {}
+ | ^^^^^^^^^
+
+error: the type `&i32` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:74:34
+ |
+LL | let _val: &'static i32 = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: references must be non-null
+
+error: the type `&i32` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:75:34
+ |
+LL | let _val: &'static i32 = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: references must be non-null
+
+error: the type `Ref` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:77:25
+ |
+LL | let _val: Ref = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `Ref` must be non-null
+note: because references must be non-null (in this struct field)
+ --> $DIR/invalid_value.rs:14:12
+ |
+LL | struct Ref(&'static i32);
+ | ^^^^^^^^^^^^
+
+error: the type `Ref` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:78:25
+ |
+LL | let _val: Ref = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `Ref` must be non-null
+note: because references must be non-null (in this struct field)
+ --> $DIR/invalid_value.rs:14:12
+ |
+LL | struct Ref(&'static i32);
+ | ^^^^^^^^^^^^
+
+error: the type `fn()` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:80:26
+ |
+LL | let _val: fn() = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: function pointers must be non-null
+
+error: the type `fn()` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:81:26
+ |
+LL | let _val: fn() = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: function pointers must be non-null
+
+error: the type `Wrap<fn()>` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:83:32
+ |
+LL | let _val: Wrap<fn()> = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `Wrap<fn()>` must be non-null
+note: because function pointers must be non-null (in this struct field)
+ --> $DIR/invalid_value.rs:17:18
+ |
+LL | struct Wrap<T> { wrapped: T }
+ | ^^^^^^^^^^
+
+error: the type `Wrap<fn()>` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:84:32
+ |
+LL | let _val: Wrap<fn()> = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `Wrap<fn()>` must be non-null
+note: because function pointers must be non-null (in this struct field)
+ --> $DIR/invalid_value.rs:17:18
+ |
+LL | struct Wrap<T> { wrapped: T }
+ | ^^^^^^^^^^
+
+error: the type `WrapEnum<fn()>` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:86:36
+ |
+LL | let _val: WrapEnum<fn()> = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `WrapEnum<fn()>` must be non-null
+note: because function pointers must be non-null (in this field of the only potentially inhabited enum variant)
+ --> $DIR/invalid_value.rs:18:28
+ |
+LL | enum WrapEnum<T> { Wrapped(T) }
+ | ^
+
+error: the type `WrapEnum<fn()>` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:87:36
+ |
+LL | let _val: WrapEnum<fn()> = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `WrapEnum<fn()>` must be non-null
+note: because function pointers must be non-null (in this field of the only potentially inhabited enum variant)
+ --> $DIR/invalid_value.rs:18:28
+ |
+LL | enum WrapEnum<T> { Wrapped(T) }
+ | ^
+
+error: the type `Wrap<(RefPair, i32)>` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:89:42
+ |
+LL | let _val: Wrap<(RefPair, i32)> = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+note: `RefPair` must be non-null (in this struct field)
+ --> $DIR/invalid_value.rs:17:18
+ |
+LL | struct Wrap<T> { wrapped: T }
+ | ^^^^^^^^^^
+note: because references must be non-null (in this struct field)
+ --> $DIR/invalid_value.rs:15:16
+ |
+LL | struct RefPair((&'static i32, i32));
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: the type `Wrap<(RefPair, i32)>` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:90:42
+ |
+LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+note: `RefPair` must be non-null (in this struct field)
+ --> $DIR/invalid_value.rs:17:18
+ |
+LL | struct Wrap<T> { wrapped: T }
+ | ^^^^^^^^^^
+note: because references must be non-null (in this struct field)
+ --> $DIR/invalid_value.rs:15:16
+ |
+LL | struct RefPair((&'static i32, i32));
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: the type `NonNull<i32>` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:92:34
+ |
+LL | let _val: NonNull<i32> = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `std::ptr::NonNull<i32>` must be non-null
+
+error: the type `NonNull<i32>` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:93:34
+ |
+LL | let _val: NonNull<i32> = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `std::ptr::NonNull<i32>` must be non-null
+ = note: raw pointers must be initialized
+
+error: the type `(NonZeroU32, i32)` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:95:39
+ |
+LL | let _val: (NonZeroU32, i32) = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `std::num::NonZeroU32` must be non-null
+
+error: the type `(NonZeroU32, i32)` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:96:39
+ |
+LL | let _val: (NonZeroU32, i32) = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `std::num::NonZeroU32` must be non-null
+ = note: integers must be initialized
+
+error: the type `*const dyn Send` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:98:37
+ |
+LL | let _val: *const dyn Send = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: the vtable of a wide raw pointer must be non-null
+
+error: the type `*const dyn Send` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:99:37
+ |
+LL | let _val: *const dyn Send = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: the vtable of a wide raw pointer must be non-null
+
+error: the type `[fn(); 2]` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:101:31
+ |
+LL | let _val: [fn(); 2] = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: function pointers must be non-null
+
+error: the type `[fn(); 2]` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:102:31
+ |
+LL | let _val: [fn(); 2] = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: function pointers must be non-null
+
+error: the type `TwoUninhabited` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:104:36
+ |
+LL | let _val: TwoUninhabited = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+note: enums with no inhabited variants have no valid value
+ --> $DIR/invalid_value.rs:42:1
+ |
+LL | enum TwoUninhabited {
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: the type `TwoUninhabited` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:105:36
+ |
+LL | let _val: TwoUninhabited = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+note: enums with no inhabited variants have no valid value
+ --> $DIR/invalid_value.rs:42:1
+ |
+LL | enum TwoUninhabited {
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: the type `OneFruitNonZero` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:107:37
+ |
+LL | let _val: OneFruitNonZero = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `OneFruitNonZero` must be non-null
+note: because `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant)
+ --> $DIR/invalid_value.rs:39:12
+ |
+LL | Banana(NonZeroU32),
+ | ^^^^^^^^^^
+
+error: the type `OneFruitNonZero` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:108:37
+ |
+LL | let _val: OneFruitNonZero = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `OneFruitNonZero` must be non-null
+note: because `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant)
+ --> $DIR/invalid_value.rs:39:12
+ |
+LL | Banana(NonZeroU32),
+ | ^^^^^^^^^^
+ = note: integers must be initialized
+
+error: the type `bool` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:112:26
+ |
+LL | let _val: bool = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: booleans must be either `true` or `false`
+
+error: the type `Wrap<char>` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:115:32
+ |
+LL | let _val: Wrap<char> = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `Wrap<char>` must be initialized inside its custom valid range
+note: characters must be a valid Unicode codepoint (in this struct field)
+ --> $DIR/invalid_value.rs:17:18
+ |
+LL | struct Wrap<T> { wrapped: T }
+ | ^^^^^^^^^^
+
+error: the type `NonBig` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:118:28
+ |
+LL | let _val: NonBig = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `NonBig` must be initialized inside its custom valid range
+note: integers must be initialized (in this struct field)
+ --> $DIR/invalid_value.rs:23:26
+ |
+LL | pub(crate) struct NonBig(u64);
+ | ^^^
+
+error: the type `Fruit` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:121:27
+ |
+LL | let _val: Fruit = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+note: enums with multiple inhabited variants have to be initialized to a variant
+ --> $DIR/invalid_value.rs:26:1
+ |
+LL | enum Fruit {
+ | ^^^^^^^^^^
+
+error: the type `[bool; 2]` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:124:31
+ |
+LL | let _val: [bool; 2] = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: booleans must be either `true` or `false`
+
+error: the type `i32` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:127:25
+ |
+LL | let _val: i32 = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: integers must be initialized
+
+error: the type `f32` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:130:25
+ |
+LL | let _val: f32 = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: floats must be initialized
+
+error: the type `*const ()` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:133:31
+ |
+LL | let _val: *const () = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: raw pointers must be initialized
+
+error: the type `*const [()]` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:136:33
+ |
+LL | let _val: *const [()] = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: raw pointers must be initialized
+
+error: the type `WrapAroundRange` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:139:37
+ |
+LL | let _val: WrapAroundRange = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `WrapAroundRange` must be initialized inside its custom valid range
+note: integers must be initialized (in this struct field)
+ --> $DIR/invalid_value.rs:49:35
+ |
+LL | pub(crate) struct WrapAroundRange(u8);
+ | ^^
+
+error: the type `Result<i32, i32>` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:144:38
+ |
+LL | let _val: Result<i32, i32> = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+note: enums with multiple inhabited variants have to be initialized to a variant
+ --> $SRC_DIR/core/src/result.rs:LL:COL
+
+error: the type `&i32` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:152:34
+ |
+LL | let _val: &'static i32 = mem::transmute(0usize);
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: references must be non-null
+
+error: the type `&[i32]` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:153:36
+ |
+LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: references must be non-null
+
+error: the type `NonZeroU32` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:154:32
+ |
+LL | let _val: NonZeroU32 = mem::transmute(0);
+ | ^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `std::num::NonZeroU32` must be non-null
+
+error: the type `NonNull<i32>` does not permit zero-initialization
+ --> $DIR/invalid_value.rs:157:34
+ |
+LL | let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `std::ptr::NonNull<i32>` must be non-null
+
+error: the type `NonNull<i32>` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:158:34
+ |
+LL | let _val: NonNull<i32> = MaybeUninit::uninit().assume_init();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `std::ptr::NonNull<i32>` must be non-null
+ = note: raw pointers must be initialized
+
+error: the type `bool` does not permit being left uninitialized
+ --> $DIR/invalid_value.rs:159:26
+ |
+LL | let _val: bool = MaybeUninit::uninit().assume_init();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: booleans must be either `true` or `false`
+
+error: aborting due to 51 previous errors
+
diff --git a/tests/ui/lint/issue-101284.rs b/tests/ui/lint/issue-101284.rs
new file mode 100644
index 000000000..1381d4f17
--- /dev/null
+++ b/tests/ui/lint/issue-101284.rs
@@ -0,0 +1,15 @@
+// check-pass
+// edition:2021
+#![deny(rust_2021_compatibility)]
+
+pub struct Warns {
+ // `Arc` has significant drop
+ _significant_drop: std::sync::Arc<()>,
+ field: String,
+}
+
+pub fn test(w: Warns) {
+ _ = || drop(w.field);
+}
+
+fn main() {}
diff --git a/tests/ui/lint/issue-102705.rs b/tests/ui/lint/issue-102705.rs
new file mode 100644
index 000000000..5bcc8950a
--- /dev/null
+++ b/tests/ui/lint/issue-102705.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+#![allow(opaque_hidden_inferred_bound)]
+#![allow(dead_code)]
+
+trait Duh {}
+
+impl Duh for i32 {}
+
+trait Trait {
+ type Assoc: Duh;
+}
+
+impl<R: Duh, F: FnMut() -> R> Trait for F {
+ type Assoc = R;
+}
+
+fn foo() -> impl Trait<Assoc = impl Send> {
+ || 42
+}
+
+fn main() {}
diff --git a/tests/ui/lint/issue-103317.fixed b/tests/ui/lint/issue-103317.fixed
new file mode 100644
index 000000000..5a987423e
--- /dev/null
+++ b/tests/ui/lint/issue-103317.fixed
@@ -0,0 +1,14 @@
+// check-pass
+// run-rustfix
+
+#[warn(unreachable_pub)]
+mod inner {
+ #[allow(unused)]
+ pub(crate) enum T {
+ //~^ WARN unreachable `pub` item
+ A(u8),
+ X { a: f32, b: () },
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/issue-103317.rs b/tests/ui/lint/issue-103317.rs
new file mode 100644
index 000000000..c2ba939e1
--- /dev/null
+++ b/tests/ui/lint/issue-103317.rs
@@ -0,0 +1,14 @@
+// check-pass
+// run-rustfix
+
+#[warn(unreachable_pub)]
+mod inner {
+ #[allow(unused)]
+ pub enum T {
+ //~^ WARN unreachable `pub` item
+ A(u8),
+ X { a: f32, b: () },
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/issue-103317.stderr b/tests/ui/lint/issue-103317.stderr
new file mode 100644
index 000000000..9c982ddc3
--- /dev/null
+++ b/tests/ui/lint/issue-103317.stderr
@@ -0,0 +1,17 @@
+warning: unreachable `pub` item
+ --> $DIR/issue-103317.rs:7:5
+ |
+LL | pub enum T {
+ | ---^^^^^^^
+ | |
+ | help: consider restricting its visibility: `pub(crate)`
+ |
+ = help: or consider exporting it for use by other crates
+note: the lint level is defined here
+ --> $DIR/issue-103317.rs:4:8
+ |
+LL | #[warn(unreachable_pub)]
+ | ^^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/issue-103435-extra-parentheses.fixed b/tests/ui/lint/issue-103435-extra-parentheses.fixed
new file mode 100644
index 000000000..2b01b414b
--- /dev/null
+++ b/tests/ui/lint/issue-103435-extra-parentheses.fixed
@@ -0,0 +1,18 @@
+// run-rustfix
+#![deny(unused_parens)]
+
+fn main() {
+ if let Some(_) = Some(1) {}
+ //~^ ERROR unnecessary parentheses around pattern
+
+ for _x in 1..10 {}
+ //~^ ERROR unnecessary parentheses around pattern
+
+ if 2 == 1 {}
+ //~^ ERROR unnecessary parentheses around `if` condition
+
+ // reported by parser
+ for _x in 1..10 {}
+ //~^ ERROR expected one of
+ //~| ERROR unexpected parentheses surrounding
+}
diff --git a/tests/ui/lint/issue-103435-extra-parentheses.rs b/tests/ui/lint/issue-103435-extra-parentheses.rs
new file mode 100644
index 000000000..8261610cf
--- /dev/null
+++ b/tests/ui/lint/issue-103435-extra-parentheses.rs
@@ -0,0 +1,18 @@
+// run-rustfix
+#![deny(unused_parens)]
+
+fn main() {
+ if let(Some(_))= Some(1) {}
+ //~^ ERROR unnecessary parentheses around pattern
+
+ for(_x)in 1..10 {}
+ //~^ ERROR unnecessary parentheses around pattern
+
+ if(2 == 1){}
+ //~^ ERROR unnecessary parentheses around `if` condition
+
+ // reported by parser
+ for(_x in 1..10){}
+ //~^ ERROR expected one of
+ //~| ERROR unexpected parentheses surrounding
+}
diff --git a/tests/ui/lint/issue-103435-extra-parentheses.stderr b/tests/ui/lint/issue-103435-extra-parentheses.stderr
new file mode 100644
index 000000000..29c41c910
--- /dev/null
+++ b/tests/ui/lint/issue-103435-extra-parentheses.stderr
@@ -0,0 +1,61 @@
+error: expected one of `)`, `,`, `@`, or `|`, found keyword `in`
+ --> $DIR/issue-103435-extra-parentheses.rs:15:12
+ |
+LL | for(_x in 1..10){}
+ | ^^ expected one of `)`, `,`, `@`, or `|`
+
+error: unexpected parentheses surrounding `for` loop head
+ --> $DIR/issue-103435-extra-parentheses.rs:15:8
+ |
+LL | for(_x in 1..10){}
+ | ^ ^
+ |
+help: remove parentheses in `for` loop
+ |
+LL - for(_x in 1..10){}
+LL + for _x in 1..10 {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-103435-extra-parentheses.rs:5:11
+ |
+LL | if let(Some(_))= Some(1) {}
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-103435-extra-parentheses.rs:2:9
+ |
+LL | #![deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - if let(Some(_))= Some(1) {}
+LL + if let Some(_) = Some(1) {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-103435-extra-parentheses.rs:8:8
+ |
+LL | for(_x)in 1..10 {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - for(_x)in 1..10 {}
+LL + for _x in 1..10 {}
+ |
+
+error: unnecessary parentheses around `if` condition
+ --> $DIR/issue-103435-extra-parentheses.rs:11:7
+ |
+LL | if(2 == 1){}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - if(2 == 1){}
+LL + if 2 == 1 {}
+ |
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/lint/issue-104392.rs b/tests/ui/lint/issue-104392.rs
new file mode 100644
index 000000000..d5608edb4
--- /dev/null
+++ b/tests/ui/lint/issue-104392.rs
@@ -0,0 +1,11 @@
+fn main() {
+ { unsafe 92 } //~ ERROR expected `{`, found `92`
+}
+
+fn foo() {
+ { mod 92 } //~ ERROR expected identifier, found `92`
+}
+
+fn bar() {
+ { trait 92 } //~ ERROR expected identifier, found `92`
+}
diff --git a/tests/ui/lint/issue-104392.stderr b/tests/ui/lint/issue-104392.stderr
new file mode 100644
index 000000000..8e466439a
--- /dev/null
+++ b/tests/ui/lint/issue-104392.stderr
@@ -0,0 +1,27 @@
+error: expected `{`, found `92`
+ --> $DIR/issue-104392.rs:2:14
+ |
+LL | { unsafe 92 }
+ | ------ ^^ expected `{`
+ | |
+ | while parsing this `unsafe` expression
+ |
+help: try placing this code inside a block
+ |
+LL | { unsafe { 92 } }
+ | + +
+
+error: expected identifier, found `92`
+ --> $DIR/issue-104392.rs:6:11
+ |
+LL | { mod 92 }
+ | ^^ expected identifier
+
+error: expected identifier, found `92`
+ --> $DIR/issue-104392.rs:10:13
+ |
+LL | { trait 92 }
+ | ^^ expected identifier
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/issue-104897.rs b/tests/ui/lint/issue-104897.rs
new file mode 100644
index 000000000..5fbc658f1
--- /dev/null
+++ b/tests/ui/lint/issue-104897.rs
@@ -0,0 +1,6 @@
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: format argument must be a string literal
+
+fn f(){(print!(á
diff --git a/tests/ui/lint/issue-104897.stderr b/tests/ui/lint/issue-104897.stderr
new file mode 100644
index 000000000..817a93c2f
--- /dev/null
+++ b/tests/ui/lint/issue-104897.stderr
@@ -0,0 +1,43 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-104897.rs:6:18
+ |
+LL | fn f(){(print!(á
+ | -- - ^
+ | || |
+ | || unclosed delimiter
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-104897.rs:6:18
+ |
+LL | fn f(){(print!(á
+ | -- - ^
+ | || |
+ | || unclosed delimiter
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-104897.rs:6:18
+ |
+LL | fn f(){(print!(á
+ | -- - ^
+ | || |
+ | || unclosed delimiter
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: format argument must be a string literal
+ --> $DIR/issue-104897.rs:6:16
+ |
+LL | fn f(){(print!(á
+ | ^
+ |
+help: you might be missing a string literal to format with
+ |
+LL | fn f(){(print!("{}", á
+ | +++++
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lint/issue-108155.rs b/tests/ui/lint/issue-108155.rs
new file mode 100644
index 000000000..4ae0cbd92
--- /dev/null
+++ b/tests/ui/lint/issue-108155.rs
@@ -0,0 +1,15 @@
+// check-pass
+// check that `deref_into_dyn_supertrait` doesn't cause ICE by eagerly converting
+// a cancelled lint
+
+#![allow(deref_into_dyn_supertrait)]
+
+trait Trait {}
+impl std::ops::Deref for dyn Trait + Send + Sync {
+ type Target = dyn Trait;
+ fn deref(&self) -> &Self::Target {
+ self
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/issue-14309.rs b/tests/ui/lint/issue-14309.rs
new file mode 100644
index 000000000..328a4c982
--- /dev/null
+++ b/tests/ui/lint/issue-14309.rs
@@ -0,0 +1,39 @@
+#![deny(improper_ctypes)]
+#![allow(dead_code)]
+
+struct A {
+ x: i32
+}
+
+#[repr(C, packed)]
+struct B {
+ x: i32,
+ y: A
+}
+
+#[repr(C)]
+struct C {
+ x: i32
+}
+
+type A2 = A;
+type B2 = B;
+type C2 = C;
+
+#[repr(C)]
+struct D {
+ x: C,
+ y: A
+}
+
+extern "C" {
+ fn foo(x: A); //~ ERROR type `A`, which is not FFI-safe
+ fn bar(x: B); //~ ERROR type `A`
+ fn baz(x: C);
+ fn qux(x: A2); //~ ERROR type `A`
+ fn quux(x: B2); //~ ERROR type `A`
+ fn corge(x: C2);
+ fn fred(x: D); //~ ERROR type `A`
+}
+
+fn main() { }
diff --git a/tests/ui/lint/issue-14309.stderr b/tests/ui/lint/issue-14309.stderr
new file mode 100644
index 000000000..9ce62a6b8
--- /dev/null
+++ b/tests/ui/lint/issue-14309.stderr
@@ -0,0 +1,77 @@
+error: `extern` block uses type `A`, which is not FFI-safe
+ --> $DIR/issue-14309.rs:30:15
+ |
+LL | fn foo(x: A);
+ | ^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+ = note: this struct has unspecified layout
+note: the type is defined here
+ --> $DIR/issue-14309.rs:4:1
+ |
+LL | struct A {
+ | ^^^^^^^^
+note: the lint level is defined here
+ --> $DIR/issue-14309.rs:1:9
+ |
+LL | #![deny(improper_ctypes)]
+ | ^^^^^^^^^^^^^^^
+
+error: `extern` block uses type `A`, which is not FFI-safe
+ --> $DIR/issue-14309.rs:31:15
+ |
+LL | fn bar(x: B);
+ | ^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+ = note: this struct has unspecified layout
+note: the type is defined here
+ --> $DIR/issue-14309.rs:4:1
+ |
+LL | struct A {
+ | ^^^^^^^^
+
+error: `extern` block uses type `A`, which is not FFI-safe
+ --> $DIR/issue-14309.rs:33:15
+ |
+LL | fn qux(x: A2);
+ | ^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+ = note: this struct has unspecified layout
+note: the type is defined here
+ --> $DIR/issue-14309.rs:4:1
+ |
+LL | struct A {
+ | ^^^^^^^^
+
+error: `extern` block uses type `A`, which is not FFI-safe
+ --> $DIR/issue-14309.rs:34:16
+ |
+LL | fn quux(x: B2);
+ | ^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+ = note: this struct has unspecified layout
+note: the type is defined here
+ --> $DIR/issue-14309.rs:4:1
+ |
+LL | struct A {
+ | ^^^^^^^^
+
+error: `extern` block uses type `A`, which is not FFI-safe
+ --> $DIR/issue-14309.rs:36:16
+ |
+LL | fn fred(x: D);
+ | ^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+ = note: this struct has unspecified layout
+note: the type is defined here
+ --> $DIR/issue-14309.rs:4:1
+ |
+LL | struct A {
+ | ^^^^^^^^
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/lint/issue-14837.rs b/tests/ui/lint/issue-14837.rs
new file mode 100644
index 000000000..a83bc4150
--- /dev/null
+++ b/tests/ui/lint/issue-14837.rs
@@ -0,0 +1,11 @@
+// check-pass
+// pretty-expanded FIXME #23616
+
+#[deny(dead_code)]
+pub enum Foo {
+ Bar {
+ baz: isize
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/lint/issue-17718-const-naming.rs b/tests/ui/lint/issue-17718-const-naming.rs
new file mode 100644
index 000000000..d7f0e7276
--- /dev/null
+++ b/tests/ui/lint/issue-17718-const-naming.rs
@@ -0,0 +1,8 @@
+#![warn(unused)]
+#![deny(warnings)]
+
+const foo: isize = 3;
+//~^ ERROR: should have an upper case name
+//~^^ ERROR: constant `foo` is never used
+
+fn main() {}
diff --git a/tests/ui/lint/issue-17718-const-naming.stderr b/tests/ui/lint/issue-17718-const-naming.stderr
new file mode 100644
index 000000000..7d2aadd5f
--- /dev/null
+++ b/tests/ui/lint/issue-17718-const-naming.stderr
@@ -0,0 +1,23 @@
+error: constant `foo` is never used
+ --> $DIR/issue-17718-const-naming.rs:4:7
+ |
+LL | const foo: isize = 3;
+ | ^^^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-17718-const-naming.rs:2:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(dead_code)]` implied by `#[deny(warnings)]`
+
+error: constant `foo` should have an upper case name
+ --> $DIR/issue-17718-const-naming.rs:4:7
+ |
+LL | const foo: isize = 3;
+ | ^^^ help: convert the identifier to upper case (notice the capitalization): `FOO`
+ |
+ = note: `#[deny(non_upper_case_globals)]` implied by `#[deny(warnings)]`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/issue-1866.rs b/tests/ui/lint/issue-1866.rs
new file mode 100644
index 000000000..caac0c504
--- /dev/null
+++ b/tests/ui/lint/issue-1866.rs
@@ -0,0 +1,29 @@
+// build-pass
+#![allow(dead_code)]
+#![allow(non_camel_case_types)]
+#![warn(clashing_extern_declarations)]
+
+// pretty-expanded FIXME #23616
+
+mod a {
+ pub type rust_task = usize;
+ pub mod rustrt {
+ use super::rust_task;
+ extern "C" {
+ pub fn rust_task_is_unwinding(rt: *const rust_task) -> bool;
+ }
+ }
+}
+
+mod b {
+ pub type rust_task = bool;
+ pub mod rustrt {
+ use super::rust_task;
+ extern "C" {
+ pub fn rust_task_is_unwinding(rt: *const rust_task) -> bool;
+ //~^ WARN `rust_task_is_unwinding` redeclared with a different signature
+ }
+ }
+}
+
+pub fn main() {}
diff --git a/tests/ui/lint/issue-1866.stderr b/tests/ui/lint/issue-1866.stderr
new file mode 100644
index 000000000..d19a13496
--- /dev/null
+++ b/tests/ui/lint/issue-1866.stderr
@@ -0,0 +1,19 @@
+warning: `rust_task_is_unwinding` redeclared with a different signature
+ --> $DIR/issue-1866.rs:23:13
+ |
+LL | pub fn rust_task_is_unwinding(rt: *const rust_task) -> bool;
+ | ------------------------------------------------------------ `rust_task_is_unwinding` previously declared here
+...
+LL | pub fn rust_task_is_unwinding(rt: *const rust_task) -> bool;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn(*const usize) -> bool`
+ found `unsafe extern "C" fn(*const bool) -> bool`
+note: the lint level is defined here
+ --> $DIR/issue-1866.rs:4:9
+ |
+LL | #![warn(clashing_extern_declarations)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/issue-20343.rs b/tests/ui/lint/issue-20343.rs
new file mode 100644
index 000000000..000b63984
--- /dev/null
+++ b/tests/ui/lint/issue-20343.rs
@@ -0,0 +1,32 @@
+// run-pass
+#![allow(unused_variables)]
+// Regression test for Issue #20343.
+
+// pretty-expanded FIXME #23616
+
+#![deny(dead_code)]
+
+struct B { b: u32 }
+struct C;
+struct D;
+
+trait T<A> { fn dummy(&self, a: A) { } }
+impl<A> T<A> for () {}
+
+impl B {
+ // test for unused code in arguments
+ fn foo(B { b }: B) -> u32 { b }
+
+ // test for unused code in return type
+ fn bar() -> C { unsafe { ::std::mem::transmute(()) } }
+
+ // test for unused code in generics
+ fn baz<A: T<D>>() {}
+}
+
+pub fn main() {
+ let b = B { b: 3 };
+ B::foo(b);
+ B::bar();
+ B::baz::<()>();
+}
diff --git a/tests/ui/lint/issue-30302.rs b/tests/ui/lint/issue-30302.rs
new file mode 100644
index 000000000..5eccb8cd5
--- /dev/null
+++ b/tests/ui/lint/issue-30302.rs
@@ -0,0 +1,20 @@
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![allow(non_snake_case)]
+#![deny(unreachable_patterns)]
+
+enum Stack<T> {
+ Nil,
+ Cons(T, Box<Stack<T>>)
+}
+
+fn is_empty<T>(s: Stack<T>) -> bool {
+ match s {
+ Nil => true,
+//~^ ERROR pattern binding `Nil` is named the same as one of the variants of the type `Stack`
+ _ => false
+//~^ ERROR unreachable pattern
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/issue-30302.stderr b/tests/ui/lint/issue-30302.stderr
new file mode 100644
index 000000000..baf6c0d7a
--- /dev/null
+++ b/tests/ui/lint/issue-30302.stderr
@@ -0,0 +1,26 @@
+error[E0170]: pattern binding `Nil` is named the same as one of the variants of the type `Stack`
+ --> $DIR/issue-30302.rs:13:9
+ |
+LL | Nil => true,
+ | ^^^ help: to match on the variant, qualify the path: `Stack::Nil`
+ |
+ = note: `#[deny(bindings_with_variant_name)]` on by default
+
+error: unreachable pattern
+ --> $DIR/issue-30302.rs:15:9
+ |
+LL | Nil => true,
+ | --- matches any value
+LL |
+LL | _ => false
+ | ^ unreachable pattern
+ |
+note: the lint level is defined here
+ --> $DIR/issue-30302.rs:4:9
+ |
+LL | #![deny(unreachable_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0170`.
diff --git a/tests/ui/lint/issue-31924-non-snake-ffi.rs b/tests/ui/lint/issue-31924-non-snake-ffi.rs
new file mode 100644
index 000000000..5b9faca49
--- /dev/null
+++ b/tests/ui/lint/issue-31924-non-snake-ffi.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+#![deny(non_snake_case)]
+
+#[no_mangle]
+pub extern "C" fn SparklingGenerationForeignFunctionInterface() {} // OK
+
+pub struct Foo;
+
+impl Foo {
+ #[no_mangle]
+ pub extern "C" fn SparklingGenerationForeignFunctionInterface() {} // OK
+}
+
+fn main() {}
diff --git a/tests/ui/lint/issue-34798.rs b/tests/ui/lint/issue-34798.rs
new file mode 100644
index 000000000..f0d710123
--- /dev/null
+++ b/tests/ui/lint/issue-34798.rs
@@ -0,0 +1,25 @@
+// run-pass
+#![forbid(improper_ctypes)]
+#![allow(dead_code)]
+
+#[repr(C)]
+pub struct Foo {
+ size: u8,
+ __value: ::std::marker::PhantomData<i32>,
+}
+
+#[repr(C)]
+pub struct ZeroSizeWithPhantomData<T>(::std::marker::PhantomData<T>);
+
+#[repr(C)]
+pub struct Bar {
+ size: u8,
+ baz: ZeroSizeWithPhantomData<i32>,
+}
+
+extern "C" {
+ pub fn bar(_: *mut Foo, _: *mut Bar);
+}
+
+fn main() {
+}
diff --git a/tests/ui/lint/issue-35075.rs b/tests/ui/lint/issue-35075.rs
new file mode 100644
index 000000000..0e54131c2
--- /dev/null
+++ b/tests/ui/lint/issue-35075.rs
@@ -0,0 +1,9 @@
+struct Bar<T> {
+ inner: Foo<T> //~ ERROR cannot find type `Foo` in this scope
+}
+
+enum Baz<T> {
+ Foo(Foo<T>) //~ ERROR cannot find type `Foo` in this scope
+}
+
+fn main() {}
diff --git a/tests/ui/lint/issue-35075.stderr b/tests/ui/lint/issue-35075.stderr
new file mode 100644
index 000000000..08bdaa728
--- /dev/null
+++ b/tests/ui/lint/issue-35075.stderr
@@ -0,0 +1,25 @@
+error[E0412]: cannot find type `Foo` in this scope
+ --> $DIR/issue-35075.rs:2:12
+ |
+LL | inner: Foo<T>
+ | ^^^ not found in this scope
+ |
+help: there is an enum variant `Baz::Foo`; try using the variant's enum
+ |
+LL | inner: Baz
+ | ~~~
+
+error[E0412]: cannot find type `Foo` in this scope
+ --> $DIR/issue-35075.rs:6:9
+ |
+LL | Foo(Foo<T>)
+ | ^^^ not found in this scope
+ |
+help: there is an enum variant `Baz::Foo`; try using the variant's enum
+ |
+LL | Foo(Baz)
+ | ~~~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs b/tests/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs
new file mode 100644
index 000000000..0a951cfa9
--- /dev/null
+++ b/tests/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs
@@ -0,0 +1,27 @@
+// check-pass
+
+#![warn(unused_parens)]
+
+macro_rules! the_worship_the_heart_lifts_above {
+ ( @as_expr, $e:expr) => { $e };
+ ( @generate_fn, $name:tt) => {
+ #[allow(dead_code)] fn the_moth_for_the_star<'a>() -> Option<&'a str> {
+ Some(the_worship_the_heart_lifts_above!( @as_expr, $name ))
+ }
+ };
+ ( $name:ident ) => { the_worship_the_heart_lifts_above!( @generate_fn, (stringify!($name))); }
+ // ↑ Notably, this does 𝘯𝘰𝘵 warn: we're declining to lint unused parens in
+ // function/method arguments inside of nested macros because of situations
+ // like those reported in Issue #47775
+}
+
+macro_rules! and_the_heavens_reject_not {
+ () => {
+ #[allow(dead_code)] fn the_night_for_the_morrow() -> Option<isize> { Some((2)) }
+ }
+}
+
+the_worship_the_heart_lifts_above!(rah);
+and_the_heavens_reject_not!();
+
+fn main() {}
diff --git a/tests/ui/lint/issue-54099-camel-case-underscore-types.rs b/tests/ui/lint/issue-54099-camel-case-underscore-types.rs
new file mode 100644
index 000000000..b2bf87358
--- /dev/null
+++ b/tests/ui/lint/issue-54099-camel-case-underscore-types.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+#![forbid(non_camel_case_types)]
+#![allow(dead_code)]
+
+// None of the following types should generate a warning
+struct _X {}
+struct __X {}
+struct __ {}
+struct X_ {}
+struct X__ {}
+struct X___ {}
+
+fn main() { }
diff --git a/tests/ui/lint/issue-57410-1.rs b/tests/ui/lint/issue-57410-1.rs
new file mode 100644
index 000000000..d825cb180
--- /dev/null
+++ b/tests/ui/lint/issue-57410-1.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+// Originally from #53925.
+// Tests that the `unreachable_pub` lint doesn't fire for `pub self::bar::Bar`.
+
+#![deny(unreachable_pub)]
+
+mod foo {
+ mod bar {
+ pub struct Bar;
+ }
+
+ pub use self::bar::Bar;
+}
+
+pub use foo::Bar;
+
+fn main() {}
diff --git a/tests/ui/lint/issue-57410.rs b/tests/ui/lint/issue-57410.rs
new file mode 100644
index 000000000..0cf4b8068
--- /dev/null
+++ b/tests/ui/lint/issue-57410.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+// Tests that the `unreachable_pub` lint doesn't fire for `pub self::imp::f`.
+
+#![deny(unreachable_pub)]
+
+mod m {
+ mod imp {
+ pub fn f() {}
+ }
+
+ pub use self::imp::f;
+}
+
+pub use self::m::f;
+
+fn main() {}
diff --git a/tests/ui/lint/issue-63364.rs b/tests/ui/lint/issue-63364.rs
new file mode 100644
index 000000000..5223267a6
--- /dev/null
+++ b/tests/ui/lint/issue-63364.rs
@@ -0,0 +1,10 @@
+fn part(_: u16) -> u32 {
+ 1
+}
+
+fn main() {
+ for n in 100_000.. {
+ //~^ ERROR: literal out of range for `u16`
+ let _ = part(n);
+ }
+}
diff --git a/tests/ui/lint/issue-63364.stderr b/tests/ui/lint/issue-63364.stderr
new file mode 100644
index 000000000..9b5453fa8
--- /dev/null
+++ b/tests/ui/lint/issue-63364.stderr
@@ -0,0 +1,11 @@
+error: literal out of range for `u16`
+ --> $DIR/issue-63364.rs:6:14
+ |
+LL | for n in 100_000.. {
+ | ^^^^^^^
+ |
+ = note: the literal `100_000` does not fit into the type `u16` whose range is `0..=65535`
+ = note: `#[deny(overflowing_literals)]` on by default
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs b/tests/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs
new file mode 100644
index 000000000..c2b81959f
--- /dev/null
+++ b/tests/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs
@@ -0,0 +1,29 @@
+#![deny(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(dead_code)]
+
+enum Foo {
+ Bad {
+ lowerCamelCaseName: bool,
+ //~^ ERROR structure field `lowerCamelCaseName` should have a snake case name
+ },
+ Good {
+ snake_case_name: bool,
+ },
+}
+
+fn main() {
+ let b = Foo::Bad { lowerCamelCaseName: true };
+
+ match b {
+ Foo::Bad { lowerCamelCaseName } => {}
+ Foo::Good { snake_case_name: lowerCamelCaseBinding } => { }
+ //~^ ERROR variable `lowerCamelCaseBinding` should have a snake case name
+ }
+
+ if let Foo::Good { snake_case_name: anotherLowerCamelCaseBinding } = b { }
+ //~^ ERROR variable `anotherLowerCamelCaseBinding` should have a snake case name
+
+ if let Foo::Bad { lowerCamelCaseName: yetAnotherLowerCamelCaseBinding } = b { }
+ //~^ ERROR variable `yetAnotherLowerCamelCaseBinding` should have a snake case name
+}
diff --git a/tests/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr b/tests/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr
new file mode 100644
index 000000000..09dc3640f
--- /dev/null
+++ b/tests/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr
@@ -0,0 +1,32 @@
+error: structure field `lowerCamelCaseName` should have a snake case name
+ --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:7:9
+ |
+LL | lowerCamelCaseName: bool,
+ | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `lower_camel_case_name`
+ |
+note: the lint level is defined here
+ --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:1:9
+ |
+LL | #![deny(non_snake_case)]
+ | ^^^^^^^^^^^^^^
+
+error: variable `lowerCamelCaseBinding` should have a snake case name
+ --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:20:38
+ |
+LL | Foo::Good { snake_case_name: lowerCamelCaseBinding } => { }
+ | ^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `lower_camel_case_binding`
+
+error: variable `anotherLowerCamelCaseBinding` should have a snake case name
+ --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:24:41
+ |
+LL | if let Foo::Good { snake_case_name: anotherLowerCamelCaseBinding } = b { }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `another_lower_camel_case_binding`
+
+error: variable `yetAnotherLowerCamelCaseBinding` should have a snake case name
+ --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:27:43
+ |
+LL | if let Foo::Bad { lowerCamelCaseName: yetAnotherLowerCamelCaseBinding } = b { }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `yet_another_lower_camel_case_binding`
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs b/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs
new file mode 100644
index 000000000..b4fc33174
--- /dev/null
+++ b/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs
@@ -0,0 +1,50 @@
+// This test is checking that you cannot override a `forbid` by adding in other
+// attributes later in the same scope. (We already ensure that you cannot
+// override it in nested scopes).
+
+// If you turn off deduplicate diagnostics (which rustc turns on by default but
+// compiletest turns off when it runs ui tests), then the errors are
+// (unfortunately) repeated here because the checking is done as we read in the
+// errors, and currently that happens two or three different times, depending on
+// compiler flags.
+//
+// I decided avoiding the redundant output was not worth the time in engineering
+// effort for bug like this, which 1. end users are unlikely to run into in the
+// first place, and 2. they won't see the redundant output anyway.
+
+// compile-flags: -Z deduplicate-diagnostics=yes
+
+#![forbid(forbidden_lint_groups)]
+
+fn forbid_first(num: i32) -> i32 {
+ #![forbid(unused)]
+ #![deny(unused)]
+ //~^ ERROR: deny(unused) incompatible with previous forbid
+ //~| WARNING being phased out
+ #![warn(unused)]
+ #![allow(unused)]
+
+ num * num
+}
+
+fn forbid_last(num: i32) -> i32 {
+ #![deny(unused)]
+ #![warn(unused)]
+ #![allow(unused)]
+ #![forbid(unused)]
+
+ num * num
+}
+
+fn forbid_multiple(num: i32) -> i32 {
+ #![forbid(unused)]
+ #![forbid(unused)]
+
+ num * num
+}
+
+fn main() {
+ forbid_first(10);
+ forbid_last(10);
+ forbid_multiple(10);
+}
diff --git a/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr b/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr
new file mode 100644
index 000000000..cc44f8aa5
--- /dev/null
+++ b/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr
@@ -0,0 +1,18 @@
+error: deny(unused) incompatible with previous forbid
+ --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:21:13
+ |
+LL | #![forbid(unused)]
+ | ------ `forbid` level set here
+LL | #![deny(unused)]
+ | ^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+note: the lint level is defined here
+ --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11
+ |
+LL | #![forbid(forbidden_lint_groups)]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/issue-79546-fuel-ice.rs b/tests/ui/lint/issue-79546-fuel-ice.rs
new file mode 100644
index 000000000..0e9f54088
--- /dev/null
+++ b/tests/ui/lint/issue-79546-fuel-ice.rs
@@ -0,0 +1,8 @@
+// Regression test for the ICE described in #79546.
+
+// compile-flags: --cap-lints=allow -Zfuel=issue79546=0
+// check-pass
+#![crate_name="issue79546"]
+
+struct S;
+fn main() {}
diff --git a/tests/ui/lint/issue-79744.rs b/tests/ui/lint/issue-79744.rs
new file mode 100644
index 000000000..e9725a027
--- /dev/null
+++ b/tests/ui/lint/issue-79744.rs
@@ -0,0 +1,13 @@
+fn main() {
+ let elem = 6i8;
+ let e2 = 230;
+ //~^ ERROR literal out of range for `i8`
+ //~| HELP consider using the type `u8` instead
+
+ let mut vec = Vec::new();
+
+ vec.push(e2);
+ vec.push(elem);
+
+ println!("{:?}", vec);
+}
diff --git a/tests/ui/lint/issue-79744.stderr b/tests/ui/lint/issue-79744.stderr
new file mode 100644
index 000000000..c1b56250d
--- /dev/null
+++ b/tests/ui/lint/issue-79744.stderr
@@ -0,0 +1,12 @@
+error: literal out of range for `i8`
+ --> $DIR/issue-79744.rs:3:14
+ |
+LL | let e2 = 230;
+ | ^^^
+ |
+ = note: the literal `230` does not fit into the type `i8` whose range is `-128..=127`
+ = help: consider using the type `u8` instead
+ = note: `#[deny(overflowing_literals)]` on by default
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/issue-80988.rs b/tests/ui/lint/issue-80988.rs
new file mode 100644
index 000000000..1e116206f
--- /dev/null
+++ b/tests/ui/lint/issue-80988.rs
@@ -0,0 +1,14 @@
+// Regression test for #80988
+//
+// check-pass
+
+#![forbid(warnings)]
+
+#[deny(warnings)]
+//~^ WARNING incompatible with previous forbid
+//~| WARNING being phased out
+//~| WARNING incompatible with previous forbid
+//~| WARNING being phased out
+//~| WARNING incompatible with previous forbid
+//~| WARNING being phased out
+fn main() {}
diff --git a/tests/ui/lint/issue-80988.stderr b/tests/ui/lint/issue-80988.stderr
new file mode 100644
index 000000000..73e27ffda
--- /dev/null
+++ b/tests/ui/lint/issue-80988.stderr
@@ -0,0 +1,39 @@
+warning: deny(warnings) incompatible with previous forbid
+ --> $DIR/issue-80988.rs:7:8
+ |
+LL | #![forbid(warnings)]
+ | -------- `forbid` level set here
+LL |
+LL | #[deny(warnings)]
+ | ^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+ = note: `#[warn(forbidden_lint_groups)]` on by default
+
+warning: deny(warnings) incompatible with previous forbid
+ --> $DIR/issue-80988.rs:7:8
+ |
+LL | #![forbid(warnings)]
+ | -------- `forbid` level set here
+LL |
+LL | #[deny(warnings)]
+ | ^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+
+warning: deny(warnings) incompatible with previous forbid
+ --> $DIR/issue-80988.rs:7:8
+ |
+LL | #![forbid(warnings)]
+ | -------- `forbid` level set here
+LL |
+LL | #[deny(warnings)]
+ | ^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/lint/issue-81218.rs b/tests/ui/lint/issue-81218.rs
new file mode 100644
index 000000000..f02aa9040
--- /dev/null
+++ b/tests/ui/lint/issue-81218.rs
@@ -0,0 +1,14 @@
+// Regression test for #81218
+//
+// check-pass
+
+#![forbid(warnings)]
+
+#[allow(unused_variables)]
+fn main() {
+ // We want to ensure that you don't get an error
+ // here. The idea is that a derive might generate
+ // code that would otherwise trigger the "unused variables"
+ // lint, but it is meant to be suppressed.
+ let x: ();
+}
diff --git a/tests/ui/lint/issue-83477.rs b/tests/ui/lint/issue-83477.rs
new file mode 100644
index 000000000..4262a2879
--- /dev/null
+++ b/tests/ui/lint/issue-83477.rs
@@ -0,0 +1,16 @@
+// compile-flags: -Zunstable-options
+// check-pass
+#![warn(rustc::internal)]
+
+#[allow(rustc::foo::bar::default_hash_types)]
+//~^ WARN unknown lint: `rustc::foo::bar::default_hash_types`
+//~| HELP did you mean
+//~| SUGGESTION rustc::default_hash_types
+#[allow(rustc::foo::default_hash_types)]
+//~^ WARN unknown lint: `rustc::foo::default_hash_types`
+//~| HELP did you mean
+//~| SUGGESTION rustc::default_hash_types
+fn main() {
+ let _ = std::collections::HashMap::<String, String>::new();
+ //~^ WARN prefer `FxHashMap` over `HashMap`, it has better performance
+}
diff --git a/tests/ui/lint/issue-83477.stderr b/tests/ui/lint/issue-83477.stderr
new file mode 100644
index 000000000..f824fc09e
--- /dev/null
+++ b/tests/ui/lint/issue-83477.stderr
@@ -0,0 +1,30 @@
+warning: unknown lint: `rustc::foo::bar::default_hash_types`
+ --> $DIR/issue-83477.rs:5:9
+ |
+LL | #[allow(rustc::foo::bar::default_hash_types)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `rustc::default_hash_types`
+ |
+ = note: `#[warn(unknown_lints)]` on by default
+
+warning: unknown lint: `rustc::foo::default_hash_types`
+ --> $DIR/issue-83477.rs:9:9
+ |
+LL | #[allow(rustc::foo::default_hash_types)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `rustc::default_hash_types`
+
+warning: prefer `FxHashMap` over `HashMap`, it has better performance
+ --> $DIR/issue-83477.rs:14:13
+ |
+LL | let _ = std::collections::HashMap::<String, String>::new();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
+note: the lint level is defined here
+ --> $DIR/issue-83477.rs:3:9
+ |
+LL | #![warn(rustc::internal)]
+ | ^^^^^^^^^^^^^^^
+ = note: `#[warn(rustc::default_hash_types)]` implied by `#[warn(rustc::internal)]`
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/lint/issue-86600-lint-twice.rs b/tests/ui/lint/issue-86600-lint-twice.rs
new file mode 100644
index 000000000..0e8a837d9
--- /dev/null
+++ b/tests/ui/lint/issue-86600-lint-twice.rs
@@ -0,0 +1,15 @@
+// Regression test for #86600, where an instance of the
+// `illegal_floating_point_literal_pattern` lint was issued twice.
+
+// check-pass
+
+fn main() {
+ let x = 42.0;
+
+ match x {
+ 5.0 => {}
+ //~^ WARNING: floating-point types cannot be used in patterns
+ //~| WARNING: this was previously accepted by the compiler
+ _ => {}
+ }
+}
diff --git a/tests/ui/lint/issue-86600-lint-twice.stderr b/tests/ui/lint/issue-86600-lint-twice.stderr
new file mode 100644
index 000000000..5a65c6121
--- /dev/null
+++ b/tests/ui/lint/issue-86600-lint-twice.stderr
@@ -0,0 +1,12 @@
+warning: floating-point types cannot be used in patterns
+ --> $DIR/issue-86600-lint-twice.rs:10:9
+ |
+LL | 5.0 => {}
+ | ^^^
+ |
+ = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
+ = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/issue-87274-paren-parent.rs b/tests/ui/lint/issue-87274-paren-parent.rs
new file mode 100644
index 000000000..0141c5a25
--- /dev/null
+++ b/tests/ui/lint/issue-87274-paren-parent.rs
@@ -0,0 +1,9 @@
+// check-pass
+// Tests that we properly lint at 'paren' expressions
+
+fn foo() -> Result<(), String> {
+ (try!(Ok::<u8, String>(1))); //~ WARN use of deprecated macro `try`
+ Ok(())
+}
+
+fn main() {}
diff --git a/tests/ui/lint/issue-87274-paren-parent.stderr b/tests/ui/lint/issue-87274-paren-parent.stderr
new file mode 100644
index 000000000..f06024298
--- /dev/null
+++ b/tests/ui/lint/issue-87274-paren-parent.stderr
@@ -0,0 +1,10 @@
+warning: use of deprecated macro `try`: use the `?` operator instead
+ --> $DIR/issue-87274-paren-parent.rs:5:6
+ |
+LL | (try!(Ok::<u8, String>(1)));
+ | ^^^
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/issue-89469.rs b/tests/ui/lint/issue-89469.rs
new file mode 100644
index 000000000..3a6ab4528
--- /dev/null
+++ b/tests/ui/lint/issue-89469.rs
@@ -0,0 +1,20 @@
+// Regression test for #89469, where an extra non_snake_case warning was
+// reported for a shorthand field binding.
+
+// check-pass
+#![deny(non_snake_case)]
+
+#[allow(non_snake_case)]
+struct Entry {
+ A: u16,
+ a: u16
+}
+
+fn foo() -> Entry {todo!()}
+
+pub fn f() {
+ let Entry { A, a } = foo();
+ let _ = (A, a);
+}
+
+fn main() {}
diff --git a/tests/ui/lint/issue-90614-accept-allow-text-direction-codepoint-in-comment-lint.rs b/tests/ui/lint/issue-90614-accept-allow-text-direction-codepoint-in-comment-lint.rs
new file mode 100644
index 000000000..425e2703c
--- /dev/null
+++ b/tests/ui/lint/issue-90614-accept-allow-text-direction-codepoint-in-comment-lint.rs
@@ -0,0 +1,9 @@
+// check-pass
+// Allowing the code lint should work without warning and
+// the text flow char in the comment should be ignored.
+
+#![allow(text_direction_codepoint_in_comment)]
+
+fn main() {
+ // U+2066 LEFT-TO-RIGHT ISOLATE follows:⁦⁦
+}
diff --git a/tests/ui/lint/issue-97094.rs b/tests/ui/lint/issue-97094.rs
new file mode 100644
index 000000000..22525ca11
--- /dev/null
+++ b/tests/ui/lint/issue-97094.rs
@@ -0,0 +1,50 @@
+#![deny(warnings)]
+
+// Ensure that unknown lints inside cfg-attr's are linted for
+
+#![cfg_attr(all(), allow(nonex_lint_top_level))]
+//~^ ERROR unknown lint
+#![cfg_attr(all(), allow(bare_trait_object))]
+//~^ ERROR has been renamed
+
+#[cfg_attr(all(), allow(nonex_lint_mod))]
+//~^ ERROR unknown lint
+mod baz {
+ #![cfg_attr(all(), allow(nonex_lint_mod_inner))]
+ //~^ ERROR unknown lint
+}
+
+#[cfg_attr(all(), allow(nonex_lint_fn))]
+//~^ ERROR unknown lint
+pub fn main() {}
+
+macro_rules! bar {
+ ($($t:tt)*) => {
+ $($t)*
+ };
+}
+
+bar!(
+ #[cfg_attr(all(), allow(nonex_lint_in_macro))]
+ //~^ ERROR unknown lint
+ pub fn _bar() {}
+);
+
+// No warning for non-applying cfg
+#[cfg_attr(any(), allow(nonex_lint_fn))]
+pub fn _foo() {}
+
+// Allowing unknown lints works if inside cfg_attr
+#[cfg_attr(all(), allow(unknown_lints))]
+mod bar_allowed {
+ #[allow(nonex_lint_fn)]
+ fn _foo() {}
+}
+
+// ... but not if the cfg_attr doesn't evaluate
+#[cfg_attr(any(), allow(unknown_lints))]
+mod bar_not_allowed {
+ #[allow(nonex_lint_fn)]
+ //~^ ERROR unknown lint
+ fn _foo() {}
+}
diff --git a/tests/ui/lint/issue-97094.stderr b/tests/ui/lint/issue-97094.stderr
new file mode 100644
index 000000000..1a0a3eaf2
--- /dev/null
+++ b/tests/ui/lint/issue-97094.stderr
@@ -0,0 +1,53 @@
+error: unknown lint: `nonex_lint_top_level`
+ --> $DIR/issue-97094.rs:5:26
+ |
+LL | #![cfg_attr(all(), allow(nonex_lint_top_level))]
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-97094.rs:1:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(unknown_lints)]` implied by `#[deny(warnings)]`
+
+error: lint `bare_trait_object` has been renamed to `bare_trait_objects`
+ --> $DIR/issue-97094.rs:7:26
+ |
+LL | #![cfg_attr(all(), allow(bare_trait_object))]
+ | ^^^^^^^^^^^^^^^^^ help: use the new name: `bare_trait_objects`
+ |
+ = note: `#[deny(renamed_and_removed_lints)]` implied by `#[deny(warnings)]`
+
+error: unknown lint: `nonex_lint_mod`
+ --> $DIR/issue-97094.rs:10:25
+ |
+LL | #[cfg_attr(all(), allow(nonex_lint_mod))]
+ | ^^^^^^^^^^^^^^
+
+error: unknown lint: `nonex_lint_mod_inner`
+ --> $DIR/issue-97094.rs:13:30
+ |
+LL | #![cfg_attr(all(), allow(nonex_lint_mod_inner))]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unknown lint: `nonex_lint_fn`
+ --> $DIR/issue-97094.rs:17:25
+ |
+LL | #[cfg_attr(all(), allow(nonex_lint_fn))]
+ | ^^^^^^^^^^^^^
+
+error: unknown lint: `nonex_lint_in_macro`
+ --> $DIR/issue-97094.rs:28:29
+ |
+LL | #[cfg_attr(all(), allow(nonex_lint_in_macro))]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: unknown lint: `nonex_lint_fn`
+ --> $DIR/issue-97094.rs:47:13
+ |
+LL | #[allow(nonex_lint_fn)]
+ | ^^^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
+
diff --git a/tests/ui/lint/issue-99387.rs b/tests/ui/lint/issue-99387.rs
new file mode 100644
index 000000000..616eb935e
--- /dev/null
+++ b/tests/ui/lint/issue-99387.rs
@@ -0,0 +1,24 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(private_in_public)]
+
+pub type Successors<'a> = impl Iterator<Item = &'a ()>;
+
+pub fn f<'a>() -> Successors<'a> {
+ None.into_iter()
+}
+
+trait Tr {
+ type Item;
+}
+
+impl<'a> Tr for &'a () {
+ type Item = Successors<'a>;
+}
+
+pub fn ohno<'a>() -> <&'a () as Tr>::Item {
+ None.into_iter()
+}
+
+fn main() {}
diff --git a/tests/ui/lint/known-tool-in-submodule/root.rs b/tests/ui/lint/known-tool-in-submodule/root.rs
new file mode 100644
index 000000000..80806dcbd
--- /dev/null
+++ b/tests/ui/lint/known-tool-in-submodule/root.rs
@@ -0,0 +1,10 @@
+// check-pass
+
+#![feature(register_tool)]
+#![register_tool(tool)]
+
+mod submodule;
+
+fn main() {
+ submodule::foo();
+}
diff --git a/tests/ui/lint/known-tool-in-submodule/submodule.rs b/tests/ui/lint/known-tool-in-submodule/submodule.rs
new file mode 100644
index 000000000..bb25e1005
--- /dev/null
+++ b/tests/ui/lint/known-tool-in-submodule/submodule.rs
@@ -0,0 +1,4 @@
+// ignore-test: not a test
+
+#[allow(tool::lint)]
+pub fn foo() {}
diff --git a/tests/ui/lint/let_underscore/let_underscore_drop.rs b/tests/ui/lint/let_underscore/let_underscore_drop.rs
new file mode 100644
index 000000000..f298871f1
--- /dev/null
+++ b/tests/ui/lint/let_underscore/let_underscore_drop.rs
@@ -0,0 +1,14 @@
+// check-pass
+#![warn(let_underscore_drop)]
+
+struct NontrivialDrop;
+
+impl Drop for NontrivialDrop {
+ fn drop(&mut self) {
+ println!("Dropping!");
+ }
+}
+
+fn main() {
+ let _ = NontrivialDrop; //~WARNING non-binding let on a type that implements `Drop`
+}
diff --git a/tests/ui/lint/let_underscore/let_underscore_drop.stderr b/tests/ui/lint/let_underscore/let_underscore_drop.stderr
new file mode 100644
index 000000000..7b7de202e
--- /dev/null
+++ b/tests/ui/lint/let_underscore/let_underscore_drop.stderr
@@ -0,0 +1,22 @@
+warning: non-binding let on a type that implements `Drop`
+ --> $DIR/let_underscore_drop.rs:13:5
+ |
+LL | let _ = NontrivialDrop;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/let_underscore_drop.rs:2:9
+ |
+LL | #![warn(let_underscore_drop)]
+ | ^^^^^^^^^^^^^^^^^^^
+help: consider binding to an unused variable to avoid immediately dropping the value
+ |
+LL | let _unused = NontrivialDrop;
+ | ~~~~~~~
+help: consider immediately dropping the value
+ |
+LL | drop(NontrivialDrop);
+ | ~~~~~ +
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/let_underscore/let_underscore_lock.rs b/tests/ui/lint/let_underscore/let_underscore_lock.rs
new file mode 100644
index 000000000..7423862cd
--- /dev/null
+++ b/tests/ui/lint/let_underscore/let_underscore_lock.rs
@@ -0,0 +1,7 @@
+// check-fail
+use std::sync::{Arc, Mutex};
+
+fn main() {
+ let data = Arc::new(Mutex::new(0));
+ let _ = data.lock().unwrap(); //~ERROR non-binding let on a synchronization lock
+}
diff --git a/tests/ui/lint/let_underscore/let_underscore_lock.stderr b/tests/ui/lint/let_underscore/let_underscore_lock.stderr
new file mode 100644
index 000000000..fb58af0a4
--- /dev/null
+++ b/tests/ui/lint/let_underscore/let_underscore_lock.stderr
@@ -0,0 +1,20 @@
+error: non-binding let on a synchronization lock
+ --> $DIR/let_underscore_lock.rs:6:9
+ |
+LL | let _ = data.lock().unwrap();
+ | ^ ^^^^^^^^^^^^^^^^^^^^ this binding will immediately drop the value assigned to it
+ | |
+ | this lock is not assigned to a binding and is immediately dropped
+ |
+ = note: `#[deny(let_underscore_lock)]` on by default
+help: consider binding to an unused variable to avoid immediately dropping the value
+ |
+LL | let _unused = data.lock().unwrap();
+ | ~~~~~~~
+help: consider immediately dropping the value
+ |
+LL | drop(data.lock().unwrap());
+ | ~~~~~ +
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-attr-everywhere-early.rs b/tests/ui/lint/lint-attr-everywhere-early.rs
new file mode 100644
index 000000000..fd0c4b43e
--- /dev/null
+++ b/tests/ui/lint/lint-attr-everywhere-early.rs
@@ -0,0 +1,176 @@
+// Tests that lint levels can be set for early lints.
+#![allow(non_camel_case_types, unsafe_code, while_true, unused_parens)]
+
+// The following is a check of the lints used here to verify they do not warn
+// when allowed.
+fn verify_no_warnings() {
+ type non_camel_type = i32; // non_camel_case_types
+ struct NON_CAMEL_IS_ALLOWED; // non_camel_case_types
+ unsafe {} // unsafe_code
+ enum Enum {
+ VARIANT_CAMEL // non_camel_case_types
+ }
+ fn generics<foo>() {} // non_camel_case_types
+ while true {} // while_true
+ type T = (i32); // unused_parens
+}
+
+
+// ################## Types
+
+#[deny(non_camel_case_types)]
+type type_outer = i32; //~ ERROR type `type_outer` should have an upper camel case name
+
+type BareFnPtr = fn(#[deny(unused_parens)](i32)); //~ ERROR unnecessary parentheses around type
+// There aren't any early lints that currently apply to the variadic spot.
+// type BareFnPtrVariadic = extern "C" fn(i32, #[deny()]...);
+
+// ################## Items
+#[deny(non_camel_case_types)]
+struct ITEM_OUTER; //~ ERROR type `ITEM_OUTER` should have an upper camel case name
+
+mod module_inner {
+ #![deny(unsafe_code)]
+ fn f() {
+ unsafe {} //~ ERROR usage of an `unsafe` block
+ }
+}
+
+struct Associated;
+impl Associated {
+ #![deny(unsafe_code)]
+
+ fn inherent_denied_from_inner() { unsafe {} } //~ usage of an `unsafe` block
+
+ #[deny(while_true)]
+ fn inherent_fn() { while true {} } //~ ERROR denote infinite loops with
+
+ #[deny(while_true)]
+ const INHERENT_CONST: i32 = {while true {} 1}; //~ ERROR denote infinite loops with
+}
+
+trait trait_inner { //~ ERROR trait `trait_inner` should have an upper camel case name
+ #![deny(non_camel_case_types)]
+}
+
+trait AssociatedTrait {
+ #![deny(unsafe_code)]
+
+ fn denied_from_inner() { unsafe {} } //~ ERROR usage of an `unsafe` block
+
+ #[deny(while_true)]
+ fn assoc_fn() { while true {} } //~ ERROR denote infinite loops with
+
+ #[deny(while_true)]
+ const ASSOC_CONST: i32 = {while true {} 1}; //~ ERROR denote infinite loops with
+
+ #[deny(non_camel_case_types)]
+ type assoc_type; //~ ERROR associated type `assoc_type` should have an upper camel case name
+}
+
+impl AssociatedTrait for Associated {
+ #![deny(unsafe_code)]
+
+ fn denied_from_inner() { unsafe {} } //~ ERROR usage of an `unsafe` block
+
+ #[deny(while_true)]
+ fn assoc_fn() { while true {} } //~ ERROR denote infinite loops with
+
+ #[deny(while_true)]
+ const ASSOC_CONST: i32 = {while true {} 1}; //~ ERROR denote infinite loops with
+
+ #[deny(unused_parens)]
+ type assoc_type = (i32); //~ ERROR unnecessary parentheses around type
+}
+
+struct StructFields {
+ #[deny(unused_parens)]f1: (i32), //~ ERROR unnecessary parentheses around type
+}
+struct StructTuple(#[deny(unused_parens)](i32)); //~ ERROR unnecessary parentheses around type
+
+enum Enum {
+ #[deny(non_camel_case_types)]
+ VARIANT_CAMEL, //~ ERROR variant `VARIANT_CAMEL` should have an upper camel case name
+}
+
+extern "C" {
+ #![deny(unused_parens)]
+
+ fn foreign_denied_from_inner(x: (i32)); //~ ERROR unnecessary parentheses around type
+}
+
+extern "C" {
+ #[deny(unused_parens)]
+ fn foreign_denied_from_outer(x: (i32)); //~ ERROR unnecessary parentheses around type
+}
+
+fn function(#[deny(unused_parens)] param: (i32)) {} //~ ERROR unnecessary parentheses around type
+
+fn generics<#[deny(non_camel_case_types)]foo>() {} //~ ERROR type parameter `foo` should have an upper camel case name
+
+
+// ################## Statements
+fn statements() {
+ #[deny(unused_parens)]
+ let x = (1); //~ ERROR unnecessary parentheses around assigned value
+}
+
+
+// ################## Expressions
+fn expressions() {
+ let closure = |#[deny(unused_parens)] param: (i32)| {}; //~ ERROR unnecessary parentheses around type
+
+ struct Match{f1: i32}
+ // Strangely unused_parens doesn't fire with {f1: (123)}
+ let f = Match{#[deny(unused_parens)]f1: {(123)}}; //~ ERROR unnecessary parentheses around block return value
+
+ match f {
+ #![deny(unsafe_code)]
+
+ #[deny(while_true)]
+ Match{f1} => {
+ unsafe {} //~ ERROR usage of an `unsafe` block
+ while true {} //~ ERROR denote infinite loops with
+ }
+ }
+
+ // Statement Block
+ {
+ #![deny(unsafe_code)]
+ unsafe {} //~ ERROR usage of an `unsafe` block
+ }
+ let block_tail = {
+ #[deny(unsafe_code)]
+ unsafe {} //~ ERROR usage of an `unsafe` block
+ };
+
+ // Before expression as a statement.
+ #[deny(unsafe_code)]
+ unsafe {}; //~ ERROR usage of an `unsafe` block
+
+ [#[deny(unsafe_code)] unsafe {123}]; //~ ERROR usage of an `unsafe` block
+ (#[deny(unsafe_code)] unsafe {123},); //~ ERROR usage of an `unsafe` block
+ fn call(p: i32) {}
+ call(#[deny(unsafe_code)] unsafe {123}); //~ ERROR usage of an `unsafe` block
+ struct TupleStruct(i32);
+ TupleStruct(#[deny(unsafe_code)] unsafe {123}); //~ ERROR usage of an `unsafe` block
+}
+
+
+// ################## Patterns
+fn patterns() {
+ struct PatField{f1: i32, f2: i32};
+ let f = PatField{f1: 1, f2: 2};
+ match f {
+ PatField {
+ #[deny(ellipsis_inclusive_range_patterns)]
+ f1: 0...100,
+ //~^ ERROR range patterns are deprecated
+ //~| WARNING this is accepted in the current edition
+ ..
+ } => {}
+ _ => {}
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-attr-everywhere-early.stderr b/tests/ui/lint/lint-attr-everywhere-early.stderr
new file mode 100644
index 000000000..d6c6d5fae
--- /dev/null
+++ b/tests/ui/lint/lint-attr-everywhere-early.stderr
@@ -0,0 +1,486 @@
+error: type `type_outer` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:22:6
+ |
+LL | type type_outer = i32;
+ | ^^^^^^^^^^ help: convert the identifier to upper camel case: `TypeOuter`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:21:8
+ |
+LL | #[deny(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:24:43
+ |
+LL | type BareFnPtr = fn(#[deny(unused_parens)](i32));
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:24:28
+ |
+LL | type BareFnPtr = fn(#[deny(unused_parens)](i32));
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - type BareFnPtr = fn(#[deny(unused_parens)](i32));
+LL + type BareFnPtr = fn(#[deny(unused_parens)]i32);
+ |
+
+error: type `ITEM_OUTER` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:30:8
+ |
+LL | struct ITEM_OUTER;
+ | ^^^^^^^^^^ help: convert the identifier to upper camel case: `ItemOuter`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:29:8
+ |
+LL | #[deny(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:35:9
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:33:13
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:43:39
+ |
+LL | fn inherent_denied_from_inner() { unsafe {} }
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:41:13
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:46:24
+ |
+LL | fn inherent_fn() { while true {} }
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:45:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:49:34
+ |
+LL | const INHERENT_CONST: i32 = {while true {} 1};
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:48:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: trait `trait_inner` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:52:7
+ |
+LL | trait trait_inner {
+ | ^^^^^^^^^^^ help: convert the identifier to upper camel case: `TraitInner`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:53:13
+ |
+LL | #![deny(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:59:30
+ |
+LL | fn denied_from_inner() { unsafe {} }
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:57:13
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:62:21
+ |
+LL | fn assoc_fn() { while true {} }
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:61:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:65:31
+ |
+LL | const ASSOC_CONST: i32 = {while true {} 1};
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:64:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: associated type `assoc_type` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:68:10
+ |
+LL | type assoc_type;
+ | ^^^^^^^^^^ help: convert the identifier to upper camel case: `AssocType`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:67:12
+ |
+LL | #[deny(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:74:30
+ |
+LL | fn denied_from_inner() { unsafe {} }
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:72:13
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:77:21
+ |
+LL | fn assoc_fn() { while true {} }
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:76:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:80:31
+ |
+LL | const ASSOC_CONST: i32 = {while true {} 1};
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:79:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:83:23
+ |
+LL | type assoc_type = (i32);
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:82:12
+ |
+LL | #[deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - type assoc_type = (i32);
+LL + type assoc_type = i32;
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:87:31
+ |
+LL | #[deny(unused_parens)]f1: (i32),
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:87:12
+ |
+LL | #[deny(unused_parens)]f1: (i32),
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - #[deny(unused_parens)]f1: (i32),
+LL + #[deny(unused_parens)]f1: i32,
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:89:42
+ |
+LL | struct StructTuple(#[deny(unused_parens)](i32));
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:89:27
+ |
+LL | struct StructTuple(#[deny(unused_parens)](i32));
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - struct StructTuple(#[deny(unused_parens)](i32));
+LL + struct StructTuple(#[deny(unused_parens)]i32);
+ |
+
+error: variant `VARIANT_CAMEL` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:93:5
+ |
+LL | VARIANT_CAMEL,
+ | ^^^^^^^^^^^^^ help: convert the identifier to upper camel case: `VariantCamel`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:92:12
+ |
+LL | #[deny(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:99:37
+ |
+LL | fn foreign_denied_from_inner(x: (i32));
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:97:13
+ |
+LL | #![deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - fn foreign_denied_from_inner(x: (i32));
+LL + fn foreign_denied_from_inner(x: i32);
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:104:37
+ |
+LL | fn foreign_denied_from_outer(x: (i32));
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:103:12
+ |
+LL | #[deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - fn foreign_denied_from_outer(x: (i32));
+LL + fn foreign_denied_from_outer(x: i32);
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:107:43
+ |
+LL | fn function(#[deny(unused_parens)] param: (i32)) {}
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:107:20
+ |
+LL | fn function(#[deny(unused_parens)] param: (i32)) {}
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - fn function(#[deny(unused_parens)] param: (i32)) {}
+LL + fn function(#[deny(unused_parens)] param: i32) {}
+ |
+
+error: type parameter `foo` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:109:42
+ |
+LL | fn generics<#[deny(non_camel_case_types)]foo>() {}
+ | ^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:109:20
+ |
+LL | fn generics<#[deny(non_camel_case_types)]foo>() {}
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary parentheses around assigned value
+ --> $DIR/lint-attr-everywhere-early.rs:115:13
+ |
+LL | let x = (1);
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:114:12
+ |
+LL | #[deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - let x = (1);
+LL + let x = 1;
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:121:50
+ |
+LL | let closure = |#[deny(unused_parens)] param: (i32)| {};
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:121:27
+ |
+LL | let closure = |#[deny(unused_parens)] param: (i32)| {};
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - let closure = |#[deny(unused_parens)] param: (i32)| {};
+LL + let closure = |#[deny(unused_parens)] param: i32| {};
+ |
+
+error: unnecessary parentheses around block return value
+ --> $DIR/lint-attr-everywhere-early.rs:125:46
+ |
+LL | let f = Match{#[deny(unused_parens)]f1: {(123)}};
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:125:26
+ |
+LL | let f = Match{#[deny(unused_parens)]f1: {(123)}};
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - let f = Match{#[deny(unused_parens)]f1: {(123)}};
+LL + let f = Match{#[deny(unused_parens)]f1: {123}};
+ |
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:132:13
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:128:17
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:133:13
+ |
+LL | while true {}
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:130:16
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:140:9
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:139:17
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:144:9
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:143:16
+ |
+LL | #[deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:149:5
+ |
+LL | unsafe {};
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:148:12
+ |
+LL | #[deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:151:27
+ |
+LL | [#[deny(unsafe_code)] unsafe {123}];
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:151:13
+ |
+LL | [#[deny(unsafe_code)] unsafe {123}];
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:152:27
+ |
+LL | (#[deny(unsafe_code)] unsafe {123},);
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:152:13
+ |
+LL | (#[deny(unsafe_code)] unsafe {123},);
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:154:31
+ |
+LL | call(#[deny(unsafe_code)] unsafe {123});
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:154:17
+ |
+LL | call(#[deny(unsafe_code)] unsafe {123});
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:156:38
+ |
+LL | TupleStruct(#[deny(unsafe_code)] unsafe {123});
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:156:24
+ |
+LL | TupleStruct(#[deny(unsafe_code)] unsafe {123});
+ | ^^^^^^^^^^^
+
+error: `...` range patterns are deprecated
+ --> $DIR/lint-attr-everywhere-early.rs:167:18
+ |
+LL | f1: 0...100,
+ | ^^^ help: use `..=` for an inclusive range
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:166:20
+ |
+LL | #[deny(ellipsis_inclusive_range_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 36 previous errors
+
diff --git a/tests/ui/lint/lint-attr-everywhere-late.rs b/tests/ui/lint/lint-attr-everywhere-late.rs
new file mode 100644
index 000000000..1055157d6
--- /dev/null
+++ b/tests/ui/lint/lint-attr-everywhere-late.rs
@@ -0,0 +1,197 @@
+// Tests that lint levels can be set for late lints.
+#![allow(
+ non_snake_case,
+ overflowing_literals,
+ missing_docs,
+ dyn_drop,
+ enum_intrinsics_non_enums,
+ clashing_extern_declarations
+)]
+
+extern crate core;
+use core::mem::{Discriminant, discriminant};
+
+// The following is a check of the lints used here to verify they do not warn
+// when allowed.
+pub fn missing_docs_allowed() {} // missing_docs
+fn dyn_drop_allowed(_x: Box<dyn Drop>) {} // dyn_drop
+fn verify_no_warnings() {
+ discriminant::<i32>(&123); // enum_intrinsics_non_enums
+ let x: u8 = 1000; // overflowing_literals
+ let NON_SNAKE_CASE = 1; // non_snake_case
+}
+mod clashing_extern_allowed {
+ extern "C" {
+ fn extern_allowed();
+ }
+}
+extern "C" {
+ fn extern_allowed(_: i32); // clashing_extern_declarations
+}
+
+// ################## Types
+
+#[deny(missing_docs)]
+pub type MissingDocType = i32; //~ ERROR missing documentation for a type alias
+
+// There aren't any late lints that I can find that can be easily used with types.
+// type BareFnPtr = fn(#[deny()]i32);
+// type BareFnPtrVariadic = extern "C" fn(i32, #[deny()]...);
+
+// ################## Items
+#[deny(missing_docs)]
+pub struct ItemOuter; //~ ERROR missing documentation for a struct
+
+pub mod module_inner { //~ ERROR missing documentation for a module
+ #![deny(missing_docs)]
+ pub fn missing_inner() {} //~ ERROR missing documentation for a function
+}
+
+pub struct Associated;
+impl Associated {
+ #![deny(missing_docs)]
+
+ pub fn inherent_denied_from_inner() {} //~ ERROR missing documentation for an associated function
+}
+
+impl Associated {
+ #[deny(missing_docs)]
+ pub fn inherent_fn() {} //~ ERROR missing documentation for an associated function
+
+ #[deny(missing_docs)]
+ pub const INHERENT_CONST: i32 = 1; //~ ERROR missing documentation for an associated constant
+}
+
+pub trait TraitInner { //~ ERROR missing documentation for a trait
+ #![deny(missing_docs)]
+}
+
+pub trait AssociatedTraitInner { //~ ERROR missing documentation for a trait
+ #![deny(missing_docs)]
+
+ fn denied_from_inner() {} //~ ERROR missing documentation for an associated function
+}
+
+pub trait AssociatedTrait {
+ fn denied_from_inner(_x: Box<dyn Drop>) {} // Used below
+
+ #[deny(missing_docs)]
+ fn assoc_fn() {} //~ ERROR missing documentation for an associated function
+
+ #[deny(missing_docs)]
+ const ASSOC_CONST: u8 = 1; //~ ERROR missing documentation for an associated constant
+
+ #[deny(missing_docs)]
+ type AssocType; //~ ERROR missing documentation for an associated type
+}
+
+struct Foo;
+
+impl AssociatedTrait for Associated {
+ #![deny(dyn_drop)]
+
+ fn denied_from_inner(_x: Box<dyn Drop>) {} //~ ERROR types that do not implement `Drop`
+
+ #[deny(enum_intrinsics_non_enums)]
+ fn assoc_fn() { discriminant::<i32>(&123); } //~ ERROR the return value of
+
+ #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000; //~ ERROR literal out of range
+ type AssocType = i32;
+}
+
+
+// There aren't any late lints that can apply to a field that I can find.
+// non_snake_case doesn't work on fields
+// struct StructFields {
+// #[deny()]f1: i32,
+// }
+// struct StructTuple(#[deny()]i32);
+
+pub enum Enum {
+ #[deny(missing_docs)]
+ Variant1, //~ ERROR missing documentation for a variant
+}
+
+mod clashing_extern {
+ extern "C" {
+ fn clashing1();
+ fn clashing2();
+ }
+}
+extern "C" {
+ #![deny(clashing_extern_declarations)]
+ fn clashing1(_: i32); //~ ERROR `clashing1` redeclared with a different signature
+}
+
+extern "C" {
+ #[deny(clashing_extern_declarations)]
+ fn clashing2(_: i32); //~ ERROR `clashing2` redeclared with a different signature
+}
+
+fn function(#[deny(non_snake_case)] PARAM: i32) {} //~ ERROR variable `PARAM` should have a snake case name
+// There aren't any late lints that can apply to generics that I can find.
+// fn generics<#[deny()]T>() {}
+
+
+// ################## Statements
+fn statements() {
+ #[deny(enum_intrinsics_non_enums)]
+ let _ = discriminant::<i32>(&123); //~ ERROR the return value of
+}
+
+
+// ################## Expressions
+fn expressions() {
+ let closure = |#[deny(non_snake_case)] PARAM: i32| {}; //~ ERROR variable `PARAM` should have a snake case name
+
+ struct Match{f1: i32}
+ // I can't find any late lints for patterns.
+ // let f = Match{#[deny()]f1: 123};
+
+ let f = Match{f1: 123};
+ match f {
+ #![deny(enum_intrinsics_non_enums)]
+ Match{f1} => {
+ discriminant::<i32>(&123); //~ ERROR the return value of
+ }
+ }
+ match f {
+ #[deny(enum_intrinsics_non_enums)]
+ Match{f1} => {
+ discriminant::<i32>(&123); //~ ERROR the return value of
+ }
+ }
+
+ // Statement Block
+ {
+ #![deny(enum_intrinsics_non_enums)]
+ discriminant::<i32>(&123); //~ ERROR the return value of
+ }
+ let block_tail = {
+ #[deny(enum_intrinsics_non_enums)]
+ discriminant::<i32>(&123); //~ ERROR the return value of
+ };
+
+ // Before expression as a statement.
+ #[deny(enum_intrinsics_non_enums)]
+ discriminant::<i32>(&123); //~ ERROR the return value of
+
+ [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)]; //~ ERROR the return value of
+ (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),); //~ ERROR the return value of
+ fn call(p: Discriminant<i32>) {}
+ call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); //~ ERROR the return value of
+ struct TupleStruct(Discriminant<i32>);
+ TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); //~ ERROR the return value of
+}
+
+
+// ################## Patterns
+fn patterns() {
+ // There aren't any late lints that I can find that apply to pattern fields.
+ //
+ // struct PatField{f1: i32, f2: i32};
+ // let f = PatField{f1: 1, f2: 2};
+ // let PatField{#[deny()]f1, #[deny()]..} = f;
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-attr-everywhere-late.stderr b/tests/ui/lint/lint-attr-everywhere-late.stderr
new file mode 100644
index 000000000..a69c2e0ef
--- /dev/null
+++ b/tests/ui/lint/lint-attr-everywhere-late.stderr
@@ -0,0 +1,428 @@
+error: missing documentation for a type alias
+ --> $DIR/lint-attr-everywhere-late.rs:35:1
+ |
+LL | pub type MissingDocType = i32;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:34:8
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a struct
+ --> $DIR/lint-attr-everywhere-late.rs:43:1
+ |
+LL | pub struct ItemOuter;
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:42:8
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a module
+ --> $DIR/lint-attr-everywhere-late.rs:45:1
+ |
+LL | pub mod module_inner {
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:46:13
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a function
+ --> $DIR/lint-attr-everywhere-late.rs:47:5
+ |
+LL | pub fn missing_inner() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+ --> $DIR/lint-attr-everywhere-late.rs:54:5
+ |
+LL | pub fn inherent_denied_from_inner() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:52:13
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+ --> $DIR/lint-attr-everywhere-late.rs:59:5
+ |
+LL | pub fn inherent_fn() {}
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:58:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an associated constant
+ --> $DIR/lint-attr-everywhere-late.rs:62:5
+ |
+LL | pub const INHERENT_CONST: i32 = 1;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:61:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a trait
+ --> $DIR/lint-attr-everywhere-late.rs:65:1
+ |
+LL | pub trait TraitInner {
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:66:13
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a trait
+ --> $DIR/lint-attr-everywhere-late.rs:69:1
+ |
+LL | pub trait AssociatedTraitInner {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:70:13
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+ --> $DIR/lint-attr-everywhere-late.rs:72:5
+ |
+LL | fn denied_from_inner() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+ --> $DIR/lint-attr-everywhere-late.rs:79:5
+ |
+LL | fn assoc_fn() {}
+ | ^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:78:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an associated constant
+ --> $DIR/lint-attr-everywhere-late.rs:82:5
+ |
+LL | const ASSOC_CONST: u8 = 1;
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:81:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an associated type
+ --> $DIR/lint-attr-everywhere-late.rs:85:5
+ |
+LL | type AssocType;
+ | ^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:84:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a variant
+ --> $DIR/lint-attr-everywhere-late.rs:112:5
+ |
+LL | Variant1,
+ | ^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:111:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: `clashing1` redeclared with a different signature
+ --> $DIR/lint-attr-everywhere-late.rs:123:5
+ |
+LL | fn clashing1();
+ | --------------- `clashing1` previously declared here
+...
+LL | fn clashing1(_: i32);
+ | ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn()`
+ found `unsafe extern "C" fn(i32)`
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:122:13
+ |
+LL | #![deny(clashing_extern_declarations)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `clashing2` redeclared with a different signature
+ --> $DIR/lint-attr-everywhere-late.rs:128:5
+ |
+LL | fn clashing2();
+ | --------------- `clashing2` previously declared here
+...
+LL | fn clashing2(_: i32);
+ | ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+ = note: expected `unsafe extern "C" fn()`
+ found `unsafe extern "C" fn(i32)`
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:127:12
+ |
+LL | #[deny(clashing_extern_declarations)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: types that do not implement `Drop` can still have drop glue, consider instead using `std::mem::needs_drop` to detect whether a type is trivially dropped
+ --> $DIR/lint-attr-everywhere-late.rs:93:38
+ |
+LL | fn denied_from_inner(_x: Box<dyn Drop>) {}
+ | ^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:91:13
+ |
+LL | #![deny(dyn_drop)]
+ | ^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:96:21
+ |
+LL | fn assoc_fn() { discriminant::<i32>(&123); }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:96:41
+ |
+LL | fn assoc_fn() { discriminant::<i32>(&123); }
+ | ^^^^
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:95:12
+ |
+LL | #[deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: literal out of range for `u8`
+ --> $DIR/lint-attr-everywhere-late.rs:98:59
+ |
+LL | #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000;
+ | ^^^^
+ |
+ = note: the literal `1000` does not fit into the type `u8` whose range is `0..=255`
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:98:12
+ |
+LL | #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000;
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: variable `PARAM` should have a snake case name
+ --> $DIR/lint-attr-everywhere-late.rs:131:37
+ |
+LL | fn function(#[deny(non_snake_case)] PARAM: i32) {}
+ | ^^^^^ help: convert the identifier to snake case: `param`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:131:20
+ |
+LL | fn function(#[deny(non_snake_case)] PARAM: i32) {}
+ | ^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:139:13
+ |
+LL | let _ = discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:139:33
+ |
+LL | let _ = discriminant::<i32>(&123);
+ | ^^^^
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:138:12
+ |
+LL | #[deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: variable `PARAM` should have a snake case name
+ --> $DIR/lint-attr-everywhere-late.rs:145:44
+ |
+LL | let closure = |#[deny(non_snake_case)] PARAM: i32| {};
+ | ^^^^^ help: convert the identifier to snake case: `param`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:145:27
+ |
+LL | let closure = |#[deny(non_snake_case)] PARAM: i32| {};
+ | ^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:155:13
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:155:33
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:153:17
+ |
+LL | #![deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:161:13
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:161:33
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:159:16
+ |
+LL | #[deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:168:9
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:168:29
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:167:17
+ |
+LL | #![deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:172:9
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:172:29
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:171:16
+ |
+LL | #[deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:177:5
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:177:25
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:176:12
+ |
+LL | #[deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:179:41
+ |
+LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:179:61
+ |
+LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+ | ^^^^
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:179:13
+ |
+LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:180:41
+ |
+LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:180:61
+ |
+LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+ | ^^^^
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:180:13
+ |
+LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:182:45
+ |
+LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:182:65
+ |
+LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:182:17
+ |
+LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:184:52
+ |
+LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:184:72
+ |
+LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:184:24
+ |
+LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 31 previous errors
+
diff --git a/tests/ui/lint/lint-attr-non-item-node.rs b/tests/ui/lint/lint-attr-non-item-node.rs
new file mode 100644
index 000000000..3f05e83a7
--- /dev/null
+++ b/tests/ui/lint/lint-attr-non-item-node.rs
@@ -0,0 +1,9 @@
+// Checks that lint attributes work on non-item AST nodes
+
+fn main() {
+ #[deny(unreachable_code)]
+ loop {
+ break;
+ "unreachable"; //~ ERROR unreachable statement
+ }
+}
diff --git a/tests/ui/lint/lint-attr-non-item-node.stderr b/tests/ui/lint/lint-attr-non-item-node.stderr
new file mode 100644
index 000000000..583579140
--- /dev/null
+++ b/tests/ui/lint/lint-attr-non-item-node.stderr
@@ -0,0 +1,16 @@
+error: unreachable statement
+ --> $DIR/lint-attr-non-item-node.rs:7:9
+ |
+LL | break;
+ | ----- any code following this expression is unreachable
+LL | "unreachable";
+ | ^^^^^^^^^^^^^^ unreachable statement
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-non-item-node.rs:4:12
+ |
+LL | #[deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-cap.rs b/tests/ui/lint/lint-cap.rs
new file mode 100644
index 000000000..461b923cc
--- /dev/null
+++ b/tests/ui/lint/lint-cap.rs
@@ -0,0 +1,8 @@
+// run-pass
+// compile-flags: --cap-lints allow
+
+#![deny(warnings)]
+
+use std::option;
+
+fn main() {}
diff --git a/tests/ui/lint/lint-change-warnings.rs b/tests/ui/lint/lint-change-warnings.rs
new file mode 100644
index 000000000..37af3b761
--- /dev/null
+++ b/tests/ui/lint/lint-change-warnings.rs
@@ -0,0 +1,21 @@
+#![deny(warnings)]
+#![allow(dead_code)]
+
+fn main() {
+ while true {} //~ ERROR: infinite
+}
+
+#[allow(warnings)]
+fn foo() {
+ while true {}
+}
+
+#[warn(warnings)]
+fn bar() {
+ while true {} //~ WARNING: infinite
+}
+
+#[forbid(warnings)]
+fn baz() {
+ while true {} //~ ERROR: infinite
+}
diff --git a/tests/ui/lint/lint-change-warnings.stderr b/tests/ui/lint/lint-change-warnings.stderr
new file mode 100644
index 000000000..3fd5283aa
--- /dev/null
+++ b/tests/ui/lint/lint-change-warnings.stderr
@@ -0,0 +1,36 @@
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-change-warnings.rs:5:5
+ |
+LL | while true {}
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-change-warnings.rs:1:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(while_true)]` implied by `#[deny(warnings)]`
+
+warning: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-change-warnings.rs:15:5
+ |
+LL | while true {}
+ | ^^^^^^^^^^ help: use `loop`
+ |
+ = note: `#[warn(while_true)]` on by default
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-change-warnings.rs:20:5
+ |
+LL | while true {}
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-change-warnings.rs:18:10
+ |
+LL | #[forbid(warnings)]
+ | ^^^^^^^^
+ = note: `#[forbid(while_true)]` implied by `#[forbid(warnings)]`
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
diff --git a/tests/ui/lint/lint-const-item-mutation.rs b/tests/ui/lint/lint-const-item-mutation.rs
new file mode 100644
index 000000000..4bf5e0a9e
--- /dev/null
+++ b/tests/ui/lint/lint-const-item-mutation.rs
@@ -0,0 +1,66 @@
+// check-pass
+
+struct MyStruct {
+ field: bool,
+ inner_array: [char; 1],
+ raw_ptr: *mut u8
+}
+impl MyStruct {
+ fn use_mut(&mut self) {}
+}
+
+struct Mutable {
+ msg: &'static str,
+}
+impl Drop for Mutable {
+ fn drop(&mut self) {
+ println!("{}", self.msg);
+ }
+}
+
+struct Mutable2 { // this one has drop glue but not a Drop impl
+ msg: &'static str,
+ other: String,
+}
+
+const ARRAY: [u8; 1] = [25];
+const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
+const RAW_PTR: *mut u8 = 1 as *mut u8;
+const MUTABLE: Mutable = Mutable { msg: "" };
+const MUTABLE2: Mutable2 = Mutable2 { msg: "", other: String::new() };
+const VEC: Vec<i32> = Vec::new();
+const PTR: *mut () = 1 as *mut _;
+const PTR_TO_ARRAY: *mut [u32; 4] = 0x12345678 as _;
+const ARRAY_OF_PTR: [*mut u32; 1] = [1 as *mut _];
+
+fn main() {
+ ARRAY[0] = 5; //~ WARN attempting to modify
+ MY_STRUCT.field = false; //~ WARN attempting to modify
+ MY_STRUCT.inner_array[0] = 'b'; //~ WARN attempting to modify
+ MY_STRUCT.use_mut(); //~ WARN taking
+ &mut MY_STRUCT; //~ WARN taking
+ (&mut MY_STRUCT).use_mut(); //~ WARN taking
+
+ // Test that we don't warn when writing through
+ // a raw pointer
+ // This is U.B., but this test is check-pass,
+ // so this never actually executes
+ unsafe {
+ *RAW_PTR = 0;
+ *MY_STRUCT.raw_ptr = 0;
+ }
+
+ MUTABLE.msg = "wow"; // no warning, because Drop observes the mutation
+ MUTABLE2.msg = "wow"; //~ WARN attempting to modify
+ VEC.push(0); //~ WARN taking a mutable reference to a `const` item
+
+ // Test that we don't warn when converting a raw pointer
+ // into a mutable reference
+ unsafe { &mut *PTR };
+
+ // Test that we don't warn when there's a dereference involved.
+ // If we ever 'leave' the const via a deference, we're going
+ // to end up modifying something other than the temporary
+ unsafe { (*PTR_TO_ARRAY)[0] = 1 };
+ unsafe { *ARRAY_OF_PTR[0] = 25; }
+}
diff --git a/tests/ui/lint/lint-const-item-mutation.stderr b/tests/ui/lint/lint-const-item-mutation.stderr
new file mode 100644
index 000000000..747c38b80
--- /dev/null
+++ b/tests/ui/lint/lint-const-item-mutation.stderr
@@ -0,0 +1,118 @@
+warning: attempting to modify a `const` item
+ --> $DIR/lint-const-item-mutation.rs:37:5
+ |
+LL | ARRAY[0] = 5;
+ | ^^^^^^^^^^^^
+ |
+ = note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified
+note: `const` item defined here
+ --> $DIR/lint-const-item-mutation.rs:26:1
+ |
+LL | const ARRAY: [u8; 1] = [25];
+ | ^^^^^^^^^^^^^^^^^^^^
+ = note: `#[warn(const_item_mutation)]` on by default
+
+warning: attempting to modify a `const` item
+ --> $DIR/lint-const-item-mutation.rs:38:5
+ |
+LL | MY_STRUCT.field = false;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified
+note: `const` item defined here
+ --> $DIR/lint-const-item-mutation.rs:27:1
+ |
+LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: attempting to modify a `const` item
+ --> $DIR/lint-const-item-mutation.rs:39:5
+ |
+LL | MY_STRUCT.inner_array[0] = 'b';
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified
+note: `const` item defined here
+ --> $DIR/lint-const-item-mutation.rs:27:1
+ |
+LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: taking a mutable reference to a `const` item
+ --> $DIR/lint-const-item-mutation.rs:40:5
+ |
+LL | MY_STRUCT.use_mut();
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: each usage of a `const` item creates a new temporary
+ = note: the mutable reference will refer to this temporary, not the original `const` item
+note: mutable reference created due to call to this method
+ --> $DIR/lint-const-item-mutation.rs:9:5
+ |
+LL | fn use_mut(&mut self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^
+note: `const` item defined here
+ --> $DIR/lint-const-item-mutation.rs:27:1
+ |
+LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: taking a mutable reference to a `const` item
+ --> $DIR/lint-const-item-mutation.rs:41:5
+ |
+LL | &mut MY_STRUCT;
+ | ^^^^^^^^^^^^^^
+ |
+ = note: each usage of a `const` item creates a new temporary
+ = note: the mutable reference will refer to this temporary, not the original `const` item
+note: `const` item defined here
+ --> $DIR/lint-const-item-mutation.rs:27:1
+ |
+LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: taking a mutable reference to a `const` item
+ --> $DIR/lint-const-item-mutation.rs:42:5
+ |
+LL | (&mut MY_STRUCT).use_mut();
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: each usage of a `const` item creates a new temporary
+ = note: the mutable reference will refer to this temporary, not the original `const` item
+note: `const` item defined here
+ --> $DIR/lint-const-item-mutation.rs:27:1
+ |
+LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: attempting to modify a `const` item
+ --> $DIR/lint-const-item-mutation.rs:54:5
+ |
+LL | MUTABLE2.msg = "wow";
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified
+note: `const` item defined here
+ --> $DIR/lint-const-item-mutation.rs:30:1
+ |
+LL | const MUTABLE2: Mutable2 = Mutable2 { msg: "", other: String::new() };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: taking a mutable reference to a `const` item
+ --> $DIR/lint-const-item-mutation.rs:55:5
+ |
+LL | VEC.push(0);
+ | ^^^^^^^^^^^
+ |
+ = note: each usage of a `const` item creates a new temporary
+ = note: the mutable reference will refer to this temporary, not the original `const` item
+note: mutable reference created due to call to this method
+ --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+note: `const` item defined here
+ --> $DIR/lint-const-item-mutation.rs:31:1
+ |
+LL | const VEC: Vec<i32> = Vec::new();
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: 8 warnings emitted
+
diff --git a/tests/ui/lint/lint-ctypes-66202.rs b/tests/ui/lint/lint-ctypes-66202.rs
new file mode 100644
index 000000000..ebab41d14
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-66202.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+#![deny(improper_ctypes)]
+
+// This test checks that return types are normalized before being checked for FFI-safety, and that
+// transparent newtype wrappers are FFI-safe if the type being wrapped is FFI-safe.
+
+#[repr(transparent)]
+pub struct W<T>(T);
+
+extern "C" {
+ pub fn bare() -> ();
+ pub fn normalize() -> <() as ToOwned>::Owned;
+ pub fn transparent() -> W<()>;
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-73249-1.rs b/tests/ui/lint/lint-ctypes-73249-1.rs
new file mode 100644
index 000000000..cf416c3fe
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-73249-1.rs
@@ -0,0 +1,21 @@
+// check-pass
+#![deny(improper_ctypes)]
+
+pub trait Foo {
+ type Assoc: 'static;
+}
+
+impl Foo for () {
+ type Assoc = u32;
+}
+
+extern "C" {
+ pub fn lint_me(x: Bar<()>);
+}
+
+#[repr(transparent)]
+pub struct Bar<T: Foo> {
+ value: &'static <T as Foo>::Assoc,
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-73249-2.rs b/tests/ui/lint/lint-ctypes-73249-2.rs
new file mode 100644
index 000000000..691047c8a
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-73249-2.rs
@@ -0,0 +1,29 @@
+#![feature(type_alias_impl_trait)]
+#![deny(improper_ctypes)]
+
+pub trait Baz {}
+
+impl Baz for () {}
+
+type Qux = impl Baz;
+
+fn assign() -> Qux {}
+
+pub trait Foo {
+ type Assoc: 'static;
+}
+
+impl Foo for () {
+ type Assoc = Qux;
+}
+
+#[repr(transparent)]
+pub struct A<T: Foo> {
+ x: &'static <T as Foo>::Assoc,
+}
+
+extern "C" {
+ pub fn lint_me() -> A<()>; //~ ERROR: uses type `Qux`
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-73249-2.stderr b/tests/ui/lint/lint-ctypes-73249-2.stderr
new file mode 100644
index 000000000..8073c33dd
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-73249-2.stderr
@@ -0,0 +1,15 @@
+error: `extern` block uses type `Qux`, which is not FFI-safe
+ --> $DIR/lint-ctypes-73249-2.rs:26:25
+ |
+LL | pub fn lint_me() -> A<()>;
+ | ^^^^^ not FFI-safe
+ |
+ = note: opaque types have no C equivalent
+note: the lint level is defined here
+ --> $DIR/lint-ctypes-73249-2.rs:2:9
+ |
+LL | #![deny(improper_ctypes)]
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-ctypes-73249-3.rs b/tests/ui/lint/lint-ctypes-73249-3.rs
new file mode 100644
index 000000000..ef8ab7e03
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-73249-3.rs
@@ -0,0 +1,23 @@
+#![feature(type_alias_impl_trait)]
+#![deny(improper_ctypes)]
+
+pub trait Baz {}
+
+impl Baz for u32 {}
+
+type Qux = impl Baz;
+
+fn assign() -> Qux {
+ 3
+}
+
+#[repr(C)]
+pub struct A {
+ x: Qux,
+}
+
+extern "C" {
+ pub fn lint_me() -> A; //~ ERROR: uses type `Qux`
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-73249-3.stderr b/tests/ui/lint/lint-ctypes-73249-3.stderr
new file mode 100644
index 000000000..c41ce666d
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-73249-3.stderr
@@ -0,0 +1,15 @@
+error: `extern` block uses type `Qux`, which is not FFI-safe
+ --> $DIR/lint-ctypes-73249-3.rs:20:25
+ |
+LL | pub fn lint_me() -> A;
+ | ^ not FFI-safe
+ |
+ = note: opaque types have no C equivalent
+note: the lint level is defined here
+ --> $DIR/lint-ctypes-73249-3.rs:2:9
+ |
+LL | #![deny(improper_ctypes)]
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-ctypes-73249-4.rs b/tests/ui/lint/lint-ctypes-73249-4.rs
new file mode 100644
index 000000000..6c72bd691
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-73249-4.rs
@@ -0,0 +1,24 @@
+// check-pass
+#![deny(improper_ctypes)]
+
+use std::marker::PhantomData;
+
+trait Foo {
+ type Assoc;
+}
+
+impl Foo for () {
+ type Assoc = PhantomData<()>;
+}
+
+#[repr(transparent)]
+struct Wow<T> where T: Foo<Assoc = PhantomData<T>> {
+ x: <T as Foo>::Assoc,
+ v: u32,
+}
+
+extern "C" {
+ fn test(v: Wow<()>);
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-73249-5.rs b/tests/ui/lint/lint-ctypes-73249-5.rs
new file mode 100644
index 000000000..083fb6c5f
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-73249-5.rs
@@ -0,0 +1,23 @@
+#![feature(type_alias_impl_trait)]
+#![deny(improper_ctypes)]
+
+pub trait Baz {}
+
+impl Baz for u32 {}
+
+type Qux = impl Baz;
+
+fn assign() -> Qux {
+ 3
+}
+
+#[repr(transparent)]
+pub struct A {
+ x: Qux,
+}
+
+extern "C" {
+ pub fn lint_me() -> A; //~ ERROR: uses type `Qux`
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-73249-5.stderr b/tests/ui/lint/lint-ctypes-73249-5.stderr
new file mode 100644
index 000000000..98245c4f1
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-73249-5.stderr
@@ -0,0 +1,15 @@
+error: `extern` block uses type `Qux`, which is not FFI-safe
+ --> $DIR/lint-ctypes-73249-5.rs:20:25
+ |
+LL | pub fn lint_me() -> A;
+ | ^ not FFI-safe
+ |
+ = note: opaque types have no C equivalent
+note: the lint level is defined here
+ --> $DIR/lint-ctypes-73249-5.rs:2:9
+ |
+LL | #![deny(improper_ctypes)]
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-ctypes-73249.rs b/tests/ui/lint/lint-ctypes-73249.rs
new file mode 100644
index 000000000..5b48fa9b7
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-73249.rs
@@ -0,0 +1,21 @@
+// check-pass
+#![deny(improper_ctypes)]
+
+pub trait Foo {
+ type Assoc;
+}
+
+impl Foo for () {
+ type Assoc = u32;
+}
+
+extern "C" {
+ pub fn lint_me(x: Bar<()>);
+}
+
+#[repr(transparent)]
+pub struct Bar<T: Foo> {
+ value: <T as Foo>::Assoc,
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-73251-1.rs b/tests/ui/lint/lint-ctypes-73251-1.rs
new file mode 100644
index 000000000..145ba784f
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-73251-1.rs
@@ -0,0 +1,26 @@
+#![feature(type_alias_impl_trait)]
+#![deny(improper_ctypes)]
+
+pub trait Baz {}
+
+impl Baz for u32 {}
+
+type Qux = impl Baz;
+
+pub trait Foo {
+ type Assoc;
+}
+
+impl Foo for u32 {
+ type Assoc = Qux;
+}
+
+fn assign() -> Qux {
+ 1
+}
+
+extern "C" {
+ pub fn lint_me() -> <u32 as Foo>::Assoc; //~ ERROR: uses type `Qux`
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-73251-1.stderr b/tests/ui/lint/lint-ctypes-73251-1.stderr
new file mode 100644
index 000000000..9f43576ad
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-73251-1.stderr
@@ -0,0 +1,15 @@
+error: `extern` block uses type `Qux`, which is not FFI-safe
+ --> $DIR/lint-ctypes-73251-1.rs:23:25
+ |
+LL | pub fn lint_me() -> <u32 as Foo>::Assoc;
+ | ^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = note: opaque types have no C equivalent
+note: the lint level is defined here
+ --> $DIR/lint-ctypes-73251-1.rs:2:9
+ |
+LL | #![deny(improper_ctypes)]
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-ctypes-73251-2.rs b/tests/ui/lint/lint-ctypes-73251-2.rs
new file mode 100644
index 000000000..df71a9457
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-73251-2.rs
@@ -0,0 +1,39 @@
+#![feature(type_alias_impl_trait)]
+#![deny(improper_ctypes)]
+
+pub trait TraitA {
+ type Assoc;
+}
+
+impl TraitA for u32 {
+ type Assoc = u32;
+}
+
+pub trait TraitB {
+ type Assoc;
+}
+
+impl<T> TraitB for T
+where
+ T: TraitA,
+{
+ type Assoc = <T as TraitA>::Assoc;
+}
+
+type AliasA = impl TraitA<Assoc = u32>;
+
+type AliasB = impl TraitB<Assoc = AliasA>;
+
+fn use_of_a() -> AliasA {
+ 3
+}
+
+fn use_of_b() -> AliasB {
+ 3
+}
+
+extern "C" {
+ pub fn lint_me() -> <AliasB as TraitB>::Assoc; //~ ERROR: uses type `AliasA`
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-73251-2.stderr b/tests/ui/lint/lint-ctypes-73251-2.stderr
new file mode 100644
index 000000000..0b3de379c
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-73251-2.stderr
@@ -0,0 +1,15 @@
+error: `extern` block uses type `AliasA`, which is not FFI-safe
+ --> $DIR/lint-ctypes-73251-2.rs:36:25
+ |
+LL | pub fn lint_me() -> <AliasB as TraitB>::Assoc;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = note: opaque types have no C equivalent
+note: the lint level is defined here
+ --> $DIR/lint-ctypes-73251-2.rs:2:9
+ |
+LL | #![deny(improper_ctypes)]
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-ctypes-73251.rs b/tests/ui/lint/lint-ctypes-73251.rs
new file mode 100644
index 000000000..ebc2ca77b
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-73251.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![deny(improper_ctypes)]
+
+pub trait Foo {
+ type Assoc;
+}
+
+impl Foo for () {
+ type Assoc = u32;
+}
+
+type Bar = impl Foo<Assoc = u32>;
+
+fn assign() -> Bar {}
+
+extern "C" {
+ pub fn lint_me() -> <Bar as Foo>::Assoc;
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-73747.rs b/tests/ui/lint/lint-ctypes-73747.rs
new file mode 100644
index 000000000..293ffd5c2
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-73747.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+#[repr(transparent)]
+struct NonNullRawComPtr<T: ComInterface> {
+ inner: std::ptr::NonNull<<T as ComInterface>::VTable>,
+}
+
+trait ComInterface {
+ type VTable;
+}
+
+extern "C" fn invoke<T: ComInterface>(_: Option<NonNullRawComPtr<T>>) {}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-enum.rs b/tests/ui/lint/lint-ctypes-enum.rs
new file mode 100644
index 000000000..7c2060805
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-enum.rs
@@ -0,0 +1,92 @@
+#![feature(transparent_unions)]
+#![feature(ptr_internals)]
+#![deny(improper_ctypes)]
+#![allow(dead_code)]
+
+use std::num;
+
+enum Z {}
+enum U {
+ A,
+}
+enum B {
+ C,
+ D,
+}
+enum T {
+ E,
+ F,
+ G,
+}
+
+#[repr(C)]
+enum ReprC {
+ A,
+ B,
+ C,
+}
+
+#[repr(u8)]
+enum U8 {
+ A,
+ B,
+ C,
+}
+
+#[repr(isize)]
+enum Isize {
+ A,
+ B,
+ C,
+}
+
+#[repr(transparent)]
+struct TransparentStruct<T>(T, std::marker::PhantomData<Z>);
+
+#[repr(transparent)]
+enum TransparentEnum<T> {
+ Variant(T, std::marker::PhantomData<Z>),
+}
+
+#[repr(transparent)]
+union TransparentUnion<T: Copy> {
+ field: T,
+}
+
+struct Rust<T>(T);
+
+extern "C" {
+ fn zf(x: Z);
+ fn uf(x: U); //~ ERROR `extern` block uses type `U`
+ fn bf(x: B); //~ ERROR `extern` block uses type `B`
+ fn tf(x: T); //~ ERROR `extern` block uses type `T`
+ fn repr_c(x: ReprC);
+ fn repr_u8(x: U8);
+ fn repr_isize(x: Isize);
+ fn option_ref(x: Option<&'static u8>);
+ fn option_fn(x: Option<extern "C" fn()>);
+ fn nonnull(x: Option<std::ptr::NonNull<u8>>);
+ fn unique(x: Option<std::ptr::Unique<u8>>);
+ fn nonzero_u8(x: Option<num::NonZeroU8>);
+ fn nonzero_u16(x: Option<num::NonZeroU16>);
+ fn nonzero_u32(x: Option<num::NonZeroU32>);
+ fn nonzero_u64(x: Option<num::NonZeroU64>);
+ fn nonzero_u128(x: Option<num::NonZeroU128>);
+ //~^ ERROR `extern` block uses type `u128`
+ fn nonzero_usize(x: Option<num::NonZeroUsize>);
+ fn nonzero_i8(x: Option<num::NonZeroI8>);
+ fn nonzero_i16(x: Option<num::NonZeroI16>);
+ fn nonzero_i32(x: Option<num::NonZeroI32>);
+ fn nonzero_i64(x: Option<num::NonZeroI64>);
+ fn nonzero_i128(x: Option<num::NonZeroI128>);
+ //~^ ERROR `extern` block uses type `i128`
+ fn nonzero_isize(x: Option<num::NonZeroIsize>);
+ fn transparent_struct(x: Option<TransparentStruct<num::NonZeroU8>>);
+ fn transparent_enum(x: Option<TransparentEnum<num::NonZeroU8>>);
+ fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
+ //~^ ERROR `extern` block uses type
+ fn repr_rust(x: Option<Rust<num::NonZeroU8>>); //~ ERROR `extern` block uses type
+ fn no_result(x: Result<(), num::NonZeroI32>); //~ ERROR `extern` block uses type
+}
+
+pub fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-enum.stderr b/tests/ui/lint/lint-ctypes-enum.stderr
new file mode 100644
index 000000000..8554e2617
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-enum.stderr
@@ -0,0 +1,92 @@
+error: `extern` block uses type `U`, which is not FFI-safe
+ --> $DIR/lint-ctypes-enum.rs:60:13
+ |
+LL | fn uf(x: U);
+ | ^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+ = note: enum has no representation hint
+note: the type is defined here
+ --> $DIR/lint-ctypes-enum.rs:9:1
+ |
+LL | enum U {
+ | ^^^^^^
+note: the lint level is defined here
+ --> $DIR/lint-ctypes-enum.rs:3:9
+ |
+LL | #![deny(improper_ctypes)]
+ | ^^^^^^^^^^^^^^^
+
+error: `extern` block uses type `B`, which is not FFI-safe
+ --> $DIR/lint-ctypes-enum.rs:61:13
+ |
+LL | fn bf(x: B);
+ | ^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+ = note: enum has no representation hint
+note: the type is defined here
+ --> $DIR/lint-ctypes-enum.rs:12:1
+ |
+LL | enum B {
+ | ^^^^^^
+
+error: `extern` block uses type `T`, which is not FFI-safe
+ --> $DIR/lint-ctypes-enum.rs:62:13
+ |
+LL | fn tf(x: T);
+ | ^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+ = note: enum has no representation hint
+note: the type is defined here
+ --> $DIR/lint-ctypes-enum.rs:16:1
+ |
+LL | enum T {
+ | ^^^^^^
+
+error: `extern` block uses type `u128`, which is not FFI-safe
+ --> $DIR/lint-ctypes-enum.rs:74:23
+ |
+LL | fn nonzero_u128(x: Option<num::NonZeroU128>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` block uses type `i128`, which is not FFI-safe
+ --> $DIR/lint-ctypes-enum.rs:81:23
+ |
+LL | fn nonzero_i128(x: Option<num::NonZeroI128>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` block uses type `Option<TransparentUnion<NonZeroU8>>`, which is not FFI-safe
+ --> $DIR/lint-ctypes-enum.rs:86:28
+ |
+LL | fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+ = note: enum has no representation hint
+
+error: `extern` block uses type `Option<Rust<NonZeroU8>>`, which is not FFI-safe
+ --> $DIR/lint-ctypes-enum.rs:88:20
+ |
+LL | fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+ = note: enum has no representation hint
+
+error: `extern` block uses type `Result<(), NonZeroI32>`, which is not FFI-safe
+ --> $DIR/lint-ctypes-enum.rs:89:20
+ |
+LL | fn no_result(x: Result<(), num::NonZeroI32>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+ = note: enum has no representation hint
+
+error: aborting due to 8 previous errors
+
diff --git a/tests/ui/lint/lint-ctypes-fn.rs b/tests/ui/lint/lint-ctypes-fn.rs
new file mode 100644
index 000000000..d3b36a9d5
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-fn.rs
@@ -0,0 +1,196 @@
+#![feature(rustc_private)]
+
+#![allow(private_in_public)]
+#![deny(improper_ctypes_definitions)]
+
+extern crate libc;
+
+use std::default::Default;
+use std::marker::PhantomData;
+
+trait Trait {}
+
+trait Mirror { type It: ?Sized; }
+
+impl<T: ?Sized> Mirror for T { type It = Self; }
+
+#[repr(C)]
+pub struct StructWithProjection(*mut <StructWithProjection as Mirror>::It);
+
+#[repr(C)]
+pub struct StructWithProjectionAndLifetime<'a>(
+ &'a mut <StructWithProjectionAndLifetime<'a> as Mirror>::It
+);
+
+pub type I32Pair = (i32, i32);
+
+#[repr(C)]
+pub struct ZeroSize;
+
+pub type RustFn = fn();
+
+pub type RustBadRet = extern "C" fn() -> Box<u32>;
+
+pub type CVoidRet = ();
+
+pub struct Foo;
+
+#[repr(transparent)]
+pub struct TransparentI128(i128);
+
+#[repr(transparent)]
+pub struct TransparentStr(&'static str);
+
+#[repr(transparent)]
+pub struct TransparentBadFn(RustBadRet);
+
+#[repr(transparent)]
+pub struct TransparentInt(u32);
+
+#[repr(transparent)]
+pub struct TransparentRef<'a>(&'a TransparentInt);
+
+#[repr(transparent)]
+pub struct TransparentLifetime<'a>(*const u8, PhantomData<&'a ()>);
+
+#[repr(transparent)]
+pub struct TransparentUnit<U>(f32, PhantomData<U>);
+
+#[repr(transparent)]
+pub struct TransparentCustomZst(i32, ZeroSize);
+
+#[repr(C)]
+pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
+
+pub extern "C" fn ptr_type1(size: *const Foo) { }
+
+pub extern "C" fn ptr_type2(size: *const Foo) { }
+
+pub extern "C" fn ptr_unit(p: *const ()) { }
+
+pub extern "C" fn ptr_tuple(p: *const ((),)) { }
+
+pub extern "C" fn slice_type(p: &[u32]) { }
+//~^ ERROR: uses type `[u32]`
+
+pub extern "C" fn str_type(p: &str) { }
+//~^ ERROR: uses type `str`
+
+pub extern "C" fn box_type(p: Box<u32>) { }
+
+pub extern "C" fn opt_box_type(p: Option<Box<u32>>) { }
+
+pub extern "C" fn boxed_slice(p: Box<[u8]>) { }
+//~^ ERROR: uses type `Box<[u8]>`
+
+pub extern "C" fn boxed_string(p: Box<str>) { }
+//~^ ERROR: uses type `Box<str>`
+
+pub extern "C" fn boxed_trait(p: Box<dyn Trait>) { }
+//~^ ERROR: uses type `Box<dyn Trait>`
+
+pub extern "C" fn char_type(p: char) { }
+//~^ ERROR uses type `char`
+
+pub extern "C" fn i128_type(p: i128) { }
+//~^ ERROR uses type `i128`
+
+pub extern "C" fn u128_type(p: u128) { }
+//~^ ERROR uses type `u128`
+
+pub extern "C" fn tuple_type(p: (i32, i32)) { }
+//~^ ERROR uses type `(i32, i32)`
+
+pub extern "C" fn tuple_type2(p: I32Pair) { }
+//~^ ERROR uses type `(i32, i32)`
+
+pub extern "C" fn zero_size(p: ZeroSize) { }
+//~^ ERROR uses type `ZeroSize`
+
+pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
+//~^ ERROR uses type `ZeroSizeWithPhantomData`
+
+pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
+//~^ ERROR uses type `PhantomData<bool>`
+ Default::default()
+}
+
+pub extern "C" fn fn_type(p: RustFn) { }
+//~^ ERROR uses type `fn()`
+
+pub extern "C" fn fn_type2(p: fn()) { }
+//~^ ERROR uses type `fn()`
+
+pub extern "C" fn fn_contained(p: RustBadRet) { }
+
+pub extern "C" fn transparent_i128(p: TransparentI128) { }
+//~^ ERROR: uses type `i128`
+
+pub extern "C" fn transparent_str(p: TransparentStr) { }
+//~^ ERROR: uses type `str`
+
+pub extern "C" fn transparent_fn(p: TransparentBadFn) { }
+
+pub extern "C" fn good3(fptr: Option<extern "C" fn()>) { }
+
+pub extern "C" fn good4(aptr: &[u8; 4 as usize]) { }
+
+pub extern "C" fn good5(s: StructWithProjection) { }
+
+pub extern "C" fn good6(s: StructWithProjectionAndLifetime) { }
+
+pub extern "C" fn good7(fptr: extern "C" fn() -> ()) { }
+
+pub extern "C" fn good8(fptr: extern "C" fn() -> !) { }
+
+pub extern "C" fn good9() -> () { }
+
+pub extern "C" fn good10() -> CVoidRet { }
+
+pub extern "C" fn good11(size: isize) { }
+
+pub extern "C" fn good12(size: usize) { }
+
+pub extern "C" fn good13(n: TransparentInt) { }
+
+pub extern "C" fn good14(p: TransparentRef) { }
+
+pub extern "C" fn good15(p: TransparentLifetime) { }
+
+pub extern "C" fn good16(p: TransparentUnit<ZeroSize>) { }
+
+pub extern "C" fn good17(p: TransparentCustomZst) { }
+
+#[allow(improper_ctypes_definitions)]
+pub extern "C" fn good18(_: &String) { }
+
+#[cfg(not(target_arch = "wasm32"))]
+pub extern "C" fn good1(size: *const libc::c_int) { }
+
+#[cfg(not(target_arch = "wasm32"))]
+pub extern "C" fn good2(size: *const libc::c_uint) { }
+
+pub extern "C" fn unused_generic1<T>(size: *const Foo) { }
+
+pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
+//~^ ERROR uses type `PhantomData<bool>`
+ Default::default()
+}
+
+pub extern "C" fn used_generic1<T>(x: T) { }
+
+pub extern "C" fn used_generic2<T>(x: T, size: *const Foo) { }
+
+pub extern "C" fn used_generic3<T: Default>() -> T {
+ Default::default()
+}
+
+pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
+//~^ ERROR: uses type `Vec<T>`
+
+pub extern "C" fn used_generic5<T>() -> Vec<T> {
+//~^ ERROR: uses type `Vec<T>`
+ Default::default()
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-fn.stderr b/tests/ui/lint/lint-ctypes-fn.stderr
new file mode 100644
index 000000000..a05206bf1
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-fn.stderr
@@ -0,0 +1,188 @@
+error: `extern` fn uses type `[u32]`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:73:33
+ |
+LL | pub extern "C" fn slice_type(p: &[u32]) { }
+ | ^^^^^^ not FFI-safe
+ |
+ = help: consider using a raw pointer instead
+ = note: slices have no C equivalent
+note: the lint level is defined here
+ --> $DIR/lint-ctypes-fn.rs:4:9
+ |
+LL | #![deny(improper_ctypes_definitions)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `str`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:76:31
+ |
+LL | pub extern "C" fn str_type(p: &str) { }
+ | ^^^^ not FFI-safe
+ |
+ = help: consider using `*const u8` and a length instead
+ = note: string slices have no C equivalent
+
+error: `extern` fn uses type `Box<[u8]>`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:83:34
+ |
+LL | pub extern "C" fn boxed_slice(p: Box<[u8]>) { }
+ | ^^^^^^^^^ not FFI-safe
+ |
+ = note: box cannot be represented as a single pointer
+
+error: `extern` fn uses type `Box<str>`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:86:35
+ |
+LL | pub extern "C" fn boxed_string(p: Box<str>) { }
+ | ^^^^^^^^ not FFI-safe
+ |
+ = note: box cannot be represented as a single pointer
+
+error: `extern` fn uses type `Box<dyn Trait>`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:89:34
+ |
+LL | pub extern "C" fn boxed_trait(p: Box<dyn Trait>) { }
+ | ^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = note: box cannot be represented as a single pointer
+
+error: `extern` fn uses type `char`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:92:32
+ |
+LL | pub extern "C" fn char_type(p: char) { }
+ | ^^^^ not FFI-safe
+ |
+ = help: consider using `u32` or `libc::wchar_t` instead
+ = note: the `char` type has no C equivalent
+
+error: `extern` fn uses type `i128`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:95:32
+ |
+LL | pub extern "C" fn i128_type(p: i128) { }
+ | ^^^^ not FFI-safe
+ |
+ = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` fn uses type `u128`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:98:32
+ |
+LL | pub extern "C" fn u128_type(p: u128) { }
+ | ^^^^ not FFI-safe
+ |
+ = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:101:33
+ |
+LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
+ | ^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider using a struct instead
+ = note: tuples have unspecified layout
+
+error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:104:34
+ |
+LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
+ | ^^^^^^^ not FFI-safe
+ |
+ = help: consider using a struct instead
+ = note: tuples have unspecified layout
+
+error: `extern` fn uses type `ZeroSize`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:107:32
+ |
+LL | pub extern "C" fn zero_size(p: ZeroSize) { }
+ | ^^^^^^^^ not FFI-safe
+ |
+ = help: consider adding a member to this struct
+ = note: this struct has no fields
+note: the type is defined here
+ --> $DIR/lint-ctypes-fn.rs:28:1
+ |
+LL | pub struct ZeroSize;
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:110:40
+ |
+LL | pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
+ | ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = note: composed only of `PhantomData`
+note: the type is defined here
+ --> $DIR/lint-ctypes-fn.rs:63:1
+ |
+LL | pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `PhantomData<bool>`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:113:51
+ |
+LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
+ | ^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = note: composed only of `PhantomData`
+
+error: `extern` fn uses type `fn()`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:118:30
+ |
+LL | pub extern "C" fn fn_type(p: RustFn) { }
+ | ^^^^^^ not FFI-safe
+ |
+ = help: consider using an `extern fn(...) -> ...` function pointer instead
+ = note: this function pointer has Rust-specific calling convention
+
+error: `extern` fn uses type `fn()`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:121:31
+ |
+LL | pub extern "C" fn fn_type2(p: fn()) { }
+ | ^^^^ not FFI-safe
+ |
+ = help: consider using an `extern fn(...) -> ...` function pointer instead
+ = note: this function pointer has Rust-specific calling convention
+
+error: `extern` fn uses type `i128`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:126:39
+ |
+LL | pub extern "C" fn transparent_i128(p: TransparentI128) { }
+ | ^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` fn uses type `str`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:129:38
+ |
+LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
+ | ^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider using `*const u8` and a length instead
+ = note: string slices have no C equivalent
+
+error: `extern` fn uses type `PhantomData<bool>`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:175:43
+ |
+LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
+ | ^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = note: composed only of `PhantomData`
+
+error: `extern` fn uses type `Vec<T>`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:188:39
+ |
+LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
+ | ^^^^^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+ = note: this struct has unspecified layout
+
+error: `extern` fn uses type `Vec<T>`, which is not FFI-safe
+ --> $DIR/lint-ctypes-fn.rs:191:41
+ |
+LL | pub extern "C" fn used_generic5<T>() -> Vec<T> {
+ | ^^^^^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+ = note: this struct has unspecified layout
+
+error: aborting due to 20 previous errors
+
diff --git a/tests/ui/lint/lint-ctypes.rs b/tests/ui/lint/lint-ctypes.rs
new file mode 100644
index 000000000..9165e14b7
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes.rs
@@ -0,0 +1,118 @@
+#![feature(rustc_private)]
+
+#![allow(private_in_public)]
+#![deny(improper_ctypes)]
+
+extern crate libc;
+
+use std::cell::UnsafeCell;
+use std::marker::PhantomData;
+
+trait Bar { }
+trait Mirror { type It: ?Sized; }
+impl<T: ?Sized> Mirror for T { type It = Self; }
+#[repr(C)]
+pub struct StructWithProjection(*mut <StructWithProjection as Mirror>::It);
+#[repr(C)]
+pub struct StructWithProjectionAndLifetime<'a>(
+ &'a mut <StructWithProjectionAndLifetime<'a> as Mirror>::It
+);
+pub type I32Pair = (i32, i32);
+#[repr(C)]
+pub struct ZeroSize;
+pub type RustFn = fn();
+pub type RustBadRet = extern "C" fn() -> Box<u32>;
+pub type CVoidRet = ();
+pub struct Foo;
+#[repr(transparent)]
+pub struct TransparentI128(i128);
+#[repr(transparent)]
+pub struct TransparentStr(&'static str);
+#[repr(transparent)]
+pub struct TransparentBadFn(RustBadRet);
+#[repr(transparent)]
+pub struct TransparentInt(u32);
+#[repr(transparent)]
+pub struct TransparentRef<'a>(&'a TransparentInt);
+#[repr(transparent)]
+pub struct TransparentLifetime<'a>(*const u8, PhantomData<&'a ()>);
+#[repr(transparent)]
+pub struct TransparentUnit<U>(f32, PhantomData<U>);
+#[repr(transparent)]
+pub struct TransparentCustomZst(i32, ZeroSize);
+
+#[repr(C)]
+pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData<i32>);
+
+extern "C" {
+ pub fn ptr_type1(size: *const Foo); //~ ERROR: uses type `Foo`
+ pub fn ptr_type2(size: *const Foo); //~ ERROR: uses type `Foo`
+ pub fn ptr_unit(p: *const ());
+ pub fn ptr_tuple(p: *const ((),)); //~ ERROR: uses type `((),)`
+ pub fn slice_type(p: &[u32]); //~ ERROR: uses type `[u32]`
+ pub fn str_type(p: &str); //~ ERROR: uses type `str`
+ pub fn box_type(p: Box<u32>); //~ ERROR uses type `Box<u32>`
+ pub fn opt_box_type(p: Option<Box<u32>>);
+ //~^ ERROR uses type `Option<Box<u32>>`
+ pub fn char_type(p: char); //~ ERROR uses type `char`
+ pub fn i128_type(p: i128); //~ ERROR uses type `i128`
+ pub fn u128_type(p: u128); //~ ERROR uses type `u128`
+ pub fn trait_type(p: &dyn Bar); //~ ERROR uses type `dyn Bar`
+ pub fn tuple_type(p: (i32, i32)); //~ ERROR uses type `(i32, i32)`
+ pub fn tuple_type2(p: I32Pair); //~ ERROR uses type `(i32, i32)`
+ pub fn zero_size(p: ZeroSize); //~ ERROR uses type `ZeroSize`
+ pub fn zero_size_phantom(p: ZeroSizeWithPhantomData);
+ //~^ ERROR uses type `ZeroSizeWithPhantomData`
+ pub fn zero_size_phantom_toplevel()
+ -> ::std::marker::PhantomData<bool>; //~ ERROR uses type `PhantomData<bool>`
+ pub fn fn_type(p: RustFn); //~ ERROR uses type `fn()`
+ pub fn fn_type2(p: fn()); //~ ERROR uses type `fn()`
+ pub fn fn_contained(p: RustBadRet); //~ ERROR: uses type `Box<u32>`
+ pub fn transparent_i128(p: TransparentI128); //~ ERROR: uses type `i128`
+ pub fn transparent_str(p: TransparentStr); //~ ERROR: uses type `str`
+ pub fn transparent_fn(p: TransparentBadFn); //~ ERROR: uses type `Box<u32>`
+ pub fn raw_array(arr: [u8; 8]); //~ ERROR: uses type `[u8; 8]`
+
+ pub fn no_niche_a(a: Option<UnsafeCell<extern fn()>>);
+ //~^ ERROR: uses type `Option<UnsafeCell<extern "C" fn()>>`
+ pub fn no_niche_b(b: Option<UnsafeCell<&i32>>);
+ //~^ ERROR: uses type `Option<UnsafeCell<&i32>>`
+
+ pub static static_u128_type: u128; //~ ERROR: uses type `u128`
+ pub static static_u128_array_type: [u128; 16]; //~ ERROR: uses type `u128`
+
+ pub fn good3(fptr: Option<extern "C" fn()>);
+ pub fn good4(aptr: &[u8; 4 as usize]);
+ pub fn good5(s: StructWithProjection);
+ pub fn good6(s: StructWithProjectionAndLifetime);
+ pub fn good7(fptr: extern "C" fn() -> ());
+ pub fn good8(fptr: extern "C" fn() -> !);
+ pub fn good9() -> ();
+ pub fn good10() -> CVoidRet;
+ pub fn good11(size: isize);
+ pub fn good12(size: usize);
+ pub fn good13(n: TransparentInt);
+ pub fn good14(p: TransparentRef);
+ pub fn good15(p: TransparentLifetime);
+ pub fn good16(p: TransparentUnit<ZeroSize>);
+ pub fn good17(p: TransparentCustomZst);
+ #[allow(improper_ctypes)]
+ pub fn good18(_: &String);
+ pub fn good20(arr: *const [u8; 8]);
+ pub static good21: [u8; 8];
+
+}
+
+#[allow(improper_ctypes)]
+extern "C" {
+ pub fn good19(_: &String);
+}
+
+#[cfg(not(target_arch = "wasm32"))]
+extern "C" {
+ pub fn good1(size: *const libc::c_int);
+ pub fn good2(size: *const libc::c_uint);
+}
+
+fn main() {
+}
diff --git a/tests/ui/lint/lint-ctypes.stderr b/tests/ui/lint/lint-ctypes.stderr
new file mode 100644
index 000000000..121ad0ce8
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes.stderr
@@ -0,0 +1,262 @@
+error: `extern` block uses type `Foo`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:48:28
+ |
+LL | pub fn ptr_type1(size: *const Foo);
+ | ^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+ = note: this struct has unspecified layout
+note: the type is defined here
+ --> $DIR/lint-ctypes.rs:26:1
+ |
+LL | pub struct Foo;
+ | ^^^^^^^^^^^^^^
+note: the lint level is defined here
+ --> $DIR/lint-ctypes.rs:4:9
+ |
+LL | #![deny(improper_ctypes)]
+ | ^^^^^^^^^^^^^^^
+
+error: `extern` block uses type `Foo`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:49:28
+ |
+LL | pub fn ptr_type2(size: *const Foo);
+ | ^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+ = note: this struct has unspecified layout
+note: the type is defined here
+ --> $DIR/lint-ctypes.rs:26:1
+ |
+LL | pub struct Foo;
+ | ^^^^^^^^^^^^^^
+
+error: `extern` block uses type `((),)`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:51:25
+ |
+LL | pub fn ptr_tuple(p: *const ((),));
+ | ^^^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider using a struct instead
+ = note: tuples have unspecified layout
+
+error: `extern` block uses type `[u32]`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:52:26
+ |
+LL | pub fn slice_type(p: &[u32]);
+ | ^^^^^^ not FFI-safe
+ |
+ = help: consider using a raw pointer instead
+ = note: slices have no C equivalent
+
+error: `extern` block uses type `str`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:53:24
+ |
+LL | pub fn str_type(p: &str);
+ | ^^^^ not FFI-safe
+ |
+ = help: consider using `*const u8` and a length instead
+ = note: string slices have no C equivalent
+
+error: `extern` block uses type `Box<u32>`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:54:24
+ |
+LL | pub fn box_type(p: Box<u32>);
+ | ^^^^^^^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+ = note: this struct has unspecified layout
+
+error: `extern` block uses type `Option<Box<u32>>`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:55:28
+ |
+LL | pub fn opt_box_type(p: Option<Box<u32>>);
+ | ^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+ = note: enum has no representation hint
+
+error: `extern` block uses type `char`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:57:25
+ |
+LL | pub fn char_type(p: char);
+ | ^^^^ not FFI-safe
+ |
+ = help: consider using `u32` or `libc::wchar_t` instead
+ = note: the `char` type has no C equivalent
+
+error: `extern` block uses type `i128`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:58:25
+ |
+LL | pub fn i128_type(p: i128);
+ | ^^^^ not FFI-safe
+ |
+ = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` block uses type `u128`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:59:25
+ |
+LL | pub fn u128_type(p: u128);
+ | ^^^^ not FFI-safe
+ |
+ = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` block uses type `dyn Bar`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:60:26
+ |
+LL | pub fn trait_type(p: &dyn Bar);
+ | ^^^^^^^^ not FFI-safe
+ |
+ = note: trait objects have no C equivalent
+
+error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:61:26
+ |
+LL | pub fn tuple_type(p: (i32, i32));
+ | ^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider using a struct instead
+ = note: tuples have unspecified layout
+
+error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:62:27
+ |
+LL | pub fn tuple_type2(p: I32Pair);
+ | ^^^^^^^ not FFI-safe
+ |
+ = help: consider using a struct instead
+ = note: tuples have unspecified layout
+
+error: `extern` block uses type `ZeroSize`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:63:25
+ |
+LL | pub fn zero_size(p: ZeroSize);
+ | ^^^^^^^^ not FFI-safe
+ |
+ = help: consider adding a member to this struct
+ = note: this struct has no fields
+note: the type is defined here
+ --> $DIR/lint-ctypes.rs:22:1
+ |
+LL | pub struct ZeroSize;
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: `extern` block uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:64:33
+ |
+LL | pub fn zero_size_phantom(p: ZeroSizeWithPhantomData);
+ | ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = note: composed only of `PhantomData`
+note: the type is defined here
+ --> $DIR/lint-ctypes.rs:45:1
+ |
+LL | pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData<i32>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `extern` block uses type `PhantomData<bool>`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:67:12
+ |
+LL | -> ::std::marker::PhantomData<bool>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = note: composed only of `PhantomData`
+
+error: `extern` block uses type `fn()`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:68:23
+ |
+LL | pub fn fn_type(p: RustFn);
+ | ^^^^^^ not FFI-safe
+ |
+ = help: consider using an `extern fn(...) -> ...` function pointer instead
+ = note: this function pointer has Rust-specific calling convention
+
+error: `extern` block uses type `fn()`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:69:24
+ |
+LL | pub fn fn_type2(p: fn());
+ | ^^^^ not FFI-safe
+ |
+ = help: consider using an `extern fn(...) -> ...` function pointer instead
+ = note: this function pointer has Rust-specific calling convention
+
+error: `extern` block uses type `Box<u32>`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:70:28
+ |
+LL | pub fn fn_contained(p: RustBadRet);
+ | ^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+ = note: this struct has unspecified layout
+
+error: `extern` block uses type `i128`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:71:32
+ |
+LL | pub fn transparent_i128(p: TransparentI128);
+ | ^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` block uses type `str`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:72:31
+ |
+LL | pub fn transparent_str(p: TransparentStr);
+ | ^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider using `*const u8` and a length instead
+ = note: string slices have no C equivalent
+
+error: `extern` block uses type `Box<u32>`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:73:30
+ |
+LL | pub fn transparent_fn(p: TransparentBadFn);
+ | ^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+ = note: this struct has unspecified layout
+
+error: `extern` block uses type `[u8; 8]`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:74:27
+ |
+LL | pub fn raw_array(arr: [u8; 8]);
+ | ^^^^^^^ not FFI-safe
+ |
+ = help: consider passing a pointer to the array
+ = note: passing raw arrays by value is not FFI-safe
+
+error: `extern` block uses type `Option<UnsafeCell<extern "C" fn()>>`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:76:26
+ |
+LL | pub fn no_niche_a(a: Option<UnsafeCell<extern fn()>>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+ = note: enum has no representation hint
+
+error: `extern` block uses type `Option<UnsafeCell<&i32>>`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:78:26
+ |
+LL | pub fn no_niche_b(b: Option<UnsafeCell<&i32>>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+ = note: enum has no representation hint
+
+error: `extern` block uses type `u128`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:81:34
+ |
+LL | pub static static_u128_type: u128;
+ | ^^^^ not FFI-safe
+ |
+ = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` block uses type `u128`, which is not FFI-safe
+ --> $DIR/lint-ctypes.rs:82:40
+ |
+LL | pub static static_u128_array_type: [u128; 16];
+ | ^^^^^^^^^^ not FFI-safe
+ |
+ = note: 128-bit integers don't currently have a known stable ABI
+
+error: aborting due to 27 previous errors
+
diff --git a/tests/ui/lint/lint-deref-nullptr.rs b/tests/ui/lint/lint-deref-nullptr.rs
new file mode 100644
index 000000000..d052dbd9b
--- /dev/null
+++ b/tests/ui/lint/lint-deref-nullptr.rs
@@ -0,0 +1,38 @@
+// test the deref_nullptr lint
+
+#![deny(deref_nullptr)]
+
+use std::ptr;
+
+struct Struct {
+ field: u8,
+}
+
+fn f() {
+ unsafe {
+ let a = 1;
+ let ub = *(a as *const i32);
+ let ub = *(0 as *const i32);
+ //~^ ERROR dereferencing a null pointer
+ let ub = *ptr::null::<i32>();
+ //~^ ERROR dereferencing a null pointer
+ let ub = *ptr::null_mut::<i32>();
+ //~^ ERROR dereferencing a null pointer
+ let ub = *(ptr::null::<i16>() as *const i32);
+ //~^ ERROR dereferencing a null pointer
+ let ub = *(ptr::null::<i16>() as *mut i32 as *mut usize as *const u8);
+ //~^ ERROR dereferencing a null pointer
+ let ub = &*ptr::null::<i32>();
+ //~^ ERROR dereferencing a null pointer
+ let ub = &*ptr::null_mut::<i32>();
+ //~^ ERROR dereferencing a null pointer
+ ptr::addr_of!(*ptr::null::<i32>());
+ //~^ ERROR dereferencing a null pointer
+ ptr::addr_of_mut!(*ptr::null_mut::<i32>());
+ //~^ ERROR dereferencing a null pointer
+ let offset = ptr::addr_of!((*ptr::null::<Struct>()).field);
+ //~^ ERROR dereferencing a null pointer
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-deref-nullptr.stderr b/tests/ui/lint/lint-deref-nullptr.stderr
new file mode 100644
index 000000000..c6f432e4e
--- /dev/null
+++ b/tests/ui/lint/lint-deref-nullptr.stderr
@@ -0,0 +1,68 @@
+error: dereferencing a null pointer
+ --> $DIR/lint-deref-nullptr.rs:15:18
+ |
+LL | let ub = *(0 as *const i32);
+ | ^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
+ |
+note: the lint level is defined here
+ --> $DIR/lint-deref-nullptr.rs:3:9
+ |
+LL | #![deny(deref_nullptr)]
+ | ^^^^^^^^^^^^^
+
+error: dereferencing a null pointer
+ --> $DIR/lint-deref-nullptr.rs:17:18
+ |
+LL | let ub = *ptr::null::<i32>();
+ | ^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
+
+error: dereferencing a null pointer
+ --> $DIR/lint-deref-nullptr.rs:19:18
+ |
+LL | let ub = *ptr::null_mut::<i32>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
+
+error: dereferencing a null pointer
+ --> $DIR/lint-deref-nullptr.rs:21:18
+ |
+LL | let ub = *(ptr::null::<i16>() as *const i32);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
+
+error: dereferencing a null pointer
+ --> $DIR/lint-deref-nullptr.rs:23:18
+ |
+LL | let ub = *(ptr::null::<i16>() as *mut i32 as *mut usize as *const u8);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
+
+error: dereferencing a null pointer
+ --> $DIR/lint-deref-nullptr.rs:25:19
+ |
+LL | let ub = &*ptr::null::<i32>();
+ | ^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
+
+error: dereferencing a null pointer
+ --> $DIR/lint-deref-nullptr.rs:27:19
+ |
+LL | let ub = &*ptr::null_mut::<i32>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
+
+error: dereferencing a null pointer
+ --> $DIR/lint-deref-nullptr.rs:29:23
+ |
+LL | ptr::addr_of!(*ptr::null::<i32>());
+ | ^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
+
+error: dereferencing a null pointer
+ --> $DIR/lint-deref-nullptr.rs:31:27
+ |
+LL | ptr::addr_of_mut!(*ptr::null_mut::<i32>());
+ | ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
+
+error: dereferencing a null pointer
+ --> $DIR/lint-deref-nullptr.rs:33:36
+ |
+LL | let offset = ptr::addr_of!((*ptr::null::<Struct>()).field);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
+
+error: aborting due to 10 previous errors
+
diff --git a/tests/ui/lint/lint-directives-on-use-items-issue-10534.rs b/tests/ui/lint/lint-directives-on-use-items-issue-10534.rs
new file mode 100644
index 000000000..e5cb0d3df
--- /dev/null
+++ b/tests/ui/lint/lint-directives-on-use-items-issue-10534.rs
@@ -0,0 +1,24 @@
+#![deny(unused_imports)]
+#![allow(non_upper_case_globals)]
+
+// The aim of this test is to ensure that deny/allow/warn directives
+// are applied to individual "use" statements instead of silently
+// ignored.
+
+#[allow(dead_code)]
+mod a { pub static x: isize = 3; pub static y: isize = 4; }
+
+mod b {
+ use a::x; //~ ERROR: unused import
+ #[allow(unused_imports)]
+ use a::y; // no error here
+}
+
+#[allow(unused_imports)]
+mod c {
+ use a::x;
+ #[deny(unused_imports)]
+ use a::y; //~ ERROR: unused import
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-directives-on-use-items-issue-10534.stderr b/tests/ui/lint/lint-directives-on-use-items-issue-10534.stderr
new file mode 100644
index 000000000..ccb139e0e
--- /dev/null
+++ b/tests/ui/lint/lint-directives-on-use-items-issue-10534.stderr
@@ -0,0 +1,26 @@
+error: unused import: `a::x`
+ --> $DIR/lint-directives-on-use-items-issue-10534.rs:12:9
+ |
+LL | use a::x;
+ | ^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-directives-on-use-items-issue-10534.rs:1:9
+ |
+LL | #![deny(unused_imports)]
+ | ^^^^^^^^^^^^^^
+
+error: unused import: `a::y`
+ --> $DIR/lint-directives-on-use-items-issue-10534.rs:21:9
+ |
+LL | use a::y;
+ | ^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-directives-on-use-items-issue-10534.rs:20:12
+ |
+LL | #[deny(unused_imports)]
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/lint-enum-intrinsics-non-enums.rs b/tests/ui/lint/lint-enum-intrinsics-non-enums.rs
new file mode 100644
index 000000000..8ad337064
--- /dev/null
+++ b/tests/ui/lint/lint-enum-intrinsics-non-enums.rs
@@ -0,0 +1,67 @@
+// Test the enum_intrinsics_non_enums lint.
+
+#![feature(variant_count)]
+
+use std::mem::{discriminant, variant_count};
+
+enum SomeEnum {
+ A,
+ B,
+}
+
+struct SomeStruct;
+
+fn generic_discriminant<T>(v: &T) {
+ discriminant::<T>(v);
+}
+
+fn generic_variant_count<T>() -> usize {
+ variant_count::<T>()
+}
+
+fn test_discriminant() {
+ discriminant(&SomeEnum::A);
+ generic_discriminant(&SomeEnum::B);
+
+ discriminant(&());
+ //~^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+
+ discriminant(&&SomeEnum::B);
+ //~^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+
+ discriminant(&SomeStruct);
+ //~^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+
+ discriminant(&123u32);
+ //~^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+
+ discriminant(&&123i8);
+ //~^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+}
+
+fn test_variant_count() {
+ variant_count::<SomeEnum>();
+ generic_variant_count::<SomeEnum>();
+
+ variant_count::<&str>();
+ //~^ error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+
+ variant_count::<*const u8>();
+ //~^ error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+
+ variant_count::<()>();
+ //~^ error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+
+ variant_count::<&SomeEnum>();
+ //~^ error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+}
+
+fn main() {
+ test_discriminant();
+ test_variant_count();
+
+ // The lint ignores cases where the type is generic, so these should be
+ // allowed even though their return values are unspecified
+ generic_variant_count::<SomeStruct>();
+ generic_discriminant::<SomeStruct>(&SomeStruct);
+}
diff --git a/tests/ui/lint/lint-enum-intrinsics-non-enums.stderr b/tests/ui/lint/lint-enum-intrinsics-non-enums.stderr
new file mode 100644
index 000000000..63ed2503c
--- /dev/null
+++ b/tests/ui/lint/lint-enum-intrinsics-non-enums.stderr
@@ -0,0 +1,95 @@
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-enum-intrinsics-non-enums.rs:26:5
+ |
+LL | discriminant(&());
+ | ^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `()`, which is not an enum.
+ --> $DIR/lint-enum-intrinsics-non-enums.rs:26:18
+ |
+LL | discriminant(&());
+ | ^^^
+ = note: `#[deny(enum_intrinsics_non_enums)]` on by default
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-enum-intrinsics-non-enums.rs:29:5
+ |
+LL | discriminant(&&SomeEnum::B);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `&SomeEnum`, which is not an enum.
+ --> $DIR/lint-enum-intrinsics-non-enums.rs:29:18
+ |
+LL | discriminant(&&SomeEnum::B);
+ | ^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-enum-intrinsics-non-enums.rs:32:5
+ |
+LL | discriminant(&SomeStruct);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `SomeStruct`, which is not an enum.
+ --> $DIR/lint-enum-intrinsics-non-enums.rs:32:18
+ |
+LL | discriminant(&SomeStruct);
+ | ^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-enum-intrinsics-non-enums.rs:35:5
+ |
+LL | discriminant(&123u32);
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `u32`, which is not an enum.
+ --> $DIR/lint-enum-intrinsics-non-enums.rs:35:18
+ |
+LL | discriminant(&123u32);
+ | ^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-enum-intrinsics-non-enums.rs:38:5
+ |
+LL | discriminant(&&123i8);
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `&i8`, which is not an enum.
+ --> $DIR/lint-enum-intrinsics-non-enums.rs:38:18
+ |
+LL | discriminant(&&123i8);
+ | ^^^^^^^
+
+error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+ --> $DIR/lint-enum-intrinsics-non-enums.rs:46:5
+ |
+LL | variant_count::<&str>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the type parameter of `variant_count` should be an enum, but it was instantiated with the type `&str`, which is not an enum.
+
+error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+ --> $DIR/lint-enum-intrinsics-non-enums.rs:49:5
+ |
+LL | variant_count::<*const u8>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the type parameter of `variant_count` should be an enum, but it was instantiated with the type `*const u8`, which is not an enum.
+
+error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+ --> $DIR/lint-enum-intrinsics-non-enums.rs:52:5
+ |
+LL | variant_count::<()>();
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the type parameter of `variant_count` should be an enum, but it was instantiated with the type `()`, which is not an enum.
+
+error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+ --> $DIR/lint-enum-intrinsics-non-enums.rs:55:5
+ |
+LL | variant_count::<&SomeEnum>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the type parameter of `variant_count` should be an enum, but it was instantiated with the type `&SomeEnum`, which is not an enum.
+
+error: aborting due to 9 previous errors
+
diff --git a/tests/ui/lint/lint-exceeding-bitshifts.noopt.stderr b/tests/ui/lint/lint-exceeding-bitshifts.noopt.stderr
new file mode 100644
index 000000000..3a84c6c1f
--- /dev/null
+++ b/tests/ui/lint/lint-exceeding-bitshifts.noopt.stderr
@@ -0,0 +1,152 @@
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:18:20
+ |
+LL | const N: i32 = T::N << 42;
+ | ^^^^^^^^^^ attempt to shift left by `42_i32`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/lint-exceeding-bitshifts.rs:10:9
+ |
+LL | #![warn(arithmetic_overflow)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:22:13
+ |
+LL | let _ = x << 42;
+ | ^^^^^^^ attempt to shift left by `42_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:27:15
+ |
+LL | let n = 1u8 << 8;
+ | ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:29:15
+ |
+LL | let n = 1u16 << 16;
+ | ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:31:15
+ |
+LL | let n = 1u32 << 32;
+ | ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:33:15
+ |
+LL | let n = 1u64 << 64;
+ | ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:35:15
+ |
+LL | let n = 1i8 << 8;
+ | ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:37:15
+ |
+LL | let n = 1i16 << 16;
+ | ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:39:15
+ |
+LL | let n = 1i32 << 32;
+ | ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:41:15
+ |
+LL | let n = 1i64 << 64;
+ | ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:44:15
+ |
+LL | let n = 1u8 >> 8;
+ | ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:46:15
+ |
+LL | let n = 1u16 >> 16;
+ | ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:48:15
+ |
+LL | let n = 1u32 >> 32;
+ | ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:50:15
+ |
+LL | let n = 1u64 >> 64;
+ | ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:52:15
+ |
+LL | let n = 1i8 >> 8;
+ | ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:54:15
+ |
+LL | let n = 1i16 >> 16;
+ | ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:56:15
+ |
+LL | let n = 1i32 >> 32;
+ | ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:58:15
+ |
+LL | let n = 1i64 >> 64;
+ | ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:62:15
+ |
+LL | let n = n << 8;
+ | ^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:64:15
+ |
+LL | let n = 1u8 << -8;
+ | ^^^^^^^^^ attempt to shift left by `-8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:69:15
+ |
+LL | let n = 1u8 << (4+4);
+ | ^^^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:71:15
+ |
+LL | let n = 1i64 >> [64][0];
+ | ^^^^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:77:15
+ |
+LL | let n = 1_isize << BITS;
+ | ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:78:15
+ |
+LL | let n = 1_usize << BITS;
+ | ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+warning: 24 warnings emitted
+
diff --git a/tests/ui/lint/lint-exceeding-bitshifts.opt.stderr b/tests/ui/lint/lint-exceeding-bitshifts.opt.stderr
new file mode 100644
index 000000000..3a84c6c1f
--- /dev/null
+++ b/tests/ui/lint/lint-exceeding-bitshifts.opt.stderr
@@ -0,0 +1,152 @@
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:18:20
+ |
+LL | const N: i32 = T::N << 42;
+ | ^^^^^^^^^^ attempt to shift left by `42_i32`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/lint-exceeding-bitshifts.rs:10:9
+ |
+LL | #![warn(arithmetic_overflow)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:22:13
+ |
+LL | let _ = x << 42;
+ | ^^^^^^^ attempt to shift left by `42_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:27:15
+ |
+LL | let n = 1u8 << 8;
+ | ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:29:15
+ |
+LL | let n = 1u16 << 16;
+ | ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:31:15
+ |
+LL | let n = 1u32 << 32;
+ | ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:33:15
+ |
+LL | let n = 1u64 << 64;
+ | ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:35:15
+ |
+LL | let n = 1i8 << 8;
+ | ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:37:15
+ |
+LL | let n = 1i16 << 16;
+ | ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:39:15
+ |
+LL | let n = 1i32 << 32;
+ | ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:41:15
+ |
+LL | let n = 1i64 << 64;
+ | ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:44:15
+ |
+LL | let n = 1u8 >> 8;
+ | ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:46:15
+ |
+LL | let n = 1u16 >> 16;
+ | ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:48:15
+ |
+LL | let n = 1u32 >> 32;
+ | ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:50:15
+ |
+LL | let n = 1u64 >> 64;
+ | ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:52:15
+ |
+LL | let n = 1i8 >> 8;
+ | ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:54:15
+ |
+LL | let n = 1i16 >> 16;
+ | ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:56:15
+ |
+LL | let n = 1i32 >> 32;
+ | ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:58:15
+ |
+LL | let n = 1i64 >> 64;
+ | ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:62:15
+ |
+LL | let n = n << 8;
+ | ^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:64:15
+ |
+LL | let n = 1u8 << -8;
+ | ^^^^^^^^^ attempt to shift left by `-8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:69:15
+ |
+LL | let n = 1u8 << (4+4);
+ | ^^^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:71:15
+ |
+LL | let n = 1i64 >> [64][0];
+ | ^^^^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:77:15
+ |
+LL | let n = 1_isize << BITS;
+ | ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:78:15
+ |
+LL | let n = 1_usize << BITS;
+ | ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+warning: 24 warnings emitted
+
diff --git a/tests/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr b/tests/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr
new file mode 100644
index 000000000..3a84c6c1f
--- /dev/null
+++ b/tests/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr
@@ -0,0 +1,152 @@
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:18:20
+ |
+LL | const N: i32 = T::N << 42;
+ | ^^^^^^^^^^ attempt to shift left by `42_i32`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/lint-exceeding-bitshifts.rs:10:9
+ |
+LL | #![warn(arithmetic_overflow)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:22:13
+ |
+LL | let _ = x << 42;
+ | ^^^^^^^ attempt to shift left by `42_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:27:15
+ |
+LL | let n = 1u8 << 8;
+ | ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:29:15
+ |
+LL | let n = 1u16 << 16;
+ | ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:31:15
+ |
+LL | let n = 1u32 << 32;
+ | ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:33:15
+ |
+LL | let n = 1u64 << 64;
+ | ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:35:15
+ |
+LL | let n = 1i8 << 8;
+ | ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:37:15
+ |
+LL | let n = 1i16 << 16;
+ | ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:39:15
+ |
+LL | let n = 1i32 << 32;
+ | ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:41:15
+ |
+LL | let n = 1i64 << 64;
+ | ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:44:15
+ |
+LL | let n = 1u8 >> 8;
+ | ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:46:15
+ |
+LL | let n = 1u16 >> 16;
+ | ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:48:15
+ |
+LL | let n = 1u32 >> 32;
+ | ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:50:15
+ |
+LL | let n = 1u64 >> 64;
+ | ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:52:15
+ |
+LL | let n = 1i8 >> 8;
+ | ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:54:15
+ |
+LL | let n = 1i16 >> 16;
+ | ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:56:15
+ |
+LL | let n = 1i32 >> 32;
+ | ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:58:15
+ |
+LL | let n = 1i64 >> 64;
+ | ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:62:15
+ |
+LL | let n = n << 8;
+ | ^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:64:15
+ |
+LL | let n = 1u8 << -8;
+ | ^^^^^^^^^ attempt to shift left by `-8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:69:15
+ |
+LL | let n = 1u8 << (4+4);
+ | ^^^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:71:15
+ |
+LL | let n = 1i64 >> [64][0];
+ | ^^^^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:77:15
+ |
+LL | let n = 1_isize << BITS;
+ | ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+warning: this arithmetic operation will overflow
+ --> $DIR/lint-exceeding-bitshifts.rs:78:15
+ |
+LL | let n = 1_usize << BITS;
+ | ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+warning: 24 warnings emitted
+
diff --git a/tests/ui/lint/lint-exceeding-bitshifts.rs b/tests/ui/lint/lint-exceeding-bitshifts.rs
new file mode 100644
index 000000000..048c1aff8
--- /dev/null
+++ b/tests/ui/lint/lint-exceeding-bitshifts.rs
@@ -0,0 +1,79 @@
+// revisions: noopt opt opt_with_overflow_checks
+//[noopt]compile-flags: -C opt-level=0
+//[opt]compile-flags: -O
+//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
+// build-pass
+// ignore-pass (test emits codegen-time warnings and verifies that they are not errors)
+// normalize-stderr-test "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which"
+
+#![crate_type="lib"]
+#![warn(arithmetic_overflow)]
+
+
+pub trait Foo {
+ const N: i32;
+}
+
+impl<T: Foo> Foo for Vec<T> {
+ const N: i32 = T::N << 42; //~ WARN: arithmetic operation will overflow
+}
+
+pub fn foo(x: i32) {
+ let _ = x << 42; //~ WARN: arithmetic operation will overflow
+}
+
+pub fn main() {
+ let n = 1u8 << 7;
+ let n = 1u8 << 8; //~ WARN: arithmetic operation will overflow
+ let n = 1u16 << 15;
+ let n = 1u16 << 16; //~ WARN: arithmetic operation will overflow
+ let n = 1u32 << 31;
+ let n = 1u32 << 32; //~ WARN: arithmetic operation will overflow
+ let n = 1u64 << 63;
+ let n = 1u64 << 64; //~ WARN: arithmetic operation will overflow
+ let n = 1i8 << 7;
+ let n = 1i8 << 8; //~ WARN: arithmetic operation will overflow
+ let n = 1i16 << 15;
+ let n = 1i16 << 16; //~ WARN: arithmetic operation will overflow
+ let n = 1i32 << 31;
+ let n = 1i32 << 32; //~ WARN: arithmetic operation will overflow
+ let n = 1i64 << 63;
+ let n = 1i64 << 64; //~ WARN: arithmetic operation will overflow
+
+ let n = 1u8 >> 7;
+ let n = 1u8 >> 8; //~ WARN: arithmetic operation will overflow
+ let n = 1u16 >> 15;
+ let n = 1u16 >> 16; //~ WARN: arithmetic operation will overflow
+ let n = 1u32 >> 31;
+ let n = 1u32 >> 32; //~ WARN: arithmetic operation will overflow
+ let n = 1u64 >> 63;
+ let n = 1u64 >> 64; //~ WARN: arithmetic operation will overflow
+ let n = 1i8 >> 7;
+ let n = 1i8 >> 8; //~ WARN: arithmetic operation will overflow
+ let n = 1i16 >> 15;
+ let n = 1i16 >> 16; //~ WARN: arithmetic operation will overflow
+ let n = 1i32 >> 31;
+ let n = 1i32 >> 32; //~ WARN: arithmetic operation will overflow
+ let n = 1i64 >> 63;
+ let n = 1i64 >> 64; //~ WARN: arithmetic operation will overflow
+
+ let n = 1u8;
+ let n = n << 7;
+ let n = n << 8; //~ WARN: arithmetic operation will overflow
+
+ let n = 1u8 << -8; //~ WARN: arithmetic operation will overflow
+
+ let n = 1i8<<(1isize+-1);
+
+ let n = 1u8 << (4+3);
+ let n = 1u8 << (4+4); //~ WARN: arithmetic operation will overflow
+ let n = 1i64 >> [63][0];
+ let n = 1i64 >> [64][0]; //~ WARN: arithmetic operation will overflow
+
+ #[cfg(target_pointer_width = "32")]
+ const BITS: usize = 32;
+ #[cfg(target_pointer_width = "64")]
+ const BITS: usize = 64;
+ let n = 1_isize << BITS; //~ WARN: arithmetic operation will overflow
+ let n = 1_usize << BITS; //~ WARN: arithmetic operation will overflow
+}
diff --git a/tests/ui/lint/lint-expr-stmt-attrs-for-early-lints.rs b/tests/ui/lint/lint-expr-stmt-attrs-for-early-lints.rs
new file mode 100644
index 000000000..07a32904a
--- /dev/null
+++ b/tests/ui/lint/lint-expr-stmt-attrs-for-early-lints.rs
@@ -0,0 +1,14 @@
+// run-pass
+
+#![feature(stmt_expr_attributes)]
+#![deny(unused_parens)]
+
+// Tests that lint attributes on statements/expressions are
+// correctly applied to non-builtin early (AST) lints
+
+fn main() {
+ #[allow(unused_parens)]
+ {
+ let _ = (9);
+ }
+}
diff --git a/tests/ui/lint/lint-ffi-safety-all-phantom.rs b/tests/ui/lint/lint-ffi-safety-all-phantom.rs
new file mode 100644
index 000000000..7419d3458
--- /dev/null
+++ b/tests/ui/lint/lint-ffi-safety-all-phantom.rs
@@ -0,0 +1,22 @@
+// This is a regression test for issue https://github.com/rust-lang/rust/issues/106629.
+// It ensures that transparent types where all fields are PhantomData are marked as
+// FFI-safe.
+
+// check-pass
+
+#[repr(transparent)]
+#[derive(Copy, Clone)]
+struct MyPhantom(core::marker::PhantomData<u8>);
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct Bar {
+ pub x: i32,
+ _marker: MyPhantom,
+}
+
+extern "C" {
+ pub fn foo(bar: *mut Bar);
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-forbid-attr.rs b/tests/ui/lint/lint-forbid-attr.rs
new file mode 100644
index 000000000..6d4cfd834
--- /dev/null
+++ b/tests/ui/lint/lint-forbid-attr.rs
@@ -0,0 +1,7 @@
+#![forbid(deprecated)]
+
+#[allow(deprecated)]
+//~^ ERROR allow(deprecated) incompatible
+//~| ERROR allow(deprecated) incompatible
+fn main() {
+}
diff --git a/tests/ui/lint/lint-forbid-attr.stderr b/tests/ui/lint/lint-forbid-attr.stderr
new file mode 100644
index 000000000..5977b9c94
--- /dev/null
+++ b/tests/ui/lint/lint-forbid-attr.stderr
@@ -0,0 +1,21 @@
+error[E0453]: allow(deprecated) incompatible with previous forbid
+ --> $DIR/lint-forbid-attr.rs:3:9
+ |
+LL | #![forbid(deprecated)]
+ | ---------- `forbid` level set here
+LL |
+LL | #[allow(deprecated)]
+ | ^^^^^^^^^^ overruled by previous forbid
+
+error[E0453]: allow(deprecated) incompatible with previous forbid
+ --> $DIR/lint-forbid-attr.rs:3:9
+ |
+LL | #![forbid(deprecated)]
+ | ---------- `forbid` level set here
+LL |
+LL | #[allow(deprecated)]
+ | ^^^^^^^^^^ overruled by previous forbid
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0453`.
diff --git a/tests/ui/lint/lint-forbid-cmdline.rs b/tests/ui/lint/lint-forbid-cmdline.rs
new file mode 100644
index 000000000..5246ccb57
--- /dev/null
+++ b/tests/ui/lint/lint-forbid-cmdline.rs
@@ -0,0 +1,6 @@
+// compile-flags: -F deprecated
+
+#[allow(deprecated)] //~ ERROR allow(deprecated) incompatible
+ //~| ERROR allow(deprecated) incompatible
+fn main() {
+}
diff --git a/tests/ui/lint/lint-forbid-cmdline.stderr b/tests/ui/lint/lint-forbid-cmdline.stderr
new file mode 100644
index 000000000..0a92e58c0
--- /dev/null
+++ b/tests/ui/lint/lint-forbid-cmdline.stderr
@@ -0,0 +1,19 @@
+error[E0453]: allow(deprecated) incompatible with previous forbid
+ --> $DIR/lint-forbid-cmdline.rs:3:9
+ |
+LL | #[allow(deprecated)]
+ | ^^^^^^^^^^ overruled by previous forbid
+ |
+ = note: `forbid` lint level was set on command line
+
+error[E0453]: allow(deprecated) incompatible with previous forbid
+ --> $DIR/lint-forbid-cmdline.rs:3:9
+ |
+LL | #[allow(deprecated)]
+ | ^^^^^^^^^^ overruled by previous forbid
+ |
+ = note: `forbid` lint level was set on command line
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0453`.
diff --git a/tests/ui/lint/lint-forbid-internal-unsafe.rs b/tests/ui/lint/lint-forbid-internal-unsafe.rs
new file mode 100644
index 000000000..3ee55ba96
--- /dev/null
+++ b/tests/ui/lint/lint-forbid-internal-unsafe.rs
@@ -0,0 +1,17 @@
+#![forbid(unsafe_code)]
+#![feature(allow_internal_unsafe)]
+
+#[allow_internal_unsafe]
+//~^ ERROR: `allow_internal_unsafe` allows defining
+macro_rules! evil {
+ ($e:expr) => {
+ unsafe {
+ $e
+ }
+ }
+}
+
+fn main() {
+ println!("{}", evil!(*(0 as *const u8)));
+ //~^ WARNING dereferencing a null pointer
+}
diff --git a/tests/ui/lint/lint-forbid-internal-unsafe.stderr b/tests/ui/lint/lint-forbid-internal-unsafe.stderr
new file mode 100644
index 000000000..ba425ceb4
--- /dev/null
+++ b/tests/ui/lint/lint-forbid-internal-unsafe.stderr
@@ -0,0 +1,22 @@
+error: `allow_internal_unsafe` allows defining macros using unsafe without triggering the `unsafe_code` lint at their call site
+ --> $DIR/lint-forbid-internal-unsafe.rs:4:1
+ |
+LL | #[allow_internal_unsafe]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-forbid-internal-unsafe.rs:1:11
+ |
+LL | #![forbid(unsafe_code)]
+ | ^^^^^^^^^^^
+
+warning: dereferencing a null pointer
+ --> $DIR/lint-forbid-internal-unsafe.rs:15:26
+ |
+LL | println!("{}", evil!(*(0 as *const u8)));
+ | ^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
+ |
+ = note: `#[warn(deref_nullptr)]` on by default
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/tests/ui/lint/lint-group-nonstandard-style.rs b/tests/ui/lint/lint-group-nonstandard-style.rs
new file mode 100644
index 000000000..bd7f327bc
--- /dev/null
+++ b/tests/ui/lint/lint-group-nonstandard-style.rs
@@ -0,0 +1,26 @@
+#![deny(nonstandard_style)]
+#![allow(dead_code)]
+
+fn CamelCase() {} //~ ERROR should have a snake
+
+#[allow(nonstandard_style)]
+mod test {
+ fn CamelCase() {}
+
+ #[forbid(nonstandard_style)]
+ mod bad {
+ fn CamelCase() {} //~ ERROR should have a snake
+
+ static bad: isize = 1; //~ ERROR should have an upper
+ }
+
+ mod warn {
+ #![warn(nonstandard_style)]
+
+ fn CamelCase() {} //~ WARN should have a snake
+
+ struct snake_case; //~ WARN should have an upper camel
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-group-nonstandard-style.stderr b/tests/ui/lint/lint-group-nonstandard-style.stderr
new file mode 100644
index 000000000..fcd010123
--- /dev/null
+++ b/tests/ui/lint/lint-group-nonstandard-style.stderr
@@ -0,0 +1,57 @@
+warning: type `snake_case` should have an upper camel case name
+ --> $DIR/lint-group-nonstandard-style.rs:22:16
+ |
+LL | struct snake_case;
+ | ^^^^^^^^^^ help: convert the identifier to upper camel case: `SnakeCase`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-group-nonstandard-style.rs:18:17
+ |
+LL | #![warn(nonstandard_style)]
+ | ^^^^^^^^^^^^^^^^^
+ = note: `#[warn(non_camel_case_types)]` implied by `#[warn(nonstandard_style)]`
+
+error: function `CamelCase` should have a snake case name
+ --> $DIR/lint-group-nonstandard-style.rs:4:4
+ |
+LL | fn CamelCase() {}
+ | ^^^^^^^^^ help: convert the identifier to snake case: `camel_case`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-group-nonstandard-style.rs:1:9
+ |
+LL | #![deny(nonstandard_style)]
+ | ^^^^^^^^^^^^^^^^^
+ = note: `#[deny(non_snake_case)]` implied by `#[deny(nonstandard_style)]`
+
+error: function `CamelCase` should have a snake case name
+ --> $DIR/lint-group-nonstandard-style.rs:12:12
+ |
+LL | fn CamelCase() {}
+ | ^^^^^^^^^ help: convert the identifier to snake case: `camel_case`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-group-nonstandard-style.rs:10:14
+ |
+LL | #[forbid(nonstandard_style)]
+ | ^^^^^^^^^^^^^^^^^
+ = note: `#[forbid(non_snake_case)]` implied by `#[forbid(nonstandard_style)]`
+
+error: static variable `bad` should have an upper case name
+ --> $DIR/lint-group-nonstandard-style.rs:14:16
+ |
+LL | static bad: isize = 1;
+ | ^^^ help: convert the identifier to upper case: `BAD`
+ |
+ = note: `#[forbid(non_upper_case_globals)]` implied by `#[forbid(nonstandard_style)]`
+
+warning: function `CamelCase` should have a snake case name
+ --> $DIR/lint-group-nonstandard-style.rs:20:12
+ |
+LL | fn CamelCase() {}
+ | ^^^^^^^^^ help: convert the identifier to snake case: `camel_case`
+ |
+ = note: `#[warn(non_snake_case)]` implied by `#[warn(nonstandard_style)]`
+
+error: aborting due to 3 previous errors; 2 warnings emitted
+
diff --git a/tests/ui/lint/lint-impl-fn.rs b/tests/ui/lint/lint-impl-fn.rs
new file mode 100644
index 000000000..46874d95c
--- /dev/null
+++ b/tests/ui/lint/lint-impl-fn.rs
@@ -0,0 +1,33 @@
+#![allow(while_true)]
+#![allow(dead_code)]
+
+struct A(isize);
+
+impl A {
+ fn foo(&self) { while true {} }
+
+ #[deny(while_true)]
+ fn bar(&self) { while true {} } //~ ERROR: infinite loops
+}
+
+#[deny(while_true)]
+mod foo {
+ struct B(isize);
+
+ impl B {
+ fn foo(&self) { while true {} } //~ ERROR: infinite loops
+
+ #[allow(while_true)]
+ fn bar(&self) { while true {} }
+ }
+}
+
+#[deny(while_true)]
+fn main() {
+ while true {} //~ ERROR: infinite loops
+}
+
+#[deny(while_true)]
+fn bar() {
+ while cfg!(unix) {} // no error
+}
diff --git a/tests/ui/lint/lint-impl-fn.stderr b/tests/ui/lint/lint-impl-fn.stderr
new file mode 100644
index 000000000..24ec9c7e4
--- /dev/null
+++ b/tests/ui/lint/lint-impl-fn.stderr
@@ -0,0 +1,38 @@
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-impl-fn.rs:10:21
+ |
+LL | fn bar(&self) { while true {} }
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-impl-fn.rs:9:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-impl-fn.rs:18:25
+ |
+LL | fn foo(&self) { while true {} }
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-impl-fn.rs:13:8
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-impl-fn.rs:27:5
+ |
+LL | while true {}
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-impl-fn.rs:25:8
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/lint-incoherent-auto-trait-objects.rs b/tests/ui/lint/lint-incoherent-auto-trait-objects.rs
new file mode 100644
index 000000000..d53b51447
--- /dev/null
+++ b/tests/ui/lint/lint-incoherent-auto-trait-objects.rs
@@ -0,0 +1,19 @@
+trait Foo {}
+
+impl Foo for dyn Send {}
+
+impl Foo for dyn Send + Send {}
+//~^ ERROR conflicting implementations
+//~| hard error
+
+impl Foo for dyn Send + Sync {}
+
+impl Foo for dyn Sync + Send {}
+//~^ ERROR conflicting implementations
+//~| hard error
+
+impl Foo for dyn Send + Sync + Send {}
+//~^ ERROR conflicting implementations
+//~| hard error
+
+fn main() {}
diff --git a/tests/ui/lint/lint-incoherent-auto-trait-objects.stderr b/tests/ui/lint/lint-incoherent-auto-trait-objects.stderr
new file mode 100644
index 000000000..553ab3869
--- /dev/null
+++ b/tests/ui/lint/lint-incoherent-auto-trait-objects.stderr
@@ -0,0 +1,81 @@
+error: conflicting implementations of trait `Foo` for type `(dyn Send + 'static)`: (E0119)
+ --> $DIR/lint-incoherent-auto-trait-objects.rs:5:1
+ |
+LL | impl Foo for dyn Send {}
+ | --------------------- first implementation here
+LL |
+LL | impl Foo for dyn Send + Send {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
+ |
+ = 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 #56484 <https://github.com/rust-lang/rust/issues/56484>
+ = note: `#[deny(order_dependent_trait_objects)]` on by default
+
+error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
+ --> $DIR/lint-incoherent-auto-trait-objects.rs:11:1
+ |
+LL | impl Foo for dyn Send + Sync {}
+ | ---------------------------- first implementation here
+LL |
+LL | impl Foo for dyn Sync + Send {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
+ |
+ = 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 #56484 <https://github.com/rust-lang/rust/issues/56484>
+
+error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
+ --> $DIR/lint-incoherent-auto-trait-objects.rs:15:1
+ |
+LL | impl Foo for dyn Sync + Send {}
+ | ---------------------------- first implementation here
+...
+LL | impl Foo for dyn Send + Sync + Send {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
+ |
+ = 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 #56484 <https://github.com/rust-lang/rust/issues/56484>
+
+error: aborting due to 3 previous errors
+
+Future incompatibility report: Future breakage diagnostic:
+error: conflicting implementations of trait `Foo` for type `(dyn Send + 'static)`: (E0119)
+ --> $DIR/lint-incoherent-auto-trait-objects.rs:5:1
+ |
+LL | impl Foo for dyn Send {}
+ | --------------------- first implementation here
+LL |
+LL | impl Foo for dyn Send + Send {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
+ |
+ = 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 #56484 <https://github.com/rust-lang/rust/issues/56484>
+ = note: `#[deny(order_dependent_trait_objects)]` on by default
+
+Future breakage diagnostic:
+error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
+ --> $DIR/lint-incoherent-auto-trait-objects.rs:11:1
+ |
+LL | impl Foo for dyn Send + Sync {}
+ | ---------------------------- first implementation here
+LL |
+LL | impl Foo for dyn Sync + Send {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
+ |
+ = 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 #56484 <https://github.com/rust-lang/rust/issues/56484>
+ = note: `#[deny(order_dependent_trait_objects)]` on by default
+
+Future breakage diagnostic:
+error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
+ --> $DIR/lint-incoherent-auto-trait-objects.rs:15:1
+ |
+LL | impl Foo for dyn Sync + Send {}
+ | ---------------------------- first implementation here
+...
+LL | impl Foo for dyn Send + Sync + Send {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
+ |
+ = 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 #56484 <https://github.com/rust-lang/rust/issues/56484>
+ = note: `#[deny(order_dependent_trait_objects)]` on by default
+
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-bool.rs b/tests/ui/lint/lint-invalid-atomic-ordering-bool.rs
new file mode 100644
index 000000000..15ceb6195
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-bool.rs
@@ -0,0 +1,28 @@
+// only-x86_64
+use std::sync::atomic::{AtomicBool, Ordering};
+
+fn main() {
+ let x = AtomicBool::new(true);
+
+ // Allowed load ordering modes
+ let _ = x.load(Ordering::Acquire);
+ let _ = x.load(Ordering::SeqCst);
+ let _ = x.load(Ordering::Relaxed);
+
+ // Disallowed load ordering modes
+ let _ = x.load(Ordering::Release);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+ let _ = x.load(Ordering::AcqRel);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+
+ // Allowed store ordering modes
+ x.store(false, Ordering::Release);
+ x.store(false, Ordering::SeqCst);
+ x.store(false, Ordering::Relaxed);
+
+ // Disallowed store ordering modes
+ x.store(false, Ordering::Acquire);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+ x.store(false, Ordering::AcqRel);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+}
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-bool.stderr b/tests/ui/lint/lint-invalid-atomic-ordering-bool.stderr
new file mode 100644
index 000000000..9f38dcb0b
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-bool.stderr
@@ -0,0 +1,35 @@
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-bool.rs:13:20
+ |
+LL | let _ = x.load(Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+ = note: `#[deny(invalid_atomic_ordering)]` on by default
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-bool.rs:15:20
+ |
+LL | let _ = x.load(Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-bool.rs:24:20
+ |
+LL | x.store(false, Ordering::Acquire);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-bool.rs:26:20
+ |
+LL | x.store(false, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-exchange-weak.rs b/tests/ui/lint/lint-invalid-atomic-ordering-exchange-weak.rs
new file mode 100644
index 000000000..63204c725
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-exchange-weak.rs
@@ -0,0 +1,50 @@
+// only-x86_64
+use std::sync::atomic::{AtomicPtr, Ordering};
+
+fn main() {
+ let ptr = &mut 5;
+ let ptr2 = &mut 10;
+ // `compare_exchange_weak` testing
+ let x = AtomicPtr::new(ptr);
+
+ // Allowed ordering combos
+ let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::Relaxed);
+ let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::Acquire);
+ let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::SeqCst);
+ let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Acquire, Ordering::Relaxed);
+ let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Acquire, Ordering::Acquire);
+ let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Acquire, Ordering::SeqCst);
+ let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Release, Ordering::Relaxed);
+ let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Release, Ordering::Acquire);
+ let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Release, Ordering::SeqCst);
+ let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::AcqRel, Ordering::Relaxed);
+ let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::AcqRel, Ordering::Acquire);
+ let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::AcqRel, Ordering::SeqCst);
+ let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::SeqCst, Ordering::Relaxed);
+ let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::SeqCst, Ordering::Acquire);
+ let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::SeqCst, Ordering::SeqCst);
+
+ // 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`
+ let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Acquire, Ordering::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`
+ let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::AcqRel, Ordering::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`
+
+ // 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`
+ let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Acquire, Ordering::Release);
+ //~^ 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`
+ let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::AcqRel, Ordering::Release);
+ //~^ 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`
+}
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr b/tests/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr
new file mode 100644
index 000000000..cc075ce9e
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr
@@ -0,0 +1,83 @@
+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:67
+ |
+LL | let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Relaxed, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+ = note: `#[deny(invalid_atomic_ordering)]` on by default
+
+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:67
+ |
+LL | let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Acquire, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:32:67
+ |
+LL | let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Release, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:66
+ |
+LL | let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::AcqRel, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:66
+ |
+LL | let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::SeqCst, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:67
+ |
+LL | let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:67
+ |
+LL | let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Acquire, Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:44:67
+ |
+LL | let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Release, Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:46:66
+ |
+LL | let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::AcqRel, Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:48:66
+ |
+LL | let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::SeqCst, Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+error: aborting due to 10 previous errors
+
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-exchange.rs b/tests/ui/lint/lint-invalid-atomic-ordering-exchange.rs
new file mode 100644
index 000000000..488d268ee
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-exchange.rs
@@ -0,0 +1,48 @@
+// only-x86_64
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+fn main() {
+ // `compare_exchange` (not weak) testing
+ let x = AtomicUsize::new(0);
+
+ // Allowed ordering combos
+ let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::Relaxed);
+ let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::Acquire);
+ let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::SeqCst);
+ let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::Relaxed);
+ let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::Acquire);
+ let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::SeqCst);
+ let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::Relaxed);
+ let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::Acquire);
+ let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::SeqCst);
+ let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::Relaxed);
+ let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::Acquire);
+ let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::SeqCst);
+ let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::Relaxed);
+ let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::Acquire);
+ let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::SeqCst);
+
+ // 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`
+ let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::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`
+ let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::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`
+
+ // 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`
+ let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::Release);
+ //~^ 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`
+ let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::Release);
+ //~^ 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`
+}
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-exchange.stderr b/tests/ui/lint/lint-invalid-atomic-ordering-exchange.stderr
new file mode 100644
index 000000000..fe6c7e55c
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-exchange.stderr
@@ -0,0 +1,83 @@
+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:57
+ |
+LL | let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+ = note: `#[deny(invalid_atomic_ordering)]` on by default
+
+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:57
+ |
+LL | let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:30:57
+ |
+LL | let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:56
+ |
+LL | let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:56
+ |
+LL | let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:57
+ |
+LL | let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:57
+ |
+LL | let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:42:57
+ |
+LL | let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:44:56
+ |
+LL | let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:46:56
+ |
+LL | let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+error: aborting due to 10 previous errors
+
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-false-positive.rs b/tests/ui/lint/lint-invalid-atomic-ordering-false-positive.rs
new file mode 100644
index 000000000..4fb8605b4
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-false-positive.rs
@@ -0,0 +1,18 @@
+// only-x86_64
+// check-pass
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+trait Foo {
+ fn store(self, ordering: Ordering);
+}
+
+impl Foo for AtomicUsize {
+ fn store(self, _ordering: Ordering) {
+ AtomicUsize::store(&self, 4, Ordering::SeqCst);
+ }
+}
+
+fn main() {
+ let x = AtomicUsize::new(3);
+ x.store(Ordering::Acquire);
+}
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-fence.rs b/tests/ui/lint/lint-invalid-atomic-ordering-fence.rs
new file mode 100644
index 000000000..22034472c
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-fence.rs
@@ -0,0 +1,21 @@
+// only-x86_64
+use std::sync::atomic::{compiler_fence, fence, Ordering};
+
+fn main() {
+ // Allowed ordering modes
+ fence(Ordering::Acquire);
+ fence(Ordering::Release);
+ fence(Ordering::AcqRel);
+ fence(Ordering::SeqCst);
+
+ compiler_fence(Ordering::Acquire);
+ compiler_fence(Ordering::Release);
+ compiler_fence(Ordering::AcqRel);
+ compiler_fence(Ordering::SeqCst);
+
+ // Disallowed ordering modes
+ fence(Ordering::Relaxed);
+ //~^ ERROR memory fences cannot have `Relaxed` ordering
+ compiler_fence(Ordering::Relaxed);
+ //~^ ERROR memory fences cannot have `Relaxed` ordering
+}
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-fence.stderr b/tests/ui/lint/lint-invalid-atomic-ordering-fence.stderr
new file mode 100644
index 000000000..38327d607
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-fence.stderr
@@ -0,0 +1,19 @@
+error: memory fences cannot have `Relaxed` ordering
+ --> $DIR/lint-invalid-atomic-ordering-fence.rs:17:11
+ |
+LL | fence(Ordering::Relaxed);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst`
+ = note: `#[deny(invalid_atomic_ordering)]` on by default
+
+error: memory fences cannot have `Relaxed` ordering
+ --> $DIR/lint-invalid-atomic-ordering-fence.rs:19:20
+ |
+LL | compiler_fence(Ordering::Relaxed);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.rs b/tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.rs
new file mode 100644
index 000000000..734b63324
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.rs
@@ -0,0 +1,49 @@
+// only-x86_64
+use std::sync::atomic::{AtomicIsize, Ordering};
+
+fn main() {
+ // `fetch_update` testing
+ let x = AtomicIsize::new(0);
+
+ // Allowed ordering combos
+ let _ = x.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |old| Some(old + 1));
+ let _ = x.fetch_update(Ordering::Relaxed, Ordering::Acquire, |old| Some(old + 1));
+ let _ = x.fetch_update(Ordering::Relaxed, Ordering::SeqCst, |old| Some(old + 1));
+ let _ = x.fetch_update(Ordering::Acquire, Ordering::Relaxed, |old| Some(old + 1));
+ let _ = x.fetch_update(Ordering::Acquire, Ordering::Acquire, |old| Some(old + 1));
+ let _ = x.fetch_update(Ordering::Acquire, Ordering::SeqCst, |old| Some(old + 1));
+ let _ = x.fetch_update(Ordering::Release, Ordering::Relaxed, |old| Some(old + 1));
+ let _ = x.fetch_update(Ordering::Release, Ordering::Acquire, |old| Some(old + 1));
+ let _ = x.fetch_update(Ordering::Release, Ordering::SeqCst, |old| Some(old + 1));
+ let _ = x.fetch_update(Ordering::AcqRel, Ordering::Relaxed, |old| Some(old + 1));
+ let _ = x.fetch_update(Ordering::AcqRel, Ordering::Acquire, |old| Some(old + 1));
+ let _ = x.fetch_update(Ordering::AcqRel, Ordering::SeqCst, |old| Some(old + 1));
+ let _ = x.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |old| Some(old + 1));
+ let _ = x.fetch_update(Ordering::SeqCst, Ordering::Acquire, |old| Some(old + 1));
+ let _ = x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |old| Some(old + 1));
+
+ // 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`
+ let _ = x.fetch_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1));
+ //~^ 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`
+ let _ = x.fetch_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1));
+ //~^ 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`
+
+ // 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`
+ let _ = x.fetch_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1));
+ //~^ 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`
+ let _ = x.fetch_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1));
+ //~^ 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`
+
+}
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr b/tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr
new file mode 100644
index 000000000..33829d68f
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr
@@ -0,0 +1,83 @@
+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:47
+ |
+LL | let _ = x.fetch_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1));
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+ = note: `#[deny(invalid_atomic_ordering)]` on by default
+
+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:47
+ |
+LL | let _ = x.fetch_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1));
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:30:47
+ |
+LL | let _ = x.fetch_update(Ordering::Release, Ordering::AcqRel, |old| Some(old + 1));
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:46
+ |
+LL | let _ = x.fetch_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1));
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:46
+ |
+LL | let _ = x.fetch_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old + 1));
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:47
+ |
+LL | let _ = x.fetch_update(Ordering::Relaxed, Ordering::Release, |old| Some(old + 1));
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:47
+ |
+LL | let _ = x.fetch_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1));
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:42:47
+ |
+LL | let _ = x.fetch_update(Ordering::Release, Ordering::Release, |old| Some(old + 1));
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:44:46
+ |
+LL | let _ = x.fetch_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1));
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+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:46:46
+ |
+LL | let _ = x.fetch_update(Ordering::SeqCst, Ordering::Release, |old| Some(old + 1));
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
+ |
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
+
+error: aborting due to 10 previous errors
+
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-int.rs b/tests/ui/lint/lint-invalid-atomic-ordering-int.rs
new file mode 100644
index 000000000..462c9670f
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-int.rs
@@ -0,0 +1,130 @@
+// FIXME: add support for `// only-atomic` to compiletest/header.rs
+// only-x86_64
+use std::sync::atomic::{AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, Ordering};
+
+fn main() {
+ // `AtomicI8` test cases
+ let x = AtomicI8::new(0);
+
+ // Allowed load ordering modes
+ let _ = x.load(Ordering::Acquire);
+ let _ = x.load(Ordering::SeqCst);
+ let _ = x.load(Ordering::Relaxed);
+
+ // Allowed store ordering modes
+ x.store(1, Ordering::Release);
+ x.store(1, Ordering::SeqCst);
+ x.store(1, Ordering::Relaxed);
+
+ // Disallowed load ordering modes
+ let _ = x.load(Ordering::Release);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+ let _ = x.load(Ordering::AcqRel);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+
+ // Disallowed store ordering modes
+ x.store(1, Ordering::Acquire);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+ x.store(1, Ordering::AcqRel);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+
+ // `AtomicI16` test cases
+ let x = AtomicI16::new(0);
+
+ // Allowed load ordering modes
+ let _ = x.load(Ordering::Acquire);
+ let _ = x.load(Ordering::SeqCst);
+ let _ = x.load(Ordering::Relaxed);
+
+ // Allowed store ordering modes
+ x.store(1, Ordering::Release);
+ x.store(1, Ordering::SeqCst);
+ x.store(1, Ordering::Relaxed);
+
+ // Disallowed load ordering modes
+ let _ = x.load(Ordering::Release);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+ let _ = x.load(Ordering::AcqRel);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+
+ // Disallowed store ordering modes
+ x.store(1, Ordering::Acquire);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+ x.store(1, Ordering::AcqRel);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+
+ // `AtomicI32` test cases
+ let x = AtomicI32::new(0);
+
+ // Allowed load ordering modes
+ let _ = x.load(Ordering::Acquire);
+ let _ = x.load(Ordering::SeqCst);
+ let _ = x.load(Ordering::Relaxed);
+
+ // Allowed store ordering modes
+ x.store(1, Ordering::Release);
+ x.store(1, Ordering::SeqCst);
+ x.store(1, Ordering::Relaxed);
+
+ // Disallowed load ordering modes
+ let _ = x.load(Ordering::Release);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+ let _ = x.load(Ordering::AcqRel);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+
+ // Disallowed store ordering modes
+ x.store(1, Ordering::Acquire);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+ x.store(1, Ordering::AcqRel);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+
+ // `AtomicI64` test cases
+ let x = AtomicI64::new(0);
+
+ // Allowed load ordering modes
+ let _ = x.load(Ordering::Acquire);
+ let _ = x.load(Ordering::SeqCst);
+ let _ = x.load(Ordering::Relaxed);
+
+ // Allowed store ordering modes
+ x.store(1, Ordering::Release);
+ x.store(1, Ordering::SeqCst);
+ x.store(1, Ordering::Relaxed);
+
+ // Disallowed load ordering modes
+ let _ = x.load(Ordering::Release);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+ let _ = x.load(Ordering::AcqRel);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+
+ // Disallowed store ordering modes
+ x.store(1, Ordering::Acquire);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+ x.store(1, Ordering::AcqRel);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+
+ // `AtomicIsize` test cases
+ let x = AtomicIsize::new(0);
+
+ // Allowed load ordering modes
+ let _ = x.load(Ordering::Acquire);
+ let _ = x.load(Ordering::SeqCst);
+ let _ = x.load(Ordering::Relaxed);
+
+ // Allowed store ordering modes
+ x.store(1, Ordering::Release);
+ x.store(1, Ordering::SeqCst);
+ x.store(1, Ordering::Relaxed);
+
+ // Disallowed load ordering modes
+ let _ = x.load(Ordering::Release);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+ let _ = x.load(Ordering::AcqRel);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+
+ // Disallowed store ordering modes
+ x.store(1, Ordering::Acquire);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+ x.store(1, Ordering::AcqRel);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+}
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-int.stderr b/tests/ui/lint/lint-invalid-atomic-ordering-int.stderr
new file mode 100644
index 000000000..36930e2f4
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-int.stderr
@@ -0,0 +1,163 @@
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:20:20
+ |
+LL | let _ = x.load(Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+ = note: `#[deny(invalid_atomic_ordering)]` on by default
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:22:20
+ |
+LL | let _ = x.load(Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:26:16
+ |
+LL | x.store(1, Ordering::Acquire);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:28:16
+ |
+LL | x.store(1, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:45:20
+ |
+LL | let _ = x.load(Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:47:20
+ |
+LL | let _ = x.load(Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:51:16
+ |
+LL | x.store(1, Ordering::Acquire);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:53:16
+ |
+LL | x.store(1, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:70:20
+ |
+LL | let _ = x.load(Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:72:20
+ |
+LL | let _ = x.load(Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:76:16
+ |
+LL | x.store(1, Ordering::Acquire);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:78:16
+ |
+LL | x.store(1, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:95:20
+ |
+LL | let _ = x.load(Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:97:20
+ |
+LL | let _ = x.load(Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:101:16
+ |
+LL | x.store(1, Ordering::Acquire);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:103:16
+ |
+LL | x.store(1, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:120:20
+ |
+LL | let _ = x.load(Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:122:20
+ |
+LL | let _ = x.load(Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:126:16
+ |
+LL | x.store(1, Ordering::Acquire);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-int.rs:128:16
+ |
+LL | x.store(1, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: aborting due to 20 previous errors
+
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-ptr.rs b/tests/ui/lint/lint-invalid-atomic-ordering-ptr.rs
new file mode 100644
index 000000000..984f7edeb
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-ptr.rs
@@ -0,0 +1,30 @@
+// only-x86_64
+use std::sync::atomic::{AtomicPtr, Ordering};
+
+fn main() {
+ let ptr = &mut 5;
+ let other_ptr = &mut 10;
+ let x = AtomicPtr::new(ptr);
+
+ // Allowed load ordering modes
+ let _ = x.load(Ordering::Acquire);
+ let _ = x.load(Ordering::SeqCst);
+ let _ = x.load(Ordering::Relaxed);
+
+ // Disallowed load ordering modes
+ let _ = x.load(Ordering::Release);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+ let _ = x.load(Ordering::AcqRel);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+
+ // Allowed store ordering modes
+ x.store(other_ptr, Ordering::Release);
+ x.store(other_ptr, Ordering::SeqCst);
+ x.store(other_ptr, Ordering::Relaxed);
+
+ // Disallowed store ordering modes
+ x.store(other_ptr, Ordering::Acquire);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+ x.store(other_ptr, Ordering::AcqRel);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+}
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-ptr.stderr b/tests/ui/lint/lint-invalid-atomic-ordering-ptr.stderr
new file mode 100644
index 000000000..12f4cad90
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-ptr.stderr
@@ -0,0 +1,35 @@
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-ptr.rs:15:20
+ |
+LL | let _ = x.load(Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+ = note: `#[deny(invalid_atomic_ordering)]` on by default
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-ptr.rs:17:20
+ |
+LL | let _ = x.load(Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-ptr.rs:26:24
+ |
+LL | x.store(other_ptr, Ordering::Acquire);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-ptr.rs:28:24
+ |
+LL | x.store(other_ptr, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-uint.rs b/tests/ui/lint/lint-invalid-atomic-ordering-uint.rs
new file mode 100644
index 000000000..80ec3b9ee
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-uint.rs
@@ -0,0 +1,129 @@
+// only-x86_64
+use std::sync::atomic::{AtomicU16, AtomicU32, AtomicU64, AtomicU8, AtomicUsize, Ordering};
+
+fn main() {
+ // `AtomicU8` test cases
+ let x = AtomicU8::new(0);
+
+ // Allowed load ordering modes
+ let _ = x.load(Ordering::Acquire);
+ let _ = x.load(Ordering::SeqCst);
+ let _ = x.load(Ordering::Relaxed);
+
+ // Allowed store ordering modes
+ x.store(1, Ordering::Release);
+ x.store(1, Ordering::SeqCst);
+ x.store(1, Ordering::Relaxed);
+
+ // Disallowed load ordering modes
+ let _ = x.load(Ordering::Release);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+ let _ = x.load(Ordering::AcqRel);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+
+ // Disallowed store ordering modes
+ x.store(1, Ordering::Acquire);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+ x.store(1, Ordering::AcqRel);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+
+ // `AtomicU16` test cases
+ let x = AtomicU16::new(0);
+
+ // Allowed load ordering modes
+ let _ = x.load(Ordering::Acquire);
+ let _ = x.load(Ordering::SeqCst);
+ let _ = x.load(Ordering::Relaxed);
+
+ // Allowed store ordering modes
+ x.store(1, Ordering::Release);
+ x.store(1, Ordering::SeqCst);
+ x.store(1, Ordering::Relaxed);
+
+ // Disallowed load ordering modes
+ let _ = x.load(Ordering::Release);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+ let _ = x.load(Ordering::AcqRel);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+
+ // Disallowed store ordering modes
+ x.store(1, Ordering::Acquire);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+ x.store(1, Ordering::AcqRel);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+
+ // `AtomicU32` test cases
+ let x = AtomicU32::new(0);
+
+ // Allowed load ordering modes
+ let _ = x.load(Ordering::Acquire);
+ let _ = x.load(Ordering::SeqCst);
+ let _ = x.load(Ordering::Relaxed);
+
+ // Allowed store ordering modes
+ x.store(1, Ordering::Release);
+ x.store(1, Ordering::SeqCst);
+ x.store(1, Ordering::Relaxed);
+
+ // Disallowed load ordering modes
+ let _ = x.load(Ordering::Release);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+ let _ = x.load(Ordering::AcqRel);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+
+ // Disallowed store ordering modes
+ x.store(1, Ordering::Acquire);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+ x.store(1, Ordering::AcqRel);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+
+ // `AtomicU64` test cases
+ let x = AtomicU64::new(0);
+
+ // Allowed load ordering modes
+ let _ = x.load(Ordering::Acquire);
+ let _ = x.load(Ordering::SeqCst);
+ let _ = x.load(Ordering::Relaxed);
+
+ // Allowed store ordering modes
+ x.store(1, Ordering::Release);
+ x.store(1, Ordering::SeqCst);
+ x.store(1, Ordering::Relaxed);
+
+ // Disallowed load ordering modes
+ let _ = x.load(Ordering::Release);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+ let _ = x.load(Ordering::AcqRel);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+
+ // Disallowed store ordering modes
+ x.store(1, Ordering::Acquire);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+ x.store(1, Ordering::AcqRel);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+
+ // `AtomicUsize` test cases
+ let x = AtomicUsize::new(0);
+
+ // Allowed load ordering modes
+ let _ = x.load(Ordering::Acquire);
+ let _ = x.load(Ordering::SeqCst);
+ let _ = x.load(Ordering::Relaxed);
+
+ // Allowed store ordering modes
+ x.store(1, Ordering::Release);
+ x.store(1, Ordering::SeqCst);
+ x.store(1, Ordering::Relaxed);
+
+ // Disallowed load ordering modes
+ let _ = x.load(Ordering::Release);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+ let _ = x.load(Ordering::AcqRel);
+ //~^ ERROR atomic loads cannot have `Release` or `AcqRel` ordering
+
+ // Disallowed store ordering modes
+ x.store(1, Ordering::Acquire);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+ x.store(1, Ordering::AcqRel);
+ //~^ ERROR atomic stores cannot have `Acquire` or `AcqRel` ordering
+}
diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-uint.stderr b/tests/ui/lint/lint-invalid-atomic-ordering-uint.stderr
new file mode 100644
index 000000000..d26621f2a
--- /dev/null
+++ b/tests/ui/lint/lint-invalid-atomic-ordering-uint.stderr
@@ -0,0 +1,163 @@
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:19:20
+ |
+LL | let _ = x.load(Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+ = note: `#[deny(invalid_atomic_ordering)]` on by default
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:21:20
+ |
+LL | let _ = x.load(Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:25:16
+ |
+LL | x.store(1, Ordering::Acquire);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:27:16
+ |
+LL | x.store(1, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:44:20
+ |
+LL | let _ = x.load(Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:46:20
+ |
+LL | let _ = x.load(Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:50:16
+ |
+LL | x.store(1, Ordering::Acquire);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:52:16
+ |
+LL | x.store(1, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:69:20
+ |
+LL | let _ = x.load(Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:71:20
+ |
+LL | let _ = x.load(Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:75:16
+ |
+LL | x.store(1, Ordering::Acquire);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:77:16
+ |
+LL | x.store(1, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:94:20
+ |
+LL | let _ = x.load(Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:96:20
+ |
+LL | let _ = x.load(Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:100:16
+ |
+LL | x.store(1, Ordering::Acquire);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:102:16
+ |
+LL | x.store(1, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:119:20
+ |
+LL | let _ = x.load(Ordering::Release);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic loads cannot have `Release` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:121:20
+ |
+LL | let _ = x.load(Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:125:16
+ |
+LL | x.store(1, Ordering::Acquire);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: atomic stores cannot have `Acquire` or `AcqRel` ordering
+ --> $DIR/lint-invalid-atomic-ordering-uint.rs:127:16
+ |
+LL | x.store(1, Ordering::AcqRel);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider using ordering modes `Release`, `SeqCst` or `Relaxed`
+
+error: aborting due to 20 previous errors
+
diff --git a/tests/ui/lint/lint-level-macro-def-mod.rs b/tests/ui/lint/lint-level-macro-def-mod.rs
new file mode 100644
index 000000000..79f7d1206
--- /dev/null
+++ b/tests/ui/lint/lint-level-macro-def-mod.rs
@@ -0,0 +1,17 @@
+// This checks that exported macros lint as part of their module of origin, not
+// the root module.
+//
+// check-pass
+
+//! Top level documentation
+#![deny(missing_docs)]
+
+#[allow(missing_docs)]
+mod module {
+ #[macro_export]
+ macro_rules! hello {
+ () => ()
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-level-macro-def.rs b/tests/ui/lint/lint-level-macro-def.rs
new file mode 100644
index 000000000..720f4b453
--- /dev/null
+++ b/tests/ui/lint/lint-level-macro-def.rs
@@ -0,0 +1,17 @@
+// Checks that you can set a lint level specficially for a macro definition.
+//
+// This is a regression test for issue #59306.
+//
+// check-pass
+
+
+#[deny(missing_docs)]
+mod module {
+ #[allow(missing_docs)]
+ #[macro_export]
+ macro_rules! hello {
+ () => ()
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-lowercase-static-const-pattern-rename.rs b/tests/ui/lint/lint-lowercase-static-const-pattern-rename.rs
new file mode 100644
index 000000000..d085db43a
--- /dev/null
+++ b/tests/ui/lint/lint-lowercase-static-const-pattern-rename.rs
@@ -0,0 +1,63 @@
+// check-pass
+// Issue #7526: lowercase static constants in patterns look like bindings
+
+// This is similar to lint-lowercase-static-const-pattern.rs, except it
+// shows the expected usual workaround (choosing a different name for
+// the static definition) and also demonstrates that one can work
+// around this problem locally by renaming the constant in the `use`
+// form to an uppercase identifier that placates the lint.
+
+#![deny(non_upper_case_globals)]
+
+pub const A : isize = 97;
+
+fn f() {
+ let r = match (0,0) {
+ (0, A) => 0,
+ (x, y) => 1 + x + y,
+ };
+ assert_eq!(r, 1);
+ let r = match (0,97) {
+ (0, A) => 0,
+ (x, y) => 1 + x + y,
+ };
+ assert_eq!(r, 0);
+}
+
+mod m {
+ #[allow(non_upper_case_globals)]
+ pub const aha : isize = 7;
+}
+
+fn g() {
+ use self::m::aha as AHA;
+ let r = match (0,0) {
+ (0, AHA) => 0,
+ (x, y) => 1 + x + y,
+ };
+ assert_eq!(r, 1);
+ let r = match (0,7) {
+ (0, AHA) => 0,
+ (x, y) => 1 + x + y,
+ };
+ assert_eq!(r, 0);
+}
+
+fn h() {
+ let r = match (0,0) {
+ (0, self::m::aha) => 0,
+ (x, y) => 1 + x + y,
+ };
+ assert_eq!(r, 1);
+ let r = match (0,7) {
+ (0, self::m::aha) => 0,
+ (x, y) => 1 + x + y,
+ };
+ assert_eq!(r, 0);
+}
+
+pub fn main () {
+ f();
+ g();
+ h();
+}
diff --git a/tests/ui/lint/lint-lowercase-static-const-pattern.rs b/tests/ui/lint/lint-lowercase-static-const-pattern.rs
new file mode 100644
index 000000000..c2e159eec
--- /dev/null
+++ b/tests/ui/lint/lint-lowercase-static-const-pattern.rs
@@ -0,0 +1,51 @@
+// Issue #7526: lowercase static constants in patterns look like bindings
+
+#![allow(dead_code)]
+#![deny(non_upper_case_globals)]
+
+#[allow(non_upper_case_globals)]
+pub const a : isize = 97;
+
+fn f() {
+ let r = match (0,0) {
+ (0, a) => 0,
+ //~^ ERROR constant in pattern `a` should have an upper case name
+ (x, y) => 1 + x + y,
+ };
+ assert_eq!(r, 1);
+}
+
+mod m {
+ #[allow(non_upper_case_globals)]
+ pub const aha : isize = 7;
+}
+
+fn g() {
+ use self::m::aha;
+ let r = match (0,0) {
+ (0, aha) => 0,
+ //~^ ERROR constant in pattern `aha` should have an upper case name
+ (x, y) => 1 + x + y,
+ };
+ assert_eq!(r, 1);
+}
+
+mod n {
+ pub const OKAY : isize = 8;
+}
+
+fn h() {
+ use self::n::OKAY as not_okay;
+ let r = match (0,0) {
+ (0, not_okay) => 0,
+//~^ ERROR constant in pattern `not_okay` should have an upper case name
+ (x, y) => 1 + x + y,
+ };
+ assert_eq!(r, 1);
+}
+
+fn main () {
+ f();
+ g();
+ h();
+}
diff --git a/tests/ui/lint/lint-lowercase-static-const-pattern.stderr b/tests/ui/lint/lint-lowercase-static-const-pattern.stderr
new file mode 100644
index 000000000..8780fac05
--- /dev/null
+++ b/tests/ui/lint/lint-lowercase-static-const-pattern.stderr
@@ -0,0 +1,26 @@
+error: constant in pattern `a` should have an upper case name
+ --> $DIR/lint-lowercase-static-const-pattern.rs:11:13
+ |
+LL | (0, a) => 0,
+ | ^ help: convert the identifier to upper case: `A`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-lowercase-static-const-pattern.rs:4:9
+ |
+LL | #![deny(non_upper_case_globals)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: constant in pattern `aha` should have an upper case name
+ --> $DIR/lint-lowercase-static-const-pattern.rs:26:13
+ |
+LL | (0, aha) => 0,
+ | ^^^ help: convert the identifier to upper case: `AHA`
+
+error: constant in pattern `not_okay` should have an upper case name
+ --> $DIR/lint-lowercase-static-const-pattern.rs:40:13
+ |
+LL | (0, not_okay) => 0,
+ | ^^^^^^^^ help: convert the identifier to upper case: `NOT_OKAY`
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/lint-malformed.rs b/tests/ui/lint/lint-malformed.rs
new file mode 100644
index 000000000..188e702f9
--- /dev/null
+++ b/tests/ui/lint/lint-malformed.rs
@@ -0,0 +1,6 @@
+#![deny = "foo"] //~ ERROR malformed `deny` attribute input
+#![allow(bar = "baz")] //~ ERROR malformed lint attribute
+ //~| ERROR malformed lint attribute
+ //~| ERROR malformed lint attribute
+ //~| ERROR malformed lint attribute
+fn main() { }
diff --git a/tests/ui/lint/lint-malformed.stderr b/tests/ui/lint/lint-malformed.stderr
new file mode 100644
index 000000000..91b4e509b
--- /dev/null
+++ b/tests/ui/lint/lint-malformed.stderr
@@ -0,0 +1,33 @@
+error[E0452]: malformed lint attribute input
+ --> $DIR/lint-malformed.rs:2:10
+ |
+LL | #![allow(bar = "baz")]
+ | ^^^^^^^^^^^ bad attribute argument
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/lint-malformed.rs:2:10
+ |
+LL | #![allow(bar = "baz")]
+ | ^^^^^^^^^^^ bad attribute argument
+
+error: malformed `deny` attribute input
+ --> $DIR/lint-malformed.rs:1:1
+ |
+LL | #![deny = "foo"]
+ | ^^^^^^^^^^^^^^^^ help: must be of the form: `#![deny(lint1, lint2, ..., /*opt*/ reason = "...")]`
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/lint-malformed.rs:2:10
+ |
+LL | #![allow(bar = "baz")]
+ | ^^^^^^^^^^^ bad attribute argument
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/lint-malformed.rs:2:10
+ |
+LL | #![allow(bar = "baz")]
+ | ^^^^^^^^^^^ bad attribute argument
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0452`.
diff --git a/tests/ui/lint/lint-match-arms.rs b/tests/ui/lint/lint-match-arms.rs
new file mode 100644
index 000000000..5c2ccc60e
--- /dev/null
+++ b/tests/ui/lint/lint-match-arms.rs
@@ -0,0 +1,18 @@
+fn deny_on_arm() {
+ match 0 {
+ #[deny(unused_variables)]
+ //~^ NOTE the lint level is defined here
+ y => (),
+ //~^ ERROR unused variable
+ }
+}
+
+#[deny(unused_variables)]
+fn allow_on_arm() {
+ match 0 {
+ #[allow(unused_variables)]
+ y => (), // OK
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-match-arms.stderr b/tests/ui/lint/lint-match-arms.stderr
new file mode 100644
index 000000000..1bc0e41fd
--- /dev/null
+++ b/tests/ui/lint/lint-match-arms.stderr
@@ -0,0 +1,14 @@
+error: unused variable: `y`
+ --> $DIR/lint-match-arms.rs:5:9
+ |
+LL | y => (),
+ | ^ help: if this is intentional, prefix it with an underscore: `_y`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-match-arms.rs:3:16
+ |
+LL | #[deny(unused_variables)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-misplaced-attr.rs b/tests/ui/lint/lint-misplaced-attr.rs
new file mode 100644
index 000000000..d06917ea3
--- /dev/null
+++ b/tests/ui/lint/lint-misplaced-attr.rs
@@ -0,0 +1,10 @@
+// When denying at the crate level, be sure to not get random warnings from the
+// injected intrinsics by the compiler.
+
+#![deny(unused_attributes)]
+
+mod a {
+ #![crate_type = "bin"] //~ ERROR should be in the root module
+}
+
+#[crate_type = "bin"] fn main() {} //~ ERROR should be an inner
diff --git a/tests/ui/lint/lint-misplaced-attr.stderr b/tests/ui/lint/lint-misplaced-attr.stderr
new file mode 100644
index 000000000..abaf4620e
--- /dev/null
+++ b/tests/ui/lint/lint-misplaced-attr.stderr
@@ -0,0 +1,20 @@
+error: crate-level attribute should be in the root module
+ --> $DIR/lint-misplaced-attr.rs:7:5
+ |
+LL | #![crate_type = "bin"]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-misplaced-attr.rs:4:9
+ |
+LL | #![deny(unused_attributes)]
+ | ^^^^^^^^^^^^^^^^^
+
+error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
+ --> $DIR/lint-misplaced-attr.rs:10:1
+ |
+LL | #[crate_type = "bin"] fn main() {}
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/lint-missing-copy-implementations-allow.rs b/tests/ui/lint/lint-missing-copy-implementations-allow.rs
new file mode 100644
index 000000000..051a905ae
--- /dev/null
+++ b/tests/ui/lint/lint-missing-copy-implementations-allow.rs
@@ -0,0 +1,35 @@
+// check-pass
+#![deny(missing_copy_implementations)]
+
+// Don't recommend implementing Copy on something stateful like an iterator.
+pub struct MyIterator {
+ num: u8,
+}
+
+impl Iterator for MyIterator {
+ type Item = u8;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ todo!()
+ }
+}
+
+pub struct Handle {
+ inner: *mut (),
+}
+
+pub struct Handle2 {
+ inner: *const (),
+}
+
+pub enum MaybeHandle {
+ Ptr(*mut ()),
+}
+
+pub union UnionHandle {
+ ptr: *mut (),
+}
+
+pub struct Array([u8; 2048]);
+
+fn main() {}
diff --git a/tests/ui/lint/lint-missing-copy-implementations.rs b/tests/ui/lint/lint-missing-copy-implementations.rs
new file mode 100644
index 000000000..918f40de1
--- /dev/null
+++ b/tests/ui/lint/lint-missing-copy-implementations.rs
@@ -0,0 +1,15 @@
+// See issue 19712
+
+#![deny(missing_copy_implementations)]
+
+mod inner {
+ pub struct Foo { //~ ERROR type could implement `Copy`; consider adding `impl Copy`
+ pub field: i32
+ }
+}
+
+pub fn foo() -> inner::Foo {
+ inner::Foo { field: 42 }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-missing-copy-implementations.stderr b/tests/ui/lint/lint-missing-copy-implementations.stderr
new file mode 100644
index 000000000..e5f5ce20d
--- /dev/null
+++ b/tests/ui/lint/lint-missing-copy-implementations.stderr
@@ -0,0 +1,16 @@
+error: type could implement `Copy`; consider adding `impl Copy`
+ --> $DIR/lint-missing-copy-implementations.rs:6:5
+ |
+LL | / pub struct Foo {
+LL | | pub field: i32
+LL | | }
+ | |_____^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-missing-copy-implementations.rs:3:9
+ |
+LL | #![deny(missing_copy_implementations)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-missing-doc.rs b/tests/ui/lint/lint-missing-doc.rs
new file mode 100644
index 000000000..229725791
--- /dev/null
+++ b/tests/ui/lint/lint-missing-doc.rs
@@ -0,0 +1,203 @@
+// When denying at the crate level, be sure to not get random warnings from the
+// injected intrinsics by the compiler.
+#![deny(missing_docs)]
+#![allow(dead_code)]
+#![feature(associated_type_defaults, extern_types)]
+
+//! Some garbage docs for the crate here
+#![doc="More garbage"]
+
+type Typedef = String;
+pub type PubTypedef = String; //~ ERROR: missing documentation for a type alias
+
+struct Foo {
+ a: isize,
+ b: isize,
+}
+
+pub struct PubFoo { //~ ERROR: missing documentation for a struct
+ pub a: isize, //~ ERROR: missing documentation for a struct field
+ b: isize,
+}
+
+#[allow(missing_docs)]
+pub struct PubFoo2 {
+ pub a: isize,
+ pub c: isize,
+}
+
+mod module_no_dox {}
+pub mod pub_module_no_dox {} //~ ERROR: missing documentation for a module
+
+/// dox
+pub fn foo() {}
+pub fn foo2() {} //~ ERROR: missing documentation for a function
+fn foo3() {}
+#[allow(missing_docs)] pub fn foo4() {}
+
+/// dox
+pub trait A {
+ /// dox
+ fn foo(&self);
+ /// dox
+ fn foo_with_impl(&self) {}
+}
+
+#[allow(missing_docs)]
+trait B {
+ fn foo(&self);
+ fn foo_with_impl(&self) {}
+}
+
+pub trait C { //~ ERROR: missing documentation for a trait
+ fn foo(&self); //~ ERROR: missing documentation for an associated function
+ fn foo_with_impl(&self) {} //~ ERROR: missing documentation for an associated function
+}
+
+#[allow(missing_docs)]
+pub trait D {
+ fn dummy(&self) { }
+}
+
+/// dox
+pub trait E: Sized {
+ type AssociatedType; //~ ERROR: missing documentation for an associated type
+ type AssociatedTypeDef = Self; //~ ERROR: missing documentation for an associated type
+
+ /// dox
+ type DocumentedType;
+ /// dox
+ type DocumentedTypeDef = Self;
+ /// dox
+ fn dummy(&self) {}
+}
+
+impl Foo {
+ pub fn foo() {}
+ fn bar() {}
+}
+
+impl PubFoo {
+ pub fn foo() {} //~ ERROR: missing documentation for an associated function
+ /// dox
+ pub fn foo1() {}
+ fn foo2() {}
+ #[allow(missing_docs)] pub fn foo3() {}
+}
+
+#[allow(missing_docs)]
+trait F {
+ fn a();
+ fn b(&self);
+}
+
+// should need to redefine documentation for implementations of traits
+impl F for Foo {
+ fn a() {}
+ fn b(&self) {}
+}
+
+// It sure is nice if doc(hidden) implies allow(missing_docs), and that it
+// applies recursively
+#[doc(hidden)]
+mod a {
+ pub fn baz() {}
+ pub mod b {
+ pub fn baz() {}
+ }
+}
+
+enum Baz {
+ BazA {
+ a: isize,
+ b: isize
+ },
+ BarB
+}
+
+pub enum PubBaz { //~ ERROR: missing documentation for an enum
+ PubBazA { //~ ERROR: missing documentation for a variant
+ a: isize, //~ ERROR: missing documentation for a struct field
+ },
+}
+
+/// dox
+pub enum PubBaz2 {
+ /// dox
+ PubBaz2A {
+ /// dox
+ a: isize,
+ },
+}
+
+#[allow(missing_docs)]
+pub enum PubBaz3 {
+ PubBaz3A {
+ b: isize
+ },
+}
+
+#[doc(hidden)]
+pub fn baz() {}
+
+
+const FOO: u32 = 0;
+/// dox
+pub const FOO1: u32 = 0;
+#[allow(missing_docs)]
+pub const FOO2: u32 = 0;
+#[doc(hidden)]
+pub const FOO3: u32 = 0;
+pub const FOO4: u32 = 0; //~ ERROR: missing documentation for a const
+
+
+static BAR: u32 = 0;
+/// dox
+pub static BAR1: u32 = 0;
+#[allow(missing_docs)]
+pub static BAR2: u32 = 0;
+#[doc(hidden)]
+pub static BAR3: u32 = 0;
+pub static BAR4: u32 = 0; //~ ERROR: missing documentation for a static
+
+
+mod internal_impl {
+ /// dox
+ pub fn documented() {}
+ pub fn undocumented1() {} //~ ERROR: missing documentation for a function
+ pub fn undocumented2() {} //~ ERROR: missing documentation for a function
+ fn undocumented3() {}
+ /// dox
+ pub mod globbed {
+ /// dox
+ pub fn also_documented() {}
+ pub fn also_undocumented1() {} //~ ERROR: missing documentation for a function
+ fn also_undocumented2() {}
+ }
+}
+/// dox
+pub mod public_interface {
+ pub use internal_impl::documented as foo;
+ pub use internal_impl::undocumented1 as bar;
+ pub use internal_impl::{documented, undocumented2};
+ pub use internal_impl::globbed::*;
+}
+
+extern "C" {
+ /// dox
+ pub fn extern_fn_documented(f: f32) -> f32;
+ pub fn extern_fn_undocumented(f: f32) -> f32;
+ //~^ ERROR: missing documentation for a function
+
+ /// dox
+ pub static EXTERN_STATIC_DOCUMENTED: u8;
+ pub static EXTERN_STATIC_UNDOCUMENTED: u8;
+ //~^ ERROR: missing documentation for a static
+
+ /// dox
+ pub type ExternTyDocumented;
+ pub type ExternTyUndocumented;
+ //~^ ERROR: missing documentation for a foreign type
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-missing-doc.stderr b/tests/ui/lint/lint-missing-doc.stderr
new file mode 100644
index 000000000..d68472d4b
--- /dev/null
+++ b/tests/ui/lint/lint-missing-doc.stderr
@@ -0,0 +1,140 @@
+error: missing documentation for a type alias
+ --> $DIR/lint-missing-doc.rs:11:1
+ |
+LL | pub type PubTypedef = String;
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-missing-doc.rs:3:9
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a struct
+ --> $DIR/lint-missing-doc.rs:18:1
+ |
+LL | pub struct PubFoo {
+ | ^^^^^^^^^^^^^^^^^
+
+error: missing documentation for a struct field
+ --> $DIR/lint-missing-doc.rs:19:5
+ |
+LL | pub a: isize,
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a module
+ --> $DIR/lint-missing-doc.rs:30:1
+ |
+LL | pub mod pub_module_no_dox {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for a function
+ --> $DIR/lint-missing-doc.rs:34:1
+ |
+LL | pub fn foo2() {}
+ | ^^^^^^^^^^^^^
+
+error: missing documentation for a trait
+ --> $DIR/lint-missing-doc.rs:52:1
+ |
+LL | pub trait C {
+ | ^^^^^^^^^^^
+
+error: missing documentation for an associated function
+ --> $DIR/lint-missing-doc.rs:53:5
+ |
+LL | fn foo(&self);
+ | ^^^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+ --> $DIR/lint-missing-doc.rs:54:5
+ |
+LL | fn foo_with_impl(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for an associated type
+ --> $DIR/lint-missing-doc.rs:64:5
+ |
+LL | type AssociatedType;
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for an associated type
+ --> $DIR/lint-missing-doc.rs:65:5
+ |
+LL | type AssociatedTypeDef = Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+ --> $DIR/lint-missing-doc.rs:81:5
+ |
+LL | pub fn foo() {}
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an enum
+ --> $DIR/lint-missing-doc.rs:118:1
+ |
+LL | pub enum PubBaz {
+ | ^^^^^^^^^^^^^^^
+
+error: missing documentation for a variant
+ --> $DIR/lint-missing-doc.rs:119:5
+ |
+LL | PubBazA {
+ | ^^^^^^^
+
+error: missing documentation for a struct field
+ --> $DIR/lint-missing-doc.rs:120:9
+ |
+LL | a: isize,
+ | ^^^^^^^^
+
+error: missing documentation for a constant
+ --> $DIR/lint-missing-doc.rs:151:1
+ |
+LL | pub const FOO4: u32 = 0;
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for a static
+ --> $DIR/lint-missing-doc.rs:161:1
+ |
+LL | pub static BAR4: u32 = 0;
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for a function
+ --> $DIR/lint-missing-doc.rs:167:5
+ |
+LL | pub fn undocumented1() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for a function
+ --> $DIR/lint-missing-doc.rs:168:5
+ |
+LL | pub fn undocumented2() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for a function
+ --> $DIR/lint-missing-doc.rs:174:9
+ |
+LL | pub fn also_undocumented1() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for a function
+ --> $DIR/lint-missing-doc.rs:189:5
+ |
+LL | pub fn extern_fn_undocumented(f: f32) -> f32;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for a static
+ --> $DIR/lint-missing-doc.rs:194:5
+ |
+LL | pub static EXTERN_STATIC_UNDOCUMENTED: u8;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for a foreign type
+ --> $DIR/lint-missing-doc.rs:199:5
+ |
+LL | pub type ExternTyUndocumented;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 22 previous errors
+
diff --git a/tests/ui/lint/lint-non-camel-case-types.rs b/tests/ui/lint/lint-non-camel-case-types.rs
new file mode 100644
index 000000000..acd5c5df9
--- /dev/null
+++ b/tests/ui/lint/lint-non-camel-case-types.rs
@@ -0,0 +1,37 @@
+#![forbid(non_camel_case_types)]
+#![allow(dead_code)]
+
+struct ONE_TWO_THREE;
+//~^ ERROR type `ONE_TWO_THREE` should have an upper camel case name
+
+struct foo { //~ ERROR type `foo` should have an upper camel case name
+ bar: isize,
+}
+
+enum foo2 { //~ ERROR type `foo2` should have an upper camel case name
+ Bar
+}
+
+struct foo3 { //~ ERROR type `foo3` should have an upper camel case name
+ bar: isize
+}
+
+type foo4 = isize; //~ ERROR type `foo4` should have an upper camel case name
+
+enum Foo5 {
+ bar //~ ERROR variant `bar` should have an upper camel case name
+}
+
+trait foo6 { //~ ERROR trait `foo6` should have an upper camel case name
+ type foo7; //~ ERROR associated type `foo7` should have an upper camel case name
+ fn dummy(&self) { }
+}
+
+fn f<ty>(_: ty) {} //~ ERROR type parameter `ty` should have an upper camel case name
+
+#[repr(C)]
+struct foo7 {
+ bar: isize,
+}
+
+fn main() { }
diff --git a/tests/ui/lint/lint-non-camel-case-types.stderr b/tests/ui/lint/lint-non-camel-case-types.stderr
new file mode 100644
index 000000000..875380b5d
--- /dev/null
+++ b/tests/ui/lint/lint-non-camel-case-types.stderr
@@ -0,0 +1,62 @@
+error: type `ONE_TWO_THREE` should have an upper camel case name
+ --> $DIR/lint-non-camel-case-types.rs:4:8
+ |
+LL | struct ONE_TWO_THREE;
+ | ^^^^^^^^^^^^^ help: convert the identifier to upper camel case: `OneTwoThree`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-non-camel-case-types.rs:1:11
+ |
+LL | #![forbid(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: type `foo` should have an upper camel case name
+ --> $DIR/lint-non-camel-case-types.rs:7:8
+ |
+LL | struct foo {
+ | ^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo`
+
+error: type `foo2` should have an upper camel case name
+ --> $DIR/lint-non-camel-case-types.rs:11:6
+ |
+LL | enum foo2 {
+ | ^^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo2`
+
+error: type `foo3` should have an upper camel case name
+ --> $DIR/lint-non-camel-case-types.rs:15:8
+ |
+LL | struct foo3 {
+ | ^^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo3`
+
+error: type `foo4` should have an upper camel case name
+ --> $DIR/lint-non-camel-case-types.rs:19:6
+ |
+LL | type foo4 = isize;
+ | ^^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo4`
+
+error: variant `bar` should have an upper camel case name
+ --> $DIR/lint-non-camel-case-types.rs:22:5
+ |
+LL | bar
+ | ^^^ help: convert the identifier to upper camel case: `Bar`
+
+error: trait `foo6` should have an upper camel case name
+ --> $DIR/lint-non-camel-case-types.rs:25:7
+ |
+LL | trait foo6 {
+ | ^^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo6`
+
+error: associated type `foo7` should have an upper camel case name
+ --> $DIR/lint-non-camel-case-types.rs:26:10
+ |
+LL | type foo7;
+ | ^^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo7`
+
+error: type parameter `ty` should have an upper camel case name
+ --> $DIR/lint-non-camel-case-types.rs:30:6
+ |
+LL | fn f<ty>(_: ty) {}
+ | ^^ help: convert the identifier to upper camel case: `Ty`
+
+error: aborting due to 9 previous errors
+
diff --git a/tests/ui/lint/lint-non-camel-case-variant.rs b/tests/ui/lint/lint-non-camel-case-variant.rs
new file mode 100644
index 000000000..2b1a52f25
--- /dev/null
+++ b/tests/ui/lint/lint-non-camel-case-variant.rs
@@ -0,0 +1,10 @@
+// check-pass
+
+#![deny(non_camel_case_types)]
+
+pub enum Foo {
+ #[allow(non_camel_case_types)]
+ bar
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-non-camel-case-with-trailing-underscores.rs b/tests/ui/lint/lint-non-camel-case-with-trailing-underscores.rs
new file mode 100644
index 000000000..b832e4bcd
--- /dev/null
+++ b/tests/ui/lint/lint-non-camel-case-with-trailing-underscores.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+#![allow(dead_code)]
+// This is ok because we often use the trailing underscore to mean 'prime'
+
+// pretty-expanded FIXME #23616
+
+#[forbid(non_camel_case_types)]
+type Foo_ = isize;
+
+pub fn main() { }
diff --git a/tests/ui/lint/lint-non-snake-case-crate-2.rs b/tests/ui/lint/lint-non-snake-case-crate-2.rs
new file mode 100644
index 000000000..1b763a9d8
--- /dev/null
+++ b/tests/ui/lint/lint-non-snake-case-crate-2.rs
@@ -0,0 +1,6 @@
+// compile-flags: --crate-name NonSnakeCase
+// error-pattern: crate `NonSnakeCase` should have a snake case name
+
+#![deny(non_snake_case)]
+
+fn main() {}
diff --git a/tests/ui/lint/lint-non-snake-case-crate-2.stderr b/tests/ui/lint/lint-non-snake-case-crate-2.stderr
new file mode 100644
index 000000000..4b42145bb
--- /dev/null
+++ b/tests/ui/lint/lint-non-snake-case-crate-2.stderr
@@ -0,0 +1,11 @@
+error: crate `NonSnakeCase` should have a snake case name
+ |
+ = help: convert the identifier to snake case: `non_snake_case`
+note: the lint level is defined here
+ --> $DIR/lint-non-snake-case-crate-2.rs:4:9
+ |
+LL | #![deny(non_snake_case)]
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-non-snake-case-crate.rs b/tests/ui/lint/lint-non-snake-case-crate.rs
new file mode 100644
index 000000000..e4e84261a
--- /dev/null
+++ b/tests/ui/lint/lint-non-snake-case-crate.rs
@@ -0,0 +1,5 @@
+#![crate_name = "NonSnakeCase"]
+//~^ ERROR crate `NonSnakeCase` should have a snake case name
+#![deny(non_snake_case)]
+
+fn main() {}
diff --git a/tests/ui/lint/lint-non-snake-case-crate.stderr b/tests/ui/lint/lint-non-snake-case-crate.stderr
new file mode 100644
index 000000000..da6b89c1e
--- /dev/null
+++ b/tests/ui/lint/lint-non-snake-case-crate.stderr
@@ -0,0 +1,14 @@
+error: crate `NonSnakeCase` should have a snake case name
+ --> $DIR/lint-non-snake-case-crate.rs:1:18
+ |
+LL | #![crate_name = "NonSnakeCase"]
+ | ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-non-snake-case-crate.rs:3:9
+ |
+LL | #![deny(non_snake_case)]
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-non-snake-case-functions.rs b/tests/ui/lint/lint-non-snake-case-functions.rs
new file mode 100644
index 000000000..fa64a9f98
--- /dev/null
+++ b/tests/ui/lint/lint-non-snake-case-functions.rs
@@ -0,0 +1,44 @@
+#![deny(non_snake_case)]
+#![allow(dead_code)]
+
+struct Foo;
+
+impl Foo {
+ fn Foo_Method() {}
+ //~^ ERROR method `Foo_Method` should have a snake case name
+
+ // Don't allow two underscores in a row
+ fn foo__method(&self) {}
+ //~^ ERROR method `foo__method` should have a snake case name
+
+ pub fn xyZ(&mut self) {}
+ //~^ ERROR method `xyZ` should have a snake case name
+
+ fn render_HTML() {}
+ //~^ ERROR method `render_HTML` should have a snake case name
+}
+
+trait X {
+ fn ABC();
+ //~^ ERROR trait method `ABC` should have a snake case name
+
+ fn a_b_C(&self) {}
+ //~^ ERROR trait method `a_b_C` should have a snake case name
+
+ fn something__else(&mut self);
+ //~^ ERROR trait method `something__else` should have a snake case name
+}
+
+impl X for Foo {
+ // These errors should be caught at the trait definition not the impl
+ fn ABC() {}
+ fn something__else(&mut self) {}
+}
+
+fn Cookie() {}
+//~^ ERROR function `Cookie` should have a snake case name
+
+pub fn bi_S_Cuit() {}
+//~^ ERROR function `bi_S_Cuit` should have a snake case name
+
+fn main() { }
diff --git a/tests/ui/lint/lint-non-snake-case-functions.stderr b/tests/ui/lint/lint-non-snake-case-functions.stderr
new file mode 100644
index 000000000..f6ac6b99b
--- /dev/null
+++ b/tests/ui/lint/lint-non-snake-case-functions.stderr
@@ -0,0 +1,62 @@
+error: method `Foo_Method` should have a snake case name
+ --> $DIR/lint-non-snake-case-functions.rs:7:8
+ |
+LL | fn Foo_Method() {}
+ | ^^^^^^^^^^ help: convert the identifier to snake case: `foo_method`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-non-snake-case-functions.rs:1:9
+ |
+LL | #![deny(non_snake_case)]
+ | ^^^^^^^^^^^^^^
+
+error: method `foo__method` should have a snake case name
+ --> $DIR/lint-non-snake-case-functions.rs:11:8
+ |
+LL | fn foo__method(&self) {}
+ | ^^^^^^^^^^^ help: convert the identifier to snake case: `foo_method`
+
+error: method `xyZ` should have a snake case name
+ --> $DIR/lint-non-snake-case-functions.rs:14:12
+ |
+LL | pub fn xyZ(&mut self) {}
+ | ^^^ help: convert the identifier to snake case: `xy_z`
+
+error: method `render_HTML` should have a snake case name
+ --> $DIR/lint-non-snake-case-functions.rs:17:8
+ |
+LL | fn render_HTML() {}
+ | ^^^^^^^^^^^ help: convert the identifier to snake case: `render_html`
+
+error: trait method `ABC` should have a snake case name
+ --> $DIR/lint-non-snake-case-functions.rs:22:8
+ |
+LL | fn ABC();
+ | ^^^ help: convert the identifier to snake case: `abc`
+
+error: trait method `a_b_C` should have a snake case name
+ --> $DIR/lint-non-snake-case-functions.rs:25:8
+ |
+LL | fn a_b_C(&self) {}
+ | ^^^^^ help: convert the identifier to snake case (notice the capitalization): `a_b_c`
+
+error: trait method `something__else` should have a snake case name
+ --> $DIR/lint-non-snake-case-functions.rs:28:8
+ |
+LL | fn something__else(&mut self);
+ | ^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `something_else`
+
+error: function `Cookie` should have a snake case name
+ --> $DIR/lint-non-snake-case-functions.rs:38:4
+ |
+LL | fn Cookie() {}
+ | ^^^^^^ help: convert the identifier to snake case (notice the capitalization): `cookie`
+
+error: function `bi_S_Cuit` should have a snake case name
+ --> $DIR/lint-non-snake-case-functions.rs:41:8
+ |
+LL | pub fn bi_S_Cuit() {}
+ | ^^^^^^^^^ help: convert the identifier to snake case (notice the capitalization): `bi_s_cuit`
+
+error: aborting due to 9 previous errors
+
diff --git a/tests/ui/lint/lint-non-snake-case-identifiers-suggestion-reserved.rs b/tests/ui/lint/lint-non-snake-case-identifiers-suggestion-reserved.rs
new file mode 100644
index 000000000..8cc4f976a
--- /dev/null
+++ b/tests/ui/lint/lint-non-snake-case-identifiers-suggestion-reserved.rs
@@ -0,0 +1,19 @@
+#![warn(unused)]
+#![allow(dead_code)]
+#![deny(non_snake_case)]
+
+mod Impl {}
+//~^ ERROR module `Impl` should have a snake case name
+
+fn While() {}
+//~^ ERROR function `While` should have a snake case name
+
+fn main() {
+ let Mod: usize = 0;
+ //~^ ERROR variable `Mod` should have a snake case name
+ //~^^ WARN unused variable: `Mod`
+
+ let Super: usize = 0;
+ //~^ ERROR variable `Super` should have a snake case name
+ //~^^ WARN unused variable: `Super`
+}
diff --git a/tests/ui/lint/lint-non-snake-case-identifiers-suggestion-reserved.stderr b/tests/ui/lint/lint-non-snake-case-identifiers-suggestion-reserved.stderr
new file mode 100644
index 000000000..2841815ec
--- /dev/null
+++ b/tests/ui/lint/lint-non-snake-case-identifiers-suggestion-reserved.stderr
@@ -0,0 +1,67 @@
+warning: unused variable: `Mod`
+ --> $DIR/lint-non-snake-case-identifiers-suggestion-reserved.rs:12:9
+ |
+LL | let Mod: usize = 0;
+ | ^^^ help: if this is intentional, prefix it with an underscore: `_Mod`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-non-snake-case-identifiers-suggestion-reserved.rs:1:9
+ |
+LL | #![warn(unused)]
+ | ^^^^^^
+ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
+
+warning: unused variable: `Super`
+ --> $DIR/lint-non-snake-case-identifiers-suggestion-reserved.rs:16:9
+ |
+LL | let Super: usize = 0;
+ | ^^^^^ help: if this is intentional, prefix it with an underscore: `_Super`
+
+error: module `Impl` should have a snake case name
+ --> $DIR/lint-non-snake-case-identifiers-suggestion-reserved.rs:5:5
+ |
+LL | mod Impl {}
+ | ^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-non-snake-case-identifiers-suggestion-reserved.rs:3:9
+ |
+LL | #![deny(non_snake_case)]
+ | ^^^^^^^^^^^^^^
+help: rename the identifier or convert it to a snake case raw identifier
+ |
+LL | mod r#impl {}
+ | ~~~~~~
+
+error: function `While` should have a snake case name
+ --> $DIR/lint-non-snake-case-identifiers-suggestion-reserved.rs:8:4
+ |
+LL | fn While() {}
+ | ^^^^^
+ |
+help: rename the identifier or convert it to a snake case raw identifier
+ |
+LL | fn r#while() {}
+ | ~~~~~~~
+
+error: variable `Mod` should have a snake case name
+ --> $DIR/lint-non-snake-case-identifiers-suggestion-reserved.rs:12:9
+ |
+LL | let Mod: usize = 0;
+ | ^^^
+ |
+help: rename the identifier or convert it to a snake case raw identifier
+ |
+LL | let r#mod: usize = 0;
+ | ~~~~~
+
+error: variable `Super` should have a snake case name
+ --> $DIR/lint-non-snake-case-identifiers-suggestion-reserved.rs:16:9
+ |
+LL | let Super: usize = 0;
+ | ^^^^^ help: rename the identifier
+ |
+ = note: `super` cannot be used as a raw identifier
+
+error: aborting due to 4 previous errors; 2 warnings emitted
+
diff --git a/tests/ui/lint/lint-non-snake-case-lifetimes.rs b/tests/ui/lint/lint-non-snake-case-lifetimes.rs
new file mode 100644
index 000000000..de76d2dbe
--- /dev/null
+++ b/tests/ui/lint/lint-non-snake-case-lifetimes.rs
@@ -0,0 +1,8 @@
+#![deny(non_snake_case)]
+#![allow(dead_code)]
+
+fn f<'FooBar>( //~ ERROR lifetime `'FooBar` should have a snake case name
+ _: &'FooBar ()
+) {}
+
+fn main() { }
diff --git a/tests/ui/lint/lint-non-snake-case-lifetimes.stderr b/tests/ui/lint/lint-non-snake-case-lifetimes.stderr
new file mode 100644
index 000000000..d4fe26a43
--- /dev/null
+++ b/tests/ui/lint/lint-non-snake-case-lifetimes.stderr
@@ -0,0 +1,14 @@
+error: lifetime `'FooBar` should have a snake case name
+ --> $DIR/lint-non-snake-case-lifetimes.rs:4:6
+ |
+LL | fn f<'FooBar>(
+ | ^^^^^^^ help: convert the identifier to snake case: `'foo_bar`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-non-snake-case-lifetimes.rs:1:9
+ |
+LL | #![deny(non_snake_case)]
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-non-snake-case-modules.rs b/tests/ui/lint/lint-non-snake-case-modules.rs
new file mode 100644
index 000000000..73f123321
--- /dev/null
+++ b/tests/ui/lint/lint-non-snake-case-modules.rs
@@ -0,0 +1,10 @@
+#![deny(non_snake_case)]
+#![allow(dead_code)]
+
+mod FooBar { //~ ERROR module `FooBar` should have a snake case name
+ pub struct S;
+}
+
+fn f(_: FooBar::S) { }
+
+fn main() { }
diff --git a/tests/ui/lint/lint-non-snake-case-modules.stderr b/tests/ui/lint/lint-non-snake-case-modules.stderr
new file mode 100644
index 000000000..c8b997c87
--- /dev/null
+++ b/tests/ui/lint/lint-non-snake-case-modules.stderr
@@ -0,0 +1,14 @@
+error: module `FooBar` should have a snake case name
+ --> $DIR/lint-non-snake-case-modules.rs:4:5
+ |
+LL | mod FooBar {
+ | ^^^^^^ help: convert the identifier to snake case: `foo_bar`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-non-snake-case-modules.rs:1:9
+ |
+LL | #![deny(non_snake_case)]
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs b/tests/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs
new file mode 100644
index 000000000..9f0c87dca
--- /dev/null
+++ b/tests/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+#![allow(dead_code)]
+// pretty-expanded FIXME #23616
+
+#![deny(non_snake_case)]
+
+// This name is neither upper nor lower case
+fn 你好() {}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-non-uppercase-associated-const.rs b/tests/ui/lint/lint-non-uppercase-associated-const.rs
new file mode 100644
index 000000000..7b0d93960
--- /dev/null
+++ b/tests/ui/lint/lint-non-uppercase-associated-const.rs
@@ -0,0 +1,11 @@
+#![deny(non_upper_case_globals)]
+#![allow(dead_code)]
+
+struct Foo;
+
+impl Foo {
+ const not_upper: bool = true;
+}
+//~^^ ERROR associated constant `not_upper` should have an upper case name
+
+fn main() {}
diff --git a/tests/ui/lint/lint-non-uppercase-associated-const.stderr b/tests/ui/lint/lint-non-uppercase-associated-const.stderr
new file mode 100644
index 000000000..411ff51aa
--- /dev/null
+++ b/tests/ui/lint/lint-non-uppercase-associated-const.stderr
@@ -0,0 +1,14 @@
+error: associated constant `not_upper` should have an upper case name
+ --> $DIR/lint-non-uppercase-associated-const.rs:7:11
+ |
+LL | const not_upper: bool = true;
+ | ^^^^^^^^^ help: convert the identifier to upper case: `NOT_UPPER`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-non-uppercase-associated-const.rs:1:9
+ |
+LL | #![deny(non_upper_case_globals)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-non-uppercase-statics.rs b/tests/ui/lint/lint-non-uppercase-statics.rs
new file mode 100644
index 000000000..5bd143032
--- /dev/null
+++ b/tests/ui/lint/lint-non-uppercase-statics.rs
@@ -0,0 +1,11 @@
+#![forbid(non_upper_case_globals)]
+#![allow(dead_code)]
+
+static foo: isize = 1; //~ ERROR static variable `foo` should have an upper case name
+
+static mut bar: isize = 1; //~ ERROR static variable `bar` should have an upper case name
+
+#[no_mangle]
+pub static extern_foo: isize = 1; // OK, because #[no_mangle] supersedes the warning
+
+fn main() { }
diff --git a/tests/ui/lint/lint-non-uppercase-statics.stderr b/tests/ui/lint/lint-non-uppercase-statics.stderr
new file mode 100644
index 000000000..c6fd0a6e0
--- /dev/null
+++ b/tests/ui/lint/lint-non-uppercase-statics.stderr
@@ -0,0 +1,20 @@
+error: static variable `foo` should have an upper case name
+ --> $DIR/lint-non-uppercase-statics.rs:4:8
+ |
+LL | static foo: isize = 1;
+ | ^^^ help: convert the identifier to upper case (notice the capitalization): `FOO`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-non-uppercase-statics.rs:1:11
+ |
+LL | #![forbid(non_upper_case_globals)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: static variable `bar` should have an upper case name
+ --> $DIR/lint-non-uppercase-statics.rs:6:12
+ |
+LL | static mut bar: isize = 1;
+ | ^^^ help: convert the identifier to upper case: `BAR`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/lint-nonstandard-style-unicode-1.rs b/tests/ui/lint/lint-nonstandard-style-unicode-1.rs
new file mode 100644
index 000000000..7c45c0993
--- /dev/null
+++ b/tests/ui/lint/lint-nonstandard-style-unicode-1.rs
@@ -0,0 +1,49 @@
+#![allow(dead_code)]
+
+#![forbid(non_camel_case_types)]
+
+// Some scripts (e.g., hiragana) don't have a concept of
+// upper/lowercase
+
+// 1. non_camel_case_types
+
+// Can start with non-lowercase letter
+struct Θχ;
+struct ヒa;
+
+struct χa;
+//~^ ERROR type `χa` should have an upper camel case name
+
+// If there's already leading or trailing underscores, they get trimmed before checking.
+// This is fine:
+struct _ヒb;
+
+// This is not:
+struct __χa;
+//~^ ERROR type `__χa` should have an upper camel case name
+
+// Besides this, we cannot have two continuous underscores in the middle.
+
+struct 对__否;
+//~^ ERROR type `对__否` should have an upper camel case name
+
+struct ヒ__χ;
+//~^ ERROR type `ヒ__χ` should have an upper camel case name
+
+// also cannot have lowercase letter next to an underscore.
+// so this triggers the lint:
+
+struct Hello_你好;
+//~^ ERROR type `Hello_你好` should have an upper camel case name
+
+struct Hello_World;
+//~^ ERROR type `Hello_World` should have an upper camel case name
+
+struct 你_ӟ;
+//~^ ERROR type `你_ӟ` should have an upper camel case name
+
+// and this is ok:
+
+struct 你_好;
+
+fn main() {}
diff --git a/tests/ui/lint/lint-nonstandard-style-unicode-1.stderr b/tests/ui/lint/lint-nonstandard-style-unicode-1.stderr
new file mode 100644
index 000000000..6c2aa225e
--- /dev/null
+++ b/tests/ui/lint/lint-nonstandard-style-unicode-1.stderr
@@ -0,0 +1,50 @@
+error: type `χa` should have an upper camel case name
+ --> $DIR/lint-nonstandard-style-unicode-1.rs:14:8
+ |
+LL | struct χa;
+ | ^^ help: convert the identifier to upper camel case: `Χa`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-nonstandard-style-unicode-1.rs:3:11
+ |
+LL | #![forbid(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: type `__χa` should have an upper camel case name
+ --> $DIR/lint-nonstandard-style-unicode-1.rs:22:8
+ |
+LL | struct __χa;
+ | ^^^^ help: convert the identifier to upper camel case: `Χa`
+
+error: type `对__否` should have an upper camel case name
+ --> $DIR/lint-nonstandard-style-unicode-1.rs:27:8
+ |
+LL | struct 对__否;
+ | ^^^^^^ help: convert the identifier to upper camel case: `对_否`
+
+error: type `ヒ__χ` should have an upper camel case name
+ --> $DIR/lint-nonstandard-style-unicode-1.rs:30:8
+ |
+LL | struct ヒ__χ;
+ | ^^^^^ help: convert the identifier to upper camel case: `ヒΧ`
+
+error: type `Hello_你好` should have an upper camel case name
+ --> $DIR/lint-nonstandard-style-unicode-1.rs:36:8
+ |
+LL | struct Hello_你好;
+ | ^^^^^^^^^^ help: convert the identifier to upper camel case: `Hello你好`
+
+error: type `Hello_World` should have an upper camel case name
+ --> $DIR/lint-nonstandard-style-unicode-1.rs:39:8
+ |
+LL | struct Hello_World;
+ | ^^^^^^^^^^^ help: convert the identifier to upper camel case: `HelloWorld`
+
+error: type `你_ӟ` should have an upper camel case name
+ --> $DIR/lint-nonstandard-style-unicode-1.rs:42:8
+ |
+LL | struct 你_ӟ;
+ | ^^^^ help: convert the identifier to upper camel case: `你Ӟ`
+
+error: aborting due to 7 previous errors
+
diff --git a/tests/ui/lint/lint-nonstandard-style-unicode-2.rs b/tests/ui/lint/lint-nonstandard-style-unicode-2.rs
new file mode 100644
index 000000000..9690be590
--- /dev/null
+++ b/tests/ui/lint/lint-nonstandard-style-unicode-2.rs
@@ -0,0 +1,29 @@
+#![allow(dead_code)]
+
+#![forbid(non_snake_case)]
+
+// Some scripts (e.g., hiragana) don't have a concept of
+// upper/lowercase
+
+// 2. non_snake_case
+
+// Can only use non-uppercase letters.
+// So this works:
+
+fn 编程() {}
+
+// but this doesn't:
+
+fn Ц() {}
+//~^ ERROR function `Ц` should have a snake case name
+
+// besides this, you cannot use continuous underscores in the middle
+
+fn 分__隔() {}
+//~^ ERROR function `分__隔` should have a snake case name
+
+// but you can use them both at the beginning and at the end.
+
+fn _______不_连_续_的_存_在_______() {}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-nonstandard-style-unicode-2.stderr b/tests/ui/lint/lint-nonstandard-style-unicode-2.stderr
new file mode 100644
index 000000000..8eb0654e0
--- /dev/null
+++ b/tests/ui/lint/lint-nonstandard-style-unicode-2.stderr
@@ -0,0 +1,20 @@
+error: function `Ц` should have a snake case name
+ --> $DIR/lint-nonstandard-style-unicode-2.rs:17:4
+ |
+LL | fn Ц() {}
+ | ^ help: convert the identifier to snake case: `ц`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-nonstandard-style-unicode-2.rs:3:11
+ |
+LL | #![forbid(non_snake_case)]
+ | ^^^^^^^^^^^^^^
+
+error: function `分__隔` should have a snake case name
+ --> $DIR/lint-nonstandard-style-unicode-2.rs:22:4
+ |
+LL | fn 分__隔() {}
+ | ^^^^^^ help: convert the identifier to snake case: `分_隔`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/lint-nonstandard-style-unicode-3.rs b/tests/ui/lint/lint-nonstandard-style-unicode-3.rs
new file mode 100644
index 000000000..9175be7a0
--- /dev/null
+++ b/tests/ui/lint/lint-nonstandard-style-unicode-3.rs
@@ -0,0 +1,24 @@
+#![allow(dead_code)]
+
+#![forbid(non_upper_case_globals)]
+
+// Some scripts (e.g., hiragana) don't have a concept of
+// upper/lowercase
+
+// 3. non_upper_case_globals
+
+// Can only use non-lowercase letters.
+// So this works:
+
+static ラ: usize = 0;
+
+// but this doesn't:
+
+static τεχ: f32 = 3.14159265;
+//~^ ERROR static variable `τεχ` should have an upper case name
+
+// This has no limit at all on underscore usages.
+
+static __密__封__线__内__禁__止__答__题__: bool = true;
+
+fn main() {}
diff --git a/tests/ui/lint/lint-nonstandard-style-unicode-3.stderr b/tests/ui/lint/lint-nonstandard-style-unicode-3.stderr
new file mode 100644
index 000000000..970e6b838
--- /dev/null
+++ b/tests/ui/lint/lint-nonstandard-style-unicode-3.stderr
@@ -0,0 +1,14 @@
+error: static variable `τεχ` should have an upper case name
+ --> $DIR/lint-nonstandard-style-unicode-3.rs:17:8
+ |
+LL | static τεχ: f32 = 3.14159265;
+ | ^^^ help: convert the identifier to upper case: `ΤΕΧ`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-nonstandard-style-unicode-3.rs:3:11
+ |
+LL | #![forbid(non_upper_case_globals)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-output-format-2.rs b/tests/ui/lint/lint-output-format-2.rs
new file mode 100644
index 000000000..985166e09
--- /dev/null
+++ b/tests/ui/lint/lint-output-format-2.rs
@@ -0,0 +1,15 @@
+// aux-build:lint_output_format.rs
+
+#![feature(unstable_test_feature)]
+// check-pass
+
+extern crate lint_output_format;
+use lint_output_format::{foo, bar};
+//~^ WARNING use of deprecated function `lint_output_format::foo`: text
+
+
+fn main() {
+ let _x = foo();
+ //~^ WARNING use of deprecated function `lint_output_format::foo`: text
+ let _y = bar();
+}
diff --git a/tests/ui/lint/lint-output-format-2.stderr b/tests/ui/lint/lint-output-format-2.stderr
new file mode 100644
index 000000000..a36dbd61f
--- /dev/null
+++ b/tests/ui/lint/lint-output-format-2.stderr
@@ -0,0 +1,16 @@
+warning: use of deprecated function `lint_output_format::foo`: text
+ --> $DIR/lint-output-format-2.rs:7:26
+ |
+LL | use lint_output_format::{foo, bar};
+ | ^^^
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+warning: use of deprecated function `lint_output_format::foo`: text
+ --> $DIR/lint-output-format-2.rs:12:14
+ |
+LL | let _x = foo();
+ | ^^^
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/lint/lint-output-format.rs b/tests/ui/lint/lint-output-format.rs
new file mode 100644
index 000000000..67e8ec8f1
--- /dev/null
+++ b/tests/ui/lint/lint-output-format.rs
@@ -0,0 +1,13 @@
+// compile-flags: -F unused_features
+// aux-build:lint_output_format.rs
+
+#![allow(deprecated)]
+
+extern crate lint_output_format; //~ ERROR use of unstable library feature
+use lint_output_format::{foo, bar}; //~ ERROR use of unstable library feature
+//~| ERROR use of unstable library feature
+
+fn main() {
+ let _x = foo();
+ let _y = bar(); //~ ERROR use of unstable library feature
+}
diff --git a/tests/ui/lint/lint-output-format.stderr b/tests/ui/lint/lint-output-format.stderr
new file mode 100644
index 000000000..0db79a156
--- /dev/null
+++ b/tests/ui/lint/lint-output-format.stderr
@@ -0,0 +1,35 @@
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-output-format.rs:6:1
+ |
+LL | extern crate lint_output_format;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-output-format.rs:7:26
+ |
+LL | use lint_output_format::{foo, bar};
+ | ^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-output-format.rs:7:31
+ |
+LL | use lint_output_format::{foo, bar};
+ | ^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-output-format.rs:12:14
+ |
+LL | let _y = bar();
+ | ^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/lint/lint-owned-heap-memory.rs b/tests/ui/lint/lint-owned-heap-memory.rs
new file mode 100644
index 000000000..af47d5c07
--- /dev/null
+++ b/tests/ui/lint/lint-owned-heap-memory.rs
@@ -0,0 +1,12 @@
+#![allow(dead_code)]
+#![forbid(box_pointers)]
+
+
+struct Foo {
+ x: Box<isize> //~ ERROR type uses owned
+}
+
+fn main() {
+ let _x: Foo = Foo { x : Box::new(10) };
+ //~^ ERROR type uses owned
+}
diff --git a/tests/ui/lint/lint-owned-heap-memory.stderr b/tests/ui/lint/lint-owned-heap-memory.stderr
new file mode 100644
index 000000000..5ba396970
--- /dev/null
+++ b/tests/ui/lint/lint-owned-heap-memory.stderr
@@ -0,0 +1,20 @@
+error: type uses owned (Box type) pointers: Box<isize>
+ --> $DIR/lint-owned-heap-memory.rs:6:5
+ |
+LL | x: Box<isize>
+ | ^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-owned-heap-memory.rs:2:11
+ |
+LL | #![forbid(box_pointers)]
+ | ^^^^^^^^^^^^
+
+error: type uses owned (Box type) pointers: Box<isize>
+ --> $DIR/lint-owned-heap-memory.rs:10:29
+ |
+LL | let _x: Foo = Foo { x : Box::new(10) };
+ | ^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/lint-pre-expansion-extern-module.rs b/tests/ui/lint/lint-pre-expansion-extern-module.rs
new file mode 100644
index 000000000..30e2ed8b7
--- /dev/null
+++ b/tests/ui/lint/lint-pre-expansion-extern-module.rs
@@ -0,0 +1,7 @@
+// check-pass
+// compile-flags: -W rust-2018-compatibility
+// error-pattern: `try` is a keyword in the 2018 edition
+
+fn main() {}
+
+mod lint_pre_expansion_extern_module_aux;
diff --git a/tests/ui/lint/lint-pre-expansion-extern-module.stderr b/tests/ui/lint/lint-pre-expansion-extern-module.stderr
new file mode 100644
index 000000000..ce3e8806a
--- /dev/null
+++ b/tests/ui/lint/lint-pre-expansion-extern-module.stderr
@@ -0,0 +1,12 @@
+warning: `try` is a keyword in the 2018 edition
+ --> $DIR/lint_pre_expansion_extern_module_aux.rs:3:8
+ |
+LL | pub fn try() {}
+ | ^^^ help: you can use a raw identifier to stay compatible: `r#try`
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+ = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+ = note: `-W keyword-idents` implied by `-W rust-2018-compatibility`
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/lint-pub-unreachable-for-nested-glob.rs b/tests/ui/lint/lint-pub-unreachable-for-nested-glob.rs
new file mode 100644
index 000000000..2df6d08e7
--- /dev/null
+++ b/tests/ui/lint/lint-pub-unreachable-for-nested-glob.rs
@@ -0,0 +1,28 @@
+// check-pass
+
+#![deny(unreachable_pub)]
+
+pub use self::m1::*;
+
+mod m1 {
+ pub use self::m2::*;
+
+ mod m2 {
+ pub struct Item1;
+ pub struct Item2;
+ }
+}
+
+
+pub use self::o1::{ Item42, Item24 };
+
+mod o1 {
+ pub use self::o2::{ Item42, Item24 };
+
+ mod o2 {
+ pub struct Item42;
+ pub struct Item24;
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-qualification.rs b/tests/ui/lint/lint-qualification.rs
new file mode 100644
index 000000000..0cace0ca0
--- /dev/null
+++ b/tests/ui/lint/lint-qualification.rs
@@ -0,0 +1,20 @@
+#![deny(unused_qualifications)]
+#![allow(deprecated)]
+
+mod foo {
+ pub fn bar() {}
+}
+
+fn main() {
+ use foo::bar;
+ foo::bar(); //~ ERROR: unnecessary qualification
+ bar();
+
+ let _ = || -> Result<(), ()> { try!(Ok(())); Ok(()) }; // issue #37345
+
+ macro_rules! m { () => {
+ $crate::foo::bar(); // issue #37357
+ ::foo::bar(); // issue #38682
+ } }
+ m!();
+}
diff --git a/tests/ui/lint/lint-qualification.stderr b/tests/ui/lint/lint-qualification.stderr
new file mode 100644
index 000000000..149a782d9
--- /dev/null
+++ b/tests/ui/lint/lint-qualification.stderr
@@ -0,0 +1,14 @@
+error: unnecessary qualification
+ --> $DIR/lint-qualification.rs:10:5
+ |
+LL | foo::bar();
+ | ^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-qualification.rs:1:9
+ |
+LL | #![deny(unused_qualifications)]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-range-endpoint-overflow.rs b/tests/ui/lint/lint-range-endpoint-overflow.rs
new file mode 100644
index 000000000..7034d56aa
--- /dev/null
+++ b/tests/ui/lint/lint-range-endpoint-overflow.rs
@@ -0,0 +1,17 @@
+#![deny(overflowing_literals)]
+
+fn main() {
+ let range_a = 0..256; //~ ERROR range endpoint is out of range for `u8`
+ let range_b = 0..=255; // ok
+ let range_c = 0..=256; //~ ERROR literal out of range for `u8`
+ let range_d = 256..5; //~ ERROR literal out of range for `u8`
+ let range_e = 0..257; //~ ERROR literal out of range for `u8`
+ let _range_f = 0..256u8; //~ ERROR range endpoint is out of range for `u8`
+ let _range_g = 0..128i8; //~ ERROR range endpoint is out of range for `i8`
+
+ range_a.collect::<Vec<u8>>();
+ range_b.collect::<Vec<u8>>();
+ range_c.collect::<Vec<u8>>();
+ range_d.collect::<Vec<u8>>();
+ range_e.collect::<Vec<u8>>();
+}
diff --git a/tests/ui/lint/lint-range-endpoint-overflow.stderr b/tests/ui/lint/lint-range-endpoint-overflow.stderr
new file mode 100644
index 000000000..d2df73727
--- /dev/null
+++ b/tests/ui/lint/lint-range-endpoint-overflow.stderr
@@ -0,0 +1,50 @@
+error: range endpoint is out of range for `u8`
+ --> $DIR/lint-range-endpoint-overflow.rs:4:19
+ |
+LL | let range_a = 0..256;
+ | ^^^^^^ help: use an inclusive range instead: `0..=255`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-range-endpoint-overflow.rs:1:9
+ |
+LL | #![deny(overflowing_literals)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: literal out of range for `u8`
+ --> $DIR/lint-range-endpoint-overflow.rs:6:23
+ |
+LL | let range_c = 0..=256;
+ | ^^^
+ |
+ = note: the literal `256` does not fit into the type `u8` whose range is `0..=255`
+
+error: literal out of range for `u8`
+ --> $DIR/lint-range-endpoint-overflow.rs:7:19
+ |
+LL | let range_d = 256..5;
+ | ^^^
+ |
+ = note: the literal `256` does not fit into the type `u8` whose range is `0..=255`
+
+error: literal out of range for `u8`
+ --> $DIR/lint-range-endpoint-overflow.rs:8:22
+ |
+LL | let range_e = 0..257;
+ | ^^^
+ |
+ = note: the literal `257` does not fit into the type `u8` whose range is `0..=255`
+
+error: range endpoint is out of range for `u8`
+ --> $DIR/lint-range-endpoint-overflow.rs:9:20
+ |
+LL | let _range_f = 0..256u8;
+ | ^^^^^^^^ help: use an inclusive range instead: `0..=255u8`
+
+error: range endpoint is out of range for `i8`
+ --> $DIR/lint-range-endpoint-overflow.rs:10:20
+ |
+LL | let _range_g = 0..128i8;
+ | ^^^^^^^^ help: use an inclusive range instead: `0..=127i8`
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/lint/lint-removed-allow.rs b/tests/ui/lint/lint-removed-allow.rs
new file mode 100644
index 000000000..30ba4f02f
--- /dev/null
+++ b/tests/ui/lint/lint-removed-allow.rs
@@ -0,0 +1,8 @@
+// No warnings about removed lint when
+// allow(renamed_and_removed_lints)
+
+#![allow(renamed_and_removed_lints)]
+
+#[deny(raw_pointer_derive)]
+#[deny(unused_variables)]
+fn main() { let unused = (); } //~ ERROR unused
diff --git a/tests/ui/lint/lint-removed-allow.stderr b/tests/ui/lint/lint-removed-allow.stderr
new file mode 100644
index 000000000..029334c2e
--- /dev/null
+++ b/tests/ui/lint/lint-removed-allow.stderr
@@ -0,0 +1,14 @@
+error: unused variable: `unused`
+ --> $DIR/lint-removed-allow.rs:8:17
+ |
+LL | fn main() { let unused = (); }
+ | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-removed-allow.rs:7:8
+ |
+LL | #[deny(unused_variables)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-removed-cmdline.rs b/tests/ui/lint/lint-removed-cmdline.rs
new file mode 100644
index 000000000..462beabb9
--- /dev/null
+++ b/tests/ui/lint/lint-removed-cmdline.rs
@@ -0,0 +1,12 @@
+// The raw_pointer_derived lint warns about its removal
+// cc #30346
+
+// compile-flags:-D raw_pointer_derive
+
+// error-pattern:lint `raw_pointer_derive` has been removed
+// error-pattern:requested on the command line with `-D raw_pointer_derive`
+
+#![warn(unused)]
+
+#[deny(warnings)]
+fn main() { let unused = (); }
diff --git a/tests/ui/lint/lint-removed-cmdline.stderr b/tests/ui/lint/lint-removed-cmdline.stderr
new file mode 100644
index 000000000..9be532ef2
--- /dev/null
+++ b/tests/ui/lint/lint-removed-cmdline.stderr
@@ -0,0 +1,27 @@
+warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok
+ |
+ = note: requested on the command line with `-D raw_pointer_derive`
+
+warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok
+ |
+ = note: requested on the command line with `-D raw_pointer_derive`
+
+warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok
+ |
+ = note: requested on the command line with `-D raw_pointer_derive`
+
+error: unused variable: `unused`
+ --> $DIR/lint-removed-cmdline.rs:12:17
+ |
+LL | fn main() { let unused = (); }
+ | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-removed-cmdline.rs:11:8
+ |
+LL | #[deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]`
+
+error: aborting due to previous error; 3 warnings emitted
+
diff --git a/tests/ui/lint/lint-removed.rs b/tests/ui/lint/lint-removed.rs
new file mode 100644
index 000000000..92f4372c2
--- /dev/null
+++ b/tests/ui/lint/lint-removed.rs
@@ -0,0 +1,8 @@
+// The raw_pointer_derived lint was removed, but is now reported by
+// the renamed_and_removed_lints lint, which means it's a warning by
+// default, and allowed in cargo dependency builds.
+// cc #30346
+
+#[deny(raw_pointer_derive)] //~ WARN `raw_pointer_derive` has been removed
+#[deny(unused_variables)]
+fn main() { let unused = (); } //~ ERROR unused
diff --git a/tests/ui/lint/lint-removed.stderr b/tests/ui/lint/lint-removed.stderr
new file mode 100644
index 000000000..dc0515b84
--- /dev/null
+++ b/tests/ui/lint/lint-removed.stderr
@@ -0,0 +1,22 @@
+warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok
+ --> $DIR/lint-removed.rs:6:8
+ |
+LL | #[deny(raw_pointer_derive)]
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(renamed_and_removed_lints)]` on by default
+
+error: unused variable: `unused`
+ --> $DIR/lint-removed.rs:8:17
+ |
+LL | fn main() { let unused = (); }
+ | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-removed.rs:7:8
+ |
+LL | #[deny(unused_variables)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/tests/ui/lint/lint-renamed-allow.rs b/tests/ui/lint/lint-renamed-allow.rs
new file mode 100644
index 000000000..9cf6f329c
--- /dev/null
+++ b/tests/ui/lint/lint-renamed-allow.rs
@@ -0,0 +1,8 @@
+// No warnings about renamed lint when
+// allow(renamed_and_removed_lints)
+
+#![allow(renamed_and_removed_lints)]
+
+#[deny(single_use_lifetime)]
+#[deny(unused)]
+fn main() { let unused = (); } //~ ERROR unused
diff --git a/tests/ui/lint/lint-renamed-allow.stderr b/tests/ui/lint/lint-renamed-allow.stderr
new file mode 100644
index 000000000..46f6a10de
--- /dev/null
+++ b/tests/ui/lint/lint-renamed-allow.stderr
@@ -0,0 +1,15 @@
+error: unused variable: `unused`
+ --> $DIR/lint-renamed-allow.rs:8:17
+ |
+LL | fn main() { let unused = (); }
+ | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-renamed-allow.rs:7:8
+ |
+LL | #[deny(unused)]
+ | ^^^^^^
+ = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-renamed-cmdline.rs b/tests/ui/lint/lint-renamed-cmdline.rs
new file mode 100644
index 000000000..c873771e3
--- /dev/null
+++ b/tests/ui/lint/lint-renamed-cmdline.rs
@@ -0,0 +1,8 @@
+// compile-flags:-D bare_trait_object
+
+// error-pattern:lint `bare_trait_object` has been renamed to `bare_trait_objects`
+// error-pattern:requested on the command line with `-D bare_trait_object`
+// error-pattern:unused
+
+#[deny(unused)]
+fn main() { let unused = (); }
diff --git a/tests/ui/lint/lint-renamed-cmdline.stderr b/tests/ui/lint/lint-renamed-cmdline.stderr
new file mode 100644
index 000000000..8dfd61ac9
--- /dev/null
+++ b/tests/ui/lint/lint-renamed-cmdline.stderr
@@ -0,0 +1,27 @@
+warning: lint `bare_trait_object` has been renamed to `bare_trait_objects`
+ |
+ = note: requested on the command line with `-D bare_trait_object`
+
+warning: lint `bare_trait_object` has been renamed to `bare_trait_objects`
+ |
+ = note: requested on the command line with `-D bare_trait_object`
+
+warning: lint `bare_trait_object` has been renamed to `bare_trait_objects`
+ |
+ = note: requested on the command line with `-D bare_trait_object`
+
+error: unused variable: `unused`
+ --> $DIR/lint-renamed-cmdline.rs:8:17
+ |
+LL | fn main() { let unused = (); }
+ | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-renamed-cmdline.rs:7:8
+ |
+LL | #[deny(unused)]
+ | ^^^^^^
+ = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
+
+error: aborting due to previous error; 3 warnings emitted
+
diff --git a/tests/ui/lint/lint-renamed.rs b/tests/ui/lint/lint-renamed.rs
new file mode 100644
index 000000000..ca3299430
--- /dev/null
+++ b/tests/ui/lint/lint-renamed.rs
@@ -0,0 +1,4 @@
+#[deny(bare_trait_object)]
+//~^ WARN lint `bare_trait_object` has been renamed to `bare_trait_objects`
+#[deny(unused)]
+fn main() { let unused = (); } //~ ERROR unused
diff --git a/tests/ui/lint/lint-renamed.stderr b/tests/ui/lint/lint-renamed.stderr
new file mode 100644
index 000000000..984254571
--- /dev/null
+++ b/tests/ui/lint/lint-renamed.stderr
@@ -0,0 +1,23 @@
+warning: lint `bare_trait_object` has been renamed to `bare_trait_objects`
+ --> $DIR/lint-renamed.rs:1:8
+ |
+LL | #[deny(bare_trait_object)]
+ | ^^^^^^^^^^^^^^^^^ help: use the new name: `bare_trait_objects`
+ |
+ = note: `#[warn(renamed_and_removed_lints)]` on by default
+
+error: unused variable: `unused`
+ --> $DIR/lint-renamed.rs:4:17
+ |
+LL | fn main() { let unused = (); }
+ | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-renamed.rs:3:8
+ |
+LL | #[deny(unused)]
+ | ^^^^^^
+ = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/tests/ui/lint/lint-shorthand-field.fixed b/tests/ui/lint/lint-shorthand-field.fixed
new file mode 100644
index 000000000..7cd5717bc
--- /dev/null
+++ b/tests/ui/lint/lint-shorthand-field.fixed
@@ -0,0 +1,70 @@
+// run-rustfix
+
+#![allow(nonstandard_style, unused_variables, unused_mut)]
+#![deny(non_shorthand_field_patterns)]
+
+struct Foo {
+ x: isize,
+ y: isize,
+}
+
+fn main() {
+ {
+ let Foo {
+ x, //~ ERROR the `x:` in this pattern is redundant
+ ref y, //~ ERROR the `y:` in this pattern is redundant
+ } = Foo { x: 0, y: 0 };
+
+ let Foo {
+ x,
+ ref y,
+ } = Foo { x: 0, y: 0 };
+ }
+
+ {
+ const x: isize = 1;
+
+ match (Foo { x: 1, y: 1 }) {
+ Foo { x: x, ..} => {},
+ _ => {},
+ }
+ }
+
+ {
+ struct Bar {
+ x: x,
+ }
+
+ struct x;
+
+ match (Bar { x: x }) {
+ Bar { x: x } => {},
+ }
+ }
+
+ {
+ struct Bar {
+ x: Foo,
+ }
+
+ enum Foo { x }
+
+ match (Bar { x: Foo::x }) {
+ Bar { x: Foo::x } => {},
+ }
+ }
+
+ {
+ struct Baz {
+ x: isize,
+ y: isize,
+ z: isize,
+ }
+
+ let Baz {
+ mut x, //~ ERROR the `x:` in this pattern is redundant
+ ref y, //~ ERROR the `y:` in this pattern is redundant
+ ref mut z, //~ ERROR the `z:` in this pattern is redundant
+ } = Baz { x: 0, y: 0, z: 0 };
+ }
+}
diff --git a/tests/ui/lint/lint-shorthand-field.rs b/tests/ui/lint/lint-shorthand-field.rs
new file mode 100644
index 000000000..22de9c325
--- /dev/null
+++ b/tests/ui/lint/lint-shorthand-field.rs
@@ -0,0 +1,70 @@
+// run-rustfix
+
+#![allow(nonstandard_style, unused_variables, unused_mut)]
+#![deny(non_shorthand_field_patterns)]
+
+struct Foo {
+ x: isize,
+ y: isize,
+}
+
+fn main() {
+ {
+ let Foo {
+ x: x, //~ ERROR the `x:` in this pattern is redundant
+ y: ref y, //~ ERROR the `y:` in this pattern is redundant
+ } = Foo { x: 0, y: 0 };
+
+ let Foo {
+ x,
+ ref y,
+ } = Foo { x: 0, y: 0 };
+ }
+
+ {
+ const x: isize = 1;
+
+ match (Foo { x: 1, y: 1 }) {
+ Foo { x: x, ..} => {},
+ _ => {},
+ }
+ }
+
+ {
+ struct Bar {
+ x: x,
+ }
+
+ struct x;
+
+ match (Bar { x: x }) {
+ Bar { x: x } => {},
+ }
+ }
+
+ {
+ struct Bar {
+ x: Foo,
+ }
+
+ enum Foo { x }
+
+ match (Bar { x: Foo::x }) {
+ Bar { x: Foo::x } => {},
+ }
+ }
+
+ {
+ struct Baz {
+ x: isize,
+ y: isize,
+ z: isize,
+ }
+
+ let Baz {
+ x: mut x, //~ ERROR the `x:` in this pattern is redundant
+ y: ref y, //~ ERROR the `y:` in this pattern is redundant
+ z: ref mut z, //~ ERROR the `z:` in this pattern is redundant
+ } = Baz { x: 0, y: 0, z: 0 };
+ }
+}
diff --git a/tests/ui/lint/lint-shorthand-field.stderr b/tests/ui/lint/lint-shorthand-field.stderr
new file mode 100644
index 000000000..2d1ca30f9
--- /dev/null
+++ b/tests/ui/lint/lint-shorthand-field.stderr
@@ -0,0 +1,38 @@
+error: the `x:` in this pattern is redundant
+ --> $DIR/lint-shorthand-field.rs:14:13
+ |
+LL | x: x,
+ | ^^^^ help: use shorthand field pattern: `x`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-shorthand-field.rs:4:9
+ |
+LL | #![deny(non_shorthand_field_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the `y:` in this pattern is redundant
+ --> $DIR/lint-shorthand-field.rs:15:13
+ |
+LL | y: ref y,
+ | ^^^^^^^^ help: use shorthand field pattern: `ref y`
+
+error: the `x:` in this pattern is redundant
+ --> $DIR/lint-shorthand-field.rs:65:13
+ |
+LL | x: mut x,
+ | ^^^^^^^^ help: use shorthand field pattern: `mut x`
+
+error: the `y:` in this pattern is redundant
+ --> $DIR/lint-shorthand-field.rs:66:13
+ |
+LL | y: ref y,
+ | ^^^^^^^^ help: use shorthand field pattern: `ref y`
+
+error: the `z:` in this pattern is redundant
+ --> $DIR/lint-shorthand-field.rs:67:13
+ |
+LL | z: ref mut z,
+ | ^^^^^^^^^^^^ help: use shorthand field pattern: `ref mut z`
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/lint/lint-stability-2.rs b/tests/ui/lint/lint-stability-2.rs
new file mode 100644
index 000000000..94a8d08c8
--- /dev/null
+++ b/tests/ui/lint/lint-stability-2.rs
@@ -0,0 +1,413 @@
+// aux-build:lint_stability.rs
+// aux-build:stability_cfg1.rs
+
+#![allow(deprecated)]
+#![allow(dead_code)]
+#![feature(staged_api)]
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+#[macro_use]
+extern crate lint_stability;
+
+mod cross_crate {
+ extern crate stability_cfg1;
+
+ use lint_stability::*;
+
+ fn test() {
+ type Foo = MethodTester;
+ let foo = MethodTester;
+
+ deprecated();
+ foo.method_deprecated();
+ Foo::method_deprecated(&foo);
+ <Foo>::method_deprecated(&foo);
+ foo.trait_deprecated();
+ Trait::trait_deprecated(&foo);
+ <Foo>::trait_deprecated(&foo);
+ <Foo as Trait>::trait_deprecated(&foo);
+
+ deprecated_text();
+ foo.method_deprecated_text();
+ Foo::method_deprecated_text(&foo);
+ <Foo>::method_deprecated_text(&foo);
+ foo.trait_deprecated_text();
+ Trait::trait_deprecated_text(&foo);
+ <Foo>::trait_deprecated_text(&foo);
+ <Foo as Trait>::trait_deprecated_text(&foo);
+
+ foo.method_deprecated_unstable();
+ //~^ ERROR use of unstable library feature
+ Foo::method_deprecated_unstable(&foo);
+ //~^ ERROR use of unstable library feature
+ <Foo>::method_deprecated_unstable(&foo);
+ //~^ ERROR use of unstable library feature
+ foo.trait_deprecated_unstable();
+ //~^ ERROR use of unstable library feature
+ <Foo>::trait_deprecated_unstable(&foo);
+ //~^ ERROR use of unstable library feature
+
+ foo.method_deprecated_unstable_text();
+ //~^ ERROR use of unstable library feature
+ Foo::method_deprecated_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature
+ <Foo>::method_deprecated_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature
+ foo.trait_deprecated_unstable_text();
+ //~^ ERROR use of unstable library feature
+ <Foo>::trait_deprecated_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature
+
+ foo.method_unstable(); //~ ERROR use of unstable library feature
+ Foo::method_unstable(&foo); //~ ERROR use of unstable library feature
+ <Foo>::method_unstable(&foo); //~ ERROR use of unstable library feature
+ foo.trait_unstable(); //~ ERROR use of unstable library feature
+ <Foo>::trait_unstable(&foo); //~ ERROR use of unstable library feature
+
+ foo.method_unstable_text();
+ //~^ ERROR use of unstable library feature 'unstable_test_feature': text
+ Foo::method_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature 'unstable_test_feature': text
+ <Foo>::method_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature 'unstable_test_feature': text
+ foo.trait_unstable_text();
+ //~^ ERROR use of unstable library feature 'unstable_test_feature': text
+ <Foo>::trait_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature 'unstable_test_feature': text
+
+ stable();
+ foo.method_stable();
+ Foo::method_stable(&foo);
+ <Foo>::method_stable(&foo);
+ foo.trait_stable();
+ Trait::trait_stable(&foo);
+ <Foo>::trait_stable(&foo);
+ <Foo as Trait>::trait_stable(&foo);
+
+ stable_text();
+ foo.method_stable_text();
+ Foo::method_stable_text(&foo);
+ <Foo>::method_stable_text(&foo);
+ foo.trait_stable_text();
+ Trait::trait_stable_text(&foo);
+ <Foo>::trait_stable_text(&foo);
+ <Foo as Trait>::trait_stable_text(&foo);
+
+ struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated);
+
+ let _ = DeprecatedStruct {
+ i: 0
+ };
+ let _ = StableStruct { i: 0 };
+
+ let _ = DeprecatedUnitStruct;
+ let _ = StableUnitStruct;
+
+ let _ = Enum::DeprecatedVariant;
+ let _ = Enum::StableVariant;
+
+ let _ = DeprecatedTupleStruct (1);
+ let _ = StableTupleStruct (1);
+
+ // At the moment, the lint checker only checks stability in
+ // in the arguments of macros.
+ // Eventually, we will want to lint the contents of the
+ // macro in the module *defining* it. Also, stability levels
+ // on macros themselves are not yet linted.
+ macro_test_arg!(deprecated_text());
+ macro_test_arg!(macro_test_arg!(deprecated_text()));
+ }
+
+ fn test_method_param<Foo: Trait>(foo: Foo) {
+ foo.trait_deprecated();
+ Trait::trait_deprecated(&foo);
+ <Foo>::trait_deprecated(&foo);
+ <Foo as Trait>::trait_deprecated(&foo);
+ foo.trait_deprecated_text();
+ Trait::trait_deprecated_text(&foo);
+ <Foo>::trait_deprecated_text(&foo);
+ <Foo as Trait>::trait_deprecated_text(&foo);
+ foo.trait_deprecated_unstable();
+ //~^ ERROR use of unstable library feature
+ <Foo>::trait_deprecated_unstable(&foo);
+ //~^ ERROR use of unstable library feature
+ foo.trait_deprecated_unstable_text();
+ //~^ ERROR use of unstable library feature
+ <Foo>::trait_deprecated_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature
+ foo.trait_unstable(); //~ ERROR use of unstable library feature
+ <Foo>::trait_unstable(&foo); //~ ERROR use of unstable library feature
+ foo.trait_unstable_text();
+ //~^ ERROR use of unstable library feature 'unstable_test_feature': text
+ <Foo>::trait_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature 'unstable_test_feature': text
+ foo.trait_stable();
+ Trait::trait_stable(&foo);
+ <Foo>::trait_stable(&foo);
+ <Foo as Trait>::trait_stable(&foo);
+ }
+
+ fn test_method_object(foo: &dyn Trait) {
+ foo.trait_deprecated();
+ foo.trait_deprecated_text();
+ foo.trait_deprecated_unstable();
+ //~^ ERROR use of unstable library feature
+ foo.trait_deprecated_unstable_text();
+ //~^ ERROR use of unstable library feature
+ foo.trait_unstable(); //~ ERROR use of unstable library feature
+ foo.trait_unstable_text();
+ //~^ ERROR use of unstable library feature 'unstable_test_feature': text
+ foo.trait_stable();
+ }
+
+ struct S;
+
+ impl DeprecatedTrait for S {}
+ trait LocalTrait2 : DeprecatedTrait { }
+}
+
+mod this_crate {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn deprecated() {}
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn deprecated_text() {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub fn unstable() {}
+ #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")]
+ pub fn unstable_text() {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn stable() {}
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn stable_text() {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct MethodTester;
+
+ impl MethodTester {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn method_deprecated(&self) {}
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn method_deprecated_text(&self) {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub fn method_unstable(&self) {}
+ #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")]
+ pub fn method_unstable_text(&self) {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn method_stable(&self) {}
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn method_stable_text(&self) {}
+ }
+
+ pub trait Trait {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn trait_deprecated(&self) {}
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn trait_deprecated_text(&self) {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ fn trait_unstable(&self) {}
+ #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")]
+ fn trait_unstable_text(&self) {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn trait_stable(&self) {}
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn trait_stable_text(&self) {}
+ }
+
+ impl Trait for MethodTester {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub struct DeprecatedStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize
+ }
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub struct UnstableStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize
+ }
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct StableStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub struct DeprecatedUnitStruct;
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub struct UnstableUnitStruct;
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct StableUnitStruct;
+
+ pub enum Enum {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ DeprecatedVariant,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ UnstableVariant,
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ StableVariant,
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub struct DeprecatedTupleStruct(isize);
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub struct UnstableTupleStruct(isize);
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct StableTupleStruct(isize);
+
+ fn test() {
+ // Only the deprecated cases of the following should generate
+ // errors, because other stability attributes now have meaning
+ // only *across* crates, not within a single crate.
+
+ type Foo = MethodTester;
+ let foo = MethodTester;
+
+ deprecated();
+ foo.method_deprecated();
+ Foo::method_deprecated(&foo);
+ <Foo>::method_deprecated(&foo);
+ foo.trait_deprecated();
+ Trait::trait_deprecated(&foo);
+ <Foo>::trait_deprecated(&foo);
+ <Foo as Trait>::trait_deprecated(&foo);
+
+ deprecated_text();
+ foo.method_deprecated_text();
+ Foo::method_deprecated_text(&foo);
+ <Foo>::method_deprecated_text(&foo);
+ foo.trait_deprecated_text();
+ Trait::trait_deprecated_text(&foo);
+ <Foo>::trait_deprecated_text(&foo);
+ <Foo as Trait>::trait_deprecated_text(&foo);
+
+ unstable();
+ foo.method_unstable();
+ Foo::method_unstable(&foo);
+ <Foo>::method_unstable(&foo);
+ foo.trait_unstable();
+ Trait::trait_unstable(&foo);
+ <Foo>::trait_unstable(&foo);
+ <Foo as Trait>::trait_unstable(&foo);
+
+ unstable_text();
+ foo.method_unstable_text();
+ Foo::method_unstable_text(&foo);
+ <Foo>::method_unstable_text(&foo);
+ foo.trait_unstable_text();
+ Trait::trait_unstable_text(&foo);
+ <Foo>::trait_unstable_text(&foo);
+ <Foo as Trait>::trait_unstable_text(&foo);
+
+ stable();
+ foo.method_stable();
+ Foo::method_stable(&foo);
+ <Foo>::method_stable(&foo);
+ foo.trait_stable();
+ Trait::trait_stable(&foo);
+ <Foo>::trait_stable(&foo);
+ <Foo as Trait>::trait_stable(&foo);
+
+ stable_text();
+ foo.method_stable_text();
+ Foo::method_stable_text(&foo);
+ <Foo>::method_stable_text(&foo);
+ foo.trait_stable_text();
+ Trait::trait_stable_text(&foo);
+ <Foo>::trait_stable_text(&foo);
+ <Foo as Trait>::trait_stable_text(&foo);
+
+ let _ = DeprecatedStruct {
+ i: 0
+ };
+ let _ = UnstableStruct { i: 0 };
+ let _ = StableStruct { i: 0 };
+
+ let _ = DeprecatedUnitStruct;
+ let _ = UnstableUnitStruct;
+ let _ = StableUnitStruct;
+
+ let _ = Enum::DeprecatedVariant;
+ let _ = Enum::UnstableVariant;
+ let _ = Enum::StableVariant;
+
+ let _ = DeprecatedTupleStruct (1);
+ let _ = UnstableTupleStruct (1);
+ let _ = StableTupleStruct (1);
+ }
+
+ fn test_method_param<Foo: Trait>(foo: Foo) {
+ foo.trait_deprecated();
+ Trait::trait_deprecated(&foo);
+ <Foo>::trait_deprecated(&foo);
+ <Foo as Trait>::trait_deprecated(&foo);
+ foo.trait_deprecated_text();
+ Trait::trait_deprecated_text(&foo);
+ <Foo>::trait_deprecated_text(&foo);
+ <Foo as Trait>::trait_deprecated_text(&foo);
+ foo.trait_unstable();
+ Trait::trait_unstable(&foo);
+ <Foo>::trait_unstable(&foo);
+ <Foo as Trait>::trait_unstable(&foo);
+ foo.trait_unstable_text();
+ Trait::trait_unstable_text(&foo);
+ <Foo>::trait_unstable_text(&foo);
+ <Foo as Trait>::trait_unstable_text(&foo);
+ foo.trait_stable();
+ Trait::trait_stable(&foo);
+ <Foo>::trait_stable(&foo);
+ <Foo as Trait>::trait_stable(&foo);
+ }
+
+ fn test_method_object(foo: &dyn Trait) {
+ foo.trait_deprecated();
+ foo.trait_deprecated_text();
+ foo.trait_unstable();
+ foo.trait_unstable_text();
+ foo.trait_stable();
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn test_fn_body() {
+ fn fn_in_body() {}
+ fn_in_body();
+ }
+
+ impl MethodTester {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn test_method_body(&self) {
+ fn fn_in_body() {}
+ fn_in_body();
+ }
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub trait DeprecatedTrait {
+ fn dummy(&self) { }
+ }
+
+ struct S;
+
+ impl DeprecatedTrait for S { }
+
+ trait LocalTrait : DeprecatedTrait { }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-stability-2.stderr b/tests/ui/lint/lint-stability-2.stderr
new file mode 100644
index 000000000..5b7537fa2
--- /dev/null
+++ b/tests/ui/lint/lint-stability-2.stderr
@@ -0,0 +1,259 @@
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:40:13
+ |
+LL | foo.method_deprecated_unstable();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:42:9
+ |
+LL | Foo::method_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:44:9
+ |
+LL | <Foo>::method_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:46:13
+ |
+LL | foo.trait_deprecated_unstable();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:48:9
+ |
+LL | <Foo>::trait_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:51:13
+ |
+LL | foo.method_deprecated_unstable_text();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:53:9
+ |
+LL | Foo::method_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:55:9
+ |
+LL | <Foo>::method_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:57:13
+ |
+LL | foo.trait_deprecated_unstable_text();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:59:9
+ |
+LL | <Foo>::trait_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:62:13
+ |
+LL | foo.method_unstable();
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:63:9
+ |
+LL | Foo::method_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:64:9
+ |
+LL | <Foo>::method_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:65:13
+ |
+LL | foo.trait_unstable();
+ | ^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:66:9
+ |
+LL | <Foo>::trait_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature': text
+ --> $DIR/lint-stability-2.rs:68:13
+ |
+LL | foo.method_unstable_text();
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature': text
+ --> $DIR/lint-stability-2.rs:70:9
+ |
+LL | Foo::method_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature': text
+ --> $DIR/lint-stability-2.rs:72:9
+ |
+LL | <Foo>::method_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature': text
+ --> $DIR/lint-stability-2.rs:74:13
+ |
+LL | foo.trait_unstable_text();
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature': text
+ --> $DIR/lint-stability-2.rs:76:9
+ |
+LL | <Foo>::trait_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:131:13
+ |
+LL | foo.trait_deprecated_unstable();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:133:9
+ |
+LL | <Foo>::trait_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:135:13
+ |
+LL | foo.trait_deprecated_unstable_text();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:137:9
+ |
+LL | <Foo>::trait_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:139:13
+ |
+LL | foo.trait_unstable();
+ | ^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:140:9
+ |
+LL | <Foo>::trait_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature': text
+ --> $DIR/lint-stability-2.rs:141:13
+ |
+LL | foo.trait_unstable_text();
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature': text
+ --> $DIR/lint-stability-2.rs:143:9
+ |
+LL | <Foo>::trait_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:154:13
+ |
+LL | foo.trait_deprecated_unstable();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:156:13
+ |
+LL | foo.trait_deprecated_unstable_text();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-2.rs:158:13
+ |
+LL | foo.trait_unstable();
+ | ^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature': text
+ --> $DIR/lint-stability-2.rs:159:13
+ |
+LL | foo.trait_unstable_text();
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error: aborting due to 32 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/lint/lint-stability-deprecated.rs b/tests/ui/lint/lint-stability-deprecated.rs
new file mode 100644
index 000000000..74c35083e
--- /dev/null
+++ b/tests/ui/lint/lint-stability-deprecated.rs
@@ -0,0 +1,464 @@
+// check-pass
+// aux-build:lint_stability.rs
+// aux-build:inherited_stability.rs
+// aux-build:stability_cfg1.rs
+// aux-build:stability-cfg2.rs
+#![warn(deprecated)]
+#![feature(staged_api, unstable_test_feature)]
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+#[macro_use]
+extern crate lint_stability;
+
+mod cross_crate {
+ extern crate stability_cfg1;
+ extern crate stability_cfg2;
+
+ use lint_stability::*;
+
+ fn test() {
+ type Foo = MethodTester;
+ let foo = MethodTester;
+
+ deprecated(); //~ WARN use of deprecated function `lint_stability::deprecated`
+ foo.method_deprecated(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated`
+ Foo::method_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated`
+ <Foo>::method_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated`
+ foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+ Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+ <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+ <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+
+ deprecated_text(); //~ WARN use of deprecated function `lint_stability::deprecated_text`: text
+ foo.method_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
+ Foo::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
+ <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
+ foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+
+ deprecated_unstable(); //~ WARN use of deprecated function `lint_stability::deprecated_unstable`
+ foo.method_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`
+ Foo::method_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`
+ <Foo>::method_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`
+ foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+ Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+ <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+ <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+
+ deprecated_unstable_text(); //~ WARN use of deprecated function `lint_stability::deprecated_unstable_text`: text
+ foo.method_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
+ Foo::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
+ <Foo>::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
+ foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+
+ unstable();
+ foo.method_unstable();
+ Foo::method_unstable(&foo);
+ <Foo>::method_unstable(&foo);
+ foo.trait_unstable();
+ Trait::trait_unstable(&foo);
+ <Foo>::trait_unstable(&foo);
+ <Foo as Trait>::trait_unstable(&foo);
+
+ unstable_text();
+ foo.method_unstable_text();
+ Foo::method_unstable_text(&foo);
+ <Foo>::method_unstable_text(&foo);
+ foo.trait_unstable_text();
+ Trait::trait_unstable_text(&foo);
+ <Foo>::trait_unstable_text(&foo);
+ <Foo as Trait>::trait_unstable_text(&foo);
+
+ stable();
+ foo.method_stable();
+ Foo::method_stable(&foo);
+ <Foo>::method_stable(&foo);
+ foo.trait_stable();
+ Trait::trait_stable(&foo);
+ <Foo>::trait_stable(&foo);
+ <Foo as Trait>::trait_stable(&foo);
+
+ stable_text();
+ foo.method_stable_text();
+ Foo::method_stable_text(&foo);
+ <Foo>::method_stable_text(&foo);
+ foo.trait_stable_text();
+ Trait::trait_stable_text(&foo);
+ <Foo>::trait_stable_text(&foo);
+ <Foo as Trait>::trait_stable_text(&foo);
+
+ struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable);
+ struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated);
+ //~^ WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
+ //~| WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
+ type A = dyn TraitWithAssociatedTypes<
+ TypeUnstable = u8,
+ TypeDeprecated = u16,
+ //~^ WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`
+ //~| WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`
+ //~| WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`
+ >;
+
+ let _ = DeprecatedStruct { //~ WARN use of deprecated struct `lint_stability::DeprecatedStruct`
+ i: 0 //~ WARN use of deprecated field `lint_stability::DeprecatedStruct::i`
+ };
+ let _ = DeprecatedUnstableStruct {
+ //~^ WARN use of deprecated struct `lint_stability::DeprecatedUnstableStruct`
+ i: 0 //~ WARN use of deprecated field `lint_stability::DeprecatedUnstableStruct::i`
+ };
+ let _ = UnstableStruct { i: 0 };
+ let _ = StableStruct { i: 0 };
+
+ let _ = DeprecatedUnitStruct; //~ WARN use of deprecated unit struct `lint_stability::DeprecatedUnitStruct`
+ let _ = DeprecatedUnstableUnitStruct; //~ WARN use of deprecated unit struct `lint_stability::DeprecatedUnstableUnitStruct`
+ let _ = UnstableUnitStruct;
+ let _ = StableUnitStruct;
+
+ let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated unit variant `lint_stability::Enum::DeprecatedVariant`
+ let _ = Enum::DeprecatedUnstableVariant; //~ WARN use of deprecated unit variant `lint_stability::Enum::DeprecatedUnstableVariant`
+ let _ = Enum::UnstableVariant;
+ let _ = Enum::StableVariant;
+
+ let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated tuple struct `lint_stability::DeprecatedTupleStruct`
+ let _ = DeprecatedUnstableTupleStruct (1); //~ WARN use of deprecated tuple struct `lint_stability::DeprecatedUnstableTupleStruct`
+ let _ = UnstableTupleStruct (1);
+ let _ = StableTupleStruct (1);
+
+ // At the moment, the lint checker only checks stability
+ // in the arguments of macros.
+ // Eventually, we will want to lint the contents of the
+ // macro in the module *defining* it. Also, stability levels
+ // on macros themselves are not yet linted.
+ macro_test_arg!(deprecated_text()); //~ WARN use of deprecated function `lint_stability::deprecated_text`: text
+ macro_test_arg!(deprecated_unstable_text()); //~ WARN use of deprecated function `lint_stability::deprecated_unstable_text`: text
+ macro_test_arg!(macro_test_arg!(deprecated_text())); //~ WARN use of deprecated function `lint_stability::deprecated_text`: text
+ }
+
+ fn test_method_param<Foo: Trait>(foo: Foo) {
+ foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+ Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+ <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+ <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+ foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+ Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+ <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+ <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+ foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ foo.trait_unstable();
+ Trait::trait_unstable(&foo);
+ <Foo>::trait_unstable(&foo);
+ <Foo as Trait>::trait_unstable(&foo);
+ foo.trait_unstable_text();
+ Trait::trait_unstable_text(&foo);
+ <Foo>::trait_unstable_text(&foo);
+ <Foo as Trait>::trait_unstable_text(&foo);
+ foo.trait_stable();
+ Trait::trait_stable(&foo);
+ <Foo>::trait_stable(&foo);
+ <Foo as Trait>::trait_stable(&foo);
+ }
+
+ fn test_method_object(foo: &dyn Trait) {
+ foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+ foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+ foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ foo.trait_unstable();
+ foo.trait_unstable_text();
+ foo.trait_stable();
+ }
+
+ struct S;
+
+ impl UnstableTrait for S { }
+ impl DeprecatedTrait for S {} //~ WARN use of deprecated trait `lint_stability::DeprecatedTrait`: text
+ trait LocalTrait : UnstableTrait { }
+ trait LocalTrait2 : DeprecatedTrait { } //~ WARN use of deprecated trait `lint_stability::DeprecatedTrait`: text
+
+ impl Trait for S {
+ fn trait_stable(&self) {}
+ fn trait_unstable(&self) {}
+ }
+}
+
+mod inheritance {
+ extern crate inherited_stability;
+ use self::inherited_stability::*;
+
+ fn test_inheritance() {
+ unstable();
+ stable();
+
+ stable_mod::unstable();
+ stable_mod::stable();
+
+ unstable_mod::deprecated(); //~ WARN use of deprecated function `inheritance::inherited_stability::unstable_mod::deprecated`: text
+ unstable_mod::unstable();
+
+ let _ = Unstable::UnstableVariant;
+ let _ = Unstable::StableVariant;
+
+ let x: usize = 0;
+ x.unstable();
+ x.stable();
+ }
+}
+
+mod this_crate {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn deprecated() {}
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn deprecated_text() {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub fn unstable() {}
+ #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")]
+ pub fn unstable_text() {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn stable() {}
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn stable_text() {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct MethodTester;
+
+ impl MethodTester {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn method_deprecated(&self) {}
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn method_deprecated_text(&self) {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub fn method_unstable(&self) {}
+ #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")]
+ pub fn method_unstable_text(&self) {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn method_stable(&self) {}
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn method_stable_text(&self) {}
+ }
+
+ pub trait Trait {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn trait_deprecated(&self) {}
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn trait_deprecated_text(&self) {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ fn trait_unstable(&self) {}
+ #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")]
+ fn trait_unstable_text(&self) {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn trait_stable(&self) {}
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn trait_stable_text(&self) {}
+ }
+
+ impl Trait for MethodTester {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub struct DeprecatedStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize
+ }
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub struct UnstableStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize
+ }
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct StableStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub struct DeprecatedUnitStruct;
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub struct UnstableUnitStruct;
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct StableUnitStruct;
+
+ pub enum Enum {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ DeprecatedVariant,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ UnstableVariant,
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ StableVariant,
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub struct DeprecatedTupleStruct(isize);
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub struct UnstableTupleStruct(isize);
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct StableTupleStruct(isize);
+
+ fn test() {
+ // Only the deprecated cases of the following should generate
+ // errors, because other stability attributes now have meaning
+ // only *across* crates, not within a single crate.
+
+ type Foo = MethodTester;
+ let foo = MethodTester;
+
+ deprecated(); //~ WARN use of deprecated function `this_crate::deprecated`
+ foo.method_deprecated(); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated`
+ Foo::method_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated`
+ <Foo>::method_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated`
+ foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+ Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+ <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+ <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+
+ deprecated_text(); //~ WARN use of deprecated function `this_crate::deprecated_text`: text
+ foo.method_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+ Foo::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+ <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+ foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+
+ unstable();
+ foo.method_unstable();
+ Foo::method_unstable(&foo);
+ <Foo>::method_unstable(&foo);
+ foo.trait_unstable();
+ Trait::trait_unstable(&foo);
+ <Foo>::trait_unstable(&foo);
+ <Foo as Trait>::trait_unstable(&foo);
+
+ unstable_text();
+ foo.method_unstable_text();
+ Foo::method_unstable_text(&foo);
+ <Foo>::method_unstable_text(&foo);
+ foo.trait_unstable_text();
+ Trait::trait_unstable_text(&foo);
+ <Foo>::trait_unstable_text(&foo);
+ <Foo as Trait>::trait_unstable_text(&foo);
+
+ stable();
+ foo.method_stable();
+ Foo::method_stable(&foo);
+ <Foo>::method_stable(&foo);
+ foo.trait_stable();
+ Trait::trait_stable(&foo);
+ <Foo>::trait_stable(&foo);
+ <Foo as Trait>::trait_stable(&foo);
+
+ stable_text();
+ foo.method_stable_text();
+ Foo::method_stable_text(&foo);
+ <Foo>::method_stable_text(&foo);
+ foo.trait_stable_text();
+ Trait::trait_stable_text(&foo);
+ <Foo>::trait_stable_text(&foo);
+ <Foo as Trait>::trait_stable_text(&foo);
+
+ let _ = DeprecatedStruct {
+ //~^ WARN use of deprecated struct `this_crate::DeprecatedStruct`
+ i: 0 //~ WARN use of deprecated field `this_crate::DeprecatedStruct::i`
+ };
+ let _ = UnstableStruct { i: 0 };
+ let _ = StableStruct { i: 0 };
+
+ let _ = DeprecatedUnitStruct; //~ WARN use of deprecated unit struct `this_crate::DeprecatedUnitStruct`
+ let _ = UnstableUnitStruct;
+ let _ = StableUnitStruct;
+
+ let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`
+ let _ = Enum::UnstableVariant;
+ let _ = Enum::StableVariant;
+
+ let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`
+ let _ = UnstableTupleStruct (1);
+ let _ = StableTupleStruct (1);
+ }
+
+ fn test_method_param<Foo: Trait>(foo: Foo) {
+ foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+ Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+ <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+ <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+ foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ foo.trait_unstable();
+ Trait::trait_unstable(&foo);
+ <Foo>::trait_unstable(&foo);
+ <Foo as Trait>::trait_unstable(&foo);
+ foo.trait_unstable_text();
+ Trait::trait_unstable_text(&foo);
+ <Foo>::trait_unstable_text(&foo);
+ <Foo as Trait>::trait_unstable_text(&foo);
+ foo.trait_stable();
+ Trait::trait_stable(&foo);
+ <Foo>::trait_stable(&foo);
+ <Foo as Trait>::trait_stable(&foo);
+ }
+
+ fn test_method_object(foo: &dyn Trait) {
+ foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+ foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ foo.trait_unstable();
+ foo.trait_unstable_text();
+ foo.trait_stable();
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn test_fn_body() {
+ fn fn_in_body() {}
+ fn_in_body(); //~ WARN use of deprecated function `this_crate::test_fn_body::fn_in_body`: text
+ }
+
+ impl MethodTester {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn test_method_body(&self) {
+ fn fn_in_body() {}
+ fn_in_body(); //~ WARN use of deprecated function `this_crate::MethodTester::test_method_body::fn_in_body`: text
+ }
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub trait DeprecatedTrait {
+ fn dummy(&self) { }
+ }
+
+ struct S;
+
+ impl DeprecatedTrait for S { } //~ WARN use of deprecated trait `this_crate::DeprecatedTrait`
+
+ trait LocalTrait : DeprecatedTrait { } //~ WARN use of deprecated trait `this_crate::DeprecatedTrait`
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-stability-deprecated.stderr b/tests/ui/lint/lint-stability-deprecated.stderr
new file mode 100644
index 000000000..9f1e7b281
--- /dev/null
+++ b/tests/ui/lint/lint-stability-deprecated.stderr
@@ -0,0 +1,656 @@
+warning: use of deprecated function `lint_stability::deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:24:9
+ |
+LL | deprecated();
+ | ^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-stability-deprecated.rs:6:9
+ |
+LL | #![warn(deprecated)]
+ | ^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:29:16
+ |
+LL | Trait::trait_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:31:25
+ |
+LL | <Foo as Trait>::trait_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated function `lint_stability::deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:33:9
+ |
+LL | deprecated_text();
+ | ^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:38:16
+ |
+LL | ... Trait::trait_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:40:25
+ |
+LL | ... <Foo as Trait>::trait_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated function `lint_stability::deprecated_unstable`: text
+ --> $DIR/lint-stability-deprecated.rs:42:9
+ |
+LL | deprecated_unstable();
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+ --> $DIR/lint-stability-deprecated.rs:47:16
+ |
+LL | ... Trait::trait_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+ --> $DIR/lint-stability-deprecated.rs:49:25
+ |
+LL | ... <Foo as Trait>::trait_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated function `lint_stability::deprecated_unstable_text`: text
+ --> $DIR/lint-stability-deprecated.rs:51:9
+ |
+LL | deprecated_unstable_text();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ --> $DIR/lint-stability-deprecated.rs:56:16
+ |
+LL | ... Trait::trait_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ --> $DIR/lint-stability-deprecated.rs:58:25
+ |
+LL | ... <Foo as Trait>::trait_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated struct `lint_stability::DeprecatedStruct`: text
+ --> $DIR/lint-stability-deprecated.rs:108:17
+ |
+LL | let _ = DeprecatedStruct {
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated struct `lint_stability::DeprecatedUnstableStruct`: text
+ --> $DIR/lint-stability-deprecated.rs:111:17
+ |
+LL | let _ = DeprecatedUnstableStruct {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated unit struct `lint_stability::DeprecatedUnitStruct`: text
+ --> $DIR/lint-stability-deprecated.rs:118:17
+ |
+LL | let _ = DeprecatedUnitStruct;
+ | ^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated unit struct `lint_stability::DeprecatedUnstableUnitStruct`: text
+ --> $DIR/lint-stability-deprecated.rs:119:17
+ |
+LL | let _ = DeprecatedUnstableUnitStruct;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated unit variant `lint_stability::Enum::DeprecatedVariant`: text
+ --> $DIR/lint-stability-deprecated.rs:123:23
+ |
+LL | let _ = Enum::DeprecatedVariant;
+ | ^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated unit variant `lint_stability::Enum::DeprecatedUnstableVariant`: text
+ --> $DIR/lint-stability-deprecated.rs:124:23
+ |
+LL | let _ = Enum::DeprecatedUnstableVariant;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated tuple struct `lint_stability::DeprecatedTupleStruct`: text
+ --> $DIR/lint-stability-deprecated.rs:128:17
+ |
+LL | let _ = DeprecatedTupleStruct (1);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated tuple struct `lint_stability::DeprecatedUnstableTupleStruct`: text
+ --> $DIR/lint-stability-deprecated.rs:129:17
+ |
+LL | let _ = DeprecatedUnstableTupleStruct (1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated function `lint_stability::deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:138:25
+ |
+LL | macro_test_arg!(deprecated_text());
+ | ^^^^^^^^^^^^^^^
+
+warning: use of deprecated function `lint_stability::deprecated_unstable_text`: text
+ --> $DIR/lint-stability-deprecated.rs:139:25
+ |
+LL | macro_test_arg!(deprecated_unstable_text());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated function `lint_stability::deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:140:41
+ |
+LL | macro_test_arg!(macro_test_arg!(deprecated_text()));
+ | ^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:145:16
+ |
+LL | Trait::trait_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:147:25
+ |
+LL | <Foo as Trait>::trait_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:149:16
+ |
+LL | ... Trait::trait_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:151:25
+ |
+LL | ... <Foo as Trait>::trait_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+ --> $DIR/lint-stability-deprecated.rs:153:16
+ |
+LL | ... Trait::trait_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+ --> $DIR/lint-stability-deprecated.rs:155:25
+ |
+LL | ... <Foo as Trait>::trait_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ --> $DIR/lint-stability-deprecated.rs:157:16
+ |
+LL | ... Trait::trait_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ --> $DIR/lint-stability-deprecated.rs:159:25
+ |
+LL | ... <Foo as Trait>::trait_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated trait `lint_stability::DeprecatedTrait`: text
+ --> $DIR/lint-stability-deprecated.rs:187:10
+ |
+LL | impl DeprecatedTrait for S {}
+ | ^^^^^^^^^^^^^^^
+
+warning: use of deprecated trait `lint_stability::DeprecatedTrait`: text
+ --> $DIR/lint-stability-deprecated.rs:189:25
+ |
+LL | trait LocalTrait2 : DeprecatedTrait { }
+ | ^^^^^^^^^^^^^^^
+
+warning: use of deprecated function `inheritance::inherited_stability::unstable_mod::deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:208:23
+ |
+LL | unstable_mod::deprecated();
+ | ^^^^^^^^^^
+
+warning: use of deprecated function `this_crate::deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:330:9
+ |
+LL | deprecated();
+ | ^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:335:16
+ |
+LL | Trait::trait_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:337:25
+ |
+LL | <Foo as Trait>::trait_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated function `this_crate::deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:339:9
+ |
+LL | deprecated_text();
+ | ^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:344:16
+ |
+LL | Trait::trait_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:346:25
+ |
+LL | ... <Foo as Trait>::trait_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated struct `this_crate::DeprecatedStruct`: text
+ --> $DIR/lint-stability-deprecated.rs:384:17
+ |
+LL | let _ = DeprecatedStruct {
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated unit struct `this_crate::DeprecatedUnitStruct`: text
+ --> $DIR/lint-stability-deprecated.rs:391:17
+ |
+LL | let _ = DeprecatedUnitStruct;
+ | ^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text
+ --> $DIR/lint-stability-deprecated.rs:395:23
+ |
+LL | let _ = Enum::DeprecatedVariant;
+ | ^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text
+ --> $DIR/lint-stability-deprecated.rs:399:17
+ |
+LL | let _ = DeprecatedTupleStruct (1);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:406:16
+ |
+LL | Trait::trait_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:408:25
+ |
+LL | <Foo as Trait>::trait_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:410:16
+ |
+LL | Trait::trait_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:412:25
+ |
+LL | ... <Foo as Trait>::trait_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated function `this_crate::test_fn_body::fn_in_body`: text
+ --> $DIR/lint-stability-deprecated.rs:439:9
+ |
+LL | fn_in_body();
+ | ^^^^^^^^^^
+
+warning: use of deprecated trait `this_crate::DeprecatedTrait`: text
+ --> $DIR/lint-stability-deprecated.rs:459:10
+ |
+LL | impl DeprecatedTrait for S { }
+ | ^^^^^^^^^^^^^^^
+
+warning: use of deprecated trait `this_crate::DeprecatedTrait`: text
+ --> $DIR/lint-stability-deprecated.rs:461:24
+ |
+LL | trait LocalTrait : DeprecatedTrait { }
+ | ^^^^^^^^^^^^^^^
+
+warning: use of deprecated function `this_crate::MethodTester::test_method_body::fn_in_body`: text
+ --> $DIR/lint-stability-deprecated.rs:447:13
+ |
+LL | fn_in_body();
+ | ^^^^^^^^^^
+
+warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:97:48
+ |
+LL | struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated);
+ | ^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:102:13
+ |
+LL | TypeDeprecated = u16,
+ | ^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:25:13
+ |
+LL | foo.method_deprecated();
+ | ^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:26:14
+ |
+LL | Foo::method_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:27:16
+ |
+LL | <Foo>::method_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:28:13
+ |
+LL | foo.trait_deprecated();
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:30:16
+ |
+LL | <Foo>::trait_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:34:13
+ |
+LL | ... foo.method_deprecated_text();
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:35:14
+ |
+LL | ... Foo::method_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:36:16
+ |
+LL | ... <Foo>::method_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:37:13
+ |
+LL | foo.trait_deprecated_text();
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:39:16
+ |
+LL | ... <Foo>::trait_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text
+ --> $DIR/lint-stability-deprecated.rs:43:13
+ |
+LL | ... foo.method_deprecated_unstable();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text
+ --> $DIR/lint-stability-deprecated.rs:44:14
+ |
+LL | ... Foo::method_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text
+ --> $DIR/lint-stability-deprecated.rs:45:16
+ |
+LL | ... <Foo>::method_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+ --> $DIR/lint-stability-deprecated.rs:46:13
+ |
+LL | foo.trait_deprecated_unstable();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+ --> $DIR/lint-stability-deprecated.rs:48:16
+ |
+LL | ... <Foo>::trait_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
+ --> $DIR/lint-stability-deprecated.rs:52:13
+ |
+LL | ... foo.method_deprecated_unstable_text();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
+ --> $DIR/lint-stability-deprecated.rs:53:14
+ |
+LL | ... Foo::method_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
+ --> $DIR/lint-stability-deprecated.rs:54:16
+ |
+LL | ... <Foo>::method_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ --> $DIR/lint-stability-deprecated.rs:55:13
+ |
+LL | ... foo.trait_deprecated_unstable_text();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ --> $DIR/lint-stability-deprecated.rs:57:16
+ |
+LL | ... <Foo>::trait_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated field `lint_stability::DeprecatedStruct::i`: text
+ --> $DIR/lint-stability-deprecated.rs:109:13
+ |
+LL | i: 0
+ | ^^^^
+
+warning: use of deprecated field `lint_stability::DeprecatedUnstableStruct::i`: text
+ --> $DIR/lint-stability-deprecated.rs:113:13
+ |
+LL | i: 0
+ | ^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:144:13
+ |
+LL | foo.trait_deprecated();
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:146:16
+ |
+LL | <Foo>::trait_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:148:13
+ |
+LL | foo.trait_deprecated_text();
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:150:16
+ |
+LL | ... <Foo>::trait_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+ --> $DIR/lint-stability-deprecated.rs:152:13
+ |
+LL | foo.trait_deprecated_unstable();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+ --> $DIR/lint-stability-deprecated.rs:154:16
+ |
+LL | ... <Foo>::trait_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ --> $DIR/lint-stability-deprecated.rs:156:13
+ |
+LL | ... foo.trait_deprecated_unstable_text();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ --> $DIR/lint-stability-deprecated.rs:158:16
+ |
+LL | ... <Foo>::trait_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:175:13
+ |
+LL | foo.trait_deprecated();
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:176:13
+ |
+LL | foo.trait_deprecated_text();
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
+ --> $DIR/lint-stability-deprecated.rs:177:13
+ |
+LL | foo.trait_deprecated_unstable();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+ --> $DIR/lint-stability-deprecated.rs:178:13
+ |
+LL | ... foo.trait_deprecated_unstable_text();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:331:13
+ |
+LL | foo.method_deprecated();
+ | ^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:332:14
+ |
+LL | Foo::method_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:333:16
+ |
+LL | <Foo>::method_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:334:13
+ |
+LL | foo.trait_deprecated();
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:336:16
+ |
+LL | <Foo>::trait_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:340:13
+ |
+LL | ... foo.method_deprecated_text();
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:341:14
+ |
+LL | ... Foo::method_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:342:16
+ |
+LL | ... <Foo>::method_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:343:13
+ |
+LL | foo.trait_deprecated_text();
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:345:16
+ |
+LL | <Foo>::trait_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated field `this_crate::DeprecatedStruct::i`: text
+ --> $DIR/lint-stability-deprecated.rs:386:13
+ |
+LL | i: 0
+ | ^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:405:13
+ |
+LL | foo.trait_deprecated();
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:407:16
+ |
+LL | <Foo>::trait_deprecated(&foo);
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:409:13
+ |
+LL | foo.trait_deprecated_text();
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:411:16
+ |
+LL | <Foo>::trait_deprecated_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:428:13
+ |
+LL | foo.trait_deprecated();
+ | ^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+ --> $DIR/lint-stability-deprecated.rs:429:13
+ |
+LL | foo.trait_deprecated_text();
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:97:48
+ |
+LL | struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated);
+ | ^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:102:13
+ |
+LL | TypeDeprecated = u16,
+ | ^^^^^^^^^^^^^^^^^^^^
+
+warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
+ --> $DIR/lint-stability-deprecated.rs:102:13
+ |
+LL | TypeDeprecated = u16,
+ | ^^^^^^^^^^^^^^^^^^^^
+
+warning: 108 warnings emitted
+
diff --git a/tests/ui/lint/lint-stability-fields-deprecated.rs b/tests/ui/lint/lint-stability-fields-deprecated.rs
new file mode 100644
index 000000000..a5511966d
--- /dev/null
+++ b/tests/ui/lint/lint-stability-fields-deprecated.rs
@@ -0,0 +1,344 @@
+// aux-build:lint_stability_fields.rs
+
+#![deny(deprecated)]
+#![allow(dead_code)]
+#![feature(staged_api, unstable_test_feature)]
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+mod cross_crate {
+ extern crate lint_stability_fields;
+
+ use self::lint_stability_fields::*;
+
+ pub fn foo() {
+ let x = Stable {
+ inherit: 1,
+ override1: 2,
+ override2: 3,
+ //~^ ERROR use of deprecated field
+ override3: 4,
+ };
+
+ let _ = x.inherit;
+ let _ = x.override1;
+ let _ = x.override2;
+ //~^ ERROR use of deprecated field
+ let _ = x.override3;
+
+ let Stable {
+ inherit: _,
+ override1: _,
+ override2: _,
+ //~^ ERROR use of deprecated field
+ override3: _,
+ } = x;
+ // all fine
+ let Stable { .. } = x;
+
+ let x = Stable2(1, 2, 3, 4);
+
+ let _ = x.0;
+ let _ = x.1;
+ let _ = x.2;
+ //~^ ERROR use of deprecated field
+ let _ = x.3;
+
+ let Stable2(_,
+ _,
+ _,
+ //~^ ERROR use of deprecated field
+ _)
+ = x;
+ // all fine
+ let Stable2(..) = x;
+
+
+ let x = Unstable {
+ inherit: 1,
+ override1: 2,
+ override2: 3,
+ //~^ ERROR use of deprecated field
+ };
+
+ let _ = x.inherit;
+ let _ = x.override1;
+ let _ = x.override2;
+ //~^ ERROR use of deprecated field
+
+ let Unstable {
+ inherit: _,
+ override1: _,
+ override2: _
+ //~^ ERROR use of deprecated field
+ } = x;
+
+ let Unstable
+ // the patterns are all fine:
+ { .. } = x;
+
+
+ let x = Unstable2(1, 2, 3);
+
+ let _ = x.0;
+ let _ = x.1;
+ let _ = x.2;
+ //~^ ERROR use of deprecated field
+
+ let Unstable2
+ (_,
+ _,
+ _)
+ //~^ ERROR use of deprecated field
+ = x;
+ let Unstable2
+ // the patterns are all fine:
+ (..) = x;
+
+
+ let x = Deprecated {
+ //~^ ERROR use of deprecated struct
+ inherit: 1,
+ //~^ ERROR use of deprecated field
+ override1: 2,
+ //~^ ERROR use of deprecated field
+ override2: 3,
+ //~^ ERROR use of deprecated field
+ };
+
+ let _ = x.inherit;
+ //~^ ERROR use of deprecated field
+ let _ = x.override1;
+ //~^ ERROR use of deprecated field
+ let _ = x.override2;
+ //~^ ERROR use of deprecated field
+
+ let Deprecated {
+ //~^ ERROR use of deprecated struct
+ inherit: _,
+ //~^ ERROR use of deprecated field
+ override1: _,
+ //~^ ERROR use of deprecated field
+ override2: _
+ //~^ ERROR use of deprecated field
+ } = x;
+
+ let Deprecated
+ //~^ ERROR use of deprecated struct
+ // the patterns are all fine:
+ { .. } = x;
+
+ let x = Deprecated2(1, 2, 3);
+ //~^ ERROR use of deprecated tuple struct
+
+ let _ = x.0;
+ //~^ ERROR use of deprecated field
+ let _ = x.1;
+ //~^ ERROR use of deprecated field
+ let _ = x.2;
+ //~^ ERROR use of deprecated field
+
+ let Deprecated2
+ //~^ ERROR use of deprecated tuple struct
+ (_,
+ //~^ ERROR use of deprecated field
+ _,
+ //~^ ERROR use of deprecated field
+ _)
+ //~^ ERROR use of deprecated field
+ = x;
+ let Deprecated2
+ //~^ ERROR use of deprecated tuple struct
+ // the patterns are all fine:
+ (..) = x;
+ }
+}
+
+mod this_crate {
+ #[stable(feature = "rust1", since = "1.0.0")]
+ struct Stable {
+ inherit: u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ override1: u8,
+ #[deprecated(since = "1.0.0", note = "text")]
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ override2: u8,
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ struct Stable2(u8,
+ #[stable(feature = "rust1", since = "1.0.0")] u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")] u8);
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ struct Unstable {
+ inherit: u8,
+ #[stable(feature = "rust1", since = "1.0.0")]
+ override1: u8,
+ #[deprecated(since = "1.0.0", note = "text")]
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ override2: u8,
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ struct Unstable2(u8,
+ #[stable(feature = "rust1", since = "1.0.0")] u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")] u8);
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ struct Deprecated {
+ inherit: u8,
+ #[stable(feature = "rust1", since = "1.0.0")]
+ override1: u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ override2: u8,
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ struct Deprecated2(u8,
+ #[stable(feature = "rust1", since = "1.0.0")] u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")] u8);
+
+ pub fn foo() {
+ let x = Stable {
+ inherit: 1,
+ override1: 2,
+ override2: 3,
+ //~^ ERROR use of deprecated field
+ };
+
+ let _ = x.inherit;
+ let _ = x.override1;
+ let _ = x.override2;
+ //~^ ERROR use of deprecated field
+
+ let Stable {
+ inherit: _,
+ override1: _,
+ override2: _
+ //~^ ERROR use of deprecated field
+ } = x;
+ // all fine
+ let Stable { .. } = x;
+
+ let x = Stable2(1, 2, 3);
+
+ let _ = x.0;
+ let _ = x.1;
+ let _ = x.2;
+ //~^ ERROR use of deprecated field
+
+ let Stable2(_,
+ _,
+ _)
+ //~^ ERROR use of deprecated field
+ = x;
+ // all fine
+ let Stable2(..) = x;
+
+
+ let x = Unstable {
+ inherit: 1,
+ override1: 2,
+ override2: 3,
+ //~^ ERROR use of deprecated field
+ };
+
+ let _ = x.inherit;
+ let _ = x.override1;
+ let _ = x.override2;
+ //~^ ERROR use of deprecated field
+
+ let Unstable {
+ inherit: _,
+ override1: _,
+ override2: _
+ //~^ ERROR use of deprecated field
+ } = x;
+
+ let Unstable
+ // the patterns are all fine:
+ { .. } = x;
+
+
+ let x = Unstable2(1, 2, 3);
+
+ let _ = x.0;
+ let _ = x.1;
+ let _ = x.2;
+ //~^ ERROR use of deprecated field
+
+ let Unstable2
+ (_,
+ _,
+ _)
+ //~^ ERROR use of deprecated field
+ = x;
+ let Unstable2
+ // the patterns are all fine:
+ (..) = x;
+
+
+ let x = Deprecated {
+ //~^ ERROR use of deprecated struct
+ inherit: 1,
+ //~^ ERROR use of deprecated field
+ override1: 2,
+ //~^ ERROR use of deprecated field
+ override2: 3,
+ //~^ ERROR use of deprecated field
+ };
+
+ let _ = x.inherit;
+ //~^ ERROR use of deprecated field
+ let _ = x.override1;
+ //~^ ERROR use of deprecated field
+ let _ = x.override2;
+ //~^ ERROR use of deprecated field
+
+ let Deprecated {
+ //~^ ERROR use of deprecated struct
+ inherit: _,
+ //~^ ERROR use of deprecated field
+ override1: _,
+ //~^ ERROR use of deprecated field
+ override2: _
+ //~^ ERROR use of deprecated field
+ } = x;
+
+ let Deprecated
+ //~^ ERROR use of deprecated struct
+ // the patterns are all fine:
+ { .. } = x;
+
+ let x = Deprecated2(1, 2, 3);
+ //~^ ERROR use of deprecated tuple struct
+
+ let _ = x.0;
+ //~^ ERROR use of deprecated field
+ let _ = x.1;
+ //~^ ERROR use of deprecated field
+ let _ = x.2;
+ //~^ ERROR use of deprecated field
+
+ let Deprecated2
+ //~^ ERROR use of deprecated tuple struct
+ (_,
+ //~^ ERROR use of deprecated field
+ _,
+ //~^ ERROR use of deprecated field
+ _)
+ //~^ ERROR use of deprecated field
+ = x;
+ let Deprecated2
+ //~^ ERROR use of deprecated tuple struct
+ // the patterns are all fine:
+ (..) = x;
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-stability-fields-deprecated.stderr b/tests/ui/lint/lint-stability-fields-deprecated.stderr
new file mode 100644
index 000000000..2d8326020
--- /dev/null
+++ b/tests/ui/lint/lint-stability-fields-deprecated.stderr
@@ -0,0 +1,380 @@
+error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:99:17
+ |
+LL | let x = Deprecated {
+ | ^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-stability-fields-deprecated.rs:3:9
+ |
+LL | #![deny(deprecated)]
+ | ^^^^^^^^^^
+
+error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:116:13
+ |
+LL | let Deprecated {
+ | ^^^^^^^^^^
+
+error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:126:13
+ |
+LL | let Deprecated
+ | ^^^^^^^^^^
+
+error: use of deprecated tuple struct `cross_crate::lint_stability_fields::Deprecated2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:131:17
+ |
+LL | let x = Deprecated2(1, 2, 3);
+ | ^^^^^^^^^^^
+
+error: use of deprecated tuple struct `cross_crate::lint_stability_fields::Deprecated2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:141:13
+ |
+LL | let Deprecated2
+ | ^^^^^^^^^^^
+
+error: use of deprecated tuple struct `cross_crate::lint_stability_fields::Deprecated2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:150:13
+ |
+LL | let Deprecated2
+ | ^^^^^^^^^^^
+
+error: use of deprecated struct `this_crate::Deprecated`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:286:17
+ |
+LL | let x = Deprecated {
+ | ^^^^^^^^^^
+
+error: use of deprecated struct `this_crate::Deprecated`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:303:13
+ |
+LL | let Deprecated {
+ | ^^^^^^^^^^
+
+error: use of deprecated struct `this_crate::Deprecated`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:313:13
+ |
+LL | let Deprecated
+ | ^^^^^^^^^^
+
+error: use of deprecated tuple struct `this_crate::Deprecated2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:318:17
+ |
+LL | let x = Deprecated2(1, 2, 3);
+ | ^^^^^^^^^^^
+
+error: use of deprecated tuple struct `this_crate::Deprecated2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:328:13
+ |
+LL | let Deprecated2
+ | ^^^^^^^^^^^
+
+error: use of deprecated tuple struct `this_crate::Deprecated2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:337:13
+ |
+LL | let Deprecated2
+ | ^^^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Stable::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:18:13
+ |
+LL | override2: 3,
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Stable::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:25:17
+ |
+LL | let _ = x.override2;
+ | ^^^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Stable::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:32:13
+ |
+LL | override2: _,
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Stable2::2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:43:17
+ |
+LL | let _ = x.2;
+ | ^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Stable2::2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:49:20
+ |
+LL | _,
+ | ^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Unstable::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:60:13
+ |
+LL | override2: 3,
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Unstable::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:66:17
+ |
+LL | let _ = x.override2;
+ | ^^^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Unstable::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:72:13
+ |
+LL | override2: _
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Unstable2::2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:85:17
+ |
+LL | let _ = x.2;
+ | ^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Unstable2::2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:91:14
+ |
+LL | _)
+ | ^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::inherit`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:101:13
+ |
+LL | inherit: 1,
+ | ^^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override1`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:103:13
+ |
+LL | override1: 2,
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:105:13
+ |
+LL | override2: 3,
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::inherit`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:109:17
+ |
+LL | let _ = x.inherit;
+ | ^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override1`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:111:17
+ |
+LL | let _ = x.override1;
+ | ^^^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:113:17
+ |
+LL | let _ = x.override2;
+ | ^^^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::inherit`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:118:13
+ |
+LL | inherit: _,
+ | ^^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override1`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:120:13
+ |
+LL | override1: _,
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:122:13
+ |
+LL | override2: _
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::0`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:134:17
+ |
+LL | let _ = x.0;
+ | ^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::1`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:136:17
+ |
+LL | let _ = x.1;
+ | ^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:138:17
+ |
+LL | let _ = x.2;
+ | ^^^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::0`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:143:14
+ |
+LL | (_,
+ | ^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::1`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:145:14
+ |
+LL | _,
+ | ^
+
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:147:14
+ |
+LL | _)
+ | ^
+
+error: use of deprecated field `this_crate::Stable::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:210:13
+ |
+LL | override2: 3,
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `this_crate::Stable::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:216:17
+ |
+LL | let _ = x.override2;
+ | ^^^^^^^^^^^
+
+error: use of deprecated field `this_crate::Stable::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:222:13
+ |
+LL | override2: _
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `this_crate::Stable2::2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:232:17
+ |
+LL | let _ = x.2;
+ | ^^^
+
+error: use of deprecated field `this_crate::Stable2::2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:237:20
+ |
+LL | _)
+ | ^
+
+error: use of deprecated field `this_crate::Unstable::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:247:13
+ |
+LL | override2: 3,
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `this_crate::Unstable::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:253:17
+ |
+LL | let _ = x.override2;
+ | ^^^^^^^^^^^
+
+error: use of deprecated field `this_crate::Unstable::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:259:13
+ |
+LL | override2: _
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `this_crate::Unstable2::2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:272:17
+ |
+LL | let _ = x.2;
+ | ^^^
+
+error: use of deprecated field `this_crate::Unstable2::2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:278:14
+ |
+LL | _)
+ | ^
+
+error: use of deprecated field `this_crate::Deprecated::inherit`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:288:13
+ |
+LL | inherit: 1,
+ | ^^^^^^^^^^
+
+error: use of deprecated field `this_crate::Deprecated::override1`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:290:13
+ |
+LL | override1: 2,
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `this_crate::Deprecated::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:292:13
+ |
+LL | override2: 3,
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `this_crate::Deprecated::inherit`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:296:17
+ |
+LL | let _ = x.inherit;
+ | ^^^^^^^^^
+
+error: use of deprecated field `this_crate::Deprecated::override1`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:298:17
+ |
+LL | let _ = x.override1;
+ | ^^^^^^^^^^^
+
+error: use of deprecated field `this_crate::Deprecated::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:300:17
+ |
+LL | let _ = x.override2;
+ | ^^^^^^^^^^^
+
+error: use of deprecated field `this_crate::Deprecated::inherit`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:305:13
+ |
+LL | inherit: _,
+ | ^^^^^^^^^^
+
+error: use of deprecated field `this_crate::Deprecated::override1`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:307:13
+ |
+LL | override1: _,
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `this_crate::Deprecated::override2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:309:13
+ |
+LL | override2: _
+ | ^^^^^^^^^^^^
+
+error: use of deprecated field `this_crate::Deprecated2::0`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:321:17
+ |
+LL | let _ = x.0;
+ | ^^^
+
+error: use of deprecated field `this_crate::Deprecated2::1`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:323:17
+ |
+LL | let _ = x.1;
+ | ^^^
+
+error: use of deprecated field `this_crate::Deprecated2::2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:325:17
+ |
+LL | let _ = x.2;
+ | ^^^
+
+error: use of deprecated field `this_crate::Deprecated2::0`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:330:14
+ |
+LL | (_,
+ | ^
+
+error: use of deprecated field `this_crate::Deprecated2::1`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:332:14
+ |
+LL | _,
+ | ^
+
+error: use of deprecated field `this_crate::Deprecated2::2`: text
+ --> $DIR/lint-stability-fields-deprecated.rs:334:14
+ |
+LL | _)
+ | ^
+
+error: aborting due to 62 previous errors
+
diff --git a/tests/ui/lint/lint-stability-fields.rs b/tests/ui/lint/lint-stability-fields.rs
new file mode 100644
index 000000000..51990b6ee
--- /dev/null
+++ b/tests/ui/lint/lint-stability-fields.rs
@@ -0,0 +1,293 @@
+// aux-build:lint_stability_fields.rs
+#![allow(deprecated)]
+#![allow(dead_code)]
+#![feature(staged_api)]
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+mod cross_crate {
+ extern crate lint_stability_fields;
+
+ mod reexport {
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub use super::lint_stability_fields::*;
+ }
+
+ use self::lint_stability_fields::*;
+
+ pub fn foo() {
+ let x = Stable {
+ inherit: 1,
+ override1: 2, //~ ERROR use of unstable
+ override2: 3, //~ ERROR use of unstable
+ override3: 4,
+ };
+
+ let _ = x.inherit;
+ let _ = x.override1; //~ ERROR use of unstable
+ let _ = x.override2; //~ ERROR use of unstable
+ let _ = x.override3;
+
+ let Stable {
+ inherit: _,
+ override1: _, //~ ERROR use of unstable
+ override2: _, //~ ERROR use of unstable
+ override3: _
+ } = x;
+ // all fine
+ let Stable { .. } = x;
+
+ let x = Stable2(1, 2, 3, 4);
+
+ let _ = x.0;
+ let _ = x.1; //~ ERROR use of unstable
+ let _ = x.2; //~ ERROR use of unstable
+ let _ = x.3;
+
+ let Stable2(_,
+ _, //~ ERROR use of unstable
+ _, //~ ERROR use of unstable
+ _)
+ = x;
+ // all fine
+ let Stable2(..) = x;
+
+
+ let x = Unstable { //~ ERROR use of unstable
+ inherit: 1, //~ ERROR use of unstable
+ override1: 2,
+ override2: 3, //~ ERROR use of unstable
+ };
+
+ let _ = x.inherit; //~ ERROR use of unstable
+ let _ = x.override1;
+ let _ = x.override2; //~ ERROR use of unstable
+
+ let Unstable { //~ ERROR use of unstable
+ inherit: _, //~ ERROR use of unstable
+ override1: _,
+ override2: _ //~ ERROR use of unstable
+ } = x;
+
+ let Unstable //~ ERROR use of unstable
+ // the patterns are all fine:
+ { .. } = x;
+
+ // Unstable items are still unstable even when used through a stable "pub use".
+ let x = reexport::Unstable2(1, 2, 3); //~ ERROR use of unstable
+
+ let x = Unstable2(1, 2, 3); //~ ERROR use of unstable
+
+ let _ = x.0; //~ ERROR use of unstable
+ let _ = x.1;
+ let _ = x.2; //~ ERROR use of unstable
+
+ let Unstable2 //~ ERROR use of unstable
+ (_, //~ ERROR use of unstable
+ _,
+ _) //~ ERROR use of unstable
+ = x;
+ let Unstable2 //~ ERROR use of unstable
+ // the patterns are all fine:
+ (..) = x;
+
+
+ let x = Deprecated { //~ ERROR use of unstable
+ inherit: 1, //~ ERROR use of unstable
+ override1: 2,
+ override2: 3, //~ ERROR use of unstable
+ };
+
+ let _ = x.inherit; //~ ERROR use of unstable
+ let _ = x.override1;
+ let _ = x.override2; //~ ERROR use of unstable
+
+ let Deprecated { //~ ERROR use of unstable
+ inherit: _, //~ ERROR use of unstable
+ override1: _,
+ override2: _ //~ ERROR use of unstable
+ } = x;
+
+ let Deprecated //~ ERROR use of unstable
+ // the patterns are all fine:
+ { .. } = x;
+
+ let x = Deprecated2(1, 2, 3); //~ ERROR use of unstable
+
+ let _ = x.0; //~ ERROR use of unstable
+ let _ = x.1;
+ let _ = x.2; //~ ERROR use of unstable
+
+ let Deprecated2 //~ ERROR use of unstable
+ (_, //~ ERROR use of unstable
+ _,
+ _) //~ ERROR use of unstable
+ = x;
+ let Deprecated2 //~ ERROR use of unstable
+ // the patterns are all fine:
+ (..) = x;
+ }
+}
+
+mod this_crate {
+ #[stable(feature = "rust1", since = "1.0.0")]
+ struct Stable {
+ inherit: u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ override1: u8,
+ #[deprecated(since = "1.0.0", note = "text")]
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ override2: u8,
+ #[stable(feature = "rust2", since = "2.0.0")]
+ override3: u8,
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ struct Stable2(u8,
+ #[stable(feature = "rust2", since = "2.0.0")] u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")] u8);
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ struct Unstable {
+ inherit: u8,
+ #[stable(feature = "rust1", since = "1.0.0")]
+ override1: u8,
+ #[deprecated(since = "1.0.0", note = "text")]
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ override2: u8,
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ struct Unstable2(u8,
+ #[stable(feature = "rust1", since = "1.0.0")] u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")] u8);
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ struct Deprecated {
+ inherit: u8,
+ #[stable(feature = "rust1", since = "1.0.0")]
+ override1: u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ override2: u8,
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ struct Deprecated2(u8,
+ #[stable(feature = "rust1", since = "1.0.0")] u8,
+ #[unstable(feature = "unstable_test_feature", issue = "none")] u8);
+
+ pub fn foo() {
+ let x = Stable {
+ inherit: 1,
+ override1: 2,
+ override2: 3,
+ override3: 4,
+ };
+
+ let _ = x.inherit;
+ let _ = x.override1;
+ let _ = x.override2;
+ let _ = x.override3;
+
+ let Stable {
+ inherit: _,
+ override1: _,
+ override2: _,
+ override3: _
+ } = x;
+ // all fine
+ let Stable { .. } = x;
+
+ let x = Stable2(1, 2, 3);
+
+ let _ = x.0;
+ let _ = x.1;
+ let _ = x.2;
+
+ let Stable2(_,
+ _,
+ _)
+ = x;
+ // all fine
+ let Stable2(..) = x;
+
+
+ let x = Unstable {
+ inherit: 1,
+ override1: 2,
+ override2: 3,
+ };
+
+ let _ = x.inherit;
+ let _ = x.override1;
+ let _ = x.override2;
+
+ let Unstable {
+ inherit: _,
+ override1: _,
+ override2: _
+ } = x;
+
+ let Unstable
+ // the patterns are all fine:
+ { .. } = x;
+
+
+ let x = Unstable2(1, 2, 3);
+
+ let _ = x.0;
+ let _ = x.1;
+ let _ = x.2;
+
+ let Unstable2
+ (_,
+ _,
+ _)
+ = x;
+ let Unstable2
+ // the patterns are all fine:
+ (..) = x;
+
+
+ let x = Deprecated {
+ inherit: 1,
+ override1: 2,
+ override2: 3,
+ };
+
+ let _ = x.inherit;
+ let _ = x.override1;
+ let _ = x.override2;
+
+ let Deprecated {
+ inherit: _,
+ override1: _,
+ override2: _
+ } = x;
+
+ let Deprecated
+ // the patterns are all fine:
+ { .. } = x;
+
+ let x = Deprecated2(1, 2, 3);
+
+ let _ = x.0;
+ let _ = x.1;
+ let _ = x.2;
+
+ let Deprecated2
+ (_,
+ _,
+ _)
+ = x;
+ let Deprecated2
+ // the patterns are all fine:
+ (..) = x;
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-stability-fields.stderr b/tests/ui/lint/lint-stability-fields.stderr
new file mode 100644
index 000000000..3d2e73c1e
--- /dev/null
+++ b/tests/ui/lint/lint-stability-fields.stderr
@@ -0,0 +1,347 @@
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:56:17
+ |
+LL | let x = Unstable {
+ | ^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:66:13
+ |
+LL | let Unstable {
+ | ^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:72:13
+ |
+LL | let Unstable
+ | ^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:77:17
+ |
+LL | let x = reexport::Unstable2(1, 2, 3);
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:79:17
+ |
+LL | let x = Unstable2(1, 2, 3);
+ | ^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:85:13
+ |
+LL | let Unstable2
+ | ^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:90:13
+ |
+LL | let Unstable2
+ | ^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:95:17
+ |
+LL | let x = Deprecated {
+ | ^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:105:13
+ |
+LL | let Deprecated {
+ | ^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:111:13
+ |
+LL | let Deprecated
+ | ^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:115:17
+ |
+LL | let x = Deprecated2(1, 2, 3);
+ | ^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:121:13
+ |
+LL | let Deprecated2
+ | ^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:126:13
+ |
+LL | let Deprecated2
+ | ^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:21:13
+ |
+LL | override1: 2,
+ | ^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:22:13
+ |
+LL | override2: 3,
+ | ^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:27:17
+ |
+LL | let _ = x.override1;
+ | ^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:28:17
+ |
+LL | let _ = x.override2;
+ | ^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:33:13
+ |
+LL | override1: _,
+ | ^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:34:13
+ |
+LL | override2: _,
+ | ^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:43:17
+ |
+LL | let _ = x.1;
+ | ^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:44:17
+ |
+LL | let _ = x.2;
+ | ^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:48:20
+ |
+LL | _,
+ | ^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:49:20
+ |
+LL | _,
+ | ^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:57:13
+ |
+LL | inherit: 1,
+ | ^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:59:13
+ |
+LL | override2: 3,
+ | ^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:62:17
+ |
+LL | let _ = x.inherit;
+ | ^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:64:17
+ |
+LL | let _ = x.override2;
+ | ^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:67:13
+ |
+LL | inherit: _,
+ | ^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:69:13
+ |
+LL | override2: _
+ | ^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:81:17
+ |
+LL | let _ = x.0;
+ | ^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:83:17
+ |
+LL | let _ = x.2;
+ | ^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:86:14
+ |
+LL | (_,
+ | ^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:88:14
+ |
+LL | _)
+ | ^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:96:13
+ |
+LL | inherit: 1,
+ | ^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:98:13
+ |
+LL | override2: 3,
+ | ^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:101:17
+ |
+LL | let _ = x.inherit;
+ | ^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:103:17
+ |
+LL | let _ = x.override2;
+ | ^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:106:13
+ |
+LL | inherit: _,
+ | ^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:108:13
+ |
+LL | override2: _
+ | ^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:117:17
+ |
+LL | let _ = x.0;
+ | ^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:119:17
+ |
+LL | let _ = x.2;
+ | ^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:122:14
+ |
+LL | (_,
+ | ^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability-fields.rs:124:14
+ |
+LL | _)
+ | ^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error: aborting due to 43 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/lint/lint-stability.rs b/tests/ui/lint/lint-stability.rs
new file mode 100644
index 000000000..d0f0e9f80
--- /dev/null
+++ b/tests/ui/lint/lint-stability.rs
@@ -0,0 +1,454 @@
+// aux-build:lint_stability.rs
+// aux-build:inherited_stability.rs
+// aux-build:stability_cfg1.rs
+// aux-build:stability-cfg2.rs
+
+#![allow(deprecated)]
+#![allow(dead_code)]
+#![feature(staged_api)]
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+#[macro_use]
+extern crate lint_stability;
+
+mod cross_crate {
+ extern crate stability_cfg1;
+ extern crate stability_cfg2; //~ ERROR use of unstable library feature
+
+ use lint_stability::*;
+
+ fn test() {
+ type Foo = MethodTester;
+ let foo = MethodTester;
+
+ deprecated();
+ foo.method_deprecated();
+ Foo::method_deprecated(&foo);
+ <Foo>::method_deprecated(&foo);
+ foo.trait_deprecated();
+ Trait::trait_deprecated(&foo);
+ <Foo>::trait_deprecated(&foo);
+ <Foo as Trait>::trait_deprecated(&foo);
+
+ deprecated_text();
+ foo.method_deprecated_text();
+ Foo::method_deprecated_text(&foo);
+ <Foo>::method_deprecated_text(&foo);
+ foo.trait_deprecated_text();
+ Trait::trait_deprecated_text(&foo);
+ <Foo>::trait_deprecated_text(&foo);
+ <Foo as Trait>::trait_deprecated_text(&foo);
+
+ deprecated_future(); // Fine; no error.
+
+ deprecated_unstable();
+ //~^ ERROR use of unstable library feature
+ Trait::trait_deprecated_unstable(&foo);
+ //~^ ERROR use of unstable library feature
+ <Foo as Trait>::trait_deprecated_unstable(&foo);
+ //~^ ERROR use of unstable library feature
+
+ deprecated_unstable_text();
+ //~^ ERROR use of unstable library feature
+ Trait::trait_deprecated_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature
+ <Foo as Trait>::trait_deprecated_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature
+
+ unstable(); //~ ERROR use of unstable library feature
+ Trait::trait_unstable(&foo); //~ ERROR use of unstable library feature
+ <Foo as Trait>::trait_unstable(&foo); //~ ERROR use of unstable library feature
+
+ unstable_text();
+ //~^ ERROR use of unstable library feature 'unstable_test_feature': text
+ Trait::trait_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature 'unstable_test_feature': text
+ <Foo as Trait>::trait_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature 'unstable_test_feature': text
+
+ stable();
+ foo.method_stable();
+ Foo::method_stable(&foo);
+ <Foo>::method_stable(&foo);
+ foo.trait_stable();
+ Trait::trait_stable(&foo);
+ <Foo>::trait_stable(&foo);
+ <Foo as Trait>::trait_stable(&foo);
+
+ stable_text();
+ foo.method_stable_text();
+ Foo::method_stable_text(&foo);
+ <Foo>::method_stable_text(&foo);
+ foo.trait_stable_text();
+ Trait::trait_stable_text(&foo);
+ <Foo>::trait_stable_text(&foo);
+ <Foo as Trait>::trait_stable_text(&foo);
+
+ struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable);
+ //~^ ERROR use of unstable library feature
+ struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated);
+ type A = dyn TraitWithAssociatedTypes<
+ TypeUnstable = u8, //~ ERROR use of unstable library feature
+ TypeDeprecated = u16,
+ >;
+
+ let _ = DeprecatedStruct {
+ i: 0
+ };
+ let _ = DeprecatedUnstableStruct {
+ //~^ ERROR use of unstable library feature
+ i: 0
+ };
+ let _ = UnstableStruct { i: 0 }; //~ ERROR use of unstable library feature
+ let _ = StableStruct { i: 0 };
+
+ let _ = DeprecatedUnitStruct;
+ let _ = DeprecatedUnstableUnitStruct;
+ //~^ ERROR use of unstable library feature
+ let _ = UnstableUnitStruct; //~ ERROR use of unstable library feature
+ let _ = StableUnitStruct;
+
+ let _ = Enum::DeprecatedVariant;
+ let _ = Enum::DeprecatedUnstableVariant;
+ //~^ ERROR use of unstable library feature
+ let _ = Enum::UnstableVariant; //~ ERROR use of unstable library feature
+ let _ = Enum::StableVariant;
+
+ let _ = DeprecatedTupleStruct (1);
+ let _ = DeprecatedUnstableTupleStruct (1);
+ //~^ ERROR use of unstable library feature
+ let _ = UnstableTupleStruct (1); //~ ERROR use of unstable library feature
+ let _ = StableTupleStruct (1);
+
+ // At the moment, the lint checker only checks stability in
+ // in the arguments of macros.
+ // Eventually, we will want to lint the contents of the
+ // macro in the module *defining* it. Also, stability levels
+ // on macros themselves are not yet linted.
+ macro_test_arg!(deprecated_text());
+ macro_test_arg!(deprecated_unstable_text());
+ //~^ ERROR use of unstable library feature
+ macro_test_arg!(macro_test_arg!(deprecated_text()));
+ }
+
+ fn test_method_param<Foo: Trait>(foo: Foo) {
+ foo.trait_deprecated();
+ Trait::trait_deprecated(&foo);
+ <Foo>::trait_deprecated(&foo);
+ <Foo as Trait>::trait_deprecated(&foo);
+ foo.trait_deprecated_text();
+ Trait::trait_deprecated_text(&foo);
+ <Foo>::trait_deprecated_text(&foo);
+ <Foo as Trait>::trait_deprecated_text(&foo);
+ Trait::trait_deprecated_unstable(&foo);
+ //~^ ERROR use of unstable library feature
+ <Foo as Trait>::trait_deprecated_unstable(&foo);
+ //~^ ERROR use of unstable library feature
+ Trait::trait_deprecated_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature
+ <Foo as Trait>::trait_deprecated_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature
+ Trait::trait_unstable(&foo); //~ ERROR use of unstable library feature
+ <Foo as Trait>::trait_unstable(&foo); //~ ERROR use of unstable library feature
+ Trait::trait_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature 'unstable_test_feature': text
+ <Foo as Trait>::trait_unstable_text(&foo);
+ //~^ ERROR use of unstable library feature 'unstable_test_feature': text
+ foo.trait_stable();
+ Trait::trait_stable(&foo);
+ <Foo>::trait_stable(&foo);
+ <Foo as Trait>::trait_stable(&foo);
+ }
+
+ fn test_method_object(foo: &dyn Trait) {
+ foo.trait_deprecated();
+ foo.trait_deprecated_text();
+ foo.trait_stable();
+ }
+
+ struct S;
+
+ impl UnstableTrait for S { } //~ ERROR use of unstable library feature
+ impl DeprecatedTrait for S {}
+ trait LocalTrait : UnstableTrait { } //~ ERROR use of unstable library feature
+ trait LocalTrait2 : DeprecatedTrait { }
+
+ impl Trait for S {
+ fn trait_stable(&self) {}
+ fn trait_unstable(&self) {} //~ ERROR use of unstable library feature
+ }
+}
+
+mod inheritance {
+ extern crate inherited_stability; //~ ERROR use of unstable library feature
+ use self::inherited_stability::*; //~ ERROR use of unstable library feature
+
+ fn test_inheritance() {
+ unstable(); //~ ERROR use of unstable library feature
+ stable();
+
+ stable_mod::unstable(); //~ ERROR use of unstable library feature
+ stable_mod::stable();
+
+ unstable_mod::deprecated(); //~ ERROR use of unstable library feature
+ unstable_mod::unstable(); //~ ERROR use of unstable library feature
+
+ let _ = Unstable::UnstableVariant; //~ ERROR use of unstable library feature
+ let _ = Unstable::StableVariant; //~ ERROR use of unstable library feature
+
+ let x: usize = 0;
+ x.stable();
+ }
+}
+
+mod this_crate {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn deprecated() {}
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn deprecated_text() {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[deprecated(since = "99.99.99", note = "text")]
+ pub fn deprecated_future() {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub fn unstable() {}
+ #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")]
+ pub fn unstable_text() {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn stable() {}
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn stable_text() {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct MethodTester;
+
+ impl MethodTester {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn method_deprecated(&self) {}
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub fn method_deprecated_text(&self) {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub fn method_unstable(&self) {}
+ #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")]
+ pub fn method_unstable_text(&self) {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn method_stable(&self) {}
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn method_stable_text(&self) {}
+ }
+
+ pub trait Trait {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn trait_deprecated(&self) {}
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn trait_deprecated_text(&self) {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ fn trait_unstable(&self) {}
+ #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")]
+ fn trait_unstable_text(&self) {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn trait_stable(&self) {}
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn trait_stable_text(&self) {}
+ }
+
+ impl Trait for MethodTester {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub struct DeprecatedStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize
+ }
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub struct UnstableStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize
+ }
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct StableStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub struct DeprecatedUnitStruct;
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub struct UnstableUnitStruct;
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct StableUnitStruct;
+
+ pub enum Enum {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ DeprecatedVariant,
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ UnstableVariant,
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ StableVariant,
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub struct DeprecatedTupleStruct(isize);
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ pub struct UnstableTupleStruct(isize);
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct StableTupleStruct(isize);
+
+ fn test() {
+ // Only the deprecated cases of the following should generate
+ // errors, because other stability attributes now have meaning
+ // only *across* crates, not within a single crate.
+
+ type Foo = MethodTester;
+ let foo = MethodTester;
+
+ deprecated();
+ foo.method_deprecated();
+ Foo::method_deprecated(&foo);
+ <Foo>::method_deprecated(&foo);
+ foo.trait_deprecated();
+ Trait::trait_deprecated(&foo);
+ <Foo>::trait_deprecated(&foo);
+ <Foo as Trait>::trait_deprecated(&foo);
+
+ deprecated_text();
+ foo.method_deprecated_text();
+ Foo::method_deprecated_text(&foo);
+ <Foo>::method_deprecated_text(&foo);
+ foo.trait_deprecated_text();
+ Trait::trait_deprecated_text(&foo);
+ <Foo>::trait_deprecated_text(&foo);
+ <Foo as Trait>::trait_deprecated_text(&foo);
+
+ deprecated_future();
+
+ unstable();
+ foo.method_unstable();
+ Foo::method_unstable(&foo);
+ <Foo>::method_unstable(&foo);
+ foo.trait_unstable();
+ Trait::trait_unstable(&foo);
+ <Foo>::trait_unstable(&foo);
+ <Foo as Trait>::trait_unstable(&foo);
+
+ unstable_text();
+ foo.method_unstable_text();
+ Foo::method_unstable_text(&foo);
+ <Foo>::method_unstable_text(&foo);
+ foo.trait_unstable_text();
+ Trait::trait_unstable_text(&foo);
+ <Foo>::trait_unstable_text(&foo);
+ <Foo as Trait>::trait_unstable_text(&foo);
+
+ stable();
+ foo.method_stable();
+ Foo::method_stable(&foo);
+ <Foo>::method_stable(&foo);
+ foo.trait_stable();
+ Trait::trait_stable(&foo);
+ <Foo>::trait_stable(&foo);
+ <Foo as Trait>::trait_stable(&foo);
+
+ stable_text();
+ foo.method_stable_text();
+ Foo::method_stable_text(&foo);
+ <Foo>::method_stable_text(&foo);
+ foo.trait_stable_text();
+ Trait::trait_stable_text(&foo);
+ <Foo>::trait_stable_text(&foo);
+ <Foo as Trait>::trait_stable_text(&foo);
+
+ let _ = DeprecatedStruct {
+ i: 0
+ };
+ let _ = UnstableStruct { i: 0 };
+ let _ = StableStruct { i: 0 };
+
+ let _ = DeprecatedUnitStruct;
+ let _ = UnstableUnitStruct;
+ let _ = StableUnitStruct;
+
+ let _ = Enum::DeprecatedVariant;
+ let _ = Enum::UnstableVariant;
+ let _ = Enum::StableVariant;
+
+ let _ = DeprecatedTupleStruct (1);
+ let _ = UnstableTupleStruct (1);
+ let _ = StableTupleStruct (1);
+ }
+
+ fn test_method_param<Foo: Trait>(foo: Foo) {
+ foo.trait_deprecated();
+ Trait::trait_deprecated(&foo);
+ <Foo>::trait_deprecated(&foo);
+ <Foo as Trait>::trait_deprecated(&foo);
+ foo.trait_deprecated_text();
+ Trait::trait_deprecated_text(&foo);
+ <Foo>::trait_deprecated_text(&foo);
+ <Foo as Trait>::trait_deprecated_text(&foo);
+ foo.trait_unstable();
+ Trait::trait_unstable(&foo);
+ <Foo>::trait_unstable(&foo);
+ <Foo as Trait>::trait_unstable(&foo);
+ foo.trait_unstable_text();
+ Trait::trait_unstable_text(&foo);
+ <Foo>::trait_unstable_text(&foo);
+ <Foo as Trait>::trait_unstable_text(&foo);
+ foo.trait_stable();
+ Trait::trait_stable(&foo);
+ <Foo>::trait_stable(&foo);
+ <Foo as Trait>::trait_stable(&foo);
+ }
+
+ fn test_method_object(foo: &dyn Trait) {
+ foo.trait_deprecated();
+ foo.trait_deprecated_text();
+ foo.trait_unstable();
+ foo.trait_unstable_text();
+ foo.trait_stable();
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn test_fn_body() {
+ fn fn_in_body() {}
+ fn_in_body();
+ }
+
+ impl MethodTester {
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ fn test_method_body(&self) {
+ fn fn_in_body() {}
+ fn_in_body();
+ }
+ }
+
+ #[unstable(feature = "unstable_test_feature", issue = "none")]
+ #[deprecated(since = "1.0.0", note = "text")]
+ pub trait DeprecatedTrait {
+ fn dummy(&self) { }
+ }
+
+ struct S;
+
+ impl DeprecatedTrait for S { }
+
+ trait LocalTrait : DeprecatedTrait { }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-stability.stderr b/tests/ui/lint/lint-stability.stderr
new file mode 100644
index 000000000..bd1a57dc4
--- /dev/null
+++ b/tests/ui/lint/lint-stability.stderr
@@ -0,0 +1,347 @@
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:17:5
+ |
+LL | extern crate stability_cfg2;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:45:9
+ |
+LL | deprecated_unstable();
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:47:9
+ |
+LL | Trait::trait_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:49:9
+ |
+LL | <Foo as Trait>::trait_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:52:9
+ |
+LL | deprecated_unstable_text();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:54:9
+ |
+LL | Trait::trait_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:56:9
+ |
+LL | <Foo as Trait>::trait_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:59:9
+ |
+LL | unstable();
+ | ^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:60:9
+ |
+LL | Trait::trait_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:61:9
+ |
+LL | <Foo as Trait>::trait_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature': text
+ --> $DIR/lint-stability.rs:63:9
+ |
+LL | unstable_text();
+ | ^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature': text
+ --> $DIR/lint-stability.rs:65:9
+ |
+LL | Trait::trait_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature': text
+ --> $DIR/lint-stability.rs:67:9
+ |
+LL | <Foo as Trait>::trait_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:99:17
+ |
+LL | let _ = DeprecatedUnstableStruct {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:103:17
+ |
+LL | let _ = UnstableStruct { i: 0 };
+ | ^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:107:17
+ |
+LL | let _ = DeprecatedUnstableUnitStruct;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:109:17
+ |
+LL | let _ = UnstableUnitStruct;
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:113:17
+ |
+LL | let _ = Enum::DeprecatedUnstableVariant;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:115:17
+ |
+LL | let _ = Enum::UnstableVariant;
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:119:17
+ |
+LL | let _ = DeprecatedUnstableTupleStruct (1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:121:17
+ |
+LL | let _ = UnstableTupleStruct (1);
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:130:25
+ |
+LL | macro_test_arg!(deprecated_unstable_text());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:144:9
+ |
+LL | Trait::trait_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:146:9
+ |
+LL | <Foo as Trait>::trait_deprecated_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:148:9
+ |
+LL | Trait::trait_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:150:9
+ |
+LL | <Foo as Trait>::trait_deprecated_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:152:9
+ |
+LL | Trait::trait_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:153:9
+ |
+LL | <Foo as Trait>::trait_unstable(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature': text
+ --> $DIR/lint-stability.rs:154:9
+ |
+LL | Trait::trait_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature': text
+ --> $DIR/lint-stability.rs:156:9
+ |
+LL | <Foo as Trait>::trait_unstable_text(&foo);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:172:10
+ |
+LL | impl UnstableTrait for S { }
+ | ^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:174:24
+ |
+LL | trait LocalTrait : UnstableTrait { }
+ | ^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:179:9
+ |
+LL | fn trait_unstable(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:184:5
+ |
+LL | extern crate inherited_stability;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:185:9
+ |
+LL | use self::inherited_stability::*;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:188:9
+ |
+LL | unstable();
+ | ^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:191:9
+ |
+LL | stable_mod::unstable();
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:194:9
+ |
+LL | unstable_mod::deprecated();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:195:9
+ |
+LL | unstable_mod::unstable();
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:197:17
+ |
+LL | let _ = Unstable::UnstableVariant;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:198:17
+ |
+LL | let _ = Unstable::StableVariant;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:88:48
+ |
+LL | struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable);
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+ --> $DIR/lint-stability.rs:92:13
+ |
+LL | TypeUnstable = u8,
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error: aborting due to 43 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/lint/lint-stability2.rs b/tests/ui/lint/lint-stability2.rs
new file mode 100644
index 000000000..9ae23dac6
--- /dev/null
+++ b/tests/ui/lint/lint-stability2.rs
@@ -0,0 +1,13 @@
+// aux-build:lint_stability.rs
+// error-pattern: use of deprecated function
+
+#![deny(deprecated)]
+
+#[macro_use]
+extern crate lint_stability;
+
+use lint_stability::*;
+
+fn main() {
+ macro_test!();
+}
diff --git a/tests/ui/lint/lint-stability2.stderr b/tests/ui/lint/lint-stability2.stderr
new file mode 100644
index 000000000..51bdf84a3
--- /dev/null
+++ b/tests/ui/lint/lint-stability2.stderr
@@ -0,0 +1,15 @@
+error: use of deprecated function `lint_stability::deprecated`: text
+ --> $DIR/lint-stability2.rs:12:5
+ |
+LL | macro_test!();
+ | ^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-stability2.rs:4:9
+ |
+LL | #![deny(deprecated)]
+ | ^^^^^^^^^^
+ = note: this error originates in the macro `macro_test` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-stability3.rs b/tests/ui/lint/lint-stability3.rs
new file mode 100644
index 000000000..4452846ec
--- /dev/null
+++ b/tests/ui/lint/lint-stability3.rs
@@ -0,0 +1,14 @@
+// aux-build:lint_stability.rs
+// error-pattern: use of deprecated function
+
+#![deny(deprecated)]
+#![allow(warnings)]
+
+#[macro_use]
+extern crate lint_stability;
+
+use lint_stability::*;
+
+fn main() {
+ macro_test_arg_nested!(deprecated_text);
+}
diff --git a/tests/ui/lint/lint-stability3.stderr b/tests/ui/lint/lint-stability3.stderr
new file mode 100644
index 000000000..3bbb60dd3
--- /dev/null
+++ b/tests/ui/lint/lint-stability3.stderr
@@ -0,0 +1,14 @@
+error: use of deprecated function `lint_stability::deprecated_text`: text
+ --> $DIR/lint-stability3.rs:13:28
+ |
+LL | macro_test_arg_nested!(deprecated_text);
+ | ^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-stability3.rs:4:9
+ |
+LL | #![deny(deprecated)]
+ | ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-strict-provenance-fuzzy-casts.rs b/tests/ui/lint/lint-strict-provenance-fuzzy-casts.rs
new file mode 100644
index 000000000..d2d72a68f
--- /dev/null
+++ b/tests/ui/lint/lint-strict-provenance-fuzzy-casts.rs
@@ -0,0 +1,7 @@
+#![feature(strict_provenance)]
+#![deny(fuzzy_provenance_casts)]
+
+fn main() {
+ let dangling = 16_usize as *const u8;
+ //~^ ERROR strict provenance disallows casting integer `usize` to pointer `*const u8`
+}
diff --git a/tests/ui/lint/lint-strict-provenance-fuzzy-casts.stderr b/tests/ui/lint/lint-strict-provenance-fuzzy-casts.stderr
new file mode 100644
index 000000000..383623b48
--- /dev/null
+++ b/tests/ui/lint/lint-strict-provenance-fuzzy-casts.stderr
@@ -0,0 +1,19 @@
+error: strict provenance disallows casting integer `usize` to pointer `*const u8`
+ --> $DIR/lint-strict-provenance-fuzzy-casts.rs:5:20
+ |
+LL | let dangling = 16_usize as *const u8;
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::from_exposed_addr()` instead
+note: the lint level is defined here
+ --> $DIR/lint-strict-provenance-fuzzy-casts.rs:2:9
+ |
+LL | #![deny(fuzzy_provenance_casts)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+help: use `.with_addr()` to adjust a valid pointer in the same allocation, to this address
+ |
+LL | let dangling = (...).with_addr(16_usize);
+ | ++++++++++++++++ ~
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-strict-provenance-lossy-casts.rs b/tests/ui/lint/lint-strict-provenance-lossy-casts.rs
new file mode 100644
index 000000000..9799a0537
--- /dev/null
+++ b/tests/ui/lint/lint-strict-provenance-lossy-casts.rs
@@ -0,0 +1,18 @@
+#![feature(strict_provenance)]
+#![deny(lossy_provenance_casts)]
+
+fn main() {
+ let x: u8 = 37;
+ let addr: usize = &x as *const u8 as usize;
+ //~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
+
+ let addr_32bit = &x as *const u8 as u32;
+ //~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
+
+ // don't add unnecessary parens in the suggestion
+ let ptr = &x as *const u8;
+ let ptr_addr = ptr as usize;
+ //~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
+ let ptr_addr_32bit = ptr as u32;
+ //~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
+}
diff --git a/tests/ui/lint/lint-strict-provenance-lossy-casts.stderr b/tests/ui/lint/lint-strict-provenance-lossy-casts.stderr
new file mode 100644
index 000000000..aa151fe2d
--- /dev/null
+++ b/tests/ui/lint/lint-strict-provenance-lossy-casts.stderr
@@ -0,0 +1,51 @@
+error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
+ --> $DIR/lint-strict-provenance-lossy-casts.rs:6:23
+ |
+LL | let addr: usize = &x as *const u8 as usize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
+note: the lint level is defined here
+ --> $DIR/lint-strict-provenance-lossy-casts.rs:2:9
+ |
+LL | #![deny(lossy_provenance_casts)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+help: use `.addr()` to obtain the address of a pointer
+ |
+LL | let addr: usize = (&x as *const u8).addr();
+ | + ~~~~~~~~
+
+error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
+ --> $DIR/lint-strict-provenance-lossy-casts.rs:9:22
+ |
+LL | let addr_32bit = &x as *const u8 as u32;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
+help: use `.addr()` to obtain the address of a pointer
+ |
+LL | let addr_32bit = (&x as *const u8).addr() as u32;
+ | + ~~~~~~~~~~~~~~~
+
+error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
+ --> $DIR/lint-strict-provenance-lossy-casts.rs:14:20
+ |
+LL | let ptr_addr = ptr as usize;
+ | ^^^---------
+ | |
+ | help: use `.addr()` to obtain the address of a pointer: `.addr()`
+ |
+ = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
+
+error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
+ --> $DIR/lint-strict-provenance-lossy-casts.rs:16:26
+ |
+LL | let ptr_addr_32bit = ptr as u32;
+ | ^^^-------
+ | |
+ | help: use `.addr()` to obtain the address of a pointer: `.addr() as u32`
+ |
+ = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lint/lint-temporary-cstring-as-param.rs b/tests/ui/lint/lint-temporary-cstring-as-param.rs
new file mode 100644
index 000000000..9f5805367
--- /dev/null
+++ b/tests/ui/lint/lint-temporary-cstring-as-param.rs
@@ -0,0 +1,11 @@
+#![deny(temporary_cstring_as_ptr)]
+
+use std::ffi::CString;
+use std::os::raw::c_char;
+
+fn some_function(data: *const c_char) {}
+
+fn main() {
+ some_function(CString::new("").unwrap().as_ptr());
+ //~^ ERROR getting the inner pointer of a temporary `CString`
+}
diff --git a/tests/ui/lint/lint-temporary-cstring-as-param.stderr b/tests/ui/lint/lint-temporary-cstring-as-param.stderr
new file mode 100644
index 000000000..838b3bc13
--- /dev/null
+++ b/tests/ui/lint/lint-temporary-cstring-as-param.stderr
@@ -0,0 +1,18 @@
+error: getting the inner pointer of a temporary `CString`
+ --> $DIR/lint-temporary-cstring-as-param.rs:9:45
+ |
+LL | some_function(CString::new("").unwrap().as_ptr());
+ | ------------------------- ^^^^^^ this pointer will be invalid
+ | |
+ | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
+ |
+ = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
+ = help: for more information, see https://doc.rust-lang.org/reference/destructors.html
+note: the lint level is defined here
+ --> $DIR/lint-temporary-cstring-as-param.rs:1:9
+ |
+LL | #![deny(temporary_cstring_as_ptr)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-temporary-cstring-as-ptr.rs b/tests/ui/lint/lint-temporary-cstring-as-ptr.rs
new file mode 100644
index 000000000..7aa4f2e1e
--- /dev/null
+++ b/tests/ui/lint/lint-temporary-cstring-as-ptr.rs
@@ -0,0 +1,9 @@
+// this program is not technically incorrect, but is an obscure enough style to be worth linting
+#![deny(temporary_cstring_as_ptr)]
+
+use std::ffi::CString;
+
+fn main() {
+ let s = CString::new("some text").unwrap().as_ptr();
+ //~^ ERROR getting the inner pointer of a temporary `CString`
+}
diff --git a/tests/ui/lint/lint-temporary-cstring-as-ptr.stderr b/tests/ui/lint/lint-temporary-cstring-as-ptr.stderr
new file mode 100644
index 000000000..79ef57dd1
--- /dev/null
+++ b/tests/ui/lint/lint-temporary-cstring-as-ptr.stderr
@@ -0,0 +1,18 @@
+error: getting the inner pointer of a temporary `CString`
+ --> $DIR/lint-temporary-cstring-as-ptr.rs:7:48
+ |
+LL | let s = CString::new("some text").unwrap().as_ptr();
+ | ---------------------------------- ^^^^^^ this pointer will be invalid
+ | |
+ | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
+ |
+ = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
+ = help: for more information, see https://doc.rust-lang.org/reference/destructors.html
+note: the lint level is defined here
+ --> $DIR/lint-temporary-cstring-as-ptr.rs:2:9
+ |
+LL | #![deny(temporary_cstring_as_ptr)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-type-limits.rs b/tests/ui/lint/lint-type-limits.rs
new file mode 100644
index 000000000..2b140f869
--- /dev/null
+++ b/tests/ui/lint/lint-type-limits.rs
@@ -0,0 +1,27 @@
+#![allow(dead_code)]
+
+// compile-flags: -D unused-comparisons
+fn main() { }
+
+fn foo() {
+ let mut i = 100_usize;
+ while i >= 0 { //~ ERROR comparison is useless due to type limits
+ i -= 1;
+ }
+}
+
+fn bar() -> i8 {
+ return 123;
+}
+
+fn bleh() {
+ let u = 42u8;
+ let _ = u > 255; //~ ERROR comparison is useless due to type limits
+ let _ = 255 < u; //~ ERROR comparison is useless due to type limits
+ let _ = u < 0; //~ ERROR comparison is useless due to type limits
+ let _ = 0 > u; //~ ERROR comparison is useless due to type limits
+ let _ = u <= 255; //~ ERROR comparison is useless due to type limits
+ let _ = 255 >= u; //~ ERROR comparison is useless due to type limits
+ let _ = u >= 0; //~ ERROR comparison is useless due to type limits
+ let _ = 0 <= u; //~ ERROR comparison is useless due to type limits
+}
diff --git a/tests/ui/lint/lint-type-limits.stderr b/tests/ui/lint/lint-type-limits.stderr
new file mode 100644
index 000000000..71a2b3bfd
--- /dev/null
+++ b/tests/ui/lint/lint-type-limits.stderr
@@ -0,0 +1,58 @@
+error: comparison is useless due to type limits
+ --> $DIR/lint-type-limits.rs:8:11
+ |
+LL | while i >= 0 {
+ | ^^^^^^
+ |
+ = note: requested on the command line with `-D unused-comparisons`
+
+error: comparison is useless due to type limits
+ --> $DIR/lint-type-limits.rs:19:13
+ |
+LL | let _ = u > 255;
+ | ^^^^^^^
+
+error: comparison is useless due to type limits
+ --> $DIR/lint-type-limits.rs:20:13
+ |
+LL | let _ = 255 < u;
+ | ^^^^^^^
+
+error: comparison is useless due to type limits
+ --> $DIR/lint-type-limits.rs:21:13
+ |
+LL | let _ = u < 0;
+ | ^^^^^
+
+error: comparison is useless due to type limits
+ --> $DIR/lint-type-limits.rs:22:13
+ |
+LL | let _ = 0 > u;
+ | ^^^^^
+
+error: comparison is useless due to type limits
+ --> $DIR/lint-type-limits.rs:23:13
+ |
+LL | let _ = u <= 255;
+ | ^^^^^^^^
+
+error: comparison is useless due to type limits
+ --> $DIR/lint-type-limits.rs:24:13
+ |
+LL | let _ = 255 >= u;
+ | ^^^^^^^^
+
+error: comparison is useless due to type limits
+ --> $DIR/lint-type-limits.rs:25:13
+ |
+LL | let _ = u >= 0;
+ | ^^^^^^
+
+error: comparison is useless due to type limits
+ --> $DIR/lint-type-limits.rs:26:13
+ |
+LL | let _ = 0 <= u;
+ | ^^^^^^
+
+error: aborting due to 9 previous errors
+
diff --git a/tests/ui/lint/lint-type-limits2.rs b/tests/ui/lint/lint-type-limits2.rs
new file mode 100644
index 000000000..3f90119cd
--- /dev/null
+++ b/tests/ui/lint/lint-type-limits2.rs
@@ -0,0 +1,15 @@
+#![allow(dead_code)]
+#![warn(overflowing_literals)]
+
+// compile-flags: -D unused-comparisons
+fn main() { }
+
+
+fn bar() -> i8 {
+ return 123;
+}
+
+fn baz() -> bool {
+ 128 > bar() //~ ERROR comparison is useless due to type limits
+ //~| WARN literal out of range for `i8`
+}
diff --git a/tests/ui/lint/lint-type-limits2.stderr b/tests/ui/lint/lint-type-limits2.stderr
new file mode 100644
index 000000000..b3420ad8a
--- /dev/null
+++ b/tests/ui/lint/lint-type-limits2.stderr
@@ -0,0 +1,24 @@
+error: comparison is useless due to type limits
+ --> $DIR/lint-type-limits2.rs:13:5
+ |
+LL | 128 > bar()
+ | ^^^^^^^^^^^
+ |
+ = note: requested on the command line with `-D unused-comparisons`
+
+warning: literal out of range for `i8`
+ --> $DIR/lint-type-limits2.rs:13:5
+ |
+LL | 128 > bar()
+ | ^^^
+ |
+ = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127`
+ = help: consider using the type `u8` instead
+note: the lint level is defined here
+ --> $DIR/lint-type-limits2.rs:2:9
+ |
+LL | #![warn(overflowing_literals)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/tests/ui/lint/lint-type-limits3.rs b/tests/ui/lint/lint-type-limits3.rs
new file mode 100644
index 000000000..ceecf9ab3
--- /dev/null
+++ b/tests/ui/lint/lint-type-limits3.rs
@@ -0,0 +1,13 @@
+#![allow(dead_code)]
+#![warn(overflowing_literals)]
+
+// compile-flags: -D unused-comparisons
+fn main() { }
+
+fn qux() {
+ let mut i = 1i8;
+ while 200 != i { //~ ERROR comparison is useless due to type limits
+ //~| WARN literal out of range for `i8`
+ i += 1;
+ }
+}
diff --git a/tests/ui/lint/lint-type-limits3.stderr b/tests/ui/lint/lint-type-limits3.stderr
new file mode 100644
index 000000000..db46e7ae7
--- /dev/null
+++ b/tests/ui/lint/lint-type-limits3.stderr
@@ -0,0 +1,24 @@
+error: comparison is useless due to type limits
+ --> $DIR/lint-type-limits3.rs:9:11
+ |
+LL | while 200 != i {
+ | ^^^^^^^^
+ |
+ = note: requested on the command line with `-D unused-comparisons`
+
+warning: literal out of range for `i8`
+ --> $DIR/lint-type-limits3.rs:9:11
+ |
+LL | while 200 != i {
+ | ^^^
+ |
+ = note: the literal `200` does not fit into the type `i8` whose range is `-128..=127`
+ = help: consider using the type `u8` instead
+note: the lint level is defined here
+ --> $DIR/lint-type-limits3.rs:2:9
+ |
+LL | #![warn(overflowing_literals)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/tests/ui/lint/lint-type-overflow.rs b/tests/ui/lint/lint-type-overflow.rs
new file mode 100644
index 000000000..9672da6d3
--- /dev/null
+++ b/tests/ui/lint/lint-type-overflow.rs
@@ -0,0 +1,45 @@
+#![deny(overflowing_literals)]
+
+fn test(x: i8) {
+ println!("x {}", x);
+}
+
+#[allow(unused_variables)]
+fn main() {
+ let x1: u8 = 255; // should be OK
+ let x1: u8 = 256; //~ error: literal out of range for `u8`
+
+ let x1 = 255_u8; // should be OK
+ let x1 = 256_u8; //~ error: literal out of range for `u8`
+
+ let x2: i8 = -128; // should be OK
+ let x1: i8 = 128; //~ error: literal out of range for `i8`
+
+ let x3: i8 = -129; //~ error: literal out of range for `i8`
+ let x3: i8 = -(129); //~ error: literal out of range for `i8`
+ let x3: i8 = -{129}; //~ error: literal out of range for `i8`
+
+ test(1000); //~ error: literal out of range for `i8`
+
+ let x = 128_i8; //~ error: literal out of range for `i8`
+ let x = 127_i8;
+ let x = -128_i8;
+ let x = -(128_i8);
+ let x = -129_i8; //~ error: literal out of range for `i8`
+
+ let x: i32 = 2147483647; // should be OK
+ let x = 2147483647_i32; // should be OK
+ let x: i32 = 2147483648; //~ error: literal out of range for `i32`
+ let x = 2147483648_i32; //~ error: literal out of range for `i32`
+ let x: i32 = -2147483648; // should be OK
+ let x = -2147483648_i32; // should be OK
+ let x: i32 = -2147483649; //~ error: literal out of range for `i32`
+ let x = -2147483649_i32; //~ error: literal out of range for `i32`
+ let x = 2147483648; //~ error: literal out of range for `i32`
+
+ let x = 9223372036854775808_i64; //~ error: literal out of range for `i64`
+ let x = -9223372036854775808_i64; // should be OK
+ let x = 18446744073709551615_i64; //~ error: literal out of range for `i64`
+ let x: i64 = -9223372036854775809; //~ error: literal out of range for `i64`
+ let x = -9223372036854775809_i64; //~ error: literal out of range for `i64`
+}
diff --git a/tests/ui/lint/lint-type-overflow.stderr b/tests/ui/lint/lint-type-overflow.stderr
new file mode 100644
index 000000000..48d8228b8
--- /dev/null
+++ b/tests/ui/lint/lint-type-overflow.stderr
@@ -0,0 +1,167 @@
+error: literal out of range for `u8`
+ --> $DIR/lint-type-overflow.rs:10:18
+ |
+LL | let x1: u8 = 256;
+ | ^^^
+ |
+ = note: the literal `256` does not fit into the type `u8` whose range is `0..=255`
+note: the lint level is defined here
+ --> $DIR/lint-type-overflow.rs:1:9
+ |
+LL | #![deny(overflowing_literals)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: literal out of range for `u8`
+ --> $DIR/lint-type-overflow.rs:13:14
+ |
+LL | let x1 = 256_u8;
+ | ^^^^^^
+ |
+ = note: the literal `256_u8` does not fit into the type `u8` whose range is `0..=255`
+
+error: literal out of range for `i8`
+ --> $DIR/lint-type-overflow.rs:16:18
+ |
+LL | let x1: i8 = 128;
+ | ^^^
+ |
+ = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127`
+ = help: consider using the type `u8` instead
+
+error: literal out of range for `i8`
+ --> $DIR/lint-type-overflow.rs:18:19
+ |
+LL | let x3: i8 = -129;
+ | ^^^
+ |
+ = note: the literal `129` does not fit into the type `i8` whose range is `-128..=127`
+ = help: consider using the type `i16` instead
+
+error: literal out of range for `i8`
+ --> $DIR/lint-type-overflow.rs:19:19
+ |
+LL | let x3: i8 = -(129);
+ | ^^^^^
+ |
+ = note: the literal `129` does not fit into the type `i8` whose range is `-128..=127`
+ = help: consider using the type `i16` instead
+
+error: literal out of range for `i8`
+ --> $DIR/lint-type-overflow.rs:20:20
+ |
+LL | let x3: i8 = -{129};
+ | ^^^
+ |
+ = note: the literal `129` does not fit into the type `i8` whose range is `-128..=127`
+ = help: consider using the type `u8` instead
+
+error: literal out of range for `i8`
+ --> $DIR/lint-type-overflow.rs:22:10
+ |
+LL | test(1000);
+ | ^^^^
+ |
+ = note: the literal `1000` does not fit into the type `i8` whose range is `-128..=127`
+ = help: consider using the type `i16` instead
+
+error: literal out of range for `i8`
+ --> $DIR/lint-type-overflow.rs:24:13
+ |
+LL | let x = 128_i8;
+ | ^^^^^^
+ |
+ = note: the literal `128_i8` does not fit into the type `i8` whose range is `-128..=127`
+ = help: consider using the type `u8` instead
+
+error: literal out of range for `i8`
+ --> $DIR/lint-type-overflow.rs:28:14
+ |
+LL | let x = -129_i8;
+ | ^^^^^^
+ |
+ = note: the literal `129_i8` does not fit into the type `i8` whose range is `-128..=127`
+ = help: consider using the type `i16` instead
+
+error: literal out of range for `i32`
+ --> $DIR/lint-type-overflow.rs:32:18
+ |
+LL | let x: i32 = 2147483648;
+ | ^^^^^^^^^^
+ |
+ = note: the literal `2147483648` does not fit into the type `i32` whose range is `-2147483648..=2147483647`
+ = help: consider using the type `u32` instead
+
+error: literal out of range for `i32`
+ --> $DIR/lint-type-overflow.rs:33:13
+ |
+LL | let x = 2147483648_i32;
+ | ^^^^^^^^^^^^^^
+ |
+ = note: the literal `2147483648_i32` does not fit into the type `i32` whose range is `-2147483648..=2147483647`
+ = help: consider using the type `u32` instead
+
+error: literal out of range for `i32`
+ --> $DIR/lint-type-overflow.rs:36:19
+ |
+LL | let x: i32 = -2147483649;
+ | ^^^^^^^^^^
+ |
+ = note: the literal `2147483649` does not fit into the type `i32` whose range is `-2147483648..=2147483647`
+ = help: consider using the type `i64` instead
+
+error: literal out of range for `i32`
+ --> $DIR/lint-type-overflow.rs:37:14
+ |
+LL | let x = -2147483649_i32;
+ | ^^^^^^^^^^^^^^
+ |
+ = note: the literal `2147483649_i32` does not fit into the type `i32` whose range is `-2147483648..=2147483647`
+ = help: consider using the type `i64` instead
+
+error: literal out of range for `i32`
+ --> $DIR/lint-type-overflow.rs:38:13
+ |
+LL | let x = 2147483648;
+ | ^^^^^^^^^^
+ |
+ = note: the literal `2147483648` does not fit into the type `i32` whose range is `-2147483648..=2147483647`
+ = help: consider using the type `u32` instead
+
+error: literal out of range for `i64`
+ --> $DIR/lint-type-overflow.rs:40:13
+ |
+LL | let x = 9223372036854775808_i64;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the literal `9223372036854775808_i64` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807`
+ = help: consider using the type `u64` instead
+
+error: literal out of range for `i64`
+ --> $DIR/lint-type-overflow.rs:42:13
+ |
+LL | let x = 18446744073709551615_i64;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the literal `18446744073709551615_i64` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807`
+ = help: consider using the type `u64` instead
+
+error: literal out of range for `i64`
+ --> $DIR/lint-type-overflow.rs:43:19
+ |
+LL | let x: i64 = -9223372036854775809;
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the literal `9223372036854775809` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807`
+ = help: consider using the type `i128` instead
+
+error: literal out of range for `i64`
+ --> $DIR/lint-type-overflow.rs:44:14
+ |
+LL | let x = -9223372036854775809_i64;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the literal `9223372036854775809_i64` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807`
+ = help: consider using the type `i128` instead
+
+error: aborting due to 18 previous errors
+
diff --git a/tests/ui/lint/lint-type-overflow2.rs b/tests/ui/lint/lint-type-overflow2.rs
new file mode 100644
index 000000000..9b1eb510b
--- /dev/null
+++ b/tests/ui/lint/lint-type-overflow2.rs
@@ -0,0 +1,12 @@
+// compile-flags: -O
+
+#![deny(overflowing_literals)]
+
+fn main() {
+ let x2: i8 = --128; //~ ERROR literal out of range for `i8`
+
+ let x = -3.40282357e+38_f32; //~ ERROR literal out of range for `f32`
+ let x = 3.40282357e+38_f32; //~ ERROR literal out of range for `f32`
+ let x = -1.7976931348623159e+308_f64; //~ ERROR literal out of range for `f64`
+ let x = 1.7976931348623159e+308_f64; //~ ERROR literal out of range for `f64`
+}
diff --git a/tests/ui/lint/lint-type-overflow2.stderr b/tests/ui/lint/lint-type-overflow2.stderr
new file mode 100644
index 000000000..eb593d062
--- /dev/null
+++ b/tests/ui/lint/lint-type-overflow2.stderr
@@ -0,0 +1,48 @@
+error: literal out of range for `i8`
+ --> $DIR/lint-type-overflow2.rs:6:20
+ |
+LL | let x2: i8 = --128;
+ | ^^^
+ |
+ = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127`
+ = help: consider using the type `u8` instead
+note: the lint level is defined here
+ --> $DIR/lint-type-overflow2.rs:3:9
+ |
+LL | #![deny(overflowing_literals)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: literal out of range for `f32`
+ --> $DIR/lint-type-overflow2.rs:8:14
+ |
+LL | let x = -3.40282357e+38_f32;
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = note: the literal `3.40282357e+38_f32` does not fit into the type `f32` and will be converted to `f32::INFINITY`
+
+error: literal out of range for `f32`
+ --> $DIR/lint-type-overflow2.rs:9:14
+ |
+LL | let x = 3.40282357e+38_f32;
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = note: the literal `3.40282357e+38_f32` does not fit into the type `f32` and will be converted to `f32::INFINITY`
+
+error: literal out of range for `f64`
+ --> $DIR/lint-type-overflow2.rs:10:14
+ |
+LL | let x = -1.7976931348623159e+308_f64;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the literal `1.7976931348623159e+308_f64` does not fit into the type `f64` and will be converted to `f64::INFINITY`
+
+error: literal out of range for `f64`
+ --> $DIR/lint-type-overflow2.rs:11:14
+ |
+LL | let x = 1.7976931348623159e+308_f64;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the literal `1.7976931348623159e+308_f64` does not fit into the type `f64` and will be converted to `f64::INFINITY`
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/lint/lint-unconditional-recursion.rs b/tests/ui/lint/lint-unconditional-recursion.rs
new file mode 100644
index 000000000..ad052d36f
--- /dev/null
+++ b/tests/ui/lint/lint-unconditional-recursion.rs
@@ -0,0 +1,194 @@
+#![deny(unconditional_recursion)]
+
+#![allow(dead_code)]
+fn foo() { //~ ERROR function cannot return without recursing
+ foo();
+}
+
+fn bar() {
+ if true {
+ bar()
+ }
+}
+
+fn baz() { //~ ERROR function cannot return without recursing
+ if true {
+ baz()
+ } else {
+ baz()
+ }
+}
+
+fn qux() {
+ loop {}
+}
+
+fn quz() -> bool { //~ ERROR function cannot return without recursing
+ if true {
+ while quz() {}
+ true
+ } else {
+ loop { quz(); }
+ }
+}
+
+// Trait method calls.
+trait Foo {
+ fn bar(&self) { //~ ERROR function cannot return without recursing
+ self.bar()
+ }
+}
+
+impl Foo for Box<dyn Foo + 'static> {
+ fn bar(&self) { //~ ERROR function cannot return without recursing
+ loop {
+ self.bar()
+ }
+ }
+}
+
+// Trait method call with integer fallback after method resolution.
+impl Foo for i32 {
+ fn bar(&self) { //~ ERROR function cannot return without recursing
+ 0.bar()
+ }
+}
+
+impl Foo for u32 {
+ fn bar(&self) {
+ 0.bar()
+ }
+}
+
+// Trait method calls via paths.
+trait Foo2 {
+ fn bar(&self) { //~ ERROR function cannot return without recursing
+ Foo2::bar(self)
+ }
+}
+
+impl Foo2 for Box<dyn Foo2 + 'static> {
+ fn bar(&self) { //~ ERROR function cannot return without recursing
+ loop {
+ Foo2::bar(self)
+ }
+ }
+}
+
+struct Baz;
+impl Baz {
+ // Inherent method call.
+ fn qux(&self) { //~ ERROR function cannot return without recursing
+ self.qux();
+ }
+
+ // Inherent method call via path.
+ fn as_ref(&self) -> &Self { //~ ERROR function cannot return without recursing
+ Baz::as_ref(self)
+ }
+}
+
+// Trait method calls to impls via paths.
+impl Default for Baz {
+ fn default() -> Baz { //~ ERROR function cannot return without recursing
+ let x = Default::default();
+ x
+ }
+}
+
+// Overloaded operators.
+impl std::ops::Deref for Baz {
+ type Target = ();
+ fn deref(&self) -> &() { //~ ERROR function cannot return without recursing
+ &**self
+ }
+}
+
+impl std::ops::Index<usize> for Baz {
+ type Output = Baz;
+ fn index(&self, x: usize) -> &Baz { //~ ERROR function cannot return without recursing
+ &self[x]
+ }
+}
+
+// Overloaded autoderef.
+struct Quux;
+impl std::ops::Deref for Quux {
+ type Target = Baz;
+ fn deref(&self) -> &Baz { //~ ERROR function cannot return without recursing
+ self.as_ref()
+ }
+}
+
+fn all_fine() {
+ let _f = all_fine;
+}
+
+// issue 26333
+trait Bar {
+ fn method<T: Bar>(&self, x: &T) {
+ x.method(x)
+ }
+}
+
+// Do not trigger on functions that may diverge instead of self-recursing (#54444)
+
+pub fn loops(x: bool) {
+ if x {
+ loops(x);
+ } else {
+ loop {}
+ }
+}
+
+pub fn panics(x: bool) {
+ if x {
+ panics(!x);
+ } else {
+ panic!("panics");
+ }
+}
+
+pub fn unreachable1() {
+ panic!();
+ unreachable1(); // WARN unreachable statement
+}
+
+pub fn unreachable2() {
+ loop {}
+ unreachable2(); // WARN unreachable statement
+}
+
+pub fn drop_and_replace(mut a: Option<String>) { //~ ERROR function cannot return without recursing
+ a = None;
+ drop_and_replace(a);
+}
+
+// Calls are assumed to return normally.
+pub fn call() -> String { //~ ERROR function cannot return without recursing
+ let s = String::new();
+ call();
+ s
+}
+
+// Arithmetic operations are assumed not to overflow.
+pub fn overflow_check(a: i32, b: i32) { //~ ERROR function cannot return without recursing
+ let _ = a + b;
+ overflow_check(a, b);
+}
+
+pub struct Point {
+ pub x: f32,
+ pub y: f32,
+}
+
+impl Default for Point {
+ fn default() -> Self { //~ ERROR function cannot return without recursing
+ Point {
+ x: Default::default(),
+ ..Default::default()
+ }
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-unconditional-recursion.stderr b/tests/ui/lint/lint-unconditional-recursion.stderr
new file mode 100644
index 000000000..9d200a789
--- /dev/null
+++ b/tests/ui/lint/lint-unconditional-recursion.stderr
@@ -0,0 +1,201 @@
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:4:1
+ |
+LL | fn foo() {
+ | ^^^^^^^^ cannot return without recursing
+LL | foo();
+ | ----- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+note: the lint level is defined here
+ --> $DIR/lint-unconditional-recursion.rs:1:9
+ |
+LL | #![deny(unconditional_recursion)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:14:1
+ |
+LL | fn baz() {
+ | ^^^^^^^^ cannot return without recursing
+LL | if true {
+LL | baz()
+ | ----- recursive call site
+LL | } else {
+LL | baz()
+ | ----- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:26:1
+ |
+LL | fn quz() -> bool {
+ | ^^^^^^^^^^^^^^^^ cannot return without recursing
+LL | if true {
+LL | while quz() {}
+ | ----- recursive call site
+...
+LL | loop { quz(); }
+ | ----- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:37:5
+ |
+LL | fn bar(&self) {
+ | ^^^^^^^^^^^^^ cannot return without recursing
+LL | self.bar()
+ | ---------- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:43:5
+ |
+LL | fn bar(&self) {
+ | ^^^^^^^^^^^^^ cannot return without recursing
+LL | loop {
+LL | self.bar()
+ | ---------- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:52:5
+ |
+LL | fn bar(&self) {
+ | ^^^^^^^^^^^^^ cannot return without recursing
+LL | 0.bar()
+ | ------- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:65:5
+ |
+LL | fn bar(&self) {
+ | ^^^^^^^^^^^^^ cannot return without recursing
+LL | Foo2::bar(self)
+ | --------------- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:71:5
+ |
+LL | fn bar(&self) {
+ | ^^^^^^^^^^^^^ cannot return without recursing
+LL | loop {
+LL | Foo2::bar(self)
+ | --------------- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:81:5
+ |
+LL | fn qux(&self) {
+ | ^^^^^^^^^^^^^ cannot return without recursing
+LL | self.qux();
+ | ---------- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:86:5
+ |
+LL | fn as_ref(&self) -> &Self {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+LL | Baz::as_ref(self)
+ | ----------------- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:93:5
+ |
+LL | fn default() -> Baz {
+ | ^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+LL | let x = Default::default();
+ | ------------------ recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:102:5
+ |
+LL | fn deref(&self) -> &() {
+ | ^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+LL | &**self
+ | ------ recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:109:5
+ |
+LL | fn index(&self, x: usize) -> &Baz {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+LL | &self[x]
+ | ------- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:118:5
+ |
+LL | fn deref(&self) -> &Baz {
+ | ^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+LL | self.as_ref()
+ | ------------- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:162:1
+ |
+LL | pub fn drop_and_replace(mut a: Option<String>) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+LL | a = None;
+LL | drop_and_replace(a);
+ | ------------------- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:168:1
+ |
+LL | pub fn call() -> String {
+ | ^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+LL | let s = String::new();
+LL | call();
+ | ------ recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:175:1
+ |
+LL | pub fn overflow_check(a: i32, b: i32) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+LL | let _ = a + b;
+LL | overflow_check(a, b);
+ | -------------------- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: function cannot return without recursing
+ --> $DIR/lint-unconditional-recursion.rs:186:5
+ |
+LL | fn default() -> Self {
+ | ^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+...
+LL | ..Default::default()
+ | ------------------ recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: aborting due to 18 previous errors
+
diff --git a/tests/ui/lint/lint-unexported-no-mangle.rs b/tests/ui/lint/lint-unexported-no-mangle.rs
new file mode 100644
index 000000000..f260fc323
--- /dev/null
+++ b/tests/ui/lint/lint-unexported-no-mangle.rs
@@ -0,0 +1,29 @@
+// compile-flags:-F private_no_mangle_fns -F no_mangle_const_items -F private_no_mangle_statics
+
+#[no_mangle]
+fn foo() {
+}
+
+#[allow(dead_code)]
+#[no_mangle]
+const FOO: u64 = 1; //~ ERROR const items should never be `#[no_mangle]`
+
+#[no_mangle]
+pub const PUB_FOO: u64 = 1; //~ ERROR const items should never be `#[no_mangle]`
+
+#[no_mangle]
+pub fn bar() {
+}
+
+#[no_mangle]
+pub static BAR: u64 = 1;
+
+#[allow(dead_code)]
+#[no_mangle]
+static PRIVATE_BAR: u64 = 1;
+
+
+fn main() {
+ foo();
+ bar();
+}
diff --git a/tests/ui/lint/lint-unexported-no-mangle.stderr b/tests/ui/lint/lint-unexported-no-mangle.stderr
new file mode 100644
index 000000000..a11ee769c
--- /dev/null
+++ b/tests/ui/lint/lint-unexported-no-mangle.stderr
@@ -0,0 +1,44 @@
+warning: lint `private_no_mangle_fns` has been removed: no longer a warning, `#[no_mangle]` functions always exported
+ |
+ = note: requested on the command line with `-F private_no_mangle_fns`
+
+warning: lint `private_no_mangle_statics` has been removed: no longer a warning, `#[no_mangle]` statics always exported
+ |
+ = note: requested on the command line with `-F private_no_mangle_statics`
+
+warning: lint `private_no_mangle_fns` has been removed: no longer a warning, `#[no_mangle]` functions always exported
+ |
+ = note: requested on the command line with `-F private_no_mangle_fns`
+
+warning: lint `private_no_mangle_statics` has been removed: no longer a warning, `#[no_mangle]` statics always exported
+ |
+ = note: requested on the command line with `-F private_no_mangle_statics`
+
+warning: lint `private_no_mangle_fns` has been removed: no longer a warning, `#[no_mangle]` functions always exported
+ |
+ = note: requested on the command line with `-F private_no_mangle_fns`
+
+warning: lint `private_no_mangle_statics` has been removed: no longer a warning, `#[no_mangle]` statics always exported
+ |
+ = note: requested on the command line with `-F private_no_mangle_statics`
+
+error: const items should never be `#[no_mangle]`
+ --> $DIR/lint-unexported-no-mangle.rs:9:1
+ |
+LL | const FOO: u64 = 1;
+ | -----^^^^^^^^^^^^^^
+ | |
+ | help: try a static value: `pub static`
+ |
+ = note: requested on the command line with `-F no-mangle-const-items`
+
+error: const items should never be `#[no_mangle]`
+ --> $DIR/lint-unexported-no-mangle.rs:12:1
+ |
+LL | pub const PUB_FOO: u64 = 1;
+ | ---------^^^^^^^^^^^^^^^^^^
+ | |
+ | help: try a static value: `pub static`
+
+error: aborting due to 2 previous errors; 6 warnings emitted
+
diff --git a/tests/ui/lint/lint-unknown-feature-default.rs b/tests/ui/lint/lint-unknown-feature-default.rs
new file mode 100644
index 000000000..84a2e5a4b
--- /dev/null
+++ b/tests/ui/lint/lint-unknown-feature-default.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+// Tests the default for the unused_features lint
+
+#![allow(stable_features)]
+// FIXME(#44232) we should warn that this isn't used.
+#![feature(rust1)]
+
+fn main() {}
diff --git a/tests/ui/lint/lint-unknown-feature.rs b/tests/ui/lint/lint-unknown-feature.rs
new file mode 100644
index 000000000..1af8d4ff8
--- /dev/null
+++ b/tests/ui/lint/lint-unknown-feature.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+#![warn(unused_features)]
+
+#![allow(stable_features)]
+// FIXME(#44232) we should warn that this isn't used.
+#![feature(rust1)]
+
+fn main() {}
diff --git a/tests/ui/lint/lint-unknown-lint-cmdline.rs b/tests/ui/lint/lint-unknown-lint-cmdline.rs
new file mode 100644
index 000000000..7f3f55fba
--- /dev/null
+++ b/tests/ui/lint/lint-unknown-lint-cmdline.rs
@@ -0,0 +1,9 @@
+// compile-flags:-D bogus -D dead_cod
+
+// error-pattern:unknown lint: `bogus`
+// error-pattern:requested on the command line with `-D bogus`
+// error-pattern:unknown lint: `dead_cod`
+// error-pattern:requested on the command line with `-D dead_cod`
+// error-pattern:did you mean: `dead_code`
+
+fn main() { }
diff --git a/tests/ui/lint/lint-unknown-lint-cmdline.stderr b/tests/ui/lint/lint-unknown-lint-cmdline.stderr
new file mode 100644
index 000000000..3855d5527
--- /dev/null
+++ b/tests/ui/lint/lint-unknown-lint-cmdline.stderr
@@ -0,0 +1,21 @@
+error[E0602]: unknown lint: `bogus`
+ |
+ = note: requested on the command line with `-D bogus`
+
+error[E0602]: unknown lint: `dead_cod`
+ |
+ = help: did you mean: `dead_code`
+ = note: requested on the command line with `-D dead_cod`
+
+error[E0602]: unknown lint: `bogus`
+ |
+ = note: requested on the command line with `-D bogus`
+
+error[E0602]: unknown lint: `dead_cod`
+ |
+ = help: did you mean: `dead_code`
+ = note: requested on the command line with `-D dead_cod`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0602`.
diff --git a/tests/ui/lint/lint-unknown-lint.rs b/tests/ui/lint/lint-unknown-lint.rs
new file mode 100644
index 000000000..2d842d514
--- /dev/null
+++ b/tests/ui/lint/lint-unknown-lint.rs
@@ -0,0 +1,13 @@
+#![deny(unknown_lints)]
+
+#![allow(not_a_real_lint)] //~ ERROR unknown lint
+
+#![deny(dead_cod)] //~ ERROR unknown lint
+ //~| HELP did you mean
+ //~| SUGGESTION dead_code
+
+#![deny(rust_2018_idiots)] //~ ERROR unknown lint
+ //~| HELP did you mean
+ //~| SUGGESTION rust_2018_idioms
+
+fn main() {}
diff --git a/tests/ui/lint/lint-unknown-lint.stderr b/tests/ui/lint/lint-unknown-lint.stderr
new file mode 100644
index 000000000..0cb6b4957
--- /dev/null
+++ b/tests/ui/lint/lint-unknown-lint.stderr
@@ -0,0 +1,26 @@
+error: unknown lint: `not_a_real_lint`
+ --> $DIR/lint-unknown-lint.rs:3:10
+ |
+LL | #![allow(not_a_real_lint)]
+ | ^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unknown-lint.rs:1:9
+ |
+LL | #![deny(unknown_lints)]
+ | ^^^^^^^^^^^^^
+
+error: unknown lint: `dead_cod`
+ --> $DIR/lint-unknown-lint.rs:5:9
+ |
+LL | #![deny(dead_cod)]
+ | ^^^^^^^^ help: did you mean: `dead_code`
+
+error: unknown lint: `rust_2018_idiots`
+ --> $DIR/lint-unknown-lint.rs:9:9
+ |
+LL | #![deny(rust_2018_idiots)]
+ | ^^^^^^^^^^^^^^^^ help: did you mean: `rust_2018_idioms`
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/lint-unnecessary-import-braces.rs b/tests/ui/lint/lint-unnecessary-import-braces.rs
new file mode 100644
index 000000000..9a3398a87
--- /dev/null
+++ b/tests/ui/lint/lint-unnecessary-import-braces.rs
@@ -0,0 +1,11 @@
+#![deny(unused_import_braces)]
+
+use test::{A}; //~ ERROR braces around A is unnecessary
+
+mod test {
+ use test::{self}; // OK
+ use test::{self as rename}; // OK
+ pub struct A;
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-unnecessary-import-braces.stderr b/tests/ui/lint/lint-unnecessary-import-braces.stderr
new file mode 100644
index 000000000..2d289404d
--- /dev/null
+++ b/tests/ui/lint/lint-unnecessary-import-braces.stderr
@@ -0,0 +1,14 @@
+error: braces around A is unnecessary
+ --> $DIR/lint-unnecessary-import-braces.rs:3:1
+ |
+LL | use test::{A};
+ | ^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unnecessary-import-braces.rs:1:9
+ |
+LL | #![deny(unused_import_braces)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/lint-unnecessary-parens.fixed b/tests/ui/lint/lint-unnecessary-parens.fixed
new file mode 100644
index 000000000..9c144324f
--- /dev/null
+++ b/tests/ui/lint/lint-unnecessary-parens.fixed
@@ -0,0 +1,81 @@
+// run-rustfix
+
+#![deny(unused_parens)]
+#![allow(while_true)] // for rustfix
+
+#[derive(Eq, PartialEq)]
+struct X { y: bool }
+impl X {
+ fn foo(&self, conjunct: bool) -> bool { self.y && conjunct }
+}
+
+fn foo() -> isize {
+ return 1; //~ ERROR unnecessary parentheses around `return` value
+}
+fn bar(y: bool) -> X {
+ return X { y }; //~ ERROR unnecessary parentheses around `return` value
+}
+
+pub fn unused_parens_around_return_type() -> u32 { //~ ERROR unnecessary parentheses around type
+ panic!()
+}
+
+pub fn unused_parens_around_block_return() -> u32 {
+ let _foo = {
+ 5 //~ ERROR unnecessary parentheses around block return value
+ };
+ 5 //~ ERROR unnecessary parentheses around block return value
+}
+
+pub trait Trait {
+ fn test(&self);
+}
+
+pub fn passes_unused_parens_lint() -> &'static (dyn Trait) {
+ panic!()
+}
+
+macro_rules! baz {
+ ($($foo:expr),+) => {
+ ($($foo),*)
+ }
+}
+
+pub const CONST_ITEM: usize = 10; //~ ERROR unnecessary parentheses around assigned value
+pub static STATIC_ITEM: usize = 10; //~ ERROR unnecessary parentheses around assigned value
+
+fn main() {
+ foo();
+ bar(true); //~ ERROR unnecessary parentheses around function argument
+
+ if true {} //~ ERROR unnecessary parentheses around `if` condition
+ while true {} //~ ERROR unnecessary parentheses around `while` condition
+ match true { //~ ERROR unnecessary parentheses around `match` scrutinee expression
+ _ => {}
+ }
+ if let 1 = 1 {} //~ ERROR unnecessary parentheses around `let` scrutinee expression
+ while let 1 = 2 {} //~ ERROR unnecessary parentheses around `let` scrutinee expression
+ let v = X { y: false };
+ // struct lits needs parens, so these shouldn't warn.
+ if (v == X { y: true }) {}
+ if (X { y: true } == v) {}
+ if (X { y: false }.y) {}
+ // this shouldn't warn, because the parens are necessary to disambiguate let chains
+ if let true = (true && false) {}
+
+ while (X { y: false }.foo(true)) {}
+ while (true | X { y: false }.y) {}
+
+ match (X { y: false }) {
+ _ => {}
+ }
+
+ X { y: false }.foo(true); //~ ERROR unnecessary parentheses around method argument
+
+ let mut _a = 0; //~ ERROR unnecessary parentheses around assigned value
+ _a = 0; //~ ERROR unnecessary parentheses around assigned value
+ _a += 1; //~ ERROR unnecessary parentheses around assigned value
+
+ let _a = baz!(3, 4);
+ let _b = baz!(3);
+}
diff --git a/tests/ui/lint/lint-unnecessary-parens.rs b/tests/ui/lint/lint-unnecessary-parens.rs
new file mode 100644
index 000000000..4fd9cabb3
--- /dev/null
+++ b/tests/ui/lint/lint-unnecessary-parens.rs
@@ -0,0 +1,81 @@
+// run-rustfix
+
+#![deny(unused_parens)]
+#![allow(while_true)] // for rustfix
+
+#[derive(Eq, PartialEq)]
+struct X { y: bool }
+impl X {
+ fn foo(&self, conjunct: bool) -> bool { self.y && conjunct }
+}
+
+fn foo() -> isize {
+ return (1); //~ ERROR unnecessary parentheses around `return` value
+}
+fn bar(y: bool) -> X {
+ return (X { y }); //~ ERROR unnecessary parentheses around `return` value
+}
+
+pub fn unused_parens_around_return_type() -> (u32) { //~ ERROR unnecessary parentheses around type
+ panic!()
+}
+
+pub fn unused_parens_around_block_return() -> u32 {
+ let _foo = {
+ (5) //~ ERROR unnecessary parentheses around block return value
+ };
+ (5) //~ ERROR unnecessary parentheses around block return value
+}
+
+pub trait Trait {
+ fn test(&self);
+}
+
+pub fn passes_unused_parens_lint() -> &'static (dyn Trait) {
+ panic!()
+}
+
+macro_rules! baz {
+ ($($foo:expr),+) => {
+ ($($foo),*)
+ }
+}
+
+pub const CONST_ITEM: usize = (10); //~ ERROR unnecessary parentheses around assigned value
+pub static STATIC_ITEM: usize = (10); //~ ERROR unnecessary parentheses around assigned value
+
+fn main() {
+ foo();
+ bar((true)); //~ ERROR unnecessary parentheses around function argument
+
+ if (true) {} //~ ERROR unnecessary parentheses around `if` condition
+ while (true) {} //~ ERROR unnecessary parentheses around `while` condition
+ match (true) { //~ ERROR unnecessary parentheses around `match` scrutinee expression
+ _ => {}
+ }
+ if let 1 = (1) {} //~ ERROR unnecessary parentheses around `let` scrutinee expression
+ while let 1 = (2) {} //~ ERROR unnecessary parentheses around `let` scrutinee expression
+ let v = X { y: false };
+ // struct lits needs parens, so these shouldn't warn.
+ if (v == X { y: true }) {}
+ if (X { y: true } == v) {}
+ if (X { y: false }.y) {}
+ // this shouldn't warn, because the parens are necessary to disambiguate let chains
+ if let true = (true && false) {}
+
+ while (X { y: false }.foo(true)) {}
+ while (true | X { y: false }.y) {}
+
+ match (X { y: false }) {
+ _ => {}
+ }
+
+ X { y: false }.foo((true)); //~ ERROR unnecessary parentheses around method argument
+
+ let mut _a = (0); //~ ERROR unnecessary parentheses around assigned value
+ _a = (0); //~ ERROR unnecessary parentheses around assigned value
+ _a += (1); //~ ERROR unnecessary parentheses around assigned value
+
+ let _a = baz!(3, 4);
+ let _b = baz!(3);
+}
diff --git a/tests/ui/lint/lint-unnecessary-parens.stderr b/tests/ui/lint/lint-unnecessary-parens.stderr
new file mode 100644
index 000000000..e13620f06
--- /dev/null
+++ b/tests/ui/lint/lint-unnecessary-parens.stderr
@@ -0,0 +1,211 @@
+error: unnecessary parentheses around `return` value
+ --> $DIR/lint-unnecessary-parens.rs:13:12
+ |
+LL | return (1);
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unnecessary-parens.rs:3:9
+ |
+LL | #![deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - return (1);
+LL + return 1;
+ |
+
+error: unnecessary parentheses around `return` value
+ --> $DIR/lint-unnecessary-parens.rs:16:12
+ |
+LL | return (X { y });
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - return (X { y });
+LL + return X { y };
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-unnecessary-parens.rs:19:46
+ |
+LL | pub fn unused_parens_around_return_type() -> (u32) {
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - pub fn unused_parens_around_return_type() -> (u32) {
+LL + pub fn unused_parens_around_return_type() -> u32 {
+ |
+
+error: unnecessary parentheses around block return value
+ --> $DIR/lint-unnecessary-parens.rs:25:9
+ |
+LL | (5)
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - (5)
+LL + 5
+ |
+
+error: unnecessary parentheses around block return value
+ --> $DIR/lint-unnecessary-parens.rs:27:5
+ |
+LL | (5)
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - (5)
+LL + 5
+ |
+
+error: unnecessary parentheses around assigned value
+ --> $DIR/lint-unnecessary-parens.rs:44:31
+ |
+LL | pub const CONST_ITEM: usize = (10);
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - pub const CONST_ITEM: usize = (10);
+LL + pub const CONST_ITEM: usize = 10;
+ |
+
+error: unnecessary parentheses around assigned value
+ --> $DIR/lint-unnecessary-parens.rs:45:33
+ |
+LL | pub static STATIC_ITEM: usize = (10);
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - pub static STATIC_ITEM: usize = (10);
+LL + pub static STATIC_ITEM: usize = 10;
+ |
+
+error: unnecessary parentheses around function argument
+ --> $DIR/lint-unnecessary-parens.rs:49:9
+ |
+LL | bar((true));
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - bar((true));
+LL + bar(true);
+ |
+
+error: unnecessary parentheses around `if` condition
+ --> $DIR/lint-unnecessary-parens.rs:51:8
+ |
+LL | if (true) {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - if (true) {}
+LL + if true {}
+ |
+
+error: unnecessary parentheses around `while` condition
+ --> $DIR/lint-unnecessary-parens.rs:52:11
+ |
+LL | while (true) {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - while (true) {}
+LL + while true {}
+ |
+
+error: unnecessary parentheses around `match` scrutinee expression
+ --> $DIR/lint-unnecessary-parens.rs:53:11
+ |
+LL | match (true) {
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - match (true) {
+LL + match true {
+ |
+
+error: unnecessary parentheses around `let` scrutinee expression
+ --> $DIR/lint-unnecessary-parens.rs:56:16
+ |
+LL | if let 1 = (1) {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - if let 1 = (1) {}
+LL + if let 1 = 1 {}
+ |
+
+error: unnecessary parentheses around `let` scrutinee expression
+ --> $DIR/lint-unnecessary-parens.rs:57:19
+ |
+LL | while let 1 = (2) {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - while let 1 = (2) {}
+LL + while let 1 = 2 {}
+ |
+
+error: unnecessary parentheses around method argument
+ --> $DIR/lint-unnecessary-parens.rs:73:24
+ |
+LL | X { y: false }.foo((true));
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - X { y: false }.foo((true));
+LL + X { y: false }.foo(true);
+ |
+
+error: unnecessary parentheses around assigned value
+ --> $DIR/lint-unnecessary-parens.rs:75:18
+ |
+LL | let mut _a = (0);
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - let mut _a = (0);
+LL + let mut _a = 0;
+ |
+
+error: unnecessary parentheses around assigned value
+ --> $DIR/lint-unnecessary-parens.rs:76:10
+ |
+LL | _a = (0);
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - _a = (0);
+LL + _a = 0;
+ |
+
+error: unnecessary parentheses around assigned value
+ --> $DIR/lint-unnecessary-parens.rs:77:11
+ |
+LL | _a += (1);
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - _a += (1);
+LL + _a += 1;
+ |
+
+error: aborting due to 17 previous errors
+
diff --git a/tests/ui/lint/lint-unsafe-code.rs b/tests/ui/lint/lint-unsafe-code.rs
new file mode 100644
index 000000000..b72e4c3a9
--- /dev/null
+++ b/tests/ui/lint/lint-unsafe-code.rs
@@ -0,0 +1,130 @@
+#![allow(unused_unsafe)]
+#![allow(dead_code)]
+#![deny(unsafe_code)]
+
+struct Bar;
+struct Bar2;
+struct Bar3;
+
+#[allow(unsafe_code)]
+mod allowed_unsafe {
+ fn allowed() { unsafe {} }
+ unsafe fn also_allowed() {}
+ unsafe trait AllowedUnsafe { }
+ unsafe impl AllowedUnsafe for super::Bar {}
+ #[no_mangle] fn allowed2() {}
+ #[export_name = "foo"] fn allowed3() {}
+}
+
+macro_rules! unsafe_in_macro {
+ () => {{
+ #[no_mangle] fn foo() {} //~ ERROR: declaration of a `no_mangle` function
+ #[no_mangle] static FOO: u32 = 5; //~ ERROR: declaration of a `no_mangle` static
+ #[export_name = "bar"] fn bar() {}
+ //~^ ERROR: declaration of a function with `export_name`
+ #[export_name = "BAR"] static BAR: u32 = 5;
+ //~^ ERROR: declaration of a static with `export_name`
+ unsafe {} //~ ERROR: usage of an `unsafe` block
+ }}
+}
+
+#[no_mangle] fn foo() {} //~ ERROR: declaration of a `no_mangle` function
+#[no_mangle] static FOO: u32 = 5; //~ ERROR: declaration of a `no_mangle` static
+
+trait AssocFnTrait {
+ fn foo();
+}
+
+struct AssocFnFoo;
+
+impl AssocFnFoo {
+ #[no_mangle] fn foo() {} //~ ERROR: declaration of a `no_mangle` method
+}
+
+impl AssocFnTrait for AssocFnFoo {
+ #[no_mangle] fn foo() {} //~ ERROR: declaration of a `no_mangle` method
+}
+
+#[export_name = "bar"] fn bar() {} //~ ERROR: declaration of a function with `export_name`
+#[export_name = "BAR"] static BAR: u32 = 5; //~ ERROR: declaration of a static with `export_name`
+
+#[link_section = ".example_section"] fn uwu() {} //~ ERROR: declaration of a function with `link_section`
+#[link_section = ".example_section"] static UWU: u32 = 5; //~ ERROR: declaration of a static with `link_section`
+
+struct AssocFnBar;
+
+impl AssocFnBar {
+ #[export_name = "bar"] fn bar() {} //~ ERROR: declaration of a method with `export_name`
+}
+
+impl AssocFnTrait for AssocFnBar {
+ #[export_name = "bar"] fn foo() {} //~ ERROR: declaration of a method with `export_name`
+}
+
+unsafe fn baz() {} //~ ERROR: declaration of an `unsafe` function
+unsafe trait Foo {} //~ ERROR: declaration of an `unsafe` trait
+unsafe impl Foo for Bar {} //~ ERROR: implementation of an `unsafe` trait
+
+trait Baz {
+ unsafe fn baz(&self); //~ ERROR: declaration of an `unsafe` method
+ unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method
+ unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+impl Baz for Bar {
+ unsafe fn baz(&self) {} //~ ERROR: implementation of an `unsafe` method
+ unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+
+#[allow(unsafe_code)]
+trait A {
+ unsafe fn allowed_unsafe(&self);
+ unsafe fn allowed_unsafe_provided(&self) {}
+}
+
+#[allow(unsafe_code)]
+impl Baz for Bar2 {
+ unsafe fn baz(&self) {}
+ unsafe fn provided_override(&self) {}
+}
+
+impl Baz for Bar3 {
+ #[allow(unsafe_code)]
+ unsafe fn baz(&self) {}
+ unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+#[allow(unsafe_code)]
+unsafe trait B {
+ fn dummy(&self) {}
+}
+
+trait C {
+ #[allow(unsafe_code)]
+ unsafe fn baz(&self);
+ unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+impl C for Bar {
+ #[allow(unsafe_code)]
+ unsafe fn baz(&self) {}
+ unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+impl C for Bar2 {
+ unsafe fn baz(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+trait D {
+ #[allow(unsafe_code)]
+ unsafe fn unsafe_provided(&self) {}
+}
+
+impl D for Bar {}
+
+fn main() {
+ unsafe {} //~ ERROR: usage of an `unsafe` block
+
+ unsafe_in_macro!()
+}
diff --git a/tests/ui/lint/lint-unsafe-code.stderr b/tests/ui/lint/lint-unsafe-code.stderr
new file mode 100644
index 000000000..037f0a832
--- /dev/null
+++ b/tests/ui/lint/lint-unsafe-code.stderr
@@ -0,0 +1,224 @@
+error: declaration of a `no_mangle` function
+ --> $DIR/lint-unsafe-code.rs:31:1
+ |
+LL | #[no_mangle] fn foo() {}
+ | ^^^^^^^^^^^^
+ |
+ = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+note: the lint level is defined here
+ --> $DIR/lint-unsafe-code.rs:3:9
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: declaration of a `no_mangle` static
+ --> $DIR/lint-unsafe-code.rs:32:1
+ |
+LL | #[no_mangle] static FOO: u32 = 5;
+ | ^^^^^^^^^^^^
+ |
+ = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+
+error: declaration of a `no_mangle` method
+ --> $DIR/lint-unsafe-code.rs:41:5
+ |
+LL | #[no_mangle] fn foo() {}
+ | ^^^^^^^^^^^^
+ |
+ = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+
+error: declaration of a `no_mangle` method
+ --> $DIR/lint-unsafe-code.rs:45:5
+ |
+LL | #[no_mangle] fn foo() {}
+ | ^^^^^^^^^^^^
+ |
+ = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+
+error: declaration of a function with `export_name`
+ --> $DIR/lint-unsafe-code.rs:48:1
+ |
+LL | #[export_name = "bar"] fn bar() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+
+error: declaration of a static with `export_name`
+ --> $DIR/lint-unsafe-code.rs:49:1
+ |
+LL | #[export_name = "BAR"] static BAR: u32 = 5;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+
+error: declaration of a function with `link_section`
+ --> $DIR/lint-unsafe-code.rs:51:1
+ |
+LL | #[link_section = ".example_section"] fn uwu() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them
+
+error: declaration of a static with `link_section`
+ --> $DIR/lint-unsafe-code.rs:52:1
+ |
+LL | #[link_section = ".example_section"] static UWU: u32 = 5;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them
+
+error: declaration of a method with `export_name`
+ --> $DIR/lint-unsafe-code.rs:57:5
+ |
+LL | #[export_name = "bar"] fn bar() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+
+error: declaration of a method with `export_name`
+ --> $DIR/lint-unsafe-code.rs:61:5
+ |
+LL | #[export_name = "bar"] fn foo() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+
+error: declaration of an `unsafe` function
+ --> $DIR/lint-unsafe-code.rs:64:1
+ |
+LL | unsafe fn baz() {}
+ | ^^^^^^^^^^^^^^^^^^
+
+error: declaration of an `unsafe` trait
+ --> $DIR/lint-unsafe-code.rs:65:1
+ |
+LL | unsafe trait Foo {}
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: implementation of an `unsafe` trait
+ --> $DIR/lint-unsafe-code.rs:66:1
+ |
+LL | unsafe impl Foo for Bar {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: declaration of an `unsafe` method
+ --> $DIR/lint-unsafe-code.rs:69:5
+ |
+LL | unsafe fn baz(&self);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: implementation of an `unsafe` method
+ --> $DIR/lint-unsafe-code.rs:70:5
+ |
+LL | unsafe fn provided(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: implementation of an `unsafe` method
+ --> $DIR/lint-unsafe-code.rs:71:5
+ |
+LL | unsafe fn provided_override(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: implementation of an `unsafe` method
+ --> $DIR/lint-unsafe-code.rs:75:5
+ |
+LL | unsafe fn baz(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: implementation of an `unsafe` method
+ --> $DIR/lint-unsafe-code.rs:76:5
+ |
+LL | unsafe fn provided_override(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: implementation of an `unsafe` method
+ --> $DIR/lint-unsafe-code.rs:95:5
+ |
+LL | unsafe fn provided_override(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: implementation of an `unsafe` method
+ --> $DIR/lint-unsafe-code.rs:106:5
+ |
+LL | unsafe fn provided(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: implementation of an `unsafe` method
+ --> $DIR/lint-unsafe-code.rs:112:5
+ |
+LL | unsafe fn provided(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: implementation of an `unsafe` method
+ --> $DIR/lint-unsafe-code.rs:116:5
+ |
+LL | unsafe fn baz(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-unsafe-code.rs:127:5
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+
+error: declaration of a `no_mangle` function
+ --> $DIR/lint-unsafe-code.rs:21:9
+ |
+LL | #[no_mangle] fn foo() {}
+ | ^^^^^^^^^^^^
+...
+LL | unsafe_in_macro!()
+ | ------------------ in this macro invocation
+ |
+ = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+ = note: this error originates in the macro `unsafe_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: declaration of a `no_mangle` static
+ --> $DIR/lint-unsafe-code.rs:22:9
+ |
+LL | #[no_mangle] static FOO: u32 = 5;
+ | ^^^^^^^^^^^^
+...
+LL | unsafe_in_macro!()
+ | ------------------ in this macro invocation
+ |
+ = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+ = note: this error originates in the macro `unsafe_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: declaration of a function with `export_name`
+ --> $DIR/lint-unsafe-code.rs:23:9
+ |
+LL | #[export_name = "bar"] fn bar() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | unsafe_in_macro!()
+ | ------------------ in this macro invocation
+ |
+ = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+ = note: this error originates in the macro `unsafe_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: declaration of a static with `export_name`
+ --> $DIR/lint-unsafe-code.rs:25:9
+ |
+LL | #[export_name = "BAR"] static BAR: u32 = 5;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | unsafe_in_macro!()
+ | ------------------ in this macro invocation
+ |
+ = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
+ = note: this error originates in the macro `unsafe_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-unsafe-code.rs:27:9
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+...
+LL | unsafe_in_macro!()
+ | ------------------ in this macro invocation
+ |
+ = note: this error originates in the macro `unsafe_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 28 previous errors
+
diff --git a/tests/ui/lint/lint-uppercase-variables.rs b/tests/ui/lint/lint-uppercase-variables.rs
new file mode 100644
index 000000000..59dba536f
--- /dev/null
+++ b/tests/ui/lint/lint-uppercase-variables.rs
@@ -0,0 +1,41 @@
+#![warn(unused)]
+#![allow(dead_code)]
+#![deny(non_snake_case)]
+
+mod foo {
+ pub enum Foo { Foo }
+}
+
+struct Something {
+ X: usize //~ ERROR structure field `X` should have a snake case name
+}
+
+fn test(Xx: usize) { //~ ERROR variable `Xx` should have a snake case name
+ println!("{}", Xx);
+}
+
+fn main() {
+ let Test: usize = 0; //~ ERROR variable `Test` should have a snake case name
+ println!("{}", Test);
+
+ match foo::Foo::Foo {
+ Foo => {}
+ //~^ ERROR variable `Foo` should have a snake case name
+ //~^^ ERROR `Foo` is named the same as one of the variants of the type `foo::Foo`
+ //~^^^ WARN unused variable: `Foo`
+ }
+
+ let Foo = foo::Foo::Foo;
+ //~^ ERROR variable `Foo` should have a snake case name
+ //~^^ ERROR `Foo` is named the same as one of the variants of the type `foo::Foo`
+ //~^^^ WARN unused variable: `Foo`
+
+ fn in_param(Foo: foo::Foo) {}
+ //~^ ERROR variable `Foo` should have a snake case name
+ //~^^ ERROR `Foo` is named the same as one of the variants of the type `foo::Foo`
+ //~^^^ WARN unused variable: `Foo`
+
+ test(1);
+
+ let _ = Something { X: 0 };
+}
diff --git a/tests/ui/lint/lint-uppercase-variables.stderr b/tests/ui/lint/lint-uppercase-variables.stderr
new file mode 100644
index 000000000..42ec9364b
--- /dev/null
+++ b/tests/ui/lint/lint-uppercase-variables.stderr
@@ -0,0 +1,90 @@
+error[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `foo::Foo`
+ --> $DIR/lint-uppercase-variables.rs:22:9
+ |
+LL | Foo => {}
+ | ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo`
+ |
+ = note: `#[deny(bindings_with_variant_name)]` on by default
+
+error[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `foo::Foo`
+ --> $DIR/lint-uppercase-variables.rs:28:9
+ |
+LL | let Foo = foo::Foo::Foo;
+ | ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo`
+
+error[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `foo::Foo`
+ --> $DIR/lint-uppercase-variables.rs:33:17
+ |
+LL | fn in_param(Foo: foo::Foo) {}
+ | ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo`
+
+warning: unused variable: `Foo`
+ --> $DIR/lint-uppercase-variables.rs:22:9
+ |
+LL | Foo => {}
+ | ^^^ help: if this is intentional, prefix it with an underscore: `_Foo`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-uppercase-variables.rs:1:9
+ |
+LL | #![warn(unused)]
+ | ^^^^^^
+ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
+
+warning: unused variable: `Foo`
+ --> $DIR/lint-uppercase-variables.rs:28:9
+ |
+LL | let Foo = foo::Foo::Foo;
+ | ^^^ help: if this is intentional, prefix it with an underscore: `_Foo`
+
+warning: unused variable: `Foo`
+ --> $DIR/lint-uppercase-variables.rs:33:17
+ |
+LL | fn in_param(Foo: foo::Foo) {}
+ | ^^^ help: if this is intentional, prefix it with an underscore: `_Foo`
+
+error: structure field `X` should have a snake case name
+ --> $DIR/lint-uppercase-variables.rs:10:5
+ |
+LL | X: usize
+ | ^ help: convert the identifier to snake case (notice the capitalization): `x`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-uppercase-variables.rs:3:9
+ |
+LL | #![deny(non_snake_case)]
+ | ^^^^^^^^^^^^^^
+
+error: variable `Xx` should have a snake case name
+ --> $DIR/lint-uppercase-variables.rs:13:9
+ |
+LL | fn test(Xx: usize) {
+ | ^^ help: convert the identifier to snake case (notice the capitalization): `xx`
+
+error: variable `Test` should have a snake case name
+ --> $DIR/lint-uppercase-variables.rs:18:9
+ |
+LL | let Test: usize = 0;
+ | ^^^^ help: convert the identifier to snake case: `test`
+
+error: variable `Foo` should have a snake case name
+ --> $DIR/lint-uppercase-variables.rs:22:9
+ |
+LL | Foo => {}
+ | ^^^ help: convert the identifier to snake case (notice the capitalization): `foo`
+
+error: variable `Foo` should have a snake case name
+ --> $DIR/lint-uppercase-variables.rs:28:9
+ |
+LL | let Foo = foo::Foo::Foo;
+ | ^^^ help: convert the identifier to snake case (notice the capitalization): `foo`
+
+error: variable `Foo` should have a snake case name
+ --> $DIR/lint-uppercase-variables.rs:33:17
+ |
+LL | fn in_param(Foo: foo::Foo) {}
+ | ^^^ help: convert the identifier to snake case (notice the capitalization): `foo`
+
+error: aborting due to 9 previous errors; 3 warnings emitted
+
+For more information about this error, try `rustc --explain E0170`.
diff --git a/tests/ui/lint/lint_pre_expansion_extern_module_aux.rs b/tests/ui/lint/lint_pre_expansion_extern_module_aux.rs
new file mode 100644
index 000000000..71dec40ea
--- /dev/null
+++ b/tests/ui/lint/lint_pre_expansion_extern_module_aux.rs
@@ -0,0 +1,3 @@
+// ignore-test: not a test
+
+pub fn try() {}
diff --git a/tests/ui/lint/lints-in-foreign-macros.rs b/tests/ui/lint/lints-in-foreign-macros.rs
new file mode 100644
index 000000000..1e8b6788a
--- /dev/null
+++ b/tests/ui/lint/lints-in-foreign-macros.rs
@@ -0,0 +1,21 @@
+// aux-build:lints-in-foreign-macros.rs
+// check-pass
+
+#![warn(unused_imports)] //~ missing documentation for the crate [missing_docs]
+#![warn(missing_docs)]
+
+#[macro_use]
+extern crate lints_in_foreign_macros;
+
+macro_rules! foo {
+ () => {use std::string::ToString;} //~ WARN: unused import
+}
+
+mod a { foo!(); }
+mod b { bar!(); }
+mod c { baz!(use std::string::ToString;); } //~ WARN: unused import
+mod d { baz2!(use std::string::ToString;); } //~ WARN: unused import
+baz!(pub fn undocumented() {}); //~ WARN: missing documentation for a function
+baz2!(pub fn undocumented2() {}); //~ WARN: missing documentation for a function
+
+fn main() {}
diff --git a/tests/ui/lint/lints-in-foreign-macros.stderr b/tests/ui/lint/lints-in-foreign-macros.stderr
new file mode 100644
index 000000000..f20e16287
--- /dev/null
+++ b/tests/ui/lint/lints-in-foreign-macros.stderr
@@ -0,0 +1,60 @@
+warning: unused import: `std::string::ToString`
+ --> $DIR/lints-in-foreign-macros.rs:11:16
+ |
+LL | () => {use std::string::ToString;}
+ | ^^^^^^^^^^^^^^^^^^^^^
+...
+LL | mod a { foo!(); }
+ | ------ in this macro invocation
+ |
+note: the lint level is defined here
+ --> $DIR/lints-in-foreign-macros.rs:4:9
+ |
+LL | #![warn(unused_imports)]
+ | ^^^^^^^^^^^^^^
+ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: unused import: `std::string::ToString`
+ --> $DIR/lints-in-foreign-macros.rs:16:18
+ |
+LL | mod c { baz!(use std::string::ToString;); }
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused import: `std::string::ToString`
+ --> $DIR/lints-in-foreign-macros.rs:17:19
+ |
+LL | mod d { baz2!(use std::string::ToString;); }
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: missing documentation for the crate
+ --> $DIR/lints-in-foreign-macros.rs:4:1
+ |
+LL | / #![warn(unused_imports)]
+LL | | #![warn(missing_docs)]
+LL | |
+LL | | #[macro_use]
+... |
+LL | |
+LL | | fn main() {}
+ | |____________^
+ |
+note: the lint level is defined here
+ --> $DIR/lints-in-foreign-macros.rs:5:9
+ |
+LL | #![warn(missing_docs)]
+ | ^^^^^^^^^^^^
+
+warning: missing documentation for a function
+ --> $DIR/lints-in-foreign-macros.rs:18:6
+ |
+LL | baz!(pub fn undocumented() {});
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: missing documentation for a function
+ --> $DIR/lints-in-foreign-macros.rs:19:7
+ |
+LL | baz2!(pub fn undocumented2() {});
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+warning: 6 warnings emitted
+
diff --git a/tests/ui/lint/missing-doc-private-macro.rs b/tests/ui/lint/missing-doc-private-macro.rs
new file mode 100644
index 000000000..0d4332ed0
--- /dev/null
+++ b/tests/ui/lint/missing-doc-private-macro.rs
@@ -0,0 +1,43 @@
+// Checks that undocumented private macros will not generate `missing_docs`
+// lints, but public ones will.
+//
+// This is a regression test for issue #57569
+#![deny(missing_docs)]
+#![feature(decl_macro)]
+//! Empty documentation.
+
+macro new_style_private_macro {
+ () => ()
+}
+
+pub(crate) macro new_style_crate_macro {
+ () => ()
+}
+
+macro_rules! old_style_private_macro {
+ () => ()
+}
+
+mod submodule {
+ pub macro new_style_macro_in_private_module {
+ () => ()
+ }
+
+ macro_rules! old_style_mod_private_macro {
+ () => ()
+ }
+
+ #[macro_export]
+ macro_rules! exported_to_top_level {
+ //~^ ERROR missing documentation for a macro
+ () => ()
+ }
+}
+
+pub macro top_level_pub_macro {
+ //~^ ERROR missing documentation for a macro
+ () => ()
+}
+
+/// Empty documentation.
+pub fn main() {}
diff --git a/tests/ui/lint/missing-doc-private-macro.stderr b/tests/ui/lint/missing-doc-private-macro.stderr
new file mode 100644
index 000000000..979b007d0
--- /dev/null
+++ b/tests/ui/lint/missing-doc-private-macro.stderr
@@ -0,0 +1,20 @@
+error: missing documentation for a macro
+ --> $DIR/missing-doc-private-macro.rs:31:5
+ |
+LL | macro_rules! exported_to_top_level {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/missing-doc-private-macro.rs:5:9
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a macro
+ --> $DIR/missing-doc-private-macro.rs:37:1
+ |
+LL | pub macro top_level_pub_macro {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/must_not_suspend/boxed.rs b/tests/ui/lint/must_not_suspend/boxed.rs
new file mode 100644
index 000000000..1f823fc55
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/boxed.rs
@@ -0,0 +1,25 @@
+// edition:2018
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend = "You gotta use Umm's, ya know?"]
+struct Umm {
+ i: i64
+}
+
+
+fn bar() -> Box<Umm> {
+ Box::new(Umm {
+ i: 1
+ })
+}
+
+async fn other() {}
+
+pub async fn uhoh() {
+ let _guard = bar(); //~ ERROR boxed `Umm` held across
+ other().await;
+}
+
+fn main() {
+}
diff --git a/tests/ui/lint/must_not_suspend/boxed.stderr b/tests/ui/lint/must_not_suspend/boxed.stderr
new file mode 100644
index 000000000..9efc7b069
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/boxed.stderr
@@ -0,0 +1,26 @@
+error: boxed `Umm` held across a suspend point, but should not be
+ --> $DIR/boxed.rs:20:9
+ |
+LL | let _guard = bar();
+ | ^^^^^^
+LL | other().await;
+ | ------ the value is held across this suspend point
+ |
+note: You gotta use Umm's, ya know?
+ --> $DIR/boxed.rs:20:9
+ |
+LL | let _guard = bar();
+ | ^^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+ --> $DIR/boxed.rs:20:9
+ |
+LL | let _guard = bar();
+ | ^^^^^^
+note: the lint level is defined here
+ --> $DIR/boxed.rs:3:9
+ |
+LL | #![deny(must_not_suspend)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/must_not_suspend/dedup.rs b/tests/ui/lint/must_not_suspend/dedup.rs
new file mode 100644
index 000000000..81a08579b
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/dedup.rs
@@ -0,0 +1,20 @@
+// edition:2018
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend]
+struct No {}
+
+async fn shushspend() {}
+
+async fn wheeee<T>(t: T) {
+ shushspend().await;
+ drop(t);
+}
+
+async fn yes() {
+ wheeee(&No {}).await; //~ ERROR `No` held across
+}
+
+fn main() {
+}
diff --git a/tests/ui/lint/must_not_suspend/dedup.stderr b/tests/ui/lint/must_not_suspend/dedup.stderr
new file mode 100644
index 000000000..f8978ba57
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/dedup.stderr
@@ -0,0 +1,19 @@
+error: `No` held across a suspend point, but should not be
+ --> $DIR/dedup.rs:16:13
+ |
+LL | wheeee(&No {}).await;
+ | ^^^^^ ------ the value is held across this suspend point
+ |
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+ --> $DIR/dedup.rs:16:13
+ |
+LL | wheeee(&No {}).await;
+ | ^^^^^
+note: the lint level is defined here
+ --> $DIR/dedup.rs:3:9
+ |
+LL | #![deny(must_not_suspend)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/must_not_suspend/feature-gate-must_not_suspend.rs b/tests/ui/lint/must_not_suspend/feature-gate-must_not_suspend.rs
new file mode 100644
index 000000000..1554408c1
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/feature-gate-must_not_suspend.rs
@@ -0,0 +1,9 @@
+// edition:2018
+
+#[must_not_suspend = "You gotta use Umm's, ya know?"] //~ ERROR the `#[must_not_suspend]`
+struct Umm {
+ _i: i64
+}
+
+fn main() {
+}
diff --git a/tests/ui/lint/must_not_suspend/feature-gate-must_not_suspend.stderr b/tests/ui/lint/must_not_suspend/feature-gate-must_not_suspend.stderr
new file mode 100644
index 000000000..ab20a8be8
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/feature-gate-must_not_suspend.stderr
@@ -0,0 +1,12 @@
+error[E0658]: the `#[must_not_suspend]` attribute is an experimental feature
+ --> $DIR/feature-gate-must_not_suspend.rs:3:1
+ |
+LL | #[must_not_suspend = "You gotta use Umm's, ya know?"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information
+ = help: add `#![feature(must_not_suspend)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/lint/must_not_suspend/gated.rs b/tests/ui/lint/must_not_suspend/gated.rs
new file mode 100644
index 000000000..b73a76555
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/gated.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+// edition:2018
+#![deny(must_not_suspend)]
+//~^ WARNING unknown lint: `must_not_suspend`
+//~| WARNING unknown lint: `must_not_suspend`
+//~| WARNING unknown lint: `must_not_suspend`
+
+async fn other() {}
+
+pub async fn uhoh(m: std::sync::Mutex<()>) {
+ let _guard = m.lock().unwrap();
+ other().await;
+}
+
+fn main() {
+}
diff --git a/tests/ui/lint/must_not_suspend/gated.stderr b/tests/ui/lint/must_not_suspend/gated.stderr
new file mode 100644
index 000000000..64de1ebea
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/gated.stderr
@@ -0,0 +1,33 @@
+warning: unknown lint: `must_not_suspend`
+ --> $DIR/gated.rs:4:1
+ |
+LL | #![deny(must_not_suspend)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the `must_not_suspend` lint is unstable
+ = note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information
+ = help: add `#![feature(must_not_suspend)]` to the crate attributes to enable
+ = note: `#[warn(unknown_lints)]` on by default
+
+warning: unknown lint: `must_not_suspend`
+ --> $DIR/gated.rs:4:1
+ |
+LL | #![deny(must_not_suspend)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the `must_not_suspend` lint is unstable
+ = note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information
+ = help: add `#![feature(must_not_suspend)]` to the crate attributes to enable
+
+warning: unknown lint: `must_not_suspend`
+ --> $DIR/gated.rs:4:1
+ |
+LL | #![deny(must_not_suspend)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the `must_not_suspend` lint is unstable
+ = note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information
+ = help: add `#![feature(must_not_suspend)]` to the crate attributes to enable
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/lint/must_not_suspend/generic.rs b/tests/ui/lint/must_not_suspend/generic.rs
new file mode 100644
index 000000000..b3effa020
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/generic.rs
@@ -0,0 +1,20 @@
+// edition:2018
+// run-pass
+//
+// this test shows a case where the lint doesn't fire in generic code
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend]
+struct No {}
+
+async fn shushspend() {}
+
+async fn wheeee<T>(t: T) {
+ shushspend().await;
+ drop(t);
+}
+
+fn main() {
+ let _fut = wheeee(No {});
+}
diff --git a/tests/ui/lint/must_not_suspend/handled.rs b/tests/ui/lint/must_not_suspend/handled.rs
new file mode 100644
index 000000000..8714be644
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/handled.rs
@@ -0,0 +1,28 @@
+// edition:2018
+// run-pass
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend = "You gotta use Umm's, ya know?"]
+struct Umm {
+ _i: i64
+}
+
+
+fn bar() -> Umm {
+ Umm {
+ _i: 1
+ }
+}
+
+async fn other() {}
+
+pub async fn uhoh() {
+ {
+ let _guard = bar();
+ }
+ other().await;
+}
+
+fn main() {
+}
diff --git a/tests/ui/lint/must_not_suspend/issue-89562.rs b/tests/ui/lint/must_not_suspend/issue-89562.rs
new file mode 100644
index 000000000..acdb36fcd
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/issue-89562.rs
@@ -0,0 +1,19 @@
+// edition:2018
+// run-pass
+
+use std::sync::Mutex;
+
+// Copied from the issue. Allow-by-default for now, so run-pass
+pub async fn foo() {
+ let foo = Mutex::new(1);
+ let lock = foo.lock().unwrap();
+
+ // Prevent mutex lock being held across `.await` point.
+ drop(lock);
+
+ bar().await;
+}
+
+async fn bar() {}
+
+fn main() {}
diff --git a/tests/ui/lint/must_not_suspend/mutex.rs b/tests/ui/lint/must_not_suspend/mutex.rs
new file mode 100644
index 000000000..7bb895e7d
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/mutex.rs
@@ -0,0 +1,13 @@
+// edition:2018
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+async fn other() {}
+
+pub async fn uhoh(m: std::sync::Mutex<()>) {
+ let _guard = m.lock().unwrap(); //~ ERROR `MutexGuard` held across
+ other().await;
+}
+
+fn main() {
+}
diff --git a/tests/ui/lint/must_not_suspend/mutex.stderr b/tests/ui/lint/must_not_suspend/mutex.stderr
new file mode 100644
index 000000000..c251cb845
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/mutex.stderr
@@ -0,0 +1,26 @@
+error: `MutexGuard` held across a suspend point, but should not be
+ --> $DIR/mutex.rs:8:9
+ |
+LL | let _guard = m.lock().unwrap();
+ | ^^^^^^
+LL | other().await;
+ | ------ the value is held across this suspend point
+ |
+note: holding a MutexGuard across suspend points can cause deadlocks, delays, and cause Futures to not implement `Send`
+ --> $DIR/mutex.rs:8:9
+ |
+LL | let _guard = m.lock().unwrap();
+ | ^^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+ --> $DIR/mutex.rs:8:9
+ |
+LL | let _guard = m.lock().unwrap();
+ | ^^^^^^
+note: the lint level is defined here
+ --> $DIR/mutex.rs:3:9
+ |
+LL | #![deny(must_not_suspend)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/must_not_suspend/other_items.rs b/tests/ui/lint/must_not_suspend/other_items.rs
new file mode 100644
index 000000000..5aa1abb14
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/other_items.rs
@@ -0,0 +1,8 @@
+// edition:2018
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend] //~ ERROR attribute should be
+mod inner {}
+
+fn main() {}
diff --git a/tests/ui/lint/must_not_suspend/other_items.stderr b/tests/ui/lint/must_not_suspend/other_items.stderr
new file mode 100644
index 000000000..41c889692
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/other_items.stderr
@@ -0,0 +1,10 @@
+error: `must_not_suspend` attribute should be applied to a struct, enum, or trait
+ --> $DIR/other_items.rs:5:1
+ |
+LL | #[must_not_suspend]
+ | ^^^^^^^^^^^^^^^^^^^
+LL | mod inner {}
+ | ------------ is not a struct, enum, or trait
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/must_not_suspend/ref-drop-tracking.rs b/tests/ui/lint/must_not_suspend/ref-drop-tracking.rs
new file mode 100644
index 000000000..1bc4a3812
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/ref-drop-tracking.rs
@@ -0,0 +1,30 @@
+// edition:2018
+// compile-flags: -Zdrop-tracking
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend = "You gotta use Umm's, ya know?"]
+struct Umm {
+ i: i64
+}
+
+struct Bar {
+ u: Umm,
+}
+
+async fn other() {}
+
+impl Bar {
+ async fn uhoh(&mut self) {
+ let guard = &mut self.u; //~ ERROR `Umm` held across
+
+ other().await;
+
+ *guard = Umm {
+ i: 2
+ }
+ }
+}
+
+fn main() {
+}
diff --git a/tests/ui/lint/must_not_suspend/ref-drop-tracking.stderr b/tests/ui/lint/must_not_suspend/ref-drop-tracking.stderr
new file mode 100644
index 000000000..180e187c1
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/ref-drop-tracking.stderr
@@ -0,0 +1,27 @@
+error: reference to `Umm` held across a suspend point, but should not be
+ --> $DIR/ref-drop-tracking.rs:19:13
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^
+LL |
+LL | other().await;
+ | ------ the value is held across this suspend point
+ |
+note: You gotta use Umm's, ya know?
+ --> $DIR/ref-drop-tracking.rs:19:13
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+ --> $DIR/ref-drop-tracking.rs:19:13
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^
+note: the lint level is defined here
+ --> $DIR/ref-drop-tracking.rs:4:9
+ |
+LL | #![deny(must_not_suspend)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/must_not_suspend/ref.drop_tracking.stderr b/tests/ui/lint/must_not_suspend/ref.drop_tracking.stderr
new file mode 100644
index 000000000..abf76711b
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/ref.drop_tracking.stderr
@@ -0,0 +1,27 @@
+error: reference to `Umm` held across a suspend point, but should not be
+ --> $DIR/ref.rs:21:13
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^
+LL |
+LL | other().await;
+ | ------ the value is held across this suspend point
+ |
+note: You gotta use Umm's, ya know?
+ --> $DIR/ref.rs:21:13
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+ --> $DIR/ref.rs:21:13
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^
+note: the lint level is defined here
+ --> $DIR/ref.rs:6:9
+ |
+LL | #![deny(must_not_suspend)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr b/tests/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr
new file mode 100644
index 000000000..41ac09ea7
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr
@@ -0,0 +1,27 @@
+error: `Umm` held across a suspend point, but should not be
+ --> $DIR/ref.rs:21:26
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^^
+LL |
+LL | other().await;
+ | ------ the value is held across this suspend point
+ |
+note: You gotta use Umm's, ya know?
+ --> $DIR/ref.rs:21:26
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+ --> $DIR/ref.rs:21:26
+ |
+LL | let guard = &mut self.u;
+ | ^^^^^^
+note: the lint level is defined here
+ --> $DIR/ref.rs:6:9
+ |
+LL | #![deny(must_not_suspend)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/must_not_suspend/ref.rs b/tests/ui/lint/must_not_suspend/ref.rs
new file mode 100644
index 000000000..f6b23746f
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/ref.rs
@@ -0,0 +1,29 @@
+// edition:2018
+// revisions: no_drop_tracking drop_tracking
+// [drop_tracking] compile-flags: -Zdrop-tracking=yes
+// [no_drop_tracking] compile-flags: -Zdrop-tracking=no
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend = "You gotta use Umm's, ya know?"]
+struct Umm {
+ i: i64,
+}
+
+struct Bar {
+ u: Umm,
+}
+
+async fn other() {}
+
+impl Bar {
+ async fn uhoh(&mut self) {
+ let guard = &mut self.u; //~ ERROR `Umm` held across
+
+ other().await;
+
+ *guard = Umm { i: 2 }
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/must_not_suspend/return.rs b/tests/ui/lint/must_not_suspend/return.rs
new file mode 100644
index 000000000..5b1fa5e27
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/return.rs
@@ -0,0 +1,9 @@
+// edition:2018
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend] //~ ERROR attribute should be
+fn foo() -> i32 {
+ 0
+}
+fn main() {}
diff --git a/tests/ui/lint/must_not_suspend/return.stderr b/tests/ui/lint/must_not_suspend/return.stderr
new file mode 100644
index 000000000..fdada85eb
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/return.stderr
@@ -0,0 +1,12 @@
+error: `must_not_suspend` attribute should be applied to a struct, enum, or trait
+ --> $DIR/return.rs:5:1
+ |
+LL | #[must_not_suspend]
+ | ^^^^^^^^^^^^^^^^^^^
+LL | / fn foo() -> i32 {
+LL | | 0
+LL | | }
+ | |_- is not a struct, enum, or trait
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/must_not_suspend/trait.rs b/tests/ui/lint/must_not_suspend/trait.rs
new file mode 100644
index 000000000..6c911cb4b
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/trait.rs
@@ -0,0 +1,28 @@
+// edition:2018
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend]
+trait Wow {}
+
+impl Wow for i32 {}
+
+fn r#impl() -> impl Wow {
+ 1
+}
+
+fn r#dyn() -> Box<dyn Wow> {
+ Box::new(1)
+}
+
+async fn other() {}
+
+pub async fn uhoh() {
+ let _guard1 = r#impl(); //~ ERROR implementer of `Wow` held across
+ let _guard2 = r#dyn(); //~ ERROR boxed `Wow` trait object held across
+
+ other().await;
+}
+
+fn main() {
+}
diff --git a/tests/ui/lint/must_not_suspend/trait.stderr b/tests/ui/lint/must_not_suspend/trait.stderr
new file mode 100644
index 000000000..d64d25aae
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/trait.stderr
@@ -0,0 +1,37 @@
+error: implementer of `Wow` held across a suspend point, but should not be
+ --> $DIR/trait.rs:21:9
+ |
+LL | let _guard1 = r#impl();
+ | ^^^^^^^
+...
+LL | other().await;
+ | ------ the value is held across this suspend point
+ |
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+ --> $DIR/trait.rs:21:9
+ |
+LL | let _guard1 = r#impl();
+ | ^^^^^^^
+note: the lint level is defined here
+ --> $DIR/trait.rs:3:9
+ |
+LL | #![deny(must_not_suspend)]
+ | ^^^^^^^^^^^^^^^^
+
+error: boxed `Wow` trait object held across a suspend point, but should not be
+ --> $DIR/trait.rs:22:9
+ |
+LL | let _guard2 = r#dyn();
+ | ^^^^^^^
+LL |
+LL | other().await;
+ | ------ the value is held across this suspend point
+ |
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+ --> $DIR/trait.rs:22:9
+ |
+LL | let _guard2 = r#dyn();
+ | ^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/must_not_suspend/tuple-mismatch.rs b/tests/ui/lint/must_not_suspend/tuple-mismatch.rs
new file mode 100644
index 000000000..c7e14e425
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/tuple-mismatch.rs
@@ -0,0 +1,9 @@
+#![feature(generators)]
+
+fn main() {
+ let _generator = || {
+ yield ((), ((), ()));
+ yield ((), ());
+ //~^ ERROR mismatched types
+ };
+}
diff --git a/tests/ui/lint/must_not_suspend/tuple-mismatch.stderr b/tests/ui/lint/must_not_suspend/tuple-mismatch.stderr
new file mode 100644
index 000000000..cca8cd9bd
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/tuple-mismatch.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+ --> $DIR/tuple-mismatch.rs:6:20
+ |
+LL | yield ((), ());
+ | ^^ expected tuple, found `()`
+ |
+ = note: expected tuple `((), ())`
+ found unit type `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/lint/must_not_suspend/unit.rs b/tests/ui/lint/must_not_suspend/unit.rs
new file mode 100644
index 000000000..d3a19f704
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/unit.rs
@@ -0,0 +1,25 @@
+// edition:2018
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend = "You gotta use Umm's, ya know?"]
+struct Umm {
+ i: i64
+}
+
+
+fn bar() -> Umm {
+ Umm {
+ i: 1
+ }
+}
+
+async fn other() {}
+
+pub async fn uhoh() {
+ let _guard = bar(); //~ ERROR `Umm` held across
+ other().await;
+}
+
+fn main() {
+}
diff --git a/tests/ui/lint/must_not_suspend/unit.stderr b/tests/ui/lint/must_not_suspend/unit.stderr
new file mode 100644
index 000000000..c967dbac5
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/unit.stderr
@@ -0,0 +1,26 @@
+error: `Umm` held across a suspend point, but should not be
+ --> $DIR/unit.rs:20:9
+ |
+LL | let _guard = bar();
+ | ^^^^^^
+LL | other().await;
+ | ------ the value is held across this suspend point
+ |
+note: You gotta use Umm's, ya know?
+ --> $DIR/unit.rs:20:9
+ |
+LL | let _guard = bar();
+ | ^^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+ --> $DIR/unit.rs:20:9
+ |
+LL | let _guard = bar();
+ | ^^^^^^
+note: the lint level is defined here
+ --> $DIR/unit.rs:3:9
+ |
+LL | #![deny(must_not_suspend)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/must_not_suspend/warn.rs b/tests/ui/lint/must_not_suspend/warn.rs
new file mode 100644
index 000000000..7fdea66a2
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/warn.rs
@@ -0,0 +1,26 @@
+// edition:2018
+// run-pass
+#![feature(must_not_suspend)]
+#![warn(must_not_suspend)]
+
+#[must_not_suspend = "You gotta use Umm's, ya know?"]
+struct Umm {
+ _i: i64
+}
+
+
+fn bar() -> Umm {
+ Umm {
+ _i: 1
+ }
+}
+
+async fn other() {}
+
+pub async fn uhoh() {
+ let _guard = bar(); //~ WARNING `Umm` held across
+ other().await;
+}
+
+fn main() {
+}
diff --git a/tests/ui/lint/must_not_suspend/warn.stderr b/tests/ui/lint/must_not_suspend/warn.stderr
new file mode 100644
index 000000000..fe551c652
--- /dev/null
+++ b/tests/ui/lint/must_not_suspend/warn.stderr
@@ -0,0 +1,26 @@
+warning: `Umm` held across a suspend point, but should not be
+ --> $DIR/warn.rs:21:9
+ |
+LL | let _guard = bar();
+ | ^^^^^^
+LL | other().await;
+ | ------ the value is held across this suspend point
+ |
+note: You gotta use Umm's, ya know?
+ --> $DIR/warn.rs:21:9
+ |
+LL | let _guard = bar();
+ | ^^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+ --> $DIR/warn.rs:21:9
+ |
+LL | let _guard = bar();
+ | ^^^^^^
+note: the lint level is defined here
+ --> $DIR/warn.rs:4:9
+ |
+LL | #![warn(must_not_suspend)]
+ | ^^^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/no-coverage.rs b/tests/ui/lint/no-coverage.rs
new file mode 100644
index 000000000..ff24c12b2
--- /dev/null
+++ b/tests/ui/lint/no-coverage.rs
@@ -0,0 +1,55 @@
+#![feature(extern_types)]
+#![feature(no_coverage)]
+#![feature(type_alias_impl_trait)]
+#![warn(unused_attributes)]
+#![no_coverage]
+//~^ WARN: `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly
+
+#[no_coverage]
+//~^ WARN: `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly
+trait Trait {
+ #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code
+ const X: u32;
+
+ #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code
+ type T;
+
+ type U;
+}
+
+#[no_coverage]
+//~^ WARN: `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly
+impl Trait for () {
+ const X: u32 = 0;
+
+ #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code
+ type T = Self;
+
+ #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code
+ type U = impl Trait; //~ ERROR unconstrained opaque type
+}
+
+extern "C" {
+ #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code
+ static X: u32;
+
+ #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code
+ type T;
+}
+
+#[no_coverage]
+fn main() {
+ #[no_coverage]
+ //~^ WARN `#[no_coverage]` may only be applied to function definitions
+ let _ = ();
+
+ match () {
+ #[no_coverage]
+ //~^ WARN `#[no_coverage]` may only be applied to function definitions
+ () => (),
+ }
+
+ #[no_coverage]
+ //~^ WARN `#[no_coverage]` may only be applied to function definitions
+ return ();
+}
diff --git a/tests/ui/lint/no-coverage.stderr b/tests/ui/lint/no-coverage.stderr
new file mode 100644
index 000000000..404efbeac
--- /dev/null
+++ b/tests/ui/lint/no-coverage.stderr
@@ -0,0 +1,101 @@
+warning: `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly
+ --> $DIR/no-coverage.rs:8:1
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/no-coverage.rs:4:9
+ |
+LL | #![warn(unused_attributes)]
+ | ^^^^^^^^^^^^^^^^^
+
+warning: `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly
+ --> $DIR/no-coverage.rs:20:1
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+
+warning: `#[no_coverage]` may only be applied to function definitions
+ --> $DIR/no-coverage.rs:42:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+
+warning: `#[no_coverage]` may only be applied to function definitions
+ --> $DIR/no-coverage.rs:47:9
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+
+warning: `#[no_coverage]` may only be applied to function definitions
+ --> $DIR/no-coverage.rs:52:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+
+error[E0788]: `#[no_coverage]` must be applied to coverable code
+ --> $DIR/no-coverage.rs:11:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+LL | const X: u32;
+ | ------------- not coverable code
+
+error[E0788]: `#[no_coverage]` must be applied to coverable code
+ --> $DIR/no-coverage.rs:14:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+LL | type T;
+ | ------- not coverable code
+
+error[E0788]: `#[no_coverage]` must be applied to coverable code
+ --> $DIR/no-coverage.rs:25:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+LL | type T = Self;
+ | -------------- not coverable code
+
+error[E0788]: `#[no_coverage]` must be applied to coverable code
+ --> $DIR/no-coverage.rs:28:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+LL | type U = impl Trait;
+ | -------------------- not coverable code
+
+error[E0788]: `#[no_coverage]` must be applied to coverable code
+ --> $DIR/no-coverage.rs:33:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+LL | static X: u32;
+ | -------------- not coverable code
+
+error[E0788]: `#[no_coverage]` must be applied to coverable code
+ --> $DIR/no-coverage.rs:36:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+LL | type T;
+ | ------- not coverable code
+
+warning: `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly
+ --> $DIR/no-coverage.rs:5:1
+ |
+LL | #![no_coverage]
+ | ^^^^^^^^^^^^^^^
+
+error: unconstrained opaque type
+ --> $DIR/no-coverage.rs:29:14
+ |
+LL | type U = impl Trait;
+ | ^^^^^^^^^^
+ |
+ = note: `U` must be used in combination with a concrete type within the same impl
+
+error: aborting due to 7 previous errors; 6 warnings emitted
+
+For more information about this error, try `rustc --explain E0788`.
diff --git a/tests/ui/lint/noop-method-call.rs b/tests/ui/lint/noop-method-call.rs
new file mode 100644
index 000000000..89b296635
--- /dev/null
+++ b/tests/ui/lint/noop-method-call.rs
@@ -0,0 +1,55 @@
+// check-pass
+
+#![allow(unused)]
+#![warn(noop_method_call)]
+
+use std::borrow::Borrow;
+use std::ops::Deref;
+
+struct PlainType<T>(T);
+
+#[derive(Clone)]
+struct CloneType<T>(T);
+
+fn main() {
+ let non_clone_type_ref = &PlainType(1u32);
+ let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone();
+ //~^ WARNING call to `.clone()` on a reference in this situation does nothing
+
+ let clone_type_ref = &CloneType(1u32);
+ let clone_type_ref_clone: CloneType<u32> = clone_type_ref.clone();
+
+ // Calling clone on a double reference doesn't warn since the method call itself
+ // peels the outer reference off
+ let clone_type_ref = &&CloneType(1u32);
+ let clone_type_ref_clone: &CloneType<u32> = clone_type_ref.clone();
+
+ let non_deref_type = &PlainType(1u32);
+ let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
+ //~^ WARNING call to `.deref()` on a reference in this situation does nothing
+
+ // Dereferencing a &&T does not warn since it has collapsed the double reference
+ let non_deref_type = &&PlainType(1u32);
+ let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
+
+ let non_borrow_type = &PlainType(1u32);
+ let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
+ //~^ WARNING call to `.borrow()` on a reference in this situation does nothing
+
+ // Borrowing a &&T does not warn since it has collapsed the double reference
+ let non_borrow_type = &&PlainType(1u32);
+ let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
+
+ let xs = ["a", "b", "c"];
+ let _v: Vec<&str> = xs.iter().map(|x| x.clone()).collect(); // ok, but could use `*x` instead
+}
+
+fn generic<T>(non_clone_type: &PlainType<T>) {
+ non_clone_type.clone();
+ //~^ WARNING call to `.clone()` on a reference in this situation does nothing
+}
+
+fn non_generic(non_clone_type: &PlainType<u32>) {
+ non_clone_type.clone();
+ //~^ WARNING call to `.clone()` on a reference in this situation does nothing
+}
diff --git a/tests/ui/lint/noop-method-call.stderr b/tests/ui/lint/noop-method-call.stderr
new file mode 100644
index 000000000..6a904d01a
--- /dev/null
+++ b/tests/ui/lint/noop-method-call.stderr
@@ -0,0 +1,47 @@
+warning: call to `.clone()` on a reference in this situation does nothing
+ --> $DIR/noop-method-call.rs:16:71
+ |
+LL | let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone();
+ | ^^^^^^^^ unnecessary method call
+ |
+ = note: the type `&PlainType<u32>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed
+note: the lint level is defined here
+ --> $DIR/noop-method-call.rs:4:9
+ |
+LL | #![warn(noop_method_call)]
+ | ^^^^^^^^^^^^^^^^
+
+warning: call to `.deref()` on a reference in this situation does nothing
+ --> $DIR/noop-method-call.rs:28:63
+ |
+LL | let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
+ | ^^^^^^^^ unnecessary method call
+ |
+ = note: the type `&PlainType<u32>` which `deref` is being called on is the same as the type returned from `deref`, so the method call does not do anything and can be removed
+
+warning: call to `.borrow()` on a reference in this situation does nothing
+ --> $DIR/noop-method-call.rs:36:66
+ |
+LL | let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
+ | ^^^^^^^^^ unnecessary method call
+ |
+ = note: the type `&PlainType<u32>` which `borrow` is being called on is the same as the type returned from `borrow`, so the method call does not do anything and can be removed
+
+warning: call to `.clone()` on a reference in this situation does nothing
+ --> $DIR/noop-method-call.rs:48:19
+ |
+LL | non_clone_type.clone();
+ | ^^^^^^^^ unnecessary method call
+ |
+ = note: the type `&PlainType<T>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed
+
+warning: call to `.clone()` on a reference in this situation does nothing
+ --> $DIR/noop-method-call.rs:53:19
+ |
+LL | non_clone_type.clone();
+ | ^^^^^^^^ unnecessary method call
+ |
+ = note: the type `&PlainType<u32>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed
+
+warning: 5 warnings emitted
+
diff --git a/tests/ui/lint/not_found.rs b/tests/ui/lint/not_found.rs
new file mode 100644
index 000000000..de120b6e0
--- /dev/null
+++ b/tests/ui/lint/not_found.rs
@@ -0,0 +1,21 @@
+// check-pass
+
+// this tests the `unknown_lint` lint, especially the suggestions
+
+// the suggestion only appears if a lint with the lowercase name exists
+#[allow(FOO_BAR)]
+//~^ WARNING unknown lint
+
+// the suggestion appears on all-uppercase names
+#[warn(DEAD_CODE)]
+//~^ WARNING unknown lint
+//~| HELP did you mean
+
+// the suggestion appears also on mixed-case names
+#[deny(Warnings)]
+//~^ WARNING unknown lint
+//~| HELP did you mean
+
+fn main() {
+ unimplemented!();
+}
diff --git a/tests/ui/lint/not_found.stderr b/tests/ui/lint/not_found.stderr
new file mode 100644
index 000000000..ea118c73c
--- /dev/null
+++ b/tests/ui/lint/not_found.stderr
@@ -0,0 +1,22 @@
+warning: unknown lint: `FOO_BAR`
+ --> $DIR/not_found.rs:6:9
+ |
+LL | #[allow(FOO_BAR)]
+ | ^^^^^^^
+ |
+ = note: `#[warn(unknown_lints)]` on by default
+
+warning: unknown lint: `DEAD_CODE`
+ --> $DIR/not_found.rs:10:8
+ |
+LL | #[warn(DEAD_CODE)]
+ | ^^^^^^^^^ help: did you mean: `dead_code`
+
+warning: unknown lint: `Warnings`
+ --> $DIR/not_found.rs:15:8
+ |
+LL | #[deny(Warnings)]
+ | ^^^^^^^^ help: did you mean (notice the capitalization): `warnings`
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/lint/opaque-ty-ffi-normalization-cycle.rs b/tests/ui/lint/opaque-ty-ffi-normalization-cycle.rs
new file mode 100644
index 000000000..c83bca4a4
--- /dev/null
+++ b/tests/ui/lint/opaque-ty-ffi-normalization-cycle.rs
@@ -0,0 +1,41 @@
+#![feature(type_alias_impl_trait)]
+#![allow(unused)]
+#![deny(improper_ctypes)]
+
+pub trait TraitA {
+ type Assoc;
+}
+
+impl TraitA for u32 {
+ type Assoc = u32;
+}
+
+pub trait TraitB {
+ type Assoc;
+}
+
+impl<T> TraitB for T
+where
+ T: TraitA,
+{
+ type Assoc = <T as TraitA>::Assoc;
+}
+
+type AliasA = impl TraitA<Assoc = u32>;
+
+type AliasB = impl TraitB;
+
+fn use_of_a() -> AliasA {
+ 3
+}
+
+fn use_of_b() -> AliasB {
+ 3
+}
+
+extern "C" {
+ fn lint_me() -> <AliasB as TraitB>::Assoc;
+ //~^ ERROR `extern` block uses type `AliasB`, which is not FFI-safe
+}
+
+fn main() {}
diff --git a/tests/ui/lint/opaque-ty-ffi-normalization-cycle.stderr b/tests/ui/lint/opaque-ty-ffi-normalization-cycle.stderr
new file mode 100644
index 000000000..e8d696477
--- /dev/null
+++ b/tests/ui/lint/opaque-ty-ffi-normalization-cycle.stderr
@@ -0,0 +1,15 @@
+error: `extern` block uses type `AliasB`, which is not FFI-safe
+ --> $DIR/opaque-ty-ffi-normalization-cycle.rs:37:21
+ |
+LL | fn lint_me() -> <AliasB as TraitB>::Assoc;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = note: opaque types have no C equivalent
+note: the lint level is defined here
+ --> $DIR/opaque-ty-ffi-normalization-cycle.rs:3:9
+ |
+LL | #![deny(improper_ctypes)]
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/opaque-ty-ffi-unsafe.rs b/tests/ui/lint/opaque-ty-ffi-unsafe.rs
new file mode 100644
index 000000000..b7cc38e99
--- /dev/null
+++ b/tests/ui/lint/opaque-ty-ffi-unsafe.rs
@@ -0,0 +1,15 @@
+#![feature(type_alias_impl_trait)]
+#![deny(improper_ctypes)]
+
+type A = impl Fn();
+
+pub fn ret_closure() -> A {
+ || {}
+}
+
+extern "C" {
+ pub fn a(_: A);
+ //~^ ERROR `extern` block uses type `A`, which is not FFI-safe [improper_ctypes]
+}
+
+fn main() {}
diff --git a/tests/ui/lint/opaque-ty-ffi-unsafe.stderr b/tests/ui/lint/opaque-ty-ffi-unsafe.stderr
new file mode 100644
index 000000000..33aa95854
--- /dev/null
+++ b/tests/ui/lint/opaque-ty-ffi-unsafe.stderr
@@ -0,0 +1,15 @@
+error: `extern` block uses type `A`, which is not FFI-safe
+ --> $DIR/opaque-ty-ffi-unsafe.rs:11:17
+ |
+LL | pub fn a(_: A);
+ | ^ not FFI-safe
+ |
+ = note: opaque types have no C equivalent
+note: the lint level is defined here
+ --> $DIR/opaque-ty-ffi-unsafe.rs:2:9
+ |
+LL | #![deny(improper_ctypes)]
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/outer-forbid.rs b/tests/ui/lint/outer-forbid.rs
new file mode 100644
index 000000000..ba330258d
--- /dev/null
+++ b/tests/ui/lint/outer-forbid.rs
@@ -0,0 +1,32 @@
+// Forbidding a group (here, `unused`) overrules subsequent allowance of both
+// the group, and an individual lint in the group (here, `unused_variables`);
+// and, forbidding an individual lint (here, `non_snake_case`) overrules
+// subsequent allowance of a lint group containing it (here, `nonstandard_style`). See
+// Issue #42873.
+
+// If you turn off deduplicate diagnostics (which rustc turns on by default but
+// compiletest turns off when it runs ui tests), then the errors are
+// (unfortunately) repeated here because the checking is done as we read in the
+// errors, and currently that happens two or three different times, depending on
+// compiler flags.
+//
+// The test is much cleaner if we deduplicate, though.
+
+// compile-flags: -Z deduplicate-diagnostics=yes
+
+#![forbid(unused, non_snake_case)]
+#![forbid(forbidden_lint_groups)]
+
+#[allow(unused_variables)]
+//~^ ERROR incompatible with previous
+//~| WARNING this was previously accepted by the compiler
+fn foo() {}
+
+#[allow(unused)] //~ ERROR incompatible with previous
+//~^ WARNING this was previously accepted by the compiler
+fn bar() {}
+
+#[allow(nonstandard_style)] //~ ERROR incompatible with previous
+fn main() {
+ println!("hello forbidden world")
+}
diff --git a/tests/ui/lint/outer-forbid.stderr b/tests/ui/lint/outer-forbid.stderr
new file mode 100644
index 000000000..a47877980
--- /dev/null
+++ b/tests/ui/lint/outer-forbid.stderr
@@ -0,0 +1,41 @@
+error: allow(unused_variables) incompatible with previous forbid
+ --> $DIR/outer-forbid.rs:20:9
+ |
+LL | #![forbid(unused, non_snake_case)]
+ | ------ `forbid` level set here
+...
+LL | #[allow(unused_variables)]
+ | ^^^^^^^^^^^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+note: the lint level is defined here
+ --> $DIR/outer-forbid.rs:18:11
+ |
+LL | #![forbid(forbidden_lint_groups)]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: allow(unused) incompatible with previous forbid
+ --> $DIR/outer-forbid.rs:25:9
+ |
+LL | #![forbid(unused, non_snake_case)]
+ | ------ `forbid` level set here
+...
+LL | #[allow(unused)]
+ | ^^^^^^ overruled by previous forbid
+ |
+ = 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 #81670 <https://github.com/rust-lang/rust/issues/81670>
+
+error[E0453]: allow(nonstandard_style) incompatible with previous forbid
+ --> $DIR/outer-forbid.rs:29:9
+ |
+LL | #![forbid(unused, non_snake_case)]
+ | -------------- `forbid` level set here
+...
+LL | #[allow(nonstandard_style)]
+ | ^^^^^^^^^^^^^^^^^ overruled by previous forbid
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0453`.
diff --git a/tests/ui/lint/reasons-erroneous.rs b/tests/ui/lint/reasons-erroneous.rs
new file mode 100644
index 000000000..cd693ae16
--- /dev/null
+++ b/tests/ui/lint/reasons-erroneous.rs
@@ -0,0 +1,54 @@
+#![feature(lint_reasons)]
+
+#![warn(absolute_paths_not_starting_with_crate, reason = 0)]
+//~^ ERROR malformed lint attribute
+//~| ERROR malformed lint attribute
+//~| NOTE reason must be a string literal
+//~| NOTE reason must be a string literal
+#![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")]
+//~^ ERROR malformed lint attribute
+//~| ERROR malformed lint attribute
+//~| NOTE reason must be a string literal
+//~| NOTE reason must be a string literal
+#![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
+//~^ ERROR malformed lint attribute
+//~| ERROR malformed lint attribute
+//~| ERROR malformed lint attribute
+//~| ERROR malformed lint attribute
+//~| NOTE bad attribute argument
+//~| NOTE bad attribute argument
+//~| NOTE bad attribute argument
+//~| NOTE bad attribute argument
+#![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
+//~^ ERROR malformed lint attribute
+//~| ERROR malformed lint attribute
+//~| ERROR malformed lint attribute
+//~| ERROR malformed lint attribute
+//~| NOTE bad attribute argument
+//~| NOTE bad attribute argument
+//~| NOTE bad attribute argument
+//~| NOTE bad attribute argument
+#![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
+//~^ ERROR malformed lint attribute
+//~| ERROR malformed lint attribute
+//~| ERROR malformed lint attribute
+//~| ERROR malformed lint attribute
+//~| NOTE bad attribute argument
+//~| NOTE bad attribute argument
+//~| NOTE bad attribute argument
+//~| NOTE bad attribute argument
+#![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")]
+//~^ ERROR malformed lint attribute
+//~| ERROR malformed lint attribute
+//~| NOTE reason in lint attribute must come last
+//~| NOTE reason in lint attribute must come last
+#![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)]
+//~^ ERROR malformed lint attribute
+//~| ERROR malformed lint attribute
+//~| NOTE reason in lint attribute must come last
+//~| NOTE reason in lint attribute must come last
+#![warn(missing_copy_implementations, reason)]
+//~^ WARN unknown lint
+//~| NOTE `#[warn(unknown_lints)]` on by default
+
+fn main() {}
diff --git a/tests/ui/lint/reasons-erroneous.stderr b/tests/ui/lint/reasons-erroneous.stderr
new file mode 100644
index 000000000..5521af17c
--- /dev/null
+++ b/tests/ui/lint/reasons-erroneous.stderr
@@ -0,0 +1,131 @@
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:3:58
+ |
+LL | #![warn(absolute_paths_not_starting_with_crate, reason = 0)]
+ | ^ reason must be a string literal
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:8:40
+ |
+LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:13:29
+ |
+LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:13:29
+ |
+LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:22:23
+ |
+LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:22:23
+ |
+LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:31:36
+ |
+LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:31:36
+ |
+LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:40:44
+ |
+LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")]
+ | ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:45:25
+ |
+LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:3:58
+ |
+LL | #![warn(absolute_paths_not_starting_with_crate, reason = 0)]
+ | ^ reason must be a string literal
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:8:40
+ |
+LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:13:29
+ |
+LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:13:29
+ |
+LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:22:23
+ |
+LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:22:23
+ |
+LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:31:36
+ |
+LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:31:36
+ |
+LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:40:44
+ |
+LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")]
+ | ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
+
+error[E0452]: malformed lint attribute input
+ --> $DIR/reasons-erroneous.rs:45:25
+ |
+LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
+
+warning: unknown lint: `reason`
+ --> $DIR/reasons-erroneous.rs:50:39
+ |
+LL | #![warn(missing_copy_implementations, reason)]
+ | ^^^^^^
+ |
+ = note: `#[warn(unknown_lints)]` on by default
+
+error: aborting due to 20 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0452`.
diff --git a/tests/ui/lint/reasons-forbidden.rs b/tests/ui/lint/reasons-forbidden.rs
new file mode 100644
index 000000000..9c2edec4d
--- /dev/null
+++ b/tests/ui/lint/reasons-forbidden.rs
@@ -0,0 +1,34 @@
+#![feature(lint_reasons)]
+
+// If you turn off deduplicate diagnostics (which rustc turns on by default but
+// compiletest turns off when it runs ui tests), then the errors are
+// (unfortunately) repeated here because the checking is done as we read in the
+// errors, and currently that happens two or three different times, depending on
+// compiler flags.
+//
+// The test is much cleaner if we deduplicate, though.
+
+// compile-flags: -Z deduplicate-diagnostics=yes
+
+#![forbid(
+ unsafe_code,
+ //~^ NOTE `forbid` level set here
+ //~| NOTE the lint level is defined here
+ reason = "our errors & omissions insurance policy doesn't cover unsafe Rust"
+)]
+
+use std::ptr;
+
+fn main() {
+ let a_billion_dollar_mistake = ptr::null();
+
+ #[allow(unsafe_code)]
+ //~^ ERROR allow(unsafe_code) incompatible with previous forbid
+ //~| NOTE our errors & omissions insurance policy doesn't cover unsafe Rust
+ //~| NOTE overruled by previous forbid
+ unsafe {
+ //~^ ERROR usage of an `unsafe` block
+ //~| NOTE our errors & omissions insurance policy doesn't cover unsafe Rust
+ *a_billion_dollar_mistake
+ }
+}
diff --git a/tests/ui/lint/reasons-forbidden.stderr b/tests/ui/lint/reasons-forbidden.stderr
new file mode 100644
index 000000000..ab6f19a01
--- /dev/null
+++ b/tests/ui/lint/reasons-forbidden.stderr
@@ -0,0 +1,31 @@
+error[E0453]: allow(unsafe_code) incompatible with previous forbid
+ --> $DIR/reasons-forbidden.rs:25:13
+ |
+LL | unsafe_code,
+ | ----------- `forbid` level set here
+...
+LL | #[allow(unsafe_code)]
+ | ^^^^^^^^^^^ overruled by previous forbid
+ |
+ = note: our errors & omissions insurance policy doesn't cover unsafe Rust
+
+error: usage of an `unsafe` block
+ --> $DIR/reasons-forbidden.rs:29:5
+ |
+LL | / unsafe {
+LL | |
+LL | |
+LL | | *a_billion_dollar_mistake
+LL | | }
+ | |_____^
+ |
+ = note: our errors & omissions insurance policy doesn't cover unsafe Rust
+note: the lint level is defined here
+ --> $DIR/reasons-forbidden.rs:14:5
+ |
+LL | unsafe_code,
+ | ^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0453`.
diff --git a/tests/ui/lint/reasons.rs b/tests/ui/lint/reasons.rs
new file mode 100644
index 000000000..da1c740c4
--- /dev/null
+++ b/tests/ui/lint/reasons.rs
@@ -0,0 +1,35 @@
+// check-pass
+
+#![feature(lint_reasons)]
+#![warn(elided_lifetimes_in_paths,
+ //~^ NOTE the lint level is defined here
+ reason = "explicit anonymous lifetimes aid reasoning about ownership")]
+#![warn(
+ nonstandard_style,
+ //~^ NOTE the lint level is defined here
+ reason = r#"people shouldn't have to change their usual style habits
+to contribute to our project"#
+)]
+#![allow(unused, reason = "unused code has never killed anypony")]
+
+use std::fmt;
+
+pub struct CheaterDetectionMechanism {}
+
+impl fmt::Debug for CheaterDetectionMechanism {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ //~^ WARN hidden lifetime parameters in types are deprecated
+ //~| NOTE expected lifetime parameter
+ //~| NOTE explicit anonymous lifetimes aid
+ //~| HELP indicate the anonymous lifetime
+ fmt.debug_struct("CheaterDetectionMechanism").finish()
+ }
+}
+
+fn main() {
+ let Social_exchange_psychology = CheaterDetectionMechanism {};
+ //~^ WARN should have a snake case name
+ //~| NOTE #[warn(non_snake_case)]` implied by `#[warn(nonstandard_style)]
+ //~| NOTE people shouldn't have to change their usual style habits
+ //~| HELP convert the identifier to snake case
+}
diff --git a/tests/ui/lint/reasons.stderr b/tests/ui/lint/reasons.stderr
new file mode 100644
index 000000000..cd8412153
--- /dev/null
+++ b/tests/ui/lint/reasons.stderr
@@ -0,0 +1,36 @@
+warning: hidden lifetime parameters in types are deprecated
+ --> $DIR/reasons.rs:20:34
+ |
+LL | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ | -----^^^^^^^^^
+ | |
+ | expected lifetime parameter
+ |
+ = note: explicit anonymous lifetimes aid reasoning about ownership
+note: the lint level is defined here
+ --> $DIR/reasons.rs:4:9
+ |
+LL | #![warn(elided_lifetimes_in_paths,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+help: indicate the anonymous lifetime
+ |
+LL | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ | ++++
+
+warning: variable `Social_exchange_psychology` should have a snake case name
+ --> $DIR/reasons.rs:30:9
+ |
+LL | let Social_exchange_psychology = CheaterDetectionMechanism {};
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case (notice the capitalization): `social_exchange_psychology`
+ |
+ = note: people shouldn't have to change their usual style habits
+ to contribute to our project
+note: the lint level is defined here
+ --> $DIR/reasons.rs:8:5
+ |
+LL | nonstandard_style,
+ | ^^^^^^^^^^^^^^^^^
+ = note: `#[warn(non_snake_case)]` implied by `#[warn(nonstandard_style)]`
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/lint/recommend-literal.rs b/tests/ui/lint/recommend-literal.rs
new file mode 100644
index 000000000..453cbf285
--- /dev/null
+++ b/tests/ui/lint/recommend-literal.rs
@@ -0,0 +1,42 @@
+type Real = double;
+//~^ ERROR cannot find type `double` in this scope
+//~| HELP perhaps you intended to use this type
+
+fn main() {
+ let x: Real = 3.5;
+ let y: long = 74802374902374923;
+ //~^ ERROR cannot find type `long` in this scope
+ //~| HELP perhaps you intended to use this type
+ let v1: Boolean = true;
+ //~^ ERROR: cannot find type `Boolean` in this scope [E0412]
+ //~| HELP perhaps you intended to use this type
+ let v2: Bool = true;
+ //~^ ERROR: cannot find type `Bool` in this scope [E0412]
+ //~| HELP a builtin type with a similar name exists
+ //~| HELP perhaps you intended to use this type
+}
+
+fn z(a: boolean) {
+ //~^ ERROR cannot find type `boolean` in this scope
+ //~| HELP perhaps you intended to use this type
+}
+
+fn a() -> byte {
+//~^ ERROR cannot find type `byte` in this scope
+//~| HELP perhaps you intended to use this type
+ 3
+}
+
+struct Data { //~ HELP you might be missing a type parameter
+ width: float,
+ //~^ ERROR cannot find type `float` in this scope
+ //~| HELP perhaps you intended to use this type
+ depth: Option<int>,
+ //~^ ERROR cannot find type `int` in this scope
+ //~| HELP perhaps you intended to use this type
+}
+
+trait Stuff {}
+impl Stuff for short {}
+//~^ ERROR cannot find type `short` in this scope
+//~| HELP perhaps you intended to use this type
diff --git a/tests/ui/lint/recommend-literal.stderr b/tests/ui/lint/recommend-literal.stderr
new file mode 100644
index 000000000..424ecadd4
--- /dev/null
+++ b/tests/ui/lint/recommend-literal.stderr
@@ -0,0 +1,96 @@
+error[E0412]: cannot find type `double` in this scope
+ --> $DIR/recommend-literal.rs:1:13
+ |
+LL | type Real = double;
+ | ^^^^^^
+ | |
+ | not found in this scope
+ | help: perhaps you intended to use this type: `f64`
+
+error[E0412]: cannot find type `long` in this scope
+ --> $DIR/recommend-literal.rs:7:12
+ |
+LL | let y: long = 74802374902374923;
+ | ^^^^
+ | |
+ | not found in this scope
+ | help: perhaps you intended to use this type: `i64`
+
+error[E0412]: cannot find type `Boolean` in this scope
+ --> $DIR/recommend-literal.rs:10:13
+ |
+LL | let v1: Boolean = true;
+ | ^^^^^^^
+ | |
+ | not found in this scope
+ | help: perhaps you intended to use this type: `bool`
+
+error[E0412]: cannot find type `Bool` in this scope
+ --> $DIR/recommend-literal.rs:13:13
+ |
+LL | let v2: Bool = true;
+ | ^^^^
+ |
+help: a builtin type with a similar name exists
+ |
+LL | let v2: bool = true;
+ | ~~~~
+help: perhaps you intended to use this type
+ |
+LL | let v2: bool = true;
+ | ~~~~
+
+error[E0412]: cannot find type `boolean` in this scope
+ --> $DIR/recommend-literal.rs:19:9
+ |
+LL | fn z(a: boolean) {
+ | ^^^^^^^
+ | |
+ | not found in this scope
+ | help: perhaps you intended to use this type: `bool`
+
+error[E0412]: cannot find type `byte` in this scope
+ --> $DIR/recommend-literal.rs:24:11
+ |
+LL | fn a() -> byte {
+ | ^^^^
+ | |
+ | not found in this scope
+ | help: perhaps you intended to use this type: `u8`
+
+error[E0412]: cannot find type `float` in this scope
+ --> $DIR/recommend-literal.rs:31:12
+ |
+LL | width: float,
+ | ^^^^^
+ | |
+ | not found in this scope
+ | help: perhaps you intended to use this type: `f32`
+
+error[E0412]: cannot find type `int` in this scope
+ --> $DIR/recommend-literal.rs:34:19
+ |
+LL | depth: Option<int>,
+ | ^^^ not found in this scope
+ |
+help: perhaps you intended to use this type
+ |
+LL | depth: Option<i32>,
+ | ~~~
+help: you might be missing a type parameter
+ |
+LL | struct Data<int> {
+ | +++++
+
+error[E0412]: cannot find type `short` in this scope
+ --> $DIR/recommend-literal.rs:40:16
+ |
+LL | impl Stuff for short {}
+ | ^^^^^
+ | |
+ | not found in this scope
+ | help: perhaps you intended to use this type: `i16`
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs b/tests/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs
new file mode 100644
index 000000000..5a94ccd74
--- /dev/null
+++ b/tests/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs
@@ -0,0 +1,12 @@
+// force-host
+// no-prefer-dynamic
+#![crate_type="proc-macro"]
+#![crate_name="redundant_semi_proc_macro"]
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro_attribute]
+pub fn should_preserve_spans(_attr: TokenStream, item: TokenStream) -> TokenStream {
+ eprintln!("{:?}", item);
+ item
+}
diff --git a/tests/ui/lint/redundant-semicolon/item-stmt-semi.rs b/tests/ui/lint/redundant-semicolon/item-stmt-semi.rs
new file mode 100644
index 000000000..8c79630b7
--- /dev/null
+++ b/tests/ui/lint/redundant-semicolon/item-stmt-semi.rs
@@ -0,0 +1,6 @@
+#![deny(redundant_semicolons)]
+
+fn main() {
+ fn inner() {}; //~ ERROR unnecessary
+ struct Bar {}; //~ ERROR unnecessary
+}
diff --git a/tests/ui/lint/redundant-semicolon/item-stmt-semi.stderr b/tests/ui/lint/redundant-semicolon/item-stmt-semi.stderr
new file mode 100644
index 000000000..451b152cb
--- /dev/null
+++ b/tests/ui/lint/redundant-semicolon/item-stmt-semi.stderr
@@ -0,0 +1,20 @@
+error: unnecessary trailing semicolon
+ --> $DIR/item-stmt-semi.rs:4:18
+ |
+LL | fn inner() {};
+ | ^ help: remove this semicolon
+ |
+note: the lint level is defined here
+ --> $DIR/item-stmt-semi.rs:1:9
+ |
+LL | #![deny(redundant_semicolons)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary trailing semicolon
+ --> $DIR/item-stmt-semi.rs:5:18
+ |
+LL | struct Bar {};
+ | ^ help: remove this semicolon
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs b/tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs
new file mode 100644
index 000000000..08a5c6c2b
--- /dev/null
+++ b/tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs
@@ -0,0 +1,19 @@
+// aux-build:redundant-semi-proc-macro-def.rs
+
+#![deny(redundant_semicolons)]
+extern crate redundant_semi_proc_macro;
+use redundant_semi_proc_macro::should_preserve_spans;
+
+#[should_preserve_spans]
+fn span_preservation() {
+ let tst = 123;; //~ ERROR unnecessary trailing semicolon
+ match tst {
+ // Redundant semicolons are parsed as empty tuple exprs
+ // for the lint, so ensure the lint doesn't affect
+ // empty tuple exprs explicitly in source.
+ 123 => (),
+ _ => ()
+ };;; //~ ERROR unnecessary trailing semicolons
+}
+
+fn main() {}
diff --git a/tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr b/tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr
new file mode 100644
index 000000000..e31d14c55
--- /dev/null
+++ b/tests/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr
@@ -0,0 +1,21 @@
+TokenStream [Ident { ident: "fn", span: #0 bytes(198..200) }, Ident { ident: "span_preservation", span: #0 bytes(201..218) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(218..220) }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "let", span: #0 bytes(228..231) }, Ident { ident: "tst", span: #0 bytes(232..235) }, Punct { ch: '=', spacing: Alone, span: #0 bytes(236..237) }, Literal { kind: Integer, symbol: "123", suffix: None, span: #0 bytes(238..241) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(241..242) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(242..243) }, Ident { ident: "match", span: #0 bytes(289..294) }, Ident { ident: "tst", span: #0 bytes(295..298) }, Group { delimiter: Brace, stream: TokenStream [Literal { kind: Integer, symbol: "123", suffix: None, span: #0 bytes(483..486) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(487..488) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(488..489) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(490..492) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(492..493) }, Ident { ident: "_", span: #0 bytes(502..503) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(504..505) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(505..506) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(507..509) }], span: #0 bytes(299..515) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(515..516) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(516..517) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(517..518) }], span: #0 bytes(222..562) }]
+error: unnecessary trailing semicolon
+ --> $DIR/redundant-semi-proc-macro.rs:9:19
+ |
+LL | let tst = 123;;
+ | ^ help: remove this semicolon
+ |
+note: the lint level is defined here
+ --> $DIR/redundant-semi-proc-macro.rs:3:9
+ |
+LL | #![deny(redundant_semicolons)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary trailing semicolons
+ --> $DIR/redundant-semi-proc-macro.rs:16:7
+ |
+LL | };;;
+ | ^^ help: remove these semicolons
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/register-tool-lint.rs b/tests/ui/lint/register-tool-lint.rs
new file mode 100644
index 000000000..17d3afbf6
--- /dev/null
+++ b/tests/ui/lint/register-tool-lint.rs
@@ -0,0 +1,9 @@
+#![crate_type = "lib"]
+#![feature(register_tool)]
+#![register_tool(xyz)]
+#![warn(xyz::my_lint)] // this should not error
+#![warn(abc::my_lint)]
+//~^ ERROR unknown tool name `abc` found in scoped lint
+//~| HELP add `#![register_tool(abc)]`
+//~| ERROR unknown tool name `abc`
+//~| HELP add `#![register_tool(abc)]`
diff --git a/tests/ui/lint/register-tool-lint.stderr b/tests/ui/lint/register-tool-lint.stderr
new file mode 100644
index 000000000..842d845ff
--- /dev/null
+++ b/tests/ui/lint/register-tool-lint.stderr
@@ -0,0 +1,19 @@
+error[E0710]: unknown tool name `abc` found in scoped lint: `abc::my_lint`
+ --> $DIR/register-tool-lint.rs:5:9
+ |
+LL | #![warn(abc::my_lint)]
+ | ^^^
+ |
+ = help: add `#![register_tool(abc)]` to the crate root
+
+error[E0710]: unknown tool name `abc` found in scoped lint: `abc::my_lint`
+ --> $DIR/register-tool-lint.rs:5:9
+ |
+LL | #![warn(abc::my_lint)]
+ | ^^^
+ |
+ = help: add `#![register_tool(abc)]` to the crate root
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0710`.
diff --git a/tests/ui/lint/renamed-lints-still-apply.rs b/tests/ui/lint/renamed-lints-still-apply.rs
new file mode 100644
index 000000000..01cd32536
--- /dev/null
+++ b/tests/ui/lint/renamed-lints-still-apply.rs
@@ -0,0 +1,9 @@
+// compile-flags: --crate-type lib
+#![deny(single_use_lifetime)]
+//~^ WARNING renamed
+//~| NOTE `#[warn(renamed_and_removed_lints)]` on by default
+//~| NOTE defined here
+fn _foo<'a>(_x: &'a u32) {}
+//~^ ERROR only used once
+//~| NOTE this lifetime
+//~| NOTE is used only here
diff --git a/tests/ui/lint/renamed-lints-still-apply.stderr b/tests/ui/lint/renamed-lints-still-apply.stderr
new file mode 100644
index 000000000..e926719bb
--- /dev/null
+++ b/tests/ui/lint/renamed-lints-still-apply.stderr
@@ -0,0 +1,29 @@
+warning: lint `single_use_lifetime` has been renamed to `single_use_lifetimes`
+ --> $DIR/renamed-lints-still-apply.rs:2:9
+ |
+LL | #![deny(single_use_lifetime)]
+ | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `single_use_lifetimes`
+ |
+ = note: `#[warn(renamed_and_removed_lints)]` on by default
+
+error: lifetime parameter `'a` only used once
+ --> $DIR/renamed-lints-still-apply.rs:6:9
+ |
+LL | fn _foo<'a>(_x: &'a u32) {}
+ | ^^ -- ...is used only here
+ | |
+ | this lifetime...
+ |
+note: the lint level is defined here
+ --> $DIR/renamed-lints-still-apply.rs:2:9
+ |
+LL | #![deny(single_use_lifetime)]
+ | ^^^^^^^^^^^^^^^^^^^
+help: elide the single-use lifetime
+ |
+LL - fn _foo<'a>(_x: &'a u32) {}
+LL + fn _foo(_x: &u32) {}
+ |
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/tests/ui/lint/rfc-2383-lint-reason/avoid_delayed_good_path_ice.rs b/tests/ui/lint/rfc-2383-lint-reason/avoid_delayed_good_path_ice.rs
new file mode 100644
index 000000000..912e831d8
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/avoid_delayed_good_path_ice.rs
@@ -0,0 +1,8 @@
+// check-pass
+#![feature(lint_reasons)]
+
+#[expect(drop_bounds)]
+fn trigger_rustc_lints<T: Drop>() {
+}
+
+fn main() {}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/catch_multiple_lint_triggers.rs b/tests/ui/lint/rfc-2383-lint-reason/catch_multiple_lint_triggers.rs
new file mode 100644
index 000000000..6b255b799
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/catch_multiple_lint_triggers.rs
@@ -0,0 +1,45 @@
+// check-pass
+
+#![feature(lint_reasons)]
+
+#![warn(unused)]
+
+// This expect attribute should catch all lint triggers
+#[expect(unused_variables)]
+fn check_multiple_lints_1() {
+ let value_i = 0xff00ff;
+ let value_ii = 0xff00ff;
+ let value_iii = 0xff00ff;
+ let value_iiii = 0xff00ff;
+ let value_iiiii = 0xff00ff;
+}
+
+// This expect attribute should catch all lint triggers
+#[expect(unused_mut)]
+fn check_multiple_lints_2() {
+ let mut a = 0xa;
+ let mut b = 0xb;
+ let mut c = 0xc;
+ println!("The ABC goes as: {:#x} {:#x} {:#x}", a, b, c);
+}
+
+// This expect attribute should catch all lint triggers
+#[expect(while_true)]
+fn check_multiple_lints_3() {
+ // `while_true` is an early lint
+ while true {}
+
+ while true {}
+
+ while true {}
+
+ while true {}
+
+ while true {}
+}
+
+fn main() {
+ check_multiple_lints_1();
+ check_multiple_lints_2();
+ check_multiple_lints_3();
+}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/crate_level_expect.rs b/tests/ui/lint/rfc-2383-lint-reason/crate_level_expect.rs
new file mode 100644
index 000000000..9f591ba98
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/crate_level_expect.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+#![feature(lint_reasons)]
+
+#![warn(unused)]
+
+#![expect(unused_mut)]
+//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+//~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default
+
+#![expect(unused_variables)]
+
+fn main() {
+ let x = 0;
+}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/crate_level_expect.stderr b/tests/ui/lint/rfc-2383-lint-reason/crate_level_expect.stderr
new file mode 100644
index 000000000..7237f6fb6
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/crate_level_expect.stderr
@@ -0,0 +1,10 @@
+warning: this lint expectation is unfulfilled
+ --> $DIR/crate_level_expect.rs:7:11
+ |
+LL | #![expect(unused_mut)]
+ | ^^^^^^^^^^
+ |
+ = note: `#[warn(unfulfilled_lint_expectations)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_inside_macro.rs b/tests/ui/lint/rfc-2383-lint-reason/expect_inside_macro.rs
new file mode 100644
index 000000000..b95815bc5
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_inside_macro.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+#![feature(lint_reasons)]
+
+#![warn(unused)]
+
+macro_rules! expect_inside_macro {
+ () => {
+ #[expect(unused_variables)]
+ let x = 0;
+ };
+}
+
+fn main() {
+ expect_inside_macro!();
+}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.rs b/tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.rs
new file mode 100644
index 000000000..07c60fa0c
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.rs
@@ -0,0 +1,42 @@
+// check-pass
+
+#![feature(lint_reasons)]
+
+#![warn(unused_variables)]
+
+macro_rules! trigger_unused_variables_macro {
+ () => {
+ let x = 0;
+ //~^ WARNING unused variable: `x` [unused_variables]
+ //~| WARNING unused variable: `x` [unused_variables]
+ };
+}
+
+pub fn check_macro() {
+ // This should trigger the `unused_variables` from inside the macro
+ trigger_unused_variables_macro!();
+}
+
+// This should be fulfilled by the macro
+#[expect(unused_variables)]
+pub fn check_expect_on_item() {
+ trigger_unused_variables_macro!();
+}
+
+pub fn check_expect_on_macro() {
+ // This should be fulfilled by the macro
+ #[expect(unused_variables)]
+ trigger_unused_variables_macro!();
+
+ // FIXME: Lint attributes currently don't work directly on macros, and
+ // therefore also doesn't work for the new `expect` attribute. This bug
+ // is being tracked in rust#87391. The test will until then produce two
+ // warnings about the unused variable x.
+ //
+ // The expectation is still marked as fulfilled. I'm not totally why but
+ // my guess is that this will remain working when rust#87391 has been fixed.
+}
+
+fn main() {
+
+}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.stderr b/tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.stderr
new file mode 100644
index 000000000..817e16fdc
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.stderr
@@ -0,0 +1,29 @@
+warning: unused variable: `x`
+ --> $DIR/expect_lint_from_macro.rs:9:13
+ |
+LL | let x = 0;
+ | ^ help: if this is intentional, prefix it with an underscore: `_x`
+...
+LL | trigger_unused_variables_macro!();
+ | --------------------------------- in this macro invocation
+ |
+note: the lint level is defined here
+ --> $DIR/expect_lint_from_macro.rs:5:9
+ |
+LL | #![warn(unused_variables)]
+ | ^^^^^^^^^^^^^^^^
+ = note: this warning originates in the macro `trigger_unused_variables_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: unused variable: `x`
+ --> $DIR/expect_lint_from_macro.rs:9:13
+ |
+LL | let x = 0;
+ | ^ help: if this is intentional, prefix it with an underscore: `_x`
+...
+LL | trigger_unused_variables_macro!();
+ | --------------------------------- in this macro invocation
+ |
+ = note: this warning originates in the macro `trigger_unused_variables_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.rs b/tests/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.rs
new file mode 100644
index 000000000..928e16106
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.rs
@@ -0,0 +1,9 @@
+// should error due to missing feature gate.
+
+#![warn(unused)]
+
+#[expect(unused)]
+//~^ ERROR: the `#[expect]` attribute is an experimental feature [E0658]
+fn main() {
+ let x = 1;
+}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.stderr b/tests/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.stderr
new file mode 100644
index 000000000..b5601cf9e
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_missing_feature_gate.stderr
@@ -0,0 +1,12 @@
+error[E0658]: the `#[expect]` attribute is an experimental feature
+ --> $DIR/expect_missing_feature_gate.rs:5:1
+ |
+LL | #[expect(unused)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #54503 <https://github.com/rust-lang/rust/issues/54503> for more information
+ = help: add `#![feature(lint_reasons)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_multiple_lints.rs b/tests/ui/lint/rfc-2383-lint-reason/expect_multiple_lints.rs
new file mode 100644
index 000000000..dc9a719a3
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_multiple_lints.rs
@@ -0,0 +1,58 @@
+// check-pass
+
+#![feature(lint_reasons)]
+
+#![warn(unused)]
+
+// The warnings are not double triggers, they identify different unfulfilled lint
+// expectations one for each listed lint.
+
+#[expect(unused_variables, unused_mut, while_true)]
+//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+//~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default
+//~| WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+fn check_multiple_lints_1() {
+ // This only trigger `unused_variables`
+ let who_am_i = 666;
+}
+
+#[expect(unused_variables, unused_mut, while_true)]
+//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+//~| WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+fn check_multiple_lints_2() {
+ // This only triggers `unused_mut`
+ let mut x = 0;
+ println!("I use x: {}", x);
+}
+
+#[expect(unused_variables, unused_mut, while_true)]
+//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+//~| WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+fn check_multiple_lints_3() {
+ // This only triggers `while_true` which is also an early lint
+ while true {}
+}
+
+#[expect(unused, while_true)]
+//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+fn check_multiple_lints_with_lint_group_1() {
+ let who_am_i = 666;
+
+ let mut x = 0;
+ println!("I use x: {}", x);
+}
+
+#[expect(unused, while_true)]
+//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+fn check_multiple_lints_with_lint_group_2() {
+ while true {}
+}
+
+fn main() {
+ check_multiple_lints_1();
+ check_multiple_lints_2();
+ check_multiple_lints_3();
+
+ check_multiple_lints_with_lint_group_1();
+ check_multiple_lints_with_lint_group_2();
+}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_multiple_lints.stderr b/tests/ui/lint/rfc-2383-lint-reason/expect_multiple_lints.stderr
new file mode 100644
index 000000000..90ee744b2
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_multiple_lints.stderr
@@ -0,0 +1,52 @@
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_multiple_lints.rs:10:28
+ |
+LL | #[expect(unused_variables, unused_mut, while_true)]
+ | ^^^^^^^^^^
+ |
+ = note: `#[warn(unfulfilled_lint_expectations)]` on by default
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_multiple_lints.rs:10:40
+ |
+LL | #[expect(unused_variables, unused_mut, while_true)]
+ | ^^^^^^^^^^
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_multiple_lints.rs:19:10
+ |
+LL | #[expect(unused_variables, unused_mut, while_true)]
+ | ^^^^^^^^^^^^^^^^
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_multiple_lints.rs:19:40
+ |
+LL | #[expect(unused_variables, unused_mut, while_true)]
+ | ^^^^^^^^^^
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_multiple_lints.rs:28:10
+ |
+LL | #[expect(unused_variables, unused_mut, while_true)]
+ | ^^^^^^^^^^^^^^^^
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_multiple_lints.rs:28:28
+ |
+LL | #[expect(unused_variables, unused_mut, while_true)]
+ | ^^^^^^^^^^
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_multiple_lints.rs:36:18
+ |
+LL | #[expect(unused, while_true)]
+ | ^^^^^^^^^^
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_multiple_lints.rs:45:10
+ |
+LL | #[expect(unused, while_true)]
+ | ^^^^^^
+
+warning: 8 warnings emitted
+
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.rs b/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.rs
new file mode 100644
index 000000000..8f94bd6ec
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.rs
@@ -0,0 +1,53 @@
+// ignore-tidy-linelength
+
+#![feature(lint_reasons)]
+#![warn(unused_mut)]
+
+#[expect(
+ unused_mut,
+ //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+ //~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default
+ //~| NOTE this `expect` is overridden by a `allow` attribute before the `unused_mut` lint is triggered
+ reason = "this `expect` is overridden by a `allow` attribute before the `unused_mut` lint is triggered"
+)]
+mod foo {
+ fn bar() {
+ #[allow(
+ unused_mut,
+ reason = "this overrides the previous `expect` lint level and allows the `unused_mut` lint here"
+ )]
+ let mut v = 0;
+ }
+}
+
+#[expect(
+ unused_mut,
+ //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+ //~| NOTE this `expect` is overridden by a `warn` attribute before the `unused_mut` lint is triggered
+ reason = "this `expect` is overridden by a `warn` attribute before the `unused_mut` lint is triggered"
+)]
+mod oof {
+ #[warn(
+ unused_mut,
+ //~^ NOTE the lint level is defined here
+ reason = "this overrides the previous `expect` lint level and warns about the `unused_mut` lint here"
+ )]
+ fn bar() {
+ let mut v = 0;
+ //~^ WARNING variable does not need to be mutable [unused_mut]
+ //~| NOTE this overrides the previous `expect` lint level and warns about the `unused_mut` lint here
+ //~| HELP remove this `mut`
+ }
+}
+
+#[expect(unused_variables)]
+//~^ WARNING this lint expectation is unfulfilled
+#[forbid(unused_variables)]
+//~^ NOTE the lint level is defined here
+fn check_expect_then_forbid() {
+ let this_is_my_function = 3;
+ //~^ ERROR unused variable: `this_is_my_function` [unused_variables]
+ //~| HELP if this is intentional, prefix it with an underscore
+}
+
+fn main() {}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr b/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr
new file mode 100644
index 000000000..2c35647b8
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr
@@ -0,0 +1,52 @@
+error: unused variable: `this_is_my_function`
+ --> $DIR/expect_nested_lint_levels.rs:48:9
+ |
+LL | let this_is_my_function = 3;
+ | ^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_this_is_my_function`
+ |
+note: the lint level is defined here
+ --> $DIR/expect_nested_lint_levels.rs:45:10
+ |
+LL | #[forbid(unused_variables)]
+ | ^^^^^^^^^^^^^^^^
+
+warning: variable does not need to be mutable
+ --> $DIR/expect_nested_lint_levels.rs:36:13
+ |
+LL | let mut v = 0;
+ | ----^
+ | |
+ | help: remove this `mut`
+ |
+ = note: this overrides the previous `expect` lint level and warns about the `unused_mut` lint here
+note: the lint level is defined here
+ --> $DIR/expect_nested_lint_levels.rs:31:9
+ |
+LL | unused_mut,
+ | ^^^^^^^^^^
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_nested_lint_levels.rs:7:5
+ |
+LL | unused_mut,
+ | ^^^^^^^^^^
+ |
+ = note: this `expect` is overridden by a `allow` attribute before the `unused_mut` lint is triggered
+ = note: `#[warn(unfulfilled_lint_expectations)]` on by default
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_nested_lint_levels.rs:24:5
+ |
+LL | unused_mut,
+ | ^^^^^^^^^^
+ |
+ = note: this `expect` is overridden by a `warn` attribute before the `unused_mut` lint is triggered
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_nested_lint_levels.rs:43:10
+ |
+LL | #[expect(unused_variables)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error; 4 warnings emitted
+
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_on_fn_params.rs b/tests/ui/lint/rfc-2383-lint-reason/expect_on_fn_params.rs
new file mode 100644
index 000000000..5fdb71041
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_on_fn_params.rs
@@ -0,0 +1,15 @@
+// check-pass
+#![feature(lint_reasons)]
+
+#[warn(unused_variables)]
+
+/// This should catch the unused_variables lint and not emit anything
+fn check_fulfilled_expectation(#[expect(unused_variables)] unused_value: u32) {}
+
+fn check_unfulfilled_expectation(#[expect(unused_variables)] used_value: u32) {
+ //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+ //~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default
+ println!("I use the value {used_value}");
+}
+
+fn main() {}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_on_fn_params.stderr b/tests/ui/lint/rfc-2383-lint-reason/expect_on_fn_params.stderr
new file mode 100644
index 000000000..69f7cda08
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_on_fn_params.stderr
@@ -0,0 +1,10 @@
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_on_fn_params.rs:9:43
+ |
+LL | fn check_unfulfilled_expectation(#[expect(unused_variables)] used_value: u32) {
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(unfulfilled_lint_expectations)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_tool_lint_rfc_2383.rs b/tests/ui/lint/rfc-2383-lint-reason/expect_tool_lint_rfc_2383.rs
new file mode 100644
index 000000000..f80fe88cb
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_tool_lint_rfc_2383.rs
@@ -0,0 +1,155 @@
+// check-pass
+#![feature(lint_reasons)]
+
+//! This file tests the `#[expect]` attribute implementation for tool lints. The same
+//! file is used to test clippy and rustdoc. Any changes to this file should be synced
+//! to the other test files.
+//!
+//! Expectations:
+//! * rustc: only rustc lint expectations are emitted
+//! * clippy: rustc and Clippy's expectations are emitted
+//! * rustdoc: only rustdoc lint expectations are emitted
+//!
+//! This test can't cover every lint from Clippy, rustdoc and potentially other
+//! tools that will be developed. This therefore only tests a small subset of lints
+
+#![expect(rustdoc::missing_crate_level_docs)]
+
+mod rustc_ok {
+ //! See <https://doc.rust-lang.org/rustc/lints/index.html>
+
+ #[expect(dead_code)]
+ pub fn rustc_lints() {
+ let x = 42.0;
+
+ #[expect(illegal_floating_point_literal_pattern)]
+ match x {
+ 5.0 => {}
+ 6.0 => {}
+ _ => {}
+ }
+ }
+}
+
+mod rustc_warn {
+ //! See <https://doc.rust-lang.org/rustc/lints/index.html>
+
+ #[expect(dead_code)]
+ //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+ //~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default
+ pub fn rustc_lints() {
+ let x = 42;
+
+ #[expect(illegal_floating_point_literal_pattern)]
+ //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+ match x {
+ 5 => {}
+ 6 => {}
+ _ => {}
+ }
+ }
+}
+
+pub mod rustdoc_ok {
+ //! See <https://doc.rust-lang.org/rustdoc/lints.html>
+
+ #[expect(rustdoc::broken_intra_doc_links)]
+ /// I want to link to [`Nonexistent`] but it doesn't exist!
+ pub fn foo() {}
+
+ #[expect(rustdoc::invalid_html_tags)]
+ /// <h1>
+ pub fn bar() {}
+
+ #[expect(rustdoc::bare_urls)]
+ /// http://example.org
+ pub fn baz() {}
+}
+
+pub mod rustdoc_warn {
+ //! See <https://doc.rust-lang.org/rustdoc/lints.html>
+
+ #[expect(rustdoc::broken_intra_doc_links)]
+ /// I want to link to [`bar`] but it doesn't exist!
+ pub fn foo() {}
+
+ #[expect(rustdoc::invalid_html_tags)]
+ /// <h1></h1>
+ pub fn bar() {}
+
+ #[expect(rustdoc::bare_urls)]
+ /// <http://example.org>
+ pub fn baz() {}
+}
+
+mod clippy_ok {
+ //! See <https://rust-lang.github.io/rust-clippy/master/index.html>
+
+ #[expect(clippy::almost_swapped)]
+ fn foo() {
+ let mut a = 0;
+ let mut b = 9;
+ a = b;
+ b = a;
+ }
+
+ #[expect(clippy::bytes_nth)]
+ fn bar() {
+ let _ = "Hello".bytes().nth(3);
+ }
+
+ #[expect(clippy::if_same_then_else)]
+ fn baz() {
+ let _ = if true {
+ 42
+ } else {
+ 42
+ };
+ }
+
+ #[expect(clippy::logic_bug)]
+ fn burger() {
+ let a = false;
+ let b = true;
+
+ if a && b || a {}
+ }
+}
+
+mod clippy_warn {
+ //! See <https://rust-lang.github.io/rust-clippy/master/index.html>
+
+ #[expect(clippy::almost_swapped)]
+ fn foo() {
+ let mut a = 0;
+ let mut b = 9;
+ a = b;
+ }
+
+ #[expect(clippy::bytes_nth)]
+ fn bar() {
+ let _ = "Hello".as_bytes().get(3);
+ }
+
+ #[expect(clippy::if_same_then_else)]
+ fn baz() {
+ let _ = if true {
+ 33
+ } else {
+ 42
+ };
+ }
+
+ #[expect(clippy::logic_bug)]
+ fn burger() {
+ let a = false;
+ let b = true;
+ let c = false;
+
+ if a && b || c {}
+ }
+}
+
+fn main() {
+ rustc_warn::rustc_lints();
+}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_tool_lint_rfc_2383.stderr b/tests/ui/lint/rfc-2383-lint-reason/expect_tool_lint_rfc_2383.stderr
new file mode 100644
index 000000000..6d49e7543
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_tool_lint_rfc_2383.stderr
@@ -0,0 +1,16 @@
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_tool_lint_rfc_2383.rs:37:14
+ |
+LL | #[expect(dead_code)]
+ | ^^^^^^^^^
+ |
+ = note: `#[warn(unfulfilled_lint_expectations)]` on by default
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_tool_lint_rfc_2383.rs:43:18
+ |
+LL | #[expect(illegal_floating_point_literal_pattern)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.rs b/tests/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.rs
new file mode 100644
index 000000000..d38e65533
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.rs
@@ -0,0 +1,39 @@
+// check-pass
+// ignore-tidy-linelength
+
+#![feature(lint_reasons)]
+#![warn(unused_mut)]
+
+#![expect(unfulfilled_lint_expectations, reason = "idk why you would expect this")]
+//~^ WARNING this lint expectation is unfulfilled
+//~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default
+//~| NOTE idk why you would expect this
+//~| NOTE the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
+
+#[expect(unfulfilled_lint_expectations, reason = "a local: idk why you would expect this")]
+//~^ WARNING this lint expectation is unfulfilled
+//~| NOTE a local: idk why you would expect this
+//~| NOTE the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
+pub fn normal_test_fn() {
+ #[expect(unused_mut, reason = "this expectation will create a diagnostic with the default lint level")]
+ //~^ WARNING this lint expectation is unfulfilled
+ //~| NOTE this expectation will create a diagnostic with the default lint level
+ let mut v = vec![1, 1, 2, 3, 5];
+ v.sort();
+
+ // Check that lint lists including `unfulfilled_lint_expectations` are also handled correctly
+ #[expect(unused, unfulfilled_lint_expectations, reason = "the expectation for `unused` should be fulfilled")]
+ //~^ WARNING this lint expectation is unfulfilled
+ //~| NOTE the expectation for `unused` should be fulfilled
+ //~| NOTE the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
+ let value = "I'm unused";
+}
+
+#[expect(warnings, reason = "this suppresses all warnings and also suppresses itself. No warning will be issued")]
+pub fn expect_warnings() {
+ // This lint trigger will be suppressed
+ #[warn(unused_mut)]
+ let mut v = vec![1, 1, 2, 3, 5];
+}
+
+fn main() {}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.stderr b/tests/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.stderr
new file mode 100644
index 000000000..9a1c3e442
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.stderr
@@ -0,0 +1,38 @@
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_unfulfilled_expectation.rs:7:11
+ |
+LL | #![expect(unfulfilled_lint_expectations, reason = "idk why you would expect this")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: idk why you would expect this
+ = note: the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
+ = note: `#[warn(unfulfilled_lint_expectations)]` on by default
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_unfulfilled_expectation.rs:13:10
+ |
+LL | #[expect(unfulfilled_lint_expectations, reason = "a local: idk why you would expect this")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: a local: idk why you would expect this
+ = note: the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_unfulfilled_expectation.rs:18:14
+ |
+LL | #[expect(unused_mut, reason = "this expectation will create a diagnostic with the default lint level")]
+ | ^^^^^^^^^^
+ |
+ = note: this expectation will create a diagnostic with the default lint level
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_unfulfilled_expectation.rs:25:22
+ |
+LL | #[expect(unused, unfulfilled_lint_expectations, reason = "the expectation for `unused` should be fulfilled")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the expectation for `unused` should be fulfilled
+ = note: the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
+
+warning: 4 warnings emitted
+
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.rs b/tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.rs
new file mode 100644
index 000000000..479ee198e
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.rs
@@ -0,0 +1,34 @@
+#![feature(lint_reasons)]
+
+#[forbid(unused_variables)]
+//~^ NOTE `forbid` level set here
+//~| NOTE `forbid` level set here
+#[expect(unused_variables)]
+//~^ ERROR incompatible with previous forbid [E0453]
+//~| NOTE overruled by previous forbid
+//~| ERROR incompatible with previous forbid [E0453]
+//~| NOTE overruled by previous forbid
+fn expect_forbidden_lint_1() {}
+
+#[forbid(while_true)]
+//~^ NOTE `forbid` level set here
+//~| NOTE `forbid` level set here
+//~| NOTE the lint level is defined here
+#[expect(while_true)]
+//~^ ERROR incompatible with previous forbid [E0453]
+//~| NOTE overruled by previous forbid
+//~| ERROR incompatible with previous forbid [E0453]
+//~| NOTE overruled by previous forbid
+fn expect_forbidden_lint_2() {
+ // This while loop will produce a `while_true` lint as the lint level
+ // at this node is still `forbid` and the `while_true` check happens
+ // before the compilation terminates due to `E0453`
+ while true {}
+ //~^ ERROR denote infinite loops with `loop { ... }`
+ //~| HELP use `loop`
+}
+
+fn main() {
+ expect_forbidden_lint_1();
+ expect_forbidden_lint_2();
+}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.stderr b/tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.stderr
new file mode 100644
index 000000000..a8116e934
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.stderr
@@ -0,0 +1,51 @@
+error[E0453]: expect(unused_variables) incompatible with previous forbid
+ --> $DIR/expect_with_forbid.rs:6:10
+ |
+LL | #[forbid(unused_variables)]
+ | ---------------- `forbid` level set here
+...
+LL | #[expect(unused_variables)]
+ | ^^^^^^^^^^^^^^^^ overruled by previous forbid
+
+error[E0453]: expect(while_true) incompatible with previous forbid
+ --> $DIR/expect_with_forbid.rs:17:10
+ |
+LL | #[forbid(while_true)]
+ | ---------- `forbid` level set here
+...
+LL | #[expect(while_true)]
+ | ^^^^^^^^^^ overruled by previous forbid
+
+error[E0453]: expect(unused_variables) incompatible with previous forbid
+ --> $DIR/expect_with_forbid.rs:6:10
+ |
+LL | #[forbid(unused_variables)]
+ | ---------------- `forbid` level set here
+...
+LL | #[expect(unused_variables)]
+ | ^^^^^^^^^^^^^^^^ overruled by previous forbid
+
+error[E0453]: expect(while_true) incompatible with previous forbid
+ --> $DIR/expect_with_forbid.rs:17:10
+ |
+LL | #[forbid(while_true)]
+ | ---------- `forbid` level set here
+...
+LL | #[expect(while_true)]
+ | ^^^^^^^^^^ overruled by previous forbid
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/expect_with_forbid.rs:26:5
+ |
+LL | while true {}
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/expect_with_forbid.rs:13:10
+ |
+LL | #[forbid(while_true)]
+ | ^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0453`.
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_with_reason.rs b/tests/ui/lint/rfc-2383-lint-reason/expect_with_reason.rs
new file mode 100644
index 000000000..b4183d982
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_with_reason.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+#![feature(lint_reasons)]
+#![warn(unused)]
+
+#![expect(unused_variables, reason = "<This should fail and display this reason>")]
+//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+//~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default
+//~| NOTE <This should fail and display this reason>
+
+fn main() {}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr b/tests/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr
new file mode 100644
index 000000000..e349e4081
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr
@@ -0,0 +1,11 @@
+warning: this lint expectation is unfulfilled
+ --> $DIR/expect_with_reason.rs:6:11
+ |
+LL | #![expect(unused_variables, reason = "<This should fail and display this reason>")]
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: <This should fail and display this reason>
+ = note: `#[warn(unfulfilled_lint_expectations)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.rs b/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.rs
new file mode 100644
index 000000000..a3c3933d7
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.rs
@@ -0,0 +1,48 @@
+// compile-flags: --force-warn while_true
+// compile-flags: --force-warn unused_variables
+// compile-flags: --force-warn unused_mut
+// check-pass
+
+#![feature(lint_reasons)]
+
+fn expect_early_pass_lint() {
+ #[expect(while_true)]
+ while true {
+ //~^ WARNING denote infinite loops with `loop { ... }` [while_true]
+ //~| NOTE requested on the command line with `--force-warn while-true`
+ //~| HELP use `loop`
+ println!("I never stop")
+ }
+}
+
+#[expect(unused_variables, reason="<this should fail and display this reason>")]
+fn check_specific_lint() {
+ let x = 2;
+ //~^ WARNING unused variable: `x` [unused_variables]
+ //~| NOTE requested on the command line with `--force-warn unused-variables`
+ //~| HELP if this is intentional, prefix it with an underscore
+}
+
+#[expect(unused)]
+fn check_multiple_lints_with_lint_group() {
+ let fox_name = "Sir Nibbles";
+ //~^ WARNING unused variable: `fox_name` [unused_variables]
+ //~| HELP if this is intentional, prefix it with an underscore
+
+ let mut what_does_the_fox_say = "*ding* *deng* *dung*";
+ //~^ WARNING variable does not need to be mutable [unused_mut]
+ //~| NOTE requested on the command line with `--force-warn unused-mut`
+ //~| HELP remove this `mut`
+
+ println!("The fox says: {what_does_the_fox_say}");
+}
+
+#[allow(unused_variables)]
+fn check_expect_overrides_allow_lint_level() {
+ #[expect(unused_variables)]
+ let this_should_fulfill_the_expectation = "The `#[allow]` has no power here";
+ //~^ WARNING unused variable: `this_should_fulfill_the_expectation` [unused_variables]
+ //~| HELP if this is intentional, prefix it with an underscore
+}
+
+fn main() {}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr b/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr
new file mode 100644
index 000000000..5942fa8ae
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr
@@ -0,0 +1,40 @@
+warning: unused variable: `x`
+ --> $DIR/force_warn_expected_lints_fulfilled.rs:20:9
+ |
+LL | let x = 2;
+ | ^ help: if this is intentional, prefix it with an underscore: `_x`
+ |
+ = note: requested on the command line with `--force-warn unused-variables`
+
+warning: unused variable: `fox_name`
+ --> $DIR/force_warn_expected_lints_fulfilled.rs:28:9
+ |
+LL | let fox_name = "Sir Nibbles";
+ | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_fox_name`
+
+warning: unused variable: `this_should_fulfill_the_expectation`
+ --> $DIR/force_warn_expected_lints_fulfilled.rs:43:9
+ |
+LL | let this_should_fulfill_the_expectation = "The `#[allow]` has no power here";
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_this_should_fulfill_the_expectation`
+
+warning: variable does not need to be mutable
+ --> $DIR/force_warn_expected_lints_fulfilled.rs:32:9
+ |
+LL | let mut what_does_the_fox_say = "*ding* *deng* *dung*";
+ | ----^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | help: remove this `mut`
+ |
+ = note: requested on the command line with `--force-warn unused-mut`
+
+warning: denote infinite loops with `loop { ... }`
+ --> $DIR/force_warn_expected_lints_fulfilled.rs:10:5
+ |
+LL | while true {
+ | ^^^^^^^^^^ help: use `loop`
+ |
+ = note: requested on the command line with `--force-warn while-true`
+
+warning: 5 warnings emitted
+
diff --git a/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_unfulfilled.rs b/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_unfulfilled.rs
new file mode 100644
index 000000000..080e30023
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_unfulfilled.rs
@@ -0,0 +1,49 @@
+// compile-flags: --force-warn while_true
+// compile-flags: --force-warn unused_variables
+// compile-flags: --force-warn unused_mut
+// check-pass
+
+#![feature(lint_reasons)]
+
+fn expect_early_pass_lint(terminate: bool) {
+ #[expect(while_true)]
+ //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+ //~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default
+ while !terminate {
+ println!("Do you know what a spin lock is?")
+ }
+}
+
+#[expect(unused_variables, reason="<this should fail and display this reason>")]
+//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+//~| NOTE <this should fail and display this reason>
+fn check_specific_lint() {
+ let _x = 2;
+}
+
+#[expect(unused)]
+//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+fn check_multiple_lints_with_lint_group() {
+ let fox_name = "Sir Nibbles";
+
+ let what_does_the_fox_say = "*ding* *deng* *dung*";
+
+ println!("The fox says: {what_does_the_fox_say}");
+ println!("~ {fox_name}")
+}
+
+
+#[expect(unused)]
+//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+fn check_overridden_expectation_lint_level() {
+ #[allow(unused_variables)]
+ let this_should_not_fulfill_the_expectation = "maybe";
+ //~^ WARNING unused variable: `this_should_not_fulfill_the_expectation` [unused_variables]
+ //~| NOTE requested on the command line with `--force-warn unused-variables`
+ //~| HELP if this is intentional, prefix it with an underscore
+}
+
+fn main() {
+ check_multiple_lints_with_lint_group();
+ check_overridden_expectation_lint_level();
+}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_unfulfilled.stderr b/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_unfulfilled.stderr
new file mode 100644
index 000000000..c74fabe27
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_unfulfilled.stderr
@@ -0,0 +1,38 @@
+warning: unused variable: `this_should_not_fulfill_the_expectation`
+ --> $DIR/force_warn_expected_lints_unfulfilled.rs:40:9
+ |
+LL | let this_should_not_fulfill_the_expectation = "maybe";
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_this_should_not_fulfill_the_expectation`
+ |
+ = note: requested on the command line with `--force-warn unused-variables`
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/force_warn_expected_lints_unfulfilled.rs:9:14
+ |
+LL | #[expect(while_true)]
+ | ^^^^^^^^^^
+ |
+ = note: `#[warn(unfulfilled_lint_expectations)]` on by default
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/force_warn_expected_lints_unfulfilled.rs:17:10
+ |
+LL | #[expect(unused_variables, reason="<this should fail and display this reason>")]
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: <this should fail and display this reason>
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/force_warn_expected_lints_unfulfilled.rs:24:10
+ |
+LL | #[expect(unused)]
+ | ^^^^^^
+
+warning: this lint expectation is unfulfilled
+ --> $DIR/force_warn_expected_lints_unfulfilled.rs:36:10
+ |
+LL | #[expect(unused)]
+ | ^^^^^^
+
+warning: 5 warnings emitted
+
diff --git a/tests/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_early_lints.rs b/tests/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_early_lints.rs
new file mode 100644
index 000000000..6624b930e
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_early_lints.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+#![feature(lint_reasons)]
+
+fn expect_early_pass_lints() {
+ #[expect(while_true)]
+ while true {
+ println!("I never stop")
+ }
+
+ #[expect(unused_doc_comments)]
+ /// This comment triggers the `unused_doc_comments` lint
+ let _sheep = "wolf";
+
+ let x = 123;
+ #[expect(ellipsis_inclusive_range_patterns)]
+ match x {
+ 0...100 => {}
+ _ => {}
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_late_lints.rs b/tests/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_late_lints.rs
new file mode 100644
index 000000000..5d928b3ca
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/fulfilled_expectation_late_lints.rs
@@ -0,0 +1,43 @@
+// check-pass
+
+#![feature(lint_reasons)]
+#![warn(unused)]
+
+#[expect(unused_variables)]
+fn check_specific_lint() {
+ let x = 2;
+}
+
+#[expect(unused)]
+fn check_lint_group() {
+ let x = 15;
+}
+
+#[expect(unused_variables)]
+fn check_multiple_lint_emissions() {
+ let r = 1;
+ let u = 8;
+ let s = 2;
+ let t = 9;
+}
+
+mod check_fulfilled_expect_in_macro {
+ macro_rules! expect_inside_macro {
+ () => {
+ #[expect(unused_variables)]
+ let x = 0;
+ };
+ }
+
+ pub fn check_macro() {
+ expect_inside_macro!();
+ }
+}
+
+fn main() {
+ check_specific_lint();
+ check_lint_group();
+ check_multiple_lint_emissions();
+
+ check_fulfilled_expect_in_macro::check_macro();
+}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.rs b/tests/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.rs
new file mode 100644
index 000000000..bafdea96e
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.rs
@@ -0,0 +1,14 @@
+#![feature(lint_reasons)]
+
+#![deny(unused_attributes)]
+
+#[allow(reason = "I want to allow something")]//~ ERROR unused attribute
+#[expect(reason = "I don't know what I'm waiting for")]//~ ERROR unused attribute
+#[warn(reason = "This should be warn by default")]//~ ERROR unused attribute
+#[deny(reason = "All listed lints are denied")]//~ ERROR unused attribute
+#[forbid(reason = "Just some reason")]//~ ERROR unused attribute
+
+#[allow(clippy::box_collection, reason = "This is still valid")]
+#[warn(dead_code, reason = "This is also reasonable")]
+
+fn main() {}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr b/tests/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr
new file mode 100644
index 000000000..3e9d70821
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr
@@ -0,0 +1,47 @@
+error: unused attribute
+ --> $DIR/lint-attribute-only-with-reason.rs:5:1
+ |
+LL | #[allow(reason = "I want to allow something")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+ = note: attribute `allow` without any lints has no effect
+note: the lint level is defined here
+ --> $DIR/lint-attribute-only-with-reason.rs:3:9
+ |
+LL | #![deny(unused_attributes)]
+ | ^^^^^^^^^^^^^^^^^
+
+error: unused attribute
+ --> $DIR/lint-attribute-only-with-reason.rs:6:1
+ |
+LL | #[expect(reason = "I don't know what I'm waiting for")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+ = note: attribute `expect` without any lints has no effect
+
+error: unused attribute
+ --> $DIR/lint-attribute-only-with-reason.rs:7:1
+ |
+LL | #[warn(reason = "This should be warn by default")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+ = note: attribute `warn` without any lints has no effect
+
+error: unused attribute
+ --> $DIR/lint-attribute-only-with-reason.rs:8:1
+ |
+LL | #[deny(reason = "All listed lints are denied")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+ = note: attribute `deny` without any lints has no effect
+
+error: unused attribute
+ --> $DIR/lint-attribute-only-with-reason.rs:9:1
+ |
+LL | #[forbid(reason = "Just some reason")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+ = note: attribute `forbid` without any lints has no effect
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.rs b/tests/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.rs
new file mode 100644
index 000000000..98080b4e8
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+#![feature(lint_reasons)]
+#![warn(unused)]
+
+#[warn(unused_variables)]
+#[expect(unused_variables)]
+//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations]
+//~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default
+#[allow(unused_variables)]
+#[expect(unused_variables)] // Only this expectation will be fulfilled
+fn main() {
+ let x = 2;
+}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.stderr b/tests/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.stderr
new file mode 100644
index 000000000..df7d6584f
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.stderr
@@ -0,0 +1,10 @@
+warning: this lint expectation is unfulfilled
+ --> $DIR/multiple_expect_attrs.rs:7:10
+ |
+LL | #[expect(unused_variables)]
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(unfulfilled_lint_expectations)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.rs b/tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.rs
new file mode 100644
index 000000000..2b6c3c6a1
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.rs
@@ -0,0 +1,16 @@
+// This ensures that ICEs like rust#94953 don't happen
+// check-pass
+// compile-flags: -Z unpretty=expanded
+
+#![feature(lint_reasons)]
+
+// This `expect` will create an expectation with an unstable expectation id
+#[expect(while_true)]
+fn create_early_lint_pass_expectation() {
+ // `while_true` is an early lint
+ while true {}
+}
+
+fn main() {
+ create_early_lint_pass_expectation();
+}
diff --git a/tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.stdout b/tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.stdout
new file mode 100644
index 000000000..0ee3a03c3
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.stdout
@@ -0,0 +1,20 @@
+#![feature(prelude_import)]
+#![no_std]
+// This ensures that ICEs like rust#94953 don't happen
+// check-pass
+// compile-flags: -Z unpretty=expanded
+
+#![feature(lint_reasons)]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+
+// This `expect` will create an expectation with an unstable expectation id
+#[expect(while_true)]
+fn create_early_lint_pass_expectation() {
+ // `while_true` is an early lint
+ while true {}
+}
+
+fn main() { create_early_lint_pass_expectation(); }
diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs
new file mode 100644
index 000000000..e7da825ae
--- /dev/null
+++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs
@@ -0,0 +1,16 @@
+#![deny(confusable_idents)]
+#![allow(uncommon_codepoints, non_upper_case_globals)]
+
+const s: usize = 42;
+const s_s: usize = 42;
+
+fn main() {
+ let s = "rust"; //~ ERROR identifier pair considered confusable
+ let s_s = "rust2"; //~ ERROR identifier pair considered confusable
+ not_affected();
+}
+
+fn not_affected() {
+ let s1 = 1;
+ let sl = 'l';
+}
diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr
new file mode 100644
index 000000000..e9906c83d
--- /dev/null
+++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr
@@ -0,0 +1,26 @@
+error: identifier pair considered confusable between `s` and `s`
+ --> $DIR/lint-confusable-idents.rs:8:9
+ |
+LL | const s: usize = 42;
+ | -- this is where the previous identifier occurred
+...
+LL | let s = "rust";
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-confusable-idents.rs:1:9
+ |
+LL | #![deny(confusable_idents)]
+ | ^^^^^^^^^^^^^^^^^
+
+error: identifier pair considered confusable between `s_s` and `s_s`
+ --> $DIR/lint-confusable-idents.rs:9:9
+ |
+LL | const s_s: usize = 42;
+ | --- this is where the previous identifier occurred
+...
+LL | let s_s = "rust2";
+ | ^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables-2.rs b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables-2.rs
new file mode 100644
index 000000000..f62c8a190
--- /dev/null
+++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables-2.rs
@@ -0,0 +1,19 @@
+// check-pass
+#![deny(mixed_script_confusables)]
+
+struct ΑctuallyNotLatin;
+
+fn main() {
+ let λ = 42; // this usage of Greek confirms that Greek is used intentionally.
+}
+
+mod роре {
+ const エ: &'static str = "アイウ";
+
+ // this usage of Katakana confirms that Katakana is used intentionally.
+ fn ニャン() {
+ let д: usize = 100; // this usage of Cyrillic confirms that Cyrillic is used intentionally.
+
+ println!("meow!");
+ }
+}
diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.rs b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.rs
new file mode 100644
index 000000000..9d837d41f
--- /dev/null
+++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.rs
@@ -0,0 +1,14 @@
+#![deny(mixed_script_confusables)]
+
+struct ΑctuallyNotLatin;
+//~^ ERROR the usage of Script Group `Greek` in this crate consists solely of
+
+fn main() {
+ let v = ΑctuallyNotLatin;
+}
+
+mod роре {
+//~^ ERROR the usage of Script Group `Cyrillic` in this crate consists solely of
+ const エ: &'static str = "アイウ";
+ //~^ ERROR the usage of Script Group `Japanese, Katakana` in this crate consists solely of
+}
diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.stderr b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.stderr
new file mode 100644
index 000000000..884a4a453
--- /dev/null
+++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.stderr
@@ -0,0 +1,34 @@
+error: the usage of Script Group `Greek` in this crate consists solely of mixed script confusables
+ --> $DIR/lint-mixed-script-confusables.rs:3:8
+ |
+LL | struct ΑctuallyNotLatin;
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: the usage includes 'Α' (U+0391)
+ = note: please recheck to make sure their usages are indeed what you want
+note: the lint level is defined here
+ --> $DIR/lint-mixed-script-confusables.rs:1:9
+ |
+LL | #![deny(mixed_script_confusables)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the usage of Script Group `Cyrillic` in this crate consists solely of mixed script confusables
+ --> $DIR/lint-mixed-script-confusables.rs:10:5
+ |
+LL | mod роре {
+ | ^^^^
+ |
+ = note: the usage includes 'е' (U+0435), 'о' (U+043E), 'р' (U+0440)
+ = note: please recheck to make sure their usages are indeed what you want
+
+error: the usage of Script Group `Japanese, Katakana` in this crate consists solely of mixed script confusables
+ --> $DIR/lint-mixed-script-confusables.rs:12:11
+ |
+LL | const エ: &'static str = "アイウ";
+ | ^^
+ |
+ = note: the usage includes 'エ' (U+30A8)
+ = note: please recheck to make sure their usages are indeed what you want
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs
new file mode 100644
index 000000000..8ae174409
--- /dev/null
+++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs
@@ -0,0 +1,12 @@
+#![deny(non_ascii_idents)]
+
+const חלודה: usize = 2; //~ ERROR identifier contains non-ASCII characters
+
+fn coöperation() {} //~ ERROR identifier contains non-ASCII characters
+
+fn main() {
+ let naïveté = 2; //~ ERROR identifier contains non-ASCII characters
+
+ // using the same identifier the second time won't trigger the lint.
+ println!("{}", naïveté);
+}
diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr
new file mode 100644
index 000000000..8ed7f093c
--- /dev/null
+++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr
@@ -0,0 +1,26 @@
+error: identifier contains non-ASCII characters
+ --> $DIR/lint-non-ascii-idents.rs:3:7
+ |
+LL | const חלודה: usize = 2;
+ | ^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-non-ascii-idents.rs:1:9
+ |
+LL | #![deny(non_ascii_idents)]
+ | ^^^^^^^^^^^^^^^^
+
+error: identifier contains non-ASCII characters
+ --> $DIR/lint-non-ascii-idents.rs:5:4
+ |
+LL | fn coöperation() {}
+ | ^^^^^^^^^^^
+
+error: identifier contains non-ASCII characters
+ --> $DIR/lint-non-ascii-idents.rs:8:9
+ |
+LL | let naïveté = 2;
+ | ^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs
new file mode 100644
index 000000000..ed8e7dddd
--- /dev/null
+++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs
@@ -0,0 +1,13 @@
+#![deny(uncommon_codepoints)]
+
+const µ: f64 = 0.000001; //~ ERROR identifier contains uncommon Unicode codepoints
+//~| WARNING should have an upper case name
+
+fn dijkstra() {} //~ ERROR identifier contains uncommon Unicode codepoints
+
+fn main() {
+ let ㇻㇲㇳ = "rust"; //~ ERROR identifier contains uncommon Unicode codepoints
+
+ // using the same identifier the second time won't trigger the lint.
+ println!("{}", ㇻㇲㇳ);
+}
diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr
new file mode 100644
index 000000000..0533da030
--- /dev/null
+++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr
@@ -0,0 +1,34 @@
+error: identifier contains uncommon Unicode codepoints
+ --> $DIR/lint-uncommon-codepoints.rs:3:7
+ |
+LL | const µ: f64 = 0.000001;
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-uncommon-codepoints.rs:1:9
+ |
+LL | #![deny(uncommon_codepoints)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: identifier contains uncommon Unicode codepoints
+ --> $DIR/lint-uncommon-codepoints.rs:6:4
+ |
+LL | fn dijkstra() {}
+ | ^^^^^^^
+
+error: identifier contains uncommon Unicode codepoints
+ --> $DIR/lint-uncommon-codepoints.rs:9:9
+ |
+LL | let ㇻㇲㇳ = "rust";
+ | ^^^^^^
+
+warning: constant `µ` should have an upper case name
+ --> $DIR/lint-uncommon-codepoints.rs:3:7
+ |
+LL | const µ: f64 = 0.000001;
+ | ^ help: convert the identifier to upper case: `Μ`
+ |
+ = note: `#[warn(non_upper_case_globals)]` on by default
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
diff --git a/tests/ui/lint/rustdoc-group.rs b/tests/ui/lint/rustdoc-group.rs
new file mode 100644
index 000000000..130abe425
--- /dev/null
+++ b/tests/ui/lint/rustdoc-group.rs
@@ -0,0 +1,5 @@
+// check-pass
+// compile-flags: --crate-type lib
+#![deny(rustdoc)]
+//~^ WARNING removed: use `rustdoc::all`
+#![deny(rustdoc::all)] // has no effect when run with rustc directly
diff --git a/tests/ui/lint/rustdoc-group.stderr b/tests/ui/lint/rustdoc-group.stderr
new file mode 100644
index 000000000..fddc863ae
--- /dev/null
+++ b/tests/ui/lint/rustdoc-group.stderr
@@ -0,0 +1,10 @@
+warning: lint `rustdoc` has been removed: use `rustdoc::all` instead
+ --> $DIR/rustdoc-group.rs:3:9
+ |
+LL | #![deny(rustdoc)]
+ | ^^^^^^^
+ |
+ = note: `#[warn(renamed_and_removed_lints)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/rustdoc-renamed.rs b/tests/ui/lint/rustdoc-renamed.rs
new file mode 100644
index 000000000..ecd6155b7
--- /dev/null
+++ b/tests/ui/lint/rustdoc-renamed.rs
@@ -0,0 +1,15 @@
+#![crate_type = "lib"]
+
+#![deny(unknown_lints)]
+#![deny(renamed_and_removed_lints)]
+//~^ NOTE lint level is defined
+
+// both allowed, since the compiler doesn't yet know what rustdoc lints are valid
+#![deny(rustdoc::x)]
+#![deny(rustdoc::intra_doc_link_resolution_failure)]
+
+#![deny(intra_doc_link_resolution_failure)]
+//~^ ERROR removed: use `rustdoc::broken_intra_doc_links`
+#![deny(non_autolinks)]
+// FIXME: the old names for rustdoc lints should warn by default once `rustdoc::` makes it to the
+// stable channel.
diff --git a/tests/ui/lint/rustdoc-renamed.stderr b/tests/ui/lint/rustdoc-renamed.stderr
new file mode 100644
index 000000000..096e867aa
--- /dev/null
+++ b/tests/ui/lint/rustdoc-renamed.stderr
@@ -0,0 +1,14 @@
+error: lint `intra_doc_link_resolution_failure` has been removed: use `rustdoc::broken_intra_doc_links` instead
+ --> $DIR/rustdoc-renamed.rs:11:9
+ |
+LL | #![deny(intra_doc_link_resolution_failure)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/rustdoc-renamed.rs:4:9
+ |
+LL | #![deny(renamed_and_removed_lints)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs b/tests/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs
new file mode 100644
index 000000000..781391cc5
--- /dev/null
+++ b/tests/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs
@@ -0,0 +1,4 @@
+#[macro_export]
+macro_rules! my_macro {
+ () => { true; }
+}
diff --git a/tests/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs b/tests/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs
new file mode 100644
index 000000000..374506366
--- /dev/null
+++ b/tests/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs
@@ -0,0 +1,9 @@
+// aux-build:foreign-crate.rs
+// check-pass
+
+extern crate foreign_crate;
+
+// Test that we do not lint for a macro in a foreign crate
+fn main() {
+ let _ = foreign_crate::my_macro!();
+}
diff --git a/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.rs b/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.rs
new file mode 100644
index 000000000..fff380934
--- /dev/null
+++ b/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.rs
@@ -0,0 +1,51 @@
+// check-pass
+// edition:2018
+#![feature(stmt_expr_attributes)]
+#![warn(semicolon_in_expressions_from_macros)]
+
+#[allow(dead_code)]
+macro_rules! foo {
+ ($val:ident) => {
+ true; //~ WARN trailing semicolon in macro
+ //~| WARN this was previously accepted
+ //~| WARN trailing semicolon in macro
+ //~| WARN this was previously accepted
+ //~| WARN trailing semicolon in macro
+ //~| WARN this was previously accepted
+ }
+}
+
+#[allow(semicolon_in_expressions_from_macros)]
+async fn bar() {
+ foo!(first);
+}
+
+fn main() {
+ #[allow(semicolon_in_expressions_from_macros)]
+ let _ = {
+ foo!(first)
+ };
+
+ #[allow(semicolon_in_expressions_from_macros)]
+ let _ = foo!(second);
+
+ #[allow(semicolon_in_expressions_from_macros)]
+ fn inner() {
+ let _ = foo!(third);
+ }
+
+ #[allow(semicolon_in_expressions_from_macros)]
+ async {
+ let _ = foo!(fourth);
+ };
+
+ let _ = {
+ foo!(warn_in_block)
+ };
+
+ let _ = foo!(warn_in_expr);
+
+ // This `#[allow]` does not work, since the attribute gets dropped
+ // when we expand the macro
+ let _ = #[allow(semicolon_in_expressions_from_macros)] foo!(allow_does_not_work);
+}
diff --git a/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr b/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr
new file mode 100644
index 000000000..c60120061
--- /dev/null
+++ b/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr
@@ -0,0 +1,185 @@
+warning: trailing semicolon in macro used in expression position
+ --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+ |
+LL | true;
+ | ^
+...
+LL | foo!(warn_in_block)
+ | ------------------- in this macro invocation
+ |
+ = 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
+ = note: macro invocations at the end of a block are treated as expressions
+ = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
+note: the lint level is defined here
+ --> $DIR/semicolon-in-expressions-from-macros.rs:4:9
+ |
+LL | #![warn(semicolon_in_expressions_from_macros)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: trailing semicolon in macro used in expression position
+ --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+ |
+LL | true;
+ | ^
+...
+LL | let _ = foo!(warn_in_expr);
+ | ------------------ in this macro invocation
+ |
+ = 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
+ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: trailing semicolon in macro used in expression position
+ --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+ |
+LL | true;
+ | ^
+...
+LL | let _ = #[allow(semicolon_in_expressions_from_macros)] foo!(allow_does_not_work);
+ | ------------------------- in this macro invocation
+ |
+ = 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
+ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: 3 warnings emitted
+
+Future incompatibility report: Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+ --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+ |
+LL | true;
+ | ^
+...
+LL | foo!(first)
+ | ----------- in this macro invocation
+ |
+ = 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
+ = note: macro invocations at the end of a block are treated as expressions
+ = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
+note: the lint level is defined here
+ --> $DIR/semicolon-in-expressions-from-macros.rs:24:13
+ |
+LL | #[allow(semicolon_in_expressions_from_macros)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+ --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+ |
+LL | true;
+ | ^
+...
+LL | let _ = foo!(second);
+ | ------------ in this macro invocation
+ |
+ = 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
+note: the lint level is defined here
+ --> $DIR/semicolon-in-expressions-from-macros.rs:29:13
+ |
+LL | #[allow(semicolon_in_expressions_from_macros)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+ --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+ |
+LL | true;
+ | ^
+...
+LL | let _ = foo!(third);
+ | ----------- in this macro invocation
+ |
+ = 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
+note: the lint level is defined here
+ --> $DIR/semicolon-in-expressions-from-macros.rs:32:13
+ |
+LL | #[allow(semicolon_in_expressions_from_macros)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+ --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+ |
+LL | true;
+ | ^
+...
+LL | let _ = foo!(fourth);
+ | ------------ in this macro invocation
+ |
+ = 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
+note: the lint level is defined here
+ --> $DIR/semicolon-in-expressions-from-macros.rs:37:13
+ |
+LL | #[allow(semicolon_in_expressions_from_macros)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+ --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+ |
+LL | true;
+ | ^
+...
+LL | foo!(warn_in_block)
+ | ------------------- in this macro invocation
+ |
+ = 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
+ = note: macro invocations at the end of a block are treated as expressions
+ = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
+note: the lint level is defined here
+ --> $DIR/semicolon-in-expressions-from-macros.rs:4:9
+ |
+LL | #![warn(semicolon_in_expressions_from_macros)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+ --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+ |
+LL | true;
+ | ^
+...
+LL | let _ = foo!(warn_in_expr);
+ | ------------------ in this macro invocation
+ |
+ = 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
+note: the lint level is defined here
+ --> $DIR/semicolon-in-expressions-from-macros.rs:4:9
+ |
+LL | #![warn(semicolon_in_expressions_from_macros)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+ --> $DIR/semicolon-in-expressions-from-macros.rs:9:13
+ |
+LL | true;
+ | ^
+...
+LL | let _ = #[allow(semicolon_in_expressions_from_macros)] foo!(allow_does_not_work);
+ | ------------------------- in this macro invocation
+ |
+ = 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
+note: the lint level is defined here
+ --> $DIR/semicolon-in-expressions-from-macros.rs:4:9
+ |
+LL | #![warn(semicolon_in_expressions_from_macros)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/tests/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs b/tests/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs
new file mode 100644
index 000000000..2c63311e6
--- /dev/null
+++ b/tests/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs
@@ -0,0 +1,16 @@
+// check-pass
+// Ensure that trailing semicolons cause warnings by default
+
+macro_rules! foo {
+ () => {
+ true; //~ WARN trailing semicolon in macro
+ //~| WARN this was previously
+ }
+}
+
+fn main() {
+ let _val = match true {
+ true => false,
+ _ => foo!()
+ };
+}
diff --git a/tests/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr b/tests/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr
new file mode 100644
index 000000000..0fec4996f
--- /dev/null
+++ b/tests/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr
@@ -0,0 +1,31 @@
+warning: trailing semicolon in macro used in expression position
+ --> $DIR/warn-semicolon-in-expressions-from-macros.rs:6:13
+ |
+LL | true;
+ | ^
+...
+LL | _ => foo!()
+ | ------ in this macro invocation
+ |
+ = 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
+ = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
+ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: 1 warning emitted
+
+Future incompatibility report: Future breakage diagnostic:
+warning: trailing semicolon in macro used in expression position
+ --> $DIR/warn-semicolon-in-expressions-from-macros.rs:6:13
+ |
+LL | true;
+ | ^
+...
+LL | _ => foo!()
+ | ------ in this macro invocation
+ |
+ = 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
+ = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
+ = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/tests/ui/lint/special-upper-lower-cases.rs b/tests/ui/lint/special-upper-lower-cases.rs
new file mode 100644
index 000000000..761be61fa
--- /dev/null
+++ b/tests/ui/lint/special-upper-lower-cases.rs
@@ -0,0 +1,23 @@
+// (#77273) These characters are in the general categories of
+// "Uppercase/Lowercase Letter".
+// The diagnostics don't provide meaningful suggestions for them
+// as we cannot convert them properly.
+
+// check-pass
+
+#![allow(uncommon_codepoints, unused)]
+
+struct 𝕟𝕠𝕥𝕒𝕔𝕒𝕞𝕖𝕝;
+//~^ WARN: type `𝕟𝕠𝕥𝕒𝕔𝕒𝕞𝕖𝕝` should have an upper camel case name
+
+// FIXME: How we should handle this?
+struct 𝕟𝕠𝕥_𝕒_𝕔𝕒𝕞𝕖𝕝;
+//~^ WARN: type `𝕟𝕠𝕥_𝕒_𝕔𝕒𝕞𝕖𝕝` should have an upper camel case name
+
+static 𝗻𝗼𝗻𝘂𝗽𝗽𝗲𝗿𝗰𝗮𝘀𝗲: i32 = 1;
+//~^ WARN: static variable `𝗻𝗼𝗻𝘂𝗽𝗽𝗲𝗿𝗰𝗮𝘀𝗲` should have an upper case name
+
+fn main() {
+ let 𝓢𝓝𝓐𝓐𝓐𝓐𝓚𝓔𝓢 = 1;
+ //~^ WARN: variable `𝓢𝓝𝓐𝓐𝓐𝓐𝓚𝓔𝓢` should have a snake case name
+}
diff --git a/tests/ui/lint/special-upper-lower-cases.stderr b/tests/ui/lint/special-upper-lower-cases.stderr
new file mode 100644
index 000000000..2aa13c33b
--- /dev/null
+++ b/tests/ui/lint/special-upper-lower-cases.stderr
@@ -0,0 +1,32 @@
+warning: type `𝕟𝕠𝕥𝕒𝕔𝕒𝕞𝕖𝕝` should have an upper camel case name
+ --> $DIR/special-upper-lower-cases.rs:10:8
+ |
+LL | struct 𝕟𝕠𝕥𝕒𝕔𝕒𝕞𝕖𝕝;
+ | ^^^^^^^^^ should have an UpperCamelCase name
+ |
+ = note: `#[warn(non_camel_case_types)]` on by default
+
+warning: type `𝕟𝕠𝕥_𝕒_𝕔𝕒𝕞𝕖𝕝` should have an upper camel case name
+ --> $DIR/special-upper-lower-cases.rs:14:8
+ |
+LL | struct 𝕟𝕠𝕥_𝕒_𝕔𝕒𝕞𝕖𝕝;
+ | ^^^^^^^^^^^ should have an UpperCamelCase name
+
+warning: static variable `𝗻𝗼𝗻𝘂𝗽𝗽𝗲𝗿𝗰𝗮𝘀𝗲` should have an upper case name
+ --> $DIR/special-upper-lower-cases.rs:17:8
+ |
+LL | static 𝗻𝗼𝗻𝘂𝗽𝗽𝗲𝗿𝗰𝗮𝘀𝗲: i32 = 1;
+ | ^^^^^^^^^^^^ should have an UPPER_CASE name
+ |
+ = note: `#[warn(non_upper_case_globals)]` on by default
+
+warning: variable `𝓢𝓝𝓐𝓐𝓐𝓐𝓚𝓔𝓢` should have a snake case name
+ --> $DIR/special-upper-lower-cases.rs:21:9
+ |
+LL | let 𝓢𝓝𝓐𝓐𝓐𝓐𝓚𝓔𝓢 = 1;
+ | ^^^^^^^^^ should have a snake_case name
+ |
+ = note: `#[warn(non_snake_case)]` on by default
+
+warning: 4 warnings emitted
+
diff --git a/tests/ui/lint/suggestions.fixed b/tests/ui/lint/suggestions.fixed
new file mode 100644
index 000000000..35851690b
--- /dev/null
+++ b/tests/ui/lint/suggestions.fixed
@@ -0,0 +1,66 @@
+// ignore-tidy-tab
+// run-rustfix
+
+#![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
+
+#[no_mangle] pub static DISCOVERY: usize = 1;
+//~^ ERROR const items should never be `#[no_mangle]`
+//~| HELP try a static value
+
+
+//~^ HELP remove this attribute
+pub fn defiant<T>(_t: T) {}
+//~^ WARN functions generic over types or consts must be mangled
+
+#[no_mangle]
+fn rio_grande() {}
+
+mod badlands {
+ // The private-no-mangle lints shouldn't suggest inserting `pub` when the
+ // item is already `pub` (but triggered the lint because, e.g., it's in a
+ // private module). (Issue #47383)
+ #[no_mangle] pub static DAUNTLESS: bool = true;
+ //~^ ERROR const items should never be `#[no_mangle]`
+ //~| HELP try a static value
+ #[allow(dead_code)] // for rustfix
+ pub fn val_jean<T>() {}
+ //~^ WARN functions generic over types or consts must be mangled
+ //~| HELP remove this attribute
+
+ // ... but we can suggest just-`pub` instead of restricted
+ #[no_mangle] pub static VETAR: bool = true;
+ //~^ ERROR const items should never be `#[no_mangle]`
+ //~| HELP try a static value
+ #[allow(dead_code)] // for rustfix
+ pub(crate) fn crossfield<T>() {}
+ //~^ WARN functions generic over types or consts must be mangled
+ //~| HELP remove this attribute
+}
+
+struct Equinox {
+ warp_factor: f32,
+}
+
+fn main() {
+ loop {
+ //~^ WARN denote infinite loops
+ //~| HELP use `loop`
+ let registry_no = format!("NX-{}", 74205);
+ //~^ WARN does not need to be mutable
+ //~| HELP remove this `mut`
+ //~| WARN unnecessary parentheses
+ //~| HELP remove these parentheses
+ // the line after `mut` has a `\t` at the beginning, this is on purpose
+ let b = 1;
+ //~^^ WARN does not need to be mutable
+ //~| HELP remove this `mut`
+ let d = Equinox { warp_factor: 9.975 };
+ match d {
+ #[allow(unused_variables)] // for rustfix
+ Equinox { warp_factor } => {}
+ //~^ WARN this pattern is redundant
+ //~| HELP use shorthand field pattern
+ }
+ println!("{} {}", registry_no, b);
+ }
+}
diff --git a/tests/ui/lint/suggestions.rs b/tests/ui/lint/suggestions.rs
new file mode 100644
index 000000000..be6f0d6b3
--- /dev/null
+++ b/tests/ui/lint/suggestions.rs
@@ -0,0 +1,67 @@
+// ignore-tidy-tab
+// run-rustfix
+
+#![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
+
+#[no_mangle] const DISCOVERY: usize = 1;
+//~^ ERROR const items should never be `#[no_mangle]`
+//~| HELP try a static value
+
+#[no_mangle]
+//~^ HELP remove this attribute
+pub fn defiant<T>(_t: T) {}
+//~^ WARN functions generic over types or consts must be mangled
+
+#[no_mangle]
+fn rio_grande() {}
+
+mod badlands {
+ // The private-no-mangle lints shouldn't suggest inserting `pub` when the
+ // item is already `pub` (but triggered the lint because, e.g., it's in a
+ // private module). (Issue #47383)
+ #[no_mangle] pub const DAUNTLESS: bool = true;
+ //~^ ERROR const items should never be `#[no_mangle]`
+ //~| HELP try a static value
+ #[allow(dead_code)] // for rustfix
+ #[no_mangle] pub fn val_jean<T>() {}
+ //~^ WARN functions generic over types or consts must be mangled
+ //~| HELP remove this attribute
+
+ // ... but we can suggest just-`pub` instead of restricted
+ #[no_mangle] pub(crate) const VETAR: bool = true;
+ //~^ ERROR const items should never be `#[no_mangle]`
+ //~| HELP try a static value
+ #[allow(dead_code)] // for rustfix
+ #[no_mangle] pub(crate) fn crossfield<T>() {}
+ //~^ WARN functions generic over types or consts must be mangled
+ //~| HELP remove this attribute
+}
+
+struct Equinox {
+ warp_factor: f32,
+}
+
+fn main() {
+ while true {
+ //~^ WARN denote infinite loops
+ //~| HELP use `loop`
+ let mut registry_no = (format!("NX-{}", 74205));
+ //~^ WARN does not need to be mutable
+ //~| HELP remove this `mut`
+ //~| WARN unnecessary parentheses
+ //~| HELP remove these parentheses
+ // the line after `mut` has a `\t` at the beginning, this is on purpose
+ let mut
+ b = 1;
+ //~^^ WARN does not need to be mutable
+ //~| HELP remove this `mut`
+ let d = Equinox { warp_factor: 9.975 };
+ match d {
+ #[allow(unused_variables)] // for rustfix
+ Equinox { warp_factor: warp_factor } => {}
+ //~^ WARN this pattern is redundant
+ //~| HELP use shorthand field pattern
+ }
+ println!("{} {}", registry_no, b);
+ }
+}
diff --git a/tests/ui/lint/suggestions.stderr b/tests/ui/lint/suggestions.stderr
new file mode 100644
index 000000000..4caee777a
--- /dev/null
+++ b/tests/ui/lint/suggestions.stderr
@@ -0,0 +1,114 @@
+warning: denote infinite loops with `loop { ... }`
+ --> $DIR/suggestions.rs:45:5
+ |
+LL | while true {
+ | ^^^^^^^^^^ help: use `loop`
+ |
+ = note: `#[warn(while_true)]` on by default
+
+warning: unnecessary parentheses around assigned value
+ --> $DIR/suggestions.rs:48:31
+ |
+LL | let mut registry_no = (format!("NX-{}", 74205));
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/suggestions.rs:4:21
+ |
+LL | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - let mut registry_no = (format!("NX-{}", 74205));
+LL + let mut registry_no = format!("NX-{}", 74205);
+ |
+
+warning: variable does not need to be mutable
+ --> $DIR/suggestions.rs:48:13
+ |
+LL | let mut registry_no = (format!("NX-{}", 74205));
+ | ----^^^^^^^^^^^
+ | |
+ | help: remove this `mut`
+ |
+note: the lint level is defined here
+ --> $DIR/suggestions.rs:4:9
+ |
+LL | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
+ | ^^^^^^^^^^
+
+warning: variable does not need to be mutable
+ --> $DIR/suggestions.rs:54:13
+ |
+LL | let mut
+ | ______________^
+ | | _____________|
+ | ||
+LL | || b = 1;
+ | ||____________-^
+ | |_____________|
+ | help: remove this `mut`
+
+error: const items should never be `#[no_mangle]`
+ --> $DIR/suggestions.rs:6:14
+ |
+LL | #[no_mangle] const DISCOVERY: usize = 1;
+ | -----^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | help: try a static value: `pub static`
+ |
+ = note: `#[deny(no_mangle_const_items)]` on by default
+
+warning: functions generic over types or consts must be mangled
+ --> $DIR/suggestions.rs:12:1
+ |
+LL | #[no_mangle]
+ | ------------ help: remove this attribute
+LL |
+LL | pub fn defiant<T>(_t: T) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(no_mangle_generic_items)]` on by default
+
+warning: the `warp_factor:` in this pattern is redundant
+ --> $DIR/suggestions.rs:61:23
+ |
+LL | Equinox { warp_factor: warp_factor } => {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use shorthand field pattern: `warp_factor`
+ |
+ = note: `#[warn(non_shorthand_field_patterns)]` on by default
+
+error: const items should never be `#[no_mangle]`
+ --> $DIR/suggestions.rs:22:18
+ |
+LL | #[no_mangle] pub const DAUNTLESS: bool = true;
+ | ---------^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | help: try a static value: `pub static`
+
+warning: functions generic over types or consts must be mangled
+ --> $DIR/suggestions.rs:26:18
+ |
+LL | #[no_mangle] pub fn val_jean<T>() {}
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | help: remove this attribute
+
+error: const items should never be `#[no_mangle]`
+ --> $DIR/suggestions.rs:31:18
+ |
+LL | #[no_mangle] pub(crate) const VETAR: bool = true;
+ | ----------------^^^^^^^^^^^^^^^^^^^^
+ | |
+ | help: try a static value: `pub static`
+
+warning: functions generic over types or consts must be mangled
+ --> $DIR/suggestions.rs:35:18
+ |
+LL | #[no_mangle] pub(crate) fn crossfield<T>() {}
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | help: remove this attribute
+
+error: aborting due to 3 previous errors; 8 warnings emitted
+
diff --git a/tests/ui/lint/test-allow-dead-extern-static-no-warning.rs b/tests/ui/lint/test-allow-dead-extern-static-no-warning.rs
new file mode 100644
index 000000000..2583e431e
--- /dev/null
+++ b/tests/ui/lint/test-allow-dead-extern-static-no-warning.rs
@@ -0,0 +1,11 @@
+// run-pass
+// compile-flags: --test
+
+#![deny(dead_code)]
+
+extern "C" {
+ #[allow(dead_code)]
+ static Qt: u64;
+}
+
+fn main() {}
diff --git a/tests/ui/lint/test-inner-fn.rs b/tests/ui/lint/test-inner-fn.rs
new file mode 100644
index 000000000..d419cc6fa
--- /dev/null
+++ b/tests/ui/lint/test-inner-fn.rs
@@ -0,0 +1,19 @@
+// compile-flags: --test -D unnameable_test_items
+
+#[test]
+fn foo() {
+ #[test] //~ ERROR cannot test inner items [unnameable_test_items]
+ fn bar() {}
+ bar();
+}
+
+mod x {
+ #[test]
+ fn foo() {
+ #[test] //~ ERROR cannot test inner items [unnameable_test_items]
+ fn bar() {}
+ bar();
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/test-inner-fn.stderr b/tests/ui/lint/test-inner-fn.stderr
new file mode 100644
index 000000000..7a32bc86b
--- /dev/null
+++ b/tests/ui/lint/test-inner-fn.stderr
@@ -0,0 +1,19 @@
+error: cannot test inner items
+ --> $DIR/test-inner-fn.rs:5:5
+ |
+LL | #[test]
+ | ^^^^^^^
+ |
+ = note: requested on the command line with `-D unnameable-test-items`
+ = note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: cannot test inner items
+ --> $DIR/test-inner-fn.rs:13:9
+ |
+LL | #[test]
+ | ^^^^^^^
+ |
+ = note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/trivial-cast-ice.rs b/tests/ui/lint/trivial-cast-ice.rs
new file mode 100644
index 000000000..f781fab22
--- /dev/null
+++ b/tests/ui/lint/trivial-cast-ice.rs
@@ -0,0 +1,12 @@
+// aux-build:trivial-cast-ice.rs
+// check-pass
+
+// Demonstrates the ICE in #102561
+
+#![deny(trivial_casts)]
+
+extern crate trivial_cast_ice;
+
+fn main() {
+ trivial_cast_ice::foo!();
+}
diff --git a/tests/ui/lint/trivial-casts-featuring-type-ascription.rs b/tests/ui/lint/trivial-casts-featuring-type-ascription.rs
new file mode 100644
index 000000000..96bf2dcfb
--- /dev/null
+++ b/tests/ui/lint/trivial-casts-featuring-type-ascription.rs
@@ -0,0 +1,10 @@
+#![deny(trivial_casts, trivial_numeric_casts)]
+#![feature(type_ascription)]
+
+fn main() {
+ let lugubrious = 12i32 as i32;
+ //~^ ERROR trivial numeric cast
+ let haunted: &u32 = &99;
+ let _ = haunted as *const u32;
+ //~^ ERROR trivial cast
+}
diff --git a/tests/ui/lint/trivial-casts-featuring-type-ascription.stderr b/tests/ui/lint/trivial-casts-featuring-type-ascription.stderr
new file mode 100644
index 000000000..5087807b6
--- /dev/null
+++ b/tests/ui/lint/trivial-casts-featuring-type-ascription.stderr
@@ -0,0 +1,28 @@
+error: trivial numeric cast: `i32` as `i32`
+ --> $DIR/trivial-casts-featuring-type-ascription.rs:5:22
+ |
+LL | let lugubrious = 12i32 as i32;
+ | ^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require type ascription or a temporary variable
+note: the lint level is defined here
+ --> $DIR/trivial-casts-featuring-type-ascription.rs:1:24
+ |
+LL | #![deny(trivial_casts, trivial_numeric_casts)]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: trivial cast: `&u32` as `*const u32`
+ --> $DIR/trivial-casts-featuring-type-ascription.rs:8:13
+ |
+LL | let _ = haunted as *const u32;
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require type ascription or a temporary variable
+note: the lint level is defined here
+ --> $DIR/trivial-casts-featuring-type-ascription.rs:1:9
+ |
+LL | #![deny(trivial_casts, trivial_numeric_casts)]
+ | ^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/trivial-casts.rs b/tests/ui/lint/trivial-casts.rs
new file mode 100644
index 000000000..b17de624a
--- /dev/null
+++ b/tests/ui/lint/trivial-casts.rs
@@ -0,0 +1,9 @@
+#![deny(trivial_casts, trivial_numeric_casts)]
+
+fn main() {
+ let lugubrious = 12i32 as i32;
+ //~^ ERROR trivial numeric cast
+ let haunted: &u32 = &99;
+ let _ = haunted as *const u32;
+ //~^ ERROR trivial cast
+}
diff --git a/tests/ui/lint/trivial-casts.stderr b/tests/ui/lint/trivial-casts.stderr
new file mode 100644
index 000000000..7ace353de
--- /dev/null
+++ b/tests/ui/lint/trivial-casts.stderr
@@ -0,0 +1,28 @@
+error: trivial numeric cast: `i32` as `i32`
+ --> $DIR/trivial-casts.rs:4:22
+ |
+LL | let lugubrious = 12i32 as i32;
+ | ^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+note: the lint level is defined here
+ --> $DIR/trivial-casts.rs:1:24
+ |
+LL | #![deny(trivial_casts, trivial_numeric_casts)]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: trivial cast: `&u32` as `*const u32`
+ --> $DIR/trivial-casts.rs:7:13
+ |
+LL | let _ = haunted as *const u32;
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+note: the lint level is defined here
+ --> $DIR/trivial-casts.rs:1:9
+ |
+LL | #![deny(trivial_casts, trivial_numeric_casts)]
+ | ^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/trivial_casts.rs b/tests/ui/lint/trivial_casts.rs
new file mode 100644
index 000000000..0a8b9de1d
--- /dev/null
+++ b/tests/ui/lint/trivial_casts.rs
@@ -0,0 +1,85 @@
+// Test the trivial_casts and trivial_numeric_casts lints. For each error we also
+// check that the cast can be done using just coercion.
+
+#![deny(trivial_casts, trivial_numeric_casts)]
+
+trait Foo {
+ fn foo(&self) {}
+}
+
+pub struct Bar;
+
+impl Foo for Bar {}
+
+pub fn main() {
+ // Numeric
+ let _ = 42_i32 as i32; //~ ERROR trivial numeric cast: `i32` as `i32`
+ let _: i32 = 42_i32;
+
+ let _ = 42_u8 as u8; //~ ERROR trivial numeric cast: `u8` as `u8`
+ let _: u8 = 42_u8;
+
+ // & to * pointers
+ let x: &u32 = &42;
+ let _ = x as *const u32; //~ERROR trivial cast: `&u32` as `*const u32`
+ let _: *const u32 = x;
+
+ let x: &mut u32 = &mut 42;
+ let _ = x as *mut u32; //~ERROR trivial cast: `&mut u32` as `*mut u32`
+ let _: *mut u32 = x;
+
+ // unsize array
+ let x: &[u32; 3] = &[42, 43, 44];
+ let _ = x as &[u32]; //~ERROR trivial cast: `&[u32; 3]` as `&[u32]`
+ let _ = x as *const [u32]; //~ERROR trivial cast: `&[u32; 3]` as `*const [u32]`
+ let _: &[u32] = x;
+ let _: *const [u32] = x;
+
+ let x: &mut [u32; 3] = &mut [42, 43, 44];
+ let _ = x as &mut [u32]; //~ERROR trivial cast: `&mut [u32; 3]` as `&mut [u32]`
+ let _ = x as *mut [u32]; //~ERROR trivial cast: `&mut [u32; 3]` as `*mut [u32]`
+ let _: &mut [u32] = x;
+ let _: *mut [u32] = x;
+
+ let x: Box<[u32; 3]> = Box::new([42, 43, 44]);
+ let _ = x as Box<[u32]>;
+ //~^ ERROR trivial cast: `Box<[u32; 3]>` as `Box<[u32]>`
+ let x: Box<[u32; 3]> = Box::new([42, 43, 44]);
+ let _: Box<[u32]> = x;
+
+ // unsize trait
+ let x: &Bar = &Bar;
+ let _ = x as &dyn Foo; //~ERROR trivial cast: `&Bar` as `&dyn Foo`
+ let _ = x as *const dyn Foo; //~ERROR trivial cast: `&Bar` as `*const dyn Foo`
+ let _: &dyn Foo = x;
+ let _: *const dyn Foo = x;
+
+ let x: &mut Bar = &mut Bar;
+ let _ = x as &mut dyn Foo; //~ERROR trivial cast: `&mut Bar` as `&mut dyn Foo`
+ let _ = x as *mut dyn Foo; //~ERROR trivial cast: `&mut Bar` as `*mut dyn Foo`
+ let _: &mut dyn Foo = x;
+ let _: *mut dyn Foo = x;
+
+ let x: Box<Bar> = Box::new(Bar);
+ let _ = x as Box<dyn Foo>; //~ERROR `Box<Bar>` as `Box<dyn Foo>`
+ let x: Box<Bar> = Box::new(Bar);
+ let _: Box<dyn Foo> = x;
+
+ // functions
+ fn baz(_x: i32) {}
+ let _ = &baz as &dyn Fn(i32); //~ERROR `&fn(i32) {baz}` as `&dyn Fn(i32)`
+ let _: &dyn Fn(i32) = &baz;
+ let x = |_x: i32| {};
+ let _ = &x as &dyn Fn(i32); //~ERROR trivial cast
+ let _: &dyn Fn(i32) = &x;
+}
+
+// subtyping
+pub fn test_subtyping<'a, 'b: 'a>(a: &'a Bar, b: &'b Bar) {
+ let _ = a as &'a Bar; //~ERROR trivial cast
+ let _: &'a Bar = a;
+ let _ = b as &'a Bar; //~ERROR trivial cast
+ let _: &'a Bar = b;
+ let _ = b as &'b Bar; //~ERROR trivial cast
+ let _: &'b Bar = b;
+}
diff --git a/tests/ui/lint/trivial_casts.stderr b/tests/ui/lint/trivial_casts.stderr
new file mode 100644
index 000000000..74f962835
--- /dev/null
+++ b/tests/ui/lint/trivial_casts.stderr
@@ -0,0 +1,164 @@
+error: trivial numeric cast: `i32` as `i32`
+ --> $DIR/trivial_casts.rs:16:13
+ |
+LL | let _ = 42_i32 as i32;
+ | ^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+note: the lint level is defined here
+ --> $DIR/trivial_casts.rs:4:24
+ |
+LL | #![deny(trivial_casts, trivial_numeric_casts)]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: trivial numeric cast: `u8` as `u8`
+ --> $DIR/trivial_casts.rs:19:13
+ |
+LL | let _ = 42_u8 as u8;
+ | ^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `&u32` as `*const u32`
+ --> $DIR/trivial_casts.rs:24:13
+ |
+LL | let _ = x as *const u32;
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+note: the lint level is defined here
+ --> $DIR/trivial_casts.rs:4:9
+ |
+LL | #![deny(trivial_casts, trivial_numeric_casts)]
+ | ^^^^^^^^^^^^^
+
+error: trivial cast: `&mut u32` as `*mut u32`
+ --> $DIR/trivial_casts.rs:28:13
+ |
+LL | let _ = x as *mut u32;
+ | ^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `&[u32; 3]` as `&[u32]`
+ --> $DIR/trivial_casts.rs:33:13
+ |
+LL | let _ = x as &[u32];
+ | ^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `&[u32; 3]` as `*const [u32]`
+ --> $DIR/trivial_casts.rs:34:13
+ |
+LL | let _ = x as *const [u32];
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `&mut [u32; 3]` as `&mut [u32]`
+ --> $DIR/trivial_casts.rs:39:13
+ |
+LL | let _ = x as &mut [u32];
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `&mut [u32; 3]` as `*mut [u32]`
+ --> $DIR/trivial_casts.rs:40:13
+ |
+LL | let _ = x as *mut [u32];
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `Box<[u32; 3]>` as `Box<[u32]>`
+ --> $DIR/trivial_casts.rs:45:13
+ |
+LL | let _ = x as Box<[u32]>;
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `&Bar` as `&dyn Foo`
+ --> $DIR/trivial_casts.rs:52:13
+ |
+LL | let _ = x as &dyn Foo;
+ | ^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `&Bar` as `*const dyn Foo`
+ --> $DIR/trivial_casts.rs:53:13
+ |
+LL | let _ = x as *const dyn Foo;
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `&mut Bar` as `&mut dyn Foo`
+ --> $DIR/trivial_casts.rs:58:13
+ |
+LL | let _ = x as &mut dyn Foo;
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `&mut Bar` as `*mut dyn Foo`
+ --> $DIR/trivial_casts.rs:59:13
+ |
+LL | let _ = x as *mut dyn Foo;
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `Box<Bar>` as `Box<dyn Foo>`
+ --> $DIR/trivial_casts.rs:64:13
+ |
+LL | let _ = x as Box<dyn Foo>;
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `&fn(i32) {baz}` as `&dyn Fn(i32)`
+ --> $DIR/trivial_casts.rs:70:13
+ |
+LL | let _ = &baz as &dyn Fn(i32);
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `&[closure@$DIR/trivial_casts.rs:72:13: 72:22]` as `&dyn Fn(i32)`
+ --> $DIR/trivial_casts.rs:73:13
+ |
+LL | let _ = &x as &dyn Fn(i32);
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `&'a Bar` as `&'a Bar`
+ --> $DIR/trivial_casts.rs:79:13
+ |
+LL | let _ = a as &'a Bar;
+ | ^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `&'b Bar` as `&'a Bar`
+ --> $DIR/trivial_casts.rs:81:13
+ |
+LL | let _ = b as &'a Bar;
+ | ^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: trivial cast: `&'b Bar` as `&'b Bar`
+ --> $DIR/trivial_casts.rs:83:13
+ |
+LL | let _ = b as &'b Bar;
+ | ^^^^^^^^^^^^
+ |
+ = help: cast can be replaced by coercion; this might require a temporary variable
+
+error: aborting due to 19 previous errors
+
diff --git a/tests/ui/lint/type-overflow.rs b/tests/ui/lint/type-overflow.rs
new file mode 100644
index 000000000..6234b794c
--- /dev/null
+++ b/tests/ui/lint/type-overflow.rs
@@ -0,0 +1,22 @@
+// check-pass
+#![warn(overflowing_literals)]
+
+fn main() {
+ let error = 255i8; //~WARNING literal out of range for `i8`
+
+ let ok = 0b1000_0001; // should be ok -> i32
+ let ok = 0b0111_1111i8; // should be ok -> 127i8
+
+ let fail = 0b1000_0001i8; //~WARNING literal out of range for `i8`
+
+ let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for `i64`
+
+ let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for `u32`
+
+ let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000;
+ //~^ WARNING literal out of range for `i128`
+
+ let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for `i32`
+
+ let fail = -0b1111_1111i8; //~WARNING literal out of range for `i8`
+}
diff --git a/tests/ui/lint/type-overflow.stderr b/tests/ui/lint/type-overflow.stderr
new file mode 100644
index 000000000..62cb1f7f4
--- /dev/null
+++ b/tests/ui/lint/type-overflow.stderr
@@ -0,0 +1,67 @@
+warning: literal out of range for `i8`
+ --> $DIR/type-overflow.rs:5:17
+ |
+LL | let error = 255i8;
+ | ^^^^^
+ |
+ = note: the literal `255i8` does not fit into the type `i8` whose range is `-128..=127`
+ = help: consider using the type `u8` instead
+note: the lint level is defined here
+ --> $DIR/type-overflow.rs:2:9
+ |
+LL | #![warn(overflowing_literals)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+warning: literal out of range for `i8`
+ --> $DIR/type-overflow.rs:10:16
+ |
+LL | let fail = 0b1000_0001i8;
+ | ^^^^^^^^^^^^^ help: consider using the type `u8` instead: `0b1000_0001u8`
+ |
+ = note: the literal `0b1000_0001i8` (decimal `129`) does not fit into the type `i8` and will become `-127i8`
+
+warning: literal out of range for `i64`
+ --> $DIR/type-overflow.rs:12:16
+ |
+LL | let fail = 0x8000_0000_0000_0000i64;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the type `u64` instead: `0x8000_0000_0000_0000u64`
+ |
+ = note: the literal `0x8000_0000_0000_0000i64` (decimal `9223372036854775808`) does not fit into the type `i64` and will become `-9223372036854775808i64`
+
+warning: literal out of range for `u32`
+ --> $DIR/type-overflow.rs:14:16
+ |
+LL | let fail = 0x1_FFFF_FFFFu32;
+ | ^^^^^^^^^^^^^^^^ help: consider using the type `u64` instead: `0x1_FFFF_FFFFu64`
+ |
+ = note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into the type `u32` and will become `4294967295u32`
+
+warning: literal out of range for `i128`
+ --> $DIR/type-overflow.rs:16:22
+ |
+LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into the type `i128` and will become `-170141183460469231731687303715884105728i128`
+ = help: consider using the type `u128` instead
+
+warning: literal out of range for `i32`
+ --> $DIR/type-overflow.rs:19:16
+ |
+LL | let fail = 0x8FFF_FFFF_FFFF_FFFE;
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into the type `i32` and will become `-2i32`
+ = help: consider using the type `i128` instead
+
+warning: literal out of range for `i8`
+ --> $DIR/type-overflow.rs:21:17
+ |
+LL | let fail = -0b1111_1111i8;
+ | ^^^^^^^^^^^^^ help: consider using the type `i16` instead: `0b1111_1111i16`
+ |
+ = note: the literal `0b1111_1111i8` (decimal `255`) does not fit into the type `i8`
+ = note: and the value `-0b1111_1111i8` will become `1i8`
+
+warning: 7 warnings emitted
+
diff --git a/tests/ui/lint/unaligned_references.rs b/tests/ui/lint/unaligned_references.rs
new file mode 100644
index 000000000..e547f031a
--- /dev/null
+++ b/tests/ui/lint/unaligned_references.rs
@@ -0,0 +1,103 @@
+#![deny(unaligned_references)]
+
+#[repr(packed)]
+pub struct Good {
+ data: u64,
+ ptr: &'static u64,
+ data2: [u64; 2],
+ aligned: [u8; 32],
+}
+
+#[repr(packed(2))]
+pub struct Packed2 {
+ x: u32,
+ y: u16,
+ z: u8,
+}
+
+fn main() {
+ unsafe {
+ let good = Good { data: 0, ptr: &0, data2: [0, 0], aligned: [0; 32] };
+
+ let _ = &good.ptr; //~ ERROR reference to packed field
+ //~^ previously accepted
+ let _ = &good.data; //~ ERROR reference to packed field
+ //~^ previously accepted
+ // Error even when turned into raw pointer immediately.
+ let _ = &good.data as *const _; //~ ERROR reference to packed field
+ //~^ previously accepted
+ let _: *const _ = &good.data; //~ ERROR reference to packed field
+ //~^ previously accepted
+ // Error on method call.
+ let _ = good.data.clone(); //~ ERROR reference to packed field
+ //~^ previously accepted
+ // Error for nested fields.
+ let _ = &good.data2[0]; //~ ERROR reference to packed field
+ //~^ previously accepted
+
+ let _ = &*good.ptr; // ok, behind a pointer
+ let _ = &good.aligned; // ok, has align 1
+ let _ = &good.aligned[2]; // ok, has align 1
+ }
+
+ unsafe {
+ let packed2 = Packed2 { x: 0, y: 0, z: 0 };
+ let _ = &packed2.x; //~ ERROR reference to packed field
+ //~^ previously accepted
+ let _ = &packed2.y; // ok, has align 2 in packed(2) struct
+ let _ = &packed2.z; // ok, has align 1
+ }
+
+ unsafe {
+ struct U16(u16);
+
+ impl Drop for U16 {
+ fn drop(&mut self) {
+ println!("{:p}", self);
+ }
+ }
+
+ struct HasDrop;
+
+ impl Drop for HasDrop {
+ fn drop(&mut self) {}
+ }
+
+ #[allow(unused)]
+ struct Wrapper {
+ a: U16,
+ b: HasDrop,
+ }
+ #[allow(unused)]
+ #[repr(packed(2))]
+ struct Wrapper2 {
+ a: U16,
+ b: HasDrop,
+ }
+
+ // An outer struct with more restrictive packing than the inner struct -- make sure we
+ // notice that!
+ #[repr(packed)]
+ struct Misalign<T>(u8, T);
+
+ let m1 = Misalign(
+ 0,
+ Wrapper {
+ a: U16(10),
+ b: HasDrop,
+ },
+ );
+ let _ref = &m1.1.a; //~ ERROR reference to packed field
+ //~^ previously accepted
+
+ let m2 = Misalign(
+ 0,
+ Wrapper2 {
+ a: U16(10),
+ b: HasDrop,
+ },
+ );
+ let _ref = &m2.1.a; //~ ERROR reference to packed field
+ //~^ previously accepted
+ }
+}
diff --git a/tests/ui/lint/unaligned_references.stderr b/tests/ui/lint/unaligned_references.stderr
new file mode 100644
index 000000000..346f49b92
--- /dev/null
+++ b/tests/ui/lint/unaligned_references.stderr
@@ -0,0 +1,259 @@
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:22:17
+ |
+LL | let _ = &good.ptr;
+ | ^^^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+note: the lint level is defined here
+ --> $DIR/unaligned_references.rs:1:9
+ |
+LL | #![deny(unaligned_references)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:24:17
+ |
+LL | let _ = &good.data;
+ | ^^^^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:27:17
+ |
+LL | let _ = &good.data as *const _;
+ | ^^^^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:29:27
+ |
+LL | let _: *const _ = &good.data;
+ | ^^^^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:32:17
+ |
+LL | let _ = good.data.clone();
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:35:17
+ |
+LL | let _ = &good.data2[0];
+ | ^^^^^^^^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:45:17
+ |
+LL | let _ = &packed2.x;
+ | ^^^^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:90:20
+ |
+LL | let _ref = &m1.1.a;
+ | ^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:100:20
+ |
+LL | let _ref = &m2.1.a;
+ | ^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+error: aborting due to 9 previous errors
+
+Future incompatibility report: Future breakage diagnostic:
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:22:17
+ |
+LL | let _ = &good.ptr;
+ | ^^^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+note: the lint level is defined here
+ --> $DIR/unaligned_references.rs:1:9
+ |
+LL | #![deny(unaligned_references)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:24:17
+ |
+LL | let _ = &good.data;
+ | ^^^^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+note: the lint level is defined here
+ --> $DIR/unaligned_references.rs:1:9
+ |
+LL | #![deny(unaligned_references)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:27:17
+ |
+LL | let _ = &good.data as *const _;
+ | ^^^^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+note: the lint level is defined here
+ --> $DIR/unaligned_references.rs:1:9
+ |
+LL | #![deny(unaligned_references)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:29:27
+ |
+LL | let _: *const _ = &good.data;
+ | ^^^^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+note: the lint level is defined here
+ --> $DIR/unaligned_references.rs:1:9
+ |
+LL | #![deny(unaligned_references)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:32:17
+ |
+LL | let _ = good.data.clone();
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+note: the lint level is defined here
+ --> $DIR/unaligned_references.rs:1:9
+ |
+LL | #![deny(unaligned_references)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:35:17
+ |
+LL | let _ = &good.data2[0];
+ | ^^^^^^^^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+note: the lint level is defined here
+ --> $DIR/unaligned_references.rs:1:9
+ |
+LL | #![deny(unaligned_references)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:45:17
+ |
+LL | let _ = &packed2.x;
+ | ^^^^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+note: the lint level is defined here
+ --> $DIR/unaligned_references.rs:1:9
+ |
+LL | #![deny(unaligned_references)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:90:20
+ |
+LL | let _ref = &m1.1.a;
+ | ^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+note: the lint level is defined here
+ --> $DIR/unaligned_references.rs:1:9
+ |
+LL | #![deny(unaligned_references)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references.rs:100:20
+ |
+LL | let _ref = &m2.1.a;
+ | ^^^^^^^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+note: the lint level is defined here
+ --> $DIR/unaligned_references.rs:1:9
+ |
+LL | #![deny(unaligned_references)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/lint/unaligned_references_external_macro.rs b/tests/ui/lint/unaligned_references_external_macro.rs
new file mode 100644
index 000000000..cb597c38e
--- /dev/null
+++ b/tests/ui/lint/unaligned_references_external_macro.rs
@@ -0,0 +1,13 @@
+// aux-build:unaligned_references_external_crate.rs
+
+extern crate unaligned_references_external_crate;
+
+unaligned_references_external_crate::mac! { //~ERROR reference to packed field is unaligned
+ //~^ previously accepted
+ #[repr(packed)]
+ pub struct X {
+ pub field: u16
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/unaligned_references_external_macro.stderr b/tests/ui/lint/unaligned_references_external_macro.stderr
new file mode 100644
index 000000000..c46ca6742
--- /dev/null
+++ b/tests/ui/lint/unaligned_references_external_macro.stderr
@@ -0,0 +1,61 @@
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references_external_macro.rs:5:1
+ |
+LL | / unaligned_references_external_crate::mac! {
+LL | |
+LL | | #[repr(packed)]
+LL | | pub struct X {
+LL | | pub field: u16
+LL | | }
+LL | | }
+ | |_^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+note: the lint level is defined here
+ --> $DIR/unaligned_references_external_macro.rs:5:1
+ |
+LL | / unaligned_references_external_crate::mac! {
+LL | |
+LL | | #[repr(packed)]
+LL | | pub struct X {
+LL | | pub field: u16
+LL | | }
+LL | | }
+ | |_^
+ = note: this error originates in the macro `unaligned_references_external_crate::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+Future incompatibility report: Future breakage diagnostic:
+error: reference to packed field is unaligned
+ --> $DIR/unaligned_references_external_macro.rs:5:1
+ |
+LL | / unaligned_references_external_crate::mac! {
+LL | |
+LL | | #[repr(packed)]
+LL | | pub struct X {
+LL | | pub field: u16
+LL | | }
+LL | | }
+ | |_^
+ |
+ = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+ = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+ = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+note: the lint level is defined here
+ --> $DIR/unaligned_references_external_macro.rs:5:1
+ |
+LL | / unaligned_references_external_crate::mac! {
+LL | |
+LL | | #[repr(packed)]
+LL | | pub struct X {
+LL | | pub field: u16
+LL | | }
+LL | | }
+ | |_^
+ = note: this error originates in the macro `unaligned_references_external_crate::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/tests/ui/lint/unnecessary-extern-crate.rs b/tests/ui/lint/unnecessary-extern-crate.rs
new file mode 100644
index 000000000..af2bd84bd
--- /dev/null
+++ b/tests/ui/lint/unnecessary-extern-crate.rs
@@ -0,0 +1,71 @@
+// edition:2018
+
+#![deny(unused_extern_crates)]
+#![feature(test, rustc_private)]
+
+extern crate libc;
+//~^ ERROR unused extern crate
+//~| HELP remove
+extern crate libc as x;
+//~^ ERROR unused extern crate
+//~| HELP remove
+
+extern crate proc_macro;
+
+#[macro_use]
+extern crate test;
+
+pub extern crate test as y;
+
+pub extern crate alloc;
+
+pub(crate) extern crate alloc as a;
+
+pub(crate) extern crate alloc as b;
+
+mod foo {
+ pub(in crate::foo) extern crate alloc as c;
+
+ pub(super) extern crate alloc as d;
+
+ extern crate libc;
+ //~^ ERROR unused extern crate
+ //~| HELP remove
+
+ extern crate libc as x;
+ //~^ ERROR unused extern crate
+ //~| HELP remove
+
+ pub extern crate test;
+
+ pub extern crate test as y;
+
+ mod bar {
+ extern crate libc;
+ //~^ ERROR unused extern crate
+ //~| HELP remove
+
+ extern crate libc as x;
+ //~^ ERROR unused extern crate
+ //~| HELP remove
+
+ pub(in crate::foo::bar) extern crate alloc as e;
+
+ fn dummy() {
+ e::string::String::new();
+ }
+ }
+
+ fn dummy() {
+ c::string::String::new();
+ d::string::String::new();
+ }
+}
+
+
+fn main() {
+ a::string::String::new();
+ b::string::String::new();
+
+ proc_macro::TokenStream::new();
+}
diff --git a/tests/ui/lint/unnecessary-extern-crate.stderr b/tests/ui/lint/unnecessary-extern-crate.stderr
new file mode 100644
index 000000000..14ba9d052
--- /dev/null
+++ b/tests/ui/lint/unnecessary-extern-crate.stderr
@@ -0,0 +1,44 @@
+error: unused extern crate
+ --> $DIR/unnecessary-extern-crate.rs:6:1
+ |
+LL | extern crate libc;
+ | ^^^^^^^^^^^^^^^^^^ help: remove it
+ |
+note: the lint level is defined here
+ --> $DIR/unnecessary-extern-crate.rs:3:9
+ |
+LL | #![deny(unused_extern_crates)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unused extern crate
+ --> $DIR/unnecessary-extern-crate.rs:9:1
+ |
+LL | extern crate libc as x;
+ | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+ --> $DIR/unnecessary-extern-crate.rs:31:5
+ |
+LL | extern crate libc;
+ | ^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+ --> $DIR/unnecessary-extern-crate.rs:35:5
+ |
+LL | extern crate libc as x;
+ | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+ --> $DIR/unnecessary-extern-crate.rs:44:9
+ |
+LL | extern crate libc;
+ | ^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+ --> $DIR/unnecessary-extern-crate.rs:48:9
+ |
+LL | extern crate libc as x;
+ | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/lint/unreachable-async-fn.rs b/tests/ui/lint/unreachable-async-fn.rs
new file mode 100644
index 000000000..eedd877fe
--- /dev/null
+++ b/tests/ui/lint/unreachable-async-fn.rs
@@ -0,0 +1,9 @@
+// check-pass
+// edition:2018
+
+#[allow(dead_code)]
+async fn foo () { // unreachable lint doesn't trigger
+ unimplemented!()
+}
+
+fn main() {}
diff --git a/tests/ui/lint/unreachable_pub.rs b/tests/ui/lint/unreachable_pub.rs
new file mode 100644
index 000000000..a50467ce8
--- /dev/null
+++ b/tests/ui/lint/unreachable_pub.rs
@@ -0,0 +1,66 @@
+// check-pass
+
+#![allow(unused)]
+#![warn(unreachable_pub)]
+
+mod private_mod {
+ // non-leaked `pub` items in private module should be linted
+ pub use std::fmt; //~ WARNING unreachable_pub
+ pub use std::env::{Args}; // braced-use has different item spans than unbraced
+ //~^ WARNING unreachable_pub
+
+ pub struct Hydrogen { //~ WARNING unreachable_pub
+ // `pub` struct fields, too
+ pub neutrons: usize, //~ WARNING unreachable_pub
+ // (... but not more-restricted fields)
+ pub(crate) electrons: usize
+ }
+ impl Hydrogen {
+ // impls, too
+ pub fn count_neutrons(&self) -> usize { self.neutrons } //~ WARNING unreachable_pub
+ pub(crate) fn count_electrons(&self) -> usize { self.electrons }
+ }
+ impl Clone for Hydrogen {
+ fn clone(&self) -> Hydrogen {
+ Hydrogen { neutrons: self.neutrons, electrons: self.electrons }
+ }
+ }
+
+ pub enum Helium {} //~ WARNING unreachable_pub
+ pub union Lithium { c1: usize, c2: u8 } //~ WARNING unreachable_pub
+ pub fn beryllium() {} //~ WARNING unreachable_pub
+ pub trait Boron {} //~ WARNING unreachable_pub
+ pub const CARBON: usize = 1; //~ WARNING unreachable_pub
+ pub static NITROGEN: usize = 2; //~ WARNING unreachable_pub
+ pub type Oxygen = bool; //~ WARNING unreachable_pub
+
+ macro_rules! define_empty_struct_with_visibility {
+ ($visibility: vis, $name: ident) => { $visibility struct $name {} }
+ //~^ WARNING unreachable_pub
+ }
+ define_empty_struct_with_visibility!(pub, Fluorine);
+
+ extern "C" {
+ pub fn catalyze() -> bool; //~ WARNING unreachable_pub
+ }
+
+ // items leaked through signatures (see `get_neon` below) are OK
+ pub struct Neon {}
+
+ // crate-visible items are OK
+ pub(crate) struct Sodium {}
+}
+
+pub mod public_mod {
+ // module is public: these are OK, too
+ pub struct Magnesium {}
+ pub(crate) struct Aluminum {}
+}
+
+pub fn get_neon() -> private_mod::Neon {
+ private_mod::Neon {}
+}
+
+fn main() {
+ let _ = get_neon();
+}
diff --git a/tests/ui/lint/unreachable_pub.stderr b/tests/ui/lint/unreachable_pub.stderr
new file mode 100644
index 000000000..762834b97
--- /dev/null
+++ b/tests/ui/lint/unreachable_pub.stderr
@@ -0,0 +1,148 @@
+warning: unreachable `pub` item
+ --> $DIR/unreachable_pub.rs:8:13
+ |
+LL | pub use std::fmt;
+ | --- ^^^^^^^^
+ | |
+ | help: consider restricting its visibility: `pub(crate)`
+ |
+ = help: or consider exporting it for use by other crates
+note: the lint level is defined here
+ --> $DIR/unreachable_pub.rs:4:9
+ |
+LL | #![warn(unreachable_pub)]
+ | ^^^^^^^^^^^^^^^
+
+warning: unreachable `pub` item
+ --> $DIR/unreachable_pub.rs:9:24
+ |
+LL | pub use std::env::{Args}; // braced-use has different item spans than unbraced
+ | --- ^^^^
+ | |
+ | help: consider restricting its visibility: `pub(crate)`
+ |
+ = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+ --> $DIR/unreachable_pub.rs:12:5
+ |
+LL | pub struct Hydrogen {
+ | ---^^^^^^^^^^^^^^^^
+ | |
+ | help: consider restricting its visibility: `pub(crate)`
+ |
+ = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` field
+ --> $DIR/unreachable_pub.rs:14:9
+ |
+LL | pub neutrons: usize,
+ | ---^^^^^^^^^^^^^^^^
+ | |
+ | help: consider restricting its visibility: `pub(crate)`
+
+warning: unreachable `pub` item
+ --> $DIR/unreachable_pub.rs:20:9
+ |
+LL | pub fn count_neutrons(&self) -> usize { self.neutrons }
+ | ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | help: consider restricting its visibility: `pub(crate)`
+
+warning: unreachable `pub` item
+ --> $DIR/unreachable_pub.rs:29:5
+ |
+LL | pub enum Helium {}
+ | ---^^^^^^^^^^^^
+ | |
+ | help: consider restricting its visibility: `pub(crate)`
+ |
+ = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+ --> $DIR/unreachable_pub.rs:30:5
+ |
+LL | pub union Lithium { c1: usize, c2: u8 }
+ | ---^^^^^^^^^^^^^^
+ | |
+ | help: consider restricting its visibility: `pub(crate)`
+ |
+ = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+ --> $DIR/unreachable_pub.rs:31:5
+ |
+LL | pub fn beryllium() {}
+ | ---^^^^^^^^^^^^^^^
+ | |
+ | help: consider restricting its visibility: `pub(crate)`
+ |
+ = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+ --> $DIR/unreachable_pub.rs:32:5
+ |
+LL | pub trait Boron {}
+ | ---^^^^^^^^^^^^
+ | |
+ | help: consider restricting its visibility: `pub(crate)`
+ |
+ = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+ --> $DIR/unreachable_pub.rs:33:5
+ |
+LL | pub const CARBON: usize = 1;
+ | ---^^^^^^^^^^^^^^^^^^^^
+ | |
+ | help: consider restricting its visibility: `pub(crate)`
+ |
+ = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+ --> $DIR/unreachable_pub.rs:34:5
+ |
+LL | pub static NITROGEN: usize = 2;
+ | ---^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | help: consider restricting its visibility: `pub(crate)`
+ |
+ = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+ --> $DIR/unreachable_pub.rs:35:5
+ |
+LL | pub type Oxygen = bool;
+ | ---^^^^^^^^^^^^
+ | |
+ | help: consider restricting its visibility: `pub(crate)`
+ |
+ = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+ --> $DIR/unreachable_pub.rs:38:47
+ |
+LL | ($visibility: vis, $name: ident) => { $visibility struct $name {} }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | define_empty_struct_with_visibility!(pub, Fluorine);
+ | ---------------------------------------------------
+ | | |
+ | | help: consider restricting its visibility: `pub(crate)`
+ | in this macro invocation
+ |
+ = help: or consider exporting it for use by other crates
+ = note: this warning originates in the macro `define_empty_struct_with_visibility` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: unreachable `pub` item
+ --> $DIR/unreachable_pub.rs:44:9
+ |
+LL | pub fn catalyze() -> bool;
+ | ---^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | help: consider restricting its visibility: `pub(crate)`
+ |
+ = help: or consider exporting it for use by other crates
+
+warning: 14 warnings emitted
+
diff --git a/tests/ui/lint/unsafe_code/auxiliary/forge_unsafe_block.rs b/tests/ui/lint/unsafe_code/auxiliary/forge_unsafe_block.rs
new file mode 100644
index 000000000..26871c98d
--- /dev/null
+++ b/tests/ui/lint/unsafe_code/auxiliary/forge_unsafe_block.rs
@@ -0,0 +1,16 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};
+
+#[proc_macro]
+pub fn forge_unsafe_block(input: TokenStream) -> TokenStream {
+ let mut output = TokenStream::new();
+ output.extend(Some(TokenTree::from(Ident::new("unsafe", Span::call_site()))));
+ output.extend(Some(TokenTree::from(Group::new(Delimiter::Brace, input))));
+ output
+}
diff --git a/tests/ui/lint/unsafe_code/forge_unsafe_block.rs b/tests/ui/lint/unsafe_code/forge_unsafe_block.rs
new file mode 100644
index 000000000..a1bd7b413
--- /dev/null
+++ b/tests/ui/lint/unsafe_code/forge_unsafe_block.rs
@@ -0,0 +1,16 @@
+// check-pass
+// aux-build:forge_unsafe_block.rs
+
+#[macro_use]
+extern crate forge_unsafe_block;
+
+unsafe fn foo() {}
+
+#[forbid(unsafe_code)]
+fn main() {
+ // `forbid` doesn't work for non-user-provided unsafe blocks.
+ // see `UnsafeCode::check_expr`.
+ forge_unsafe_block! {
+ foo();
+ }
+}
diff --git a/tests/ui/lint/unused-borrows.rs b/tests/ui/lint/unused-borrows.rs
new file mode 100644
index 000000000..4518522ae
--- /dev/null
+++ b/tests/ui/lint/unused-borrows.rs
@@ -0,0 +1,33 @@
+#![deny(unused_must_use)]
+
+fn foo(_: i32) -> bool { todo!() }
+
+fn bar() -> &'static i32 {
+ &42;
+ //~^ unused
+
+ &mut foo(42);
+ //~^ unused
+
+ &&42;
+ //~^ unused
+
+ &&mut 42;
+ //~^ unused
+
+ &mut &42;
+ //~^ unused
+
+ let _result = foo(4)
+ && foo(2); // Misplaced semi-colon (perhaps due to reordering of lines)
+ && foo(42);
+ //~^ unused
+
+ let _ = &42; // ok
+
+ &42 // ok
+}
+
+fn main() {
+ let _ = bar();
+}
diff --git a/tests/ui/lint/unused-borrows.stderr b/tests/ui/lint/unused-borrows.stderr
new file mode 100644
index 000000000..d8dd2b5fd
--- /dev/null
+++ b/tests/ui/lint/unused-borrows.stderr
@@ -0,0 +1,73 @@
+error: unused borrow that must be used
+ --> $DIR/unused-borrows.rs:6:5
+ |
+LL | &42;
+ | ^^^ the borrow produces a value
+ |
+note: the lint level is defined here
+ --> $DIR/unused-borrows.rs:1:9
+ |
+LL | #![deny(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = &42;
+ | +++++++
+
+error: unused borrow that must be used
+ --> $DIR/unused-borrows.rs:9:5
+ |
+LL | &mut foo(42);
+ | ^^^^^^^^^^^^ the borrow produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = &mut foo(42);
+ | +++++++
+
+error: unused borrow that must be used
+ --> $DIR/unused-borrows.rs:12:5
+ |
+LL | &&42;
+ | ^^^^ the borrow produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = &&42;
+ | +++++++
+
+error: unused borrow that must be used
+ --> $DIR/unused-borrows.rs:15:5
+ |
+LL | &&mut 42;
+ | ^^^^^^^^ the borrow produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = &&mut 42;
+ | +++++++
+
+error: unused borrow that must be used
+ --> $DIR/unused-borrows.rs:18:5
+ |
+LL | &mut &42;
+ | ^^^^^^^^ the borrow produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = &mut &42;
+ | +++++++
+
+error: unused borrow that must be used
+ --> $DIR/unused-borrows.rs:23:5
+ |
+LL | && foo(42);
+ | ^^^^^^^^^^ the borrow produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = && foo(42);
+ | +++++++
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/lint/unused-braces-while-let-with-mutable-value.rs b/tests/ui/lint/unused-braces-while-let-with-mutable-value.rs
new file mode 100644
index 000000000..ac547293c
--- /dev/null
+++ b/tests/ui/lint/unused-braces-while-let-with-mutable-value.rs
@@ -0,0 +1,12 @@
+// check-pass
+
+#![deny(unused_braces)]
+
+fn main() {
+ let mut a = Some(3);
+ // Shouldn't warn below `a`.
+ while let Some(ref mut v) = {a} {
+ a.as_mut().map(|a| std::mem::swap(a, v));
+ break;
+ }
+}
diff --git a/tests/ui/lint/unused-qualification-in-derive-expansion.rs b/tests/ui/lint/unused-qualification-in-derive-expansion.rs
new file mode 100644
index 000000000..c2efbf507
--- /dev/null
+++ b/tests/ui/lint/unused-qualification-in-derive-expansion.rs
@@ -0,0 +1,16 @@
+// run-pass
+// aux-build:add-impl.rs
+
+#![forbid(unused_qualifications)]
+
+#[macro_use]
+extern crate add_impl;
+
+#[derive(AddImpl)]
+struct B;
+
+fn main() {
+ B.foo();
+ foo();
+ bar::foo();
+}
diff --git a/tests/ui/lint/unused/auxiliary/lint_unused_extern_crate.rs b/tests/ui/lint/unused/auxiliary/lint_unused_extern_crate.rs
new file mode 100644
index 000000000..b76b4321d
--- /dev/null
+++ b/tests/ui/lint/unused/auxiliary/lint_unused_extern_crate.rs
@@ -0,0 +1 @@
+pub fn foo() {}
diff --git a/tests/ui/lint/unused/auxiliary/lint_unused_extern_crate2.rs b/tests/ui/lint/unused/auxiliary/lint_unused_extern_crate2.rs
new file mode 100644
index 000000000..b76b4321d
--- /dev/null
+++ b/tests/ui/lint/unused/auxiliary/lint_unused_extern_crate2.rs
@@ -0,0 +1 @@
+pub fn foo() {}
diff --git a/tests/ui/lint/unused/auxiliary/lint_unused_extern_crate3.rs b/tests/ui/lint/unused/auxiliary/lint_unused_extern_crate3.rs
new file mode 100644
index 000000000..b76b4321d
--- /dev/null
+++ b/tests/ui/lint/unused/auxiliary/lint_unused_extern_crate3.rs
@@ -0,0 +1 @@
+pub fn foo() {}
diff --git a/tests/ui/lint/unused/auxiliary/lint_unused_extern_crate4.rs b/tests/ui/lint/unused/auxiliary/lint_unused_extern_crate4.rs
new file mode 100644
index 000000000..d11c69f81
--- /dev/null
+++ b/tests/ui/lint/unused/auxiliary/lint_unused_extern_crate4.rs
@@ -0,0 +1 @@
+// intentionally empty
diff --git a/tests/ui/lint/unused/auxiliary/lint_unused_extern_crate5.rs b/tests/ui/lint/unused/auxiliary/lint_unused_extern_crate5.rs
new file mode 100644
index 000000000..d11c69f81
--- /dev/null
+++ b/tests/ui/lint/unused/auxiliary/lint_unused_extern_crate5.rs
@@ -0,0 +1 @@
+// intentionally empty
diff --git a/tests/ui/lint/unused/issue-104397.rs b/tests/ui/lint/unused/issue-104397.rs
new file mode 100644
index 000000000..94e15cd96
--- /dev/null
+++ b/tests/ui/lint/unused/issue-104397.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+#![warn(unused)]
+#![deny(warnings)]
+
+struct Inv<'a>(&'a mut &'a ());
+
+trait Trait {}
+impl Trait for for<'a> fn(Inv<'a>) {}
+
+fn with_bound()
+where
+ (for<'a> fn(Inv<'a>)): Trait,
+{}
+
+fn main() {
+ with_bound();
+}
diff --git a/tests/ui/lint/unused/issue-105061-array-lint.rs b/tests/ui/lint/unused/issue-105061-array-lint.rs
new file mode 100644
index 000000000..9b06a4fde
--- /dev/null
+++ b/tests/ui/lint/unused/issue-105061-array-lint.rs
@@ -0,0 +1,11 @@
+#![warn(unused)]
+#![deny(warnings)]
+
+fn main() {
+ let _x: ([u32; 3]); //~ ERROR unnecessary parentheses around type
+ let _y: [u8; (3)]; //~ ERROR unnecessary parentheses around const expression
+ let _z: ([u8; (3)]);
+ //~^ ERROR unnecessary parentheses around const expression
+ //~| ERROR unnecessary parentheses around type
+
+}
diff --git a/tests/ui/lint/unused/issue-105061-array-lint.stderr b/tests/ui/lint/unused/issue-105061-array-lint.stderr
new file mode 100644
index 000000000..7eb761aee
--- /dev/null
+++ b/tests/ui/lint/unused/issue-105061-array-lint.stderr
@@ -0,0 +1,56 @@
+error: unnecessary parentheses around type
+ --> $DIR/issue-105061-array-lint.rs:5:13
+ |
+LL | let _x: ([u32; 3]);
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-105061-array-lint.rs:2:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(unused_parens)]` implied by `#[deny(warnings)]`
+help: remove these parentheses
+ |
+LL - let _x: ([u32; 3]);
+LL + let _x: [u32; 3];
+ |
+
+error: unnecessary parentheses around const expression
+ --> $DIR/issue-105061-array-lint.rs:6:18
+ |
+LL | let _y: [u8; (3)];
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - let _y: [u8; (3)];
+LL + let _y: [u8; 3];
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/issue-105061-array-lint.rs:7:13
+ |
+LL | let _z: ([u8; (3)]);
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - let _z: ([u8; (3)]);
+LL + let _z: [u8; (3)];
+ |
+
+error: unnecessary parentheses around const expression
+ --> $DIR/issue-105061-array-lint.rs:7:19
+ |
+LL | let _z: ([u8; (3)]);
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - let _z: ([u8; (3)]);
+LL + let _z: ([u8; 3]);
+ |
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lint/unused/issue-105061-should-lint.rs b/tests/ui/lint/unused/issue-105061-should-lint.rs
new file mode 100644
index 000000000..7e4e09473
--- /dev/null
+++ b/tests/ui/lint/unused/issue-105061-should-lint.rs
@@ -0,0 +1,23 @@
+#![warn(unused)]
+#![deny(warnings)]
+
+struct Inv<'a>(&'a mut &'a ());
+
+trait Trait<'a> {}
+impl<'b> Trait<'b> for for<'a> fn(Inv<'a>) {}
+
+fn with_bound()
+where
+ for<'b> (for<'a> fn(Inv<'a>)): Trait<'b>, //~ ERROR unnecessary parentheses around type
+{}
+
+trait Hello<T> {}
+fn with_dyn_bound<T>()
+where
+ (dyn Hello<(for<'b> fn(&'b ()))>): Hello<T> //~ ERROR unnecessary parentheses around type
+{}
+
+fn main() {
+ with_bound();
+ with_dyn_bound();
+}
diff --git a/tests/ui/lint/unused/issue-105061-should-lint.stderr b/tests/ui/lint/unused/issue-105061-should-lint.stderr
new file mode 100644
index 000000000..e591f1ffb
--- /dev/null
+++ b/tests/ui/lint/unused/issue-105061-should-lint.stderr
@@ -0,0 +1,32 @@
+error: unnecessary parentheses around type
+ --> $DIR/issue-105061-should-lint.rs:11:13
+ |
+LL | for<'b> (for<'a> fn(Inv<'a>)): Trait<'b>,
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-105061-should-lint.rs:2:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(unused_parens)]` implied by `#[deny(warnings)]`
+help: remove these parentheses
+ |
+LL - for<'b> (for<'a> fn(Inv<'a>)): Trait<'b>,
+LL + for<'b> for<'a> fn(Inv<'a>): Trait<'b>,
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/issue-105061-should-lint.rs:17:16
+ |
+LL | (dyn Hello<(for<'b> fn(&'b ()))>): Hello<T>
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - (dyn Hello<(for<'b> fn(&'b ()))>): Hello<T>
+LL + (dyn Hello<for<'b> fn(&'b ())>): Hello<T>
+ |
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/unused/issue-105061.rs b/tests/ui/lint/unused/issue-105061.rs
new file mode 100644
index 000000000..92d636d0a
--- /dev/null
+++ b/tests/ui/lint/unused/issue-105061.rs
@@ -0,0 +1,17 @@
+#![warn(unused)]
+#![deny(warnings)]
+
+struct Inv<'a>(&'a mut &'a ());
+
+trait Trait {}
+impl Trait for (for<'a> fn(Inv<'a>),) {}
+
+
+fn with_bound()
+where
+ ((for<'a> fn(Inv<'a>)),): Trait, //~ ERROR unnecessary parentheses around type
+{}
+
+fn main() {
+ with_bound();
+}
diff --git a/tests/ui/lint/unused/issue-105061.stderr b/tests/ui/lint/unused/issue-105061.stderr
new file mode 100644
index 000000000..f07aa2012
--- /dev/null
+++ b/tests/ui/lint/unused/issue-105061.stderr
@@ -0,0 +1,20 @@
+error: unnecessary parentheses around type
+ --> $DIR/issue-105061.rs:12:6
+ |
+LL | ((for<'a> fn(Inv<'a>)),): Trait,
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-105061.rs:2:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(unused_parens)]` implied by `#[deny(warnings)]`
+help: remove these parentheses
+ |
+LL - ((for<'a> fn(Inv<'a>)),): Trait,
+LL + (for<'a> fn(Inv<'a>),): Trait,
+ |
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/unused/issue-30730.rs b/tests/ui/lint/unused/issue-30730.rs
new file mode 100644
index 000000000..d6be90c81
--- /dev/null
+++ b/tests/ui/lint/unused/issue-30730.rs
@@ -0,0 +1,5 @@
+#![warn(unused)]
+#![deny(warnings)]
+use std::thread;
+//~^ ERROR: unused import
+fn main() {}
diff --git a/tests/ui/lint/unused/issue-30730.stderr b/tests/ui/lint/unused/issue-30730.stderr
new file mode 100644
index 000000000..b299e99a3
--- /dev/null
+++ b/tests/ui/lint/unused/issue-30730.stderr
@@ -0,0 +1,15 @@
+error: unused import: `std::thread`
+ --> $DIR/issue-30730.rs:3:5
+ |
+LL | use std::thread;
+ | ^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-30730.rs:2:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(unused_imports)]` implied by `#[deny(warnings)]`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/unused/issue-46576.rs b/tests/ui/lint/unused/issue-46576.rs
new file mode 100644
index 000000000..15f458f38
--- /dev/null
+++ b/tests/ui/lint/unused/issue-46576.rs
@@ -0,0 +1,21 @@
+#![allow(dead_code)]
+#![deny(unused_imports)]
+
+use std::fs::File;
+use std::io::{BufRead, BufReader, Read};
+//~^ ERROR unused import: `BufRead`
+
+pub fn read_from_file(path: &str) {
+ let file = File::open(&path).unwrap();
+ let mut reader = BufReader::new(file);
+ let mut s = String::new();
+ reader.read_to_string(&mut s).unwrap();
+}
+
+pub fn read_lines(s: &str) {
+ for _line in s.lines() {
+
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/unused/issue-46576.stderr b/tests/ui/lint/unused/issue-46576.stderr
new file mode 100644
index 000000000..6f4d97068
--- /dev/null
+++ b/tests/ui/lint/unused/issue-46576.stderr
@@ -0,0 +1,14 @@
+error: unused import: `BufRead`
+ --> $DIR/issue-46576.rs:5:15
+ |
+LL | use std::io::{BufRead, BufReader, Read};
+ | ^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-46576.rs:2:9
+ |
+LL | #![deny(unused_imports)]
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs b/tests/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs
new file mode 100644
index 000000000..4822a9b2c
--- /dev/null
+++ b/tests/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs
@@ -0,0 +1,88 @@
+// check-pass
+
+#![feature(box_patterns)]
+
+#![warn(unused)] // UI tests pass `-A unused` (#43896)
+
+struct SoulHistory {
+ corridors_of_light: usize,
+ hours_are_suns: bool,
+ endless_and_singing: bool
+}
+
+struct LovelyAmbition {
+ lips: usize,
+ fire: usize
+}
+
+#[derive(Clone, Copy)]
+enum Large {
+ Suit { case: () }
+}
+
+struct Tuple(Large, ());
+
+fn main() {
+ let i_think_continually = 2; //~ WARNING unused variable: `i_think_continually`
+ let who_from_the_womb_remembered = SoulHistory {
+ corridors_of_light: 5,
+ hours_are_suns: true,
+ endless_and_singing: true
+ };
+
+ let mut mut_unused_var = 1;
+ //~^ WARNING unused variable: `mut_unused_var`
+ //~| WARNING variable does not need to be mutable
+
+ let (mut var, unused_var) = (1, 2);
+ //~^ WARNING unused variable: `var`
+ //~| WARNING unused variable: `unused_var`
+ //~| WARNING variable does not need to be mutable
+ // NOTE: `var` comes after `unused_var` lexicographically yet the warning
+ // for `var` will be emitted before the one for `unused_var`. We use an
+ // `IndexMap` to ensure this is the case instead of a `BTreeMap`.
+
+ if let SoulHistory { corridors_of_light, //~ WARNING unused variable: `corridors_of_light`
+ mut hours_are_suns, //~ WARNING `hours_are_suns` is assigned to, but
+ endless_and_singing: true } = who_from_the_womb_remembered {
+ hours_are_suns = false; //~ WARNING unused_assignments
+ }
+
+ let the_spirit = LovelyAmbition { lips: 1, fire: 2 };
+ let LovelyAmbition { lips, fire } = the_spirit; //~ WARNING unused variable: `fire`
+ println!("{}", lips);
+
+ let bag = Large::Suit {
+ case: ()
+ };
+
+ // Plain struct
+ match bag {
+ Large::Suit { case } => {} //~ WARNING unused variable: `case`
+ };
+
+ // Referenced struct
+ match &bag {
+ &Large::Suit { case } => {} //~ WARNING unused variable: `case`
+ };
+
+ // Boxed struct
+ match Box::new(bag) {
+ box Large::Suit { case } => {} //~ WARNING unused variable: `case`
+ };
+
+ // Tuple with struct
+ match (bag,) {
+ (Large::Suit { case },) => {} //~ WARNING unused variable: `case`
+ };
+
+ // Slice with struct
+ match [bag] {
+ [Large::Suit { case }] => {} //~ WARNING unused variable: `case`
+ };
+
+ // Tuple struct with struct
+ match Tuple(bag, ()) {
+ Tuple(Large::Suit { case }, ()) => {} //~ WARNING unused variable: `case`
+ };
+}
diff --git a/tests/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr b/tests/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr
new file mode 100644
index 000000000..fe2e3afc8
--- /dev/null
+++ b/tests/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr
@@ -0,0 +1,116 @@
+warning: unused variable: `i_think_continually`
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:26:9
+ |
+LL | let i_think_continually = 2;
+ | ^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_i_think_continually`
+ |
+note: the lint level is defined here
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:5:9
+ |
+LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
+ | ^^^^^^
+ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
+
+warning: unused variable: `mut_unused_var`
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:13
+ |
+LL | let mut mut_unused_var = 1;
+ | ^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_mut_unused_var`
+
+warning: unused variable: `var`
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:14
+ |
+LL | let (mut var, unused_var) = (1, 2);
+ | ^^^ help: if this is intentional, prefix it with an underscore: `_var`
+
+warning: unused variable: `unused_var`
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:19
+ |
+LL | let (mut var, unused_var) = (1, 2);
+ | ^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_var`
+
+warning: unused variable: `corridors_of_light`
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:45:26
+ |
+LL | if let SoulHistory { corridors_of_light,
+ | ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _`
+
+warning: variable `hours_are_suns` is assigned to, but never used
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:46:30
+ |
+LL | mut hours_are_suns,
+ | ^^^^^^^^^^^^^^
+ |
+ = note: consider using `_hours_are_suns` instead
+
+warning: value assigned to `hours_are_suns` is never read
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:48:9
+ |
+LL | hours_are_suns = false;
+ | ^^^^^^^^^^^^^^
+ |
+ = help: maybe it is overwritten before being read?
+ = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]`
+
+warning: unused variable: `fire`
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:52:32
+ |
+LL | let LovelyAmbition { lips, fire } = the_spirit;
+ | ^^^^ help: try ignoring the field: `fire: _`
+
+warning: unused variable: `case`
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:61:23
+ |
+LL | Large::Suit { case } => {}
+ | ^^^^ help: try ignoring the field: `case: _`
+
+warning: unused variable: `case`
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:66:24
+ |
+LL | &Large::Suit { case } => {}
+ | ^^^^ help: try ignoring the field: `case: _`
+
+warning: unused variable: `case`
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:71:27
+ |
+LL | box Large::Suit { case } => {}
+ | ^^^^ help: try ignoring the field: `case: _`
+
+warning: unused variable: `case`
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:76:24
+ |
+LL | (Large::Suit { case },) => {}
+ | ^^^^ help: try ignoring the field: `case: _`
+
+warning: unused variable: `case`
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:81:24
+ |
+LL | [Large::Suit { case }] => {}
+ | ^^^^ help: try ignoring the field: `case: _`
+
+warning: unused variable: `case`
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:86:29
+ |
+LL | Tuple(Large::Suit { case }, ()) => {}
+ | ^^^^ help: try ignoring the field: `case: _`
+
+warning: variable does not need to be mutable
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:9
+ |
+LL | let mut mut_unused_var = 1;
+ | ----^^^^^^^^^^^^^^
+ | |
+ | help: remove this `mut`
+ |
+ = note: `#[warn(unused_mut)]` implied by `#[warn(unused)]`
+
+warning: variable does not need to be mutable
+ --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:10
+ |
+LL | let (mut var, unused_var) = (1, 2);
+ | ----^^^
+ | |
+ | help: remove this `mut`
+
+warning: 16 warnings emitted
+
diff --git a/tests/ui/lint/unused/issue-54180-unused-ref-field.fixed b/tests/ui/lint/unused/issue-54180-unused-ref-field.fixed
new file mode 100644
index 000000000..1350b7ca6
--- /dev/null
+++ b/tests/ui/lint/unused/issue-54180-unused-ref-field.fixed
@@ -0,0 +1,34 @@
+// run-rustfix
+
+#![deny(unused)]
+
+pub struct S {
+ pub f1: i32,
+}
+
+pub struct Point {
+ pub x: i32,
+ pub y: i32,
+}
+
+pub enum E {
+ Variant { field: String }
+}
+
+pub fn foo(arg: &E) {
+ match arg {
+ E::Variant { field: _ } => (), //~ ERROR unused variable
+ }
+}
+
+fn main() {
+ let s = S { f1: 123 };
+ let S { f1: _ } = s; //~ ERROR unused variable
+
+ let points = vec![Point { x: 1, y: 2 }];
+ let _: i32 = points.iter().map(|Point { x: _, y }| y).sum(); //~ ERROR unused variable
+
+ match (Point { x: 1, y: 2 }) {
+ Point { y, x: _ } => y, //~ ERROR unused variable
+ };
+}
diff --git a/tests/ui/lint/unused/issue-54180-unused-ref-field.rs b/tests/ui/lint/unused/issue-54180-unused-ref-field.rs
new file mode 100644
index 000000000..7b3392b60
--- /dev/null
+++ b/tests/ui/lint/unused/issue-54180-unused-ref-field.rs
@@ -0,0 +1,34 @@
+// run-rustfix
+
+#![deny(unused)]
+
+pub struct S {
+ pub f1: i32,
+}
+
+pub struct Point {
+ pub x: i32,
+ pub y: i32,
+}
+
+pub enum E {
+ Variant { field: String }
+}
+
+pub fn foo(arg: &E) {
+ match arg {
+ E::Variant { ref field } => (), //~ ERROR unused variable
+ }
+}
+
+fn main() {
+ let s = S { f1: 123 };
+ let S { ref f1 } = s; //~ ERROR unused variable
+
+ let points = vec![Point { x: 1, y: 2 }];
+ let _: i32 = points.iter().map(|Point { x, y }| y).sum(); //~ ERROR unused variable
+
+ match (Point { x: 1, y: 2 }) {
+ Point { y, ref mut x } => y, //~ ERROR unused variable
+ };
+}
diff --git a/tests/ui/lint/unused/issue-54180-unused-ref-field.stderr b/tests/ui/lint/unused/issue-54180-unused-ref-field.stderr
new file mode 100644
index 000000000..f2e616899
--- /dev/null
+++ b/tests/ui/lint/unused/issue-54180-unused-ref-field.stderr
@@ -0,0 +1,33 @@
+error: unused variable: `field`
+ --> $DIR/issue-54180-unused-ref-field.rs:20:22
+ |
+LL | E::Variant { ref field } => (),
+ | ^^^^^^^^^ help: try ignoring the field: `field: _`
+ |
+note: the lint level is defined here
+ --> $DIR/issue-54180-unused-ref-field.rs:3:9
+ |
+LL | #![deny(unused)]
+ | ^^^^^^
+ = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
+
+error: unused variable: `f1`
+ --> $DIR/issue-54180-unused-ref-field.rs:26:13
+ |
+LL | let S { ref f1 } = s;
+ | ^^^^^^ help: try ignoring the field: `f1: _`
+
+error: unused variable: `x`
+ --> $DIR/issue-54180-unused-ref-field.rs:32:20
+ |
+LL | Point { y, ref mut x } => y,
+ | ^^^^^^^^^ help: try ignoring the field: `x: _`
+
+error: unused variable: `x`
+ --> $DIR/issue-54180-unused-ref-field.rs:29:45
+ |
+LL | let _: i32 = points.iter().map(|Point { x, y }| y).sum();
+ | ^ help: try ignoring the field: `x: _`
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed b/tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed
new file mode 100644
index 000000000..71ebaea8e
--- /dev/null
+++ b/tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed
@@ -0,0 +1,113 @@
+// run-rustfix
+
+#![feature(box_patterns, stmt_expr_attributes, yeet_expr)]
+
+#![allow(
+ dead_code,
+ ellipsis_inclusive_range_patterns,
+ irrefutable_let_patterns,
+ unreachable_patterns,
+ unused_mut,
+ unused_variables
+)]
+#![deny(unused_parens)]
+
+fn lint_on_top_level() {
+ let a = 0; //~ ERROR unnecessary parentheses around pattern
+ for a in 0..1 {} //~ ERROR unnecessary parentheses around pattern
+ if let a = 0 {} //~ ERROR unnecessary parentheses around pattern
+ while let a = 0 {} //~ ERROR unnecessary parentheses around pattern
+ fn foo(a: u8) {} //~ ERROR unnecessary parentheses around pattern
+ let _ = |a: u8| 0; //~ ERROR unnecessary parentheses around pattern
+}
+
+fn _no_lint_attr() {
+ let _x = #[allow(dead_code)] (1 + 2);
+}
+
+fn _no_lint_yeet() -> Result<(), ()> {
+ #[allow(unreachable_code)]
+ if (do yeet) {}
+
+ Ok(())
+}
+
+// Don't lint in these cases (#64106).
+fn or_patterns_no_lint() {
+ match Box::new(0) {
+ box (0 | 1) => {} // Should not lint as `box 0 | 1` binds as `(box 0) | 1`.
+ _ => {}
+ }
+
+ match 0 {
+ x @ (0 | 1) => {} // Should not lint as `x @ 0 | 1` binds as `(x @ 0) | 1`.
+ _ => {}
+ }
+
+ if let &(0 | 1) = &0 {} // Should also not lint.
+ if let &mut (0 | 1) = &mut 0 {} // Same.
+
+ fn foo((Ok(a) | Err(a)): Result<u8, u8>) {} // Doesn't parse if we remove parens for now.
+
+ let _ = |(Ok(a) | Err(a)): Result<u8, u8>| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or.
+}
+
+fn or_patterns_will_lint() {
+ if let 0 | 1 = 0 {} //~ ERROR unnecessary parentheses around pattern
+ if let (0 | 1,) = (0,) {} //~ ERROR unnecessary parentheses around pattern
+ if let [0 | 1] = [0] {} //~ ERROR unnecessary parentheses around pattern
+ if let 0 | 1 | 2 = 0 {} //~ ERROR unnecessary parentheses around pattern
+ struct TS(u8);
+ if let TS(0 | 1) = TS(0) {} //~ ERROR unnecessary parentheses around pattern
+ struct NS { f: u8 }
+ if let NS { f: 0 | 1 } = (NS { f: 0 }) {} //~ ERROR unnecessary parentheses around pattern
+}
+
+// Don't lint on `&(mut x)` because `&mut x` means something else (#55342).
+fn deref_mut_binding_no_lint() {
+ let &(mut x) = &0;
+}
+
+fn main() {
+ match 1 {
+ _ => {} //~ ERROR unnecessary parentheses around pattern
+ y => {} //~ ERROR unnecessary parentheses around pattern
+ ref r => {} //~ ERROR unnecessary parentheses around pattern
+ e @ 1...2 => {} //~ ERROR unnecessary parentheses around pattern
+ (1...2) => {} // Non ambiguous range pattern should not warn
+ e @ (3...4) => {} // Non ambiguous range pattern should not warn
+ }
+
+ match &1 {
+ e @ &(1...2) => {} //~ ERROR unnecessary parentheses around pattern
+ &_ => {} //~ ERROR unnecessary parentheses around pattern
+ e @ &(1...2) => {} // Ambiguous range pattern should not warn
+ &(1...2) => {} // Ambiguous range pattern should not warn
+ }
+
+ match &1 {
+ e @ &(1...2) | e @ &(3...4) => {} // Complex ambiguous pattern should not warn
+ &_ => {}
+ }
+
+ match 1 {
+ _ => {} //~ ERROR unnecessary parentheses around pattern
+ y => {} //~ ERROR unnecessary parentheses around pattern
+ ref r => {} //~ ERROR unnecessary parentheses around pattern
+ e @ 1..=2 => {} //~ ERROR unnecessary parentheses around pattern
+ (1..=2) => {} // Non ambiguous range pattern should not warn
+ e @ (3..=4) => {} // Non ambiguous range pattern should not warn
+ }
+
+ match &1 {
+ e @ &(1..=2) => {} //~ ERROR unnecessary parentheses around pattern
+ &_ => {} //~ ERROR unnecessary parentheses around pattern
+ e @ &(1..=2) => {} // Ambiguous range pattern should not warn
+ &(1..=2) => {} // Ambiguous range pattern should not warn
+ }
+
+ match &1 {
+ e @ &(1..=2) | e @ &(3..=4) => {} // Complex ambiguous pattern should not warn
+ &_ => {}
+ }
+}
diff --git a/tests/ui/lint/unused/issue-54538-unused-parens-lint.rs b/tests/ui/lint/unused/issue-54538-unused-parens-lint.rs
new file mode 100644
index 000000000..28b662dd0
--- /dev/null
+++ b/tests/ui/lint/unused/issue-54538-unused-parens-lint.rs
@@ -0,0 +1,113 @@
+// run-rustfix
+
+#![feature(box_patterns, stmt_expr_attributes, yeet_expr)]
+
+#![allow(
+ dead_code,
+ ellipsis_inclusive_range_patterns,
+ irrefutable_let_patterns,
+ unreachable_patterns,
+ unused_mut,
+ unused_variables
+)]
+#![deny(unused_parens)]
+
+fn lint_on_top_level() {
+ let (a) = 0; //~ ERROR unnecessary parentheses around pattern
+ for (a) in 0..1 {} //~ ERROR unnecessary parentheses around pattern
+ if let (a) = 0 {} //~ ERROR unnecessary parentheses around pattern
+ while let (a) = 0 {} //~ ERROR unnecessary parentheses around pattern
+ fn foo((a): u8) {} //~ ERROR unnecessary parentheses around pattern
+ let _ = |(a): u8| 0; //~ ERROR unnecessary parentheses around pattern
+}
+
+fn _no_lint_attr() {
+ let _x = #[allow(dead_code)] (1 + 2);
+}
+
+fn _no_lint_yeet() -> Result<(), ()> {
+ #[allow(unreachable_code)]
+ if (do yeet) {}
+
+ Ok(())
+}
+
+// Don't lint in these cases (#64106).
+fn or_patterns_no_lint() {
+ match Box::new(0) {
+ box (0 | 1) => {} // Should not lint as `box 0 | 1` binds as `(box 0) | 1`.
+ _ => {}
+ }
+
+ match 0 {
+ x @ (0 | 1) => {} // Should not lint as `x @ 0 | 1` binds as `(x @ 0) | 1`.
+ _ => {}
+ }
+
+ if let &(0 | 1) = &0 {} // Should also not lint.
+ if let &mut (0 | 1) = &mut 0 {} // Same.
+
+ fn foo((Ok(a) | Err(a)): Result<u8, u8>) {} // Doesn't parse if we remove parens for now.
+
+ let _ = |(Ok(a) | Err(a)): Result<u8, u8>| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or.
+}
+
+fn or_patterns_will_lint() {
+ if let (0 | 1) = 0 {} //~ ERROR unnecessary parentheses around pattern
+ if let ((0 | 1),) = (0,) {} //~ ERROR unnecessary parentheses around pattern
+ if let [(0 | 1)] = [0] {} //~ ERROR unnecessary parentheses around pattern
+ if let 0 | (1 | 2) = 0 {} //~ ERROR unnecessary parentheses around pattern
+ struct TS(u8);
+ if let TS((0 | 1)) = TS(0) {} //~ ERROR unnecessary parentheses around pattern
+ struct NS { f: u8 }
+ if let NS { f: (0 | 1) } = (NS { f: 0 }) {} //~ ERROR unnecessary parentheses around pattern
+}
+
+// Don't lint on `&(mut x)` because `&mut x` means something else (#55342).
+fn deref_mut_binding_no_lint() {
+ let &(mut x) = &0;
+}
+
+fn main() {
+ match 1 {
+ (_) => {} //~ ERROR unnecessary parentheses around pattern
+ (y) => {} //~ ERROR unnecessary parentheses around pattern
+ (ref r) => {} //~ ERROR unnecessary parentheses around pattern
+ (e @ 1...2) => {} //~ ERROR unnecessary parentheses around pattern
+ (1...2) => {} // Non ambiguous range pattern should not warn
+ e @ (3...4) => {} // Non ambiguous range pattern should not warn
+ }
+
+ match &1 {
+ (e @ &(1...2)) => {} //~ ERROR unnecessary parentheses around pattern
+ &(_) => {} //~ ERROR unnecessary parentheses around pattern
+ e @ &(1...2) => {} // Ambiguous range pattern should not warn
+ &(1...2) => {} // Ambiguous range pattern should not warn
+ }
+
+ match &1 {
+ e @ &(1...2) | e @ &(3...4) => {} // Complex ambiguous pattern should not warn
+ &_ => {}
+ }
+
+ match 1 {
+ (_) => {} //~ ERROR unnecessary parentheses around pattern
+ (y) => {} //~ ERROR unnecessary parentheses around pattern
+ (ref r) => {} //~ ERROR unnecessary parentheses around pattern
+ (e @ 1..=2) => {} //~ ERROR unnecessary parentheses around pattern
+ (1..=2) => {} // Non ambiguous range pattern should not warn
+ e @ (3..=4) => {} // Non ambiguous range pattern should not warn
+ }
+
+ match &1 {
+ (e @ &(1..=2)) => {} //~ ERROR unnecessary parentheses around pattern
+ &(_) => {} //~ ERROR unnecessary parentheses around pattern
+ e @ &(1..=2) => {} // Ambiguous range pattern should not warn
+ &(1..=2) => {} // Ambiguous range pattern should not warn
+ }
+
+ match &1 {
+ e @ &(1..=2) | e @ &(3..=4) => {} // Complex ambiguous pattern should not warn
+ &_ => {}
+ }
+}
diff --git a/tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr b/tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr
new file mode 100644
index 000000000..a5e69e6d9
--- /dev/null
+++ b/tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr
@@ -0,0 +1,295 @@
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:16:9
+ |
+LL | let (a) = 0;
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-54538-unused-parens-lint.rs:13:9
+ |
+LL | #![deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - let (a) = 0;
+LL + let a = 0;
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:17:9
+ |
+LL | for (a) in 0..1 {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - for (a) in 0..1 {}
+LL + for a in 0..1 {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:18:12
+ |
+LL | if let (a) = 0 {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - if let (a) = 0 {}
+LL + if let a = 0 {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:19:15
+ |
+LL | while let (a) = 0 {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - while let (a) = 0 {}
+LL + while let a = 0 {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:20:12
+ |
+LL | fn foo((a): u8) {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - fn foo((a): u8) {}
+LL + fn foo(a: u8) {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:21:14
+ |
+LL | let _ = |(a): u8| 0;
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - let _ = |(a): u8| 0;
+LL + let _ = |a: u8| 0;
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:56:12
+ |
+LL | if let (0 | 1) = 0 {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - if let (0 | 1) = 0 {}
+LL + if let 0 | 1 = 0 {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:57:13
+ |
+LL | if let ((0 | 1),) = (0,) {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - if let ((0 | 1),) = (0,) {}
+LL + if let (0 | 1,) = (0,) {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:58:13
+ |
+LL | if let [(0 | 1)] = [0] {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - if let [(0 | 1)] = [0] {}
+LL + if let [0 | 1] = [0] {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:59:16
+ |
+LL | if let 0 | (1 | 2) = 0 {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - if let 0 | (1 | 2) = 0 {}
+LL + if let 0 | 1 | 2 = 0 {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:61:15
+ |
+LL | if let TS((0 | 1)) = TS(0) {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - if let TS((0 | 1)) = TS(0) {}
+LL + if let TS(0 | 1) = TS(0) {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:63:20
+ |
+LL | if let NS { f: (0 | 1) } = (NS { f: 0 }) {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - if let NS { f: (0 | 1) } = (NS { f: 0 }) {}
+LL + if let NS { f: 0 | 1 } = (NS { f: 0 }) {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:73:9
+ |
+LL | (_) => {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - (_) => {}
+LL + _ => {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:74:9
+ |
+LL | (y) => {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - (y) => {}
+LL + y => {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:75:9
+ |
+LL | (ref r) => {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - (ref r) => {}
+LL + ref r => {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:76:9
+ |
+LL | (e @ 1...2) => {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - (e @ 1...2) => {}
+LL + e @ 1...2 => {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:82:9
+ |
+LL | (e @ &(1...2)) => {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - (e @ &(1...2)) => {}
+LL + e @ &(1...2) => {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:83:10
+ |
+LL | &(_) => {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - &(_) => {}
+LL + &_ => {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:94:9
+ |
+LL | (_) => {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - (_) => {}
+LL + _ => {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:95:9
+ |
+LL | (y) => {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - (y) => {}
+LL + y => {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:96:9
+ |
+LL | (ref r) => {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - (ref r) => {}
+LL + ref r => {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:97:9
+ |
+LL | (e @ 1..=2) => {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - (e @ 1..=2) => {}
+LL + e @ 1..=2 => {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:103:9
+ |
+LL | (e @ &(1..=2)) => {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - (e @ &(1..=2)) => {}
+LL + e @ &(1..=2) => {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-54538-unused-parens-lint.rs:104:10
+ |
+LL | &(_) => {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - &(_) => {}
+LL + &_ => {}
+ |
+
+error: aborting due to 24 previous errors
+
diff --git a/tests/ui/lint/unused/issue-59896.rs b/tests/ui/lint/unused/issue-59896.rs
new file mode 100644
index 000000000..ff9f19acf
--- /dev/null
+++ b/tests/ui/lint/unused/issue-59896.rs
@@ -0,0 +1,9 @@
+#![deny(unused_imports)]
+
+struct S;
+
+fn main() {
+ use S; //~ ERROR the item `S` is imported redundantly
+
+ let _s = S;
+}
diff --git a/tests/ui/lint/unused/issue-59896.stderr b/tests/ui/lint/unused/issue-59896.stderr
new file mode 100644
index 000000000..95b7938ae
--- /dev/null
+++ b/tests/ui/lint/unused/issue-59896.stderr
@@ -0,0 +1,17 @@
+error: the item `S` is imported redundantly
+ --> $DIR/issue-59896.rs:6:9
+ |
+LL | struct S;
+ | --------- the item `S` is already defined here
+...
+LL | use S;
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-59896.rs:1:9
+ |
+LL | #![deny(unused_imports)]
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/unused/issue-67691-unused-field-in-or-pattern.rs b/tests/ui/lint/unused/issue-67691-unused-field-in-or-pattern.rs
new file mode 100644
index 000000000..e3631d014
--- /dev/null
+++ b/tests/ui/lint/unused/issue-67691-unused-field-in-or-pattern.rs
@@ -0,0 +1,85 @@
+// FIXME: should be run-rustfix, but rustfix doesn't currently support multipart suggestions, see
+// #53934
+
+#![deny(unused)]
+
+pub enum MyEnum {
+ A { i: i32, j: i32 },
+ B { i: i32, j: i32 },
+}
+
+pub enum MixedEnum {
+ A { i: i32 },
+ B(i32),
+}
+
+pub fn no_ref(x: MyEnum) {
+ use MyEnum::*;
+
+ match x {
+ A { i, j } | B { i, j } => { //~ ERROR unused variable
+ println!("{}", i);
+ }
+ }
+}
+
+pub fn with_ref(x: MyEnum) {
+ use MyEnum::*;
+
+ match x {
+ A { i, ref j } | B { i, ref j } => { //~ ERROR unused variable
+ println!("{}", i);
+ }
+ }
+}
+
+pub fn inner_no_ref(x: Option<MyEnum>) {
+ use MyEnum::*;
+
+ match x {
+ Some(A { i, j } | B { i, j }) => { //~ ERROR unused variable
+ println!("{}", i);
+ }
+
+ _ => {}
+ }
+}
+
+pub fn inner_with_ref(x: Option<MyEnum>) {
+ use MyEnum::*;
+
+ match x {
+ Some(A { i, ref j } | B { i, ref j }) => { //~ ERROR unused variable
+ println!("{}", i);
+ }
+
+ _ => {}
+ }
+}
+
+pub fn mixed_no_ref(x: MixedEnum) {
+ match x {
+ MixedEnum::A { i } | MixedEnum::B(i) => { //~ ERROR unused variable
+ println!("match");
+ }
+ }
+}
+
+pub fn mixed_with_ref(x: MixedEnum) {
+ match x {
+ MixedEnum::A { ref i } | MixedEnum::B(ref i) => { //~ ERROR unused variable
+ println!("match");
+ }
+ }
+}
+
+pub fn main() {
+ no_ref(MyEnum::A { i: 1, j: 2 });
+ with_ref(MyEnum::A { i: 1, j: 2 });
+
+ inner_no_ref(Some(MyEnum::A { i: 1, j: 2 }));
+ inner_with_ref(Some(MyEnum::A { i: 1, j: 2 }));
+
+ mixed_no_ref(MixedEnum::B(5));
+ mixed_with_ref(MixedEnum::B(5));
+}
diff --git a/tests/ui/lint/unused/issue-67691-unused-field-in-or-pattern.stderr b/tests/ui/lint/unused/issue-67691-unused-field-in-or-pattern.stderr
new file mode 100644
index 000000000..8fc2d1bc8
--- /dev/null
+++ b/tests/ui/lint/unused/issue-67691-unused-field-in-or-pattern.stderr
@@ -0,0 +1,74 @@
+error: unused variable: `j`
+ --> $DIR/issue-67691-unused-field-in-or-pattern.rs:20:16
+ |
+LL | A { i, j } | B { i, j } => {
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-67691-unused-field-in-or-pattern.rs:4:9
+ |
+LL | #![deny(unused)]
+ | ^^^^^^
+ = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
+help: try ignoring the field
+ |
+LL | A { i, j: _ } | B { i, j: _ } => {
+ | ~~~~ ~~~~
+
+error: unused variable: `j`
+ --> $DIR/issue-67691-unused-field-in-or-pattern.rs:30:16
+ |
+LL | A { i, ref j } | B { i, ref j } => {
+ | ^^^^^ ^^^^^
+ |
+help: try ignoring the field
+ |
+LL | A { i, j: _ } | B { i, j: _ } => {
+ | ~~~~ ~~~~
+
+error: unused variable: `j`
+ --> $DIR/issue-67691-unused-field-in-or-pattern.rs:40:21
+ |
+LL | Some(A { i, j } | B { i, j }) => {
+ | ^ ^
+ |
+help: try ignoring the field
+ |
+LL | Some(A { i, j: _ } | B { i, j: _ }) => {
+ | ~~~~ ~~~~
+
+error: unused variable: `j`
+ --> $DIR/issue-67691-unused-field-in-or-pattern.rs:52:21
+ |
+LL | Some(A { i, ref j } | B { i, ref j }) => {
+ | ^^^^^ ^^^^^
+ |
+help: try ignoring the field
+ |
+LL | Some(A { i, j: _ } | B { i, j: _ }) => {
+ | ~~~~ ~~~~
+
+error: unused variable: `i`
+ --> $DIR/issue-67691-unused-field-in-or-pattern.rs:62:24
+ |
+LL | MixedEnum::A { i } | MixedEnum::B(i) => {
+ | ^ ^
+ |
+help: try ignoring the field
+ |
+LL | MixedEnum::A { i: _ } | MixedEnum::B(_) => {
+ | ~~~~ ~
+
+error: unused variable: `i`
+ --> $DIR/issue-67691-unused-field-in-or-pattern.rs:70:24
+ |
+LL | MixedEnum::A { ref i } | MixedEnum::B(ref i) => {
+ | ^^^^^ ^^^^^
+ |
+help: try ignoring the field
+ |
+LL | MixedEnum::A { i: _ } | MixedEnum::B(_) => {
+ | ~~~~ ~
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/lint/unused/issue-70041.rs b/tests/ui/lint/unused/issue-70041.rs
new file mode 100644
index 000000000..22e42295e
--- /dev/null
+++ b/tests/ui/lint/unused/issue-70041.rs
@@ -0,0 +1,13 @@
+// compile-flags: --edition=2018
+// run-pass
+
+macro_rules! regex {
+ //~^ WARN unused macro definition
+ () => {};
+}
+
+#[allow(dead_code)]
+use regex;
+//~^ WARN unused import
+
+fn main() {}
diff --git a/tests/ui/lint/unused/issue-70041.stderr b/tests/ui/lint/unused/issue-70041.stderr
new file mode 100644
index 000000000..b2e6d1aeb
--- /dev/null
+++ b/tests/ui/lint/unused/issue-70041.stderr
@@ -0,0 +1,18 @@
+warning: unused macro definition: `regex`
+ --> $DIR/issue-70041.rs:4:14
+ |
+LL | macro_rules! regex {
+ | ^^^^^
+ |
+ = note: `#[warn(unused_macros)]` on by default
+
+warning: unused import: `regex`
+ --> $DIR/issue-70041.rs:10:5
+ |
+LL | use regex;
+ | ^^^^^
+ |
+ = note: `#[warn(unused_imports)]` on by default
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/lint/unused/issue-71290-unused-paren-binop.rs b/tests/ui/lint/unused/issue-71290-unused-paren-binop.rs
new file mode 100644
index 000000000..24d77e36d
--- /dev/null
+++ b/tests/ui/lint/unused/issue-71290-unused-paren-binop.rs
@@ -0,0 +1,23 @@
+// check-pass
+// Make sure unused parens lint doesn't emit a false positive.
+// See https://github.com/rust-lang/rust/issues/71290 for details.
+#![deny(unused_parens)]
+
+fn x() -> u8 {
+ ({ 0 }) + 1
+}
+
+fn y() -> u8 {
+ ({ 0 } + 1)
+}
+
+pub fn foo(a: bool, b: bool) -> u8 {
+ (if a { 1 } else { 0 } + if b { 1 } else { 0 })
+}
+
+pub fn bar() -> u8 {
+ // Make sure nested expressions are handled correctly as well
+ ({ 0 } + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9)
+}
+
+fn main() {}
diff --git a/tests/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs b/tests/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs
new file mode 100644
index 000000000..8064c3a88
--- /dev/null
+++ b/tests/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs
@@ -0,0 +1,26 @@
+#![feature(generator_trait)]
+#![feature(generators)]
+#![deny(unused_braces, unused_parens)]
+
+use std::ops::Generator;
+use std::pin::Pin;
+
+fn main() {
+ let mut x = |_| {
+ while let Some(_) = (yield) {}
+ while let Some(_) = {yield} {}
+
+ // Only warn these cases
+ while let Some(_) = ({yield}) {} //~ ERROR: unnecessary parentheses
+ while let Some(_) = ((yield)) {} //~ ERROR: unnecessary parentheses
+ {{yield}}; //~ ERROR: unnecessary braces
+ {( yield )}; //~ ERROR: unnecessary parentheses
+ while let Some(_) = {(yield)} {} //~ ERROR: unnecessary parentheses
+ while let Some(_) = {{yield}} {} //~ ERROR: unnecessary braces
+
+ // FIXME: It'd be great if we could also warn them.
+ ((yield));
+ ({ yield });
+ };
+ let _ = Pin::new(&mut x).resume(Some(5));
+}
diff --git a/tests/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr b/tests/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr
new file mode 100644
index 000000000..3f1fee332
--- /dev/null
+++ b/tests/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr
@@ -0,0 +1,84 @@
+error: unnecessary parentheses around `let` scrutinee expression
+ --> $DIR/issue-74883-unused-paren-baren-yield.rs:14:29
+ |
+LL | while let Some(_) = ({yield}) {}
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-74883-unused-paren-baren-yield.rs:3:24
+ |
+LL | #![deny(unused_braces, unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - while let Some(_) = ({yield}) {}
+LL + while let Some(_) = {yield} {}
+ |
+
+error: unnecessary parentheses around `let` scrutinee expression
+ --> $DIR/issue-74883-unused-paren-baren-yield.rs:15:29
+ |
+LL | while let Some(_) = ((yield)) {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - while let Some(_) = ((yield)) {}
+LL + while let Some(_) = (yield) {}
+ |
+
+error: unnecessary braces around block return value
+ --> $DIR/issue-74883-unused-paren-baren-yield.rs:16:10
+ |
+LL | {{yield}};
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-74883-unused-paren-baren-yield.rs:3:9
+ |
+LL | #![deny(unused_braces, unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these braces
+ |
+LL - {{yield}};
+LL + {yield};
+ |
+
+error: unnecessary parentheses around block return value
+ --> $DIR/issue-74883-unused-paren-baren-yield.rs:17:10
+ |
+LL | {( yield )};
+ | ^^ ^^
+ |
+help: remove these parentheses
+ |
+LL - {( yield )};
+LL + {yield};
+ |
+
+error: unnecessary parentheses around block return value
+ --> $DIR/issue-74883-unused-paren-baren-yield.rs:18:30
+ |
+LL | while let Some(_) = {(yield)} {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - while let Some(_) = {(yield)} {}
+LL + while let Some(_) = {yield} {}
+ |
+
+error: unnecessary braces around block return value
+ --> $DIR/issue-74883-unused-paren-baren-yield.rs:19:30
+ |
+LL | while let Some(_) = {{yield}} {}
+ | ^ ^
+ |
+help: remove these braces
+ |
+LL - while let Some(_) = {{yield}} {}
+LL + while let Some(_) = {yield} {}
+ |
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/lint/unused/issue-81314-unused-span-ident.fixed b/tests/ui/lint/unused/issue-81314-unused-span-ident.fixed
new file mode 100644
index 000000000..aac918f2b
--- /dev/null
+++ b/tests/ui/lint/unused/issue-81314-unused-span-ident.fixed
@@ -0,0 +1,12 @@
+// run-rustfix
+// Regression test for #81314: Unused variable lint should
+// span only the identifier and not the rest of the pattern
+
+#![deny(unused)]
+
+fn main() {
+ let [_rest @ ..] = [1, 2, 3]; //~ ERROR unused variable
+}
+
+pub fn foo([_rest @ ..]: &[i32]) { //~ ERROR unused variable
+}
diff --git a/tests/ui/lint/unused/issue-81314-unused-span-ident.rs b/tests/ui/lint/unused/issue-81314-unused-span-ident.rs
new file mode 100644
index 000000000..78296f425
--- /dev/null
+++ b/tests/ui/lint/unused/issue-81314-unused-span-ident.rs
@@ -0,0 +1,12 @@
+// run-rustfix
+// Regression test for #81314: Unused variable lint should
+// span only the identifier and not the rest of the pattern
+
+#![deny(unused)]
+
+fn main() {
+ let [rest @ ..] = [1, 2, 3]; //~ ERROR unused variable
+}
+
+pub fn foo([rest @ ..]: &[i32]) { //~ ERROR unused variable
+}
diff --git a/tests/ui/lint/unused/issue-81314-unused-span-ident.stderr b/tests/ui/lint/unused/issue-81314-unused-span-ident.stderr
new file mode 100644
index 000000000..519c71e94
--- /dev/null
+++ b/tests/ui/lint/unused/issue-81314-unused-span-ident.stderr
@@ -0,0 +1,21 @@
+error: unused variable: `rest`
+ --> $DIR/issue-81314-unused-span-ident.rs:8:10
+ |
+LL | let [rest @ ..] = [1, 2, 3];
+ | ^^^^ help: if this is intentional, prefix it with an underscore: `_rest`
+ |
+note: the lint level is defined here
+ --> $DIR/issue-81314-unused-span-ident.rs:5:9
+ |
+LL | #![deny(unused)]
+ | ^^^^^^
+ = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
+
+error: unused variable: `rest`
+ --> $DIR/issue-81314-unused-span-ident.rs:11:13
+ |
+LL | pub fn foo([rest @ ..]: &[i32]) {
+ | ^^^^ help: if this is intentional, prefix it with an underscore: `_rest`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/unused/issue-85913.rs b/tests/ui/lint/unused/issue-85913.rs
new file mode 100644
index 000000000..7f3817b6e
--- /dev/null
+++ b/tests/ui/lint/unused/issue-85913.rs
@@ -0,0 +1,13 @@
+#![deny(unused_must_use)]
+
+pub fn fun() -> i32 {
+ function() && return 1;
+ //~^ ERROR: unused logical operation that must be used
+ return 0;
+}
+
+fn function() -> bool {
+ true
+}
+
+fn main() {}
diff --git a/tests/ui/lint/unused/issue-85913.stderr b/tests/ui/lint/unused/issue-85913.stderr
new file mode 100644
index 000000000..8234ed3b1
--- /dev/null
+++ b/tests/ui/lint/unused/issue-85913.stderr
@@ -0,0 +1,18 @@
+error: unused logical operation that must be used
+ --> $DIR/issue-85913.rs:4:5
+ |
+LL | function() && return 1;
+ | ^^^^^^^^^^^^^^^^^^^^^^ the logical operation produces a value
+ |
+note: the lint level is defined here
+ --> $DIR/issue-85913.rs:1:9
+ |
+LL | #![deny(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = function() && return 1;
+ | +++++++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/unused/issue-88519-unused-paren.rs b/tests/ui/lint/unused/issue-88519-unused-paren.rs
new file mode 100644
index 000000000..ce3d15ac1
--- /dev/null
+++ b/tests/ui/lint/unused/issue-88519-unused-paren.rs
@@ -0,0 +1,85 @@
+// check-pass
+// Make sure unused parens lint doesn't emit a false positive.
+// See https://github.com/rust-lang/rust/issues/88519
+#![deny(unused_parens)]
+#![feature(type_ascription)]
+
+// binary ops are tested in issue-71290-unused-paren-binop.rs
+
+mod call {
+ fn noop() -> u8 { 0 }
+ fn outside() -> u8 {
+ ({ noop })()
+ }
+ fn inside() -> u8 {
+ ({ noop }())
+ }
+ fn outside_match() -> u8 {
+ (match noop { x => x })()
+ }
+ fn inside_match() -> u8 {
+ (match noop { x => x }())
+ }
+ fn outside_if() -> u8 {
+ (if false { noop } else { noop })()
+ }
+ fn inside_if() -> u8 {
+ (if false { noop } else { noop }())
+ }
+}
+
+mod casts {
+ fn outside() -> u8 {
+ ({ 0 }) as u8
+ }
+ fn inside() -> u8 {
+ ({ 0 } as u8)
+ }
+ fn outside_match() -> u8 {
+ (match 0 { x => x }) as u8
+ }
+ fn inside_match() -> u8 {
+ (match 0 { x => x } as u8)
+ }
+ fn outside_if() -> u8 {
+ (if false { 0 } else { 0 }) as u8
+ }
+ fn inside_if() -> u8 {
+ (if false { 0 } else { 0 } as u8)
+ }
+}
+
+mod typeascription {
+ fn outside() -> u8 {
+ type_ascribe!(({ 0 }), u8)
+ }
+ fn outside_match() -> u8 {
+ type_ascribe!((match 0 { x => x }), u8)
+ }
+ fn outside_if() -> u8 {
+ type_ascribe!((if false { 0 } else { 0 }), u8)
+ }
+}
+
+mod index {
+ fn outside(x: &[u8]) -> u8 {
+ ({ x })[0]
+ }
+ fn inside(x: &[u8]) -> u8 {
+ ({ x }[0])
+ }
+ fn outside_match(x: &[u8]) -> u8 {
+ (match x { x => x })[0]
+ }
+ fn inside_match(x: &[u8]) -> u8 {
+ (match x { x => x }[0])
+ }
+ fn outside_if(x: &[u8]) -> u8 {
+ (if false { x } else { x })[0]
+ }
+ fn inside_if(x: &[u8]) -> u8 {
+ (if false { x } else { x }[0])
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/unused/issue-90807-unused-paren-error.rs b/tests/ui/lint/unused/issue-90807-unused-paren-error.rs
new file mode 100644
index 000000000..2fca2e262
--- /dev/null
+++ b/tests/ui/lint/unused/issue-90807-unused-paren-error.rs
@@ -0,0 +1,9 @@
+// Make sure unused parens lint emit is emitted for loop and match.
+// See https://github.com/rust-lang/rust/issues/90807
+// and https://github.com/rust-lang/rust/pull/91956#discussion_r771647953
+#![deny(unused_parens)]
+
+fn main() {
+ for _ in (1..loop { break 2 }) {} //~ERROR
+ for _ in (1..match () { () => 2 }) {} //~ERROR
+}
diff --git a/tests/ui/lint/unused/issue-90807-unused-paren-error.stderr b/tests/ui/lint/unused/issue-90807-unused-paren-error.stderr
new file mode 100644
index 000000000..b3b809d5f
--- /dev/null
+++ b/tests/ui/lint/unused/issue-90807-unused-paren-error.stderr
@@ -0,0 +1,31 @@
+error: unnecessary parentheses around `for` iterator expression
+ --> $DIR/issue-90807-unused-paren-error.rs:7:14
+ |
+LL | for _ in (1..loop { break 2 }) {}
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-90807-unused-paren-error.rs:4:9
+ |
+LL | #![deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - for _ in (1..loop { break 2 }) {}
+LL + for _ in 1..loop { break 2 } {}
+ |
+
+error: unnecessary parentheses around `for` iterator expression
+ --> $DIR/issue-90807-unused-paren-error.rs:8:14
+ |
+LL | for _ in (1..match () { () => 2 }) {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - for _ in (1..match () { () => 2 }) {}
+LL + for _ in 1..match () { () => 2 } {}
+ |
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/unused/issue-90807-unused-paren.rs b/tests/ui/lint/unused/issue-90807-unused-paren.rs
new file mode 100644
index 000000000..4c0930f96
--- /dev/null
+++ b/tests/ui/lint/unused/issue-90807-unused-paren.rs
@@ -0,0 +1,8 @@
+// check-pass
+// Make sure unused parens lint doesn't emit a false positive.
+// See https://github.com/rust-lang/rust/issues/90807
+#![deny(unused_parens)]
+
+fn main() {
+ for _ in (1..{ 2 }) {}
+}
diff --git a/tests/ui/lint/unused/issue-92751.rs b/tests/ui/lint/unused/issue-92751.rs
new file mode 100644
index 000000000..2fb292736
--- /dev/null
+++ b/tests/ui/lint/unused/issue-92751.rs
@@ -0,0 +1,9 @@
+#[deny(unused)]
+pub fn broken(x: Option<()>) -> i32 {
+ match x {
+ Some(()) => (1), //~ ERROR unnecessary parentheses around match arm expression
+ None => (2), //~ ERROR unnecessary parentheses around match arm expression
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/lint/unused/issue-92751.stderr b/tests/ui/lint/unused/issue-92751.stderr
new file mode 100644
index 000000000..0a8d8e672
--- /dev/null
+++ b/tests/ui/lint/unused/issue-92751.stderr
@@ -0,0 +1,32 @@
+error: unnecessary parentheses around match arm expression
+ --> $DIR/issue-92751.rs:4:21
+ |
+LL | Some(()) => (1),
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-92751.rs:1:8
+ |
+LL | #[deny(unused)]
+ | ^^^^^^
+ = note: `#[deny(unused_parens)]` implied by `#[deny(unused)]`
+help: remove these parentheses
+ |
+LL - Some(()) => (1),
+LL + Some(()) => 1,
+ |
+
+error: unnecessary parentheses around match arm expression
+ --> $DIR/issue-92751.rs:5:17
+ |
+LL | None => (2),
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - None => (2),
+LL + None => 2,
+ |
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/unused/lint-unused-extern-crate.rs b/tests/ui/lint/unused/lint-unused-extern-crate.rs
new file mode 100644
index 000000000..d5e4da526
--- /dev/null
+++ b/tests/ui/lint/unused/lint-unused-extern-crate.rs
@@ -0,0 +1,35 @@
+// aux-build:lint_unused_extern_crate.rs
+// aux-build:lint_unused_extern_crate2.rs
+// aux-build:lint_unused_extern_crate3.rs
+// aux-build:lint_unused_extern_crate4.rs
+// aux-build:lint_unused_extern_crate5.rs
+
+#![deny(unused_extern_crates)]
+#![allow(unused_variables)]
+#![allow(deprecated)]
+
+extern crate lint_unused_extern_crate5; //~ ERROR: unused extern crate
+
+pub extern crate lint_unused_extern_crate4; // no error, it is re-exported
+
+extern crate lint_unused_extern_crate3; // no error, it is used
+
+extern crate lint_unused_extern_crate2; // no error, the use marks it as used
+ // even if imported objects aren't used
+
+extern crate lint_unused_extern_crate as other; // no error, the use * marks it as used
+
+#[allow(unused_imports)]
+use lint_unused_extern_crate2::foo as bar;
+
+use other::*;
+
+mod foo {
+ // Test that this is unused even though an earlier `extern crate` is used.
+ extern crate lint_unused_extern_crate2; //~ ERROR unused extern crate
+}
+
+fn main() {
+ lint_unused_extern_crate3::foo();
+ let y = foo();
+}
diff --git a/tests/ui/lint/unused/lint-unused-extern-crate.stderr b/tests/ui/lint/unused/lint-unused-extern-crate.stderr
new file mode 100644
index 000000000..46d8f3bee
--- /dev/null
+++ b/tests/ui/lint/unused/lint-unused-extern-crate.stderr
@@ -0,0 +1,20 @@
+error: unused extern crate
+ --> $DIR/lint-unused-extern-crate.rs:11:1
+ |
+LL | extern crate lint_unused_extern_crate5;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-extern-crate.rs:7:9
+ |
+LL | #![deny(unused_extern_crates)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unused extern crate
+ --> $DIR/lint-unused-extern-crate.rs:29:5
+ |
+LL | extern crate lint_unused_extern_crate2;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/unused/lint-unused-imports.rs b/tests/ui/lint/unused/lint-unused-imports.rs
new file mode 100644
index 000000000..4754d8880
--- /dev/null
+++ b/tests/ui/lint/unused/lint-unused-imports.rs
@@ -0,0 +1,90 @@
+#![deny(unused_imports)]
+#![allow(dead_code)]
+
+use bar::c::cc as cal;
+
+use std::mem::*; // shouldn't get errors for not using
+ // everything imported
+use std::fmt::{};
+//~^ ERROR unused import: `std::fmt::{}`
+
+// Should get errors for both 'Some' and 'None'
+use std::option::Option::{Some, None};
+//~^ ERROR unused imports: `None`, `Some`
+
+use test::A; //~ ERROR unused import: `test::A`
+// Be sure that if we just bring some methods into scope that they're also
+// counted as being used.
+use test::B;
+// But only when actually used: do not get confused by the method with the same name.
+use test::B2; //~ ERROR unused import: `test::B2`
+
+// Make sure this import is warned about when at least one of its imported names
+// is unused
+use test2::{foo, bar}; //~ ERROR unused import: `bar`
+
+mod test2 {
+ pub fn foo() {}
+ pub fn bar() {}
+}
+
+mod test {
+ pub trait A { fn a(&self) {} }
+ pub trait B { fn b(&self) {} }
+ pub trait B2 { fn b(&self) {} }
+ pub struct C;
+ impl A for C {}
+ impl B for C {}
+}
+
+mod foo {
+ pub struct Point{pub x: isize, pub y: isize}
+ pub struct Square{pub p: Point, pub h: usize, pub w: usize}
+}
+
+mod bar {
+ // Don't ignore on 'pub use' because we're not sure if it's used or not
+ pub use std::cmp::PartialEq;
+ pub struct Square;
+
+ pub mod c {
+ use foo::Point;
+ use foo::Square; //~ ERROR unused import: `foo::Square`
+ pub fn cc(_p: Point) -> super::Square {
+ fn f() -> super::Square {
+ super::Square
+ }
+ f()
+ }
+ }
+
+ #[allow(unused_imports)]
+ mod foo {
+ use std::cmp::PartialEq;
+ }
+}
+
+fn g() {
+ use self::g; //~ ERROR unused import: `self::g`
+ //~^ ERROR the item `g` is imported redundantly
+ fn f() {
+ self::g();
+ }
+}
+
+// cf. issue #35135.
+#[allow(unused_variables)]
+fn h() {
+ use test2::foo; //~ ERROR unused import: `test2::foo`
+ //~^ ERROR the item `foo` is imported redundantly
+ let foo = 0;
+}
+
+fn main() {
+ cal(foo::Point{x:3, y:9});
+ let mut a = 3;
+ let mut b = 4;
+ swap(&mut a, &mut b);
+ test::C.b();
+ let _a = foo();
+}
diff --git a/tests/ui/lint/unused/lint-unused-imports.stderr b/tests/ui/lint/unused/lint-unused-imports.stderr
new file mode 100644
index 000000000..0574ca456
--- /dev/null
+++ b/tests/ui/lint/unused/lint-unused-imports.stderr
@@ -0,0 +1,78 @@
+error: unused import: `std::fmt::{}`
+ --> $DIR/lint-unused-imports.rs:8:5
+ |
+LL | use std::fmt::{};
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-imports.rs:1:9
+ |
+LL | #![deny(unused_imports)]
+ | ^^^^^^^^^^^^^^
+
+error: unused imports: `None`, `Some`
+ --> $DIR/lint-unused-imports.rs:12:27
+ |
+LL | use std::option::Option::{Some, None};
+ | ^^^^ ^^^^
+
+error: unused import: `test::A`
+ --> $DIR/lint-unused-imports.rs:15:5
+ |
+LL | use test::A;
+ | ^^^^^^^
+
+error: unused import: `bar`
+ --> $DIR/lint-unused-imports.rs:24:18
+ |
+LL | use test2::{foo, bar};
+ | ^^^
+
+error: unused import: `foo::Square`
+ --> $DIR/lint-unused-imports.rs:52:13
+ |
+LL | use foo::Square;
+ | ^^^^^^^^^^^
+
+error: the item `g` is imported redundantly
+ --> $DIR/lint-unused-imports.rs:68:9
+ |
+LL | / fn g() {
+LL | | use self::g;
+ | | ^^^^^^^
+LL | |
+LL | | fn f() {
+LL | | self::g();
+LL | | }
+LL | | }
+ | |_- the item `g` is already defined here
+
+error: unused import: `self::g`
+ --> $DIR/lint-unused-imports.rs:68:9
+ |
+LL | use self::g;
+ | ^^^^^^^
+
+error: the item `foo` is imported redundantly
+ --> $DIR/lint-unused-imports.rs:78:9
+ |
+LL | use test2::{foo, bar};
+ | --- the item `foo` is already imported here
+...
+LL | use test2::foo;
+ | ^^^^^^^^^^
+
+error: unused import: `test2::foo`
+ --> $DIR/lint-unused-imports.rs:78:9
+ |
+LL | use test2::foo;
+ | ^^^^^^^^^^
+
+error: unused import: `test::B2`
+ --> $DIR/lint-unused-imports.rs:20:5
+ |
+LL | use test::B2;
+ | ^^^^^^^^
+
+error: aborting due to 10 previous errors
+
diff --git a/tests/ui/lint/unused/lint-unused-mut-self.fixed b/tests/ui/lint/unused/lint-unused-mut-self.fixed
new file mode 100644
index 000000000..92ce10358
--- /dev/null
+++ b/tests/ui/lint/unused/lint-unused-mut-self.fixed
@@ -0,0 +1,14 @@
+// run-rustfix
+
+#![allow(unused_assignments)]
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![deny(unused_mut)]
+
+struct Foo;
+impl Foo {
+ fn foo(self) {} //~ ERROR: variable does not need to be mutable
+ fn bar(self: Box<Foo>) {} //~ ERROR: variable does not need to be mutable
+}
+
+fn main() {}
diff --git a/tests/ui/lint/unused/lint-unused-mut-self.rs b/tests/ui/lint/unused/lint-unused-mut-self.rs
new file mode 100644
index 000000000..70736ce21
--- /dev/null
+++ b/tests/ui/lint/unused/lint-unused-mut-self.rs
@@ -0,0 +1,14 @@
+// run-rustfix
+
+#![allow(unused_assignments)]
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![deny(unused_mut)]
+
+struct Foo;
+impl Foo {
+ fn foo(mut self) {} //~ ERROR: variable does not need to be mutable
+ fn bar(mut self: Box<Foo>) {} //~ ERROR: variable does not need to be mutable
+}
+
+fn main() {}
diff --git a/tests/ui/lint/unused/lint-unused-mut-self.stderr b/tests/ui/lint/unused/lint-unused-mut-self.stderr
new file mode 100644
index 000000000..01a524bd3
--- /dev/null
+++ b/tests/ui/lint/unused/lint-unused-mut-self.stderr
@@ -0,0 +1,24 @@
+error: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-self.rs:10:12
+ |
+LL | fn foo(mut self) {}
+ | ----^^^^
+ | |
+ | help: remove this `mut`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-mut-self.rs:6:9
+ |
+LL | #![deny(unused_mut)]
+ | ^^^^^^^^^^
+
+error: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-self.rs:11:12
+ |
+LL | fn bar(mut self: Box<Foo>) {}
+ | ----^^^^
+ | |
+ | help: remove this `mut`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/unused/lint-unused-mut-variables.rs b/tests/ui/lint/unused/lint-unused-mut-variables.rs
new file mode 100644
index 000000000..67ec7facf
--- /dev/null
+++ b/tests/ui/lint/unused/lint-unused-mut-variables.rs
@@ -0,0 +1,207 @@
+// edition:2018
+
+// Exercise the unused_mut attribute in some positive and negative cases
+
+#![warn(unused_mut)]
+#![feature(async_closure, raw_ref_op)]
+
+async fn baz_async(
+ mut a: i32,
+ //~^ WARN: variable does not need to be mutable
+ #[allow(unused_mut)] mut b: i32,
+) {}
+fn baz(
+ mut a: i32,
+ //~^ WARN: variable does not need to be mutable
+ #[allow(unused_mut)] mut b: i32,
+ #[allow(unused_mut)] (mut c, d): (i32, i32)
+) {}
+
+struct RefStruct {}
+impl RefStruct {
+ async fn baz_async(
+ mut a: i32,
+ //~^ WARN: variable does not need to be mutable
+ #[allow(unused_mut)] mut b: i32,
+ ) {}
+ fn baz(
+ &self,
+ mut a: i32,
+ //~^ WARN: variable does not need to be mutable
+ #[allow(unused_mut)] mut b: i32,
+ #[allow(unused_mut)] (mut c, d): (i32, i32)
+ ) {}
+}
+
+trait RefTrait {
+ fn baz(
+ &self,
+ mut a: i32,
+ //~^ WARN: variable does not need to be mutable
+ #[allow(unused_mut)] mut b: i32,
+ #[allow(unused_mut)] (mut c, d): (i32, i32)
+ ) {}
+}
+impl RefTrait for () {
+ fn baz(
+ &self,
+ mut a: i32,
+ //~^ WARN: variable does not need to be mutable
+ #[allow(unused_mut)] mut b: i32,
+ #[allow(unused_mut)] (mut c, d): (i32, i32)
+ ) {}
+}
+
+fn main() {
+ let _ = async move |
+ mut a: i32,
+ //~^ WARN: variable does not need to be mutable
+ #[allow(unused_mut)] mut b: i32,
+ | {};
+ let _ = |
+ mut a: i32,
+ //~^ WARN: variable does not need to be mutable
+ #[allow(unused_mut)] mut b: i32,
+ #[allow(unused_mut)] (mut c, d): (i32, i32)
+ | {};
+
+ // negative cases
+ let mut a = 3; //~ WARN: variable does not need to be mutable
+
+ let mut a = 2; //~ WARN: variable does not need to be mutable
+
+ let mut b = 3; //~ WARN: variable does not need to be mutable
+
+ let mut a = vec![3]; //~ WARN: variable does not need to be mutable
+
+ let (mut a, b) = (1, 2); //~ WARN: variable does not need to be mutable
+
+ let mut a; //~ WARN: variable does not need to be mutable
+
+ a = 3;
+
+ let mut b; //~ WARN: variable does not need to be mutable
+
+ if true {
+ b = 3;
+ } else {
+ b = 4;
+ }
+
+ match 30 {
+ mut x => {} //~ WARN: variable does not need to be mutable
+
+ }
+
+ match (30, 2) {
+ // FIXME: Here's a false positive,
+ // shouldn't be removed `mut` not to be bound with a different way.
+ (mut x, 1) | //~ WARN: variable does not need to be mutable
+
+ (mut x, 2) |
+ (mut x, 3) => {
+ }
+ _ => {}
+ }
+
+ let x = |mut y: isize| 10; //~ WARN: variable does not need to be mutable
+
+ fn what(mut foo: isize) {} //~ WARN: variable does not need to be mutable
+
+
+ let mut a = &mut 5; //~ WARN: variable does not need to be mutable
+
+ *a = 4;
+
+ let mut a = 5;
+ let mut b = (&mut a,); //~ WARN: variable does not need to be mutable
+ *b.0 = 4;
+
+ let mut x = &mut 1; //~ WARN: variable does not need to be mutable
+
+ let mut f = || {
+ *x += 1;
+ };
+ f();
+
+ fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
+ &mut arg[..] //~^ WARN: variable does not need to be mutable
+
+ }
+
+ let mut v : &mut Vec<()> = &mut vec![]; //~ WARN: variable does not need to be mutable
+
+ v.push(());
+
+ // positive cases
+ let mut a = 2;
+ a = 3;
+ let mut a = Vec::new();
+ a.push(3);
+ let mut a = Vec::new();
+ callback(|| {
+ a.push(3);
+ });
+ let mut a = Vec::new();
+ callback(|| {
+ callback(|| {
+ a.push(3);
+ });
+ });
+ let (mut a, b) = (1, 2);
+ a = 34;
+
+ match 30 {
+ mut x => {
+ x = 21;
+ }
+ }
+
+ match (30, 2) {
+ (mut x, 1) |
+ (mut x, 2) |
+ (mut x, 3) => {
+ x = 21
+ }
+ _ => {}
+ }
+
+ // Attribute should be respected on match arms
+ match 0 {
+ #[allow(unused_mut)]
+ mut x => {
+ let mut y = 1;
+ },
+ }
+
+ let x = |mut y: isize| y = 32;
+ fn nothing(mut foo: isize) { foo = 37; }
+
+ // leading underscore should avoid the warning, just like the
+ // unused variable lint.
+ let mut _allowed = 1;
+
+ let mut raw_address_of_mut = 1; // OK
+ let mut_ptr = &raw mut raw_address_of_mut;
+
+ let mut raw_address_of_const = 1; //~ WARN: variable does not need to be mutable
+ let const_ptr = &raw const raw_address_of_const;
+}
+
+fn callback<F>(f: F) where F: FnOnce() {}
+
+// make sure the lint attribute can be turned off
+#[allow(unused_mut)]
+fn foo(mut a: isize) {
+ let mut a = 3;
+ let mut b = vec![2];
+}
+
+// make sure the lint attribute can be turned off on let statements
+#[deny(unused_mut)]
+fn bar() {
+ #[allow(unused_mut)]
+ let mut a = 3;
+ let mut b = vec![2]; //~ ERROR: variable does not need to be mutable
+
+}
diff --git a/tests/ui/lint/unused/lint-unused-mut-variables.stderr b/tests/ui/lint/unused/lint-unused-mut-variables.stderr
new file mode 100644
index 000000000..805ed2b40
--- /dev/null
+++ b/tests/ui/lint/unused/lint-unused-mut-variables.stderr
@@ -0,0 +1,222 @@
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:9:5
+ |
+LL | mut a: i32,
+ | ----^
+ | |
+ | help: remove this `mut`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-mut-variables.rs:5:9
+ |
+LL | #![warn(unused_mut)]
+ | ^^^^^^^^^^
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:23:9
+ |
+LL | mut a: i32,
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:14:5
+ |
+LL | mut a: i32,
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:29:9
+ |
+LL | mut a: i32,
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:39:9
+ |
+LL | mut a: i32,
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:48:9
+ |
+LL | mut a: i32,
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:57:9
+ |
+LL | mut a: i32,
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:62:9
+ |
+LL | mut a: i32,
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:107:14
+ |
+LL | let x = |mut y: isize| 10;
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:69:9
+ |
+LL | let mut a = 3;
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:71:9
+ |
+LL | let mut a = 2;
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:73:9
+ |
+LL | let mut b = 3;
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:75:9
+ |
+LL | let mut a = vec![3];
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:77:10
+ |
+LL | let (mut a, b) = (1, 2);
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:79:9
+ |
+LL | let mut a;
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:83:9
+ |
+LL | let mut b;
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:92:9
+ |
+LL | mut x => {}
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:99:10
+ |
+LL | (mut x, 1) |
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:112:9
+ |
+LL | let mut a = &mut 5;
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:117:9
+ |
+LL | let mut b = (&mut a,);
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:120:9
+ |
+LL | let mut x = &mut 1;
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:132:9
+ |
+LL | let mut v : &mut Vec<()> = &mut vec![];
+ | ----^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:187:9
+ |
+LL | let mut raw_address_of_const = 1;
+ | ----^^^^^^^^^^^^^^^^^^^^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:109:13
+ |
+LL | fn what(mut foo: isize) {}
+ | ----^^^
+ | |
+ | help: remove this `mut`
+
+warning: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:127:20
+ |
+LL | fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
+ | ----^^^
+ | |
+ | help: remove this `mut`
+
+error: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:205:9
+ |
+LL | let mut b = vec![2];
+ | ----^
+ | |
+ | help: remove this `mut`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-mut-variables.rs:201:8
+ |
+LL | #[deny(unused_mut)]
+ | ^^^^^^^^^^
+
+error: aborting due to previous error; 25 warnings emitted
+
diff --git a/tests/ui/lint/unused/lint-unused-variables.rs b/tests/ui/lint/unused/lint-unused-variables.rs
new file mode 100644
index 000000000..6850e9992
--- /dev/null
+++ b/tests/ui/lint/unused/lint-unused-variables.rs
@@ -0,0 +1,79 @@
+// compile-flags: --cfg something
+// edition:2018
+
+#![feature(async_closure)]
+#![deny(unused_variables)]
+
+async fn foo_async(
+ a: i32,
+ //~^ ERROR unused variable: `a`
+ #[allow(unused_variables)] b: i32,
+) {}
+fn foo(
+ #[allow(unused_variables)] a: i32,
+ b: i32,
+ //~^ ERROR unused variable: `b`
+) {}
+
+struct RefStruct {}
+impl RefStruct {
+ async fn bar_async(
+ &self,
+ a: i32,
+ //~^ ERROR unused variable: `a`
+ #[allow(unused_variables)] b: i32,
+ ) {}
+ fn bar(
+ &self,
+ #[allow(unused_variables)] a: i32,
+ b: i32,
+ //~^ ERROR unused variable: `b`
+ ) {}
+ fn issue_64682_associated_fn(
+ #[allow(unused_variables)] a: i32,
+ b: i32,
+ //~^ ERROR unused variable: `b`
+ ) {}
+}
+trait RefTrait {
+ fn bar(
+ &self,
+ #[allow(unused_variables)] a: i32,
+ b: i32,
+ //~^ ERROR unused variable: `b`
+ ) {}
+ fn issue_64682_associated_fn(
+ #[allow(unused_variables)] a: i32,
+ b: i32,
+ //~^ ERROR unused variable: `b`
+ ) {}
+}
+impl RefTrait for RefStruct {
+ fn bar(
+ &self,
+ #[allow(unused_variables)] a: i32,
+ b: i32,
+ //~^ ERROR unused variable: `b`
+ ) {}
+ fn issue_64682_associated_fn(
+ #[allow(unused_variables)] a: i32,
+ b: i32,
+ //~^ ERROR unused variable: `b`
+ ) {}
+}
+
+fn main() {
+ let _: fn(_, _) = foo;
+ let a = async move |
+ a: i32,
+ //~^ ERROR unused variable: `a`
+ #[allow(unused_variables)] b: i32,
+ | {};
+ let b = |
+ #[allow(unused_variables)] a: i32,
+ b: i32,
+ //~^ ERROR unused variable: `b`
+ | {};
+ let _ = a(1, 2);
+ let _ = b(1, 2);
+}
diff --git a/tests/ui/lint/unused/lint-unused-variables.stderr b/tests/ui/lint/unused/lint-unused-variables.stderr
new file mode 100644
index 000000000..fd9a5bcbf
--- /dev/null
+++ b/tests/ui/lint/unused/lint-unused-variables.stderr
@@ -0,0 +1,74 @@
+error: unused variable: `a`
+ --> $DIR/lint-unused-variables.rs:8:5
+ |
+LL | a: i32,
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-unused-variables.rs:5:9
+ |
+LL | #![deny(unused_variables)]
+ | ^^^^^^^^^^^^^^^^
+
+error: unused variable: `b`
+ --> $DIR/lint-unused-variables.rs:14:5
+ |
+LL | b: i32,
+ | ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `a`
+ --> $DIR/lint-unused-variables.rs:22:9
+ |
+LL | a: i32,
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+
+error: unused variable: `b`
+ --> $DIR/lint-unused-variables.rs:29:9
+ |
+LL | b: i32,
+ | ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `b`
+ --> $DIR/lint-unused-variables.rs:34:9
+ |
+LL | b: i32,
+ | ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `b`
+ --> $DIR/lint-unused-variables.rs:42:9
+ |
+LL | b: i32,
+ | ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `b`
+ --> $DIR/lint-unused-variables.rs:47:9
+ |
+LL | b: i32,
+ | ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `b`
+ --> $DIR/lint-unused-variables.rs:55:9
+ |
+LL | b: i32,
+ | ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `b`
+ --> $DIR/lint-unused-variables.rs:60:9
+ |
+LL | b: i32,
+ | ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `a`
+ --> $DIR/lint-unused-variables.rs:68:9
+ |
+LL | a: i32,
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+
+error: unused variable: `b`
+ --> $DIR/lint-unused-variables.rs:74:9
+ |
+LL | b: i32,
+ | ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: aborting due to 11 previous errors
+
diff --git a/tests/ui/lint/unused/must-use-box-from-raw.rs b/tests/ui/lint/unused/must-use-box-from-raw.rs
new file mode 100644
index 000000000..9ea772689
--- /dev/null
+++ b/tests/ui/lint/unused/must-use-box-from-raw.rs
@@ -0,0 +1,11 @@
+// #99269
+
+// check-pass
+
+#![warn(unused_must_use)]
+
+unsafe fn free<T>(ptr: *mut T) {
+ Box::from_raw(ptr); //~ WARNING unused return value
+}
+
+fn main() {}
diff --git a/tests/ui/lint/unused/must-use-box-from-raw.stderr b/tests/ui/lint/unused/must-use-box-from-raw.stderr
new file mode 100644
index 000000000..47ab613be
--- /dev/null
+++ b/tests/ui/lint/unused/must-use-box-from-raw.stderr
@@ -0,0 +1,15 @@
+warning: unused return value of `Box::<T>::from_raw` that must be used
+ --> $DIR/must-use-box-from-raw.rs:8:5
+ |
+LL | Box::from_raw(ptr);
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = note: call `drop(Box::from_raw(ptr))` if you intend to drop the `Box`
+note: the lint level is defined here
+ --> $DIR/must-use-box-from-raw.rs:5:9
+ |
+LL | #![warn(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/unused/must-use-ops.rs b/tests/ui/lint/unused/must-use-ops.rs
new file mode 100644
index 000000000..60f877aa8
--- /dev/null
+++ b/tests/ui/lint/unused/must-use-ops.rs
@@ -0,0 +1,51 @@
+// Issue #50124 - Test warning for unused operator expressions
+
+// check-pass
+
+#![warn(unused_must_use)]
+#![feature(never_type)]
+
+fn deref_never(x: &!) {
+ // Don't lint for uninhabited typess
+ *x;
+}
+
+fn main() {
+ let val = 1;
+ let val_pointer = &val;
+
+ // Comparison Operators
+ val == 1; //~ WARNING unused comparison
+ val < 1; //~ WARNING unused comparison
+ val <= 1; //~ WARNING unused comparison
+ val != 1; //~ WARNING unused comparison
+ val >= 1; //~ WARNING unused comparison
+ val > 1; //~ WARNING unused comparison
+
+ // Arithmetic Operators
+ val + 2; //~ WARNING unused arithmetic operation
+ val - 2; //~ WARNING unused arithmetic operation
+ val / 2; //~ WARNING unused arithmetic operation
+ val * 2; //~ WARNING unused arithmetic operation
+ val % 2; //~ WARNING unused arithmetic operation
+
+ // Logical Operators
+ true && true; //~ WARNING unused logical operation
+ false || true; //~ WARNING unused logical operation
+
+ // Bitwise Operators
+ 5 ^ val; //~ WARNING unused bitwise operation
+ 5 & val; //~ WARNING unused bitwise operation
+ 5 | val; //~ WARNING unused bitwise operation
+ 5 << val; //~ WARNING unused bitwise operation
+ 5 >> val; //~ WARNING unused bitwise operation
+
+ // Unary Operators
+ !val; //~ WARNING unused unary operation
+ -val; //~ WARNING unused unary operation
+ *val_pointer; //~ WARNING unused unary operation
+
+ if false {
+ deref_never(&panic!());
+ }
+}
diff --git a/tests/ui/lint/unused/must-use-ops.stderr b/tests/ui/lint/unused/must-use-ops.stderr
new file mode 100644
index 000000000..79a53d39c
--- /dev/null
+++ b/tests/ui/lint/unused/must-use-ops.stderr
@@ -0,0 +1,238 @@
+warning: unused comparison that must be used
+ --> $DIR/must-use-ops.rs:18:5
+ |
+LL | val == 1;
+ | ^^^^^^^^ the comparison produces a value
+ |
+note: the lint level is defined here
+ --> $DIR/must-use-ops.rs:5:9
+ |
+LL | #![warn(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = val == 1;
+ | +++++++
+
+warning: unused comparison that must be used
+ --> $DIR/must-use-ops.rs:19:5
+ |
+LL | val < 1;
+ | ^^^^^^^ the comparison produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = val < 1;
+ | +++++++
+
+warning: unused comparison that must be used
+ --> $DIR/must-use-ops.rs:20:5
+ |
+LL | val <= 1;
+ | ^^^^^^^^ the comparison produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = val <= 1;
+ | +++++++
+
+warning: unused comparison that must be used
+ --> $DIR/must-use-ops.rs:21:5
+ |
+LL | val != 1;
+ | ^^^^^^^^ the comparison produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = val != 1;
+ | +++++++
+
+warning: unused comparison that must be used
+ --> $DIR/must-use-ops.rs:22:5
+ |
+LL | val >= 1;
+ | ^^^^^^^^ the comparison produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = val >= 1;
+ | +++++++
+
+warning: unused comparison that must be used
+ --> $DIR/must-use-ops.rs:23:5
+ |
+LL | val > 1;
+ | ^^^^^^^ the comparison produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = val > 1;
+ | +++++++
+
+warning: unused arithmetic operation that must be used
+ --> $DIR/must-use-ops.rs:26:5
+ |
+LL | val + 2;
+ | ^^^^^^^ the arithmetic operation produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = val + 2;
+ | +++++++
+
+warning: unused arithmetic operation that must be used
+ --> $DIR/must-use-ops.rs:27:5
+ |
+LL | val - 2;
+ | ^^^^^^^ the arithmetic operation produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = val - 2;
+ | +++++++
+
+warning: unused arithmetic operation that must be used
+ --> $DIR/must-use-ops.rs:28:5
+ |
+LL | val / 2;
+ | ^^^^^^^ the arithmetic operation produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = val / 2;
+ | +++++++
+
+warning: unused arithmetic operation that must be used
+ --> $DIR/must-use-ops.rs:29:5
+ |
+LL | val * 2;
+ | ^^^^^^^ the arithmetic operation produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = val * 2;
+ | +++++++
+
+warning: unused arithmetic operation that must be used
+ --> $DIR/must-use-ops.rs:30:5
+ |
+LL | val % 2;
+ | ^^^^^^^ the arithmetic operation produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = val % 2;
+ | +++++++
+
+warning: unused logical operation that must be used
+ --> $DIR/must-use-ops.rs:33:5
+ |
+LL | true && true;
+ | ^^^^^^^^^^^^ the logical operation produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = true && true;
+ | +++++++
+
+warning: unused logical operation that must be used
+ --> $DIR/must-use-ops.rs:34:5
+ |
+LL | false || true;
+ | ^^^^^^^^^^^^^ the logical operation produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = false || true;
+ | +++++++
+
+warning: unused bitwise operation that must be used
+ --> $DIR/must-use-ops.rs:37:5
+ |
+LL | 5 ^ val;
+ | ^^^^^^^ the bitwise operation produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = 5 ^ val;
+ | +++++++
+
+warning: unused bitwise operation that must be used
+ --> $DIR/must-use-ops.rs:38:5
+ |
+LL | 5 & val;
+ | ^^^^^^^ the bitwise operation produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = 5 & val;
+ | +++++++
+
+warning: unused bitwise operation that must be used
+ --> $DIR/must-use-ops.rs:39:5
+ |
+LL | 5 | val;
+ | ^^^^^^^ the bitwise operation produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = 5 | val;
+ | +++++++
+
+warning: unused bitwise operation that must be used
+ --> $DIR/must-use-ops.rs:40:5
+ |
+LL | 5 << val;
+ | ^^^^^^^^ the bitwise operation produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = 5 << val;
+ | +++++++
+
+warning: unused bitwise operation that must be used
+ --> $DIR/must-use-ops.rs:41:5
+ |
+LL | 5 >> val;
+ | ^^^^^^^^ the bitwise operation produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = 5 >> val;
+ | +++++++
+
+warning: unused unary operation that must be used
+ --> $DIR/must-use-ops.rs:44:5
+ |
+LL | !val;
+ | ^^^^ the unary operation produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = !val;
+ | +++++++
+
+warning: unused unary operation that must be used
+ --> $DIR/must-use-ops.rs:45:5
+ |
+LL | -val;
+ | ^^^^ the unary operation produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = -val;
+ | +++++++
+
+warning: unused unary operation that must be used
+ --> $DIR/must-use-ops.rs:46:5
+ |
+LL | *val_pointer;
+ | ^^^^^^^^^^^^ the unary operation produces a value
+ |
+help: use `let _ = ...` to ignore the resulting value
+ |
+LL | let _ = *val_pointer;
+ | +++++++
+
+warning: 21 warnings emitted
+
diff --git a/tests/ui/lint/unused/must_use-array.rs b/tests/ui/lint/unused/must_use-array.rs
new file mode 100644
index 000000000..b7bae4b0a
--- /dev/null
+++ b/tests/ui/lint/unused/must_use-array.rs
@@ -0,0 +1,54 @@
+#![deny(unused_must_use)]
+
+#[must_use]
+#[derive(Clone, Copy)]
+struct S;
+
+struct A;
+
+#[must_use]
+trait T {}
+
+impl T for A {}
+
+fn empty() -> [S; 0] {
+ []
+}
+
+fn singleton() -> [S; 1] {
+ [S]
+}
+
+fn many() -> [S; 4] {
+ [S, S, S, S]
+}
+
+fn array_of_impl_trait() -> [impl T; 2] {
+ [A, A]
+}
+
+fn impl_array() -> [(u8, Box<dyn T>); 2] {
+ [(0, Box::new(A)), (0, Box::new(A))]
+}
+
+fn array_of_arrays_of_arrays() -> [[[S; 1]; 2]; 1] {
+ [[[S], [S]]]
+}
+
+fn usize_max() -> [S; usize::MAX] {
+ [S; usize::MAX]
+}
+
+fn main() {
+ empty(); // ok
+ singleton(); //~ ERROR unused array of `S` that must be used
+ many(); //~ ERROR unused array of `S` that must be used
+ ([S], 0, ()); //~ ERROR unused array of `S` in tuple element 0 that must be used
+ array_of_impl_trait(); //~ ERROR unused array of implementers of `T` that must be used
+ impl_array();
+ //~^ ERROR unused array of boxed `T` trait objects in tuple element 1 that must be used
+ array_of_arrays_of_arrays();
+ //~^ ERROR unused array of arrays of arrays of `S` that must be used
+ usize_max();
+ //~^ ERROR unused array of `S` that must be used
+}
diff --git a/tests/ui/lint/unused/must_use-array.stderr b/tests/ui/lint/unused/must_use-array.stderr
new file mode 100644
index 000000000..61ef2088d
--- /dev/null
+++ b/tests/ui/lint/unused/must_use-array.stderr
@@ -0,0 +1,50 @@
+error: unused array of `S` that must be used
+ --> $DIR/must_use-array.rs:44:5
+ |
+LL | singleton();
+ | ^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/must_use-array.rs:1:9
+ |
+LL | #![deny(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+
+error: unused array of `S` that must be used
+ --> $DIR/must_use-array.rs:45:5
+ |
+LL | many();
+ | ^^^^^^
+
+error: unused array of `S` in tuple element 0 that must be used
+ --> $DIR/must_use-array.rs:46:6
+ |
+LL | ([S], 0, ());
+ | ^^^
+
+error: unused array of implementers of `T` that must be used
+ --> $DIR/must_use-array.rs:47:5
+ |
+LL | array_of_impl_trait();
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: unused array of boxed `T` trait objects in tuple element 1 that must be used
+ --> $DIR/must_use-array.rs:48:5
+ |
+LL | impl_array();
+ | ^^^^^^^^^^^^
+
+error: unused array of arrays of arrays of `S` that must be used
+ --> $DIR/must_use-array.rs:50:5
+ |
+LL | array_of_arrays_of_arrays();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unused array of `S` that must be used
+ --> $DIR/must_use-array.rs:52:5
+ |
+LL | usize_max();
+ | ^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
+
diff --git a/tests/ui/lint/unused/must_use-in-stdlib-traits.rs b/tests/ui/lint/unused/must_use-in-stdlib-traits.rs
new file mode 100644
index 000000000..70dddf61f
--- /dev/null
+++ b/tests/ui/lint/unused/must_use-in-stdlib-traits.rs
@@ -0,0 +1,47 @@
+#![deny(unused_must_use)]
+#![feature(arbitrary_self_types)]
+
+use std::iter::Iterator;
+use std::future::Future;
+
+use std::task::{Context, Poll};
+use std::pin::Pin;
+use std::unimplemented;
+
+struct MyFuture;
+
+impl Future for MyFuture {
+ type Output = u32;
+
+ fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<u32> {
+ Poll::Pending
+ }
+}
+
+fn iterator() -> impl Iterator {
+ std::iter::empty::<u32>()
+}
+
+fn future() -> impl Future {
+ MyFuture
+}
+
+fn square_fn_once() -> impl FnOnce(u32) -> u32 {
+ |x| x * x
+}
+
+fn square_fn_mut() -> impl FnMut(u32) -> u32 {
+ |x| x * x
+}
+
+fn square_fn() -> impl Fn(u32) -> u32 {
+ |x| x * x
+}
+
+fn main() {
+ iterator(); //~ ERROR unused implementer of `Iterator` that must be used
+ future(); //~ ERROR unused implementer of `Future` that must be used
+ square_fn_once(); //~ ERROR unused implementer of `FnOnce` that must be used
+ square_fn_mut(); //~ ERROR unused implementer of `FnMut` that must be used
+ square_fn(); //~ ERROR unused implementer of `Fn` that must be used
+}
diff --git a/tests/ui/lint/unused/must_use-in-stdlib-traits.stderr b/tests/ui/lint/unused/must_use-in-stdlib-traits.stderr
new file mode 100644
index 000000000..ef738708d
--- /dev/null
+++ b/tests/ui/lint/unused/must_use-in-stdlib-traits.stderr
@@ -0,0 +1,47 @@
+error: unused implementer of `Iterator` that must be used
+ --> $DIR/must_use-in-stdlib-traits.rs:42:4
+ |
+LL | iterator();
+ | ^^^^^^^^^^
+ |
+ = note: iterators are lazy and do nothing unless consumed
+note: the lint level is defined here
+ --> $DIR/must_use-in-stdlib-traits.rs:1:9
+ |
+LL | #![deny(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+
+error: unused implementer of `Future` that must be used
+ --> $DIR/must_use-in-stdlib-traits.rs:43:4
+ |
+LL | future();
+ | ^^^^^^^^
+ |
+ = note: futures do nothing unless you `.await` or poll them
+
+error: unused implementer of `FnOnce` that must be used
+ --> $DIR/must_use-in-stdlib-traits.rs:44:4
+ |
+LL | square_fn_once();
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: closures are lazy and do nothing unless called
+
+error: unused implementer of `FnMut` that must be used
+ --> $DIR/must_use-in-stdlib-traits.rs:45:4
+ |
+LL | square_fn_mut();
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: closures are lazy and do nothing unless called
+
+error: unused implementer of `Fn` that must be used
+ --> $DIR/must_use-in-stdlib-traits.rs:46:4
+ |
+LL | square_fn();
+ | ^^^^^^^^^^^
+ |
+ = note: closures are lazy and do nothing unless called
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/lint/unused/must_use-trait.rs b/tests/ui/lint/unused/must_use-trait.rs
new file mode 100644
index 000000000..0aa751443
--- /dev/null
+++ b/tests/ui/lint/unused/must_use-trait.rs
@@ -0,0 +1,39 @@
+#![deny(unused_must_use)]
+
+#[must_use]
+trait Critical {}
+
+trait NotSoCritical {}
+
+trait DecidedlyUnimportant {}
+
+struct Anon;
+
+impl Critical for Anon {}
+impl NotSoCritical for Anon {}
+impl DecidedlyUnimportant for Anon {}
+
+fn get_critical() -> impl NotSoCritical + Critical + DecidedlyUnimportant {
+ Anon {}
+}
+
+fn get_boxed_critical() -> Box<dyn Critical> {
+ Box::new(Anon {})
+}
+
+fn get_nested_boxed_critical() -> Box<Box<dyn Critical>> {
+ Box::new(Box::new(Anon {}))
+}
+
+fn get_critical_tuple() -> (u32, Box<dyn Critical>, impl Critical, ()) {
+ (0, get_boxed_critical(), get_critical(), ())
+}
+
+fn main() {
+ get_critical(); //~ ERROR unused implementer of `Critical` that must be used
+ get_boxed_critical(); //~ ERROR unused boxed `Critical` trait object that must be used
+ get_nested_boxed_critical();
+ //~^ ERROR unused boxed boxed `Critical` trait object that must be used
+ get_critical_tuple(); //~ ERROR unused boxed `Critical` trait object in tuple element 1
+ //~^ ERROR unused implementer of `Critical` in tuple element 2
+}
diff --git a/tests/ui/lint/unused/must_use-trait.stderr b/tests/ui/lint/unused/must_use-trait.stderr
new file mode 100644
index 000000000..2f5496484
--- /dev/null
+++ b/tests/ui/lint/unused/must_use-trait.stderr
@@ -0,0 +1,38 @@
+error: unused implementer of `Critical` that must be used
+ --> $DIR/must_use-trait.rs:33:5
+ |
+LL | get_critical();
+ | ^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/must_use-trait.rs:1:9
+ |
+LL | #![deny(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+
+error: unused boxed `Critical` trait object that must be used
+ --> $DIR/must_use-trait.rs:34:5
+ |
+LL | get_boxed_critical();
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unused boxed boxed `Critical` trait object that must be used
+ --> $DIR/must_use-trait.rs:35:5
+ |
+LL | get_nested_boxed_critical();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unused boxed `Critical` trait object in tuple element 1 that must be used
+ --> $DIR/must_use-trait.rs:37:5
+ |
+LL | get_critical_tuple();
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unused implementer of `Critical` in tuple element 2 that must be used
+ --> $DIR/must_use-trait.rs:37:5
+ |
+LL | get_critical_tuple();
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/lint/unused/must_use-tuple.rs b/tests/ui/lint/unused/must_use-tuple.rs
new file mode 100644
index 000000000..0f0aa2025
--- /dev/null
+++ b/tests/ui/lint/unused/must_use-tuple.rs
@@ -0,0 +1,17 @@
+#![deny(unused_must_use)]
+
+fn foo() -> (Result<(), ()>, ()) {
+ (Ok::<(), ()>(()), ())
+}
+
+fn main() {
+ (Ok::<(), ()>(()),); //~ ERROR unused `Result`
+
+ (Ok::<(), ()>(()), 0, Ok::<(), ()>(()), 5);
+ //~^ ERROR unused `Result`
+ //~^^ ERROR unused `Result`
+
+ foo(); //~ ERROR unused `Result`
+
+ ((Err::<(), ()>(()), ()), ()); //~ ERROR unused `Result`
+}
diff --git a/tests/ui/lint/unused/must_use-tuple.stderr b/tests/ui/lint/unused/must_use-tuple.stderr
new file mode 100644
index 000000000..63e0318fb
--- /dev/null
+++ b/tests/ui/lint/unused/must_use-tuple.stderr
@@ -0,0 +1,47 @@
+error: unused `Result` in tuple element 0 that must be used
+ --> $DIR/must_use-tuple.rs:8:6
+ |
+LL | (Ok::<(), ()>(()),);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: this `Result` may be an `Err` variant, which should be handled
+note: the lint level is defined here
+ --> $DIR/must_use-tuple.rs:1:9
+ |
+LL | #![deny(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+
+error: unused `Result` in tuple element 0 that must be used
+ --> $DIR/must_use-tuple.rs:10:6
+ |
+LL | (Ok::<(), ()>(()), 0, Ok::<(), ()>(()), 5);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: this `Result` may be an `Err` variant, which should be handled
+
+error: unused `Result` in tuple element 2 that must be used
+ --> $DIR/must_use-tuple.rs:10:27
+ |
+LL | (Ok::<(), ()>(()), 0, Ok::<(), ()>(()), 5);
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: this `Result` may be an `Err` variant, which should be handled
+
+error: unused `Result` in tuple element 0 that must be used
+ --> $DIR/must_use-tuple.rs:14:5
+ |
+LL | foo();
+ | ^^^^^
+ |
+ = note: this `Result` may be an `Err` variant, which should be handled
+
+error: unused `Result` in tuple element 0 that must be used
+ --> $DIR/must_use-tuple.rs:16:7
+ |
+LL | ((Err::<(), ()>(()), ()), ());
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: this `Result` may be an `Err` variant, which should be handled
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/lint/unused/must_use-unit.rs b/tests/ui/lint/unused/must_use-unit.rs
new file mode 100644
index 000000000..4dd4798ab
--- /dev/null
+++ b/tests/ui/lint/unused/must_use-unit.rs
@@ -0,0 +1,16 @@
+#![feature(never_type)]
+#![deny(unused_must_use)]
+
+#[must_use]
+fn foo() {}
+
+#[must_use]
+fn bar() -> ! {
+ unimplemented!()
+}
+
+fn main() {
+ foo(); //~ unused return value of `foo`
+
+ bar(); //~ unused return value of `bar`
+}
diff --git a/tests/ui/lint/unused/must_use-unit.stderr b/tests/ui/lint/unused/must_use-unit.stderr
new file mode 100644
index 000000000..9fcbc5074
--- /dev/null
+++ b/tests/ui/lint/unused/must_use-unit.stderr
@@ -0,0 +1,20 @@
+error: unused return value of `foo` that must be used
+ --> $DIR/must_use-unit.rs:13:5
+ |
+LL | foo();
+ | ^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/must_use-unit.rs:2:9
+ |
+LL | #![deny(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+
+error: unused return value of `bar` that must be used
+ --> $DIR/must_use-unit.rs:15:5
+ |
+LL | bar();
+ | ^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/unused/no-unused-parens-return-block.rs b/tests/ui/lint/unused/no-unused-parens-return-block.rs
new file mode 100644
index 000000000..37dc519a2
--- /dev/null
+++ b/tests/ui/lint/unused/no-unused-parens-return-block.rs
@@ -0,0 +1,9 @@
+// run-pass
+
+#![deny(unused_parens)]
+#![allow(unreachable_code)]
+
+fn main() {
+ match (return) {} // ok
+ if (return) {} // ok
+}
diff --git a/tests/ui/lint/unused/unused-async.rs b/tests/ui/lint/unused/unused-async.rs
new file mode 100644
index 000000000..4be93aa15
--- /dev/null
+++ b/tests/ui/lint/unused/unused-async.rs
@@ -0,0 +1,62 @@
+// edition:2018
+#![deny(unused_must_use)]
+
+
+#[must_use]
+async fn foo() -> i32 {
+ 1
+}
+
+#[must_use]
+fn bar() -> impl std::future::Future<Output=i32> {
+ async {
+ 42
+ }
+}
+
+async fn baz() -> i32 {
+ 0
+}
+
+struct Wowee {}
+
+impl Wowee {
+ #[must_use]
+ async fn test_method() -> i32 {
+ 1
+ }
+}
+
+async fn test() {
+ foo(); //~ ERROR unused return value of `foo` that must be used
+ //~^ ERROR unused implementer of `Future` that must be used
+ foo().await; //~ ERROR unused output of future returned by `foo` that must be used
+ bar(); //~ ERROR unused return value of `bar` that must be used
+ //~^ ERROR unused implementer of `Future` that must be used
+ bar().await; //~ ERROR unused output of future returned by `bar` that must be used
+ baz(); //~ ERROR unused implementer of `Future` that must be used
+ baz().await; // ok
+}
+
+/* FIXME(guswynn) update this test when async-fn-in-traits works
+trait Doer {
+ #[must_use]
+ async fn test_trait_method() -> i32;
+ WARNING must_use
+ async fn test_other_trait() -> i32;
+}
+
+impl Doer for Wowee {
+ async fn test_trait_method() -> i32 {
+ 1
+ }
+ #[must_use]
+ async fn test_other_trait() -> i32 {
+ WARNING must_use
+ 1
+ }
+}
+*/
+
+fn main() {
+}
diff --git a/tests/ui/lint/unused/unused-async.stderr b/tests/ui/lint/unused/unused-async.stderr
new file mode 100644
index 000000000..4bcb26dc1
--- /dev/null
+++ b/tests/ui/lint/unused/unused-async.stderr
@@ -0,0 +1,55 @@
+error: unused implementer of `Future` that must be used
+ --> $DIR/unused-async.rs:31:5
+ |
+LL | foo();
+ | ^^^^^
+ |
+ = note: futures do nothing unless you `.await` or poll them
+note: the lint level is defined here
+ --> $DIR/unused-async.rs:2:9
+ |
+LL | #![deny(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+
+error: unused return value of `foo` that must be used
+ --> $DIR/unused-async.rs:31:5
+ |
+LL | foo();
+ | ^^^^^
+
+error: unused output of future returned by `foo` that must be used
+ --> $DIR/unused-async.rs:33:5
+ |
+LL | foo().await;
+ | ^^^^^^^^^^^
+
+error: unused implementer of `Future` that must be used
+ --> $DIR/unused-async.rs:34:5
+ |
+LL | bar();
+ | ^^^^^
+ |
+ = note: futures do nothing unless you `.await` or poll them
+
+error: unused return value of `bar` that must be used
+ --> $DIR/unused-async.rs:34:5
+ |
+LL | bar();
+ | ^^^^^
+
+error: unused output of future returned by `bar` that must be used
+ --> $DIR/unused-async.rs:36:5
+ |
+LL | bar().await;
+ | ^^^^^^^^^^^
+
+error: unused implementer of `Future` that must be used
+ --> $DIR/unused-async.rs:37:5
+ |
+LL | baz();
+ | ^^^^^
+ |
+ = note: futures do nothing unless you `.await` or poll them
+
+error: aborting due to 7 previous errors
+
diff --git a/tests/ui/lint/unused/unused-attr-duplicate.rs b/tests/ui/lint/unused/unused-attr-duplicate.rs
new file mode 100644
index 000000000..692617eac
--- /dev/null
+++ b/tests/ui/lint/unused/unused-attr-duplicate.rs
@@ -0,0 +1,105 @@
+// Tests for repeating attribute warnings.
+// aux-build:lint_unused_extern_crate.rs
+// compile-flags:--test
+// Not tested due to extra requirements:
+// - panic_handler: needs extra setup
+// - target_feature: platform-specific
+// - link_section: platform-specific
+// - proc_macro, proc_macro_derive, proc_macro_attribute: needs to be a
+// proc-macro, and have special handling for mixing.
+// - unstable attributes (not going to bother)
+// - no_main: extra setup
+#![deny(unused_attributes)]
+#![crate_name = "unused_attr_duplicate"]
+#![crate_name = "unused_attr_duplicate2"] //~ ERROR unused attribute
+//~^ WARN this was previously accepted
+#![recursion_limit = "128"]
+#![recursion_limit = "256"] //~ ERROR unused attribute
+//~^ WARN this was previously accepted
+#![type_length_limit = "1048576"]
+#![type_length_limit = "1"] //~ ERROR unused attribute
+//~^ WARN this was previously accepted
+#![no_std]
+#![no_std] //~ ERROR unused attribute
+#![no_implicit_prelude]
+#![no_implicit_prelude] //~ ERROR unused attribute
+#![windows_subsystem = "console"]
+#![windows_subsystem = "windows"] //~ ERROR unused attribute
+//~^ WARN this was previously accepted
+#![no_builtins]
+#![no_builtins] //~ ERROR unused attribute
+
+#[no_link]
+#[no_link] //~ ERROR unused attribute
+extern crate lint_unused_extern_crate;
+
+#[macro_use]
+#[macro_use] //~ ERROR unused attribute
+pub mod m {
+ #[macro_export]
+ #[macro_export] //~ ERROR unused attribute
+ macro_rules! foo {
+ () => {};
+ }
+}
+
+#[path = "auxiliary/lint_unused_extern_crate.rs"]
+#[path = "bar.rs"] //~ ERROR unused attribute
+//~^ WARN this was previously accepted
+pub mod from_path;
+
+#[test]
+#[ignore]
+#[ignore = "some text"] //~ ERROR unused attribute
+#[should_panic]
+#[should_panic(expected = "values don't match")] //~ ERROR unused attribute
+//~^ WARN this was previously accepted
+fn t1() {}
+
+#[must_use]
+#[must_use = "some message"] //~ ERROR unused attribute
+//~^ WARN this was previously accepted
+// No warnings for #[repr], would require more logic.
+#[repr(C)]
+#[repr(C)]
+#[non_exhaustive]
+#[non_exhaustive] //~ ERROR unused attribute
+pub struct X;
+
+#[automatically_derived]
+#[automatically_derived] //~ ERROR unused attribute
+impl X {}
+
+#[inline(always)]
+#[inline(never)] //~ ERROR unused attribute
+//~^ WARN this was previously accepted
+#[cold]
+#[cold] //~ ERROR unused attribute
+#[track_caller]
+#[track_caller] //~ ERROR unused attribute
+pub fn xyz() {}
+
+// No warnings for #[link], would require more logic.
+#[link(name = "rust_test_helpers", kind = "static")]
+#[link(name = "rust_test_helpers", kind = "static")]
+extern "C" {
+ #[link_name = "this_does_not_exist"] //~ ERROR unused attribute
+ //~^ WARN this was previously accepted
+ #[link_name = "rust_dbg_extern_identity_u32"]
+ pub fn name_in_rust(v: u32) -> u32;
+}
+
+#[export_name = "exported_symbol_name"] //~ ERROR unused attribute
+//~^ WARN this was previously accepted
+#[export_name = "exported_symbol_name2"]
+pub fn export_test() {}
+
+#[no_mangle]
+#[no_mangle] //~ ERROR unused attribute
+pub fn no_mangle_test() {}
+
+#[used]
+#[used] //~ ERROR unused attribute
+static FOO: u32 = 0;
+
+fn main() {}
diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr
new file mode 100644
index 000000000..769b17487
--- /dev/null
+++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr
@@ -0,0 +1,293 @@
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:33:1
+ |
+LL | #[no_link]
+ | ^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:32:1
+ |
+LL | #[no_link]
+ | ^^^^^^^^^^
+note: the lint level is defined here
+ --> $DIR/unused-attr-duplicate.rs:12:9
+ |
+LL | #![deny(unused_attributes)]
+ | ^^^^^^^^^^^^^^^^^
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:37:1
+ |
+LL | #[macro_use]
+ | ^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:36:1
+ |
+LL | #[macro_use]
+ | ^^^^^^^^^^^^
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:47:1
+ |
+LL | #[path = "bar.rs"]
+ | ^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:46:1
+ |
+LL | #[path = "auxiliary/lint_unused_extern_crate.rs"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:53:1
+ |
+LL | #[ignore = "some text"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:52:1
+ |
+LL | #[ignore]
+ | ^^^^^^^^^
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:55:1
+ |
+LL | #[should_panic(expected = "values don't match")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:54:1
+ |
+LL | #[should_panic]
+ | ^^^^^^^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:60:1
+ |
+LL | #[must_use = "some message"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:59:1
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:66:1
+ |
+LL | #[non_exhaustive]
+ | ^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:65:1
+ |
+LL | #[non_exhaustive]
+ | ^^^^^^^^^^^^^^^^^
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:70:1
+ |
+LL | #[automatically_derived]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:69:1
+ |
+LL | #[automatically_derived]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:74:1
+ |
+LL | #[inline(never)]
+ | ^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:73:1
+ |
+LL | #[inline(always)]
+ | ^^^^^^^^^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:77:1
+ |
+LL | #[cold]
+ | ^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:76:1
+ |
+LL | #[cold]
+ | ^^^^^^^
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:79:1
+ |
+LL | #[track_caller]
+ | ^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:78:1
+ |
+LL | #[track_caller]
+ | ^^^^^^^^^^^^^^^
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:92:1
+ |
+LL | #[export_name = "exported_symbol_name"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:94:1
+ |
+LL | #[export_name = "exported_symbol_name2"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:98:1
+ |
+LL | #[no_mangle]
+ | ^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:97:1
+ |
+LL | #[no_mangle]
+ | ^^^^^^^^^^^^
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:102:1
+ |
+LL | #[used]
+ | ^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:101:1
+ |
+LL | #[used]
+ | ^^^^^^^
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:86:5
+ |
+LL | #[link_name = "this_does_not_exist"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:88:5
+ |
+LL | #[link_name = "rust_dbg_extern_identity_u32"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:14:1
+ |
+LL | #![crate_name = "unused_attr_duplicate2"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:13:1
+ |
+LL | #![crate_name = "unused_attr_duplicate"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:17:1
+ |
+LL | #![recursion_limit = "256"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:16:1
+ |
+LL | #![recursion_limit = "128"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:20:1
+ |
+LL | #![type_length_limit = "1"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:19:1
+ |
+LL | #![type_length_limit = "1048576"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:23:1
+ |
+LL | #![no_std]
+ | ^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:22:1
+ |
+LL | #![no_std]
+ | ^^^^^^^^^^
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:25:1
+ |
+LL | #![no_implicit_prelude]
+ | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:24:1
+ |
+LL | #![no_implicit_prelude]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:27:1
+ |
+LL | #![windows_subsystem = "windows"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:26:1
+ |
+LL | #![windows_subsystem = "console"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:30:1
+ |
+LL | #![no_builtins]
+ | ^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:29:1
+ |
+LL | #![no_builtins]
+ | ^^^^^^^^^^^^^^^
+
+error: unused attribute
+ --> $DIR/unused-attr-duplicate.rs:40:5
+ |
+LL | #[macro_export]
+ | ^^^^^^^^^^^^^^^ help: remove this attribute
+ |
+note: attribute also specified here
+ --> $DIR/unused-attr-duplicate.rs:39:5
+ |
+LL | #[macro_export]
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to 23 previous errors
+
diff --git a/tests/ui/lint/unused/unused-attr-macro-rules.rs b/tests/ui/lint/unused/unused-attr-macro-rules.rs
new file mode 100644
index 000000000..c0fc280ab
--- /dev/null
+++ b/tests/ui/lint/unused/unused-attr-macro-rules.rs
@@ -0,0 +1,33 @@
+#![deny(unused_attributes)]
+// Unused attributes on macro_rules requires special handling since the
+// macro_rules definition does not survive towards HIR.
+
+// A sample of various built-in attributes.
+#[macro_export]
+#[macro_use] //~ ERROR `#[macro_use]` only has an effect
+#[path="foo"] //~ ERROR #[path]` only has an effect
+#[recursion_limit="1"] //~ ERROR crate-level attribute should be an inner attribute
+macro_rules! foo {
+ () => {};
+}
+
+// The following should not warn about unused attributes.
+#[allow(unused)]
+macro_rules! foo2 {
+ () => {};
+}
+
+#[cfg(FALSE)]
+macro_rules! foo {
+ () => {};
+}
+
+/// Some docs
+#[deprecated]
+#[doc = "more docs"]
+#[macro_export]
+macro_rules! bar {
+ () => {};
+}
+
+fn main() {}
diff --git a/tests/ui/lint/unused/unused-attr-macro-rules.stderr b/tests/ui/lint/unused/unused-attr-macro-rules.stderr
new file mode 100644
index 000000000..e3ca90d9a
--- /dev/null
+++ b/tests/ui/lint/unused/unused-attr-macro-rules.stderr
@@ -0,0 +1,26 @@
+error: `#[macro_use]` only has an effect on `extern crate` and modules
+ --> $DIR/unused-attr-macro-rules.rs:7:1
+ |
+LL | #[macro_use]
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused-attr-macro-rules.rs:1:9
+ |
+LL | #![deny(unused_attributes)]
+ | ^^^^^^^^^^^^^^^^^
+
+error: `#[path]` only has an effect on modules
+ --> $DIR/unused-attr-macro-rules.rs:8:1
+ |
+LL | #[path="foo"]
+ | ^^^^^^^^^^^^^
+
+error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
+ --> $DIR/unused-attr-macro-rules.rs:9:1
+ |
+LL | #[recursion_limit="1"]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/unused/unused-closure.rs b/tests/ui/lint/unused/unused-closure.rs
new file mode 100644
index 000000000..c96c90731
--- /dev/null
+++ b/tests/ui/lint/unused/unused-closure.rs
@@ -0,0 +1,35 @@
+// Test that closures and generators are "must use" types.
+// edition:2018
+
+#![feature(async_closure)]
+#![feature(generators)]
+#![deny(unused_must_use)]
+
+fn unused() {
+ || { //~ ERROR unused closure that must be used
+ println!("Hello!");
+ };
+
+ async {}; //~ ERROR unused implementer of `Future` that must be used
+ || async {}; //~ ERROR unused closure that must be used
+ async || {}; //~ ERROR unused closure that must be used
+
+
+ [Box::new([|| {}; 10]); 1]; //~ ERROR unused array of boxed arrays of closures that must be used
+
+ vec![|| "a"].pop().unwrap(); //~ ERROR unused closure that must be used
+
+ let b = false;
+ || true; //~ ERROR unused closure that must be used
+ println!("{}", b);
+}
+
+fn ignored() {
+ let _ = || {};
+ let _ = || yield 42;
+}
+
+fn main() {
+ unused();
+ ignored();
+}
diff --git a/tests/ui/lint/unused/unused-closure.stderr b/tests/ui/lint/unused/unused-closure.stderr
new file mode 100644
index 000000000..c3a82402e
--- /dev/null
+++ b/tests/ui/lint/unused/unused-closure.stderr
@@ -0,0 +1,65 @@
+error: unused closure that must be used
+ --> $DIR/unused-closure.rs:9:5
+ |
+LL | / || {
+LL | | println!("Hello!");
+LL | | };
+ | |_____^
+ |
+ = note: closures are lazy and do nothing unless called
+note: the lint level is defined here
+ --> $DIR/unused-closure.rs:6:9
+ |
+LL | #![deny(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+
+error: unused implementer of `Future` that must be used
+ --> $DIR/unused-closure.rs:13:5
+ |
+LL | async {};
+ | ^^^^^^^^
+ |
+ = note: futures do nothing unless you `.await` or poll them
+
+error: unused closure that must be used
+ --> $DIR/unused-closure.rs:14:5
+ |
+LL | || async {};
+ | ^^^^^^^^^^^
+ |
+ = note: closures are lazy and do nothing unless called
+
+error: unused closure that must be used
+ --> $DIR/unused-closure.rs:15:5
+ |
+LL | async || {};
+ | ^^^^^^^^^^^
+ |
+ = note: closures are lazy and do nothing unless called
+
+error: unused array of boxed arrays of closures that must be used
+ --> $DIR/unused-closure.rs:18:5
+ |
+LL | [Box::new([|| {}; 10]); 1];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: closures are lazy and do nothing unless called
+
+error: unused closure that must be used
+ --> $DIR/unused-closure.rs:20:5
+ |
+LL | vec![|| "a"].pop().unwrap();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: closures are lazy and do nothing unless called
+
+error: unused closure that must be used
+ --> $DIR/unused-closure.rs:23:9
+ |
+LL | || true;
+ | ^^^^^^^
+ |
+ = note: closures are lazy and do nothing unless called
+
+error: aborting due to 7 previous errors
+
diff --git a/tests/ui/lint/unused/unused-doc-comments-edge-cases.rs b/tests/ui/lint/unused/unused-doc-comments-edge-cases.rs
new file mode 100644
index 000000000..54d86c31f
--- /dev/null
+++ b/tests/ui/lint/unused/unused-doc-comments-edge-cases.rs
@@ -0,0 +1,46 @@
+#![deny(unused_doc_comments)]
+
+fn doc_comment_on_match_arms(num: u8) -> bool {
+ match num {
+ 3 => true,
+ /// useless doc comment
+ //~^ ERROR: unused doc comment
+ _ => false,
+ }
+}
+
+fn doc_comment_between_if_else(num: u8) -> bool {
+ if num == 3 {
+ true //~ ERROR: mismatched types
+ }
+ /// useless doc comment
+ else { //~ ERROR: expected expression, found keyword `else`
+ false
+ }
+}
+
+fn doc_comment_on_expr(num: u8) -> bool {
+ /// useless doc comment
+ //~^ ERROR: attributes on expressions are experimental
+ //~| ERROR: unused doc comment
+ num == 3
+}
+
+fn doc_comment_on_generic<#[doc = "x"] T>(val: T) {}
+//~^ ERROR: unused doc comment
+
+fn doc_comment_on_block() {
+ /// unused doc comment
+ //~^ ERROR: unused doc comment
+ {
+ let x = 12;
+ }
+}
+
+/// unused doc comment
+//~^ ERROR: unused doc comment
+extern "C" {
+ fn foo();
+}
+
+fn main() {}
diff --git a/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr b/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr
new file mode 100644
index 000000000..078b780d8
--- /dev/null
+++ b/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr
@@ -0,0 +1,95 @@
+error: expected expression, found keyword `else`
+ --> $DIR/unused-doc-comments-edge-cases.rs:17:5
+ |
+LL | else {
+ | ^^^^ expected expression
+
+error[E0658]: attributes on expressions are experimental
+ --> $DIR/unused-doc-comments-edge-cases.rs:23:5
+ |
+LL | /// useless doc comment
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+ = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+ = help: `///` is for documentation comments. For a plain comment, use `//`.
+
+error: unused doc comment
+ --> $DIR/unused-doc-comments-edge-cases.rs:6:9
+ |
+LL | /// useless doc comment
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | _ => false,
+ | ---------- rustdoc does not generate documentation for match arms
+ |
+ = help: use `//` for a plain comment
+note: the lint level is defined here
+ --> $DIR/unused-doc-comments-edge-cases.rs:1:9
+ |
+LL | #![deny(unused_doc_comments)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: unused doc comment
+ --> $DIR/unused-doc-comments-edge-cases.rs:23:5
+ |
+LL | /// useless doc comment
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | num == 3
+ | --- rustdoc does not generate documentation for expressions
+ |
+ = help: use `//` for a plain comment
+
+error: unused doc comment
+ --> $DIR/unused-doc-comments-edge-cases.rs:29:27
+ |
+LL | fn doc_comment_on_generic<#[doc = "x"] T>(val: T) {}
+ | ^^^^^^^^^^^^ - rustdoc does not generate documentation for generic parameters
+ |
+ = help: use `//` for a plain comment
+
+error: unused doc comment
+ --> $DIR/unused-doc-comments-edge-cases.rs:33:5
+ |
+LL | /// unused doc comment
+ | ^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / {
+LL | | let x = 12;
+LL | | }
+ | |_____- rustdoc does not generate documentation for expressions
+ |
+ = help: use `//` for a plain comment
+
+error: unused doc comment
+ --> $DIR/unused-doc-comments-edge-cases.rs:40:1
+ |
+LL | /// unused doc comment
+ | ^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / extern "C" {
+LL | | fn foo();
+LL | | }
+ | |_- rustdoc does not generate documentation for extern blocks
+ |
+ = help: use `//` for a plain comment
+
+error[E0308]: mismatched types
+ --> $DIR/unused-doc-comments-edge-cases.rs:14:9
+ |
+LL | / if num == 3 {
+LL | | true
+ | | ^^^^ expected `()`, found `bool`
+LL | | }
+ | |_____- expected this to be `()`
+ |
+help: you might have meant to return this value
+ |
+LL | return true;
+ | ++++++ +
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0308, E0658.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/lint/unused/unused-doc-comments-for-macros.rs b/tests/ui/lint/unused/unused-doc-comments-for-macros.rs
new file mode 100644
index 000000000..05828ebb2
--- /dev/null
+++ b/tests/ui/lint/unused/unused-doc-comments-for-macros.rs
@@ -0,0 +1,17 @@
+#![deny(unused_doc_comments)]
+#![feature(rustc_attrs)]
+
+macro_rules! foo { () => {}; }
+
+fn main() {
+ /// line1 //~ ERROR: unused doc comment
+ /// line2
+ /// line3
+ foo!();
+
+ // Ensure we still detect another doc-comment block.
+ /// line1 //~ ERROR: unused doc comment
+ /// line2
+ /// line3
+ foo!();
+}
diff --git a/tests/ui/lint/unused/unused-doc-comments-for-macros.stderr b/tests/ui/lint/unused/unused-doc-comments-for-macros.stderr
new file mode 100644
index 000000000..26b1c2b05
--- /dev/null
+++ b/tests/ui/lint/unused/unused-doc-comments-for-macros.stderr
@@ -0,0 +1,31 @@
+error: unused doc comment
+ --> $DIR/unused-doc-comments-for-macros.rs:7:5
+ |
+LL | / /// line1
+LL | | /// line2
+LL | | /// line3
+ | |_____--------^
+ | |
+ | rustdoc does not generate documentation for macro invocations
+ |
+ = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion
+note: the lint level is defined here
+ --> $DIR/unused-doc-comments-for-macros.rs:1:9
+ |
+LL | #![deny(unused_doc_comments)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: unused doc comment
+ --> $DIR/unused-doc-comments-for-macros.rs:13:5
+ |
+LL | / /// line1
+LL | | /// line2
+LL | | /// line3
+ | |_____--------^
+ | |
+ | rustdoc does not generate documentation for macro invocations
+ |
+ = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/unused/unused-macro-rules-compile-error.rs b/tests/ui/lint/unused/unused-macro-rules-compile-error.rs
new file mode 100644
index 000000000..4d51db89b
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macro-rules-compile-error.rs
@@ -0,0 +1,27 @@
+#![deny(unused_macro_rules)]
+// To make sure we are not hitting this
+#![deny(unused_macros)]
+
+macro_rules! num {
+ (one) => { 1 };
+ // Most simple (and common) case
+ (two) => { compile_error!("foo"); };
+ // Some nested use
+ (two_) => { foo(compile_error!("foo")); };
+ (three) => { 3 };
+ (four) => { 4 }; //~ ERROR: rule of macro
+}
+const _NUM: u8 = num!(one) + num!(three);
+
+// compile_error not used as a macro invocation
+macro_rules! num2 {
+ (one) => { 1 };
+ // Only identifier present
+ (two) => { fn compile_error() {} }; //~ ERROR: rule of macro
+ // Only identifier and bang present
+ (two_) => { compile_error! }; //~ ERROR: rule of macro
+ (three) => { 3 };
+}
+const _NUM2: u8 = num2!(one) + num2!(three);
+
+fn main() {}
diff --git a/tests/ui/lint/unused/unused-macro-rules-compile-error.stderr b/tests/ui/lint/unused/unused-macro-rules-compile-error.stderr
new file mode 100644
index 000000000..76af8c967
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macro-rules-compile-error.stderr
@@ -0,0 +1,26 @@
+error: 5th rule of macro `num` is never used
+ --> $DIR/unused-macro-rules-compile-error.rs:12:5
+ |
+LL | (four) => { 4 };
+ | ^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused-macro-rules-compile-error.rs:1:9
+ |
+LL | #![deny(unused_macro_rules)]
+ | ^^^^^^^^^^^^^^^^^^
+
+error: 3rd rule of macro `num2` is never used
+ --> $DIR/unused-macro-rules-compile-error.rs:22:5
+ |
+LL | (two_) => { compile_error! };
+ | ^^^^^^
+
+error: 2nd rule of macro `num2` is never used
+ --> $DIR/unused-macro-rules-compile-error.rs:20:5
+ |
+LL | (two) => { fn compile_error() {} };
+ | ^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/unused/unused-macro-rules-decl.rs b/tests/ui/lint/unused/unused-macro-rules-decl.rs
new file mode 100644
index 000000000..537c84940
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macro-rules-decl.rs
@@ -0,0 +1,49 @@
+#![feature(decl_macro)]
+#![deny(unused_macro_rules)]
+// To make sure we are not hitting this
+#![deny(unused_macros)]
+
+// Most simple case
+macro num {
+ (one) => { 1 },
+ (two) => { 2 }, //~ ERROR: 2nd rule of macro
+ (three) => { 3 },
+ (four) => { 4 }, //~ ERROR: 4th rule of macro
+}
+const _NUM: u8 = num!(one) + num!(three);
+
+// Check that allowing the lint works
+#[allow(unused_macro_rules)]
+macro num_allowed {
+ (one) => { 1 },
+ (two) => { 2 },
+ (three) => { 3 },
+ (four) => { 4 },
+}
+const _NUM_ALLOWED: u8 = num_allowed!(one) + num_allowed!(three);
+
+// Check that macro calls inside the macro trigger as usage
+macro num_rec {
+ (one) => { 1 },
+ (two) => {
+ num_rec!(one) + num_rec!(one)
+ },
+ (three) => { //~ ERROR: 3rd rule of macro
+ num_rec!(one) + num_rec!(two)
+ },
+ (four) => {
+ num_rec!(two) + num_rec!(two)
+ },
+}
+const _NUM_RECURSIVE: u8 = num_rec!(four);
+
+// No error if the macro is public
+pub macro num_public {
+ (one) => { 1 },
+ (two) => { 2 },
+ (three) => { 3 },
+ (four) => { 4 },
+}
+const _NUM_PUBLIC: u8 = num_public!(one) + num_public!(three);
+
+fn main() {}
diff --git a/tests/ui/lint/unused/unused-macro-rules-decl.stderr b/tests/ui/lint/unused/unused-macro-rules-decl.stderr
new file mode 100644
index 000000000..4d9b22fed
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macro-rules-decl.stderr
@@ -0,0 +1,26 @@
+error: 4th rule of macro `num` is never used
+ --> $DIR/unused-macro-rules-decl.rs:11:5
+ |
+LL | (four) => { 4 },
+ | ^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused-macro-rules-decl.rs:2:9
+ |
+LL | #![deny(unused_macro_rules)]
+ | ^^^^^^^^^^^^^^^^^^
+
+error: 2nd rule of macro `num` is never used
+ --> $DIR/unused-macro-rules-decl.rs:9:5
+ |
+LL | (two) => { 2 },
+ | ^^^^^
+
+error: 3rd rule of macro `num_rec` is never used
+ --> $DIR/unused-macro-rules-decl.rs:31:5
+ |
+LL | (three) => {
+ | ^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/unused/unused-macro-rules-malformed-rule.rs b/tests/ui/lint/unused/unused-macro-rules-malformed-rule.rs
new file mode 100644
index 000000000..a826026ec
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macro-rules-malformed-rule.rs
@@ -0,0 +1,11 @@
+#![deny(unused_macro_rules)]
+
+macro_rules! foo {
+ (v) => {};
+ (w) => {};
+ () => 0; //~ ERROR: macro rhs must be delimited
+}
+
+fn main() {
+ foo!(v);
+}
diff --git a/tests/ui/lint/unused/unused-macro-rules-malformed-rule.stderr b/tests/ui/lint/unused/unused-macro-rules-malformed-rule.stderr
new file mode 100644
index 000000000..797c86710
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macro-rules-malformed-rule.stderr
@@ -0,0 +1,8 @@
+error: macro rhs must be delimited
+ --> $DIR/unused-macro-rules-malformed-rule.rs:6:11
+ |
+LL | () => 0;
+ | ^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/unused/unused-macro-rules.rs b/tests/ui/lint/unused/unused-macro-rules.rs
new file mode 100644
index 000000000..eeaf4d1b0
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macro-rules.rs
@@ -0,0 +1,47 @@
+#![deny(unused_macro_rules)]
+// To make sure we are not hitting this
+#![deny(unused_macros)]
+
+// Most simple case
+macro_rules! num {
+ (one) => { 1 };
+ (two) => { 2 }; //~ ERROR: 2nd rule of macro
+ (three) => { 3 };
+ (four) => { 4 }; //~ ERROR: 4th rule of macro
+}
+const _NUM: u8 = num!(one) + num!(three);
+
+// Check that allowing the lint works
+#[allow(unused_macro_rules)]
+macro_rules! num_allowed {
+ (one) => { 1 };
+ (two) => { 2 };
+ (three) => { 3 };
+ (four) => { 4 };
+}
+const _NUM_ALLOWED: u8 = num_allowed!(one) + num_allowed!(three);
+
+// Check that macro calls inside the macro trigger as usage
+macro_rules! num_rec {
+ (one) => { 1 };
+ (two) => {
+ num_rec!(one) + num_rec!(one)
+ };
+ (three) => { //~ ERROR: 3rd rule of macro
+ num_rec!(one) + num_rec!(two)
+ };
+ (four) => { num_rec!(two) + num_rec!(two) };
+}
+const _NUM_RECURSIVE: u8 = num_rec!(four);
+
+// No error if the macro is being exported
+#[macro_export]
+macro_rules! num_exported {
+ (one) => { 1 };
+ (two) => { 2 };
+ (three) => { 3 };
+ (four) => { 4 };
+}
+const _NUM_EXPORTED: u8 = num_exported!(one) + num_exported!(three);
+
+fn main() {}
diff --git a/tests/ui/lint/unused/unused-macro-rules.stderr b/tests/ui/lint/unused/unused-macro-rules.stderr
new file mode 100644
index 000000000..2b3098a51
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macro-rules.stderr
@@ -0,0 +1,26 @@
+error: 4th rule of macro `num` is never used
+ --> $DIR/unused-macro-rules.rs:10:5
+ |
+LL | (four) => { 4 };
+ | ^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused-macro-rules.rs:1:9
+ |
+LL | #![deny(unused_macro_rules)]
+ | ^^^^^^^^^^^^^^^^^^
+
+error: 2nd rule of macro `num` is never used
+ --> $DIR/unused-macro-rules.rs:8:5
+ |
+LL | (two) => { 2 };
+ | ^^^^^
+
+error: 3rd rule of macro `num_rec` is never used
+ --> $DIR/unused-macro-rules.rs:30:5
+ |
+LL | (three) => {
+ | ^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/unused/unused-macro-with-bad-frag-spec.rs b/tests/ui/lint/unused/unused-macro-with-bad-frag-spec.rs
new file mode 100644
index 000000000..ce187047b
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macro-with-bad-frag-spec.rs
@@ -0,0 +1,9 @@
+#![allow(unused_macros)]
+
+// Issue #21370
+
+macro_rules! test {
+ ($wrong:t_ty) => () //~ ERROR invalid fragment specifier `t_ty`
+}
+
+fn main() { }
diff --git a/tests/ui/lint/unused/unused-macro-with-bad-frag-spec.stderr b/tests/ui/lint/unused/unused-macro-with-bad-frag-spec.stderr
new file mode 100644
index 000000000..6edf0a2cf
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macro-with-bad-frag-spec.stderr
@@ -0,0 +1,10 @@
+error: invalid fragment specifier `t_ty`
+ --> $DIR/unused-macro-with-bad-frag-spec.rs:6:6
+ |
+LL | ($wrong:t_ty) => ()
+ | ^^^^^^^^^^^
+ |
+ = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/unused/unused-macro-with-follow-violation.rs b/tests/ui/lint/unused/unused-macro-with-follow-violation.rs
new file mode 100644
index 000000000..1666dae69
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macro-with-follow-violation.rs
@@ -0,0 +1,7 @@
+#![allow(unused_macros)]
+
+macro_rules! test {
+ ($e:expr +) => () //~ ERROR not allowed for `expr` fragments
+}
+
+fn main() { }
diff --git a/tests/ui/lint/unused/unused-macro-with-follow-violation.stderr b/tests/ui/lint/unused/unused-macro-with-follow-violation.stderr
new file mode 100644
index 000000000..5eced4f06
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macro-with-follow-violation.stderr
@@ -0,0 +1,10 @@
+error: `$e:expr` is followed by `+`, which is not allowed for `expr` fragments
+ --> $DIR/unused-macro-with-follow-violation.rs:4:14
+ |
+LL | ($e:expr +) => ()
+ | ^ not allowed after `expr` fragments
+ |
+ = note: allowed there are: `=>`, `,` or `;`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/unused/unused-macros-decl.rs b/tests/ui/lint/unused/unused-macros-decl.rs
new file mode 100644
index 000000000..21f6108b1
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macros-decl.rs
@@ -0,0 +1,28 @@
+#![feature(decl_macro)]
+#![deny(unused_macros)]
+// To make sure we are not hitting this
+#![deny(unused_macro_rules)]
+
+// Most simple case
+macro unused { //~ ERROR: unused macro definition
+ () => {}
+}
+
+#[allow(unused_macros)]
+mod bar {
+ // Test that putting the #[deny] close to the macro's definition
+ // works.
+
+ #[deny(unused_macros)]
+ macro unused { //~ ERROR: unused macro definition
+ () => {}
+ }
+}
+
+mod boo {
+ pub(crate) macro unused { //~ ERROR: unused macro definition
+ () => {}
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/unused/unused-macros-decl.stderr b/tests/ui/lint/unused/unused-macros-decl.stderr
new file mode 100644
index 000000000..1f426b9d9
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macros-decl.stderr
@@ -0,0 +1,32 @@
+error: unused macro definition: `unused`
+ --> $DIR/unused-macros-decl.rs:7:7
+ |
+LL | macro unused {
+ | ^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused-macros-decl.rs:2:9
+ |
+LL | #![deny(unused_macros)]
+ | ^^^^^^^^^^^^^
+
+error: unused macro definition: `unused`
+ --> $DIR/unused-macros-decl.rs:17:11
+ |
+LL | macro unused {
+ | ^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused-macros-decl.rs:16:12
+ |
+LL | #[deny(unused_macros)]
+ | ^^^^^^^^^^^^^
+
+error: unused macro definition: `unused`
+ --> $DIR/unused-macros-decl.rs:23:22
+ |
+LL | pub(crate) macro unused {
+ | ^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/unused/unused-macros-malformed-rule.rs b/tests/ui/lint/unused/unused-macros-malformed-rule.rs
new file mode 100644
index 000000000..d4c35fad9
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macros-malformed-rule.rs
@@ -0,0 +1,15 @@
+#![deny(unused_macros)]
+
+macro_rules! foo { //~ ERROR: unused macro definition
+ (v) => {};
+ () => 0; //~ ERROR: macro rhs must be delimited
+}
+
+macro_rules! bar {
+ (v) => {};
+ () => 0; //~ ERROR: macro rhs must be delimited
+}
+
+fn main() {
+ bar!(v);
+}
diff --git a/tests/ui/lint/unused/unused-macros-malformed-rule.stderr b/tests/ui/lint/unused/unused-macros-malformed-rule.stderr
new file mode 100644
index 000000000..9a880dccf
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macros-malformed-rule.stderr
@@ -0,0 +1,26 @@
+error: macro rhs must be delimited
+ --> $DIR/unused-macros-malformed-rule.rs:5:11
+ |
+LL | () => 0;
+ | ^
+
+error: macro rhs must be delimited
+ --> $DIR/unused-macros-malformed-rule.rs:10:11
+ |
+LL | () => 0;
+ | ^
+
+error: unused macro definition: `foo`
+ --> $DIR/unused-macros-malformed-rule.rs:3:14
+ |
+LL | macro_rules! foo {
+ | ^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused-macros-malformed-rule.rs:1:9
+ |
+LL | #![deny(unused_macros)]
+ | ^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/unused/unused-macros.rs b/tests/ui/lint/unused/unused-macros.rs
new file mode 100644
index 000000000..70b50b208
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macros.rs
@@ -0,0 +1,31 @@
+#![deny(unused_macros)]
+// To make sure we are not hitting this
+#![deny(unused_macro_rules)]
+
+// Most simple case
+macro_rules! unused { //~ ERROR: unused macro definition
+ () => {};
+}
+
+// Test macros created by macros
+macro_rules! create_macro {
+ () => {
+ macro_rules! m { //~ ERROR: unused macro definition
+ () => {};
+ }
+ };
+}
+create_macro!();
+
+#[allow(unused_macros)]
+mod bar {
+ // Test that putting the #[deny] close to the macro's definition
+ // works.
+
+ #[deny(unused_macros)]
+ macro_rules! unused { //~ ERROR: unused macro definition
+ () => {};
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/unused/unused-macros.stderr b/tests/ui/lint/unused/unused-macros.stderr
new file mode 100644
index 000000000..d0baf5bec
--- /dev/null
+++ b/tests/ui/lint/unused/unused-macros.stderr
@@ -0,0 +1,32 @@
+error: unused macro definition: `unused`
+ --> $DIR/unused-macros.rs:6:14
+ |
+LL | macro_rules! unused {
+ | ^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused-macros.rs:1:9
+ |
+LL | #![deny(unused_macros)]
+ | ^^^^^^^^^^^^^
+
+error: unused macro definition: `m`
+ --> $DIR/unused-macros.rs:13:22
+ |
+LL | macro_rules! m {
+ | ^
+
+error: unused macro definition: `unused`
+ --> $DIR/unused-macros.rs:26:18
+ |
+LL | macro_rules! unused {
+ | ^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused-macros.rs:25:12
+ |
+LL | #[deny(unused_macros)]
+ | ^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/unused/unused-mut-warning-captured-var.fixed b/tests/ui/lint/unused/unused-mut-warning-captured-var.fixed
new file mode 100644
index 000000000..c21f18015
--- /dev/null
+++ b/tests/ui/lint/unused/unused-mut-warning-captured-var.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+
+#![forbid(unused_mut)]
+
+fn main() {
+ let x = 1;
+ //~^ ERROR: variable does not need to be mutable
+ (move|| { println!("{}", x); })();
+}
diff --git a/tests/ui/lint/unused/unused-mut-warning-captured-var.rs b/tests/ui/lint/unused/unused-mut-warning-captured-var.rs
new file mode 100644
index 000000000..3119d83a0
--- /dev/null
+++ b/tests/ui/lint/unused/unused-mut-warning-captured-var.rs
@@ -0,0 +1,9 @@
+// run-rustfix
+
+#![forbid(unused_mut)]
+
+fn main() {
+ let mut x = 1;
+ //~^ ERROR: variable does not need to be mutable
+ (move|| { println!("{}", x); })();
+}
diff --git a/tests/ui/lint/unused/unused-mut-warning-captured-var.stderr b/tests/ui/lint/unused/unused-mut-warning-captured-var.stderr
new file mode 100644
index 000000000..20aeedcc2
--- /dev/null
+++ b/tests/ui/lint/unused/unused-mut-warning-captured-var.stderr
@@ -0,0 +1,16 @@
+error: variable does not need to be mutable
+ --> $DIR/unused-mut-warning-captured-var.rs:6:9
+ |
+LL | let mut x = 1;
+ | ----^
+ | |
+ | help: remove this `mut`
+ |
+note: the lint level is defined here
+ --> $DIR/unused-mut-warning-captured-var.rs:3:11
+ |
+LL | #![forbid(unused_mut)]
+ | ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/unused/unused-result.rs b/tests/ui/lint/unused/unused-result.rs
new file mode 100644
index 000000000..e283eaa88
--- /dev/null
+++ b/tests/ui/lint/unused/unused-result.rs
@@ -0,0 +1,42 @@
+#![allow(dead_code)]
+#![deny(unused_results, unused_must_use)]
+//~^ NOTE: the lint level is defined here
+//~| NOTE: the lint level is defined here
+
+#[must_use]
+enum MustUse { Test }
+
+#[must_use = "some message"]
+enum MustUseMsg { Test2 }
+
+fn foo<T>() -> T { panic!() }
+
+fn bar() -> isize { return foo::<isize>(); }
+fn baz() -> MustUse { return foo::<MustUse>(); }
+fn qux() -> MustUseMsg { return foo::<MustUseMsg>(); }
+
+#[allow(unused_results)]
+fn test() {
+ foo::<isize>();
+ foo::<MustUse>(); //~ ERROR: unused `MustUse` that must be used
+ foo::<MustUseMsg>(); //~ ERROR: unused `MustUseMsg` that must be used
+ //~^ NOTE: some message
+}
+
+#[allow(unused_results, unused_must_use)]
+fn test2() {
+ foo::<isize>();
+ foo::<MustUse>();
+ foo::<MustUseMsg>();
+}
+
+fn main() {
+ foo::<isize>(); //~ ERROR: unused result of type `isize`
+ foo::<MustUse>(); //~ ERROR: unused `MustUse` that must be used
+ foo::<MustUseMsg>(); //~ ERROR: unused `MustUseMsg` that must be used
+ //~^ NOTE: some message
+
+ let _ = foo::<isize>();
+ let _ = foo::<MustUse>();
+ let _ = foo::<MustUseMsg>();
+}
diff --git a/tests/ui/lint/unused/unused-result.stderr b/tests/ui/lint/unused/unused-result.stderr
new file mode 100644
index 000000000..4e1ba1fd9
--- /dev/null
+++ b/tests/ui/lint/unused/unused-result.stderr
@@ -0,0 +1,48 @@
+error: unused `MustUse` that must be used
+ --> $DIR/unused-result.rs:21:5
+ |
+LL | foo::<MustUse>();
+ | ^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused-result.rs:2:25
+ |
+LL | #![deny(unused_results, unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+
+error: unused `MustUseMsg` that must be used
+ --> $DIR/unused-result.rs:22:5
+ |
+LL | foo::<MustUseMsg>();
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: some message
+
+error: unused result of type `isize`
+ --> $DIR/unused-result.rs:34:5
+ |
+LL | foo::<isize>();
+ | ^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused-result.rs:2:9
+ |
+LL | #![deny(unused_results, unused_must_use)]
+ | ^^^^^^^^^^^^^^
+
+error: unused `MustUse` that must be used
+ --> $DIR/unused-result.rs:35:5
+ |
+LL | foo::<MustUse>();
+ | ^^^^^^^^^^^^^^^^
+
+error: unused `MustUseMsg` that must be used
+ --> $DIR/unused-result.rs:36:5
+ |
+LL | foo::<MustUseMsg>();
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: some message
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/lint/unused/unused-supertrait.rs b/tests/ui/lint/unused/unused-supertrait.rs
new file mode 100644
index 000000000..64a8e5204
--- /dev/null
+++ b/tests/ui/lint/unused/unused-supertrait.rs
@@ -0,0 +1,11 @@
+#![deny(unused_must_use)]
+
+fn it() -> impl ExactSizeIterator<Item = ()> {
+ let x: Box<dyn ExactSizeIterator<Item = ()>> = todo!();
+ x
+}
+
+fn main() {
+ it();
+ //~^ ERROR unused implementer of `Iterator` that must be used
+}
diff --git a/tests/ui/lint/unused/unused-supertrait.stderr b/tests/ui/lint/unused/unused-supertrait.stderr
new file mode 100644
index 000000000..cb45add9c
--- /dev/null
+++ b/tests/ui/lint/unused/unused-supertrait.stderr
@@ -0,0 +1,15 @@
+error: unused implementer of `Iterator` that must be used
+ --> $DIR/unused-supertrait.rs:9:5
+ |
+LL | it();
+ | ^^^^
+ |
+ = note: iterators are lazy and do nothing unless consumed
+note: the lint level is defined here
+ --> $DIR/unused-supertrait.rs:1:9
+ |
+LL | #![deny(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/unused/unused_attributes-must_use.rs b/tests/ui/lint/unused/unused_attributes-must_use.rs
new file mode 100644
index 000000000..51f868706
--- /dev/null
+++ b/tests/ui/lint/unused/unused_attributes-must_use.rs
@@ -0,0 +1,131 @@
+#![allow(dead_code, path_statements)]
+#![deny(unused_attributes, unused_must_use)]
+#![feature(asm_experimental_arch, stmt_expr_attributes, trait_alias)]
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+extern crate std as std2;
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+mod test_mod {}
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+use std::arch::global_asm;
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+const CONST: usize = 4;
+#[must_use] //~ ERROR `#[must_use]` has no effect
+#[no_mangle]
+static STATIC: usize = 4;
+
+#[must_use]
+struct X;
+
+#[must_use]
+enum Y {
+ Z,
+}
+
+#[must_use]
+union U {
+ unit: (),
+}
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+impl U {
+ #[must_use]
+ fn method() -> i32 {
+ 4
+ }
+}
+
+#[must_use]
+#[no_mangle]
+fn foo() -> i64 {
+ 4
+}
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+extern "Rust" {
+ #[link_name = "STATIC"]
+ #[must_use] //~ ERROR `#[must_use]` has no effect
+ static FOREIGN_STATIC: usize;
+
+ #[link_name = "foo"]
+ #[must_use]
+ fn foreign_foo() -> i64;
+}
+
+#[must_use] //~ ERROR unused attribute
+global_asm!("");
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+type UseMe = ();
+
+fn qux<#[must_use] T>(_: T) {} //~ ERROR `#[must_use]` has no effect
+
+#[must_use]
+trait Use {
+ #[must_use] //~ ERROR `#[must_use]` has no effect
+ const ASSOC_CONST: usize = 4;
+ #[must_use] //~ ERROR `#[must_use]` has no effect
+ type AssocTy;
+
+ #[must_use]
+ fn get_four(&self) -> usize {
+ 4
+ }
+}
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+impl Use for () {
+ type AssocTy = ();
+}
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+trait Alias = Use;
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+macro_rules! cool_macro {
+ () => {
+ 4
+ };
+}
+
+fn main() {
+ #[must_use] //~ ERROR `#[must_use]` has no effect
+ let x = || {};
+ x();
+
+ let x = #[must_use] //~ ERROR `#[must_use]` has no effect
+ || {};
+ x();
+
+ X; //~ ERROR that must be used
+ Y::Z; //~ ERROR that must be used
+ U { unit: () }; //~ ERROR that must be used
+ U::method(); //~ ERROR that must be used
+ foo(); //~ ERROR that must be used
+
+ unsafe {
+ foreign_foo(); //~ ERROR that must be used
+ };
+
+ CONST;
+ STATIC;
+ unsafe { FOREIGN_STATIC };
+ cool_macro!();
+ qux(4);
+ ().get_four(); //~ ERROR that must be used
+
+ match Some(4) {
+ #[must_use] //~ ERROR `#[must_use]` has no effect
+ Some(res) => res,
+ None => 0,
+ };
+
+ struct PatternField {
+ foo: i32,
+ }
+ let s = PatternField { #[must_use] foo: 123 }; //~ ERROR `#[must_use]` has no effect
+ let PatternField { #[must_use] foo } = s; //~ ERROR `#[must_use]` has no effect
+}
diff --git a/tests/ui/lint/unused/unused_attributes-must_use.stderr b/tests/ui/lint/unused/unused_attributes-must_use.stderr
new file mode 100644
index 000000000..0f699429e
--- /dev/null
+++ b/tests/ui/lint/unused/unused_attributes-must_use.stderr
@@ -0,0 +1,187 @@
+error: unused attribute `must_use`
+ --> $DIR/unused_attributes-must_use.rs:58:1
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+ |
+note: the built-in attribute `must_use` will be ignored, since it's applied to the macro invocation `global_asm`
+ --> $DIR/unused_attributes-must_use.rs:59:1
+ |
+LL | global_asm!("");
+ | ^^^^^^^^^^
+note: the lint level is defined here
+ --> $DIR/unused_attributes-must_use.rs:2:9
+ |
+LL | #![deny(unused_attributes, unused_must_use)]
+ | ^^^^^^^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to an extern crate
+ --> $DIR/unused_attributes-must_use.rs:5:1
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a module
+ --> $DIR/unused_attributes-must_use.rs:8:1
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a use
+ --> $DIR/unused_attributes-must_use.rs:11:1
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a constant item
+ --> $DIR/unused_attributes-must_use.rs:14:1
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a static item
+ --> $DIR/unused_attributes-must_use.rs:16:1
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to an implementation block
+ --> $DIR/unused_attributes-must_use.rs:33:1
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a foreign module
+ --> $DIR/unused_attributes-must_use.rs:47:1
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a type alias
+ --> $DIR/unused_attributes-must_use.rs:61:1
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a type parameter
+ --> $DIR/unused_attributes-must_use.rs:64:8
+ |
+LL | fn qux<#[must_use] T>(_: T) {}
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to an implementation block
+ --> $DIR/unused_attributes-must_use.rs:79:1
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a trait alias
+ --> $DIR/unused_attributes-must_use.rs:84:1
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a macro def
+ --> $DIR/unused_attributes-must_use.rs:87:1
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a statement
+ --> $DIR/unused_attributes-must_use.rs:95:5
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a closure
+ --> $DIR/unused_attributes-must_use.rs:99:13
+ |
+LL | let x = #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to an match arm
+ --> $DIR/unused_attributes-must_use.rs:121:9
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a struct field
+ --> $DIR/unused_attributes-must_use.rs:129:28
+ |
+LL | let s = PatternField { #[must_use] foo: 123 };
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a pattern field
+ --> $DIR/unused_attributes-must_use.rs:130:24
+ |
+LL | let PatternField { #[must_use] foo } = s;
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to an associated const
+ --> $DIR/unused_attributes-must_use.rs:68:5
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to an associated type
+ --> $DIR/unused_attributes-must_use.rs:70:5
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a foreign static item
+ --> $DIR/unused_attributes-must_use.rs:50:5
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: unused `X` that must be used
+ --> $DIR/unused_attributes-must_use.rs:103:5
+ |
+LL | X;
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/unused_attributes-must_use.rs:2:28
+ |
+LL | #![deny(unused_attributes, unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+
+error: unused `Y` that must be used
+ --> $DIR/unused_attributes-must_use.rs:104:5
+ |
+LL | Y::Z;
+ | ^^^^
+
+error: unused `U` that must be used
+ --> $DIR/unused_attributes-must_use.rs:105:5
+ |
+LL | U { unit: () };
+ | ^^^^^^^^^^^^^^
+
+error: unused return value of `U::method` that must be used
+ --> $DIR/unused_attributes-must_use.rs:106:5
+ |
+LL | U::method();
+ | ^^^^^^^^^^^
+
+error: unused return value of `foo` that must be used
+ --> $DIR/unused_attributes-must_use.rs:107:5
+ |
+LL | foo();
+ | ^^^^^
+
+error: unused return value of `foreign_foo` that must be used
+ --> $DIR/unused_attributes-must_use.rs:110:9
+ |
+LL | foreign_foo();
+ | ^^^^^^^^^^^^^
+
+error: unused return value of `Use::get_four` that must be used
+ --> $DIR/unused_attributes-must_use.rs:118:5
+ |
+LL | ().get_four();
+ | ^^^^^^^^^^^^^
+
+error: aborting due to 28 previous errors
+
diff --git a/tests/ui/lint/unused/useless-comment.rs b/tests/ui/lint/unused/useless-comment.rs
new file mode 100644
index 000000000..7d2e5ab6f
--- /dev/null
+++ b/tests/ui/lint/unused/useless-comment.rs
@@ -0,0 +1,45 @@
+#![feature(stmt_expr_attributes)]
+
+#![deny(unused_doc_comments)]
+
+macro_rules! mac {
+ () => {}
+}
+
+/// foo //~ ERROR unused doc comment
+mac!();
+
+fn foo() {
+ /// a //~ ERROR unused doc comment
+ let x = 12;
+
+ /// multi-line //~ unused doc comment
+ /// doc comment
+ /// that is unused
+ match x {
+ /// c //~ ERROR unused doc comment
+ 1 => {},
+ _ => {}
+ }
+
+ /// foo //~ ERROR unused doc comment
+ unsafe {}
+
+ #[doc = "foo"] //~ ERROR unused doc comment
+ #[doc = "bar"] //~ ERROR unused doc comment
+ 3;
+
+ /// bar //~ ERROR unused doc comment
+ mac!();
+
+ let x = /** comment */ 47; //~ ERROR unused doc comment
+
+ /// dox //~ ERROR unused doc comment
+ {
+
+ }
+}
+
+fn main() {
+ foo();
+}
diff --git a/tests/ui/lint/unused/useless-comment.stderr b/tests/ui/lint/unused/useless-comment.stderr
new file mode 100644
index 000000000..8bb5bdaeb
--- /dev/null
+++ b/tests/ui/lint/unused/useless-comment.stderr
@@ -0,0 +1,110 @@
+error: unused doc comment
+ --> $DIR/useless-comment.rs:9:1
+ |
+LL | /// foo
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustdoc does not generate documentation for macro invocations
+ |
+ = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion
+note: the lint level is defined here
+ --> $DIR/useless-comment.rs:3:9
+ |
+LL | #![deny(unused_doc_comments)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: unused doc comment
+ --> $DIR/useless-comment.rs:32:5
+ |
+LL | /// bar
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustdoc does not generate documentation for macro invocations
+ |
+ = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion
+
+error: unused doc comment
+ --> $DIR/useless-comment.rs:13:5
+ |
+LL | /// a
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | let x = 12;
+ | ----------- rustdoc does not generate documentation for statements
+ |
+ = help: use `//` for a plain comment
+
+error: unused doc comment
+ --> $DIR/useless-comment.rs:16:5
+ |
+LL | / /// multi-line
+LL | | /// doc comment
+LL | | /// that is unused
+ | |______________________^
+LL | / match x {
+LL | | /// c
+LL | | 1 => {},
+LL | | _ => {}
+LL | | }
+ | |_____- rustdoc does not generate documentation for expressions
+ |
+ = help: use `//` for a plain comment
+
+error: unused doc comment
+ --> $DIR/useless-comment.rs:20:9
+ |
+LL | /// c
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | 1 => {},
+ | ------- rustdoc does not generate documentation for match arms
+ |
+ = help: use `//` for a plain comment
+
+error: unused doc comment
+ --> $DIR/useless-comment.rs:25:5
+ |
+LL | /// foo
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | unsafe {}
+ | --------- rustdoc does not generate documentation for expressions
+ |
+ = help: use `//` for a plain comment
+
+error: unused doc comment
+ --> $DIR/useless-comment.rs:28:5
+ |
+LL | #[doc = "foo"]
+ | ^^^^^^^^^^^^^^
+LL | #[doc = "bar"]
+LL | 3;
+ | - rustdoc does not generate documentation for expressions
+ |
+ = help: use `//` for a plain comment
+
+error: unused doc comment
+ --> $DIR/useless-comment.rs:29:5
+ |
+LL | #[doc = "bar"]
+ | ^^^^^^^^^^^^^^
+LL | 3;
+ | - rustdoc does not generate documentation for expressions
+ |
+ = help: use `//` for a plain comment
+
+error: unused doc comment
+ --> $DIR/useless-comment.rs:35:13
+ |
+LL | let x = /** comment */ 47;
+ | ^^^^^^^^^^^^^^ -- rustdoc does not generate documentation for expressions
+ |
+ = help: use `/* */` for a plain comment
+
+error: unused doc comment
+ --> $DIR/useless-comment.rs:37:5
+ |
+LL | /// dox
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / {
+LL | |
+LL | | }
+ | |_____- rustdoc does not generate documentation for expressions
+ |
+ = help: use `//` for a plain comment
+
+error: aborting due to 10 previous errors
+
diff --git a/tests/ui/lint/unused_braces.fixed b/tests/ui/lint/unused_braces.fixed
new file mode 100644
index 000000000..e691fb37e
--- /dev/null
+++ b/tests/ui/lint/unused_braces.fixed
@@ -0,0 +1,57 @@
+// check-pass
+// run-rustfix
+
+#![warn(unused_braces, unused_parens)]
+#![allow(unreachable_code, unused_unsafe)] // for rustfix
+
+fn consume<T>(_: T) {}
+
+fn main() {
+ let _ = 7;
+ //~^WARN unnecessary parentheses
+
+ // Do not emit a lint in these cases,
+ // as we have to be careful with
+ // `ref` patterns.
+ {
+ let _ = { 7 };
+
+ if let 7 = { 7 } { }
+
+ match { 7 } {
+ _ => (),
+ }
+ }
+
+ if true {
+ //~^ WARN unnecessary braces
+ }
+
+ while false {
+ //~^ WARN unnecessary braces
+ }
+
+ let _: [u8; 3];
+ //~^ WARN unnecessary braces
+
+ consume(7);
+ //~^ WARN unnecessary braces
+
+ // Do not emit lint for multiline blocks.
+ let _ = {
+ 7
+ };
+
+ // Do not emit lint for unsafe blocks.
+ let _ = unsafe { 7 };
+
+ // Do not emit lint, as the `{` would then
+ // be parsed as part of the `return`.
+ if { return } {
+
+ }
+
+ // regression test for https://github.com/rust-lang/rust/issues/106899
+ return println!("!");
+ //~^ WARN unnecessary braces
+}
diff --git a/tests/ui/lint/unused_braces.rs b/tests/ui/lint/unused_braces.rs
new file mode 100644
index 000000000..0d260d2cb
--- /dev/null
+++ b/tests/ui/lint/unused_braces.rs
@@ -0,0 +1,57 @@
+// check-pass
+// run-rustfix
+
+#![warn(unused_braces, unused_parens)]
+#![allow(unreachable_code, unused_unsafe)] // for rustfix
+
+fn consume<T>(_: T) {}
+
+fn main() {
+ let _ = (7);
+ //~^WARN unnecessary parentheses
+
+ // Do not emit a lint in these cases,
+ // as we have to be careful with
+ // `ref` patterns.
+ {
+ let _ = { 7 };
+
+ if let 7 = { 7 } { }
+
+ match { 7 } {
+ _ => (),
+ }
+ }
+
+ if { true } {
+ //~^ WARN unnecessary braces
+ }
+
+ while { false } {
+ //~^ WARN unnecessary braces
+ }
+
+ let _: [u8; { 3 }];
+ //~^ WARN unnecessary braces
+
+ consume({ 7 });
+ //~^ WARN unnecessary braces
+
+ // Do not emit lint for multiline blocks.
+ let _ = {
+ 7
+ };
+
+ // Do not emit lint for unsafe blocks.
+ let _ = unsafe { 7 };
+
+ // Do not emit lint, as the `{` would then
+ // be parsed as part of the `return`.
+ if { return } {
+
+ }
+
+ // regression test for https://github.com/rust-lang/rust/issues/106899
+ return { println!("!") };
+ //~^ WARN unnecessary braces
+}
diff --git a/tests/ui/lint/unused_braces.stderr b/tests/ui/lint/unused_braces.stderr
new file mode 100644
index 000000000..0b4a1c321
--- /dev/null
+++ b/tests/ui/lint/unused_braces.stderr
@@ -0,0 +1,84 @@
+warning: unnecessary parentheses around assigned value
+ --> $DIR/unused_braces.rs:10:13
+ |
+LL | let _ = (7);
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/unused_braces.rs:4:24
+ |
+LL | #![warn(unused_braces, unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - let _ = (7);
+LL + let _ = 7;
+ |
+
+warning: unnecessary braces around `if` condition
+ --> $DIR/unused_braces.rs:26:8
+ |
+LL | if { true } {
+ | ^^ ^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused_braces.rs:4:9
+ |
+LL | #![warn(unused_braces, unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these braces
+ |
+LL - if { true } {
+LL + if true {
+ |
+
+warning: unnecessary braces around `while` condition
+ --> $DIR/unused_braces.rs:30:11
+ |
+LL | while { false } {
+ | ^^ ^^
+ |
+help: remove these braces
+ |
+LL - while { false } {
+LL + while false {
+ |
+
+warning: unnecessary braces around const expression
+ --> $DIR/unused_braces.rs:34:17
+ |
+LL | let _: [u8; { 3 }];
+ | ^^ ^^
+ |
+help: remove these braces
+ |
+LL - let _: [u8; { 3 }];
+LL + let _: [u8; 3];
+ |
+
+warning: unnecessary braces around function argument
+ --> $DIR/unused_braces.rs:37:13
+ |
+LL | consume({ 7 });
+ | ^^ ^^
+ |
+help: remove these braces
+ |
+LL - consume({ 7 });
+LL + consume(7);
+ |
+
+warning: unnecessary braces around `return` value
+ --> $DIR/unused_braces.rs:55:12
+ |
+LL | return { println!("!") };
+ | ^^ ^^
+ |
+help: remove these braces
+ |
+LL - return { println!("!") };
+LL + return println!("!");
+ |
+
+warning: 6 warnings emitted
+
diff --git a/tests/ui/lint/unused_braces_borrow.fixed b/tests/ui/lint/unused_braces_borrow.fixed
new file mode 100644
index 000000000..583506f89
--- /dev/null
+++ b/tests/ui/lint/unused_braces_borrow.fixed
@@ -0,0 +1,26 @@
+// check-pass
+// run-rustfix
+
+#![warn(unused_braces)]
+
+// changing `&{ expr }` to `&expr` changes the semantic of the program
+// so we should not warn this case
+
+#[repr(packed)]
+pub struct A {
+ pub a: u8,
+ pub b: u32,
+}
+
+fn consume<T>(_: T) {}
+
+fn main() {
+ let a = A {
+ a: 42,
+ b: 1729,
+ };
+
+ consume(&{ a.b });
+ consume(a.b);
+ //~^ WARN unnecessary braces
+}
diff --git a/tests/ui/lint/unused_braces_borrow.rs b/tests/ui/lint/unused_braces_borrow.rs
new file mode 100644
index 000000000..b7c529d73
--- /dev/null
+++ b/tests/ui/lint/unused_braces_borrow.rs
@@ -0,0 +1,26 @@
+// check-pass
+// run-rustfix
+
+#![warn(unused_braces)]
+
+// changing `&{ expr }` to `&expr` changes the semantic of the program
+// so we should not warn this case
+
+#[repr(packed)]
+pub struct A {
+ pub a: u8,
+ pub b: u32,
+}
+
+fn consume<T>(_: T) {}
+
+fn main() {
+ let a = A {
+ a: 42,
+ b: 1729,
+ };
+
+ consume(&{ a.b });
+ consume({ a.b });
+ //~^ WARN unnecessary braces
+}
diff --git a/tests/ui/lint/unused_braces_borrow.stderr b/tests/ui/lint/unused_braces_borrow.stderr
new file mode 100644
index 000000000..05f7432b8
--- /dev/null
+++ b/tests/ui/lint/unused_braces_borrow.stderr
@@ -0,0 +1,19 @@
+warning: unnecessary braces around function argument
+ --> $DIR/unused_braces_borrow.rs:24:13
+ |
+LL | consume({ a.b });
+ | ^^ ^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused_braces_borrow.rs:4:9
+ |
+LL | #![warn(unused_braces)]
+ | ^^^^^^^^^^^^^
+help: remove these braces
+ |
+LL - consume({ a.b });
+LL + consume(a.b);
+ |
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/unused_braces_macro.rs b/tests/ui/lint/unused_braces_macro.rs
new file mode 100644
index 000000000..bfee95378
--- /dev/null
+++ b/tests/ui/lint/unused_braces_macro.rs
@@ -0,0 +1,6 @@
+// build-pass
+pub fn foo<const BAR: bool> () {}
+
+fn main() {
+ foo::<{cfg!(feature = "foo")}>();
+}
diff --git a/tests/ui/lint/unused_import_warning_issue_45268.rs b/tests/ui/lint/unused_import_warning_issue_45268.rs
new file mode 100644
index 000000000..5ae482863
--- /dev/null
+++ b/tests/ui/lint/unused_import_warning_issue_45268.rs
@@ -0,0 +1,49 @@
+// check-pass
+
+#![warn(unused_imports)] // Warning explanation here, it's OK
+
+mod test {
+ pub trait A {
+ fn a();
+ }
+
+ impl A for () {
+ fn a() { }
+ }
+
+ pub trait B {
+ fn b(self);
+ }
+
+ impl B for () {
+ fn b(self) { }
+ }
+
+ pub trait Unused {
+ }
+}
+
+use test::Unused; // This is really unused, so warning is OK
+ //~^ WARNING unused import
+use test::A; // This is used by the test2::func() through import of super::*
+use test::B; // This is used by the test2::func() through import of super::*
+
+mod test2 {
+ use super::*;
+ pub fn func() {
+ let _ = <()>::a();
+ let _ = ().b();
+ test3::inner_func();
+ }
+ mod test3 {
+ use super::*;
+ pub fn inner_func() {
+ let _ = <()>::a();
+ let _ = ().b();
+ }
+ }
+}
+
+fn main() {
+ test2::func();
+}
diff --git a/tests/ui/lint/unused_import_warning_issue_45268.stderr b/tests/ui/lint/unused_import_warning_issue_45268.stderr
new file mode 100644
index 000000000..fa8699abc
--- /dev/null
+++ b/tests/ui/lint/unused_import_warning_issue_45268.stderr
@@ -0,0 +1,14 @@
+warning: unused import: `test::Unused`
+ --> $DIR/unused_import_warning_issue_45268.rs:26:5
+ |
+LL | use test::Unused; // This is really unused, so warning is OK
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused_import_warning_issue_45268.rs:3:9
+ |
+LL | #![warn(unused_imports)] // Warning explanation here, it's OK
+ | ^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/unused_labels.rs b/tests/ui/lint/unused_labels.rs
new file mode 100644
index 000000000..87a5392fd
--- /dev/null
+++ b/tests/ui/lint/unused_labels.rs
@@ -0,0 +1,85 @@
+// The output should warn when a loop label is not used. However, it
+// should also deal with the edge cases where a label is shadowed,
+// within nested loops
+
+// check-pass
+
+#![warn(unused_labels)]
+
+fn main() {
+ 'unused_while_label: while 0 == 0 {
+ //~^ WARN unused label
+ }
+
+ let opt = Some(0);
+ 'unused_while_let_label: while let Some(_) = opt {
+ //~^ WARN unused label
+ }
+
+ 'unused_for_label: for _ in 0..10 {
+ //~^ WARN unused label
+ }
+
+ 'used_loop_label: loop {
+ break 'used_loop_label;
+ }
+
+ 'used_loop_label_outer_1: for _ in 0..10 {
+ 'used_loop_label_inner_1: for _ in 0..10 {
+ break 'used_loop_label_inner_1;
+ }
+ break 'used_loop_label_outer_1;
+ }
+
+ 'used_loop_label_outer_2: for _ in 0..10 {
+ 'unused_loop_label_inner_2: for _ in 0..10 {
+ //~^ WARN unused label
+ break 'used_loop_label_outer_2;
+ }
+ }
+
+ 'unused_loop_label_outer_3: for _ in 0..10 {
+ //~^ WARN unused label
+ 'used_loop_label_inner_3: for _ in 0..10 {
+ break 'used_loop_label_inner_3;
+ }
+ }
+
+ // You should be able to break the same label many times
+ 'many_used: loop {
+ if true {
+ break 'many_used;
+ } else {
+ break 'many_used;
+ }
+ }
+
+ // Test breaking many times with the same inner label doesn't break the
+ // warning on the outer label
+ 'many_used_shadowed: for _ in 0..10 {
+ //~^ WARN unused label
+ 'many_used_shadowed: for _ in 0..10 {
+ //~^ WARN label name `'many_used_shadowed` shadows a label name that is already in scope
+ if 1 % 2 == 0 {
+ break 'many_used_shadowed;
+ } else {
+ break 'many_used_shadowed;
+ }
+ }
+ }
+
+ 'unused_loop_label: loop {
+ //~^ WARN unused label
+ break;
+ }
+
+ // Make sure unused block labels give warnings...
+ 'unused_block_label: {
+ //~^ WARN unused label
+ }
+
+ // ...and that used ones don't:
+ 'used_block_label: {
+ break 'used_block_label;
+ }
+}
diff --git a/tests/ui/lint/unused_labels.stderr b/tests/ui/lint/unused_labels.stderr
new file mode 100644
index 000000000..846da792b
--- /dev/null
+++ b/tests/ui/lint/unused_labels.stderr
@@ -0,0 +1,65 @@
+warning: label name `'many_used_shadowed` shadows a label name that is already in scope
+ --> $DIR/unused_labels.rs:61:9
+ |
+LL | 'many_used_shadowed: for _ in 0..10 {
+ | ------------------- first declared here
+LL |
+LL | 'many_used_shadowed: for _ in 0..10 {
+ | ^^^^^^^^^^^^^^^^^^^ label `'many_used_shadowed` already in scope
+
+warning: unused label
+ --> $DIR/unused_labels.rs:10:5
+ |
+LL | 'unused_while_label: while 0 == 0 {
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unused_labels.rs:7:9
+ |
+LL | #![warn(unused_labels)]
+ | ^^^^^^^^^^^^^
+
+warning: unused label
+ --> $DIR/unused_labels.rs:15:5
+ |
+LL | 'unused_while_let_label: while let Some(_) = opt {
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused label
+ --> $DIR/unused_labels.rs:19:5
+ |
+LL | 'unused_for_label: for _ in 0..10 {
+ | ^^^^^^^^^^^^^^^^^
+
+warning: unused label
+ --> $DIR/unused_labels.rs:35:9
+ |
+LL | 'unused_loop_label_inner_2: for _ in 0..10 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused label
+ --> $DIR/unused_labels.rs:41:5
+ |
+LL | 'unused_loop_label_outer_3: for _ in 0..10 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused label
+ --> $DIR/unused_labels.rs:59:5
+ |
+LL | 'many_used_shadowed: for _ in 0..10 {
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: unused label
+ --> $DIR/unused_labels.rs:71:5
+ |
+LL | 'unused_loop_label: loop {
+ | ^^^^^^^^^^^^^^^^^^
+
+warning: unused label
+ --> $DIR/unused_labels.rs:77:5
+ |
+LL | 'unused_block_label: {
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: 9 warnings emitted
+
diff --git a/tests/ui/lint/unused_parens_json_suggestion.fixed b/tests/ui/lint/unused_parens_json_suggestion.fixed
new file mode 100644
index 000000000..c40045404
--- /dev/null
+++ b/tests/ui/lint/unused_parens_json_suggestion.fixed
@@ -0,0 +1,26 @@
+// compile-flags: --error-format json
+// run-rustfix
+
+// The output for humans should just highlight the whole span without showing
+// the suggested replacement, but we also want to test that suggested
+// replacement only removes one set of parentheses, rather than naïvely
+// stripping away any starting or ending parenthesis characters—hence this
+// test of the JSON error format.
+
+#![deny(unused_parens)]
+#![allow(unreachable_code)]
+
+fn main() {
+ // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not
+ // the malformed `1 / (2 + 3`
+ let _a = 1 / (2 + 3); //~ERROR unnecessary parentheses
+ f();
+}
+
+fn f() -> bool {
+ loop {
+ if (break { return true }) {
+ }
+ }
+ false
+}
diff --git a/tests/ui/lint/unused_parens_json_suggestion.rs b/tests/ui/lint/unused_parens_json_suggestion.rs
new file mode 100644
index 000000000..962c8bdd7
--- /dev/null
+++ b/tests/ui/lint/unused_parens_json_suggestion.rs
@@ -0,0 +1,26 @@
+// compile-flags: --error-format json
+// run-rustfix
+
+// The output for humans should just highlight the whole span without showing
+// the suggested replacement, but we also want to test that suggested
+// replacement only removes one set of parentheses, rather than naïvely
+// stripping away any starting or ending parenthesis characters—hence this
+// test of the JSON error format.
+
+#![deny(unused_parens)]
+#![allow(unreachable_code)]
+
+fn main() {
+ // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not
+ // the malformed `1 / (2 + 3`
+ let _a = (1 / (2 + 3)); //~ERROR unnecessary parentheses
+ f();
+}
+
+fn f() -> bool {
+ loop {
+ if (break { return true }) {
+ }
+ }
+ false
+}
diff --git a/tests/ui/lint/unused_parens_json_suggestion.stderr b/tests/ui/lint/unused_parens_json_suggestion.stderr
new file mode 100644
index 000000000..ea19e0cdc
--- /dev/null
+++ b/tests/ui/lint/unused_parens_json_suggestion.stderr
@@ -0,0 +1,21 @@
+{"message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":577,"byte_end":578,"line_start":16,"line_end":16,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":" let _a = (1 / (2 + 3));
+ --> $DIR/unused_parens_json_suggestion.rs:16:14
+ |
+LL | let _a = (1 / (2 + 3));
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/unused_parens_json_suggestion.rs:10:9
+ |
+LL | #![deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - let _a = (1 / (2 + 3));
+LL + let _a = 1 / (2 + 3);
+ |
+
+"}
+{"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error
+
+"}
diff --git a/tests/ui/lint/unused_parens_multibyte_recovery.rs b/tests/ui/lint/unused_parens_multibyte_recovery.rs
new file mode 100644
index 000000000..8fcfae22a
--- /dev/null
+++ b/tests/ui/lint/unused_parens_multibyte_recovery.rs
@@ -0,0 +1,11 @@
+// ignore-tidy-trailing-newlines
+//
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: format argument must be a string literal
+//
+// Verify that unused parens lint does not try to create a span
+// which points in the middle of a multibyte character.
+
+fn f(){(print!(á \ No newline at end of file
diff --git a/tests/ui/lint/unused_parens_multibyte_recovery.stderr b/tests/ui/lint/unused_parens_multibyte_recovery.stderr
new file mode 100644
index 000000000..a0302b17e
--- /dev/null
+++ b/tests/ui/lint/unused_parens_multibyte_recovery.stderr
@@ -0,0 +1,43 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/unused_parens_multibyte_recovery.rs:11:17
+ |
+LL | fn f(){(print!(á
+ | -- - ^
+ | || |
+ | || unclosed delimiter
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/unused_parens_multibyte_recovery.rs:11:17
+ |
+LL | fn f(){(print!(á
+ | -- - ^
+ | || |
+ | || unclosed delimiter
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/unused_parens_multibyte_recovery.rs:11:17
+ |
+LL | fn f(){(print!(á
+ | -- - ^
+ | || |
+ | || unclosed delimiter
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: format argument must be a string literal
+ --> $DIR/unused_parens_multibyte_recovery.rs:11:16
+ |
+LL | fn f(){(print!(á
+ | ^
+ |
+help: you might be missing a string literal to format with
+ |
+LL | fn f(){(print!("{}", á
+ | +++++
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lint/unused_parens_remove_json_suggestion.fixed b/tests/ui/lint/unused_parens_remove_json_suggestion.fixed
new file mode 100644
index 000000000..8a57cd573
--- /dev/null
+++ b/tests/ui/lint/unused_parens_remove_json_suggestion.fixed
@@ -0,0 +1,61 @@
+// compile-flags: --error-format json
+// run-rustfix
+
+// The output for humans should just highlight the whole span without showing
+// the suggested replacement, but we also want to test that suggested
+// replacement only removes one set of parentheses, rather than naïvely
+// stripping away any starting or ending parenthesis characters—hence this
+// test of the JSON error format.
+
+#![deny(unused_parens)]
+#![allow(unreachable_code)]
+
+fn main() {
+
+ let _b = false;
+
+ if _b { //~ ERROR unnecessary parentheses
+ println!("hello");
+ }
+
+ f();
+
+}
+
+fn f() -> bool {
+ let c = false;
+
+ if c { //~ ERROR unnecessary parentheses
+ println!("next");
+ }
+
+ if c { //~ ERROR unnecessary parentheses
+ println!("prev");
+ }
+
+ while false && true {
+ if c { //~ ERROR unnecessary parentheses
+ println!("norm");
+ }
+
+ }
+
+ while true && false { //~ ERROR unnecessary parentheses
+ for _ in 0 .. 3 { //~ ERROR unnecessary parentheses
+ println!("e~")
+ }
+ }
+
+ for _ in 0 .. 3 { //~ ERROR unnecessary parentheses
+ while true && false { //~ ERROR unnecessary parentheses
+ println!("e~")
+ }
+ }
+
+
+ loop {
+ if (break { return true }) {
+ }
+ }
+ false
+}
diff --git a/tests/ui/lint/unused_parens_remove_json_suggestion.rs b/tests/ui/lint/unused_parens_remove_json_suggestion.rs
new file mode 100644
index 000000000..952332d54
--- /dev/null
+++ b/tests/ui/lint/unused_parens_remove_json_suggestion.rs
@@ -0,0 +1,61 @@
+// compile-flags: --error-format json
+// run-rustfix
+
+// The output for humans should just highlight the whole span without showing
+// the suggested replacement, but we also want to test that suggested
+// replacement only removes one set of parentheses, rather than naïvely
+// stripping away any starting or ending parenthesis characters—hence this
+// test of the JSON error format.
+
+#![deny(unused_parens)]
+#![allow(unreachable_code)]
+
+fn main() {
+
+ let _b = false;
+
+ if (_b) { //~ ERROR unnecessary parentheses
+ println!("hello");
+ }
+
+ f();
+
+}
+
+fn f() -> bool {
+ let c = false;
+
+ if(c) { //~ ERROR unnecessary parentheses
+ println!("next");
+ }
+
+ if (c){ //~ ERROR unnecessary parentheses
+ println!("prev");
+ }
+
+ while (false && true){
+ if (c) { //~ ERROR unnecessary parentheses
+ println!("norm");
+ }
+
+ }
+
+ while(true && false) { //~ ERROR unnecessary parentheses
+ for _ in (0 .. 3){ //~ ERROR unnecessary parentheses
+ println!("e~")
+ }
+ }
+
+ for _ in (0 .. 3) { //~ ERROR unnecessary parentheses
+ while (true && false) { //~ ERROR unnecessary parentheses
+ println!("e~")
+ }
+ }
+
+
+ loop {
+ if (break { return true }) {
+ }
+ }
+ false
+}
diff --git a/tests/ui/lint/unused_parens_remove_json_suggestion.stderr b/tests/ui/lint/unused_parens_remove_json_suggestion.stderr
new file mode 100644
index 000000000..f4c6ceaf1
--- /dev/null
+++ b/tests/ui/lint/unused_parens_remove_json_suggestion.stderr
@@ -0,0 +1,125 @@
+{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":481,"byte_end":482,"line_start":17,"line_end":17,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":" if (_b) {
+ --> $DIR/unused_parens_remove_json_suggestion.rs:17:8
+ |
+LL | if (_b) {
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/unused_parens_remove_json_suggestion.rs:10:9
+ |
+LL | #![deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - if (_b) {
+LL + if _b {
+ |
+
+"}
+{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":612,"byte_end":613,"line_start":28,"line_end":28,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":" if(c) {
+ --> $DIR/unused_parens_remove_json_suggestion.rs:28:7
+ |
+LL | if(c) {
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - if(c) {
+LL + if c {
+ |
+
+"}
+{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":692,"byte_end":693,"line_start":32,"line_end":32,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":" if (c){
+ --> $DIR/unused_parens_remove_json_suggestion.rs:32:8
+ |
+LL | if (c){
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - if (c){
+LL + if c {
+ |
+
+"}
+{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":774,"byte_end":775,"line_start":36,"line_end":36,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":788,"byte_end":789,"line_start":36,"line_end":36,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":774,"byte_end":775,"line_start":36,"line_end":36,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":788,"byte_end":789,"line_start":36,"line_end":36,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
+ --> $DIR/unused_parens_remove_json_suggestion.rs:36:11
+ |
+LL | while (false && true){
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - while (false && true){
+LL + while false && true {
+ |
+
+"}
+{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":802,"byte_end":803,"line_start":37,"line_end":37,"column_start":12,"column_end":13,"is_primary":true,"text":[{"text":" if (c) {
+ --> $DIR/unused_parens_remove_json_suggestion.rs:37:12
+ |
+LL | if (c) {
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - if (c) {
+LL + if c {
+ |
+
+"}
+{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":899,"byte_end":900,"line_start":43,"line_end":43,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":" while(true && false) {
+ --> $DIR/unused_parens_remove_json_suggestion.rs:43:10
+ |
+LL | while(true && false) {
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - while(true && false) {
+LL + while true && false {
+ |
+
+"}
+{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":968,"byte_end":969,"line_start":44,"line_end":44,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":" for _ in (0 .. 3){
+ --> $DIR/unused_parens_remove_json_suggestion.rs:44:18
+ |
+LL | for _ in (0 .. 3){
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - for _ in (0 .. 3){
+LL + for _ in 0 .. 3 {
+ |
+
+"}
+{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1069,"byte_end":1070,"line_start":49,"line_end":49,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":" for _ in (0 .. 3) {
+ --> $DIR/unused_parens_remove_json_suggestion.rs:49:14
+ |
+LL | for _ in (0 .. 3) {
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - for _ in (0 .. 3) {
+LL + for _ in 0 .. 3 {
+ |
+
+"}
+{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1128,"byte_end":1129,"line_start":50,"line_end":50,"column_start":15,"column_end":16,"is_primary":true,"text":[{"text":" while (true && false) {
+ --> $DIR/unused_parens_remove_json_suggestion.rs:50:15
+ |
+LL | while (true && false) {
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - while (true && false) {
+LL + while true && false {
+ |
+
+"}
+{"message":"aborting due to 9 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 9 previous errors
+
+"}
diff --git a/tests/ui/lint/unused_variables-issue-82488.fixed b/tests/ui/lint/unused_variables-issue-82488.fixed
new file mode 100644
index 000000000..3cb2c90d0
--- /dev/null
+++ b/tests/ui/lint/unused_variables-issue-82488.fixed
@@ -0,0 +1,16 @@
+// run-rustfix
+#![deny(unused_variables)]
+
+struct Point {
+ x: u32,
+ y: u32
+}
+
+fn process_point(Point { x, y: _renamed }: Point) {
+//~^ ERROR unused variable: `renamed`
+ let _ = x;
+}
+
+fn main() {
+ process_point(Point { x: 0, y: 0 });
+}
diff --git a/tests/ui/lint/unused_variables-issue-82488.rs b/tests/ui/lint/unused_variables-issue-82488.rs
new file mode 100644
index 000000000..007b0799b
--- /dev/null
+++ b/tests/ui/lint/unused_variables-issue-82488.rs
@@ -0,0 +1,16 @@
+// run-rustfix
+#![deny(unused_variables)]
+
+struct Point {
+ x: u32,
+ y: u32
+}
+
+fn process_point(Point { x, y: renamed }: Point) {
+//~^ ERROR unused variable: `renamed`
+ let _ = x;
+}
+
+fn main() {
+ process_point(Point { x: 0, y: 0 });
+}
diff --git a/tests/ui/lint/unused_variables-issue-82488.stderr b/tests/ui/lint/unused_variables-issue-82488.stderr
new file mode 100644
index 000000000..dce03a0f7
--- /dev/null
+++ b/tests/ui/lint/unused_variables-issue-82488.stderr
@@ -0,0 +1,14 @@
+error: unused variable: `renamed`
+ --> $DIR/unused_variables-issue-82488.rs:9:32
+ |
+LL | fn process_point(Point { x, y: renamed }: Point) {
+ | ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_renamed`
+ |
+note: the lint level is defined here
+ --> $DIR/unused_variables-issue-82488.rs:2:9
+ |
+LL | #![deny(unused_variables)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/use-redundant.rs b/tests/ui/lint/use-redundant.rs
new file mode 100644
index 000000000..53315dcf6
--- /dev/null
+++ b/tests/ui/lint/use-redundant.rs
@@ -0,0 +1,27 @@
+// check-pass
+#![warn(unused_imports)]
+
+use crate::foo::Bar;
+
+mod foo {
+ pub type Bar = i32;
+}
+
+fn baz() -> Bar {
+ 3
+}
+
+mod m1 { pub struct S {} }
+mod m2 { pub struct S {} }
+
+use m1::*; //~ WARNING unused import
+use m2::*; //~ WARNING unused import
+
+fn main() {
+ use crate::foo::Bar; //~ WARNING imported redundantly
+ let _a: Bar = 3;
+ baz();
+
+ use m1::S;
+ let _s = S {};
+}
diff --git a/tests/ui/lint/use-redundant.stderr b/tests/ui/lint/use-redundant.stderr
new file mode 100644
index 000000000..c861a1956
--- /dev/null
+++ b/tests/ui/lint/use-redundant.stderr
@@ -0,0 +1,29 @@
+warning: unused import: `m1::*`
+ --> $DIR/use-redundant.rs:17:5
+ |
+LL | use m1::*;
+ | ^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/use-redundant.rs:2:9
+ |
+LL | #![warn(unused_imports)]
+ | ^^^^^^^^^^^^^^
+
+warning: unused import: `m2::*`
+ --> $DIR/use-redundant.rs:18:5
+ |
+LL | use m2::*;
+ | ^^^^^
+
+warning: the item `Bar` is imported redundantly
+ --> $DIR/use-redundant.rs:21:9
+ |
+LL | use crate::foo::Bar;
+ | --------------- the item `Bar` is already imported here
+...
+LL | use crate::foo::Bar;
+ | ^^^^^^^^^^^^^^^
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/lint/use_suggestion_json.rs b/tests/ui/lint/use_suggestion_json.rs
new file mode 100644
index 000000000..7d641e08b
--- /dev/null
+++ b/tests/ui/lint/use_suggestion_json.rs
@@ -0,0 +1,13 @@
+// ignore-windows
+// ignore-sgx std::os::fortanix_sgx::usercalls::alloc::Iter changes compiler suggestions
+// compile-flags: --error-format pretty-json --json=diagnostic-rendered-ansi
+
+// The output for humans should just highlight the whole span without showing
+// the suggested replacement, but we also want to test that suggested
+// replacement only removes one set of parentheses, rather than naïvely
+// stripping away any starting or ending parenthesis characters—hence this
+// test of the JSON error format.
+
+fn main() {
+ let x: Iter;
+}
diff --git a/tests/ui/lint/use_suggestion_json.stderr b/tests/ui/lint/use_suggestion_json.stderr
new file mode 100644
index 000000000..d17514303
--- /dev/null
+++ b/tests/ui/lint/use_suggestion_json.stderr
@@ -0,0 +1,3 @@
+{"message":"`--error-format=pretty-json` is unstable","code":null,"level":"error","spans":[],"children":[],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;9merror\u001b[0m\u001b[0m\u001b[1m: `--error-format=pretty-json` is unstable\u001b[0m
+
+"}
diff --git a/tests/ui/lint/warn-ctypes-inhibit.rs b/tests/ui/lint/warn-ctypes-inhibit.rs
new file mode 100644
index 000000000..15d8b09d2
--- /dev/null
+++ b/tests/ui/lint/warn-ctypes-inhibit.rs
@@ -0,0 +1,15 @@
+// run-pass
+
+#![allow(dead_code)]
+// compile-flags:-D improper-ctypes
+
+// pretty-expanded FIXME #23616
+#![allow(improper_ctypes)]
+
+mod libc {
+ extern "C" {
+ pub fn malloc(size: isize) -> *const u8;
+ }
+}
+
+pub fn main() {}
diff --git a/tests/ui/lint/warn-path-statement.rs b/tests/ui/lint/warn-path-statement.rs
new file mode 100644
index 000000000..2435be623
--- /dev/null
+++ b/tests/ui/lint/warn-path-statement.rs
@@ -0,0 +1,17 @@
+// compile-flags: -D path-statements
+struct Droppy;
+
+impl Drop for Droppy {
+ fn drop(&mut self) {}
+}
+
+fn main() {
+ let x = 10;
+ x; //~ ERROR path statement with no effect
+
+ let y = Droppy;
+ y; //~ ERROR path statement drops value
+
+ let z = (Droppy,);
+ z; //~ ERROR path statement drops value
+}
diff --git a/tests/ui/lint/warn-path-statement.stderr b/tests/ui/lint/warn-path-statement.stderr
new file mode 100644
index 000000000..248d2ef29
--- /dev/null
+++ b/tests/ui/lint/warn-path-statement.stderr
@@ -0,0 +1,22 @@
+error: path statement with no effect
+ --> $DIR/warn-path-statement.rs:10:5
+ |
+LL | x;
+ | ^^
+ |
+ = note: requested on the command line with `-D path-statements`
+
+error: path statement drops value
+ --> $DIR/warn-path-statement.rs:13:5
+ |
+LL | y;
+ | ^^ help: use `drop` to clarify the intent: `drop(y);`
+
+error: path statement drops value
+ --> $DIR/warn-path-statement.rs:16:5
+ |
+LL | z;
+ | ^^ help: use `drop` to clarify the intent: `drop(z);`
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/warn-unused-inline-on-fn-prototypes.rs b/tests/ui/lint/warn-unused-inline-on-fn-prototypes.rs
new file mode 100644
index 000000000..4684fe145
--- /dev/null
+++ b/tests/ui/lint/warn-unused-inline-on-fn-prototypes.rs
@@ -0,0 +1,13 @@
+#![deny(unused_attributes)]
+
+trait Trait {
+ #[inline] //~ ERROR `#[inline]` is ignored on function prototypes
+ fn foo();
+}
+
+extern "C" {
+ #[inline] //~ ERROR `#[inline]` is ignored on function prototypes
+ fn foo();
+}
+
+fn main() {}
diff --git a/tests/ui/lint/warn-unused-inline-on-fn-prototypes.stderr b/tests/ui/lint/warn-unused-inline-on-fn-prototypes.stderr
new file mode 100644
index 000000000..ab19d80e7
--- /dev/null
+++ b/tests/ui/lint/warn-unused-inline-on-fn-prototypes.stderr
@@ -0,0 +1,20 @@
+error: `#[inline]` is ignored on function prototypes
+ --> $DIR/warn-unused-inline-on-fn-prototypes.rs:4:5
+ |
+LL | #[inline]
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/warn-unused-inline-on-fn-prototypes.rs:1:9
+ |
+LL | #![deny(unused_attributes)]
+ | ^^^^^^^^^^^^^^^^^
+
+error: `#[inline]` is ignored on function prototypes
+ --> $DIR/warn-unused-inline-on-fn-prototypes.rs:9:5
+ |
+LL | #[inline]
+ | ^^^^^^^^^
+
+error: aborting due to 2 previous errors
+