Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split BoundInterpolatedString into BoundInterpolatedString and BoundUnconvertedInterpolatedString #52061

Merged
merged 3 commits into from
Mar 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,17 @@ protected BoundExpression CreateConversion(
return ConvertConditionalExpression((BoundUnconvertedConditionalOperator)source, destination, conversionIfTargetTyped: conversion, diagnostics);
}

if (conversion.Kind == ConversionKind.InterpolatedString)
{
var unconvertedSource = (BoundUnconvertedInterpolatedString)source;
source = new BoundInterpolatedString(
unconvertedSource.Syntax,
unconvertedSource.Parts,
unconvertedSource.ConstantValue,
unconvertedSource.Type,
unconvertedSource.HasErrors);
}

if (source.Kind == BoundKind.UnconvertedSwitchExpression)
{
TypeSymbol? type = source.Type;
Expand Down
12 changes: 12 additions & 0 deletions src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,18 @@ internal BoundExpression BindToNaturalType(BoundExpression expression, BindingDi
result = BindObjectCreationForErrorRecovery(expr, diagnostics);
}
break;
case BoundUnconvertedInterpolatedString unconvertedInterpolatedString:
{
// We determine the best method of emitting as a string (either via Concat, Format, or the builder pattern)
// during lowering, and it's not part of the publicly-visible API, unlike conversion to a builder type.
result = new BoundInterpolatedString(
333fred marked this conversation as resolved.
Show resolved Hide resolved
unconvertedInterpolatedString.Syntax,
unconvertedInterpolatedString.Parts,
unconvertedInterpolatedString.ConstantValue,
unconvertedInterpolatedString.Type,
unconvertedInterpolatedString.HasErrors);
}
break;
default:
result = expression;
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private BoundExpression BindInterpolatedString(InterpolatedStringExpressionSynta
}

Debug.Assert(isResultConstant == (resultConstant != null));
return new BoundInterpolatedString(node, builder.ToImmutableAndFree(), resultConstant, stringType);
return new BoundUnconvertedInterpolatedString(node, builder.ToImmutableAndFree(), resultConstant, stringType);
}
}
}
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/Binder/Binder_Patterns.cs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ private BoundExpression BindExpressionForPatternContinued(
BoundExpression convertedExpression = ConvertPatternExpression(
inputType, patternExpression, expression, out constantValueOpt, hasErrors, diagnostics);

ConstantValueUtils.CheckLangVersionForConstantValue(expression, diagnostics);
ConstantValueUtils.CheckLangVersionForConstantValue(convertedExpression, diagnostics);
333fred marked this conversation as resolved.
Show resolved Hide resolved

if (!convertedExpression.HasErrors && !hasErrors)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public override Conversion GetMethodGroupFunctionPointerConversion(BoundMethodGr
return conversion;
}

protected override Conversion GetInterpolatedStringConversion(BoundInterpolatedString source, TypeSymbol destination, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
protected override Conversion GetInterpolatedStringConversion(BoundUnconvertedInterpolatedString source, TypeSymbol destination, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
{
// An interpolated string expression may be converted to the types
// System.IFormattable and System.FormattableString
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ internal ConversionsBase WithNullability(bool includeNullability)

protected abstract ConversionsBase CreateInstance(int currentRecursionDepth);

protected abstract Conversion GetInterpolatedStringConversion(BoundInterpolatedString source, TypeSymbol destination, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo);
protected abstract Conversion GetInterpolatedStringConversion(BoundUnconvertedInterpolatedString source, TypeSymbol destination, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo);

internal AssemblySymbol CorLibrary { get { return corLibrary; } }

Expand Down Expand Up @@ -931,8 +931,8 @@ private Conversion ClassifyImplicitBuiltInConversionFromExpression(BoundExpressi
}
break;

case BoundKind.InterpolatedString:
Conversion interpolatedStringConversion = GetInterpolatedStringConversion((BoundInterpolatedString)sourceExpression, destination, ref useSiteInfo);
case BoundKind.UnconvertedInterpolatedString:
Conversion interpolatedStringConversion = GetInterpolatedStringConversion((BoundUnconvertedInterpolatedString)sourceExpression, destination, ref useSiteInfo);
if (interpolatedStringConversion.Exists)
{
return interpolatedStringConversion;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public override Conversion GetStackAllocConversion(BoundStackAllocArrayCreation
throw ExceptionUtilities.Unreachable;
}

protected override Conversion GetInterpolatedStringConversion(BoundInterpolatedString source, TypeSymbol destination, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
protected override Conversion GetInterpolatedStringConversion(BoundUnconvertedInterpolatedString source, TypeSymbol destination, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
{
// Conversions involving interpolated strings require a Binder.
throw ExceptionUtilities.Unreachable;
Expand Down
5 changes: 3 additions & 2 deletions src/Compilers/CSharp/Portable/BoundTree/BoundExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ internal bool NeedsToBeConverted()
case BoundKind.UnconvertedObjectCreationExpression:
case BoundKind.UnconvertedConditionalOperator:
case BoundKind.DefaultLiteral:
case BoundKind.UnconvertedInterpolatedString:
return true;
case BoundKind.StackAllocArrayCreation:
// A BoundStackAllocArrayCreation is given a null type when it is in a
Expand Down Expand Up @@ -286,9 +287,9 @@ public override Symbol? ExpressionSymbol
}
}

internal partial class BoundInterpolatedString
internal partial class BoundInterpolatedStringBase
{
public override ConstantValue? ConstantValue
public sealed override ConstantValue? ConstantValue
{
get { return this.ConstantValueOpt; }
}
Expand Down
8 changes: 7 additions & 1 deletion src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2002,12 +2002,18 @@
<Field Name="ConstantValueOpt" Type="ConstantValue" Null="disallow"/>
</Node>

<Node Name="BoundInterpolatedString" Base="BoundExpression">
<AbstractNode Name="BoundInterpolatedStringBase" Base="BoundExpression">
<!-- The sequence of parts of an interpolated string. The even numbered positions (starting with 0) are
from the literal parts of the input. The odd numbered positions are the string inserts. When a
width or format string are provided, the corresponding insert will be a BoundStringInsert -->
<Field Name="Parts" Type="ImmutableArray&lt;BoundExpression&gt;"/>
<Field Name="ConstantValueOpt" Type="ConstantValue?"/>
</AbstractNode>

<Node Name="BoundUnconvertedInterpolatedString" Base="BoundInterpolatedStringBase">
</Node>

<Node Name="BoundInterpolatedString" Base="BoundInterpolatedStringBase">
</Node>

<Node Name="BoundStringInsert" Base="BoundExpression">
Expand Down
12 changes: 11 additions & 1 deletion src/Compilers/CSharp/Portable/FlowAnalysis/AbstractFlowPass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,7 @@ public override BoundNode VisitDynamicInvocation(BoundDynamicInvocation node)
return null;
}

public override BoundNode VisitInterpolatedString(BoundInterpolatedString node)
protected BoundNode VisitInterpolatedStringBase(BoundInterpolatedStringBase node)
{
foreach (var expr in node.Parts)
{
Expand All @@ -1056,6 +1056,16 @@ public override BoundNode VisitInterpolatedString(BoundInterpolatedString node)
return null;
}

public override BoundNode VisitInterpolatedString(BoundInterpolatedString node)
333fred marked this conversation as resolved.
Show resolved Hide resolved
{
return VisitInterpolatedStringBase(node);
}

public override BoundNode VisitUnconvertedInterpolatedString(BoundUnconvertedInterpolatedString node)
{
return VisitInterpolatedStringBase(node);
}

public override BoundNode VisitStringInsert(BoundStringInsert node)
{
VisitRvalue(node.Value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9362,6 +9362,14 @@ private static bool IsNullabilityMismatch(TypeSymbol type1, TypeSymbol type2)
return result;
}

public override BoundNode? VisitUnconvertedInterpolatedString(BoundUnconvertedInterpolatedString node)
{
// This is only involved with unbound lambdas or when visiting the source of a converted tuple literal
var result = base.VisitUnconvertedInterpolatedString(node);
SetResultType(node, TypeWithState.Create(node.Type, NullableFlowState.NotNull));
return result;
}

public override BoundNode? VisitStringInsert(BoundStringInsert node)
{
var result = base.VisitStringInsert(node);
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ public CSharpOperationFactory(SemanticModel semanticModel)
case BoundKind.TupleLiteral:
case BoundKind.ConvertedTupleLiteral:
return CreateBoundTupleOperation((BoundTupleExpression)boundNode);
case BoundKind.UnconvertedInterpolatedString:
throw ExceptionUtilities.Unreachable;
case BoundKind.InterpolatedString:
return CreateBoundInterpolatedStringExpressionOperation((BoundInterpolatedString)boundNode);
case BoundKind.StringInsert:
Expand Down