@@ -120,26 +120,48 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
120
120
use_tree : & ast:: UseTree ,
121
121
id : NodeId ,
122
122
vis : ty:: Visibility ,
123
- prefix : & ast :: Path ,
123
+ parent_prefix : & [ Ident ] ,
124
124
mut uniform_paths_canary_emitted : bool ,
125
125
nested : bool ,
126
126
item : & Item ,
127
127
expansion : Mark ,
128
128
) {
129
- debug ! ( "build_reduced_graph_for_use_tree(prefix ={:?}, \
129
+ debug ! ( "build_reduced_graph_for_use_tree(parent_prefix ={:?}, \
130
130
uniform_paths_canary_emitted={}, \
131
131
use_tree={:?}, nested={})",
132
- prefix , uniform_paths_canary_emitted, use_tree, nested) ;
132
+ parent_prefix , uniform_paths_canary_emitted, use_tree, nested) ;
133
133
134
134
let is_prelude = attr:: contains_name ( & item. attrs , "prelude_import" ) ;
135
- let path = & use_tree. prefix ;
135
+ let uniform_paths =
136
+ self . session . rust_2018 ( ) &&
137
+ self . session . features_untracked ( ) . uniform_paths ;
138
+
139
+ let prefix_iter = || parent_prefix. iter ( ) . cloned ( )
140
+ . chain ( use_tree. prefix . segments . iter ( ) . map ( |seg| seg. ident ) ) ;
141
+ let prefix_start = prefix_iter ( ) . nth ( 0 ) ;
142
+ let starts_with_non_keyword = prefix_start. map_or ( false , |ident| {
143
+ !ident. is_path_segment_keyword ( )
144
+ } ) ;
145
+
146
+ // Imports are resolved as global by default, prepend `CrateRoot`,
147
+ // unless `#![feature(uniform_paths)]` is enabled.
148
+ let inject_crate_root =
149
+ !uniform_paths &&
150
+ match use_tree. kind {
151
+ // HACK(eddyb) special-case `use *` to mean `use ::*`.
152
+ ast:: UseTreeKind :: Glob if prefix_start. is_none ( ) => true ,
153
+ _ => starts_with_non_keyword,
154
+ } ;
155
+ let root = if inject_crate_root {
156
+ let span = use_tree. prefix . span . shrink_to_lo ( ) ;
157
+ Some ( Ident :: new ( keywords:: CrateRoot . name ( ) , span) )
158
+ } else {
159
+ None
160
+ } ;
136
161
137
- let mut module_path: Vec < _ > = prefix. segments . iter ( )
138
- . chain ( path. segments . iter ( ) )
139
- . map ( |seg| seg. ident )
140
- . collect ( ) ;
162
+ let prefix: Vec < _ > = root. into_iter ( ) . chain ( prefix_iter ( ) ) . collect ( ) ;
141
163
142
- debug ! ( "build_reduced_graph_for_use_tree: module_path ={:?}" , module_path ) ;
164
+ debug ! ( "build_reduced_graph_for_use_tree: prefix ={:?}" , prefix ) ;
143
165
144
166
// `#[feature(uniform_paths)]` allows an unqualified import path,
145
167
// e.g. `use x::...;` to resolve not just globally (`use ::x::...;`)
@@ -172,15 +194,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
172
194
// ergonomically unacceptable.
173
195
let emit_uniform_paths_canary =
174
196
!uniform_paths_canary_emitted &&
175
- module_path. get ( 0 ) . map_or ( false , |ident| {
176
- !ident. is_path_segment_keyword ( )
177
- } ) ;
197
+ uniform_paths &&
198
+ starts_with_non_keyword;
178
199
if emit_uniform_paths_canary {
179
- // Relative paths should only get here if the feature-gate is on.
180
- assert ! ( self . session. rust_2018( ) &&
181
- self . session. features_untracked( ) . uniform_paths) ;
182
-
183
- let source = module_path[ 0 ] ;
200
+ let source = prefix_start. unwrap ( ) ;
184
201
185
202
// HACK(eddyb) For `use x::{self, ...};`, use the ID of the
186
203
// `self` nested import for the canary. This allows the
@@ -256,6 +273,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
256
273
match use_tree. kind {
257
274
ast:: UseTreeKind :: Simple ( rename, ..) => {
258
275
let mut ident = use_tree. ident ( ) ;
276
+ let mut module_path = prefix;
259
277
let mut source = module_path. pop ( ) . unwrap ( ) ;
260
278
let mut type_ns_only = false ;
261
279
@@ -354,7 +372,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
354
372
max_vis : Cell :: new ( ty:: Visibility :: Invisible ) ,
355
373
} ;
356
374
self . add_import_directive (
357
- module_path ,
375
+ prefix ,
358
376
subclass,
359
377
use_tree. span ,
360
378
id,
@@ -366,13 +384,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
366
384
) ;
367
385
}
368
386
ast:: UseTreeKind :: Nested ( ref items) => {
369
- let prefix = ast:: Path {
370
- segments : module_path. into_iter ( )
371
- . map ( |ident| ast:: PathSegment :: from_ident ( ident) )
372
- . collect ( ) ,
373
- span : path. span ,
374
- } ;
375
-
376
387
// Ensure there is at most one `self` in the list
377
388
let self_spans = items. iter ( ) . filter_map ( |& ( ref use_tree, _) | {
378
389
if let ast:: UseTreeKind :: Simple ( ..) = use_tree. kind {
@@ -422,28 +433,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
422
433
423
434
match item. node {
424
435
ItemKind :: Use ( ref use_tree) => {
425
- let uniform_paths =
426
- self . session . rust_2018 ( ) &&
427
- self . session . features_untracked ( ) . uniform_paths ;
428
- // Imports are resolved as global by default, add starting root segment.
429
- let root = if !uniform_paths {
430
- use_tree. prefix . make_root ( )
431
- } else {
432
- // Except when `#![feature(uniform_paths)]` is on.
433
- None
434
- } ;
435
- let prefix = ast:: Path {
436
- segments : root. into_iter ( ) . collect ( ) ,
437
- span : use_tree. span ,
438
- } ;
439
-
440
436
self . build_reduced_graph_for_use_tree (
441
437
use_tree,
442
438
item. id ,
443
439
use_tree,
444
440
item. id ,
445
441
vis,
446
- & prefix ,
442
+ & [ ] ,
447
443
false , // uniform_paths_canary_emitted
448
444
false ,
449
445
item,
0 commit comments