+ static Expression ImplicitTupleLiteralConversion (ResolveContext rc, Expression source, TypeSpec targetType, Location loc)
+ {
+ var targetTypeArgument = targetType.TypeArguments;
+ if (source.Type.Arity != targetTypeArgument.Length)
+ return null;
+
+ var namedTarget = targetType as NamedTupleSpec;
+ var tupleLiteral = source as TupleLiteral;
+ Expression instance;
+
+ if (tupleLiteral == null && !ExpressionAnalyzer.IsInexpensiveLoad (source)) {
+ var expr_variable = LocalVariable.CreateCompilerGenerated (source.Type, rc.CurrentBlock, loc);
+ source = new CompilerAssign (expr_variable.CreateReferenceExpression (rc, loc), source, loc);
+ instance = expr_variable.CreateReferenceExpression (rc, loc);
+ } else {
+ instance = null;
+ }
+
+ var converted = new List<Expression> (targetType.Arity);
+ for (int i = 0; i < targetType.Arity; ++i) {
+ Expression elementSrc;
+ if (tupleLiteral != null) {
+ elementSrc = tupleLiteral.Elements [i].Expr;
+
+ if (namedTarget != null) {
+ var elementSrcName = tupleLiteral.Elements [i].Name;
+ if (elementSrcName != null && elementSrcName != namedTarget.Elements [i]) {
+ rc.Report.Warning (8123, 1, loc,
+ "The tuple element name `{0}' is ignored because a different name or no name is specified by the target type `{1}'",
+ elementSrcName, namedTarget.GetSignatureForErrorWithNames ());
+ }
+ }
+ } else {
+ elementSrc = new MemberAccess (instance, NamedTupleSpec.GetElementPropertyName (i)).Resolve (rc);
+ }
+
+ var res = ImplicitConversionStandard (rc, elementSrc, targetTypeArgument [i], loc);
+ if (res == null)
+ return null;
+
+ converted.Add (res);
+ }
+
+ return new TupleLiteralConversion (source, targetType, converted, loc);
+ }
+
+ static bool ImplicitTupleLiteralConversionExists (Expression source, TypeSpec targetType)
+ {
+ if (source.Type.Arity != targetType.Arity)
+ return false;
+
+ var srcTypeArgument = source.Type.TypeArguments;
+ var targetTypeArgument = targetType.TypeArguments;
+
+ var tupleLiteralElements = (source as TupleLiteral)?.Elements;
+
+ for (int i = 0; i < targetType.Arity; ++i) {
+ if (tupleLiteralElements != null) {
+ if (!ImplicitStandardConversionExists (tupleLiteralElements[i].Expr, targetTypeArgument [i])) {
+ return false;
+ }
+ } else {
+ if (!ImplicitStandardConversionExists (new EmptyExpression (srcTypeArgument [i]), targetTypeArgument [i])) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+