@@ -12,14 +12,14 @@ use self::ImportDirectiveSubclass::*;
12
12
13
13
use { AmbiguityError , Module , PerNS } ;
14
14
use Namespace :: { self , TypeNS , MacroNS } ;
15
- use { NameBinding , NameBindingKind , PathResult , PrivacyError } ;
15
+ use { NameBinding , NameBindingKind , ToNameBinding , PathResult , PrivacyError } ;
16
16
use Resolver ;
17
17
use { names_to_string, module_to_string} ;
18
18
use { resolve_error, ResolutionError } ;
19
19
20
20
use rustc:: ty;
21
21
use rustc:: lint:: builtin:: PUB_USE_OF_PRIVATE_EXTERN_CRATE ;
22
- use rustc:: hir:: def_id:: DefId ;
22
+ use rustc:: hir:: def_id:: { CRATE_DEF_INDEX , DefId } ;
23
23
use rustc:: hir:: def:: * ;
24
24
use rustc:: session:: DiagnosticMessageId ;
25
25
use rustc:: util:: nodemap:: { FxHashMap , FxHashSet } ;
@@ -602,8 +602,60 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
602
602
// If appropriate, returns an error to report.
603
603
fn finalize_import ( & mut self , directive : & ' b ImportDirective < ' b > ) -> Option < ( Span , String ) > {
604
604
self . current_module = directive. parent ;
605
-
606
605
let ImportDirective { ref module_path, span, .. } = * directive;
606
+
607
+ // Extern crate mode for absolute paths needs some
608
+ // special support for single-segment imports.
609
+ let extern_absolute_paths = self . session . features . borrow ( ) . extern_absolute_paths ;
610
+ if module_path. len ( ) == 1 && module_path[ 0 ] . node . name == keywords:: CrateRoot . name ( ) {
611
+ match directive. subclass {
612
+ GlobImport { .. } if extern_absolute_paths => {
613
+ return Some ( ( directive. span ,
614
+ "cannot glob-import all possible crates" . to_string ( ) ) ) ;
615
+ }
616
+ SingleImport { source, target, .. } => {
617
+ let crate_root = if source. name == keywords:: Crate . name ( ) {
618
+ if target. name == keywords:: Crate . name ( ) {
619
+ return Some ( ( directive. span ,
620
+ "crate root imports need to be explicitly named: \
621
+ `use crate as name;`". to_string ( ) ) ) ;
622
+ } else {
623
+ Some ( self . resolve_crate_root ( source. ctxt . modern ( ) ) )
624
+ }
625
+ } else if extern_absolute_paths &&
626
+ !token:: Ident ( source) . is_path_segment_keyword ( ) {
627
+ let crate_id =
628
+ self . crate_loader . resolve_crate_from_path ( source. name , directive. span ) ;
629
+ let crate_root =
630
+ self . get_module ( DefId { krate : crate_id, index : CRATE_DEF_INDEX } ) ;
631
+ self . populate_module_if_necessary ( crate_root) ;
632
+ Some ( crate_root)
633
+ } else {
634
+ None
635
+ } ;
636
+
637
+ if let Some ( crate_root) = crate_root {
638
+ let binding = ( crate_root, ty:: Visibility :: Public , directive. span ,
639
+ directive. expansion ) . to_name_binding ( self . arenas ) ;
640
+ let binding = self . arenas . alloc_name_binding ( NameBinding {
641
+ kind : NameBindingKind :: Import {
642
+ binding,
643
+ directive,
644
+ used : Cell :: new ( false ) ,
645
+ legacy_self_import : false ,
646
+ } ,
647
+ vis : directive. vis . get ( ) ,
648
+ span : directive. span ,
649
+ expansion : directive. expansion ,
650
+ } ) ;
651
+ let _ = self . try_define ( directive. parent , target, TypeNS , binding) ;
652
+ return None ;
653
+ }
654
+ }
655
+ _ => { }
656
+ }
657
+ }
658
+
607
659
let module_result = self . resolve_path ( & module_path, None , true , span) ;
608
660
let module = match module_result {
609
661
PathResult :: Module ( module) => module,
0 commit comments