@@ -596,65 +596,87 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
596596 }
597597 }
598598 } else {
599- // Disallow `self`
600- if source. ident . name == kw:: SelfLower {
601- let parent = module_path. last ( ) ;
602-
603- let span = match parent {
604- // only `::self` from `use foo::self as bar`
605- Some ( seg) => seg. ident . span . shrink_to_hi ( ) . to ( source. ident . span ) ,
606- None => source. ident . span ,
607- } ;
608- let span_with_rename = match rename {
609- // only `self as bar` from `use foo::self as bar`
610- Some ( rename) => source. ident . span . to ( rename. span ) ,
611- None => source. ident . span ,
612- } ;
613- self . r . report_error (
614- span,
615- ResolutionError :: SelfImportsOnlyAllowedWithin {
616- root : parent. is_none ( ) ,
617- span_with_rename,
618- } ,
619- ) ;
620-
621- // Error recovery: replace `use foo::self;` with `use foo;`
622- if let Some ( parent) = module_path. pop ( ) {
623- source = parent;
624- if rename. is_none ( ) {
625- ident = source. ident ;
599+ match source. ident . name {
600+ kw:: Crate => {
601+ if !module_path. is_empty ( ) {
602+ self . r . dcx ( ) . span_err (
603+ ident. span ,
604+ "`crate` in paths can only be used in start position" ,
605+ ) ;
606+ return ;
626607 }
627608 }
628- }
629-
630- // Disallow `use $crate;`
631- if source. ident . name == kw:: DollarCrate && module_path. is_empty ( ) {
632- let crate_root = self . r . resolve_crate_root ( source. ident ) ;
633- let crate_name = match crate_root. kind {
634- ModuleKind :: Def ( .., name) => name,
635- ModuleKind :: Block => unreachable ! ( ) ,
636- } ;
637- // HACK(eddyb) unclear how good this is, but keeping `$crate`
638- // in `source` breaks `tests/ui/imports/import-crate-var.rs`,
639- // while the current crate doesn't have a valid `crate_name`.
640- if let Some ( crate_name) = crate_name {
641- // `crate_name` should not be interpreted as relative.
642- module_path. push ( Segment :: from_ident_and_id (
643- Ident :: new ( kw:: PathRoot , source. ident . span ) ,
644- self . r . next_node_id ( ) ,
645- ) ) ;
646- source. ident . name = crate_name;
609+ kw:: Super => {
610+ type_ns_only = true ;
647611 }
648- if rename. is_none ( ) {
649- ident. name = sym:: dummy;
612+ kw:: SelfLower => {
613+ if let Some ( parent) = module_path. pop ( ) {
614+ let span_with_rename = match rename {
615+ Some ( rename) => source. ident . span . to ( rename. span ) ,
616+ None => source. ident . span ,
617+ } ;
618+
619+ if parent. ident . name != kw:: PathRoot {
620+ self . r . report_error (
621+ parent. ident . span . shrink_to_hi ( ) . to ( source. ident . span ) ,
622+ ResolutionError :: SelfImportsOnlyAllowedWithin {
623+ root : false ,
624+ span_with_rename,
625+ } ,
626+ ) ;
627+ }
628+
629+ let self_span = source. ident . span ;
630+ source = parent;
631+ if rename. is_none ( ) {
632+ ident = Ident :: new ( source. ident . name , self_span) ;
633+ }
634+ }
635+
636+ type_ns_only = true ;
650637 }
638+ kw:: DollarCrate => {
639+ if !module_path. is_empty ( ) {
640+ self . r . dcx ( ) . span_err (
641+ ident. span ,
642+ "`$crate` in paths can only be used in start position" ,
643+ ) ;
644+ return ;
645+ }
651646
652- self . r . dcx ( ) . emit_err ( errors:: CrateImported { span : item. span } ) ;
647+ let crate_root = self . r . resolve_crate_root ( source. ident ) ;
648+ let crate_name = match crate_root. kind {
649+ ModuleKind :: Def ( .., name) => name,
650+ ModuleKind :: Block => unreachable ! ( ) ,
651+ } ;
652+ // HACK(eddyb) unclear how good this is, but keeping `$crate`
653+ // in `source` breaks `tests/ui/imports/import-crate-var.rs`,
654+ // while the current crate doesn't have a valid `crate_name`.
655+ if let Some ( crate_name) = crate_name {
656+ // `crate_name` should not be interpreted as relative.
657+ module_path. push ( Segment :: from_ident_and_id (
658+ Ident :: new ( kw:: PathRoot , source. ident . span ) ,
659+ self . r . next_node_id ( ) ,
660+ ) ) ;
661+ source. ident . name = crate_name;
662+ }
663+ }
664+ _ => { }
653665 }
654666 }
655667
656668 if ident. name == kw:: Crate {
657669 self . r . dcx ( ) . emit_err ( errors:: UnnamedCrateRootImport { span : ident. span } ) ;
670+ return ;
671+ } else if ident. name == kw:: DollarCrate {
672+ self . r . dcx ( ) . emit_err ( errors:: CrateImported { span : item. span } ) ;
673+ return ;
674+ } else if source. ident . name == kw:: PathRoot {
675+ self . r . dcx ( ) . span_err ( ident. span , "{{root}} cannot be imported" ) ;
676+ return ;
677+ } else if ident. is_path_segment_keyword ( ) {
678+ self . r . dcx ( ) . emit_err ( errors:: UnnamedImports { span : ident. span , ident } ) ;
679+ return ;
658680 }
659681
660682 let kind = ImportKind :: Single {
@@ -708,6 +730,12 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
708730 }
709731
710732 e. emit ( ) ;
733+ } else if let & [ self_span] = & self_spans[ ..]
734+ && prefix. len ( ) == 1
735+ && prefix[ 0 ] . ident . name == kw:: DollarCrate
736+ {
737+ // Disallow `use $crate::{self};`
738+ self . r . dcx ( ) . emit_err ( errors:: CrateImported { span : self_span } ) ;
711739 }
712740
713741 for & ( ref tree, id) in items {
0 commit comments