summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/tests/ui-internal
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/clippy/tests/ui-internal')
-rw-r--r--src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.rs87
-rw-r--r--src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr68
-rw-r--r--src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.fixed57
-rw-r--r--src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs67
-rw-r--r--src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr49
-rw-r--r--src/tools/clippy/tests/ui-internal/custom_ice_message.rs11
-rw-r--r--src/tools/clippy/tests/ui-internal/custom_ice_message.stderr13
-rw-r--r--src/tools/clippy/tests/ui-internal/default_deprecation_reason.rs30
-rw-r--r--src/tools/clippy/tests/ui-internal/default_deprecation_reason.stderr22
-rw-r--r--src/tools/clippy/tests/ui-internal/default_lint.rs28
-rw-r--r--src/tools/clippy/tests/ui-internal/default_lint.stderr21
-rw-r--r--src/tools/clippy/tests/ui-internal/if_chain_style.rs92
-rw-r--r--src/tools/clippy/tests/ui-internal/if_chain_style.stderr85
-rw-r--r--src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed37
-rw-r--r--src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs37
-rw-r--r--src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr33
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed40
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs38
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.stderr32
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_paths.rs27
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_paths.stderr22
-rw-r--r--src/tools/clippy/tests/ui-internal/lint_without_lint_pass.rs45
-rw-r--r--src/tools/clippy/tests/ui-internal/lint_without_lint_pass.stderr21
-rw-r--r--src/tools/clippy/tests/ui-internal/match_type_on_diag_item.rs39
-rw-r--r--src/tools/clippy/tests/ui-internal/match_type_on_diag_item.stderr27
-rw-r--r--src/tools/clippy/tests/ui-internal/outer_expn_data.fixed29
-rw-r--r--src/tools/clippy/tests/ui-internal/outer_expn_data.rs29
-rw-r--r--src/tools/clippy/tests/ui-internal/outer_expn_data.stderr15
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed21
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs21
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr39
31 files changed, 1182 insertions, 0 deletions
diff --git a/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.rs b/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.rs
new file mode 100644
index 000000000..31acac89c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.rs
@@ -0,0 +1,87 @@
+#![deny(clippy::internal)]
+#![feature(rustc_private)]
+
+#[macro_use]
+extern crate rustc_middle;
+#[macro_use]
+extern crate rustc_session;
+extern crate rustc_lint;
+
+///////////////////////
+// Valid descriptions
+///////////////////////
+declare_tool_lint! {
+ #[clippy::version = "pre 1.29.0"]
+ pub clippy::VALID_ONE,
+ Warn,
+ "One",
+ report_in_external_macro: true
+}
+
+declare_tool_lint! {
+ #[clippy::version = "1.29.0"]
+ pub clippy::VALID_TWO,
+ Warn,
+ "Two",
+ report_in_external_macro: true
+}
+
+declare_tool_lint! {
+ #[clippy::version = "1.59.0"]
+ pub clippy::VALID_THREE,
+ Warn,
+ "Three",
+ report_in_external_macro: true
+}
+
+///////////////////////
+// Invalid attributes
+///////////////////////
+declare_tool_lint! {
+ #[clippy::version = "1.2.3.4.5.6"]
+ pub clippy::INVALID_ONE,
+ Warn,
+ "One",
+ report_in_external_macro: true
+}
+
+declare_tool_lint! {
+ #[clippy::version = "I'm a string"]
+ pub clippy::INVALID_TWO,
+ Warn,
+ "Two",
+ report_in_external_macro: true
+}
+
+///////////////////////
+// Missing attribute test
+///////////////////////
+declare_tool_lint! {
+ #[clippy::version]
+ pub clippy::MISSING_ATTRIBUTE_ONE,
+ Warn,
+ "Two",
+ report_in_external_macro: true
+}
+
+declare_tool_lint! {
+ pub clippy::MISSING_ATTRIBUTE_TWO,
+ Warn,
+ "Two",
+ report_in_external_macro: true
+}
+
+#[allow(clippy::missing_clippy_version_attribute)]
+mod internal_clippy_lints {
+ declare_tool_lint! {
+ pub clippy::ALLOW_MISSING_ATTRIBUTE_ONE,
+ Warn,
+ "Two",
+ report_in_external_macro: true
+ }
+}
+
+use crate::internal_clippy_lints::ALLOW_MISSING_ATTRIBUTE_ONE;
+declare_lint_pass!(Pass2 => [VALID_ONE, VALID_TWO, VALID_THREE, INVALID_ONE, INVALID_TWO, MISSING_ATTRIBUTE_ONE, MISSING_ATTRIBUTE_TWO, ALLOW_MISSING_ATTRIBUTE_ONE]);
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr b/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr
new file mode 100644
index 000000000..533107588
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr
@@ -0,0 +1,68 @@
+error: this item has an invalid `clippy::version` attribute
+ --> $DIR/check_clippy_version_attribute.rs:40:1
+ |
+LL | / declare_tool_lint! {
+LL | | #[clippy::version = "1.2.3.4.5.6"]
+LL | | pub clippy::INVALID_ONE,
+LL | | Warn,
+LL | | "One",
+LL | | report_in_external_macro: true
+LL | | }
+ | |_^
+ |
+note: the lint level is defined here
+ --> $DIR/check_clippy_version_attribute.rs:1:9
+ |
+LL | #![deny(clippy::internal)]
+ | ^^^^^^^^^^^^^^^^
+ = note: `#[deny(clippy::invalid_clippy_version_attribute)]` implied by `#[deny(clippy::internal)]`
+ = help: please use a valid sematic version, see `doc/adding_lints.md`
+ = note: this error originates in the macro `$crate::declare_tool_lint` which comes from the expansion of the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: this item has an invalid `clippy::version` attribute
+ --> $DIR/check_clippy_version_attribute.rs:48:1
+ |
+LL | / declare_tool_lint! {
+LL | | #[clippy::version = "I'm a string"]
+LL | | pub clippy::INVALID_TWO,
+LL | | Warn,
+LL | | "Two",
+LL | | report_in_external_macro: true
+LL | | }
+ | |_^
+ |
+ = help: please use a valid sematic version, see `doc/adding_lints.md`
+ = note: this error originates in the macro `$crate::declare_tool_lint` which comes from the expansion of the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: this lint is missing the `clippy::version` attribute or version value
+ --> $DIR/check_clippy_version_attribute.rs:59:1
+ |
+LL | / declare_tool_lint! {
+LL | | #[clippy::version]
+LL | | pub clippy::MISSING_ATTRIBUTE_ONE,
+LL | | Warn,
+LL | | "Two",
+LL | | report_in_external_macro: true
+LL | | }
+ | |_^
+ |
+ = note: `#[deny(clippy::missing_clippy_version_attribute)]` implied by `#[deny(clippy::internal)]`
+ = help: please use a `clippy::version` attribute, see `doc/adding_lints.md`
+ = note: this error originates in the macro `$crate::declare_tool_lint` which comes from the expansion of the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: this lint is missing the `clippy::version` attribute or version value
+ --> $DIR/check_clippy_version_attribute.rs:67:1
+ |
+LL | / declare_tool_lint! {
+LL | | pub clippy::MISSING_ATTRIBUTE_TWO,
+LL | | Warn,
+LL | | "Two",
+LL | | report_in_external_macro: true
+LL | | }
+ | |_^
+ |
+ = help: please use a `clippy::version` attribute, see `doc/adding_lints.md`
+ = note: this error originates in the macro `$crate::declare_tool_lint` which comes from the expansion of the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.fixed b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.fixed
new file mode 100644
index 000000000..9f299d7de
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.fixed
@@ -0,0 +1,57 @@
+// run-rustfix
+#![deny(clippy::internal)]
+#![allow(clippy::missing_clippy_version_attribute)]
+#![feature(rustc_private)]
+
+extern crate clippy_utils;
+extern crate rustc_ast;
+extern crate rustc_errors;
+extern crate rustc_lint;
+extern crate rustc_session;
+extern crate rustc_span;
+
+use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then};
+use rustc_ast::ast::Expr;
+use rustc_errors::Applicability;
+use rustc_lint::{EarlyContext, EarlyLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+declare_tool_lint! {
+ pub clippy::TEST_LINT,
+ Warn,
+ "",
+ report_in_external_macro: true
+}
+
+declare_lint_pass!(Pass => [TEST_LINT]);
+
+impl EarlyLintPass for Pass {
+ fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
+ let lint_msg = "lint message";
+ let help_msg = "help message";
+ let note_msg = "note message";
+ let sugg = "new_call()";
+ let predicate = true;
+
+ span_lint_and_sugg(cx, TEST_LINT, expr.span, lint_msg, help_msg, sugg.to_string(), Applicability::MachineApplicable);
+ span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), help_msg);
+ span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, None, help_msg);
+ span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), note_msg);
+ span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, None, note_msg);
+
+ // This expr shouldn't trigger this lint.
+ span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+ db.note(note_msg);
+ if predicate {
+ db.note(note_msg);
+ }
+ });
+
+ // Issue #8798
+ span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+ db.help(help_msg).help(help_msg);
+ });
+ }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs
new file mode 100644
index 000000000..2b113f555
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs
@@ -0,0 +1,67 @@
+// run-rustfix
+#![deny(clippy::internal)]
+#![allow(clippy::missing_clippy_version_attribute)]
+#![feature(rustc_private)]
+
+extern crate clippy_utils;
+extern crate rustc_ast;
+extern crate rustc_errors;
+extern crate rustc_lint;
+extern crate rustc_session;
+extern crate rustc_span;
+
+use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then};
+use rustc_ast::ast::Expr;
+use rustc_errors::Applicability;
+use rustc_lint::{EarlyContext, EarlyLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+declare_tool_lint! {
+ pub clippy::TEST_LINT,
+ Warn,
+ "",
+ report_in_external_macro: true
+}
+
+declare_lint_pass!(Pass => [TEST_LINT]);
+
+impl EarlyLintPass for Pass {
+ fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
+ let lint_msg = "lint message";
+ let help_msg = "help message";
+ let note_msg = "note message";
+ let sugg = "new_call()";
+ let predicate = true;
+
+ span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+ db.span_suggestion(expr.span, help_msg, sugg.to_string(), Applicability::MachineApplicable);
+ });
+ span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+ db.span_help(expr.span, help_msg);
+ });
+ span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+ db.help(help_msg);
+ });
+ span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+ db.span_note(expr.span, note_msg);
+ });
+ span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+ db.note(note_msg);
+ });
+
+ // This expr shouldn't trigger this lint.
+ span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+ db.note(note_msg);
+ if predicate {
+ db.note(note_msg);
+ }
+ });
+
+ // Issue #8798
+ span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+ db.help(help_msg).help(help_msg);
+ });
+ }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr
new file mode 100644
index 000000000..0852fe65a
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr
@@ -0,0 +1,49 @@
+error: this call is collapsible
+ --> $DIR/collapsible_span_lint_calls.rs:36:9
+ |
+LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+LL | | db.span_suggestion(expr.span, help_msg, sugg.to_string(), Applicability::MachineApplicable);
+LL | | });
+ | |__________^ help: collapse into: `span_lint_and_sugg(cx, TEST_LINT, expr.span, lint_msg, help_msg, sugg.to_string(), Applicability::MachineApplicable)`
+ |
+note: the lint level is defined here
+ --> $DIR/collapsible_span_lint_calls.rs:2:9
+ |
+LL | #![deny(clippy::internal)]
+ | ^^^^^^^^^^^^^^^^
+ = note: `#[deny(clippy::collapsible_span_lint_calls)]` implied by `#[deny(clippy::internal)]`
+
+error: this call is collapsible
+ --> $DIR/collapsible_span_lint_calls.rs:39:9
+ |
+LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+LL | | db.span_help(expr.span, help_msg);
+LL | | });
+ | |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), help_msg)`
+
+error: this call is collapsible
+ --> $DIR/collapsible_span_lint_calls.rs:42:9
+ |
+LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+LL | | db.help(help_msg);
+LL | | });
+ | |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, None, help_msg)`
+
+error: this call is collapsible
+ --> $DIR/collapsible_span_lint_calls.rs:45:9
+ |
+LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+LL | | db.span_note(expr.span, note_msg);
+LL | | });
+ | |__________^ help: collapse into: `span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), note_msg)`
+
+error: this call is collapsible
+ --> $DIR/collapsible_span_lint_calls.rs:48:9
+ |
+LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+LL | | db.note(note_msg);
+LL | | });
+ | |__________^ help: collapse into: `span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, None, note_msg)`
+
+error: aborting due to 5 previous errors
+
diff --git a/src/tools/clippy/tests/ui-internal/custom_ice_message.rs b/src/tools/clippy/tests/ui-internal/custom_ice_message.rs
new file mode 100644
index 000000000..5057a0183
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/custom_ice_message.rs
@@ -0,0 +1,11 @@
+// rustc-env:RUST_BACKTRACE=0
+// normalize-stderr-test: "Clippy version: .*" -> "Clippy version: foo"
+// normalize-stderr-test: "internal_lints.rs:\d*:\d*" -> "internal_lints.rs"
+// normalize-stderr-test: "', .*clippy_lints" -> "', clippy_lints"
+
+#![deny(clippy::internal)]
+#![allow(clippy::missing_clippy_version_attribute)]
+
+fn it_looks_like_you_are_trying_to_kill_clippy() {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
new file mode 100644
index 000000000..a1b8e2ee1
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
@@ -0,0 +1,13 @@
+thread 'rustc' panicked at 'Would you like some help with that?', clippy_lints/src/utils/internal_lints.rs
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+
+error: internal compiler error: unexpected panic
+
+note: the compiler unexpectedly panicked. this is a bug.
+
+note: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new
+
+note: Clippy version: foo
+
+query stack during panic:
+end of query stack
diff --git a/src/tools/clippy/tests/ui-internal/default_deprecation_reason.rs b/src/tools/clippy/tests/ui-internal/default_deprecation_reason.rs
new file mode 100644
index 000000000..c8961d5e1
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/default_deprecation_reason.rs
@@ -0,0 +1,30 @@
+#![deny(clippy::internal)]
+#![feature(rustc_private)]
+
+#[macro_use]
+extern crate clippy_lints;
+use clippy_lints::deprecated_lints::ClippyDeprecatedLint;
+
+declare_deprecated_lint! {
+ /// ### What it does
+ /// Nothing. This lint has been deprecated.
+ ///
+ /// ### Deprecation reason
+ /// TODO
+ #[clippy::version = "1.63.0"]
+ pub COOL_LINT_DEFAULT,
+ "default deprecation note"
+}
+
+declare_deprecated_lint! {
+ /// ### What it does
+ /// Nothing. This lint has been deprecated.
+ ///
+ /// ### Deprecation reason
+ /// This lint has been replaced by `cooler_lint`
+ #[clippy::version = "1.63.0"]
+ pub COOL_LINT,
+ "this lint has been replaced by `cooler_lint`"
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/default_deprecation_reason.stderr b/src/tools/clippy/tests/ui-internal/default_deprecation_reason.stderr
new file mode 100644
index 000000000..ca26b649f
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/default_deprecation_reason.stderr
@@ -0,0 +1,22 @@
+error: the lint `COOL_LINT_DEFAULT` has the default deprecation reason
+ --> $DIR/default_deprecation_reason.rs:8:1
+ |
+LL | / declare_deprecated_lint! {
+LL | | /// ### What it does
+LL | | /// Nothing. This lint has been deprecated.
+LL | | ///
+... |
+LL | | "default deprecation note"
+LL | | }
+ | |_^
+ |
+note: the lint level is defined here
+ --> $DIR/default_deprecation_reason.rs:1:9
+ |
+LL | #![deny(clippy::internal)]
+ | ^^^^^^^^^^^^^^^^
+ = note: `#[deny(clippy::default_deprecation_reason)]` implied by `#[deny(clippy::internal)]`
+ = note: this error originates in the macro `declare_deprecated_lint` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-internal/default_lint.rs b/src/tools/clippy/tests/ui-internal/default_lint.rs
new file mode 100644
index 000000000..da29aedb2
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/default_lint.rs
@@ -0,0 +1,28 @@
+#![deny(clippy::internal)]
+#![allow(clippy::missing_clippy_version_attribute)]
+#![feature(rustc_private)]
+
+#[macro_use]
+extern crate rustc_middle;
+#[macro_use]
+extern crate rustc_session;
+extern crate rustc_lint;
+
+declare_tool_lint! {
+ pub clippy::TEST_LINT,
+ Warn,
+ "",
+ report_in_external_macro: true
+}
+
+declare_tool_lint! {
+ pub clippy::TEST_LINT_DEFAULT,
+ Warn,
+ "default lint description",
+ report_in_external_macro: true
+}
+
+declare_lint_pass!(Pass => [TEST_LINT]);
+declare_lint_pass!(Pass2 => [TEST_LINT_DEFAULT]);
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/default_lint.stderr b/src/tools/clippy/tests/ui-internal/default_lint.stderr
new file mode 100644
index 000000000..8961bd462
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/default_lint.stderr
@@ -0,0 +1,21 @@
+error: the lint `TEST_LINT_DEFAULT` has the default lint description
+ --> $DIR/default_lint.rs:18:1
+ |
+LL | / declare_tool_lint! {
+LL | | pub clippy::TEST_LINT_DEFAULT,
+LL | | Warn,
+LL | | "default lint description",
+LL | | report_in_external_macro: true
+LL | | }
+ | |_^
+ |
+note: the lint level is defined here
+ --> $DIR/default_lint.rs:1:9
+ |
+LL | #![deny(clippy::internal)]
+ | ^^^^^^^^^^^^^^^^
+ = note: `#[deny(clippy::default_lint)]` implied by `#[deny(clippy::internal)]`
+ = note: this error originates in the macro `$crate::declare_tool_lint` which comes from the expansion of the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-internal/if_chain_style.rs b/src/tools/clippy/tests/ui-internal/if_chain_style.rs
new file mode 100644
index 000000000..b0d89e038
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/if_chain_style.rs
@@ -0,0 +1,92 @@
+#![warn(clippy::if_chain_style)]
+#![allow(clippy::no_effect, clippy::nonminimal_bool, clippy::missing_clippy_version_attribute)]
+
+extern crate if_chain;
+
+use if_chain::if_chain;
+
+fn main() {
+ if true {
+ let x = "";
+ // `if_chain!` inside `if`
+ if_chain! {
+ if true;
+ if true;
+ then {}
+ }
+ }
+ if_chain! {
+ if true
+ // multi-line AND'ed conditions
+ && false;
+ if let Some(1) = Some(1);
+ // `let` before `then`
+ let x = "";
+ then {
+ ();
+ }
+ }
+ if_chain! {
+ // single `if` condition
+ if true;
+ then {
+ let x = "";
+ // nested if
+ if true {}
+ }
+ }
+ if_chain! {
+ // starts with `let ..`
+ let x = "";
+ if let Some(1) = Some(1);
+ then {
+ let x = "";
+ let x = "";
+ // nested if_chain!
+ if_chain! {
+ if true;
+ if true;
+ then {}
+ }
+ }
+ }
+}
+
+fn negative() {
+ if true {
+ ();
+ if_chain! {
+ if true;
+ if true;
+ then { (); }
+ }
+ }
+ if_chain! {
+ if true;
+ let x = "";
+ if true;
+ then { (); }
+ }
+ if_chain! {
+ if true;
+ if true;
+ then {
+ if true { 1 } else { 2 }
+ } else {
+ 3
+ }
+ };
+ if true {
+ if_chain! {
+ if true;
+ if true;
+ then {}
+ }
+ } else if false {
+ if_chain! {
+ if true;
+ if false;
+ then {}
+ }
+ }
+}
diff --git a/src/tools/clippy/tests/ui-internal/if_chain_style.stderr b/src/tools/clippy/tests/ui-internal/if_chain_style.stderr
new file mode 100644
index 000000000..24106510e
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/if_chain_style.stderr
@@ -0,0 +1,85 @@
+error: this `if` can be part of the inner `if_chain!`
+ --> $DIR/if_chain_style.rs:9:5
+ |
+LL | / if true {
+LL | | let x = "";
+LL | | // `if_chain!` inside `if`
+LL | | if_chain! {
+... |
+LL | | }
+LL | | }
+ | |_____^
+ |
+ = note: `-D clippy::if-chain-style` implied by `-D warnings`
+help: this `let` statement can also be in the `if_chain!`
+ --> $DIR/if_chain_style.rs:10:9
+ |
+LL | let x = "";
+ | ^^^^^^^^^^^
+
+error: `if a && b;` should be `if a; if b;`
+ --> $DIR/if_chain_style.rs:19:12
+ |
+LL | if true
+ | ____________^
+LL | | // multi-line AND'ed conditions
+LL | | && false;
+ | |____________________^
+
+error: `let` expression should be inside `then { .. }`
+ --> $DIR/if_chain_style.rs:24:9
+ |
+LL | let x = "";
+ | ^^^^^^^^^^^
+
+error: this `if` can be part of the outer `if_chain!`
+ --> $DIR/if_chain_style.rs:35:13
+ |
+LL | if true {}
+ | ^^^^^^^^^^
+ |
+help: this `let` statement can also be in the `if_chain!`
+ --> $DIR/if_chain_style.rs:33:13
+ |
+LL | let x = "";
+ | ^^^^^^^^^^^
+
+error: `if_chain!` only has one `if`
+ --> $DIR/if_chain_style.rs:29:5
+ |
+LL | / if_chain! {
+LL | | // single `if` condition
+LL | | if true;
+LL | | then {
+... |
+LL | | }
+LL | | }
+ | |_____^
+ |
+ = note: this error originates in the macro `__if_chain` which comes from the expansion of the macro `if_chain` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: `let` expression should be above the `if_chain!`
+ --> $DIR/if_chain_style.rs:40:9
+ |
+LL | let x = "";
+ | ^^^^^^^^^^^
+
+error: this `if_chain!` can be merged with the outer `if_chain!`
+ --> $DIR/if_chain_style.rs:46:13
+ |
+LL | / if_chain! {
+LL | | if true;
+LL | | if true;
+LL | | then {}
+LL | | }
+ | |_____________^
+ |
+help: these `let` statements can also be in the `if_chain!`
+ --> $DIR/if_chain_style.rs:43:13
+ |
+LL | / let x = "";
+LL | | let x = "";
+ | |_______________________^
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed
new file mode 100644
index 000000000..eaea218e1
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed
@@ -0,0 +1,37 @@
+// run-rustfix
+#![deny(clippy::internal)]
+#![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)]
+#![feature(rustc_private)]
+
+extern crate rustc_span;
+
+use rustc_span::symbol::Symbol;
+
+macro_rules! sym {
+ ($tt:tt) => {
+ rustc_span::symbol::Symbol::intern(stringify!($tt))
+ };
+}
+
+fn main() {
+ // Direct use of Symbol::intern
+ let _ = rustc_span::sym::f32;
+
+ // Using a sym macro
+ let _ = rustc_span::sym::f32;
+
+ // Correct suggestion when symbol isn't stringified constant name
+ let _ = rustc_span::sym::proc_dash_macro;
+
+ // interning a keyword
+ let _ = rustc_span::symbol::kw::SelfLower;
+
+ // Interning a symbol that is not defined
+ let _ = Symbol::intern("xyz123");
+ let _ = sym!(xyz123);
+
+ // Using a different `intern` function
+ let _ = intern("f32");
+}
+
+fn intern(_: &str) {}
diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs
new file mode 100644
index 000000000..7efebb8fa
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs
@@ -0,0 +1,37 @@
+// run-rustfix
+#![deny(clippy::internal)]
+#![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)]
+#![feature(rustc_private)]
+
+extern crate rustc_span;
+
+use rustc_span::symbol::Symbol;
+
+macro_rules! sym {
+ ($tt:tt) => {
+ rustc_span::symbol::Symbol::intern(stringify!($tt))
+ };
+}
+
+fn main() {
+ // Direct use of Symbol::intern
+ let _ = Symbol::intern("f32");
+
+ // Using a sym macro
+ let _ = sym!(f32);
+
+ // Correct suggestion when symbol isn't stringified constant name
+ let _ = Symbol::intern("proc-macro");
+
+ // interning a keyword
+ let _ = Symbol::intern("self");
+
+ // Interning a symbol that is not defined
+ let _ = Symbol::intern("xyz123");
+ let _ = sym!(xyz123);
+
+ // Using a different `intern` function
+ let _ = intern("f32");
+}
+
+fn intern(_: &str) {}
diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr
new file mode 100644
index 000000000..4e99636e6
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr
@@ -0,0 +1,33 @@
+error: interning a defined symbol
+ --> $DIR/interning_defined_symbol.rs:18:13
+ |
+LL | let _ = Symbol::intern("f32");
+ | ^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::sym::f32`
+ |
+note: the lint level is defined here
+ --> $DIR/interning_defined_symbol.rs:2:9
+ |
+LL | #![deny(clippy::internal)]
+ | ^^^^^^^^^^^^^^^^
+ = note: `#[deny(clippy::interning_defined_symbol)]` implied by `#[deny(clippy::internal)]`
+
+error: interning a defined symbol
+ --> $DIR/interning_defined_symbol.rs:21:13
+ |
+LL | let _ = sym!(f32);
+ | ^^^^^^^^^ help: try: `rustc_span::sym::f32`
+
+error: interning a defined symbol
+ --> $DIR/interning_defined_symbol.rs:24:13
+ |
+LL | let _ = Symbol::intern("proc-macro");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::sym::proc_dash_macro`
+
+error: interning a defined symbol
+ --> $DIR/interning_defined_symbol.rs:27:13
+ |
+LL | let _ = Symbol::intern("self");
+ | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::symbol::kw::SelfLower`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed
new file mode 100644
index 000000000..900a8fffd
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed
@@ -0,0 +1,40 @@
+// run-rustfix
+
+#![deny(clippy::internal)]
+#![allow(clippy::missing_clippy_version_attribute)]
+#![feature(rustc_private)]
+
+extern crate rustc_ast;
+extern crate rustc_hir;
+extern crate rustc_lint;
+extern crate rustc_middle;
+#[macro_use]
+extern crate rustc_session;
+use clippy_utils::extract_msrv_attr;
+use rustc_hir::Expr;
+use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
+use rustc_semver::RustcVersion;
+
+declare_lint! {
+ pub TEST_LINT,
+ Warn,
+ ""
+}
+
+struct Pass {
+ msrv: Option<RustcVersion>,
+}
+
+impl_lint_pass!(Pass => [TEST_LINT]);
+
+impl LateLintPass<'_> for Pass {
+ extract_msrv_attr!(LateContext);
+ fn check_expr(&mut self, _: &LateContext<'_>, _: &Expr<'_>) {}
+}
+
+impl EarlyLintPass for Pass {
+ extract_msrv_attr!(EarlyContext);
+ fn check_expr(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Expr) {}
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs
new file mode 100644
index 000000000..4bc8164db
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs
@@ -0,0 +1,38 @@
+// run-rustfix
+
+#![deny(clippy::internal)]
+#![allow(clippy::missing_clippy_version_attribute)]
+#![feature(rustc_private)]
+
+extern crate rustc_ast;
+extern crate rustc_hir;
+extern crate rustc_lint;
+extern crate rustc_middle;
+#[macro_use]
+extern crate rustc_session;
+use clippy_utils::extract_msrv_attr;
+use rustc_hir::Expr;
+use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
+use rustc_semver::RustcVersion;
+
+declare_lint! {
+ pub TEST_LINT,
+ Warn,
+ ""
+}
+
+struct Pass {
+ msrv: Option<RustcVersion>,
+}
+
+impl_lint_pass!(Pass => [TEST_LINT]);
+
+impl LateLintPass<'_> for Pass {
+ fn check_expr(&mut self, _: &LateContext<'_>, _: &Expr<'_>) {}
+}
+
+impl EarlyLintPass for Pass {
+ fn check_expr(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Expr) {}
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.stderr b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.stderr
new file mode 100644
index 000000000..ddc06f0be
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.stderr
@@ -0,0 +1,32 @@
+error: `extract_msrv_attr!` macro missing from `LateLintPass` implementation
+ --> $DIR/invalid_msrv_attr_impl.rs:30:1
+ |
+LL | impl LateLintPass<'_> for Pass {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/invalid_msrv_attr_impl.rs:3:9
+ |
+LL | #![deny(clippy::internal)]
+ | ^^^^^^^^^^^^^^^^
+ = note: `#[deny(clippy::missing_msrv_attr_impl)]` implied by `#[deny(clippy::internal)]`
+help: add `extract_msrv_attr!(LateContext)` to the `LateLintPass` implementation
+ |
+LL + impl LateLintPass<'_> for Pass {
+LL + extract_msrv_attr!(LateContext);
+ |
+
+error: `extract_msrv_attr!` macro missing from `EarlyLintPass` implementation
+ --> $DIR/invalid_msrv_attr_impl.rs:34:1
+ |
+LL | impl EarlyLintPass for Pass {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: add `extract_msrv_attr!(EarlyContext)` to the `EarlyLintPass` implementation
+ |
+LL + impl EarlyLintPass for Pass {
+LL + extract_msrv_attr!(EarlyContext);
+ |
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui-internal/invalid_paths.rs b/src/tools/clippy/tests/ui-internal/invalid_paths.rs
new file mode 100644
index 000000000..b823ff7fe
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/invalid_paths.rs
@@ -0,0 +1,27 @@
+#![warn(clippy::internal)]
+#![allow(clippy::missing_clippy_version_attribute)]
+
+mod paths {
+ // Good path
+ pub const ANY_TRAIT: [&str; 3] = ["std", "any", "Any"];
+
+ // Path to method on inherent impl of a primitive type
+ pub const F32_EPSILON: [&str; 4] = ["core", "f32", "<impl f32>", "EPSILON"];
+
+ // Path to method on inherent impl
+ pub const ARC_PTR_EQ: [&str; 4] = ["alloc", "sync", "Arc", "ptr_eq"];
+
+ // Path with empty segment
+ pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"];
+
+ // Path with bad crate
+ pub const BAD_CRATE_PATH: [&str; 2] = ["bad", "path"];
+
+ // Path with bad module
+ pub const BAD_MOD_PATH: [&str; 2] = ["std", "xxx"];
+
+ // Path to method on an enum inherent impl
+ pub const OPTION_IS_SOME: [&str; 4] = ["core", "option", "Option", "is_some"];
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/invalid_paths.stderr b/src/tools/clippy/tests/ui-internal/invalid_paths.stderr
new file mode 100644
index 000000000..0e8508869
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/invalid_paths.stderr
@@ -0,0 +1,22 @@
+error: invalid path
+ --> $DIR/invalid_paths.rs:15:5
+ |
+LL | pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `-D clippy::invalid-paths` implied by `-D warnings`
+
+error: invalid path
+ --> $DIR/invalid_paths.rs:18:5
+ |
+LL | pub const BAD_CRATE_PATH: [&str; 2] = ["bad", "path"];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: invalid path
+ --> $DIR/invalid_paths.rs:21:5
+ |
+LL | pub const BAD_MOD_PATH: [&str; 2] = ["std", "xxx"];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.rs b/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.rs
new file mode 100644
index 000000000..1fd03cfe3
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.rs
@@ -0,0 +1,45 @@
+#![deny(clippy::internal)]
+#![allow(clippy::missing_clippy_version_attribute)]
+#![feature(rustc_private)]
+
+#[macro_use]
+extern crate rustc_middle;
+#[macro_use]
+extern crate rustc_session;
+extern crate rustc_lint;
+use rustc_lint::LintPass;
+
+declare_tool_lint! {
+ pub clippy::TEST_LINT,
+ Warn,
+ "",
+ report_in_external_macro: true
+}
+
+declare_tool_lint! {
+ pub clippy::TEST_LINT_REGISTERED,
+ Warn,
+ "",
+ report_in_external_macro: true
+}
+
+declare_tool_lint! {
+ pub clippy::TEST_LINT_REGISTERED_ONLY_IMPL,
+ Warn,
+ "",
+ report_in_external_macro: true
+}
+
+pub struct Pass;
+impl LintPass for Pass {
+ fn name(&self) -> &'static str {
+ "TEST_LINT"
+ }
+}
+
+declare_lint_pass!(Pass2 => [TEST_LINT_REGISTERED]);
+
+pub struct Pass3;
+impl_lint_pass!(Pass3 => [TEST_LINT_REGISTERED_ONLY_IMPL]);
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.stderr b/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.stderr
new file mode 100644
index 000000000..de04920b8
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.stderr
@@ -0,0 +1,21 @@
+error: the lint `TEST_LINT` is not added to any `LintPass`
+ --> $DIR/lint_without_lint_pass.rs:12:1
+ |
+LL | / declare_tool_lint! {
+LL | | pub clippy::TEST_LINT,
+LL | | Warn,
+LL | | "",
+LL | | report_in_external_macro: true
+LL | | }
+ | |_^
+ |
+note: the lint level is defined here
+ --> $DIR/lint_without_lint_pass.rs:1:9
+ |
+LL | #![deny(clippy::internal)]
+ | ^^^^^^^^^^^^^^^^
+ = note: `#[deny(clippy::lint_without_lint_pass)]` implied by `#[deny(clippy::internal)]`
+ = note: this error originates in the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-internal/match_type_on_diag_item.rs b/src/tools/clippy/tests/ui-internal/match_type_on_diag_item.rs
new file mode 100644
index 000000000..4b41ff15e
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/match_type_on_diag_item.rs
@@ -0,0 +1,39 @@
+#![deny(clippy::internal)]
+#![allow(clippy::missing_clippy_version_attribute)]
+#![feature(rustc_private)]
+
+extern crate clippy_utils;
+extern crate rustc_hir;
+extern crate rustc_lint;
+extern crate rustc_middle;
+
+#[macro_use]
+extern crate rustc_session;
+use clippy_utils::{paths, ty::match_type};
+use rustc_hir::Expr;
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::Ty;
+
+declare_lint! {
+ pub TEST_LINT,
+ Warn,
+ ""
+}
+
+declare_lint_pass!(Pass => [TEST_LINT]);
+
+static OPTION: [&str; 3] = ["core", "option", "Option"];
+
+impl<'tcx> LateLintPass<'tcx> for Pass {
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr) {
+ let ty = cx.typeck_results().expr_ty(expr);
+
+ let _ = match_type(cx, ty, &OPTION);
+ let _ = match_type(cx, ty, &["core", "result", "Result"]);
+
+ let rc_path = &["alloc", "rc", "Rc"];
+ let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
+ }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/match_type_on_diag_item.stderr b/src/tools/clippy/tests/ui-internal/match_type_on_diag_item.stderr
new file mode 100644
index 000000000..e3cb6b6c2
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/match_type_on_diag_item.stderr
@@ -0,0 +1,27 @@
+error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
+ --> $DIR/match_type_on_diag_item.rs:31:17
+ |
+LL | let _ = match_type(cx, ty, &OPTION);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::Option)`
+ |
+note: the lint level is defined here
+ --> $DIR/match_type_on_diag_item.rs:1:9
+ |
+LL | #![deny(clippy::internal)]
+ | ^^^^^^^^^^^^^^^^
+ = note: `#[deny(clippy::match_type_on_diagnostic_item)]` implied by `#[deny(clippy::internal)]`
+
+error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
+ --> $DIR/match_type_on_diag_item.rs:32:17
+ |
+LL | let _ = match_type(cx, ty, &["core", "result", "Result"]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::Result)`
+
+error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
+ --> $DIR/match_type_on_diag_item.rs:35:17
+ |
+LL | let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::Rc)`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui-internal/outer_expn_data.fixed b/src/tools/clippy/tests/ui-internal/outer_expn_data.fixed
new file mode 100644
index 000000000..bb82faf0c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/outer_expn_data.fixed
@@ -0,0 +1,29 @@
+// run-rustfix
+
+#![deny(clippy::internal)]
+#![allow(clippy::missing_clippy_version_attribute)]
+#![feature(rustc_private)]
+
+extern crate rustc_hir;
+extern crate rustc_lint;
+extern crate rustc_middle;
+#[macro_use]
+extern crate rustc_session;
+use rustc_hir::Expr;
+use rustc_lint::{LateContext, LateLintPass};
+
+declare_lint! {
+ pub TEST_LINT,
+ Warn,
+ ""
+}
+
+declare_lint_pass!(Pass => [TEST_LINT]);
+
+impl<'tcx> LateLintPass<'tcx> for Pass {
+ fn check_expr(&mut self, _cx: &LateContext<'tcx>, expr: &'tcx Expr) {
+ let _ = expr.span.ctxt().outer_expn_data();
+ }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/outer_expn_data.rs b/src/tools/clippy/tests/ui-internal/outer_expn_data.rs
new file mode 100644
index 000000000..187d468b3
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/outer_expn_data.rs
@@ -0,0 +1,29 @@
+// run-rustfix
+
+#![deny(clippy::internal)]
+#![allow(clippy::missing_clippy_version_attribute)]
+#![feature(rustc_private)]
+
+extern crate rustc_hir;
+extern crate rustc_lint;
+extern crate rustc_middle;
+#[macro_use]
+extern crate rustc_session;
+use rustc_hir::Expr;
+use rustc_lint::{LateContext, LateLintPass};
+
+declare_lint! {
+ pub TEST_LINT,
+ Warn,
+ ""
+}
+
+declare_lint_pass!(Pass => [TEST_LINT]);
+
+impl<'tcx> LateLintPass<'tcx> for Pass {
+ fn check_expr(&mut self, _cx: &LateContext<'tcx>, expr: &'tcx Expr) {
+ let _ = expr.span.ctxt().outer_expn().expn_data();
+ }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/outer_expn_data.stderr b/src/tools/clippy/tests/ui-internal/outer_expn_data.stderr
new file mode 100644
index 000000000..afef69678
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/outer_expn_data.stderr
@@ -0,0 +1,15 @@
+error: usage of `outer_expn().expn_data()`
+ --> $DIR/outer_expn_data.rs:25:34
+ |
+LL | let _ = expr.span.ctxt().outer_expn().expn_data();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `outer_expn_data()`
+ |
+note: the lint level is defined here
+ --> $DIR/outer_expn_data.rs:3:9
+ |
+LL | #![deny(clippy::internal)]
+ | ^^^^^^^^^^^^^^^^
+ = note: `#[deny(clippy::outer_expn_expn_data)]` implied by `#[deny(clippy::internal)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed
new file mode 100644
index 000000000..6033d06e4
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed
@@ -0,0 +1,21 @@
+// run-rustfix
+#![feature(rustc_private)]
+#![deny(clippy::internal)]
+#![allow(
+ clippy::borrow_deref_ref,
+ clippy::unnecessary_operation,
+ unused_must_use,
+ clippy::missing_clippy_version_attribute
+)]
+
+extern crate rustc_span;
+
+use rustc_span::symbol::{Ident, Symbol};
+
+fn main() {
+ Symbol::intern("foo") == rustc_span::sym::clippy;
+ Symbol::intern("foo") == rustc_span::symbol::kw::SelfLower;
+ Symbol::intern("foo") != rustc_span::symbol::kw::SelfUpper;
+ Ident::empty().name == rustc_span::sym::clippy;
+ rustc_span::sym::clippy == Ident::empty().name;
+}
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs
new file mode 100644
index 000000000..1bb5d55f0
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs
@@ -0,0 +1,21 @@
+// run-rustfix
+#![feature(rustc_private)]
+#![deny(clippy::internal)]
+#![allow(
+ clippy::borrow_deref_ref,
+ clippy::unnecessary_operation,
+ unused_must_use,
+ clippy::missing_clippy_version_attribute
+)]
+
+extern crate rustc_span;
+
+use rustc_span::symbol::{Ident, Symbol};
+
+fn main() {
+ Symbol::intern("foo").as_str() == "clippy";
+ Symbol::intern("foo").to_string() == "self";
+ Symbol::intern("foo").to_ident_string() != "Self";
+ &*Ident::empty().as_str() == "clippy";
+ "clippy" == Ident::empty().to_string();
+}
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr
new file mode 100644
index 000000000..a1f507f33
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr
@@ -0,0 +1,39 @@
+error: unnecessary `Symbol` to string conversion
+ --> $DIR/unnecessary_symbol_str.rs:16:5
+ |
+LL | Symbol::intern("foo").as_str() == "clippy";
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") == rustc_span::sym::clippy`
+ |
+note: the lint level is defined here
+ --> $DIR/unnecessary_symbol_str.rs:3:9
+ |
+LL | #![deny(clippy::internal)]
+ | ^^^^^^^^^^^^^^^^
+ = note: `#[deny(clippy::unnecessary_symbol_str)]` implied by `#[deny(clippy::internal)]`
+
+error: unnecessary `Symbol` to string conversion
+ --> $DIR/unnecessary_symbol_str.rs:17:5
+ |
+LL | Symbol::intern("foo").to_string() == "self";
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") == rustc_span::symbol::kw::SelfLower`
+
+error: unnecessary `Symbol` to string conversion
+ --> $DIR/unnecessary_symbol_str.rs:18:5
+ |
+LL | Symbol::intern("foo").to_ident_string() != "Self";
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") != rustc_span::symbol::kw::SelfUpper`
+
+error: unnecessary `Symbol` to string conversion
+ --> $DIR/unnecessary_symbol_str.rs:19:5
+ |
+LL | &*Ident::empty().as_str() == "clippy";
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Ident::empty().name == rustc_span::sym::clippy`
+
+error: unnecessary `Symbol` to string conversion
+ --> $DIR/unnecessary_symbol_str.rs:20:5
+ |
+LL | "clippy" == Ident::empty().to_string();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::sym::clippy == Ident::empty().name`
+
+error: aborting due to 5 previous errors
+