@@ -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,12 @@ pub enum ResolutionError<'a> {
202
202
AttemptToUseNonConstantValueInConstant ,
203
203
}
204
204
205
+ #[ derive( Clone , PartialEq , Eq , Debug ) ]
206
+ pub enum UnresolvedNameContext {
207
+ PathIsMod ( ast:: NodeId ) ,
208
+ Other ,
209
+ }
210
+
205
211
fn resolve_error < ' b , ' a : ' b , ' tcx : ' a > ( resolver : & ' b Resolver < ' a , ' tcx > ,
206
212
span : syntax:: codemap:: Span ,
207
213
resolution_error : ResolutionError < ' b > ) {
@@ -402,13 +408,46 @@ fn resolve_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
402
408
"`self` is not available in a static method. Maybe a `self` argument is \
403
409
missing?") ;
404
410
}
405
- ResolutionError :: UnresolvedName ( path, name ) => {
411
+ ResolutionError :: UnresolvedName ( path, msg , context ) => {
406
412
span_err ! ( resolver. session,
407
413
span,
408
414
E0425 ,
409
415
"unresolved name `{}`{}" ,
410
416
path,
411
- name) ;
417
+ msg) ;
418
+
419
+ match context {
420
+ UnresolvedNameContext :: Other => { } // no help available
421
+ UnresolvedNameContext :: PathIsMod ( id) => {
422
+ let mut help_msg = String :: new ( ) ;
423
+ let parent_id = resolver. ast_map . get_parent_node ( id) ;
424
+ if let Some ( hir_map:: Node :: NodeExpr ( e) ) = resolver. ast_map . find ( parent_id) {
425
+ match e. node {
426
+ ExprField ( _, ident) => {
427
+ help_msg = format ! ( "To reference an item from the \
428
+ `{module}` module, use \
429
+ `{module}::{ident}`",
430
+ module = & * path,
431
+ ident = ident. node) ;
432
+ }
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
+
442
+ _ => { } // no help available
443
+ }
444
+ }
445
+
446
+ if !help_msg. is_empty ( ) {
447
+ resolver. session . fileline_help ( span, & help_msg) ;
448
+ }
449
+ }
450
+ }
412
451
}
413
452
ResolutionError :: UndeclaredLabel ( name) => {
414
453
span_err ! ( resolver. session,
@@ -3509,13 +3548,33 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3509
3548
format ! ( "to call `{}::{}`" , path_str, path_name) ,
3510
3549
} ;
3511
3550
3551
+ let mut context = UnresolvedNameContext :: Other ;
3512
3552
if !msg. is_empty ( ) {
3513
- msg = format ! ( ". Did you mean {}?" , msg)
3553
+ msg = format ! ( ". Did you mean {}?" , msg) ;
3554
+ } else {
3555
+ // we check if this a module and if so, we display a help
3556
+ // message
3557
+ let name_path = path. segments . iter ( )
3558
+ . map ( |seg| seg. identifier . name )
3559
+ . collect :: < Vec < _ > > ( ) ;
3560
+ let current_module = self . current_module . clone ( ) ;
3561
+
3562
+ match self . resolve_module_path ( current_module,
3563
+ & name_path[ ..] ,
3564
+ UseLexicalScope ,
3565
+ expr. span ,
3566
+ PathSearch ) {
3567
+ Success ( _) => {
3568
+ context = UnresolvedNameContext :: PathIsMod ( expr. id ) ;
3569
+ } ,
3570
+ _ => { } ,
3571
+ } ;
3514
3572
}
3515
3573
3516
3574
resolve_error ( self ,
3517
3575
expr. span ,
3518
- ResolutionError :: UnresolvedName ( & * path_name, & * msg) ) ;
3576
+ ResolutionError :: UnresolvedName (
3577
+ & * path_name, & * msg, context) ) ;
3519
3578
}
3520
3579
}
3521
3580
}
0 commit comments