mirror of
https://github.com/rust-lang/rust-clippy
synced 2025-02-25 11:57:25 +00:00
Auto merge of #10399 - samueltardieu:issue-10396, r=Manishearth
Do not suggest to derive `Default` on generics with implicit arguments Fixes #10396 changelog: FP: [`derivable_impls`]: do not suggest to derive `Default` on generics with implicit arguments
This commit is contained in:
commit
2742ac0748
3 changed files with 87 additions and 8 deletions
|
@ -8,7 +8,7 @@ use rustc_hir::{
|
||||||
Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, Ty, TyKind,
|
Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, Ty, TyKind,
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::ty::{AdtDef, DefIdTree};
|
use rustc_middle::ty::{Adt, AdtDef, DefIdTree, SubstsRef};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
|
||||||
|
@ -81,13 +81,18 @@ fn check_struct<'tcx>(
|
||||||
self_ty: &Ty<'_>,
|
self_ty: &Ty<'_>,
|
||||||
func_expr: &Expr<'_>,
|
func_expr: &Expr<'_>,
|
||||||
adt_def: AdtDef<'_>,
|
adt_def: AdtDef<'_>,
|
||||||
|
substs: SubstsRef<'_>,
|
||||||
) {
|
) {
|
||||||
if let TyKind::Path(QPath::Resolved(_, p)) = self_ty.kind {
|
if let TyKind::Path(QPath::Resolved(_, p)) = self_ty.kind {
|
||||||
if let Some(PathSegment { args: Some(a), .. }) = p.segments.last() {
|
if let Some(PathSegment { args, .. }) = p.segments.last() {
|
||||||
for arg in a.args {
|
let args = args.map(|a| a.args).unwrap_or(&[]);
|
||||||
if !matches!(arg, GenericArg::Lifetime(_)) {
|
|
||||||
return;
|
// substs contains the generic parameters of the type declaration, while args contains the arguments
|
||||||
}
|
// used at instantiation time. If both len are not equal, it means that some parameters were not
|
||||||
|
// provided (which means that the default values were used); in this case we will not risk
|
||||||
|
// suggesting too broad a rewrite. We won't either if any argument is a type or a const.
|
||||||
|
if substs.len() != args.len() || args.iter().any(|arg| !matches!(arg, GenericArg::Lifetime(_))) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,7 +189,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
|
||||||
if let Some(Node::ImplItem(impl_item)) = cx.tcx.hir().find(impl_item_hir);
|
if let Some(Node::ImplItem(impl_item)) = cx.tcx.hir().find(impl_item_hir);
|
||||||
if let ImplItemKind::Fn(_, b) = &impl_item.kind;
|
if let ImplItemKind::Fn(_, b) = &impl_item.kind;
|
||||||
if let Body { value: func_expr, .. } = cx.tcx.hir().body(*b);
|
if let Body { value: func_expr, .. } = cx.tcx.hir().body(*b);
|
||||||
if let Some(adt_def) = cx.tcx.type_of(item.owner_id).subst_identity().ty_adt_def();
|
if let &Adt(adt_def, substs) = cx.tcx.type_of(item.owner_id).subst_identity().kind();
|
||||||
if let attrs = cx.tcx.hir().attrs(item.hir_id());
|
if let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||||
if !attrs.iter().any(|attr| attr.doc_str().is_some());
|
if !attrs.iter().any(|attr| attr.doc_str().is_some());
|
||||||
if let child_attrs = cx.tcx.hir().attrs(impl_item_hir);
|
if let child_attrs = cx.tcx.hir().attrs(impl_item_hir);
|
||||||
|
@ -192,7 +197,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
|
||||||
|
|
||||||
then {
|
then {
|
||||||
if adt_def.is_struct() {
|
if adt_def.is_struct() {
|
||||||
check_struct(cx, item, self_ty, func_expr, adt_def);
|
check_struct(cx, item, self_ty, func_expr, adt_def, substs);
|
||||||
} else if adt_def.is_enum() && self.msrv.meets(msrvs::DEFAULT_ENUM_ATTRIBUTE) {
|
} else if adt_def.is_enum() && self.msrv.meets(msrvs::DEFAULT_ENUM_ATTRIBUTE) {
|
||||||
check_enum(cx, item, func_expr, adt_def);
|
check_enum(cx, item, func_expr, adt_def);
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,4 +231,41 @@ impl Default for NonExhaustiveEnum {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://github.com/rust-lang/rust-clippy/issues/10396
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct DefaultType;
|
||||||
|
|
||||||
|
struct GenericType<T = DefaultType> {
|
||||||
|
t: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GenericType {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { t: Default::default() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct InnerGenericType<T> {
|
||||||
|
t: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for InnerGenericType<DefaultType> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { t: Default::default() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct OtherGenericType<T = DefaultType> {
|
||||||
|
inner: InnerGenericType<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for OtherGenericType {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -267,4 +267,41 @@ impl Default for NonExhaustiveEnum {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://github.com/rust-lang/rust-clippy/issues/10396
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct DefaultType;
|
||||||
|
|
||||||
|
struct GenericType<T = DefaultType> {
|
||||||
|
t: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GenericType {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { t: Default::default() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct InnerGenericType<T> {
|
||||||
|
t: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for InnerGenericType<DefaultType> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { t: Default::default() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct OtherGenericType<T = DefaultType> {
|
||||||
|
inner: InnerGenericType<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for OtherGenericType {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
Loading…
Add table
Reference in a new issue