@@ -68,7 +68,7 @@ use rustc::hir::intravisit::{self, FnKind, Visitor};
68
68
use rustc:: hir;
69
69
use rustc:: hir:: { Arm , BindByRef , BindByValue , BindingMode , Block } ;
70
70
use rustc:: hir:: Crate ;
71
- use rustc:: hir:: { Expr , ExprAgain , ExprBreak , ExprCall , ExprField } ;
71
+ use rustc:: hir:: { Expr , ExprAgain , ExprBreak , ExprField } ;
72
72
use rustc:: hir:: { ExprLoop , ExprWhile , ExprMethodCall } ;
73
73
use rustc:: hir:: { ExprPath , ExprStruct , FnDecl } ;
74
74
use rustc:: hir:: { ForeignItemFn , ForeignItemStatic , Generics } ;
@@ -163,7 +163,7 @@ enum ResolutionError<'a> {
163
163
/// error E0424: `self` is not available in a static method
164
164
SelfNotAvailableInStaticMethod ,
165
165
/// error E0425: unresolved name
166
- UnresolvedName ( & ' a str , & ' a str , UnresolvedNameContext ) ,
166
+ UnresolvedName ( & ' a str , & ' a str , UnresolvedNameContext < ' a > ) ,
167
167
/// error E0426: use of undeclared label
168
168
UndeclaredLabel ( & ' a str ) ,
169
169
/// error E0427: cannot use `ref` binding mode with ...
@@ -186,12 +186,12 @@ enum ResolutionError<'a> {
186
186
187
187
/// Context of where `ResolutionError::UnresolvedName` arose.
188
188
#[ derive( Clone , PartialEq , Eq , Debug ) ]
189
- enum UnresolvedNameContext {
190
- /// `PathIsMod(id )` indicates that a given path, used in
189
+ enum UnresolvedNameContext < ' a > {
190
+ /// `PathIsMod(parent )` indicates that a given path, used in
191
191
/// expression context, actually resolved to a module rather than
192
- /// a value. The `id` attached to the variant is the node id of
193
- /// the erroneous path expression.
194
- PathIsMod ( ast :: NodeId ) ,
192
+ /// a value. The optional expression attached to the variant is the
193
+ /// the parent of the erroneous path expression.
194
+ PathIsMod ( Option < & ' a Expr > ) ,
195
195
196
196
/// `Other` means we have no extra information about the context
197
197
/// of the unresolved name error. (Maybe we could eliminate all
@@ -419,39 +419,25 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
419
419
420
420
match context {
421
421
UnresolvedNameContext :: Other => { } // no help available
422
- UnresolvedNameContext :: PathIsMod ( id) => {
423
- let mut help_msg = String :: new ( ) ;
424
- let parent_id = resolver. ast_map . get_parent_node ( id) ;
425
- if let Some ( hir_map:: Node :: NodeExpr ( e) ) = resolver. ast_map . find ( parent_id) {
426
- match e. node {
427
- ExprField ( _, ident) => {
428
- help_msg = format ! ( "To reference an item from the \
429
- `{module}` module, use \
430
- `{module}::{ident}`",
431
- module = path,
432
- ident = ident. node) ;
433
- }
434
- ExprMethodCall ( ident, _, _) => {
435
- help_msg = format ! ( "To call a function from the \
436
- `{module}` module, use \
437
- `{module}::{ident}(..)`",
438
- module = path,
439
- ident = ident. node) ;
440
- }
441
- ExprCall ( _, _) => {
442
- help_msg = format ! ( "No function corresponds to `{module}(..)`" ,
443
- module = path) ;
444
- }
445
- _ => { } // no help available
422
+ UnresolvedNameContext :: PathIsMod ( parent) => {
423
+ err. fileline_help ( span, & match parent. map ( |parent| & parent. node ) {
424
+ Some ( & ExprField ( _, ident) ) => {
425
+ format ! ( "To reference an item from the `{module}` module, \
426
+ use `{module}::{ident}`",
427
+ module = path,
428
+ ident = ident. node)
446
429
}
447
- } else {
448
- help_msg = format ! ( "Module `{module}` cannot be the value of an expression" ,
449
- module = path) ;
450
- }
451
-
452
- if !help_msg. is_empty ( ) {
453
- err. fileline_help ( span, & help_msg) ;
454
- }
430
+ Some ( & ExprMethodCall ( ident, _, _) ) => {
431
+ format ! ( "To call a function from the `{module}` module, \
432
+ use `{module}::{ident}(..)`",
433
+ module = path,
434
+ ident = ident. node)
435
+ }
436
+ _ => {
437
+ format ! ( "Module `{module}` cannot be used as an expression" ,
438
+ module = path)
439
+ }
440
+ } ) ;
455
441
}
456
442
}
457
443
err
@@ -553,7 +539,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
553
539
self . resolve_block ( block) ;
554
540
}
555
541
fn visit_expr ( & mut self , expr : & Expr ) {
556
- self . resolve_expr ( expr) ;
542
+ self . resolve_expr ( expr, None ) ;
557
543
}
558
544
fn visit_local ( & mut self , local : & Local ) {
559
545
self . resolve_local ( local) ;
@@ -2850,7 +2836,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2850
2836
} SuggestionType :: NotFound
2851
2837
}
2852
2838
2853
- fn resolve_expr ( & mut self , expr : & Expr ) {
2839
+ fn resolve_expr ( & mut self , expr : & Expr , parent : Option < & Expr > ) {
2854
2840
// First, record candidate traits for this expression if it could
2855
2841
// result in the invocation of a method call.
2856
2842
@@ -2995,7 +2981,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2995
2981
UseLexicalScope ,
2996
2982
expr. span ) {
2997
2983
Success ( _) => {
2998
- context = UnresolvedNameContext :: PathIsMod ( expr . id ) ;
2984
+ context = UnresolvedNameContext :: PathIsMod ( parent ) ;
2999
2985
} ,
3000
2986
_ => { } ,
3001
2987
} ;
@@ -3069,6 +3055,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3069
3055
}
3070
3056
}
3071
3057
}
3058
+ ExprField ( ref subexpression, _) => {
3059
+ self . resolve_expr ( subexpression, Some ( expr) ) ;
3060
+ }
3061
+ ExprMethodCall ( _, ref types, ref arguments) => {
3062
+ let mut arguments = arguments. iter ( ) ;
3063
+ self . resolve_expr ( arguments. next ( ) . unwrap ( ) , Some ( expr) ) ;
3064
+ for argument in arguments {
3065
+ self . resolve_expr ( argument, None ) ;
3066
+ }
3067
+ for ty in types. iter ( ) {
3068
+ self . visit_ty ( ty) ;
3069
+ }
3070
+ }
3072
3071
3073
3072
_ => {
3074
3073
intravisit:: walk_expr ( self , expr) ;
0 commit comments