Skip to content

Commit

Permalink
address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Centri3 committed Jun 29, 2023
1 parent d89fe8c commit 5a9b2be
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 37 deletions.
47 changes: 19 additions & 28 deletions clippy_lints/src/trivial_default_constructed_types.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
use clippy_utils::{diagnostics::span_lint_and_sugg, is_from_proc_macro, is_lang_item_or_ctor, last_path_segment};
use clippy_utils::{diagnostics::span_lint_and_sugg, is_from_proc_macro, is_lang_item_or_ctor, is_trait_item};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, LangItem, QPath};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::{
lint::in_external_macro,
ty::{self, Ty},
};
use rustc_hir::{Expr, ExprKind, LangItem};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, Ty};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::kw;
use rustc_span::sym;
use std::borrow::Cow;

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

impl<'tcx> LateLintPass<'tcx> for TrivialDefaultConstructedTypes {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
if !in_external_macro(cx.sess(), expr.span)
if !expr.span.from_expansion()
&& let ExprKind::Call(call, _) = expr.kind
&& let ExprKind::Path(qpath) = call.kind
// `last_path_segment` ICEs if we give it a `LangItem`.
&& !matches!(qpath, QPath::LangItem(..))
&& last_path_segment(&qpath).ident.name == kw::Default
&& is_trait_item(cx, call, sym::Default)
{
let ret_ty = cx
.typeck_results()
Expand All @@ -58,14 +53,15 @@ impl<'tcx> LateLintPass<'tcx> for TrivialDefaultConstructedTypes {
Applicability::MachineApplicable,
);
} else if let ty::Tuple(fields) = ret_ty.kind()
&& fields.len() <= 3
&& let Some(fields_default) = fields.iter()
.map(|field| default_value(cx, field))
.collect::<Option<Vec<&'static str>>>()
.collect::<Option<Vec<_>>>()
&& !is_from_proc_macro(cx, expr)
{
let default = if fields.len() == 1 {
let default = if let [default] = &*fields_default {
// Needs trailing comma to be a single-element tuple
fields_default[0].to_owned() + ","
format!("{default},")
} else {
fields_default.join(", ")
};
Expand Down Expand Up @@ -101,19 +97,14 @@ impl<'tcx> LateLintPass<'tcx> for TrivialDefaultConstructedTypes {
}

/// Gets the default value of `ty`.
fn default_value(cx: &LateContext<'_>, ty: Ty<'_>) -> Option<&'static str> {
fn default_value(cx: &LateContext<'_>, ty: Ty<'_>) -> Option<Cow<'static, str>> {
match ty.kind() {
ty::Adt(def, _) => {
if is_lang_item_or_ctor(cx, def.did(), LangItem::Option) {
return Some("None");
}

None
},
ty::Bool => Some("false"),
ty::Str => Some(r#""""#),
ty::Int(_) | ty::Uint(_) => Some("0"),
ty::Float(_) => Some("0.0"),
ty::Adt(def, _) => is_lang_item_or_ctor(cx, def.did(), LangItem::Option).then(|| "None".into()),
ty::Bool => Some("false".into()),
ty::Str => Some(r#""""#.into()),
ty::Int(suffix) => Some(format!("0{}", suffix.name_str()).into()),
ty::Uint(suffix) => Some(format!("0{}", suffix.name_str()).into()),
ty::Float(suffix) => Some(format!("0.0{}", suffix.name_str()).into()),
// Do not handle `ty::Char`, it's a lot less readable
_ => None,
}
Expand Down
19 changes: 15 additions & 4 deletions tests/ui/trivial_default_constructed_types.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,19 @@
extern crate proc_macros;

fn main() {
0;
0u32;
let x: Option<u32> = None;
let y: (usize,) = (0,);
let y: (usize,) = (0usize,);
();
let x: [u32; 10] = [0; 10];
let x: [f32; 1000] = [0.0; 1000];
let x: [u32; 10] = [0u32; 10];
let x: [f32; 1000] = [0.0f32; 1000];
let x = "";
let x = false;
let x = (0u32, 0u32, false);
// Do not lint
let x = char::default();
let x = NotDefault::default();
let x = <(u32, u32, bool, &str)>::default();

external! {
u32::default();
Expand All @@ -42,3 +45,11 @@ fn main() {
let x = char::default();
}
}

struct NotDefault;

impl NotDefault {
pub fn default() -> u32 {
0
}
}
11 changes: 11 additions & 0 deletions tests/ui/trivial_default_constructed_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ fn main() {
let x: [f32; 1000] = [Default::default(); 1000];
let x = <&str>::default();
let x = bool::default();
let x = <(u32, u32, bool)>::default();
// Do not lint
let x = char::default();
let x = NotDefault::default();
let x = <(u32, u32, bool, &str)>::default();

external! {
u32::default();
Expand All @@ -42,3 +45,11 @@ fn main() {
let x = char::default();
}
}

struct NotDefault;

impl NotDefault {
pub fn default() -> u32 {
0
}
}
16 changes: 11 additions & 5 deletions tests/ui/trivial_default_constructed_types.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error: constructing a trivial type using `default`
--> $DIR/trivial_default_constructed_types.rs:10:5
|
LL | u32::default();
| ^^^^^^^^^^^^^^ help: try: `0`
| ^^^^^^^^^^^^^^ help: try: `0u32`
|
= note: `-D clippy::trivial-default-constructed-types` implied by `-D warnings`

Expand All @@ -16,7 +16,7 @@ error: constructing a trivial tuple using `default`
--> $DIR/trivial_default_constructed_types.rs:12:23
|
LL | let y: (usize,) = Default::default();
| ^^^^^^^^^^^^^^^^^^ help: try: `(0,)`
| ^^^^^^^^^^^^^^^^^^ help: try: `(0usize,)`

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

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

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

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

error: aborting due to 9 previous errors

0 comments on commit 5a9b2be

Please sign in to comment.