@@ -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 }
@@ -1653,7 +1672,9 @@ impl<'a> Resolver<'a> {
16531672 let type_parameters =
16541673 HasTypeParameters ( & sig. generics ,
16551674 FnSpace ,
1656- MethodRibKind ) ;
1675+ MethodRibKind (
1676+ sig. explicit_self . node ==
1677+ SelfKind :: Static ) ) ;
16571678 this. with_type_parameter_rib ( type_parameters, |this| {
16581679 visit:: walk_trait_item ( this, trait_item)
16591680 } ) ;
@@ -1772,7 +1793,10 @@ impl<'a> Resolver<'a> {
17721793 self . value_ribs . pop ( ) ;
17731794 }
17741795
1775- fn resolve_function ( & mut self , rib_kind : RibKind < ' a > , declaration : & FnDecl , block : & Block ) {
1796+ fn resolve_function ( & mut self ,
1797+ rib_kind : RibKind < ' a > ,
1798+ declaration : & FnDecl ,
1799+ block : & Block ) {
17761800 // Create a value rib for the function.
17771801 self . value_ribs . push ( Rib :: new ( rib_kind) ) ;
17781802
@@ -1979,7 +2003,9 @@ impl<'a> Resolver<'a> {
19792003 let type_parameters =
19802004 HasTypeParameters ( & sig. generics ,
19812005 FnSpace ,
1982- MethodRibKind ) ;
2006+ MethodRibKind (
2007+ sig. explicit_self . node ==
2008+ SelfKind :: Static ) ) ;
19832009 this. with_type_parameter_rib ( type_parameters, |this| {
19842010 visit:: walk_impl_item ( this, impl_item) ;
19852011 } ) ;
@@ -2673,7 +2699,7 @@ impl<'a> Resolver<'a> {
26732699 def = Def :: Upvar ( node_def_id, node_id, depth, function_id) ;
26742700 seen. insert ( node_id, depth) ;
26752701 }
2676- ItemRibKind | MethodRibKind => {
2702+ ItemRibKind | MethodRibKind ( _ ) => {
26772703 // This was an attempt to access an upvar inside a
26782704 // named function item. This is not allowed, so we
26792705 // report an error.
@@ -2695,7 +2721,7 @@ impl<'a> Resolver<'a> {
26952721 Def :: TyParam ( ..) | Def :: SelfTy ( ..) => {
26962722 for rib in ribs {
26972723 match rib. kind {
2698- NormalRibKind | MethodRibKind | ClosureRibKind ( ..) |
2724+ NormalRibKind | MethodRibKind ( _ ) | ClosureRibKind ( ..) |
26992725 ModuleRibKind ( ..) => {
27002726 // Nothing to do. Continue.
27012727 }
@@ -2988,9 +3014,13 @@ impl<'a> Resolver<'a> {
29883014 // `resolve_path` already reported the error
29893015 } else {
29903016 let mut method_scope = false ;
3017+ let mut is_static = false ;
29913018 self . value_ribs . iter ( ) . rev ( ) . all ( |rib| {
29923019 method_scope = match rib. kind {
2993- MethodRibKind => true ,
3020+ MethodRibKind ( is_static_) => {
3021+ is_static = is_static_;
3022+ true
3023+ }
29943024 ItemRibKind | ConstantItemRibKind => false ,
29953025 _ => return true , // Keep advancing
29963026 } ;
@@ -3004,22 +3034,29 @@ impl<'a> Resolver<'a> {
30043034 ResolutionError :: SelfNotAvailableInStaticMethod ) ;
30053035 } else {
30063036 let last_name = path. segments . last ( ) . unwrap ( ) . identifier . name ;
3007- let mut msg = match self . find_fallback_in_self_type ( last_name) {
3037+ let ( mut msg, is_field) =
3038+ match self . find_fallback_in_self_type ( last_name) {
30083039 NoSuggestion => {
30093040 // limit search to 5 to reduce the number
30103041 // of stupid suggestions
3011- match self . find_best_match ( & path_name) {
3042+ ( match self . find_best_match ( & path_name) {
30123043 SuggestionType :: Macro ( s) => {
30133044 format ! ( "the macro `{}`" , s)
30143045 }
30153046 SuggestionType :: Function ( s) => format ! ( "`{}`" , s) ,
30163047 SuggestionType :: NotFound => "" . to_string ( ) ,
3017- }
3048+ } , false )
3049+ }
3050+ Field => {
3051+ ( if is_static && method_scope {
3052+ "" . to_string ( )
3053+ } else {
3054+ format ! ( "`self.{}`" , path_name)
3055+ } , true )
30183056 }
3019- Field => format ! ( "`self.{}`" , path_name) ,
3020- TraitItem => format ! ( "to call `self.{}`" , path_name) ,
3057+ TraitItem => ( format ! ( "to call `self.{}`" , path_name) , false ) ,
30213058 TraitMethod ( path_str) =>
3022- format ! ( "to call `{}::{}`" , path_str, path_name) ,
3059+ ( format ! ( "to call `{}::{}`" , path_str, path_name) , false ) ,
30233060 } ;
30243061
30253062 let mut context = UnresolvedNameContext :: Other ;
@@ -3044,8 +3081,13 @@ impl<'a> Resolver<'a> {
30443081
30453082 resolve_error ( self ,
30463083 expr. span ,
3047- ResolutionError :: UnresolvedName (
3048- & path_name, & msg, context) ) ;
3084+ ResolutionError :: UnresolvedName {
3085+ path : & path_name,
3086+ message : & msg,
3087+ context : context,
3088+ is_static_method : method_scope && is_static,
3089+ is_field : is_field,
3090+ } ) ;
30493091 }
30503092 }
30513093 }
0 commit comments