From fceab9fb348becb62f404d0d9381a49446beac7a Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Mon, 14 Aug 2017 15:06:14 +0300 Subject: [PATCH] make probe priority logic clearer --- src/librustc_typeck/check/method/probe.rs | 66 ++++++++++------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 5e5a27f2ba13..30683eeeba89 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1116,21 +1116,17 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { let steps = self.steps.clone(); // find the first step that works - steps.iter().filter_map(|step| self.pick_step(step)).next() - } - - fn pick_step(&mut self, step: &CandidateStep<'tcx>) -> Option> { - debug!("pick_step: step={:?}", step); - - if step.self_ty.references_error() { - return None; - } - - if let Some(result) = self.pick_by_value_method(step) { - return Some(result); - } - - self.pick_autorefd_method(step) + steps + .iter() + .filter(|step| { + debug!("pick_core: step={:?}", step); + !step.self_ty.references_error() + }).flat_map(|step| { + self.pick_by_value_method(step).or_else(|| { + self.pick_autorefd_method(step, hir::MutImmutable).or_else(|| { + self.pick_autorefd_method(step, hir::MutMutable) + })})}) + .next() } fn pick_by_value_method(&mut self, step: &CandidateStep<'tcx>) -> Option> { @@ -1161,36 +1157,30 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { }) } - fn pick_autorefd_method(&mut self, step: &CandidateStep<'tcx>) -> Option> { + fn pick_autorefd_method(&mut self, step: &CandidateStep<'tcx>, mutbl: hir::Mutability) + -> Option> { let tcx = self.tcx; // In general, during probing we erase regions. See // `impl_self_ty()` for an explanation. let region = tcx.types.re_erased; - // Search through mutabilities in order to find one where pick works: - [hir::MutImmutable, hir::MutMutable] - .iter() - .filter_map(|&m| { - let autoref_ty = tcx.mk_ref(region, - ty::TypeAndMut { - ty: step.self_ty, - mutbl: m, - }); - self.pick_method(autoref_ty).map(|r| { - r.map(|mut pick| { - pick.autoderefs = step.autoderefs; - pick.autoref = Some(m); - pick.unsize = if step.unsize { - Some(step.self_ty) - } else { - None - }; - pick - }) - }) + let autoref_ty = tcx.mk_ref(region, + ty::TypeAndMut { + ty: step.self_ty, mutbl + }); + self.pick_method(autoref_ty).map(|r| { + r.map(|mut pick| { + pick.autoderefs = step.autoderefs; + pick.autoref = Some(mutbl); + pick.unsize = if step.unsize { + Some(step.self_ty) + } else { + None + }; + pick }) - .nth(0) + }) } fn pick_method(&mut self, self_ty: Ty<'tcx>) -> Option> {