4
4
use rustc_hir:: def:: Res ;
5
5
use rustc_hir:: def_id:: DefId ;
6
6
use rustc_hir:: { Expr , ExprKind , HirId } ;
7
- use rustc_middle:: ty:: {
8
- self , ClauseKind , GenericArgsRef , ParamTy , ProjectionPredicate , TraitPredicate , Ty ,
9
- } ;
7
+ use rustc_infer:: infer:: canonical:: ir:: TraitPredicate ;
8
+ use rustc_middle:: ty:: { self , ClauseKind , GenericArgsRef , PredicatePolarity , Ty } ;
10
9
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
11
10
use rustc_span:: hygiene:: { ExpnKind , MacroKind } ;
12
11
use rustc_span:: { Span , sym} ;
@@ -122,47 +121,38 @@ fn check_into_iter_stability<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx
122
121
return ;
123
122
} ;
124
123
// Is `expr` a function or method call?
125
- let Some ( ( callee_def_id, _span , generic_args, recv , args ) ) =
124
+ let Some ( ( callee_def_id, span , generic_args, _recv , _args ) ) =
126
125
get_callee_span_generic_args_and_args ( cx, expr)
127
126
else {
128
127
return ;
129
128
} ;
130
- let fn_sig = cx. tcx . fn_sig ( callee_def_id) . instantiate_identity ( ) . skip_binder ( ) ;
131
- for ( arg_index, & input) in fn_sig. inputs ( ) . iter ( ) . enumerate ( ) {
132
- let & ty:: Param ( ParamTy { index : param_index, .. } ) = input. kind ( ) else {
129
+ let predicates = cx. tcx . predicates_of ( callee_def_id) . instantiate ( cx. tcx , generic_args) ;
130
+ for ( predicate, _) in predicates {
131
+ let ClauseKind :: Trait ( TraitPredicate { trait_ref, polarity : PredicatePolarity :: Positive } ) =
132
+ predicate. kind ( ) . skip_binder ( )
133
+ else {
133
134
continue ;
134
135
} ;
135
- let ( trait_predicates, _) = get_input_traits_and_projections ( cx, callee_def_id, input) ;
136
- for TraitPredicate { trait_ref, .. } in trait_predicates {
137
- // Does the function or method require any of its arguments to implement `IntoIterator`?
138
- if trait_ref. def_id != into_iterator_def_id {
139
- continue ;
140
- }
141
- let self_ty_generic_arg = generic_args[ param_index as usize ] ;
142
- let Ok ( Some ( instance) ) = ty:: Instance :: try_resolve (
143
- cx. tcx ,
144
- cx. typing_env ( ) ,
145
- into_iter_fn_def_id,
146
- cx. tcx . mk_args ( & [ self_ty_generic_arg] ) ,
147
- ) else {
148
- continue ;
149
- } ;
150
- // Does the input type's `IntoIterator` implementation have the
151
- // `rustc_lint_query_instability` attribute on its `into_iter` method?
152
- if !cx. tcx . has_attr ( instance. def_id ( ) , sym:: rustc_lint_query_instability) {
153
- return ;
154
- }
155
- let span = if let Some ( recv) = recv {
156
- if arg_index == 0 { recv. span } else { args[ arg_index - 1 ] . span }
157
- } else {
158
- args[ arg_index] . span
159
- } ;
160
- cx. emit_span_lint (
161
- POTENTIAL_QUERY_INSTABILITY ,
162
- span,
163
- QueryInstability { query : cx. tcx . item_name ( instance. def_id ( ) ) } ,
164
- ) ;
136
+ // Does the function or method require any of its arguments to implement `IntoIterator`?
137
+ if trait_ref. def_id != into_iterator_def_id {
138
+ continue ;
139
+ }
140
+ let Ok ( Some ( instance) ) =
141
+ ty:: Instance :: try_resolve ( cx. tcx , cx. typing_env ( ) , into_iter_fn_def_id, trait_ref. args )
142
+ else {
143
+ continue ;
144
+ } ;
145
+ // Does the input type's `IntoIterator` implementation have the
146
+ // `rustc_lint_query_instability` attribute on its `into_iter` method?
147
+ if !cx. tcx . has_attr ( instance. def_id ( ) , sym:: rustc_lint_query_instability) {
148
+ return ;
165
149
}
150
+ let span = span. with_hi ( expr. span . hi ( ) ) ;
151
+ cx. emit_span_lint (
152
+ POTENTIAL_QUERY_INSTABILITY ,
153
+ span,
154
+ QueryInstability { query : cx. tcx . item_name ( instance. def_id ( ) ) } ,
155
+ ) ;
166
156
}
167
157
}
168
158
@@ -188,32 +178,6 @@ fn get_callee_span_generic_args_and_args<'tcx>(
188
178
None
189
179
}
190
180
191
- /// Returns the `TraitPredicate`s and `ProjectionPredicate`s for a function's input type.
192
- fn get_input_traits_and_projections < ' tcx > (
193
- cx : & LateContext < ' tcx > ,
194
- callee_def_id : DefId ,
195
- input : Ty < ' tcx > ,
196
- ) -> ( Vec < TraitPredicate < ' tcx > > , Vec < ProjectionPredicate < ' tcx > > ) {
197
- let mut trait_predicates = Vec :: new ( ) ;
198
- let mut projection_predicates = Vec :: new ( ) ;
199
- for predicate in cx. tcx . param_env ( callee_def_id) . caller_bounds ( ) {
200
- match predicate. kind ( ) . skip_binder ( ) {
201
- ClauseKind :: Trait ( trait_predicate) => {
202
- if trait_predicate. trait_ref . self_ty ( ) == input {
203
- trait_predicates. push ( trait_predicate) ;
204
- }
205
- }
206
- ClauseKind :: Projection ( projection_predicate) => {
207
- if projection_predicate. projection_term . self_ty ( ) == input {
208
- projection_predicates. push ( projection_predicate) ;
209
- }
210
- }
211
- _ => { }
212
- }
213
- }
214
- ( trait_predicates, projection_predicates)
215
- }
216
-
217
181
declare_tool_lint ! {
218
182
/// The `usage_of_ty_tykind` lint detects usages of `ty::TyKind::<kind>`,
219
183
/// where `ty::<kind>` would suffice.
0 commit comments