@@ -593,8 +593,28 @@ impl<'a> InferenceContext<'a> {
593593 }
594594 Expr :: BinaryOp { lhs, rhs, op } => match op {
595595 Some ( BinaryOp :: Assignment { op : None } ) => {
596- let rhs_ty = self . infer_expr ( * rhs, & Expectation :: none ( ) ) ;
597- self . infer_assignee_expr ( * lhs, & rhs_ty) ;
596+ let lhs = * lhs;
597+ let is_ordinary = match & self . body [ lhs] {
598+ Expr :: Array ( _)
599+ | Expr :: RecordLit { .. }
600+ | Expr :: Tuple { .. }
601+ | Expr :: Underscore => false ,
602+ Expr :: Call { callee, .. } => !matches ! ( & self . body[ * callee] , Expr :: Path ( _) ) ,
603+ _ => true ,
604+ } ;
605+
606+ // In ordinary (non-destructuring) assignments, the type of
607+ // `lhs` must be inferred first so that the ADT fields
608+ // instantiations in RHS can be coerced to it. Note that this
609+ // cannot happen in destructuring assignments because of how
610+ // they are desugared.
611+ if is_ordinary {
612+ let lhs_ty = self . infer_expr ( lhs, & Expectation :: none ( ) ) ;
613+ self . infer_expr_coerce ( * rhs, & Expectation :: has_type ( lhs_ty) ) ;
614+ } else {
615+ let rhs_ty = self . infer_expr ( * rhs, & Expectation :: none ( ) ) ;
616+ self . infer_assignee_expr ( lhs, & rhs_ty) ;
617+ }
598618 self . result . standard_types . unit . clone ( )
599619 }
600620 Some ( BinaryOp :: LogicOp ( _) ) => {
0 commit comments