Skip to content

Commit 4583dc9

Browse files
committedMar 31, 2016
Auto merge of #32439 - jseyfried:visible_suggestions, r=nrc
diagnostics: make paths to external items more visible This PR changes the reported path for an external item so that it is visible from at least one local module (i.e. it does not use any inaccessible external modules) if possible. If the external item's crate was declared with an `extern crate`, the path is guarenteed to use the `extern crate`. Fixes #23224, fixes #23355, fixes #26635, fixes #27165. r? @nrc
2 parents 30a3849 + da41e58 commit 4583dc9

File tree

129 files changed

+396
-291
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

129 files changed

+396
-291
lines changed
 

‎src/librustc/middle/cstore.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use mir::repr::Mir;
3232
use mir::mir_map::MirMap;
3333
use session::Session;
3434
use session::search_paths::PathKind;
35-
use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
35+
use util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap};
3636
use std::any::Any;
3737
use std::cell::RefCell;
3838
use std::rc::Rc;
@@ -169,6 +169,7 @@ pub trait CrateStore<'tcx> : Any {
169169
fn item_type(&self, tcx: &TyCtxt<'tcx>, def: DefId)
170170
-> ty::TypeScheme<'tcx>;
171171
fn relative_item_path(&self, def: DefId) -> Vec<hir_map::PathElem>;
172+
fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>>;
172173
fn extern_item_path(&self, def: DefId) -> Vec<hir_map::PathElem>;
173174
fn item_name(&self, def: DefId) -> ast::Name;
174175
fn item_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId)
@@ -347,6 +348,9 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
347348
fn item_type(&self, tcx: &TyCtxt<'tcx>, def: DefId)
348349
-> ty::TypeScheme<'tcx> { unimplemented!() }
349350
fn relative_item_path(&self, def: DefId) -> Vec<hir_map::PathElem> { unimplemented!() }
351+
fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>> {
352+
unimplemented!()
353+
}
350354
fn extern_item_path(&self, def: DefId) -> Vec<hir_map::PathElem> { unimplemented!() }
351355
fn item_name(&self, def: DefId) -> ast::Name { unimplemented!() }
352356
fn item_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId)

‎src/librustc/ty/item_path.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use front::map::DefPathData;
1212
use middle::cstore::LOCAL_CRATE;
13-
use middle::def_id::DefId;
13+
use middle::def_id::{DefId, CRATE_DEF_INDEX};
1414
use ty::{self, Ty, TyCtxt};
1515
use syntax::ast;
1616

@@ -75,9 +75,51 @@ impl<'tcx> TyCtxt<'tcx> {
7575
}
7676
}
7777

78+
/// If possible, this pushes a global path resolving to `external_def_id` that is visible
79+
/// from at least one local module and returns true. If the crate defining `external_def_id` is
80+
/// declared with an `extern crate`, the path is guarenteed to use the `extern crate`.
81+
pub fn try_push_visible_item_path<T>(&self, buffer: &mut T, external_def_id: DefId) -> bool
82+
where T: ItemPathBuffer
83+
{
84+
let visible_parent_map = self.sess.cstore.visible_parent_map();
85+
86+
let (mut cur_def, mut cur_path) = (external_def_id, Vec::<ast::Name>::new());
87+
loop {
88+
// If `cur_def` is a direct or injected extern crate, push the path to the crate
89+
// followed by the path to the item within the crate and return.
90+
if cur_def.index == CRATE_DEF_INDEX {
91+
match self.sess.cstore.extern_crate(cur_def.krate) {
92+
Some(extern_crate) if extern_crate.direct => {
93+
self.push_item_path(buffer, extern_crate.def_id);
94+
cur_path.iter().rev().map(|segment| buffer.push(&segment.as_str())).count();
95+
return true;
96+
}
97+
None => {
98+
buffer.push(&self.crate_name(cur_def.krate));
99+
cur_path.iter().rev().map(|segment| buffer.push(&segment.as_str())).count();
100+
return true;
101+
}
102+
_ => {},
103+
}
104+
}
105+
106+
cur_path.push(self.sess.cstore.item_name(cur_def));
107+
match visible_parent_map.get(&cur_def) {
108+
Some(&def) => cur_def = def,
109+
None => return false,
110+
};
111+
}
112+
}
113+
78114
pub fn push_item_path<T>(&self, buffer: &mut T, def_id: DefId)
79115
where T: ItemPathBuffer
80116
{
117+
match *buffer.root_mode() {
118+
RootMode::Local if !def_id.is_local() =>
119+
if self.try_push_visible_item_path(buffer, def_id) { return },
120+
_ => {}
121+
}
122+
81123
let key = self.def_key(def_id);
82124
match key.disambiguated_data.data {
83125
DefPathData::CrateRoot => {

0 commit comments

Comments
 (0)