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

Remove Utf8StringLiteral conversion #61481

Merged
merged 2 commits into from
May 26, 2022
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
5 changes: 0 additions & 5 deletions src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,6 @@ BoundExpression createConversion(
.WithSuppression(source.IsSuppressed);
}

if (conversion.IsUTF8StringLiteral)
{
CheckFeatureAvailability(syntax, MessageID.IDS_FeatureUTF8StringLiterals, diagnostics);
}

reportUseSiteDiagnosticsForUnderlyingConversions(conversion);

return new BoundConversion(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ private static void AssertTrivialConversion(ConversionKind kind)
case ConversionKind.NoConversion:
case ConversionKind.Identity:
case ConversionKind.ImplicitConstant:
case ConversionKind.ImplicitUtf8StringLiteral:
case ConversionKind.ImplicitNumeric:
case ConversionKind.ImplicitReference:
case ConversionKind.ImplicitEnumeration:
Expand Down Expand Up @@ -227,7 +226,6 @@ internal static Conversion GetTrivialConversion(ConversionKind kind)
internal static Conversion NoConversion => new Conversion(ConversionKind.NoConversion);
internal static Conversion Identity => new Conversion(ConversionKind.Identity);
internal static Conversion ImplicitConstant => new Conversion(ConversionKind.ImplicitConstant);
internal static Conversion ImplicitUtf8StringLiteral => new Conversion(ConversionKind.ImplicitUtf8StringLiteral);
internal static Conversion ImplicitNumeric => new Conversion(ConversionKind.ImplicitNumeric);
internal static Conversion ImplicitReference => new Conversion(ConversionKind.ImplicitReference);
internal static Conversion ImplicitEnumeration => new Conversion(ConversionKind.ImplicitEnumeration);
Expand Down Expand Up @@ -827,17 +825,6 @@ public bool IsConstantExpression
}
}

/// <summary>
/// Returns true if the conversion is an implicit Utf8 string literal conversion.
/// </summary>
public bool IsUTF8StringLiteral
{
get
{
return Kind == ConversionKind.ImplicitUtf8StringLiteral;
}
}

/// <summary>
/// Returns true if the conversion is an implicit anonymous function conversion.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ internal enum ConversionKind : byte
ImplicitDynamic,
ExplicitDynamic,
ImplicitConstant,
ImplicitUtf8StringLiteral,
ImplicitUserDefined,
AnonymousFunction,
MethodGroup,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public static bool IsImplicitConversion(this ConversionKind conversionKind)
case Boxing:
case ImplicitDynamic:
case ImplicitConstant:
case ImplicitUtf8StringLiteral:
case ImplicitUserDefined:
case AnonymousFunction:
case ConversionKind.MethodGroup:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,6 @@ private static bool IsStandardImplicitConversionFromType(ConversionKind kind)
case ConversionKind.ImplicitReference:
case ConversionKind.Boxing:
case ConversionKind.ImplicitConstant:
case ConversionKind.ImplicitUtf8StringLiteral:
case ConversionKind.ImplicitPointer:
case ConversionKind.ImplicitPointerToVoid:
case ConversionKind.ImplicitTuple:
Expand Down Expand Up @@ -657,8 +656,7 @@ private Conversion ClassifyStandardImplicitConversion(BoundExpression sourceExpr

Conversion conversion = ClassifyImplicitBuiltInConversionFromExpression(sourceExpression, source, destination, ref useSiteInfo);
if (conversion.Exists &&
!conversion.IsInterpolatedStringHandler &&
!conversion.IsUTF8StringLiteral) // UTF-8 string conversion is not a standard conversion.
!conversion.IsInterpolatedStringHandler)
{
Debug.Assert(IsStandardImplicitConversionFromExpression(conversion.Kind));
return conversion;
Expand Down Expand Up @@ -1021,12 +1019,6 @@ private Conversion ClassifyImplicitBuiltInConversionFromExpression(BoundExpressi
return constantConversion;
}

constantConversion = ClassifyImplicitUtf8StringLiteralConversion(sourceExpression, destination);
if (constantConversion.Exists)
{
return constantConversion;
}

switch (sourceExpression.Kind)
{
case BoundKind.Literal:
Expand Down Expand Up @@ -1107,35 +1099,6 @@ private Conversion ClassifyImplicitBuiltInConversionFromExpression(BoundExpressi
return Conversion.NoConversion;
}

#nullable enable
private Conversion ClassifyImplicitUtf8StringLiteralConversion(BoundExpression sourceExpression, TypeSymbol destination)
{
var compilation = Compilation;

// The language will allow conversions between string constants and byte sequences
// where the text is converted into the equivalent UTF8 byte representation.
// Specifically the compiler will allow for implicit conversions from string constants to
// byte[], Span<byte>, and ReadOnlySpan<byte>.
ConstantValue? constantValue = sourceExpression.ConstantValue;

TypeSymbol destinationOriginalDefinition = destination.OriginalDefinition;
if (constantValue is ({ IsString: true } or { IsNull: true }) &&
sourceExpression.Type?.SpecialType == SpecialType.System_String &&
(destination is ArrayTypeSymbol { IsSZArray: true, ElementType.SpecialType: SpecialType.System_Byte } || // byte[]
(destinationOriginalDefinition.TypeKind == TypeKind.Struct && destinationOriginalDefinition.IsRefLikeType &&
compilation is not null &&
(destinationOriginalDefinition.Equals(compilation.GetWellKnownType(WellKnownType.System_Span_T), TypeCompareKind.AllIgnoreOptions) || // Span<T>
destinationOriginalDefinition.Equals(compilation.GetWellKnownType(WellKnownType.System_ReadOnlySpan_T), TypeCompareKind.AllIgnoreOptions)) && // ReadOnlySpan<T>
((NamedTypeSymbol)destination).TypeArgumentsWithAnnotationsNoUseSiteDiagnostics.Single().SpecialType == SpecialType.System_Byte))) // T is byte
{
return Conversion.ImplicitUtf8StringLiteral;
}

Debug.Assert(compilation is not null);
return Conversion.NoConversion;
}
#nullable disable

private Conversion GetSwitchExpressionConversion(BoundExpression source, TypeSymbol destination, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
{
Debug.Assert(Compilation is not null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,6 @@ private static bool IsEncompassingImplicitConversionKind(ConversionKind kind)
case ConversionKind.StackAllocToPointerType:
case ConversionKind.StackAllocToSpanType:
case ConversionKind.InterpolatedStringHandler:
case ConversionKind.ImplicitUtf8StringLiteral:

// Not "standard".
case ConversionKind.ImplicitUserDefined:
Expand Down
11 changes: 0 additions & 11 deletions src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7775,17 +7775,6 @@ private TypeWithState VisitConversion(
resultState = NullableFlowState.NotNull;
break;

case ConversionKind.ImplicitUtf8StringLiteral:
if (targetType.IsReferenceType)
{
resultState = getConversionResultState(operandType);
}
else
{
resultState = NullableFlowState.NotNull;
}
break;

case ConversionKind.ObjectCreation:
case ConversionKind.SwitchExpression:
case ConversionKind.ConditionalExpression:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -761,13 +761,6 @@ public override BoundNode VisitConversion(BoundConversion node)
}
break;

case ConversionKind.ImplicitUtf8StringLiteral:
if (_inExpressionLambda)
{
Error(ErrorCode.ERR_ExpressionTreeContainsUTF8StringLiterals, node);
}
break;

default:

if (_inExpressionLambda && node.Conversion.Method is MethodSymbol method && (method.IsAbstract || method.IsVirtual) && method.IsStatic)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ public override BoundNode VisitConversion(BoundConversion node)
InterpolationHandlerResult interpolationResult = RewriteToInterpolatedStringHandlerPattern(data, parts, node.Operand.Syntax);
return interpolationResult.WithFinalResult(interpolationResult.HandlerTemp);

case ConversionKind.ImplicitUtf8StringLiteral:
return RewriteUtf8StringLiteralConversion(node);

case ConversionKind.SwitchExpression:
// Skip through target-typed switches
Debug.Assert(node.Operand is BoundConvertedSwitchExpression { WasTargetTyped: true });
Expand Down Expand Up @@ -76,62 +73,6 @@ public override BoundNode VisitConversion(BoundConversion node)
return result;
}

private BoundNode RewriteUtf8StringLiteralConversion(BoundConversion node)
{
string? value = node.Operand.ConstantValue?.StringValue;

if (value == null)
{
return new BoundDefaultExpression(node.Syntax, node.Type);
}

ArrayTypeSymbol byteArray;

if (node.Type is ArrayTypeSymbol array)
{
Debug.Assert(array.IsSZArray);
Debug.Assert(array.ElementType.SpecialType == SpecialType.System_Byte);
byteArray = array;
}
else
{
Debug.Assert(node.Type.OriginalDefinition.Equals(_compilation.GetWellKnownType(WellKnownType.System_Span_T), TypeCompareKind.AllIgnoreOptions) ||
node.Type.OriginalDefinition.Equals(_compilation.GetWellKnownType(WellKnownType.System_ReadOnlySpan_T), TypeCompareKind.AllIgnoreOptions));
Debug.Assert(node.Type.OriginalDefinition.TypeKind == TypeKind.Struct && node.Type.OriginalDefinition.IsRefLikeType);

var byteType = ((NamedTypeSymbol)node.Type).TypeArgumentsWithAnnotationsNoUseSiteDiagnostics.Single().Type;
Debug.Assert(byteType.SpecialType == SpecialType.System_Byte);

byteArray = ArrayTypeSymbol.CreateSZArray(_compilation.Assembly, TypeWithAnnotations.Create(byteType));
}

BoundExpression utf8Bytes = CreateUTF8ByteRepresentation(node.Syntax, node.Operand.Syntax, value, byteArray);

if ((object)node.Type == byteArray)
{
return utf8Bytes;
}

WellKnownMember wellKnownCtor;

if (node.Type.Name == "Span")
{
wellKnownCtor = WellKnownMember.System_Span_T__ctor_Array;
}
else
{
Debug.Assert(node.Type.Name == "ReadOnlySpan");
wellKnownCtor = WellKnownMember.System_ReadOnlySpan_T__ctor_Array;
}

if (!TryGetWellKnownTypeMember<MethodSymbol>(node.Syntax, wellKnownCtor, out MethodSymbol ctor))
{
return BadExpression(node.Syntax, node.Type, ImmutableArray<BoundExpression>.Empty);
}

return new BoundObjectCreationExpression(node.Syntax, ctor.AsMember((NamedTypeSymbol)node.Type), utf8Bytes);
}

private BoundExpression CreateUTF8ByteRepresentation(SyntaxNode resultSyntax, SyntaxNode valueSyntax, string value, ArrayTypeSymbol byteArray)
{
Debug.Assert(byteArray.IsSZArray);
Expand Down
1 change: 0 additions & 1 deletion src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ConversionOperatorDeclaration
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.OperatorMemberCref(Microsoft.CodeAnalysis.SyntaxToken operatorKeyword, Microsoft.CodeAnalysis.SyntaxToken checkedKeyword, Microsoft.CodeAnalysis.SyntaxToken operatorToken, Microsoft.CodeAnalysis.CSharp.Syntax.CrefParameterListSyntax? parameters) -> Microsoft.CodeAnalysis.CSharp.Syntax.OperatorMemberCrefSyntax!
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ConversionOperatorMemberCref(Microsoft.CodeAnalysis.SyntaxToken implicitOrExplicitKeyword, Microsoft.CodeAnalysis.SyntaxToken operatorKeyword, Microsoft.CodeAnalysis.SyntaxToken checkedKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax! type, Microsoft.CodeAnalysis.CSharp.Syntax.CrefParameterListSyntax? parameters) -> Microsoft.CodeAnalysis.CSharp.Syntax.ConversionOperatorMemberCrefSyntax!
static Microsoft.CodeAnalysis.CSharp.SyntaxFacts.IsCheckedOperator(string! operatorMetadataName) -> bool
Microsoft.CodeAnalysis.CSharp.Conversion.IsUTF8StringLiteral.get -> bool
*REMOVED*Microsoft.CodeAnalysis.CSharp.SyntaxKind.ExclamationExclamationToken = 8285 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind
Microsoft.CodeAnalysis.CSharp.SyntaxKind.UTF8StringLiteralExpression = 8756 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind
Microsoft.CodeAnalysis.CSharp.SyntaxKind.UTF8StringLiteralToken = 8520 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ internal static bool ReportDefaultParameterErrors(
}
}
else if (!defaultExpression.HasAnyErrors &&
!IsValidDefaultValue(defaultExpression.IsImplicitObjectCreation() || convertedExpression is BoundConversion { Conversion.IsUTF8StringLiteral: true } ?
!IsValidDefaultValue(defaultExpression.IsImplicitObjectCreation() ?
convertedExpression : defaultExpression))
{
// error CS1736: Default parameter value for '{0}' must be a compile-time constant
Expand Down
Loading