Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 4 additions & 29 deletions clippy_lints/src/methods/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ mod needless_character_iteration;
mod needless_collect;
mod needless_option_as_deref;
mod needless_option_take;
mod new_ret_no_self;
mod no_effect_replace;
mod obfuscated_if_else;
mod ok_expect;
Expand Down Expand Up @@ -148,11 +149,9 @@ mod zst_offset;

use clippy_config::Conf;
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::span_lint;
use clippy_utils::macros::FormatArgsStorage;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::ty::contains_ty_adt_constructor_opaque;
use clippy_utils::{contains_return, is_trait_method, iter_input_pats, peel_blocks, return_ty, sym};
use clippy_utils::{contains_return, is_trait_method, iter_input_pats, peel_blocks, sym};
pub use path_ends_with_ext::DEFAULT_ALLOWED_DOTFILES;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::{self as hir, Expr, ExprKind, Node, Stmt, StmtKind, TraitItem, TraitItemKind};
Expand Down Expand Up @@ -4918,20 +4917,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
);
}

// if this impl block implements a trait, lint in trait definition instead
if !implements_trait
&& impl_item.ident.name == sym::new
&& let ret_ty = return_ty(cx, impl_item.owner_id)
&& ret_ty != self_ty
&& !contains_ty_adt_constructor_opaque(cx, ret_ty, self_ty)
{
span_lint(
cx,
NEW_RET_NO_SELF,
impl_item.span,
"methods called `new` usually return `Self`",
);
}
new_ret_no_self::check_impl_item(cx, impl_item, self_ty, implements_trait);
}
}

Expand Down Expand Up @@ -4963,18 +4949,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
);
}

if item.ident.name == sym::new
&& let ret_ty = return_ty(cx, item.owner_id)
&& let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id()).self_ty()
&& !ret_ty.contains(self_ty)
{
span_lint(
cx,
NEW_RET_NO_SELF,
item.span,
"methods called `new` usually return `Self`",
);
}
new_ret_no_self::check_trait_item(cx, item);
}
}
}
Expand Down
46 changes: 46 additions & 0 deletions clippy_lints/src/methods/new_ret_no_self.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::return_ty;
use clippy_utils::ty::contains_ty_adt_constructor_opaque;
use rustc_hir::{ImplItem, TraitItem};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty};
use rustc_span::sym;

use super::NEW_RET_NO_SELF;

pub(super) fn check_impl_item<'tcx>(
cx: &LateContext<'tcx>,
impl_item: &'tcx ImplItem<'_>,
self_ty: Ty<'tcx>,
implements_trait: bool,
) {
// if this impl block implements a trait, lint in trait definition instead
if !implements_trait
&& impl_item.ident.name == sym::new
&& let ret_ty = return_ty(cx, impl_item.owner_id)
&& ret_ty != self_ty
&& !contains_ty_adt_constructor_opaque(cx, ret_ty, self_ty)
{
span_lint(
cx,
NEW_RET_NO_SELF,
impl_item.span,
"methods called `new` usually return `Self`",
);
}
}

pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'tcx>) {
if trait_item.ident.name == sym::new
&& let ret_ty = return_ty(cx, trait_item.owner_id)
&& let self_ty = ty::TraitRef::identity(cx.tcx, trait_item.owner_id.to_def_id()).self_ty()
&& !ret_ty.contains(self_ty)
{
span_lint(
cx,
NEW_RET_NO_SELF,
trait_item.span,
"methods called `new` usually return `Self`",
);
}
}