@@ -2535,15 +2535,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2535
2535
) ;
2536
2536
2537
2537
// try to add a suggestion in case the field is a nested field of a field of the Adt
2538
- if let Some ( ( fields, substs) ) = self . get_field_candidates ( span, expr_t) {
2539
- for candidate_field in fields. iter ( ) {
2538
+ let mod_id = self . tcx . parent_module ( id) . to_def_id ( ) ;
2539
+ if let Some ( ( fields, substs) ) =
2540
+ self . get_field_candidates_considering_privacy ( span, expr_t, mod_id)
2541
+ {
2542
+ for candidate_field in fields {
2540
2543
if let Some ( mut field_path) = self . check_for_nested_field_satisfying (
2541
2544
span,
2542
2545
& |candidate_field, _| candidate_field. ident ( self . tcx ( ) ) == field,
2543
2546
candidate_field,
2544
2547
substs,
2545
2548
vec ! [ ] ,
2546
- self . tcx . parent_module ( id ) . to_def_id ( ) ,
2549
+ mod_id ,
2547
2550
) {
2548
2551
// field_path includes `field` that we're looking for, so pop it.
2549
2552
field_path. pop ( ) ;
@@ -2567,22 +2570,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2567
2570
err
2568
2571
}
2569
2572
2570
- pub ( crate ) fn get_field_candidates (
2573
+ pub ( crate ) fn get_field_candidates_considering_privacy (
2571
2574
& self ,
2572
2575
span : Span ,
2573
- base_t : Ty < ' tcx > ,
2574
- ) -> Option < ( & [ ty:: FieldDef ] , SubstsRef < ' tcx > ) > {
2575
- debug ! ( "get_field_candidates(span: {:?}, base_t: {:?}" , span, base_t) ;
2576
+ base_ty : Ty < ' tcx > ,
2577
+ mod_id : DefId ,
2578
+ ) -> Option < ( impl Iterator < Item = & ' tcx ty:: FieldDef > + ' tcx , SubstsRef < ' tcx > ) > {
2579
+ debug ! ( "get_field_candidates(span: {:?}, base_t: {:?}" , span, base_ty) ;
2576
2580
2577
- for ( base_t, _) in self . autoderef ( span, base_t ) {
2581
+ for ( base_t, _) in self . autoderef ( span, base_ty ) {
2578
2582
match base_t. kind ( ) {
2579
2583
ty:: Adt ( base_def, substs) if !base_def. is_enum ( ) => {
2580
- let fields = & base_def. non_enum_variant ( ) . fields ;
2581
- // For compile-time reasons put a limit on number of fields we search
2582
- if fields. len ( ) > 100 {
2583
- return None ;
2584
- }
2585
- return Some ( ( fields, substs) ) ;
2584
+ let tcx = self . tcx ;
2585
+ return Some ( (
2586
+ base_def
2587
+ . non_enum_variant ( )
2588
+ . fields
2589
+ . iter ( )
2590
+ . filter ( move |field| field. vis . is_accessible_from ( mod_id, tcx) )
2591
+ // For compile-time reasons put a limit on number of fields we search
2592
+ . take ( 100 ) ,
2593
+ substs,
2594
+ ) ) ;
2586
2595
}
2587
2596
_ => { }
2588
2597
}
@@ -2599,7 +2608,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2599
2608
candidate_field : & ty:: FieldDef ,
2600
2609
subst : SubstsRef < ' tcx > ,
2601
2610
mut field_path : Vec < Ident > ,
2602
- id : DefId ,
2611
+ mod_id : DefId ,
2603
2612
) -> Option < Vec < Ident > > {
2604
2613
debug ! (
2605
2614
"check_for_nested_field_satisfying(span: {:?}, candidate_field: {:?}, field_path: {:?}" ,
@@ -2615,20 +2624,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2615
2624
let field_ty = candidate_field. ty ( self . tcx , subst) ;
2616
2625
if matches ( candidate_field, field_ty) {
2617
2626
return Some ( field_path) ;
2618
- } else if let Some ( ( nested_fields, subst) ) = self . get_field_candidates ( span, field_ty) {
2627
+ } else if let Some ( ( nested_fields, subst) ) =
2628
+ self . get_field_candidates_considering_privacy ( span, field_ty, mod_id)
2629
+ {
2619
2630
// recursively search fields of `candidate_field` if it's a ty::Adt
2620
2631
for field in nested_fields {
2621
- if field. vis . is_accessible_from ( id, self . tcx ) {
2622
- if let Some ( field_path) = self . check_for_nested_field_satisfying (
2623
- span,
2624
- matches,
2625
- field,
2626
- subst,
2627
- field_path. clone ( ) ,
2628
- id,
2629
- ) {
2630
- return Some ( field_path) ;
2631
- }
2632
+ if let Some ( field_path) = self . check_for_nested_field_satisfying (
2633
+ span,
2634
+ matches,
2635
+ field,
2636
+ subst,
2637
+ field_path. clone ( ) ,
2638
+ mod_id,
2639
+ ) {
2640
+ return Some ( field_path) ;
2632
2641
}
2633
2642
}
2634
2643
}
0 commit comments