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

Handle explicit conversions between enums and native integers #48041

Merged
merged 8 commits into from
Sep 30, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,7 @@ private Conversion ClassifyExplicitOnlyConversionFromExpression(BoundExpression
return GetExplicitUserDefinedConversion(sourceExpression, sourceType, destination, ref useSiteDiagnostics);
}

#nullable enable
private static bool HasImplicitEnumerationConversion(BoundExpression source, TypeSymbol destination)
{
Debug.Assert((object)source != null);
Expand All @@ -1239,9 +1240,11 @@ private static bool HasImplicitEnumerationConversion(BoundExpression source, Typ

var sourceConstantValue = source.ConstantValue;
return sourceConstantValue != null &&
IsNumericType(source.Type.GetSpecialTypeSafe()) &&
source.Type is object &&
IsNumericType(source.Type) &&
IsConstantNumericZero(sourceConstantValue);
}
#nullable restore

private static LambdaConversionResult IsAnonymousFunctionCompatibleWithDelegate(UnboundLambda anonymousFunction, TypeSymbol type)
{
Expand Down Expand Up @@ -1785,6 +1788,7 @@ private static int GetNumericTypeIndex(SpecialType specialType)
}
}

#nullable enable
private static bool HasImplicitNumericConversion(TypeSymbol source, TypeSymbol destination)
{
Debug.Assert((object)source != null);
Expand Down Expand Up @@ -1827,7 +1831,7 @@ private static bool HasExplicitNumericConversion(TypeSymbol source, TypeSymbol d
return s_explicitNumericConversions[sourceIndex, destinationIndex];
}

public static bool IsConstantNumericZero(ConstantValue value)
private static bool IsConstantNumericZero(ConstantValue value)
{
switch (value.Discriminator)
{
Expand All @@ -1841,12 +1845,16 @@ public static bool IsConstantNumericZero(ConstantValue value)
return value.Int32Value == 0;
case ConstantValueTypeDiscriminator.Int64:
return value.Int64Value == 0;
case ConstantValueTypeDiscriminator.NInt:
Copy link
Contributor

@RikkiGibson RikkiGibson Sep 25, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add labels to the Int32 and UInt32 sections instead of creating new switch sections for these? #Resolved

return value.Int32Value == 0;
case ConstantValueTypeDiscriminator.UInt16:
return value.UInt16Value == 0;
case ConstantValueTypeDiscriminator.UInt32:
return value.UInt32Value == 0;
case ConstantValueTypeDiscriminator.UInt64:
return value.UInt64Value == 0;
case ConstantValueTypeDiscriminator.NUInt:
return value.UInt32Value == 0;
case ConstantValueTypeDiscriminator.Single:
case ConstantValueTypeDiscriminator.Double:
return value.DoubleValue == 0;
Expand All @@ -1856,9 +1864,9 @@ public static bool IsConstantNumericZero(ConstantValue value)
return false;
}

public static bool IsNumericType(SpecialType specialType)
private static bool IsNumericType(TypeSymbol type)
{
switch (specialType)
switch (type.SpecialType)
{
case SpecialType.System_Char:
case SpecialType.System_SByte:
Expand All @@ -1872,11 +1880,14 @@ public static bool IsNumericType(SpecialType specialType)
case SpecialType.System_Single:
case SpecialType.System_Double:
case SpecialType.System_Decimal:
case SpecialType.System_IntPtr when type.IsNativeIntegerType:
case SpecialType.System_UIntPtr when type.IsNativeIntegerType:
return true;
default:
return false;
}
}
#nullable restore

private static bool HasSpecialIntPtrConversion(TypeSymbol source, TypeSymbol target)
{
Expand Down Expand Up @@ -1964,6 +1975,7 @@ static bool isIntPtrOrUIntPtr(TypeSymbol type) =>
(type.SpecialType == SpecialType.System_IntPtr || type.SpecialType == SpecialType.System_UIntPtr) && !type.IsNativeIntegerType;
}

#nullable enable
private static bool HasExplicitEnumerationConversion(TypeSymbol source, TypeSymbol destination)
{
Debug.Assert((object)source != null);
Expand All @@ -1974,12 +1986,12 @@ private static bool HasExplicitEnumerationConversion(TypeSymbol source, TypeSymb
// SPEC: From any enum-type to sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, or decimal.
// SPEC: From any enum-type to any other enum-type.

if (IsNumericType(source.SpecialType) && destination.IsEnumType())
if (IsNumericType(source) && destination.IsEnumType())
{
return true;
}

if (IsNumericType(destination.SpecialType) && source.IsEnumType())
if (IsNumericType(destination) && source.IsEnumType())
{
return true;
}
Expand All @@ -1991,6 +2003,7 @@ private static bool HasExplicitEnumerationConversion(TypeSymbol source, TypeSymb

return false;
}
#nullable restore

private Conversion ClassifyImplicitNullableConversion(TypeSymbol source, TypeSymbol destination, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,8 @@ internal static bool ContainsOnlyEmptyConstraintClauses(this ImmutableArray<Type
}

// Returns true if constraintClauses was updated with value.
// Returns false if constraintClauses already had a value with expected 'IgnoresNullableContext'
// or was updated to a value with the expected 'IgnoresNullableContext' value on another thread.
// Returns false if constraintClauses already had a value with sufficient 'IgnoresNullableContext'
// or was updated to a value with sufficient 'IgnoresNullableContext' on another thread.
internal static bool InterlockedUpdate(ref ImmutableArray<TypeParameterConstraintClause> constraintClauses, ImmutableArray<TypeParameterConstraintClause> value)
{
bool canIgnoreNullableContext = value.IgnoresNullableContext();
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/Symbols/TypeParameterBounds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ internal static bool HasValue(this TypeParameterBounds? boundsOpt, bool canIgnor
}

// Returns true if bounds was updated with value.
// Returns false if bounds already had a value with expected 'IgnoresNullableContext'
// or was updated to a value with the expected 'IgnoresNullableContext' value on another thread.
// Returns false if bounds already had a value with sufficient 'IgnoresNullableContext'
// or was updated to a value with sufficient 'IgnoresNullableContext' on another thread.
internal static bool InterlockedUpdate(ref TypeParameterBounds? bounds, TypeParameterBounds? value)
{
bool canIgnoreNullableContext = (value?.IgnoresNullableContext == true);
Expand Down
Loading