@@ -2865,12 +2865,13 @@ impl<'a> Resolver<'a> {
2865
2865
debug ! ( "resolve_path ident {} {:?}" , i, ident) ;
2866
2866
let is_last = i == path. len ( ) - 1 ;
2867
2867
let ns = if is_last { opt_ns. unwrap_or ( TypeNS ) } else { TypeNS } ;
2868
+ let name = ident. node . name ;
2868
2869
2869
- if i == 0 && ns == TypeNS && ident . node . name == keywords:: SelfValue . name ( ) {
2870
+ if i == 0 && ns == TypeNS && name == keywords:: SelfValue . name ( ) {
2870
2871
let mut ctxt = ident. node . ctxt . modern ( ) ;
2871
2872
module = Some ( self . resolve_self ( & mut ctxt, self . current_module ) ) ;
2872
2873
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 ( ) {
2874
2875
let mut ctxt = ident. node . ctxt . modern ( ) ;
2875
2876
let self_module = match i {
2876
2877
0 => self . resolve_self ( & mut ctxt, self . current_module ) ,
@@ -2886,12 +2887,41 @@ impl<'a> Resolver<'a> {
2886
2887
}
2887
2888
allow_super = false ;
2888
2889
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 ) ;
2895
2925
}
2896
2926
2897
2927
let binding = if let Some ( module) = module {
@@ -2942,7 +2972,7 @@ impl<'a> Resolver<'a> {
2942
2972
let msg = if module. and_then ( ModuleData :: def) == self . graph_root . def ( ) {
2943
2973
let is_mod = |def| match def { Def :: Mod ( ..) => true , _ => false } ;
2944
2974
let mut candidates =
2945
- self . lookup_import_candidates ( ident . node . name , TypeNS , is_mod) ;
2975
+ self . lookup_import_candidates ( name, TypeNS , is_mod) ;
2946
2976
candidates. sort_by_key ( |c| ( c. path . segments . len ( ) , c. path . to_string ( ) ) ) ;
2947
2977
if let Some ( candidate) = candidates. get ( 0 ) {
2948
2978
format ! ( "Did you mean `{}`?" , candidate. path)
0 commit comments