[default_constructed_unit_structs
]: do not lint type aliases
This commit is contained in:
parent
435a8ad86c
commit
8c82486ea9
@ -1,4 +1,4 @@
|
||||
use clippy_utils::{diagnostics::span_lint_and_sugg, match_def_path, paths};
|
||||
use clippy_utils::{diagnostics::span_lint_and_sugg, is_ty_alias, match_def_path, paths};
|
||||
use hir::{def::Res, ExprKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
@ -43,12 +43,23 @@
|
||||
}
|
||||
declare_lint_pass!(DefaultConstructedUnitStructs => [DEFAULT_CONSTRUCTED_UNIT_STRUCTS]);
|
||||
|
||||
fn is_alias(ty: hir::Ty<'_>) -> bool {
|
||||
if let hir::TyKind::Path(ref qpath) = ty.kind {
|
||||
is_ty_alias(qpath)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl LateLintPass<'_> for DefaultConstructedUnitStructs {
|
||||
fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
|
||||
if_chain!(
|
||||
// make sure we have a call to `Default::default`
|
||||
if let hir::ExprKind::Call(fn_expr, &[]) = expr.kind;
|
||||
if let ExprKind::Path(ref qpath@ hir::QPath::TypeRelative(_,_)) = fn_expr.kind;
|
||||
if let ExprKind::Path(ref qpath @ hir::QPath::TypeRelative(base, _)) = fn_expr.kind;
|
||||
// make sure this isn't a type alias:
|
||||
// `<Foo as Bar>::Assoc` cannot be used as a constructor
|
||||
if !is_alias(*base);
|
||||
if let Res::Def(_, def_id) = cx.qpath_res(qpath, fn_expr.hir_id);
|
||||
if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD);
|
||||
// make sure we have a struct with no fields (unit struct)
|
||||
|
@ -287,7 +287,7 @@ pub fn is_wild(pat: &Pat<'_>) -> bool {
|
||||
/// Checks if the given `QPath` belongs to a type alias.
|
||||
pub fn is_ty_alias(qpath: &QPath<'_>) -> bool {
|
||||
match *qpath {
|
||||
QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias, ..)),
|
||||
QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias | DefKind::AssocTy, ..)),
|
||||
QPath::TypeRelative(ty, _) if let TyKind::Path(qpath) = ty.kind => { is_ty_alias(&qpath) },
|
||||
_ => false,
|
||||
}
|
||||
|
@ -101,6 +101,28 @@ struct EmptyStruct {}
|
||||
#[non_exhaustive]
|
||||
struct NonExhaustiveStruct;
|
||||
|
||||
mod issue_10755 {
|
||||
struct Sqlite {}
|
||||
|
||||
trait HasArguments<'q> {
|
||||
type Arguments;
|
||||
}
|
||||
|
||||
impl<'q> HasArguments<'q> for Sqlite {
|
||||
type Arguments = std::marker::PhantomData<&'q ()>;
|
||||
}
|
||||
|
||||
type SqliteArguments<'q> = <Sqlite as HasArguments<'q>>::Arguments;
|
||||
|
||||
fn foo() {
|
||||
// should not lint
|
||||
// type alias cannot be used as a constructor
|
||||
let _ = <Sqlite as HasArguments>::Arguments::default();
|
||||
|
||||
let _ = SqliteArguments::default();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// should lint
|
||||
let _ = PhantomData::<usize>;
|
||||
|
@ -101,6 +101,28 @@ struct EmptyStruct {}
|
||||
#[non_exhaustive]
|
||||
struct NonExhaustiveStruct;
|
||||
|
||||
mod issue_10755 {
|
||||
struct Sqlite {}
|
||||
|
||||
trait HasArguments<'q> {
|
||||
type Arguments;
|
||||
}
|
||||
|
||||
impl<'q> HasArguments<'q> for Sqlite {
|
||||
type Arguments = std::marker::PhantomData<&'q ()>;
|
||||
}
|
||||
|
||||
type SqliteArguments<'q> = <Sqlite as HasArguments<'q>>::Arguments;
|
||||
|
||||
fn foo() {
|
||||
// should not lint
|
||||
// type alias cannot be used as a constructor
|
||||
let _ = <Sqlite as HasArguments>::Arguments::default();
|
||||
|
||||
let _ = SqliteArguments::default();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// should lint
|
||||
let _ = PhantomData::<usize>::default();
|
||||
|
@ -13,25 +13,25 @@ LL | inner: PhantomData::default(),
|
||||
| ^^^^^^^^^^^ help: remove this call to `default`
|
||||
|
||||
error: use of `default` to create a unit struct
|
||||
--> $DIR/default_constructed_unit_structs.rs:106:33
|
||||
--> $DIR/default_constructed_unit_structs.rs:128:33
|
||||
|
|
||||
LL | let _ = PhantomData::<usize>::default();
|
||||
| ^^^^^^^^^^^ help: remove this call to `default`
|
||||
|
||||
error: use of `default` to create a unit struct
|
||||
--> $DIR/default_constructed_unit_structs.rs:107:42
|
||||
--> $DIR/default_constructed_unit_structs.rs:129:42
|
||||
|
|
||||
LL | let _: PhantomData<i32> = PhantomData::default();
|
||||
| ^^^^^^^^^^^ help: remove this call to `default`
|
||||
|
||||
error: use of `default` to create a unit struct
|
||||
--> $DIR/default_constructed_unit_structs.rs:108:55
|
||||
--> $DIR/default_constructed_unit_structs.rs:130:55
|
||||
|
|
||||
LL | let _: PhantomData<i32> = std::marker::PhantomData::default();
|
||||
| ^^^^^^^^^^^ help: remove this call to `default`
|
||||
|
||||
error: use of `default` to create a unit struct
|
||||
--> $DIR/default_constructed_unit_structs.rs:109:23
|
||||
--> $DIR/default_constructed_unit_structs.rs:131:23
|
||||
|
|
||||
LL | let _ = UnitStruct::default();
|
||||
| ^^^^^^^^^^^ help: remove this call to `default`
|
||||
|
Loading…
Reference in New Issue
Block a user