@@ -41,8 +41,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
41
41
use rustc_infer:: infer:: InferOk ;
42
42
use rustc_middle:: middle:: stability;
43
43
use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AllowTwoPhase } ;
44
- use rustc_middle:: ty:: error:: ExpectedFound ;
45
- use rustc_middle:: ty:: error:: TypeError :: { FieldMisMatch , Sorts } ;
44
+ use rustc_middle:: ty:: error:: TypeError :: FieldMisMatch ;
46
45
use rustc_middle:: ty:: subst:: SubstsRef ;
47
46
use rustc_middle:: ty:: { self , AdtKind , DefIdTree , Ty , TypeFoldable } ;
48
47
use rustc_session:: parse:: feature_err;
@@ -65,7 +64,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
65
64
& self ,
66
65
expr : & ' tcx hir:: Expr < ' tcx > ,
67
66
expected : Ty < ' tcx > ,
68
- extend_err : impl Fn ( & mut Diagnostic ) ,
67
+ extend_err : impl FnMut ( & mut Diagnostic ) ,
69
68
) -> Ty < ' tcx > {
70
69
self . check_expr_meets_expectation_or_error ( expr, ExpectHasType ( expected) , extend_err)
71
70
}
@@ -74,7 +73,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
74
73
& self ,
75
74
expr : & ' tcx hir:: Expr < ' tcx > ,
76
75
expected : Expectation < ' tcx > ,
77
- extend_err : impl Fn ( & mut Diagnostic ) ,
76
+ mut extend_err : impl FnMut ( & mut Diagnostic ) ,
78
77
) -> Ty < ' tcx > {
79
78
let expected_ty = expected. to_option ( & self ) . unwrap_or ( self . tcx . types . bool ) ;
80
79
let mut ty = self . check_expr_with_expectation ( expr, expected) ;
@@ -1557,89 +1556,81 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1557
1556
// FIXME: We are currently creating two branches here in order to maintain
1558
1557
// consistency. But they should be merged as much as possible.
1559
1558
let fru_tys = if self . tcx . features ( ) . type_changing_struct_update {
1560
- match adt_ty. kind ( ) {
1561
- ty:: Adt ( adt, substs) if adt. is_struct ( ) => {
1562
- // Make an ADT with fresh inference substitutions. This
1563
- // will allow us to guide inference along so that, e.g.
1564
- // ```
1565
- // let x = MyStruct<'a, B, const C: usize> {
1566
- // f: 1,
1567
- // ..Default::default()
1568
- // };
1569
- // ```
1570
- // will have the default base expression constrained to
1571
- // `MyStruct<'_, _, _>`, as opposed to just `_`... This
1572
- // will allow us to then do a subtyping relation on all
1573
- // of the `remaining_fields` below, per the RFC.
1574
- let fresh_substs = self . fresh_substs_for_item ( base_expr. span , adt. did ( ) ) ;
1575
- let base_ty = self . check_expr_has_type_or_error (
1576
- base_expr,
1577
- self . tcx . mk_adt ( * adt, fresh_substs) ,
1578
- |_| { } ,
1579
- ) ;
1580
- let base_ty = self . shallow_resolve ( base_ty) ;
1581
- match base_ty. kind ( ) {
1582
- ty:: Adt ( base_adt, base_subs) if adt == base_adt => {
1583
- variant
1584
- . fields
1585
- . iter ( )
1586
- . map ( |f| {
1587
- let fru_ty = self . normalize_associated_types_in (
1588
- expr_span,
1589
- self . field_ty ( base_expr. span , f, base_subs) ,
1590
- ) ;
1591
- let ident = self
1592
- . tcx
1593
- . adjust_ident ( f. ident ( self . tcx ) , variant. def_id ) ;
1594
- if let Some ( _) = remaining_fields. remove ( & ident) {
1595
- let target_ty =
1596
- self . field_ty ( base_expr. span , f, substs) ;
1597
- let cause = self . misc ( base_expr. span ) ;
1598
- match self
1599
- . at ( & cause, self . param_env )
1600
- . sup ( target_ty, fru_ty)
1601
- {
1602
- Ok ( InferOk { obligations, value : ( ) } ) => {
1603
- self . register_predicates ( obligations)
1604
- }
1605
- // FIXME: Need better diagnostics for `FieldMisMatch` error
1606
- Err ( type_error) => {
1607
- debug ! ( "check_expr_struct_fields: {fru_ty} sub {target_ty} failed: {type_error:?}" ) ;
1608
- self . report_mismatched_types (
1609
- & cause,
1610
- target_ty,
1611
- fru_ty,
1612
- FieldMisMatch ( variant. name , ident. name ) ,
1613
- )
1614
- . emit ( ) ;
1615
- }
1616
- }
1559
+ if let ty:: Adt ( adt, substs) = adt_ty. kind ( ) && adt. is_struct ( ) {
1560
+ // Make an ADT with fresh inference substitutions. This
1561
+ // will allow us to guide inference along so that, e.g.
1562
+ // ```
1563
+ // let x = MyStruct<'a, B, const C: usize> {
1564
+ // f: 1,
1565
+ // ..Default::default()
1566
+ // };
1567
+ // ```
1568
+ // will have the default base expression constrained to
1569
+ // `MyStruct<'_, _, _>`, as opposed to just `_`... This
1570
+ // will allow us to then do a subtyping relation on all
1571
+ // of the `remaining_fields` below, per the RFC.
1572
+ let fresh_substs = self . fresh_substs_for_item ( base_expr. span , adt. did ( ) ) ;
1573
+ let fresh_base_ty = self . tcx . mk_adt ( * adt, fresh_substs) ;
1574
+ let base_ty = self . check_expr_has_type_or_error (
1575
+ base_expr,
1576
+ fresh_base_ty,
1577
+ |_| {
1578
+ error_happened = true ;
1579
+ } ,
1580
+ ) ;
1581
+ let base_ty = self . shallow_resolve ( base_ty) ;
1582
+ if let ty:: Adt ( base_adt, base_substs) = base_ty. kind ( ) && adt == base_adt {
1583
+ variant
1584
+ . fields
1585
+ . iter ( )
1586
+ . map ( |f| {
1587
+ let fru_ty = self . normalize_associated_types_in (
1588
+ expr_span,
1589
+ self . field_ty ( base_expr. span , f, base_substs) ,
1590
+ ) ;
1591
+ let ident = self
1592
+ . tcx
1593
+ . adjust_ident ( f. ident ( self . tcx ) , variant. def_id ) ;
1594
+ if let Some ( _) = remaining_fields. remove ( & ident) {
1595
+ let target_ty =
1596
+ self . field_ty ( base_expr. span , f, substs) ;
1597
+ let cause = self . misc ( base_expr. span ) ;
1598
+ match self
1599
+ . at ( & cause, self . param_env )
1600
+ . sup ( target_ty, fru_ty)
1601
+ {
1602
+ Ok ( InferOk { obligations, value : ( ) } ) => {
1603
+ self . register_predicates ( obligations)
1617
1604
}
1618
- self . resolve_vars_if_possible ( fru_ty)
1619
- } )
1620
- . collect ( )
1621
- }
1622
- _ => {
1623
- self . report_mismatched_types (
1624
- & self . misc ( base_expr. span ) ,
1625
- adt_ty,
1626
- base_ty,
1627
- Sorts ( ExpectedFound :: new ( true , adt_ty, base_ty) ) ,
1628
- )
1629
- . emit ( ) ;
1630
- return ;
1631
- }
1605
+ // FIXME: Need better diagnostics for `FieldMisMatch` error
1606
+ Err ( _) => {
1607
+ self . report_mismatched_types (
1608
+ & cause,
1609
+ target_ty,
1610
+ fru_ty,
1611
+ FieldMisMatch ( variant. name , ident. name ) ,
1612
+ )
1613
+ . emit ( ) ;
1614
+ }
1615
+ }
1616
+ }
1617
+ self . resolve_vars_if_possible ( fru_ty)
1618
+ } )
1619
+ . collect ( )
1620
+ } else {
1621
+ if !error_happened && !base_ty. references_error ( ) {
1622
+ span_bug ! ( base_expr. span, "expected an error to have been reported in `check_expr_has_type_or_error`" ) ;
1632
1623
}
1633
- }
1634
- _ => {
1635
- // Check the base_expr, regardless of a bad expected adt_ty, so we can get
1636
- // type errors on that expression, too.
1637
- self . check_expr ( base_expr) ;
1638
- self . tcx
1639
- . sess
1640
- . emit_err ( FunctionalRecordUpdateOnNonStruct { span : base_expr. span } ) ;
1641
1624
return ;
1642
1625
}
1626
+ } else {
1627
+ // Check the base_expr, regardless of a bad expected adt_ty, so we can get
1628
+ // type errors on that expression, too.
1629
+ self . check_expr ( base_expr) ;
1630
+ self . tcx
1631
+ . sess
1632
+ . emit_err ( FunctionalRecordUpdateOnNonStruct { span : base_expr. span } ) ;
1633
+ return ;
1643
1634
}
1644
1635
} else {
1645
1636
self . check_expr_has_type_or_error ( base_expr, adt_ty, |_| {
0 commit comments