@@ -179,7 +179,7 @@ pub enum ResolutionError<'a> {
179179 /// error E0424: `self` is not available in a static method
180180 SelfNotAvailableInStaticMethod ,
181181 /// error E0425: unresolved name
182- UnresolvedName ( & ' a str , & ' a str ) ,
182+ UnresolvedName ( & ' a str , & ' a str , UnresolvedNameContext ) ,
183183 /// error E0426: use of undeclared label
184184 UndeclaredLabel ( & ' a str ) ,
185185 /// error E0427: cannot use `ref` binding mode with ...
@@ -202,6 +202,12 @@ pub enum ResolutionError<'a> {
202202 AttemptToUseNonConstantValueInConstant ,
203203}
204204
205+ #[ derive( Clone , PartialEq , Eq , Debug ) ]
206+ pub enum UnresolvedNameContext {
207+ PathIsMod ( ast:: NodeId ) ,
208+ Other ,
209+ }
210+
205211fn resolve_error < ' b , ' a : ' b , ' tcx : ' a > ( resolver : & ' b Resolver < ' a , ' tcx > ,
206212 span : syntax:: codemap:: Span ,
207213 resolution_error : ResolutionError < ' b > ) {
@@ -402,13 +408,46 @@ fn resolve_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
402408 "`self` is not available in a static method. Maybe a `self` argument is \
403409 missing?") ;
404410 }
405- ResolutionError :: UnresolvedName ( path, name ) => {
411+ ResolutionError :: UnresolvedName ( path, msg , context ) => {
406412 span_err ! ( resolver. session,
407413 span,
408414 E0425 ,
409415 "unresolved name `{}`{}" ,
410416 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+ }
412451 }
413452 ResolutionError :: UndeclaredLabel ( name) => {
414453 span_err ! ( resolver. session,
@@ -3509,13 +3548,33 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
35093548 format ! ( "to call `{}::{}`" , path_str, path_name) ,
35103549 } ;
35113550
3551+ let mut context = UnresolvedNameContext :: Other ;
35123552 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+ } ;
35143572 }
35153573
35163574 resolve_error ( self ,
35173575 expr. span ,
3518- ResolutionError :: UnresolvedName ( & * path_name, & * msg) ) ;
3576+ ResolutionError :: UnresolvedName (
3577+ & * path_name, & * msg, context) ) ;
35193578 }
35203579 }
35213580 }
0 commit comments