@@ -68,7 +68,7 @@ use rustc::hir::intravisit::{self, FnKind, Visitor};
6868use rustc:: hir;
6969use rustc:: hir:: { Arm , BindByRef , BindByValue , BindingMode , Block } ;
7070use rustc:: hir:: Crate ;
71- use rustc:: hir:: { Expr , ExprAgain , ExprBreak , ExprCall , ExprField } ;
71+ use rustc:: hir:: { Expr , ExprAgain , ExprBreak , ExprField } ;
7272use rustc:: hir:: { ExprLoop , ExprWhile , ExprMethodCall } ;
7373use rustc:: hir:: { ExprPath , ExprStruct , FnDecl } ;
7474use rustc:: hir:: { ForeignItemFn , ForeignItemStatic , Generics } ;
@@ -163,7 +163,7 @@ enum ResolutionError<'a> {
163163 /// error E0424: `self` is not available in a static method
164164 SelfNotAvailableInStaticMethod ,
165165 /// error E0425: unresolved name
166- UnresolvedName ( & ' a str , & ' a str , UnresolvedNameContext ) ,
166+ UnresolvedName ( & ' a str , & ' a str , UnresolvedNameContext < ' a > ) ,
167167 /// error E0426: use of undeclared label
168168 UndeclaredLabel ( & ' a str ) ,
169169 /// error E0427: cannot use `ref` binding mode with ...
@@ -186,12 +186,12 @@ enum ResolutionError<'a> {
186186
187187/// Context of where `ResolutionError::UnresolvedName` arose.
188188#[ 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
191191 /// 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 > ) ,
195195
196196 /// `Other` means we have no extra information about the context
197197 /// 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>,
419419
420420 match context {
421421 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)
446429 }
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+ } ) ;
455441 }
456442 }
457443 err
@@ -553,7 +539,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
553539 self . resolve_block ( block) ;
554540 }
555541 fn visit_expr ( & mut self , expr : & Expr ) {
556- self . resolve_expr ( expr) ;
542+ self . resolve_expr ( expr, None ) ;
557543 }
558544 fn visit_local ( & mut self , local : & Local ) {
559545 self . resolve_local ( local) ;
@@ -2850,7 +2836,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
28502836 } SuggestionType :: NotFound
28512837 }
28522838
2853- fn resolve_expr ( & mut self , expr : & Expr ) {
2839+ fn resolve_expr ( & mut self , expr : & Expr , parent : Option < & Expr > ) {
28542840 // First, record candidate traits for this expression if it could
28552841 // result in the invocation of a method call.
28562842
@@ -2995,7 +2981,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
29952981 UseLexicalScope ,
29962982 expr. span ) {
29972983 Success ( _) => {
2998- context = UnresolvedNameContext :: PathIsMod ( expr . id ) ;
2984+ context = UnresolvedNameContext :: PathIsMod ( parent ) ;
29992985 } ,
30002986 _ => { } ,
30012987 } ;
@@ -3069,6 +3055,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
30693055 }
30703056 }
30713057 }
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+ }
30723071
30733072 _ => {
30743073 intravisit:: walk_expr ( self , expr) ;
0 commit comments