Skip to content

Commit

Permalink
HasPlaceholder for None
Browse files Browse the repository at this point in the history
  • Loading branch information
Centri3 committed Jun 29, 2023
1 parent dcaf1b1 commit 7aee58b
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 9 deletions.
18 changes: 11 additions & 7 deletions clippy_lints/src/trivial_default_constructed_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@ impl<'tcx> LateLintPass<'tcx> for TrivialDefaultConstructedTypes {
&& let ExprKind::Call(call, _) = expr.kind
&& is_trait_item(cx, call, sym::Default)
{
let mut app = Applicability::MachineApplicable;
let ret_ty = cx
.typeck_results()
.expr_ty(call)
.fn_sig(cx.tcx)
.output()
.skip_binder()
.peel_refs();
if let Some(default) = default_value(cx, ret_ty) && !is_from_proc_macro(cx, expr) {
if let Some(default) = default_value(cx, ret_ty, &mut app) && !is_from_proc_macro(cx, expr) {
span_lint_and_sugg(
cx,
TRIVIAL_DEFAULT_CONSTRUCTED_TYPES,
Expand All @@ -55,7 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialDefaultConstructedTypes {
} else if let ty::Tuple(fields) = ret_ty.kind()
&& fields.len() <= 3
&& let Some(fields_default) = fields.iter()
.map(|field| default_value(cx, field))
.map(|field| default_value(cx, field, &mut app))
.collect::<Option<Vec<_>>>()
&& !is_from_proc_macro(cx, expr)
{
Expand All @@ -79,7 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialDefaultConstructedTypes {
Applicability::MachineApplicable,
);
} else if let ty::Array(ty, len) = ret_ty.kind()
&& let Some(default) = default_value(cx, *ty)
&& let Some(default) = default_value(cx, *ty, &mut app)
&& !is_from_proc_macro(cx, expr)
{
span_lint_and_sugg(
Expand All @@ -89,18 +90,21 @@ impl<'tcx> LateLintPass<'tcx> for TrivialDefaultConstructedTypes {
"constructing a trivial array using `default`",
"try",
format!("[{default}; {len}]"),
Applicability::MachineApplicable,
app,
);
}
}
}
}

/// Gets the default value of `ty`.
fn default_value(cx: &LateContext<'_>, ty: Ty<'_>) -> Option<Cow<'static, str>> {
fn default_value(cx: &LateContext<'_>, ty: Ty<'_>, app: &mut Applicability) -> Option<Cow<'static, str>> {
match ty.kind() {
ty::Adt(def, substs) if let [subst] = substs.as_slice() => {
is_lang_item_or_ctor(cx, def.did(), LangItem::Option).then(|| format!("None::<{subst}>").into())
ty::Adt(def, _) => {
*app = Applicability::HasPlaceholders;
// Checking if the generic argument is required would substantially increase the
// complexity of this lint, for now, just use a placeholder (`_`).
is_lang_item_or_ctor(cx, def.did(), LangItem::Option).then(|| "None::<_>".into())
},
ty::Bool => Some("false".into()),
ty::Str => Some(r#""""#.into()),
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/trivial_default_constructed_types.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ extern crate proc_macros;

fn main() {
0u32;
let x: Option<u32> = None::<u32>;
let x: Option<u32> = None::<_>;
let y: (usize,) = (0usize,);
();
let x: [u32; 10] = [0u32; 10];
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/trivial_default_constructed_types.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ error: constructing a trivial type using `default`
--> $DIR/trivial_default_constructed_types.rs:11:26
|
LL | let x: Option<u32> = Option::default();
| ^^^^^^^^^^^^^^^^^ help: try: `None::<u32>`
| ^^^^^^^^^^^^^^^^^ help: try: `None::<_>`

error: constructing a trivial tuple using `default`
--> $DIR/trivial_default_constructed_types.rs:12:23
Expand Down

0 comments on commit 7aee58b

Please sign in to comment.