1
1
//! Type inference for expressions.
2
2
3
3
use std:: {
4
- collections:: hash_map:: Entry ,
5
4
iter:: { repeat, repeat_with} ,
6
5
mem,
7
6
} ;
@@ -521,6 +520,7 @@ impl<'a> InferenceContext<'a> {
521
520
let receiver_ty = self . infer_expr_inner ( * expr, & Expectation :: none ( ) ) ;
522
521
523
522
let mut autoderef = Autoderef :: new ( & mut self . table , receiver_ty) ;
523
+ let mut private_field = None ;
524
524
let ty = autoderef. by_ref ( ) . find_map ( |( derefed_ty, _) | {
525
525
let ( field_id, parameters) = match derefed_ty. kind ( Interner ) {
526
526
TyKind :: Tuple ( _, substs) => {
@@ -547,13 +547,8 @@ impl<'a> InferenceContext<'a> {
547
547
let is_visible = self . db . field_visibilities ( field_id. parent ) [ field_id. local_id ]
548
548
. is_visible_from ( self . db . upcast ( ) , self . resolver . module ( ) ) ;
549
549
if !is_visible {
550
- // Write down the first field resolution even if it is not visible
551
- // This aids IDE features for private fields like goto def and in
552
- // case of autoderef finding an applicable field, this will be
553
- // overwritten in a following cycle
554
- if let Entry :: Vacant ( entry) = self . result . field_resolutions . entry ( tgt_expr)
555
- {
556
- entry. insert ( field_id) ;
550
+ if private_field. is_none ( ) {
551
+ private_field = Some ( field_id) ;
557
552
}
558
553
return None ;
559
554
}
@@ -572,7 +567,17 @@ impl<'a> InferenceContext<'a> {
572
567
let ty = self . normalize_associated_types_in ( ty) ;
573
568
ty
574
569
}
575
- _ => self . err_ty ( ) ,
570
+ _ => {
571
+ // Write down the first private field resolution if we found no field
572
+ // This aids IDE features for private fields like goto def
573
+ if let Some ( field) = private_field {
574
+ self . result . field_resolutions . insert ( tgt_expr, field) ;
575
+ self . result
576
+ . diagnostics
577
+ . push ( InferenceDiagnostic :: PrivateField { expr : tgt_expr, field } ) ;
578
+ }
579
+ self . err_ty ( )
580
+ }
576
581
} ;
577
582
ty
578
583
}
0 commit comments