@@ -17,8 +17,8 @@ use rustc_infer::infer::TyCtxtInferExt;
17
17
use rustc_lint:: { LateContext , LateLintPass } ;
18
18
use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AutoBorrow , AutoBorrowMutability } ;
19
19
use rustc_middle:: ty:: {
20
- self , subst:: Subst , EarlyBinder , FnSig , ParamTy , PredicateKind , ProjectionPredicate , TraitPredicate , TraitRef , Ty ,
21
- TyCtxt , TypeVisitable , TypeckResults ,
20
+ self , subst:: Subst , EarlyBinder , FnSig , ParamTy , PredicateKind , ProjectionPredicate , Ty , TyCtxt , TypeVisitable ,
21
+ TypeckResults ,
22
22
} ;
23
23
use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
24
24
use rustc_span:: { symbol:: sym, Span , Symbol } ;
@@ -985,20 +985,24 @@ fn needless_borrow_impl_arg_position<'tcx>(
985
985
let mut trait_with_ref_mut_self_method = false ;
986
986
987
987
// If no traits were found, or only the `Sized` or `Any` traits were found, return.
988
- if predicates. iter ( ) . all ( |predicate| {
989
- if let PredicateKind :: Trait ( TraitPredicate {
990
- trait_ref : TraitRef {
991
- def_id : trait_def_id, ..
992
- } ,
993
- ..
994
- } ) = predicate. kind ( ) . skip_binder ( )
995
- {
996
- trait_with_ref_mut_self_method |= has_ref_mut_self_method ( cx, trait_def_id) ;
988
+ if predicates
989
+ . iter ( )
990
+ . filter_map ( |predicate| {
991
+ if let PredicateKind :: Trait ( trait_predicate) = predicate. kind ( ) . skip_binder ( )
992
+ && trait_predicate. trait_ref . self_ty ( ) == param_ty. to_ty ( cx. tcx )
993
+ {
994
+ Some ( trait_predicate. trait_ref . def_id )
995
+ } else {
996
+ None
997
+ }
998
+ } )
999
+ . inspect ( |trait_def_id| {
1000
+ trait_with_ref_mut_self_method |= has_ref_mut_self_method ( cx, * trait_def_id) ;
1001
+ } )
1002
+ . all ( |trait_def_id| {
997
1003
Some ( trait_def_id) == sized_trait_def_id || cx. tcx . is_diagnostic_item ( sym:: Any , trait_def_id)
998
- } else {
999
- true
1000
- }
1001
- } ) {
1004
+ } )
1005
+ {
1002
1006
return Position :: Other ( precedence) ;
1003
1007
}
1004
1008
@@ -1083,55 +1087,41 @@ fn replace_types<'tcx>(
1083
1087
substs : & mut [ ty:: GenericArg < ' tcx > ] ,
1084
1088
) -> bool {
1085
1089
let mut replaced = BitSet :: new_empty ( substs. len ( ) ) ;
1086
- let mut deque = VecDeque :: with_capacity ( substs. len ( ) ) ;
1087
-
1088
- if fn_sig
1089
- . inputs_and_output
1090
- . iter ( )
1091
- . enumerate ( )
1092
- . any ( |( i, ty) | i != arg_index && contains_ty ( ty, param_ty. to_ty ( cx. tcx ) ) )
1093
- {
1094
- return false ;
1095
- }
1096
-
1097
- substs[ param_ty. index as usize ] = ty:: GenericArg :: from ( new_ty) ;
1098
1090
1091
+ let mut deque = VecDeque :: with_capacity ( substs. len ( ) ) ;
1099
1092
deque. push_back ( ( param_ty, new_ty) ) ;
1100
1093
1101
1094
while let Some ( ( param_ty, new_ty) ) = deque. pop_front ( ) {
1102
- for projection_predicate in projection_predicates {
1103
- if projection_predicate. projection_ty . self_ty ( ) == param_ty. to_ty ( cx. tcx )
1104
- && let ty:: Term :: Ty ( term_ty) = projection_predicate. term
1105
- && let ty:: Param ( term_param_ty) = term_ty. kind ( )
1106
- {
1107
- let item_def_id = projection_predicate. projection_ty . item_def_id ;
1108
- let assoc_item = cx. tcx . associated_item ( item_def_id) ;
1109
- let projection = cx. tcx
1110
- . mk_projection ( assoc_item. def_id , cx. tcx . mk_substs_trait ( new_ty, & [ ] ) ) ;
1111
- let projected_ty = cx. tcx . normalize_erasing_regions ( cx. param_env , projection) ;
1112
-
1113
- let inserted = replaced. insert ( term_param_ty. index ) ;
1114
-
1115
- let new_generic_arg = ty:: GenericArg :: from ( projected_ty) ;
1116
-
1117
- if substs[ term_param_ty. index as usize ] == new_generic_arg {
1118
- continue ;
1119
- }
1095
+ let new_generic_arg = ty:: GenericArg :: from ( new_ty) ;
1096
+
1097
+ // If `replaced.is_empty()`, then `param_ty` and `new_ty` are those initially passed in.
1098
+ if substs[ param_ty. index as usize ] != new_generic_arg
1099
+ && !fn_sig
1100
+ . inputs_and_output
1101
+ . iter ( )
1102
+ . enumerate ( )
1103
+ . all ( |( i, ty) | ( replaced. is_empty ( ) && i == arg_index) || !contains_ty ( ty, param_ty. to_ty ( cx. tcx ) ) )
1104
+ {
1105
+ return false ;
1106
+ }
1120
1107
1121
- // The next line provides some protection against infinite loops.
1122
- assert ! ( inserted) ;
1108
+ substs[ param_ty. index as usize ] = new_generic_arg;
1123
1109
1124
- if fn_sig
1125
- . inputs_and_output
1126
- . iter ( )
1127
- . any ( |ty| contains_ty ( ty, term_param_ty. to_ty ( cx. tcx ) ) )
1110
+ // The `replaced.insert(...)` check provides some protection against infinite loops.
1111
+ if replaced. insert ( param_ty. index ) {
1112
+ for projection_predicate in projection_predicates {
1113
+ if projection_predicate. projection_ty . self_ty ( ) == param_ty. to_ty ( cx. tcx )
1114
+ && let ty:: Term :: Ty ( term_ty) = projection_predicate. term
1115
+ && let ty:: Param ( term_param_ty) = term_ty. kind ( )
1128
1116
{
1129
- return false ;
1130
- }
1117
+ let item_def_id = projection_predicate. projection_ty . item_def_id ;
1118
+ let assoc_item = cx. tcx . associated_item ( item_def_id) ;
1119
+ let projection = cx. tcx
1120
+ . mk_projection ( assoc_item. def_id , cx. tcx . mk_substs_trait ( new_ty, & [ ] ) ) ;
1121
+ let projected_ty = cx. tcx . normalize_erasing_regions ( cx. param_env , projection) ;
1131
1122
1132
- substs[ term_param_ty. index as usize ] = new_generic_arg;
1133
-
1134
- deque. push_back ( ( * term_param_ty, projected_ty) ) ;
1123
+ deque. push_back ( ( * term_param_ty, projected_ty) ) ;
1124
+ }
1135
1125
}
1136
1126
}
1137
1127
}
0 commit comments