Skip to content

Commit

Permalink
Merge pull request #43169 from jcouv/update-ttn
Browse files Browse the repository at this point in the history
Merge "target-typed new" feature in 16.7p1
  • Loading branch information
jcouv authored Apr 8, 2020
2 parents 4f4675d + 3e680ab commit 8ab475f
Show file tree
Hide file tree
Showing 73 changed files with 8,348 additions and 644 deletions.
1 change: 1 addition & 0 deletions docs/contributing/Compiler Test Plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ a[e]
x++
x--
new X()
new()
typeof(T)
default(T)
default
Expand Down
7 changes: 7 additions & 0 deletions src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,13 @@ private BoundExpression CheckValue(BoundExpression expr, BindValueKind valueKind
}
}
break;

case BoundKind.UnconvertedObjectCreationExpression:
if (valueKind == BindValueKind.RValue)
{
return expr;
}
break;
}

bool hasResolutionErrors = false;
Expand Down
63 changes: 63 additions & 0 deletions src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ protected BoundExpression CreateConversion(
}
}

if (conversion.IsObjectCreation)
{
return ConvertObjectCreationExpression(syntax, (BoundUnconvertedObjectCreationExpression)source, isCast, destination, diagnostics);
}

if (conversion.IsUserDefined)
{
// User-defined conversions are likely to be represented as multiple
Expand Down Expand Up @@ -157,6 +162,64 @@ protected BoundExpression CreateConversion(
{ WasCompilerGenerated = wasCompilerGenerated };
}

private BoundExpression ConvertObjectCreationExpression(SyntaxNode syntax, BoundUnconvertedObjectCreationExpression node, bool isCast, TypeSymbol destination, DiagnosticBag diagnostics)
{
var arguments = AnalyzedArguments.GetInstance(node.Arguments, node.ArgumentRefKindsOpt, node.ArgumentNamesOpt);
BoundExpression expr = BindObjectCreationExpression(node, destination.StrippedType(), arguments, diagnostics);
if (destination.IsNullableType())
{
// We manually create an ImplicitNullable conversion
// if the destination is nullable, in which case we
// target the underlying type e.g. `S? x = new();`
// is actually identical to `S? x = new S();`.
HashSet<DiagnosticInfo>? useSiteDiagnostics = null;
var conversion = Conversions.ClassifyStandardConversion(null, expr.Type, destination, ref useSiteDiagnostics);
expr = new BoundConversion(
node.Syntax,
operand: expr,
conversion: conversion,
@checked: false,
explicitCastInCode: isCast,
conversionGroupOpt: new ConversionGroup(conversion),
constantValueOpt: expr.ConstantValue,
type: destination);

diagnostics.Add(syntax, useSiteDiagnostics);
}
arguments.Free();
return expr;
}

private BoundExpression BindObjectCreationExpression(BoundUnconvertedObjectCreationExpression node, TypeSymbol type, AnalyzedArguments arguments, DiagnosticBag diagnostics)
{
var syntax = node.Syntax;
switch (type.TypeKind)
{
case TypeKind.Enum:
case TypeKind.Struct:
case TypeKind.Class when !type.IsAnonymousType: // We don't want to enable object creation with unspeakable types
return BindClassCreationExpression(syntax, type.Name, typeNode: syntax, (NamedTypeSymbol)type, arguments, diagnostics, node.InitializerOpt, wasTargetTyped: true);
case TypeKind.TypeParameter:
return BindTypeParameterCreationExpression(syntax, (TypeParameterSymbol)type, arguments, node.InitializerOpt, typeSyntax: syntax, diagnostics);
case TypeKind.Delegate:
return BindDelegateCreationExpression(syntax, (NamedTypeSymbol)type, arguments, node.InitializerOpt, diagnostics);
case TypeKind.Interface:
return BindInterfaceCreationExpression(syntax, (NamedTypeSymbol)type, diagnostics, typeNode: syntax, arguments, node.InitializerOpt, wasTargetTyped: true);
case TypeKind.Array:
case TypeKind.Class:
case TypeKind.Dynamic:
Error(diagnostics, ErrorCode.ERR_TypelessNewIllegalTargetType, syntax, type);
goto case TypeKind.Error;
case TypeKind.Pointer:
Error(diagnostics, ErrorCode.ERR_UnsafeTypeInObjectCreation, syntax, type);
goto case TypeKind.Error;
case TypeKind.Error:
return MakeBadExpressionForObjectCreation(syntax, type, arguments, node.InitializerOpt, typeSyntax: syntax, diagnostics);
case var v:
throw ExceptionUtilities.UnexpectedValue(v);
}
}

/// <summary>
/// Rewrite the expressions in the switch expression arms to add a conversion to the destination type.
/// </summary>
Expand Down
Loading

0 comments on commit 8ab475f

Please sign in to comment.