@@ -2614,6 +2614,22 @@ impl<'a> Resolver<'a> {
2614
2614
}
2615
2615
_ => { }
2616
2616
} ,
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
+ } ,
2617
2633
_ if ns == ValueNS && is_struct_like ( def) => {
2618
2634
if let Def :: Struct ( def_id) = def {
2619
2635
if let Some ( ( ctor_def, ctor_vis) )
@@ -3540,6 +3556,72 @@ impl<'a> Resolver<'a> {
3540
3556
candidates
3541
3557
}
3542
3558
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
+
3543
3625
fn record_def ( & mut self , node_id : NodeId , resolution : PathResolution ) {
3544
3626
debug ! ( "(recording def) recording {:?} for {}" , resolution, node_id) ;
3545
3627
if let Some ( prev_res) = self . def_map . insert ( node_id, resolution) {
0 commit comments