Skip to content

Commit dcaf1b1

Browse files
committed
address comments
1 parent d89fe8c commit dcaf1b1

4 files changed

+59
-38
lines changed

clippy_lints/src/trivial_default_constructed_types.rs

+20-27
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
use clippy_utils::{diagnostics::span_lint_and_sugg, is_from_proc_macro, is_lang_item_or_ctor, last_path_segment};
1+
use clippy_utils::{diagnostics::span_lint_and_sugg, is_from_proc_macro, is_lang_item_or_ctor, is_trait_item};
22
use rustc_errors::Applicability;
3-
use rustc_hir::{Expr, ExprKind, LangItem, QPath};
4-
use rustc_lint::{LateContext, LateLintPass, LintContext};
5-
use rustc_middle::{
6-
lint::in_external_macro,
7-
ty::{self, Ty},
8-
};
3+
use rustc_hir::{Expr, ExprKind, LangItem};
4+
use rustc_lint::{LateContext, LateLintPass};
5+
use rustc_middle::ty::{self, Ty};
96
use rustc_session::{declare_lint_pass, declare_tool_lint};
10-
use rustc_span::symbol::kw;
7+
use rustc_span::sym;
8+
use std::borrow::Cow;
119

1210
declare_clippy_lint! {
1311
/// ### What it does
@@ -33,12 +31,9 @@ declare_lint_pass!(TrivialDefaultConstructedTypes => [TRIVIAL_DEFAULT_CONSTRUCTE
3331

3432
impl<'tcx> LateLintPass<'tcx> for TrivialDefaultConstructedTypes {
3533
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
36-
if !in_external_macro(cx.sess(), expr.span)
34+
if !expr.span.from_expansion()
3735
&& let ExprKind::Call(call, _) = expr.kind
38-
&& let ExprKind::Path(qpath) = call.kind
39-
// `last_path_segment` ICEs if we give it a `LangItem`.
40-
&& !matches!(qpath, QPath::LangItem(..))
41-
&& last_path_segment(&qpath).ident.name == kw::Default
36+
&& is_trait_item(cx, call, sym::Default)
4237
{
4338
let ret_ty = cx
4439
.typeck_results()
@@ -58,14 +53,15 @@ impl<'tcx> LateLintPass<'tcx> for TrivialDefaultConstructedTypes {
5853
Applicability::MachineApplicable,
5954
);
6055
} else if let ty::Tuple(fields) = ret_ty.kind()
56+
&& fields.len() <= 3
6157
&& let Some(fields_default) = fields.iter()
6258
.map(|field| default_value(cx, field))
63-
.collect::<Option<Vec<&'static str>>>()
59+
.collect::<Option<Vec<_>>>()
6460
&& !is_from_proc_macro(cx, expr)
6561
{
66-
let default = if fields.len() == 1 {
62+
let default = if let [default] = &*fields_default {
6763
// Needs trailing comma to be a single-element tuple
68-
fields_default[0].to_owned() + ","
64+
format!("{default},")
6965
} else {
7066
fields_default.join(", ")
7167
};
@@ -101,19 +97,16 @@ impl<'tcx> LateLintPass<'tcx> for TrivialDefaultConstructedTypes {
10197
}
10298

10399
/// Gets the default value of `ty`.
104-
fn default_value(cx: &LateContext<'_>, ty: Ty<'_>) -> Option<&'static str> {
100+
fn default_value(cx: &LateContext<'_>, ty: Ty<'_>) -> Option<Cow<'static, str>> {
105101
match ty.kind() {
106-
ty::Adt(def, _) => {
107-
if is_lang_item_or_ctor(cx, def.did(), LangItem::Option) {
108-
return Some("None");
109-
}
110-
111-
None
102+
ty::Adt(def, substs) if let [subst] = substs.as_slice() => {
103+
is_lang_item_or_ctor(cx, def.did(), LangItem::Option).then(|| format!("None::<{subst}>").into())
112104
},
113-
ty::Bool => Some("false"),
114-
ty::Str => Some(r#""""#),
115-
ty::Int(_) | ty::Uint(_) => Some("0"),
116-
ty::Float(_) => Some("0.0"),
105+
ty::Bool => Some("false".into()),
106+
ty::Str => Some(r#""""#.into()),
107+
ty::Int(suffix) => Some(format!("0{}", suffix.name_str()).into()),
108+
ty::Uint(suffix) => Some(format!("0{}", suffix.name_str()).into()),
109+
ty::Float(suffix) => Some(format!("0.0{}", suffix.name_str()).into()),
117110
// Do not handle `ty::Char`, it's a lot less readable
118111
_ => None,
119112
}

tests/ui/trivial_default_constructed_types.fixed

+16-5
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,19 @@
77
extern crate proc_macros;
88

99
fn main() {
10-
0;
11-
let x: Option<u32> = None;
12-
let y: (usize,) = (0,);
10+
0u32;
11+
let x: Option<u32> = None::<u32>;
12+
let y: (usize,) = (0usize,);
1313
();
14-
let x: [u32; 10] = [0; 10];
15-
let x: [f32; 1000] = [0.0; 1000];
14+
let x: [u32; 10] = [0u32; 10];
15+
let x: [f32; 1000] = [0.0f32; 1000];
1616
let x = "";
1717
let x = false;
18+
let x = (0u32, 0u32, false);
1819
// Do not lint
1920
let x = char::default();
21+
let x = NotDefault::default();
22+
let x = <(u32, u32, bool, &str)>::default();
2023

2124
external! {
2225
u32::default();
@@ -42,3 +45,11 @@ fn main() {
4245
let x = char::default();
4346
}
4447
}
48+
49+
struct NotDefault;
50+
51+
impl NotDefault {
52+
pub fn default() -> u32 {
53+
0
54+
}
55+
}

tests/ui/trivial_default_constructed_types.rs

+11
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ fn main() {
1515
let x: [f32; 1000] = [Default::default(); 1000];
1616
let x = <&str>::default();
1717
let x = bool::default();
18+
let x = <(u32, u32, bool)>::default();
1819
// Do not lint
1920
let x = char::default();
21+
let x = NotDefault::default();
22+
let x = <(u32, u32, bool, &str)>::default();
2023

2124
external! {
2225
u32::default();
@@ -42,3 +45,11 @@ fn main() {
4245
let x = char::default();
4346
}
4447
}
48+
49+
struct NotDefault;
50+
51+
impl NotDefault {
52+
pub fn default() -> u32 {
53+
0
54+
}
55+
}

tests/ui/trivial_default_constructed_types.stderr

+12-6
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@ error: constructing a trivial type using `default`
22
--> $DIR/trivial_default_constructed_types.rs:10:5
33
|
44
LL | u32::default();
5-
| ^^^^^^^^^^^^^^ help: try: `0`
5+
| ^^^^^^^^^^^^^^ help: try: `0u32`
66
|
77
= note: `-D clippy::trivial-default-constructed-types` implied by `-D warnings`
88

99
error: constructing a trivial type using `default`
1010
--> $DIR/trivial_default_constructed_types.rs:11:26
1111
|
1212
LL | let x: Option<u32> = Option::default();
13-
| ^^^^^^^^^^^^^^^^^ help: try: `None`
13+
| ^^^^^^^^^^^^^^^^^ help: try: `None::<u32>`
1414

1515
error: constructing a trivial tuple using `default`
1616
--> $DIR/trivial_default_constructed_types.rs:12:23
1717
|
1818
LL | let y: (usize,) = Default::default();
19-
| ^^^^^^^^^^^^^^^^^^ help: try: `(0,)`
19+
| ^^^^^^^^^^^^^^^^^^ help: try: `(0usize,)`
2020

2121
error: constructing a unit using `default`
2222
--> $DIR/trivial_default_constructed_types.rs:13:5
@@ -28,13 +28,13 @@ error: constructing a trivial array using `default`
2828
--> $DIR/trivial_default_constructed_types.rs:14:24
2929
|
3030
LL | let x: [u32; 10] = Default::default();
31-
| ^^^^^^^^^^^^^^^^^^ help: try: `[0; 10]`
31+
| ^^^^^^^^^^^^^^^^^^ help: try: `[0u32; 10]`
3232

3333
error: constructing a trivial type using `default`
3434
--> $DIR/trivial_default_constructed_types.rs:15:27
3535
|
3636
LL | let x: [f32; 1000] = [Default::default(); 1000];
37-
| ^^^^^^^^^^^^^^^^^^ help: try: `0.0`
37+
| ^^^^^^^^^^^^^^^^^^ help: try: `0.0f32`
3838

3939
error: constructing a trivial type using `default`
4040
--> $DIR/trivial_default_constructed_types.rs:16:13
@@ -48,5 +48,11 @@ error: constructing a trivial type using `default`
4848
LL | let x = bool::default();
4949
| ^^^^^^^^^^^^^^^ help: try: `false`
5050

51-
error: aborting due to 8 previous errors
51+
error: constructing a trivial tuple using `default`
52+
--> $DIR/trivial_default_constructed_types.rs:18:13
53+
|
54+
LL | let x = <(u32, u32, bool)>::default();
55+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(0u32, 0u32, false)`
56+
57+
error: aborting due to 9 previous errors
5258

0 commit comments

Comments
 (0)