@@ -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,6 +77,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
6477 }
6578 } ) ;
6679 let mut buffer = LocalPathBuffer :: new ( mode) ;
80+ debug ! ( "item_path_str: buffer={:?} def_id={:?}" , buffer, def_id) ;
6781 self . push_item_path ( & mut buffer, def_id) ;
6882 buffer. into_string ( )
6983 }
@@ -77,6 +91,7 @@ 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 ) ;
94+ debug ! ( "absolute_item_path_str: buffer={:?} def_id={:?}" , buffer, def_id) ;
8095 self . push_item_path ( & mut buffer, def_id) ;
8196 buffer. into_string ( )
8297 }
@@ -85,8 +100,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
85100 /// various ways, depending on the `root_mode` of the `buffer`.
86101 /// (See `RootMode` enum for more details.)
87102 pub fn push_krate_path < T > ( self , buffer : & mut T , cnum : CrateNum )
88- where T : ItemPathBuffer
103+ where T : ItemPathBuffer + Debug
89104 {
105+ debug ! (
106+ "push_krate_path: buffer={:?} cnum={:?} LOCAL_CRATE={:?}" ,
107+ buffer, cnum, LOCAL_CRATE
108+ ) ;
90109 match * buffer. root_mode ( ) {
91110 RootMode :: Local => {
92111 // In local mode, when we encounter a crate other than
@@ -109,16 +128,32 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
109128 ..
110129 } ) = * opt_extern_crate
111130 {
131+ debug ! ( "push_krate_path: def_id={:?}" , def_id) ;
112132 self . push_item_path ( buffer, def_id) ;
113133 } else {
114- buffer. push ( & self . crate_name ( cnum) . as_str ( ) ) ;
134+ let name = self . crate_name ( cnum) . as_str ( ) ;
135+ debug ! ( "push_krate_path: name={:?}" , name) ;
136+ buffer. push ( & name) ;
115137 }
138+ } else if self . sess . edition ( ) == Edition :: Edition2018 {
139+ 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+ if flag. get ( ) {
146+ buffer. push ( & keywords:: Crate . name ( ) . as_str ( ) )
147+ }
148+ } )
116149 }
117150 }
118151 RootMode :: Absolute => {
119152 // In absolute mode, just write the crate name
120153 // unconditionally.
121- buffer. push ( & self . original_crate_name ( cnum) . as_str ( ) ) ;
154+ let name = self . original_crate_name ( cnum) . as_str ( ) ;
155+ debug ! ( "push_krate_path: original_name={:?}" , name) ;
156+ buffer. push ( & name) ;
122157 }
123158 }
124159 }
@@ -127,12 +162,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
127162 /// from at least one local module and returns true. If the crate defining `external_def_id` is
128163 /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
129164 pub fn try_push_visible_item_path < T > ( self , buffer : & mut T , external_def_id : DefId ) -> bool
130- where T : ItemPathBuffer
165+ where T : ItemPathBuffer + Debug
131166 {
167+ debug ! (
168+ "try_push_visible_item_path: buffer={:?} external_def_id={:?}" ,
169+ buffer, external_def_id
170+ ) ;
132171 let visible_parent_map = self . visible_parent_map ( LOCAL_CRATE ) ;
133172
134173 let ( mut cur_def, mut cur_path) = ( external_def_id, Vec :: < LocalInternedString > :: new ( ) ) ;
135174 loop {
175+ debug ! (
176+ "try_push_visible_item_path: cur_def={:?} cur_path={:?} CRATE_DEF_INDEX={:?}" ,
177+ cur_def, cur_path, CRATE_DEF_INDEX ,
178+ ) ;
136179 // If `cur_def` is a direct or injected extern crate, push the path to the crate
137180 // followed by the path to the item within the crate and return.
138181 if cur_def. index == CRATE_DEF_INDEX {
@@ -142,6 +185,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
142185 direct : true ,
143186 ..
144187 } ) => {
188+ debug ! ( "try_push_visible_item_path: def_id={:?}" , def_id) ;
145189 self . push_item_path ( buffer, def_id) ;
146190 cur_path. iter ( ) . rev ( ) . for_each ( |segment| buffer. push ( & segment) ) ;
147191 return true ;
@@ -156,6 +200,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
156200 }
157201
158202 let mut cur_def_key = self . def_key ( cur_def) ;
203+ debug ! ( "try_push_visible_item_path: cur_def_key={:?}" , cur_def_key) ;
159204
160205 // For a UnitStruct or TupleStruct we want the name of its parent rather than <unnamed>.
161206 if let DefPathData :: StructCtor = cur_def_key. disambiguated_data . data {
@@ -175,6 +220,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
175220 Symbol :: intern ( "<unnamed>" ) . as_str ( )
176221 }
177222 } ) ;
223+ debug ! ( "try_push_visible_item_path: symbol={:?}" , symbol) ;
178224 cur_path. push ( symbol) ;
179225
180226 match visible_parent_map. get ( & cur_def) {
@@ -185,15 +231,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
185231 }
186232
187233 pub fn push_item_path < T > ( self , buffer : & mut T , def_id : DefId )
188- where T : ItemPathBuffer
234+ where T : ItemPathBuffer + Debug
189235 {
236+ debug ! ( "push_item_path: buffer={:?} def_id={:?}" , buffer, def_id) ;
190237 match * buffer. root_mode ( ) {
191238 RootMode :: Local if !def_id. is_local ( ) =>
192239 if self . try_push_visible_item_path ( buffer, def_id) { return } ,
193240 _ => { }
194241 }
195242
196243 let key = self . def_key ( def_id) ;
244+ debug ! ( "push_item_path: key={:?}" , key) ;
197245 match key. disambiguated_data . data {
198246 DefPathData :: CrateRoot => {
199247 assert ! ( key. parent. is_none( ) ) ;
@@ -225,9 +273,21 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
225273 data @ DefPathData :: ImplTrait |
226274 data @ DefPathData :: GlobalMetaData ( ..) => {
227275 let parent_def_id = self . parent_def_id ( def_id) . unwrap ( ) ;
228- self . push_item_path ( buffer, parent_def_id) ;
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 data. as_interned_str ( ) == "std" => { } ,
285+ _ => self . push_item_path ( buffer, parent_def_id) ,
286+ }
287+
229288 buffer. push ( & data. as_interned_str ( ) . as_symbol ( ) . as_str ( ) ) ;
230- }
289+ } ,
290+
231291 DefPathData :: StructCtor => { // present `X` instead of `X::{{constructor}}`
232292 let parent_def_id = self . parent_def_id ( def_id) . unwrap ( ) ;
233293 self . push_item_path ( buffer, parent_def_id) ;
@@ -238,8 +298,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
238298 fn push_impl_path < T > ( self ,
239299 buffer : & mut T ,
240300 impl_def_id : DefId )
241- where T : ItemPathBuffer
301+ where T : ItemPathBuffer + Debug
242302 {
303+ debug ! ( "push_impl_path: buffer={:?} impl_def_id={:?}" , buffer, impl_def_id) ;
243304 let parent_def_id = self . parent_def_id ( impl_def_id) . unwrap ( ) ;
244305
245306 // Always use types for non-local impls, where types are always
@@ -327,7 +388,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
327388 fn push_impl_path_fallback < T > ( self ,
328389 buffer : & mut T ,
329390 impl_def_id : DefId )
330- where T : ItemPathBuffer
391+ where T : ItemPathBuffer + Debug
331392 {
332393 // If no type info is available, fall back to
333394 // pretty printing some span information. This should
0 commit comments