Skip to content

Commit 490cd94

Browse files
y21flip1995
authored andcommitted
[default_constructed_unit_structs]: do not lint type aliases
1 parent dbf31f1 commit 490cd94

File tree

5 files changed

+62
-7
lines changed

5 files changed

+62
-7
lines changed

src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use clippy_utils::{diagnostics::span_lint_and_sugg, match_def_path, paths};
1+
use clippy_utils::{diagnostics::span_lint_and_sugg, is_ty_alias, match_def_path, paths};
22
use hir::{def::Res, ExprKind};
33
use rustc_errors::Applicability;
44
use rustc_hir as hir;
@@ -43,12 +43,23 @@ declare_clippy_lint! {
4343
}
4444
declare_lint_pass!(DefaultConstructedUnitStructs => [DEFAULT_CONSTRUCTED_UNIT_STRUCTS]);
4545

46+
fn is_alias(ty: hir::Ty<'_>) -> bool {
47+
if let hir::TyKind::Path(ref qpath) = ty.kind {
48+
is_ty_alias(qpath)
49+
} else {
50+
false
51+
}
52+
}
53+
4654
impl LateLintPass<'_> for DefaultConstructedUnitStructs {
4755
fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
4856
if_chain!(
4957
// make sure we have a call to `Default::default`
5058
if let hir::ExprKind::Call(fn_expr, &[]) = expr.kind;
51-
if let ExprKind::Path(ref qpath@ hir::QPath::TypeRelative(_,_)) = fn_expr.kind;
59+
if let ExprKind::Path(ref qpath @ hir::QPath::TypeRelative(base, _)) = fn_expr.kind;
60+
// make sure this isn't a type alias:
61+
// `<Foo as Bar>::Assoc` cannot be used as a constructor
62+
if !is_alias(*base);
5263
if let Res::Def(_, def_id) = cx.qpath_res(qpath, fn_expr.hir_id);
5364
if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD);
5465
// make sure we have a struct with no fields (unit struct)

src/tools/clippy/clippy_utils/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ pub fn is_wild(pat: &Pat<'_>) -> bool {
287287
/// Checks if the given `QPath` belongs to a type alias.
288288
pub fn is_ty_alias(qpath: &QPath<'_>) -> bool {
289289
match *qpath {
290-
QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias, ..)),
290+
QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias | DefKind::AssocTy, ..)),
291291
QPath::TypeRelative(ty, _) if let TyKind::Path(qpath) = ty.kind => { is_ty_alias(&qpath) },
292292
_ => false,
293293
}

src/tools/clippy/tests/ui/default_constructed_unit_structs.fixed

+22
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,28 @@ struct EmptyStruct {}
101101
#[non_exhaustive]
102102
struct NonExhaustiveStruct;
103103

104+
mod issue_10755 {
105+
struct Sqlite {}
106+
107+
trait HasArguments<'q> {
108+
type Arguments;
109+
}
110+
111+
impl<'q> HasArguments<'q> for Sqlite {
112+
type Arguments = std::marker::PhantomData<&'q ()>;
113+
}
114+
115+
type SqliteArguments<'q> = <Sqlite as HasArguments<'q>>::Arguments;
116+
117+
fn foo() {
118+
// should not lint
119+
// type alias cannot be used as a constructor
120+
let _ = <Sqlite as HasArguments>::Arguments::default();
121+
122+
let _ = SqliteArguments::default();
123+
}
124+
}
125+
104126
fn main() {
105127
// should lint
106128
let _ = PhantomData::<usize>;

src/tools/clippy/tests/ui/default_constructed_unit_structs.rs

+22
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,28 @@ struct EmptyStruct {}
101101
#[non_exhaustive]
102102
struct NonExhaustiveStruct;
103103

104+
mod issue_10755 {
105+
struct Sqlite {}
106+
107+
trait HasArguments<'q> {
108+
type Arguments;
109+
}
110+
111+
impl<'q> HasArguments<'q> for Sqlite {
112+
type Arguments = std::marker::PhantomData<&'q ()>;
113+
}
114+
115+
type SqliteArguments<'q> = <Sqlite as HasArguments<'q>>::Arguments;
116+
117+
fn foo() {
118+
// should not lint
119+
// type alias cannot be used as a constructor
120+
let _ = <Sqlite as HasArguments>::Arguments::default();
121+
122+
let _ = SqliteArguments::default();
123+
}
124+
}
125+
104126
fn main() {
105127
// should lint
106128
let _ = PhantomData::<usize>::default();

src/tools/clippy/tests/ui/default_constructed_unit_structs.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,25 @@ LL | inner: PhantomData::default(),
1313
| ^^^^^^^^^^^ help: remove this call to `default`
1414

1515
error: use of `default` to create a unit struct
16-
--> $DIR/default_constructed_unit_structs.rs:106:33
16+
--> $DIR/default_constructed_unit_structs.rs:128:33
1717
|
1818
LL | let _ = PhantomData::<usize>::default();
1919
| ^^^^^^^^^^^ help: remove this call to `default`
2020

2121
error: use of `default` to create a unit struct
22-
--> $DIR/default_constructed_unit_structs.rs:107:42
22+
--> $DIR/default_constructed_unit_structs.rs:129:42
2323
|
2424
LL | let _: PhantomData<i32> = PhantomData::default();
2525
| ^^^^^^^^^^^ help: remove this call to `default`
2626

2727
error: use of `default` to create a unit struct
28-
--> $DIR/default_constructed_unit_structs.rs:108:55
28+
--> $DIR/default_constructed_unit_structs.rs:130:55
2929
|
3030
LL | let _: PhantomData<i32> = std::marker::PhantomData::default();
3131
| ^^^^^^^^^^^ help: remove this call to `default`
3232

3333
error: use of `default` to create a unit struct
34-
--> $DIR/default_constructed_unit_structs.rs:109:23
34+
--> $DIR/default_constructed_unit_structs.rs:131:23
3535
|
3636
LL | let _ = UnitStruct::default();
3737
| ^^^^^^^^^^^ help: remove this call to `default`

0 commit comments

Comments
 (0)