@@ -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,21 @@ pub enum ResolutionError<'a> {
202202 AttemptToUseNonConstantValueInConstant ,
203203}
204204
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+
205220fn resolve_error < ' b , ' a : ' b , ' tcx : ' a > ( resolver : & ' b Resolver < ' a , ' tcx > ,
206221 span : syntax:: codemap:: Span ,
207222 resolution_error : ResolutionError < ' b > ) {
@@ -402,13 +417,46 @@ fn resolve_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
402417 "`self` is not available in a static method. Maybe a `self` argument is \
403418 missing?") ;
404419 }
405- ResolutionError :: UnresolvedName ( path, name ) => {
420+ ResolutionError :: UnresolvedName ( path, msg , context ) => {
406421 span_err ! ( resolver. session,
407422 span,
408423 E0425 ,
409424 "unresolved name `{}`{}" ,
410425 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+ }
412460 }
413461 ResolutionError :: UndeclaredLabel ( name) => {
414462 span_err ! ( resolver. session,
@@ -3539,13 +3587,33 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
35393587 format ! ( "to call `{}::{}`" , path_str, path_name) ,
35403588 } ;
35413589
3590+ let mut context = UnresolvedNameContext :: Other ;
35423591 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+ } ;
35443611 }
35453612
35463613 resolve_error ( self ,
35473614 expr. span ,
3548- ResolutionError :: UnresolvedName ( & * path_name, & * msg) ) ;
3615+ ResolutionError :: UnresolvedName (
3616+ & * path_name, & * msg, context) ) ;
35493617 }
35503618 }
35513619 }
0 commit comments