return null;
}
+ 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;
+ }
+
+
//
// Full version of implicit conversion
//
return false;
}
+ var interpolated_string = expr as InterpolatedString;
+ if (interpolated_string != null) {
+ if (target_type == rc.Module.PredefinedTypes.IFormattable.TypeSpec || target_type == rc.Module.PredefinedTypes.FormattableString.TypeSpec)
+ return true;
+ }
+
return ImplicitStandardConversionExists (expr, target_type);
}
if (expr_type == target_type)
return true;
+ if (expr_type == InternalType.ThrowExpr)
+ return target_type.Kind != MemberKind.InternalCompilerType;
+
if (target_type.IsNullableType)
return ImplicitNulableConversion (null, expr, target_type) != null;
if (ImplicitBoxingConversion (null, expr_type, target_type) != null)
return true;
-
+
+ if (expr_type.IsTupleType && target_type.IsTupleType)
+ return ImplicitTupleLiteralConversionExists (expr, target_type);
+
//
// Implicit Constant Expression Conversions
//
Expression e;
if (expr_type == target_type) {
- if (expr_type != InternalType.NullLiteral && expr_type != InternalType.AnonymousMethod)
+ if (expr_type != InternalType.NullLiteral && expr_type != InternalType.AnonymousMethod && expr_type != InternalType.ThrowExpr)
return expr;
return null;
}
return null;
}
+ if (expr_type == InternalType.ThrowExpr) {
+ return target_type.Kind == MemberKind.InternalCompilerType ? null : EmptyCast.Create (expr, target_type);
+ }
+
if (target_type.IsNullableType)
return ImplicitNulableConversion (ec, expr, target_type);
return c;
}
+ if (expr_type.IsTupleType) {
+ if (target_type.IsTupleType)
+ return ImplicitTupleLiteralConversion (ec, expr, target_type, loc);
+
+ if (expr is TupleLiteral && TupleLiteral.ContainsNoTypeElement (expr_type))
+ return null;
+ }
+
e = ImplicitNumericConversion (expr, expr_type, target_type);
if (e != null)
return e;
/// ImplicitConversion. If there is no implicit conversion, then
/// an error is signaled
/// </summary>
- static public Expression ImplicitConversionRequired (ResolveContext ec, Expression source,
+ public static Expression ImplicitConversionRequired (ResolveContext ec, Expression source,
TypeSpec target_type, Location loc)
{
Expression e = ImplicitConversion (ec, source, target_type, loc);
if (e != null)
return e;
- source.Error_ValueCannotBeConverted (ec, target_type, false);
+ if (target_type != InternalType.ErrorType)
+ source.Error_ValueCannotBeConverted (ec, target_type, false);
return null;
}