@@ -3061,14 +3061,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
30613061
30623062 fn check_expr_struct_fields ( & self ,
30633063 adt_ty : Ty < ' tcx > ,
3064+ expected : Expectation < ' tcx > ,
30643065 expr_id : ast:: NodeId ,
30653066 span : Span ,
30663067 variant : & ' tcx ty:: VariantDef ,
30673068 ast_fields : & ' gcx [ hir:: Field ] ,
30683069 check_completeness : bool ) {
30693070 let tcx = self . tcx ;
3070- let ( substs, adt_kind, kind_name) = match adt_ty. sty {
3071- ty:: TyAdt ( adt, substs) => ( substs, adt. adt_kind ( ) , adt. variant_descr ( ) ) ,
3071+
3072+ let adt_ty_hint =
3073+ self . expected_inputs_for_expected_output ( span, expected, adt_ty, & [ adt_ty] )
3074+ . get ( 0 ) . cloned ( ) . unwrap_or ( adt_ty) ;
3075+
3076+ let ( substs, hint_substs, adt_kind, kind_name) = match ( & adt_ty. sty , & adt_ty_hint. sty ) {
3077+ ( & ty:: TyAdt ( adt, substs) , & ty:: TyAdt ( _, hint_substs) ) => {
3078+ ( substs, hint_substs, adt. adt_kind ( ) , adt. variant_descr ( ) )
3079+ }
30723080 _ => span_bug ! ( span, "non-ADT passed to check_expr_struct_fields" )
30733081 } ;
30743082
@@ -3083,10 +3091,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
30833091
30843092 // Typecheck each field.
30853093 for field in ast_fields {
3086- let expected_field_type;
3094+ let final_field_type;
3095+ let field_type_hint;
30873096
30883097 if let Some ( v_field) = remaining_fields. remove ( & field. name . node ) {
3089- expected_field_type = self . field_ty ( field. span , v_field, substs) ;
3098+ final_field_type = self . field_ty ( field. span , v_field, substs) ;
3099+ field_type_hint = self . field_ty ( field. span , v_field, hint_substs) ;
30903100
30913101 seen_fields. insert ( field. name . node , field. span ) ;
30923102
@@ -3098,7 +3108,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
30983108 }
30993109 } else {
31003110 error_happened = true ;
3101- expected_field_type = tcx. types . err ;
3111+ final_field_type = tcx. types . err ;
3112+ field_type_hint = tcx. types . err ;
31023113 if let Some ( _) = variant. find_field_named ( field. name . node ) {
31033114 let mut err = struct_span_err ! ( self . tcx. sess,
31043115 field. name. span,
@@ -3120,7 +3131,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
31203131
31213132 // Make sure to give a type to the field even if there's
31223133 // an error, so we can continue typechecking
3123- self . check_expr_coercable_to_type ( & field. expr , expected_field_type) ;
3134+ let ty = self . check_expr_with_hint ( & field. expr , field_type_hint) ;
3135+ self . demand_coerce ( & field. expr , ty, final_field_type) ;
31243136 }
31253137
31263138 // Make sure the programmer specified correct number of fields.
@@ -3230,6 +3242,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
32303242
32313243 fn check_expr_struct ( & self ,
32323244 expr : & hir:: Expr ,
3245+ expected : Expectation < ' tcx > ,
32333246 qpath : & hir:: QPath ,
32343247 fields : & ' gcx [ hir:: Field ] ,
32353248 base_expr : & ' gcx Option < P < hir:: Expr > > ) -> Ty < ' tcx >
@@ -3248,7 +3261,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
32483261 hir:: QPath :: TypeRelative ( ref qself, _) => qself. span
32493262 } ;
32503263
3251- self . check_expr_struct_fields ( struct_ty, expr. id , path_span, variant, fields,
3264+ self . check_expr_struct_fields ( struct_ty, expected , expr. id , path_span, variant, fields,
32523265 base_expr. is_none ( ) ) ;
32533266 if let & Some ( ref base_expr) = base_expr {
32543267 self . check_expr_has_type ( base_expr, struct_ty) ;
@@ -3793,7 +3806,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
37933806 }
37943807 }
37953808 hir:: ExprStruct ( ref qpath, ref fields, ref base_expr) => {
3796- self . check_expr_struct ( expr, qpath, fields, base_expr)
3809+ self . check_expr_struct ( expr, expected , qpath, fields, base_expr)
37973810 }
37983811 hir:: ExprField ( ref base, ref field) => {
37993812 self . check_field ( expr, lvalue_pref, & base, field)
0 commit comments