@@ -25,6 +25,7 @@ use rustc_metadata::creader::LoadedMacro;
2525use rustc_middle:: metadata:: { ModChild , Reexport } ;
2626use rustc_middle:: ty:: { Feed , Visibility } ;
2727use rustc_middle:: { bug, span_bug} ;
28+ use rustc_session:: lint:: builtin:: REDUNDANT_SELF ;
2829use rustc_span:: hygiene:: { ExpnId , LocalExpnId , MacroKind } ;
2930use rustc_span:: { Ident , Span , Symbol , kw, sym} ;
3031use thin_vec:: ThinVec ;
@@ -37,8 +38,8 @@ use crate::macros::{MacroRulesDecl, MacroRulesScope, MacroRulesScopeRef};
3738use crate :: ref_mut:: CmCell ;
3839use crate :: {
3940 BindingKey , Decl , DeclData , DeclKind , ExternPreludeEntry , Finalize , IdentKey , MacroData ,
40- Module , ModuleKind , ModuleOrUniformRoot , ParentScope , PathResult , ResolutionError , Resolver ,
41- Segment , Used , VisResolutionError , errors,
41+ Module , ModuleKind , ModuleOrUniformRoot , ParentScope , PathResult , Resolver , Segment , Used ,
42+ VisResolutionError , errors,
4243} ;
4344
4445type Res = def:: Res < NodeId > ;
@@ -626,8 +627,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
626627 let mut module_path = prefix;
627628 let mut source = module_path. pop ( ) . unwrap ( ) ;
628629
629- // `true` for `...::{self [as target]}` imports, `false` otherwise.
630- let type_ns_only = nested && source. ident . name == kw:: SelfLower ;
630+ let type_ns_only = source. ident . name == kw:: SelfLower ;
631631
632632 match source. ident . name {
633633 kw:: DollarCrate => {
@@ -666,22 +666,19 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
666666 }
667667 kw:: SelfLower => {
668668 if let Some ( parent) = module_path. pop ( ) {
669- // Suggest `use prefix::{self};` for `use prefix::self;`
670- if !type_ns_only
671- && ( parent. ident . name != kw:: PathRoot
672- || self . r . path_root_is_crate_root ( parent. ident ) )
673- {
674- let span_with_rename = match rename {
675- Some ( rename) => source. ident . span . to ( rename. span ) ,
676- None => source. ident . span ,
677- } ;
678-
679- self . r . report_error (
680- parent. ident . span . shrink_to_hi ( ) . to ( source. ident . span ) ,
681- ResolutionError :: SelfImportsOnlyAllowedWithin {
682- root : parent. ident . name == kw:: PathRoot ,
683- span_with_rename,
684- } ,
669+ // `true` for `...::{self [as target]}` imports, `false` otherwise.
670+ let nested_self = nested
671+ && source. ident . name == kw:: SelfLower
672+ && use_tree. prefix . segments . len ( ) == 1 ;
673+
674+ // Lint `use ...::self [as target];`
675+ if !nested_self && parent. ident . name != kw:: PathRoot {
676+ let span = parent. ident . span . shrink_to_hi ( ) . to ( source. ident . span ) ;
677+ self . r . lint_buffer ( ) . buffer_lint (
678+ REDUNDANT_SELF ,
679+ item. id ,
680+ source. ident . span ,
681+ errors:: RedundantSelfDiag :: Remove { span } ,
685682 ) ;
686683 }
687684
@@ -706,16 +703,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
706703 // Deny importing path-kw without renaming
707704 if rename. is_none ( ) && ident. is_path_segment_keyword ( ) {
708705 let ident = use_tree. ident ( ) ;
709-
710- // Don't suggest `use xx::self as name;` for `use xx::self;`
711- // But it's OK to suggest `use xx::{self as name};` for `use xx::{self};`
712- let sugg = if !type_ns_only && ident. name == kw:: SelfLower {
713- None
714- } else {
715- Some ( errors:: UnnamedImportSugg { span : ident. span , ident } )
716- } ;
717-
718- self . r . dcx ( ) . emit_err ( errors:: UnnamedImport { span : ident. span , sugg } ) ;
706+ self . r . dcx ( ) . emit_err ( errors:: UnnamedImport {
707+ span : ident. span ,
708+ sugg : errors:: UnnamedImportSugg { span : ident. span , ident } ,
709+ } ) ;
719710 return ;
720711 }
721712
@@ -745,7 +736,33 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
745736 }
746737 }
747738 }
748- ast:: UseTreeKind :: Nested { ref items, .. } => {
739+ ast:: UseTreeKind :: Nested { ref items, span } => {
740+ // Lint `use ...::{self [as target]};`
741+ if let Some ( parent) = prefix. last ( )
742+ && parent. ident . name != kw:: PathRoot
743+ && let [ ( tree, _) ] = & items[ ..]
744+ && let ast:: UseTreeKind :: Simple ( rename) = tree. kind
745+ && let [ segment] = & tree. prefix . segments [ ..]
746+ && segment. ident . name == kw:: SelfLower
747+ {
748+ let span = parent. ident . span . shrink_to_hi ( ) . to ( span) ;
749+ if let Some ( rename) = rename {
750+ self . r . lint_buffer ( ) . buffer_lint (
751+ REDUNDANT_SELF ,
752+ item. id ,
753+ segment. ident . span ,
754+ errors:: RedundantSelfDiag :: Replace { span, rename } ,
755+ ) ;
756+ } else {
757+ self . r . lint_buffer ( ) . buffer_lint (
758+ REDUNDANT_SELF ,
759+ item. id ,
760+ segment. ident . span ,
761+ errors:: RedundantSelfDiag :: Remove { span } ,
762+ ) ;
763+ }
764+ }
765+
749766 for & ( ref tree, id) in items {
750767 self . build_reduced_graph_for_use_tree (
751768 // This particular use tree
0 commit comments