Don't suggest unnameable types in box_default, let_underscore_untyped

This commit is contained in:
Alex Macleod 2023-05-18 12:33:52 +00:00
parent 22b319606f
commit cfa5aa2aad
6 changed files with 35 additions and 18 deletions

View File

@ -8,7 +8,9 @@ use rustc_hir::{
Block, Expr, ExprKind, Local, Node, QPath, TyKind,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::{lint::in_external_macro, ty::print::with_forced_trimmed_paths};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::print::with_forced_trimmed_paths;
use rustc_middle::ty::IsSuggestable;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
@ -49,7 +51,6 @@ impl LateLintPass<'_> for BoxDefault {
&& path_def_id(cx, ty).map_or(false, |id| Some(id) == cx.tcx.lang_items().owned_box())
&& is_default_equivalent(cx, arg)
{
let arg_ty = cx.typeck_results().expr_ty(arg);
span_lint_and_sugg(
cx,
BOX_DEFAULT,
@ -58,8 +59,10 @@ impl LateLintPass<'_> for BoxDefault {
"try",
if is_plain_default(arg_path) || given_type(cx, expr) {
"Box::default()".into()
} else {
} else if let Some(arg_ty) = cx.typeck_results().expr_ty(arg).make_suggestable(cx.tcx, true) {
with_forced_trimmed_paths!(format!("Box::<{arg_ty}>::default()"))
} else {
return
},
Applicability::MachineApplicable
);

View File

@ -2,10 +2,11 @@ use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::is_from_proc_macro;
use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type};
use clippy_utils::{is_must_use_func_call, paths};
use rustc_hir::{ExprKind, Local, PatKind};
use rustc_hir::{Local, PatKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::IsSuggestable;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{BytePos, Span};
@ -192,14 +193,12 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
if local.pat.default_binding_modes && local.ty.is_none() {
// When `default_binding_modes` is true, the `let` keyword is present.
// Ignore function calls that return impl traits...
if let Some(init) = local.init &&
matches!(init.kind, ExprKind::Call(_, _) | ExprKind::MethodCall(_, _, _, _)) {
let expr_ty = cx.typeck_results().expr_ty(init);
if expr_ty.is_impl_trait() {
return;
}
}
// Ignore unnameable types
if let Some(init) = local.init
&& !cx.typeck_results().expr_ty(init).is_suggestable(cx.tcx, true)
{
return;
}
// Ignore if it is from a procedural macro...
if is_from_proc_macro(cx, init) {

View File

@ -1,6 +1,6 @@
//@run-rustfix
#![warn(clippy::box_default)]
#![allow(clippy::default_constructed_unit_structs)]
#![allow(unused, clippy::default_constructed_unit_structs)]
#[derive(Default)]
struct ImplementsDefault;
@ -35,6 +35,13 @@ fn main() {
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(|| {});
}
fn ret_ty_fn() -> Box<bool> {

View File

@ -1,6 +1,6 @@
//@run-rustfix
#![warn(clippy::box_default)]
#![allow(clippy::default_constructed_unit_structs)]
#![allow(unused, clippy::default_constructed_unit_structs)]
#[derive(Default)]
struct ImplementsDefault;
@ -35,6 +35,13 @@ fn main() {
let _more = ret_ty_fn();
call_ty_fn(Box::new(u8::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(|| {});
}
fn ret_ty_fn() -> Box<bool> {

View File

@ -73,25 +73,25 @@ LL | call_ty_fn(Box::new(u8::default()));
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
error: `Box::new(_)` of default value
--> $DIR/box_default.rs:41:5
--> $DIR/box_default.rs:48:5
|
LL | Box::new(bool::default())
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<bool>::default()`
error: `Box::new(_)` of default value
--> $DIR/box_default.rs:58:28
--> $DIR/box_default.rs:65:28
|
LL | let _: Box<dyn Read> = Box::new(ImplementsDefault::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<ImplementsDefault>::default()`
error: `Box::new(_)` of default value
--> $DIR/box_default.rs:67:17
--> $DIR/box_default.rs:74:17
|
LL | let _ = Box::new(WeirdPathed::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<WeirdPathed>::default()`
error: `Box::new(_)` of default value
--> $DIR/box_default.rs:79:18
--> $DIR/box_default.rs:86:18
|
LL | Some(Box::new(Foo::default()))
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<Foo>::default()`

View File

@ -54,6 +54,7 @@ fn main() {
let _ = e();
let _ = f();
let _ = g();
let closure = || {};
_ = a();
_ = b(1);