@@ -67,7 +67,7 @@ use syntax::ast::{Arm, BindingMode, Block, Crate, Expr, ExprKind};
6767use syntax:: ast:: { FnDecl , ForeignItem , ForeignItemKind , Generics } ;
6868use syntax:: ast:: { Item , ItemKind , ImplItem , ImplItemKind } ;
6969use syntax:: ast:: { Local , Pat , PatKind , Path } ;
70- use syntax:: ast:: { PathSegment , PathParameters , TraitItemKind , TraitRef , Ty , TyKind } ;
70+ use syntax:: ast:: { PathSegment , PathParameters , SelfKind , TraitItemKind , TraitRef , Ty , TyKind } ;
7171
7272use std:: collections:: { HashMap , HashSet } ;
7373use std:: cell:: { Cell , RefCell } ;
@@ -148,7 +148,13 @@ enum ResolutionError<'a> {
148148 /// error E0424: `self` is not available in a static method
149149 SelfNotAvailableInStaticMethod ,
150150 /// error E0425: unresolved name
151- UnresolvedName ( & ' a str , & ' a str , UnresolvedNameContext < ' a > ) ,
151+ UnresolvedName {
152+ path : & ' a str ,
153+ message : & ' a str ,
154+ context : UnresolvedNameContext < ' a > ,
155+ is_static_method : bool ,
156+ is_field : bool
157+ } ,
152158 /// error E0426: use of undeclared label
153159 UndeclaredLabel ( & ' a str ) ,
154160 /// error E0427: cannot use `ref` binding mode with ...
@@ -406,16 +412,21 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
406412 "`self` is not available in a static method. Maybe a `self` \
407413 argument is missing?")
408414 }
409- ResolutionError :: UnresolvedName ( path, msg, context) => {
415+ ResolutionError :: UnresolvedName { path, message : msg, context, is_static_method,
416+ is_field } => {
410417 let mut err = struct_span_err ! ( resolver. session,
411418 span,
412419 E0425 ,
413420 "unresolved name `{}`{}" ,
414421 path,
415422 msg) ;
416-
417423 match context {
418- UnresolvedNameContext :: Other => { } // no help available
424+ UnresolvedNameContext :: Other => {
425+ if msg. is_empty ( ) && is_static_method && is_field {
426+ err. help ( "this is an associated function, you don't have access to \
427+ this type's fields or methods") ;
428+ }
429+ }
419430 UnresolvedNameContext :: PathIsMod ( parent) => {
420431 err. help ( & match parent. map ( |parent| & parent. node ) {
421432 Some ( & ExprKind :: Field ( _, ident) ) => {
@@ -596,7 +607,7 @@ impl<'a, 'v> Visitor<'v> for Resolver<'a> {
596607 }
597608 FnKind :: Method ( _, sig, _) => {
598609 self . visit_generics ( & sig. generics ) ;
599- MethodRibKind
610+ MethodRibKind ( sig . explicit_self . node == SelfKind :: Static )
600611 }
601612 FnKind :: Closure => ClosureRibKind ( node_id) ,
602613 } ;
@@ -666,7 +677,9 @@ enum RibKind<'a> {
666677 // methods. Allow references to ty params that impl or trait
667678 // binds. Disallow any other upvars (including other ty params that are
668679 // upvars).
669- MethodRibKind ,
680+ //
681+ // The boolean value represents the fact that this method is static or not.
682+ MethodRibKind ( bool ) ,
670683
671684 // We passed through an item scope. Disallow upvars.
672685 ItemRibKind ,
@@ -1095,7 +1108,13 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
10951108 Err ( false ) => {
10961109 let path_name = & format ! ( "{}" , path) ;
10971110 let error =
1098- ResolutionError :: UnresolvedName ( path_name, "" , UnresolvedNameContext :: Other ) ;
1111+ ResolutionError :: UnresolvedName {
1112+ path : path_name,
1113+ message : "" ,
1114+ context : UnresolvedNameContext :: Other ,
1115+ is_static_method : false ,
1116+ is_field : false
1117+ } ;
10991118 resolve_error ( self , path. span , error) ;
11001119 Def :: Err
11011120 }
@@ -1657,7 +1676,9 @@ impl<'a> Resolver<'a> {
16571676 let type_parameters =
16581677 HasTypeParameters ( & sig. generics ,
16591678 FnSpace ,
1660- MethodRibKind ) ;
1679+ MethodRibKind (
1680+ sig. explicit_self . node ==
1681+ SelfKind :: Static ) ) ;
16611682 this. with_type_parameter_rib ( type_parameters, |this| {
16621683 visit:: walk_trait_item ( this, trait_item)
16631684 } ) ;
@@ -1776,7 +1797,10 @@ impl<'a> Resolver<'a> {
17761797 self . value_ribs . pop ( ) ;
17771798 }
17781799
1779- fn resolve_function ( & mut self , rib_kind : RibKind < ' a > , declaration : & FnDecl , block : & Block ) {
1800+ fn resolve_function ( & mut self ,
1801+ rib_kind : RibKind < ' a > ,
1802+ declaration : & FnDecl ,
1803+ block : & Block ) {
17801804 // Create a value rib for the function.
17811805 self . value_ribs . push ( Rib :: new ( rib_kind) ) ;
17821806
@@ -1983,7 +2007,9 @@ impl<'a> Resolver<'a> {
19832007 let type_parameters =
19842008 HasTypeParameters ( & sig. generics ,
19852009 FnSpace ,
1986- MethodRibKind ) ;
2010+ MethodRibKind (
2011+ sig. explicit_self . node ==
2012+ SelfKind :: Static ) ) ;
19872013 this. with_type_parameter_rib ( type_parameters, |this| {
19882014 visit:: walk_impl_item ( this, impl_item) ;
19892015 } ) ;
@@ -2677,7 +2703,7 @@ impl<'a> Resolver<'a> {
26772703 def = Def :: Upvar ( node_def_id, node_id, depth, function_id) ;
26782704 seen. insert ( node_id, depth) ;
26792705 }
2680- ItemRibKind | MethodRibKind => {
2706+ ItemRibKind | MethodRibKind ( _ ) => {
26812707 // This was an attempt to access an upvar inside a
26822708 // named function item. This is not allowed, so we
26832709 // report an error.
@@ -2699,7 +2725,7 @@ impl<'a> Resolver<'a> {
26992725 Def :: TyParam ( ..) | Def :: SelfTy ( ..) => {
27002726 for rib in ribs {
27012727 match rib. kind {
2702- NormalRibKind | MethodRibKind | ClosureRibKind ( ..) |
2728+ NormalRibKind | MethodRibKind ( _ ) | ClosureRibKind ( ..) |
27032729 ModuleRibKind ( ..) => {
27042730 // Nothing to do. Continue.
27052731 }
@@ -2992,9 +3018,13 @@ impl<'a> Resolver<'a> {
29923018 // `resolve_path` already reported the error
29933019 } else {
29943020 let mut method_scope = false ;
3021+ let mut is_static = false ;
29953022 self . value_ribs . iter ( ) . rev ( ) . all ( |rib| {
29963023 method_scope = match rib. kind {
2997- MethodRibKind => true ,
3024+ MethodRibKind ( is_static_) => {
3025+ is_static = is_static_;
3026+ true
3027+ }
29983028 ItemRibKind | ConstantItemRibKind => false ,
29993029 _ => return true , // Keep advancing
30003030 } ;
@@ -3008,22 +3038,29 @@ impl<'a> Resolver<'a> {
30083038 ResolutionError :: SelfNotAvailableInStaticMethod ) ;
30093039 } else {
30103040 let last_name = path. segments . last ( ) . unwrap ( ) . identifier . name ;
3011- let mut msg = match self . find_fallback_in_self_type ( last_name) {
3041+ let ( mut msg, is_field) =
3042+ match self . find_fallback_in_self_type ( last_name) {
30123043 NoSuggestion => {
30133044 // limit search to 5 to reduce the number
30143045 // of stupid suggestions
3015- match self . find_best_match ( & path_name) {
3046+ ( match self . find_best_match ( & path_name) {
30163047 SuggestionType :: Macro ( s) => {
30173048 format ! ( "the macro `{}`" , s)
30183049 }
30193050 SuggestionType :: Function ( s) => format ! ( "`{}`" , s) ,
30203051 SuggestionType :: NotFound => "" . to_string ( ) ,
3021- }
3052+ } , false )
3053+ }
3054+ Field => {
3055+ ( if is_static && method_scope {
3056+ "" . to_string ( )
3057+ } else {
3058+ format ! ( "`self.{}`" , path_name)
3059+ } , true )
30223060 }
3023- Field => format ! ( "`self.{}`" , path_name) ,
3024- TraitItem => format ! ( "to call `self.{}`" , path_name) ,
3061+ TraitItem => ( format ! ( "to call `self.{}`" , path_name) , false ) ,
30253062 TraitMethod ( path_str) =>
3026- format ! ( "to call `{}::{}`" , path_str, path_name) ,
3063+ ( format ! ( "to call `{}::{}`" , path_str, path_name) , false ) ,
30273064 } ;
30283065
30293066 let mut context = UnresolvedNameContext :: Other ;
@@ -3048,8 +3085,13 @@ impl<'a> Resolver<'a> {
30483085
30493086 resolve_error ( self ,
30503087 expr. span ,
3051- ResolutionError :: UnresolvedName (
3052- & path_name, & msg, context) ) ;
3088+ ResolutionError :: UnresolvedName {
3089+ path : & path_name,
3090+ message : & msg,
3091+ context : context,
3092+ is_static_method : method_scope && is_static,
3093+ is_field : is_field,
3094+ } ) ;
30533095 }
30543096 }
30553097 }
0 commit comments