Skip to content

Commit 4583dc9

Browse files
committed
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

+5-1
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

+43-1
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 => {

src/librustc_metadata/csearch.rs

+59-3
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ use decoder;
1313
use encoder;
1414
use loader;
1515

16-
use middle::cstore::{CrateStore, CrateSource, ChildItem, ExternCrate, FoundAst};
16+
use middle::cstore::{CrateStore, CrateSource, ChildItem, ExternCrate, FoundAst, DefLike};
1717
use middle::cstore::{NativeLibraryKind, LinkMeta, LinkagePreference};
1818
use middle::def;
1919
use middle::lang_items;
2020
use rustc::ty::{self, Ty, TyCtxt, VariantKind};
21-
use middle::def_id::{DefId, DefIndex};
21+
use middle::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
2222

2323
use rustc::front::map as hir_map;
2424
use rustc::mir::repr::Mir;
2525
use rustc::mir::mir_map::MirMap;
26-
use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet};
26+
use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap};
2727

2828
use std::cell::RefCell;
2929
use std::rc::Rc;
@@ -544,4 +544,60 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
544544
{
545545
encoder::metadata_encoding_version
546546
}
547+
548+
/// Returns a map from a sufficiently visible external item (i.e. an external item that is
549+
/// visible from at least one local module) to a sufficiently visible parent (considering
550+
/// modules that re-export the external item to be parents).
551+
fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>> {
552+
let mut visible_parent_map = self.visible_parent_map.borrow_mut();
553+
if !visible_parent_map.is_empty() { return visible_parent_map; }
554+
555+
use rustc_front::hir;
556+
use rustc::middle::cstore::{CrateStore, ChildItem};
557+
use std::collections::vec_deque::VecDeque;
558+
use std::collections::hash_map::Entry;
559+
for cnum in 1 .. self.next_crate_num() {
560+
let cdata = self.get_crate_data(cnum);
561+
562+
match cdata.extern_crate.get() {
563+
// Ignore crates without a corresponding local `extern crate` item.
564+
Some(extern_crate) if !extern_crate.direct => continue,
565+
_ => {},
566+
}
567+
568+
let mut bfs_queue = &mut VecDeque::new();
569+
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: ChildItem, parent: DefId| {
570+
let child = match child.def {
571+
DefLike::DlDef(def) if child.vis == hir::Public => def.def_id(),
572+
_ => return,
573+
};
574+
575+
match visible_parent_map.entry(child) {
576+
Entry::Occupied(mut entry) => {
577+
// If `child` is defined in crate `cnum`, ensure
578+
// that it is mapped to a parent in `cnum`.
579+
if child.krate == cnum && entry.get().krate != cnum {
580+
entry.insert(parent);
581+
}
582+
}
583+
Entry::Vacant(entry) => {
584+
entry.insert(parent);
585+
bfs_queue.push_back(child);
586+
}
587+
}
588+
};
589+
590+
let croot = DefId { krate: cnum, index: CRATE_DEF_INDEX };
591+
for child in self.crate_top_level_items(cnum) {
592+
add_child(bfs_queue, child, croot);
593+
}
594+
while let Some(def) = bfs_queue.pop_front() {
595+
for child in self.item_children(def) {
596+
add_child(bfs_queue, child, def);
597+
}
598+
}
599+
}
600+
601+
visible_parent_map
602+
}
547603
}

src/librustc_metadata/cstore.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ use loader;
2222

2323
use rustc::back::svh::Svh;
2424
use rustc::middle::cstore::{ExternCrate};
25-
use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet};
25+
use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap};
26+
use rustc::middle::def_id::DefId;
2627

2728
use std::cell::{RefCell, Ref, Cell};
2829
use std::rc::Rc;
@@ -92,6 +93,7 @@ pub struct CStore {
9293
used_link_args: RefCell<Vec<String>>,
9394
statically_included_foreign_items: RefCell<NodeSet>,
9495
pub intr: Rc<IdentInterner>,
96+
pub visible_parent_map: RefCell<DefIdMap<DefId>>,
9597
}
9698

9799
impl CStore {
@@ -104,6 +106,7 @@ impl CStore {
104106
used_link_args: RefCell::new(Vec::new()),
105107
intr: intr,
106108
statically_included_foreign_items: RefCell::new(NodeSet()),
109+
visible_parent_map: RefCell::new(FnvHashMap()),
107110
}
108111
}
109112

src/test/compile-fail/associated-types-unsized.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ trait Get {
1414
}
1515

1616
fn foo<T:Get>(t: T) {
17-
let x = t.get(); //~ ERROR the trait `core::marker::Sized` is not implemented
17+
let x = t.get(); //~ ERROR the trait `std::marker::Sized` is not implemented
1818
}
1919

2020
fn main() {

src/test/compile-fail/bad-const-type.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
static i: String = 10;
1212
//~^ ERROR mismatched types
13-
//~| expected `collections::string::String`
13+
//~| expected `std::string::String`
1414
//~| found `_`
15-
//~| expected struct `collections::string::String`
15+
//~| expected struct `std::string::String`
1616
//~| found integral variable
1717
fn main() { println!("{}", i); }

src/test/compile-fail/bad-method-typaram-kind.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
fn foo<T:'static>() {
12-
1.bar::<T>(); //~ ERROR `core::marker::Send` is not implemented
12+
1.bar::<T>(); //~ ERROR `std::marker::Send` is not implemented
1313
}
1414

1515
trait bar {

src/test/compile-fail/bad-sized.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ trait Trait {}
1212

1313
pub fn main() {
1414
let x: Vec<Trait + Sized> = Vec::new();
15-
//~^ ERROR the trait `core::marker::Sized` is not implemented
16-
//~| ERROR the trait `core::marker::Sized` is not implemented
17-
//~| ERROR the trait `core::marker::Sized` is not implemented
15+
//~^ ERROR the trait `std::marker::Sized` is not implemented
16+
//~| ERROR the trait `std::marker::Sized` is not implemented
17+
//~| ERROR the trait `std::marker::Sized` is not implemented
1818
}

src/test/compile-fail/binop-bitxor-str.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// error-pattern:`^` cannot be applied to type `collections::string::String`
11+
// error-pattern:`^` cannot be applied to type `std::string::String`
1212

1313
fn main() { let x = "a".to_string() ^ "b".to_string(); }

src/test/compile-fail/builtin-superkinds-double-superkind.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313

1414
trait Foo : Send+Sync { }
1515

16-
impl <T: Sync+'static> Foo for (T,) { } //~ ERROR the trait `core::marker::Send` is not implemented
16+
impl <T: Sync+'static> Foo for (T,) { } //~ ERROR the trait `std::marker::Send` is not implemented
1717

18-
impl <T: Send> Foo for (T,T) { } //~ ERROR the trait `core::marker::Sync` is not implemented
18+
impl <T: Send> Foo for (T,T) { } //~ ERROR the trait `std::marker::Sync` is not implemented
1919

2020
impl <T: Send+Sync> Foo for (T,T,T) { } // (ok)
2121

src/test/compile-fail/builtin-superkinds-in-metadata.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ struct X<T>(T);
2222
impl <T:Sync> RequiresShare for X<T> { }
2323

2424
impl <T:Sync+'static> RequiresRequiresShareAndSend for X<T> { }
25-
//~^ ERROR the trait `core::marker::Send` is not implemented
25+
//~^ ERROR the trait `std::marker::Send` is not implemented
2626

2727
fn main() { }

src/test/compile-fail/builtin-superkinds-simple.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414
trait Foo : Send { }
1515

1616
impl Foo for std::rc::Rc<i8> { }
17-
//~^ ERROR the trait `core::marker::Send` is not implemented
17+
//~^ ERROR the trait `std::marker::Send` is not implemented
1818

1919
fn main() { }

src/test/compile-fail/builtin-superkinds-typaram-not-send.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212

1313
trait Foo : Send { }
1414

15-
impl <T: Sync+'static> Foo for T { } //~ ERROR the trait `core::marker::Send` is not implemented
15+
impl <T: Sync+'static> Foo for T { } //~ ERROR the trait `std::marker::Send` is not implemented
1616

1717
fn main() { }

src/test/compile-fail/cast-rfc0401.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ fn main()
9191
let _ = 42usize as *const [u8]; //~ ERROR casting
9292
let _ = v as *const [u8]; //~ ERROR cannot cast
9393
let _ = fat_v as *const Foo;
94-
//~^ ERROR `core::marker::Sized` is not implemented for the type `[u8]`
94+
//~^ ERROR `std::marker::Sized` is not implemented for the type `[u8]`
9595
//~^^ HELP run `rustc --explain E0277` to see a detailed explanation
9696
//~^^^ NOTE `[u8]` does not have a constant size known at compile-time
9797
//~^^^^ NOTE required for the cast to the object type `Foo`
@@ -106,7 +106,7 @@ fn main()
106106

107107
let a : *const str = "hello";
108108
let _ = a as *const Foo;
109-
//~^ ERROR `core::marker::Sized` is not implemented for the type `str`
109+
//~^ ERROR `std::marker::Sized` is not implemented for the type `str`
110110
//~^^ HELP run `rustc --explain E0277` to see a detailed explanation
111111
//~^^^ NOTE `str` does not have a constant size known at compile-time
112112
//~^^^^ NOTE required for the cast to the object type `Foo`

src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ struct X<F> where F: FnOnce() + 'static + Send {
1313
}
1414

1515
fn foo<F>(blk: F) -> X<F> where F: FnOnce() + 'static {
16-
//~^ ERROR the trait `core::marker::Send` is not implemented for the type
16+
//~^ ERROR the trait `std::marker::Send` is not implemented for the type
1717
return X { field: blk };
1818
}
1919

src/test/compile-fail/closure-bounds-subtype.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn give_any<F>(f: F) where F: FnOnce() {
2121

2222
fn give_owned<F>(f: F) where F: FnOnce() + Send {
2323
take_any(f);
24-
take_const_owned(f); //~ ERROR the trait `core::marker::Sync` is not implemented for the type
24+
take_const_owned(f); //~ ERROR the trait `std::marker::Sync` is not implemented for the type
2525
}
2626

2727
fn main() {}

src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ struct TestType<T>(::std::marker::PhantomData<T>);
1717
unsafe impl<T: MyTrait+'static> Send for TestType<T> {}
1818

1919
impl<T: MyTrait> !Send for TestType<T> {}
20-
//~^ ERROR conflicting implementations of trait `core::marker::Send`
20+
//~^ ERROR conflicting implementations of trait `std::marker::Send`
2121

2222
unsafe impl<T:'static> Send for TestType<T> {}
23-
//~^ ERROR error: conflicting implementations of trait `core::marker::Send`
23+
//~^ ERROR error: conflicting implementations of trait `std::marker::Send`
2424

2525
impl !Send for TestType<i32> {}
2626

src/test/compile-fail/deriving-no-inner-impl-error-message.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ struct E {
1818
#[derive(Clone)]
1919
struct C {
2020
x: NoCloneOrEq
21-
//~^ ERROR the trait `core::clone::Clone` is not implemented for the type `NoCloneOrEq`
21+
//~^ ERROR the trait `std::clone::Clone` is not implemented for the type `NoCloneOrEq`
2222
}
2323

2424

src/test/compile-fail/deriving-span-Default-struct.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ struct Error;
1717

1818
#[derive(Default)]
1919
struct Struct {
20-
x: Error //~ ERROR `core::default::Default` is not implemented
20+
x: Error //~ ERROR `std::default::Default` is not implemented
2121
}
2222

2323
fn main() {}

src/test/compile-fail/destructure-trait-ref.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn main() {
3535
// n == m
3636
let &x = &1isize as &T; //~ ERROR type `&T` cannot be dereferenced
3737
let &&x = &(&1isize as &T); //~ ERROR type `&T` cannot be dereferenced
38-
let box x = box 1isize as Box<T>; //~ ERROR the trait `core::marker::Sized` is not implemented
38+
let box x = box 1isize as Box<T>; //~ ERROR the trait `std::marker::Sized` is not implemented
3939

4040
// n > m
4141
let &&x = &1isize as &T;

src/test/compile-fail/dropck_no_diverge_on_nonregular_3.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ enum Wrapper<T:'static> {
3939
}
4040

4141
fn main() {
42-
let w = //~ ERROR overflow while adding drop-check rules for core::option
42+
let w = //~ ERROR overflow while adding drop-check rules for std::option
4343
Some(Wrapper::Simple::<u32>);
44-
//~^ ERROR overflow while adding drop-check rules for core::option::Option
44+
//~^ ERROR overflow while adding drop-check rules for std::option::Option
4545
//~| ERROR overflow while adding drop-check rules for Wrapper
4646
}

src/test/compile-fail/dst-bad-assign-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,5 @@ pub fn main() {
4444
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
4545
let z: Box<ToBar> = Box::new(Bar1 {f: 36});
4646
f5.ptr = *z;
47-
//~^ ERROR the trait `core::marker::Sized` is not implemented
47+
//~^ ERROR the trait `std::marker::Sized` is not implemented
4848
}

src/test/compile-fail/dst-bad-assign.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,5 @@ pub fn main() {
4949
//~| found `Bar1`
5050
//~| expected trait ToBar
5151
//~| found struct `Bar1`
52-
//~| ERROR the trait `core::marker::Sized` is not implemented for the type `ToBar`
52+
//~| ERROR the trait `std::marker::Sized` is not implemented for the type `ToBar`
5353
}

src/test/compile-fail/dst-bad-deep.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ pub fn main() {
2121
let f: Fat<[isize; 3]> = Fat { ptr: [5, 6, 7] };
2222
let g: &Fat<[isize]> = &f;
2323
let h: &Fat<Fat<[isize]>> = &Fat { ptr: *g };
24-
//~^ ERROR the trait `core::marker::Sized` is not implemented
24+
//~^ ERROR the trait `std::marker::Sized` is not implemented
2525
}

0 commit comments

Comments
 (0)