@@ -13,14 +13,16 @@ use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
1313use ty:: { self , Ty , TyCtxt } ;
1414use middle:: cstore:: { ExternCrate , ExternCrateSource } ;
1515use syntax:: ast;
16- use syntax:: symbol:: Symbol ;
17- use syntax :: symbol :: LocalInternedString ;
16+ use syntax:: symbol:: { keywords , LocalInternedString , Symbol } ;
17+ use syntax_pos :: edition :: Edition ;
1818
1919use std:: cell:: Cell ;
20+ use std:: fmt:: Debug ;
2021
2122thread_local ! {
2223 static FORCE_ABSOLUTE : Cell <bool > = Cell :: new( false ) ;
2324 static FORCE_IMPL_FILENAME_LINE : Cell <bool > = Cell :: new( false ) ;
25+ static SHOULD_PREFIX_WITH_CRATE : Cell <bool > = Cell :: new( false ) ;
2426}
2527
2628/// Enforces that item_path_str always returns an absolute path and
@@ -51,6 +53,17 @@ pub fn with_forced_impl_filename_line<F: FnOnce() -> R, R>(f: F) -> R {
5153 } )
5254}
5355
56+ /// Add the `crate::` prefix to paths where appropriate.
57+ pub fn with_crate_prefix < F : FnOnce ( ) -> R , R > ( f : F ) -> R {
58+ SHOULD_PREFIX_WITH_CRATE . with ( |flag| {
59+ let old = flag. get ( ) ;
60+ flag. set ( true ) ;
61+ let result = f ( ) ;
62+ flag. set ( old) ;
63+ result
64+ } )
65+ }
66+
5467impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
5568 /// Returns a string identifying this def-id. This string is
5669 /// suitable for user output. It is relative to the current crate
@@ -64,7 +77,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
6477 }
6578 } ) ;
6679 let mut buffer = LocalPathBuffer :: new ( mode) ;
67- self . push_item_path ( & mut buffer, def_id) ;
80+ debug ! ( "item_path_str: buffer={:?} def_id={:?}" , buffer, def_id) ;
81+ self . push_item_path ( & mut buffer, def_id, false ) ;
6882 buffer. into_string ( )
6983 }
7084
@@ -77,16 +91,26 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
7791 /// suitable for user output. It always begins with a crate identifier.
7892 pub fn absolute_item_path_str ( self , def_id : DefId ) -> String {
7993 let mut buffer = LocalPathBuffer :: new ( RootMode :: Absolute ) ;
80- self . push_item_path ( & mut buffer, def_id) ;
94+ debug ! ( "absolute_item_path_str: buffer={:?} def_id={:?}" , buffer, def_id) ;
95+ self . push_item_path ( & mut buffer, def_id, false ) ;
8196 buffer. into_string ( )
8297 }
8398
8499 /// Returns the "path" to a particular crate. This can proceed in
85100 /// various ways, depending on the `root_mode` of the `buffer`.
86101 /// (See `RootMode` enum for more details.)
87- pub fn push_krate_path < T > ( self , buffer : & mut T , cnum : CrateNum )
88- where T : ItemPathBuffer
102+ ///
103+ /// `pushed_prelude_crate` argument should be `true` when the buffer
104+ /// has had a prelude crate pushed to it. If this is the case, then
105+ /// we do not want to prepend `crate::` (as that would not be a valid
106+ /// path).
107+ pub fn push_krate_path < T > ( self , buffer : & mut T , cnum : CrateNum , pushed_prelude_crate : bool )
108+ where T : ItemPathBuffer + Debug
89109 {
110+ debug ! (
111+ "push_krate_path: buffer={:?} cnum={:?} LOCAL_CRATE={:?}" ,
112+ buffer, cnum, LOCAL_CRATE
113+ ) ;
90114 match * buffer. root_mode ( ) {
91115 RootMode :: Local => {
92116 // In local mode, when we encounter a crate other than
@@ -109,30 +133,56 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
109133 ..
110134 } ) = * opt_extern_crate
111135 {
112- self . push_item_path ( buffer, def_id) ;
136+ debug ! ( "push_krate_path: def_id={:?}" , def_id) ;
137+ self . push_item_path ( buffer, def_id, pushed_prelude_crate) ;
113138 } else {
114- buffer. push ( & self . crate_name ( cnum) . as_str ( ) ) ;
139+ let name = self . crate_name ( cnum) . as_str ( ) ;
140+ debug ! ( "push_krate_path: name={:?}" , name) ;
141+ buffer. push ( & name) ;
115142 }
143+ } else if self . sess . edition ( ) == Edition :: Edition2018 && !pushed_prelude_crate {
144+ SHOULD_PREFIX_WITH_CRATE . with ( |flag| {
145+ // We only add the `crate::` keyword where appropriate. In particular,
146+ // when we've not previously pushed a prelude crate to this path.
147+ if flag. get ( ) {
148+ buffer. push ( & keywords:: Crate . name ( ) . as_str ( ) )
149+ }
150+ } )
116151 }
117152 }
118153 RootMode :: Absolute => {
119154 // In absolute mode, just write the crate name
120155 // unconditionally.
121- buffer. push ( & self . original_crate_name ( cnum) . as_str ( ) ) ;
156+ let name = self . original_crate_name ( cnum) . as_str ( ) ;
157+ debug ! ( "push_krate_path: original_name={:?}" , name) ;
158+ buffer. push ( & name) ;
122159 }
123160 }
124161 }
125162
126163 /// If possible, this pushes a global path resolving to `external_def_id` that is visible
127164 /// from at least one local module and returns true. If the crate defining `external_def_id` is
128165 /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
129- pub fn try_push_visible_item_path < T > ( self , buffer : & mut T , external_def_id : DefId ) -> bool
130- where T : ItemPathBuffer
166+ pub fn try_push_visible_item_path < T > (
167+ self ,
168+ buffer : & mut T ,
169+ external_def_id : DefId ,
170+ pushed_prelude_crate : bool ,
171+ ) -> bool
172+ where T : ItemPathBuffer + Debug
131173 {
174+ debug ! (
175+ "try_push_visible_item_path: buffer={:?} external_def_id={:?}" ,
176+ buffer, external_def_id
177+ ) ;
132178 let visible_parent_map = self . visible_parent_map ( LOCAL_CRATE ) ;
133179
134180 let ( mut cur_def, mut cur_path) = ( external_def_id, Vec :: < LocalInternedString > :: new ( ) ) ;
135181 loop {
182+ debug ! (
183+ "try_push_visible_item_path: cur_def={:?} cur_path={:?} CRATE_DEF_INDEX={:?}" ,
184+ cur_def, cur_path, CRATE_DEF_INDEX ,
185+ ) ;
136186 // If `cur_def` is a direct or injected extern crate, push the path to the crate
137187 // followed by the path to the item within the crate and return.
138188 if cur_def. index == CRATE_DEF_INDEX {
@@ -142,7 +192,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
142192 direct : true ,
143193 ..
144194 } ) => {
145- self . push_item_path ( buffer, def_id) ;
195+ debug ! ( "try_push_visible_item_path: def_id={:?}" , def_id) ;
196+ self . push_item_path ( buffer, def_id, pushed_prelude_crate) ;
146197 cur_path. iter ( ) . rev ( ) . for_each ( |segment| buffer. push ( & segment) ) ;
147198 return true ;
148199 }
@@ -156,6 +207,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
156207 }
157208
158209 let mut cur_def_key = self . def_key ( cur_def) ;
210+ debug ! ( "try_push_visible_item_path: cur_def_key={:?}" , cur_def_key) ;
159211
160212 // For a UnitStruct or TupleStruct we want the name of its parent rather than <unnamed>.
161213 if let DefPathData :: StructCtor = cur_def_key. disambiguated_data . data {
@@ -175,6 +227,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
175227 Symbol :: intern ( "<unnamed>" ) . as_str ( )
176228 }
177229 } ) ;
230+ debug ! ( "try_push_visible_item_path: symbol={:?}" , symbol) ;
178231 cur_path. push ( symbol) ;
179232
180233 match visible_parent_map. get ( & cur_def) {
@@ -184,24 +237,29 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
184237 }
185238 }
186239
187- pub fn push_item_path < T > ( self , buffer : & mut T , def_id : DefId )
188- where T : ItemPathBuffer
240+ pub fn push_item_path < T > ( self , buffer : & mut T , def_id : DefId , pushed_prelude_crate : bool )
241+ where T : ItemPathBuffer + Debug
189242 {
243+ debug ! (
244+ "push_item_path: buffer={:?} def_id={:?} pushed_prelude_crate={:?}" ,
245+ buffer, def_id, pushed_prelude_crate
246+ ) ;
190247 match * buffer. root_mode ( ) {
191248 RootMode :: Local if !def_id. is_local ( ) =>
192- if self . try_push_visible_item_path ( buffer, def_id) { return } ,
249+ if self . try_push_visible_item_path ( buffer, def_id, pushed_prelude_crate ) { return } ,
193250 _ => { }
194251 }
195252
196253 let key = self . def_key ( def_id) ;
254+ debug ! ( "push_item_path: key={:?}" , key) ;
197255 match key. disambiguated_data . data {
198256 DefPathData :: CrateRoot => {
199257 assert ! ( key. parent. is_none( ) ) ;
200- self . push_krate_path ( buffer, def_id. krate ) ;
258+ self . push_krate_path ( buffer, def_id. krate , pushed_prelude_crate ) ;
201259 }
202260
203261 DefPathData :: Impl => {
204- self . push_impl_path ( buffer, def_id) ;
262+ self . push_impl_path ( buffer, def_id, pushed_prelude_crate ) ;
205263 }
206264
207265 // Unclear if there is any value in distinguishing these.
@@ -224,22 +282,40 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
224282 data @ DefPathData :: ClosureExpr |
225283 data @ DefPathData :: ImplTrait |
226284 data @ DefPathData :: GlobalMetaData ( ..) => {
227- let parent_def_id = self . parent_def_id ( def_id) . unwrap ( ) ;
228- self . push_item_path ( buffer, parent_def_id) ;
285+ let parent_did = self . parent_def_id ( def_id) . unwrap ( ) ;
286+
287+ // Keep track of whether we are one recursion away from the `CrateRoot` and
288+ // pushing the name of a prelude crate. If we are, we'll want to know this when
289+ // printing the `CrateRoot` so we don't prepend a `crate::` to paths.
290+ let mut is_prelude_crate = false ;
291+ if let DefPathData :: CrateRoot = self . def_key ( parent_did) . disambiguated_data . data {
292+ if self . sess . extern_prelude . contains ( & data. as_interned_str ( ) . as_symbol ( ) ) {
293+ is_prelude_crate = true ;
294+ }
295+ }
296+
297+ self . push_item_path (
298+ buffer, parent_did, pushed_prelude_crate || is_prelude_crate
299+ ) ;
229300 buffer. push ( & data. as_interned_str ( ) . as_symbol ( ) . as_str ( ) ) ;
230- }
301+ } ,
302+
231303 DefPathData :: StructCtor => { // present `X` instead of `X::{{constructor}}`
232304 let parent_def_id = self . parent_def_id ( def_id) . unwrap ( ) ;
233- self . push_item_path ( buffer, parent_def_id) ;
305+ self . push_item_path ( buffer, parent_def_id, pushed_prelude_crate ) ;
234306 }
235307 }
236308 }
237309
238- fn push_impl_path < T > ( self ,
239- buffer : & mut T ,
240- impl_def_id : DefId )
241- where T : ItemPathBuffer
310+ fn push_impl_path < T > (
311+ self ,
312+ buffer : & mut T ,
313+ impl_def_id : DefId ,
314+ pushed_prelude_crate : bool ,
315+ )
316+ where T : ItemPathBuffer + Debug
242317 {
318+ debug ! ( "push_impl_path: buffer={:?} impl_def_id={:?}" , buffer, impl_def_id) ;
243319 let parent_def_id = self . parent_def_id ( impl_def_id) . unwrap ( ) ;
244320
245321 // Always use types for non-local impls, where types are always
@@ -251,7 +327,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
251327 } ;
252328
253329 if !use_types {
254- return self . push_impl_path_fallback ( buffer, impl_def_id) ;
330+ return self . push_impl_path_fallback ( buffer, impl_def_id, pushed_prelude_crate ) ;
255331 }
256332
257333 // Decide whether to print the parent path for the impl.
@@ -275,7 +351,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
275351 // If the impl is not co-located with either self-type or
276352 // trait-type, then fallback to a format that identifies
277353 // the module more clearly.
278- self . push_item_path ( buffer, parent_def_id) ;
354+ self . push_item_path ( buffer, parent_def_id, pushed_prelude_crate ) ;
279355 if let Some ( trait_ref) = impl_trait_ref {
280356 buffer. push ( & format ! ( "<impl {} for {}>" , trait_ref, self_ty) ) ;
281357 } else {
@@ -301,13 +377,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
301377 match self_ty. sty {
302378 ty:: Adt ( adt_def, substs) => {
303379 if substs. types ( ) . next ( ) . is_none ( ) { // ignore regions
304- self . push_item_path ( buffer, adt_def. did ) ;
380+ self . push_item_path ( buffer, adt_def. did , pushed_prelude_crate ) ;
305381 } else {
306382 buffer. push ( & format ! ( "<{}>" , self_ty) ) ;
307383 }
308384 }
309385
310- ty:: Foreign ( did) => self . push_item_path ( buffer, did) ,
386+ ty:: Foreign ( did) => self . push_item_path ( buffer, did, pushed_prelude_crate ) ,
311387
312388 ty:: Bool |
313389 ty:: Char |
@@ -324,16 +400,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
324400 }
325401 }
326402
327- fn push_impl_path_fallback < T > ( self ,
328- buffer : & mut T ,
329- impl_def_id : DefId )
330- where T : ItemPathBuffer
403+ fn push_impl_path_fallback < T > (
404+ self ,
405+ buffer : & mut T ,
406+ impl_def_id : DefId ,
407+ pushed_prelude_crate : bool ,
408+ )
409+ where T : ItemPathBuffer + Debug
331410 {
332411 // If no type info is available, fall back to
333412 // pretty printing some span information. This should
334413 // only occur very early in the compiler pipeline.
335414 let parent_def_id = self . parent_def_id ( impl_def_id) . unwrap ( ) ;
336- self . push_item_path ( buffer, parent_def_id) ;
415+ self . push_item_path ( buffer, parent_def_id, pushed_prelude_crate ) ;
337416 let node_id = self . hir . as_local_node_id ( impl_def_id) . unwrap ( ) ;
338417 let item = self . hir . expect_item ( node_id) ;
339418 let span_str = self . sess . source_map ( ) . span_to_string ( item. span ) ;
0 commit comments