@@ -179,7 +179,7 @@ pub enum ResolutionError<'a> {
179
179
/// error E0424: `self` is not available in a static method
180
180
SelfNotAvailableInStaticMethod ,
181
181
/// error E0425: unresolved name
182
- UnresolvedName ( & ' a str , & ' a str ) ,
182
+ UnresolvedName ( & ' a str , & ' a str , UnresolvedNameContext ) ,
183
183
/// error E0426: use of undeclared label
184
184
UndeclaredLabel ( & ' a str ) ,
185
185
/// error E0427: cannot use `ref` binding mode with ...
@@ -202,6 +202,21 @@ pub enum ResolutionError<'a> {
202
202
AttemptToUseNonConstantValueInConstant ,
203
203
}
204
204
205
+ /// Context of where `ResolutionError::UnresolvedName` arose.
206
+ #[ derive( Clone , PartialEq , Eq , Debug ) ]
207
+ pub enum UnresolvedNameContext {
208
+ /// `PathIsMod(id)` indicates that a given path, used in
209
+ /// expression context, actually resolved to a module rather than
210
+ /// a value. The `id` attached to the variant is the node id of
211
+ /// the erroneous path expression.
212
+ PathIsMod ( ast:: NodeId ) ,
213
+
214
+ /// `Other` means we have no extra information about the context
215
+ /// of the unresolved name error. (Maybe we could eliminate all
216
+ /// such cases; but for now, this is an information-free default.)
217
+ Other ,
218
+ }
219
+
205
220
fn resolve_error < ' b , ' a : ' b , ' tcx : ' a > ( resolver : & ' b Resolver < ' a , ' tcx > ,
206
221
span : syntax:: codemap:: Span ,
207
222
resolution_error : ResolutionError < ' b > ) {
@@ -402,13 +417,46 @@ fn resolve_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
402
417
"`self` is not available in a static method. Maybe a `self` argument is \
403
418
missing?") ;
404
419
}
405
- ResolutionError :: UnresolvedName ( path, name ) => {
420
+ ResolutionError :: UnresolvedName ( path, msg , context ) => {
406
421
span_err ! ( resolver. session,
407
422
span,
408
423
E0425 ,
409
424
"unresolved name `{}`{}" ,
410
425
path,
411
- name) ;
426
+ msg) ;
427
+
428
+ match context {
429
+ UnresolvedNameContext :: Other => { } // no help available
430
+ UnresolvedNameContext :: PathIsMod ( id) => {
431
+ let mut help_msg = String :: new ( ) ;
432
+ let parent_id = resolver. ast_map . get_parent_node ( id) ;
433
+ if let Some ( hir_map:: Node :: NodeExpr ( e) ) = resolver. ast_map . find ( parent_id) {
434
+ match e. node {
435
+ ExprField ( _, ident) => {
436
+ help_msg = format ! ( "To reference an item from the \
437
+ `{module}` module, use \
438
+ `{module}::{ident}`",
439
+ module = & * path,
440
+ ident = ident. node) ;
441
+ }
442
+
443
+ ExprMethodCall ( ident, _, _) => {
444
+ help_msg = format ! ( "To call a function from the \
445
+ `{module}` module, use \
446
+ `{module}::{ident}(..)`",
447
+ module = & * path,
448
+ ident = ident. node) ;
449
+ }
450
+
451
+ _ => { } // no help available
452
+ }
453
+ }
454
+
455
+ if !help_msg. is_empty ( ) {
456
+ resolver. session . fileline_help ( span, & help_msg) ;
457
+ }
458
+ }
459
+ }
412
460
}
413
461
ResolutionError :: UndeclaredLabel ( name) => {
414
462
span_err ! ( resolver. session,
@@ -3539,13 +3587,33 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3539
3587
format ! ( "to call `{}::{}`" , path_str, path_name) ,
3540
3588
} ;
3541
3589
3590
+ let mut context = UnresolvedNameContext :: Other ;
3542
3591
if !msg. is_empty ( ) {
3543
- msg = format ! ( ". Did you mean {}?" , msg)
3592
+ msg = format ! ( ". Did you mean {}?" , msg) ;
3593
+ } else {
3594
+ // we check if this a module and if so, we display a help
3595
+ // message
3596
+ let name_path = path. segments . iter ( )
3597
+ . map ( |seg| seg. identifier . name )
3598
+ . collect :: < Vec < _ > > ( ) ;
3599
+ let current_module = self . current_module . clone ( ) ;
3600
+
3601
+ match self . resolve_module_path ( current_module,
3602
+ & name_path[ ..] ,
3603
+ UseLexicalScope ,
3604
+ expr. span ,
3605
+ PathSearch ) {
3606
+ Success ( _) => {
3607
+ context = UnresolvedNameContext :: PathIsMod ( expr. id ) ;
3608
+ } ,
3609
+ _ => { } ,
3610
+ } ;
3544
3611
}
3545
3612
3546
3613
resolve_error ( self ,
3547
3614
expr. span ,
3548
- ResolutionError :: UnresolvedName ( & * path_name, & * msg) ) ;
3615
+ ResolutionError :: UnresolvedName (
3616
+ & * path_name, & * msg, context) ) ;
3549
3617
}
3550
3618
}
3551
3619
}
0 commit comments