@@ -2865,12 +2865,13 @@ impl<'a> Resolver<'a> {
28652865 debug ! ( "resolve_path ident {} {:?}" , i, ident) ;
28662866 let is_last = i == path. len ( ) - 1 ;
28672867 let ns = if is_last { opt_ns. unwrap_or ( TypeNS ) } else { TypeNS } ;
2868+ let name = ident. node . name ;
28682869
2869- if i == 0 && ns == TypeNS && ident . node . name == keywords:: SelfValue . name ( ) {
2870+ if i == 0 && ns == TypeNS && name == keywords:: SelfValue . name ( ) {
28702871 let mut ctxt = ident. node . ctxt . modern ( ) ;
28712872 module = Some ( self . resolve_self ( & mut ctxt, self . current_module ) ) ;
28722873 continue
2873- } else if allow_super && ns == TypeNS && ident . node . name == keywords:: Super . name ( ) {
2874+ } else if allow_super && ns == TypeNS && name == keywords:: Super . name ( ) {
28742875 let mut ctxt = ident. node . ctxt . modern ( ) ;
28752876 let self_module = match i {
28762877 0 => self . resolve_self ( & mut ctxt, self . current_module ) ,
@@ -2886,12 +2887,41 @@ impl<'a> Resolver<'a> {
28862887 }
28872888 allow_super = false ;
28882889
2889- if i == 0 && ns == TypeNS && ident. node . name == keywords:: CrateRoot . name ( ) {
2890- module = Some ( self . resolve_crate_root ( ident. node . ctxt . modern ( ) ) ) ;
2891- continue
2892- } else if i == 0 && ns == TypeNS && ident. node . name == keywords:: DollarCrate . name ( ) {
2893- module = Some ( self . resolve_crate_root ( ident. node . ctxt ) ) ;
2894- continue
2890+ if ns == TypeNS {
2891+ if ( i == 0 && name == keywords:: CrateRoot . name ( ) ) ||
2892+ ( i == 1 && name == keywords:: Crate . name ( ) &&
2893+ path[ 0 ] . node . name == keywords:: CrateRoot . name ( ) ) {
2894+ // `::a::b` or `::crate::a::b`
2895+ module = Some ( self . resolve_crate_root ( ident. node . ctxt . modern ( ) ) ) ;
2896+ continue
2897+ } else if i == 0 && name == keywords:: DollarCrate . name ( ) {
2898+ // `$crate::a::b`
2899+ module = Some ( self . resolve_crate_root ( ident. node . ctxt ) ) ;
2900+ continue
2901+ }
2902+ }
2903+
2904+ // Report special messages for path segment keywords in wrong positions.
2905+ if name == keywords:: CrateRoot . name ( ) && i != 0 ||
2906+ name == keywords:: DollarCrate . name ( ) && i != 0 ||
2907+ name == keywords:: SelfValue . name ( ) && i != 0 ||
2908+ name == keywords:: SelfType . name ( ) && i != 0 ||
2909+ name == keywords:: Super . name ( ) && i != 0 ||
2910+ name == keywords:: Crate . name ( ) && i != 1 &&
2911+ path[ 0 ] . node . name != keywords:: CrateRoot . name ( ) {
2912+ let name_str = if name == keywords:: CrateRoot . name ( ) {
2913+ format ! ( "crate root" )
2914+ } else {
2915+ format ! ( "`{}`" , name)
2916+ } ;
2917+ let msg = if i == 1 && path[ 0 ] . node . name == keywords:: CrateRoot . name ( ) {
2918+ format ! ( "global paths cannot start with {}" , name_str)
2919+ } else if i == 0 && name == keywords:: Crate . name ( ) {
2920+ format ! ( "{} can only be used in absolute paths" , name_str)
2921+ } else {
2922+ format ! ( "{} in paths can only be used in start position" , name_str)
2923+ } ;
2924+ return PathResult :: Failed ( ident. span , msg, false ) ;
28952925 }
28962926
28972927 let binding = if let Some ( module) = module {
@@ -2942,7 +2972,7 @@ impl<'a> Resolver<'a> {
29422972 let msg = if module. and_then ( ModuleData :: def) == self . graph_root . def ( ) {
29432973 let is_mod = |def| match def { Def :: Mod ( ..) => true , _ => false } ;
29442974 let mut candidates =
2945- self . lookup_import_candidates ( ident . node . name , TypeNS , is_mod) ;
2975+ self . lookup_import_candidates ( name, TypeNS , is_mod) ;
29462976 candidates. sort_by_key ( |c| ( c. path . segments . len ( ) , c. path . to_string ( ) ) ) ;
29472977 if let Some ( candidate) = candidates. get ( 0 ) {
29482978 format ! ( "Did you mean `{}`?" , candidate. path)
0 commit comments