@@ -12,14 +12,14 @@ use self::ImportDirectiveSubclass::*;
1212
1313use { AmbiguityError , Module , PerNS } ;
1414use Namespace :: { self , TypeNS , MacroNS } ;
15- use { NameBinding , NameBindingKind , PathResult , PrivacyError } ;
15+ use { NameBinding , NameBindingKind , ToNameBinding , PathResult , PrivacyError } ;
1616use Resolver ;
1717use { names_to_string, module_to_string} ;
1818use { resolve_error, ResolutionError } ;
1919
2020use rustc:: ty;
2121use 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 } ;
2323use rustc:: hir:: def:: * ;
2424use rustc:: session:: DiagnosticMessageId ;
2525use rustc:: util:: nodemap:: { FxHashMap , FxHashSet } ;
@@ -602,8 +602,60 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
602602 // If appropriate, returns an error to report.
603603 fn finalize_import ( & mut self , directive : & ' b ImportDirective < ' b > ) -> Option < ( Span , String ) > {
604604 self . current_module = directive. parent ;
605-
606605 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+
607659 let module_result = self . resolve_path ( & module_path, None , true , span) ;
608660 let module = match module_result {
609661 PathResult :: Module ( module) => module,
0 commit comments