@@ -1556,7 +1556,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15561556 let mut error_happened = false ;
15571557
15581558 // Type-check each field.
1559- for field in ast_fields {
1559+ for ( idx , field) in ast_fields. iter ( ) . enumerate ( ) {
15601560 let ident = tcx. adjust_ident ( field. ident , variant. def_id ) ;
15611561 let field_type = if let Some ( ( i, v_field) ) = remaining_fields. remove ( & ident) {
15621562 seen_fields. insert ( ident, field. span ) ;
@@ -1594,7 +1594,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15941594
15951595 // Make sure to give a type to the field even if there's
15961596 // an error, so we can continue type-checking.
1597- self . check_expr_coercable_to_type ( & field. expr , field_type, None ) ;
1597+ let ty = self . check_expr_with_hint ( & field. expr , field_type) ;
1598+ let ( _, diag) =
1599+ self . demand_coerce_diag ( & field. expr , ty, field_type, None , AllowTwoPhase :: No ) ;
1600+
1601+ if let Some ( mut diag) = diag {
1602+ if idx == ast_fields. len ( ) - 1 && remaining_fields. is_empty ( ) {
1603+ self . suggest_fru_from_range ( field, variant, substs, & mut diag) ;
1604+ }
1605+ diag. emit ( ) ;
1606+ }
15981607 }
15991608
16001609 // Make sure the programmer specified correct number of fields.
@@ -1822,25 +1831,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18221831 ) ;
18231832 err. span_label ( span, format ! ( "missing {remaining_fields_names}{truncated_fields_error}" ) ) ;
18241833
1825- // If the last field is a range literal, but it isn't supposed to be, then they probably
1826- // meant to use functional update syntax.
1827- //
1834+ if let Some ( last) = ast_fields. last ( ) {
1835+ self . suggest_fru_from_range ( last, variant, substs, & mut err) ;
1836+ }
1837+
1838+ err. emit ( ) ;
1839+ }
1840+
1841+ /// If the last field is a range literal, but it isn't supposed to be, then they probably
1842+ /// meant to use functional update syntax.
1843+ fn suggest_fru_from_range (
1844+ & self ,
1845+ last_expr_field : & hir:: ExprField < ' tcx > ,
1846+ variant : & ty:: VariantDef ,
1847+ substs : SubstsRef < ' tcx > ,
1848+ err : & mut Diagnostic ,
1849+ ) {
18281850 // I don't use 'is_range_literal' because only double-sided, half-open ranges count.
1829- if let Some ( (
1830- last,
1831- ExprKind :: Struct (
1851+ if let ExprKind :: Struct (
18321852 QPath :: LangItem ( LangItem :: Range , ..) ,
18331853 & [ ref range_start, ref range_end] ,
18341854 _,
1835- ) ,
1836- ) ) = ast_fields. last ( ) . map ( |last| ( last, & last. expr . kind ) ) &&
1837- let variant_field =
1838- variant. fields . iter ( ) . find ( |field| field. ident ( self . tcx ) == last. ident ) &&
1839- let range_def_id = self . tcx . lang_items ( ) . range_struct ( ) &&
1840- variant_field
1841- . and_then ( |field| field. ty ( self . tcx , substs) . ty_adt_def ( ) )
1842- . map ( |adt| adt. did ( ) )
1843- != range_def_id
1855+ ) = last_expr_field. expr . kind
1856+ && let variant_field =
1857+ variant. fields . iter ( ) . find ( |field| field. ident ( self . tcx ) == last_expr_field. ident )
1858+ && let range_def_id = self . tcx . lang_items ( ) . range_struct ( )
1859+ && variant_field
1860+ . and_then ( |field| field. ty ( self . tcx , substs) . ty_adt_def ( ) )
1861+ . map ( |adt| adt. did ( ) )
1862+ != range_def_id
18441863 {
18451864 let instead = self
18461865 . tcx
@@ -1856,8 +1875,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18561875 Applicability :: MaybeIncorrect ,
18571876 ) ;
18581877 }
1859-
1860- err. emit ( ) ;
18611878 }
18621879
18631880 /// Report an error for a struct field expression when there are invisible fields.
0 commit comments