Skip to content

Commit

Permalink
Track trait import to method resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
sanxiyn committed Dec 11, 2015
1 parent 729bdc2 commit 4acdc52
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 17 deletions.
7 changes: 6 additions & 1 deletion src/librustc/middle/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2751,8 +2751,13 @@ pub type FreevarMap = NodeMap<Vec<Freevar>>;

pub type CaptureModeMap = NodeMap<hir::CaptureClause>;

pub struct TraitCandidate {
pub def_id: DefId,
pub import_id: Option<NodeId>,
}

// Trait method resolution
pub type TraitMap = NodeMap<Vec<DefId>>;
pub type TraitMap = NodeMap<Vec<TraitCandidate>>;

// Map from the NodeId of a glob import to a list of items which are actually
// imported.
Expand Down
20 changes: 13 additions & 7 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ use rustc::middle::def_id::DefId;
use rustc::middle::pat_util::pat_bindings;
use rustc::middle::privacy::*;
use rustc::middle::subst::{ParamSpace, FnSpace, TypeSpace};
use rustc::middle::ty::{Freevar, FreevarMap, TraitMap, GlobMap};
use rustc::middle::ty::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
use rustc::util::nodemap::{NodeMap, DefIdSet, FnvHashMap};

use syntax::ast;
Expand Down Expand Up @@ -3608,14 +3608,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}

fn get_traits_containing_item(&mut self, name: Name) -> Vec<DefId> {
fn get_traits_containing_item(&mut self, name: Name) -> Vec<TraitCandidate> {
debug!("(getting traits containing item) looking for '{}'", name);

fn add_trait_info(found_traits: &mut Vec<DefId>, trait_def_id: DefId, name: Name) {
fn add_trait_info(found_traits: &mut Vec<TraitCandidate>,
trait_def_id: DefId,
import_id: Option<NodeId>,
name: Name) {
debug!("(adding trait info) found trait {:?} for method '{}'",
trait_def_id,
name);
found_traits.push(trait_def_id);
found_traits.push(TraitCandidate {
def_id: trait_def_id,
import_id: import_id,
});
}

let mut found_traits = Vec::new();
Expand All @@ -3625,7 +3631,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
match self.current_trait_ref {
Some((trait_def_id, _)) => {
if self.trait_item_map.contains_key(&(name, trait_def_id)) {
add_trait_info(&mut found_traits, trait_def_id, name);
add_trait_info(&mut found_traits, trait_def_id, None, name);
}
}
None => {} // Nothing to do.
Expand All @@ -3645,7 +3651,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
_ => continue,
};
if self.trait_item_map.contains_key(&(name, trait_def_id)) {
add_trait_info(&mut found_traits, trait_def_id, name);
add_trait_info(&mut found_traits, trait_def_id, None, name);
}
}
}
Expand All @@ -3661,8 +3667,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
Some(..) | None => continue,
};
if self.trait_item_map.contains_key(&(name, did)) {
add_trait_info(&mut found_traits, did, name);
let id = import.type_ns.id;
add_trait_info(&mut found_traits, did, Some(id), name);
self.used_imports.insert((id, TypeNS));
let trait_name = self.get_trait_name(did);
self.record_import_use(id, trait_name);
Expand Down
35 changes: 26 additions & 9 deletions src/librustc_typeck/check/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ struct ProbeContext<'a, 'tcx:'a> {
inherent_candidates: Vec<Candidate<'tcx>>,
extension_candidates: Vec<Candidate<'tcx>>,
impl_dups: HashSet<DefId>,
import_id: Option<ast::NodeId>,

/// Collects near misses when the candidate functions are missing a `self` keyword and is only
/// used for error reporting
Expand All @@ -66,6 +67,7 @@ struct Candidate<'tcx> {
xform_self_ty: Ty<'tcx>,
item: ty::ImplOrTraitItem<'tcx>,
kind: CandidateKind<'tcx>,
import_id: Option<ast::NodeId>,
}

#[derive(Debug)]
Expand All @@ -83,6 +85,7 @@ enum CandidateKind<'tcx> {
pub struct Pick<'tcx> {
pub item: ty::ImplOrTraitItem<'tcx>,
pub kind: PickKind<'tcx>,
pub import_id: Option<ast::NodeId>,

// Indicates that the source expression should be autoderef'd N times
//
Expand Down Expand Up @@ -246,6 +249,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
inherent_candidates: Vec::new(),
extension_candidates: Vec::new(),
impl_dups: HashSet::new(),
import_id: None,
steps: Rc::new(steps),
opt_simplified_steps: opt_simplified_steps,
static_candidates: Vec::new(),
Expand Down Expand Up @@ -427,7 +431,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
self.inherent_candidates.push(Candidate {
xform_self_ty: xform_self_ty,
item: item,
kind: InherentImplCandidate(impl_substs, obligations)
kind: InherentImplCandidate(impl_substs, obligations),
import_id: self.import_id,
});
}

Expand Down Expand Up @@ -455,7 +460,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
this.inherent_candidates.push(Candidate {
xform_self_ty: xform_self_ty,
item: item,
kind: ObjectCandidate
kind: ObjectCandidate,
import_id: this.import_id,
});
});
}
Expand Down Expand Up @@ -524,7 +530,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
this.inherent_candidates.push(Candidate {
xform_self_ty: xform_self_ty,
item: item,
kind: WhereClauseCandidate(poly_trait_ref)
kind: WhereClauseCandidate(poly_trait_ref),
import_id: this.import_id,
});
});
}
Expand Down Expand Up @@ -568,9 +575,13 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
let mut duplicates = HashSet::new();
let opt_applicable_traits = self.fcx.ccx.trait_map.get(&expr_id);
if let Some(applicable_traits) = opt_applicable_traits {
for &trait_did in applicable_traits {
for trait_candidate in applicable_traits {
let trait_did = trait_candidate.def_id;
if duplicates.insert(trait_did) {
try!(self.assemble_extension_candidates_for_trait(trait_did));
self.import_id = trait_candidate.import_id;
let result = self.assemble_extension_candidates_for_trait(trait_did);
self.import_id = None;
try!(result);
}
}
}
Expand Down Expand Up @@ -670,7 +681,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
self.extension_candidates.push(Candidate {
xform_self_ty: xform_self_ty,
item: item.clone(),
kind: ExtensionImplCandidate(impl_def_id, impl_substs, obligations)
kind: ExtensionImplCandidate(impl_def_id, impl_substs, obligations),
import_id: self.import_id,
});
});
}
Expand Down Expand Up @@ -745,7 +757,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
self.inherent_candidates.push(Candidate {
xform_self_ty: xform_self_ty,
item: item.clone(),
kind: TraitCandidate
kind: TraitCandidate,
import_id: self.import_id,
});
}

Expand Down Expand Up @@ -802,7 +815,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
self.extension_candidates.push(Candidate {
xform_self_ty: xform_self_ty,
item: item.clone(),
kind: TraitCandidate
kind: TraitCandidate,
import_id: self.import_id,
});
}
}
Expand Down Expand Up @@ -833,7 +847,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
self.extension_candidates.push(Candidate {
xform_self_ty: xform_self_ty,
item: item.clone(),
kind: WhereClauseCandidate(poly_bound)
kind: WhereClauseCandidate(poly_bound),
import_id: self.import_id,
});
}
}
Expand Down Expand Up @@ -1126,6 +1141,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
Some(Pick {
item: probes[0].item.clone(),
kind: TraitPick,
import_id: probes[0].import_id,
autoderefs: 0,
autoref: None,
unsize: None
Expand Down Expand Up @@ -1329,6 +1345,7 @@ impl<'tcx> Candidate<'tcx> {
WhereClausePick(trait_ref.clone())
}
},
import_id: self.import_id,
autoderefs: 0,
autoref: None,
unsize: None
Expand Down

0 comments on commit 4acdc52

Please sign in to comment.