@@ -78,7 +78,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
7878 } ) ;
7979 let mut buffer = LocalPathBuffer :: new ( mode) ;
8080 debug ! ( "item_path_str: buffer={:?} def_id={:?}" , buffer, def_id) ;
81- self . push_item_path ( & mut buffer, def_id) ;
81+ self . push_item_path ( & mut buffer, def_id, false ) ;
8282 buffer. into_string ( )
8383 }
8484
@@ -92,14 +92,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
9292 pub fn absolute_item_path_str ( self , def_id : DefId ) -> String {
9393 let mut buffer = LocalPathBuffer :: new ( RootMode :: Absolute ) ;
9494 debug ! ( "absolute_item_path_str: buffer={:?} def_id={:?}" , buffer, def_id) ;
95- self . push_item_path ( & mut buffer, def_id) ;
95+ self . push_item_path ( & mut buffer, def_id, false ) ;
9696 buffer. into_string ( )
9797 }
9898
9999 /// Returns the "path" to a particular crate. This can proceed in
100100 /// various ways, depending on the `root_mode` of the `buffer`.
101101 /// (See `RootMode` enum for more details.)
102- pub fn push_krate_path < T > ( self , buffer : & mut T , cnum : CrateNum )
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 )
103108 where T : ItemPathBuffer + Debug
104109 {
105110 debug ! (
@@ -129,19 +134,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
129134 } ) = * opt_extern_crate
130135 {
131136 debug ! ( "push_krate_path: def_id={:?}" , def_id) ;
132- self . push_item_path ( buffer, def_id) ;
137+ self . push_item_path ( buffer, def_id, pushed_prelude_crate ) ;
133138 } else {
134139 let name = self . crate_name ( cnum) . as_str ( ) ;
135140 debug ! ( "push_krate_path: name={:?}" , name) ;
136141 buffer. push ( & name) ;
137142 }
138- } else if self . sess . edition ( ) == Edition :: Edition2018 {
143+ } else if self . sess . edition ( ) == Edition :: Edition2018 && !pushed_prelude_crate {
139144 SHOULD_PREFIX_WITH_CRATE . with ( |flag| {
140- // We only add the `crate::` keyword where appropriate. This
141- // is only possible because of the invariant in `push_item_path`
142- // that this function will not be called after printing the path
143- // to an item in the standard library. Without this invariant,
144- // we would print `crate::std::..` here.
145+ // We only add the `crate::` keyword where appropriate. In particular,
146+ // when we've not previously pushed a prelude crate to this path.
145147 if flag. get ( ) {
146148 buffer. push ( & keywords:: Crate . name ( ) . as_str ( ) )
147149 }
@@ -161,7 +163,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
161163 /// If possible, this pushes a global path resolving to `external_def_id` that is visible
162164 /// from at least one local module and returns true. If the crate defining `external_def_id` is
163165 /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
164- pub fn try_push_visible_item_path < T > ( self , buffer : & mut T , external_def_id : DefId ) -> bool
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
165172 where T : ItemPathBuffer + Debug
166173 {
167174 debug ! (
@@ -186,7 +193,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
186193 ..
187194 } ) => {
188195 debug ! ( "try_push_visible_item_path: def_id={:?}" , def_id) ;
189- self . push_item_path ( buffer, def_id) ;
196+ self . push_item_path ( buffer, def_id, pushed_prelude_crate ) ;
190197 cur_path. iter ( ) . rev ( ) . for_each ( |segment| buffer. push ( & segment) ) ;
191198 return true ;
192199 }
@@ -230,13 +237,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
230237 }
231238 }
232239
233- pub fn push_item_path < T > ( self , buffer : & mut T , def_id : DefId )
240+ pub fn push_item_path < T > ( self , buffer : & mut T , def_id : DefId , pushed_prelude_crate : bool )
234241 where T : ItemPathBuffer + Debug
235242 {
236- debug ! ( "push_item_path: buffer={:?} def_id={:?}" , buffer, def_id) ;
243+ debug ! (
244+ "push_item_path: buffer={:?} def_id={:?} pushed_prelude_crate={:?}" ,
245+ buffer, def_id, pushed_prelude_crate
246+ ) ;
237247 match * buffer. root_mode ( ) {
238248 RootMode :: Local if !def_id. is_local ( ) =>
239- 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 } ,
240250 _ => { }
241251 }
242252
@@ -245,11 +255,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
245255 match key. disambiguated_data . data {
246256 DefPathData :: CrateRoot => {
247257 assert ! ( key. parent. is_none( ) ) ;
248- self . push_krate_path ( buffer, def_id. krate ) ;
258+ self . push_krate_path ( buffer, def_id. krate , pushed_prelude_crate ) ;
249259 }
250260
251261 DefPathData :: Impl => {
252- self . push_impl_path ( buffer, def_id) ;
262+ self . push_impl_path ( buffer, def_id, pushed_prelude_crate ) ;
253263 }
254264
255265 // Unclear if there is any value in distinguishing these.
@@ -272,34 +282,37 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
272282 data @ DefPathData :: ClosureExpr |
273283 data @ DefPathData :: ImplTrait |
274284 data @ DefPathData :: GlobalMetaData ( ..) => {
275- let parent_def_id = self . parent_def_id ( def_id) . unwrap ( ) ;
276-
277- match self . def_key ( parent_def_id) . disambiguated_data . data {
278- // Skip recursing to print the crate root depending on the
279- // current name.
280- //
281- // In particular, don't recurse to print the crate root if we
282- // just printed `std`. In doing this, we are able to add
283- // `crate::` to trait import suggestions.
284- DefPathData :: CrateRoot if self . sess . extern_prelude . contains (
285- & data. as_interned_str ( ) . as_symbol ( )
286- ) => { } ,
287- _ => 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+ }
288295 }
289296
297+ self . push_item_path (
298+ buffer, parent_did, pushed_prelude_crate || is_prelude_crate
299+ ) ;
290300 buffer. push ( & data. as_interned_str ( ) . as_symbol ( ) . as_str ( ) ) ;
291301 } ,
292302
293303 DefPathData :: StructCtor => { // present `X` instead of `X::{{constructor}}`
294304 let parent_def_id = self . parent_def_id ( def_id) . unwrap ( ) ;
295- self . push_item_path ( buffer, parent_def_id) ;
305+ self . push_item_path ( buffer, parent_def_id, pushed_prelude_crate ) ;
296306 }
297307 }
298308 }
299309
300- fn push_impl_path < T > ( self ,
301- buffer : & mut T ,
302- impl_def_id : DefId )
310+ fn push_impl_path < T > (
311+ self ,
312+ buffer : & mut T ,
313+ impl_def_id : DefId ,
314+ pushed_prelude_crate : bool ,
315+ )
303316 where T : ItemPathBuffer + Debug
304317 {
305318 debug ! ( "push_impl_path: buffer={:?} impl_def_id={:?}" , buffer, impl_def_id) ;
@@ -314,7 +327,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
314327 } ;
315328
316329 if !use_types {
317- return self . push_impl_path_fallback ( buffer, impl_def_id) ;
330+ return self . push_impl_path_fallback ( buffer, impl_def_id, pushed_prelude_crate ) ;
318331 }
319332
320333 // Decide whether to print the parent path for the impl.
@@ -338,7 +351,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
338351 // If the impl is not co-located with either self-type or
339352 // trait-type, then fallback to a format that identifies
340353 // the module more clearly.
341- self . push_item_path ( buffer, parent_def_id) ;
354+ self . push_item_path ( buffer, parent_def_id, pushed_prelude_crate ) ;
342355 if let Some ( trait_ref) = impl_trait_ref {
343356 buffer. push ( & format ! ( "<impl {} for {}>" , trait_ref, self_ty) ) ;
344357 } else {
@@ -364,13 +377,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
364377 match self_ty. sty {
365378 ty:: Adt ( adt_def, substs) => {
366379 if substs. types ( ) . next ( ) . is_none ( ) { // ignore regions
367- self . push_item_path ( buffer, adt_def. did ) ;
380+ self . push_item_path ( buffer, adt_def. did , pushed_prelude_crate ) ;
368381 } else {
369382 buffer. push ( & format ! ( "<{}>" , self_ty) ) ;
370383 }
371384 }
372385
373- ty:: Foreign ( did) => self . push_item_path ( buffer, did) ,
386+ ty:: Foreign ( did) => self . push_item_path ( buffer, did, pushed_prelude_crate ) ,
374387
375388 ty:: Bool |
376389 ty:: Char |
@@ -387,16 +400,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
387400 }
388401 }
389402
390- fn push_impl_path_fallback < T > ( self ,
391- buffer : & mut T ,
392- impl_def_id : DefId )
403+ fn push_impl_path_fallback < T > (
404+ self ,
405+ buffer : & mut T ,
406+ impl_def_id : DefId ,
407+ pushed_prelude_crate : bool ,
408+ )
393409 where T : ItemPathBuffer + Debug
394410 {
395411 // If no type info is available, fall back to
396412 // pretty printing some span information. This should
397413 // only occur very early in the compiler pipeline.
398414 let parent_def_id = self . parent_def_id ( impl_def_id) . unwrap ( ) ;
399- self . push_item_path ( buffer, parent_def_id) ;
415+ self . push_item_path ( buffer, parent_def_id, pushed_prelude_crate ) ;
400416 let node_id = self . hir . as_local_node_id ( impl_def_id) . unwrap ( ) ;
401417 let item = self . hir . expect_item ( node_id) ;
402418 let span_str = self . sess . source_map ( ) . span_to_string ( item. span ) ;
0 commit comments