@@ -1654,11 +1654,12 @@ impl<'a> Resolver<'a> {
16541654 let path: Vec < Ident > = segments. iter ( )
16551655 . map ( |seg| Ident :: new ( seg. name , span) )
16561656 . 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 ) {
16581659 PathResult :: Module ( module) => * def = module. def ( ) . unwrap ( ) ,
16591660 PathResult :: NonModule ( path_res) if path_res. unresolved_segments ( ) == 0 =>
16601661 * 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 ) {
16621663 PathResult :: Failed ( span, msg, _) => {
16631664 error_callback ( self , span, ResolutionError :: FailedToResolve ( & msg) ) ;
16641665 }
@@ -2360,7 +2361,8 @@ impl<'a> Resolver<'a> {
23602361 if def != Def :: Err {
23612362 new_id = Some ( def. def_id ( ) ) ;
23622363 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 ) ) {
23642366 new_val = Some ( ( module, trait_ref. clone ( ) ) ) ;
23652367 }
23662368 }
@@ -2819,7 +2821,8 @@ impl<'a> Resolver<'a> {
28192821 ( format ! ( "" ) , format ! ( "the crate root" ) )
28202822 } else {
28212823 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 ) {
28232826 PathResult :: Module ( module) => module. def ( ) ,
28242827 _ => None ,
28252828 } . map_or ( format ! ( "" ) , |def| format ! ( "{} " , def. kind_name( ) ) ) ;
@@ -3149,7 +3152,7 @@ impl<'a> Resolver<'a> {
31493152 ) ) ;
31503153 }
31513154
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 ) ) {
31533156 PathResult :: NonModule ( path_res) => path_res,
31543157 PathResult :: Module ( module) if !module. is_normal ( ) => {
31553158 PathResolution :: new ( module. def ( ) . unwrap ( ) )
@@ -3186,7 +3189,7 @@ impl<'a> Resolver<'a> {
31863189 path[ 0 ] . name != keywords:: CrateRoot . name ( ) &&
31873190 path[ 0 ] . name != keywords:: DollarCrate . name ( ) {
31883191 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 ) {
31903193 PathResult :: NonModule ( path_res) => path_res. base_def ( ) ,
31913194 PathResult :: Module ( module) => module. def ( ) . unwrap ( ) ,
31923195 _ => return Some ( result) ,
@@ -3205,7 +3208,9 @@ impl<'a> Resolver<'a> {
32053208 path : & [ Ident ] ,
32063209 opt_ns : Option < Namespace > , // `None` indicates a module path
32073210 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
32093214 -> PathResult < ' a > {
32103215 let mut module = None ;
32113216 let mut allow_super = true ;
@@ -3253,6 +3258,8 @@ impl<'a> Resolver<'a> {
32533258 let prev_name = path[ 0 ] . name ;
32543259 if prev_name == keywords:: Extern . name ( ) ||
32553260 prev_name == keywords:: CrateRoot . name ( ) &&
3261+ // Note: When this feature stabilizes, this should
3262+ // be gated on sess.rust_2018()
32563263 self . session . features_untracked ( ) . extern_absolute_paths {
32573264 // `::extern_crate::a::b`
32583265 let crate_id = self . crate_loader . process_path_extern ( name, ident. span ) ;
@@ -3324,6 +3331,33 @@ impl<'a> Resolver<'a> {
33243331 format ! ( "Not a module `{}`" , ident) ,
33253332 is_last) ;
33263333 }
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+ }
33273361 }
33283362 Err ( Undetermined ) => return PathResult :: Indeterminate ,
33293363 Err ( Determined ) => {
@@ -3571,7 +3605,7 @@ impl<'a> Resolver<'a> {
35713605 // Search in module.
35723606 let mod_path = & path[ ..path. len ( ) - 1 ] ;
35733607 if let PathResult :: Module ( module) = self . resolve_path ( mod_path, Some ( TypeNS ) ,
3574- false , span) {
3608+ false , span, None ) {
35753609 add_module_candidates ( module, & mut names) ;
35763610 }
35773611 }
0 commit comments