@@ -1518,7 +1518,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1518
1518
let mut error_happened = false ;
1519
1519
1520
1520
// Type-check each field.
1521
- for field in ast_fields {
1521
+ for ( idx , field) in ast_fields. iter ( ) . enumerate ( ) {
1522
1522
let ident = tcx. adjust_ident ( field. ident , variant. def_id ) ;
1523
1523
let field_type = if let Some ( ( i, v_field) ) = remaining_fields. remove ( & ident) {
1524
1524
seen_fields. insert ( ident, field. span ) ;
@@ -1556,7 +1556,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1556
1556
1557
1557
// Make sure to give a type to the field even if there's
1558
1558
// 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
+ }
1560
1569
}
1561
1570
1562
1571
// Make sure the programmer specified correct number of fields.
@@ -1784,25 +1793,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1784
1793
) ;
1785
1794
err. span_label ( span, format ! ( "missing {remaining_fields_names}{truncated_fields_error}" ) ) ;
1786
1795
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
+ ) {
1790
1812
// 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 (
1794
1814
QPath :: LangItem ( LangItem :: Range , ..) ,
1795
1815
& [ ref range_start, ref range_end] ,
1796
1816
_,
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
1806
1825
{
1807
1826
let instead = self
1808
1827
. tcx
@@ -1818,8 +1837,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1818
1837
Applicability :: MaybeIncorrect ,
1819
1838
) ;
1820
1839
}
1821
-
1822
- err. emit ( ) ;
1823
1840
}
1824
1841
1825
1842
/// Report an error for a struct field expression when there are invisible fields.
0 commit comments