@@ -514,9 +514,6 @@ impl InferenceContext<'_> {
514514 }
515515 Expr :: RecordLit { path, fields, spread, .. } => {
516516 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- }
520517
521518 if let Some ( t) = expected. only_has_type ( & mut self . table ) {
522519 self . unify ( & ty, & t) ;
@@ -526,26 +523,56 @@ impl InferenceContext<'_> {
526523 . as_adt ( )
527524 . map ( |( _, s) | s. clone ( ) )
528525 . 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+ }
549576 }
550577 if let Some ( expr) = spread {
551578 self . infer_expr ( * expr, & Expectation :: has_type ( ty. clone ( ) ) ) ;
0 commit comments