blob: 1f2f57c2507db54473708878dd385984a9219aa0 (
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
|
#![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::default();
let string2: Box<String> = Box::default();
let impl1: Box<ImplementsDefault> = Box::default();
let vec: Box<Vec<u8>> = Box::default();
let byte: Box<u8> = Box::default();
let vec2: Box<Vec<ImplementsDefault>> = Box::default();
let vec3: Box<Vec<bool>> = Box::default();
let plain_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::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::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 % 2 == 0 {
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());
}
}
|