@@ -4,6 +4,7 @@ use clippy_utils::sym;
4
4
use rustc_errors:: Applicability ;
5
5
use rustc_hir:: { Expr , ExprKind } ;
6
6
use rustc_lint:: { LateContext , LateLintPass } ;
7
+ use rustc_middle:: ty:: adjustment:: { Adjust , PointerCoercion } ;
7
8
use rustc_middle:: ty:: { self , ExistentialPredicate , Ty , TyCtxt } ;
8
9
use rustc_session:: declare_lint_pass;
9
10
@@ -49,23 +50,18 @@ declare_lint_pass!(CoerceContainerToAny => [COERCE_CONTAINER_TO_ANY]);
49
50
50
51
impl < ' tcx > LateLintPass < ' tcx > for CoerceContainerToAny {
51
52
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , e : & ' tcx Expr < ' _ > ) {
52
- // If this expression has an effective type of `&dyn Any` ...
53
- {
54
- let coerced_ty = cx. typeck_results ( ) . expr_ty_adjusted ( e) ;
55
-
56
- let ty:: Ref ( _, coerced_ref_ty, _) = * coerced_ty. kind ( ) else {
57
- return ;
58
- } ;
59
- if !is_dyn_any ( cx. tcx , coerced_ref_ty) {
60
- return ;
61
- }
53
+ // If this expression was coerced to `&dyn Any` ...
54
+ if !cx. typeck_results ( ) . expr_adjustments ( e) . last ( ) . is_some_and ( |adj| {
55
+ matches ! ( adj. kind, Adjust :: Pointer ( PointerCoercion :: Unsize ) ) && is_ref_dyn_any ( cx. tcx , adj. target )
56
+ } ) {
57
+ return ;
62
58
}
63
59
64
60
let expr_ty = cx. typeck_results ( ) . expr_ty ( e) ;
65
61
let ty:: Ref ( _, expr_ref_ty, _) = * expr_ty. kind ( ) else {
66
62
return ;
67
63
} ;
68
- // ... but only due to coercion ...
64
+ // ... but it's not actually `&dyn Any` ...
69
65
if is_dyn_any ( cx. tcx , expr_ref_ty) {
70
66
return ;
71
67
}
@@ -89,12 +85,19 @@ impl<'tcx> LateLintPass<'tcx> for CoerceContainerToAny {
89
85
e. span ,
90
86
format ! ( "coercing `{expr_ty}` to `&dyn Any`" ) ,
91
87
"consider dereferencing" ,
92
- format ! ( "&{}{}" , str :: repeat( "*" , deref_count) , snippet( cx, span, "x " ) ) ,
88
+ format ! ( "&{}{}" , str :: repeat( "*" , deref_count) , snippet( cx, span, ".. " ) ) ,
93
89
Applicability :: MaybeIncorrect ,
94
90
) ;
95
91
}
96
92
}
97
93
94
+ fn is_ref_dyn_any ( tcx : TyCtxt < ' _ > , ty : Ty < ' _ > ) -> bool {
95
+ let ty:: Ref ( _, ref_ty, _) = * ty. kind ( ) else {
96
+ return false ;
97
+ } ;
98
+ is_dyn_any ( tcx, ref_ty)
99
+ }
100
+
98
101
fn is_dyn_any ( tcx : TyCtxt < ' _ > , ty : Ty < ' _ > ) -> bool {
99
102
let ty:: Dynamic ( traits, ..) = ty. kind ( ) else {
100
103
return false ;
0 commit comments