Skip to content

Commit 7a56edf

Browse files
committed
Lint on trait declarations
1 parent e2c22d6 commit 7a56edf

File tree

3 files changed

+47
-31
lines changed

3 files changed

+47
-31
lines changed

clippy_lints/src/unnecessary_box_returns.rs

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::{diagnostics::span_lint_and_sugg, ty::implements_trait};
22
use rustc_errors::Applicability;
3-
use rustc_hir::{intravisit::FnKind, Body, FnDecl, FnRetTy, HirId};
3+
use rustc_hir::{intravisit::FnKind, Body, FnDecl, FnRetTy, HirId, TraitItem, TraitItemKind};
44
use rustc_hir_analysis::hir_ty_to_ty;
55
use rustc_lint::{LateContext, LateLintPass};
66
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -36,7 +36,40 @@ declare_clippy_lint! {
3636
}
3737
declare_lint_pass!(UnnecessaryBoxReturns => [UNNECESSARY_BOX_RETURNS]);
3838

39+
fn check_fn_decl(cx: &LateContext<'_>, decl: &FnDecl<'_>) {
40+
let FnRetTy::Return(return_ty_hir) = &decl.output else { return };
41+
42+
// this is safe, since we're not in a body
43+
let return_ty = hir_ty_to_ty(cx.tcx, return_ty_hir);
44+
45+
if !return_ty.is_box() {
46+
return;
47+
}
48+
49+
let boxed_ty = return_ty.boxed_ty();
50+
let Some(sized_trait) = cx.tcx.lang_items().sized_trait() else { return };
51+
52+
// it's sometimes useful to return Box<T> if T is unsized, so don't lint those
53+
if implements_trait(cx, boxed_ty, sized_trait, &[]) {
54+
span_lint_and_sugg(
55+
cx,
56+
UNNECESSARY_BOX_RETURNS,
57+
return_ty_hir.span,
58+
format!("function returns `Box<{boxed_ty}>` when `{boxed_ty}` implements `Sized`").as_str(),
59+
"change the return type to",
60+
boxed_ty.to_string(),
61+
// the return value and function callers also needs to be changed, so this can't be MachineApplicable
62+
Applicability::Unspecified,
63+
);
64+
}
65+
}
66+
3967
impl LateLintPass<'_> for UnnecessaryBoxReturns {
68+
fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &TraitItem<'_>) {
69+
let TraitItemKind::Fn(signature, _) = &item.kind else { return };
70+
check_fn_decl(cx, signature.decl);
71+
}
72+
4073
fn check_fn(
4174
&mut self,
4275
cx: &LateContext<'_>,
@@ -51,30 +84,6 @@ impl LateLintPass<'_> for UnnecessaryBoxReturns {
5184
// If this is changed, please also make sure not to call `hir_ty_to_ty` below.
5285
let FnKind::ItemFn(..) = fn_kind else { return };
5386

54-
let FnRetTy::Return(return_ty_hir) = &decl.output else { return };
55-
56-
// this is safe, since we're not in a body
57-
let return_ty = hir_ty_to_ty(cx.tcx, return_ty_hir);
58-
59-
if !return_ty.is_box() {
60-
return;
61-
}
62-
63-
let boxed_ty = return_ty.boxed_ty();
64-
let Some(sized_trait) = cx.tcx.lang_items().sized_trait() else { return };
65-
66-
// it's sometimes useful to return Box<T> if T is unsized, so don't lint those
67-
if implements_trait(cx, boxed_ty, sized_trait, &[]) {
68-
span_lint_and_sugg(
69-
cx,
70-
UNNECESSARY_BOX_RETURNS,
71-
return_ty_hir.span,
72-
format!("function returns `Box<{boxed_ty}>` when `{boxed_ty}` implements `Sized`").as_str(),
73-
"change the return type to",
74-
boxed_ty.to_string(),
75-
// the return value and function callers also needs to be changed, so this can't be MachineApplicable
76-
Applicability::Unspecified,
77-
);
78-
}
87+
check_fn_decl(cx, decl);
7988
}
8089
}

tests/ui/unnecessary_box_returns.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![warn(clippy::unnecessary_box_returns)]
22

33
trait Bar {
4+
// lint
45
fn baz(&self) -> Box<usize>;
56
}
67

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
error: function returns `Box<usize>` when `usize` implements `Sized`
2-
--> $DIR/unnecessary_box_returns.rs:17:21
2+
--> $DIR/unnecessary_box_returns.rs:5:22
33
|
4-
LL | fn boxed_usize() -> Box<usize> {
5-
| ^^^^^^^^^^ help: change the return type to: `usize`
4+
LL | fn baz(&self) -> Box<usize>;
5+
| ^^^^^^^^^^ help: change the return type to: `usize`
66
|
77
= note: `-D clippy::unnecessary-box-returns` implied by `-D warnings`
88

9+
error: function returns `Box<usize>` when `usize` implements `Sized`
10+
--> $DIR/unnecessary_box_returns.rs:18:21
11+
|
12+
LL | fn boxed_usize() -> Box<usize> {
13+
| ^^^^^^^^^^ help: change the return type to: `usize`
14+
915
error: function returns `Box<Foo>` when `Foo` implements `Sized`
10-
--> $DIR/unnecessary_box_returns.rs:22:19
16+
--> $DIR/unnecessary_box_returns.rs:23:19
1117
|
1218
LL | fn boxed_foo() -> Box<Foo> {
1319
| ^^^^^^^^ help: change the return type to: `Foo`
1420

15-
error: aborting due to 2 previous errors
21+
error: aborting due to 3 previous errors
1622

0 commit comments

Comments
 (0)