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

Unify nint and IntPtr #60913

Merged
merged 15 commits into from
May 18, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -1359,7 +1359,7 @@ private void CheckDisallowedAttributeDependentType(TypeWithAnnotations typeArgum
var type = typeWithAnnotations.Type;
if (type.IsDynamic()
|| (typeWithAnnotations.NullableAnnotation.IsAnnotated() && !type.IsValueType)
|| type.IsNativeIntegerType
|| type.IsNativeIntegerWrapperType
|| (type.IsTupleType && !type.TupleElementNames.IsDefault))
{
diagnostics.Add(ErrorCode.ERR_AttrDependentTypeNotAllowed, errorLocation, topLevelType.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat));
Expand Down
8 changes: 7 additions & 1 deletion src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1394,7 +1394,7 @@ private UnaryOperatorAnalysisResult UnaryOperatorOverloadResolution(

if (kind == UnaryOperatorKind.UnaryMinus &&
(object)operand.Type != null &&
(operand.Type.SpecialType == SpecialType.System_UInt64 || (operand.Type.SpecialType == SpecialType.System_UIntPtr && operand.Type.IsNativeIntegerType)))
(operand.Type.SpecialType == SpecialType.System_UInt64 || isNuint(operand.Type)))
{
resultKind = LookupResultKind.OverloadResolutionFailure;
}
Expand Down Expand Up @@ -1422,6 +1422,12 @@ private UnaryOperatorAnalysisResult UnaryOperatorOverloadResolution(

result.Free();
return possiblyBest;

bool isNuint(TypeSymbol type)
RikkiGibson marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

@cston cston May 16, 2022

Choose a reason for hiding this comment

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

isNuint(TypeSymbol type)

Was there a reason to introduce this local function rather than leave the code inline? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

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

Felt more readable

{
return type.SpecialType == SpecialType.System_UIntPtr
&& type.IsNativeIntegerTypeOrNumericIntPtr;
}
}

private static object FoldDecimalBinaryOperators(BinaryOperatorKind kind, ConstantValue valueLeft, ConstantValue valueRight)
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/Binder/Binder_Patterns.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1650,8 +1650,8 @@ private BoundPattern BindRelationalPattern(
SpecialType.System_Decimal => BinaryOperatorKind.Decimal,
SpecialType.System_String => BinaryOperatorKind.String,
SpecialType.System_Boolean => BinaryOperatorKind.Bool,
SpecialType.System_IntPtr when type.IsNativeIntegerType => BinaryOperatorKind.NInt,
SpecialType.System_UIntPtr when type.IsNativeIntegerType => BinaryOperatorKind.NUInt,
SpecialType.System_IntPtr when type.IsNativeIntegerTypeOrNumericIntPtr => BinaryOperatorKind.NInt,
SpecialType.System_UIntPtr when type.IsNativeIntegerTypeOrNumericIntPtr => BinaryOperatorKind.NUInt,
_ => BinaryOperatorKind.Error,
};

Expand Down
3 changes: 2 additions & 1 deletion src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,8 @@ private NamedTypeSymbol BindNativeIntegerSymbolIfAny(IdentifierNameSyntax node,
}

CheckFeatureAvailability(node, MessageID.IDS_FeatureNativeInt, diagnostics);
return this.GetSpecialType(specialType, diagnostics, node).AsNativeInteger();
var type = this.GetSpecialType(specialType, diagnostics, node);
return type.ContainingAssembly.RuntimeSupportsNumericIntPtr ? type : type.AsNativeInteger();
RikkiGibson marked this conversation as resolved.
Show resolved Hide resolved
}

private void ReportUseSiteDiagnosticForDynamic(BindingDiagnosticBag diagnostics, IdentifierNameSyntax node)
Expand Down
8 changes: 4 additions & 4 deletions src/Compilers/CSharp/Portable/Binder/PatternExplainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ private static string SampleValueString(IValueSet remainingValues, TypeSymbol ty
// such an out-of-range value.

var underlyingType = type.EnumUnderlyingTypeOrSelf();
Debug.Assert(underlyingType.IsNativeIntegerType);
Debug.Assert(underlyingType.IsNativeIntegerTypeOrNumericIntPtr);
if (underlyingType.SpecialType == SpecialType.System_IntPtr)
{
if (remainingValues.Any(BinaryOperatorKind.GreaterThan, ConstantValue.Create(int.MaxValue)))
Expand All @@ -560,7 +560,7 @@ private static string SampleValueString(IValueSet remainingValues, TypeSymbol ty

private static string ValueString(ConstantValue value, TypeSymbol type, bool requireExactType)
{
bool requiresCast = (type.IsEnumType() || requireExactType || type.IsNativeIntegerType) &&
bool requiresCast = (type.IsEnumType() || requireExactType || type.IsNativeIntegerTypeOrNumericIntPtr) &&
!(typeHasExactTypeLiteral(type) && !value.IsNull);
string valueString = PrimitiveValueString(value, type.EnumUnderlyingTypeOrSelf());
return requiresCast ? $"({type.ToDisplayString()}){valueString}" : valueString;
Expand Down Expand Up @@ -597,8 +597,8 @@ private static string PrimitiveValueString(ConstantValue value, TypeSymbol type)
case SpecialType.System_UInt32:
case SpecialType.System_UInt64:
case SpecialType.System_Int64:
case SpecialType.System_IntPtr when type.IsNativeIntegerType:
case SpecialType.System_UIntPtr when type.IsNativeIntegerType:
case SpecialType.System_IntPtr when type.IsNativeIntegerTypeOrNumericIntPtr:
case SpecialType.System_UIntPtr when type.IsNativeIntegerTypeOrNumericIntPtr:
case SpecialType.System_Decimal:
case SpecialType.System_Char:
case SpecialType.System_String:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1336,10 +1336,10 @@ internal static bool HasImplicitConstantExpressionConversion(BoundExpression sou
return sbyte.MinValue <= value && value <= sbyte.MaxValue;
case SpecialType.System_Int16:
return short.MinValue <= value && value <= short.MaxValue;
case SpecialType.System_IntPtr when destination.IsNativeIntegerType:
case SpecialType.System_IntPtr when destination.IsNativeIntegerTypeOrNumericIntPtr:
return true;
case SpecialType.System_UInt32:
case SpecialType.System_UIntPtr when destination.IsNativeIntegerType:
case SpecialType.System_UIntPtr when destination.IsNativeIntegerTypeOrNumericIntPtr:
return uint.MinValue <= value;
case SpecialType.System_UInt64:
return (int)ulong.MinValue <= value;
Expand Down Expand Up @@ -2001,8 +2001,8 @@ private static bool IsNumericType(TypeSymbol type)
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:
case SpecialType.System_IntPtr when type.IsNativeIntegerTypeOrNumericIntPtr:
case SpecialType.System_UIntPtr when type.IsNativeIntegerTypeOrNumericIntPtr:
return true;
default:
return false;
Expand Down Expand Up @@ -2092,7 +2092,7 @@ private static bool HasSpecialIntPtrConversion(TypeSymbol source, TypeSymbol tar
return false;

static bool isIntPtrOrUIntPtr(TypeSymbol type) =>
(type.SpecialType == SpecialType.System_IntPtr || type.SpecialType == SpecialType.System_UIntPtr) && !type.IsNativeIntegerType;
(type.SpecialType == SpecialType.System_IntPtr || type.SpecialType == SpecialType.System_UIntPtr) && !type.IsNativeIntegerTypeOrNumericIntPtr;
}

private static bool HasExplicitEnumerationConversion(TypeSymbol source, TypeSymbol destination)
Expand Down Expand Up @@ -3733,7 +3733,7 @@ private static bool IsIntegerTypeSupportingPointerConversions(TypeSymbol type)
return true;
case SpecialType.System_IntPtr:
case SpecialType.System_UIntPtr:
return type.IsNativeIntegerType;
return type.IsNativeIntegerTypeOrNumericIntPtr;
}

return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ private void GetAllBuiltInOperators(BinaryOperatorKind kind, bool isChecked, Bou
}
else
{
this.Compilation.builtInOperators.GetSimpleBuiltInOperators(kind, operators, skipNativeIntegerOperators: !left.Type.IsNativeIntegerOrNullableNativeIntegerType() && !right.Type.IsNativeIntegerOrNullableNativeIntegerType());
this.Compilation.builtInOperators.GetSimpleBuiltInOperators(kind, operators, skipNativeIntegerOperators: !left.Type.IsNativeIntegerOrNumericIntPtrOrNullableThereof() && !right.Type.IsNativeIntegerOrNumericIntPtrOrNullableThereof());

// SPEC 7.3.4: For predefined enum and delegate operators, the only operators
// considered are those defined by an enum or delegate type that is the binding
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ public static bool DefinitelyHasNoUserDefinedOperators(TypeSymbol type)
case SpecialType.System_Int16:
case SpecialType.System_Int32:
case SpecialType.System_Int64:
case SpecialType.System_IntPtr when type.IsNativeIntegerType:
case SpecialType.System_UIntPtr when type.IsNativeIntegerType:
case SpecialType.System_IntPtr when type.IsNativeIntegerTypeOrNumericIntPtr:
case SpecialType.System_UIntPtr when type.IsNativeIntegerTypeOrNumericIntPtr:
case SpecialType.System_MulticastDelegate:
case SpecialType.System_Object:
case SpecialType.System_SByte:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ private void GetAllBuiltInOperators(UnaryOperatorKind kind, bool isChecked, Boun
// specification to match the previous implementation.

var operators = ArrayBuilder<UnaryOperatorSignature>.GetInstance();
this.Compilation.builtInOperators.GetSimpleBuiltInOperators(kind, operators, skipNativeIntegerOperators: !operand.Type.IsNativeIntegerOrNullableNativeIntegerType());
this.Compilation.builtInOperators.GetSimpleBuiltInOperators(kind, operators, skipNativeIntegerOperators: !operand.Type.IsNativeIntegerOrNumericIntPtrOrNullableThereof());

GetEnumOperations(kind, operand, operators);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3033,7 +3033,7 @@ private static bool IsSignedIntegralType(TypeSymbol type)
case SpecialType.System_Int16:
case SpecialType.System_Int32:
case SpecialType.System_Int64:
case SpecialType.System_IntPtr:
case SpecialType.System_IntPtr when type.IsNativeIntegerTypeOrNumericIntPtr:
RikkiGibson marked this conversation as resolved.
Show resolved Hide resolved
return true;

default:
Expand All @@ -3054,7 +3054,7 @@ private static bool IsUnsignedIntegralType(TypeSymbol type)
case SpecialType.System_UInt16:
case SpecialType.System_UInt32:
case SpecialType.System_UInt64:
case SpecialType.System_UIntPtr:
case SpecialType.System_UIntPtr when type.IsNativeIntegerTypeOrNumericIntPtr:
return true;

default:
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ private BoundLambda ReallyBind(NamedTypeSymbol delegateType, bool inExpressionTr

if (returnType.HasType)
{
if (returnType.Type.ContainsNativeInteger())
if (compilation.ShouldEmitNativeIntegerAttributes() && returnType.Type.ContainsNativeInteger())
RikkiGibson marked this conversation as resolved.
Show resolved Hide resolved
{
compilation.EnsureNativeIntegerAttributeExists(diagnostics, lambdaSymbol.DiagnosticLocation, modifyCompilation: false);
}
Expand Down
8 changes: 4 additions & 4 deletions src/Compilers/CSharp/Portable/CodeGen/EmitConversion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ private static bool IsNumeric(TypeSymbol type)
return true;
case Cci.PrimitiveTypeCode.IntPtr:
case Cci.PrimitiveTypeCode.UIntPtr:
return type.IsNativeIntegerType;
return type.IsNativeIntegerTypeOrNumericIntPtr;
default:
return false;
}
Expand Down Expand Up @@ -145,16 +145,16 @@ private void EmitConversion(BoundConversion conversion)
#if DEBUG
switch (fromPredefTypeKind)
{
case Microsoft.Cci.PrimitiveTypeCode.IntPtr when !fromType.IsNativeIntegerType:
case Microsoft.Cci.PrimitiveTypeCode.UIntPtr when !fromType.IsNativeIntegerType:
case Microsoft.Cci.PrimitiveTypeCode.IntPtr when !fromType.IsNativeIntegerTypeOrNumericIntPtr:
case Microsoft.Cci.PrimitiveTypeCode.UIntPtr when !fromType.IsNativeIntegerTypeOrNumericIntPtr:
case Microsoft.Cci.PrimitiveTypeCode.Pointer:
case Microsoft.Cci.PrimitiveTypeCode.FunctionPointer:
Debug.Assert(IsNumeric(toType));
break;
default:
Debug.Assert(IsNumeric(fromType));
Debug.Assert(
(toPredefTypeKind == Microsoft.Cci.PrimitiveTypeCode.IntPtr || toPredefTypeKind == Microsoft.Cci.PrimitiveTypeCode.UIntPtr) && !toType.IsNativeIntegerType ||
(toPredefTypeKind == Microsoft.Cci.PrimitiveTypeCode.IntPtr || toPredefTypeKind == Microsoft.Cci.PrimitiveTypeCode.UIntPtr) && !toType.IsNativeIntegerTypeOrNumericIntPtr ||
toPredefTypeKind == Microsoft.Cci.PrimitiveTypeCode.Pointer ||
toPredefTypeKind == Microsoft.Cci.PrimitiveTypeCode.FunctionPointer);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3998,6 +3998,11 @@ internal bool EmitNullablePublicOnly
}
}

internal bool ShouldEmitNativeIntegerAttributes()
{
return !Assembly.RuntimeSupportsNumericIntPtr;
}

internal bool ShouldEmitNullableAttributes(Symbol symbol)
{
RoslynDebug.Assert(symbol is object);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ private void CreateEmbeddedAttributesIfNeeded(BindingDiagnosticBag diagnostics)

if ((needsAttributes & EmbeddableAttributes.NativeIntegerAttribute) != 0)
{
Debug.Assert(Compilation.ShouldEmitNativeIntegerAttributes());
CreateAttributeIfNeeded(
ref _lazyNativeIntegerAttribute,
diagnostics,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1668,6 +1668,7 @@ internal SynthesizedAttributeData SynthesizeNativeIntegerAttribute(Symbol symbol
{
Debug.Assert((object)type != null);
Debug.Assert(type.ContainsNativeInteger());
Debug.Assert(!Compilation.Assembly.RuntimeSupportsNumericIntPtr);
RikkiGibson marked this conversation as resolved.
Show resolved Hide resolved

if ((object)Compilation.SourceModule != symbol.ContainingModule)
{
Expand Down Expand Up @@ -1702,6 +1703,8 @@ internal SynthesizedAttributeData SynthesizeNativeIntegerAttribute(Symbol symbol

internal virtual SynthesizedAttributeData SynthesizeNativeIntegerAttribute(WellKnownMember member, ImmutableArray<TypedConstant> arguments)
{
Debug.Assert(!Compilation.Assembly.RuntimeSupportsNumericIntPtr);
Copy link
Member

@cston cston May 16, 2022

Choose a reason for hiding this comment

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

!Compilation.Assembly.RuntimeSupportsNumericIntPtr

Compilation.ShouldEmitNativeIntegerAttributes()? #Closed


// For modules, this attribute should be present. Only assemblies generate and embed this type.
// https://github.com/dotnet/roslyn/issues/30062 Should not be optional.
return Compilation.TrySynthesizeAttribute(member, arguments, isOptionalUse: true);
Expand Down Expand Up @@ -1776,6 +1779,7 @@ internal void EnsureNullableContextAttributeExists()

internal void EnsureNativeIntegerAttributeExists()
{
Debug.Assert(Compilation.ShouldEmitNativeIntegerAttributes());
EnsureEmbeddableAttributeExists(EmbeddableAttributes.NativeIntegerAttribute);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,15 @@ private void EnsureAttributesExist(TypeCompilationState compilationState)

ParameterHelpers.EnsureIsReadOnlyAttributeExists(moduleBuilder, Parameters);

if (ReturnType.ContainsNativeInteger())
if (moduleBuilder.Compilation.ShouldEmitNativeIntegerAttributes())
{
moduleBuilder.EnsureNativeIntegerAttributeExists();
}
if (ReturnType.ContainsNativeInteger())
{
moduleBuilder.EnsureNativeIntegerAttributeExists();
}

ParameterHelpers.EnsureNativeIntegerAttributeExists(moduleBuilder, Parameters);
ParameterHelpers.EnsureNativeIntegerAttributeExists(moduleBuilder, Parameters);
}

if (compilationState.Compilation.ShouldEmitNullableAttributes(this))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ private void LowerSwitchDispatchNode(ValueDispatchNode.SwitchDispatch node, Boun
var dispatch = new BoundSwitchDispatch(node.Syntax, input, node.Cases, defaultLabel);
_loweredDecisionDag.Add(dispatch);
}
else if (input.Type.IsNativeIntegerType)
else if (input.Type.IsNativeIntegerTypeOrNumericIntPtr)
{
// Native types need to be dispatched using a larger underlying type so that any
// possible high bits are not truncated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,10 +287,13 @@ public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatemen
moduleBuilder.EnsureIsUnmanagedAttributeExists();
}

if (hasReturnTypeOrParameter(localFunction, t => t.ContainsNativeInteger()) ||
typeParameters.Any(t => t.ConstraintTypesNoUseSiteDiagnostics.Any(t => t.ContainsNativeInteger())))
if (_compilation.ShouldEmitNativeIntegerAttributes())
{
moduleBuilder.EnsureNativeIntegerAttributeExists();
if (hasReturnTypeOrParameter(localFunction, t => t.ContainsNativeInteger()) ||
typeParameters.Any(t => t.ConstraintTypesNoUseSiteDiagnostics.Any(t => t.ContainsNativeInteger())))
{
moduleBuilder.EnsureNativeIntegerAttributeExists();
}
}

if (_factory.CompilationState.Compilation.ShouldEmitNullableAttributes(localFunction))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ private BoundExpression MakeConversionNodeCore(
rewrittenType: rewrittenType);

case ConversionKind.IntPtr:
return RewriteIntPtrConversion(oldNodeOpt, syntax, rewrittenOperand, conversion, @checked,
return RewriteIntPtrConversion(syntax, rewrittenOperand, conversion, @checked,
explicitCastInCode, constantValueOpt, rewrittenType);

case ConversionKind.ImplicitNullable:
Expand Down Expand Up @@ -1288,7 +1288,6 @@ private BoundExpression RewriteLiftedUserDefinedConversion(
}

private BoundExpression RewriteIntPtrConversion(
BoundConversion? oldNode,
SyntaxNode syntax,
BoundExpression rewrittenOperand,
Conversion conversion,
Expand All @@ -1300,6 +1299,7 @@ private BoundExpression RewriteIntPtrConversion(
Debug.Assert(rewrittenOperand != null);
Debug.Assert((object)rewrittenType != null);
Debug.Assert(rewrittenOperand.Type is { });
Debug.Assert(!_compilation.Assembly.RuntimeSupportsNumericIntPtr);
RikkiGibson marked this conversation as resolved.
Show resolved Hide resolved

TypeSymbol source = rewrittenOperand.Type;
TypeSymbol target = rewrittenType;
Expand Down Expand Up @@ -1602,6 +1602,7 @@ private Conversion TryMakeConversion(SyntaxNode syntax, Conversion conversion, T
}
case ConversionKind.IntPtr:
{
Debug.Assert(!_compilation.Assembly.RuntimeSupportsNumericIntPtr);
SpecialMember member = GetIntPtrConversionMethod(fromType, toType);
MethodSymbol method;
if (!TryGetSpecialTypeMethod(syntax, member, out method))
Expand Down
Loading