diff --git a/CHANGELOG.md b/CHANGELOG.md index 7acf9bc1eaa8..14c1b0e4d3f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -616,6 +616,7 @@ All notable changes to this project will be documented in this file. [`absurd_extreme_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#absurd_extreme_comparisons [`almost_swapped`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_swapped [`approx_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant +[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants [`assign_op_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_op_pattern [`assign_ops`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_ops [`bad_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#bad_bit_mask diff --git a/README.md b/README.md index 24a57450b856..6473b8efc548 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are 291 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) +[There are 292 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you: diff --git a/clippy_lints/src/arithmetic.rs b/clippy_lints/src/arithmetic.rs index 473db1869ac0..efa53ff94c39 100644 --- a/clippy_lints/src/arithmetic.rs +++ b/clippy_lints/src/arithmetic.rs @@ -128,7 +128,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic { } self.const_span = Some(body_span); }, - hir::BodyOwnerKind::Fn => (), + hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure => (), } } diff --git a/clippy_lints/src/assertions_on_constants.rs b/clippy_lints/src/assertions_on_constants.rs new file mode 100644 index 000000000000..f88ef8e83edb --- /dev/null +++ b/clippy_lints/src/assertions_on_constants.rs @@ -0,0 +1,87 @@ +// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use crate::consts::{constant, Constant}; +use crate::rustc::hir::{Expr, ExprKind}; +use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use crate::rustc::{declare_tool_lint, lint_array}; +use crate::syntax::ast::LitKind; +use crate::utils::{is_direct_expn_of, span_help_and_lint}; +use if_chain::if_chain; + +/// **What it does:** Check to call assert!(true/false) +/// +/// **Why is this bad?** Will be optimized out by the compiler or should probably be replaced by a +/// panic!() or unreachable!() +/// +/// **Known problems:** None +/// +/// **Example:** +/// ```rust +/// assert!(false) +/// // or +/// assert!(true) +/// // or +/// const B: bool = false; +/// assert!(B) +/// ``` +declare_clippy_lint! { + pub ASSERTIONS_ON_CONSTANTS, + style, + "assert!(true/false) will be optimized out by the compiler/should probably be replaced by a panic!() or unreachable!()" +} + +pub struct AssertionsOnConstants; + +impl LintPass for AssertionsOnConstants { + fn get_lints(&self) -> LintArray { + lint_array![ASSERTIONS_ON_CONSTANTS] + } +} + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssertionsOnConstants { + fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { + if_chain! { + if is_direct_expn_of(e.span, "assert").is_some(); + if let ExprKind::Unary(_, ref lit) = e.node; + then { + if let ExprKind::Lit(ref inner) = lit.node { + match inner.node { + LitKind::Bool(true) => { + span_help_and_lint(cx, ASSERTIONS_ON_CONSTANTS, e.span, + "assert!(true) will be optimized out by the compiler", + "remove it"); + }, + LitKind::Bool(false) => { + span_help_and_lint( + cx, ASSERTIONS_ON_CONSTANTS, e.span, + "assert!(false) should probably be replaced", + "use panic!() or unreachable!()"); + }, + _ => (), + } + } else if let Some(bool_const) = constant(cx, cx.tables, lit) { + match bool_const.0 { + Constant::Bool(true) => { + span_help_and_lint(cx, ASSERTIONS_ON_CONSTANTS, e.span, + "assert!(const: true) will be optimized out by the compiler", + "remove it"); + }, + Constant::Bool(false) => { + span_help_and_lint(cx, ASSERTIONS_ON_CONSTANTS, e.span, + "assert!(const: false) should probably be replaced", + "use panic!() or unreachable!()"); + }, + _ => (), + } + } + } + } + } +} diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 608094c833d7..9d77c3c64a2a 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -78,6 +78,7 @@ mod utils; // begin lints modules, do not remove this comment, it’s used in `update_lints` pub mod approx_const; pub mod arithmetic; +pub mod assertions_on_constants; pub mod assign_ops; pub mod attrs; pub mod bit_mask; @@ -477,6 +478,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { reg.register_late_lint_pass(box redundant_clone::RedundantClone); reg.register_late_lint_pass(box slow_vector_initialization::Pass); reg.register_late_lint_pass(box types::RefToMut); + reg.register_late_lint_pass(box assertions_on_constants::AssertionsOnConstants); reg.register_lint_group("clippy::restriction", Some("clippy_restriction"), vec![ arithmetic::FLOAT_ARITHMETIC, @@ -554,6 +556,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { reg.register_lint_group("clippy::all", Some("clippy"), vec![ approx_const::APPROX_CONSTANT, + assertions_on_constants::ASSERTIONS_ON_CONSTANTS, assign_ops::ASSIGN_OP_PATTERN, assign_ops::MISREFACTORED_ASSIGN_OP, attrs::DEPRECATED_CFG_ATTR, @@ -776,6 +779,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { ]); reg.register_lint_group("clippy::style", Some("clippy_style"), vec![ + assertions_on_constants::ASSERTIONS_ON_CONSTANTS, assign_ops::ASSIGN_OP_PATTERN, attrs::UNKNOWN_CLIPPY_LINTS, bit_mask::VERBOSE_BIT_MASK, diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index a898a740cd81..3b1fea465f51 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -70,16 +70,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool { let reduce = |ret, not| { let mut applicability = Applicability::MachineApplicable; let snip = Sugg::hir_with_applicability(cx, pred, "", &mut applicability); - let snip = if not { !snip } else { snip }; + let mut snip = if not { !snip } else { snip }; - let mut hint = if ret { - format!("return {}", snip) - } else { - snip.to_string() - }; + if ret { + snip = snip.make_return(); + } if parent_node_is_if_expr(&e, &cx) { - hint = format!("{{ {} }}", hint); + snip = snip.blockify() } span_lint_and_sugg( @@ -88,7 +86,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool { e.span, "this if-then-else expression returns a bool literal", "you can reduce it to", - hint, + snip.to_string(), applicability, ); }; diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index b72401e1cca7..88cf01987b55 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -56,10 +56,15 @@ impl LintPass for UseSelf { const SEGMENTS_MSG: &str = "segments should be composed of at least 1 element"; fn span_use_self_lint(cx: &LateContext<'_, '_>, path: &Path) { + // path segments only include actual path, no methods or fields + let last_path_span = path.segments.last().expect(SEGMENTS_MSG).ident.span; + // only take path up to the end of last_path_span + let span = path.span.with_hi(last_path_span.hi()); + span_lint_and_sugg( cx, USE_SELF, - path.span, + span, "unnecessary structure name repetition", "use the applicable keyword", "Self".to_owned(), diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 5d94f0f3f051..c83b0f155fca 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -64,9 +64,25 @@ pub fn differing_macro_contexts(lhs: Span, rhs: Span) -> bool { /// ``` pub fn in_constant(cx: &LateContext<'_, '_>, id: NodeId) -> bool { let parent_id = cx.tcx.hir().get_parent(id); - match cx.tcx.hir().body_owner_kind(parent_id) { - hir::BodyOwnerKind::Fn => false, - hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(..) => true, + match cx.tcx.hir().get(parent_id) { + Node::Item(&Item { + node: ItemKind::Const(..), + .. + }) + | Node::TraitItem(&TraitItem { + node: TraitItemKind::Const(..), + .. + }) + | Node::ImplItem(&ImplItem { + node: ImplItemKind::Const(..), + .. + }) + | Node::AnonConst(_) + | Node::Item(&Item { + node: ItemKind::Static(..), + .. + }) => true, + _ => false, } } diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs index d42af5fde3ae..b95ce17ed93d 100644 --- a/clippy_lints/src/utils/sugg.rs +++ b/clippy_lints/src/utils/sugg.rs @@ -206,6 +206,17 @@ impl<'a> Sugg<'a> { make_unop("&mut *", self) } + /// Convenience method to transform suggestion into a return call + pub fn make_return(self) -> Sugg<'static> { + Sugg::NonParen(Cow::Owned(format!("return {}", self))) + } + + /// Convenience method to transform suggestion into a block + /// where the suggestion is a trailing expression + pub fn blockify(self) -> Sugg<'static> { + Sugg::NonParen(Cow::Owned(format!("{{ {} }}", self))) + } + /// Convenience method to create the `..` or `...` /// suggestion. #[allow(dead_code)] @@ -578,3 +589,21 @@ impl<'a, 'b, 'c, T: LintContext<'c>> DiagnosticBuilderExt<'c, T> for rustc_error self.span_suggestion_with_applicability(remove_span, msg, String::new(), applicability); } } + +#[cfg(test)] +mod test { + use super::Sugg; + use std::borrow::Cow; + + const SUGGESTION: Sugg<'static> = Sugg::NonParen(Cow::Borrowed("function_call()")); + + #[test] + fn make_return_transform_sugg_into_a_return_call() { + assert_eq!("return function_call()", SUGGESTION.make_return().to_string()); + } + + #[test] + fn blockify_transforms_sugg_into_a_block() { + assert_eq!("{ function_call() }", SUGGESTION.blockify().to_string()); + } +} diff --git a/tests/ui/assertions_on_constants.rs b/tests/ui/assertions_on_constants.rs new file mode 100644 index 000000000000..dcefe83f8c2f --- /dev/null +++ b/tests/ui/assertions_on_constants.rs @@ -0,0 +1,21 @@ +// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + assert!(true); + assert!(false); + assert!(true, "true message"); + assert!(false, "false message"); + + const B: bool = true; + assert!(B); + + const C: bool = false; + assert!(C); +} diff --git a/tests/ui/assertions_on_constants.stderr b/tests/ui/assertions_on_constants.stderr new file mode 100644 index 000000000000..1f1a80e0e77b --- /dev/null +++ b/tests/ui/assertions_on_constants.stderr @@ -0,0 +1,51 @@ +error: assert!(true) will be optimized out by the compiler + --> $DIR/assertions_on_constants.rs:11:5 + | +LL | assert!(true); + | ^^^^^^^^^^^^^^ + | + = note: `-D clippy::assertions-on-constants` implied by `-D warnings` + = help: remove it + +error: assert!(false) should probably be replaced + --> $DIR/assertions_on_constants.rs:12:5 + | +LL | assert!(false); + | ^^^^^^^^^^^^^^^ + | + = help: use panic!() or unreachable!() + +error: assert!(true) will be optimized out by the compiler + --> $DIR/assertions_on_constants.rs:13:5 + | +LL | assert!(true, "true message"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: remove it + +error: assert!(false) should probably be replaced + --> $DIR/assertions_on_constants.rs:14:5 + | +LL | assert!(false, "false message"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use panic!() or unreachable!() + +error: assert!(const: true) will be optimized out by the compiler + --> $DIR/assertions_on_constants.rs:17:5 + | +LL | assert!(B); + | ^^^^^^^^^^^ + | + = help: remove it + +error: assert!(const: false) should probably be replaced + --> $DIR/assertions_on_constants.rs:20:5 + | +LL | assert!(C); + | ^^^^^^^^^^^ + | + = help: use panic!() or unreachable!() + +error: aborting due to 6 previous errors + diff --git a/tests/ui/attrs.rs b/tests/ui/attrs.rs index 4dbb5c67f5d1..df7eafc65518 100644 --- a/tests/ui/attrs.rs +++ b/tests/ui/attrs.rs @@ -1,5 +1,5 @@ #![warn(clippy::inline_always, clippy::deprecated_semver)] - +#![allow(clippy::assertions_on_constants::assertions_on_constants)] #[inline(always)] fn test_attr_lint() { assert!(true) diff --git a/tests/ui/empty_line_after_outer_attribute.rs b/tests/ui/empty_line_after_outer_attribute.rs index 1e067a542326..3af8e3eeac08 100644 --- a/tests/ui/empty_line_after_outer_attribute.rs +++ b/tests/ui/empty_line_after_outer_attribute.rs @@ -1,5 +1,5 @@ #![warn(clippy::empty_line_after_outer_attr)] - +#![allow(clippy::assertions_on_constants::assertions_on_constants)] // This should produce a warning #[crate_type = "lib"] diff --git a/tests/ui/panic_unimplemented.rs b/tests/ui/panic_unimplemented.rs index f205e07cd30d..a7c5b91fdb56 100644 --- a/tests/ui/panic_unimplemented.rs +++ b/tests/ui/panic_unimplemented.rs @@ -1,5 +1,5 @@ #![warn(clippy::panic_params, clippy::unimplemented)] - +#![allow(clippy::assertions_on_constants::assertions_on_constants)] fn missing() { if true { panic!("{}"); diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed new file mode 100644 index 000000000000..5eae9a7a8069 --- /dev/null +++ b/tests/ui/use_self.fixed @@ -0,0 +1,299 @@ +// run-rustfix + +#![warn(clippy::use_self)] +#![allow(dead_code)] +#![allow(clippy::should_implement_trait)] + +fn main() {} + +mod use_self { + struct Foo {} + + impl Foo { + fn new() -> Self { + Self {} + } + fn test() -> Self { + Self::new() + } + } + + impl Default for Foo { + fn default() -> Self { + Self::new() + } + } +} + +mod better { + struct Foo {} + + impl Foo { + fn new() -> Self { + Self {} + } + fn test() -> Self { + Self::new() + } + } + + impl Default for Foo { + fn default() -> Self { + Self::new() + } + } +} + +mod lifetimes { + struct Foo<'a> { + foo_str: &'a str, + } + + impl<'a> Foo<'a> { + // Cannot use `Self` as return type, because the function is actually `fn foo<'b>(s: &'b str) -> + // Foo<'b>` + fn foo(s: &str) -> Foo { + Foo { foo_str: s } + } + // cannot replace with `Self`, because that's `Foo<'a>` + fn bar() -> Foo<'static> { + Foo { foo_str: "foo" } + } + + // FIXME: the lint does not handle lifetimed struct + // `Self` should be applicable here + fn clone(&self) -> Foo<'a> { + Foo { foo_str: self.foo_str } + } + } +} + +#[allow(clippy::boxed_local)] +mod traits { + + use std::ops::Mul; + + trait SelfTrait { + fn refs(p1: &Self) -> &Self; + fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self; + fn mut_refs(p1: &mut Self) -> &mut Self; + fn nested(p1: Box, p2: (&u8, &Self)); + fn vals(r: Self) -> Self; + } + + #[derive(Default)] + struct Bad; + + impl SelfTrait for Bad { + fn refs(p1: &Self) -> &Self { + p1 + } + + fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self { + p1 + } + + fn mut_refs(p1: &mut Self) -> &mut Self { + p1 + } + + fn nested(_p1: Box, _p2: (&u8, &Self)) {} + + fn vals(_: Self) -> Self { + Self::default() + } + } + + impl Mul for Bad { + type Output = Self; + + fn mul(self, rhs: Self) -> Self { + rhs + } + } + + #[derive(Default)] + struct Good; + + impl SelfTrait for Good { + fn refs(p1: &Self) -> &Self { + p1 + } + + fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self { + p1 + } + + fn mut_refs(p1: &mut Self) -> &mut Self { + p1 + } + + fn nested(_p1: Box, _p2: (&u8, &Self)) {} + + fn vals(_: Self) -> Self { + Self::default() + } + } + + impl Mul for Good { + type Output = Self; + + fn mul(self, rhs: Self) -> Self { + rhs + } + } + + trait NameTrait { + fn refs(p1: &u8) -> &u8; + fn ref_refs<'a>(p1: &'a &'a u8) -> &'a &'a u8; + fn mut_refs(p1: &mut u8) -> &mut u8; + fn nested(p1: Box, p2: (&u8, &u8)); + fn vals(p1: u8) -> u8; + } + + // Using `Self` instead of the type name is OK + impl NameTrait for u8 { + fn refs(p1: &Self) -> &Self { + p1 + } + + fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self { + p1 + } + + fn mut_refs(p1: &mut Self) -> &mut Self { + p1 + } + + fn nested(_p1: Box, _p2: (&Self, &Self)) {} + + fn vals(_: Self) -> Self { + Self::default() + } + } + + // Check that self arg isn't linted + impl Clone for Good { + fn clone(&self) -> Self { + // Note: Not linted and it wouldn't be valid + // because "can't use `Self` as a constructor`" + Good + } + } +} + +mod issue2894 { + trait IntoBytes { + fn into_bytes(&self) -> Vec; + } + + // This should not be linted + impl IntoBytes for u8 { + fn into_bytes(&self) -> Vec { + vec![*self] + } + } +} + +mod existential { + struct Foo; + + impl Foo { + fn bad(foos: &[Self]) -> impl Iterator { + foos.iter() + } + + fn good(foos: &[Self]) -> impl Iterator { + foos.iter() + } + } +} + +mod tuple_structs { + pub struct TS(i32); + + impl TS { + pub fn ts() -> Self { + Self(0) + } + } +} + +mod macros { + macro_rules! use_self_expand { + () => { + fn new() -> Self { + Self {} + } + }; + } + + struct Foo {} + + impl Foo { + use_self_expand!(); // Should lint in local macros + } +} + +mod nesting { + struct Foo {} + impl Foo { + fn foo() { + use self::Foo; // Can't use Self here + struct Bar { + foo: Foo, // Foo != Self + } + + impl Bar { + fn bar() -> Self { + Self { foo: Foo {} } + } + } + } + } + + enum Enum { + A, + } + impl Enum { + fn method() { + #[allow(unused_imports)] + use self::Enum::*; // Issue 3425 + static STATIC: Enum = Enum::A; // Can't use Self as type + } + } +} + +mod issue3410 { + + struct A; + struct B; + + trait Trait { + fn a(v: T); + } + + impl Trait> for Vec { + fn a(_: Vec) {} + } +} + +#[allow(clippy::no_effect, path_statements)] +mod rustfix { + mod nested { + pub struct A {} + } + + impl nested::A { + const A: bool = true; + + fn fun_1() {} + + fn fun_2() { + Self::fun_1(); + Self::A; + + Self {}; + } + } +} diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index b839aead95a0..8e28bbbeb9c6 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -1,3 +1,5 @@ +// run-rustfix + #![warn(clippy::use_self)] #![allow(dead_code)] #![allow(clippy::should_implement_trait)] @@ -255,6 +257,7 @@ mod nesting { } impl Enum { fn method() { + #[allow(unused_imports)] use self::Enum::*; // Issue 3425 static STATIC: Enum = Enum::A; // Can't use Self as type } @@ -274,3 +277,23 @@ mod issue3410 { fn a(_: Vec) {} } } + +#[allow(clippy::no_effect, path_statements)] +mod rustfix { + mod nested { + pub struct A {} + } + + impl nested::A { + const A: bool = true; + + fn fun_1() {} + + fn fun_2() { + nested::A::fun_1(); + nested::A::A; + + nested::A {}; + } + } +} diff --git a/tests/ui/use_self.stderr b/tests/ui/use_self.stderr index 9d23433ba645..af9e15edb6cf 100644 --- a/tests/ui/use_self.stderr +++ b/tests/ui/use_self.stderr @@ -1,5 +1,5 @@ error: unnecessary structure name repetition - --> $DIR/use_self.rs:11:21 + --> $DIR/use_self.rs:13:21 | LL | fn new() -> Foo { | ^^^ help: use the applicable keyword: `Self` @@ -7,133 +7,133 @@ LL | fn new() -> Foo { = note: `-D clippy::use-self` implied by `-D warnings` error: unnecessary structure name repetition - --> $DIR/use_self.rs:12:13 + --> $DIR/use_self.rs:14:13 | LL | Foo {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:14:22 + --> $DIR/use_self.rs:16:22 | LL | fn test() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:15:13 + --> $DIR/use_self.rs:17:13 | LL | Foo::new() - | ^^^^^^^^ help: use the applicable keyword: `Self` + | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:20:25 + --> $DIR/use_self.rs:22:25 | LL | fn default() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:21:13 + --> $DIR/use_self.rs:23:13 | LL | Foo::new() - | ^^^^^^^^ help: use the applicable keyword: `Self` + | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:86:22 + --> $DIR/use_self.rs:88:22 | LL | fn refs(p1: &Bad) -> &Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:86:31 + --> $DIR/use_self.rs:88:31 | LL | fn refs(p1: &Bad) -> &Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:90:37 + --> $DIR/use_self.rs:92:37 | LL | fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:90:53 + --> $DIR/use_self.rs:92:53 | LL | fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:94:30 + --> $DIR/use_self.rs:96:30 | LL | fn mut_refs(p1: &mut Bad) -> &mut Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:94:43 + --> $DIR/use_self.rs:96:43 | LL | fn mut_refs(p1: &mut Bad) -> &mut Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:98:28 + --> $DIR/use_self.rs:100:28 | LL | fn nested(_p1: Box, _p2: (&u8, &Bad)) {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:98:46 + --> $DIR/use_self.rs:100:46 | LL | fn nested(_p1: Box, _p2: (&u8, &Bad)) {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:100:20 + --> $DIR/use_self.rs:102:20 | LL | fn vals(_: Bad) -> Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:100:28 + --> $DIR/use_self.rs:102:28 | LL | fn vals(_: Bad) -> Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:101:13 + --> $DIR/use_self.rs:103:13 | LL | Bad::default() - | ^^^^^^^^^^^^ help: use the applicable keyword: `Self` + | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:106:23 + --> $DIR/use_self.rs:108:23 | LL | type Output = Bad; | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:108:27 + --> $DIR/use_self.rs:110:27 | LL | fn mul(self, rhs: Bad) -> Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:108:35 + --> $DIR/use_self.rs:110:35 | LL | fn mul(self, rhs: Bad) -> Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:200:56 + --> $DIR/use_self.rs:202:56 | LL | fn bad(foos: &[Self]) -> impl Iterator { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:215:13 + --> $DIR/use_self.rs:217:13 | LL | TS(0) | ^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:223:25 + --> $DIR/use_self.rs:225:25 | LL | fn new() -> Foo { | ^^^ help: use the applicable keyword: `Self` @@ -142,7 +142,7 @@ LL | use_self_expand!(); // Should lint in local macros | ------------------- in this macro invocation error: unnecessary structure name repetition - --> $DIR/use_self.rs:224:17 + --> $DIR/use_self.rs:226:17 | LL | Foo {} | ^^^ help: use the applicable keyword: `Self` @@ -151,16 +151,34 @@ LL | use_self_expand!(); // Should lint in local macros | ------------------- in this macro invocation error: unnecessary structure name repetition - --> $DIR/use_self.rs:246:29 + --> $DIR/use_self.rs:248:29 | LL | fn bar() -> Bar { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:247:21 + --> $DIR/use_self.rs:249:21 | LL | Bar { foo: Foo {} } | ^^^ help: use the applicable keyword: `Self` -error: aborting due to 26 previous errors +error: unnecessary structure name repetition + --> $DIR/use_self.rs:293:13 + | +LL | nested::A::fun_1(); + | ^^^^^^^^^ help: use the applicable keyword: `Self` + +error: unnecessary structure name repetition + --> $DIR/use_self.rs:294:13 + | +LL | nested::A::A; + | ^^^^^^^^^ help: use the applicable keyword: `Self` + +error: unnecessary structure name repetition + --> $DIR/use_self.rs:296:13 + | +LL | nested::A {}; + | ^^^^^^^^^ help: use the applicable keyword: `Self` + +error: aborting due to 29 previous errors