@@ -120,26 +120,48 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
120120 use_tree : & ast:: UseTree ,
121121 id : NodeId ,
122122 vis : ty:: Visibility ,
123- prefix : & ast :: Path ,
123+ parent_prefix : & [ Ident ] ,
124124 mut uniform_paths_canary_emitted : bool ,
125125 nested : bool ,
126126 item : & Item ,
127127 expansion : Mark ,
128128 ) {
129- debug ! ( "build_reduced_graph_for_use_tree(prefix ={:?}, \
129+ debug ! ( "build_reduced_graph_for_use_tree(parent_prefix ={:?}, \
130130 uniform_paths_canary_emitted={}, \
131131 use_tree={:?}, nested={})",
132- prefix , uniform_paths_canary_emitted, use_tree, nested) ;
132+ parent_prefix , uniform_paths_canary_emitted, use_tree, nested) ;
133133
134134 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+ } ;
136161
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 ( ) ;
141163
142- debug ! ( "build_reduced_graph_for_use_tree: module_path ={:?}" , module_path ) ;
164+ debug ! ( "build_reduced_graph_for_use_tree: prefix ={:?}" , prefix ) ;
143165
144166 // `#[feature(uniform_paths)]` allows an unqualified import path,
145167 // e.g. `use x::...;` to resolve not just globally (`use ::x::...;`)
@@ -172,15 +194,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
172194 // ergonomically unacceptable.
173195 let emit_uniform_paths_canary =
174196 !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;
178199 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 ( ) ;
184201
185202 // HACK(eddyb) For `use x::{self, ...};`, use the ID of the
186203 // `self` nested import for the canary. This allows the
@@ -256,6 +273,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
256273 match use_tree. kind {
257274 ast:: UseTreeKind :: Simple ( rename, ..) => {
258275 let mut ident = use_tree. ident ( ) ;
276+ let mut module_path = prefix;
259277 let mut source = module_path. pop ( ) . unwrap ( ) ;
260278 let mut type_ns_only = false ;
261279
@@ -354,7 +372,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
354372 max_vis : Cell :: new ( ty:: Visibility :: Invisible ) ,
355373 } ;
356374 self . add_import_directive (
357- module_path ,
375+ prefix ,
358376 subclass,
359377 use_tree. span ,
360378 id,
@@ -366,13 +384,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
366384 ) ;
367385 }
368386 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-
376387 // Ensure there is at most one `self` in the list
377388 let self_spans = items. iter ( ) . filter_map ( |& ( ref use_tree, _) | {
378389 if let ast:: UseTreeKind :: Simple ( ..) = use_tree. kind {
@@ -422,28 +433,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
422433
423434 match item. node {
424435 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-
440436 self . build_reduced_graph_for_use_tree (
441437 use_tree,
442438 item. id ,
443439 use_tree,
444440 item. id ,
445441 vis,
446- & prefix ,
442+ & [ ] ,
447443 false , // uniform_paths_canary_emitted
448444 false ,
449445 item,
0 commit comments