@@ -15,14 +15,16 @@ extern crate rustc_trait_selection;
15
15
mod constants;
16
16
mod variable_check;
17
17
18
- use clippy_utils:: { get_parent_expr, get_trait_def_id } ;
18
+ use clippy_utils:: get_parent_expr;
19
19
use rustc_data_structures:: fx:: FxHashSet ;
20
20
use rustc_errors:: Applicability ;
21
21
use rustc_hir:: intravisit:: { walk_expr, Visitor } ;
22
22
use rustc_hir:: { self as hir} ;
23
+ use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
24
+ use rustc_infer:: infer:: TyCtxtInferExt ;
23
25
use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
24
- use rustc_middle :: ty :: { self } ;
25
- use rustc_span :: sym ;
26
+ use rustc_span :: { sym , Span } ;
27
+ use rustc_trait_selection :: traits :: ObligationCtxt ;
26
28
use variable_check:: {
27
29
check_implements_par_iter, check_trait_impl, check_variables, generate_suggestion,
28
30
is_type_valid,
@@ -54,21 +56,22 @@ dylint_linting::declare_late_lint! {
54
56
impl < ' tcx > LateLintPass < ' tcx > for ParIter {
55
57
// TODO: implement check crate to check if rayon is present
56
58
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx hir:: Expr < ' _ > ) {
57
- if let hir:: ExprKind :: MethodCall ( path, recv, _args, _span ) = & expr. kind
59
+ if let hir:: ExprKind :: MethodCall ( path, recv, _args, span ) = & expr. kind
58
60
&& let Some ( suggestion) = generate_suggestion ( cx, expr, path)
59
61
{
60
62
let ty = cx. typeck_results ( ) . expr_ty ( recv) ;
61
-
62
63
let par_iter_traits = check_implements_par_iter ( cx, recv) ;
63
64
if !par_iter_traits. is_empty ( ) && is_type_valid ( cx, ty) {
64
65
// TODO: issue with into_par_iter() need to check directly with
65
66
// parallel iterator
66
-
67
+ //
67
68
let mut allowed_methods: FxHashSet < & str > =
68
69
[ "into_iter" , "iter" , "iter_mut" , "map_or" ]
69
70
. into_iter ( )
70
71
. collect ( ) ;
71
- allowed_methods. extend ( get_methods ( cx) ) ;
72
+ for par_iter_trait in par_iter_traits {
73
+ allowed_methods. extend ( get_methods ( cx, par_iter_trait, ty, span) ) ;
74
+ }
72
75
73
76
let mut top_expr = * recv;
74
77
let mut found_iter_method = false ;
@@ -164,25 +167,35 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'_> for Validator<'a, 'tcx> {
164
167
walk_expr ( self , ex)
165
168
}
166
169
}
167
-
168
- fn get_methods < ' tcx > ( cx : & LateContext < ' tcx > ) -> Vec < & ' tcx str > {
169
- let mut res = Vec :: new ( ) ;
170
- if let ( Some ( parallel_iterator_def_id) , Some ( parallel_indexed_iterator_def_id) ) = (
171
- get_trait_def_id ( cx, & [ "rayon" , "iter" , "ParallelIterator" ] ) ,
172
- get_trait_def_id ( cx, & [ "rayon" , "iter" , "IndexedParallelIterator" ] ) ,
173
- ) {
174
- let ids = & [ parallel_iterator_def_id, parallel_indexed_iterator_def_id] ;
175
- for def_id in ids {
176
- let associated_items = cx. tcx . associated_items ( def_id) ;
177
- // Filter out only methods from the associated items
178
- let methods: Vec < & str > = associated_items
179
- . in_definition_order ( )
180
- . filter ( |item| matches ! ( item. kind, ty:: AssocKind :: Fn ) )
181
- . map ( |item| item. name . as_str ( ) )
182
- . collect ( ) ;
183
- res. extend ( methods) ;
184
- }
170
+ use clippy_utils:: ty:: make_normalized_projection;
171
+
172
+ fn get_methods< ' tcx > (
173
+ cx : & LateContext < ' tcx > ,
174
+ trait_def_id : hir:: def_id:: DefId ,
175
+ original_ty : rustc_middle:: ty:: Ty ,
176
+ span : Span ,
177
+ ) -> Vec < & ' tcx str > {
178
+ let res = Vec :: new ( ) ;
179
+
180
+ let tcx = cx. tcx ;
181
+ let infcx = tcx. infer_ctxt ( ) . build ( ) ;
182
+ let origin = TypeVariableOrigin {
183
+ kind : TypeVariableOriginKind :: TypeInference ,
184
+ span,
185
+ } ;
186
+ let ty_var = infcx. next_ty_var ( origin) ;
187
+ if let Some ( param_env) =
188
+ // FIXME: what is assoc_ty
189
+ if let Some ( projection) =
190
+ make_normalized_projection ( tcx, param_env, trait_def_id, sym:: Item , vec ! [ ] )
191
+ {
192
+ let ocx = ObligationCtxt :: new ( & infcx) ;
193
+
194
+ // FIXME: what is obligation
195
+ ocx. register_obligation ( obligation) ;
196
+ let some_errors = ocx. select_where_possible ( ) ;
185
197
}
198
+
186
199
res
187
200
}
188
201
0 commit comments