1
1
use clippy_utils:: { diagnostics:: span_lint_and_sugg, ty:: implements_trait} ;
2
2
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 } ;
4
4
use rustc_hir_analysis:: hir_ty_to_ty;
5
5
use rustc_lint:: { LateContext , LateLintPass } ;
6
6
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
@@ -36,7 +36,40 @@ declare_clippy_lint! {
36
36
}
37
37
declare_lint_pass ! ( UnnecessaryBoxReturns => [ UNNECESSARY_BOX_RETURNS ] ) ;
38
38
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
+
39
67
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
+
40
73
fn check_fn (
41
74
& mut self ,
42
75
cx : & LateContext < ' _ > ,
@@ -51,30 +84,6 @@ impl LateLintPass<'_> for UnnecessaryBoxReturns {
51
84
// If this is changed, please also make sure not to call `hir_ty_to_ty` below.
52
85
let FnKind :: ItemFn ( ..) = fn_kind else { return } ;
53
86
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) ;
79
88
}
80
89
}
0 commit comments