Skip to content

Commit 3e1cef7

Browse files
committed
rustc: pass Option<&Substs> and Namespace around in ty::item_path.
1 parent ed2be6f commit 3e1cef7

26 files changed

+159
-94
lines changed

src/librustc/ty/item_path.rs

Lines changed: 103 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
use crate::hir::def::Namespace;
12
use crate::hir::map::DefPathData;
23
use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
34
use crate::ty::{self, DefIdTree, Ty, TyCtxt};
5+
use crate::ty::print::PrintCx;
6+
use crate::ty::subst::{Subst, Substs};
47
use crate::middle::cstore::{ExternCrate, ExternCrateSource};
5-
use ty::print::PrintCx;
68
use syntax::ast;
79
use syntax::symbol::{keywords, Symbol};
810

@@ -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 `DefId`. 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.
@@ -117,18 +155,23 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
117155
data @ DefPathData::ImplTrait |
118156
data @ DefPathData::GlobalMetaData(..) => {
119157
let parent_did = self.tcx.parent_def_id(def_id).unwrap();
120-
let path = self.print_item_path(parent_did);
158+
let path = self.print_item_path(parent_did, None, ns);
121159
self.path_append(path, &data.as_interned_str().as_symbol().as_str())
122160
},
123161

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

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

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

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

185-
ty::Foreign(did) => self.print_item_path(did),
233+
ty::Foreign(did) => self.print_item_path(did, None, ns),
186234

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

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

273331
fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path;
@@ -312,6 +370,7 @@ impl LocalPathPrinter {
312370
fn try_print_visible_item_path(
313371
self: &mut PrintCx<'_, '_, '_, Self>,
314372
def_id: DefId,
373+
ns: Namespace,
315374
) -> Option<<Self as ItemPathPrinter>::Path> {
316375
debug!("try_print_visible_item_path: def_id={:?}", def_id);
317376

@@ -343,7 +402,7 @@ impl LocalPathPrinter {
343402
}) => {
344403
debug!("try_print_visible_item_path: def_id={:?}", def_id);
345404
let path = if !span.is_dummy() {
346-
self.print_item_path(def_id)
405+
self.print_item_path(def_id, None, ns)
347406
} else {
348407
self.path_crate(cnum)
349408
};
@@ -376,7 +435,7 @@ impl LocalPathPrinter {
376435
}
377436

378437
let visible_parent = visible_parent_map.get(&def_id).cloned()?;
379-
let path = self.try_print_visible_item_path(visible_parent)?;
438+
let path = self.try_print_visible_item_path(visible_parent, ns)?;
380439
let actual_parent = self.tcx.parent(def_id);
381440

382441
let data = cur_def_key.disambiguated_data.data;
@@ -444,11 +503,21 @@ impl LocalPathPrinter {
444503
impl ItemPathPrinter for LocalPathPrinter {
445504
type Path = String;
446505

447-
fn print_item_path(self: &mut PrintCx<'_, '_, '_, Self>, def_id: DefId) -> Self::Path {
448-
self.try_print_visible_item_path(def_id)
449-
.unwrap_or_else(|| self.default_print_item_path(def_id))
506+
fn print_item_path(
507+
self: &mut PrintCx<'_, '_, 'tcx, Self>,
508+
def_id: DefId,
509+
substs: Option<&Substs<'tcx>>,
510+
ns: Namespace,
511+
) -> Self::Path {
512+
self.try_print_visible_item_path(def_id, ns)
513+
.unwrap_or_else(|| self.default_print_item_path(def_id, substs, ns))
450514
}
451-
fn print_impl_path(self: &mut PrintCx<'_, '_, '_, Self>, impl_def_id: DefId) -> Self::Path {
515+
fn print_impl_path(
516+
self: &mut PrintCx<'_, '_, 'tcx, Self>,
517+
impl_def_id: DefId,
518+
substs: Option<&Substs<'tcx>>,
519+
ns: Namespace,
520+
) -> Self::Path {
452521
// Always use types for non-local impls, where types are always
453522
// available, and filename/line-number is mostly uninteresting.
454523
let use_types = !impl_def_id.is_local() || {
@@ -463,12 +532,12 @@ impl ItemPathPrinter for LocalPathPrinter {
463532
// only occur very early in the compiler pipeline.
464533
// FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)`
465534
let parent_def_id = self.tcx.parent_def_id(impl_def_id).unwrap();
466-
let path = self.print_item_path(parent_def_id);
535+
let path = self.print_item_path(parent_def_id, None, ns);
467536
let span = self.tcx.def_span(impl_def_id);
468537
return self.path_append(path, &format!("<impl at {:?}>", span));
469538
}
470539

471-
self.default_print_impl_path(impl_def_id)
540+
self.default_print_impl_path(impl_def_id, substs, ns)
472541
}
473542

474543
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;
@@ -225,7 +226,9 @@ fn get_symbol_hash<'a, 'tcx>(
225226

226227
fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName {
227228
item_path::with_forced_absolute_paths(|| {
228-
PrintCx::new(tcx, SymbolPathPrinter).print_item_path(def_id).into_interned()
229+
PrintCx::new(tcx, SymbolPathPrinter)
230+
.print_item_path(def_id, None, Namespace::ValueNS)
231+
.into_interned()
229232
})
230233
}
231234

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::{InternalSubsts, SubstsRef};
2424
use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind};
@@ -4249,7 +4249,8 @@ where F: Fn(DefId) -> Def {
42494249
}
42504250
}
42514251

4252-
let names = PrintCx::new(tcx, AbsolutePathPrinter).print_item_path(def_id);
4252+
let names = PrintCx::new(tcx, AbsolutePathPrinter)
4253+
.print_item_path(def_id, None, Namespace::TypeNS);
42534254

42544255
hir::Path {
42554256
span: DUMMY_SP,

0 commit comments

Comments
 (0)