@@ -3151,14 +3151,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
3151
3151
3152
3152
fn check_expr_struct_fields ( & self ,
3153
3153
adt_ty : Ty < ' tcx > ,
3154
+ expected : Expectation < ' tcx > ,
3154
3155
expr_id : ast:: NodeId ,
3155
3156
span : Span ,
3156
3157
variant : & ' tcx ty:: VariantDef ,
3157
3158
ast_fields : & ' gcx [ hir:: Field ] ,
3158
3159
check_completeness : bool ) {
3159
3160
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
+ }
3162
3170
_ => span_bug ! ( span, "non-ADT passed to check_expr_struct_fields" )
3163
3171
} ;
3164
3172
@@ -3173,10 +3181,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
3173
3181
3174
3182
// Typecheck each field.
3175
3183
for field in ast_fields {
3176
- let expected_field_type;
3184
+ let final_field_type;
3185
+ let field_type_hint;
3177
3186
3178
3187
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) ;
3180
3190
3181
3191
seen_fields. insert ( field. name . node , field. span ) ;
3182
3192
@@ -3188,7 +3198,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
3188
3198
}
3189
3199
} else {
3190
3200
error_happened = true ;
3191
- expected_field_type = tcx. types . err ;
3201
+ final_field_type = tcx. types . err ;
3202
+ field_type_hint = tcx. types . err ;
3192
3203
if let Some ( _) = variant. find_field_named ( field. name . node ) {
3193
3204
let mut err = struct_span_err ! ( self . tcx. sess,
3194
3205
field. name. span,
@@ -3210,7 +3221,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
3210
3221
3211
3222
// Make sure to give a type to the field even if there's
3212
3223
// 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) ;
3214
3226
}
3215
3227
3216
3228
// Make sure the programmer specified correct number of fields.
@@ -3320,6 +3332,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
3320
3332
3321
3333
fn check_expr_struct ( & self ,
3322
3334
expr : & hir:: Expr ,
3335
+ expected : Expectation < ' tcx > ,
3323
3336
qpath : & hir:: QPath ,
3324
3337
fields : & ' gcx [ hir:: Field ] ,
3325
3338
base_expr : & ' gcx Option < P < hir:: Expr > > ) -> Ty < ' tcx >
@@ -3338,7 +3351,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
3338
3351
hir:: QPath :: TypeRelative ( ref qself, _) => qself. span
3339
3352
} ;
3340
3353
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,
3342
3355
base_expr. is_none ( ) ) ;
3343
3356
if let & Some ( ref base_expr) = base_expr {
3344
3357
self . check_expr_has_type ( base_expr, struct_ty) ;
@@ -3883,7 +3896,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
3883
3896
}
3884
3897
}
3885
3898
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)
3887
3900
}
3888
3901
hir:: ExprField ( ref base, ref field) => {
3889
3902
self . check_field ( expr, lvalue_pref, & base, field)
0 commit comments