@@ -2614,6 +2614,22 @@ impl<'a> Resolver<'a> {
26142614 }
26152615 _ => { }
26162616 } ,
2617+ ( Def :: Enum ( ..) , PathSource :: TupleStruct )
2618+ | ( Def :: Enum ( ..) , PathSource :: Expr ( ..) ) => {
2619+ if let Some ( variants) = this. collect_enum_variants ( def) {
2620+ err. note ( & format ! ( "did you mean to use one \
2621+ of the following variants?\n {}",
2622+ variants. iter( )
2623+ . map( |suggestion| path_names_to_string( suggestion) )
2624+ . map( |suggestion| format!( "- `{}`" , suggestion) )
2625+ . collect:: <Vec <_>>( )
2626+ . join( "\n " ) ) ) ;
2627+
2628+ } else {
2629+ err. note ( "did you mean to use one of the enum's variants?" ) ;
2630+ }
2631+ return ( err, candidates) ;
2632+ } ,
26172633 _ if ns == ValueNS && is_struct_like ( def) => {
26182634 if let Def :: Struct ( def_id) = def {
26192635 if let Some ( ( ctor_def, ctor_vis) )
@@ -3540,6 +3556,72 @@ impl<'a> Resolver<'a> {
35403556 candidates
35413557 }
35423558
3559+ fn find_module ( & mut self ,
3560+ module_def : Def )
3561+ -> Option < ( Module < ' a > , ImportSuggestion ) >
3562+ {
3563+ let mut result = None ;
3564+ let mut worklist = Vec :: new ( ) ;
3565+ let mut seen_modules = FxHashSet ( ) ;
3566+ worklist. push ( ( self . graph_root , Vec :: new ( ) ) ) ;
3567+
3568+ while let Some ( ( in_module, path_segments) ) = worklist. pop ( ) {
3569+ // abort if the module is already found
3570+ if let Some ( _) = result { break ; }
3571+
3572+ self . populate_module_if_necessary ( in_module) ;
3573+
3574+ in_module. for_each_child_stable ( |ident, _, name_binding| {
3575+ // abort if the module is already found
3576+ if let Some ( _) = result {
3577+ return ( ) ;
3578+ }
3579+ if let Some ( module) = name_binding. module ( ) {
3580+ // form the path
3581+ let mut path_segments = path_segments. clone ( ) ;
3582+ path_segments. push ( ast:: PathSegment :: from_ident ( ident, name_binding. span ) ) ;
3583+ if module. def ( ) == Some ( module_def) {
3584+ let path = Path {
3585+ span : name_binding. span ,
3586+ segments : path_segments,
3587+ } ;
3588+ result = Some ( ( module, ImportSuggestion { path : path } ) ) ;
3589+ } else {
3590+ // add the module to the lookup
3591+ if seen_modules. insert ( module. def_id ( ) . unwrap ( ) ) {
3592+ worklist. push ( ( module, path_segments) ) ;
3593+ }
3594+ }
3595+ }
3596+ } ) ;
3597+ }
3598+
3599+ result
3600+ }
3601+
3602+ fn collect_enum_variants ( & mut self , enum_def : Def ) -> Option < Vec < Path > > {
3603+ if let Def :: Enum ( ..) = enum_def { } else {
3604+ panic ! ( "Non-enum def passed to collect_enum_variants: {:?}" , enum_def)
3605+ }
3606+
3607+ self . find_module ( enum_def) . map ( |( enum_module, enum_import_suggestion) | {
3608+ self . populate_module_if_necessary ( enum_module) ;
3609+
3610+ let mut variants = Vec :: new ( ) ;
3611+ enum_module. for_each_child_stable ( |ident, _, name_binding| {
3612+ if let Def :: Variant ( ..) = name_binding. def ( ) {
3613+ let mut segms = enum_import_suggestion. path . segments . clone ( ) ;
3614+ segms. push ( ast:: PathSegment :: from_ident ( ident, name_binding. span ) ) ;
3615+ variants. push ( Path {
3616+ span : name_binding. span ,
3617+ segments : segms,
3618+ } ) ;
3619+ }
3620+ } ) ;
3621+ variants
3622+ } )
3623+ }
3624+
35433625 fn record_def ( & mut self , node_id : NodeId , resolution : PathResolution ) {
35443626 debug ! ( "(recording def) recording {:?} for {}" , resolution, node_id) ;
35453627 if let Some ( prev_res) = self . def_map . insert ( node_id, resolution) {
0 commit comments