blob: 801d92f5c290ff74d70118ef840184753241ea18 (
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
|
#![warn(clippy::box_default)]
#![allow(clippy::boxed_local, clippy::default_constructed_unit_structs)]
#[derive(Default)]
struct ImplementsDefault;
struct OwnDefault;
impl OwnDefault {
fn default() -> Self {
Self
}
}
macro_rules! default {
() => {
Default::default()
};
}
macro_rules! string_new {
() => {
String::new()
};
}
macro_rules! box_new {
($e:expr) => {
Box::new($e)
};
}
fn main() {
let string1: Box<String> = Box::new(Default::default());
//~^ box_default
let string2: Box<String> = Box::new(String::new());
//~^ box_default
let impl1: Box<ImplementsDefault> = Box::new(Default::default());
//~^ box_default
let vec: Box<Vec<u8>> = Box::new(Vec::new());
//~^ box_default
let byte: Box<u8> = Box::new(u8::default());
//~^ box_default
let vec2: Box<Vec<ImplementsDefault>> = Box::new(vec![]);
//~^ box_default
let vec3: Box<Vec<bool>> = Box::new(Vec::from([]));
//~^ box_default
let plain_default = Box::new(Default::default());
//~^ box_default
let _: Box<String> = plain_default;
let _: Box<String> = Box::new(default!());
let _: Box<String> = Box::new(string_new!());
let _: Box<String> = box_new!(Default::default());
let _: Box<String> = box_new!(String::new());
let _: Box<String> = box_new!(default!());
let _: Box<String> = box_new!(string_new!());
let own: Box<OwnDefault> = Box::new(OwnDefault::default()); // should not lint
// Do not suggest where a turbofish would be required
let impl2 = Box::new(ImplementsDefault::default());
let impl3 = Box::new(<ImplementsDefault as Default>::default());
let vec4: Box<_> = Box::new(Vec::from([false; 0]));
let more = ret_ty_fn();
call_ty_fn(Box::new(u8::default()));
//~^ box_default
issue_10381();
// `Box::<Option<_>>::default()` would be valid here, but not `Box::default()` or
// `Box::<Option<{closure@...}>::default()`
//
// Would have a suggestion after https://github.com/rust-lang/rust/blob/fdd030127cc68afec44a8d3f6341525dd34e50ae/compiler/rustc_middle/src/ty/diagnostics.rs#L554-L563
let mut unnameable = Box::new(Option::default());
let _ = unnameable.insert(|| {});
let _ = Box::into_raw(Box::new(String::default()));
}
fn ret_ty_fn() -> Box<bool> {
Box::new(bool::default()) // Could lint, currently doesn't
}
fn call_ty_fn(_b: Box<u8>) {
issue_9621_dyn_trait();
}
struct X<T>(T);
impl<T: Default> X<T> {
fn x(_: Box<T>) {}
fn same_generic_param() {
Self::x(Box::new(T::default()));
//~^ box_default
}
}
use std::io::{Read, Result};
impl Read for ImplementsDefault {
fn read(&mut self, _: &mut [u8]) -> Result<usize> {
Ok(0)
}
}
fn issue_9621_dyn_trait() {
let _: Box<dyn Read> = Box::new(ImplementsDefault::default());
issue_10089();
}
fn issue_10089() {
let _closure = || {
#[derive(Default)]
struct WeirdPathed;
let _ = Box::new(WeirdPathed::default());
};
}
fn issue_10381() {
#[derive(Default)]
pub struct Foo {}
pub trait Bar {}
impl Bar for Foo {}
fn maybe_get_bar(i: u32) -> Option<Box<dyn Bar>> {
if i.is_multiple_of(2) {
Some(Box::new(Foo::default()))
} else {
None
}
}
assert!(maybe_get_bar(2).is_some());
}
// Issue #11927: The quickfix for the `Box::new` suggests replacing with `Box::<Inner>::default()`,
// removing the `outer::` segment.
fn issue_11927() {
mod outer {
#[derive(Default)]
pub struct Inner {
_i: usize,
}
}
fn foo() {
let _b = Box::new(outer::Inner::default());
let _b = Box::new(std::collections::HashSet::<i32>::new());
}
}
|