Skip to content

Commit ab99eec

Browse files
committed
Auto merge of #7684 - surechen:solve_derivable_impls, r=flip1995
fix for issue #7683 Fixes #7683. For Repeat [x; y] (x is the type and y is the times to repeat) . When y > 32, the compiler will report an error: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7148558162685e91056e0550797ea74c Because https://github.com/rust-lang/rust/blob/6cdd42f9f8dd4e5e5ba0aa816bc4c99ab8b102f9/library/std/src/primitive_docs.rs#L538 /// Arrays of sizes from 0 to 32 (inclusive) implement [`Default`] trait /// if the element type allows it. As a stopgap, trait implementations are /// statically generated up to size 32. So here to detect this situation. changelog: [`derivable_impls`]: No longer lints when arrays bigger than 32 elements are involved
2 parents 984d466 + a3d3735 commit ab99eec

File tree

3 files changed

+44
-2
lines changed

3 files changed

+44
-2
lines changed

clippy_utils/src/lib.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,17 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
684684
_ => false,
685685
},
686686
ExprKind::Tup(items) | ExprKind::Array(items) => items.iter().all(|x| is_default_equivalent(cx, x)),
687-
ExprKind::Repeat(x, _) => is_default_equivalent(cx, x),
687+
ExprKind::Repeat(x, y) => if_chain! {
688+
if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(y.body).value.kind;
689+
if let LitKind::Int(v, _) = const_lit.node;
690+
if v <= 32 && is_default_equivalent(cx, x);
691+
then {
692+
true
693+
}
694+
else {
695+
false
696+
}
697+
},
688698
ExprKind::Call(repl_func, _) => if_chain! {
689699
if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind;
690700
if let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id();

tests/ui/derivable_impls.rs

+20
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,24 @@ impl Default for Color2 {
207207
}
208208
}
209209

210+
pub struct RepeatDefault1 {
211+
a: [i8; 32],
212+
}
213+
214+
impl Default for RepeatDefault1 {
215+
fn default() -> Self {
216+
RepeatDefault1 { a: [0; 32] }
217+
}
218+
}
219+
220+
pub struct RepeatDefault2 {
221+
a: [i8; 33],
222+
}
223+
224+
impl Default for RepeatDefault2 {
225+
fn default() -> Self {
226+
RepeatDefault2 { a: [0; 33] }
227+
}
228+
}
229+
210230
fn main() {}

tests/ui/derivable_impls.stderr

+13-1
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,17 @@ LL | | }
7373
|
7474
= help: try annotating `WithoutSelfParan` with `#[derive(Default)]`
7575

76-
error: aborting due to 6 previous errors
76+
error: this `impl` can be derived
77+
--> $DIR/derivable_impls.rs:214:1
78+
|
79+
LL | / impl Default for RepeatDefault1 {
80+
LL | | fn default() -> Self {
81+
LL | | RepeatDefault1 { a: [0; 32] }
82+
LL | | }
83+
LL | | }
84+
| |_^
85+
|
86+
= help: try annotating `RepeatDefault1` with `#[derive(Default)]`
87+
88+
error: aborting due to 7 previous errors
7789

0 commit comments

Comments
 (0)