@@ -1518,7 +1518,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15181518 let mut error_happened = false ;
15191519
15201520 // Type-check each field.
1521- for field in ast_fields {
1521+ for ( idx , field) in ast_fields. iter ( ) . enumerate ( ) {
15221522 let ident = tcx. adjust_ident ( field. ident , variant. def_id ) ;
15231523 let field_type = if let Some ( ( i, v_field) ) = remaining_fields. remove ( & ident) {
15241524 seen_fields. insert ( ident, field. span ) ;
@@ -1556,7 +1556,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15561556
15571557 // Make sure to give a type to the field even if there's
15581558 // an error, so we can continue type-checking.
1559- self . check_expr_coercable_to_type ( & field. expr , field_type, None ) ;
1559+ let ty = self . check_expr_with_hint ( & field. expr , field_type) ;
1560+ let ( _, diag) =
1561+ self . demand_coerce_diag ( & field. expr , ty, field_type, None , AllowTwoPhase :: No ) ;
1562+
1563+ if let Some ( mut diag) = diag {
1564+ if idx == ast_fields. len ( ) - 1 && remaining_fields. is_empty ( ) {
1565+ self . suggest_fru_from_range ( field, variant, substs, & mut diag) ;
1566+ }
1567+ diag. emit ( ) ;
1568+ }
15601569 }
15611570
15621571 // Make sure the programmer specified correct number of fields.
@@ -1784,25 +1793,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17841793 ) ;
17851794 err. span_label ( span, format ! ( "missing {remaining_fields_names}{truncated_fields_error}" ) ) ;
17861795
1787- // If the last field is a range literal, but it isn't supposed to be, then they probably
1788- // meant to use functional update syntax.
1789- //
1796+ if let Some ( last) = ast_fields. last ( ) {
1797+ self . suggest_fru_from_range ( last, variant, substs, & mut err) ;
1798+ }
1799+
1800+ err. emit ( ) ;
1801+ }
1802+
1803+ /// If the last field is a range literal, but it isn't supposed to be, then they probably
1804+ /// meant to use functional update syntax.
1805+ fn suggest_fru_from_range (
1806+ & self ,
1807+ last_expr_field : & hir:: ExprField < ' tcx > ,
1808+ variant : & ty:: VariantDef ,
1809+ substs : SubstsRef < ' tcx > ,
1810+ err : & mut Diagnostic ,
1811+ ) {
17901812 // I don't use 'is_range_literal' because only double-sided, half-open ranges count.
1791- if let Some ( (
1792- last,
1793- ExprKind :: Struct (
1813+ if let ExprKind :: Struct (
17941814 QPath :: LangItem ( LangItem :: Range , ..) ,
17951815 & [ ref range_start, ref range_end] ,
17961816 _,
1797- ) ,
1798- ) ) = ast_fields. last ( ) . map ( |last| ( last, & last. expr . kind ) ) &&
1799- let variant_field =
1800- variant. fields . iter ( ) . find ( |field| field. ident ( self . tcx ) == last. ident ) &&
1801- let range_def_id = self . tcx . lang_items ( ) . range_struct ( ) &&
1802- variant_field
1803- . and_then ( |field| field. ty ( self . tcx , substs) . ty_adt_def ( ) )
1804- . map ( |adt| adt. did ( ) )
1805- != range_def_id
1817+ ) = last_expr_field. expr . kind
1818+ && let variant_field =
1819+ variant. fields . iter ( ) . find ( |field| field. ident ( self . tcx ) == last_expr_field. ident )
1820+ && let range_def_id = self . tcx . lang_items ( ) . range_struct ( )
1821+ && variant_field
1822+ . and_then ( |field| field. ty ( self . tcx , substs) . ty_adt_def ( ) )
1823+ . map ( |adt| adt. did ( ) )
1824+ != range_def_id
18061825 {
18071826 let instead = self
18081827 . tcx
@@ -1818,8 +1837,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18181837 Applicability :: MaybeIncorrect ,
18191838 ) ;
18201839 }
1821-
1822- err. emit ( ) ;
18231840 }
18241841
18251842 /// Report an error for a struct field expression when there are invisible fields.
0 commit comments