public override BoundNode VisitTupleBinaryOperator(BoundTupleBinaryOperator node) { // We skip the unconverted left and right, they are only meant for lowering this.Visit(node.ConvertedLeft); this.Visit(node.ConvertedRight); return(null); }
public override BoundNode VisitTupleBinaryOperator(BoundTupleBinaryOperator node) { if (_inExpressionLambda) { Error(ErrorCode.ERR_ExpressionTreeContainsTupleBinOp, node); } return(base.VisitTupleBinaryOperator(node)); }
/// <summary> /// Rewrite <c>GetTuple() == (1, 2)</c> to <c>tuple.Item1 == 1 && tuple.Item2 == 2</c>. /// Also supports the != operator, nullable and nested tuples. /// /// Note that all the side-effects for visible expressions are evaluated first and from left to right. The initialization phase /// contains side-effects for: /// - single elements in tuple literals, like <c>a</c> in <c>(a, ...) == (...)</c> for example /// - nested expressions that aren't tuple literals, like <c>GetTuple()</c> in <c>(..., GetTuple()) == (..., (..., ...))</c> /// On the other hand, <c>Item1</c> and <c>Item2</c> of <c>GetTuple()</c> are not saved as part of the initialization phase of <c>GetTuple() == (..., ...)</c> /// /// Element-wise conversions occur late, together with the element-wise comparisons. They might not be evaluated. /// </summary> public override BoundNode VisitTupleBinaryOperator(BoundTupleBinaryOperator node) { var boolType = node.Type; // we can re-use the bool type var initEffects = ArrayBuilder <BoundExpression> .GetInstance(); var temps = ArrayBuilder <LocalSymbol> .GetInstance(); BoundExpression newLeft = ReplaceTerminalElementsWithTemps(node.Left, node.Operators, initEffects, temps); BoundExpression newRight = ReplaceTerminalElementsWithTemps(node.Right, node.Operators, initEffects, temps); var returnValue = RewriteTupleNestedOperators(node.Operators, newLeft, newRight, boolType, temps, node.OperatorKind); BoundExpression result = _factory.Sequence(temps.ToImmutableAndFree(), initEffects.ToImmutableAndFree(), returnValue); return(result); }