Skip to content

Commit fe8877a

Browse files
committed
WIP: modify get method function with new info
1 parent ba666ea commit fe8877a

File tree

1 file changed

+52
-50
lines changed

1 file changed

+52
-50
lines changed

lints/par_iter/src/lib.rs

+52-50
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,17 @@ extern crate rustc_trait_selection;
1515
mod constants;
1616
mod variable_check;
1717

18-
use clippy_utils::get_parent_expr;
18+
use clippy_utils::{get_parent_expr, get_trait_def_id};
1919
use rustc_data_structures::fx::FxHashSet;
2020
use rustc_errors::Applicability;
2121
use rustc_hir::intravisit::{walk_expr, Visitor};
22-
use rustc_hir::{self as hir, GenericArg};
22+
use rustc_hir::{self as hir};
2323
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
2424
use rustc_infer::infer::TyCtxtInferExt;
2525
use rustc_infer::traits::{Obligation, ObligationCause};
2626
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;
3029
use rustc_trait_selection::traits::ObligationCtxt;
3130
use variable_check::{
3231
check_implements_par_iter, check_trait_impl, check_variables, generate_suggestion,
@@ -59,21 +58,20 @@ dylint_linting::declare_late_lint! {
5958
impl<'tcx> LateLintPass<'tcx> for ParIter {
6059
// TODO: implement check crate to check if rayon is present
6160
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
6362
&& let Some(suggestion) = generate_suggestion(cx, expr, path)
6463
{
65-
let ty = cx.typeck_results().expr_ty(recv);
6664
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)) {
6866
// TODO: issue with into_par_iter() need to check directly with
6967
// parallel iterator
7068
//
7169
let mut allowed_methods: FxHashSet<&str> =
7270
["into_iter", "iter", "iter_mut", "map_or"]
7371
.into_iter()
7472
.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));
7775
}
7876

7977
let mut top_expr = *recv;
@@ -170,55 +168,59 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'_> for Validator<'a, 'tcx> {
170168
walk_expr(self, ex)
171169
}
172170
}
173-
use clippy_utils::ty::make_normalized_projection;
174171

175-
fn get_methods<'tcx>(
172+
fn get_all_methods<'tcx>(
176173
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,
180176
) -> 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);
202186

203-
let norm_ty = infcx.next_ty_var(TypeVariableOrigin {
187+
// Create a new inference variable, ?new
188+
let ty = infcx.next_ty_var(TypeVariableOrigin {
204189
kind: TypeVariableOriginKind::TypeInference,
205-
span: cause.span,
190+
span: original_expr.span,
206191
});
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(),
211203
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+
}
216210

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+
}
220223
}
221-
// FIXME: what is assoc_ty
222224

223225
res
224226
}

0 commit comments

Comments
 (0)