@@ -1654,11 +1654,12 @@ impl<'a> Resolver<'a> {
1654
1654
let path: Vec < Ident > = segments. iter ( )
1655
1655
. map ( |seg| Ident :: new ( seg. name , span) )
1656
1656
. collect ( ) ;
1657
- match self . resolve_path ( & path, Some ( namespace) , true , span) {
1657
+ // FIXME (Manishearth): Intra doc links won't get warned of epoch changes
1658
+ match self . resolve_path ( & path, Some ( namespace) , true , span, None ) {
1658
1659
PathResult :: Module ( module) => * def = module. def ( ) . unwrap ( ) ,
1659
1660
PathResult :: NonModule ( path_res) if path_res. unresolved_segments ( ) == 0 =>
1660
1661
* def = path_res. base_def ( ) ,
1661
- PathResult :: NonModule ( ..) => match self . resolve_path ( & path, None , true , span) {
1662
+ PathResult :: NonModule ( ..) => match self . resolve_path ( & path, None , true , span, None ) {
1662
1663
PathResult :: Failed ( span, msg, _) => {
1663
1664
error_callback ( self , span, ResolutionError :: FailedToResolve ( & msg) ) ;
1664
1665
}
@@ -2360,7 +2361,8 @@ impl<'a> Resolver<'a> {
2360
2361
if def != Def :: Err {
2361
2362
new_id = Some ( def. def_id ( ) ) ;
2362
2363
let span = trait_ref. path . span ;
2363
- if let PathResult :: Module ( module) = self . resolve_path ( & path, None , false , span) {
2364
+ if let PathResult :: Module ( module) = self . resolve_path ( & path, None , false , span,
2365
+ Some ( trait_ref. ref_id ) ) {
2364
2366
new_val = Some ( ( module, trait_ref. clone ( ) ) ) ;
2365
2367
}
2366
2368
}
@@ -2819,7 +2821,8 @@ impl<'a> Resolver<'a> {
2819
2821
( format ! ( "" ) , format ! ( "the crate root" ) )
2820
2822
} else {
2821
2823
let mod_path = & path[ ..path. len ( ) - 1 ] ;
2822
- let mod_prefix = match this. resolve_path ( mod_path, Some ( TypeNS ) , false , span) {
2824
+ let mod_prefix = match this. resolve_path ( mod_path, Some ( TypeNS ) ,
2825
+ false , span, None ) {
2823
2826
PathResult :: Module ( module) => module. def ( ) ,
2824
2827
_ => None ,
2825
2828
} . map_or ( format ! ( "" ) , |def| format ! ( "{} " , def. kind_name( ) ) ) ;
@@ -3149,7 +3152,7 @@ impl<'a> Resolver<'a> {
3149
3152
) ) ;
3150
3153
}
3151
3154
3152
- let result = match self . resolve_path ( & path, Some ( ns) , true , span) {
3155
+ let result = match self . resolve_path ( & path, Some ( ns) , true , span, Some ( id ) ) {
3153
3156
PathResult :: NonModule ( path_res) => path_res,
3154
3157
PathResult :: Module ( module) if !module. is_normal ( ) => {
3155
3158
PathResolution :: new ( module. def ( ) . unwrap ( ) )
@@ -3186,7 +3189,7 @@ impl<'a> Resolver<'a> {
3186
3189
path[ 0 ] . name != keywords:: CrateRoot . name ( ) &&
3187
3190
path[ 0 ] . name != keywords:: DollarCrate . name ( ) {
3188
3191
let unqualified_result = {
3189
- match self . resolve_path ( & [ * path. last ( ) . unwrap ( ) ] , Some ( ns) , false , span) {
3192
+ match self . resolve_path ( & [ * path. last ( ) . unwrap ( ) ] , Some ( ns) , false , span, None ) {
3190
3193
PathResult :: NonModule ( path_res) => path_res. base_def ( ) ,
3191
3194
PathResult :: Module ( module) => module. def ( ) . unwrap ( ) ,
3192
3195
_ => return Some ( result) ,
@@ -3205,7 +3208,9 @@ impl<'a> Resolver<'a> {
3205
3208
path : & [ Ident ] ,
3206
3209
opt_ns : Option < Namespace > , // `None` indicates a module path
3207
3210
record_used : bool ,
3208
- path_span : Span )
3211
+ path_span : Span ,
3212
+ node_id : Option < NodeId > ) // None indicates that we don't care about linting
3213
+ // `::module` paths
3209
3214
-> PathResult < ' a > {
3210
3215
let mut module = None ;
3211
3216
let mut allow_super = true ;
@@ -3253,6 +3258,8 @@ impl<'a> Resolver<'a> {
3253
3258
let prev_name = path[ 0 ] . name ;
3254
3259
if prev_name == keywords:: Extern . name ( ) ||
3255
3260
prev_name == keywords:: CrateRoot . name ( ) &&
3261
+ // Note: When this feature stabilizes, this should
3262
+ // be gated on sess.rust_2018()
3256
3263
self . session . features_untracked ( ) . extern_absolute_paths {
3257
3264
// `::extern_crate::a::b`
3258
3265
let crate_id = self . crate_loader . process_path_extern ( name, ident. span ) ;
@@ -3324,6 +3331,33 @@ impl<'a> Resolver<'a> {
3324
3331
format ! ( "Not a module `{}`" , ident) ,
3325
3332
is_last) ;
3326
3333
}
3334
+
3335
+ if let Some ( id) = node_id {
3336
+ if i == 1 && self . session . features_untracked ( ) . crate_in_paths
3337
+ && !self . session . rust_2018 ( ) {
3338
+ let prev_name = path[ 0 ] . name ;
3339
+ if prev_name == keywords:: Extern . name ( ) ||
3340
+ prev_name == keywords:: CrateRoot . name ( ) {
3341
+ let mut is_crate = false ;
3342
+ if let NameBindingKind :: Import { directive : d, .. } = binding. kind {
3343
+ if let ImportDirectiveSubclass :: ExternCrate ( ..) = d. subclass {
3344
+ is_crate = true ;
3345
+ }
3346
+ }
3347
+
3348
+ if !is_crate {
3349
+ let diag = lint:: builtin:: BuiltinLintDiagnostics
3350
+ :: AbsPathWithModule ( path_span) ;
3351
+ self . session . buffer_lint_with_diagnostic (
3352
+ lint:: builtin:: ABSOLUTE_PATH_STARTING_WITH_MODULE ,
3353
+ id, path_span,
3354
+ "Absolute paths must start with `self`, `super`, \
3355
+ `crate`, or an external crate name in the 2018 edition",
3356
+ diag) ;
3357
+ }
3358
+ }
3359
+ }
3360
+ }
3327
3361
}
3328
3362
Err ( Undetermined ) => return PathResult :: Indeterminate ,
3329
3363
Err ( Determined ) => {
@@ -3571,7 +3605,7 @@ impl<'a> Resolver<'a> {
3571
3605
// Search in module.
3572
3606
let mod_path = & path[ ..path. len ( ) - 1 ] ;
3573
3607
if let PathResult :: Module ( module) = self . resolve_path ( mod_path, Some ( TypeNS ) ,
3574
- false , span) {
3608
+ false , span, None ) {
3575
3609
add_module_candidates ( module, & mut names) ;
3576
3610
}
3577
3611
}
0 commit comments