Skip to content

Commit 4acdc52

Browse files
committed
Track trait import to method resolution
1 parent 729bdc2 commit 4acdc52

File tree

3 files changed

+45
-17
lines changed

3 files changed

+45
-17
lines changed

src/librustc/middle/ty/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -2751,8 +2751,13 @@ pub type FreevarMap = NodeMap<Vec<Freevar>>;
27512751

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

2754+
pub struct TraitCandidate {
2755+
pub def_id: DefId,
2756+
pub import_id: Option<NodeId>,
2757+
}
2758+
27542759
// Trait method resolution
2755-
pub type TraitMap = NodeMap<Vec<DefId>>;
2760+
pub type TraitMap = NodeMap<Vec<TraitCandidate>>;
27562761

27572762
// Map from the NodeId of a glob import to a list of items which are actually
27582763
// imported.

src/librustc_resolve/lib.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ use rustc::middle::def_id::DefId;
6060
use rustc::middle::pat_util::pat_bindings;
6161
use rustc::middle::privacy::*;
6262
use rustc::middle::subst::{ParamSpace, FnSpace, TypeSpace};
63-
use rustc::middle::ty::{Freevar, FreevarMap, TraitMap, GlobMap};
63+
use rustc::middle::ty::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
6464
use rustc::util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
6565

6666
use syntax::ast;
@@ -3608,14 +3608,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
36083608
}
36093609
}
36103610

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

3614-
fn add_trait_info(found_traits: &mut Vec<DefId>, trait_def_id: DefId, name: Name) {
3614+
fn add_trait_info(found_traits: &mut Vec<TraitCandidate>,
3615+
trait_def_id: DefId,
3616+
import_id: Option<NodeId>,
3617+
name: Name) {
36153618
debug!("(adding trait info) found trait {:?} for method '{}'",
36163619
trait_def_id,
36173620
name);
3618-
found_traits.push(trait_def_id);
3621+
found_traits.push(TraitCandidate {
3622+
def_id: trait_def_id,
3623+
import_id: import_id,
3624+
});
36193625
}
36203626

36213627
let mut found_traits = Vec::new();
@@ -3625,7 +3631,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
36253631
match self.current_trait_ref {
36263632
Some((trait_def_id, _)) => {
36273633
if self.trait_item_map.contains_key(&(name, trait_def_id)) {
3628-
add_trait_info(&mut found_traits, trait_def_id, name);
3634+
add_trait_info(&mut found_traits, trait_def_id, None, name);
36293635
}
36303636
}
36313637
None => {} // Nothing to do.
@@ -3645,7 +3651,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
36453651
_ => continue,
36463652
};
36473653
if self.trait_item_map.contains_key(&(name, trait_def_id)) {
3648-
add_trait_info(&mut found_traits, trait_def_id, name);
3654+
add_trait_info(&mut found_traits, trait_def_id, None, name);
36493655
}
36503656
}
36513657
}
@@ -3661,8 +3667,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
36613667
Some(..) | None => continue,
36623668
};
36633669
if self.trait_item_map.contains_key(&(name, did)) {
3664-
add_trait_info(&mut found_traits, did, name);
36653670
let id = import.type_ns.id;
3671+
add_trait_info(&mut found_traits, did, Some(id), name);
36663672
self.used_imports.insert((id, TypeNS));
36673673
let trait_name = self.get_trait_name(did);
36683674
self.record_import_use(id, trait_name);

src/librustc_typeck/check/method/probe.rs

+26-9
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ struct ProbeContext<'a, 'tcx:'a> {
4444
inherent_candidates: Vec<Candidate<'tcx>>,
4545
extension_candidates: Vec<Candidate<'tcx>>,
4646
impl_dups: HashSet<DefId>,
47+
import_id: Option<ast::NodeId>,
4748

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

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

8790
// Indicates that the source expression should be autoderef'd N times
8891
//
@@ -246,6 +249,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
246249
inherent_candidates: Vec::new(),
247250
extension_candidates: Vec::new(),
248251
impl_dups: HashSet::new(),
252+
import_id: None,
249253
steps: Rc::new(steps),
250254
opt_simplified_steps: opt_simplified_steps,
251255
static_candidates: Vec::new(),
@@ -427,7 +431,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
427431
self.inherent_candidates.push(Candidate {
428432
xform_self_ty: xform_self_ty,
429433
item: item,
430-
kind: InherentImplCandidate(impl_substs, obligations)
434+
kind: InherentImplCandidate(impl_substs, obligations),
435+
import_id: self.import_id,
431436
});
432437
}
433438

@@ -455,7 +460,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
455460
this.inherent_candidates.push(Candidate {
456461
xform_self_ty: xform_self_ty,
457462
item: item,
458-
kind: ObjectCandidate
463+
kind: ObjectCandidate,
464+
import_id: this.import_id,
459465
});
460466
});
461467
}
@@ -524,7 +530,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
524530
this.inherent_candidates.push(Candidate {
525531
xform_self_ty: xform_self_ty,
526532
item: item,
527-
kind: WhereClauseCandidate(poly_trait_ref)
533+
kind: WhereClauseCandidate(poly_trait_ref),
534+
import_id: this.import_id,
528535
});
529536
});
530537
}
@@ -568,9 +575,13 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
568575
let mut duplicates = HashSet::new();
569576
let opt_applicable_traits = self.fcx.ccx.trait_map.get(&expr_id);
570577
if let Some(applicable_traits) = opt_applicable_traits {
571-
for &trait_did in applicable_traits {
578+
for trait_candidate in applicable_traits {
579+
let trait_did = trait_candidate.def_id;
572580
if duplicates.insert(trait_did) {
573-
try!(self.assemble_extension_candidates_for_trait(trait_did));
581+
self.import_id = trait_candidate.import_id;
582+
let result = self.assemble_extension_candidates_for_trait(trait_did);
583+
self.import_id = None;
584+
try!(result);
574585
}
575586
}
576587
}
@@ -670,7 +681,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
670681
self.extension_candidates.push(Candidate {
671682
xform_self_ty: xform_self_ty,
672683
item: item.clone(),
673-
kind: ExtensionImplCandidate(impl_def_id, impl_substs, obligations)
684+
kind: ExtensionImplCandidate(impl_def_id, impl_substs, obligations),
685+
import_id: self.import_id,
674686
});
675687
});
676688
}
@@ -745,7 +757,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
745757
self.inherent_candidates.push(Candidate {
746758
xform_self_ty: xform_self_ty,
747759
item: item.clone(),
748-
kind: TraitCandidate
760+
kind: TraitCandidate,
761+
import_id: self.import_id,
749762
});
750763
}
751764

@@ -802,7 +815,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
802815
self.extension_candidates.push(Candidate {
803816
xform_self_ty: xform_self_ty,
804817
item: item.clone(),
805-
kind: TraitCandidate
818+
kind: TraitCandidate,
819+
import_id: self.import_id,
806820
});
807821
}
808822
}
@@ -833,7 +847,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
833847
self.extension_candidates.push(Candidate {
834848
xform_self_ty: xform_self_ty,
835849
item: item.clone(),
836-
kind: WhereClauseCandidate(poly_bound)
850+
kind: WhereClauseCandidate(poly_bound),
851+
import_id: self.import_id,
837852
});
838853
}
839854
}
@@ -1126,6 +1141,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
11261141
Some(Pick {
11271142
item: probes[0].item.clone(),
11281143
kind: TraitPick,
1144+
import_id: probes[0].import_id,
11291145
autoderefs: 0,
11301146
autoref: None,
11311147
unsize: None
@@ -1329,6 +1345,7 @@ impl<'tcx> Candidate<'tcx> {
13291345
WhereClausePick(trait_ref.clone())
13301346
}
13311347
},
1348+
import_id: self.import_id,
13321349
autoderefs: 0,
13331350
autoref: None,
13341351
unsize: None

0 commit comments

Comments
 (0)