@@ -15,18 +15,17 @@ extern crate rustc_trait_selection;
15
15
mod constants;
16
16
mod variable_check;
17
17
18
- use clippy_utils:: get_parent_expr;
18
+ use clippy_utils:: { get_parent_expr, get_trait_def_id } ;
19
19
use rustc_data_structures:: fx:: FxHashSet ;
20
20
use rustc_errors:: Applicability ;
21
21
use rustc_hir:: intravisit:: { walk_expr, Visitor } ;
22
- use rustc_hir:: { self as hir, GenericArg } ;
22
+ use rustc_hir:: { self as hir} ;
23
23
use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
24
24
use rustc_infer:: infer:: TyCtxtInferExt ;
25
25
use rustc_infer:: traits:: { Obligation , ObligationCause } ;
26
26
use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
27
- use rustc_middle:: query:: Key ;
28
- use rustc_middle:: ty:: { AliasTy , Binder , ProjectionPredicate } ;
29
- use rustc_span:: { sym, Span } ;
27
+ use rustc_middle:: ty:: { self , GenericArgs } ;
28
+ use rustc_span:: sym;
30
29
use rustc_trait_selection:: traits:: ObligationCtxt ;
31
30
use variable_check:: {
32
31
check_implements_par_iter, check_trait_impl, check_variables, generate_suggestion,
@@ -59,21 +58,20 @@ dylint_linting::declare_late_lint! {
59
58
impl < ' tcx > LateLintPass < ' tcx > for ParIter {
60
59
// TODO: implement check crate to check if rayon is present
61
60
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx hir:: Expr < ' _ > ) {
62
- if let hir:: ExprKind :: MethodCall ( path, recv, _args, span ) = & expr. kind
61
+ if let hir:: ExprKind :: MethodCall ( path, recv, _args, _span ) = & expr. kind
63
62
&& let Some ( suggestion) = generate_suggestion ( cx, expr, path)
64
63
{
65
- let ty = cx. typeck_results ( ) . expr_ty ( recv) ;
66
64
let par_iter_traits = check_implements_par_iter ( cx, recv) ;
67
- if !par_iter_traits. is_empty ( ) && is_type_valid ( cx, ty ) {
65
+ if !par_iter_traits. is_empty ( ) && is_type_valid ( cx, cx . typeck_results ( ) . expr_ty ( recv ) ) {
68
66
// TODO: issue with into_par_iter() need to check directly with
69
67
// parallel iterator
70
68
//
71
69
let mut allowed_methods: FxHashSet < & str > =
72
70
[ "into_iter" , "iter" , "iter_mut" , "map_or" ]
73
71
. into_iter ( )
74
72
. collect ( ) ;
75
- for par_iter_trait in par_iter_traits {
76
- allowed_methods. extend ( get_methods ( cx, par_iter_trait , ty , span ) ) ;
73
+ for into_par_iter_trait in par_iter_traits {
74
+ allowed_methods. extend ( get_all_methods ( cx, into_par_iter_trait , * recv ) ) ;
77
75
}
78
76
79
77
let mut top_expr = * recv;
@@ -170,55 +168,59 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'_> for Validator<'a, 'tcx> {
170
168
walk_expr ( self , ex)
171
169
}
172
170
}
173
- use clippy_utils:: ty:: make_normalized_projection;
174
171
175
- fn get_methods < ' tcx > (
172
+ fn get_all_methods < ' tcx > (
176
173
cx : & LateContext < ' tcx > ,
177
- trait_def_id : hir:: def_id:: DefId ,
178
- original_ty : rustc_middle:: ty:: Ty ,
179
- span : Span ,
174
+ into_iter_trait : hir:: def_id:: DefId ,
175
+ original_expr : & hir:: Expr ,
180
176
) -> Vec < & ' tcx str > {
181
- let res = Vec :: new ( ) ;
182
-
183
- let tcx = cx. tcx ;
184
- let infcx = tcx. infer_ctxt ( ) . build ( ) ;
185
-
186
- if let Some ( ty_def_id) = original_ty. ty_def_id ( )
187
- && let param_env = tcx. param_env ( ty_def_id)
188
- && let Some ( projection) =
189
- make_normalized_projection ( tcx, param_env, trait_def_id, sym:: Item , vec ! [ ] )
190
- {
191
- let cause = ObligationCause :: dummy ( ) ;
192
- let origin = TypeVariableOrigin {
193
- kind : TypeVariableOriginKind :: TypeInference ,
194
- span,
195
- } ;
196
- let projection_ty = infcx. next_ty_var ( origin) ;
197
-
198
- let projection = ProjectionPredicate {
199
- projection_ty : AliasTy :: new ( tcx, trait_def_id, vec ! [ ] ) ,
200
- term : tcx. mk_ty_var ( tcx. next_ty_var_id ( ) ) , // Or the specific type you expect the projection to equal.
201
- } ;
177
+ let mut res = Vec :: new ( ) ;
178
+ if let ( Some ( parallel_iterator_def_id) , Some ( parallel_indexed_iterator_def_id) ) = (
179
+ get_trait_def_id ( cx, & [ "rayon" , "iter" , "ParallelIterator" ] ) ,
180
+ get_trait_def_id ( cx, & [ "rayon" , "iter" , "IndexedParallelIterator" ] ) ,
181
+ ) {
182
+ let tcx = cx. tcx ;
183
+ let infcx = tcx. infer_ctxt ( ) . build ( ) ;
184
+ let ocx = ObligationCtxt :: new ( & infcx) ;
185
+ let param_env = tcx. param_env ( into_iter_trait) ;
202
186
203
- let norm_ty = infcx. next_ty_var ( TypeVariableOrigin {
187
+ // Create a new inference variable, ?new
188
+ let ty = infcx. next_ty_var ( TypeVariableOrigin {
204
189
kind : TypeVariableOriginKind :: TypeInference ,
205
- span : cause . span ,
190
+ span : original_expr . span ,
206
191
} ) ;
207
-
208
- // Create a projection obligation
209
- let obligation = Obligation :: new (
210
- cause. clone ( ) ,
192
+ let args = GenericArgs :: for_item ( tcx, into_iter_trait, |_, _| ty. into ( ) ) ;
193
+ let projection_ty = ty:: AliasTy :: new ( tcx, into_iter_trait, args) ;
194
+ let projection = ty:: Binder :: dummy ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection (
195
+ ty:: ProjectionPredicate {
196
+ projection_ty,
197
+ term : ty. into ( ) ,
198
+ } ,
199
+ ) ) ) ;
200
+ ocx. register_obligation ( Obligation :: new (
201
+ tcx,
202
+ ObligationCause :: dummy ( ) ,
211
203
param_env,
212
- projection. to_predicate ( tcx, norm_ty) ,
213
- ) ;
214
-
215
- let ocx = ObligationCtxt :: new ( & infcx) ;
204
+ projection,
205
+ ) ) ;
206
+ let errors = ocx. select_where_possible ( ) ;
207
+ if errors. is_empty ( ) {
208
+ dbg ! ( "no errors" ) ; // TODO: do something else here
209
+ }
216
210
217
- // FIXME: what is obligation
218
- ocx. register_obligation ( obligation) ;
219
- let some_errors = ocx. select_where_possible ( ) ;
211
+ // TODO: use the previous steps to determine which ids should be run
212
+ let ids = & [ parallel_iterator_def_id, parallel_indexed_iterator_def_id] ;
213
+ for def_id in ids {
214
+ let associated_items = cx. tcx . associated_items ( def_id) ;
215
+ // Filter out only methods from the associated items
216
+ let methods: Vec < & str > = associated_items
217
+ . in_definition_order ( )
218
+ . filter ( |item| matches ! ( item. kind, ty:: AssocKind :: Fn ) )
219
+ . map ( |item| item. name . as_str ( ) )
220
+ . collect ( ) ;
221
+ res. extend ( methods) ;
222
+ }
220
223
}
221
- // FIXME: what is assoc_ty
222
224
223
225
res
224
226
}
0 commit comments