@@ -3232,6 +3232,7 @@ impl<'a> Resolver<'a> {
32323232 -> PathResult < ' a > {
32333233 let mut module = None ;
32343234 let mut allow_super = true ;
3235+ let mut second_binding = None ;
32353236
32363237 for ( i, & ident) in path. iter ( ) . enumerate ( ) {
32373238 debug ! ( "resolve_path ident {} {:?}" , i, ident) ;
@@ -3334,13 +3335,22 @@ impl<'a> Resolver<'a> {
33343335
33353336 match binding {
33363337 Ok ( binding) => {
3338+ if i == 1 {
3339+ second_binding = Some ( binding) ;
3340+ }
33373341 let def = binding. def ( ) ;
33383342 let maybe_assoc = opt_ns != Some ( MacroNS ) && PathSource :: Type . is_expected ( def) ;
33393343 if let Some ( next_module) = binding. module ( ) {
33403344 module = Some ( next_module) ;
33413345 } else if def == Def :: Err {
33423346 return PathResult :: NonModule ( err_path_resolution ( ) ) ;
33433347 } else if opt_ns. is_some ( ) && ( is_last || maybe_assoc) {
3348+ self . lint_if_path_starts_with_module (
3349+ node_id,
3350+ path,
3351+ path_span,
3352+ second_binding,
3353+ ) ;
33443354 return PathResult :: NonModule ( PathResolution :: with_unresolved_segments (
33453355 def, path. len ( ) - i - 1
33463356 ) ) ;
@@ -3349,33 +3359,6 @@ impl<'a> Resolver<'a> {
33493359 format ! ( "Not a module `{}`" , ident) ,
33503360 is_last) ;
33513361 }
3352-
3353- if let Some ( id) = node_id {
3354- if i == 1 && self . session . features_untracked ( ) . crate_in_paths
3355- && !self . session . rust_2018 ( ) {
3356- let prev_name = path[ 0 ] . name ;
3357- if prev_name == keywords:: Extern . name ( ) ||
3358- prev_name == keywords:: CrateRoot . name ( ) {
3359- let mut is_crate = false ;
3360- if let NameBindingKind :: Import { directive : d, .. } = binding. kind {
3361- if let ImportDirectiveSubclass :: ExternCrate ( ..) = d. subclass {
3362- is_crate = true ;
3363- }
3364- }
3365-
3366- if !is_crate {
3367- let diag = lint:: builtin:: BuiltinLintDiagnostics
3368- :: AbsPathWithModule ( path_span) ;
3369- self . session . buffer_lint_with_diagnostic (
3370- lint:: builtin:: ABSOLUTE_PATH_STARTING_WITH_MODULE ,
3371- id, path_span,
3372- "Absolute paths must start with `self`, `super`, \
3373- `crate`, or an external crate name in the 2018 edition",
3374- diag) ;
3375- }
3376- }
3377- }
3378- }
33793362 }
33803363 Err ( Undetermined ) => return PathResult :: Indeterminate ,
33813364 Err ( Determined ) => {
@@ -3408,9 +3391,67 @@ impl<'a> Resolver<'a> {
34083391 }
34093392 }
34103393
3394+ self . lint_if_path_starts_with_module ( node_id, path, path_span, second_binding) ;
3395+
34113396 PathResult :: Module ( module. unwrap_or ( self . graph_root ) )
34123397 }
34133398
3399+ fn lint_if_path_starts_with_module ( & self ,
3400+ id : Option < NodeId > ,
3401+ path : & [ Ident ] ,
3402+ path_span : Span ,
3403+ second_binding : Option < & NameBinding > ) {
3404+ // In the 2018 edition this lint is a hard error, so nothing to do
3405+ if self . session . rust_2018 ( ) {
3406+ return
3407+ }
3408+ // In the 2015 edition there's no use in emitting lints unless the
3409+ // crate's already enabled the feature that we're going to suggest
3410+ if !self . session . features_untracked ( ) . crate_in_paths {
3411+ return
3412+ }
3413+ let id = match id {
3414+ Some ( id) => id,
3415+ None => return ,
3416+ } ;
3417+ let first_name = match path. get ( 0 ) {
3418+ Some ( ident) => ident. name ,
3419+ None => return ,
3420+ } ;
3421+
3422+ // We're only interested in `use` paths which should start with
3423+ // `{{root}}` or `extern` currently.
3424+ if first_name != keywords:: Extern . name ( ) && first_name != keywords:: CrateRoot . name ( ) {
3425+ return
3426+ }
3427+
3428+ if let Some ( part) = path. get ( 1 ) {
3429+ if part. name == keywords:: Crate . name ( ) {
3430+ return
3431+ }
3432+ }
3433+
3434+ // If the first element of our path was actually resolved to an
3435+ // `ExternCrate` (also used for `crate::...`) then no need to issue a
3436+ // warning, this looks all good!
3437+ if let Some ( binding) = second_binding {
3438+ if let NameBindingKind :: Import { directive : d, .. } = binding. kind {
3439+ if let ImportDirectiveSubclass :: ExternCrate ( ..) = d. subclass {
3440+ return
3441+ }
3442+ }
3443+ }
3444+
3445+ let diag = lint:: builtin:: BuiltinLintDiagnostics
3446+ :: AbsPathWithModule ( path_span) ;
3447+ self . session . buffer_lint_with_diagnostic (
3448+ lint:: builtin:: ABSOLUTE_PATH_STARTING_WITH_MODULE ,
3449+ id, path_span,
3450+ "Absolute paths must start with `self`, `super`, \
3451+ `crate`, or an external crate name in the 2018 edition",
3452+ diag) ;
3453+ }
3454+
34143455 // Resolve a local definition, potentially adjusting for closures.
34153456 fn adjust_local_def ( & mut self ,
34163457 ns : Namespace ,
0 commit comments