@@ -2599,6 +2599,21 @@ impl<'a> Resolver<'a> {
2599
2599
}
2600
2600
_ => { }
2601
2601
} ,
2602
+ ( Def :: Enum ( ..) , PathSource :: TupleStruct ) => {
2603
+ if let Some ( variants) = this. collect_enum_variants ( def) {
2604
+ err. note ( & format ! ( "did you mean to use one \
2605
+ of the following variants?\n {}",
2606
+ variants. iter( )
2607
+ . map( |suggestion| format!( "- `{}`" ,
2608
+ path_names_to_string( suggestion) ) )
2609
+ . collect:: <Vec <_>>( )
2610
+ . join( "\n " ) ) ) ;
2611
+
2612
+ } else {
2613
+ err. note ( "did you mean to use one of the enum's variants?" ) ;
2614
+ }
2615
+ return ( err, candidates) ;
2616
+ } ,
2602
2617
_ if ns == ValueNS && is_struct_like ( def) => {
2603
2618
if let Def :: Struct ( def_id) = def {
2604
2619
if let Some ( ( ctor_def, ctor_vis) )
@@ -3495,6 +3510,70 @@ impl<'a> Resolver<'a> {
3495
3510
candidates
3496
3511
}
3497
3512
3513
+ fn find_module ( & mut self ,
3514
+ module_def : Def )
3515
+ -> Option < ( Module < ' a > , ImportSuggestion ) >
3516
+ {
3517
+ let mut result = None ;
3518
+ let mut worklist = Vec :: new ( ) ;
3519
+ let mut seen_modules = FxHashSet ( ) ;
3520
+ worklist. push ( ( self . graph_root , Vec :: new ( ) ) ) ;
3521
+
3522
+ while let Some ( ( in_module, path_segments) ) = worklist. pop ( ) {
3523
+ // abort if the module is already found
3524
+ if let Some ( _) = result { break ; }
3525
+
3526
+ self . populate_module_if_necessary ( in_module) ;
3527
+
3528
+ in_module. for_each_child ( |ident, _, name_binding| {
3529
+ // abort if the module is already found
3530
+ if let Some ( _) = result {
3531
+ return ( ) ;
3532
+ }
3533
+ if let Some ( module) = name_binding. module ( ) {
3534
+ // form the path
3535
+ let mut path_segments = path_segments. clone ( ) ;
3536
+ path_segments. push ( ast:: PathSegment :: from_ident ( ident, name_binding. span ) ) ;
3537
+ if module. def ( ) == Some ( module_def) {
3538
+ let path = Path {
3539
+ span : name_binding. span ,
3540
+ segments : path_segments,
3541
+ } ;
3542
+ result = Some ( ( module, ImportSuggestion { path : path } ) ) ;
3543
+ } else {
3544
+ // add the module to the lookup
3545
+ if seen_modules. insert ( module. def_id ( ) . unwrap ( ) ) {
3546
+ worklist. push ( ( module, path_segments) ) ;
3547
+ }
3548
+ }
3549
+ }
3550
+ } ) ;
3551
+ }
3552
+
3553
+ result
3554
+ }
3555
+
3556
+ fn collect_enum_variants ( & mut self , enum_def : Def ) -> Option < Vec < Path > > {
3557
+ if let Def :: Enum ( ..) = enum_def { } else {
3558
+ panic ! ( "Non-enum def passed to collect_enum_variants: {:?}" , enum_def)
3559
+ }
3560
+
3561
+ self . find_module ( enum_def) . map ( |( enum_module, enum_import_suggestion) | {
3562
+ let mut variants = Vec :: new ( ) ;
3563
+ enum_module. for_each_child_stable ( |ident, _, name_binding| {
3564
+ if let Def :: Variant ( ..) = name_binding. def ( ) {
3565
+ let mut segms = enum_import_suggestion. path . segments . clone ( ) ;
3566
+ segms. push ( ast:: PathSegment :: from_ident ( ident, name_binding. span ) ) ;
3567
+ variants. push ( Path {
3568
+ span : name_binding. span ,
3569
+ segments : segms,
3570
+ } ) ;
3571
+ }
3572
+ } ) ;
3573
+ variants
3574
+ } )
3575
+ }
3576
+
3498
3577
fn record_def ( & mut self , node_id : NodeId , resolution : PathResolution ) {
3499
3578
debug ! ( "(recording def) recording {:?} for {}" , resolution, node_id) ;
3500
3579
if let Some ( prev_res) = self . def_map . insert ( node_id, resolution) {
0 commit comments