@@ -41,7 +41,7 @@ use crate::{
4141pub ( crate ) use hir_def:: {
4242 LocalFieldId , VariantId ,
4343 expr_store:: Body ,
44- hir:: { Expr , ExprId , MatchArm , Pat , PatId , Statement } ,
44+ hir:: { Expr , ExprId , MatchArm , Pat , PatId , RecordSpread , Statement } ,
4545} ;
4646
4747pub enum BodyValidationDiagnostic {
@@ -558,10 +558,8 @@ pub fn record_literal_missing_fields(
558558 id : ExprId ,
559559 expr : & Expr ,
560560) -> Option < ( VariantId , Vec < LocalFieldId > ) > {
561- let ( fields, spread, has_spread_syntax) = match expr {
562- Expr :: RecordLit { fields, spread, has_spread_syntax, .. } => {
563- ( fields, spread, * has_spread_syntax)
564- }
561+ let ( fields, spread) = match expr {
562+ Expr :: RecordLit { fields, spread, .. } => ( fields, spread) ,
565563 _ => return None ,
566564 } ;
567565
@@ -573,13 +571,17 @@ pub fn record_literal_missing_fields(
573571 let variant_data = variant_def. fields ( db) ;
574572
575573 let specified_fields: FxHashSet < _ > = fields. iter ( ) . map ( |f| & f. name ) . collect ( ) ;
574+ // don't suggest fields if:
575+ // - has ..expr
576+ // - has default value + ..
577+ // - already in code
576578 let missed_fields: Vec < LocalFieldId > = variant_data
577579 . fields ( )
578580 . iter ( )
579581 . filter_map ( |( f, d) | {
580582 if specified_fields. contains ( & d. name )
581- || spread. is_some ( )
582- || ( d. has_default_value && has_spread_syntax )
583+ || matches ! ( spread, RecordSpread :: Expr ( _ ) )
584+ || ( d. has_default_value && matches ! ( spread , RecordSpread :: Empty ) )
583585 {
584586 None
585587 } else {
@@ -599,10 +601,8 @@ pub fn record_literal_matched_fields(
599601 id : ExprId ,
600602 expr : & Expr ,
601603) -> Option < ( VariantId , Vec < LocalFieldId > ) > {
602- let ( fields, spread, has_spread_syntax) = match expr {
603- Expr :: RecordLit { fields, spread, has_spread_syntax, .. } => {
604- ( fields, spread, * has_spread_syntax)
605- }
604+ let ( fields, _spread) = match expr {
605+ Expr :: RecordLit { fields, spread, .. } => ( fields, spread) ,
606606 _ => return None ,
607607 } ;
608608
@@ -614,19 +614,12 @@ pub fn record_literal_matched_fields(
614614 let variant_data = variant_def. fields ( db) ;
615615
616616 let specified_fields: FxHashSet < _ > = fields. iter ( ) . map ( |f| & f. name ) . collect ( ) ;
617+ // suggest fields if:
618+ // - not in code
617619 let matched_fields: Vec < LocalFieldId > = variant_data
618620 . fields ( )
619621 . iter ( )
620- . filter_map ( |( f, d) | {
621- if !specified_fields. contains ( & d. name )
622- && ( spread. is_some ( ) || has_spread_syntax)
623- && !( d. has_default_value && has_spread_syntax)
624- {
625- Some ( f)
626- } else {
627- None
628- }
629- } )
622+ . filter_map ( |( f, d) | ( !specified_fields. contains ( & d. name ) ) . then_some ( f) )
630623 . collect ( ) ;
631624 if matched_fields. is_empty ( ) {
632625 return None ;
@@ -640,7 +633,7 @@ pub fn record_pattern_missing_fields(
640633 id : PatId ,
641634 pat : & Pat ,
642635) -> Option < ( VariantId , Vec < LocalFieldId > ) > {
643- let ( fields, ellipsis ) = match pat {
636+ let ( fields, _ellipsis ) = match pat {
644637 Pat :: Record { path : _, args, ellipsis } => ( args, * ellipsis) ,
645638 _ => return None ,
646639 } ;
@@ -653,14 +646,13 @@ pub fn record_pattern_missing_fields(
653646 let variant_data = variant_def. fields ( db) ;
654647
655648 let specified_fields: FxHashSet < _ > = fields. iter ( ) . map ( |f| & f. name ) . collect ( ) ;
649+ // suggest fields if:
650+ // - not in code
651+ // Note: ellipsis (..) is ignored - we still want to suggest all unspecified fields
656652 let missed_fields: Vec < LocalFieldId > = variant_data
657653 . fields ( )
658654 . iter ( )
659- . filter_map (
660- |( f, d) | {
661- if specified_fields. contains ( & d. name ) || ellipsis { None } else { Some ( f) }
662- } ,
663- )
655+ . filter_map ( |( f, d) | if specified_fields. contains ( & d. name ) { None } else { Some ( f) } )
664656 . collect ( ) ;
665657 if missed_fields. is_empty ( ) {
666658 return None ;
@@ -674,7 +666,7 @@ pub fn record_pattern_matched_fields(
674666 id : PatId ,
675667 pat : & Pat ,
676668) -> Option < ( VariantId , Vec < LocalFieldId > ) > {
677- let ( fields, ellipsis ) = match pat {
669+ let ( fields, _ellipsis ) = match pat {
678670 Pat :: Record { path : _, args, ellipsis } => ( args, * ellipsis) ,
679671 _ => return None ,
680672 } ;
@@ -687,14 +679,13 @@ pub fn record_pattern_matched_fields(
687679 let variant_data = variant_def. fields ( db) ;
688680
689681 let specified_fields: FxHashSet < _ > = fields. iter ( ) . map ( |f| & f. name ) . collect ( ) ;
690- let matched_fields: Vec < LocalFieldId > =
691- variant_data
692- . fields ( )
693- . iter ( )
694- . filter_map ( |( f, d) | {
695- if !specified_fields. contains ( & d. name ) && ellipsis { Some ( f) } else { None }
696- } )
697- . collect ( ) ;
682+ // suggest fields if:
683+ // - not in code
684+ let matched_fields: Vec < LocalFieldId > = variant_data
685+ . fields ( )
686+ . iter ( )
687+ . filter_map ( |( f, d) | if !specified_fields. contains ( & d. name ) { Some ( f) } else { None } )
688+ . collect ( ) ;
698689 if matched_fields. is_empty ( ) {
699690 return None ;
700691 }
0 commit comments