@@ -1556,7 +1556,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1556
1556
let mut error_happened = false ;
1557
1557
1558
1558
// Type-check each field.
1559
- for field in ast_fields {
1559
+ for ( idx , field) in ast_fields. iter ( ) . enumerate ( ) {
1560
1560
let ident = tcx. adjust_ident ( field. ident , variant. def_id ) ;
1561
1561
let field_type = if let Some ( ( i, v_field) ) = remaining_fields. remove ( & ident) {
1562
1562
seen_fields. insert ( ident, field. span ) ;
@@ -1594,7 +1594,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1594
1594
1595
1595
// Make sure to give a type to the field even if there's
1596
1596
// 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
+ }
1598
1607
}
1599
1608
1600
1609
// Make sure the programmer specified correct number of fields.
@@ -1822,25 +1831,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1822
1831
) ;
1823
1832
err. span_label ( span, format ! ( "missing {remaining_fields_names}{truncated_fields_error}" ) ) ;
1824
1833
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
+ ) {
1828
1850
// 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 (
1832
1852
QPath :: LangItem ( LangItem :: Range , ..) ,
1833
1853
& [ ref range_start, ref range_end] ,
1834
1854
_,
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
1844
1863
{
1845
1864
let instead = self
1846
1865
. tcx
@@ -1856,8 +1875,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1856
1875
Applicability :: MaybeIncorrect ,
1857
1876
) ;
1858
1877
}
1859
-
1860
- err. emit ( ) ;
1861
1878
}
1862
1879
1863
1880
/// Report an error for a struct field expression when there are invisible fields.
0 commit comments