@@ -1049,7 +1049,7 @@ fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool {
1049
1049
// If the conditions are met, returns `Some(Position::ImplArg(..))`; otherwise, returns `None`.
1050
1050
// The "is copyable" condition is to avoid the case where removing the `&` means `e` would have to
1051
1051
// be moved, but it cannot be.
1052
- #[ expect( clippy:: too_many_arguments) ]
1052
+ #[ expect( clippy:: too_many_arguments, clippy :: too_many_lines ) ]
1053
1053
fn needless_borrow_impl_arg_position < ' tcx > (
1054
1054
cx : & LateContext < ' tcx > ,
1055
1055
possible_borrowers : & mut Vec < ( LocalDefId , PossibleBorrowerMap < ' tcx , ' tcx > ) > ,
@@ -1092,7 +1092,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
1092
1092
. iter ( )
1093
1093
. filter_map ( |predicate| {
1094
1094
if let PredicateKind :: Trait ( trait_predicate) = predicate. kind ( ) . skip_binder ( )
1095
- && trait_predicate. trait_ref . self_ty ( ) == param_ty. to_ty ( cx. tcx )
1095
+ && trait_predicate. self_ty ( ) == param_ty. to_ty ( cx. tcx )
1096
1096
{
1097
1097
Some ( trait_predicate. trait_ref . def_id )
1098
1098
} else {
@@ -1111,6 +1111,16 @@ fn needless_borrow_impl_arg_position<'tcx>(
1111
1111
return Position :: Other ( precedence) ;
1112
1112
}
1113
1113
1114
+ // See:
1115
+ // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1289294201
1116
+ // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1292225232
1117
+ if projection_predicates
1118
+ . iter ( )
1119
+ . any ( |projection_predicate| is_mixed_projection_predicate ( cx, callee_def_id, projection_predicate) )
1120
+ {
1121
+ return Position :: Other ( precedence) ;
1122
+ }
1123
+
1114
1124
// `substs_with_referent_ty` can be constructed outside of `check_referent` because the same
1115
1125
// elements are modified each time `check_referent` is called.
1116
1126
let mut substs_with_referent_ty = substs_with_expr_ty. to_vec ( ) ;
@@ -1190,8 +1200,39 @@ fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {
1190
1200
} )
1191
1201
}
1192
1202
1193
- fn referent_used_exactly_once < ' tcx > (
1203
+ fn is_mixed_projection_predicate < ' tcx > (
1194
1204
cx : & LateContext < ' tcx > ,
1205
+ callee_def_id : DefId ,
1206
+ projection_predicate : & ProjectionPredicate < ' tcx > ,
1207
+ ) -> bool {
1208
+ let generics = cx. tcx . generics_of ( callee_def_id) ;
1209
+ // The predicate requires the projected type to equal a type parameter from the parent context.
1210
+ if let Some ( term_ty) = projection_predicate. term . ty ( )
1211
+ && let ty:: Param ( term_param_ty) = term_ty. kind ( )
1212
+ && ( term_param_ty. index as usize ) < generics. parent_count
1213
+ {
1214
+ // The inner-most self type is a type parameter from the current function.
1215
+ let mut projection_ty = projection_predicate. projection_ty ;
1216
+ loop {
1217
+ match projection_ty. self_ty ( ) . kind ( ) {
1218
+ ty:: Projection ( inner_projection_ty) => {
1219
+ projection_ty = * inner_projection_ty;
1220
+ }
1221
+ ty:: Param ( param_ty) => {
1222
+ return ( param_ty. index as usize ) >= generics. parent_count ;
1223
+ }
1224
+ _ => {
1225
+ return false ;
1226
+ }
1227
+ }
1228
+ }
1229
+ } else {
1230
+ false
1231
+ }
1232
+ }
1233
+
1234
+ fn referent_used_exactly_once < ' a , ' tcx > (
1235
+ cx : & ' a LateContext < ' tcx > ,
1195
1236
possible_borrowers : & mut Vec < ( LocalDefId , PossibleBorrowerMap < ' tcx , ' tcx > ) > ,
1196
1237
reference : & Expr < ' tcx > ,
1197
1238
) -> bool {
0 commit comments