internal DeconstructionAssignmentCSharpExpression(Type type, TupleLiteralCSharpExpression left, Expression right, DeconstructionConversion conversion)
 {
     Type       = type;
     Left       = left;
     Right      = right;
     Conversion = conversion;
 }
        private List <DeconstructionVariable> GetAssignmentTargetsAndSideEffects(TupleLiteralCSharpExpression variables, List <ParameterExpression> temps, List <Expression> effects, Func <Type, ParameterExpression> createTemp)
        {
            var assignmentTargets = new List <DeconstructionVariable>(variables.Arguments.Count);

            foreach (var variable in variables.Arguments)
            {
                switch (variable)
                {
                case DiscardCSharpExpression _:
                case ParameterExpression _:
                    assignmentTargets.Add(new DeconstructionVariable(variable));
                    break;

                case TupleLiteralCSharpExpression tuple:     // REVIEW: Handle ConvertedTupleLiteral.
                    assignmentTargets.Add(new DeconstructionVariable(GetAssignmentTargetsAndSideEffects(tuple, temps, effects, createTemp)));
                    break;

                default:
                    // NB: Known limitation on ref locals when needed for e.g. obj.Bar.Foo = x where Bar is a mutable struct.
                    var expr = MakeWriteable(variable);
                    var v    = ReduceAssign(expr, temps, effects, supportByRef: true);  // CONSIDER: Wire createTemp throughout.
                    assignmentTargets.Add(new DeconstructionVariable(v));
                    break;
                }
            }

            return(assignmentTargets);
        }
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="left">The <see cref="Left" /> property of the result. </param>
        /// <param name="right">The <see cref="Right" /> property of the result. </param>
        /// <param name="conversion">The <see cref="Conversion" /> property of the result. </param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public DeconstructionAssignmentCSharpExpression Update(TupleLiteralCSharpExpression left, Expression right, DeconstructionConversion conversion)
        {
            if (left == Left && right == Right && conversion == Conversion)
            {
                return(this);
            }

            return(CSharpExpression.DeconstructionAssignment(Type, left, right, Conversion));
        }