summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/tests/ui/default_constructed_unit_structs.rs
blob: de7f14ffbd95c393a8ebca68b3ab020adb9b511e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//@run-rustfix

#![allow(unused)]
#![warn(clippy::default_constructed_unit_structs)]
use std::marker::PhantomData;

#[derive(Default)]
struct UnitStruct;

impl UnitStruct {
    fn new() -> Self {
        //should lint
        Self::default()
    }
}

#[derive(Default)]
struct TupleStruct(usize);

impl TupleStruct {
    fn new() -> Self {
        // should not lint
        Self(Default::default())
    }
}

// no lint for derived impl
#[derive(Default)]
struct NormalStruct {
    inner: PhantomData<usize>,
}

struct NonDefaultStruct;

impl NonDefaultStruct {
    fn default() -> Self {
        Self
    }
}

#[derive(Default)]
enum SomeEnum {
    #[default]
    Unit,
    Tuple(UnitStruct),
    Struct {
        inner: usize,
    },
}

impl NormalStruct {
    fn new() -> Self {
        // should lint
        Self {
            inner: PhantomData::default(),
        }
    }

    fn new2() -> Self {
        // should not lint
        Self {
            inner: Default::default(),
        }
    }
}

#[derive(Default)]
struct GenericStruct<T> {
    t: T,
}

impl<T: Default> GenericStruct<T> {
    fn new() -> Self {
        // should not lint
        Self { t: T::default() }
    }

    fn new2() -> Self {
        // should not lint
        Self { t: Default::default() }
    }
}

struct FakeDefault;
impl FakeDefault {
    fn default() -> Self {
        Self
    }
}

impl Default for FakeDefault {
    fn default() -> Self {
        Self
    }
}

#[derive(Default)]
struct EmptyStruct {}

#[derive(Default)]
#[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();
    let _: PhantomData<i32> = PhantomData::default();
    let _: PhantomData<i32> = std::marker::PhantomData::default();
    let _ = UnitStruct::default();

    // should not lint
    let _ = TupleStruct::default();
    let _ = NormalStruct::default();
    let _ = NonExhaustiveStruct::default();
    let _ = SomeEnum::default();
    let _ = NonDefaultStruct::default();
    let _ = EmptyStruct::default();
    let _ = FakeDefault::default();
    let _ = <FakeDefault as Default>::default();

    macro_rules! in_macro {
        ($i:ident) => {{
            let _ = UnitStruct::default();
            let _ = $i::default();
        }};
    }

    in_macro!(UnitStruct);

    macro_rules! struct_from_macro {
        () => {
            UnitStruct
        };
    }

    let _ = <struct_from_macro!()>::default();
}