Skip to content

Commit e2ac949

Browse files
committed
rustc: pass Option<&Substs> and Namespace around in ty::item_path.
1 parent 10fbc55 commit e2ac949

24 files changed

+143
-78
lines changed

src/librustc/ty/item_path.rs

Lines changed: 102 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
use hir::def::Namespace;
12
use hir::map::DefPathData;
23
use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
34
use ty::{self, DefIdTree, Ty, TyCtxt};
45
use ty::print::PrintCx;
6+
use ty::subst::{Subst, Substs};
57
use middle::cstore::{ExternCrate, ExternCrateSource};
68
use syntax::ast;
79
use syntax::symbol::{keywords, Symbol};
@@ -54,18 +56,48 @@ pub fn with_crate_prefix<F: FnOnce() -> R, R>(f: F) -> R {
5456
}
5557

5658
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
59+
// HACK(eddyb) get rid of `item_path_str` and/or pass `Namespace` explicitly always
60+
// (but also some things just print a `DefId` generally so maybe we need this?)
61+
fn guess_def_namespace(self, def_id: DefId) -> Namespace {
62+
match self.def_key(def_id).disambiguated_data.data {
63+
DefPathData::ValueNs(..) |
64+
DefPathData::EnumVariant(..) |
65+
DefPathData::Field(..) |
66+
DefPathData::AnonConst |
67+
DefPathData::ClosureExpr |
68+
DefPathData::StructCtor => Namespace::ValueNS,
69+
70+
DefPathData::MacroDef(..) => Namespace::MacroNS,
71+
72+
_ => Namespace::TypeNS,
73+
}
74+
}
75+
5776
/// Returns a string identifying this def-id. This string is
5877
/// suitable for user output. It is relative to the current crate
5978
/// root, unless with_forced_absolute_paths was used.
60-
pub fn item_path_str(self, def_id: DefId) -> String {
61-
debug!("item_path_str: def_id={:?}", def_id);
79+
pub fn item_path_str_with_substs_and_ns(
80+
self,
81+
def_id: DefId,
82+
substs: Option<&Substs<'tcx>>,
83+
ns: Namespace,
84+
) -> String {
85+
debug!("item_path_str: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns);
6286
if FORCE_ABSOLUTE.with(|force| force.get()) {
63-
PrintCx::new(self, AbsolutePathPrinter).print_item_path(def_id)
87+
PrintCx::new(self, AbsolutePathPrinter).print_item_path(def_id, substs, ns)
6488
} else {
65-
PrintCx::new(self, LocalPathPrinter).print_item_path(def_id)
89+
PrintCx::new(self, LocalPathPrinter).print_item_path(def_id, substs, ns)
6690
}
6791
}
6892

93+
/// Returns a string identifying this def-id. This string is
94+
/// suitable for user output. It is relative to the current crate
95+
/// root, unless with_forced_absolute_paths was used.
96+
pub fn item_path_str(self, def_id: DefId) -> String {
97+
let ns = self.guess_def_namespace(def_id);
98+
self.item_path_str_with_substs_and_ns(def_id, None, ns)
99+
}
100+
69101
/// Returns a string identifying this local node-id.
70102
pub fn node_path_str(self, id: ast::NodeId) -> String {
71103
self.item_path_str(self.hir().local_def_id(id))
@@ -75,13 +107,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
75107
/// suitable for user output. It always begins with a crate identifier.
76108
pub fn absolute_item_path_str(self, def_id: DefId) -> String {
77109
debug!("absolute_item_path_str: def_id={:?}", def_id);
78-
PrintCx::new(self, AbsolutePathPrinter).print_item_path(def_id)
110+
let ns = self.guess_def_namespace(def_id);
111+
PrintCx::new(self, AbsolutePathPrinter).print_item_path(def_id, None, ns)
79112
}
80113
}
81114

82115
impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
83-
pub fn default_print_item_path(&mut self, def_id: DefId) -> P::Path {
84-
debug!("default_print_item_path: def_id={:?}", def_id);
116+
pub fn default_print_item_path(
117+
&mut self,
118+
def_id: DefId,
119+
substs: Option<&Substs<'tcx>>,
120+
ns: Namespace,
121+
) -> P::Path {
122+
debug!("default_print_item_path: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns);
85123
let key = self.tcx.def_key(def_id);
86124
debug!("default_print_item_path: key={:?}", key);
87125
match key.disambiguated_data.data {
@@ -91,7 +129,7 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
91129
}
92130

93131
DefPathData::Impl => {
94-
self.print_impl_path(def_id)
132+
self.print_impl_path(def_id, substs, ns)
95133
}
96134

97135
// Unclear if there is any value in distinguishing these.
@@ -116,18 +154,23 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
116154
data @ DefPathData::ImplTrait |
117155
data @ DefPathData::GlobalMetaData(..) => {
118156
let parent_did = self.tcx.parent_def_id(def_id).unwrap();
119-
let path = self.print_item_path(parent_did);
157+
let path = self.print_item_path(parent_did, None, ns);
120158
self.path_append(path, &data.as_interned_str().as_symbol().as_str())
121159
},
122160

123161
DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}`
124162
let parent_def_id = self.tcx.parent_def_id(def_id).unwrap();
125-
self.print_item_path(parent_def_id)
163+
self.print_item_path(parent_def_id, substs, ns)
126164
}
127165
}
128166
}
129167

130-
fn default_print_impl_path(&mut self, impl_def_id: DefId) -> P::Path {
168+
fn default_print_impl_path(
169+
&mut self,
170+
impl_def_id: DefId,
171+
substs: Option<&Substs<'tcx>>,
172+
ns: Namespace,
173+
) -> P::Path {
131174
debug!("default_print_impl_path: impl_def_id={:?}", impl_def_id);
132175
let parent_def_id = self.tcx.parent_def_id(impl_def_id).unwrap();
133176

@@ -136,13 +179,19 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
136179
// users may find it useful. Currently, we omit the parent if
137180
// the impl is either in the same module as the self-type or
138181
// as the trait.
139-
let self_ty = self.tcx.type_of(impl_def_id);
182+
let mut self_ty = self.tcx.type_of(impl_def_id);
183+
if let Some(substs) = substs {
184+
self_ty = self_ty.subst(self.tcx, substs);
185+
}
140186
let in_self_mod = match characteristic_def_id_of_type(self_ty) {
141187
None => false,
142188
Some(ty_def_id) => self.tcx.parent_def_id(ty_def_id) == Some(parent_def_id),
143189
};
144190

145-
let impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id);
191+
let mut impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id);
192+
if let Some(substs) = substs {
193+
impl_trait_ref = impl_trait_ref.subst(self.tcx, substs);
194+
}
146195
let in_trait_mod = match impl_trait_ref {
147196
None => false,
148197
Some(trait_ref) => self.tcx.parent_def_id(trait_ref.def_id) == Some(parent_def_id),
@@ -152,7 +201,7 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
152201
// If the impl is not co-located with either self-type or
153202
// trait-type, then fallback to a format that identifies
154203
// the module more clearly.
155-
let path = self.print_item_path(parent_def_id);
204+
let path = self.print_item_path(parent_def_id, None, ns);
156205
if let Some(trait_ref) = impl_trait_ref {
157206
return self.path_append(path, &format!("<impl {} for {}>", trait_ref, self_ty));
158207
} else {
@@ -173,15 +222,14 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
173222
// anything other than a simple path.
174223
match self_ty.sty {
175224
ty::Adt(adt_def, substs) => {
176-
// FIXME(eddyb) always print without <> here.
177-
if substs.types().next().is_none() { // ignore regions
178-
self.print_item_path(adt_def.did)
179-
} else {
180-
self.path_impl(&format!("<{}>", self_ty))
181-
}
225+
// FIXME(eddyb) this should recurse to build the path piecewise.
226+
// self.print_item_path(adt_def.did, Some(substs), ns)
227+
let mut s = String::new();
228+
::util::ppaux::parameterized(&mut s, adt_def.did, substs, ns).unwrap();
229+
self.path_impl(&s)
182230
}
183231

184-
ty::Foreign(did) => self.print_item_path(did),
232+
ty::Foreign(did) => self.print_item_path(did, None, ns),
185233

186234
ty::Bool |
187235
ty::Char |
@@ -262,11 +310,21 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
262310
pub trait ItemPathPrinter: Sized {
263311
type Path;
264312

265-
fn print_item_path(self: &mut PrintCx<'_, '_, '_, Self>, def_id: DefId) -> Self::Path {
266-
self.default_print_item_path(def_id)
313+
fn print_item_path(
314+
self: &mut PrintCx<'_, '_, 'tcx, Self>,
315+
def_id: DefId,
316+
substs: Option<&Substs<'tcx>>,
317+
ns: Namespace,
318+
) -> Self::Path {
319+
self.default_print_item_path(def_id, substs, ns)
267320
}
268-
fn print_impl_path(self: &mut PrintCx<'_, '_, '_, Self>, impl_def_id: DefId) -> Self::Path {
269-
self.default_print_impl_path(impl_def_id)
321+
fn print_impl_path(
322+
self: &mut PrintCx<'_, '_, 'tcx, Self>,
323+
impl_def_id: DefId,
324+
substs: Option<&Substs<'tcx>>,
325+
ns: Namespace,
326+
) -> Self::Path {
327+
self.default_print_impl_path(impl_def_id, substs, ns)
270328
}
271329

272330
fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path;
@@ -311,6 +369,7 @@ impl LocalPathPrinter {
311369
fn try_print_visible_item_path(
312370
self: &mut PrintCx<'_, '_, '_, Self>,
313371
def_id: DefId,
372+
ns: Namespace,
314373
) -> Option<<Self as ItemPathPrinter>::Path> {
315374
debug!("try_print_visible_item_path: def_id={:?}", def_id);
316375

@@ -342,7 +401,7 @@ impl LocalPathPrinter {
342401
}) => {
343402
debug!("try_print_visible_item_path: def_id={:?}", def_id);
344403
let path = if !span.is_dummy() {
345-
self.print_item_path(def_id)
404+
self.print_item_path(def_id, None, ns)
346405
} else {
347406
self.path_crate(cnum)
348407
};
@@ -375,7 +434,7 @@ impl LocalPathPrinter {
375434
}
376435

377436
let visible_parent = visible_parent_map.get(&def_id).cloned()?;
378-
let path = self.try_print_visible_item_path(visible_parent)?;
437+
let path = self.try_print_visible_item_path(visible_parent, ns)?;
379438
let actual_parent = self.tcx.parent(def_id);
380439

381440
let data = cur_def_key.disambiguated_data.data;
@@ -446,11 +505,21 @@ impl LocalPathPrinter {
446505
impl ItemPathPrinter for LocalPathPrinter {
447506
type Path = String;
448507

449-
fn print_item_path(self: &mut PrintCx<'_, '_, '_, Self>, def_id: DefId) -> Self::Path {
450-
self.try_print_visible_item_path(def_id)
451-
.unwrap_or_else(|| self.default_print_item_path(def_id))
508+
fn print_item_path(
509+
self: &mut PrintCx<'_, '_, 'tcx, Self>,
510+
def_id: DefId,
511+
substs: Option<&Substs<'tcx>>,
512+
ns: Namespace,
513+
) -> Self::Path {
514+
self.try_print_visible_item_path(def_id, ns)
515+
.unwrap_or_else(|| self.default_print_item_path(def_id, substs, ns))
452516
}
453-
fn print_impl_path(self: &mut PrintCx<'_, '_, '_, Self>, impl_def_id: DefId) -> Self::Path {
517+
fn print_impl_path(
518+
self: &mut PrintCx<'_, '_, 'tcx, Self>,
519+
impl_def_id: DefId,
520+
substs: Option<&Substs<'tcx>>,
521+
ns: Namespace,
522+
) -> Self::Path {
454523
// Always use types for non-local impls, where types are always
455524
// available, and filename/line-number is mostly uninteresting.
456525
let use_types = !impl_def_id.is_local() || {
@@ -465,12 +534,12 @@ impl ItemPathPrinter for LocalPathPrinter {
465534
// only occur very early in the compiler pipeline.
466535
// FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)`
467536
let parent_def_id = self.tcx.parent_def_id(impl_def_id).unwrap();
468-
let path = self.print_item_path(parent_def_id);
537+
let path = self.print_item_path(parent_def_id, None, ns);
469538
let span = self.tcx.def_span(impl_def_id);
470539
return self.path_append(path, &format!("<impl at {:?}>", span));
471540
}
472541

473-
self.default_print_impl_path(impl_def_id)
542+
self.default_print_impl_path(impl_def_id, substs, ns)
474543
}
475544

476545
fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path {

src/librustc/util/ppaux.rs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -317,23 +317,15 @@ impl<F: fmt::Write> PrintCx<'a, 'gcx, 'tcx, FmtPrinter<F>> {
317317
}
318318
}
319319
} else {
320-
// Try to print `impl`s more like how you'd refer to their associated items.
320+
// FIXME(eddyb) recurse through printing a path via `self`, instead
321+
// instead of using the `tcx` method that produces a `String`.
322+
print!(self, write("{}",
323+
self.tcx.item_path_str_with_substs_and_ns(def_id, Some(substs), ns)))?;
324+
325+
// For impls, the above call already prints relevant generics args.
321326
if let DefPathData::Impl = key.disambiguated_data.data {
322-
if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) {
323-
// HACK(eddyb) this is in lieu of more specific disambiguation.
324-
print!(self, write("{}", self.tcx.item_path_str(def_id)))?;
325-
326-
let trait_ref = trait_ref.subst(self.tcx, substs);
327-
print!(self, print_debug(trait_ref))?;
328-
} else {
329-
let self_ty = self.tcx.type_of(def_id).subst(self.tcx, substs);
330-
// FIXME(eddyb) omit the <> where possible.
331-
print!(self, write("<"), print(self_ty), write(">"))?;
332-
}
333327
return Ok(());
334328
}
335-
336-
print!(self, write("{}", self.tcx.item_path_str(def_id)))?;
337329
}
338330

339331
let mut empty = true;

src/librustc_codegen_utils/symbol_names.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
//! virtually impossible. Thus, symbol hash generation exclusively relies on
8888
//! DefPaths which are much more robust in the face of changes to the code base.
8989
90+
use rustc::hir::def::Namespace;
9091
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
9192
use rustc::hir::Node;
9293
use rustc::hir::CodegenFnAttrFlags;
@@ -223,7 +224,9 @@ fn get_symbol_hash<'a, 'tcx>(
223224

224225
fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName {
225226
item_path::with_forced_absolute_paths(|| {
226-
PrintCx::new(tcx, SymbolPathPrinter).print_item_path(def_id).into_interned()
227+
PrintCx::new(tcx, SymbolPathPrinter)
228+
.print_item_path(def_id, None, Namespace::ValueNS)
229+
.into_interned()
227230
})
228231
}
229232

src/librustdoc/clean/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc::middle::lang_items;
1818
use rustc::middle::stability;
1919
use rustc::mir::interpret::GlobalId;
2020
use rustc::hir::{self, GenericArg, HirVec};
21-
use rustc::hir::def::{self, Def, CtorKind};
21+
use rustc::hir::def::{self, Def, CtorKind, Namespace};
2222
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
2323
use rustc::ty::subst::Substs;
2424
use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind};
@@ -4069,7 +4069,8 @@ where F: Fn(DefId) -> Def {
40694069
}
40704070
}
40714071

4072-
let names = PrintCx::new(tcx, AbsolutePathPrinter).print_item_path(def_id);
4072+
let names = PrintCx::new(tcx, AbsolutePathPrinter)
4073+
.print_item_path(def_id, None, Namespace::TypeNS);
40734074

40744075
hir::Path {
40754076
span: DUMMY_SP,

src/test/ui/bad/bad-sized.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ LL | let x: Vec<Trait + Sized> = Vec::new();
2222
|
2323
= help: the trait `std::marker::Sized` is not implemented for `dyn Trait`
2424
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
25-
= note: required by `<std::vec::Vec<T>>::new`
25+
= note: required by `std::vec::Vec::<T>::new`
2626

2727
error: aborting due to 3 previous errors
2828

src/test/ui/hygiene/impl_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ mod foo {
99
}
1010

1111
pub macro m() {
12-
let _: () = S.f(); //~ ERROR type `for<'r> fn(&'r foo::S) {<foo::S>::f}` is private
12+
let _: () = S.f(); //~ ERROR type `for<'r> fn(&'r foo::S) {foo::S::f}` is private
1313
}
1414
}
1515

src/test/ui/hygiene/impl_items.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
error: type `for<'r> fn(&'r foo::S) {<foo::S>::f}` is private
1+
error: type `for<'r> fn(&'r foo::S) {foo::S::f}` is private
22
--> $DIR/impl_items.rs:12:23
33
|
4-
LL | let _: () = S.f(); //~ ERROR type `for<'r> fn(&'r foo::S) {<foo::S>::f}` is private
4+
LL | let _: () = S.f(); //~ ERROR type `for<'r> fn(&'r foo::S) {foo::S::f}` is private
55
| ^
66
...
77
LL | foo::m!();

src/test/ui/issues/issue-17651.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ LL | (|| Box::new(*(&[0][..])))();
66
|
77
= help: the trait `std::marker::Sized` is not implemented for `[{integer}]`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
9-
= note: required by `<std::boxed::Box<T>>::new`
9+
= note: required by `std::boxed::Box::<T>::new`
1010

1111
error: aborting due to previous error
1212

src/test/ui/issues/issue-22638.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ struct D (Box<A>);
5050

5151
impl D {
5252
pub fn matches<F: Fn()>(&self, f: &F) {
53-
//~^ ERROR reached the type-length limit while instantiating `<D>::matches::<[closure
53+
//~^ ERROR reached the type-length limit while instantiating `D::matches::<[closure
5454
let &D(ref a) = self;
5555
a.matches(f)
5656
}

src/test/ui/issues/issue-22638.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: reached the type-length limit while instantiating `<D>::matches::$CLOSURE`
1+
error: reached the type-length limit while instantiating `D::matches::$CLOSURE`
22
--> $DIR/issue-22638.rs:52:5
33
|
44
LL | / pub fn matches<F: Fn()>(&self, f: &F) {
5-
LL | | //~^ ERROR reached the type-length limit while instantiating `<D>::matches::<[closure
5+
LL | | //~^ ERROR reached the type-length limit while instantiating `D::matches::<[closure
66
LL | | let &D(ref a) = self;
77
LL | | a.matches(f)
88
LL | | }

0 commit comments

Comments
 (0)