@@ -3151,14 +3151,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
31513151
31523152 fn check_expr_struct_fields ( & self ,
31533153 adt_ty : Ty < ' tcx > ,
3154+ expected : Expectation < ' tcx > ,
31543155 expr_id : ast:: NodeId ,
31553156 span : Span ,
31563157 variant : & ' tcx ty:: VariantDef ,
31573158 ast_fields : & ' gcx [ hir:: Field ] ,
31583159 check_completeness : bool ) {
31593160 let tcx = self . tcx ;
3160- let ( substs, adt_kind, kind_name) = match adt_ty. sty {
3161- ty:: TyAdt ( adt, substs) => ( substs, adt. adt_kind ( ) , adt. variant_descr ( ) ) ,
3161+
3162+ let adt_ty_hint =
3163+ self . expected_inputs_for_expected_output ( span, expected, adt_ty, & [ adt_ty] )
3164+ . get ( 0 ) . cloned ( ) . unwrap_or ( adt_ty) ;
3165+
3166+ let ( substs, hint_substs, adt_kind, kind_name) = match ( & adt_ty. sty , & adt_ty_hint. sty ) {
3167+ ( & ty:: TyAdt ( adt, substs) , & ty:: TyAdt ( _, hint_substs) ) => {
3168+ ( substs, hint_substs, adt. adt_kind ( ) , adt. variant_descr ( ) )
3169+ }
31623170 _ => span_bug ! ( span, "non-ADT passed to check_expr_struct_fields" )
31633171 } ;
31643172
@@ -3173,10 +3181,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
31733181
31743182 // Typecheck each field.
31753183 for field in ast_fields {
3176- let expected_field_type;
3184+ let final_field_type;
3185+ let field_type_hint;
31773186
31783187 if let Some ( v_field) = remaining_fields. remove ( & field. name . node ) {
3179- expected_field_type = self . field_ty ( field. span , v_field, substs) ;
3188+ final_field_type = self . field_ty ( field. span , v_field, substs) ;
3189+ field_type_hint = self . field_ty ( field. span , v_field, hint_substs) ;
31803190
31813191 seen_fields. insert ( field. name . node , field. span ) ;
31823192
@@ -3188,7 +3198,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
31883198 }
31893199 } else {
31903200 error_happened = true ;
3191- expected_field_type = tcx. types . err ;
3201+ final_field_type = tcx. types . err ;
3202+ field_type_hint = tcx. types . err ;
31923203 if let Some ( _) = variant. find_field_named ( field. name . node ) {
31933204 let mut err = struct_span_err ! ( self . tcx. sess,
31943205 field. name. span,
@@ -3210,7 +3221,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
32103221
32113222 // Make sure to give a type to the field even if there's
32123223 // an error, so we can continue typechecking
3213- self . check_expr_coercable_to_type ( & field. expr , expected_field_type) ;
3224+ let ty = self . check_expr_with_hint ( & field. expr , field_type_hint) ;
3225+ self . demand_coerce ( & field. expr , ty, final_field_type) ;
32143226 }
32153227
32163228 // Make sure the programmer specified correct number of fields.
@@ -3320,6 +3332,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
33203332
33213333 fn check_expr_struct ( & self ,
33223334 expr : & hir:: Expr ,
3335+ expected : Expectation < ' tcx > ,
33233336 qpath : & hir:: QPath ,
33243337 fields : & ' gcx [ hir:: Field ] ,
33253338 base_expr : & ' gcx Option < P < hir:: Expr > > ) -> Ty < ' tcx >
@@ -3338,7 +3351,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
33383351 hir:: QPath :: TypeRelative ( ref qself, _) => qself. span
33393352 } ;
33403353
3341- self . check_expr_struct_fields ( struct_ty, expr. id , path_span, variant, fields,
3354+ self . check_expr_struct_fields ( struct_ty, expected , expr. id , path_span, variant, fields,
33423355 base_expr. is_none ( ) ) ;
33433356 if let & Some ( ref base_expr) = base_expr {
33443357 self . check_expr_has_type ( base_expr, struct_ty) ;
@@ -3883,7 +3896,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
38833896 }
38843897 }
38853898 hir:: ExprStruct ( ref qpath, ref fields, ref base_expr) => {
3886- self . check_expr_struct ( expr, qpath, fields, base_expr)
3899+ self . check_expr_struct ( expr, expected , qpath, fields, base_expr)
38873900 }
38883901 hir:: ExprField ( ref base, ref field) => {
38893902 self . check_field ( expr, lvalue_pref, & base, field)
0 commit comments