diff options
| author | bors <bors@rust-lang.org> | 2014-05-31 07:56:39 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-05-31 07:56:39 -0700 |
| commit | 2f221c766b10867a30d799d0899125b2dcccb872 (patch) | |
| tree | f0cad347ce5b9bc8d461fc2eb94949e4ee4c3a9d | |
| parent | 0839e940a517fcf6cf8124b22399e75c31703e2c (diff) | |
| parent | cd844c5fb54913bced99a046230e9af7b3704c9e (diff) | |
| download | rust-2f221c766b10867a30d799d0899125b2dcccb872.tar.gz rust-2f221c766b10867a30d799d0899125b2dcccb872.zip | |
auto merge of #14563 : dotdash/rust/clone_kill, r=huonw
By dropping the intermediate vector that holds the relevant candidates including duplicates and directly building the vector that has the duplicates removed we can eliminate quite a few allocations. This reduces the times for type checking by 5-10% (measured with libstd, libsyntax and librustc).
| -rw-r--r-- | src/librustc/middle/typeck/check/method.rs | 44 |
1 files changed, 10 insertions, 34 deletions
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 8cea03c59e7..9afb5b48be5 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -1026,13 +1026,7 @@ impl<'a> LookupContext<'a> { fn consider_candidates(&self, rcvr_ty: ty::t, candidates: &[Candidate]) -> Option<MethodCallee> { - // FIXME(pcwalton): Do we need to clone here? - let relevant_candidates: Vec<Candidate> = - candidates.iter().map(|c| (*c).clone()). - filter(|c| self.is_relevant(rcvr_ty, c)).collect(); - - let relevant_candidates = - self.merge_candidates(relevant_candidates.as_slice()); + let relevant_candidates = self.filter_candidates(rcvr_ty, candidates); if relevant_candidates.len() == 0 { return None; @@ -1069,22 +1063,16 @@ impl<'a> LookupContext<'a> { Some(self.confirm_candidate(rcvr_ty, relevant_candidates.get(0))) } - fn merge_candidates(&self, candidates: &[Candidate]) -> Vec<Candidate> { - let mut merged = Vec::new(); - let mut i = 0; - while i < candidates.len() { - let candidate_a = &candidates[i]; - - let mut skip = false; + fn filter_candidates(&self, rcvr_ty: ty::t, candidates: &[Candidate]) -> Vec<Candidate> { + let mut relevant_candidates: Vec<Candidate> = Vec::new(); - let mut j = i + 1; - while j < candidates.len() { - let candidate_b = &candidates[j]; + for candidate_a in candidates.iter().filter(|&c| self.is_relevant(rcvr_ty, c)) { + // Skip this one if we already have one like it + if !relevant_candidates.iter().any(|candidate_b| { debug!("attempting to merge {} and {}", candidate_a.repr(self.tcx()), candidate_b.repr(self.tcx())); - let candidates_same = match (&candidate_a.origin, - &candidate_b.origin) { + match (&candidate_a.origin, &candidate_b.origin) { (&MethodParam(ref p1), &MethodParam(ref p2)) => { let same_trait = p1.trait_id == p2.trait_id; let same_method = p1.method_num == p2.method_num; @@ -1095,25 +1083,13 @@ impl<'a> LookupContext<'a> { same_trait && same_method && same_param } _ => false - }; - if candidates_same { - skip = true; - break; } - j += 1; - } - - i += 1; - - if skip { - // There are more than one of these and we need only one - continue; - } else { - merged.push(candidate_a.clone()); + }) { + relevant_candidates.push(candidate_a.clone()); } } - return merged; + relevant_candidates } fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate) |
