@@ -41,8 +41,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
4141use rustc_infer:: infer:: InferOk ;
4242use rustc_middle:: middle:: stability;
4343use 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 ;
4645use rustc_middle:: ty:: subst:: SubstsRef ;
4746use rustc_middle:: ty:: { self , AdtKind , DefIdTree , Ty , TypeFoldable } ;
4847use rustc_session:: parse:: feature_err;
@@ -65,7 +64,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6564 & self ,
6665 expr : & ' tcx hir:: Expr < ' tcx > ,
6766 expected : Ty < ' tcx > ,
68- extend_err : impl Fn ( & mut Diagnostic ) ,
67+ extend_err : impl FnMut ( & mut Diagnostic ) ,
6968 ) -> Ty < ' tcx > {
7069 self . check_expr_meets_expectation_or_error ( expr, ExpectHasType ( expected) , extend_err)
7170 }
@@ -74,7 +73,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7473 & self ,
7574 expr : & ' tcx hir:: Expr < ' tcx > ,
7675 expected : Expectation < ' tcx > ,
77- extend_err : impl Fn ( & mut Diagnostic ) ,
76+ mut extend_err : impl FnMut ( & mut Diagnostic ) ,
7877 ) -> Ty < ' tcx > {
7978 let expected_ty = expected. to_option ( & self ) . unwrap_or ( self . tcx . types . bool ) ;
8079 let mut ty = self . check_expr_with_expectation ( expr, expected) ;
@@ -1557,89 +1556,81 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15571556 // FIXME: We are currently creating two branches here in order to maintain
15581557 // consistency. But they should be merged as much as possible.
15591558 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)
16171604 }
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`" ) ;
16321623 }
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 } ) ;
16411624 return ;
16421625 }
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 ;
16431634 }
16441635 } else {
16451636 self . check_expr_has_type_or_error ( base_expr, adt_ty, |_| {
0 commit comments