@@ -514,9 +514,6 @@ impl InferenceContext<'_> {
514
514
}
515
515
Expr :: RecordLit { path, fields, spread, .. } => {
516
516
let ( ty, def_id) = self . resolve_variant ( path. as_deref ( ) , false ) ;
517
- if let Some ( variant) = def_id {
518
- self . write_variant_resolution ( tgt_expr. into ( ) , variant) ;
519
- }
520
517
521
518
if let Some ( t) = expected. only_has_type ( & mut self . table ) {
522
519
self . unify ( & ty, & t) ;
@@ -526,26 +523,56 @@ impl InferenceContext<'_> {
526
523
. as_adt ( )
527
524
. map ( |( _, s) | s. clone ( ) )
528
525
. unwrap_or_else ( || Substitution :: empty ( Interner ) ) ;
529
- let field_types = def_id. map ( |it| self . db . field_types ( it) ) . unwrap_or_default ( ) ;
530
- let variant_data = def_id. map ( |it| it. variant_data ( self . db . upcast ( ) ) ) ;
531
- for field in fields. iter ( ) {
532
- let field_def =
533
- variant_data. as_ref ( ) . and_then ( |it| match it. field ( & field. name ) {
534
- Some ( local_id) => Some ( FieldId { parent : def_id. unwrap ( ) , local_id } ) ,
535
- None => {
536
- self . push_diagnostic ( InferenceDiagnostic :: NoSuchField {
537
- expr : field. expr ,
538
- } ) ;
539
- None
540
- }
541
- } ) ;
542
- let field_ty = field_def. map_or ( self . err_ty ( ) , |it| {
543
- field_types[ it. local_id ] . clone ( ) . substitute ( Interner , & substs)
544
- } ) ;
545
- // Field type might have some unknown types
546
- // FIXME: we may want to emit a single type variable for all instance of type fields?
547
- let field_ty = self . insert_type_vars ( field_ty) ;
548
- self . infer_expr_coerce ( field. expr , & Expectation :: has_type ( field_ty) ) ;
526
+ if let Some ( variant) = def_id {
527
+ self . write_variant_resolution ( tgt_expr. into ( ) , variant) ;
528
+ }
529
+ match def_id {
530
+ Some ( _) if fields. is_empty ( ) => { }
531
+ Some ( def) => {
532
+ let field_types = self . db . field_types ( def) ;
533
+ let variant_data = def. variant_data ( self . db . upcast ( ) ) ;
534
+ let visibilities = self . db . field_visibilities ( def) ;
535
+ for field in fields. iter ( ) {
536
+ let field_def = {
537
+ match variant_data. field ( & field. name ) {
538
+ Some ( local_id) => {
539
+ if !visibilities[ local_id] . is_visible_from (
540
+ self . db . upcast ( ) ,
541
+ self . resolver . module ( ) ,
542
+ ) {
543
+ self . push_diagnostic (
544
+ InferenceDiagnostic :: NoSuchField {
545
+ expr : field. expr ,
546
+ private : true ,
547
+ } ,
548
+ ) ;
549
+ }
550
+ Some ( FieldId { parent : def, local_id } )
551
+ }
552
+ None => {
553
+ self . push_diagnostic ( InferenceDiagnostic :: NoSuchField {
554
+ expr : field. expr ,
555
+ private : false ,
556
+ } ) ;
557
+ None
558
+ }
559
+ }
560
+ } ;
561
+ let field_ty = field_def. map_or ( self . err_ty ( ) , |it| {
562
+ field_types[ it. local_id ] . clone ( ) . substitute ( Interner , & substs)
563
+ } ) ;
564
+
565
+ // Field type might have some unknown types
566
+ // FIXME: we may want to emit a single type variable for all instance of type fields?
567
+ let field_ty = self . insert_type_vars ( field_ty) ;
568
+ self . infer_expr_coerce ( field. expr , & Expectation :: has_type ( field_ty) ) ;
569
+ }
570
+ }
571
+ None => {
572
+ for field in fields. iter ( ) {
573
+ self . infer_expr_coerce ( field. expr , & Expectation :: None ) ;
574
+ }
575
+ }
549
576
}
550
577
if let Some ( expr) = spread {
551
578
self . infer_expr ( * expr, & Expectation :: has_type ( ty. clone ( ) ) ) ;
0 commit comments