From c3fa0ba0bb6e4d3f3a85b504e340c97fbc0f35c2 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Wed, 13 Apr 2022 16:33:39 -0700 Subject: [PATCH] Unify nint/IntPtr --- .../Portable/Binder/Binder_Expressions.cs | 2 +- .../Portable/Binder/Binder_Operators.cs | 8 +- .../CSharp/Portable/Binder/Binder_Patterns.cs | 4 +- .../CSharp/Portable/Binder/Binder_Symbols.cs | 3 +- .../Portable/Binder/PatternExplainer.cs | 8 +- .../Semantics/Conversions/ConversionsBase.cs | 12 +- .../BinaryOperatorOverloadResolution.cs | 2 +- .../Semantics/Operators/OperatorFacts.cs | 4 +- .../UnaryOperatorOverloadResolution.cs | 2 +- .../OverloadResolution/OverloadResolution.cs | 4 +- .../Portable/BoundTree/UnboundLambda.cs | 2 +- .../CSharp/Portable/CodeGen/EmitConversion.cs | 8 +- .../Portable/Compilation/CSharpCompilation.cs | 5 + .../Emitter/Model/PEAssemblyBuilder.cs | 1 + .../Portable/Emitter/Model/PEModuleBuilder.cs | 4 + .../SynthesizedClosureMethod.cs | 11 +- .../LocalRewriter.DecisionDagRewriter.cs | 2 +- .../Lowering/LocalRewriter/LocalRewriter.cs | 9 +- .../LocalRewriter/LocalRewriter_Conversion.cs | 5 +- .../CSharp/Portable/Symbols/AssemblySymbol.cs | 13 +- .../Symbols/Compilation_WellKnownMembers.cs | 5 +- .../Metadata/PE/NativeIntegerTypeDecoder.cs | 7 +- .../Symbols/Metadata/PE/PEFieldSymbol.cs | 6 +- .../Symbols/Metadata/PE/PENamedTypeSymbol.cs | 4 + .../Symbols/MetadataOrSourceAssemblySymbol.cs | 34 + .../CSharp/Portable/Symbols/MethodSymbol.cs | 2 +- .../Symbols/MissingCorLibrarySymbol.cs | 15 + .../Symbols/MissingMetadataTypeSymbol.cs | 2 +- .../Portable/Symbols/NamedTypeSymbol.cs | 1 + .../Symbols/NativeIntegerTypeSymbol.cs | 9 +- .../Symbols/PublicModel/TypeSymbol.cs | 2 +- .../RetargetingSymbolTranslator.cs | 2 +- .../Symbols/Source/CustomModifierUtils.cs | 9 +- .../FieldSymbolWithAttributesAndModifiers.cs | 2 +- .../Symbols/Source/LocalFunctionSymbol.cs | 3 +- .../Symbols/Source/ParameterHelpers.cs | 7 + .../Source/SourceDelegateMethodSymbol.cs | 2 +- .../Symbols/Source/SourceEventSymbol.cs | 4 +- .../Symbols/Source/SourceFieldSymbol.cs | 2 +- .../Source/SourceMemberContainerSymbol.cs | 11 +- .../Symbols/Source/SourceNamedTypeSymbol.cs | 4 + ...dinaryMethodOrUserDefinedOperatorSymbol.cs | 2 +- .../Source/SourceParameterSymbolBase.cs | 2 +- .../Source/SourcePropertySymbolBase.cs | 4 +- .../Source/SourceTypeParameterSymbol.cs | 5 +- .../Synthesized/SynthesizedFieldSymbolBase.cs | 2 +- .../Synthesized/SynthesizedParameterSymbol.cs | 2 +- .../CSharp/Portable/Symbols/TypeSymbol.cs | 9 +- .../Portable/Symbols/TypeSymbolExtensions.cs | 27 +- .../Portable/Utilities/ValueSetFactory.cs | 2 +- .../Test/Emit2/Emit/NumericIntPtrTests.cs | 20185 +++++++--------- .../Semantic/Semantics/NativeIntegerTests.cs | 185 +- .../Symbol/Symbols/MissingSpecialMember.cs | 1 + src/Compilers/Core/Portable/SpecialMember.cs | 1 + src/Compilers/Core/Portable/SpecialMembers.cs | 11 +- .../CSharp/NativeIntegerAttributesVisitor.cs | 16 - .../Portable/Symbols/TypeSymbol.vb | 2 +- .../WellKnownTypeValidationTests.vb | 1 + .../Symbols/CodeGenerationTypeSymbol.cs | 2 + 59 files changed, 8711 insertions(+), 11990 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs index aa382d6a986bd..ec2fea6664d78 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs @@ -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)); diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs index f80d90a270873..253b2c8bb7309 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs @@ -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; } @@ -1422,6 +1422,12 @@ private UnaryOperatorAnalysisResult UnaryOperatorOverloadResolution( result.Free(); return possiblyBest; + + bool isNuint(TypeSymbol type) + { + return type.SpecialType == SpecialType.System_UIntPtr + && type.IsNativeIntegerTypeOrNumericIntPtr; + } } private static object FoldDecimalBinaryOperators(BinaryOperatorKind kind, ConstantValue valueLeft, ConstantValue valueRight) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Patterns.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Patterns.cs index e4dc68b4cff54..488e7a16755f0 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Patterns.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Patterns.cs @@ -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, }; diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs index caded00d3be20..075fd0d160200 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs @@ -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(); } private void ReportUseSiteDiagnosticForDynamic(BindingDiagnosticBag diagnostics, IdentifierNameSyntax node) diff --git a/src/Compilers/CSharp/Portable/Binder/PatternExplainer.cs b/src/Compilers/CSharp/Portable/Binder/PatternExplainer.cs index 784e159641413..f0ff0abc679de 100644 --- a/src/Compilers/CSharp/Portable/Binder/PatternExplainer.cs +++ b/src/Compilers/CSharp/Portable/Binder/PatternExplainer.cs @@ -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))) @@ -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; @@ -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: diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs index ef875b1288dce..ed1aae7728d9f 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs @@ -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; @@ -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; @@ -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) @@ -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; diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/BinaryOperatorOverloadResolution.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/BinaryOperatorOverloadResolution.cs index 69f7139b05861..0c26ac639ebe2 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/BinaryOperatorOverloadResolution.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/BinaryOperatorOverloadResolution.cs @@ -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 diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/OperatorFacts.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/OperatorFacts.cs index fc19e1bd231a0..ed5176f552d4a 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/OperatorFacts.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/OperatorFacts.cs @@ -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: diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/UnaryOperatorOverloadResolution.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/UnaryOperatorOverloadResolution.cs index 66fed744aeef9..d0d6e5629aff8 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/UnaryOperatorOverloadResolution.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/UnaryOperatorOverloadResolution.cs @@ -252,7 +252,7 @@ private void GetAllBuiltInOperators(UnaryOperatorKind kind, bool isChecked, Boun // specification to match the previous implementation. var operators = ArrayBuilder.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); diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs index be0401ed762a0..518b3e6b9b0b2 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs @@ -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: return true; default: @@ -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: diff --git a/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs b/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs index 95c475d828b6b..59c9154523697 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs +++ b/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs @@ -720,7 +720,7 @@ private BoundLambda ReallyBind(NamedTypeSymbol delegateType, bool inExpressionTr if (returnType.HasType) { - if (returnType.Type.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && returnType.Type.ContainsNativeInteger()) { compilation.EnsureNativeIntegerAttributeExists(diagnostics, lambdaSymbol.DiagnosticLocation, modifyCompilation: false); } diff --git a/src/Compilers/CSharp/Portable/CodeGen/EmitConversion.cs b/src/Compilers/CSharp/Portable/CodeGen/EmitConversion.cs index 61309792dc959..9a49b02bdb1da 100644 --- a/src/Compilers/CSharp/Portable/CodeGen/EmitConversion.cs +++ b/src/Compilers/CSharp/Portable/CodeGen/EmitConversion.cs @@ -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; } @@ -145,8 +145,8 @@ 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)); @@ -154,7 +154,7 @@ private void EmitConversion(BoundConversion conversion) 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; diff --git a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs index 6b032756ae39e..aeee6631f1ac5 100644 --- a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs +++ b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs @@ -3998,6 +3998,11 @@ internal bool EmitNullablePublicOnly } } + internal bool ShouldEmitNativeIntegerAttributes() + { + return !Assembly.RuntimeSupportsNumericIntPtr; + } + internal bool ShouldEmitNullableAttributes(Symbol symbol) { RoslynDebug.Assert(symbol is object); diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs b/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs index 5582a723df03e..32afb1dc5682b 100644 --- a/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs +++ b/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs @@ -366,6 +366,7 @@ private void CreateEmbeddedAttributesIfNeeded(BindingDiagnosticBag diagnostics) if ((needsAttributes & EmbeddableAttributes.NativeIntegerAttribute) != 0) { + Debug.Assert(Compilation.ShouldEmitNativeIntegerAttributes()); CreateAttributeIfNeeded( ref _lazyNativeIntegerAttribute, diagnostics, diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs b/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs index 66ce3b0db4ed7..465bb71bb8a1c 100644 --- a/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs +++ b/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs @@ -1668,6 +1668,7 @@ internal SynthesizedAttributeData SynthesizeNativeIntegerAttribute(Symbol symbol { Debug.Assert((object)type != null); Debug.Assert(type.ContainsNativeInteger()); + Debug.Assert(!Compilation.Assembly.RuntimeSupportsNumericIntPtr); if ((object)Compilation.SourceModule != symbol.ContainingModule) { @@ -1702,6 +1703,8 @@ internal SynthesizedAttributeData SynthesizeNativeIntegerAttribute(Symbol symbol internal virtual SynthesizedAttributeData SynthesizeNativeIntegerAttribute(WellKnownMember member, ImmutableArray arguments) { + Debug.Assert(!Compilation.Assembly.RuntimeSupportsNumericIntPtr); + // 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); @@ -1776,6 +1779,7 @@ internal void EnsureNullableContextAttributeExists() internal void EnsureNativeIntegerAttributeExists() { + Debug.Assert(Compilation.ShouldEmitNativeIntegerAttributes()); EnsureEmbeddableAttributeExists(EmbeddableAttributes.NativeIntegerAttribute); } diff --git a/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/SynthesizedClosureMethod.cs b/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/SynthesizedClosureMethod.cs index 2a6d9f2624fd8..65eed71918327 100644 --- a/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/SynthesizedClosureMethod.cs +++ b/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/SynthesizedClosureMethod.cs @@ -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)) { diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.DecisionDagRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.DecisionDagRewriter.cs index 7886efd5e553f..501e81e6e035f 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.DecisionDagRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.DecisionDagRewriter.cs @@ -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. diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs index f4e50554a1d85..cb54d78e71659 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs @@ -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)) diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Conversion.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Conversion.cs index 99129386d182b..14fe754ffda2a 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Conversion.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Conversion.cs @@ -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: @@ -1288,7 +1288,6 @@ private BoundExpression RewriteLiftedUserDefinedConversion( } private BoundExpression RewriteIntPtrConversion( - BoundConversion? oldNode, SyntaxNode syntax, BoundExpression rewrittenOperand, Conversion conversion, @@ -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); TypeSymbol source = rewrittenOperand.Type; TypeSymbol target = rewrittenType; @@ -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)) diff --git a/src/Compilers/CSharp/Portable/Symbols/AssemblySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/AssemblySymbol.cs index b4e073eb84f30..06984c5f2d465 100644 --- a/src/Compilers/CSharp/Portable/Symbols/AssemblySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/AssemblySymbol.cs @@ -440,7 +440,18 @@ internal bool RuntimeSupportsStaticAbstractMembersInInterfaces get => RuntimeSupportsFeature(SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__VirtualStaticsInInterfaces); } - private bool RuntimeSupportsFeature(SpecialMember feature) + /// + /// Whether the target runtime supports numeric IntPtr types. + /// This test hook should be removed once TargetFramework.Net70 is added. + /// Tracked by https://github.com/dotnet/roslyn/issues/61235 + /// + internal virtual bool RuntimeSupportsNumericIntPtr + { + get => CorLibrary.RuntimeSupportsNumericIntPtr; + set => CorLibrary.RuntimeSupportsNumericIntPtr = value; + } + + protected bool RuntimeSupportsFeature(SpecialMember feature) { Debug.Assert((SpecialType)SpecialMembers.GetDescriptor(feature).DeclaringTypeId == SpecialType.System_Runtime_CompilerServices_RuntimeFeature); return GetSpecialType(SpecialType.System_Runtime_CompilerServices_RuntimeFeature) is { TypeKind: TypeKind.Class, IsStatic: true } && diff --git a/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs b/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs index 60b373fcc97f6..faf2a70d28402 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs @@ -540,6 +540,7 @@ internal void EnsureNullableContextAttributeExists(BindingDiagnosticBag? diagnos internal void EnsureNativeIntegerAttributeExists(BindingDiagnosticBag? diagnostics, Location location, bool modifyCompilation) { + Debug.Assert(ShouldEmitNativeIntegerAttributes()); EnsureEmbeddableAttributeExists(EmbeddableAttributes.NativeIntegerAttribute, diagnostics, location, modifyCompilation); } @@ -593,6 +594,7 @@ internal bool CheckIfAttributeShouldBeEmbedded(EmbeddableAttributes attribute, B case EmbeddableAttributes.NativeIntegerAttribute: // If the type exists, we'll check both constructors, regardless of which one(s) we'll eventually need. + Debug.Assert(ShouldEmitNativeIntegerAttributes()); return CheckIfAttributeShouldBeEmbedded( diagnosticsOpt, locationOpt, @@ -983,6 +985,7 @@ internal static class NativeIntegerTransformsEncoder { internal static void Encode(ArrayBuilder builder, TypeSymbol type) { + Debug.Assert(type.ContainingAssembly?.RuntimeSupportsNumericIntPtr != true); type.VisitType((typeSymbol, builder, isNested) => AddFlags(typeSymbol, builder), builder); } @@ -992,7 +995,7 @@ private static bool AddFlags(TypeSymbol type, ArrayBuilder builder) { case SpecialType.System_IntPtr: case SpecialType.System_UIntPtr: - builder.Add(type.IsNativeIntegerType); + builder.Add(type.IsNativeIntegerWrapperType); break; } // Continue walking types diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/NativeIntegerTypeDecoder.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/NativeIntegerTypeDecoder.cs index fb101b1abecec..f57ba01d0a875 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/NativeIntegerTypeDecoder.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/NativeIntegerTypeDecoder.cs @@ -15,6 +15,11 @@ internal struct NativeIntegerTypeDecoder { internal static TypeSymbol TransformType(TypeSymbol type, EntityHandle handle, PEModuleSymbol containingModule) { + if (type.ContainingAssembly?.RuntimeSupportsNumericIntPtr == true) + { + return type; + } + return containingModule.Module.HasNativeIntegerAttribute(handle, out var transformFlags) ? TransformType(type, transformFlags) : type; @@ -111,7 +116,7 @@ private NativeIntegerTypeDecoder(ImmutableArray transformFlags) { throw new UnsupportedSignatureContent(); } - return (_transformFlags[_index++], type.IsNativeIntegerType) switch + return (_transformFlags[_index++], type.IsNativeIntegerWrapperType) switch { (false, true) => type.NativeIntegerUnderlyingType, (true, false) => type.AsNativeInteger(), diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs index 6895447a75757..0407ec1748435 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs @@ -266,7 +266,11 @@ private void EnsureSignatureIsLoaded() ImmutableArray customModifiersArray = CSharpCustomModifier.Convert(customModifiers); typeSymbol = DynamicTypeDecoder.TransformType(typeSymbol, customModifiersArray.Length, _handle, moduleSymbol); - typeSymbol = NativeIntegerTypeDecoder.TransformType(typeSymbol, _handle, moduleSymbol); + if (_containingType.SpecialType != SpecialType.System_Runtime_CompilerServices_RuntimeFeature) + { + // We need to break the cycle when loading fields of System.Runtime.CompilerServices.RuntimeFeature + typeSymbol = NativeIntegerTypeDecoder.TransformType(typeSymbol, _handle, moduleSymbol); + } // We start without annotations var type = TypeWithAnnotations.Create(typeSymbol, customModifiers: customModifiersArray); diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.cs index 60253710aec77..ad71f88091e7c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.cs @@ -2376,6 +2376,10 @@ internal override int MetadataArity internal override NamedTypeSymbol AsNativeInteger() { Debug.Assert(this.SpecialType == SpecialType.System_IntPtr || this.SpecialType == SpecialType.System_UIntPtr); + if (ContainingAssembly.RuntimeSupportsNumericIntPtr) + { + return this; + } return ContainingAssembly.GetNativeIntegerType(this); } diff --git a/src/Compilers/CSharp/Portable/Symbols/MetadataOrSourceAssemblySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/MetadataOrSourceAssemblySymbol.cs index f7d066be29097..54c1a99268058 100644 --- a/src/Compilers/CSharp/Portable/Symbols/MetadataOrSourceAssemblySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/MetadataOrSourceAssemblySymbol.cs @@ -32,6 +32,38 @@ internal abstract class MetadataOrSourceAssemblySymbol private int _cachedSpecialTypes; private NativeIntegerTypeSymbol[] _lazyNativeIntegerTypes; + private ThreeState _lazyRuntimeSupportsNumericIntPtr = ThreeState.Unknown; + + internal override bool RuntimeSupportsNumericIntPtr + { + get + { + if ((object)CorLibrary == this) + { + if (!_lazyRuntimeSupportsNumericIntPtr.HasValue()) + { + _lazyRuntimeSupportsNumericIntPtr = RuntimeSupportsFeature(SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__NumericIntPtr).ToThreeState(); + } + + return _lazyRuntimeSupportsNumericIntPtr.Value(); + } + + return base.RuntimeSupportsNumericIntPtr; + } + set + { + Debug.Assert(value); + Debug.Assert(!RuntimeSupportsFeature(SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__NumericIntPtr)); + if ((object)CorLibrary == this) + { + Debug.Assert(!_lazyRuntimeSupportsNumericIntPtr.HasValue()); + _lazyRuntimeSupportsNumericIntPtr = value.ToThreeState(); + return; + } + + base.RuntimeSupportsNumericIntPtr = value; + } + } /// /// Lookup declaration for predefined CorLib type in this Assembly. @@ -123,6 +155,8 @@ public override ICollection TypeNames internal sealed override NamedTypeSymbol GetNativeIntegerType(NamedTypeSymbol underlyingType) { + Debug.Assert(!underlyingType.IsNativeIntegerTypeOrNumericIntPtr); + if (_lazyNativeIntegerTypes == null) { Interlocked.CompareExchange(ref _lazyNativeIntegerTypes, new NativeIntegerTypeSymbol[2], null); diff --git a/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs index 85030a8a2eddf..c16001da22833 100644 --- a/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs @@ -1149,7 +1149,7 @@ internal virtual void AddSynthesizedReturnTypeAttributes(PEModuleBuilder moduleB AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(type.Type, type.CustomModifiers.Length + this.RefCustomModifiers.Length, this.RefKind)); } - if (type.Type.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && type.Type.ContainsNativeInteger()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNativeIntegerAttribute(this, type.Type)); } diff --git a/src/Compilers/CSharp/Portable/Symbols/MissingCorLibrarySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/MissingCorLibrarySymbol.cs index d0216601874b7..44e55d3dda2fd 100644 --- a/src/Compilers/CSharp/Portable/Symbols/MissingCorLibrarySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/MissingCorLibrarySymbol.cs @@ -64,5 +64,20 @@ internal override NamedTypeSymbol GetDeclaredSpecialType(SpecialType type) return _lazySpecialTypes[(int)type]; } + + internal override bool RuntimeSupportsNumericIntPtr + { + get + { + // For now we assume that it is not supported by default + Debug.Assert((object)CorLibrary == this); + return false; + } + set + { + Debug.Assert((object)CorLibrary == this); + throw ExceptionUtilities.Unreachable; + } + } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/MissingMetadataTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/MissingMetadataTypeSymbol.cs index 28776f5395e56..2dfb36efb2f81 100644 --- a/src/Compilers/CSharp/Portable/Symbols/MissingMetadataTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/MissingMetadataTypeSymbol.cs @@ -355,7 +355,7 @@ private TopLevel AsNativeInteger(bool asNativeInt) return other; } - internal sealed override bool IsNativeIntegerType => _isNativeInt; + internal sealed override bool IsNativeIntegerWrapperType => _isNativeInt; internal sealed override NamedTypeSymbol? NativeIntegerUnderlyingType => _isNativeInt ? AsNativeInteger(asNativeInt: false) : null; diff --git a/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs index f3b25e788f511..d5b7e34f12285 100644 --- a/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs @@ -1532,6 +1532,7 @@ internal bool IsTupleTypeOfCardinality(out int tupleCardinality) /// /// Returns an instance of a symbol that represents a native integer /// if this underlying symbol represents System.IntPtr or System.UIntPtr. + /// For platforms that support numeric IntPtr/UIntPtr, those types are returned as-is. /// For other symbols, throws . /// internal abstract NamedTypeSymbol AsNativeInteger(); diff --git a/src/Compilers/CSharp/Portable/Symbols/NativeIntegerTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/NativeIntegerTypeSymbol.cs index b42ac4326e3a6..9f47fec13a1d0 100644 --- a/src/Compilers/CSharp/Portable/Symbols/NativeIntegerTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/NativeIntegerTypeSymbol.cs @@ -25,8 +25,9 @@ internal sealed class NativeIntegerTypeSymbol : WrappedNamedTypeSymbol internal NativeIntegerTypeSymbol(NamedTypeSymbol underlyingType) : base(underlyingType, tupleData: null) { Debug.Assert(underlyingType.TupleData is null); - Debug.Assert(!underlyingType.IsNativeIntegerType); + Debug.Assert(!underlyingType.IsNativeIntegerTypeOrNumericIntPtr); Debug.Assert(underlyingType.SpecialType == SpecialType.System_IntPtr || underlyingType.SpecialType == SpecialType.System_UIntPtr); + Debug.Assert(!underlyingType.ContainingAssembly.RuntimeSupportsNumericIntPtr); VerifyEquality(this, underlyingType); } @@ -163,7 +164,7 @@ internal override UseSiteInfo GetUseSiteInfo() public override bool AreLocalsZeroed => throw ExceptionUtilities.Unreachable; - internal override bool IsNativeIntegerType => true; + internal override bool IsNativeIntegerWrapperType => true; internal sealed override NamedTypeSymbol AsNativeInteger() => throw ExceptionUtilities.Unreachable; @@ -187,8 +188,10 @@ internal override bool Equals(TypeSymbol? other, TypeCompareKind comparison) { return false; } + + Debug.Assert(!ContainingAssembly.RuntimeSupportsNumericIntPtr); return (comparison & TypeCompareKind.IgnoreNativeIntegers) != 0 || - other.IsNativeIntegerType; + other.IsNativeIntegerWrapperType; } public override int GetHashCode() => _underlyingType.GetHashCode(); diff --git a/src/Compilers/CSharp/Portable/Symbols/PublicModel/TypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/PublicModel/TypeSymbol.cs index 476a5444dc0df..1438f3710bcc5 100644 --- a/src/Compilers/CSharp/Portable/Symbols/PublicModel/TypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/PublicModel/TypeSymbol.cs @@ -142,7 +142,7 @@ TypeKind ITypeSymbol.TypeKind bool ITypeSymbol.IsTupleType => UnderlyingTypeSymbol.IsTupleType; - bool ITypeSymbol.IsNativeIntegerType => UnderlyingTypeSymbol.IsNativeIntegerType; + bool ITypeSymbol.IsNativeIntegerType => UnderlyingTypeSymbol.IsNativeIntegerTypeOrNumericIntPtr; string ITypeSymbol.ToDisplayString(CodeAnalysis.NullableFlowState topLevelNullability, SymbolDisplayFormat format) { diff --git a/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingSymbolTranslator.cs b/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingSymbolTranslator.cs index be8ece2a7ba76..abbf2c63870c8 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingSymbolTranslator.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingSymbolTranslator.cs @@ -206,7 +206,7 @@ private NamedTypeSymbol RetargetNamedTypeDefinition(NamedTypeSymbol type, Retarg { Debug.Assert(type.IsDefinition); - if (type.IsNativeIntegerType) + if (type.IsNativeIntegerWrapperType) { var result = RetargetNamedTypeDefinition(type.NativeIntegerUnderlyingType, options); return result.SpecialType == SpecialType.None ? result : result.AsNativeInteger(); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/CustomModifierUtils.cs b/src/Compilers/CSharp/Portable/Symbols/Source/CustomModifierUtils.cs index c22d081db63ad..52ff67280d250 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/CustomModifierUtils.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/CustomModifierUtils.cs @@ -78,9 +78,12 @@ internal static TypeSymbol CopyTypeCustomModifiers(TypeSymbol sourceType, TypeSy ImmutableArray flags = CSharpCompilation.DynamicTransformsEncoder.EncodeWithoutCustomModifierFlags(destinationType, refKind); TypeSymbol resultType = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(sourceType, containingAssembly, refKind, flags); - var builder = ArrayBuilder.GetInstance(); - CSharpCompilation.NativeIntegerTransformsEncoder.Encode(builder, destinationType); - resultType = NativeIntegerTypeDecoder.TransformType(resultType, builder.ToImmutableAndFree()); + if (!containingAssembly.RuntimeSupportsNumericIntPtr) + { + var builder = ArrayBuilder.GetInstance(); + CSharpCompilation.NativeIntegerTransformsEncoder.Encode(builder, destinationType); + resultType = NativeIntegerTypeDecoder.TransformType(resultType, builder.ToImmutableAndFree()); + } if (destinationType.ContainsTuple() && !sourceType.Equals(destinationType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds | TypeCompareKind.IgnoreNullableModifiersForReferenceTypes | TypeCompareKind.IgnoreDynamic)) { diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/FieldSymbolWithAttributesAndModifiers.cs b/src/Compilers/CSharp/Portable/Symbols/Source/FieldSymbolWithAttributesAndModifiers.cs index a38f6add3dfed..23a11be72118f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/FieldSymbolWithAttributesAndModifiers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/FieldSymbolWithAttributesAndModifiers.cs @@ -391,7 +391,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r compilation.SynthesizeDynamicAttribute(type.Type, type.CustomModifiers.Length)); } - if (type.Type.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && type.Type.ContainsNativeInteger()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNativeIntegerAttribute(this, type.Type)); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs index f48963065a891..e1ab27601905e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs @@ -256,7 +256,8 @@ internal void ComputeReturnType() compilation.EnsureIsReadOnlyAttributeExists(diagnostics, location, modifyCompilation: false); } - if (returnType.Type.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && + returnType.Type.ContainsNativeInteger()) { compilation.EnsureNativeIntegerAttributeExists(diagnostics, location, modifyCompilation: false); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs index bd1e596f750ee..3694b3d9bca59 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs @@ -271,6 +271,7 @@ private static void EnsureIsReadOnlyAttributeExists(CSharpCompilation compilatio internal static void EnsureNativeIntegerAttributeExists(PEModuleBuilder moduleBuilder, ImmutableArray parameters) { + Debug.Assert(moduleBuilder.Compilation.ShouldEmitNativeIntegerAttributes()); EnsureNativeIntegerAttributeExists(moduleBuilder.Compilation, parameters, diagnostics: null, modifyCompilation: false, moduleBuilder); } @@ -283,11 +284,17 @@ internal static void EnsureNativeIntegerAttributeExists(CSharpCompilation? compi return; } + if (!compilation.ShouldEmitNativeIntegerAttributes()) + { + return; + } + EnsureNativeIntegerAttributeExists(compilation, parameters, diagnostics, modifyCompilation, moduleBuilder: null); } private static void EnsureNativeIntegerAttributeExists(CSharpCompilation compilation, ImmutableArray parameters, BindingDiagnosticBag? diagnostics, bool modifyCompilation, PEModuleBuilder? moduleBuilder) { + Debug.Assert(compilation.ShouldEmitNativeIntegerAttributes()); foreach (var parameter in parameters) { if (parameter.TypeWithAnnotations.ContainsNativeInteger()) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs index 242ee106c736b..232a39b4dd8c3 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs @@ -329,7 +329,7 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, ParameterHelpers.EnsureIsReadOnlyAttributeExists(compilation, Parameters, diagnostics, modifyCompilation: true); - if (ReturnType.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && ReturnType.ContainsNativeInteger()) { compilation.EnsureNativeIntegerAttributeExists(diagnostics, location, modifyCompilation: true); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs index 1af5b62fe17ab..cd7f2570b7b04 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs @@ -321,7 +321,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(type.Type, type.CustomModifiers.Length)); } - if (type.Type.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && type.Type.ContainsNativeInteger()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNativeIntegerAttribute(this, type.Type)); } @@ -750,7 +750,7 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, this.CheckModifiersAndType(diagnostics); this.Type.CheckAllConstraints(compilation, conversions, location, diagnostics); - if (Type.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && Type.ContainsNativeInteger()) { compilation.EnsureNativeIntegerAttributeExists(diagnostics, location, modifyCompilation: true); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs index 08ab93bd28469..efaff24e72f89 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs @@ -135,7 +135,7 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, var compilation = DeclaringCompilation; var location = ErrorLocation; - if (Type.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && Type.ContainsNativeInteger()) { compilation.EnsureNativeIntegerAttributeExists(diagnostics, location, modifyCompilation: true); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index cd25021d1d4d5..ef94a760c80d7 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -1624,10 +1624,13 @@ protected void AfterMembersChecks(BindingDiagnosticBag diagnostics) var baseType = BaseTypeNoUseSiteDiagnostics; var interfaces = GetInterfacesToEmit(); - // https://github.com/dotnet/roslyn/issues/30080: Report diagnostics for base type and interfaces at more specific locations. - if (hasBaseTypeOrInterface(t => t.ContainsNativeInteger())) + if (compilation.ShouldEmitNativeIntegerAttributes()) { - compilation.EnsureNativeIntegerAttributeExists(diagnostics, location, modifyCompilation: true); + // https://github.com/dotnet/roslyn/issues/30080: Report diagnostics for base type and interfaces at more specific locations. + if (hasBaseTypeOrInterface(t => t.ContainsNativeInteger())) + { + compilation.EnsureNativeIntegerAttributeExists(diagnostics, location, modifyCompilation: true); + } } if (compilation.ShouldEmitNullableAttributes(this)) @@ -4723,7 +4726,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(baseType, customModifiersCount: 0)); } - if (baseType.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && baseType.ContainsNativeInteger()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNativeIntegerAttribute(this, baseType)); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs index e3f3627d39cc0..530209c782d40 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs @@ -1590,6 +1590,10 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r internal override NamedTypeSymbol AsNativeInteger() { Debug.Assert(this.SpecialType == SpecialType.System_IntPtr || this.SpecialType == SpecialType.System_UIntPtr); + if (ContainingAssembly.RuntimeSupportsNumericIntPtr) + { + return this; + } return ContainingAssembly.GetNativeIntegerType(this); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodOrUserDefinedOperatorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodOrUserDefinedOperatorSymbol.cs index 1d3ba796909c0..e7ce03b55a1c7 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodOrUserDefinedOperatorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodOrUserDefinedOperatorSymbol.cs @@ -253,7 +253,7 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, ParameterHelpers.EnsureIsReadOnlyAttributeExists(compilation, Parameters, diagnostics, modifyCompilation: true); - if (ReturnType.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && ReturnType.ContainsNativeInteger()) { compilation.EnsureNativeIntegerAttributeExists(diagnostics, location, modifyCompilation: true); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs index bb9838963df88..4fb9e559911f9 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs @@ -94,7 +94,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(type.Type, type.CustomModifiers.Length + this.RefCustomModifiers.Length, this.RefKind)); } - if (type.Type.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && type.Type.ContainsNativeInteger()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNativeIntegerAttribute(this, type.Type)); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs index 37f3654bc2ca2..be56c9ade397b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs @@ -819,7 +819,7 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, ParameterHelpers.EnsureIsReadOnlyAttributeExists(compilation, Parameters, diagnostics, modifyCompilation: true); - if (Type.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && Type.ContainsNativeInteger()) { compilation.EnsureNativeIntegerAttributeExists(diagnostics, location, modifyCompilation: true); } @@ -1134,7 +1134,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r compilation.SynthesizeDynamicAttribute(type.Type, type.CustomModifiers.Length + RefCustomModifiers.Length, _refKind)); } - if (type.Type.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && type.Type.ContainsNativeInteger()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNativeIntegerAttribute(this, type.Type)); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs index 7ae3bfd1e8c50..850e98bad5bcc 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs @@ -298,14 +298,17 @@ private bool ModifyCompilationForAttributeEmbedding() private void EnsureAttributesFromConstraints(BindingDiagnosticBag diagnostics) { - if (ConstraintTypesNoUseSiteDiagnostics.Any(t => t.ContainsNativeInteger())) + if (DeclaringCompilation.ShouldEmitNativeIntegerAttributes() + && ConstraintTypesNoUseSiteDiagnostics.Any(t => t.ContainsNativeInteger())) { DeclaringCompilation.EnsureNativeIntegerAttributeExists(diagnostics, getLocation(), ModifyCompilationForAttributeEmbedding()); } + if (ConstraintsNeedNullableAttribute()) { DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, getLocation(), ModifyCompilationForAttributeEmbedding()); } + Location getLocation() => this.GetNonNullSyntaxNode().Location; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs index 73a6dacbcf7ce..8cecc1ae5d789 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs @@ -65,7 +65,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(type, typeWithAnnotations.CustomModifiers.Length)); } - if (type.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && type.ContainsNativeInteger()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNativeIntegerAttribute(this, type)); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs index 883dc136b4cfc..0feaa3219b924 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs @@ -156,7 +156,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(type.Type, type.CustomModifiers.Length + this.RefCustomModifiers.Length, this.RefKind)); } - if (type.Type.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && type.Type.ContainsNativeInteger()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNativeIntegerAttribute(this, type.Type)); } diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs index 96d2962bd7362..8501b3424ca90 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs @@ -559,9 +559,14 @@ public virtual bool IsAnonymousType /// /// True if the type represents a native integer. In C#, the types represented - /// by language keywords 'nint' and 'nuint'. + /// by language keywords 'nint' and 'nuint' on platforms where they were not unified + /// with 'System.IntPtr' and 'System.UIntPtr'. /// - internal virtual bool IsNativeIntegerType => false; + internal virtual bool IsNativeIntegerWrapperType => false; + + // TODO2 will be renamed IsNativeInteger before merging this PR + internal bool IsNativeIntegerTypeOrNumericIntPtr => IsNativeIntegerWrapperType + || (SpecialType is SpecialType.System_IntPtr or SpecialType.System_UIntPtr && this.ContainingAssembly.RuntimeSupportsNumericIntPtr); /// /// Verify if the given type is a tuple of a given cardinality, or can be used to back a tuple type diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs index ccfe057817121..700dc19f7163f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs @@ -41,7 +41,7 @@ public static bool CanBeConst(this TypeSymbol typeSymbol) { RoslynDebug.Assert((object)typeSymbol != null); - return typeSymbol.IsReferenceType || typeSymbol.IsEnumType() || typeSymbol.SpecialType.CanBeConst() || typeSymbol.IsNativeIntegerType; + return typeSymbol.IsReferenceType || typeSymbol.IsEnumType() || typeSymbol.SpecialType.CanBeConst() || typeSymbol.IsNativeIntegerTypeOrNumericIntPtr; } /// @@ -164,9 +164,10 @@ public static TypeSymbol EnumUnderlyingTypeOrSelf(this TypeSymbol type) return type.GetEnumUnderlyingType() ?? type; } - public static bool IsNativeIntegerOrNullableNativeIntegerType(this TypeSymbol? type) + // TODO2 will be renamed IsNativeIntegerOrNullableThereof before merging this PR + public static bool IsNativeIntegerOrNumericIntPtrOrNullableThereof(this TypeSymbol? type) { - return type?.StrippedType().IsNativeIntegerType == true; + return type?.StrippedType().IsNativeIntegerTypeOrNumericIntPtr == true; } public static bool IsObjectType(this TypeSymbol type) @@ -581,8 +582,8 @@ public static bool TryGetElementTypesWithAnnotationsIfTupleType(this TypeSymbol case SpecialType.System_UInt32: case SpecialType.System_Int64: case SpecialType.System_UInt64: - case SpecialType.System_IntPtr when type.IsNativeIntegerType: - case SpecialType.System_UIntPtr when type.IsNativeIntegerType: + case SpecialType.System_IntPtr when type.IsNativeIntegerOrNumericIntPtrOrNullableThereof(): + case SpecialType.System_UIntPtr when type.IsNativeIntegerOrNumericIntPtrOrNullableThereof(): case SpecialType.System_Char: case SpecialType.System_Boolean: case SpecialType.System_Single: @@ -1151,7 +1152,7 @@ public static bool ContainsDynamic(this TypeSymbol type) internal static bool ContainsNativeInteger(this TypeSymbol type) { - var result = type.VisitType((type, unused1, unused2) => type.IsNativeIntegerType, (object?)null, canDigThroughNullable: true); + var result = type.VisitType((type, unused1, unused2) => type.IsNativeIntegerWrapperType, (object?)null, canDigThroughNullable: true); return result is object; } @@ -1337,8 +1338,8 @@ public static bool IsIntrinsicType(this TypeSymbol type) case SpecialType.System_UInt16: case SpecialType.System_UInt32: case SpecialType.System_UInt64: - 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_Single: case SpecialType.System_Double: // NOTE: VB treats System.DateTime as an intrinsic, while C# does not. @@ -1980,7 +1981,7 @@ internal static Cci.TypeReferenceWithAttributes GetTypeRefWithAttributes( { addIfNotNull(builder, compilation.SynthesizeTupleNamesAttribute(type.Type)); } - if (type.Type.ContainsNativeInteger()) + if (compilation.ShouldEmitNativeIntegerAttributes() && type.Type.ContainsNativeInteger()) { addIfNotNull(builder, moduleBuilder.SynthesizeNativeIntegerAttribute(declaringSymbol, type.Type)); } @@ -2075,8 +2076,8 @@ internal static int TypeToIndex(this TypeSymbol type) case SpecialType.System_UInt16: return 9; case SpecialType.System_UInt32: return 10; case SpecialType.System_UInt64: return 11; - case SpecialType.System_IntPtr when type.IsNativeIntegerType: return 12; - case SpecialType.System_UIntPtr when type.IsNativeIntegerType: return 13; + case SpecialType.System_IntPtr when type.IsNativeIntegerTypeOrNumericIntPtr: return 12; + case SpecialType.System_UIntPtr when type.IsNativeIntegerTypeOrNumericIntPtr: return 13; case SpecialType.System_Single: return 14; case SpecialType.System_Double: return 15; case SpecialType.System_Decimal: return 16; @@ -2098,8 +2099,8 @@ internal static int TypeToIndex(this TypeSymbol type) case SpecialType.System_UInt16: return 24; case SpecialType.System_UInt32: return 25; case SpecialType.System_UInt64: return 26; - case SpecialType.System_IntPtr when underlyingType.IsNativeIntegerType: return 27; - case SpecialType.System_UIntPtr when underlyingType.IsNativeIntegerType: return 28; + case SpecialType.System_IntPtr when underlyingType.IsNativeIntegerTypeOrNumericIntPtr: return 27; + case SpecialType.System_UIntPtr when underlyingType.IsNativeIntegerTypeOrNumericIntPtr: return 28; case SpecialType.System_Single: return 29; case SpecialType.System_Double: return 30; case SpecialType.System_Decimal: return 31; diff --git a/src/Compilers/CSharp/Portable/Utilities/ValueSetFactory.cs b/src/Compilers/CSharp/Portable/Utilities/ValueSetFactory.cs index 23468cca65cdc..dca6734e27ba6 100644 --- a/src/Compilers/CSharp/Portable/Utilities/ValueSetFactory.cs +++ b/src/Compilers/CSharp/Portable/Utilities/ValueSetFactory.cs @@ -58,7 +58,7 @@ internal static partial class ValueSetFactory if (type.IsSpanOrReadOnlySpanChar()) return ForString; type = type.EnumUnderlyingTypeOrSelf(); - return ForSpecialType(type.SpecialType, type.IsNativeIntegerType); + return ForSpecialType(type.SpecialType, type.IsNativeIntegerTypeOrNumericIntPtr); } public static IValueSetFactory? ForInput(BoundDagTemp input) diff --git a/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs b/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs index 0274edccd1a18..ae82feeb5d6cd 100644 --- a/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs @@ -11,6 +11,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.CSharp.UnitTests; @@ -22,6 +23,8 @@ using Xunit; using ReferenceEqualityComparer = Roslyn.Utilities.ReferenceEqualityComparer; +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Semantics; + public class NumericIntPtrTests : CSharpTestBase { internal static readonly ConversionKind[] Identity = new[] { ConversionKind.Identity }; @@ -34,6 +37,7 @@ public class NumericIntPtrTests : CSharpTestBase internal static readonly ConversionKind[] ExplicitPointerToInteger = new[] { ConversionKind.ExplicitPointerToInteger }; internal static readonly ConversionKind[] ExplicitEnumeration = new[] { ConversionKind.ExplicitEnumeration }; internal static readonly ConversionKind[] ExplicitNumeric = new[] { ConversionKind.ExplicitNumeric }; + internal static readonly ConversionKind[] ExplicitUserDefined = new[] { ConversionKind.ExplicitUserDefined }; internal static readonly ConversionKind[] ImplicitNullableNumeric = new[] { ConversionKind.ImplicitNullable, ConversionKind.ImplicitNumeric }; internal static readonly ConversionKind[] ImplicitNullableIdentity = new[] { ConversionKind.ImplicitNullable, ConversionKind.Identity }; @@ -59,788 +63,291 @@ internal static void AssertMatches(ConversionKind[] expected, Conversion convers Assert.Equal(expected, actualConversionKinds); } - [Fact] - public void LanguageVersion() - { - var source = -@"interface I -{ - nint Add(nint x, nuint y); -}"; + private static int SymbolComparison(Symbol x, Symbol y) => SymbolComparison(x.ToTestDisplayString(), y.ToTestDisplayString()); - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics( - // (3,5): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // nint Add(nint x, nuint y); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "nint").WithArguments("native-sized integers", "9.0").WithLocation(3, 5), - // (3,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // nint Add(nint x, nuint y); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "nint").WithArguments("native-sized integers", "9.0").WithLocation(3, 14), - // (3,22): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // nint Add(nint x, nuint y); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "nuint").WithArguments("native-sized integers", "9.0").WithLocation(3, 22)); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - } + private static int SymbolComparison(ISymbol x, ISymbol y) => SymbolComparison(x.ToTestDisplayString(), y.ToTestDisplayString()); - /// - /// System.IntPtr and System.UIntPtr definitions from metadata. - /// - [Fact] - public void TypeDefinitions_FromMetadata() + private static int SymbolComparison(string x, string y) { - var source = -@"interface I -{ - void F1(System.IntPtr x, nint y); - void F2(System.UIntPtr x, nuint y); -}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - - var type = comp.GetTypeByMetadataName("System.IntPtr"); - VerifyType(type, signed: true, isNativeInt: false); - VerifyType(type.GetPublicSymbol(), signed: true, isNativeInt: false); - - type = comp.GetTypeByMetadataName("System.UIntPtr"); - VerifyType(type, signed: false, isNativeInt: false); - VerifyType(type.GetPublicSymbol(), signed: false, isNativeInt: false); - - var method = comp.GetMember("I.F1"); - Assert.Equal("void I.F1(System.IntPtr x, nint y)", method.ToTestDisplayString()); - Assert.Equal("Sub I.F1(x As System.IntPtr, y As System.IntPtr)", VisualBasic.SymbolDisplay.ToDisplayString(method.GetPublicSymbol(), SymbolDisplayFormat.TestFormat)); - VerifyTypes((NamedTypeSymbol)method.Parameters[0].Type, (NamedTypeSymbol)method.Parameters[1].Type, signed: true); + return string.CompareOrdinal(normalizeDisplayString(x), normalizeDisplayString(y)); - method = comp.GetMember("I.F2"); - Assert.Equal("void I.F2(System.UIntPtr x, nuint y)", method.ToTestDisplayString()); - Assert.Equal("Sub I.F2(x As System.UIntPtr, y As System.UIntPtr)", VisualBasic.SymbolDisplay.ToDisplayString(method.GetPublicSymbol(), SymbolDisplayFormat.TestFormat)); - VerifyTypes((NamedTypeSymbol)method.Parameters[0].Type, (NamedTypeSymbol)method.Parameters[1].Type, signed: false); + static string normalizeDisplayString(string s) => s.Replace("System.IntPtr", "nint").Replace("System.UIntPtr", "nuint"); } - /// - /// System.IntPtr and System.UIntPtr definitions from source. - /// [Fact] - public void TypeDefinitions_FromSource() + public void Interfaces() { var sourceA = @"namespace System { - public class Object - { - public virtual string ToString() => null; - public virtual int GetHashCode() => 0; - public virtual bool Equals(object obj) => false; - } + public class Object { } public class String { } - public abstract class ValueType - { - public override string ToString() => null; - public override int GetHashCode() => 0; - public override bool Equals(object obj) => false; - } + public abstract class ValueType { } public struct Void { } public struct Boolean { } public struct Int32 { } + public interface ISerializable { } public interface IEquatable { bool Equals(T other); } - public struct IntPtr : IEquatable + public interface IOther { } + public struct IntPtr : ISerializable, IEquatable, IOther { - public override string ToString() => null; - public override int GetHashCode() => 0; - public override bool Equals(object obj) => false; bool IEquatable.Equals(IntPtr other) => false; } - public struct UIntPtr : IEquatable - { - public override string ToString() => null; - public override int GetHashCode() => 0; - public override bool Equals(object obj) => false; - bool IEquatable.Equals(UIntPtr other) => false; - } -}"; +} +" + RuntimeFeature_NumericIntPtr; + var sourceB = -@"interface I +@"using System; +class Program { - void F1(System.IntPtr x, nint y); - void F2(System.UIntPtr x, nuint y); + static void F0(ISerializable i) { } + static object F1(IEquatable i) => default; + static void F2(IEquatable i) { } + static void F3(IOther i) { } + static void Main() + { + System.IntPtr n = 42; + F0(n); + F1(n); + F2(n); + F3(n); + F3(n); + } }"; var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9); comp.VerifyDiagnostics(); - verify(comp); - - comp = CreateEmptyCompilation(sourceA); - comp.VerifyDiagnostics(); - var ref1 = comp.ToMetadataReference(); - var ref2 = comp.EmitToImageReference(); - - comp = CreateEmptyCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - verify(comp); - - comp = CreateEmptyCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - verify(comp); - - static void verify(CSharpCompilation comp) - { - var type = comp.GetTypeByMetadataName("System.IntPtr"); - VerifyType(type, signed: true, isNativeInt: false); - VerifyType(type.GetPublicSymbol(), signed: true, isNativeInt: false); - - type = comp.GetTypeByMetadataName("System.UIntPtr"); - VerifyType(type, signed: false, isNativeInt: false); - VerifyType(type.GetPublicSymbol(), signed: false, isNativeInt: false); - - var method = comp.GetMember("I.F1"); - Assert.Equal("void I.F1(System.IntPtr x, nint y)", method.ToTestDisplayString()); - VerifyTypes((NamedTypeSymbol)method.Parameters[0].Type, (NamedTypeSymbol)method.Parameters[1].Type, signed: true); - - method = comp.GetMember("I.F2"); - Assert.Equal("void I.F2(System.UIntPtr x, nuint y)", method.ToTestDisplayString()); - VerifyTypes((NamedTypeSymbol)method.Parameters[0].Type, (NamedTypeSymbol)method.Parameters[1].Type, signed: false); - } } - private static void VerifyType(NamedTypeSymbol type, bool signed, bool isNativeInt) + [Fact] + public void Interfaces_UIntPtr() { - Assert.Equal(signed ? SpecialType.System_IntPtr : SpecialType.System_UIntPtr, type.SpecialType); - Assert.Equal(SymbolKind.NamedType, type.Kind); - Assert.Equal(TypeKind.Struct, type.TypeKind); - Assert.Same(type, type.ConstructedFrom); - Assert.Equal(isNativeInt, type.IsNativeIntegerType); - Assert.Equal(signed ? "IntPtr" : "UIntPtr", type.Name); - - if (isNativeInt) - { - VerifyMembers(type); - } + var sourceA = +@"namespace System +{ + public class Object { } + public class String { } + public abstract class ValueType { } + public struct Void { } + public struct Boolean { } + public struct Int32 { } + public interface ISerializable { } + public interface IEquatable + { + bool Equals(T other); } - - private static void VerifyType(INamedTypeSymbol type, bool signed, bool isNativeInt) + public interface IOther { } + public struct UIntPtr : ISerializable, IEquatable, IOther { - Assert.Equal(signed ? SpecialType.System_IntPtr : SpecialType.System_UIntPtr, type.SpecialType); - Assert.Equal(SymbolKind.NamedType, type.Kind); - Assert.Equal(TypeKind.Struct, type.TypeKind); - Assert.Same(type, type.ConstructedFrom); - Assert.Equal(isNativeInt, type.IsNativeIntegerType); - Assert.Equal(signed ? "IntPtr" : "UIntPtr", type.Name); - - if (isNativeInt) - { - VerifyMembers(type); - } + bool IEquatable.Equals(UIntPtr other) => false; } +} +" + RuntimeFeature_NumericIntPtr; - private static void VerifyTypes(INamedTypeSymbol underlyingType, INamedTypeSymbol nativeIntegerType, bool signed) + var sourceB = +@"using System; +class Program +{ + static void F0(ISerializable i) { } + static object F1(IEquatable i) => default; + static void F2(IEquatable i) { } + static void F3(IOther i) { } + static void Main() { - VerifyType(underlyingType, signed, isNativeInt: false); - VerifyType(nativeIntegerType, signed, isNativeInt: true); - - Assert.Same(underlyingType.ContainingSymbol, nativeIntegerType.ContainingSymbol); - Assert.Same(underlyingType.Name, nativeIntegerType.Name); - - VerifyMembers(underlyingType, nativeIntegerType, signed); - - VerifyInterfaces(underlyingType, underlyingType.Interfaces, nativeIntegerType, nativeIntegerType.Interfaces); - - Assert.NotSame(underlyingType, nativeIntegerType); - Assert.Same(underlyingType, nativeIntegerType.NativeIntegerUnderlyingType); - Assert.NotEqual(underlyingType, nativeIntegerType); - Assert.NotEqual(nativeIntegerType, underlyingType); - Assert.False(underlyingType.Equals(nativeIntegerType)); - Assert.False(((IEquatable)underlyingType).Equals(nativeIntegerType)); - Assert.False(underlyingType.Equals(nativeIntegerType, SymbolEqualityComparer.Default)); - Assert.False(underlyingType.Equals(nativeIntegerType, SymbolEqualityComparer.IncludeNullability)); - Assert.False(underlyingType.Equals(nativeIntegerType, SymbolEqualityComparer.ConsiderEverything)); - Assert.True(underlyingType.Equals(nativeIntegerType, TypeCompareKind.IgnoreNativeIntegers)); - Assert.Equal(underlyingType.GetHashCode(), nativeIntegerType.GetHashCode()); + System.UIntPtr n = 42; + F0(n); + F1(n); + F2(n); + F3(n); + F3(n); + } +}"; + var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9); + comp.VerifyDiagnostics(); } - private static void VerifyInterfaces(INamedTypeSymbol underlyingType, ImmutableArray underlyingInterfaces, INamedTypeSymbol nativeIntegerType, ImmutableArray nativeIntegerInterfaces) + [Theory] + [InlineData(false)] + [InlineData(true)] + public void StaticMembers(bool useCompilationReference) { - Assert.Equal(underlyingInterfaces.Length, nativeIntegerInterfaces.Length); - - for (int i = 0; i < underlyingInterfaces.Length; i++) - { - verifyInterface(underlyingInterfaces[i], nativeIntegerInterfaces[i]); - } - - void verifyInterface(INamedTypeSymbol underlyingInterface, INamedTypeSymbol nativeIntegerInterface) + var sourceA = +@"namespace System +{ + public class Object { } + public class String { } + public abstract class ValueType { } + public struct Void { } + public struct Boolean { } + public struct Int32 { } + public struct IntPtr + { + public static readonly IntPtr Zero; + public static int Size => 0; + public static IntPtr MaxValue => default; + public static IntPtr MinValue => default; + public static IntPtr Add(IntPtr ptr, int offset) => default; + public static IntPtr Subtract(IntPtr ptr, int offset) => default; + public static IntPtr Parse(string s) => default; + public static bool TryParse(string s, out IntPtr value) { - Assert.True(underlyingInterface.Equals(nativeIntegerInterface, TypeCompareKind.IgnoreNativeIntegers)); - - for (int i = 0; i < underlyingInterface.TypeArguments.Length; i++) - { - var underlyingTypeArgument = underlyingInterface.TypeArguments[i]; - var nativeIntegerTypeArgument = nativeIntegerInterface.TypeArguments[i]; - Assert.Equal(underlyingTypeArgument.Equals(underlyingType, TypeCompareKind.AllIgnoreOptions), nativeIntegerTypeArgument.Equals(nativeIntegerType, TypeCompareKind.AllIgnoreOptions)); - } + value = default; + return false; } } - - private static void VerifyMembers(INamedTypeSymbol underlyingType, INamedTypeSymbol nativeIntegerType, bool signed) + public struct UIntPtr { - Assert.Empty(nativeIntegerType.GetTypeMembers()); - - var nativeIntegerMembers = nativeIntegerType.GetMembers(); - var underlyingMembers = underlyingType.GetMembers(); - - var nativeIntegerMemberNames = nativeIntegerType.MemberNames; - AssertEx.Equal(nativeIntegerMembers.SelectAsArray(m => m.Name), nativeIntegerMemberNames); - - var expectedMembers = underlyingMembers.WhereAsArray(m => includeUnderlyingMember(m)).Sort(SymbolComparison).SelectAsArray(m => m.ToTestDisplayString()); - var actualMembers = nativeIntegerMembers.WhereAsArray(m => includeNativeIntegerMember(m)).Sort(SymbolComparison).SelectAsArray(m => m.ToTestDisplayString().Replace(signed ? "nint" : "nuint", signed ? "System.IntPtr" : "System.UIntPtr")); - AssertEx.Equal(expectedMembers, actualMembers); - - static bool includeUnderlyingMember(ISymbol underlyingMember) - { - if (underlyingMember.DeclaredAccessibility != Accessibility.Public) - { - return false; - } - switch (underlyingMember.Kind) - { - case SymbolKind.Method: - var method = (IMethodSymbol)underlyingMember; - if (method.IsGenericMethod) - { - return false; - } - switch (method.MethodKind) - { - case MethodKind.Ordinary: - return !IsSkippedMethodName(method.Name); - case MethodKind.PropertyGet: - case MethodKind.PropertySet: - return includeUnderlyingMember(method.AssociatedSymbol); - default: - return false; - } - case SymbolKind.Property: - var property = (IPropertySymbol)underlyingMember; - return property.Parameters.Length == 0 && !IsSkippedPropertyName(property.Name); - default: - return false; - } - } - - static bool includeNativeIntegerMember(ISymbol nativeIntegerMember) + public static readonly UIntPtr Zero; + public static int Size => 0; + public static UIntPtr MaxValue => default; + public static UIntPtr MinValue => default; + public static UIntPtr Add(UIntPtr ptr, int offset) => default; + public static UIntPtr Subtract(UIntPtr ptr, int offset) => default; + public static UIntPtr Parse(string s) => default; + public static bool TryParse(string s, out UIntPtr value) { - return !(nativeIntegerMember is IMethodSymbol { MethodKind: MethodKind.Constructor }); + value = default; + return false; } } +} +" + RuntimeFeature_NumericIntPtr; - private static void VerifyTypes(NamedTypeSymbol underlyingType, NamedTypeSymbol nativeIntegerType, bool signed) - { - VerifyType(underlyingType, signed, isNativeInt: false); - VerifyType(nativeIntegerType, signed, isNativeInt: true); - - Assert.Same(underlyingType.ContainingSymbol, nativeIntegerType.ContainingSymbol); - Assert.Same(underlyingType.Name, nativeIntegerType.Name); - - VerifyMembers(underlyingType, nativeIntegerType, signed); - - VerifyInterfaces(underlyingType, underlyingType.InterfacesNoUseSiteDiagnostics(), nativeIntegerType, nativeIntegerType.InterfacesNoUseSiteDiagnostics()); - VerifyInterfaces(underlyingType, underlyingType.GetDeclaredInterfaces(null), nativeIntegerType, nativeIntegerType.GetDeclaredInterfaces(null)); - - Assert.Null(underlyingType.NativeIntegerUnderlyingType); - Assert.Same(nativeIntegerType, underlyingType.AsNativeInteger()); - Assert.Same(underlyingType, nativeIntegerType.NativeIntegerUnderlyingType); - VerifyEqualButDistinct(underlyingType, underlyingType.AsNativeInteger()); - VerifyEqualButDistinct(nativeIntegerType, nativeIntegerType.NativeIntegerUnderlyingType); - VerifyEqualButDistinct(underlyingType, nativeIntegerType); - - VerifyTypes(underlyingType.GetPublicSymbol(), nativeIntegerType.GetPublicSymbol(), signed); - } + var comp = CreateEmptyCompilation(sourceA); + comp.VerifyDiagnostics(); + var refA = AsReference(comp, useCompilationReference); - private static void VerifyEqualButDistinct(NamedTypeSymbol underlyingType, NamedTypeSymbol nativeIntegerType) + var sourceB = +@"class Program +{ + static nint F1() { - Assert.NotSame(underlyingType, nativeIntegerType); - Assert.NotEqual(underlyingType, nativeIntegerType); - Assert.NotEqual(nativeIntegerType, underlyingType); - Assert.False(underlyingType.Equals(nativeIntegerType, TypeCompareKind.ConsiderEverything)); - Assert.False(nativeIntegerType.Equals(underlyingType, TypeCompareKind.ConsiderEverything)); - Assert.True(underlyingType.Equals(nativeIntegerType, TypeCompareKind.IgnoreNativeIntegers)); - Assert.True(nativeIntegerType.Equals(underlyingType, TypeCompareKind.IgnoreNativeIntegers)); - Assert.Equal(underlyingType.GetHashCode(), nativeIntegerType.GetHashCode()); + _ = nint.Zero; + _ = nint.Size; + var x1 = nint.MaxValue; + var x2 = nint.MinValue; + _ = nint.Add(x1, 2); + _ = nint.Subtract(x1, 3); + var x3 = nint.Parse(null); + _ = nint.TryParse(null, out var x4); + return 0; } - - private static void VerifyInterfaces(NamedTypeSymbol underlyingType, ImmutableArray underlyingInterfaces, NamedTypeSymbol nativeIntegerType, ImmutableArray nativeIntegerInterfaces) + static nuint F2() { - Assert.Equal(underlyingInterfaces.Length, nativeIntegerInterfaces.Length); - - for (int i = 0; i < underlyingInterfaces.Length; i++) - { - verifyInterface(underlyingInterfaces[i], nativeIntegerInterfaces[i]); - } - - void verifyInterface(NamedTypeSymbol underlyingInterface, NamedTypeSymbol nativeIntegerInterface) - { - Assert.True(underlyingInterface.Equals(nativeIntegerInterface, TypeCompareKind.IgnoreNativeIntegers)); - - for (int i = 0; i < underlyingInterface.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics.Length; i++) - { - var underlyingTypeArgument = underlyingInterface.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics[i].Type; - var nativeIntegerTypeArgument = nativeIntegerInterface.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics[i].Type; - Assert.Equal(underlyingTypeArgument.Equals(underlyingType, TypeCompareKind.AllIgnoreOptions), nativeIntegerTypeArgument.Equals(nativeIntegerType, TypeCompareKind.AllIgnoreOptions)); - } - } + _ = nuint.Zero; + _ = nuint.Size; + var y1 = nuint.MaxValue; + var y2 = nuint.MinValue; + _ = nuint.Add(y1, 2); + _ = nuint.Subtract(y1, 3); + var y3 = nuint.Parse(null); + _ = nuint.TryParse(null, out var y4); + return 0; } +}"; - private static void VerifyMembers(NamedTypeSymbol underlyingType, NamedTypeSymbol nativeIntegerType, bool signed) - { - Assert.Empty(nativeIntegerType.GetTypeMembers()); - - var nativeIntegerMembers = nativeIntegerType.GetMembers(); - var underlyingMembers = underlyingType.GetMembers(); - - var nativeIntegerMemberNames = nativeIntegerType.MemberNames; - AssertEx.Equal(nativeIntegerMembers.SelectAsArray(m => m.Name), nativeIntegerMemberNames); - - var expectedMembers = underlyingMembers.WhereAsArray(m => includeUnderlyingMember(m)).Sort(SymbolComparison); - var actualMembers = nativeIntegerMembers.WhereAsArray(m => includeNativeIntegerMember(m)).Sort(SymbolComparison); - - Assert.Equal(expectedMembers.Length, actualMembers.Length); - for (int i = 0; i < expectedMembers.Length; i++) - { - VerifyMember(actualMembers[i], expectedMembers[i], signed); - } - - static bool includeUnderlyingMember(Symbol underlyingMember) - { - if (underlyingMember.DeclaredAccessibility != Accessibility.Public) - { - return false; - } - switch (underlyingMember.Kind) - { - case SymbolKind.Method: - var method = (MethodSymbol)underlyingMember; - if (method.IsGenericMethod) - { - return false; - } - switch (method.MethodKind) - { - case MethodKind.Ordinary: - return !IsSkippedMethodName(method.Name); - case MethodKind.PropertyGet: - case MethodKind.PropertySet: - return includeUnderlyingMember(method.AssociatedSymbol); - default: - return false; - } - case SymbolKind.Property: - var property = (PropertySymbol)underlyingMember; - return property.ParameterCount == 0 && !IsSkippedPropertyName(property.Name); - default: - return false; - } - } - - static bool includeNativeIntegerMember(Symbol nativeIntegerMember) - { - return !(nativeIntegerMember is MethodSymbol { MethodKind: MethodKind.Constructor }); - } + comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); + comp.VerifyDiagnostics(); } - private static void VerifyMembers(NamedTypeSymbol type) - { - var memberNames = type.MemberNames; - var allMembers = type.GetMembers(); - Assert.Equal(allMembers, type.GetMembers()); // same array - - foreach (var member in allMembers) - { - Assert.Contains(member.Name, memberNames); - verifyMember(type, member); - } - - var unorderedMembers = type.GetMembersUnordered(); - Assert.Equal(allMembers.Length, unorderedMembers.Length); - verifyMembers(type, allMembers, unorderedMembers); - - foreach (var memberName in memberNames) - { - var members = type.GetMembers(memberName); - Assert.False(members.IsDefaultOrEmpty); - verifyMembers(type, allMembers, members); - } - - static void verifyMembers(NamedTypeSymbol type, ImmutableArray allMembers, ImmutableArray members) - { - foreach (var member in members) - { - Assert.Contains(member, allMembers); - verifyMember(type, member); - } - } - - static void verifyMember(NamedTypeSymbol type, Symbol member) - { - Assert.Same(type, member.ContainingSymbol); - Assert.Same(type, member.ContainingType); - - if (member is MethodSymbol method) - { - var parameters = method.Parameters; - Assert.Equal(parameters, method.Parameters); // same array - } - } - } - - private static void VerifyMembers(INamedTypeSymbol type) - { - var memberNames = type.MemberNames; - var allMembers = type.GetMembers(); - Assert.Equal(allMembers, type.GetMembers(), ReferenceEqualityComparer.Instance); // same member instances - - foreach (var member in allMembers) - { - Assert.Contains(member.Name, memberNames); - verifyMember(type, member); - } - - foreach (var memberName in memberNames) - { - var members = type.GetMembers(memberName); - Assert.False(members.IsDefaultOrEmpty); - verifyMembers(type, allMembers, members); - } - - static void verifyMembers(INamedTypeSymbol type, ImmutableArray allMembers, ImmutableArray members) - { - foreach (var member in members) - { - Assert.Contains(member, allMembers); - verifyMember(type, member); - } - } - - static void verifyMember(INamedTypeSymbol type, ISymbol member) - { - Assert.Same(type, member.ContainingSymbol); - Assert.Same(type, member.ContainingType); - } - } - - private static void VerifyMember(Symbol member, Symbol underlyingMember, bool signed) - { - var specialType = signed ? SpecialType.System_IntPtr : SpecialType.System_UIntPtr; - - Assert.Equal(member.Name, underlyingMember.Name); - Assert.Equal(member.DeclaredAccessibility, underlyingMember.DeclaredAccessibility); - Assert.Equal(member.IsStatic, underlyingMember.IsStatic); - - Assert.NotEqual(member, underlyingMember); - Assert.True(member.Equals(underlyingMember, TypeCompareKind.IgnoreNativeIntegers)); - Assert.False(member.Equals(underlyingMember, TypeCompareKind.ConsiderEverything)); - Assert.Same(underlyingMember, getUnderlyingMember(member)); - Assert.Equal(member.GetHashCode(), underlyingMember.GetHashCode()); - - switch (member.Kind) - { - case SymbolKind.Method: - { - var method = (MethodSymbol)member; - var underlyingMethod = (MethodSymbol)underlyingMember; - verifyTypes(method.ReturnTypeWithAnnotations, underlyingMethod.ReturnTypeWithAnnotations); - for (int i = 0; i < method.ParameterCount; i++) - { - VerifyMember(method.Parameters[i], underlyingMethod.Parameters[i], signed); - } - } - break; - case SymbolKind.Property: - { - var property = (PropertySymbol)member; - var underlyingProperty = (PropertySymbol)underlyingMember; - verifyTypes(property.TypeWithAnnotations, underlyingProperty.TypeWithAnnotations); - } - break; - case SymbolKind.Parameter: - { - var parameter = (ParameterSymbol)member; - var underlyingParameter = (ParameterSymbol)underlyingMember; - verifyTypes(parameter.TypeWithAnnotations, underlyingParameter.TypeWithAnnotations); - } - break; - default: - throw ExceptionUtilities.UnexpectedValue(member.Kind); - } - - var explicitImplementations = member.GetExplicitInterfaceImplementations(); - Assert.Equal(0, explicitImplementations.Length); - - void verifyTypes(TypeWithAnnotations fromMember, TypeWithAnnotations fromUnderlyingMember) - { - Assert.True(fromMember.Equals(fromUnderlyingMember, TypeCompareKind.IgnoreNativeIntegers)); - // No use of underlying type in native integer member. - Assert.False(containsType(fromMember, useNativeInteger: false)); - // No use of native integer in underlying member. - Assert.False(containsType(fromUnderlyingMember, useNativeInteger: true)); - // Use of underlying type in underlying member should match use of native type in native integer member. - Assert.Equal(containsType(fromMember, useNativeInteger: true), containsType(fromUnderlyingMember, useNativeInteger: false)); - Assert.NotEqual(containsType(fromMember, useNativeInteger: true), fromMember.Equals(fromUnderlyingMember, TypeCompareKind.ConsiderEverything)); - } - - bool containsType(TypeWithAnnotations type, bool useNativeInteger) - { - return type.Type.VisitType((type, unused1, unused2) => type.SpecialType == specialType && useNativeInteger == type.IsNativeIntegerType, (object)null) is { }; - } - - static Symbol getUnderlyingMember(Symbol nativeIntegerMember) - { - switch (nativeIntegerMember.Kind) - { - case SymbolKind.Method: - return ((WrappedMethodSymbol)nativeIntegerMember).UnderlyingMethod; - case SymbolKind.Property: - return ((WrappedPropertySymbol)nativeIntegerMember).UnderlyingProperty; - case SymbolKind.Parameter: - return ((WrappedParameterSymbol)nativeIntegerMember).UnderlyingParameter; - default: - throw ExceptionUtilities.UnexpectedValue(nativeIntegerMember.Kind); - } - } - } - - private static bool IsSkippedMethodName(string name) - { - switch (name) - { - case "Add": - case "Subtract": - case "ToInt32": - case "ToInt64": - case "ToUInt32": - case "ToUInt64": - case "ToPointer": - return true; - default: - return false; - } - } - - private static bool IsSkippedPropertyName(string name) - { - switch (name) - { - case "Size": - return true; - default: - return false; - } - } - - private static int SymbolComparison(Symbol x, Symbol y) => SymbolComparison(x.ToTestDisplayString(), y.ToTestDisplayString()); - - private static int SymbolComparison(ISymbol x, ISymbol y) => SymbolComparison(x.ToTestDisplayString(), y.ToTestDisplayString()); - - private static int SymbolComparison(string x, string y) - { - return string.CompareOrdinal(normalizeDisplayString(x), normalizeDisplayString(y)); - - static string normalizeDisplayString(string s) => s.Replace("System.IntPtr", "nint").Replace("System.UIntPtr", "nuint"); - } - - [Fact] - public void MissingTypes() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void InstanceMembers(bool useCompilationReference) { var sourceA = @"namespace System { public class Object { } + public class String { } public abstract class ValueType { } public struct Void { } -}"; - var sourceB = -@"interface I -{ - void F1(System.IntPtr x, nint y); - void F2(System.UIntPtr x, nuint y); -}"; - var diagnostics = new[] - { - // (3,20): error CS0234: The underlyingType or namespace name 'IntPtr' does not exist in the namespace 'System' (are you missing an assembly reference?) - // void F1(System.IntPtr x, nint y); - Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "IntPtr").WithArguments("IntPtr", "System").WithLocation(3, 20), - // (3,30): error CS0518: Predefined underlyingType 'System.IntPtr' is not defined or imported - // void F1(System.IntPtr x, nint y); - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "nint").WithArguments("System.IntPtr").WithLocation(3, 30), - // (4,20): error CS0234: The underlyingType or namespace name 'UIntPtr' does not exist in the namespace 'System' (are you missing an assembly reference?) - // void F2(System.UIntPtr x, nuint y); - Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "UIntPtr").WithArguments("UIntPtr", "System").WithLocation(4, 20), - // (4,31): error CS0518: Predefined underlyingType 'System.UIntPtr' is not defined or imported - // void F2(System.UIntPtr x, nuint y); - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "nuint").WithArguments("System.UIntPtr").WithLocation(4, 31) - }; - - var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(diagnostics); - verify(comp); - - comp = CreateEmptyCompilation(sourceA); - comp.VerifyDiagnostics(); - var ref1 = comp.ToMetadataReference(); - var ref2 = comp.EmitToImageReference(); - - comp = CreateEmptyCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(diagnostics); - verify(comp); - - comp = CreateEmptyCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(diagnostics); - verify(comp); - - static void verify(CSharpCompilation comp) - { - var method = comp.GetMember("I.F1"); - Assert.Equal("void I.F1(System.IntPtr x, nint y)", method.ToTestDisplayString()); - VerifyErrorTypes((NamedTypeSymbol)method.Parameters[0].Type, (NamedTypeSymbol)method.Parameters[1].Type, signed: true); - - method = comp.GetMember("I.F2"); - Assert.Equal("void I.F2(System.UIntPtr x, nuint y)", method.ToTestDisplayString()); - VerifyErrorTypes((NamedTypeSymbol)method.Parameters[0].Type, (NamedTypeSymbol)method.Parameters[1].Type, signed: false); - } - } - - private static void VerifyErrorType(NamedTypeSymbol type, SpecialType specialType, bool isNativeInt) - { - Assert.Equal(SymbolKind.ErrorType, type.Kind); - Assert.Equal(TypeKind.Error, type.TypeKind); - Assert.Equal(isNativeInt, type.IsNativeIntegerType); - Assert.Equal(specialType, type.SpecialType); - } - - private static void VerifyErrorType(INamedTypeSymbol type, SpecialType specialType, bool isNativeInt) - { - Assert.Equal(SymbolKind.ErrorType, type.Kind); - Assert.Equal(TypeKind.Error, type.TypeKind); - Assert.Equal(isNativeInt, type.IsNativeIntegerType); - Assert.Equal(specialType, type.SpecialType); - } - - private static void VerifyErrorTypes(NamedTypeSymbol underlyingType, NamedTypeSymbol nativeIntegerType, bool signed) + public struct Boolean { } + public struct Int32 { } + public struct Int64 { } + public struct UInt32 { } + public struct UInt64 { } + public interface IFormatProvider { } + public struct IntPtr { - var specialType = signed ? SpecialType.System_IntPtr : SpecialType.System_UIntPtr; - - VerifyErrorType(underlyingType, SpecialType.None, isNativeInt: false); - VerifyErrorType(nativeIntegerType, specialType, isNativeInt: true); - - Assert.Null(underlyingType.NativeIntegerUnderlyingType); - VerifyErrorType(nativeIntegerType.NativeIntegerUnderlyingType, specialType, isNativeInt: false); - VerifyEqualButDistinct(nativeIntegerType.NativeIntegerUnderlyingType, nativeIntegerType); - - VerifyErrorTypes(underlyingType.GetPublicSymbol(), nativeIntegerType.GetPublicSymbol(), signed); + public int ToInt32() => default; + public long ToInt64() => default; + public uint ToUInt32() => default; + public ulong ToUInt64() => default; + unsafe public void* ToPointer() => default; + public int CompareTo(object other) => default; + public int CompareTo(IntPtr other) => default; + public bool Equals(IntPtr other) => default; + public string ToString(string format) => default; + public string ToString(IFormatProvider provider) => default; + public string ToString(string format, IFormatProvider provider) => default; } - - private static void VerifyErrorTypes(INamedTypeSymbol underlyingType, INamedTypeSymbol nativeIntegerType, bool signed) + public struct UIntPtr { - var specialType = signed ? SpecialType.System_IntPtr : SpecialType.System_UIntPtr; - - VerifyErrorType(underlyingType, SpecialType.None, isNativeInt: false); - VerifyErrorType(nativeIntegerType, specialType, isNativeInt: true); - - Assert.Null(underlyingType.NativeIntegerUnderlyingType); - VerifyErrorType(nativeIntegerType.NativeIntegerUnderlyingType, specialType, isNativeInt: false); + public int ToInt32() => default; + public long ToInt64() => default; + public uint ToUInt32() => default; + public ulong ToUInt64() => default; + unsafe public void* ToPointer() => default; + public int CompareTo(object other) => default; + public int CompareTo(UIntPtr other) => default; + public bool Equals(UIntPtr other) => default; + public string ToString(string format) => default; + public string ToString(IFormatProvider provider) => default; + public string ToString(string format, IFormatProvider provider) => default; } +} +" + RuntimeFeature_NumericIntPtr; - [Fact] - public void Retargeting_01() - { - var sourceA = -@"public class A -{ - public static nint F1 = int.MinValue; - public static nuint F2 = int.MaxValue; - public static nint F3 = -1; - public static nuint F4 = 1; -}"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Mscorlib40); - var refA = comp.ToMetadataReference(); - - var typeA = comp.GetMember("A.F1").Type; - var corLibA = comp.Assembly.CorLibrary; - Assert.Equal(corLibA, typeA.ContainingAssembly); + var comp = CreateEmptyCompilation(sourceA, options: TestOptions.UnsafeReleaseDll); + comp.VerifyDiagnostics(); + var refA = AsReference(comp, useCompilationReference); var sourceB = -@"class B : A +@"using System; +class Program { - static void Main() + unsafe static void F1(nint i) + { + _ = i.ToInt32(); + _ = i.ToInt64(); + _ = i.ToUInt32(); + _ = i.ToUInt64(); + _ = i.ToPointer(); + _ = i.CompareTo(null); + _ = i.CompareTo(i); + _ = i.Equals(i); + _ = i.ToString((string)null); + _ = i.ToString((IFormatProvider)null); + _ = i.ToString((string)null, (IFormatProvider)null); + } + unsafe static void F2(nuint u) { - System.Console.WriteLine(""{0}, {1}, {2}, {3}"", F1, F2, F3, F4); + _ = u.ToInt32(); + _ = u.ToInt64(); + _ = u.ToUInt32(); + _ = u.ToUInt64(); + _ = u.ToPointer(); + _ = u.CompareTo(null); + _ = u.CompareTo(u); + _ = u.Equals(u); + _ = u.ToString((string)null); + _ = u.ToString((IFormatProvider)null); + _ = u.ToString((string)null, (IFormatProvider)null); } }"; - comp = CreateCompilation(sourceB, references: new[] { refA }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Mscorlib45); - CompileAndVerify(comp, expectedOutput: $"{int.MinValue}, {int.MaxValue}, -1, 1"); - - var corLibB = comp.Assembly.CorLibrary; - Assert.NotEqual(corLibA, corLibB); - - var f1 = comp.GetMember("A.F1"); - verifyField(f1, "nint A.F1", corLibB); - var f2 = comp.GetMember("A.F2"); - verifyField(f2, "nuint A.F2", corLibB); - var f3 = comp.GetMember("A.F3"); - verifyField(f3, "nint A.F3", corLibB); - var f4 = comp.GetMember("A.F4"); - verifyField(f4, "nuint A.F4", corLibB); - - Assert.Same(f1.Type, f3.Type); - Assert.Same(f2.Type, f4.Type); - - static void verifyField(FieldSymbol field, string expectedSymbol, AssemblySymbol expectedAssembly) - { - Assert.IsType(field); - Assert.Equal(expectedSymbol, field.ToTestDisplayString()); - var type = (NamedTypeSymbol)field.Type; - Assert.True(type.IsNativeIntegerType); - Assert.IsType(type); - Assert.Equal(expectedAssembly, type.NativeIntegerUnderlyingType.ContainingAssembly); - } + comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9, options: TestOptions.UnsafeReleaseDll); + comp.VerifyDiagnostics(); } - [Fact] - public void Retargeting_02() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void ConstructorsAndOperators(bool useCompilationReference) { - var source1 = -@"namespace System -{ - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct IntPtr { } - public struct UIntPtr { } -}"; - var assemblyName = GetUniqueName(); - var comp = CreateCompilation(new AssemblyIdentity(assemblyName, new Version(1, 0, 0, 0)), new[] { source1 }, references: null); - var ref1 = comp.EmitToImageReference(); - var sourceA = -@"public class A -{ - public static nint F1 = -1; - public static nuint F2 = 1; - public static nint F3 = -2; - public static nuint F4 = 2; -}"; - comp = CreateEmptyCompilation(sourceA, references: new[] { ref1 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - var refA = comp.ToMetadataReference(); - - var typeA = comp.GetMember("A.F1").Type; - var corLibA = comp.Assembly.CorLibrary; - Assert.Equal(corLibA, typeA.ContainingAssembly); - - var source2 = @"namespace System { public class Object { } @@ -849,223 +356,192 @@ public abstract class ValueType { } public struct Void { } public struct Boolean { } public struct Int32 { } -}"; - comp = CreateCompilation(new AssemblyIdentity(assemblyName, new Version(2, 0, 0, 0)), new[] { source2 }, references: null); - var ref2 = comp.EmitToImageReference(); - - var sourceB = -@"class B : A -{ - static void Main() + public struct Int64 { } + public struct UInt32 { } + public struct UInt64 { } + public unsafe struct IntPtr { - _ = F1; - _ = F2; - } -}"; - comp = CreateEmptyCompilation(sourceB, references: new[] { ref2, refA }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (5,13): error CS0518: Predefined type 'System.IntPtr' is not defined or imported - // _ = F1; - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "F1").WithArguments("System.IntPtr").WithLocation(5, 13), - // (6,13): error CS0518: Predefined type 'System.UIntPtr' is not defined or imported - // _ = F2; - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "F2").WithArguments("System.UIntPtr").WithLocation(6, 13)); - - var corLibB = comp.Assembly.CorLibrary; - Assert.NotEqual(corLibA, corLibB); - - var f1 = comp.GetMember("A.F1"); - verifyField(f1, "nint A.F1", corLibB); - var f2 = comp.GetMember("A.F2"); - verifyField(f2, "nuint A.F2", corLibB); - var f3 = comp.GetMember("A.F3"); - verifyField(f3, "nint A.F3", corLibB); - var f4 = comp.GetMember("A.F4"); - verifyField(f4, "nuint A.F4", corLibB); - - // MissingMetadataTypeSymbol.TopLevel instances are not reused. - Assert.Equal(f1.Type, f3.Type); - Assert.NotSame(f1.Type, f3.Type); - Assert.Equal(f2.Type, f4.Type); - Assert.NotSame(f2.Type, f4.Type); - - static void verifyField(FieldSymbol field, string expectedSymbol, AssemblySymbol expectedAssembly) - { - Assert.IsType(field); - Assert.Equal(expectedSymbol, field.ToTestDisplayString()); - var type = (NamedTypeSymbol)field.Type; - Assert.True(type.IsNativeIntegerType); - Assert.IsType(type); - Assert.Equal(expectedAssembly, type.NativeIntegerUnderlyingType.ContainingAssembly); - } + public IntPtr(int i) { } + public IntPtr(long l) { } + public IntPtr(void* p) { } + public static explicit operator IntPtr(int i) => default; + public static explicit operator IntPtr(long l) => default; + public static explicit operator IntPtr(void* p) => default; + public static explicit operator int(IntPtr i) => default; + public static explicit operator long(IntPtr i) => default; + public static explicit operator void*(IntPtr i) => default; + public static IntPtr operator+(IntPtr x, int y) => default; + public static IntPtr operator-(IntPtr x, int y) => default; + public static bool operator==(IntPtr x, IntPtr y) => default; + public static bool operator!=(IntPtr x, IntPtr y) => default; } - - [Fact] - public void Retargeting_03() + public unsafe struct UIntPtr { - var source1 = -@"namespace System + public UIntPtr(uint i) { } + public UIntPtr(ulong l) { } + public UIntPtr(void* p) { } + public static explicit operator UIntPtr(uint i) => default; + public static explicit operator UIntPtr(ulong l) => default; + public static explicit operator UIntPtr(void* p) => default; + public static explicit operator uint(UIntPtr i) => default; + public static explicit operator ulong(UIntPtr i) => default; + public static explicit operator void*(UIntPtr i) => default; + public static UIntPtr operator+(UIntPtr x, int y) => default; + public static UIntPtr operator-(UIntPtr x, int y) => default; + public static bool operator==(UIntPtr x, UIntPtr y) => default; + public static bool operator!=(UIntPtr x, UIntPtr y) => default; + } +} +" + RuntimeFeature_NumericIntPtr; + var comp = CreateEmptyCompilation(sourceA, options: TestOptions.UnsafeReleaseDll); + comp.VerifyDiagnostics( + // (12,26): warning CS0660: 'nint' defines operator == or operator != but does not override Object.Equals(object o) + // public unsafe struct IntPtr + Diagnostic(ErrorCode.WRN_EqualityOpWithoutEquals, "IntPtr").WithArguments("nint").WithLocation(12, 26), + // (12,26): warning CS0661: 'nint' defines operator == or operator != but does not override Object.GetHashCode() + // public unsafe struct IntPtr + Diagnostic(ErrorCode.WRN_EqualityOpWithoutGetHashCode, "IntPtr").WithArguments("nint").WithLocation(12, 26), + // (28,26): warning CS0660: 'nuint' defines operator == or operator != but does not override Object.Equals(object o) + // public unsafe struct UIntPtr + Diagnostic(ErrorCode.WRN_EqualityOpWithoutEquals, "UIntPtr").WithArguments("nuint").WithLocation(28, 26), + // (28,26): warning CS0661: 'nuint' defines operator == or operator != but does not override Object.GetHashCode() + // public unsafe struct UIntPtr + Diagnostic(ErrorCode.WRN_EqualityOpWithoutGetHashCode, "UIntPtr").WithArguments("nuint").WithLocation(28, 26)); + var refA = AsReference(comp, useCompilationReference); + + var sourceB = +@"class Program { - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } + unsafe static void F1(nint x, nint y) + { + void* p = default; + _ = new nint(); + _ = new nint(1); + _ = new nint(2L); + _ = new nint(p); + _ = (nint)1; + _ = (nint)2L; + _ = (nint)p; + _ = (int)x; + _ = (long)x; + _ = (void*)x; + _ = x + 1; + _ = x - 2; + _ = x == y; + _ = x != y; + } + unsafe static void F2(nuint x, nuint y) + { + void* p = default; + _ = new nuint(); + _ = new nuint(1); + _ = new nuint(2UL); + _ = new nuint(p); + _ = (nuint)1; + _ = (nuint)2UL; + _ = (nuint)p; + _ = (uint)x; + _ = (ulong)x; + _ = (void*)x; + _ = x + 1; + _ = x - 2; + _ = x == y; + _ = x != y; + } }"; - var assemblyName = GetUniqueName(); - var comp = CreateCompilation(new AssemblyIdentity(assemblyName, new Version(1, 0, 0, 0)), new[] { source1 }, references: null); - var ref1 = comp.EmitToImageReference(); + comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9, options: TestOptions.UnsafeReleaseDll); + comp.VerifyDiagnostics(); + } + /// + /// Overrides from IntPtr and UIntPtr are implicitly included on nint and nuint. + /// + [Theory] + [InlineData(false)] + [InlineData(true)] + public void OverriddenMembers(bool useCompilationReference) + { var sourceA = -@"public class A -{ - public static nint F1 = -1; - public static nuint F2 = 1; -}"; - comp = CreateEmptyCompilation(sourceA, references: new[] { ref1 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (3,19): error CS0518: Predefined type 'System.IntPtr' is not defined or imported - // public static nint F1 = -1; - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "nint").WithArguments("System.IntPtr").WithLocation(3, 19), - // (4,19): error CS0518: Predefined type 'System.UIntPtr' is not defined or imported - // public static nuint F2 = 1; - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "nuint").WithArguments("System.UIntPtr").WithLocation(4, 19)); - var refA = comp.ToMetadataReference(); - - var typeA = comp.GetMember("A.F1").Type; - var corLibA = comp.Assembly.CorLibrary; - Assert.Equal(corLibA, typeA.ContainingAssembly); - - var source2 = @"namespace System { - public class Object { } + public class Object + { + public virtual string ToString() => null; + public virtual int GetHashCode() => 0; + public virtual bool Equals(object obj) => false; + } public class String { } - public abstract class ValueType { } + public abstract class ValueType + { + public override string ToString() => null; + public override int GetHashCode() => 0; + public override bool Equals(object obj) => false; + } public struct Void { } public struct Boolean { } public struct Int32 { } - public struct IntPtr { } - public struct UIntPtr { } -}"; - comp = CreateCompilation(new AssemblyIdentity(assemblyName, new Version(2, 0, 0, 0)), new[] { source2 }, references: null); - var ref2 = comp.EmitToImageReference(); - - var sourceB = -@"class B : A -{ - static void Main() + public struct IntPtr { - _ = F1; - _ = F2; - } -}"; - comp = CreateEmptyCompilation(sourceB, references: new[] { ref2, refA }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (5,13): error CS0518: Predefined type 'System.IntPtr' is not defined or imported - // _ = F1; - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "F1").WithArguments("System.IntPtr").WithLocation(5, 13), - // (6,13): error CS0518: Predefined type 'System.UIntPtr' is not defined or imported - // _ = F2; - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "F2").WithArguments("System.UIntPtr").WithLocation(6, 13)); - - var corLibB = comp.Assembly.CorLibrary; - Assert.NotEqual(corLibA, corLibB); - - var f1 = comp.GetMember("A.F1"); - verifyField(f1, "nint A.F1", corLibA); - var f2 = comp.GetMember("A.F2"); - verifyField(f2, "nuint A.F2", corLibA); - - static void verifyField(FieldSymbol field, string expectedSymbol, AssemblySymbol expectedAssembly) - { - Assert.IsType(field); - Assert.Equal(expectedSymbol, field.ToTestDisplayString()); - var type = (NamedTypeSymbol)field.Type; - Assert.True(type.IsNativeIntegerType); - Assert.IsType(type); - Assert.Equal(expectedAssembly, type.NativeIntegerUnderlyingType.ContainingAssembly); - } + public override string ToString() => null; + public override int GetHashCode() => 0; + public override bool Equals(object obj) => false; } - - [Fact] - public void Retargeting_04() + public struct UIntPtr { - var sourceA = -@"public class A -{ -}"; - var assemblyName = GetUniqueName(); - var references = TargetFrameworkUtil.GetReferences(TargetFramework.Standard).ToArray(); - var comp = CreateCompilation(new AssemblyIdentity(assemblyName, new Version(1, 0, 0, 0)), new[] { sourceA }, references: references); - var refA1 = comp.EmitToImageReference(); + public override string ToString() => null; + public override int GetHashCode() => 0; + public override bool Equals(object obj) => false; + } +} +" + RuntimeFeature_NumericIntPtr; - comp = CreateCompilation(new AssemblyIdentity(assemblyName, new Version(2, 0, 0, 0)), new[] { sourceA }, references: references); - var refA2 = comp.EmitToImageReference(); + var comp = CreateEmptyCompilation(sourceA); + comp.VerifyDiagnostics(); + var refA = AsReference(comp, useCompilationReference); var sourceB = -@"public class B -{ - public static A F0 = new A(); - public static nint F1 = int.MinValue; - public static nuint F2 = int.MaxValue; - public static nint F3 = -1; - public static nuint F4 = 1; -}"; - comp = CreateCompilation(sourceB, references: new[] { refA1 }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Standard); - var refB = comp.ToMetadataReference(); - var f0B = comp.GetMember("B.F0"); - var t1B = comp.GetMember("B.F1").Type; - var t2B = comp.GetMember("B.F2").Type; - - var sourceC = -@"class C : B +@"class Program { - static void Main() + static void F1(nint x, nint y) + { + _ = x.ToString(); + _ = x.GetHashCode(); + _ = x.Equals(y); + } + static void F2(nuint x, nuint y) { - _ = F0; - _ = F1; - _ = F2; + _ = x.ToString(); + _ = x.GetHashCode(); + _ = x.Equals(y); } }"; - comp = CreateCompilation(sourceC, references: new[] { refA2, refB }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Standard); + comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); comp.VerifyDiagnostics(); - var f0 = comp.GetMember("B.F0"); - Assert.NotEqual(f0B.Type.ContainingAssembly, f0.Type.ContainingAssembly); - Assert.IsType(f0); - - var f1 = comp.GetMember("B.F1"); - verifyField(f1, "nint B.F1"); - var f2 = comp.GetMember("B.F2"); - verifyField(f2, "nuint B.F2"); - var f3 = comp.GetMember("B.F3"); - verifyField(f3, "nint B.F3"); - var f4 = comp.GetMember("B.F4"); - verifyField(f4, "nuint B.F4"); - - Assert.Same(t1B, f1.Type); - Assert.Same(t2B, f2.Type); - Assert.Same(f1.Type, f3.Type); - Assert.Same(f2.Type, f4.Type); - - static void verifyField(FieldSymbol field, string expectedSymbol) + verifyType((NamedTypeSymbol)comp.GetMember("Program.F1").Parameters[0].Type, signed: true); + verifyType((NamedTypeSymbol)comp.GetMember("Program.F2").Parameters[0].Type, signed: false); + + static void verifyType(NamedTypeSymbol type, bool signed) { - Assert.IsType(field); - Assert.Equal(expectedSymbol, field.ToTestDisplayString()); - var type = (NamedTypeSymbol)field.Type; - Assert.True(type.IsNativeIntegerType); - Assert.IsType(type); + var members = type.GetMembers().Sort(SymbolComparison); + var actualMembers = members.SelectAsArray(m => m.ToTestDisplayString()); + var expectedMembers = new[] + { + $"System.Boolean {type}.Equals(System.Object obj)", + $"System.Int32 {type}.GetHashCode()", + $"System.String {type}.ToString()", + $"{type}..ctor()", + }; + AssertEx.Equal(expectedMembers, actualMembers); } } [Theory] [InlineData(false)] [InlineData(true)] - public void Retargeting_05(bool useCompilationReference) + public void ExplicitImplementations_01(bool useCompilationReference) { - var source1 = + var sourceA = @"namespace System { public class Object { } @@ -1074,68 +550,120 @@ public abstract class ValueType { } public struct Void { } public struct Boolean { } public struct Int32 { } - public struct Enum { } - public class Attribute { } - public class AttributeUsageAttribute : Attribute + public struct Int64 { } + public struct UInt32 { } + public struct UInt64 { } + public interface I { - public AttributeUsageAttribute(AttributeTargets validOn) { } - public bool AllowMultiple { get; set; } - public bool Inherited { get; set; } + T P { get; } + T F(); + } + public struct IntPtr : I + { + IntPtr I.P => this; + IntPtr I.F() => this; + } + public struct UIntPtr : I + { + UIntPtr I.P => this; + UIntPtr I.F() => this; } - public enum AttributeTargets { } - public struct IntPtr { } - public struct UIntPtr { } -}"; - var comp = CreateCompilation(new AssemblyIdentity("9ef8b1e0-1ae0-4af6-b9a1-00f2078f299e", new Version(1, 0, 0, 0)), new[] { source1 }, references: null); - var ref1 = comp.EmitToImageReference(EmitOptions.Default.WithRuntimeMetadataVersion("0.0.0.0")); - - var sourceA = -@"public abstract class A -{ - public abstract void F() where U : T; } -public class B : A -{ - public override void F() { } -}"; - comp = CreateEmptyCompilation(sourceA, references: new[] { ref1 }, parseOptions: TestOptions.Regular9); +" + RuntimeFeature_NumericIntPtr; + + var comp = CreateEmptyCompilation(sourceA); comp.VerifyDiagnostics(); var refA = AsReference(comp, useCompilationReference); - var type1 = getConstraintType(comp); - Assert.True(type1.IsNativeIntegerType); - Assert.False(type1.IsErrorType()); - var sourceB = -@"class C : B +@"using System; +class Program { + static T F1(I t) + { + return default; + } + static I F2(I t) + { + return t; + } + static void M1(nint x) + { + var x1 = F1(x); + var x2 = F2(x).P; + _ = x.P; + _ = x.F(); + } + static void M2(nuint y) + { + var y1 = F1(y); + var y2 = F2(y).P; + _ = y.P; + _ = y.F(); + } + static void M3(System.IntPtr x) + { + var z1 = F1(x); + var z2 = F2(x).P; + _ = x.P; + _ = x.F(); + } + static void M4(System.UIntPtr y) + { + var t1 = F1(y); + var t2 = F2(y).P; + _ = y.P; + _ = y.F(); + } }"; comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); comp.VerifyDiagnostics( - // (1,7): error CS0518: Predefined type 'System.Void' is not defined or imported - // class C : B - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "C").WithArguments("System.Void").WithLocation(1, 7), - // (1,11): error CS0518: Predefined type 'System.IntPtr' is not defined or imported - // class C : B - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "B").WithArguments("System.IntPtr").WithLocation(1, 11), - // (1,11): error CS0012: The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly '9ef8b1e0-1ae0-4af6-b9a1-00f2078f299e, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. - // class C : B - Diagnostic(ErrorCode.ERR_NoTypeDef, "B").WithArguments("System.Object", "9ef8b1e0-1ae0-4af6-b9a1-00f2078f299e, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(1, 11)); - - var type2 = getConstraintType(comp); - Assert.True(type2.ContainingAssembly.IsMissing); - Assert.False(type2.IsNativeIntegerType); - Assert.True(type2.IsErrorType()); + // (16,15): error CS1061: 'nint' does not contain a definition for 'P' and no accessible extension method 'P' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) + // _ = x.P; + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "P").WithArguments("nint", "P").WithLocation(16, 15), + // (17,15): error CS1061: 'nint' does not contain a definition for 'F' and no accessible extension method 'F' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) + // _ = x.F(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("nint", "F").WithLocation(17, 15), + // (23,15): error CS1061: 'nuint' does not contain a definition for 'P' and no accessible extension method 'P' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) + // _ = y.P; + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "P").WithArguments("nuint", "P").WithLocation(23, 15), + // (24,15): error CS1061: 'nuint' does not contain a definition for 'F' and no accessible extension method 'F' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) + // _ = y.F(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("nuint", "F").WithLocation(24, 15), + // (30,15): error CS1061: 'nint' does not contain a definition for 'P' and no accessible extension method 'P' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) + // _ = x.P; + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "P").WithArguments("nint", "P").WithLocation(30, 15), + // (31,15): error CS1061: 'nint' does not contain a definition for 'F' and no accessible extension method 'F' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) + // _ = x.F(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("nint", "F").WithLocation(31, 15), + // (37,15): error CS1061: 'nuint' does not contain a definition for 'P' and no accessible extension method 'P' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) + // _ = y.P; + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "P").WithArguments("nuint", "P").WithLocation(37, 15), + // (38,15): error CS1061: 'nuint' does not contain a definition for 'F' and no accessible extension method 'F' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) + // _ = y.F(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("nuint", "F").WithLocation(38, 15)); - static TypeSymbol getConstraintType(CSharpCompilation comp) => - comp.GetMember("B.F").TypeParameters[0].ConstraintTypesNoUseSiteDiagnostics[0].Type; + var tree = comp.SyntaxTrees[0]; + var model = comp.GetSemanticModel(tree); + var actualLocals = tree.GetRoot().DescendantNodes().OfType().Select(d => model.GetDeclaredSymbol(d).ToTestDisplayString()); + var expectedLocals = new[] + { + "nint x1", + "nint x2", + "nuint y1", + "nuint y2", + "nint z1", + "nint z2", + "nuint t1", + "nuint t2", + }; + AssertEx.Equal(expectedLocals, actualLocals); } [Fact] - [WorkItem(49845, "https://github.com/dotnet/roslyn/issues/49845")] - public void Retargeting_06() + public void NonPublicMembers_InternalUse() { - var source1 = + var source = @"namespace System { public class Object { } @@ -1144,64 +672,55 @@ public abstract class ValueType { } public struct Void { } public struct Boolean { } public struct Int32 { } - public class IntPtr { } - public class UIntPtr { } - - public class Attribute {} - - public class Enum {} - public enum AttributeTargets - { - Class = 0x4, - } - - [AttributeUsage(AttributeTargets.Class, Inherited = true)] - public sealed class AttributeUsageAttribute : Attribute + public struct IntPtr { - public bool AllowMultiple {get; set;} - public bool Inherited {get; set;} - public AttributeTargets ValidOn => 0; - public AttributeUsageAttribute(AttributeTargets validOn) + private static IntPtr F1() => default; + internal IntPtr F2() => default; + public static IntPtr F3() { + nint i = 0; + _ = nint.F1(); + _ = i.F2(); + return nint.F3(); + } + public static nint F4() + { + IntPtr i = 0; + _ = IntPtr.F1(); + _ = i.F2(); + return IntPtr.F3(); } } -}"; - var comp = CreateCompilation(new AssemblyIdentity("c804cc09-8f73-44a1-9cfe-9567bed1def6", new Version(1, 0, 0, 0)), new[] { source1 }, references: null); - var ref1 = comp.EmitToImageReference(); - - var sourceA = -@"public class A : nint -{ -}"; - comp = CreateEmptyCompilation(sourceA, references: new[] { ref1 }, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(); - - var refA = comp.ToMetadataReference(); - var typeA = comp.GetMember("A").BaseTypeNoUseSiteDiagnostics; - Assert.True(typeA.IsNativeIntegerType); - Assert.False(typeA.IsErrorType()); - - var sourceB = -@"class B : A -{ -}"; - comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (1,7): error CS0518: Predefined type 'System.Void' is not defined or imported - // class B : A - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "B").WithArguments("System.Void").WithLocation(1, 7), - // (1,11): error CS0012: The type 'IntPtr' is defined in an assembly that is not referenced. You must add a reference to assembly 'c804cc09-8f73-44a1-9cfe-9567bed1def6, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. - // class B : A - Diagnostic(ErrorCode.ERR_NoTypeDef, "A").WithArguments("System.IntPtr", "c804cc09-8f73-44a1-9cfe-9567bed1def6, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(1, 11)); + public struct UIntPtr + { + private static UIntPtr F1() => default; + internal UIntPtr F2() => default; + public static UIntPtr F3() + { + nuint i = 0; + _ = nuint.F1(); + _ = i.F2(); + return nuint.F3(); + } + public static nuint F4() + { + UIntPtr i = 0; + _ = UIntPtr.F1(); + _ = i.F2(); + return UIntPtr.F3(); + } + } +} +" + RuntimeFeature_NumericIntPtr; - var typeB = comp.GetMember("A").BaseTypeNoUseSiteDiagnostics; - Assert.True(typeB.ContainingAssembly.IsMissing); - Assert.False(typeB.IsNativeIntegerType); - Assert.True(typeB.IsErrorType()); + var comp = CreateEmptyCompilation(source, parseOptions: TestOptions.Regular9); + comp.VerifyDiagnostics(); } - [Fact] - public void Interfaces() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void NonPublicMembers(bool useCompilationReference) { var sourceA = @"namespace System @@ -1212,6451 +731,4084 @@ public abstract class ValueType { } public struct Void { } public struct Boolean { } public struct Int32 { } - public interface ISerializable { } - public interface IEquatable + public struct IntPtr { - bool Equals(T other); + private static IntPtr F1() => default; + internal IntPtr F2() => default; + public static IntPtr F3() => default; } - public interface IOther { } - public struct IntPtr : ISerializable, IEquatable, IOther + public struct UIntPtr { - bool IEquatable.Equals(IntPtr other) => false; + private static UIntPtr F1() => default; + internal UIntPtr F2() => default; + public static UIntPtr F3() => default; } -}"; +} +" + RuntimeFeature_NumericIntPtr; + + var comp = CreateEmptyCompilation(sourceA); + comp.VerifyDiagnostics(); + var refA = AsReference(comp, useCompilationReference); + var sourceB = @"using System; class Program { - static void F0(ISerializable i) { } - static object F1(IEquatable i) => default; - static void F2(IEquatable i) { } - static void F3(IOther i) { } - static void Main() + static void F1(nint x) { - nint n = 42; - F0(n); - F1(n); - F2(n); - F3(n); - F3(n); - F3((IntPtr)n); + _ = nint.F1(); + _ = x.F2(); + _ = nint.F3(); + } + static void F2(nuint y) + { + _ = nuint.F1(); + _ = y.F2(); + _ = nuint.F3(); + } + static void F3(IntPtr x) + { + _ = IntPtr.F1(); + _ = x.F2(); + _ = IntPtr.F3(); + } + static void F4(UIntPtr y) + { + _ = UIntPtr.F1(); + _ = y.F2(); + _ = UIntPtr.F3(); } }"; - var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); + comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); + if (useCompilationReference) + { + comp.VerifyDiagnostics( + // (6,18): error CS0122: 'nint.F1()' is inaccessible due to its protection level + // _ = nint.F1(); + Diagnostic(ErrorCode.ERR_BadAccess, "F1").WithArguments("nint.F1()").WithLocation(6, 18), + // (7,15): error CS0122: 'nint.F2()' is inaccessible due to its protection level + // _ = x.F2(); + Diagnostic(ErrorCode.ERR_BadAccess, "F2").WithArguments("nint.F2()").WithLocation(7, 15), + // (12,19): error CS0122: 'nuint.F1()' is inaccessible due to its protection level + // _ = nuint.F1(); + Diagnostic(ErrorCode.ERR_BadAccess, "F1").WithArguments("nuint.F1()").WithLocation(12, 19), + // (13,15): error CS0122: 'nuint.F2()' is inaccessible due to its protection level + // _ = y.F2(); + Diagnostic(ErrorCode.ERR_BadAccess, "F2").WithArguments("nuint.F2()").WithLocation(13, 15), + // (18,20): error CS0122: 'nint.F1()' is inaccessible due to its protection level + // _ = IntPtr.F1(); + Diagnostic(ErrorCode.ERR_BadAccess, "F1").WithArguments("nint.F1()").WithLocation(18, 20), + // (19,15): error CS0122: 'nint.F2()' is inaccessible due to its protection level + // _ = x.F2(); + Diagnostic(ErrorCode.ERR_BadAccess, "F2").WithArguments("nint.F2()").WithLocation(19, 15), + // (24,21): error CS0122: 'nuint.F1()' is inaccessible due to its protection level + // _ = UIntPtr.F1(); + Diagnostic(ErrorCode.ERR_BadAccess, "F1").WithArguments("nuint.F1()").WithLocation(24, 21), + // (25,15): error CS0122: 'nuint.F2()' is inaccessible due to its protection level + // _ = y.F2(); + Diagnostic(ErrorCode.ERR_BadAccess, "F2").WithArguments("nuint.F2()").WithLocation(25, 15)); + } + else + { + comp.VerifyDiagnostics( + // (6,18): error CS0117: 'nint' does not contain a definition for 'F1' + // _ = nint.F1(); + Diagnostic(ErrorCode.ERR_NoSuchMember, "F1").WithArguments("nint", "F1").WithLocation(6, 18), + // (7,15): error CS1061: 'nint' does not contain a definition for 'F2' and no accessible extension method 'F2' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) + // _ = x.F2(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F2").WithArguments("nint", "F2").WithLocation(7, 15), + // (12,19): error CS0117: 'nuint' does not contain a definition for 'F1' + // _ = nuint.F1(); + Diagnostic(ErrorCode.ERR_NoSuchMember, "F1").WithArguments("nuint", "F1").WithLocation(12, 19), + // (13,15): error CS1061: 'nuint' does not contain a definition for 'F2' and no accessible extension method 'F2' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) + // _ = y.F2(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F2").WithArguments("nuint", "F2").WithLocation(13, 15), + // (18,20): error CS0117: 'nint' does not contain a definition for 'F1' + // _ = IntPtr.F1(); + Diagnostic(ErrorCode.ERR_NoSuchMember, "F1").WithArguments("nint", "F1").WithLocation(18, 20), + // (19,15): error CS1061: 'nint' does not contain a definition for 'F2' and no accessible extension method 'F2' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) + // _ = x.F2(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F2").WithArguments("nint", "F2").WithLocation(19, 15), + // (24,21): error CS0117: 'nuint' does not contain a definition for 'F1' + // _ = UIntPtr.F1(); + Diagnostic(ErrorCode.ERR_NoSuchMember, "F1").WithArguments("nuint", "F1").WithLocation(24, 21), + // (25,15): error CS1061: 'nuint' does not contain a definition for 'F2' and no accessible extension method 'F2' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) + // _ = y.F2(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F2").WithArguments("nuint", "F2").WithLocation(25, 15)); + } } [Fact] - public void IEquatable() + public void Overrides_01() { - // Minimal definitions. - verifyAll(includesIEquatable: true, -@"namespace System + var sourceA = +@"public interface IA { - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public interface IEquatable { } - public struct IntPtr : IEquatable { } - public struct UIntPtr : IEquatable { } -}"); - - // IEquatable in global namespace. - verifyAll(includesIEquatable: false, -@"public interface IEquatable { } -namespace System + void F1(nint x, System.UIntPtr y); +} +public abstract class A { - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct IntPtr : IEquatable { } - public struct UIntPtr : IEquatable { } -}"); - - // IEquatable in other namespace. - verifyAll(includesIEquatable: false, -@"namespace Other + public abstract void F2(System.IntPtr x, nuint y); +}"; + var sourceB = +@"class B1 : A, IA { - public interface IEquatable { } + public void F1(nint x, System.UIntPtr y) { } + public override void F2(System.IntPtr x, nuint y) { } } -namespace System -{ - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct IntPtr : Other.IEquatable { } - public struct UIntPtr : Other.IEquatable { } -}"); - - // IEquatable nested in "System" type. - verifyAll(includesIEquatable: false, -@"namespace System +class B2 : A, IA { - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public class System - { - public interface IEquatable { } - } - public struct IntPtr : System.IEquatable { } - public struct UIntPtr : System.IEquatable { } -}"); - - // IEquatable nested in other type. - verifyAll(includesIEquatable: false, -@"namespace System + public void F1(System.IntPtr x, nuint y) { } + public override void F2(nint x, System.UIntPtr y) { } +} +class A3 : IA { - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public class Other - { - public interface IEquatable { } - } - public struct IntPtr : Other.IEquatable { } - public struct UIntPtr : Other.IEquatable { } -}"); - - // IEquatable. - verifyAll(includesIEquatable: false, -@"namespace System + void IA.F1(nint x, System.UIntPtr y) { } +} +class A4 : IA { - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public interface IEquatable { } - public struct IntPtr : IEquatable { } - public struct UIntPtr : IEquatable { } -}"); + void IA.F1(System.IntPtr x, nuint y) { } +}"; - // IEquatable. - verifyAll(includesIEquatable: false, -@"namespace System -{ - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public interface IEquatable { } - public struct IntPtr : IEquatable { } - public struct UIntPtr : IEquatable { } -}"); + var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(); - // IEquatable and IEquatable - verifyAll(includesIEquatable: false, -@"namespace System -{ - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public interface IEquatable { } - public struct IntPtr : IEquatable { } - public struct UIntPtr : IEquatable { } -}"); + comp = CreateEmptyCompilation(sourceA, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(); + var ref1 = comp.ToMetadataReference(); + var ref2 = comp.EmitToImageReference(); - // IEquatable and IEquatable. - verifyAll(includesIEquatable: false, -@"namespace System -{ - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public interface IEquatable { } - public struct IntPtr : IEquatable { } - public struct UIntPtr : IEquatable { } -}"); + comp = CreateEmptyCompilation(sourceB, references: new[] { ref1, MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(); - // IEquatable and IEquatable. - var comp = CreateEmptyCompilation( -@"namespace System -{ - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct Enum { } - public class Attribute { } - public class AttributeUsageAttribute : Attribute - { - public AttributeUsageAttribute(AttributeTargets validOn) { } - public bool AllowMultiple { get; set; } - public bool Inherited { get; set; } + comp = CreateEmptyCompilation(sourceB, references: new[] { ref2, MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(); } - public enum AttributeTargets { } - public interface IEquatable { } - public struct IntPtr : IEquatable { } - public struct UIntPtr : IEquatable { } -}", - parseOptions: TestOptions.Regular9); - verifyReference(comp.EmitToImageReference(EmitOptions.Default.WithRuntimeMetadataVersion("0.0.0.0")), includesIEquatable: true); - // IEquatable and IEquatable. - comp = CreateEmptyCompilation( -@"namespace System -{ - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct Enum { } - public class Attribute { } - public class AttributeUsageAttribute : Attribute + [Fact] + public void Overloads_01() { - public AttributeUsageAttribute(AttributeTargets validOn) { } - public bool AllowMultiple { get; set; } - public bool Inherited { get; set; } - } - public enum AttributeTargets { } - public interface IEquatable { } - public struct IntPtr : IEquatable { } - public struct UIntPtr : IEquatable { } -}", - parseOptions: TestOptions.Regular9); - verifyReference(comp.EmitToImageReference(EmitOptions.Default.WithRuntimeMetadataVersion("0.0.0.0")), includesIEquatable: false); - - static void verifyAll(bool includesIEquatable, string sourceA) - { - var sourceB = -@"interface I + var sourceA = +@"public class A { - nint F1(); - nuint F2(); + public void F1(System.IntPtr x) { } + public void F2(nuint y) { } }"; - var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - verifyCompilation(comp, includesIEquatable); - - comp = CreateEmptyCompilation(sourceA); - comp.VerifyDiagnostics(); - var ref1 = comp.ToMetadataReference(); - var ref2 = comp.EmitToImageReference(); - - comp = CreateEmptyCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - verifyCompilation(comp, includesIEquatable); - - comp = CreateEmptyCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - verifyCompilation(comp, includesIEquatable); - } - - static void verifyReference(MetadataReference reference, bool includesIEquatable) - { - var sourceB = -@"interface I + var sourceB = +@"class B1 : A +{ + public void F1(nuint x) { } + public void F2(System.IntPtr y) { } +} +class B2 : A +{ + public void F1(nint x) { base.F1(x); } + public void F2(System.UIntPtr y) { base.F2(y); } +} +class B3 : A +{ + public new void F1(nuint x) { } + public new void F2(System.IntPtr y) { } +} +class B4 : A { - nint F1(); - nuint F2(); + public new void F1(nint x) { base.F1(x); } + public new void F2(System.UIntPtr y) { base.F2(y); } }"; - var comp = CreateEmptyCompilation(sourceB, references: new[] { reference }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - verifyCompilation(comp, includesIEquatable); - } - - static void verifyCompilation(CSharpCompilation comp, bool includesIEquatable) - { - verifyInterfaces(comp, (NamedTypeSymbol)comp.GetMember("I.F1").ReturnType, SpecialType.System_IntPtr, includesIEquatable); - verifyInterfaces(comp, (NamedTypeSymbol)comp.GetMember("I.F2").ReturnType, SpecialType.System_UIntPtr, includesIEquatable); - } - static void verifyInterfaces(CSharpCompilation comp, NamedTypeSymbol type, SpecialType specialType, bool includesIEquatable) + var diagnostics = new[] { - var underlyingType = type.NativeIntegerUnderlyingType; - - Assert.True(type.IsNativeIntegerType); - Assert.Equal(specialType, underlyingType.SpecialType); + // (8,17): warning CS0108: 'B2.F1(nint)' hides inherited member 'A.F1(nint)'. Use the new keyword if hiding was intended. + // public void F1(nint x) { base.F1(x); } + Diagnostic(ErrorCode.WRN_NewRequired, "F1").WithArguments("B2.F1(nint)", "A.F1(nint)").WithLocation(8, 17), + // (9,17): warning CS0108: 'B2.F2(nuint)' hides inherited member 'A.F2(nuint)'. Use the new keyword if hiding was intended. + // public void F2(System.UIntPtr y) { base.F2(y); } + Diagnostic(ErrorCode.WRN_NewRequired, "F2").WithArguments("B2.F2(nuint)", "A.F2(nuint)").WithLocation(9, 17), + // (13,21): warning CS0109: The member 'B3.F1(nuint)' does not hide an accessible member. The new keyword is not required. + // public new void F1(nuint x) { } + Diagnostic(ErrorCode.WRN_NewNotRequired, "F1").WithArguments("B3.F1(nuint)").WithLocation(13, 21), + // (14,21): warning CS0109: The member 'B3.F2(nint)' does not hide an accessible member. The new keyword is not required. + // public new void F2(System.IntPtr y) { } + Diagnostic(ErrorCode.WRN_NewNotRequired, "F2").WithArguments("B3.F2(nint)").WithLocation(14, 21) + }; + + var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(diagnostics); - var interfaces = type.InterfacesNoUseSiteDiagnostics(null); - Assert.Equal(interfaces, type.GetDeclaredInterfaces(null)); - VerifyInterfaces(underlyingType, underlyingType.InterfacesNoUseSiteDiagnostics(null), type, interfaces); + comp = CreateEmptyCompilation(sourceA, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(); + var ref1 = comp.ToMetadataReference(); + var ref2 = comp.EmitToImageReference(); - Assert.Equal(1, interfaces.Length); + comp = CreateEmptyCompilation(sourceB, references: new[] { ref1, MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(diagnostics); - if (includesIEquatable) - { - var @interface = interfaces.Single(); - var def = comp.GetWellKnownType(WellKnownType.System_IEquatable_T); - Assert.NotNull(def); - Assert.Equal(def, @interface.OriginalDefinition); - Assert.Equal(type, @interface.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics[0].Type); - } - } + comp = CreateEmptyCompilation(sourceB, references: new[] { ref2, MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(diagnostics); } [Fact] - public void CreateNativeIntegerTypeSymbol_FromMetadata() + public void Partial_01() { - var comp = CreateCompilation(""); + var source = +@"partial class Program +{ + static partial void F1(System.IntPtr x); + static partial void F2(System.UIntPtr x) { } + static partial void F1(nint x) { } + static partial void F2(nuint x); +}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseDll.WithWarningLevel(5), parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(); + + comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseDll.WithWarningLevel(6), parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; comp.VerifyDiagnostics(); - VerifyCreateNativeIntegerTypeSymbol(comp); } [Fact] - public void CreateNativeIntegerTypeSymbol_FromSource() + public void Constraints_01() { - var source0 = -@"namespace System + var sourceA = +@"public class A { - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct IntPtr { } - public struct UIntPtr { } + public static void F() where U : T { } +} +public class B1 : A { } +public class B2 : A { } +public class B3 : A { } +public class B4 : A { } +"; + var sourceB = +@"class Program +{ + static void Main() + { + B1.F(); + B2.F(); + B3.F(); + B4.F(); + } }"; - var comp = CreateEmptyCompilation(source0, parseOptions: TestOptions.Regular9); + + var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; comp.VerifyDiagnostics(); - VerifyCreateNativeIntegerTypeSymbol(comp); + comp = CreateEmptyCompilation(sourceA, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(); var ref1 = comp.ToMetadataReference(); var ref2 = comp.EmitToImageReference(); - comp = CreateEmptyCompilation("", references: new[] { ref1 }, parseOptions: TestOptions.Regular9); + comp = CreateEmptyCompilation(sourceB, references: new[] { ref1, MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; comp.VerifyDiagnostics(); - VerifyCreateNativeIntegerTypeSymbol(comp); - comp = CreateEmptyCompilation("", references: new[] { ref2 }, parseOptions: TestOptions.Regular9); + comp = CreateEmptyCompilation(sourceB, references: new[] { ref2, MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; comp.VerifyDiagnostics(); - VerifyCreateNativeIntegerTypeSymbol(comp); } - private static void VerifyCreateNativeIntegerTypeSymbol(CSharpCompilation comp) + [Fact] + public void AttributeType_01() { - verifyInternalType(comp, signed: true); - verifyInternalType(comp, signed: false); - verifyPublicType(comp, signed: true); - verifyPublicType(comp, signed: false); - - static void verifyInternalType(CSharpCompilation comp, bool signed) + var source = +@"[nint] +[A, nuint()] +class Program +{ +} +class AAttribute : System.Attribute +{ +}"; + var expectedDiagnostics = new[] { - var type = comp.CreateNativeIntegerTypeSymbol(signed); - VerifyType(type, signed, isNativeInt: true); - } + // (1,2): error CS0246: The type or namespace name 'nintAttribute' could not be found (are you missing a using directive or an assembly reference?) + // [nint] + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "nint").WithArguments("nintAttribute").WithLocation(1, 2), + // (1,2): error CS0246: The type or namespace name 'nint' could not be found (are you missing a using directive or an assembly reference?) + // [nint] + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "nint").WithArguments("nint").WithLocation(1, 2), + // (2,5): error CS0246: The type or namespace name 'nuintAttribute' could not be found (are you missing a using directive or an assembly reference?) + // [A, nuint] + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "nuint").WithArguments("nuintAttribute").WithLocation(2, 5), + // (2,5): error CS0246: The type or namespace name 'nuint' could not be found (are you missing a using directive or an assembly reference?) + // [A, nuint] + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "nuint").WithArguments("nuint").WithLocation(2, 5) + }; + + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular8); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(expectedDiagnostics); - static void verifyPublicType(Compilation comp, bool signed) - { - var type = comp.CreateNativeIntegerTypeSymbol(signed); - VerifyType(type, signed, isNativeInt: true); - - var underlyingType = type.NativeIntegerUnderlyingType; - Assert.NotNull(underlyingType); - Assert.Equal(CodeAnalysis.NullableAnnotation.NotAnnotated, underlyingType.NullableAnnotation); - Assert.Same(underlyingType, ((INamedTypeSymbol)type.WithNullableAnnotation(CodeAnalysis.NullableAnnotation.None)).NativeIntegerUnderlyingType); - Assert.Same(underlyingType, ((INamedTypeSymbol)type.WithNullableAnnotation(CodeAnalysis.NullableAnnotation.Annotated)).NativeIntegerUnderlyingType); - Assert.Same(underlyingType, ((INamedTypeSymbol)type.WithNullableAnnotation(CodeAnalysis.NullableAnnotation.NotAnnotated)).NativeIntegerUnderlyingType); - } + comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(expectedDiagnostics); } [Fact] - public void CreateNativeIntegerTypeSymbol_Missing() + public void NameOf_01() { - var source0 = -@"namespace System + var source = +@"using System; +class Program { - public class Object { } - public abstract class ValueType { } - public struct Void { } + static void Main() + { + Console.WriteLine(nameof(nint)); + Console.WriteLine(nameof(nuint)); + } }"; - var comp = CreateEmptyCompilation(source0, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - verifyCreateNativeIntegerTypeSymbol(comp); - var ref1 = comp.ToMetadataReference(); - var ref2 = comp.EmitToImageReference(); - - comp = CreateEmptyCompilation("", references: new[] { ref1 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - verifyCreateNativeIntegerTypeSymbol(comp); - comp = CreateEmptyCompilation("", references: new[] { ref2 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - verifyCreateNativeIntegerTypeSymbol(comp); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - static void verifyCreateNativeIntegerTypeSymbol(CSharpCompilation comp) - { - VerifyErrorType(comp.CreateNativeIntegerTypeSymbol(signed: true), SpecialType.System_IntPtr, isNativeInt: true); - VerifyErrorType(comp.CreateNativeIntegerTypeSymbol(signed: false), SpecialType.System_UIntPtr, isNativeInt: true); - VerifyErrorType(((Compilation)comp).CreateNativeIntegerTypeSymbol(signed: true), SpecialType.System_IntPtr, isNativeInt: true); - VerifyErrorType(((Compilation)comp).CreateNativeIntegerTypeSymbol(signed: false), SpecialType.System_UIntPtr, isNativeInt: true); - } + comp.VerifyDiagnostics( + // (6,34): error CS0103: The name 'nint' does not exist in the current context + // Console.WriteLine(nameof(nint)); + Diagnostic(ErrorCode.ERR_NameNotInContext, "nint").WithArguments("nint").WithLocation(6, 34), + // (7,34): error CS0103: The name 'nuint' does not exist in the current context + // Console.WriteLine(nameof(nuint)); + Diagnostic(ErrorCode.ERR_NameNotInContext, "nuint").WithArguments("nuint").WithLocation(7, 34)); } - /// - /// Static members Zero, Size, Add(), Subtract() are explicitly excluded from nint and nuint. - /// Other static members are implicitly included on nint and nuint. - /// - [Theory] - [InlineData(false)] - [InlineData(true)] - public void StaticMembers(bool useCompilationReference) + [Fact] + public void NameOf_04() { - var sourceA = -@"namespace System + var source = +@"class Program { - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct IntPtr - { - public static readonly IntPtr Zero; - public static int Size => 0; - public static IntPtr MaxValue => default; - public static IntPtr MinValue => default; - public static IntPtr Add(IntPtr ptr, int offset) => default; - public static IntPtr Subtract(IntPtr ptr, int offset) => default; - public static IntPtr Parse(string s) => default; - public static bool TryParse(string s, out IntPtr value) - { - value = default; - return false; - } - } - public struct UIntPtr + static void F(int @nint, uint @nuint) { - public static readonly UIntPtr Zero; - public static int Size => 0; - public static UIntPtr MaxValue => default; - public static UIntPtr MinValue => default; - public static UIntPtr Add(UIntPtr ptr, int offset) => default; - public static UIntPtr Subtract(UIntPtr ptr, int offset) => default; - public static UIntPtr Parse(string s) => default; - public static bool TryParse(string s, out UIntPtr value) - { - value = default; - return false; - } + _ = nameof(@nint); + _ = nameof(@nuint); } }"; - var comp = CreateEmptyCompilation(sourceA); + + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular8); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; comp.VerifyDiagnostics(); - var refA = AsReference(comp, useCompilationReference); - var sourceB = + comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(); + } + + [Fact] + public void SizeOf_01() + { + var source = @"class Program { - static nint F1() - { - _ = nint.Zero; - _ = nint.Size; - var x1 = nint.MaxValue; - var x2 = nint.MinValue; - _ = nint.Add(x1, 2); - _ = nint.Subtract(x1, 3); - var x3 = nint.Parse(null); - _ = nint.TryParse(null, out var x4); - return 0; - } - static nuint F2() + static void Main() { - _ = nuint.Zero; - _ = nuint.Size; - var y1 = nuint.MaxValue; - var y2 = nuint.MinValue; - _ = nuint.Add(y1, 2); - _ = nuint.Subtract(y1, 3); - var y3 = nuint.Parse(null); - _ = nuint.TryParse(null, out var y4); - return 0; + _ = sizeof(System.IntPtr); + _ = sizeof(System.UIntPtr); + _ = sizeof(nint); + _ = sizeof(nuint); } }"; - comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (5,18): error CS0117: 'nint' does not contain a definition for 'Zero' - // _ = nint.Zero; - Diagnostic(ErrorCode.ERR_NoSuchMember, "Zero").WithArguments("nint", "Zero").WithLocation(5, 18), - // (6,18): error CS0117: 'nint' does not contain a definition for 'Size' - // _ = nint.Size; - Diagnostic(ErrorCode.ERR_NoSuchMember, "Size").WithArguments("nint", "Size").WithLocation(6, 18), - // (9,18): error CS0117: 'nint' does not contain a definition for 'Add' - // _ = nint.Add(x1, x2); - Diagnostic(ErrorCode.ERR_NoSuchMember, "Add").WithArguments("nint", "Add").WithLocation(9, 18), - // (10,18): error CS0117: 'nint' does not contain a definition for 'Subtract' - // _ = nint.Subtract(x1, x2); - Diagnostic(ErrorCode.ERR_NoSuchMember, "Subtract").WithArguments("nint", "Subtract").WithLocation(10, 18), - // (17,19): error CS0117: 'nuint' does not contain a definition for 'Zero' - // _ = nuint.Zero; - Diagnostic(ErrorCode.ERR_NoSuchMember, "Zero").WithArguments("nuint", "Zero").WithLocation(17, 19), - // (18,19): error CS0117: 'nuint' does not contain a definition for 'Size' - // _ = nuint.Size; - Diagnostic(ErrorCode.ERR_NoSuchMember, "Size").WithArguments("nuint", "Size").WithLocation(18, 19), - // (21,19): error CS0117: 'nuint' does not contain a definition for 'Add' - // _ = nuint.Add(y1, y2); - Diagnostic(ErrorCode.ERR_NoSuchMember, "Add").WithArguments("nuint", "Add").WithLocation(21, 19), - // (22,19): error CS0117: 'nuint' does not contain a definition for 'Subtract' - // _ = nuint.Subtract(y1, y2); - Diagnostic(ErrorCode.ERR_NoSuchMember, "Subtract").WithArguments("nuint", "Subtract").WithLocation(22, 19)); - - verifyType((NamedTypeSymbol)comp.GetMember("Program.F1").ReturnType, signed: true); - verifyType((NamedTypeSymbol)comp.GetMember("Program.F2").ReturnType, signed: false); - - var tree = comp.SyntaxTrees[0]; - var model = comp.GetSemanticModel(tree); - var actualLocals = tree.GetRoot().DescendantNodes().OfType().Select(d => model.GetDeclaredSymbol(d).ToTestDisplayString()); - var expectedLocals = new[] - { - "nint x1", - "nint x2", - "nint x3", - "nuint y1", - "nuint y2", - "nuint y3", - }; - AssertEx.Equal(expectedLocals, actualLocals); - - static void verifyType(NamedTypeSymbol type, bool signed) - { - Assert.True(type.IsNativeIntegerType); - - VerifyType(type, signed: signed, isNativeInt: true); - VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); - - var members = type.GetMembers().Sort(SymbolComparison); - var actualMembers = members.SelectAsArray(m => m.ToTestDisplayString()); - var expectedMembers = new[] - { - $"System.Boolean {type}.TryParse(System.String s, out {type} value)", - $"{type} {type}.MaxValue {{ get; }}", - $"{type} {type}.MaxValue.get", - $"{type} {type}.MinValue {{ get; }}", - $"{type} {type}.MinValue.get", - $"{type} {type}.Parse(System.String s)", - $"{type}..ctor()", - }; - AssertEx.Equal(expectedMembers, actualMembers); - - var property = (PropertySymbol)members.Single(m => m.Name == "MaxValue"); - var getMethod = (MethodSymbol)members.Single(m => m.Name == "get_MaxValue"); - Assert.Same(getMethod, property.GetMethod); - Assert.Null(property.SetMethod); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - var underlyingType = type.NativeIntegerUnderlyingType; - VerifyMembers(underlyingType, type, signed); - VerifyMembers(underlyingType.GetPublicSymbol(), type.GetPublicSymbol(), signed); - } + comp.VerifyDiagnostics( + // (5,13): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // _ = sizeof(System.IntPtr); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(System.IntPtr)").WithArguments("nint").WithLocation(5, 13), + // (6,13): error CS0233: 'nuint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // _ = sizeof(System.UIntPtr); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(System.UIntPtr)").WithArguments("nuint").WithLocation(6, 13), + // (7,13): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // _ = sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(7, 13), + // (8,13): error CS0233: 'nuint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // _ = sizeof(nuint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nuint)").WithArguments("nuint").WithLocation(8, 13)); } - /// - /// Instance members ToInt32(), ToInt64(), ToPointer() are explicitly excluded from nint and nuint. - /// Other instance members are implicitly included on nint and nuint. - /// - [Theory] - [InlineData(false)] - [InlineData(true)] - public void InstanceMembers(bool useCompilationReference) + [Fact] + public void SizeOf_02() { - var sourceA = -@"namespace System + var source = +@"using System; +class Program { - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct Int64 { } - public struct UInt32 { } - public struct UInt64 { } - public interface IFormatProvider { } - public struct IntPtr - { - public int ToInt32() => default; - public long ToInt64() => default; - public uint ToUInt32() => default; - public ulong ToUInt64() => default; - unsafe public void* ToPointer() => default; - public int CompareTo(object other) => default; - public int CompareTo(IntPtr other) => default; - public bool Equals(IntPtr other) => default; - public string ToString(string format) => default; - public string ToString(IFormatProvider provider) => default; - public string ToString(string format, IFormatProvider provider) => default; - } - public struct UIntPtr + unsafe static void Main() { - public int ToInt32() => default; - public long ToInt64() => default; - public uint ToUInt32() => default; - public ulong ToUInt64() => default; - unsafe public void* ToPointer() => default; - public int CompareTo(object other) => default; - public int CompareTo(UIntPtr other) => default; - public bool Equals(UIntPtr other) => default; - public string ToString(string format) => default; - public string ToString(IFormatProvider provider) => default; - public string ToString(string format, IFormatProvider provider) => default; + Console.Write(sizeof(System.IntPtr)); + Console.Write(sizeof(System.UIntPtr)); + Console.Write(sizeof(nint)); + Console.Write(sizeof(nuint)); } }"; - var comp = CreateEmptyCompilation(sourceA, options: TestOptions.UnsafeReleaseDll); - comp.VerifyDiagnostics(); - var refA = AsReference(comp, useCompilationReference); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.UnsafeReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + int size = IntPtr.Size; + var verifier = CompileAndVerify(comp, expectedOutput: $"{size}{size}{size}{size}"); + verifier.VerifyIL("Program.Main", +@"{ + // Code size 45 (0x2d) + .maxstack 1 + IL_0000: sizeof ""nint"" + IL_0006: call ""void System.Console.Write(int)"" + IL_000b: sizeof ""nuint"" + IL_0011: call ""void System.Console.Write(int)"" + IL_0016: sizeof ""nint"" + IL_001c: call ""void System.Console.Write(int)"" + IL_0021: sizeof ""nuint"" + IL_0027: call ""void System.Console.Write(int)"" + IL_002c: ret +}"); + } - var sourceB = -@"using System; -class Program -{ - unsafe static void F1(nint i) + [Fact] + public void SizeOf_03() { - _ = i.ToInt32(); - _ = i.ToInt64(); - _ = i.ToUInt32(); - _ = i.ToUInt64(); - _ = i.ToPointer(); - _ = i.CompareTo(null); - _ = i.CompareTo(i); - _ = i.Equals(i); - _ = i.ToString((string)null); - _ = i.ToString((IFormatProvider)null); - _ = i.ToString((string)null, (IFormatProvider)null); - } - unsafe static void F2(nuint u) + var source = +@"using System.Collections.Generic; +unsafe class Program +{ + static IEnumerable F() { - _ = u.ToInt32(); - _ = u.ToInt64(); - _ = u.ToUInt32(); - _ = u.ToUInt64(); - _ = u.ToPointer(); - _ = u.CompareTo(null); - _ = u.CompareTo(u); - _ = u.Equals(u); - _ = u.ToString((string)null); - _ = u.ToString((IFormatProvider)null); - _ = u.ToString((string)null, (IFormatProvider)null); + yield return sizeof(nint); + yield return sizeof(nuint); + yield return sizeof(System.IntPtr); + yield return sizeof(System.UIntPtr); } }"; - comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9, options: TestOptions.UnsafeReleaseDll); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; comp.VerifyDiagnostics( - // (6,15): error CS1061: 'nint' does not contain a definition for 'ToInt32' and no accessible extension method 'ToInt32' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // _ = i.ToInt32(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToInt32").WithArguments("nint", "ToInt32").WithLocation(6, 15), - // (7,15): error CS1061: 'nint' does not contain a definition for 'ToInt64' and no accessible extension method 'ToInt64' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // _ = i.ToInt64(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToInt64").WithArguments("nint", "ToInt64").WithLocation(7, 15), - // (8,15): error CS1061: 'nint' does not contain a definition for 'ToUInt32' and no accessible extension method 'ToUInt32' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // _ = i.ToUInt32(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToUInt32").WithArguments("nint", "ToUInt32").WithLocation(8, 15), - // (9,15): error CS1061: 'nint' does not contain a definition for 'ToUInt64' and no accessible extension method 'ToUInt64' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // _ = i.ToUInt64(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToUInt64").WithArguments("nint", "ToUInt64").WithLocation(9, 15), - // (10,15): error CS1061: 'nint' does not contain a definition for 'ToPointer' and no accessible extension method 'ToPointer' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // _ = i.ToPointer(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToPointer").WithArguments("nint", "ToPointer").WithLocation(10, 15), - // (20,15): error CS1061: 'nuint' does not contain a definition for 'ToInt32' and no accessible extension method 'ToInt32' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) - // _ = u.ToInt32(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToInt32").WithArguments("nuint", "ToInt32").WithLocation(20, 15), - // (21,15): error CS1061: 'nuint' does not contain a definition for 'ToInt64' and no accessible extension method 'ToInt64' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) - // _ = u.ToInt64(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToInt64").WithArguments("nuint", "ToInt64").WithLocation(21, 15), - // (22,15): error CS1061: 'nuint' does not contain a definition for 'ToUInt32' and no accessible extension method 'ToUInt32' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) - // _ = u.ToUInt32(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToUInt32").WithArguments("nuint", "ToUInt32").WithLocation(22, 15), - // (23,15): error CS1061: 'nuint' does not contain a definition for 'ToUInt64' and no accessible extension method 'ToUInt64' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) - // _ = u.ToUInt64(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToUInt64").WithArguments("nuint", "ToUInt64").WithLocation(23, 15), - // (24,15): error CS1061: 'nuint' does not contain a definition for 'ToPointer' and no accessible extension method 'ToPointer' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) - // _ = u.ToPointer(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToPointer").WithArguments("nuint", "ToPointer").WithLocation(24, 15)); - - verifyType((NamedTypeSymbol)comp.GetMember("Program.F1").Parameters[0].Type, signed: true); - verifyType((NamedTypeSymbol)comp.GetMember("Program.F2").Parameters[0].Type, signed: false); - - static void verifyType(NamedTypeSymbol type, bool signed) - { - Assert.True(type.IsNativeIntegerType); - - VerifyType(type, signed: signed, isNativeInt: true); - VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); - - var members = type.GetMembers().Sort(SymbolComparison); - var actualMembers = members.SelectAsArray(m => m.ToTestDisplayString()); - var expectedMembers = new[] - { - $"System.Boolean {type}.Equals({type} other)", - $"System.Int32 {type}.CompareTo(System.Object other)", - $"System.Int32 {type}.CompareTo({type} other)", - $"System.String {type}.ToString(System.IFormatProvider provider)", - $"System.String {type}.ToString(System.String format)", - $"System.String {type}.ToString(System.String format, System.IFormatProvider provider)", - $"{type}..ctor()", - }; - AssertEx.Equal(expectedMembers, actualMembers); - - var underlyingType = type.NativeIntegerUnderlyingType; - VerifyMembers(underlyingType, type, signed); - VerifyMembers(underlyingType.GetPublicSymbol(), type.GetPublicSymbol(), signed); - } + // (6,22): error CS1629: Unsafe code may not appear in iterators + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "sizeof(nint)").WithLocation(6, 22), + // (7,22): error CS1629: Unsafe code may not appear in iterators + // yield return sizeof(nuint); + Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "sizeof(nuint)").WithLocation(7, 22), + // (8,22): error CS1629: Unsafe code may not appear in iterators + // yield return sizeof(System.IntPtr); + Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "sizeof(System.IntPtr)").WithLocation(8, 22), + // (9,22): error CS1629: Unsafe code may not appear in iterators + // yield return sizeof(System.UIntPtr); + Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "sizeof(System.UIntPtr)").WithLocation(9, 22)); } - /// - /// Instance members ToInt32(), ToInt64(), ToPointer() are explicitly excluded from nint and nuint. - /// Other instance members are implicitly included on nint and nuint. - /// - [Theory] - [InlineData(false)] - [InlineData(true)] - public void ConstructorsAndOperators(bool useCompilationReference) + [Fact] + public void TypeOf() { - var sourceA = -@"namespace System + var source = +@"using static System.Console; +class Program { - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct Int64 { } - public struct UInt32 { } - public struct UInt64 { } - public unsafe struct IntPtr + static void Main() { - public IntPtr(int i) { } - public IntPtr(long l) { } - public IntPtr(void* p) { } - public static explicit operator IntPtr(int i) => default; - public static explicit operator IntPtr(long l) => default; - public static explicit operator IntPtr(void* p) => default; - public static explicit operator int(IntPtr i) => default; - public static explicit operator long(IntPtr i) => default; - public static explicit operator void*(IntPtr i) => default; - public static IntPtr operator+(IntPtr x, int y) => default; - public static IntPtr operator-(IntPtr x, int y) => default; - public static bool operator==(IntPtr x, IntPtr y) => default; - public static bool operator!=(IntPtr x, IntPtr y) => default; + var t1 = typeof(nint); + var t2 = typeof(nuint); + var t3 = typeof(System.IntPtr); + var t4 = typeof(System.UIntPtr); + WriteLine(t1.FullName); + WriteLine(t2.FullName); + WriteLine((object)t1 == t2); + WriteLine((object)t1 == t3); + WriteLine((object)t2 == t4); } - public unsafe struct UIntPtr +}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + CompileAndVerify(comp, expectedOutput: +@"System.IntPtr +System.UIntPtr +False +True +True"); + } + + [Fact] + public void Volatile() { - public UIntPtr(uint i) { } - public UIntPtr(ulong l) { } - public UIntPtr(void* p) { } - public static explicit operator UIntPtr(uint i) => default; - public static explicit operator UIntPtr(ulong l) => default; - public static explicit operator UIntPtr(void* p) => default; - public static explicit operator uint(UIntPtr i) => default; - public static explicit operator ulong(UIntPtr i) => default; - public static explicit operator void*(UIntPtr i) => default; - public static UIntPtr operator+(UIntPtr x, int y) => default; - public static UIntPtr operator-(UIntPtr x, int y) => default; - public static bool operator==(UIntPtr x, UIntPtr y) => default; - public static bool operator!=(UIntPtr x, UIntPtr y) => default; + var source = +@"using System; +class Program +{ + static volatile IntPtr F1 = -1; + static volatile UIntPtr F2 = 2; + static IntPtr F() => F1 + (IntPtr)F2; + static void Main() + { + System.Console.WriteLine(F()); } }"; - var comp = CreateEmptyCompilation(sourceA, options: TestOptions.UnsafeReleaseDll); - comp.VerifyDiagnostics( - // (12,26): warning CS0660: 'IntPtr' defines operator == or operator != but does not override Object.Equals(object o) - // public unsafe struct IntPtr - Diagnostic(ErrorCode.WRN_EqualityOpWithoutEquals, "IntPtr").WithArguments("System.IntPtr").WithLocation(12, 26), - // (12,26): warning CS0661: 'IntPtr' defines operator == or operator != but does not override Object.GetHashCode() - // public unsafe struct IntPtr - Diagnostic(ErrorCode.WRN_EqualityOpWithoutGetHashCode, "IntPtr").WithArguments("System.IntPtr").WithLocation(12, 26), - // (28,26): warning CS0660: 'UIntPtr' defines operator == or operator != but does not override Object.Equals(object o) - // public unsafe struct UIntPtr - Diagnostic(ErrorCode.WRN_EqualityOpWithoutEquals, "UIntPtr").WithArguments("System.UIntPtr").WithLocation(28, 26), - // (28,26): warning CS0661: 'UIntPtr' defines operator == or operator != but does not override Object.GetHashCode() - // public unsafe struct UIntPtr - Diagnostic(ErrorCode.WRN_EqualityOpWithoutGetHashCode, "UIntPtr").WithArguments("System.UIntPtr").WithLocation(28, 26)); - var refA = AsReference(comp, useCompilationReference); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + var verifier = CompileAndVerify(comp, expectedOutput: @"1"); + verifier.VerifyIL("Program.F", +@"{ + // Code size 17 (0x11) + .maxstack 2 + IL_0000: volatile. + IL_0002: ldsfld ""nint Program.F1"" + IL_0007: volatile. + IL_0009: ldsfld ""nuint Program.F2"" + IL_000e: conv.i + IL_000f: add + IL_0010: ret +}"); + } - var sourceB = + [Fact] + public void MultipleTypeRefs_01() + { + string source = @"class Program { - unsafe static void F1(nint x, nint y) + static string F1(nint i) { - void* p = default; - _ = new nint(); - _ = new nint(1); - _ = new nint(2L); - _ = new nint(p); - _ = (nint)1; - _ = (nint)2L; - _ = (nint)p; - _ = (int)x; - _ = (long)x; - _ = (void*)x; - _ = x + 1; - _ = x - 2; - _ = x == y; - _ = x != y; + return i.ToString(); } - unsafe static void F2(nuint x, nuint y) + static object F2(nint i) { - void* p = default; - _ = new nuint(); - _ = new nuint(1); - _ = new nuint(2UL); - _ = new nuint(p); - _ = (nuint)1; - _ = (nuint)2UL; - _ = (nuint)p; - _ = (uint)x; - _ = (ulong)x; - _ = (void*)x; - _ = x + 1; - _ = x - 2; - _ = x == y; - _ = x != y; + return i; + } + static void Main() + { + System.Console.WriteLine(F1(-42)); + System.Console.WriteLine(F2(42)); } }"; - comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9, options: TestOptions.UnsafeReleaseDll); - comp.VerifyDiagnostics( - // (7,17): error CS1729: 'nint' does not contain a constructor that takes 1 arguments - // _ = new nint(1); - Diagnostic(ErrorCode.ERR_BadCtorArgCount, "nint").WithArguments("nint", "1").WithLocation(7, 17), - // (8,17): error CS1729: 'nint' does not contain a constructor that takes 1 arguments - // _ = new nint(2L); - Diagnostic(ErrorCode.ERR_BadCtorArgCount, "nint").WithArguments("nint", "1").WithLocation(8, 17), - // (9,17): error CS1729: 'nint' does not contain a constructor that takes 1 arguments - // _ = new nint(p); - Diagnostic(ErrorCode.ERR_BadCtorArgCount, "nint").WithArguments("nint", "1").WithLocation(9, 17), - // (25,17): error CS1729: 'nuint' does not contain a constructor that takes 1 arguments - // _ = new nuint(1); - Diagnostic(ErrorCode.ERR_BadCtorArgCount, "nuint").WithArguments("nuint", "1").WithLocation(25, 17), - // (26,17): error CS1729: 'nuint' does not contain a constructor that takes 1 arguments - // _ = new nuint(2UL); - Diagnostic(ErrorCode.ERR_BadCtorArgCount, "nuint").WithArguments("nuint", "1").WithLocation(26, 17), - // (27,17): error CS1729: 'nuint' does not contain a constructor that takes 1 arguments - // _ = new nuint(p); - Diagnostic(ErrorCode.ERR_BadCtorArgCount, "nuint").WithArguments("nuint", "1").WithLocation(27, 17)); - - verifyType((NamedTypeSymbol)comp.GetMember("Program.F1").Parameters[0].Type, signed: true); - verifyType((NamedTypeSymbol)comp.GetMember("Program.F2").Parameters[0].Type, signed: false); - - static void verifyType(NamedTypeSymbol type, bool signed) - { - Assert.True(type.IsNativeIntegerType); - - VerifyType(type, signed: signed, isNativeInt: true); - VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); - - var members = type.GetMembers().Sort(SymbolComparison); - var actualMembers = members.SelectAsArray(m => m.ToTestDisplayString()); - var expectedMembers = new[] - { - $"{type}..ctor()", - }; - AssertEx.Equal(expectedMembers, actualMembers); - - var underlyingType = type.NativeIntegerUnderlyingType; - VerifyMembers(underlyingType, type, signed); - VerifyMembers(underlyingType.GetPublicSymbol(), type.GetPublicSymbol(), signed); - } + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + var verifier = CompileAndVerify(comp, expectedOutput: +@"-42 +42"); + verifier.VerifyIL("Program.F1", +@"{ + // Code size 8 (0x8) + .maxstack 1 + IL_0000: ldarga.s V_0 + IL_0002: call ""string nint.ToString()"" + IL_0007: ret +}"); + verifier.VerifyIL("Program.F2", +@"{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""nint"" + IL_0006: ret +}"); } /// - /// Overrides from IntPtr and UIntPtr are implicitly included on nint and nuint. + /// Verify there is the number of built in operators for { IntPtr, UIntPtr, IntPtr?, UIntPtr? } + /// for each operator kind. /// - [Theory] - [InlineData(false)] - [InlineData(true)] - public void OverriddenMembers(bool useCompilationReference) - { - var sourceA = -@"namespace System -{ - public class Object - { - public virtual string ToString() => null; - public virtual int GetHashCode() => 0; - public virtual bool Equals(object obj) => false; - } - public class String { } - public abstract class ValueType - { - public override string ToString() => null; - public override int GetHashCode() => 0; - public override bool Equals(object obj) => false; - } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct IntPtr - { - public override string ToString() => null; - public override int GetHashCode() => 0; - public override bool Equals(object obj) => false; - } - public struct UIntPtr + [Fact] + public void BuiltInOperators() { - public override string ToString() => null; - public override int GetHashCode() => 0; - public override bool Equals(object obj) => false; - } -}"; - var comp = CreateEmptyCompilation(sourceA); - comp.VerifyDiagnostics(); - var refA = AsReference(comp, useCompilationReference); + var comp = CreateEmptyCompilation("", new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - var sourceB = -@"class Program -{ - static void F1(nint x, nint y) - { - _ = x.ToString(); - _ = x.GetHashCode(); - _ = x.Equals(y); - } - static void F2(nuint x, nuint y) - { - _ = x.ToString(); - _ = x.GetHashCode(); - _ = x.Equals(y); - } -}"; - comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); comp.VerifyDiagnostics(); + verifyOperators(comp); - verifyType((NamedTypeSymbol)comp.GetMember("Program.F1").Parameters[0].Type, signed: true); - verifyType((NamedTypeSymbol)comp.GetMember("Program.F2").Parameters[0].Type, signed: false); - - static void verifyType(NamedTypeSymbol type, bool signed) + static void verifyOperators(CSharpCompilation comp) { - Assert.True(type.IsNativeIntegerType); - - VerifyType(type, signed: signed, isNativeInt: true); - VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); - - var members = type.GetMembers().Sort(SymbolComparison); - var actualMembers = members.SelectAsArray(m => m.ToTestDisplayString()); - var expectedMembers = new[] + var unaryOperators = new[] { - $"System.Boolean {type}.Equals(System.Object obj)", - $"System.Int32 {type}.GetHashCode()", - $"System.String {type}.ToString()", - $"{type}..ctor()", - }; - AssertEx.Equal(expectedMembers, actualMembers); - - var underlyingType = type.NativeIntegerUnderlyingType; - VerifyMembers(underlyingType, type, signed); - VerifyMembers(underlyingType.GetPublicSymbol(), type.GetPublicSymbol(), signed); - } - } + UnaryOperatorKind.PostfixIncrement, + UnaryOperatorKind.PostfixDecrement, + UnaryOperatorKind.PrefixIncrement, + UnaryOperatorKind.PrefixDecrement, + UnaryOperatorKind.UnaryPlus, + UnaryOperatorKind.UnaryMinus, + UnaryOperatorKind.BitwiseComplement, + }; - [Theory] - [InlineData(false)] - [InlineData(true)] - public void ExplicitImplementations_01(bool useCompilationReference) - { - var sourceA = -@"namespace System -{ - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct Int64 { } - public struct UInt32 { } - public struct UInt64 { } - public interface I - { - T P { get; } - T F(); - } - public struct IntPtr : I - { - IntPtr I.P => this; - IntPtr I.F() => this; - } - public struct UIntPtr : I - { - UIntPtr I.P => this; - UIntPtr I.F() => this; - } -}"; - var comp = CreateEmptyCompilation(sourceA); - comp.VerifyDiagnostics(); - var refA = AsReference(comp, useCompilationReference); + var binaryOperators = new[] + { + BinaryOperatorKind.Addition, + BinaryOperatorKind.Subtraction, + BinaryOperatorKind.Multiplication, + BinaryOperatorKind.Division, + BinaryOperatorKind.Remainder, + BinaryOperatorKind.LessThan, + BinaryOperatorKind.LessThanOrEqual, + BinaryOperatorKind.GreaterThan, + BinaryOperatorKind.GreaterThanOrEqual, + BinaryOperatorKind.LeftShift, + BinaryOperatorKind.RightShift, + BinaryOperatorKind.Equal, + BinaryOperatorKind.NotEqual, + BinaryOperatorKind.Or, + BinaryOperatorKind.And, + BinaryOperatorKind.Xor, + BinaryOperatorKind.UnsignedRightShift, + }; - var sourceB = -@"using System; -class Program -{ - static T F1(I t) - { - return default; - } - static I F2(I t) - { - return t; - } - static void M1(nint x) - { - var x1 = F1(x); - var x2 = F2(x).P; - _ = x.P; - _ = x.F(); - } - static void M2(nuint y) - { - var y1 = F1(y); - var y2 = F2(y).P; - _ = y.P; - _ = y.F(); - } -}"; - comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (16,15): error CS1061: 'nint' does not contain a definition for 'P' and no accessible extension method 'P' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // _ = x.P; - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "P").WithArguments("nint", "P").WithLocation(16, 15), - // (17,15): error CS1061: 'nint' does not contain a definition for 'F' and no accessible extension method 'F' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // _ = x.F(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("nint", "F").WithLocation(17, 15), - // (23,15): error CS1061: 'nuint' does not contain a definition for 'P' and no accessible extension method 'P' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) - // _ = y.P; - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "P").WithArguments("nuint", "P").WithLocation(23, 15), - // (24,15): error CS1061: 'nuint' does not contain a definition for 'F' and no accessible extension method 'F' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) - // _ = y.F(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("nuint", "F").WithLocation(24, 15)); + foreach (var operatorKind in unaryOperators) + { + verifyUnaryOperators(comp, operatorKind, skipNativeIntegerOperators: true); + verifyUnaryOperators(comp, operatorKind, skipNativeIntegerOperators: false); + } - var tree = comp.SyntaxTrees[0]; - var model = comp.GetSemanticModel(tree); - var actualLocals = tree.GetRoot().DescendantNodes().OfType().Select(d => model.GetDeclaredSymbol(d).ToTestDisplayString()); - var expectedLocals = new[] - { - "nint x1", - "nint x2", - "nuint y1", - "nuint y2", - }; - AssertEx.Equal(expectedLocals, actualLocals); + foreach (var operatorKind in binaryOperators) + { + verifyBinaryOperators(comp, operatorKind, skipNativeIntegerOperators: true); + verifyBinaryOperators(comp, operatorKind, skipNativeIntegerOperators: false); + } - verifyType((NamedTypeSymbol)comp.GetMember("Program.M1").Parameters[0].Type, signed: true); - verifyType((NamedTypeSymbol)comp.GetMember("Program.M2").Parameters[0].Type, signed: false); + static void verifyUnaryOperators(CSharpCompilation comp, UnaryOperatorKind operatorKind, bool skipNativeIntegerOperators) + { + var builder = ArrayBuilder.GetInstance(); + comp.builtInOperators.GetSimpleBuiltInOperators(operatorKind, builder, skipNativeIntegerOperators); + var operators = builder.ToImmutableAndFree(); + int expectedSigned = skipNativeIntegerOperators ? 0 : 1; + int expectedUnsigned = skipNativeIntegerOperators ? 0 : (operatorKind == UnaryOperatorKind.UnaryMinus) ? 0 : 1; + verifyOperators(operators, (op, signed) => isNativeInt(op.OperandType, signed), expectedSigned, expectedUnsigned); + verifyOperators(operators, (op, signed) => isNullableNativeInt(op.OperandType, signed), expectedSigned, expectedUnsigned); + } - static void verifyType(NamedTypeSymbol type, bool signed) - { - Assert.True(type.IsNativeIntegerType); + static void verifyBinaryOperators(CSharpCompilation comp, BinaryOperatorKind operatorKind, bool skipNativeIntegerOperators) + { + var builder = ArrayBuilder.GetInstance(); + comp.builtInOperators.GetSimpleBuiltInOperators(operatorKind, builder, skipNativeIntegerOperators); + var operators = builder.ToImmutableAndFree(); + int expected = skipNativeIntegerOperators ? 0 : 1; + verifyOperators(operators, (op, signed) => isNativeInt(op.LeftType, signed), expected, expected); + verifyOperators(operators, (op, signed) => isNullableNativeInt(op.LeftType, signed), expected, expected); + } - VerifyType(type, signed: signed, isNativeInt: true); - VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); + static void verifyOperators(ImmutableArray operators, Func predicate, int expectedSigned, int expectedUnsigned) + { + Assert.Equal(expectedSigned, operators.Count(op => predicate(op, true))); + Assert.Equal(expectedUnsigned, operators.Count(op => predicate(op, false))); + } - var underlyingType = type.NativeIntegerUnderlyingType; - var members = type.GetMembers().Sort(SymbolComparison); - var actualMembers = members.SelectAsArray(m => m.ToTestDisplayString()); - var expectedMembers = new[] + static bool isNativeInt(TypeSymbol type, bool signed) { - $"{type}..ctor()", - }; - AssertEx.Equal(expectedMembers, actualMembers); + return type.SpecialType == (signed ? SpecialType.System_IntPtr : SpecialType.System_UIntPtr); + } - VerifyMembers(underlyingType, type, signed); - VerifyMembers(underlyingType.GetPublicSymbol(), type.GetPublicSymbol(), signed); + static bool isNullableNativeInt(TypeSymbol type, bool signed) + { + return type.IsNullableType() && isNativeInt(type.GetNullableUnderlyingType(), signed); + } } } - [Fact] - public void ExplicitImplementations_02() - { - var sourceA = -@"Namespace System - Public Class [Object] - End Class - Public Class [String] - End Class - Public MustInherit Class ValueType - End Class - Public Structure Void - End Structure - Public Structure [Boolean] - End Structure - Public Structure Int32 - End Structure - Public Structure Int64 - End Structure - Public Structure UInt32 - End Structure - Public Structure UInt64 - End Structure - Public Interface I(Of T) - ReadOnly Property P As T - Function F() As T - End Interface - Public Structure IntPtr - Implements I(Of IntPtr) - Public ReadOnly Property P As IntPtr Implements I(Of IntPtr).P - Get - Return Nothing - End Get - End Property - Public Function F() As IntPtr Implements I(Of IntPtr).F - Return Nothing - End Function - End Structure - Public Structure UIntPtr - Implements I(Of UIntPtr) - Public ReadOnly Property P As UIntPtr Implements I(Of UIntPtr).P - Get - Return Nothing - End Get - End Property - Public Function F() As UIntPtr Implements I(Of UIntPtr).F - Return Nothing - End Function - End Structure -End Namespace"; - var compA = CreateVisualBasicCompilation(sourceA, referencedAssemblies: Array.Empty()); - compA.VerifyDiagnostics(); - var refA = compA.EmitToImageReference(); + // [WorkItem(3259, "https://github.com/dotnet/csharplang/issues/3259")] + // [Theory] + // [InlineData(false)] + // [InlineData(true)] + // public void BuiltInConversions_CSharp8(bool useCompilationReference) + // { + // var sourceA = + //@"public class A + //{ + // public static nint F1; + // public static nuint F2; + // public static nint? F3; + // public static nuint? F4; + //}"; + // var sourceB = + //@"class B : A + //{ + // static void M1() + // { + // long x = F1; + // ulong y = F2; + // long? z = F3; + // ulong? w = F4; + // } + // static void M2(int x, uint y, int? z, uint? w) + // { + // F1 = x; + // F2 = y; + // F3 = z; + // F4 = w; + // } + //}"; + // var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); + // var refA = AsReference(comp, useCompilationReference); + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); + // comp.VerifyDiagnostics(); + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); + // comp.VerifyDiagnostics(); + // var verifier = CompileAndVerify(comp); + // verifier.VerifyIL("B.M1", + //@"{ + // // Code size 59 (0x3b) + // .maxstack 1 + // .locals init (nint? V_0, + // nuint? V_1) + // IL_0000: ldsfld ""nint A.F1"" + // IL_0005: pop + // IL_0006: ldsfld ""nuint A.F2"" + // IL_000b: pop + // IL_000c: ldsfld ""nint? A.F3"" + // IL_0011: stloc.0 + // IL_0012: ldloca.s V_0 + // IL_0014: call ""bool nint?.HasValue.get"" + // IL_0019: brfalse.s IL_0023 + // IL_001b: ldloca.s V_0 + // IL_001d: call ""nint nint?.GetValueOrDefault()"" + // IL_0022: pop + // IL_0023: ldsfld ""nuint? A.F4"" + // IL_0028: stloc.1 + // IL_0029: ldloca.s V_1 + // IL_002b: call ""bool nuint?.HasValue.get"" + // IL_0030: brfalse.s IL_003a + // IL_0032: ldloca.s V_1 + // IL_0034: call ""nuint nuint?.GetValueOrDefault()"" + // IL_0039: pop + // IL_003a: ret + //}"); + // verifier.VerifyIL("B.M2", + //@"{ + // // Code size 95 (0x5f) + // .maxstack 1 + // .locals init (int? V_0, + // nint? V_1, + // uint? V_2, + // nuint? V_3) + // IL_0000: ldarg.0 + // IL_0001: conv.i + // IL_0002: stsfld ""nint A.F1"" + // IL_0007: ldarg.1 + // IL_0008: conv.u + // IL_0009: stsfld ""nuint A.F2"" + // IL_000e: ldarg.2 + // IL_000f: stloc.0 + // IL_0010: ldloca.s V_0 + // IL_0012: call ""bool int?.HasValue.get"" + // IL_0017: brtrue.s IL_0024 + // IL_0019: ldloca.s V_1 + // IL_001b: initobj ""nint?"" + // IL_0021: ldloc.1 + // IL_0022: br.s IL_0031 + // IL_0024: ldloca.s V_0 + // IL_0026: call ""int int?.GetValueOrDefault()"" + // IL_002b: conv.i + // IL_002c: newobj ""nint?..ctor(nint)"" + // IL_0031: stsfld ""nint? A.F3"" + // IL_0036: ldarg.3 + // IL_0037: stloc.2 + // IL_0038: ldloca.s V_2 + // IL_003a: call ""bool uint?.HasValue.get"" + // IL_003f: brtrue.s IL_004c + // IL_0041: ldloca.s V_3 + // IL_0043: initobj ""nuint?"" + // IL_0049: ldloc.3 + // IL_004a: br.s IL_0059 + // IL_004c: ldloca.s V_2 + // IL_004e: call ""uint uint?.GetValueOrDefault()"" + // IL_0053: conv.u + // IL_0054: newobj ""nuint?..ctor(nuint)"" + // IL_0059: stsfld ""nuint? A.F4"" + // IL_005e: ret + //}"); + // } + + // [WorkItem(3259, "https://github.com/dotnet/csharplang/issues/3259")] + // [Theory] + // [InlineData(false)] + // [InlineData(true)] + // public void BuiltInOperators_CSharp8(bool useCompilationReference) + // { + // var sourceA = + //@"public class A + //{ + // public static nint F1; + // public static nuint F2; + // public static nint? F3; + // public static nuint? F4; + //}"; + // var sourceB = + //@"class B : A + //{ + // static void Main() + // { + // _ = -F1; + // _ = +F2; + // _ = -F3; + // _ = +F4; + // _ = F1 * F1; + // _ = F2 / F2; + // _ = F3 * F1; + // _ = F4 / F2; + // } + //}"; + // var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); + // var refA = AsReference(comp, useCompilationReference); + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); + // comp.VerifyDiagnostics(); + // var verifier = CompileAndVerify(comp); + // verifier.VerifyIL("B.Main", + //@"{ + // // Code size 143 (0x8f) + // .maxstack 2 + // .locals init (nint? V_0, + // nuint? V_1, + // System.IntPtr V_2, + // System.UIntPtr V_3) + // IL_0000: ldsfld ""nint A.F1"" + // IL_0005: pop + // IL_0006: ldsfld ""nuint A.F2"" + // IL_000b: pop + // IL_000c: ldsfld ""nint? A.F3"" + // IL_0011: stloc.0 + // IL_0012: ldloca.s V_0 + // IL_0014: call ""bool nint?.HasValue.get"" + // IL_0019: brfalse.s IL_0023 + // IL_001b: ldloca.s V_0 + // IL_001d: call ""nint nint?.GetValueOrDefault()"" + // IL_0022: pop + // IL_0023: ldsfld ""nuint? A.F4"" + // IL_0028: stloc.1 + // IL_0029: ldloca.s V_1 + // IL_002b: call ""bool nuint?.HasValue.get"" + // IL_0030: brfalse.s IL_003a + // IL_0032: ldloca.s V_1 + // IL_0034: call ""nuint nuint?.GetValueOrDefault()"" + // IL_0039: pop + // IL_003a: ldsfld ""nint A.F1"" + // IL_003f: pop + // IL_0040: ldsfld ""nint A.F1"" + // IL_0045: pop + // IL_0046: ldsfld ""nuint A.F2"" + // IL_004b: ldsfld ""nuint A.F2"" + // IL_0050: div.un + // IL_0051: pop + // IL_0052: ldsfld ""nint? A.F3"" + // IL_0057: stloc.0 + // IL_0058: ldsfld ""nint A.F1"" + // IL_005d: stloc.2 + // IL_005e: ldloca.s V_0 + // IL_0060: call ""bool nint?.HasValue.get"" + // IL_0065: brfalse.s IL_006f + // IL_0067: ldloca.s V_0 + // IL_0069: call ""nint nint?.GetValueOrDefault()"" + // IL_006e: pop + // IL_006f: ldsfld ""nuint? A.F4"" + // IL_0074: stloc.1 + // IL_0075: ldsfld ""nuint A.F2"" + // IL_007a: stloc.3 + // IL_007b: ldloca.s V_1 + // IL_007d: call ""bool nuint?.HasValue.get"" + // IL_0082: brfalse.s IL_008e + // IL_0084: ldloca.s V_1 + // IL_0086: call ""nuint nuint?.GetValueOrDefault()"" + // IL_008b: ldloc.3 + // IL_008c: div.un + // IL_008d: pop + // IL_008e: ret + //}"); + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); + // comp.VerifyEmitDiagnostics( + // // (5,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = -F1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "-F1").WithArguments("native-sized integers", "9.0").WithLocation(5, 13), + // // (6,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = +F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "+F2").WithArguments("native-sized integers", "9.0").WithLocation(6, 13), + // // (7,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = -F3; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "-F3").WithArguments("native-sized integers", "9.0").WithLocation(7, 13), + // // (8,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = +F4; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "+F4").WithArguments("native-sized integers", "9.0").WithLocation(8, 13), + // // (9,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 * F1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 * F1").WithArguments("native-sized integers", "9.0").WithLocation(9, 13), + // // (10,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F2 / F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F2 / F2").WithArguments("native-sized integers", "9.0").WithLocation(10, 13), + // // (11,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F3 * F1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F3 * F1").WithArguments("native-sized integers", "9.0").WithLocation(11, 13), + // // (12,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F4 / F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F4 / F2").WithArguments("native-sized integers", "9.0").WithLocation(12, 13)); + // } + + // [Fact] + // public void BuiltInConversions_UnderlyingTypes() + // { + // var source = + //@"class A + //{ + // static System.IntPtr F1; + // static System.UIntPtr F2; + // static System.IntPtr? F3; + // static System.UIntPtr? F4; + // static void M1() + // { + // long x = F1; + // ulong y = F2; + // long? z = F3; + // ulong? w = F4; + // } + // static void M2(int x, uint y, int? z, uint? w) + // { + // F1 = x; + // F2 = y; + // F3 = z; + // F4 = w; + // } + //}"; + // var diagnostics = new[] + // { + // // (9,18): error CS0266: Cannot implicitly convert type 'System.IntPtr' to 'long'. An explicit conversion exists (are you missing a cast?) + // // long x = F1; + // Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "F1").WithArguments("System.IntPtr", "long").WithLocation(9, 18), + // // (10,19): error CS0266: Cannot implicitly convert type 'System.UIntPtr' to 'ulong'. An explicit conversion exists (are you missing a cast?) + // // ulong y = F2; + // Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "F2").WithArguments("System.UIntPtr", "ulong").WithLocation(10, 19), + // // (11,19): error CS0266: Cannot implicitly convert type 'System.IntPtr?' to 'long?'. An explicit conversion exists (are you missing a cast?) + // // long? z = F3; + // Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "F3").WithArguments("System.IntPtr?", "long?").WithLocation(11, 19), + // // (12,20): error CS0266: Cannot implicitly convert type 'System.UIntPtr?' to 'ulong?'. An explicit conversion exists (are you missing a cast?) + // // ulong? w = F4; + // Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "F4").WithArguments("System.UIntPtr?", "ulong?").WithLocation(12, 20), + // // (16,14): error CS0266: Cannot implicitly convert type 'int' to 'System.IntPtr'. An explicit conversion exists (are you missing a cast?) + // // F1 = x; + // Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("int", "System.IntPtr").WithLocation(16, 14), + // // (17,14): error CS0266: Cannot implicitly convert type 'uint' to 'System.UIntPtr'. An explicit conversion exists (are you missing a cast?) + // // F2 = y; + // Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "y").WithArguments("uint", "System.UIntPtr").WithLocation(17, 14), + // // (18,14): error CS0266: Cannot implicitly convert type 'int?' to 'System.IntPtr?'. An explicit conversion exists (are you missing a cast?) + // // F3 = z; + // Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "z").WithArguments("int?", "System.IntPtr?").WithLocation(18, 14), + // // (19,14): error CS0266: Cannot implicitly convert type 'uint?' to 'System.UIntPtr?'. An explicit conversion exists (are you missing a cast?) + // // F4 = w; + // Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "w").WithArguments("uint?", "System.UIntPtr?").WithLocation(19, 14) + // }; + + // var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); + // comp.VerifyDiagnostics(diagnostics); + + // comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); + // comp.VerifyDiagnostics(diagnostics); + // } + + // [WorkItem(3259, "https://github.com/dotnet/csharplang/issues/3259")] + // [Fact] + // public void BuiltInOperators_UnderlyingTypes() + // { + // var source = + //@"#pragma warning disable 649 + //class A + //{ + // static System.IntPtr F1; + // static System.UIntPtr F2; + // static System.IntPtr? F3; + // static System.UIntPtr? F4; + // static void Main() + // { + // F1 = -F1; + // F2 = +F2; + // F3 = -F3; + // F4 = +F4; + // F1 = F1 * F1; + // F2 = F2 / F2; + // F3 = F3 * F1; + // F4 = F4 / F2; + // } + //}"; + // var diagnostics = new[] + // { + // // (10,14): error CS0023: Operator '-' cannot be applied to operand of type 'IntPtr' + // // F1 = -F1; + // Diagnostic(ErrorCode.ERR_BadUnaryOp, "-F1").WithArguments("-", "System.IntPtr").WithLocation(10, 14), + // // (11,14): error CS0023: Operator '+' cannot be applied to operand of type 'UIntPtr' + // // F2 = +F2; + // Diagnostic(ErrorCode.ERR_BadUnaryOp, "+F2").WithArguments("+", "System.UIntPtr").WithLocation(11, 14), + // // (12,14): error CS0023: Operator '-' cannot be applied to operand of type 'IntPtr?' + // // F3 = -F3; + // Diagnostic(ErrorCode.ERR_BadUnaryOp, "-F3").WithArguments("-", "System.IntPtr?").WithLocation(12, 14), + // // (13,14): error CS0023: Operator '+' cannot be applied to operand of type 'UIntPtr?' + // // F4 = +F4; + // Diagnostic(ErrorCode.ERR_BadUnaryOp, "+F4").WithArguments("+", "System.UIntPtr?").WithLocation(13, 14), + // // (14,14): error CS0019: Operator '*' cannot be applied to operands of type 'IntPtr' and 'IntPtr' + // // F1 = F1 * F1; + // Diagnostic(ErrorCode.ERR_BadBinaryOps, "F1 * F1").WithArguments("*", "System.IntPtr", "System.IntPtr").WithLocation(14, 14), + // // (15,14): error CS0019: Operator '/' cannot be applied to operands of type 'UIntPtr' and 'UIntPtr' + // // F2 = F2 / F2; + // Diagnostic(ErrorCode.ERR_BadBinaryOps, "F2 / F2").WithArguments("/", "System.UIntPtr", "System.UIntPtr").WithLocation(15, 14), + // // (16,14): error CS0019: Operator '*' cannot be applied to operands of type 'IntPtr?' and 'IntPtr' + // // F3 = F3 * F1; + // Diagnostic(ErrorCode.ERR_BadBinaryOps, "F3 * F1").WithArguments("*", "System.IntPtr?", "System.IntPtr").WithLocation(16, 14), + // // (17,14): error CS0019: Operator '/' cannot be applied to operands of type 'UIntPtr?' and 'UIntPtr' + // // F4 = F4 / F2; + // Diagnostic(ErrorCode.ERR_BadBinaryOps, "F4 / F2").WithArguments("/", "System.UIntPtr?", "System.UIntPtr").WithLocation(17, 14) + // }; + + // var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); + // comp.VerifyDiagnostics(diagnostics); + + // comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); + // comp.VerifyDiagnostics(diagnostics); + // } + + // [WorkItem(3259, "https://github.com/dotnet/csharplang/issues/3259")] + // [Theory] + // [InlineData(false, false)] + // [InlineData(true, false)] + // [InlineData(false, true)] + // [InlineData(true, true)] + // public void BuiltInConversions_NativeIntegers(bool useCompilationReference, bool useLatest) + // { + // var sourceA = + //@"public class A + //{ + // public static nint F1; + // public static nuint F2; + // public static nint? F3; + // public static nuint? F4; + //}"; + // var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); + // comp.VerifyDiagnostics(); + + // var sourceB = + //@"class B : A + //{ + // static void M1() + // { + // long x = F1; + // ulong y = F2; + // long? z = F3; + // ulong? w = F4; + // } + // static void M2(int x, uint y, int? z, uint? w) + // { + // F1 = x; + // F2 = y; + // F3 = z; + // F4 = w; + // } + //}"; + // comp = CreateCompilation(sourceB, references: new[] { AsReference(comp, useCompilationReference) }, parseOptions: useLatest ? TestOptions.Regular9 : TestOptions.Regular8); + // comp.VerifyDiagnostics(); + // var verifier = CompileAndVerify(comp); + // verifier.VerifyIL("B.M1", + //@"{ + // // Code size 59 (0x3b) + // .maxstack 1 + // .locals init (nint? V_0, + // nuint? V_1) + // IL_0000: ldsfld ""nint A.F1"" + // IL_0005: pop + // IL_0006: ldsfld ""nuint A.F2"" + // IL_000b: pop + // IL_000c: ldsfld ""nint? A.F3"" + // IL_0011: stloc.0 + // IL_0012: ldloca.s V_0 + // IL_0014: call ""bool nint?.HasValue.get"" + // IL_0019: brfalse.s IL_0023 + // IL_001b: ldloca.s V_0 + // IL_001d: call ""nint nint?.GetValueOrDefault()"" + // IL_0022: pop + // IL_0023: ldsfld ""nuint? A.F4"" + // IL_0028: stloc.1 + // IL_0029: ldloca.s V_1 + // IL_002b: call ""bool nuint?.HasValue.get"" + // IL_0030: brfalse.s IL_003a + // IL_0032: ldloca.s V_1 + // IL_0034: call ""nuint nuint?.GetValueOrDefault()"" + // IL_0039: pop + // IL_003a: ret + //}"); + // verifier.VerifyIL("B.M2", + //@"{ + // // Code size 95 (0x5f) + // .maxstack 1 + // .locals init (int? V_0, + // nint? V_1, + // uint? V_2, + // nuint? V_3) + // IL_0000: ldarg.0 + // IL_0001: conv.i + // IL_0002: stsfld ""nint A.F1"" + // IL_0007: ldarg.1 + // IL_0008: conv.u + // IL_0009: stsfld ""nuint A.F2"" + // IL_000e: ldarg.2 + // IL_000f: stloc.0 + // IL_0010: ldloca.s V_0 + // IL_0012: call ""bool int?.HasValue.get"" + // IL_0017: brtrue.s IL_0024 + // IL_0019: ldloca.s V_1 + // IL_001b: initobj ""nint?"" + // IL_0021: ldloc.1 + // IL_0022: br.s IL_0031 + // IL_0024: ldloca.s V_0 + // IL_0026: call ""int int?.GetValueOrDefault()"" + // IL_002b: conv.i + // IL_002c: newobj ""nint?..ctor(nint)"" + // IL_0031: stsfld ""nint? A.F3"" + // IL_0036: ldarg.3 + // IL_0037: stloc.2 + // IL_0038: ldloca.s V_2 + // IL_003a: call ""bool uint?.HasValue.get"" + // IL_003f: brtrue.s IL_004c + // IL_0041: ldloca.s V_3 + // IL_0043: initobj ""nuint?"" + // IL_0049: ldloc.3 + // IL_004a: br.s IL_0059 + // IL_004c: ldloca.s V_2 + // IL_004e: call ""uint uint?.GetValueOrDefault()"" + // IL_0053: conv.u + // IL_0054: newobj ""nuint?..ctor(nuint)"" + // IL_0059: stsfld ""nuint? A.F4"" + // IL_005e: ret + //}"); + // } + + // [WorkItem(3259, "https://github.com/dotnet/csharplang/issues/3259")] + // [Theory] + // [InlineData(false)] + // [InlineData(true)] + // public void BuiltInOperators_NativeIntegers(bool useCompilationReference) + // { + // var sourceA = + //@"public class A + //{ + // public static nint F1; + // public static nuint F2; + // public static nint? F3; + // public static nuint? F4; + //}"; + // var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); + // comp.VerifyDiagnostics(); + // var refA = AsReference(comp, useCompilationReference); + + // var sourceB = + //@"class B : A + //{ + // static void Main() + // { + // F1 = -F1; + // F2 = +F2; + // F3 = -F3; + // F4 = +F4; + // F1 = F1 * F1; + // F2 = F2 / F2; + // F3 = F3 * F1; + // F4 = F4 / F2; + // } + //}"; + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); + // comp.VerifyDiagnostics(); + // var verifier = CompileAndVerify(comp); + // verifier.VerifyIL("B.Main", + //@"{ + // // Code size 247 (0xf7) + // .maxstack 2 + // .locals init (nint? V_0, + // nint? V_1, + // nuint? V_2, + // nuint? V_3, + // System.IntPtr V_4, + // System.UIntPtr V_5) + // IL_0000: ldsfld ""nint A.F1"" + // IL_0005: neg + // IL_0006: stsfld ""nint A.F1"" + // IL_000b: ldsfld ""nuint A.F2"" + // IL_0010: stsfld ""nuint A.F2"" + // IL_0015: ldsfld ""nint? A.F3"" + // IL_001a: stloc.0 + // IL_001b: ldloca.s V_0 + // IL_001d: call ""bool nint?.HasValue.get"" + // IL_0022: brtrue.s IL_002f + // IL_0024: ldloca.s V_1 + // IL_0026: initobj ""nint?"" + // IL_002c: ldloc.1 + // IL_002d: br.s IL_003c + // IL_002f: ldloca.s V_0 + // IL_0031: call ""nint nint?.GetValueOrDefault()"" + // IL_0036: neg + // IL_0037: newobj ""nint?..ctor(nint)"" + // IL_003c: stsfld ""nint? A.F3"" + // IL_0041: ldsfld ""nuint? A.F4"" + // IL_0046: stloc.2 + // IL_0047: ldloca.s V_2 + // IL_0049: call ""bool nuint?.HasValue.get"" + // IL_004e: brtrue.s IL_005b + // IL_0050: ldloca.s V_3 + // IL_0052: initobj ""nuint?"" + // IL_0058: ldloc.3 + // IL_0059: br.s IL_0067 + // IL_005b: ldloca.s V_2 + // IL_005d: call ""nuint nuint?.GetValueOrDefault()"" + // IL_0062: newobj ""nuint?..ctor(nuint)"" + // IL_0067: stsfld ""nuint? A.F4"" + // IL_006c: ldsfld ""nint A.F1"" + // IL_0071: ldsfld ""nint A.F1"" + // IL_0076: mul + // IL_0077: stsfld ""nint A.F1"" + // IL_007c: ldsfld ""nuint A.F2"" + // IL_0081: ldsfld ""nuint A.F2"" + // IL_0086: div.un + // IL_0087: stsfld ""nuint A.F2"" + // IL_008c: ldsfld ""nint? A.F3"" + // IL_0091: stloc.0 + // IL_0092: ldsfld ""nint A.F1"" + // IL_0097: stloc.s V_4 + // IL_0099: ldloca.s V_0 + // IL_009b: call ""bool nint?.HasValue.get"" + // IL_00a0: brtrue.s IL_00ad + // IL_00a2: ldloca.s V_1 + // IL_00a4: initobj ""nint?"" + // IL_00aa: ldloc.1 + // IL_00ab: br.s IL_00bc + // IL_00ad: ldloca.s V_0 + // IL_00af: call ""nint nint?.GetValueOrDefault()"" + // IL_00b4: ldloc.s V_4 + // IL_00b6: mul + // IL_00b7: newobj ""nint?..ctor(nint)"" + // IL_00bc: stsfld ""nint? A.F3"" + // IL_00c1: ldsfld ""nuint? A.F4"" + // IL_00c6: stloc.2 + // IL_00c7: ldsfld ""nuint A.F2"" + // IL_00cc: stloc.s V_5 + // IL_00ce: ldloca.s V_2 + // IL_00d0: call ""bool nuint?.HasValue.get"" + // IL_00d5: brtrue.s IL_00e2 + // IL_00d7: ldloca.s V_3 + // IL_00d9: initobj ""nuint?"" + // IL_00df: ldloc.3 + // IL_00e0: br.s IL_00f1 + // IL_00e2: ldloca.s V_2 + // IL_00e4: call ""nuint nuint?.GetValueOrDefault()"" + // IL_00e9: ldloc.s V_5 + // IL_00eb: div.un + // IL_00ec: newobj ""nuint?..ctor(nuint)"" + // IL_00f1: stsfld ""nuint? A.F4"" + // IL_00f6: ret + //}"); + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); + // comp.VerifyDiagnostics( + // // (5,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F1 = -F1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "-F1").WithArguments("native-sized integers", "9.0").WithLocation(5, 14), + // // (6,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F2 = +F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "+F2").WithArguments("native-sized integers", "9.0").WithLocation(6, 14), + // // (7,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F3 = -F3; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "-F3").WithArguments("native-sized integers", "9.0").WithLocation(7, 14), + // // (8,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F4 = +F4; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "+F4").WithArguments("native-sized integers", "9.0").WithLocation(8, 14), + // // (9,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F1 = F1 * F1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 * F1").WithArguments("native-sized integers", "9.0").WithLocation(9, 14), + // // (10,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F2 = F2 / F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F2 / F2").WithArguments("native-sized integers", "9.0").WithLocation(10, 14), + // // (11,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F3 = F3 * F1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F3 * F1").WithArguments("native-sized integers", "9.0").WithLocation(11, 14), + // // (12,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F4 = F4 / F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F4 / F2").WithArguments("native-sized integers", "9.0").WithLocation(12, 14)); + // } + + // [Theory] + // [CombinatorialData] + // [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] + // public void NativeIntegerOperatorsCSharp8_01(bool useCompilationReference, bool lifted) + // { + // string typeSuffix = lifted ? "?" : ""; + // var sourceA = + //$@"public class A + //{{ + // public static nint{typeSuffix} F1; + // public static nuint{typeSuffix} F2; + //}}"; + // var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); + // var refA = AsReference(comp, useCompilationReference); + + // var sourceB = + //@"class B : A + //{ + // static void Main() + // { + // _ = +F1; + // _ = -F1; + // _ = ~F1; + // _ = +F2; + // _ = ~F2; + // } + //}"; + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); + // comp.VerifyEmitDiagnostics(); + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); + // comp.VerifyEmitDiagnostics( + // // (5,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = +F1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "+F1").WithArguments("native-sized integers", "9.0").WithLocation(5, 13), + // // (6,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = -F1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "-F1").WithArguments("native-sized integers", "9.0").WithLocation(6, 13), + // // (7,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = ~F1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "~F1").WithArguments("native-sized integers", "9.0").WithLocation(7, 13), + // // (8,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = +F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "+F2").WithArguments("native-sized integers", "9.0").WithLocation(8, 13), + // // (9,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = ~F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "~F2").WithArguments("native-sized integers", "9.0").WithLocation(9, 13)); + // } + + // [Theory] + // [CombinatorialData] + // [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] + // public void NativeIntegerOperatorsCSharp8_02(bool useCompilationReference, [CombinatorialValues("nint", "nint?", "nuint", "nuint?")] string type) + // { + // var sourceA = + //$@"public class A + //{{ + // public static {type} F; + //}}"; + // var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); + // var refA = AsReference(comp, useCompilationReference); + + // var sourceB = + //@"class B : A + //{ + // static void Main() + // { + // ++F; + // F++; + // --F; + // F--; + // } + //}"; + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); + // comp.VerifyEmitDiagnostics(); + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); + // comp.VerifyEmitDiagnostics( + // // (5,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // ++F; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "++F").WithArguments("native-sized integers", "9.0").WithLocation(5, 9), + // // (6,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F++; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F++").WithArguments("native-sized integers", "9.0").WithLocation(6, 9), + // // (7,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // --F; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "--F").WithArguments("native-sized integers", "9.0").WithLocation(7, 9), + // // (8,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F--; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F--").WithArguments("native-sized integers", "9.0").WithLocation(8, 9)); + // } + + // [Theory] + // [CombinatorialData] + // [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] + // public void NativeIntegerOperatorsCSharp8_03(bool useCompilationReference, [CombinatorialValues("nint", "nint?", "nuint", "nuint?")] string type) + // { + // var sourceA = + //$@"public class A + //{{ + // public static {type} F1, F2; + //}}"; + // var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); + // var refA = AsReference(comp, useCompilationReference); + + // var sourceB = + //@"class B : A + //{ + // static void Main() + // { + // _ = F1 + F2; + // _ = F1 - F2; + // _ = F1 * F2; + // _ = F1 / F2; + // _ = F1 % F2; + // _ = F1 < F2; + // _ = F1 <= F2; + // _ = F1 > F2; + // _ = F1 >= F2; + // _ = F1 == F2; + // _ = F1 != F2; + // _ = F1 & F2; + // _ = F1 | F2; + // _ = F1 ^ F2; + // _ = F1 << 1; + // _ = F1 >> 1; + // } + //}"; + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); + // comp.VerifyEmitDiagnostics(); + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); + // comp.VerifyEmitDiagnostics( + // // (5,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 + F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 + F2").WithArguments("native-sized integers", "9.0").WithLocation(5, 13), + // // (6,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 - F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 - F2").WithArguments("native-sized integers", "9.0").WithLocation(6, 13), + // // (7,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 * F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 * F2").WithArguments("native-sized integers", "9.0").WithLocation(7, 13), + // // (8,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 / F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 / F2").WithArguments("native-sized integers", "9.0").WithLocation(8, 13), + // // (9,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 % F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 % F2").WithArguments("native-sized integers", "9.0").WithLocation(9, 13), + // // (10,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 < F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 < F2").WithArguments("native-sized integers", "9.0").WithLocation(10, 13), + // // (11,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 <= F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 <= F2").WithArguments("native-sized integers", "9.0").WithLocation(11, 13), + // // (12,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 > F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 > F2").WithArguments("native-sized integers", "9.0").WithLocation(12, 13), + // // (13,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 >= F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 >= F2").WithArguments("native-sized integers", "9.0").WithLocation(13, 13), + // // (14,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 == F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 == F2").WithArguments("native-sized integers", "9.0").WithLocation(14, 13), + // // (15,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 != F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 != F2").WithArguments("native-sized integers", "9.0").WithLocation(15, 13), + // // (16,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 & F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 & F2").WithArguments("native-sized integers", "9.0").WithLocation(16, 13), + // // (17,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 | F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 | F2").WithArguments("native-sized integers", "9.0").WithLocation(17, 13), + // // (18,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 ^ F2; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 ^ F2").WithArguments("native-sized integers", "9.0").WithLocation(18, 13), + // // (19,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 << 1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 << 1").WithArguments("native-sized integers", "9.0").WithLocation(19, 13), + // // (20,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = F1 >> 1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 >> 1").WithArguments("native-sized integers", "9.0").WithLocation(20, 13)); + // } + + // [Theory] + // [CombinatorialData] + // [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] + // public void NativeIntegerOperatorsCSharp8_04(bool useCompilationReference, [CombinatorialValues("nint", "nint?", "nuint", "nuint?")] string type) + // { + // var sourceA = + //$@"public class A + //{{ + // public static {type} F1, F2; + //}}"; + // var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); + // var refA = AsReference(comp, useCompilationReference); + + // var sourceB = + //@"class B : A + //{ + // static void Main() + // { + // _ = (F1, F1) == (F2, F2); + // _ = (F1, F1) != (F2, F2); + // } + //}"; + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); + // comp.VerifyEmitDiagnostics(); + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); + // comp.VerifyEmitDiagnostics( + // // (5,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = (F1, F1) == (F2, F2); + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "(F1, F1) == (F2, F2)").WithArguments("native-sized integers", "9.0").WithLocation(5, 13), + // // (5,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = (F1, F1) == (F2, F2); + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "(F1, F1) == (F2, F2)").WithArguments("native-sized integers", "9.0").WithLocation(5, 13), + // // (6,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = (F1, F1) != (F2, F2); + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "(F1, F1) != (F2, F2)").WithArguments("native-sized integers", "9.0").WithLocation(6, 13), + // // (6,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // _ = (F1, F1) != (F2, F2); + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "(F1, F1) != (F2, F2)").WithArguments("native-sized integers", "9.0").WithLocation(6, 13)); + // } + + // [Theory] + // [CombinatorialData] + // [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] + // public void NativeIntegerOperatorsCSharp8_05(bool useCompilationReference, [CombinatorialValues("nint", "nint?", "nuint", "nuint?")] string type) + // { + // var sourceA = + //$@"public class A + //{{ + // public static {type} F; + //}}"; + // var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); + // var refA = AsReference(comp, useCompilationReference); + + // var sourceB = + //@"class B : A + //{ + // static void Main() + // { + // F += 1; + // F -= 1; + // F *= 1; + // F /= 1; + // F %= 1; + // F &= 1; + // F |= 1; + // F ^= 1; + // F <<= 1; + // F >>= 1; + // } + //}"; + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); + // comp.VerifyEmitDiagnostics(); + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); + // comp.VerifyEmitDiagnostics( + // // (5,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F += 1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F += 1").WithArguments("native-sized integers", "9.0").WithLocation(5, 9), + // // (6,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F -= 1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F -= 1").WithArguments("native-sized integers", "9.0").WithLocation(6, 9), + // // (7,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F *= 1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F *= 1").WithArguments("native-sized integers", "9.0").WithLocation(7, 9), + // // (8,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F /= 1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F /= 1").WithArguments("native-sized integers", "9.0").WithLocation(8, 9), + // // (9,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F %= 1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F %= 1").WithArguments("native-sized integers", "9.0").WithLocation(9, 9), + // // (10,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F &= 1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F &= 1").WithArguments("native-sized integers", "9.0").WithLocation(10, 9), + // // (11,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F |= 1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F |= 1").WithArguments("native-sized integers", "9.0").WithLocation(11, 9), + // // (12,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F ^= 1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F ^= 1").WithArguments("native-sized integers", "9.0").WithLocation(12, 9), + // // (13,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F <<= 1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F <<= 1").WithArguments("native-sized integers", "9.0").WithLocation(13, 9), + // // (14,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. + // // F >>= 1; + // Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F >>= 1").WithArguments("native-sized integers", "9.0").WithLocation(14, 9)); + // } + + // [Theory] + // [CombinatorialData] + // [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] + // public void NativeIntegerConversionsCSharp8_01(bool useCompilationReference, [CombinatorialValues("nint", "nuint")] string type) + // { + // var sourceA = + //$@"public class A + //{{ + // public static {type} F1; + // public static {type}? F2; + //}}"; + // var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); + // var refA = AsReference(comp, useCompilationReference); + + // var sourceB = + //@"class B : A + //{ + // static void Main() + // { + // F1 = sbyte.MaxValue; + // F1 = byte.MaxValue; + // F1 = char.MaxValue; + // F1 = short.MaxValue; + // F1 = ushort.MaxValue; + // F1 = int.MaxValue; + // F2 = sbyte.MaxValue; + // F2 = byte.MaxValue; + // F2 = char.MaxValue; + // F2 = short.MaxValue; + // F2 = ushort.MaxValue; + // F2 = int.MaxValue; + // } + //}"; + + // var expectedDiagnostics = (type == "nuint") ? + // new DiagnosticDescription[] + // { + // // (5,14): error CS0266: Cannot implicitly convert type 'sbyte' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // // F1 = sbyte.MaxValue; + // Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "sbyte.MaxValue").WithArguments("sbyte", "nuint").WithLocation(5, 14), + // // (8,14): error CS0266: Cannot implicitly convert type 'short' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // // F1 = short.MaxValue; + // Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "short.MaxValue").WithArguments("short", "nuint").WithLocation(8, 14), + // // (11,14): error CS0266: Cannot implicitly convert type 'sbyte' to 'nuint?'. An explicit conversion exists (are you missing a cast?) + // // F2 = sbyte.MaxValue; + // Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "sbyte.MaxValue").WithArguments("sbyte", "nuint?").WithLocation(11, 14), + // // (14,14): error CS0266: Cannot implicitly convert type 'short' to 'nuint?'. An explicit conversion exists (are you missing a cast?) + // // F2 = short.MaxValue; + // Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "short.MaxValue").WithArguments("short", "nuint?").WithLocation(14, 14) + // } : + // new DiagnosticDescription[0]; + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); + // comp.VerifyEmitDiagnostics(expectedDiagnostics); + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); + // comp.VerifyEmitDiagnostics(expectedDiagnostics); + // } + + // [Theory] + // [CombinatorialData] + // [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] + // public void NativeIntegerConversionsCSharp8_02(bool useCompilationReference, bool signed) + // { + // string type = signed ? "nint" : "nuint"; + // string underlyingType = signed ? "System.IntPtr" : "System.UIntPtr"; + + // var sourceA = + //$@"public class A + //{{ + // public static {type} F1; + // public static {type}? F2; + //}}"; + // var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); + // var refA = AsReference(comp, useCompilationReference); + + // var sourceB = + //$@"class B : A + //{{ + // static T F() => throw null; + // static void Main() + // {{ + // F1 = F(); + // F1 = F(); + // F1 = F(); + // F1 = F<{underlyingType}>(); + // F2 = F(); + // F2 = F(); + // F2 = F(); + // F2 = F(); + // F2 = F(); + // F2 = F(); + // F2 = F<{underlyingType}>(); + // F2 = F<{underlyingType}?>(); + // }} + //}}"; + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); + // comp.VerifyEmitDiagnostics(); + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); + // comp.VerifyEmitDiagnostics(); + // } + + // [Theory] + // [CombinatorialData] + // [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] + // public void NativeIntegerConversionsCSharp8_03(bool useCompilationReference, bool signed) + // { + // string type = signed ? "nint" : "nuint"; + // string underlyingType = signed ? "System.IntPtr" : "System.UIntPtr"; + + // var sourceA = + //$@"public class A + //{{ + // public static {type} F1; + // public static {type}? F2; + //}}"; + // var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); + // var refA = AsReference(comp, useCompilationReference); + + // var sourceB = + //$@"class B : A + //{{ + // static void M0() + // {{ + // object o; + // o = F1; + // o = (object)F1; + // o = F2; + // o = (object)F2; + // }} + // static void M1() + // {{ + // {underlyingType} ptr; + // sbyte sb; + // byte b; + // char c; + // short s; + // ushort us; + // int i; + // uint u; + // long l; + // ulong ul; + // float f; + // double d; + // decimal dec; + // ptr = F1; + // f = F1; + // d = F1; + // dec = F1; + // ptr = ({underlyingType})F1; + // sb = (sbyte)F1; + // b = (byte)F1; + // c = (char)F1; + // s = (short)F1; + // us = (ushort)F1; + // i = (int)F1; + // u = (uint)F1; + // l = (long)F1; + // ul = (ulong)F1; + // f = (float)F1; + // d = (double)F1; + // dec = (decimal)F1; + // ptr = ({underlyingType})F2; + // sb = (sbyte)F2; + // b = (byte)F2; + // c = (char)F2; + // s = (short)F2; + // us = (ushort)F2; + // i = (int)F2; + // u = (uint)F2; + // l = (long)F2; + // ul = (ulong)F2; + // f = (float)F2; + // d = (double)F2; + // dec = (decimal)F2; + // }} + // static void M2() + // {{ + // {underlyingType}? ptr; + // sbyte? sb; + // byte? b; + // char? c; + // short? s; + // ushort? us; + // int? i; + // uint? u; + // long? l; + // ulong? ul; + // float? f; + // double? d; + // decimal? dec; + // ptr = F1; + // f = F1; + // d = F1; + // dec = F1; + // ptr = ({underlyingType}?)F1; + // sb = (sbyte?)F1; + // b = (byte?)F1; + // c = (char?)F1; + // s = (short?)F1; + // us = (ushort?)F1; + // i = (int?)F1; + // u = (uint?)F1; + // l = (long?)F1; + // ul = (ulong?)F1; + // f = (float?)F1; + // d = (double?)F1; + // dec = (decimal?)F1; + // ptr = F2; + // f = F2; + // d = F2; + // dec = F2; + // ptr = ({underlyingType}?)F2; + // sb = (sbyte?)F2; + // b = (byte?)F2; + // c = (char?)F2; + // s = (short?)F2; + // us = (ushort?)F2; + // i = (int?)F2; + // u = (uint?)F2; + // l = (long?)F2; + // ul = (ulong?)F2; + // f = (float?)F2; + // d = (double?)F2; + // dec = (decimal?)F2; + // }} + //}}"; + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); + // comp.VerifyEmitDiagnostics(); + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); + // comp.VerifyEmitDiagnostics(); + // } + + // [Theory] + // [CombinatorialData] + // [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] + // public void NativeIntegerConversionsCSharp8_04(bool useCompilationReference, [CombinatorialValues("nint", "nuint")] string type) + // { + // var sourceA = + //$@"public class A + //{{ + // public static {type} F1, F2; + // public static {type}? F3, F4; + //}}"; + // var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); + // var refA = AsReference(comp, useCompilationReference); + + // var sourceB = + //$@"class B : A + //{{ + // static void Main() + // {{ + // F2 = F1; + // F4 = F1; + // F4 = F3; + // }} + //}}"; + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); + // comp.VerifyEmitDiagnostics(); + + // comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); + // comp.VerifyEmitDiagnostics(); + // } + + // [Theory] + // [CombinatorialData] + // public void SemanticModel_UnaryOperators(bool lifted) + // { + // string typeQualifier = lifted ? "?" : ""; + // var source = + //$@"class Program + //{{ + // static void F(nint{typeQualifier} x, nuint{typeQualifier} y) + // {{ + // _ = +x; + // _ = -x; + // _ = ~x; + // _ = +y; + // _ = ~y; + // }} + //}}"; + // var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); + // comp.VerifyEmitDiagnostics(); + // var tree = comp.SyntaxTrees[0]; + // var model = comp.GetSemanticModel(tree); + // var nodes = tree.GetRoot().DescendantNodes().OfType(); + // var actualOperators = nodes.Select(n => model.GetSymbolInfo(n).Symbol.ToTestDisplayString()).ToArray(); + // var expectedOperators = new[] + // { + // "nint nint.op_UnaryPlus(nint value)", + // "nint nint.op_UnaryNegation(nint value)", + // "nint nint.op_OnesComplement(nint value)", + // "nuint nuint.op_UnaryPlus(nuint value)", + // "nuint nuint.op_OnesComplement(nuint value)", + // }; + // AssertEx.Equal(expectedOperators, actualOperators); + // } + + // [Theory] + // [InlineData("nint", false)] + // [InlineData("nuint", false)] + // [InlineData("nint", true)] + // [InlineData("nuint", true)] + // public void SemanticModel_BinaryOperators(string type, bool lifted) + // { + // string typeQualifier = lifted ? "?" : ""; + // var source = + //$@"class Program + //{{ + // static void F({type}{typeQualifier} x, {type}{typeQualifier} y) + // {{ + // _ = x + y; + // _ = x - y; + // _ = x * y; + // _ = x / y; + // _ = x % y; + // _ = x < y; + // _ = x <= y; + // _ = x > y; + // _ = x >= y; + // _ = x == y; + // _ = x != y; + // _ = x & y; + // _ = x | y; + // _ = x ^ y; + // _ = x << 1; + // _ = x >> 1; + // }} + //}}"; + // var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); + // comp.VerifyEmitDiagnostics(); + // var tree = comp.SyntaxTrees[0]; + // var model = comp.GetSemanticModel(tree); + // var nodes = tree.GetRoot().DescendantNodes().OfType(); + // var actualOperators = nodes.Select(n => model.GetSymbolInfo(n).Symbol.ToTestDisplayString()).ToArray(); + // var expectedOperators = new[] + // { + // $"{type} {type}.op_Addition({type} left, {type} right)", + // $"{type} {type}.op_Subtraction({type} left, {type} right)", + // $"{type} {type}.op_Multiply({type} left, {type} right)", + // $"{type} {type}.op_Division({type} left, {type} right)", + // $"{type} {type}.op_Modulus({type} left, {type} right)", + // $"System.Boolean {type}.op_LessThan({type} left, {type} right)", + // $"System.Boolean {type}.op_LessThanOrEqual({type} left, {type} right)", + // $"System.Boolean {type}.op_GreaterThan({type} left, {type} right)", + // $"System.Boolean {type}.op_GreaterThanOrEqual({type} left, {type} right)", + // $"System.Boolean {type}.op_Equality({type} left, {type} right)", + // $"System.Boolean {type}.op_Inequality({type} left, {type} right)", + // $"{type} {type}.op_BitwiseAnd({type} left, {type} right)", + // $"{type} {type}.op_BitwiseOr({type} left, {type} right)", + // $"{type} {type}.op_ExclusiveOr({type} left, {type} right)", + // $"{type} {type}.op_LeftShift({type} left, System.Int32 right)", + // $"{type} {type}.op_RightShift({type} left, System.Int32 right)", + // }; + // AssertEx.Equal(expectedOperators, actualOperators); + // } - var sourceB = -@"using System; -class Program -{ - static T F1(I t) - { - return default; - } - static I F2(I t) - { - return t; - } - static void M1(nint x) - { - var x1 = F1(x); - var x2 = F2(x).P; - _ = x.P; - _ = x.F(); - } - static void M2(nuint y) + [Theory] + [InlineData("")] + [InlineData("unchecked")] + [InlineData("checked")] + public void ConstantConversions_ToNativeInt(string context) { - var y1 = F1(y); - var y2 = F2(y).P; - _ = y.P; - _ = y.F(); - } -}"; - var compB = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - compB.VerifyDiagnostics(); - - var tree = compB.SyntaxTrees[0]; - var model = compB.GetSemanticModel(tree); - var actualLocals = tree.GetRoot().DescendantNodes().OfType().Select(d => model.GetDeclaredSymbol(d).ToTestDisplayString()); - var expectedLocals = new[] - { - "nint x1", - "nint x2", - "nuint y1", - "nuint y2", - }; - AssertEx.Equal(expectedLocals, actualLocals); + var source = +$@"#pragma warning disable 219 +class Program +{{ + static void F1() + {{ + System.IntPtr i; + {context} + {{ + i = sbyte.MaxValue; + i = byte.MaxValue; + i = char.MaxValue; + i = short.MaxValue; + i = ushort.MaxValue; + i = int.MaxValue; + i = uint.MaxValue; + i = long.MaxValue; + i = ulong.MaxValue; + i = float.MaxValue; + i = double.MaxValue; + i = (decimal)int.MaxValue; + i = (nint)int.MaxValue; + i = (nuint)uint.MaxValue; + }} + }} + static void F2() + {{ + System.UIntPtr u; + {context} + {{ + u = sbyte.MaxValue; + u = byte.MaxValue; + u = char.MaxValue; + u = short.MaxValue; + u = ushort.MaxValue; + u = int.MaxValue; + u = uint.MaxValue; + u = long.MaxValue; + u = ulong.MaxValue; + u = float.MaxValue; + u = double.MaxValue; + u = (decimal)uint.MaxValue; + u = (nint)int.MaxValue; + u = (nuint)uint.MaxValue; + }} + }} +}}"; - verifyType((NamedTypeSymbol)compB.GetMember("Program.M1").Parameters[0].Type, signed: true); - verifyType((NamedTypeSymbol)compB.GetMember("Program.M2").Parameters[0].Type, signed: false); + // Avoid sharing mscorlib symbols with other tests since we are about to change + // RuntimeSupportsNumericIntPtr property for it. + var mscorLibRef = MscorlibRefWithoutSharingCachedSymbols; - static void verifyType(NamedTypeSymbol type, bool signed) - { - Assert.True(type.IsNativeIntegerType); + var comp = CreateEmptyCompilation(source, references: new[] { mscorLibRef }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - VerifyType(type, signed: signed, isNativeInt: true); - VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); + comp.VerifyDiagnostics( + // (15,17): error CS0266: Cannot implicitly convert type 'uint' to 'nint'. An explicit conversion exists (are you missing a cast?) + // i = uint.MaxValue; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "uint.MaxValue").WithArguments("uint", "nint").WithLocation(15, 17), + // (16,17): error CS0266: Cannot implicitly convert type 'long' to 'nint'. An explicit conversion exists (are you missing a cast?) + // i = long.MaxValue; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "long.MaxValue").WithArguments("long", "nint").WithLocation(16, 17), + // (17,17): error CS0266: Cannot implicitly convert type 'ulong' to 'nint'. An explicit conversion exists (are you missing a cast?) + // i = ulong.MaxValue; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "ulong.MaxValue").WithArguments("ulong", "nint").WithLocation(17, 17), + // (18,17): error CS0266: Cannot implicitly convert type 'float' to 'nint'. An explicit conversion exists (are you missing a cast?) + // i = float.MaxValue; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "float.MaxValue").WithArguments("float", "nint").WithLocation(18, 17), + // (19,17): error CS0266: Cannot implicitly convert type 'double' to 'nint'. An explicit conversion exists (are you missing a cast?) + // i = double.MaxValue; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "double.MaxValue").WithArguments("double", "nint").WithLocation(19, 17), + // (20,17): error CS0266: Cannot implicitly convert type 'decimal' to 'nint'. An explicit conversion exists (are you missing a cast?) + // i = (decimal)int.MaxValue; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "(decimal)int.MaxValue").WithArguments("decimal", "nint").WithLocation(20, 17), + // (22,17): error CS0266: Cannot implicitly convert type 'nuint' to 'nint'. An explicit conversion exists (are you missing a cast?) + // i = (nuint)uint.MaxValue; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "(nuint)uint.MaxValue").WithArguments("nuint", "nint").WithLocation(22, 17), + // (30,17): error CS0266: Cannot implicitly convert type 'sbyte' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // u = sbyte.MaxValue; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "sbyte.MaxValue").WithArguments("sbyte", "nuint").WithLocation(30, 17), + // (33,17): error CS0266: Cannot implicitly convert type 'short' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // u = short.MaxValue; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "short.MaxValue").WithArguments("short", "nuint").WithLocation(33, 17), + // (37,17): error CS0266: Cannot implicitly convert type 'long' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // u = long.MaxValue; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "long.MaxValue").WithArguments("long", "nuint").WithLocation(37, 17), + // (38,17): error CS0266: Cannot implicitly convert type 'ulong' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // u = ulong.MaxValue; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "ulong.MaxValue").WithArguments("ulong", "nuint").WithLocation(38, 17), + // (39,17): error CS0266: Cannot implicitly convert type 'float' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // u = float.MaxValue; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "float.MaxValue").WithArguments("float", "nuint").WithLocation(39, 17), + // (40,17): error CS0266: Cannot implicitly convert type 'double' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // u = double.MaxValue; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "double.MaxValue").WithArguments("double", "nuint").WithLocation(40, 17), + // (41,17): error CS0266: Cannot implicitly convert type 'decimal' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // u = (decimal)uint.MaxValue; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "(decimal)uint.MaxValue").WithArguments("decimal", "nuint").WithLocation(41, 17), + // (42,17): error CS0266: Cannot implicitly convert type 'nint' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // u = (nint)int.MaxValue; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "(nint)int.MaxValue").WithArguments("nint", "nuint").WithLocation(42, 17)); + } - var underlyingType = type.NativeIntegerUnderlyingType; - var members = type.GetMembers().Sort(SymbolComparison); - foreach (var member in members) - { - Assert.True(member.GetExplicitInterfaceImplementations().IsEmpty); - } + [Theory] + [InlineData("")] + [InlineData("unchecked")] + [InlineData("checked")] + public void ConstantConversions_FromNativeInt(string context) + { + var source = +$@"#pragma warning disable 219 +class Program +{{ + static void F1() + {{ + const System.IntPtr n = (System.IntPtr)int.MaxValue; + {context} + {{ + sbyte sb = n; + byte b = n; + char c = n; + short s = n; + ushort us = n; + int i = n; + uint u = n; + long l = n; + ulong ul = n; + float f = n; + double d = n; + decimal dec = n; + nuint nu = n; + }} + }} + static void F2() + {{ + const System.UIntPtr nu = (System.UIntPtr)uint.MaxValue; + {context} + {{ + sbyte sb = nu; + byte b = nu; + char c = nu; + short s = nu; + ushort us = nu; + int i = nu; + uint u = nu; + long l = nu; + ulong ul = nu; + float f = nu; + double d = nu; + decimal dec = nu; + nint n = nu; + }} + }} +}}"; + // Avoid sharing mscorlib symbols with other tests since we are about to change + // RuntimeSupportsNumericIntPtr property for it. + var mscorLibRef = MscorlibRefWithoutSharingCachedSymbols; - var actualMembers = members.SelectAsArray(m => m.ToTestDisplayString()); - var expectedMembers = new[] - { - $"{type} {type}.F()", - $"{type} {type}.P {{ get; }}", - $"{type} {type}.P.get", - $"{type}..ctor()", - }; - AssertEx.Equal(expectedMembers, actualMembers); + var comp = CreateEmptyCompilation(source, references: new[] { mscorLibRef }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - VerifyMembers(underlyingType, type, signed); - VerifyMembers(underlyingType.GetPublicSymbol(), type.GetPublicSymbol(), signed); - } + comp.VerifyDiagnostics( + // (9,24): error CS0266: Cannot implicitly convert type 'nint' to 'sbyte'. An explicit conversion exists (are you missing a cast?) + // sbyte sb = n; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "sbyte").WithLocation(9, 24), + // (10,22): error CS0266: Cannot implicitly convert type 'nint' to 'byte'. An explicit conversion exists (are you missing a cast?) + // byte b = n; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "byte").WithLocation(10, 22), + // (11,22): error CS0266: Cannot implicitly convert type 'nint' to 'char'. An explicit conversion exists (are you missing a cast?) + // char c = n; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "char").WithLocation(11, 22), + // (12,23): error CS0266: Cannot implicitly convert type 'nint' to 'short'. An explicit conversion exists (are you missing a cast?) + // short s = n; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "short").WithLocation(12, 23), + // (13,25): error CS0266: Cannot implicitly convert type 'nint' to 'ushort'. An explicit conversion exists (are you missing a cast?) + // ushort us = n; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "ushort").WithLocation(13, 25), + // (14,21): error CS0266: Cannot implicitly convert type 'nint' to 'int'. An explicit conversion exists (are you missing a cast?) + // int i = n; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "int").WithLocation(14, 21), + // (15,22): error CS0266: Cannot implicitly convert type 'nint' to 'uint'. An explicit conversion exists (are you missing a cast?) + // uint u = n; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "uint").WithLocation(15, 22), + // (17,24): error CS0266: Cannot implicitly convert type 'nint' to 'ulong'. An explicit conversion exists (are you missing a cast?) + // ulong ul = n; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "ulong").WithLocation(17, 24), + // (21,24): error CS0266: Cannot implicitly convert type 'nint' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // nuint nu = n; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "nuint").WithLocation(21, 24), + // (29,24): error CS0266: Cannot implicitly convert type 'nuint' to 'sbyte'. An explicit conversion exists (are you missing a cast?) + // sbyte sb = nu; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "sbyte").WithLocation(29, 24), + // (30,22): error CS0266: Cannot implicitly convert type 'nuint' to 'byte'. An explicit conversion exists (are you missing a cast?) + // byte b = nu; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "byte").WithLocation(30, 22), + // (31,22): error CS0266: Cannot implicitly convert type 'nuint' to 'char'. An explicit conversion exists (are you missing a cast?) + // char c = nu; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "char").WithLocation(31, 22), + // (32,23): error CS0266: Cannot implicitly convert type 'nuint' to 'short'. An explicit conversion exists (are you missing a cast?) + // short s = nu; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "short").WithLocation(32, 23), + // (33,25): error CS0266: Cannot implicitly convert type 'nuint' to 'ushort'. An explicit conversion exists (are you missing a cast?) + // ushort us = nu; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "ushort").WithLocation(33, 25), + // (34,21): error CS0266: Cannot implicitly convert type 'nuint' to 'int'. An explicit conversion exists (are you missing a cast?) + // int i = nu; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "int").WithLocation(34, 21), + // (35,22): error CS0266: Cannot implicitly convert type 'nuint' to 'uint'. An explicit conversion exists (are you missing a cast?) + // uint u = nu; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "uint").WithLocation(35, 22), + // (36,22): error CS0266: Cannot implicitly convert type 'nuint' to 'long'. An explicit conversion exists (are you missing a cast?) + // long l = nu; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "long").WithLocation(36, 22), + // (41,22): error CS0266: Cannot implicitly convert type 'nuint' to 'nint'. An explicit conversion exists (are you missing a cast?) + // nint n = nu; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "nint").WithLocation(41, 22)); } [Fact] - public void NonPublicMembers_InternalUse() + public void ConstantConversions_01() { var source = -@"namespace System +@"using System; +class Program { - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct IntPtr + static void Main() { - private static IntPtr F1() => default; - internal IntPtr F2() => default; - public static IntPtr F3() - { - nint i = 0; - _ = nint.F1(); - _ = i.F2(); - return nint.F3(); - } + const long x = 0xFFFFFFFFFFFFFFFL; + const IntPtr y = checked((IntPtr)x); + Console.WriteLine(y); } - public struct UIntPtr +}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + + comp.VerifyDiagnostics( + // (7,26): error CS0133: The expression being assigned to 'y' must be constant + // const IntPtr y = checked((IntPtr)x); + Diagnostic(ErrorCode.ERR_NotConstantExpression, "checked((IntPtr)x)").WithArguments("y").WithLocation(7, 26), + // (7,34): warning CS8778: Constant value '1152921504606846975' may overflow 'nint' at runtime (use 'unchecked' syntax to override) + // const IntPtr y = checked((IntPtr)x); + Diagnostic(ErrorCode.WRN_ConstOutOfRangeChecked, "(IntPtr)x").WithArguments("1152921504606846975", "nint").WithLocation(7, 34)); + + source = +@"using System; +class Program +{ + static void Main() { - private static UIntPtr F1() => default; - internal UIntPtr F2() => default; - public static UIntPtr F3() + const long x = 0xFFFFFFFFFFFFFFFL; + try { - nuint i = 0; - _ = nuint.F1(); - _ = i.F2(); - return nuint.F3(); + nint y = checked((nint)x); + Console.WriteLine(y); + } + catch (Exception e) + { + Console.WriteLine(e.GetType()); } } }"; - var comp = CreateEmptyCompilation(source, parseOptions: TestOptions.Regular9); + comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; comp.VerifyDiagnostics( - // (16,22): error CS0117: 'nint' does not contain a definition for 'F1' - // _ = nint.F1(); - Diagnostic(ErrorCode.ERR_NoSuchMember, "F1").WithArguments("nint", "F1").WithLocation(16, 22), - // (17,19): error CS1061: 'nint' does not contain a definition for 'F2' and no accessible extension method 'F2' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // _ = i.F2(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F2").WithArguments("nint", "F2").WithLocation(17, 19), - // (28,23): error CS0117: 'nuint' does not contain a definition for 'F1' - // _ = nuint.F1(); - Diagnostic(ErrorCode.ERR_NoSuchMember, "F1").WithArguments("nuint", "F1").WithLocation(28, 23), - // (29,19): error CS1061: 'nuint' does not contain a definition for 'F2' and no accessible extension method 'F2' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) - // _ = i.F2(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F2").WithArguments("nuint", "F2").WithLocation(29, 19)); + // (9,30): warning CS8778: Constant value '1152921504606846975' may overflow 'nint' at runtime (use 'unchecked' syntax to override) + // nint y = checked((nint)x); + Diagnostic(ErrorCode.WRN_ConstOutOfRangeChecked, "(nint)x").WithArguments("1152921504606846975", "nint").WithLocation(9, 30)); + CompileAndVerify(comp, expectedOutput: IntPtr.Size == 4 ? "System.OverflowException" : "1152921504606846975"); } - [Theory] - [InlineData(false)] - [InlineData(true)] - public void NonPublicMembers(bool useCompilationReference) + [WorkItem(45531, "https://github.com/dotnet/roslyn/issues/45531")] + [Fact] + public void ConstantConversions_02() { - var sourceA = -@"namespace System + var source = +@"using System; +class Program { - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct IntPtr - { - private static IntPtr F1() => default; - internal IntPtr F2() => default; - public static IntPtr F3() => default; - } - public struct UIntPtr + static void Main() { - private static UIntPtr F1() => default; - internal UIntPtr F2() => default; - public static UIntPtr F3() => default; + const long x = 0xFFFFFFFFFFFFFFFL; + const IntPtr y = unchecked((IntPtr)x); + Console.WriteLine(y); } }"; - var comp = CreateEmptyCompilation(sourceA); - comp.VerifyDiagnostics(); - var refA = AsReference(comp, useCompilationReference); + var mscorLibRef = MscorlibRefWithoutSharingCachedSymbols; + var comp = CreateEmptyCompilation(source, references: new[] { mscorLibRef }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - var sourceB = -@"class Program -{ - static void F1(nint x) - { - _ = nint.F1(); - _ = x.F2(); - _ = nint.F3(); - } - static void F2(nuint y) - { - _ = nuint.F1(); - _ = y.F2(); - _ = nuint.F3(); - } -}"; - comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); comp.VerifyDiagnostics( - // (5,18): error CS0117: 'nint' does not contain a definition for 'F1' - // _ = nint.F1(); - Diagnostic(ErrorCode.ERR_NoSuchMember, "F1").WithArguments("nint", "F1").WithLocation(5, 18), - // (6,15): error CS1061: 'nint' does not contain a definition for 'F2' and no accessible extension method 'F2' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // _ = x.F2(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F2").WithArguments("nint", "F2").WithLocation(6, 15), - // (11,19): error CS0117: 'nuint' does not contain a definition for 'F1' - // _ = nuint.F1(); - Diagnostic(ErrorCode.ERR_NoSuchMember, "F1").WithArguments("nuint", "F1").WithLocation(11, 19), - // (12,15): error CS1061: 'nuint' does not contain a definition for 'F2' and no accessible extension method 'F2' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) - // _ = y.F2(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F2").WithArguments("nuint", "F2").WithLocation(12, 15)); - - verifyType((NamedTypeSymbol)comp.GetMember("Program.F1").Parameters[0].Type, signed: true); - verifyType((NamedTypeSymbol)comp.GetMember("Program.F2").Parameters[0].Type, signed: false); - - static void verifyType(NamedTypeSymbol type, bool signed) - { - Assert.True(type.IsNativeIntegerType); - - VerifyType(type, signed: signed, isNativeInt: true); - VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); - - var underlyingType = type.NativeIntegerUnderlyingType; - var members = type.GetMembers().Sort(SymbolComparison); - var actualMembers = members.SelectAsArray(m => m.ToTestDisplayString()); - var expectedMembers = new[] - { - $"{type} {type}.F3()", - $"{type}..ctor()", - }; - AssertEx.Equal(expectedMembers, actualMembers); + // (7,26): error CS0133: The expression being assigned to 'y' must be constant + // const IntPtr y = unchecked((IntPtr)x); + Diagnostic(ErrorCode.ERR_NotConstantExpression, "unchecked((IntPtr)x)").WithArguments("y").WithLocation(7, 26)); - VerifyMembers(underlyingType, type, signed); - VerifyMembers(underlyingType.GetPublicSymbol(), type.GetPublicSymbol(), signed); - } - } - - [Theory] - [InlineData(false)] - [InlineData(true)] - public void OtherMembers(bool useCompilationReference) - { - var sourceA = -@"namespace System -{ - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct Int64 { } - public struct UInt32 { } - public struct UInt64 { } - public struct IntPtr - { - public static T M(T t) => t; - public IntPtr this[int index] => default; - } - public struct UIntPtr - { - public static T M(T t) => t; - public UIntPtr this[int index] => default; - } - public class Attribute { } -} -namespace System.Reflection + source = +@"using System; +class Program { - public class DefaultMemberAttribute : Attribute + static void Main() { - public DefaultMemberAttribute(string member) { } + const long x = 0xFFFFFFFFFFFFFFFL; + IntPtr y = unchecked((IntPtr)x); + Console.WriteLine(y); } }"; - var comp = CreateEmptyCompilation(sourceA); + mscorLibRef = MscorlibRefWithoutSharingCachedSymbols; + comp = CreateEmptyCompilation(source, references: new[] { mscorLibRef }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; comp.VerifyDiagnostics(); - var refA = AsReference(comp, useCompilationReference); - - var sourceB = -@"class Program -{ - static void F1(nint x) - { - _ = x.M(); - _ = x[0]; - } - static void F2(nuint y) - { - _ = y.M(); - _ = y[0]; - } -}"; - comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (5,15): error CS1061: 'nint' does not contain a definition for 'M' and no accessible extension method 'M' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // _ = x.M(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "M").WithArguments("nint", "M").WithLocation(5, 15), - // (6,13): error CS0021: Cannot apply indexing with [] to an expression of type 'nint' - // _ = x[0]; - Diagnostic(ErrorCode.ERR_BadIndexLHS, "x[0]").WithArguments("nint").WithLocation(6, 13), - // (10,15): error CS1061: 'nuint' does not contain a definition for 'M' and no accessible extension method 'M' accepting a first argument of type 'nuint' could be found (are you missing a using directive or an assembly reference?) - // _ = y.M(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "M").WithArguments("nuint", "M").WithLocation(10, 15), - // (11,13): error CS0021: Cannot apply indexing with [] to an expression of type 'nuint' - // _ = y[0]; - Diagnostic(ErrorCode.ERR_BadIndexLHS, "y[0]").WithArguments("nuint").WithLocation(11, 13)); - - verifyType((NamedTypeSymbol)comp.GetMember("Program.F1").Parameters[0].Type, signed: true); - verifyType((NamedTypeSymbol)comp.GetMember("Program.F2").Parameters[0].Type, signed: false); - - static void verifyType(NamedTypeSymbol type, bool signed) - { - Assert.True(type.IsNativeIntegerType); - - VerifyType(type, signed: signed, isNativeInt: true); - VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); - - var underlyingType = type.NativeIntegerUnderlyingType; - var members = type.GetMembers().Sort(SymbolComparison); - var actualMembers = members.SelectAsArray(m => m.ToTestDisplayString()); - var expectedMembers = new[] - { - $"{type}..ctor()", - }; - AssertEx.Equal(expectedMembers, actualMembers); - - VerifyMembers(underlyingType, type, signed); - VerifyMembers(underlyingType.GetPublicSymbol(), type.GetPublicSymbol(), signed); - } + CompileAndVerify(comp, expectedOutput: IntPtr.Size == 4 ? "-1" : "1152921504606846975"); } - // Custom modifiers are copied to native integer types but not substituted. [Fact] - public void CustomModifiers() - { - var sourceA = -@".assembly mscorlib -{ - .ver 0:0:0:0 -} -.class public System.Object -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } - .method public hidebysig newslot virtual instance string ToString() cil managed { ldnull throw } - .method public hidebysig newslot virtual instance bool Equals(object obj) cil managed { ldnull throw } - .method public hidebysig newslot virtual instance int32 GetHashCode() cil managed { ldnull throw } -} -.class public abstract System.ValueType extends System.Object -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} -.class public System.String extends System.Object -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} -.class public sealed System.Void extends System.ValueType -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} -.class public sealed System.Boolean extends System.ValueType -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} -.class public sealed System.Int32 extends System.ValueType -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} -.class public interface System.IComparable`1 -{ -} -.class public sealed System.IntPtr extends System.ValueType -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } - .method public hidebysig static native int modopt(native int) F1() cil managed { ldnull throw } - .method public hidebysig static native int& modopt(native int) F2() cil managed { ldnull throw } - .method public hidebysig static void F3(native int modopt(native int) i) cil managed { ret } - .method public hidebysig static void F4(native int& modopt(native int) i) cil managed { ret } - .method public hidebysig instance class System.IComparable`1 F5() cil managed { ldnull throw } - .method public hidebysig instance void F6(native int modopt(class System.IComparable`1) i) cil managed { ret } - .method public hidebysig instance native int modopt(native int) get_P() cil managed { ldnull throw } - .method public hidebysig instance native int& modopt(native int) get_Q() cil managed { ldnull throw } - .method public hidebysig instance void set_P(native int modopt(native int) i) cil managed { ret } - .property instance native int modopt(native int) P() - { - .get instance native int modopt(native int) System.IntPtr::get_P() - .set instance void System.IntPtr::set_P(native int modopt(native int)) - } - .property instance native int& modopt(native int) Q() - { - .get instance native int& modopt(native int) System.IntPtr::get_Q() - } -} -.class public sealed System.UIntPtr extends System.ValueType -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } - .method public hidebysig static native uint modopt(native uint) F1() cil managed { ldnull throw } - .method public hidebysig static native uint& modopt(native uint) F2() cil managed { ldnull throw } - .method public hidebysig static void F3(native uint modopt(native uint) i) cil managed { ret } - .method public hidebysig static void F4(native uint& modopt(native uint) i) cil managed { ret } - .method public hidebysig instance class System.IComparable`1 F5() cil managed { ldnull throw } - .method public hidebysig instance void F6(native uint modopt(class System.IComparable`1) i) cil managed { ret } - .method public hidebysig instance native uint modopt(native uint) get_P() cil managed { ldnull throw } - .method public hidebysig instance native uint& modopt(native uint) get_Q() cil managed { ldnull throw } - .method public hidebysig instance void set_P(native uint modopt(native uint) i) cil managed { ret } - .property instance native uint modopt(native uint) P() - { - .get instance native uint modopt(native uint) System.UIntPtr::get_P() - .set instance void System.UIntPtr::set_P(native uint modopt(native uint)) - } - .property instance native uint& modopt(native uint) Q() - { - .get instance native uint& modopt(native uint) System.UIntPtr::get_Q() - } -}"; - var refA = CompileIL(sourceA, prependDefaultHeader: false, autoInherit: false); - var sourceB = -@"class Program -{ - static void F1(nint i) - { - _ = nint.F1(); - _ = nint.F2(); - nint.F3(i); - nint.F4(ref i); - _ = i.F5(); - i.F6(i); - _ = i.P; - _ = i.Q; - i.P = i; - } - static void F2(nuint u) + public void ConstantConversions_03() { - _ = nuint.F1(); - _ = nuint.F2(); - nuint.F3(u); - nuint.F4(ref u); - _ = u.F5(); - u.F6(u); - _ = u.P; - _ = u.Q; - u.P = u; - } -}"; - - var comp = CreateEmptyCompilation(sourceB, new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); + using var _ = new EnsureInvariantCulture(); - verifyType((NamedTypeSymbol)comp.GetMember("Program.F1").Parameters[0].Type, signed: true); - verifyType((NamedTypeSymbol)comp.GetMember("Program.F2").Parameters[0].Type, signed: false); + constantConversions("sbyte", "IntPtr", "-1", null, "-1", "-1", null, "-1", "-1"); + constantConversions("sbyte", "IntPtr", "sbyte.MinValue", null, "-128", "-128", null, "-128", "-128"); + constantConversions("sbyte", "IntPtr", "sbyte.MaxValue", null, "127", "127", null, "127", "127"); + constantConversions("byte", "IntPtr", "byte.MaxValue", null, "255", "255", null, "255", "255"); + constantConversions("short", "IntPtr", "-1", null, "-1", "-1", null, "-1", "-1"); + constantConversions("short", "IntPtr", "short.MinValue", null, "-32768", "-32768", null, "-32768", "-32768"); + constantConversions("short", "IntPtr", "short.MaxValue", null, "32767", "32767", null, "32767", "32767"); + constantConversions("ushort", "IntPtr", "ushort.MaxValue", null, "65535", "65535", null, "65535", "65535"); + constantConversions("char", "IntPtr", "char.MaxValue", null, "65535", "65535", null, "65535", "65535"); + constantConversions("int", "IntPtr", "int.MinValue", null, "-2147483648", "-2147483648", null, "-2147483648", "-2147483648"); + constantConversions("int", "IntPtr", "int.MaxValue", null, "2147483647", "2147483647", null, "2147483647", "2147483647"); + constantConversions("uint", "IntPtr", "(int.MaxValue + 1U)", warningOutOfRangeChecked("IntPtr", "2147483648"), "System.OverflowException", "2147483648", null, "-2147483648", "2147483648"); + constantConversions("uint", "IntPtr", "uint.MaxValue", warningOutOfRangeChecked("IntPtr", "4294967295"), "System.OverflowException", "4294967295", null, "-1", "4294967295"); + constantConversions("long", "IntPtr", "(int.MinValue - 1L)", warningOutOfRangeChecked("IntPtr", "-2147483649"), "System.OverflowException", "-2147483649", null, "2147483647", "-2147483649"); + constantConversions("long", "IntPtr", "(int.MaxValue + 1L)", warningOutOfRangeChecked("IntPtr", "2147483648"), "System.OverflowException", "2147483648", null, "-2147483648", "2147483648"); + constantConversions("long", "IntPtr", "long.MinValue", warningOutOfRangeChecked("IntPtr", "-9223372036854775808"), "System.OverflowException", "-9223372036854775808", null, "0", "-9223372036854775808"); + constantConversions("long", "IntPtr", "long.MaxValue", warningOutOfRangeChecked("IntPtr", "9223372036854775807"), "System.OverflowException", "9223372036854775807", null, "-1", "9223372036854775807"); + constantConversions("ulong", "IntPtr", "(int.MaxValue + 1UL)", warningOutOfRangeChecked("IntPtr", "2147483648"), "System.OverflowException", "2147483648", null, "-2147483648", "2147483648"); + constantConversions("ulong", "IntPtr", "ulong.MaxValue", errorOutOfRangeChecked("IntPtr", "18446744073709551615"), "System.OverflowException", "System.OverflowException", null, "-1", "-1"); + constantConversions("decimal", "IntPtr", "(int.MinValue - 1M)", errorOutOfRange("IntPtr", "-2147483649M"), "System.OverflowException", "-2147483649", errorOutOfRange("IntPtr", "-2147483649M"), "2147483647", "-2147483649"); + constantConversions("decimal", "IntPtr", "(int.MaxValue + 1M)", errorOutOfRange("IntPtr", "2147483648M"), "System.OverflowException", "2147483648", errorOutOfRange("IntPtr", "2147483648M"), "-2147483648", "2147483648"); + constantConversions("decimal", "IntPtr", "decimal.MinValue", errorOutOfRange("IntPtr", "-79228162514264337593543950335M"), "System.OverflowException", "System.OverflowException", errorOutOfRange("IntPtr", "-79228162514264337593543950335M"), "-1", "-1"); + constantConversions("decimal", "IntPtr", "decimal.MaxValue", errorOutOfRange("IntPtr", "79228162514264337593543950335M"), "System.OverflowException", "System.OverflowException", errorOutOfRange("IntPtr", "79228162514264337593543950335M"), "-1", "-1"); + constantConversions("IntPtr", "IntPtr", "int.MinValue", null, "-2147483648", "-2147483648", null, "-2147483648", "-2147483648"); + constantConversions("IntPtr", "IntPtr", "int.MaxValue", null, "2147483647", "2147483647", null, "2147483647", "2147483647"); + constantConversions("UIntPtr", "IntPtr", "(int.MaxValue + (nuint)1)", warningOutOfRangeChecked("IntPtr", "2147483648"), "System.OverflowException", "2147483648", null, "-2147483648", "2147483648"); + constantConversions("sbyte", "UIntPtr", "-1", errorOutOfRangeChecked("UIntPtr", "-1"), "System.OverflowException", "System.OverflowException", null, "4294967295", "18446744073709551615"); + constantConversions("sbyte", "UIntPtr", "sbyte.MinValue", errorOutOfRangeChecked("UIntPtr", "-128"), "System.OverflowException", "System.OverflowException", null, "4294967168", "18446744073709551488"); + constantConversions("sbyte", "UIntPtr", "sbyte.MaxValue", null, "127", "127", null, "127", "127"); + constantConversions("byte", "UIntPtr", "byte.MaxValue", null, "255", "255", null, "255", "255"); + constantConversions("short", "UIntPtr", "-1", errorOutOfRangeChecked("UIntPtr", "-1"), "System.OverflowException", "System.OverflowException", null, "4294967295", "18446744073709551615"); + constantConversions("short", "UIntPtr", "short.MinValue", errorOutOfRangeChecked("UIntPtr", "-32768"), "System.OverflowException", "System.OverflowException", null, "4294934528", "18446744073709518848"); + constantConversions("short", "UIntPtr", "short.MaxValue", null, "32767", "32767", null, "32767", "32767"); + constantConversions("ushort", "UIntPtr", "ushort.MaxValue", null, "65535", "65535", null, "65535", "65535"); + constantConversions("char", "UIntPtr", "char.MaxValue", null, "65535", "65535", null, "65535", "65535"); + constantConversions("int", "UIntPtr", "-1", errorOutOfRangeChecked("UIntPtr", "-1"), "System.OverflowException", "System.OverflowException", null, "4294967295", "18446744073709551615"); + constantConversions("int", "UIntPtr", "int.MinValue", errorOutOfRangeChecked("UIntPtr", "-2147483648"), "System.OverflowException", "System.OverflowException", null, "2147483648", "18446744071562067968"); + constantConversions("int", "UIntPtr", "int.MaxValue", null, "2147483647", "2147483647", null, "2147483647", "2147483647"); + constantConversions("uint", "UIntPtr", "uint.MaxValue", null, "4294967295", "4294967295", null, "4294967295", "4294967295"); + constantConversions("long", "UIntPtr", "-1", errorOutOfRangeChecked("UIntPtr", "-1"), "System.OverflowException", "System.OverflowException", null, "4294967295", "18446744073709551615"); + constantConversions("long", "UIntPtr", "uint.MaxValue + 1L", warningOutOfRangeChecked("UIntPtr", "4294967296"), "System.OverflowException", "4294967296", null, "0", "4294967296"); + constantConversions("long", "UIntPtr", "long.MinValue", errorOutOfRangeChecked("UIntPtr", "-9223372036854775808"), "System.OverflowException", "System.OverflowException", null, "0", "9223372036854775808"); + constantConversions("long", "UIntPtr", "long.MaxValue", warningOutOfRangeChecked("UIntPtr", "9223372036854775807"), "System.OverflowException", "9223372036854775807", null, "4294967295", "9223372036854775807"); + constantConversions("ulong", "UIntPtr", "uint.MaxValue + 1UL", warningOutOfRangeChecked("UIntPtr", "4294967296"), "System.OverflowException", "4294967296", null, "0", "4294967296"); + constantConversions("ulong", "UIntPtr", "ulong.MaxValue", warningOutOfRangeChecked("UIntPtr", "18446744073709551615"), "System.OverflowException", "18446744073709551615", null, "4294967295", "18446744073709551615"); + constantConversions("decimal", "UIntPtr", "-1", errorOutOfRange("UIntPtr", "-1M"), "System.OverflowException", "System.OverflowException", errorOutOfRange("UIntPtr", "-1M"), "System.OverflowException", "System.OverflowException"); + constantConversions("decimal", "UIntPtr", "(uint.MaxValue + 1M)", errorOutOfRange("UIntPtr", "4294967296M"), "System.OverflowException", "4294967296", errorOutOfRange("UIntPtr", "4294967296M"), "-1", "4294967296"); + constantConversions("decimal", "UIntPtr", "decimal.MinValue", errorOutOfRange("UIntPtr", "-79228162514264337593543950335M"), "System.OverflowException", "System.OverflowException", errorOutOfRange("UIntPtr", "-79228162514264337593543950335M"), "-1", "-1"); + constantConversions("decimal", "UIntPtr", "decimal.MaxValue", errorOutOfRange("UIntPtr", "79228162514264337593543950335M"), "System.OverflowException", "System.OverflowException", errorOutOfRange("UIntPtr", "79228162514264337593543950335M"), "-1", "-1"); + constantConversions("IntPtr", "UIntPtr", "-1", errorOutOfRangeChecked("UIntPtr", "-1"), "System.OverflowException", "System.OverflowException", null, "4294967295", "18446744073709551615"); + constantConversions("UIntPtr", "UIntPtr", "uint.MaxValue", null, "4294967295", "4294967295", null, "4294967295", "4294967295"); + if (!ExecutionConditionUtil.IsWindowsDesktop) + { + // There are differences in floating point precision across platforms + // so floating point tests are limited to one platform. + return; + } + constantConversions("float", "IntPtr", "(int.MinValue - 10000F)", warningOutOfRangeChecked("IntPtr", "-2.147494E+09"), "System.OverflowException", "-2147493632", null, "-2147483648", "-2147493632"); + constantConversions("float", "IntPtr", "(int.MaxValue + 10000F)", warningOutOfRangeChecked("IntPtr", "2.147494E+09"), "System.OverflowException", "2147493632", null, "-2147483648", "2147493632"); + constantConversions("float", "IntPtr", "float.MinValue", errorOutOfRangeChecked("IntPtr", "-3.402823E+38"), "System.OverflowException", "System.OverflowException", null, "-2147483648", "-9223372036854775808"); + constantConversions("float", "IntPtr", "float.MaxValue", errorOutOfRangeChecked("IntPtr", "3.402823E+38"), "System.OverflowException", "System.OverflowException", null, "-2147483648", "-9223372036854775808"); + constantConversions("double", "IntPtr", "(int.MinValue - 1D)", warningOutOfRangeChecked("IntPtr", "-2147483649"), "System.OverflowException", "-2147483649", null, "-2147483648", "-2147483649"); + constantConversions("double", "IntPtr", "(int.MaxValue + 1D)", warningOutOfRangeChecked("IntPtr", "2147483648"), "System.OverflowException", "2147483648", null, "-2147483648", "2147483648"); + constantConversions("double", "IntPtr", "double.MinValue", errorOutOfRangeChecked("IntPtr", "-1.79769313486232E+308"), "System.OverflowException", "System.OverflowException", null, "-2147483648", "-9223372036854775808"); + constantConversions("double", "IntPtr", "double.MaxValue", errorOutOfRangeChecked("IntPtr", "1.79769313486232E+308"), "System.OverflowException", "System.OverflowException", null, "-2147483648", "-9223372036854775808"); + constantConversions("float", "UIntPtr", "-1", errorOutOfRangeChecked("UIntPtr", "-1"), "System.OverflowException", "System.OverflowException", null, "4294967295", "18446744073709551615"); + constantConversions("float", "UIntPtr", "(uint.MaxValue + 1F)", warningOutOfRangeChecked("UIntPtr", "4.294967E+09"), "System.OverflowException", "4294967296", null, "0", "4294967296"); + constantConversions("float", "UIntPtr", "float.MinValue", errorOutOfRangeChecked("UIntPtr", "-3.402823E+38"), "System.OverflowException", "System.OverflowException", null, "0", "9223372036854775808"); + constantConversions("float", "UIntPtr", "float.MaxValue", errorOutOfRangeChecked("UIntPtr", "3.402823E+38"), "System.OverflowException", "System.OverflowException", null, "0", "0"); + constantConversions("double", "UIntPtr", "-1", errorOutOfRangeChecked("UIntPtr", "-1"), "System.OverflowException", "System.OverflowException", null, "4294967295", "18446744073709551615"); + constantConversions("double", "UIntPtr", "(uint.MaxValue + 1D)", warningOutOfRangeChecked("UIntPtr", "4294967296"), "System.OverflowException", "4294967296", null, "0", "4294967296"); + constantConversions("double", "UIntPtr", "double.MinValue", errorOutOfRangeChecked("UIntPtr", "-1.79769313486232E+308"), "System.OverflowException", "System.OverflowException", null, "0", "9223372036854775808"); + constantConversions("double", "UIntPtr", "double.MaxValue", errorOutOfRangeChecked("UIntPtr", "1.79769313486232E+308"), "System.OverflowException", "System.OverflowException", null, "0", "0"); + + static DiagnosticDescription errorOutOfRangeChecked(string destinationType, string value) => Diagnostic(ErrorCode.ERR_ConstOutOfRangeChecked, $"({destinationType})x").WithArguments(value, AsNative(destinationType)); + static DiagnosticDescription errorOutOfRange(string destinationType, string value) => Diagnostic(ErrorCode.ERR_ConstOutOfRange, $"({destinationType})x").WithArguments(value, AsNative(destinationType)); + static DiagnosticDescription warningOutOfRangeChecked(string destinationType, string value) => Diagnostic(ErrorCode.WRN_ConstOutOfRangeChecked, $"({destinationType})x").WithArguments(value, AsNative(destinationType)); - static void verifyType(NamedTypeSymbol type, bool signed) + void constantConversions(string sourceType, string destinationType, string sourceValue, DiagnosticDescription checkedError, string checked32, string checked64, DiagnosticDescription uncheckedError, string unchecked32, string unchecked64) { - Assert.True(type.IsNativeIntegerType); + constantConversion(sourceType, destinationType, sourceValue, useChecked: true, checkedError, IntPtr.Size == 4 ? checked32 : checked64); + constantConversion(sourceType, destinationType, sourceValue, useChecked: false, uncheckedError, IntPtr.Size == 4 ? unchecked32 : unchecked64); + } - VerifyType(type, signed: signed, isNativeInt: true); - VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); + void constantConversion(string sourceType, string destinationType, string sourceValue, bool useChecked, DiagnosticDescription expectedError, string expectedOutput) + { + var source = +$@"using System; +class Program +{{ + static void Main() + {{ + const {sourceType} x = {sourceValue}; + object y; + try + {{ + y = {(useChecked ? "checked" : "unchecked")}(({destinationType})x); + }} + catch (Exception e) + {{ + y = e.GetType(); + }} + Console.Write(y); + }} +}}"; + var mscorLibRef = MscorlibRefWithoutSharingCachedSymbols; + var comp = CreateEmptyCompilation(source, references: new[] { mscorLibRef }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - var underlyingType = type.NativeIntegerUnderlyingType; - var members = type.GetMembers().Sort(SymbolComparison); - var actualMembers = members.SelectAsArray(m => m.ToTestDisplayString()); - var expectedMembers = new[] + comp.VerifyDiagnostics(expectedError is null ? Array.Empty() : new[] { expectedError }); + if (expectedError == null || ErrorFacts.IsWarning((ErrorCode)expectedError.Code)) { - $"System.IComparable<{type} modopt({underlyingType})> {type}.F5()", - $"{type} modopt({underlyingType}) {type}.F1()", - $"{type} modopt({underlyingType}) {type}.P {{ get; set; }}", - $"{type} modopt({underlyingType}) {type}.P.get", - $"{type}..ctor()", - $"ref modopt({underlyingType}) {type} {type}.F2()", - $"ref modopt({underlyingType}) {type} {type}.Q {{ get; }}", - $"ref modopt({underlyingType}) {type} {type}.Q.get", - $"void {type}.F3({type} modopt({underlyingType}) i)", - $"void {type}.F4(ref modopt({underlyingType}) {type} i)", - $"void {type}.F6({type} modopt(System.IComparable<{underlyingType}>) i)", - $"void {type}.P.set", - }; - AssertEx.Equal(expectedMembers, actualMembers); - - VerifyMembers(underlyingType, type, signed); - VerifyMembers(underlyingType.GetPublicSymbol(), type.GetPublicSymbol(), signed); + CompileAndVerify(comp, expectedOutput: expectedOutput); + } } } - [Fact] - public void DefaultConstructors() + [Theory] + [InlineData("nint")] + [InlineData("System.IntPtr")] + public void Constants_NInt(string type) { - var source = -@"class Program -{ + string source = +$@"class Program +{{ static void Main() - { - F(new nint()); - F(new nuint()); - } - static void F(object o) - { - System.Console.WriteLine(o); - } + {{ + F(default); + F(int.MinValue); + F({short.MinValue - 1}); + F(short.MinValue); + F(sbyte.MinValue); + F(-2); + F(-1); + F(0); + F(1); + F(2); + F(3); + F(4); + F(5); + F(6); + F(7); + F(8); + F(9); + F(sbyte.MaxValue); + F(byte.MaxValue); + F(short.MaxValue); + F(char.MaxValue); + F(ushort.MaxValue); + F({ushort.MaxValue + 1}); + F(int.MaxValue); + }} + static void F({type} n) + {{ + System.Console.WriteLine(n); + }} +}}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + string expectedOutput = +@"0 +-2147483648 +-32769 +-32768 +-128 +-2 +-1 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +127 +255 +32767 +65535 +65535 +65536 +2147483647"; + var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput); + string expectedIL = +@"{ + // Code size 209 (0xd1) + .maxstack 1 + IL_0000: ldc.i4.0 + IL_0001: conv.i + IL_0002: call ""void Program.F(nint)"" + IL_0007: ldc.i4 0x80000000 + IL_000c: conv.i + IL_000d: call ""void Program.F(nint)"" + IL_0012: ldc.i4 0xffff7fff + IL_0017: conv.i + IL_0018: call ""void Program.F(nint)"" + IL_001d: ldc.i4 0xffff8000 + IL_0022: conv.i + IL_0023: call ""void Program.F(nint)"" + IL_0028: ldc.i4.s -128 + IL_002a: conv.i + IL_002b: call ""void Program.F(nint)"" + IL_0030: ldc.i4.s -2 + IL_0032: conv.i + IL_0033: call ""void Program.F(nint)"" + IL_0038: ldc.i4.m1 + IL_0039: conv.i + IL_003a: call ""void Program.F(nint)"" + IL_003f: ldc.i4.0 + IL_0040: conv.i + IL_0041: call ""void Program.F(nint)"" + IL_0046: ldc.i4.1 + IL_0047: conv.i + IL_0048: call ""void Program.F(nint)"" + IL_004d: ldc.i4.2 + IL_004e: conv.i + IL_004f: call ""void Program.F(nint)"" + IL_0054: ldc.i4.3 + IL_0055: conv.i + IL_0056: call ""void Program.F(nint)"" + IL_005b: ldc.i4.4 + IL_005c: conv.i + IL_005d: call ""void Program.F(nint)"" + IL_0062: ldc.i4.5 + IL_0063: conv.i + IL_0064: call ""void Program.F(nint)"" + IL_0069: ldc.i4.6 + IL_006a: conv.i + IL_006b: call ""void Program.F(nint)"" + IL_0070: ldc.i4.7 + IL_0071: conv.i + IL_0072: call ""void Program.F(nint)"" + IL_0077: ldc.i4.8 + IL_0078: conv.i + IL_0079: call ""void Program.F(nint)"" + IL_007e: ldc.i4.s 9 + IL_0080: conv.i + IL_0081: call ""void Program.F(nint)"" + IL_0086: ldc.i4.s 127 + IL_0088: conv.i + IL_0089: call ""void Program.F(nint)"" + IL_008e: ldc.i4 0xff + IL_0093: conv.i + IL_0094: call ""void Program.F(nint)"" + IL_0099: ldc.i4 0x7fff + IL_009e: conv.i + IL_009f: call ""void Program.F(nint)"" + IL_00a4: ldc.i4 0xffff + IL_00a9: conv.i + IL_00aa: call ""void Program.F(nint)"" + IL_00af: ldc.i4 0xffff + IL_00b4: conv.i + IL_00b5: call ""void Program.F(nint)"" + IL_00ba: ldc.i4 0x10000 + IL_00bf: conv.i + IL_00c0: call ""void Program.F(nint)"" + IL_00c5: ldc.i4 0x7fffffff + IL_00ca: conv.i + IL_00cb: call ""void Program.F(nint)"" + IL_00d0: ret }"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics( - // (5,15): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F(new nint()); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "nint").WithArguments("native-sized integers", "9.0").WithLocation(5, 15), - // (6,15): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F(new nuint()); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "nuint").WithArguments("native-sized integers", "9.0").WithLocation(6, 15)); - - comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); + verifier.VerifyIL("Program.Main", expectedIL); + } - var verifier = CompileAndVerify(comp, expectedOutput: + [Theory] + [InlineData("nuint")] + [InlineData("System.UIntPtr")] + public void Constants_NUInt(string type) + { + string source = +$@"class Program +{{ + static void Main() + {{ + F(default); + F(0); + F(1); + F(2); + F(3); + F(4); + F(5); + F(6); + F(7); + F(8); + F(9); + F(byte.MaxValue); + F(char.MaxValue); + F(ushort.MaxValue); + F(int.MaxValue); + F({(uint)int.MaxValue + 1}); + F(uint.MaxValue); + }} + static void F({type} n) + {{ + System.Console.WriteLine(n); + }} +}}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + string expectedOutput = @"0 -0"); - verifier.VerifyIL("Program.Main", +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +255 +65535 +65535 +2147483647 +2147483648 +4294967295"; + var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput); + string expectedIL = @"{ - // Code size 25 (0x19) + // Code size 141 (0x8d) .maxstack 1 IL_0000: ldc.i4.0 IL_0001: conv.i - IL_0002: box ""System.IntPtr"" - IL_0007: call ""void Program.F(object)"" - IL_000c: ldc.i4.0 - IL_000d: conv.i - IL_000e: box ""System.UIntPtr"" - IL_0013: call ""void Program.F(object)"" - IL_0018: ret -}"); + IL_0002: call ""void Program.F(nuint)"" + IL_0007: ldc.i4.0 + IL_0008: conv.i + IL_0009: call ""void Program.F(nuint)"" + IL_000e: ldc.i4.1 + IL_000f: conv.i + IL_0010: call ""void Program.F(nuint)"" + IL_0015: ldc.i4.2 + IL_0016: conv.i + IL_0017: call ""void Program.F(nuint)"" + IL_001c: ldc.i4.3 + IL_001d: conv.i + IL_001e: call ""void Program.F(nuint)"" + IL_0023: ldc.i4.4 + IL_0024: conv.i + IL_0025: call ""void Program.F(nuint)"" + IL_002a: ldc.i4.5 + IL_002b: conv.i + IL_002c: call ""void Program.F(nuint)"" + IL_0031: ldc.i4.6 + IL_0032: conv.i + IL_0033: call ""void Program.F(nuint)"" + IL_0038: ldc.i4.7 + IL_0039: conv.i + IL_003a: call ""void Program.F(nuint)"" + IL_003f: ldc.i4.8 + IL_0040: conv.i + IL_0041: call ""void Program.F(nuint)"" + IL_0046: ldc.i4.s 9 + IL_0048: conv.i + IL_0049: call ""void Program.F(nuint)"" + IL_004e: ldc.i4 0xff + IL_0053: conv.i + IL_0054: call ""void Program.F(nuint)"" + IL_0059: ldc.i4 0xffff + IL_005e: conv.i + IL_005f: call ""void Program.F(nuint)"" + IL_0064: ldc.i4 0xffff + IL_0069: conv.i + IL_006a: call ""void Program.F(nuint)"" + IL_006f: ldc.i4 0x7fffffff + IL_0074: conv.i + IL_0075: call ""void Program.F(nuint)"" + IL_007a: ldc.i4 0x80000000 + IL_007f: conv.u + IL_0080: call ""void Program.F(nuint)"" + IL_0085: ldc.i4.m1 + IL_0086: conv.u + IL_0087: call ""void Program.F(nuint)"" + IL_008c: ret +}"; + verifier.VerifyIL("Program.Main", expectedIL); } [Fact] - public void NewConstraint() + public void Constants_ConvertToUnsigned() { - var source = + string source = @"class Program { static void Main() { - F(); - F(); + F(sbyte.MaxValue); // 1 + F(short.MaxValue); // 2 + F(int.MaxValue); // 3 + F(long.MaxValue); // 4 + F(sbyte.MaxValue); // 5 + F(short.MaxValue); // 6 + F(int.MaxValue); // 7 + F(long.MaxValue); // 8 + F(sbyte.MaxValue); // 9 + F(short.MaxValue); // 10 + F(int.MaxValue); // 11 + F(long.MaxValue); // 12 + F(sbyte.MaxValue); // 13 + F(short.MaxValue); // 14 + F(int.MaxValue); // 15 + F(long.MaxValue); // 16 + F(sbyte.MaxValue); // 17 + F(short.MaxValue); // 18 + F(int.MaxValue); // 19 + F(long.MaxValue); // 20 } - static void F() where T : new() + static void F(T n) { - System.Console.WriteLine(new T()); } }"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular8); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; comp.VerifyDiagnostics( - // (5,11): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F(); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "nint").WithArguments("native-sized integers", "9.0").WithLocation(5, 11), - // (6,11): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F(); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "nuint").WithArguments("native-sized integers", "9.0").WithLocation(6, 11)); - - comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - - var verifier = CompileAndVerify(comp, expectedOutput: -@"0 -0"); - verifier.VerifyIL("Program.Main", -@"{ - // Code size 11 (0xb) - .maxstack 0 - IL_0000: call ""void Program.F()"" - IL_0005: call ""void Program.F()"" - IL_000a: ret -}"); + // (5,19): error CS1503: Argument 1: cannot convert from 'sbyte' to 'ushort' + // F(sbyte.MaxValue); // 1 + Diagnostic(ErrorCode.ERR_BadArgType, "sbyte.MaxValue").WithArguments("1", "sbyte", "ushort").WithLocation(5, 19), + // (6,19): error CS1503: Argument 1: cannot convert from 'short' to 'ushort' + // F(short.MaxValue); // 2 + Diagnostic(ErrorCode.ERR_BadArgType, "short.MaxValue").WithArguments("1", "short", "ushort").WithLocation(6, 19), + // (7,19): error CS1503: Argument 1: cannot convert from 'int' to 'ushort' + // F(int.MaxValue); // 3 + Diagnostic(ErrorCode.ERR_BadArgType, "int.MaxValue").WithArguments("1", "int", "ushort").WithLocation(7, 19), + // (8,19): error CS1503: Argument 1: cannot convert from 'long' to 'ushort' + // F(long.MaxValue); // 4 + Diagnostic(ErrorCode.ERR_BadArgType, "long.MaxValue").WithArguments("1", "long", "ushort").WithLocation(8, 19), + // (9,17): error CS1503: Argument 1: cannot convert from 'sbyte' to 'uint' + // F(sbyte.MaxValue); // 5 + Diagnostic(ErrorCode.ERR_BadArgType, "sbyte.MaxValue").WithArguments("1", "sbyte", "uint").WithLocation(9, 17), + // (10,17): error CS1503: Argument 1: cannot convert from 'short' to 'uint' + // F(short.MaxValue); // 6 + Diagnostic(ErrorCode.ERR_BadArgType, "short.MaxValue").WithArguments("1", "short", "uint").WithLocation(10, 17), + // (12,17): error CS1503: Argument 1: cannot convert from 'long' to 'uint' + // F(long.MaxValue); // 8 + Diagnostic(ErrorCode.ERR_BadArgType, "long.MaxValue").WithArguments("1", "long", "uint").WithLocation(12, 17), + // (13,27): error CS1503: Argument 1: cannot convert from 'sbyte' to 'nuint' + // F(sbyte.MaxValue); // 9 + Diagnostic(ErrorCode.ERR_BadArgType, "sbyte.MaxValue").WithArguments("1", "sbyte", "nuint").WithLocation(13, 27), + // (14,27): error CS1503: Argument 1: cannot convert from 'short' to 'nuint' + // F(short.MaxValue); // 10 + Diagnostic(ErrorCode.ERR_BadArgType, "short.MaxValue").WithArguments("1", "short", "nuint").WithLocation(14, 27), + // (16,27): error CS1503: Argument 1: cannot convert from 'long' to 'nuint' + // F(long.MaxValue); // 12 + Diagnostic(ErrorCode.ERR_BadArgType, "long.MaxValue").WithArguments("1", "long", "nuint").WithLocation(16, 27), + // (17,18): error CS1503: Argument 1: cannot convert from 'sbyte' to 'nuint' + // F(sbyte.MaxValue); // 13 + Diagnostic(ErrorCode.ERR_BadArgType, "sbyte.MaxValue").WithArguments("1", "sbyte", "nuint").WithLocation(17, 18), + // (18,18): error CS1503: Argument 1: cannot convert from 'short' to 'nuint' + // F(short.MaxValue); // 14 + Diagnostic(ErrorCode.ERR_BadArgType, "short.MaxValue").WithArguments("1", "short", "nuint").WithLocation(18, 18), + // (20,18): error CS1503: Argument 1: cannot convert from 'long' to 'nuint' + // F(long.MaxValue); // 16 + Diagnostic(ErrorCode.ERR_BadArgType, "long.MaxValue").WithArguments("1", "long", "nuint").WithLocation(20, 18), + // (21,18): error CS1503: Argument 1: cannot convert from 'sbyte' to 'ulong' + // F(sbyte.MaxValue); // 17 + Diagnostic(ErrorCode.ERR_BadArgType, "sbyte.MaxValue").WithArguments("1", "sbyte", "ulong").WithLocation(21, 18), + // (22,18): error CS1503: Argument 1: cannot convert from 'short' to 'ulong' + // F(short.MaxValue); // 18 + Diagnostic(ErrorCode.ERR_BadArgType, "short.MaxValue").WithArguments("1", "short", "ulong").WithLocation(22, 18) + ); } [Fact] - public void ArrayInitialization() + public void Constants_Locals() { var source = -@"class Program +@"#pragma warning disable 219 +class Program { static void Main() { - Report(new nint[] { int.MinValue, -1, 0, 1, int.MaxValue }); - Report(new nuint[] { 0, 1, 2, int.MaxValue, uint.MaxValue }); - } - static void Report(T[] items) - { - foreach (var item in items) - System.Console.WriteLine($""{item.GetType().FullName}: {item}""); + const System.IntPtr a = default; + const nint b = default; + const System.UIntPtr c = default; + const nuint d = default; } }"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - var verifier = CompileAndVerify(comp, expectedOutput: -@"System.IntPtr: -2147483648 -System.IntPtr: -1 -System.IntPtr: 0 -System.IntPtr: 1 -System.IntPtr: 2147483647 -System.UIntPtr: 0 -System.UIntPtr: 1 -System.UIntPtr: 2 -System.UIntPtr: 2147483647 -System.UIntPtr: 4294967295"); - verifier.VerifyIL("Program.Main", -@"{ - // Code size 75 (0x4b) - .maxstack 4 - IL_0000: ldc.i4.5 - IL_0001: newarr ""System.IntPtr"" - IL_0006: dup - IL_0007: ldc.i4.0 - IL_0008: ldc.i4 0x80000000 - IL_000d: conv.i - IL_000e: stelem.i - IL_000f: dup - IL_0010: ldc.i4.1 - IL_0011: ldc.i4.m1 - IL_0012: conv.i - IL_0013: stelem.i - IL_0014: dup - IL_0015: ldc.i4.3 - IL_0016: ldc.i4.1 - IL_0017: conv.i - IL_0018: stelem.i - IL_0019: dup - IL_001a: ldc.i4.4 - IL_001b: ldc.i4 0x7fffffff - IL_0020: conv.i - IL_0021: stelem.i - IL_0022: call ""void Program.Report(nint[])"" - IL_0027: ldc.i4.5 - IL_0028: newarr ""System.UIntPtr"" - IL_002d: dup - IL_002e: ldc.i4.1 - IL_002f: ldc.i4.1 - IL_0030: conv.i - IL_0031: stelem.i - IL_0032: dup - IL_0033: ldc.i4.2 - IL_0034: ldc.i4.2 - IL_0035: conv.i - IL_0036: stelem.i - IL_0037: dup - IL_0038: ldc.i4.3 - IL_0039: ldc.i4 0x7fffffff - IL_003e: conv.i - IL_003f: stelem.i - IL_0040: dup - IL_0041: ldc.i4.4 - IL_0042: ldc.i4.m1 - IL_0043: conv.u - IL_0044: stelem.i - IL_0045: call ""void Program.Report(nuint[])"" - IL_004a: ret -}"); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(); } [Fact] - public void Overrides_01() + public void Constants_Fields_01() { - var sourceA = -@"public interface IA -{ - void F1(nint x, System.UIntPtr y); -} -public abstract class A -{ - public abstract void F2(System.IntPtr x, nuint y); -}"; - var sourceB = -@"class B1 : A, IA -{ - public void F1(nint x, System.UIntPtr y) { } - public override void F2(System.IntPtr x, nuint y) { } -} -class B2 : A, IA -{ - public void F1(System.IntPtr x, nuint y) { } - public override void F2(nint x, System.UIntPtr y) { } -} -class A3 : IA -{ - void IA.F1(nint x, System.UIntPtr y) { } -} -class A4 : IA + var source = +@"class Program { - void IA.F1(System.IntPtr x, nuint y) { } -}"; - - var comp = CreateCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - - comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - var ref1 = comp.ToMetadataReference(); - var ref2 = comp.EmitToImageReference(); + const System.IntPtr A = default(System.IntPtr); + const nint B = default(nint); + const System.UIntPtr C = default(System.UIntPtr); + const nuint D = default(nuint); - comp = CreateCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); + public static void Main() + { + System.Console.Write($""{A}, {B}, {C}, {D}""); + } +}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - comp = CreateCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular9); comp.VerifyDiagnostics(); + CompileAndVerify(comp, expectedOutput: "0, 0, 0, 0"); } [Fact] - public void Overrides_02() + public void Constants_Fields_02() { - var sourceA = -@"public interface IA -{ - void F1(System.IntPtr x, System.UIntPtr y); -} -public abstract class A + var source0 = +@"public class A { - public abstract void F2(System.IntPtr x, System.UIntPtr y); + public const nint C1 = -42; + public const nuint C2 = 42; }"; - var sourceB = -@"class B1 : A, IA -{ - public void F1(nint x, System.UIntPtr y) { } - public override void F2(nint x, System.UIntPtr y) { } -} -class B2 : A, IA -{ - public void F1(System.IntPtr x, nuint y) { } - public override void F2(System.IntPtr x, nuint y) { } -} -class A3 : IA -{ - void IA.F1(nint x, System.UIntPtr y) { } -} -class A4 : IA + var comp = CreateEmptyCompilation(source0, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + var ref0 = comp.EmitToImageReference(); + var source1 = +@"using System; +class B { - void IA.F1(System.IntPtr x, nuint y) { } + static void Main() + { + Console.WriteLine(A.C1); + Console.WriteLine(A.C2); + } }"; - - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); - var ref1 = comp.ToMetadataReference(); - var ref2 = comp.EmitToImageReference(); - - comp = CreateCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - - comp = CreateCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); + comp = CreateEmptyCompilation(source1, references: new[] { ref0, MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + CompileAndVerify(comp, expectedOutput: +@"-42 +42"); } [Fact] - public void Overrides_03() + public void Constants_ParameterDefaults() { - var sourceA = -@"public interface IA -{ - void F1(nint x, System.UIntPtr y); -} -public abstract class A + var source0 = +@"public class A { - public abstract void F2(System.IntPtr x, nuint y); + public static System.IntPtr F1(System.IntPtr i = -42) => i; + public static nint F2(nint i = -42) => i; + public static System.UIntPtr F3(System.UIntPtr u = 42) => u; + public static nuint F4(nuint u = 42) => u; }"; - var sourceB = -@"class B1 : A, IA -{ - public void F1(System.IntPtr x, System.UIntPtr y) { } - public override void F2(System.IntPtr x, System.UIntPtr y) { } -} -class A2 : IA + var comp = CreateEmptyCompilation(source0, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + + var ref0 = comp.EmitToImageReference(); + var source1 = +@"using System; +class B { - void IA.F1(System.IntPtr x, System.UIntPtr y) { } + static void Main() + { + Console.WriteLine(A.F1()); + Console.WriteLine(A.F2()); + Console.WriteLine(A.F3()); + Console.WriteLine(A.F4()); + } }"; + comp = CreateEmptyCompilation(source1, references: new[] { ref0, MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - var ref1 = comp.ToMetadataReference(); - var ref2 = comp.EmitToImageReference(); + CompileAndVerify(comp, expectedOutput: +@"-42 +-42 +42 +42"); + } - comp = CreateCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); + [Fact] + public void ConstantValue_Properties() + { + var source = +@"using System; +class Program +{ + const IntPtr A = int.MinValue; + const IntPtr B = 0; + const IntPtr C = int.MaxValue; + const UIntPtr D = 0; + const UIntPtr E = uint.MaxValue; +}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - comp = CreateCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular8); comp.VerifyDiagnostics(); + verify((FieldSymbol)comp.GetMember("Program.A"), int.MinValue, signed: true, negative: true); + verify((FieldSymbol)comp.GetMember("Program.B"), 0, signed: true, negative: false); + verify((FieldSymbol)comp.GetMember("Program.C"), int.MaxValue, signed: true, negative: false); + verify((FieldSymbol)comp.GetMember("Program.D"), 0U, signed: false, negative: false); + verify((FieldSymbol)comp.GetMember("Program.E"), uint.MaxValue, signed: false, negative: false); + + static void verify(FieldSymbol field, object expectedValue, bool signed, bool negative) + { + var value = field.GetConstantValue(ConstantFieldsInProgress.Empty, earlyDecodingWellKnownAttributes: false); + Assert.Equal(signed ? ConstantValueTypeDiscriminator.NInt : ConstantValueTypeDiscriminator.NUInt, value.Discriminator); + Assert.Equal(expectedValue, value.Value); + Assert.True(value.IsIntegral); + Assert.True(value.IsNumeric); + Assert.Equal(negative, value.IsNegativeNumeric); + Assert.Equal(!signed, value.IsUnsigned); + } } + /// + /// Native integers cannot be used as attribute values. + /// [Fact] - public void Overloads_01() + public void AttributeValue_01() { - var sourceA = -@"public class A -{ - public void F1(System.IntPtr x) { } - public void F2(nuint y) { } -}"; - var sourceB = -@"class B1 : A -{ - public void F1(nuint x) { } - public void F2(System.IntPtr y) { } -} -class B2 : A -{ - public void F1(nint x) { base.F1(x); } - public void F2(System.UIntPtr y) { base.F2(y); } -} -class B3 : A + var source0 = +@"using System; +class A : System.Attribute { - public new void F1(nuint x) { } - public new void F2(System.IntPtr y) { } + public A() { } + public A(object value) { } + public object Value; } -class B4 : A +[A((IntPtr)1)] +[A(new IntPtr[0])] +[A(Value = (IntPtr)3)] +[A(Value = new[] { (IntPtr)4 })] +class B { - public new void F1(nint x) { base.F1(x); } - public new void F2(System.UIntPtr y) { base.F2(y); } }"; + var comp = CreateEmptyCompilation(source0, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - var diagnostics = new[] - { - // (8,17): warning CS0108: 'B2.F1(nint)' hides inherited member 'A.F1(IntPtr)'. Use the new keyword if hiding was intended. - // public void F1(nint x) { base.F1(x); } - Diagnostic(ErrorCode.WRN_NewRequired, "F1").WithArguments("B2.F1(nint)", "A.F1(System.IntPtr)").WithLocation(8, 17), - // (9,17): warning CS0108: 'B2.F2(UIntPtr)' hides inherited member 'A.F2(nuint)'. Use the new keyword if hiding was intended. - // public void F2(System.UIntPtr y) { base.F2(y); } - Diagnostic(ErrorCode.WRN_NewRequired, "F2").WithArguments("B2.F2(System.UIntPtr)", "A.F2(nuint)").WithLocation(9, 17), - // (13,21): warning CS0109: The member 'B3.F1(nuint)' does not hide an accessible member. The new keyword is not required. - // public new void F1(nuint x) { } - Diagnostic(ErrorCode.WRN_NewNotRequired, "F1").WithArguments("B3.F1(nuint)").WithLocation(13, 21), - // (14,21): warning CS0109: The member 'B3.F2(IntPtr)' does not hide an accessible member. The new keyword is not required. - // public new void F2(System.IntPtr y) { } - Diagnostic(ErrorCode.WRN_NewNotRequired, "F2").WithArguments("B3.F2(System.IntPtr)").WithLocation(14, 21) - }; - - var comp = CreateCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(diagnostics); - - comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - var ref1 = comp.ToMetadataReference(); - var ref2 = comp.EmitToImageReference(); - - comp = CreateCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(diagnostics); - - comp = CreateCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(diagnostics); + comp.VerifyDiagnostics( + // (8,4): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type + // [A((IntPtr)1)] + Diagnostic(ErrorCode.ERR_BadAttributeArgument, "(IntPtr)1").WithLocation(8, 4), + // (9,4): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type + // [A(new IntPtr[0])] + Diagnostic(ErrorCode.ERR_BadAttributeArgument, "new IntPtr[0]").WithLocation(9, 4), + // (10,12): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type + // [A(Value = (IntPtr)3)] + Diagnostic(ErrorCode.ERR_BadAttributeArgument, "(IntPtr)3").WithLocation(10, 12), + // (11,12): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type + // [A(Value = new[] { (IntPtr)4 })] + Diagnostic(ErrorCode.ERR_BadAttributeArgument, "new[] { (IntPtr)4 }").WithLocation(11, 12)); } [Fact] - public void Overloads_02() + public void AttributeValue_02() { - var sourceA = -@"public class A -{ - public void F1(System.IntPtr x) { } - public void F2(System.UIntPtr y) { } -}"; - var sourceB = -@"class B1 : A + var source0 = +@"using System; +class A : System.Attribute { - public void F1(nint x) { base.F1(x); } - public void F2(nuint y) { base.F2(y); } + public A() { } + public A(IntPtr value) { } + public IntPtr[] Value; } -class B2 : A +[A(1)] +[A(Value = default)] +class B { - public void F1(nuint x) { } - public void F2(nint y) { } -} -class B3 : A -{ - public void F1(nint x) { base.F1(x); } - public void F2(nuint y) { base.F2(y); } -} -class B4 : A -{ - public void F1(nuint x) { } - public void F2(nint y) { } -}"; - - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); - var ref1 = comp.ToMetadataReference(); - var ref2 = comp.EmitToImageReference(); - - var diagnostics = new[] - { - // (3,17): warning CS0108: 'B1.F1(nint)' hides inherited member 'A.F1(IntPtr)'. Use the new keyword if hiding was intended. - // public void F1(nint x) { base.F1(x); } - Diagnostic(ErrorCode.WRN_NewRequired, "F1").WithArguments("B1.F1(nint)", "A.F1(System.IntPtr)").WithLocation(3, 17), - // (4,17): warning CS0108: 'B1.F2(nuint)' hides inherited member 'A.F2(UIntPtr)'. Use the new keyword if hiding was intended. - // public void F2(nuint y) { base.F2(y); } - Diagnostic(ErrorCode.WRN_NewRequired, "F2").WithArguments("B1.F2(nuint)", "A.F2(System.UIntPtr)").WithLocation(4, 17), - // (13,17): warning CS0108: 'B3.F1(nint)' hides inherited member 'A.F1(IntPtr)'. Use the new keyword if hiding was intended. - // public void F1(nint x) { base.F1(x); } - Diagnostic(ErrorCode.WRN_NewRequired, "F1").WithArguments("B3.F1(nint)", "A.F1(System.IntPtr)").WithLocation(13, 17), - // (14,17): warning CS0108: 'B3.F2(nuint)' hides inherited member 'A.F2(UIntPtr)'. Use the new keyword if hiding was intended. - // public void F2(nuint y) { base.F2(y); } - Diagnostic(ErrorCode.WRN_NewRequired, "F2").WithArguments("B3.F2(nuint)", "A.F2(System.UIntPtr)").WithLocation(14, 17) - }; - - comp = CreateCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(diagnostics); - - comp = CreateCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(diagnostics); - } - - [Fact] - public void Overloads_03() - { - var sourceA = -@"public class A -{ - public void F1(nint x) { } - public void F2(nuint y) { } -}"; - var sourceB = -@"class B1 : A -{ - public void F1(System.UIntPtr x) { } - public void F2(System.IntPtr y) { } -} -class B2 : A -{ - public void F1(System.IntPtr x) { base.F1(x); } - public void F2(System.UIntPtr y) { base.F2(y); } -} -class B3 : A -{ - public void F1(System.UIntPtr x) { } - public void F2(System.IntPtr y) { } -} -class B4 : A -{ - public void F1(System.IntPtr x) { base.F1(x); } - public void F2(System.UIntPtr y) { base.F2(y); } }"; + var comp = CreateEmptyCompilation(source0, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - var ref1 = comp.ToMetadataReference(); - var ref2 = comp.EmitToImageReference(); - - var diagnostics = new[] - { - // (8,17): warning CS0108: 'B2.F1(IntPtr)' hides inherited member 'A.F1(nint)'. Use the new keyword if hiding was intended. - // public void F1(System.IntPtr x) { base.F1(x); } - Diagnostic(ErrorCode.WRN_NewRequired, "F1").WithArguments("B2.F1(System.IntPtr)", "A.F1(nint)").WithLocation(8, 17), - // (9,17): warning CS0108: 'B2.F2(UIntPtr)' hides inherited member 'A.F2(nuint)'. Use the new keyword if hiding was intended. - // public void F2(System.UIntPtr y) { base.F2(y); } - Diagnostic(ErrorCode.WRN_NewRequired, "F2").WithArguments("B2.F2(System.UIntPtr)", "A.F2(nuint)").WithLocation(9, 17), - // (18,17): warning CS0108: 'B4.F1(IntPtr)' hides inherited member 'A.F1(nint)'. Use the new keyword if hiding was intended. - // public void F1(System.IntPtr x) { base.F1(x); } - Diagnostic(ErrorCode.WRN_NewRequired, "F1").WithArguments("B4.F1(System.IntPtr)", "A.F1(nint)").WithLocation(18, 17), - // (19,17): warning CS0108: 'B4.F2(UIntPtr)' hides inherited member 'A.F2(nuint)'. Use the new keyword if hiding was intended. - // public void F2(System.UIntPtr y) { base.F2(y); } - Diagnostic(ErrorCode.WRN_NewRequired, "F2").WithArguments("B4.F2(System.UIntPtr)", "A.F2(nuint)").WithLocation(19, 17) - }; - - comp = CreateCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(diagnostics); - - comp = CreateCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(diagnostics); + comp.VerifyDiagnostics( + // (8,2): error CS0181: Attribute constructor parameter 'value' has type 'nint', which is not a valid attribute parameter type + // [A(1)] + Diagnostic(ErrorCode.ERR_BadAttributeParamType, "A").WithArguments("value", "nint").WithLocation(8, 2), + // (9,4): error CS0655: 'Value' is not a valid named attribute argument because it is not a valid attribute parameter type + // [A(Value = default)] + Diagnostic(ErrorCode.ERR_BadNamedAttributeArgumentType, "Value").WithArguments("Value").WithLocation(9, 4)); } [Fact] - public void Overloads_04() + public void ParameterDefaultValue_01() { var source = -@"interface I -{ - void F(System.IntPtr x); - void F(System.UIntPtr x); - void F(nint y); -} -class C +@"using System; +class A { - static void F(System.UIntPtr x) { } - static void F(nint y) { } - static void F(nuint y) { } -}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (5,10): error CS0111: Type 'I' already defines a member called 'F' with the same parameter types - // void F(nint y); - Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "F").WithArguments("F", "I").WithLocation(5, 10), - // (11,17): error CS0111: Type 'C' already defines a member called 'F' with the same parameter types - // static void F(nuint y) { } - Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "F").WithArguments("F", "C").WithLocation(11, 17)); + static void F0(IntPtr x = default, UIntPtr y = default) + { } - - [Fact] - public void Overloads_05() + static void F1(IntPtr x = (IntPtr)(-1), UIntPtr y = (UIntPtr)2) { - var source = -@"interface I -{ - object this[System.IntPtr x] { get; } - object this[nint y] { get; set; } -} -class C -{ - object this[nuint x] => null; - object this[System.UIntPtr y] { get { return null; } set { } } -}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (4,12): error CS0111: Type 'I' already defines a member called 'this' with the same parameter types - // object this[nint y] { get; set; } - Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "this").WithArguments("this", "I").WithLocation(4, 12), - // (9,12): error CS0111: Type 'C' already defines a member called 'this' with the same parameter types - // object this[System.UIntPtr y] { get { return null; } set { } } - Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "this").WithArguments("this", "C").WithLocation(9, 12)); } - - [Fact] - public void Overloads_06() + static void F2(IntPtr? x = null, UIntPtr? y = null) { - var source1 = -@"public interface IA -{ - void F1(nint i); - void F2(nuint i); -} -public interface IB -{ - void F1(System.IntPtr i); - void F2(System.UIntPtr i); -}"; - var comp = CreateCompilation(source1, parseOptions: TestOptions.Regular9); - var ref1 = comp.EmitToImageReference(); - - var source2 = -@"class C : IA, IB -{ - public void F1(System.IntPtr i) { } - public void F2(System.UIntPtr i) { } -}"; - comp = CreateCompilation(source2, references: new[] { ref1 }, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); - - var source3 = -@"class C1 : IA, IB -{ - public void F1(nint i) { } - public void F2(System.UIntPtr i) { } -} -class C2 : IA, IB -{ - public void F1(System.IntPtr i) { } - public void F2(nuint i) { } -}"; - comp = CreateCompilation(source3, references: new[] { ref1 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); } - - [Fact] - [WorkItem(45519, "https://github.com/dotnet/roslyn/issues/45519")] - public void Partial_01() + static void F3(IntPtr? x = (IntPtr)(-3), UIntPtr? y = (UIntPtr)4) { - var source = -@"partial class Program -{ - static partial void F1(System.IntPtr x); - static partial void F2(System.UIntPtr x) { } - static partial void F1(nint x) { } - static partial void F2(nuint x); + } }"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(5), parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - - comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(6), parseOptions: TestOptions.Regular9); + var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (4,25): warning CS8826: Partial method declarations 'void Program.F2(nuint x)' and 'void Program.F2(UIntPtr x)' have signature differences. - // static partial void F2(System.UIntPtr x) { } - Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "F2").WithArguments("void Program.F2(nuint x)", "void Program.F2(UIntPtr x)").WithLocation(4, 25), - // (5,25): warning CS8826: Partial method declarations 'void Program.F1(IntPtr x)' and 'void Program.F1(nint x)' have signature differences. - // static partial void F1(nint x) { } - Diagnostic(ErrorCode.WRN_PartialMethodTypeDifference, "F1").WithArguments("void Program.F1(IntPtr x)", "void Program.F1(nint x)").WithLocation(5, 25)); + // (7,31): error CS1736: Default parameter value for 'x' must be a compile-time constant + // static void F1(IntPtr x = (IntPtr)(-1), UIntPtr y = (UIntPtr)2) + Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "(IntPtr)(-1)").WithArguments("x").WithLocation(7, 31), + // (7,57): error CS1736: Default parameter value for 'y' must be a compile-time constant + // static void F1(IntPtr x = (IntPtr)(-1), UIntPtr y = (UIntPtr)2) + Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "(UIntPtr)2").WithArguments("y").WithLocation(7, 57), + // (13,32): error CS1736: Default parameter value for 'x' must be a compile-time constant + // static void F3(IntPtr? x = (IntPtr)(-3), UIntPtr? y = (UIntPtr)4) + Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "(IntPtr)(-3)").WithArguments("x").WithLocation(13, 32), + // (13,59): error CS1736: Default parameter value for 'y' must be a compile-time constant + // static void F3(IntPtr? x = (IntPtr)(-3), UIntPtr? y = (UIntPtr)4) + Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "(UIntPtr)4").WithArguments("y").WithLocation(13, 59)); } [Fact] - public void Constraints_01() + public void ParameterDefaultValue_02() { var sourceA = -@"public class A -{ - public static void F() where U : T { } -} -public class B1 : A { } -public class B2 : A { } -public class B3 : A { } -public class B4 : A { } -"; - var sourceB = -@"class Program +@"using System; +public class A { - static void Main() + public static void F0(IntPtr x = default, UIntPtr y = default) { - B1.F(); - B2.F(); - B3.F(); - B4.F(); - } -}"; - - var comp = CreateCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - - comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - var ref1 = comp.ToMetadataReference(); - var ref2 = comp.EmitToImageReference(); - - comp = CreateCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - - comp = CreateCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); + Report(x); + Report(y); } - - [Fact] - public void Constraints_02() + public static void F1(IntPtr x = -1, UIntPtr y = 2) { - var sourceA = -@"public class A -{ - public static void F() where U : T { } -} -public class B1 : A { } -public class B2 : A { } -"; - var sourceB = -@"class Program -{ - static void Main() + Report(x); + Report(y); + } + public static void F2(IntPtr? x = null, UIntPtr? y = null) { - B1.F(); - B2.F(); + Report(x); + Report(y); } -}"; - - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); - var ref1 = comp.ToMetadataReference(); - var ref2 = comp.EmitToImageReference(); - - comp = CreateCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - - comp = CreateCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); + public static void F3(IntPtr? x = -3, UIntPtr? y = 4) + { + Report(x); + Report(y); } - - [Fact] - public void Constraints_03() + static void Report(object o) { - var sourceA = -@"public class A -{ - public static void F() where U : T { } -} -public class B1 : A { } -public class B2 : A { } -"; + System.Console.WriteLine(o ?? ""null""); + } +}"; var sourceB = -@"class Program +@"class B { static void Main() { - B1.F(); - B2.F(); + A.F0(); + A.F1(); + A.F2(); + A.F3(); } }"; + var expectedOutput = +@"0 +0 +-1 +2 +null +null +-3 +4"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); + var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + CompileAndVerify(comp, expectedOutput: expectedOutput); + + comp = CreateEmptyCompilation(sourceA, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; var ref1 = comp.ToMetadataReference(); var ref2 = comp.EmitToImageReference(); - comp = CreateCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); - - comp = CreateCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); - } - - [Fact] - public void ClassName() - { - var source = -@"class @nint -{ -} -interface I -{ - nint Add(nint x, nuint y); -}"; + comp = CreateEmptyCompilation(sourceB, references: new[] { ref1, MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + CompileAndVerify(comp, expectedOutput: expectedOutput); - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics( - // (6,22): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // nint Add(nint x, nuint y); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "nuint").WithArguments("native-sized integers", "9.0").WithLocation(6, 22)); - verify(comp); + comp = CreateEmptyCompilation(sourceB, references: new[] { ref2, MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + CompileAndVerify(comp, expectedOutput: expectedOutput); - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - verify(comp); + comp = CreateEmptyCompilation(sourceB, references: new[] { ref1, MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular8); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + CompileAndVerify(comp, expectedOutput: expectedOutput); - static void verify(CSharpCompilation comp) - { - var tree = comp.SyntaxTrees[0]; - var nodes = tree.GetRoot().DescendantNodes().ToArray(); - var model = comp.GetSemanticModel(tree); - var underlyingType = model.GetDeclaredSymbol(nodes.OfType().Single()); - Assert.Equal("nint", underlyingType.ToTestDisplayString()); - Assert.Equal(SpecialType.None, underlyingType.SpecialType); - var method = model.GetDeclaredSymbol(nodes.OfType().Single()); - Assert.Equal("nint I.Add(nint x, nuint y)", method.ToTestDisplayString()); - var underlyingType0 = method.Parameters[0].Type.GetSymbol(); - var underlyingType1 = method.Parameters[1].Type.GetSymbol(); - Assert.Equal(SpecialType.None, underlyingType0.SpecialType); - Assert.False(underlyingType0.IsNativeIntegerType); - Assert.Equal(SpecialType.System_UIntPtr, underlyingType1.SpecialType); - Assert.True(underlyingType1.IsNativeIntegerType); - } + comp = CreateEmptyCompilation(sourceB, references: new[] { ref2, MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular8); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + CompileAndVerify(comp, expectedOutput: expectedOutput); } [Fact] - public void AliasName_01() + public void SwitchStatement_01() { var source = -@"using nint = System.Int16; -using nuint = System.Object; +@"using System; class Program { - static @nint F(nint x, nuint y) + static IntPtr M(IntPtr ret) { - System.Console.WriteLine(x.GetType().FullName); - System.Console.WriteLine(y.GetType().FullName); - return x; - } - static void Main() - { - F(new nint(), new nuint()); - } -}"; - - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8, options: TestOptions.ReleaseExe); - verify(comp); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe); - verify(comp); - - void verify(CSharpCompilation comp) - { - var verifier = CompileAndVerify(comp, expectedOutput: -@"System.Int16 -System.Object"); - var method = comp.GetMember("Program.F"); - Assert.Equal("System.Int16 Program.F(System.Int16 x, System.Object y)", method.ToTestDisplayString()); - var underlyingType0 = (NamedTypeSymbol)method.Parameters[0].Type; - var underlyingType1 = (NamedTypeSymbol)method.Parameters[1].Type; - Assert.Equal(SpecialType.System_Int16, underlyingType0.SpecialType); - Assert.False(underlyingType0.IsNativeIntegerType); - Assert.Equal(SpecialType.System_Object, underlyingType1.SpecialType); - Assert.False(underlyingType1.IsNativeIntegerType); + switch (ret) { + case 0: + ret--; // 2 + Report(""case 0: "", ret); + goto case 9999; + case 2: + ret--; // 4 + Report(""case 2: "", ret); + goto case 255; + case 6: // start here + ret--; // 5 + Report(""case 6: "", ret); + goto case 2; + case 9999: + ret--; // 1 + Report(""case 9999: "", ret); + goto default; + case 0xff: + ret--; // 3 + Report(""case 0xff: "", ret); + goto case 0; + default: + ret--; + Report(""default: "", ret); + if (ret > 0) { + goto case -1; + } + break; + case -1: + ret = 999; + Report(""case -1: "", ret); + break; } + return(ret); } - - [Fact] - public void AliasName_02() + static void Report(string prefix, nint value) { - var source = -@"using @nint = System.Int16; -class Program -{ - static @nint F(nint x, nuint y) => x; -}"; - - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics( - // (4,28): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // static @nint F(nint x, nuint y) => x; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "nuint").WithArguments("native-sized integers", "9.0").WithLocation(4, 28)); - verify(comp); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - verify(comp); - - static void verify(CSharpCompilation comp) - { - var method = comp.GetMember("Program.F"); - Assert.Equal("System.Int16 Program.F(System.Int16 x, nuint y)", method.ToTestDisplayString()); - var underlyingType0 = (NamedTypeSymbol)method.Parameters[0].Type; - var underlyingType1 = (NamedTypeSymbol)method.Parameters[1].Type; - Assert.Equal(SpecialType.System_Int16, underlyingType0.SpecialType); - Assert.False(underlyingType0.IsNativeIntegerType); - Assert.Equal(SpecialType.System_UIntPtr, underlyingType1.SpecialType); - Assert.True(underlyingType1.IsNativeIntegerType); - } + Console.WriteLine(prefix + value); } - - [Fact] - public void AliasName_03() + static void Main() { - var source = -@"using @nint = System.Int16; -class Program -{ - static @nint F(nint x, nuint y) => x; + Console.WriteLine(M(6)); + } }"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics( - // (4,28): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // static @nint F(nint x, nuint y) => x; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "nuint").WithArguments("native-sized integers", "9.0").WithLocation(4, 28)); - verify(comp); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - verify(comp); - - static void verify(CSharpCompilation comp) + var verifier = CompileAndVerify(comp, expectedOutput: +@"case 6: 5 +case 2: 4 +case 0xff: 3 +case 0: 2 +case 9999: 1 +default: 0 +0"); + verifier.VerifyIL("Program.M", @" { - var method = comp.GetMember("Program.F"); - Assert.Equal("System.Int16 Program.F(System.Int16 x, nuint y)", method.ToTestDisplayString()); - var underlyingType0 = (NamedTypeSymbol)method.Parameters[0].Type; - var underlyingType1 = (NamedTypeSymbol)method.Parameters[1].Type; - Assert.Equal(SpecialType.System_Int16, underlyingType0.SpecialType); - Assert.False(underlyingType0.IsNativeIntegerType); - Assert.Equal(SpecialType.System_UIntPtr, underlyingType1.SpecialType); - Assert.True(underlyingType1.IsNativeIntegerType); + // Code size 201 (0xc9) + .maxstack 3 + .locals init (long V_0) + IL_0000: ldarg.0 + IL_0001: conv.i8 + IL_0002: stloc.0 + IL_0003: ldloc.0 + IL_0004: ldc.i4.6 + IL_0005: conv.i8 + IL_0006: bgt.s IL_0031 + IL_0008: ldloc.0 + IL_0009: ldc.i4.m1 + IL_000a: conv.i8 + IL_000b: sub + IL_000c: dup + IL_000d: ldc.i4.3 + IL_000e: conv.i8 + IL_000f: ble.un.s IL_0014 + IL_0011: pop + IL_0012: br.s IL_002a + IL_0014: conv.u4 + IL_0015: switch ( + IL_00b4, + IL_0045, + IL_009f, + IL_0057) + IL_002a: ldloc.0 + IL_002b: ldc.i4.6 + IL_002c: conv.i8 + IL_002d: beq.s IL_0069 + IL_002f: br.s IL_009f + IL_0031: ldloc.0 + IL_0032: ldc.i4 0xff + IL_0037: conv.i8 + IL_0038: beq.s IL_008d + IL_003a: ldloc.0 + IL_003b: ldc.i4 0x270f + IL_0040: conv.i8 + IL_0041: beq.s IL_007b + IL_0043: br.s IL_009f + IL_0045: ldarg.0 + IL_0046: ldc.i4.1 + IL_0047: sub + IL_0048: starg.s V_0 + IL_004a: ldstr ""case 0: "" + IL_004f: ldarg.0 + IL_0050: call ""void Program.Report(string, nint)"" + IL_0055: br.s IL_007b + IL_0057: ldarg.0 + IL_0058: ldc.i4.1 + IL_0059: sub + IL_005a: starg.s V_0 + IL_005c: ldstr ""case 2: "" + IL_0061: ldarg.0 + IL_0062: call ""void Program.Report(string, nint)"" + IL_0067: br.s IL_008d + IL_0069: ldarg.0 + IL_006a: ldc.i4.1 + IL_006b: sub + IL_006c: starg.s V_0 + IL_006e: ldstr ""case 6: "" + IL_0073: ldarg.0 + IL_0074: call ""void Program.Report(string, nint)"" + IL_0079: br.s IL_0057 + IL_007b: ldarg.0 + IL_007c: ldc.i4.1 + IL_007d: sub + IL_007e: starg.s V_0 + IL_0080: ldstr ""case 9999: "" + IL_0085: ldarg.0 + IL_0086: call ""void Program.Report(string, nint)"" + IL_008b: br.s IL_009f + IL_008d: ldarg.0 + IL_008e: ldc.i4.1 + IL_008f: sub + IL_0090: starg.s V_0 + IL_0092: ldstr ""case 0xff: "" + IL_0097: ldarg.0 + IL_0098: call ""void Program.Report(string, nint)"" + IL_009d: br.s IL_0045 + IL_009f: ldarg.0 + IL_00a0: ldc.i4.1 + IL_00a1: sub + IL_00a2: starg.s V_0 + IL_00a4: ldstr ""default: "" + IL_00a9: ldarg.0 + IL_00aa: call ""void Program.Report(string, nint)"" + IL_00af: ldarg.0 + IL_00b0: ldc.i4.0 + IL_00b1: conv.i + IL_00b2: ble.s IL_00c7 + IL_00b4: ldc.i4 0x3e7 + IL_00b9: conv.i + IL_00ba: starg.s V_0 + IL_00bc: ldstr ""case -1: "" + IL_00c1: ldarg.0 + IL_00c2: call ""void Program.Report(string, nint)"" + IL_00c7: ldarg.0 + IL_00c8: ret } + "); } - [WorkItem(42975, "https://github.com/dotnet/roslyn/issues/42975")] [Fact] - public void AliasName_04() + public void SwitchStatement_02() { var source = -@"using A1 = nint; -using A2 = nuint; +@"using System; class Program { - A1 F1() => default; - A2 F2() => default; -}"; - var expectedDiagnostics = new[] - { - // (1,12): error CS0246: The type or namespace name 'nint' could not be found (are you missing a using directive or an assembly reference?) - // using A1 = nint; - Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "nint").WithArguments("nint").WithLocation(1, 12), - // (2,12): error CS0246: The type or namespace name 'nuint' could not be found (are you missing a using directive or an assembly reference?) - // using A2 = nuint; - Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "nuint").WithArguments("nuint").WithLocation(2, 12) - }; - - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(expectedDiagnostics); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(expectedDiagnostics); - } - - [WorkItem(42975, "https://github.com/dotnet/roslyn/issues/42975")] - [Fact] - public void AliasName_05() + static UIntPtr M(UIntPtr ret) { - var source1 = -@"using A1 = nint; -using A2 = nuint; -class Program -{ - A1 F1() => default; - A2.B F2() => default; -}"; - var source2 = -@"class @nint { } -namespace nuint -{ - class B { } -}"; - - var comp = CreateCompilation(new[] { source1, source2 }, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); - - comp = CreateCompilation(new[] { source1, source2 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); + switch (ret) { + case 0: + ret--; // 2 + Report(""case 0: "", ret); + goto case 9999; + case 2: + ret--; // 4 + Report(""case 2: "", ret); + goto case 255; + case 6: // start here + ret--; // 5 + Report(""case 6: "", ret); + goto case 2; + case 9999: + ret--; // 1 + Report(""case 9999: "", ret); + goto default; + case 0xff: + ret--; // 3 + Report(""case 0xff: "", ret); + goto case 0; + default: + ret--; + Report(""default: "", ret); + if (ret > 0) { + goto case int.MaxValue; + } + break; + case int.MaxValue: + ret = 999; + Report(""case int.MaxValue: "", ret); + break; + } + return(ret); } - - [WorkItem(42975, "https://github.com/dotnet/roslyn/issues/42975")] - [Fact] - public void Using_01() + static void Report(string prefix, nuint value) { - var source = -@"using nint; -using nuint; -class Program -{ -}"; - var expectedDiagnostics = new[] - { - // (1,1): hidden CS8019: Unnecessary using directive. - // using nint; - Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using nint;").WithLocation(1, 1), - // (1,7): error CS0246: The type or namespace name 'nint' could not be found (are you missing a using directive or an assembly reference?) - // using nint; - Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "nint").WithArguments("nint").WithLocation(1, 7), - // (2,1): hidden CS8019: Unnecessary using directive. - // using nuint; - Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using nuint;").WithLocation(2, 1), - // (2,7): error CS0246: The type or namespace name 'nuint' could not be found (are you missing a using directive or an assembly reference?) - // using nuint; - Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "nuint").WithArguments("nuint").WithLocation(2, 7) - }; - - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(expectedDiagnostics); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(expectedDiagnostics); + Console.WriteLine(prefix + value); } - - [WorkItem(42975, "https://github.com/dotnet/roslyn/issues/42975")] - [Fact] - public void Using_02() - { - var source1 = -@"using nint; -using nuint; -class Program -{ static void Main() { - _ = new A(); - _ = new B(); + Console.WriteLine(M(6)); } }"; - var source2 = -@"namespace nint -{ - class A { } -} -namespace nuint -{ - class B { } -}"; - - var comp = CreateCompilation(new[] { source1, source2 }, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - comp = CreateCompilation(new[] { source1, source2 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); + var verifier = CompileAndVerify(comp, expectedOutput: +@"case 6: 5 +case 2: 4 +case 0xff: 3 +case 0: 2 +case 9999: 1 +default: 0 +0"); + verifier.VerifyIL("Program.M", @" + { + // Code size 184 (0xb8) + .maxstack 2 + .locals init (ulong V_0) + IL_0000: ldarg.0 + IL_0001: conv.u8 + IL_0002: stloc.0 + IL_0003: ldloc.0 + IL_0004: ldc.i4.6 + IL_0005: conv.i8 + IL_0006: bgt.un.s IL_0017 + IL_0008: ldloc.0 + IL_0009: brfalse.s IL_0034 + IL_000b: ldloc.0 + IL_000c: ldc.i4.2 + IL_000d: conv.i8 + IL_000e: beq.s IL_0046 + IL_0010: ldloc.0 + IL_0011: ldc.i4.6 + IL_0012: conv.i8 + IL_0013: beq.s IL_0058 + IL_0015: br.s IL_008e + IL_0017: ldloc.0 + IL_0018: ldc.i4 0xff + IL_001d: conv.i8 + IL_001e: beq.s IL_007c + IL_0020: ldloc.0 + IL_0021: ldc.i4 0x270f + IL_0026: conv.i8 + IL_0027: beq.s IL_006a + IL_0029: ldloc.0 + IL_002a: ldc.i4 0x7fffffff + IL_002f: conv.i8 + IL_0030: beq.s IL_00a3 + IL_0032: br.s IL_008e + IL_0034: ldarg.0 + IL_0035: ldc.i4.1 + IL_0036: sub + IL_0037: starg.s V_0 + IL_0039: ldstr ""case 0: "" + IL_003e: ldarg.0 + IL_003f: call ""void Program.Report(string, nuint)"" + IL_0044: br.s IL_006a + IL_0046: ldarg.0 + IL_0047: ldc.i4.1 + IL_0048: sub + IL_0049: starg.s V_0 + IL_004b: ldstr ""case 2: "" + IL_0050: ldarg.0 + IL_0051: call ""void Program.Report(string, nuint)"" + IL_0056: br.s IL_007c + IL_0058: ldarg.0 + IL_0059: ldc.i4.1 + IL_005a: sub + IL_005b: starg.s V_0 + IL_005d: ldstr ""case 6: "" + IL_0062: ldarg.0 + IL_0063: call ""void Program.Report(string, nuint)"" + IL_0068: br.s IL_0046 + IL_006a: ldarg.0 + IL_006b: ldc.i4.1 + IL_006c: sub + IL_006d: starg.s V_0 + IL_006f: ldstr ""case 9999: "" + IL_0074: ldarg.0 + IL_0075: call ""void Program.Report(string, nuint)"" + IL_007a: br.s IL_008e + IL_007c: ldarg.0 + IL_007d: ldc.i4.1 + IL_007e: sub + IL_007f: starg.s V_0 + IL_0081: ldstr ""case 0xff: "" + IL_0086: ldarg.0 + IL_0087: call ""void Program.Report(string, nuint)"" + IL_008c: br.s IL_0034 + IL_008e: ldarg.0 + IL_008f: ldc.i4.1 + IL_0090: sub + IL_0091: starg.s V_0 + IL_0093: ldstr ""default: "" + IL_0098: ldarg.0 + IL_0099: call ""void Program.Report(string, nuint)"" + IL_009e: ldarg.0 + IL_009f: ldc.i4.0 + IL_00a0: conv.i + IL_00a1: ble.un.s IL_00b6 + IL_00a3: ldc.i4 0x3e7 + IL_00a8: conv.i + IL_00a9: starg.s V_0 + IL_00ab: ldstr ""case int.MaxValue: "" + IL_00b0: ldarg.0 + IL_00b1: call ""void Program.Report(string, nuint)"" + IL_00b6: ldarg.0 + IL_00b7: ret + }"); } - [WorkItem(42975, "https://github.com/dotnet/roslyn/issues/42975")] [Fact] - public void AttributeType_01() + public void Conversions() { - var source = -@"[nint] -[A, nuint()] -class Program -{ -} -class AAttribute : System.Attribute -{ + const string convNone = +@"{ + // Code size 2 (0x2) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ret }"; - var expectedDiagnostics = new[] - { - // (1,2): error CS0246: The type or namespace name 'nintAttribute' could not be found (are you missing a using directive or an assembly reference?) - // [nint] - Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "nint").WithArguments("nintAttribute").WithLocation(1, 2), - // (1,2): error CS0246: The type or namespace name 'nint' could not be found (are you missing a using directive or an assembly reference?) - // [nint] - Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "nint").WithArguments("nint").WithLocation(1, 2), - // (2,5): error CS0246: The type or namespace name 'nuintAttribute' could not be found (are you missing a using directive or an assembly reference?) - // [A, nuint] - Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "nuint").WithArguments("nuintAttribute").WithLocation(2, 5), - // (2,5): error CS0246: The type or namespace name 'nuint' could not be found (are you missing a using directive or an assembly reference?) - // [A, nuint] - Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "nuint").WithArguments("nuint").WithLocation(2, 5) - }; + static string conv(string conversion) => +$@"{{ + // Code size 3 (0x3) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: {conversion} + IL_0002: ret +}}"; + static string convFromNullableT(string conversion, string sourceType) => +$@"{{ + // Code size 9 (0x9) + .maxstack 1 + IL_0000: ldarga.s V_0 + IL_0002: call ""{sourceType} {sourceType}?.Value.get"" + IL_0007: {conversion} + IL_0008: ret +}}"; + static string convToNullableT(string conversion, string destType) => +$@"{{ + // Code size 8 (0x8) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: {conversion} + IL_0002: newobj ""{destType}?..ctor({destType})"" + IL_0007: ret +}}"; + static string convFromToNullableT(string conversion, string sourceType, string destType) => +$@"{{ + // Code size 35 (0x23) + .maxstack 1 + .locals init ({sourceType}? V_0, + {destType}? V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call ""bool {sourceType}?.HasValue.get"" + IL_0009: brtrue.s IL_0015 + IL_000b: ldloca.s V_1 + IL_000d: initobj ""{destType}?"" + IL_0013: ldloc.1 + IL_0014: ret + IL_0015: ldloca.s V_0 + IL_0017: call ""{sourceType} {sourceType}?.GetValueOrDefault()"" + IL_001c: {conversion} + IL_001d: newobj ""{destType}?..ctor({destType})"" + IL_0022: ret +}}"; + static string convExplicitFromNullableT(string sourceType, string method) => +$@"{{ + // Code size 27 (0x1b) + .maxstack 1 + .locals init ({sourceType}? V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call ""bool {sourceType}?.HasValue.get"" + IL_0009: brtrue.s IL_000e + IL_000b: ldc.i4.0 + IL_000c: conv.u + IL_000d: ret + IL_000e: ldloca.s V_0 + IL_0010: call ""{sourceType} {sourceType}?.GetValueOrDefault()"" + IL_0015: call ""{method}"" + IL_001a: ret +}}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(expectedDiagnostics); + void conversions(string sourceType, string destType, ConversionKind[] expectedConversions, string expectedImplicitIL, string expectedExplicitIL, string expectedCheckedIL = null) + { + if (expectedExplicitIL is not null) + { + Assert.False(IsNoConversion(expectedConversions)); + } - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(expectedDiagnostics); - } - - [WorkItem(42975, "https://github.com/dotnet/roslyn/issues/42975")] - [Fact] - public void AttributeType_02() - { - var source1 = -@"[nint] -[nuint()] -class Program -{ -}"; - var source2 = -@"using System; -class @nint : Attribute { } -class nuintAttribute : Attribute { }"; - - var comp = CreateCompilation(new[] { source1, source2 }, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); - - comp = CreateCompilation(new[] { source1, source2 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - } - - [WorkItem(42975, "https://github.com/dotnet/roslyn/issues/42975")] - [Fact] - public void AttributeType_03() - { - var source1 = -@"[A(nint: 0)] -[B(nuint = 2)] -class Program -{ -}"; - var source2 = -@"using System; -class AAttribute : Attribute -{ - public AAttribute(int nint) { } -} -class BAttribute : Attribute -{ - public int nuint; -}"; - - var comp = CreateCompilation(new[] { source1, source2 }, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); - - comp = CreateCompilation(new[] { source1, source2 }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - } - - [WorkItem(42975, "https://github.com/dotnet/roslyn/issues/42975")] - [Fact] - public void GetSpeculativeTypeInfo() - { - var source = -@"#pragma warning disable 219 -class Program -{ - static void Main() - { - nint i = 0; - } -}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - var tree = comp.SyntaxTrees.Single(); - var model = comp.GetSemanticModel(tree); - var typeSyntax = SyntaxFactory.ParseTypeName("nuint"); - int spanStart = source.IndexOf("nint i = 0;"); - var type = model.GetSpeculativeTypeInfo(spanStart, typeSyntax, SpeculativeBindingOption.BindAsTypeOrNamespace).Type; - Assert.True(type.IsNativeIntegerType); - } - - [Fact] - public void MemberName_01() - { - var source = -@"namespace N -{ - class @nint { } - class Program - { - internal static object nuint; - static void Main() - { - _ = new nint(); - _ = new @nint(); - _ = new N.nint(); - @nint i = null; - _ = i; - @nuint = null; - _ = nuint; - _ = @nuint; - _ = Program.nuint; - } - } -}"; - - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); - verify(comp); + convert( + sourceType, + destType, + expectedImplicitIL, + useExplicitCast: false, + useChecked: false, + expectedConversions: expectedConversions, + expectedErrorCode: expectedImplicitIL is null ? + expectedExplicitIL is null ? ErrorCode.ERR_NoImplicitConv : ErrorCode.ERR_NoImplicitConvCast : + 0); - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - verify(comp); + // Explicit cast + convert( + sourceType, + destType, + expectedExplicitIL, + useExplicitCast: true, + useChecked: false, + expectedConversions: null, + expectedErrorCode: expectedExplicitIL is null ? ErrorCode.ERR_NoExplicitConv : 0); - static void verify(CSharpCompilation comp) - { - var tree = comp.SyntaxTrees[0]; - var model = comp.GetSemanticModel(tree); - var nodes = tree.GetRoot().DescendantNodes().OfType().ToArray(); - Assert.Equal(3, nodes.Length); - foreach (var node in nodes) - { - var type = model.GetTypeInfo(node).Type; - Assert.Equal("N.nint", type.ToTestDisplayString()); - Assert.Equal(SpecialType.None, type.SpecialType); - Assert.False(type.IsNativeIntegerType); - } + // Explicit cast and checked + expectedCheckedIL ??= expectedExplicitIL; + convert( + sourceType, + destType, + expectedCheckedIL, + useExplicitCast: true, + useChecked: true, + expectedConversions: null, + expectedErrorCode: expectedCheckedIL is null ? ErrorCode.ERR_NoExplicitConv : 0); } - } - - [Fact] - public void MemberName_02() - { - var source = -@"class Program -{ - static void Main() - { - _ = nint.Equals(0, 0); - _ = nuint.Equals(0, 0); - } -}"; - - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics( - // (5,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = nint.Equals(0, 0); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "nint").WithArguments("native-sized integers", "9.0").WithLocation(5, 13), - // (6,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = nuint.Equals(0, 0); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "nuint").WithArguments("native-sized integers", "9.0").WithLocation(6, 13)); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - } - - [Fact] - public void NameOf_01() - { - var source = -@"using System; -class Program -{ - static void Main() - { - Console.WriteLine(nameof(nint)); - Console.WriteLine(nameof(nuint)); - } -}"; - - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics( - // (6,34): error CS0103: The name 'nint' does not exist in the current context - // Console.WriteLine(nameof(nint)); - Diagnostic(ErrorCode.ERR_NameNotInContext, "nint").WithArguments("nint").WithLocation(6, 34), - // (7,34): error CS0103: The name 'nuint' does not exist in the current context - // Console.WriteLine(nameof(nuint)); - Diagnostic(ErrorCode.ERR_NameNotInContext, "nuint").WithArguments("nuint").WithLocation(7, 34)); - - comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (6,34): error CS0103: The name 'nint' does not exist in the current context - // Console.WriteLine(nameof(nint)); - Diagnostic(ErrorCode.ERR_NameNotInContext, "nint").WithArguments("nint").WithLocation(6, 34), - // (7,34): error CS0103: The name 'nuint' does not exist in the current context - // Console.WriteLine(nameof(nuint)); - Diagnostic(ErrorCode.ERR_NameNotInContext, "nuint").WithArguments("nuint").WithLocation(7, 34)); - } - - [Fact] - public void NameOf_02() - { - var source = -@"class Program -{ - static void F(nint nint) - { - _ = nameof(nint); - _ = nameof(nuint); - } -}"; - - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics( - // (3,19): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // static void F(nint nint) - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "nint").WithArguments("native-sized integers", "9.0").WithLocation(3, 19), - // (6,20): error CS0103: The name 'nuint' does not exist in the current context - // _ = nameof(nuint); - Diagnostic(ErrorCode.ERR_NameNotInContext, "nuint").WithArguments("nuint").WithLocation(6, 20)); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (6,20): error CS0103: The name 'nuint' does not exist in the current context - // _ = nameof(nuint); - Diagnostic(ErrorCode.ERR_NameNotInContext, "nuint").WithArguments("nuint").WithLocation(6, 20)); - } - - [Fact] - public void NameOf_03() - { - var source = -@"class Program -{ - static void F() - { - _ = nameof(@nint); - _ = nameof(@nuint); - } -}"; - - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics( - // (5,20): error CS0103: The name 'nint' does not exist in the current context - // _ = nameof(@nint); - Diagnostic(ErrorCode.ERR_NameNotInContext, "@nint").WithArguments("nint").WithLocation(5, 20), - // (6,20): error CS0103: The name 'nuint' does not exist in the current context - // _ = nameof(@nuint); - Diagnostic(ErrorCode.ERR_NameNotInContext, "@nuint").WithArguments("nuint").WithLocation(6, 20)); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (5,20): error CS0103: The name 'nint' does not exist in the current context - // _ = nameof(@nint); - Diagnostic(ErrorCode.ERR_NameNotInContext, "@nint").WithArguments("nint").WithLocation(5, 20), - // (6,20): error CS0103: The name 'nuint' does not exist in the current context - // _ = nameof(@nuint); - Diagnostic(ErrorCode.ERR_NameNotInContext, "@nuint").WithArguments("nuint").WithLocation(6, 20)); - } - - [Fact] - public void NameOf_04() - { - var source = -@"class Program -{ - static void F(int @nint, uint @nuint) - { - _ = nameof(@nint); - _ = nameof(@nuint); - } -}"; - - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - } - - [Fact] - public void NameOf_05() - { - var source = -@"class Program -{ - static void F() - { - _ = nameof(nint.Equals); - } -}"; - - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics( - // (5,20): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = nameof(nint.Equals); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "nint").WithArguments("native-sized integers", "9.0").WithLocation(5, 20)); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - } - - /// - /// sizeof(IntPtr) and sizeof(nint) require compiling with /unsafe. - /// - [Fact] - public void SizeOf_01() - { - var source = -@"class Program -{ - static void Main() - { - _ = sizeof(System.IntPtr); - _ = sizeof(System.UIntPtr); - _ = sizeof(nint); - _ = sizeof(nuint); - } -}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (5,13): error CS0233: 'IntPtr' does not have a predefined size, therefore sizeof can only be used in an unsafe context - // _ = sizeof(System.IntPtr); - Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(System.IntPtr)").WithArguments("System.IntPtr").WithLocation(5, 13), - // (6,13): error CS0233: 'UIntPtr' does not have a predefined size, therefore sizeof can only be used in an unsafe context - // _ = sizeof(System.UIntPtr); - Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(System.UIntPtr)").WithArguments("System.UIntPtr").WithLocation(6, 13), - // (7,13): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context - // _ = sizeof(nint); - Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(7, 13), - // (8,13): error CS0233: 'nuint' does not have a predefined size, therefore sizeof can only be used in an unsafe context - // _ = sizeof(nuint); - Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nuint)").WithArguments("nuint").WithLocation(8, 13)); - } - [Fact] - public void SizeOf_02() - { - var source = -@"using System; -class Program -{ - unsafe static void Main() - { - Console.Write(sizeof(System.IntPtr)); - Console.Write(sizeof(System.UIntPtr)); - Console.Write(sizeof(nint)); - Console.Write(sizeof(nuint)); - } -}"; - var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseExe, parseOptions: TestOptions.Regular9); - int size = IntPtr.Size; - var verifier = CompileAndVerify(comp, expectedOutput: $"{size}{size}{size}{size}"); - verifier.VerifyIL("Program.Main", + // Test start: + // type to nint + conversions(sourceType: "object", destType: "nint", Unboxing, expectedImplicitIL: null, @"{ - // Code size 45 (0x2d) + // Code size 7 (0x7) .maxstack 1 - IL_0000: sizeof ""System.IntPtr"" - IL_0006: call ""void System.Console.Write(int)"" - IL_000b: sizeof ""System.UIntPtr"" - IL_0011: call ""void System.Console.Write(int)"" - IL_0016: sizeof ""System.IntPtr"" - IL_001c: call ""void System.Console.Write(int)"" - IL_0021: sizeof ""System.UIntPtr"" - IL_0027: call ""void System.Console.Write(int)"" - IL_002c: ret + IL_0000: ldarg.0 + IL_0001: unbox.any ""nint"" + IL_0006: ret }"); - } - - [Fact] - public void SizeOf_03() - { - var source = -@"using System.Collections.Generic; -unsafe class Program -{ - static IEnumerable F() - { - yield return sizeof(nint); - yield return sizeof(nuint); - } -}"; - var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (6,22): error CS1629: Unsafe code may not appear in iterators - // yield return sizeof(nint); - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "sizeof(nint)").WithLocation(6, 22), - // (7,22): error CS1629: Unsafe code may not appear in iterators - // yield return sizeof(nuint); - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "sizeof(nuint)").WithLocation(7, 22)); - } - - [Fact] - public void SizeOf_04() - { - var source = -@"unsafe class Program -{ - const int A = sizeof(System.IntPtr); - const int B = sizeof(System.UIntPtr); - const int C = sizeof(nint); - const int D = sizeof(nuint); -}"; - var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (3,19): error CS0133: The expression being assigned to 'Program.A' must be constant - // const int A = sizeof(System.IntPtr); - Diagnostic(ErrorCode.ERR_NotConstantExpression, "sizeof(System.IntPtr)").WithArguments("Program.A").WithLocation(3, 19), - // (4,19): error CS0133: The expression being assigned to 'Program.B' must be constant - // const int B = sizeof(System.UIntPtr); - Diagnostic(ErrorCode.ERR_NotConstantExpression, "sizeof(System.UIntPtr)").WithArguments("Program.B").WithLocation(4, 19), - // (5,19): error CS0133: The expression being assigned to 'Program.C' must be constant - // const int C = sizeof(nint); - Diagnostic(ErrorCode.ERR_NotConstantExpression, "sizeof(nint)").WithArguments("Program.C").WithLocation(5, 19), - // (6,19): error CS0133: The expression being assigned to 'Program.D' must be constant - // const int D = sizeof(nuint); - Diagnostic(ErrorCode.ERR_NotConstantExpression, "sizeof(nuint)").WithArguments("Program.D").WithLocation(6, 19)); - } - - [Fact] - public void TypeOf() - { - var source = -@"using static System.Console; -class Program -{ - static void Main() - { - var t1 = typeof(nint); - var t2 = typeof(nuint); - var t3 = typeof(System.IntPtr); - var t4 = typeof(System.UIntPtr); - WriteLine(t1.FullName); - WriteLine(t2.FullName); - WriteLine((object)t1 == t2); - WriteLine((object)t1 == t3); - WriteLine((object)t2 == t4); - } -}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - CompileAndVerify(comp, expectedOutput: -@"System.IntPtr -System.UIntPtr -False -True -True"); - } - - /// - /// Dynamic binding uses underlying type. - /// - [Fact] - public void Dynamic() - { - var source = -@"using System; -class Program -{ - static void Main() - { - nint x = 2; - x = x + x; - dynamic d = x; - _ = d.ToInt32(); // available on System.IntPtr, not nint - try - { - d = d + x; // available on nint, not System.IntPtr - } - catch (Exception e) - { - Console.WriteLine(e.GetType().FullName); - } - Console.WriteLine(d); - } -}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.StandardAndCSharp); - CompileAndVerify(comp, expectedOutput: -@"Microsoft.CSharp.RuntimeBinder.RuntimeBinderException -4"); - } - - [Fact] - public void Volatile() - { - var source = -@"class Program -{ - static volatile nint F1 = -1; - static volatile nuint F2 = 2; - static nint F() => F1 + (nint)F2; - static void Main() - { - System.Console.WriteLine(F()); - } -}"; - var verifier = CompileAndVerify(source, expectedOutput: @"1"); - verifier.VerifyIL("Program.F", -@"{ - // Code size 17 (0x11) - .maxstack 2 - IL_0000: volatile. - IL_0002: ldsfld ""nint Program.F1"" - IL_0007: volatile. - IL_0009: ldsfld ""nuint Program.F2"" - IL_000e: conv.i - IL_000f: add - IL_0010: ret -}"); - } - - // PEVerify should succeed. Previously, PEVerify reported duplicate - // TypeRefs for System.IntPtr in i.ToString() and (object)i. - [Fact] - public void MultipleTypeRefs_01() - { - string source = -@"class Program -{ - static string F1(nint i) - { - return i.ToString(); - } - static object F2(nint i) - { - return i; - } - static void Main() - { - System.Console.WriteLine(F1(-42)); - System.Console.WriteLine(F2(42)); - } -}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - var verifier = CompileAndVerify(comp, expectedOutput: -@"-42 -42"); - verifier.VerifyIL("Program.F1", + conversions(sourceType: "string", destType: "nint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "void*", destType: "nint", ExplicitPointerToInteger, expectedImplicitIL: null, expectedExplicitIL: convNone, expectedCheckedIL: conv("conv.ovf.i.un")); + conversions(sourceType: "delegate*", destType: "nint", ExplicitPointerToInteger, expectedImplicitIL: null, expectedExplicitIL: convNone, expectedCheckedIL: conv("conv.ovf.i.un")); + conversions(sourceType: "E", destType: "nint", ExplicitEnumeration, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i")); + conversions(sourceType: "bool", destType: "nint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "char", destType: "nint", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); + conversions(sourceType: "sbyte", destType: "nint", ImplicitNumeric, expectedImplicitIL: conv("conv.i"), expectedExplicitIL: conv("conv.i")); + conversions(sourceType: "byte", destType: "nint", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); + conversions(sourceType: "short", destType: "nint", ImplicitNumeric, expectedImplicitIL: conv("conv.i"), expectedExplicitIL: conv("conv.i")); + conversions(sourceType: "ushort", destType: "nint", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); + conversions(sourceType: "int", destType: "nint", ImplicitNumeric, expectedImplicitIL: conv("conv.i"), expectedExplicitIL: conv("conv.i")); + conversions(sourceType: "uint", destType: "nint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.i.un")); + conversions(sourceType: "long", destType: "nint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i")); + conversions(sourceType: "ulong", destType: "nint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i.un")); + conversions(sourceType: "nint", destType: "nint", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + conversions(sourceType: "nuint", destType: "nint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i.un")); + conversions(sourceType: "float", destType: "nint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i")); + conversions(sourceType: "double", destType: "nint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i")); + conversions(sourceType: "decimal", destType: "nint", ExplicitNumeric, expectedImplicitIL: null, @"{ // Code size 8 (0x8) .maxstack 1 - IL_0000: ldarga.s V_0 - IL_0002: call ""string System.IntPtr.ToString()"" + IL_0000: ldarg.0 + IL_0001: call ""long decimal.op_Explicit(decimal)"" + IL_0006: conv.i IL_0007: ret -}"); - verifier.VerifyIL("Program.F2", +}", @"{ - // Code size 7 (0x7) + // Code size 8 (0x8) .maxstack 1 IL_0000: ldarg.0 - IL_0001: box ""System.IntPtr"" - IL_0006: ret -}"); - } - - // PEVerify should succeed. Previously, PEVerify reported duplicate - // TypeRefs for System.UIntPtr in UIntPtr.get_MaxValue and (object)u. - [Fact] - public void MultipleTypeRefs_02() - { - var sourceA = -@"namespace System -{ - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct UInt64 { } - public struct UIntPtr - { - public static UIntPtr MaxValue => default; - public static UIntPtr MinValue => default; - } -}"; - var comp = CreateEmptyCompilation(sourceA); - comp.VerifyDiagnostics(); - var refA = comp.EmitToImageReference(options: EmitOptions.Default.WithRuntimeMetadataVersion("4.0.0.0")); - - var sourceB = -@"class Program -{ - static ulong F1() - { - return nuint.MaxValue; - } - static object F2() - { - nuint u = 42; - return u; - } -}"; - comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - // PEVerify is skipped because it reports "Type load failed" because of the above corlib, - // not because of duplicate TypeRefs in this assembly. Replace the above corlib with the - // actual corlib when that assembly contains UIntPtr.MaxValue or if we decide to support - // nuint.MaxValue (since MaxValue could be used in this test instead). - var verifier = CompileAndVerify(comp, verify: Verification.Skipped); - verifier.VerifyIL("Program.F1", -@"{ - // Code size 7 (0x7) - .maxstack 1 - IL_0000: call ""System.UIntPtr System.UIntPtr.MaxValue.get"" - IL_0005: conv.u8 - IL_0006: ret -}"); - verifier.VerifyIL("Program.F2", -@"{ - // Code size 9 (0x9) - .maxstack 1 - IL_0000: ldc.i4.s 42 - IL_0002: conv.i - IL_0003: box ""System.UIntPtr"" - IL_0008: ret + IL_0001: call ""long decimal.op_Explicit(decimal)"" + IL_0006: conv.ovf.i + IL_0007: ret }"); - } + conversions(sourceType: "System.IntPtr", destType: "nint", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + conversions(sourceType: "System.UIntPtr", destType: "nint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i.un")); - [WorkItem(42453, "https://github.com/dotnet/roslyn/issues/42453")] - [Fact] - public void ReadOnlyField_VirtualMethods() - { - string source = -@"using System; -using System.Linq.Expressions; -class MyInt -{ - private readonly nint _i; - internal MyInt(nint i) - { - _i = i; - } - public override string ToString() - { - return _i.ToString(); - } - public override int GetHashCode() - { - return ((Func)_i.GetHashCode)(); - } - public override bool Equals(object other) - { - return _i.Equals((other as MyInt)?._i); - } - internal string ToStringFromExpr() - { - Expression> e = () => ((Func)_i.ToString)(); - return e.Compile()(); - } - internal int GetHashCodeFromExpr() - { - Expression> e = () => _i.GetHashCode(); - return e.Compile()(); - } -} -class Program -{ - static void Main() - { - var m = new MyInt(42); - Console.WriteLine(m); - Console.WriteLine(m.GetHashCode()); - Console.WriteLine(m.Equals(null)); - Console.WriteLine(m.ToStringFromExpr()); - Console.WriteLine(m.GetHashCodeFromExpr()); - } -}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - var verifier = CompileAndVerify(comp, expectedOutput: -$@"42 -{42.GetHashCode()} -False -42 -{42.GetHashCode()}"); - verifier.VerifyIL("MyInt.ToString", + // nullable type to nint + conversions(sourceType: "E?", destType: "nint", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "E")); + conversions(sourceType: "bool?", destType: "nint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "char?", destType: "nint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "char")); + conversions(sourceType: "sbyte?", destType: "nint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "sbyte")); + conversions(sourceType: "byte?", destType: "nint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "byte")); + conversions(sourceType: "short?", destType: "nint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "short")); + conversions(sourceType: "ushort?", destType: "nint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "ushort")); + conversions(sourceType: "int?", destType: "nint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "int")); + conversions(sourceType: "uint?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "uint"), expectedCheckedIL: convFromNullableT("conv.ovf.i.un", "uint")); + conversions(sourceType: "long?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "long"), expectedCheckedIL: convFromNullableT("conv.ovf.i", "long")); + conversions(sourceType: "ulong?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "ulong"), expectedCheckedIL: convFromNullableT("conv.ovf.i.un", "ulong")); + conversions(sourceType: "nint?", destType: "nint", ExplicitNullableIdentity, expectedImplicitIL: null, @"{ - // Code size 15 (0xf) + // Code size 8 (0x8) .maxstack 1 - .locals init (System.IntPtr V_0) - IL_0000: ldarg.0 - IL_0001: ldfld ""nint MyInt._i"" - IL_0006: stloc.0 - IL_0007: ldloca.s V_0 - IL_0009: call ""string System.IntPtr.ToString()"" - IL_000e: ret -}"); - verifier.VerifyIL("MyInt.GetHashCode", -@"{ - // Code size 29 (0x1d) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldfld ""nint MyInt._i"" - IL_0006: box ""System.IntPtr"" - IL_000b: dup - IL_000c: ldvirtftn ""int object.GetHashCode()"" - IL_0012: newobj ""System.Func..ctor(object, System.IntPtr)"" - IL_0017: callvirt ""int System.Func.Invoke()"" - IL_001c: ret -}"); - verifier.VerifyIL("MyInt.Equals", -@"{ - // Code size 51 (0x33) - .maxstack 3 - .locals init (System.IntPtr V_0, - nint? V_1) - IL_0000: ldarg.0 - IL_0001: ldfld ""nint MyInt._i"" - IL_0006: stloc.0 - IL_0007: ldloca.s V_0 - IL_0009: ldarg.1 - IL_000a: isinst ""MyInt"" - IL_000f: dup - IL_0010: brtrue.s IL_001e - IL_0012: pop - IL_0013: ldloca.s V_1 - IL_0015: initobj ""nint?"" - IL_001b: ldloc.1 - IL_001c: br.s IL_0028 - IL_001e: ldfld ""nint MyInt._i"" - IL_0023: newobj ""nint?..ctor(nint)"" - IL_0028: box ""nint?"" - IL_002d: call ""bool System.IntPtr.Equals(object)"" - IL_0032: ret + IL_0000: ldarga.s V_0 + IL_0002: call ""nint nint?.Value.get"" + IL_0007: ret }"); - } - - /// - /// Verify there is the number of built in operators for { nint, nuint, nint?, nuint? } - /// for each operator kind. - /// - [Fact] - public void BuiltInOperators() - { - var source = ""; - - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); - verifyOperators(comp); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - verifyOperators(comp); - - static void verifyOperators(CSharpCompilation comp) - { - var unaryOperators = new[] - { - UnaryOperatorKind.PostfixIncrement, - UnaryOperatorKind.PostfixDecrement, - UnaryOperatorKind.PrefixIncrement, - UnaryOperatorKind.PrefixDecrement, - UnaryOperatorKind.UnaryPlus, - UnaryOperatorKind.UnaryMinus, - UnaryOperatorKind.BitwiseComplement, - }; - - var binaryOperators = new[] - { - BinaryOperatorKind.Addition, - BinaryOperatorKind.Subtraction, - BinaryOperatorKind.Multiplication, - BinaryOperatorKind.Division, - BinaryOperatorKind.Remainder, - BinaryOperatorKind.LessThan, - BinaryOperatorKind.LessThanOrEqual, - BinaryOperatorKind.GreaterThan, - BinaryOperatorKind.GreaterThanOrEqual, - BinaryOperatorKind.LeftShift, - BinaryOperatorKind.RightShift, - BinaryOperatorKind.Equal, - BinaryOperatorKind.NotEqual, - BinaryOperatorKind.Or, - BinaryOperatorKind.And, - BinaryOperatorKind.Xor, - BinaryOperatorKind.UnsignedRightShift, - }; - - foreach (var operatorKind in unaryOperators) - { - verifyUnaryOperators(comp, operatorKind, skipNativeIntegerOperators: true); - verifyUnaryOperators(comp, operatorKind, skipNativeIntegerOperators: false); - } - - foreach (var operatorKind in binaryOperators) - { - verifyBinaryOperators(comp, operatorKind, skipNativeIntegerOperators: true); - verifyBinaryOperators(comp, operatorKind, skipNativeIntegerOperators: false); - } - - static void verifyUnaryOperators(CSharpCompilation comp, UnaryOperatorKind operatorKind, bool skipNativeIntegerOperators) - { - var builder = ArrayBuilder.GetInstance(); - comp.builtInOperators.GetSimpleBuiltInOperators(operatorKind, builder, skipNativeIntegerOperators); - var operators = builder.ToImmutableAndFree(); - int expectedSigned = skipNativeIntegerOperators ? 0 : 1; - int expectedUnsigned = skipNativeIntegerOperators ? 0 : (operatorKind == UnaryOperatorKind.UnaryMinus) ? 0 : 1; - verifyOperators(operators, (op, signed) => isNativeInt(op.OperandType, signed), expectedSigned, expectedUnsigned); - verifyOperators(operators, (op, signed) => isNullableNativeInt(op.OperandType, signed), expectedSigned, expectedUnsigned); - } - - static void verifyBinaryOperators(CSharpCompilation comp, BinaryOperatorKind operatorKind, bool skipNativeIntegerOperators) - { - var builder = ArrayBuilder.GetInstance(); - comp.builtInOperators.GetSimpleBuiltInOperators(operatorKind, builder, skipNativeIntegerOperators); - var operators = builder.ToImmutableAndFree(); - int expected = skipNativeIntegerOperators ? 0 : 1; - verifyOperators(operators, (op, signed) => isNativeInt(op.LeftType, signed), expected, expected); - verifyOperators(operators, (op, signed) => isNullableNativeInt(op.LeftType, signed), expected, expected); - } - - static void verifyOperators(ImmutableArray operators, Func predicate, int expectedSigned, int expectedUnsigned) - { - Assert.Equal(expectedSigned, operators.Count(op => predicate(op, true))); - Assert.Equal(expectedUnsigned, operators.Count(op => predicate(op, false))); - } - - static bool isNativeInt(TypeSymbol type, bool signed) - { - return type.IsNativeIntegerType && - type.SpecialType == (signed ? SpecialType.System_IntPtr : SpecialType.System_UIntPtr); - } - - static bool isNullableNativeInt(TypeSymbol type, bool signed) - { - return type.IsNullableType() && isNativeInt(type.GetNullableUnderlyingType(), signed); - } - } - } - - [WorkItem(3259, "https://github.com/dotnet/csharplang/issues/3259")] - [Theory] - [InlineData(false)] - [InlineData(true)] - public void BuiltInConversions_CSharp8(bool useCompilationReference) - { - var sourceA = -@"public class A -{ - public static nint F1; - public static nuint F2; - public static nint? F3; - public static nuint? F4; -}"; - var sourceB = -@"class B : A -{ - static void M1() - { - long x = F1; - ulong y = F2; - long? z = F3; - ulong? w = F4; - } - static void M2(int x, uint y, int? z, uint? w) - { - F1 = x; - F2 = y; - F3 = z; - F4 = w; - } -}"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - var refA = AsReference(comp, useCompilationReference); - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(); - var verifier = CompileAndVerify(comp); - verifier.VerifyIL("B.M1", -@"{ - // Code size 59 (0x3b) - .maxstack 1 - .locals init (nint? V_0, - nuint? V_1) - IL_0000: ldsfld ""nint A.F1"" - IL_0005: pop - IL_0006: ldsfld ""nuint A.F2"" - IL_000b: pop - IL_000c: ldsfld ""nint? A.F3"" - IL_0011: stloc.0 - IL_0012: ldloca.s V_0 - IL_0014: call ""bool nint?.HasValue.get"" - IL_0019: brfalse.s IL_0023 - IL_001b: ldloca.s V_0 - IL_001d: call ""nint nint?.GetValueOrDefault()"" - IL_0022: pop - IL_0023: ldsfld ""nuint? A.F4"" - IL_0028: stloc.1 - IL_0029: ldloca.s V_1 - IL_002b: call ""bool nuint?.HasValue.get"" - IL_0030: brfalse.s IL_003a - IL_0032: ldloca.s V_1 - IL_0034: call ""nuint nuint?.GetValueOrDefault()"" - IL_0039: pop - IL_003a: ret -}"); - verifier.VerifyIL("B.M2", -@"{ - // Code size 95 (0x5f) - .maxstack 1 - .locals init (int? V_0, - nint? V_1, - uint? V_2, - nuint? V_3) - IL_0000: ldarg.0 - IL_0001: conv.i - IL_0002: stsfld ""nint A.F1"" - IL_0007: ldarg.1 - IL_0008: conv.u - IL_0009: stsfld ""nuint A.F2"" - IL_000e: ldarg.2 - IL_000f: stloc.0 - IL_0010: ldloca.s V_0 - IL_0012: call ""bool int?.HasValue.get"" - IL_0017: brtrue.s IL_0024 - IL_0019: ldloca.s V_1 - IL_001b: initobj ""nint?"" - IL_0021: ldloc.1 - IL_0022: br.s IL_0031 - IL_0024: ldloca.s V_0 - IL_0026: call ""int int?.GetValueOrDefault()"" - IL_002b: conv.i - IL_002c: newobj ""nint?..ctor(nint)"" - IL_0031: stsfld ""nint? A.F3"" - IL_0036: ldarg.3 - IL_0037: stloc.2 - IL_0038: ldloca.s V_2 - IL_003a: call ""bool uint?.HasValue.get"" - IL_003f: brtrue.s IL_004c - IL_0041: ldloca.s V_3 - IL_0043: initobj ""nuint?"" - IL_0049: ldloc.3 - IL_004a: br.s IL_0059 - IL_004c: ldloca.s V_2 - IL_004e: call ""uint uint?.GetValueOrDefault()"" - IL_0053: conv.u - IL_0054: newobj ""nuint?..ctor(nuint)"" - IL_0059: stsfld ""nuint? A.F4"" - IL_005e: ret -}"); - } - - [WorkItem(3259, "https://github.com/dotnet/csharplang/issues/3259")] - [Theory] - [InlineData(false)] - [InlineData(true)] - public void BuiltInOperators_CSharp8(bool useCompilationReference) - { - var sourceA = -@"public class A -{ - public static nint F1; - public static nuint F2; - public static nint? F3; - public static nuint? F4; -}"; - var sourceB = -@"class B : A -{ - static void Main() - { - _ = -F1; - _ = +F2; - _ = -F3; - _ = +F4; - _ = F1 * F1; - _ = F2 / F2; - _ = F3 * F1; - _ = F4 / F2; - } -}"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - var refA = AsReference(comp, useCompilationReference); - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - var verifier = CompileAndVerify(comp); - verifier.VerifyIL("B.Main", -@"{ - // Code size 143 (0x8f) - .maxstack 2 - .locals init (nint? V_0, - nuint? V_1, - System.IntPtr V_2, - System.UIntPtr V_3) - IL_0000: ldsfld ""nint A.F1"" - IL_0005: pop - IL_0006: ldsfld ""nuint A.F2"" - IL_000b: pop - IL_000c: ldsfld ""nint? A.F3"" - IL_0011: stloc.0 - IL_0012: ldloca.s V_0 - IL_0014: call ""bool nint?.HasValue.get"" - IL_0019: brfalse.s IL_0023 - IL_001b: ldloca.s V_0 - IL_001d: call ""nint nint?.GetValueOrDefault()"" - IL_0022: pop - IL_0023: ldsfld ""nuint? A.F4"" - IL_0028: stloc.1 - IL_0029: ldloca.s V_1 - IL_002b: call ""bool nuint?.HasValue.get"" - IL_0030: brfalse.s IL_003a - IL_0032: ldloca.s V_1 - IL_0034: call ""nuint nuint?.GetValueOrDefault()"" - IL_0039: pop - IL_003a: ldsfld ""nint A.F1"" - IL_003f: pop - IL_0040: ldsfld ""nint A.F1"" - IL_0045: pop - IL_0046: ldsfld ""nuint A.F2"" - IL_004b: ldsfld ""nuint A.F2"" - IL_0050: div.un - IL_0051: pop - IL_0052: ldsfld ""nint? A.F3"" - IL_0057: stloc.0 - IL_0058: ldsfld ""nint A.F1"" - IL_005d: stloc.2 - IL_005e: ldloca.s V_0 - IL_0060: call ""bool nint?.HasValue.get"" - IL_0065: brfalse.s IL_006f - IL_0067: ldloca.s V_0 - IL_0069: call ""nint nint?.GetValueOrDefault()"" - IL_006e: pop - IL_006f: ldsfld ""nuint? A.F4"" - IL_0074: stloc.1 - IL_0075: ldsfld ""nuint A.F2"" - IL_007a: stloc.3 - IL_007b: ldloca.s V_1 - IL_007d: call ""bool nuint?.HasValue.get"" - IL_0082: brfalse.s IL_008e - IL_0084: ldloca.s V_1 - IL_0086: call ""nuint nuint?.GetValueOrDefault()"" - IL_008b: ldloc.3 - IL_008c: div.un - IL_008d: pop - IL_008e: ret -}"); - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); - comp.VerifyEmitDiagnostics( - // (5,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = -F1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "-F1").WithArguments("native-sized integers", "9.0").WithLocation(5, 13), - // (6,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = +F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "+F2").WithArguments("native-sized integers", "9.0").WithLocation(6, 13), - // (7,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = -F3; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "-F3").WithArguments("native-sized integers", "9.0").WithLocation(7, 13), - // (8,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = +F4; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "+F4").WithArguments("native-sized integers", "9.0").WithLocation(8, 13), - // (9,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 * F1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 * F1").WithArguments("native-sized integers", "9.0").WithLocation(9, 13), - // (10,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F2 / F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F2 / F2").WithArguments("native-sized integers", "9.0").WithLocation(10, 13), - // (11,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F3 * F1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F3 * F1").WithArguments("native-sized integers", "9.0").WithLocation(11, 13), - // (12,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F4 / F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F4 / F2").WithArguments("native-sized integers", "9.0").WithLocation(12, 13)); - } - - [Fact] - public void BuiltInConversions_UnderlyingTypes() - { - var source = -@"class A -{ - static System.IntPtr F1; - static System.UIntPtr F2; - static System.IntPtr? F3; - static System.UIntPtr? F4; - static void M1() - { - long x = F1; - ulong y = F2; - long? z = F3; - ulong? w = F4; - } - static void M2(int x, uint y, int? z, uint? w) - { - F1 = x; - F2 = y; - F3 = z; - F4 = w; - } -}"; - var diagnostics = new[] - { - // (9,18): error CS0266: Cannot implicitly convert type 'System.IntPtr' to 'long'. An explicit conversion exists (are you missing a cast?) - // long x = F1; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "F1").WithArguments("System.IntPtr", "long").WithLocation(9, 18), - // (10,19): error CS0266: Cannot implicitly convert type 'System.UIntPtr' to 'ulong'. An explicit conversion exists (are you missing a cast?) - // ulong y = F2; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "F2").WithArguments("System.UIntPtr", "ulong").WithLocation(10, 19), - // (11,19): error CS0266: Cannot implicitly convert type 'System.IntPtr?' to 'long?'. An explicit conversion exists (are you missing a cast?) - // long? z = F3; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "F3").WithArguments("System.IntPtr?", "long?").WithLocation(11, 19), - // (12,20): error CS0266: Cannot implicitly convert type 'System.UIntPtr?' to 'ulong?'. An explicit conversion exists (are you missing a cast?) - // ulong? w = F4; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "F4").WithArguments("System.UIntPtr?", "ulong?").WithLocation(12, 20), - // (16,14): error CS0266: Cannot implicitly convert type 'int' to 'System.IntPtr'. An explicit conversion exists (are you missing a cast?) - // F1 = x; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("int", "System.IntPtr").WithLocation(16, 14), - // (17,14): error CS0266: Cannot implicitly convert type 'uint' to 'System.UIntPtr'. An explicit conversion exists (are you missing a cast?) - // F2 = y; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "y").WithArguments("uint", "System.UIntPtr").WithLocation(17, 14), - // (18,14): error CS0266: Cannot implicitly convert type 'int?' to 'System.IntPtr?'. An explicit conversion exists (are you missing a cast?) - // F3 = z; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "z").WithArguments("int?", "System.IntPtr?").WithLocation(18, 14), - // (19,14): error CS0266: Cannot implicitly convert type 'uint?' to 'System.UIntPtr?'. An explicit conversion exists (are you missing a cast?) - // F4 = w; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "w").WithArguments("uint?", "System.UIntPtr?").WithLocation(19, 14) - }; - - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(diagnostics); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(diagnostics); - } - - [WorkItem(3259, "https://github.com/dotnet/csharplang/issues/3259")] - [Fact] - public void BuiltInOperators_UnderlyingTypes() - { - var source = -@"#pragma warning disable 649 -class A -{ - static System.IntPtr F1; - static System.UIntPtr F2; - static System.IntPtr? F3; - static System.UIntPtr? F4; - static void Main() - { - F1 = -F1; - F2 = +F2; - F3 = -F3; - F4 = +F4; - F1 = F1 * F1; - F2 = F2 / F2; - F3 = F3 * F1; - F4 = F4 / F2; - } -}"; - var diagnostics = new[] - { - // (10,14): error CS0023: Operator '-' cannot be applied to operand of type 'IntPtr' - // F1 = -F1; - Diagnostic(ErrorCode.ERR_BadUnaryOp, "-F1").WithArguments("-", "System.IntPtr").WithLocation(10, 14), - // (11,14): error CS0023: Operator '+' cannot be applied to operand of type 'UIntPtr' - // F2 = +F2; - Diagnostic(ErrorCode.ERR_BadUnaryOp, "+F2").WithArguments("+", "System.UIntPtr").WithLocation(11, 14), - // (12,14): error CS0023: Operator '-' cannot be applied to operand of type 'IntPtr?' - // F3 = -F3; - Diagnostic(ErrorCode.ERR_BadUnaryOp, "-F3").WithArguments("-", "System.IntPtr?").WithLocation(12, 14), - // (13,14): error CS0023: Operator '+' cannot be applied to operand of type 'UIntPtr?' - // F4 = +F4; - Diagnostic(ErrorCode.ERR_BadUnaryOp, "+F4").WithArguments("+", "System.UIntPtr?").WithLocation(13, 14), - // (14,14): error CS0019: Operator '*' cannot be applied to operands of type 'IntPtr' and 'IntPtr' - // F1 = F1 * F1; - Diagnostic(ErrorCode.ERR_BadBinaryOps, "F1 * F1").WithArguments("*", "System.IntPtr", "System.IntPtr").WithLocation(14, 14), - // (15,14): error CS0019: Operator '/' cannot be applied to operands of type 'UIntPtr' and 'UIntPtr' - // F2 = F2 / F2; - Diagnostic(ErrorCode.ERR_BadBinaryOps, "F2 / F2").WithArguments("/", "System.UIntPtr", "System.UIntPtr").WithLocation(15, 14), - // (16,14): error CS0019: Operator '*' cannot be applied to operands of type 'IntPtr?' and 'IntPtr' - // F3 = F3 * F1; - Diagnostic(ErrorCode.ERR_BadBinaryOps, "F3 * F1").WithArguments("*", "System.IntPtr?", "System.IntPtr").WithLocation(16, 14), - // (17,14): error CS0019: Operator '/' cannot be applied to operands of type 'UIntPtr?' and 'UIntPtr' - // F4 = F4 / F2; - Diagnostic(ErrorCode.ERR_BadBinaryOps, "F4 / F2").WithArguments("/", "System.UIntPtr?", "System.UIntPtr").WithLocation(17, 14) - }; - - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics(diagnostics); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(diagnostics); - } - - [WorkItem(3259, "https://github.com/dotnet/csharplang/issues/3259")] - [Theory] - [InlineData(false, false)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(true, true)] - public void BuiltInConversions_NativeIntegers(bool useCompilationReference, bool useLatest) - { - var sourceA = -@"public class A -{ - public static nint F1; - public static nuint F2; - public static nint? F3; - public static nuint? F4; -}"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - - var sourceB = -@"class B : A -{ - static void M1() - { - long x = F1; - ulong y = F2; - long? z = F3; - ulong? w = F4; - } - static void M2(int x, uint y, int? z, uint? w) - { - F1 = x; - F2 = y; - F3 = z; - F4 = w; - } -}"; - comp = CreateCompilation(sourceB, references: new[] { AsReference(comp, useCompilationReference) }, parseOptions: useLatest ? TestOptions.Regular9 : TestOptions.Regular8); - comp.VerifyDiagnostics(); - var verifier = CompileAndVerify(comp); - verifier.VerifyIL("B.M1", -@"{ - // Code size 59 (0x3b) - .maxstack 1 - .locals init (nint? V_0, - nuint? V_1) - IL_0000: ldsfld ""nint A.F1"" - IL_0005: pop - IL_0006: ldsfld ""nuint A.F2"" - IL_000b: pop - IL_000c: ldsfld ""nint? A.F3"" - IL_0011: stloc.0 - IL_0012: ldloca.s V_0 - IL_0014: call ""bool nint?.HasValue.get"" - IL_0019: brfalse.s IL_0023 - IL_001b: ldloca.s V_0 - IL_001d: call ""nint nint?.GetValueOrDefault()"" - IL_0022: pop - IL_0023: ldsfld ""nuint? A.F4"" - IL_0028: stloc.1 - IL_0029: ldloca.s V_1 - IL_002b: call ""bool nuint?.HasValue.get"" - IL_0030: brfalse.s IL_003a - IL_0032: ldloca.s V_1 - IL_0034: call ""nuint nuint?.GetValueOrDefault()"" - IL_0039: pop - IL_003a: ret -}"); - verifier.VerifyIL("B.M2", -@"{ - // Code size 95 (0x5f) - .maxstack 1 - .locals init (int? V_0, - nint? V_1, - uint? V_2, - nuint? V_3) - IL_0000: ldarg.0 - IL_0001: conv.i - IL_0002: stsfld ""nint A.F1"" - IL_0007: ldarg.1 - IL_0008: conv.u - IL_0009: stsfld ""nuint A.F2"" - IL_000e: ldarg.2 - IL_000f: stloc.0 - IL_0010: ldloca.s V_0 - IL_0012: call ""bool int?.HasValue.get"" - IL_0017: brtrue.s IL_0024 - IL_0019: ldloca.s V_1 - IL_001b: initobj ""nint?"" - IL_0021: ldloc.1 - IL_0022: br.s IL_0031 - IL_0024: ldloca.s V_0 - IL_0026: call ""int int?.GetValueOrDefault()"" - IL_002b: conv.i - IL_002c: newobj ""nint?..ctor(nint)"" - IL_0031: stsfld ""nint? A.F3"" - IL_0036: ldarg.3 - IL_0037: stloc.2 - IL_0038: ldloca.s V_2 - IL_003a: call ""bool uint?.HasValue.get"" - IL_003f: brtrue.s IL_004c - IL_0041: ldloca.s V_3 - IL_0043: initobj ""nuint?"" - IL_0049: ldloc.3 - IL_004a: br.s IL_0059 - IL_004c: ldloca.s V_2 - IL_004e: call ""uint uint?.GetValueOrDefault()"" - IL_0053: conv.u - IL_0054: newobj ""nuint?..ctor(nuint)"" - IL_0059: stsfld ""nuint? A.F4"" - IL_005e: ret -}"); - } - - [WorkItem(3259, "https://github.com/dotnet/csharplang/issues/3259")] - [Theory] - [InlineData(false)] - [InlineData(true)] - public void BuiltInOperators_NativeIntegers(bool useCompilationReference) - { - var sourceA = -@"public class A -{ - public static nint F1; - public static nuint F2; - public static nint? F3; - public static nuint? F4; -}"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - var refA = AsReference(comp, useCompilationReference); - - var sourceB = -@"class B : A -{ - static void Main() - { - F1 = -F1; - F2 = +F2; - F3 = -F3; - F4 = +F4; - F1 = F1 * F1; - F2 = F2 / F2; - F3 = F3 * F1; - F4 = F4 / F2; - } -}"; - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - var verifier = CompileAndVerify(comp); - verifier.VerifyIL("B.Main", -@"{ - // Code size 247 (0xf7) - .maxstack 2 - .locals init (nint? V_0, - nint? V_1, - nuint? V_2, - nuint? V_3, - System.IntPtr V_4, - System.UIntPtr V_5) - IL_0000: ldsfld ""nint A.F1"" - IL_0005: neg - IL_0006: stsfld ""nint A.F1"" - IL_000b: ldsfld ""nuint A.F2"" - IL_0010: stsfld ""nuint A.F2"" - IL_0015: ldsfld ""nint? A.F3"" - IL_001a: stloc.0 - IL_001b: ldloca.s V_0 - IL_001d: call ""bool nint?.HasValue.get"" - IL_0022: brtrue.s IL_002f - IL_0024: ldloca.s V_1 - IL_0026: initobj ""nint?"" - IL_002c: ldloc.1 - IL_002d: br.s IL_003c - IL_002f: ldloca.s V_0 - IL_0031: call ""nint nint?.GetValueOrDefault()"" - IL_0036: neg - IL_0037: newobj ""nint?..ctor(nint)"" - IL_003c: stsfld ""nint? A.F3"" - IL_0041: ldsfld ""nuint? A.F4"" - IL_0046: stloc.2 - IL_0047: ldloca.s V_2 - IL_0049: call ""bool nuint?.HasValue.get"" - IL_004e: brtrue.s IL_005b - IL_0050: ldloca.s V_3 - IL_0052: initobj ""nuint?"" - IL_0058: ldloc.3 - IL_0059: br.s IL_0067 - IL_005b: ldloca.s V_2 - IL_005d: call ""nuint nuint?.GetValueOrDefault()"" - IL_0062: newobj ""nuint?..ctor(nuint)"" - IL_0067: stsfld ""nuint? A.F4"" - IL_006c: ldsfld ""nint A.F1"" - IL_0071: ldsfld ""nint A.F1"" - IL_0076: mul - IL_0077: stsfld ""nint A.F1"" - IL_007c: ldsfld ""nuint A.F2"" - IL_0081: ldsfld ""nuint A.F2"" - IL_0086: div.un - IL_0087: stsfld ""nuint A.F2"" - IL_008c: ldsfld ""nint? A.F3"" - IL_0091: stloc.0 - IL_0092: ldsfld ""nint A.F1"" - IL_0097: stloc.s V_4 - IL_0099: ldloca.s V_0 - IL_009b: call ""bool nint?.HasValue.get"" - IL_00a0: brtrue.s IL_00ad - IL_00a2: ldloca.s V_1 - IL_00a4: initobj ""nint?"" - IL_00aa: ldloc.1 - IL_00ab: br.s IL_00bc - IL_00ad: ldloca.s V_0 - IL_00af: call ""nint nint?.GetValueOrDefault()"" - IL_00b4: ldloc.s V_4 - IL_00b6: mul - IL_00b7: newobj ""nint?..ctor(nint)"" - IL_00bc: stsfld ""nint? A.F3"" - IL_00c1: ldsfld ""nuint? A.F4"" - IL_00c6: stloc.2 - IL_00c7: ldsfld ""nuint A.F2"" - IL_00cc: stloc.s V_5 - IL_00ce: ldloca.s V_2 - IL_00d0: call ""bool nuint?.HasValue.get"" - IL_00d5: brtrue.s IL_00e2 - IL_00d7: ldloca.s V_3 - IL_00d9: initobj ""nuint?"" - IL_00df: ldloc.3 - IL_00e0: br.s IL_00f1 - IL_00e2: ldloca.s V_2 - IL_00e4: call ""nuint nuint?.GetValueOrDefault()"" - IL_00e9: ldloc.s V_5 - IL_00eb: div.un - IL_00ec: newobj ""nuint?..ctor(nuint)"" - IL_00f1: stsfld ""nuint? A.F4"" - IL_00f6: ret -}"); - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); - comp.VerifyDiagnostics( - // (5,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F1 = -F1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "-F1").WithArguments("native-sized integers", "9.0").WithLocation(5, 14), - // (6,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F2 = +F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "+F2").WithArguments("native-sized integers", "9.0").WithLocation(6, 14), - // (7,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F3 = -F3; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "-F3").WithArguments("native-sized integers", "9.0").WithLocation(7, 14), - // (8,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F4 = +F4; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "+F4").WithArguments("native-sized integers", "9.0").WithLocation(8, 14), - // (9,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F1 = F1 * F1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 * F1").WithArguments("native-sized integers", "9.0").WithLocation(9, 14), - // (10,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F2 = F2 / F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F2 / F2").WithArguments("native-sized integers", "9.0").WithLocation(10, 14), - // (11,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F3 = F3 * F1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F3 * F1").WithArguments("native-sized integers", "9.0").WithLocation(11, 14), - // (12,14): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F4 = F4 / F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F4 / F2").WithArguments("native-sized integers", "9.0").WithLocation(12, 14)); - } - - [Theory] - [CombinatorialData] - [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] - public void NativeIntegerOperatorsCSharp8_01(bool useCompilationReference, bool lifted) - { - string typeSuffix = lifted ? "?" : ""; - var sourceA = -$@"public class A -{{ - public static nint{typeSuffix} F1; - public static nuint{typeSuffix} F2; -}}"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - var refA = AsReference(comp, useCompilationReference); - - var sourceB = -@"class B : A -{ - static void Main() - { - _ = +F1; - _ = -F1; - _ = ~F1; - _ = +F2; - _ = ~F2; - } -}"; - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(); - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); - comp.VerifyEmitDiagnostics( - // (5,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = +F1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "+F1").WithArguments("native-sized integers", "9.0").WithLocation(5, 13), - // (6,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = -F1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "-F1").WithArguments("native-sized integers", "9.0").WithLocation(6, 13), - // (7,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = ~F1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "~F1").WithArguments("native-sized integers", "9.0").WithLocation(7, 13), - // (8,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = +F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "+F2").WithArguments("native-sized integers", "9.0").WithLocation(8, 13), - // (9,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = ~F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "~F2").WithArguments("native-sized integers", "9.0").WithLocation(9, 13)); - } - - [Theory] - [CombinatorialData] - [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] - public void NativeIntegerOperatorsCSharp8_02(bool useCompilationReference, [CombinatorialValues("nint", "nint?", "nuint", "nuint?")] string type) - { - var sourceA = -$@"public class A -{{ - public static {type} F; -}}"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - var refA = AsReference(comp, useCompilationReference); - - var sourceB = -@"class B : A -{ - static void Main() - { - ++F; - F++; - --F; - F--; - } -}"; - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(); - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); - comp.VerifyEmitDiagnostics( - // (5,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // ++F; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "++F").WithArguments("native-sized integers", "9.0").WithLocation(5, 9), - // (6,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F++; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F++").WithArguments("native-sized integers", "9.0").WithLocation(6, 9), - // (7,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // --F; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "--F").WithArguments("native-sized integers", "9.0").WithLocation(7, 9), - // (8,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F--; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F--").WithArguments("native-sized integers", "9.0").WithLocation(8, 9)); - } - - [Theory] - [CombinatorialData] - [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] - public void NativeIntegerOperatorsCSharp8_03(bool useCompilationReference, [CombinatorialValues("nint", "nint?", "nuint", "nuint?")] string type) - { - var sourceA = -$@"public class A -{{ - public static {type} F1, F2; -}}"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - var refA = AsReference(comp, useCompilationReference); - - var sourceB = -@"class B : A -{ - static void Main() - { - _ = F1 + F2; - _ = F1 - F2; - _ = F1 * F2; - _ = F1 / F2; - _ = F1 % F2; - _ = F1 < F2; - _ = F1 <= F2; - _ = F1 > F2; - _ = F1 >= F2; - _ = F1 == F2; - _ = F1 != F2; - _ = F1 & F2; - _ = F1 | F2; - _ = F1 ^ F2; - _ = F1 << 1; - _ = F1 >> 1; - } -}"; - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(); - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); - comp.VerifyEmitDiagnostics( - // (5,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 + F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 + F2").WithArguments("native-sized integers", "9.0").WithLocation(5, 13), - // (6,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 - F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 - F2").WithArguments("native-sized integers", "9.0").WithLocation(6, 13), - // (7,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 * F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 * F2").WithArguments("native-sized integers", "9.0").WithLocation(7, 13), - // (8,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 / F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 / F2").WithArguments("native-sized integers", "9.0").WithLocation(8, 13), - // (9,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 % F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 % F2").WithArguments("native-sized integers", "9.0").WithLocation(9, 13), - // (10,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 < F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 < F2").WithArguments("native-sized integers", "9.0").WithLocation(10, 13), - // (11,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 <= F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 <= F2").WithArguments("native-sized integers", "9.0").WithLocation(11, 13), - // (12,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 > F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 > F2").WithArguments("native-sized integers", "9.0").WithLocation(12, 13), - // (13,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 >= F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 >= F2").WithArguments("native-sized integers", "9.0").WithLocation(13, 13), - // (14,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 == F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 == F2").WithArguments("native-sized integers", "9.0").WithLocation(14, 13), - // (15,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 != F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 != F2").WithArguments("native-sized integers", "9.0").WithLocation(15, 13), - // (16,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 & F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 & F2").WithArguments("native-sized integers", "9.0").WithLocation(16, 13), - // (17,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 | F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 | F2").WithArguments("native-sized integers", "9.0").WithLocation(17, 13), - // (18,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 ^ F2; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 ^ F2").WithArguments("native-sized integers", "9.0").WithLocation(18, 13), - // (19,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 << 1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 << 1").WithArguments("native-sized integers", "9.0").WithLocation(19, 13), - // (20,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = F1 >> 1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F1 >> 1").WithArguments("native-sized integers", "9.0").WithLocation(20, 13)); - } - - [Theory] - [CombinatorialData] - [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] - public void NativeIntegerOperatorsCSharp8_04(bool useCompilationReference, [CombinatorialValues("nint", "nint?", "nuint", "nuint?")] string type) - { - var sourceA = -$@"public class A -{{ - public static {type} F1, F2; -}}"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - var refA = AsReference(comp, useCompilationReference); - - var sourceB = -@"class B : A -{ - static void Main() - { - _ = (F1, F1) == (F2, F2); - _ = (F1, F1) != (F2, F2); - } -}"; - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(); - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); - comp.VerifyEmitDiagnostics( - // (5,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = (F1, F1) == (F2, F2); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "(F1, F1) == (F2, F2)").WithArguments("native-sized integers", "9.0").WithLocation(5, 13), - // (5,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = (F1, F1) == (F2, F2); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "(F1, F1) == (F2, F2)").WithArguments("native-sized integers", "9.0").WithLocation(5, 13), - // (6,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = (F1, F1) != (F2, F2); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "(F1, F1) != (F2, F2)").WithArguments("native-sized integers", "9.0").WithLocation(6, 13), - // (6,13): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // _ = (F1, F1) != (F2, F2); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "(F1, F1) != (F2, F2)").WithArguments("native-sized integers", "9.0").WithLocation(6, 13)); - } - - [Theory] - [CombinatorialData] - [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] - public void NativeIntegerOperatorsCSharp8_05(bool useCompilationReference, [CombinatorialValues("nint", "nint?", "nuint", "nuint?")] string type) - { - var sourceA = -$@"public class A -{{ - public static {type} F; -}}"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - var refA = AsReference(comp, useCompilationReference); - - var sourceB = -@"class B : A -{ - static void Main() - { - F += 1; - F -= 1; - F *= 1; - F /= 1; - F %= 1; - F &= 1; - F |= 1; - F ^= 1; - F <<= 1; - F >>= 1; - } -}"; - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(); - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); - comp.VerifyEmitDiagnostics( - // (5,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F += 1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F += 1").WithArguments("native-sized integers", "9.0").WithLocation(5, 9), - // (6,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F -= 1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F -= 1").WithArguments("native-sized integers", "9.0").WithLocation(6, 9), - // (7,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F *= 1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F *= 1").WithArguments("native-sized integers", "9.0").WithLocation(7, 9), - // (8,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F /= 1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F /= 1").WithArguments("native-sized integers", "9.0").WithLocation(8, 9), - // (9,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F %= 1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F %= 1").WithArguments("native-sized integers", "9.0").WithLocation(9, 9), - // (10,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F &= 1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F &= 1").WithArguments("native-sized integers", "9.0").WithLocation(10, 9), - // (11,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F |= 1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F |= 1").WithArguments("native-sized integers", "9.0").WithLocation(11, 9), - // (12,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F ^= 1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F ^= 1").WithArguments("native-sized integers", "9.0").WithLocation(12, 9), - // (13,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F <<= 1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F <<= 1").WithArguments("native-sized integers", "9.0").WithLocation(13, 9), - // (14,9): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. - // F >>= 1; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "F >>= 1").WithArguments("native-sized integers", "9.0").WithLocation(14, 9)); - } - - [Theory] - [CombinatorialData] - [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] - public void NativeIntegerConversionsCSharp8_01(bool useCompilationReference, [CombinatorialValues("nint", "nuint")] string type) - { - var sourceA = -$@"public class A -{{ - public static {type} F1; - public static {type}? F2; -}}"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - var refA = AsReference(comp, useCompilationReference); - - var sourceB = -@"class B : A -{ - static void Main() - { - F1 = sbyte.MaxValue; - F1 = byte.MaxValue; - F1 = char.MaxValue; - F1 = short.MaxValue; - F1 = ushort.MaxValue; - F1 = int.MaxValue; - F2 = sbyte.MaxValue; - F2 = byte.MaxValue; - F2 = char.MaxValue; - F2 = short.MaxValue; - F2 = ushort.MaxValue; - F2 = int.MaxValue; - } -}"; - - var expectedDiagnostics = (type == "nuint") ? - new DiagnosticDescription[] - { - // (5,14): error CS0266: Cannot implicitly convert type 'sbyte' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // F1 = sbyte.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "sbyte.MaxValue").WithArguments("sbyte", "nuint").WithLocation(5, 14), - // (8,14): error CS0266: Cannot implicitly convert type 'short' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // F1 = short.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "short.MaxValue").WithArguments("short", "nuint").WithLocation(8, 14), - // (11,14): error CS0266: Cannot implicitly convert type 'sbyte' to 'nuint?'. An explicit conversion exists (are you missing a cast?) - // F2 = sbyte.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "sbyte.MaxValue").WithArguments("sbyte", "nuint?").WithLocation(11, 14), - // (14,14): error CS0266: Cannot implicitly convert type 'short' to 'nuint?'. An explicit conversion exists (are you missing a cast?) - // F2 = short.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "short.MaxValue").WithArguments("short", "nuint?").WithLocation(14, 14) - } : - new DiagnosticDescription[0]; - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(expectedDiagnostics); - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); - comp.VerifyEmitDiagnostics(expectedDiagnostics); - } - - [Theory] - [CombinatorialData] - [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] - public void NativeIntegerConversionsCSharp8_02(bool useCompilationReference, bool signed) - { - string type = signed ? "nint" : "nuint"; - string underlyingType = signed ? "System.IntPtr" : "System.UIntPtr"; - - var sourceA = -$@"public class A -{{ - public static {type} F1; - public static {type}? F2; -}}"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - var refA = AsReference(comp, useCompilationReference); - - var sourceB = -$@"class B : A -{{ - static T F() => throw null; - static void Main() - {{ - F1 = F(); - F1 = F(); - F1 = F(); - F1 = F<{underlyingType}>(); - F2 = F(); - F2 = F(); - F2 = F(); - F2 = F(); - F2 = F(); - F2 = F(); - F2 = F<{underlyingType}>(); - F2 = F<{underlyingType}?>(); - }} -}}"; - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(); - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); - comp.VerifyEmitDiagnostics(); - } - - [Theory] - [CombinatorialData] - [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] - public void NativeIntegerConversionsCSharp8_03(bool useCompilationReference, bool signed) - { - string type = signed ? "nint" : "nuint"; - string underlyingType = signed ? "System.IntPtr" : "System.UIntPtr"; - - var sourceA = -$@"public class A -{{ - public static {type} F1; - public static {type}? F2; -}}"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - var refA = AsReference(comp, useCompilationReference); - - var sourceB = -$@"class B : A -{{ - static void M0() - {{ - object o; - o = F1; - o = (object)F1; - o = F2; - o = (object)F2; - }} - static void M1() - {{ - {underlyingType} ptr; - sbyte sb; - byte b; - char c; - short s; - ushort us; - int i; - uint u; - long l; - ulong ul; - float f; - double d; - decimal dec; - ptr = F1; - f = F1; - d = F1; - dec = F1; - ptr = ({underlyingType})F1; - sb = (sbyte)F1; - b = (byte)F1; - c = (char)F1; - s = (short)F1; - us = (ushort)F1; - i = (int)F1; - u = (uint)F1; - l = (long)F1; - ul = (ulong)F1; - f = (float)F1; - d = (double)F1; - dec = (decimal)F1; - ptr = ({underlyingType})F2; - sb = (sbyte)F2; - b = (byte)F2; - c = (char)F2; - s = (short)F2; - us = (ushort)F2; - i = (int)F2; - u = (uint)F2; - l = (long)F2; - ul = (ulong)F2; - f = (float)F2; - d = (double)F2; - dec = (decimal)F2; - }} - static void M2() - {{ - {underlyingType}? ptr; - sbyte? sb; - byte? b; - char? c; - short? s; - ushort? us; - int? i; - uint? u; - long? l; - ulong? ul; - float? f; - double? d; - decimal? dec; - ptr = F1; - f = F1; - d = F1; - dec = F1; - ptr = ({underlyingType}?)F1; - sb = (sbyte?)F1; - b = (byte?)F1; - c = (char?)F1; - s = (short?)F1; - us = (ushort?)F1; - i = (int?)F1; - u = (uint?)F1; - l = (long?)F1; - ul = (ulong?)F1; - f = (float?)F1; - d = (double?)F1; - dec = (decimal?)F1; - ptr = F2; - f = F2; - d = F2; - dec = F2; - ptr = ({underlyingType}?)F2; - sb = (sbyte?)F2; - b = (byte?)F2; - c = (char?)F2; - s = (short?)F2; - us = (ushort?)F2; - i = (int?)F2; - u = (uint?)F2; - l = (long?)F2; - ul = (ulong?)F2; - f = (float?)F2; - d = (double?)F2; - dec = (decimal?)F2; - }} -}}"; - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(); - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); - comp.VerifyEmitDiagnostics(); - } - - [Theory] - [CombinatorialData] - [WorkItem(42941, "https://github.com/dotnet/roslyn/issues/42941")] - public void NativeIntegerConversionsCSharp8_04(bool useCompilationReference, [CombinatorialValues("nint", "nuint")] string type) - { - var sourceA = -$@"public class A -{{ - public static {type} F1, F2; - public static {type}? F3, F4; -}}"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - var refA = AsReference(comp, useCompilationReference); - - var sourceB = -$@"class B : A -{{ - static void Main() - {{ - F2 = F1; - F4 = F1; - F4 = F3; - }} -}}"; - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(); - - comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular8); - comp.VerifyEmitDiagnostics(); - } - - [Theory] - [CombinatorialData] - public void SemanticModel_UnaryOperators(bool lifted) - { - string typeQualifier = lifted ? "?" : ""; - var source = -$@"class Program -{{ - static void F(nint{typeQualifier} x, nuint{typeQualifier} y) - {{ - _ = +x; - _ = -x; - _ = ~x; - _ = +y; - _ = ~y; - }} -}}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(); - var tree = comp.SyntaxTrees[0]; - var model = comp.GetSemanticModel(tree); - var nodes = tree.GetRoot().DescendantNodes().OfType(); - var actualOperators = nodes.Select(n => model.GetSymbolInfo(n).Symbol.ToTestDisplayString()).ToArray(); - var expectedOperators = new[] - { - "nint nint.op_UnaryPlus(nint value)", - "nint nint.op_UnaryNegation(nint value)", - "nint nint.op_OnesComplement(nint value)", - "nuint nuint.op_UnaryPlus(nuint value)", - "nuint nuint.op_OnesComplement(nuint value)", - }; - AssertEx.Equal(expectedOperators, actualOperators); - } - - [Theory] - [InlineData("nint", false)] - [InlineData("nuint", false)] - [InlineData("nint", true)] - [InlineData("nuint", true)] - public void SemanticModel_BinaryOperators(string type, bool lifted) - { - string typeQualifier = lifted ? "?" : ""; - var source = -$@"class Program -{{ - static void F({type}{typeQualifier} x, {type}{typeQualifier} y) - {{ - _ = x + y; - _ = x - y; - _ = x * y; - _ = x / y; - _ = x % y; - _ = x < y; - _ = x <= y; - _ = x > y; - _ = x >= y; - _ = x == y; - _ = x != y; - _ = x & y; - _ = x | y; - _ = x ^ y; - _ = x << 1; - _ = x >> 1; - }} -}}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(); - var tree = comp.SyntaxTrees[0]; - var model = comp.GetSemanticModel(tree); - var nodes = tree.GetRoot().DescendantNodes().OfType(); - var actualOperators = nodes.Select(n => model.GetSymbolInfo(n).Symbol.ToTestDisplayString()).ToArray(); - var expectedOperators = new[] - { - $"{type} {type}.op_Addition({type} left, {type} right)", - $"{type} {type}.op_Subtraction({type} left, {type} right)", - $"{type} {type}.op_Multiply({type} left, {type} right)", - $"{type} {type}.op_Division({type} left, {type} right)", - $"{type} {type}.op_Modulus({type} left, {type} right)", - $"System.Boolean {type}.op_LessThan({type} left, {type} right)", - $"System.Boolean {type}.op_LessThanOrEqual({type} left, {type} right)", - $"System.Boolean {type}.op_GreaterThan({type} left, {type} right)", - $"System.Boolean {type}.op_GreaterThanOrEqual({type} left, {type} right)", - $"System.Boolean {type}.op_Equality({type} left, {type} right)", - $"System.Boolean {type}.op_Inequality({type} left, {type} right)", - $"{type} {type}.op_BitwiseAnd({type} left, {type} right)", - $"{type} {type}.op_BitwiseOr({type} left, {type} right)", - $"{type} {type}.op_ExclusiveOr({type} left, {type} right)", - $"{type} {type}.op_LeftShift({type} left, System.Int32 right)", - $"{type} {type}.op_RightShift({type} left, System.Int32 right)", - }; - AssertEx.Equal(expectedOperators, actualOperators); - } - - [Theory] - [InlineData("")] - [InlineData("unchecked")] - [InlineData("checked")] - public void ConstantConversions_ToNativeInt(string context) - { - var source = -$@"#pragma warning disable 219 -class Program -{{ - static void F1() - {{ - nint i; - {context} - {{ - i = sbyte.MaxValue; - i = byte.MaxValue; - i = char.MaxValue; - i = short.MaxValue; - i = ushort.MaxValue; - i = int.MaxValue; - i = uint.MaxValue; - i = long.MaxValue; - i = ulong.MaxValue; - i = float.MaxValue; - i = double.MaxValue; - i = (decimal)int.MaxValue; - i = (nint)int.MaxValue; - i = (nuint)uint.MaxValue; - }} - }} - static void F2() - {{ - nuint u; - {context} - {{ - u = sbyte.MaxValue; - u = byte.MaxValue; - u = char.MaxValue; - u = short.MaxValue; - u = ushort.MaxValue; - u = int.MaxValue; - u = uint.MaxValue; - u = long.MaxValue; - u = ulong.MaxValue; - u = float.MaxValue; - u = double.MaxValue; - u = (decimal)uint.MaxValue; - u = (nint)int.MaxValue; - u = (nuint)uint.MaxValue; - }} - }} -}}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (15,17): error CS0266: Cannot implicitly convert type 'uint' to 'nint'. An explicit conversion exists (are you missing a cast?) - // i = uint.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "uint.MaxValue").WithArguments("uint", "nint").WithLocation(15, 17), - // (16,17): error CS0266: Cannot implicitly convert type 'long' to 'nint'. An explicit conversion exists (are you missing a cast?) - // i = long.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "long.MaxValue").WithArguments("long", "nint").WithLocation(16, 17), - // (17,17): error CS0266: Cannot implicitly convert type 'ulong' to 'nint'. An explicit conversion exists (are you missing a cast?) - // i = ulong.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "ulong.MaxValue").WithArguments("ulong", "nint").WithLocation(17, 17), - // (18,17): error CS0266: Cannot implicitly convert type 'float' to 'nint'. An explicit conversion exists (are you missing a cast?) - // i = float.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "float.MaxValue").WithArguments("float", "nint").WithLocation(18, 17), - // (19,17): error CS0266: Cannot implicitly convert type 'double' to 'nint'. An explicit conversion exists (are you missing a cast?) - // i = double.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "double.MaxValue").WithArguments("double", "nint").WithLocation(19, 17), - // (20,17): error CS0266: Cannot implicitly convert type 'decimal' to 'nint'. An explicit conversion exists (are you missing a cast?) - // i = (decimal)int.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "(decimal)int.MaxValue").WithArguments("decimal", "nint").WithLocation(20, 17), - // (22,17): error CS0266: Cannot implicitly convert type 'nuint' to 'nint'. An explicit conversion exists (are you missing a cast?) - // i = (nuint)uint.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "(nuint)uint.MaxValue").WithArguments("nuint", "nint").WithLocation(22, 17), - // (30,17): error CS0266: Cannot implicitly convert type 'sbyte' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // u = sbyte.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "sbyte.MaxValue").WithArguments("sbyte", "nuint").WithLocation(30, 17), - // (33,17): error CS0266: Cannot implicitly convert type 'short' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // u = short.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "short.MaxValue").WithArguments("short", "nuint").WithLocation(33, 17), - // (37,17): error CS0266: Cannot implicitly convert type 'long' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // u = long.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "long.MaxValue").WithArguments("long", "nuint").WithLocation(37, 17), - // (38,17): error CS0266: Cannot implicitly convert type 'ulong' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // u = ulong.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "ulong.MaxValue").WithArguments("ulong", "nuint").WithLocation(38, 17), - // (39,17): error CS0266: Cannot implicitly convert type 'float' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // u = float.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "float.MaxValue").WithArguments("float", "nuint").WithLocation(39, 17), - // (40,17): error CS0266: Cannot implicitly convert type 'double' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // u = double.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "double.MaxValue").WithArguments("double", "nuint").WithLocation(40, 17), - // (41,17): error CS0266: Cannot implicitly convert type 'decimal' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // u = (decimal)uint.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "(decimal)uint.MaxValue").WithArguments("decimal", "nuint").WithLocation(41, 17), - // (42,17): error CS0266: Cannot implicitly convert type 'nint' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // u = (nint)int.MaxValue; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "(nint)int.MaxValue").WithArguments("nint", "nuint").WithLocation(42, 17)); - } - - [Theory] - [InlineData("")] - [InlineData("unchecked")] - [InlineData("checked")] - public void ConstantConversions_FromNativeInt(string context) - { - var source = -$@"#pragma warning disable 219 -class Program -{{ - static void F1() - {{ - const nint n = (nint)int.MaxValue; - {context} - {{ - sbyte sb = n; - byte b = n; - char c = n; - short s = n; - ushort us = n; - int i = n; - uint u = n; - long l = n; - ulong ul = n; - float f = n; - double d = n; - decimal dec = n; - nuint nu = n; - }} - }} - static void F2() - {{ - const nuint nu = (nuint)uint.MaxValue; - {context} - {{ - sbyte sb = nu; - byte b = nu; - char c = nu; - short s = nu; - ushort us = nu; - int i = nu; - uint u = nu; - long l = nu; - ulong ul = nu; - float f = nu; - double d = nu; - decimal dec = nu; - nint n = nu; - }} - }} -}}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (9,24): error CS0266: Cannot implicitly convert type 'nint' to 'sbyte'. An explicit conversion exists (are you missing a cast?) - // sbyte sb = n; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "sbyte").WithLocation(9, 24), - // (10,22): error CS0266: Cannot implicitly convert type 'nint' to 'byte'. An explicit conversion exists (are you missing a cast?) - // byte b = n; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "byte").WithLocation(10, 22), - // (11,22): error CS0266: Cannot implicitly convert type 'nint' to 'char'. An explicit conversion exists (are you missing a cast?) - // char c = n; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "char").WithLocation(11, 22), - // (12,23): error CS0266: Cannot implicitly convert type 'nint' to 'short'. An explicit conversion exists (are you missing a cast?) - // short s = n; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "short").WithLocation(12, 23), - // (13,25): error CS0266: Cannot implicitly convert type 'nint' to 'ushort'. An explicit conversion exists (are you missing a cast?) - // ushort us = n; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "ushort").WithLocation(13, 25), - // (14,21): error CS0266: Cannot implicitly convert type 'nint' to 'int'. An explicit conversion exists (are you missing a cast?) - // int i = n; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "int").WithLocation(14, 21), - // (15,22): error CS0266: Cannot implicitly convert type 'nint' to 'uint'. An explicit conversion exists (are you missing a cast?) - // uint u = n; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "uint").WithLocation(15, 22), - // (17,24): error CS0266: Cannot implicitly convert type 'nint' to 'ulong'. An explicit conversion exists (are you missing a cast?) - // ulong ul = n; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "ulong").WithLocation(17, 24), - // (21,24): error CS0266: Cannot implicitly convert type 'nint' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // nuint nu = n; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "n").WithArguments("nint", "nuint").WithLocation(21, 24), - // (29,24): error CS0266: Cannot implicitly convert type 'nuint' to 'sbyte'. An explicit conversion exists (are you missing a cast?) - // sbyte sb = nu; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "sbyte").WithLocation(29, 24), - // (30,22): error CS0266: Cannot implicitly convert type 'nuint' to 'byte'. An explicit conversion exists (are you missing a cast?) - // byte b = nu; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "byte").WithLocation(30, 22), - // (31,22): error CS0266: Cannot implicitly convert type 'nuint' to 'char'. An explicit conversion exists (are you missing a cast?) - // char c = nu; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "char").WithLocation(31, 22), - // (32,23): error CS0266: Cannot implicitly convert type 'nuint' to 'short'. An explicit conversion exists (are you missing a cast?) - // short s = nu; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "short").WithLocation(32, 23), - // (33,25): error CS0266: Cannot implicitly convert type 'nuint' to 'ushort'. An explicit conversion exists (are you missing a cast?) - // ushort us = nu; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "ushort").WithLocation(33, 25), - // (34,21): error CS0266: Cannot implicitly convert type 'nuint' to 'int'. An explicit conversion exists (are you missing a cast?) - // int i = nu; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "int").WithLocation(34, 21), - // (35,22): error CS0266: Cannot implicitly convert type 'nuint' to 'uint'. An explicit conversion exists (are you missing a cast?) - // uint u = nu; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "uint").WithLocation(35, 22), - // (36,22): error CS0266: Cannot implicitly convert type 'nuint' to 'long'. An explicit conversion exists (are you missing a cast?) - // long l = nu; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "long").WithLocation(36, 22), - // (41,22): error CS0266: Cannot implicitly convert type 'nuint' to 'nint'. An explicit conversion exists (are you missing a cast?) - // nint n = nu; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "nu").WithArguments("nuint", "nint").WithLocation(41, 22)); - } - - [WorkItem(42955, "https://github.com/dotnet/roslyn/issues/42955")] - [WorkItem(45525, "https://github.com/dotnet/roslyn/issues/45525")] - [Fact] - public void ConstantConversions_01() - { - var source = -@"using System; -class Program -{ - static void Main() - { - const long x = 0xFFFFFFFFFFFFFFFL; - const nint y = checked((nint)x); - Console.WriteLine(y); - } -}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (7,24): error CS0133: The expression being assigned to 'y' must be constant - // const nint y = checked((nint)x); - Diagnostic(ErrorCode.ERR_NotConstantExpression, "checked((nint)x)").WithArguments("y").WithLocation(7, 24), - // (7,32): warning CS8778: Constant value '1152921504606846975' may overflow 'nint' at runtime (use 'unchecked' syntax to override) - // const nint y = checked((nint)x); - Diagnostic(ErrorCode.WRN_ConstOutOfRangeChecked, "(nint)x").WithArguments("1152921504606846975", "nint").WithLocation(7, 32)); - - source = -@"using System; -class Program -{ - static void Main() - { - const long x = 0xFFFFFFFFFFFFFFFL; - try - { - nint y = checked((nint)x); - Console.WriteLine(y); - } - catch (Exception e) - { - Console.WriteLine(e.GetType()); - } - } -}"; - comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (9,30): warning CS8778: Constant value '1152921504606846975' may overflow 'nint' at runtime (use 'unchecked' syntax to override) - // nint y = checked((nint)x); - Diagnostic(ErrorCode.WRN_ConstOutOfRangeChecked, "(nint)x").WithArguments("1152921504606846975", "nint").WithLocation(9, 30)); - CompileAndVerify(comp, expectedOutput: IntPtr.Size == 4 ? "System.OverflowException" : "1152921504606846975"); - } - - [WorkItem(45531, "https://github.com/dotnet/roslyn/issues/45531")] - [Fact] - public void ConstantConversions_02() - { - var source = -@"using System; -class Program -{ - static void Main() - { - const long x = 0xFFFFFFFFFFFFFFFL; - const nint y = unchecked((nint)x); - Console.WriteLine(y); - } -}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (7,24): error CS0133: The expression being assigned to 'y' must be constant - // const nint y = unchecked((nint)x); - Diagnostic(ErrorCode.ERR_NotConstantExpression, "unchecked((nint)x)").WithArguments("y").WithLocation(7, 24)); - - source = -@"using System; -class Program -{ - static void Main() - { - const long x = 0xFFFFFFFFFFFFFFFL; - nint y = unchecked((nint)x); - Console.WriteLine(y); - } -}"; - comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - CompileAndVerify(comp, expectedOutput: IntPtr.Size == 4 ? "-1" : "1152921504606846975"); - } - - [WorkItem(42955, "https://github.com/dotnet/roslyn/issues/42955")] - [WorkItem(45525, "https://github.com/dotnet/roslyn/issues/45525")] - [WorkItem(45531, "https://github.com/dotnet/roslyn/issues/45531")] - [Fact] - public void ConstantConversions_03() - { - using var _ = new EnsureInvariantCulture(); - - constantConversions("sbyte", "nint", "-1", null, "-1", "-1", null, "-1", "-1"); - constantConversions("sbyte", "nint", "sbyte.MinValue", null, "-128", "-128", null, "-128", "-128"); - constantConversions("sbyte", "nint", "sbyte.MaxValue", null, "127", "127", null, "127", "127"); - constantConversions("byte", "nint", "byte.MaxValue", null, "255", "255", null, "255", "255"); - constantConversions("short", "nint", "-1", null, "-1", "-1", null, "-1", "-1"); - constantConversions("short", "nint", "short.MinValue", null, "-32768", "-32768", null, "-32768", "-32768"); - constantConversions("short", "nint", "short.MaxValue", null, "32767", "32767", null, "32767", "32767"); - constantConversions("ushort", "nint", "ushort.MaxValue", null, "65535", "65535", null, "65535", "65535"); - constantConversions("char", "nint", "char.MaxValue", null, "65535", "65535", null, "65535", "65535"); - constantConversions("int", "nint", "int.MinValue", null, "-2147483648", "-2147483648", null, "-2147483648", "-2147483648"); - constantConversions("int", "nint", "int.MaxValue", null, "2147483647", "2147483647", null, "2147483647", "2147483647"); - constantConversions("uint", "nint", "(int.MaxValue + 1U)", warningOutOfRangeChecked("nint", "2147483648"), "System.OverflowException", "2147483648", null, "-2147483648", "2147483648"); - constantConversions("uint", "nint", "uint.MaxValue", warningOutOfRangeChecked("nint", "4294967295"), "System.OverflowException", "4294967295", null, "-1", "4294967295"); - constantConversions("long", "nint", "(int.MinValue - 1L)", warningOutOfRangeChecked("nint", "-2147483649"), "System.OverflowException", "-2147483649", null, "2147483647", "-2147483649"); - constantConversions("long", "nint", "(int.MaxValue + 1L)", warningOutOfRangeChecked("nint", "2147483648"), "System.OverflowException", "2147483648", null, "-2147483648", "2147483648"); - constantConversions("long", "nint", "long.MinValue", warningOutOfRangeChecked("nint", "-9223372036854775808"), "System.OverflowException", "-9223372036854775808", null, "0", "-9223372036854775808"); - constantConversions("long", "nint", "long.MaxValue", warningOutOfRangeChecked("nint", "9223372036854775807"), "System.OverflowException", "9223372036854775807", null, "-1", "9223372036854775807"); - constantConversions("ulong", "nint", "(int.MaxValue + 1UL)", warningOutOfRangeChecked("nint", "2147483648"), "System.OverflowException", "2147483648", null, "-2147483648", "2147483648"); - constantConversions("ulong", "nint", "ulong.MaxValue", errorOutOfRangeChecked("nint", "18446744073709551615"), "System.OverflowException", "System.OverflowException", null, "-1", "-1"); - constantConversions("decimal", "nint", "(int.MinValue - 1M)", errorOutOfRange("nint", "-2147483649M"), "System.OverflowException", "-2147483649", errorOutOfRange("nint", "-2147483649M"), "2147483647", "-2147483649"); - constantConversions("decimal", "nint", "(int.MaxValue + 1M)", errorOutOfRange("nint", "2147483648M"), "System.OverflowException", "2147483648", errorOutOfRange("nint", "2147483648M"), "-2147483648", "2147483648"); - constantConversions("decimal", "nint", "decimal.MinValue", errorOutOfRange("nint", "-79228162514264337593543950335M"), "System.OverflowException", "System.OverflowException", errorOutOfRange("nint", "-79228162514264337593543950335M"), "-1", "-1"); - constantConversions("decimal", "nint", "decimal.MaxValue", errorOutOfRange("nint", "79228162514264337593543950335M"), "System.OverflowException", "System.OverflowException", errorOutOfRange("nint", "79228162514264337593543950335M"), "-1", "-1"); - constantConversions("nint", "nint", "int.MinValue", null, "-2147483648", "-2147483648", null, "-2147483648", "-2147483648"); - constantConversions("nint", "nint", "int.MaxValue", null, "2147483647", "2147483647", null, "2147483647", "2147483647"); - constantConversions("nuint", "nint", "(int.MaxValue + (nuint)1)", warningOutOfRangeChecked("nint", "2147483648"), "System.OverflowException", "2147483648", null, "-2147483648", "2147483648"); - constantConversions("sbyte", "nuint", "-1", errorOutOfRangeChecked("nuint", "-1"), "System.OverflowException", "System.OverflowException", null, "4294967295", "18446744073709551615"); - constantConversions("sbyte", "nuint", "sbyte.MinValue", errorOutOfRangeChecked("nuint", "-128"), "System.OverflowException", "System.OverflowException", null, "4294967168", "18446744073709551488"); - constantConversions("sbyte", "nuint", "sbyte.MaxValue", null, "127", "127", null, "127", "127"); - constantConversions("byte", "nuint", "byte.MaxValue", null, "255", "255", null, "255", "255"); - constantConversions("short", "nuint", "-1", errorOutOfRangeChecked("nuint", "-1"), "System.OverflowException", "System.OverflowException", null, "4294967295", "18446744073709551615"); - constantConversions("short", "nuint", "short.MinValue", errorOutOfRangeChecked("nuint", "-32768"), "System.OverflowException", "System.OverflowException", null, "4294934528", "18446744073709518848"); - constantConversions("short", "nuint", "short.MaxValue", null, "32767", "32767", null, "32767", "32767"); - constantConversions("ushort", "nuint", "ushort.MaxValue", null, "65535", "65535", null, "65535", "65535"); - constantConversions("char", "nuint", "char.MaxValue", null, "65535", "65535", null, "65535", "65535"); - constantConversions("int", "nuint", "-1", errorOutOfRangeChecked("nuint", "-1"), "System.OverflowException", "System.OverflowException", null, "4294967295", "18446744073709551615"); - constantConversions("int", "nuint", "int.MinValue", errorOutOfRangeChecked("nuint", "-2147483648"), "System.OverflowException", "System.OverflowException", null, "2147483648", "18446744071562067968"); - constantConversions("int", "nuint", "int.MaxValue", null, "2147483647", "2147483647", null, "2147483647", "2147483647"); - constantConversions("uint", "nuint", "uint.MaxValue", null, "4294967295", "4294967295", null, "4294967295", "4294967295"); - constantConversions("long", "nuint", "-1", errorOutOfRangeChecked("nuint", "-1"), "System.OverflowException", "System.OverflowException", null, "4294967295", "18446744073709551615"); - constantConversions("long", "nuint", "uint.MaxValue + 1L", warningOutOfRangeChecked("nuint", "4294967296"), "System.OverflowException", "4294967296", null, "0", "4294967296"); - constantConversions("long", "nuint", "long.MinValue", errorOutOfRangeChecked("nuint", "-9223372036854775808"), "System.OverflowException", "System.OverflowException", null, "0", "9223372036854775808"); - constantConversions("long", "nuint", "long.MaxValue", warningOutOfRangeChecked("nuint", "9223372036854775807"), "System.OverflowException", "9223372036854775807", null, "4294967295", "9223372036854775807"); - constantConversions("ulong", "nuint", "uint.MaxValue + 1UL", warningOutOfRangeChecked("nuint", "4294967296"), "System.OverflowException", "4294967296", null, "0", "4294967296"); - constantConversions("ulong", "nuint", "ulong.MaxValue", warningOutOfRangeChecked("nuint", "18446744073709551615"), "System.OverflowException", "18446744073709551615", null, "4294967295", "18446744073709551615"); - constantConversions("decimal", "nuint", "-1", errorOutOfRange("nuint", "-1M"), "System.OverflowException", "System.OverflowException", errorOutOfRange("nuint", "-1M"), "System.OverflowException", "System.OverflowException"); - constantConversions("decimal", "nuint", "(uint.MaxValue + 1M)", errorOutOfRange("nuint", "4294967296M"), "System.OverflowException", "4294967296", errorOutOfRange("nuint", "4294967296M"), "-1", "4294967296"); - constantConversions("decimal", "nuint", "decimal.MinValue", errorOutOfRange("nuint", "-79228162514264337593543950335M"), "System.OverflowException", "System.OverflowException", errorOutOfRange("nuint", "-79228162514264337593543950335M"), "-1", "-1"); - constantConversions("decimal", "nuint", "decimal.MaxValue", errorOutOfRange("nuint", "79228162514264337593543950335M"), "System.OverflowException", "System.OverflowException", errorOutOfRange("nuint", "79228162514264337593543950335M"), "-1", "-1"); - constantConversions("nint", "nuint", "-1", errorOutOfRangeChecked("nuint", "-1"), "System.OverflowException", "System.OverflowException", null, "4294967295", "18446744073709551615"); - constantConversions("nuint", "nuint", "uint.MaxValue", null, "4294967295", "4294967295", null, "4294967295", "4294967295"); - if (!ExecutionConditionUtil.IsWindowsDesktop) - { - // There are differences in floating point precision across platforms - // so floating point tests are limited to one platform. - return; - } - constantConversions("float", "nint", "(int.MinValue - 10000F)", warningOutOfRangeChecked("nint", "-2.147494E+09"), "System.OverflowException", "-2147493632", null, "-2147483648", "-2147493632"); - constantConversions("float", "nint", "(int.MaxValue + 10000F)", warningOutOfRangeChecked("nint", "2.147494E+09"), "System.OverflowException", "2147493632", null, "-2147483648", "2147493632"); - constantConversions("float", "nint", "float.MinValue", errorOutOfRangeChecked("nint", "-3.402823E+38"), "System.OverflowException", "System.OverflowException", null, "-2147483648", "-9223372036854775808"); - constantConversions("float", "nint", "float.MaxValue", errorOutOfRangeChecked("nint", "3.402823E+38"), "System.OverflowException", "System.OverflowException", null, "-2147483648", "-9223372036854775808"); - constantConversions("double", "nint", "(int.MinValue - 1D)", warningOutOfRangeChecked("nint", "-2147483649"), "System.OverflowException", "-2147483649", null, "-2147483648", "-2147483649"); - constantConversions("double", "nint", "(int.MaxValue + 1D)", warningOutOfRangeChecked("nint", "2147483648"), "System.OverflowException", "2147483648", null, "-2147483648", "2147483648"); - constantConversions("double", "nint", "double.MinValue", errorOutOfRangeChecked("nint", "-1.79769313486232E+308"), "System.OverflowException", "System.OverflowException", null, "-2147483648", "-9223372036854775808"); - constantConversions("double", "nint", "double.MaxValue", errorOutOfRangeChecked("nint", "1.79769313486232E+308"), "System.OverflowException", "System.OverflowException", null, "-2147483648", "-9223372036854775808"); - constantConversions("float", "nuint", "-1", errorOutOfRangeChecked("nuint", "-1"), "System.OverflowException", "System.OverflowException", null, "4294967295", "18446744073709551615"); - constantConversions("float", "nuint", "(uint.MaxValue + 1F)", warningOutOfRangeChecked("nuint", "4.294967E+09"), "System.OverflowException", "4294967296", null, "0", "4294967296"); - constantConversions("float", "nuint", "float.MinValue", errorOutOfRangeChecked("nuint", "-3.402823E+38"), "System.OverflowException", "System.OverflowException", null, "0", "9223372036854775808"); - constantConversions("float", "nuint", "float.MaxValue", errorOutOfRangeChecked("nuint", "3.402823E+38"), "System.OverflowException", "System.OverflowException", null, "0", "0"); - constantConversions("double", "nuint", "-1", errorOutOfRangeChecked("nuint", "-1"), "System.OverflowException", "System.OverflowException", null, "4294967295", "18446744073709551615"); - constantConversions("double", "nuint", "(uint.MaxValue + 1D)", warningOutOfRangeChecked("nuint", "4294967296"), "System.OverflowException", "4294967296", null, "0", "4294967296"); - constantConversions("double", "nuint", "double.MinValue", errorOutOfRangeChecked("nuint", "-1.79769313486232E+308"), "System.OverflowException", "System.OverflowException", null, "0", "9223372036854775808"); - constantConversions("double", "nuint", "double.MaxValue", errorOutOfRangeChecked("nuint", "1.79769313486232E+308"), "System.OverflowException", "System.OverflowException", null, "0", "0"); - - static DiagnosticDescription errorOutOfRangeChecked(string destinationType, string value) => Diagnostic(ErrorCode.ERR_ConstOutOfRangeChecked, $"({destinationType})x").WithArguments(value, destinationType); - static DiagnosticDescription errorOutOfRange(string destinationType, string value) => Diagnostic(ErrorCode.ERR_ConstOutOfRange, $"({destinationType})x").WithArguments(value, destinationType); - static DiagnosticDescription warningOutOfRangeChecked(string destinationType, string value) => Diagnostic(ErrorCode.WRN_ConstOutOfRangeChecked, $"({destinationType})x").WithArguments(value, destinationType); - - void constantConversions(string sourceType, string destinationType, string sourceValue, DiagnosticDescription checkedError, string checked32, string checked64, DiagnosticDescription uncheckedError, string unchecked32, string unchecked64) - { - constantConversion(sourceType, destinationType, sourceValue, useChecked: true, checkedError, IntPtr.Size == 4 ? checked32 : checked64); - constantConversion(sourceType, destinationType, sourceValue, useChecked: false, uncheckedError, IntPtr.Size == 4 ? unchecked32 : unchecked64); - } - - void constantConversion(string sourceType, string destinationType, string sourceValue, bool useChecked, DiagnosticDescription expectedError, string expectedOutput) - { - var source = -$@"using System; -class Program -{{ - static void Main() - {{ - const {sourceType} x = {sourceValue}; - object y; - try - {{ - y = {(useChecked ? "checked" : "unchecked")}(({destinationType})x); - }} - catch (Exception e) - {{ - y = e.GetType(); - }} - Console.Write(y); - }} -}}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(expectedError is null ? Array.Empty() : new[] { expectedError }); - if (expectedError == null || ErrorFacts.IsWarning((ErrorCode)expectedError.Code)) - { - CompileAndVerify(comp, expectedOutput: expectedOutput); - } - } - } - - [Fact] - public void Constants_NInt() - { - string source = -$@"class Program -{{ - static void Main() - {{ - F(default); - F(int.MinValue); - F({short.MinValue - 1}); - F(short.MinValue); - F(sbyte.MinValue); - F(-2); - F(-1); - F(0); - F(1); - F(2); - F(3); - F(4); - F(5); - F(6); - F(7); - F(8); - F(9); - F(sbyte.MaxValue); - F(byte.MaxValue); - F(short.MaxValue); - F(char.MaxValue); - F(ushort.MaxValue); - F({ushort.MaxValue + 1}); - F(int.MaxValue); - }} - static void F(nint n) - {{ - System.Console.WriteLine(n); - }} -}}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - string expectedOutput = -@"0 --2147483648 --32769 --32768 --128 --2 --1 -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -127 -255 -32767 -65535 -65535 -65536 -2147483647"; - var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput); - string expectedIL = -@"{ - // Code size 209 (0xd1) - .maxstack 1 - IL_0000: ldc.i4.0 - IL_0001: conv.i - IL_0002: call ""void Program.F(nint)"" - IL_0007: ldc.i4 0x80000000 - IL_000c: conv.i - IL_000d: call ""void Program.F(nint)"" - IL_0012: ldc.i4 0xffff7fff - IL_0017: conv.i - IL_0018: call ""void Program.F(nint)"" - IL_001d: ldc.i4 0xffff8000 - IL_0022: conv.i - IL_0023: call ""void Program.F(nint)"" - IL_0028: ldc.i4.s -128 - IL_002a: conv.i - IL_002b: call ""void Program.F(nint)"" - IL_0030: ldc.i4.s -2 - IL_0032: conv.i - IL_0033: call ""void Program.F(nint)"" - IL_0038: ldc.i4.m1 - IL_0039: conv.i - IL_003a: call ""void Program.F(nint)"" - IL_003f: ldc.i4.0 - IL_0040: conv.i - IL_0041: call ""void Program.F(nint)"" - IL_0046: ldc.i4.1 - IL_0047: conv.i - IL_0048: call ""void Program.F(nint)"" - IL_004d: ldc.i4.2 - IL_004e: conv.i - IL_004f: call ""void Program.F(nint)"" - IL_0054: ldc.i4.3 - IL_0055: conv.i - IL_0056: call ""void Program.F(nint)"" - IL_005b: ldc.i4.4 - IL_005c: conv.i - IL_005d: call ""void Program.F(nint)"" - IL_0062: ldc.i4.5 - IL_0063: conv.i - IL_0064: call ""void Program.F(nint)"" - IL_0069: ldc.i4.6 - IL_006a: conv.i - IL_006b: call ""void Program.F(nint)"" - IL_0070: ldc.i4.7 - IL_0071: conv.i - IL_0072: call ""void Program.F(nint)"" - IL_0077: ldc.i4.8 - IL_0078: conv.i - IL_0079: call ""void Program.F(nint)"" - IL_007e: ldc.i4.s 9 - IL_0080: conv.i - IL_0081: call ""void Program.F(nint)"" - IL_0086: ldc.i4.s 127 - IL_0088: conv.i - IL_0089: call ""void Program.F(nint)"" - IL_008e: ldc.i4 0xff - IL_0093: conv.i - IL_0094: call ""void Program.F(nint)"" - IL_0099: ldc.i4 0x7fff - IL_009e: conv.i - IL_009f: call ""void Program.F(nint)"" - IL_00a4: ldc.i4 0xffff - IL_00a9: conv.i - IL_00aa: call ""void Program.F(nint)"" - IL_00af: ldc.i4 0xffff - IL_00b4: conv.i - IL_00b5: call ""void Program.F(nint)"" - IL_00ba: ldc.i4 0x10000 - IL_00bf: conv.i - IL_00c0: call ""void Program.F(nint)"" - IL_00c5: ldc.i4 0x7fffffff - IL_00ca: conv.i - IL_00cb: call ""void Program.F(nint)"" - IL_00d0: ret -}"; - verifier.VerifyIL("Program.Main", expectedIL); - } - - [Fact] - public void Constants_NUInt() - { - string source = -$@"class Program -{{ - static void Main() - {{ - F(default); - F(0); - F(1); - F(2); - F(3); - F(4); - F(5); - F(6); - F(7); - F(8); - F(9); - F(byte.MaxValue); - F(char.MaxValue); - F(ushort.MaxValue); - F(int.MaxValue); - F({(uint)int.MaxValue + 1}); - F(uint.MaxValue); - }} - static void F(nuint n) - {{ - System.Console.WriteLine(n); - }} -}}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - string expectedOutput = -@"0 -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -255 -65535 -65535 -2147483647 -2147483648 -4294967295"; - var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput); - string expectedIL = -@"{ - // Code size 141 (0x8d) - .maxstack 1 - IL_0000: ldc.i4.0 - IL_0001: conv.i - IL_0002: call ""void Program.F(nuint)"" - IL_0007: ldc.i4.0 - IL_0008: conv.i - IL_0009: call ""void Program.F(nuint)"" - IL_000e: ldc.i4.1 - IL_000f: conv.i - IL_0010: call ""void Program.F(nuint)"" - IL_0015: ldc.i4.2 - IL_0016: conv.i - IL_0017: call ""void Program.F(nuint)"" - IL_001c: ldc.i4.3 - IL_001d: conv.i - IL_001e: call ""void Program.F(nuint)"" - IL_0023: ldc.i4.4 - IL_0024: conv.i - IL_0025: call ""void Program.F(nuint)"" - IL_002a: ldc.i4.5 - IL_002b: conv.i - IL_002c: call ""void Program.F(nuint)"" - IL_0031: ldc.i4.6 - IL_0032: conv.i - IL_0033: call ""void Program.F(nuint)"" - IL_0038: ldc.i4.7 - IL_0039: conv.i - IL_003a: call ""void Program.F(nuint)"" - IL_003f: ldc.i4.8 - IL_0040: conv.i - IL_0041: call ""void Program.F(nuint)"" - IL_0046: ldc.i4.s 9 - IL_0048: conv.i - IL_0049: call ""void Program.F(nuint)"" - IL_004e: ldc.i4 0xff - IL_0053: conv.i - IL_0054: call ""void Program.F(nuint)"" - IL_0059: ldc.i4 0xffff - IL_005e: conv.i - IL_005f: call ""void Program.F(nuint)"" - IL_0064: ldc.i4 0xffff - IL_0069: conv.i - IL_006a: call ""void Program.F(nuint)"" - IL_006f: ldc.i4 0x7fffffff - IL_0074: conv.i - IL_0075: call ""void Program.F(nuint)"" - IL_007a: ldc.i4 0x80000000 - IL_007f: conv.u - IL_0080: call ""void Program.F(nuint)"" - IL_0085: ldc.i4.m1 - IL_0086: conv.u - IL_0087: call ""void Program.F(nuint)"" - IL_008c: ret -}"; - verifier.VerifyIL("Program.Main", expectedIL); - } - - [Fact] - public void Constants_ConvertToUnsigned() - { - string source = -@"class Program -{ - static void Main() - { - F(sbyte.MaxValue); - F(short.MaxValue); - F(int.MaxValue); - F(long.MaxValue); - F(sbyte.MaxValue); - F(short.MaxValue); - F(int.MaxValue); - F(long.MaxValue); - F(sbyte.MaxValue); - F(short.MaxValue); - F(int.MaxValue); - F(long.MaxValue); - F(sbyte.MaxValue); - F(short.MaxValue); - F(int.MaxValue); - F(long.MaxValue); - } - static void F(T n) - { - } -}"; - var comp = CreateCompilation(source); - comp.VerifyDiagnostics( - // (5,19): error CS1503: Argument 1: cannot convert from 'sbyte' to 'ushort' - // F(sbyte.MaxValue); - Diagnostic(ErrorCode.ERR_BadArgType, "sbyte.MaxValue").WithArguments("1", "sbyte", "ushort").WithLocation(5, 19), - // (6,19): error CS1503: Argument 1: cannot convert from 'short' to 'ushort' - // F(short.MaxValue); - Diagnostic(ErrorCode.ERR_BadArgType, "short.MaxValue").WithArguments("1", "short", "ushort").WithLocation(6, 19), - // (7,19): error CS1503: Argument 1: cannot convert from 'int' to 'ushort' - // F(int.MaxValue); - Diagnostic(ErrorCode.ERR_BadArgType, "int.MaxValue").WithArguments("1", "int", "ushort").WithLocation(7, 19), - // (8,19): error CS1503: Argument 1: cannot convert from 'long' to 'ushort' - // F(long.MaxValue); - Diagnostic(ErrorCode.ERR_BadArgType, "long.MaxValue").WithArguments("1", "long", "ushort").WithLocation(8, 19), - // (9,17): error CS1503: Argument 1: cannot convert from 'sbyte' to 'uint' - // F(sbyte.MaxValue); - Diagnostic(ErrorCode.ERR_BadArgType, "sbyte.MaxValue").WithArguments("1", "sbyte", "uint").WithLocation(9, 17), - // (10,17): error CS1503: Argument 1: cannot convert from 'short' to 'uint' - // F(short.MaxValue); - Diagnostic(ErrorCode.ERR_BadArgType, "short.MaxValue").WithArguments("1", "short", "uint").WithLocation(10, 17), - // (12,17): error CS1503: Argument 1: cannot convert from 'long' to 'uint' - // F(long.MaxValue); - Diagnostic(ErrorCode.ERR_BadArgType, "long.MaxValue").WithArguments("1", "long", "uint").WithLocation(12, 17), - // (13,18): error CS1503: Argument 1: cannot convert from 'sbyte' to 'nuint' - // F(sbyte.MaxValue); - Diagnostic(ErrorCode.ERR_BadArgType, "sbyte.MaxValue").WithArguments("1", "sbyte", "nuint").WithLocation(13, 18), - // (14,18): error CS1503: Argument 1: cannot convert from 'short' to 'nuint' - // F(short.MaxValue); - Diagnostic(ErrorCode.ERR_BadArgType, "short.MaxValue").WithArguments("1", "short", "nuint").WithLocation(14, 18), - // (16,18): error CS1503: Argument 1: cannot convert from 'long' to 'nuint' - // F(long.MaxValue); - Diagnostic(ErrorCode.ERR_BadArgType, "long.MaxValue").WithArguments("1", "long", "nuint").WithLocation(16, 18), - // (17,18): error CS1503: Argument 1: cannot convert from 'sbyte' to 'ulong' - // F(sbyte.MaxValue); - Diagnostic(ErrorCode.ERR_BadArgType, "sbyte.MaxValue").WithArguments("1", "sbyte", "ulong").WithLocation(17, 18), - // (18,18): error CS1503: Argument 1: cannot convert from 'short' to 'ulong' - // F(short.MaxValue); - Diagnostic(ErrorCode.ERR_BadArgType, "short.MaxValue").WithArguments("1", "short", "ulong").WithLocation(18, 18)); - } - - [Fact] - public void Constants_Locals() - { - var source = -@"#pragma warning disable 219 -class Program -{ - static void Main() - { - const System.IntPtr a = default; - const nint b = default; - const System.UIntPtr c = default; - const nuint d = default; - } -}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (6,15): error CS0283: The type 'IntPtr' cannot be declared const - // const System.IntPtr a = default; - Diagnostic(ErrorCode.ERR_BadConstType, "System.IntPtr").WithArguments("System.IntPtr").WithLocation(6, 15), - // (8,15): error CS0283: The type 'UIntPtr' cannot be declared const - // const System.UIntPtr c = default; - Diagnostic(ErrorCode.ERR_BadConstType, "System.UIntPtr").WithArguments("System.UIntPtr").WithLocation(8, 15)); - } - - [Fact] - public void Constants_Fields_01() - { - var source = -@"class Program -{ - const System.IntPtr A = default(System.IntPtr); - const nint B = default(nint); - const System.UIntPtr C = default(System.UIntPtr); - const nuint D = default(nuint); -}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (3,5): error CS0283: The type 'IntPtr' cannot be declared const - // const System.IntPtr A = default(System.IntPtr); - Diagnostic(ErrorCode.ERR_BadConstType, "const").WithArguments("System.IntPtr").WithLocation(3, 5), - // (3,29): error CS0133: The expression being assigned to 'Program.A' must be constant - // const System.IntPtr A = default(System.IntPtr); - Diagnostic(ErrorCode.ERR_NotConstantExpression, "default(System.IntPtr)").WithArguments("Program.A").WithLocation(3, 29), - // (5,5): error CS0283: The type 'UIntPtr' cannot be declared const - // const System.UIntPtr C = default(System.UIntPtr); - Diagnostic(ErrorCode.ERR_BadConstType, "const").WithArguments("System.UIntPtr").WithLocation(5, 5), - // (5,30): error CS0133: The expression being assigned to 'Program.C' must be constant - // const System.UIntPtr C = default(System.UIntPtr); - Diagnostic(ErrorCode.ERR_NotConstantExpression, "default(System.UIntPtr)").WithArguments("Program.C").WithLocation(5, 30)); - } - - [Fact] - public void Constants_Fields_02() - { - var source0 = -@"public class A -{ - public const nint C1 = -42; - public const nuint C2 = 42; -}"; - var comp = CreateCompilation(source0, parseOptions: TestOptions.Regular9); - var ref0 = comp.EmitToImageReference(); - var source1 = -@"using System; -class B -{ - static void Main() - { - Console.WriteLine(A.C1); - Console.WriteLine(A.C2); - } -}"; - comp = CreateCompilation(source1, references: new[] { ref0 }, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe); - CompileAndVerify(comp, expectedOutput: -@"-42 -42"); - } - - [Fact] - public void Constants_ParameterDefaults() - { - var source0 = -@"public class A -{ - public static System.IntPtr F1(System.IntPtr i = default) => i; - public static nint F2(nint i = -42) => i; - public static System.UIntPtr F3(System.UIntPtr u = default) => u; - public static nuint F4(nuint u = 42) => u; -}"; - var comp = CreateCompilation(source0, parseOptions: TestOptions.Regular9); - var ref0 = comp.EmitToImageReference(); - var source1 = -@"using System; -class B -{ - static void Main() - { - Console.WriteLine(A.F1()); - Console.WriteLine(A.F2()); - Console.WriteLine(A.F3()); - Console.WriteLine(A.F4()); - } -}"; - comp = CreateCompilation(source1, references: new[] { ref0 }, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe); - CompileAndVerify(comp, expectedOutput: -@"0 --42 -0 -42"); - } - - [Fact] - public void Constants_FromMetadata() - { - var source0 = -@"public class Constants -{ - public const nint NIntMin = int.MinValue; - public const nint NIntMax = int.MaxValue; - public const nuint NUIntMin = uint.MinValue; - public const nuint NUIntMax = uint.MaxValue; -}"; - var comp = CreateCompilation(source0, parseOptions: TestOptions.Regular9); - var ref0 = comp.EmitToImageReference(); - - var source1 = -@"using System; -class Program -{ - static void Main() - { - const nint nintMin = Constants.NIntMin; - const nint nintMax = Constants.NIntMax; - const nuint nuintMin = Constants.NUIntMin; - const nuint nuintMax = Constants.NUIntMax; - Console.WriteLine(nintMin); - Console.WriteLine(nintMax); - Console.WriteLine(nuintMin); - Console.WriteLine(nuintMax); - } -}"; - comp = CreateCompilation(source1, references: new[] { ref0 }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - CompileAndVerify(comp, expectedOutput: -@"-2147483648 -2147483647 -0 -4294967295"); - } - - [Fact] - public void ConstantValue_Properties() - { - var source = -@"class Program -{ - const nint A = int.MinValue; - const nint B = 0; - const nint C = int.MaxValue; - const nuint D = 0; - const nuint E = uint.MaxValue; -}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - verify((FieldSymbol)comp.GetMember("Program.A"), int.MinValue, signed: true, negative: true); - verify((FieldSymbol)comp.GetMember("Program.B"), 0, signed: true, negative: false); - verify((FieldSymbol)comp.GetMember("Program.C"), int.MaxValue, signed: true, negative: false); - verify((FieldSymbol)comp.GetMember("Program.D"), 0U, signed: false, negative: false); - verify((FieldSymbol)comp.GetMember("Program.E"), uint.MaxValue, signed: false, negative: false); - - static void verify(FieldSymbol field, object expectedValue, bool signed, bool negative) - { - var value = field.GetConstantValue(ConstantFieldsInProgress.Empty, earlyDecodingWellKnownAttributes: false); - Assert.Equal(signed ? ConstantValueTypeDiscriminator.NInt : ConstantValueTypeDiscriminator.NUInt, value.Discriminator); - Assert.Equal(expectedValue, value.Value); - Assert.True(value.IsIntegral); - Assert.True(value.IsNumeric); - Assert.Equal(negative, value.IsNegativeNumeric); - Assert.Equal(!signed, value.IsUnsigned); - } - } - - /// - /// Native integers cannot be used as attribute values. - /// - [Fact] - public void AttributeValue_01() - { - var source0 = -@"class A : System.Attribute -{ - public A() { } - public A(object value) { } - public object Value; -} -[A((nint)1)] -[A(new nuint[0])] -[A(Value = (nint)3)] -[A(Value = new[] { (nuint)4 })] -class B -{ -}"; - var comp = CreateCompilation(source0, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (7,4): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type - // [A((nint)1)] - Diagnostic(ErrorCode.ERR_BadAttributeArgument, "(nint)1").WithLocation(7, 4), - // (8,4): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type - // [A(new nuint[0])] - Diagnostic(ErrorCode.ERR_BadAttributeArgument, "new nuint[0]").WithLocation(8, 4), - // (9,12): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type - // [A(Value = (nint)3)] - Diagnostic(ErrorCode.ERR_BadAttributeArgument, "(nint)3").WithLocation(9, 12), - // (10,12): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type - // [A(Value = new[] { (nuint)4 })] - Diagnostic(ErrorCode.ERR_BadAttributeArgument, "new[] { (nuint)4 }").WithLocation(10, 12)); - } - - /// - /// Native integers cannot be used as attribute values. - /// - [Fact] - public void AttributeValue_02() - { - var source0 = -@"class A : System.Attribute -{ - public A() { } - public A(nint value) { } - public nuint[] Value; -} -[A(1)] -[A(Value = default)] -class B -{ -}"; - var comp = CreateCompilation(source0, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (7,2): error CS0181: Attribute constructor parameter 'value' has type 'nint', which is not a valid attribute parameter type - // [A(1)] - Diagnostic(ErrorCode.ERR_BadAttributeParamType, "A").WithArguments("value", "nint").WithLocation(7, 2), - // (8,4): error CS0655: 'Value' is not a valid named attribute argument because it is not a valid attribute parameter type - // [A(Value = default)] - Diagnostic(ErrorCode.ERR_BadNamedAttributeArgumentType, "Value").WithArguments("Value").WithLocation(8, 4)); - } - - [Fact] - public void ParameterDefaultValue_01() - { - var source = -@"using System; -class A -{ - static void F0(IntPtr x = default, UIntPtr y = default) - { - } - static void F1(IntPtr x = (IntPtr)(-1), UIntPtr y = (UIntPtr)2) - { - } - static void F2(IntPtr? x = null, UIntPtr? y = null) - { - } - static void F3(IntPtr? x = (IntPtr)(-3), UIntPtr? y = (UIntPtr)4) - { - } -}"; - var comp = CreateCompilation(source); - comp.VerifyDiagnostics( - // (7,31): error CS1736: Default parameter value for 'x' must be a compile-time constant - // static void F1(IntPtr x = (IntPtr)(-1), UIntPtr y = (UIntPtr)2) - Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "(IntPtr)(-1)").WithArguments("x").WithLocation(7, 31), - // (7,57): error CS1736: Default parameter value for 'y' must be a compile-time constant - // static void F1(IntPtr x = (IntPtr)(-1), UIntPtr y = (UIntPtr)2) - Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "(UIntPtr)2").WithArguments("y").WithLocation(7, 57), - // (13,32): error CS1736: Default parameter value for 'x' must be a compile-time constant - // static void F3(IntPtr? x = (IntPtr)(-3), UIntPtr? y = (UIntPtr)4) - Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "(IntPtr)(-3)").WithArguments("x").WithLocation(13, 32), - // (13,59): error CS1736: Default parameter value for 'y' must be a compile-time constant - // static void F3(IntPtr? x = (IntPtr)(-3), UIntPtr? y = (UIntPtr)4) - Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "(UIntPtr)4").WithArguments("y").WithLocation(13, 59)); - } - - [Fact] - public void ParameterDefaultValue_02() - { - var sourceA = -@"public class A -{ - public static void F0(nint x = default, nuint y = default) - { - Report(x); - Report(y); - } - public static void F1(nint x = -1, nuint y = 2) - { - Report(x); - Report(y); - } - public static void F2(nint? x = null, nuint? y = null) - { - Report(x); - Report(y); - } - public static void F3(nint? x = -3, nuint? y = 4) - { - Report(x); - Report(y); - } - static void Report(object o) - { - System.Console.WriteLine(o ?? ""null""); - } -}"; - var sourceB = -@"class B -{ - static void Main() - { - A.F0(); - A.F1(); - A.F2(); - A.F3(); - } -}"; - var expectedOutput = -@"0 -0 --1 -2 -null -null --3 -4"; - - var comp = CreateCompilation(new[] { sourceA, sourceB }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - CompileAndVerify(comp, expectedOutput: expectedOutput); - - comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - var ref1 = comp.ToMetadataReference(); - var ref2 = comp.EmitToImageReference(); - - comp = CreateCompilation(sourceB, references: new[] { ref1 }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - CompileAndVerify(comp, expectedOutput: expectedOutput); - - comp = CreateCompilation(sourceB, references: new[] { ref2 }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - CompileAndVerify(comp, expectedOutput: expectedOutput); - - comp = CreateCompilation(sourceB, references: new[] { ref1 }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular8); - CompileAndVerify(comp, expectedOutput: expectedOutput); - - comp = CreateCompilation(sourceB, references: new[] { ref2 }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular8); - CompileAndVerify(comp, expectedOutput: expectedOutput); - } - - [Fact] - public void SwitchStatement_01() - { - var source = -@"using System; -class Program -{ - static nint M(nint ret) - { - switch (ret) { - case 0: - ret--; // 2 - Report(""case 0: "", ret); - goto case 9999; - case 2: - ret--; // 4 - Report(""case 2: "", ret); - goto case 255; - case 6: // start here - ret--; // 5 - Report(""case 6: "", ret); - goto case 2; - case 9999: - ret--; // 1 - Report(""case 9999: "", ret); - goto default; - case 0xff: - ret--; // 3 - Report(""case 0xff: "", ret); - goto case 0; - default: - ret--; - Report(""default: "", ret); - if (ret > 0) { - goto case -1; - } - break; - case -1: - ret = 999; - Report(""case -1: "", ret); - break; - } - return(ret); - } - static void Report(string prefix, nint value) - { - Console.WriteLine(prefix + value); - } - static void Main() - { - Console.WriteLine(M(6)); - } -}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - var verifier = CompileAndVerify(comp, expectedOutput: -@"case 6: 5 -case 2: 4 -case 0xff: 3 -case 0: 2 -case 9999: 1 -default: 0 -0"); - verifier.VerifyIL("Program.M", @" - { - // Code size 201 (0xc9) - .maxstack 3 - .locals init (long V_0) - IL_0000: ldarg.0 - IL_0001: conv.i8 - IL_0002: stloc.0 - IL_0003: ldloc.0 - IL_0004: ldc.i4.6 - IL_0005: conv.i8 - IL_0006: bgt.s IL_0031 - IL_0008: ldloc.0 - IL_0009: ldc.i4.m1 - IL_000a: conv.i8 - IL_000b: sub - IL_000c: dup - IL_000d: ldc.i4.3 - IL_000e: conv.i8 - IL_000f: ble.un.s IL_0014 - IL_0011: pop - IL_0012: br.s IL_002a - IL_0014: conv.u4 - IL_0015: switch ( - IL_00b4, - IL_0045, - IL_009f, - IL_0057) - IL_002a: ldloc.0 - IL_002b: ldc.i4.6 - IL_002c: conv.i8 - IL_002d: beq.s IL_0069 - IL_002f: br.s IL_009f - IL_0031: ldloc.0 - IL_0032: ldc.i4 0xff - IL_0037: conv.i8 - IL_0038: beq.s IL_008d - IL_003a: ldloc.0 - IL_003b: ldc.i4 0x270f - IL_0040: conv.i8 - IL_0041: beq.s IL_007b - IL_0043: br.s IL_009f - IL_0045: ldarg.0 - IL_0046: ldc.i4.1 - IL_0047: sub - IL_0048: starg.s V_0 - IL_004a: ldstr ""case 0: "" - IL_004f: ldarg.0 - IL_0050: call ""void Program.Report(string, nint)"" - IL_0055: br.s IL_007b - IL_0057: ldarg.0 - IL_0058: ldc.i4.1 - IL_0059: sub - IL_005a: starg.s V_0 - IL_005c: ldstr ""case 2: "" - IL_0061: ldarg.0 - IL_0062: call ""void Program.Report(string, nint)"" - IL_0067: br.s IL_008d - IL_0069: ldarg.0 - IL_006a: ldc.i4.1 - IL_006b: sub - IL_006c: starg.s V_0 - IL_006e: ldstr ""case 6: "" - IL_0073: ldarg.0 - IL_0074: call ""void Program.Report(string, nint)"" - IL_0079: br.s IL_0057 - IL_007b: ldarg.0 - IL_007c: ldc.i4.1 - IL_007d: sub - IL_007e: starg.s V_0 - IL_0080: ldstr ""case 9999: "" - IL_0085: ldarg.0 - IL_0086: call ""void Program.Report(string, nint)"" - IL_008b: br.s IL_009f - IL_008d: ldarg.0 - IL_008e: ldc.i4.1 - IL_008f: sub - IL_0090: starg.s V_0 - IL_0092: ldstr ""case 0xff: "" - IL_0097: ldarg.0 - IL_0098: call ""void Program.Report(string, nint)"" - IL_009d: br.s IL_0045 - IL_009f: ldarg.0 - IL_00a0: ldc.i4.1 - IL_00a1: sub - IL_00a2: starg.s V_0 - IL_00a4: ldstr ""default: "" - IL_00a9: ldarg.0 - IL_00aa: call ""void Program.Report(string, nint)"" - IL_00af: ldarg.0 - IL_00b0: ldc.i4.0 - IL_00b1: conv.i - IL_00b2: ble.s IL_00c7 - IL_00b4: ldc.i4 0x3e7 - IL_00b9: conv.i - IL_00ba: starg.s V_0 - IL_00bc: ldstr ""case -1: "" - IL_00c1: ldarg.0 - IL_00c2: call ""void Program.Report(string, nint)"" - IL_00c7: ldarg.0 - IL_00c8: ret - } -"); - } - - [Fact] - public void SwitchStatement_02() - { - var source = -@"using System; -class Program -{ - static nuint M(nuint ret) - { - switch (ret) { - case 0: - ret--; // 2 - Report(""case 0: "", ret); - goto case 9999; - case 2: - ret--; // 4 - Report(""case 2: "", ret); - goto case 255; - case 6: // start here - ret--; // 5 - Report(""case 6: "", ret); - goto case 2; - case 9999: - ret--; // 1 - Report(""case 9999: "", ret); - goto default; - case 0xff: - ret--; // 3 - Report(""case 0xff: "", ret); - goto case 0; - default: - ret--; - Report(""default: "", ret); - if (ret > 0) { - goto case int.MaxValue; - } - break; - case int.MaxValue: - ret = 999; - Report(""case int.MaxValue: "", ret); - break; - } - return(ret); - } - static void Report(string prefix, nuint value) - { - Console.WriteLine(prefix + value); - } - static void Main() - { - Console.WriteLine(M(6)); - } -}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - var verifier = CompileAndVerify(comp, expectedOutput: -@"case 6: 5 -case 2: 4 -case 0xff: 3 -case 0: 2 -case 9999: 1 -default: 0 -0"); - verifier.VerifyIL("Program.M", @" - { - // Code size 184 (0xb8) - .maxstack 2 - .locals init (ulong V_0) - IL_0000: ldarg.0 - IL_0001: conv.u8 - IL_0002: stloc.0 - IL_0003: ldloc.0 - IL_0004: ldc.i4.6 - IL_0005: conv.i8 - IL_0006: bgt.un.s IL_0017 - IL_0008: ldloc.0 - IL_0009: brfalse.s IL_0034 - IL_000b: ldloc.0 - IL_000c: ldc.i4.2 - IL_000d: conv.i8 - IL_000e: beq.s IL_0046 - IL_0010: ldloc.0 - IL_0011: ldc.i4.6 - IL_0012: conv.i8 - IL_0013: beq.s IL_0058 - IL_0015: br.s IL_008e - IL_0017: ldloc.0 - IL_0018: ldc.i4 0xff - IL_001d: conv.i8 - IL_001e: beq.s IL_007c - IL_0020: ldloc.0 - IL_0021: ldc.i4 0x270f - IL_0026: conv.i8 - IL_0027: beq.s IL_006a - IL_0029: ldloc.0 - IL_002a: ldc.i4 0x7fffffff - IL_002f: conv.i8 - IL_0030: beq.s IL_00a3 - IL_0032: br.s IL_008e - IL_0034: ldarg.0 - IL_0035: ldc.i4.1 - IL_0036: sub - IL_0037: starg.s V_0 - IL_0039: ldstr ""case 0: "" - IL_003e: ldarg.0 - IL_003f: call ""void Program.Report(string, nuint)"" - IL_0044: br.s IL_006a - IL_0046: ldarg.0 - IL_0047: ldc.i4.1 - IL_0048: sub - IL_0049: starg.s V_0 - IL_004b: ldstr ""case 2: "" - IL_0050: ldarg.0 - IL_0051: call ""void Program.Report(string, nuint)"" - IL_0056: br.s IL_007c - IL_0058: ldarg.0 - IL_0059: ldc.i4.1 - IL_005a: sub - IL_005b: starg.s V_0 - IL_005d: ldstr ""case 6: "" - IL_0062: ldarg.0 - IL_0063: call ""void Program.Report(string, nuint)"" - IL_0068: br.s IL_0046 - IL_006a: ldarg.0 - IL_006b: ldc.i4.1 - IL_006c: sub - IL_006d: starg.s V_0 - IL_006f: ldstr ""case 9999: "" - IL_0074: ldarg.0 - IL_0075: call ""void Program.Report(string, nuint)"" - IL_007a: br.s IL_008e - IL_007c: ldarg.0 - IL_007d: ldc.i4.1 - IL_007e: sub - IL_007f: starg.s V_0 - IL_0081: ldstr ""case 0xff: "" - IL_0086: ldarg.0 - IL_0087: call ""void Program.Report(string, nuint)"" - IL_008c: br.s IL_0034 - IL_008e: ldarg.0 - IL_008f: ldc.i4.1 - IL_0090: sub - IL_0091: starg.s V_0 - IL_0093: ldstr ""default: "" - IL_0098: ldarg.0 - IL_0099: call ""void Program.Report(string, nuint)"" - IL_009e: ldarg.0 - IL_009f: ldc.i4.0 - IL_00a0: conv.i - IL_00a1: ble.un.s IL_00b6 - IL_00a3: ldc.i4 0x3e7 - IL_00a8: conv.i - IL_00a9: starg.s V_0 - IL_00ab: ldstr ""case int.MaxValue: "" - IL_00b0: ldarg.0 - IL_00b1: call ""void Program.Report(string, nuint)"" - IL_00b6: ldarg.0 - IL_00b7: ret - } -"); - } + conversions(sourceType: "nuint?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i.un", "nuint")); + conversions(sourceType: "float?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "float"), expectedCheckedIL: convFromNullableT("conv.ovf.i", "float")); + conversions(sourceType: "double?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "double"), expectedCheckedIL: convFromNullableT("conv.ovf.i", "double")); + conversions(sourceType: "decimal?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, +@"{ + // Code size 14 (0xe) + .maxstack 1 + IL_0000: ldarga.s V_0 + IL_0002: call ""decimal decimal?.Value.get"" + IL_0007: call ""long decimal.op_Explicit(decimal)"" + IL_000c: conv.i + IL_000d: ret +}", +@"{ + // Code size 14 (0xe) + .maxstack 1 + IL_0000: ldarga.s V_0 + IL_0002: call ""decimal decimal?.Value.get"" + IL_0007: call ""long decimal.op_Explicit(decimal)"" + IL_000c: conv.ovf.i + IL_000d: ret +}"); + conversions(sourceType: "System.IntPtr?", destType: "nint", ExplicitNullableIdentity, expectedImplicitIL: null, +@"{ + // Code size 8 (0x8) + .maxstack 1 + IL_0000: ldarga.s V_0 + IL_0002: call ""nint nint?.Value.get"" + IL_0007: ret +}"); + conversions(sourceType: "System.UIntPtr?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i.un", "nuint")); - [Fact] - public void Conversions() - { - const string convNone = + // type to nullable nint + conversions(sourceType: "object", destType: "nint?", Unboxing, expectedImplicitIL: null, @"{ - // Code size 2 (0x2) + // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: ret -}"; - static string conv(string conversion) => -$@"{{ - // Code size 3 (0x3) + IL_0001: unbox.any ""nint?"" + IL_0006: ret +}"); + conversions(sourceType: "string", destType: "nint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "void*", destType: "nint?", ExplicitNullablePointerToInteger, expectedImplicitIL: null, +@"{ + // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: {conversion} - IL_0002: ret -}}"; - static string convFromNullableT(string conversion, string sourceType) => -$@"{{ - // Code size 9 (0x9) + IL_0001: newobj ""nint?..ctor(nint)"" + IL_0006: ret +}", +@"{ + // Code size 8 (0x8) .maxstack 1 - IL_0000: ldarga.s V_0 - IL_0002: call ""{sourceType} {sourceType}?.Value.get"" - IL_0007: {conversion} - IL_0008: ret -}}"; - static string convToNullableT(string conversion, string destType) => -$@"{{ + IL_0000: ldarg.0 + IL_0001: conv.ovf.i.un + IL_0002: newobj ""nint?..ctor(nint)"" + IL_0007: ret +}"); + conversions(sourceType: "delegate*", destType: "nint?", ExplicitNullablePointerToInteger, expectedImplicitIL: null, +@"{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: newobj ""nint?..ctor(nint)"" + IL_0006: ret +}", +@"{ // Code size 8 (0x8) .maxstack 1 IL_0000: ldarg.0 - IL_0001: {conversion} - IL_0002: newobj ""{destType}?..ctor({destType})"" + IL_0001: conv.ovf.i.un + IL_0002: newobj ""nint?..ctor(nint)"" IL_0007: ret -}}"; - static string convFromToNullableT(string conversion, string sourceType, string destType) => -$@"{{ - // Code size 35 (0x23) +}"); + conversions(sourceType: "E", destType: "nint?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint")); + conversions(sourceType: "bool", destType: "nint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "char", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nint"), expectedExplicitIL: convToNullableT("conv.u", "nint")); + conversions(sourceType: "sbyte", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.i", "nint"), expectedExplicitIL: convToNullableT("conv.i", "nint")); + conversions(sourceType: "byte", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nint"), expectedExplicitIL: convToNullableT("conv.u", "nint")); + conversions(sourceType: "short", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.i", "nint"), expectedExplicitIL: convToNullableT("conv.i", "nint")); + conversions(sourceType: "ushort", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nint"), expectedExplicitIL: convToNullableT("conv.u", "nint")); + conversions(sourceType: "int", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.i", "nint"), expectedExplicitIL: convToNullableT("conv.i", "nint")); + conversions(sourceType: "uint", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i.un", "nint")); + conversions(sourceType: "long", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i", "nint")); + conversions(sourceType: "ulong", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i.un", "nint")); + conversions(sourceType: "nint", destType: "nint?", ImplicitNullableIdentity, +@"{ + // Code size 7 (0x7) .maxstack 1 - .locals init ({sourceType}? V_0, - {destType}? V_1) + IL_0000: ldarg.0 + IL_0001: newobj ""nint?..ctor(nint)"" + IL_0006: ret +}", +@"{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: newobj ""nint?..ctor(nint)"" + IL_0006: ret +}"); + conversions(sourceType: "nuint", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i.un", "nint")); + conversions(sourceType: "float", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i", "nint")); + conversions(sourceType: "double", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i", "nint")); + conversions(sourceType: "decimal", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, +@"{ + // Code size 13 (0xd) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: call ""long decimal.op_Explicit(decimal)"" + IL_0006: conv.i + IL_0007: newobj ""nint?..ctor(nint)"" + IL_000c: ret +}", +@"{ + // Code size 13 (0xd) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: call ""long decimal.op_Explicit(decimal)"" + IL_0006: conv.ovf.i + IL_0007: newobj ""nint?..ctor(nint)"" + IL_000c: ret +}"); + conversions(sourceType: "System.IntPtr", destType: "nint?", ImplicitNullableIdentity, +@"{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: newobj ""nint?..ctor(nint)"" + IL_0006: ret +}", +@"{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: newobj ""nint?..ctor(nint)"" + IL_0006: ret +}"); + conversions(sourceType: "System.UIntPtr", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i.un", "nint")); + + // nullable type to nullable nint + conversions(sourceType: "E?", destType: "nint?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "E", "nint")); + conversions(sourceType: "bool?", destType: "nint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "char?", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "char", "nint"), expectedExplicitIL: convFromToNullableT("conv.u", "char", "nint")); + conversions(sourceType: "sbyte?", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.i", "sbyte", "nint"), expectedExplicitIL: convFromToNullableT("conv.i", "sbyte", "nint")); + conversions(sourceType: "byte?", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "byte", "nint"), expectedExplicitIL: convFromToNullableT("conv.u", "byte", "nint")); + conversions(sourceType: "short?", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.i", "short", "nint"), expectedExplicitIL: convFromToNullableT("conv.i", "short", "nint")); + conversions(sourceType: "ushort?", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "ushort", "nint"), expectedExplicitIL: convFromToNullableT("conv.u", "ushort", "nint")); + conversions(sourceType: "int?", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.i", "int", "nint"), expectedExplicitIL: convFromToNullableT("conv.i", "int", "nint")); + conversions(sourceType: "uint?", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "uint", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i.un", "uint", "nint")); + conversions(sourceType: "long?", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "long", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i", "long", "nint")); + conversions(sourceType: "ulong?", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "ulong", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i.un", "ulong", "nint")); + conversions(sourceType: "nint?", destType: "nint?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + conversions(sourceType: "nuint?", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "nuint", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i.un", "nuint", "nint")); + conversions(sourceType: "float?", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "float", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i", "float", "nint")); + conversions(sourceType: "double?", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "double", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i", "double", "nint")); + conversions(sourceType: "decimal?", destType: "nint?", ExplicitNullableNumeric, null, +@"{ + // Code size 40 (0x28) + .maxstack 1 + .locals init (decimal? V_0, + nint? V_1) IL_0000: ldarg.0 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: call ""bool {sourceType}?.HasValue.get"" + IL_0004: call ""bool decimal?.HasValue.get"" IL_0009: brtrue.s IL_0015 IL_000b: ldloca.s V_1 - IL_000d: initobj ""{destType}?"" + IL_000d: initobj ""nint?"" IL_0013: ldloc.1 IL_0014: ret IL_0015: ldloca.s V_0 - IL_0017: call ""{sourceType} {sourceType}?.GetValueOrDefault()"" - IL_001c: {conversion} - IL_001d: newobj ""{destType}?..ctor({destType})"" - IL_0022: ret -}}"; - static string convAndExplicit(string method, string conv = null) => conv is null ? -$@"{{ + IL_0017: call ""decimal decimal?.GetValueOrDefault()"" + IL_001c: call ""long decimal.op_Explicit(decimal)"" + IL_0021: conv.i + IL_0022: newobj ""nint?..ctor(nint)"" + IL_0027: ret +}", +@"{ + // Code size 40 (0x28) + .maxstack 1 + .locals init (decimal? V_0, + nint? V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call ""bool decimal?.HasValue.get"" + IL_0009: brtrue.s IL_0015 + IL_000b: ldloca.s V_1 + IL_000d: initobj ""nint?"" + IL_0013: ldloc.1 + IL_0014: ret + IL_0015: ldloca.s V_0 + IL_0017: call ""decimal decimal?.GetValueOrDefault()"" + IL_001c: call ""long decimal.op_Explicit(decimal)"" + IL_0021: conv.ovf.i + IL_0022: newobj ""nint?..ctor(nint)"" + IL_0027: ret +}"); + conversions(sourceType: "System.IntPtr?", destType: "nint?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + conversions(sourceType: "System.UIntPtr?", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "nuint", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i.un", "nuint", "nint")); + + // nint to type + conversions(sourceType: "nint", destType: "object", Boxing, +@"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""{method}"" + IL_0001: box ""nint"" IL_0006: ret -}}" : -$@"{{ +}", +@"{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""nint"" + IL_0006: ret +}"); + conversions(sourceType: "nint", destType: "string", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "nint", destType: "void*", ExplicitIntegerToPointer, expectedImplicitIL: null, expectedExplicitIL: convNone, expectedCheckedIL: conv("conv.ovf.u")); // TODO2 why not user-defined conversion? + conversions(sourceType: "nint", destType: "delegate*", ExplicitIntegerToPointer, expectedImplicitIL: null, expectedExplicitIL: convNone, expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "nint", destType: "E", ExplicitEnumeration, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i4"), expectedCheckedIL: conv("conv.ovf.i4")); + conversions(sourceType: "nint", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "nint", destType: "char", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u2"), expectedCheckedIL: conv("conv.ovf.u2")); + conversions(sourceType: "nint", destType: "sbyte", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i1"), expectedCheckedIL: conv("conv.ovf.i1")); + conversions(sourceType: "nint", destType: "byte", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u1"), expectedCheckedIL: conv("conv.ovf.u1")); + conversions(sourceType: "nint", destType: "short", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i2"), expectedCheckedIL: conv("conv.ovf.i2")); + conversions(sourceType: "nint", destType: "ushort", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u2"), expectedCheckedIL: conv("conv.ovf.u2")); + conversions(sourceType: "nint", destType: "int", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i4"), expectedCheckedIL: conv("conv.ovf.i4")); + conversions(sourceType: "nint", destType: "uint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u4"), expectedCheckedIL: conv("conv.ovf.u4")); + conversions(sourceType: "nint", destType: "long", ImplicitNumeric, expectedImplicitIL: conv("conv.i8"), expectedExplicitIL: conv("conv.i8")); + conversions(sourceType: "nint", destType: "ulong", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i8"), expectedCheckedIL: conv("conv.ovf.u8")); + conversions(sourceType: "nint", destType: "float", ImplicitNumeric, expectedImplicitIL: conv("conv.r4"), expectedExplicitIL: conv("conv.r4")); + conversions(sourceType: "nint", destType: "double", ImplicitNumeric, expectedImplicitIL: conv("conv.r8"), expectedExplicitIL: conv("conv.r8")); + conversions(sourceType: "nint", destType: "decimal", ImplicitNumeric, +@"{ // Code size 8 (0x8) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""{method}"" - IL_0006: {conv} + IL_0001: conv.i8 + IL_0002: call ""decimal decimal.op_Implicit(long)"" IL_0007: ret -}}"; - static string convAndExplicitFromNullableT(string sourceType, string method, string conv = null) => conv is null ? -$@"{{ - // Code size 13 (0xd) - .maxstack 1 - IL_0000: ldarga.s V_0 - IL_0002: call ""{sourceType} {sourceType}?.Value.get"" - IL_0007: call ""{method}"" - IL_000c: ret -}}" : -$@"{{ - // Code size 14 (0xe) +}", +@"{ + // Code size 8 (0x8) .maxstack 1 - IL_0000: ldarga.s V_0 - IL_0002: call ""{sourceType} {sourceType}?.Value.get"" - IL_0007: call ""{method}"" - IL_000c: {conv} - IL_000d: ret -}}"; - static string convAndExplicitToNullableT(string destType, string method, string conv = null) => conv is null ? -$@"{{ - // Code size 12 (0xc) + IL_0000: ldarg.0 + IL_0001: conv.i8 + IL_0002: call ""decimal decimal.op_Implicit(long)"" + IL_0007: ret +}"); + conversions(sourceType: "nint", destType: "System.IntPtr", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + conversions(sourceType: "nint", destType: "System.UIntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); + + // nint to nullable type + conversions(sourceType: "nint", destType: "E?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i4", "E"), expectedCheckedIL: convToNullableT("conv.ovf.i4", "E")); + conversions(sourceType: "nint", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "nint", destType: "char?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u2", "char"), expectedCheckedIL: convToNullableT("conv.ovf.u2", "char")); + conversions(sourceType: "nint", destType: "sbyte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i1", "sbyte"), expectedCheckedIL: convToNullableT("conv.ovf.i1", "sbyte")); + conversions(sourceType: "nint", destType: "byte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u1", "byte"), expectedCheckedIL: convToNullableT("conv.ovf.u1", "byte")); + conversions(sourceType: "nint", destType: "short?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i2", "short"), expectedCheckedIL: convToNullableT("conv.ovf.i2", "short")); + conversions(sourceType: "nint", destType: "ushort?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u2", "ushort"), expectedCheckedIL: convToNullableT("conv.ovf.u2", "ushort")); + conversions(sourceType: "nint", destType: "int?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i4", "int"), expectedCheckedIL: convToNullableT("conv.ovf.i4", "int")); + conversions(sourceType: "nint", destType: "uint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u4", "uint"), expectedCheckedIL: convToNullableT("conv.ovf.u4", "uint")); + conversions(sourceType: "nint", destType: "long?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.i8", "long"), expectedExplicitIL: convToNullableT("conv.i8", "long")); + conversions(sourceType: "nint", destType: "ulong?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i8", "ulong"), expectedCheckedIL: convToNullableT("conv.ovf.u8", "ulong")); + conversions(sourceType: "nint", destType: "float?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.r4", "float"), expectedExplicitIL: convToNullableT("conv.r4", "float"), null); + conversions(sourceType: "nint", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.r8", "double"), expectedExplicitIL: convToNullableT("conv.r8", "double"), null); + conversions(sourceType: "nint", destType: "decimal?", ImplicitNullableNumeric, +@"{ + // Code size 13 (0xd) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""{method}"" - IL_0006: newobj ""{destType}?..ctor({destType})"" - IL_000b: ret -}}" : -$@"{{ + IL_0001: conv.i8 + IL_0002: call ""decimal decimal.op_Implicit(long)"" + IL_0007: newobj ""decimal?..ctor(decimal)"" + IL_000c: ret +}", +@"{ // Code size 13 (0xd) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""{method}"" - IL_0006: {conv} - IL_0007: newobj ""{destType}?..ctor({destType})"" + IL_0001: conv.i8 + IL_0002: call ""decimal decimal.op_Implicit(long)"" + IL_0007: newobj ""decimal?..ctor(decimal)"" IL_000c: ret -}}"; - // https://github.com/dotnet/roslyn/issues/42834: Invalid code generated for nullable conversions - // involving System.[U]IntPtr: the conversion is dropped. - static string convAndExplicitFromToNullableT(string sourceType, string destType, string method, string conv = null) => -$@"{{ - // Code size 39 (0x27) +}"); + conversions(sourceType: "nint", destType: "System.IntPtr?", ImplicitNullableIdentity, +@"{ + // Code size 7 (0x7) .maxstack 1 - .locals init ({sourceType}? V_0, - {destType}? V_1) IL_0000: ldarg.0 - IL_0001: stloc.0 - IL_0002: ldloca.s V_0 - IL_0004: call ""bool {sourceType}?.HasValue.get"" - IL_0009: brtrue.s IL_0015 - IL_000b: ldloca.s V_1 - IL_000d: initobj ""{destType}?"" - IL_0013: ldloc.1 - IL_0014: ret - IL_0015: ldloca.s V_0 - IL_0017: call ""{sourceType} {sourceType}?.GetValueOrDefault()"" - IL_001c: call ""{method}"" - IL_0021: newobj ""{destType}?..ctor({destType})"" - IL_0026: ret -}}"; - static string explicitAndConv(string method, string conv = null) => conv is null ? -$@"{{ + IL_0001: newobj ""nint?..ctor(nint)"" + IL_0006: ret +}", +@"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""{method}"" + IL_0001: newobj ""nint?..ctor(nint)"" IL_0006: ret -}}" : -$@"{{ - // Code size 8 (0x8) +}"); + conversions(sourceType: "nint", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + + // nullable nint to type + conversions(sourceType: "nint?", destType: "object", Boxing, +@"{ + // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: {conv} - IL_0002: call ""{method}"" - IL_0007: ret -}}"; - static string explicitAndConvFromNullableT(string sourceType, string method, string conv = null) => conv is null ? -$@"{{ - // Code size 13 (0xd) + IL_0001: box ""nint?"" + IL_0006: ret +}", +@"{ + // Code size 7 (0x7) .maxstack 1 - IL_0000: ldarga.s V_0 - IL_0002: call ""{sourceType} {sourceType}?.Value.get"" - IL_0007: call ""{method}"" - IL_000c: ret -}}" : -$@"{{ + IL_0000: ldarg.0 + IL_0001: box ""nint?"" + IL_0006: ret +}"); + conversions(sourceType: "nint?", destType: "string", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "nint?", destType: "void*", ExplicitUserDefined, expectedImplicitIL: null, expectedExplicitIL: convExplicitFromNullableT("nint", "void* nint.op_Explicit(nint)")); // TODO2 why user-defined conversion? + conversions(sourceType: "nint?", destType: "delegate*", ExplicitUserDefined, expectedImplicitIL: null, expectedExplicitIL: convExplicitFromNullableT("nint", "void* nint.op_Explicit(nint)")); + conversions(sourceType: "nint?", destType: "E", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i4", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.i4", "nint")); + conversions(sourceType: "nint?", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "nint?", destType: "char", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u2", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u2", "nint")); + conversions(sourceType: "nint?", destType: "sbyte", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i1", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.i1", "nint")); + conversions(sourceType: "nint?", destType: "byte", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u1", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u1", "nint")); + conversions(sourceType: "nint?", destType: "short", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i2", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.i2", "nint")); + conversions(sourceType: "nint?", destType: "ushort", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u2", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u2", "nint")); + conversions(sourceType: "nint?", destType: "int", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i4", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.i4", "nint")); + conversions(sourceType: "nint?", destType: "uint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u4", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u4", "nint")); + conversions(sourceType: "nint?", destType: "long", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i8", "nint")); + conversions(sourceType: "nint?", destType: "ulong", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i8", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u8", "nint")); + conversions(sourceType: "nint?", destType: "float", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.r4", "nint")); + conversions(sourceType: "nint?", destType: "double", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.r8", "nint")); + conversions(sourceType: "nint?", destType: "decimal", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, +@"{ // Code size 14 (0xe) .maxstack 1 IL_0000: ldarga.s V_0 - IL_0002: call ""{sourceType} {sourceType}?.Value.get"" - IL_0007: {conv} - IL_0008: call ""{method}"" + IL_0002: call ""nint nint?.Value.get"" + IL_0007: conv.i8 + IL_0008: call ""decimal decimal.op_Implicit(long)"" IL_000d: ret -}}"; - static string explicitAndConvToNullableT(string destType, string method, string conv = null) => conv is null ? -$@"{{ - // Code size 12 (0xc) +}"); + conversions(sourceType: "nint?", destType: "System.IntPtr", ExplicitNullableIdentity, expectedImplicitIL: null, +@"{ + // Code size 8 (0x8) .maxstack 1 - IL_0000: ldarg.0 - IL_0001: call ""{method}"" - IL_0006: newobj ""{destType}?..ctor({destType})"" - IL_000b: ret -}}" : -$@"{{ - // Code size 13 (0xd) + IL_0000: ldarga.s V_0 + IL_0002: call ""nint nint?.Value.get"" + IL_0007: ret +}"); + conversions(sourceType: "nint?", destType: "System.UIntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "nint")); + + // nullable nint to nullable type + conversions(sourceType: "nint?", destType: "E?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i4", "nint", "E"), expectedCheckedIL: convFromToNullableT("conv.ovf.i4", "nint", "E")); + conversions(sourceType: "nint?", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "nint?", destType: "char?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u2", "nint", "char"), expectedCheckedIL: convFromToNullableT("conv.ovf.u2", "nint", "char")); + conversions(sourceType: "nint?", destType: "sbyte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i1", "nint", "sbyte"), expectedCheckedIL: convFromToNullableT("conv.ovf.i1", "nint", "sbyte")); + conversions(sourceType: "nint?", destType: "byte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u1", "nint", "byte"), expectedCheckedIL: convFromToNullableT("conv.ovf.u1", "nint", "byte")); + conversions(sourceType: "nint?", destType: "short?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i2", "nint", "short"), expectedCheckedIL: convFromToNullableT("conv.ovf.i2", "nint", "short")); + conversions(sourceType: "nint?", destType: "ushort?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u2", "nint", "ushort"), expectedCheckedIL: convFromToNullableT("conv.ovf.u2", "nint", "ushort")); + conversions(sourceType: "nint?", destType: "int?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i4", "nint", "int"), expectedCheckedIL: convFromToNullableT("conv.ovf.i4", "nint", "int")); + conversions(sourceType: "nint?", destType: "uint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u4", "nint", "uint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u4", "nint", "uint")); + conversions(sourceType: "nint?", destType: "long?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.i8", "nint", "long"), expectedExplicitIL: convFromToNullableT("conv.i8", "nint", "long")); + conversions(sourceType: "nint?", destType: "ulong?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i8", "nint", "ulong"), expectedCheckedIL: convFromToNullableT("conv.ovf.u8", "nint", "ulong")); + conversions(sourceType: "nint?", destType: "float?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.r4", "nint", "float"), expectedExplicitIL: convFromToNullableT("conv.r4", "nint", "float"), null); + conversions(sourceType: "nint?", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.r8", "nint", "double"), expectedExplicitIL: convFromToNullableT("conv.r8", "nint", "double"), null); + conversions(sourceType: "nint?", destType: "decimal?", ImplicitNullableNumeric, +@"{ + // Code size 40 (0x28) .maxstack 1 + .locals init (nint? V_0, + decimal? V_1) IL_0000: ldarg.0 - IL_0001: {conv} - IL_0002: call ""{method}"" - IL_0007: newobj ""{destType}?..ctor({destType})"" - IL_000c: ret -}}"; - // https://github.com/dotnet/roslyn/issues/42834: Invalid code generated for nullable conversions - // involving System.[U]IntPtr: the conversion is dropped. - static string explicitAndConvFromToNullableT(string sourceType, string destType, string method, string conv = null) => -$@"{{ - // Code size 39 (0x27) + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call ""bool nint?.HasValue.get"" + IL_0009: brtrue.s IL_0015 + IL_000b: ldloca.s V_1 + IL_000d: initobj ""decimal?"" + IL_0013: ldloc.1 + IL_0014: ret + IL_0015: ldloca.s V_0 + IL_0017: call ""nint nint?.GetValueOrDefault()"" + IL_001c: conv.i8 + IL_001d: call ""decimal decimal.op_Implicit(long)"" + IL_0022: newobj ""decimal?..ctor(decimal)"" + IL_0027: ret +}", +@"{ + // Code size 40 (0x28) .maxstack 1 - .locals init ({sourceType}? V_0, - {destType}? V_1) + .locals init (nint? V_0, + decimal? V_1) IL_0000: ldarg.0 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: call ""bool {sourceType}?.HasValue.get"" + IL_0004: call ""bool nint?.HasValue.get"" IL_0009: brtrue.s IL_0015 IL_000b: ldloca.s V_1 - IL_000d: initobj ""{destType}?"" + IL_000d: initobj ""decimal?"" IL_0013: ldloc.1 IL_0014: ret IL_0015: ldloca.s V_0 - IL_0017: call ""{sourceType} {sourceType}?.GetValueOrDefault()"" - IL_001c: call ""{method}"" - IL_0021: newobj ""{destType}?..ctor({destType})"" - IL_0026: ret -}}"; - void conversions(string sourceType, string destType, ConversionKind[] expectedConversions, string expectedImplicitIL, string expectedExplicitIL, string expectedCheckedIL = null) - { - if (expectedExplicitIL is not null) - { - Assert.False(IsNoConversion(expectedConversions)); - } - - // https://github.com/dotnet/roslyn/issues/42834: Invalid code generated for nullable conversions - // involving System.[U]IntPtr: the conversion is dropped. And when converting from System.[U]IntPtr, - // an assert in LocalRewriter.MakeLiftedUserDefinedConversionConsequence fails. - bool verify = !(sourceType.EndsWith("?") && - destType.EndsWith("?") && - (usesIntPtrOrUIntPtr(sourceType) || usesIntPtrOrUIntPtr(destType))); -#if DEBUG - if (!verify) return; -#endif - convert( - sourceType, - destType, - expectedImplicitIL, - // https://github.com/dotnet/roslyn/issues/42454: TypeInfo.ConvertedType does not include identity conversion between underlying type and native int. - skipTypeChecks: usesIntPtrOrUIntPtr(sourceType) || usesIntPtrOrUIntPtr(destType), - useExplicitCast: false, - useChecked: false, - verify: verify, - expectedConversions, - expectedImplicitIL is null ? - expectedExplicitIL is null ? ErrorCode.ERR_NoImplicitConv : ErrorCode.ERR_NoImplicitConvCast : - 0); - convert( - sourceType, - destType, - expectedExplicitIL, - skipTypeChecks: true, - useExplicitCast: true, - useChecked: false, - verify: verify, - expectedConversions: null, - expectedExplicitIL is null ? ErrorCode.ERR_NoExplicitConv : 0); - expectedCheckedIL ??= expectedExplicitIL; - convert( - sourceType, - destType, - expectedCheckedIL, - skipTypeChecks: true, - useExplicitCast: true, - useChecked: true, - verify: verify, - expectedConversions: null, - expectedCheckedIL is null ? ErrorCode.ERR_NoExplicitConv : 0); - - static bool usesIntPtrOrUIntPtr(string underlyingType) => underlyingType.Contains("IntPtr"); - } + IL_0017: call ""nint nint?.GetValueOrDefault()"" + IL_001c: conv.i8 + IL_001d: call ""decimal decimal.op_Implicit(long)"" + IL_0022: newobj ""decimal?..ctor(decimal)"" + IL_0027: ret +}"); + conversions(sourceType: "nint?", destType: "System.IntPtr?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + conversions(sourceType: "nint?", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "nint", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "nint", "nuint")); - conversions(sourceType: "object", destType: "nint", Unboxing, expectedImplicitIL: null, + // type to nuint + conversions(sourceType: "object", destType: "nuint", Unboxing, expectedImplicitIL: null, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: unbox.any ""System.IntPtr"" + IL_0001: unbox.any ""nuint"" IL_0006: ret }"); - conversions(sourceType: "string", destType: "nint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "void*", destType: "nint", ExplicitPointerToInteger, expectedImplicitIL: null, expectedExplicitIL: convNone, expectedCheckedIL: conv("conv.ovf.i.un")); - conversions(sourceType: "delegate*", destType: "nint", ExplicitPointerToInteger, expectedImplicitIL: null, expectedExplicitIL: convNone, expectedCheckedIL: conv("conv.ovf.i.un")); - conversions(sourceType: "E", destType: "nint", ExplicitEnumeration, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i")); - conversions(sourceType: "bool", destType: "nint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char", destType: "nint", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); - conversions(sourceType: "sbyte", destType: "nint", ImplicitNumeric, expectedImplicitIL: conv("conv.i"), expectedExplicitIL: conv("conv.i")); - conversions(sourceType: "byte", destType: "nint", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); - conversions(sourceType: "short", destType: "nint", ImplicitNumeric, expectedImplicitIL: conv("conv.i"), expectedExplicitIL: conv("conv.i")); - conversions(sourceType: "ushort", destType: "nint", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); - conversions(sourceType: "int", destType: "nint", ImplicitNumeric, expectedImplicitIL: conv("conv.i"), expectedExplicitIL: conv("conv.i")); - conversions(sourceType: "uint", destType: "nint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.i.un")); - conversions(sourceType: "long", destType: "nint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i")); - conversions(sourceType: "ulong", destType: "nint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i.un")); - conversions(sourceType: "nint", destType: "nint", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "nuint", destType: "nint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i.un")); - conversions(sourceType: "float", destType: "nint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i")); - conversions(sourceType: "double", destType: "nint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i")); - conversions(sourceType: "decimal", destType: "nint", ExplicitNumeric, expectedImplicitIL: null, + conversions(sourceType: "string", destType: "nuint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "void*", destType: "nuint", ExplicitPointerToInteger, expectedImplicitIL: null, expectedExplicitIL: convNone); + conversions(sourceType: "delegate*", destType: "nuint", ExplicitPointerToInteger, expectedImplicitIL: null, expectedExplicitIL: convNone); + conversions(sourceType: "E", destType: "nuint", ExplicitEnumeration, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "bool", destType: "nuint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "char", destType: "nuint", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); + conversions(sourceType: "sbyte", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "byte", destType: "nuint", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); + conversions(sourceType: "short", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "ushort", destType: "nuint", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); + conversions(sourceType: "int", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "uint", destType: "nuint", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); + conversions(sourceType: "long", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "ulong", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u.un")); + conversions(sourceType: "nint", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "nuint", destType: "nuint", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + conversions(sourceType: "float", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "double", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "decimal", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, @"{ // Code size 8 (0x8) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""long decimal.op_Explicit(decimal)"" - IL_0006: conv.i + IL_0001: call ""ulong decimal.op_Explicit(decimal)"" + IL_0006: conv.u IL_0007: ret }", @"{ // Code size 8 (0x8) .maxstack 1 - IL_0000: ldarg.0 - IL_0001: call ""long decimal.op_Explicit(decimal)"" - IL_0006: conv.ovf.i + IL_0000: ldarg.0 + IL_0001: call ""ulong decimal.op_Explicit(decimal)"" + IL_0006: conv.ovf.u.un IL_0007: ret }"); - conversions(sourceType: "System.IntPtr", destType: "nint", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "System.UIntPtr", destType: "nint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "E?", destType: "nint", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "E")); - conversions(sourceType: "bool?", destType: "nint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char?", destType: "nint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "char")); - conversions(sourceType: "sbyte?", destType: "nint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "sbyte")); - conversions(sourceType: "byte?", destType: "nint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "byte")); - conversions(sourceType: "short?", destType: "nint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "short")); - conversions(sourceType: "ushort?", destType: "nint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "ushort")); - conversions(sourceType: "int?", destType: "nint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "int")); - conversions(sourceType: "uint?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "uint"), expectedCheckedIL: convFromNullableT("conv.ovf.i.un", "uint")); - conversions(sourceType: "long?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "long"), expectedCheckedIL: convFromNullableT("conv.ovf.i", "long")); - conversions(sourceType: "ulong?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "ulong"), expectedCheckedIL: convFromNullableT("conv.ovf.i.un", "ulong")); - conversions(sourceType: "nint?", destType: "nint", ExplicitNullableIdentity, expectedImplicitIL: null, + conversions(sourceType: "System.IntPtr", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "System.UIntPtr", destType: "nuint", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + + // nullable type to nuint + conversions(sourceType: "E?", destType: "nuint", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "E"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "E")); + conversions(sourceType: "bool?", destType: "nuint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "char?", destType: "nuint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "char")); + conversions(sourceType: "sbyte?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "sbyte"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "sbyte")); + conversions(sourceType: "byte?", destType: "nuint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "byte")); + conversions(sourceType: "short?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "short"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "short")); + conversions(sourceType: "ushort?", destType: "nuint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "ushort")); + conversions(sourceType: "int?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "int"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "int")); + conversions(sourceType: "uint?", destType: "nuint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "uint")); + conversions(sourceType: "long?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "long"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "long")); + conversions(sourceType: "ulong?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "ulong"), expectedCheckedIL: convFromNullableT("conv.ovf.u.un", "ulong")); + conversions(sourceType: "nint?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "nint")); + conversions(sourceType: "nuint?", destType: "nuint", ExplicitNullableIdentity, expectedImplicitIL: null, @"{ // Code size 8 (0x8) .maxstack 1 IL_0000: ldarga.s V_0 - IL_0002: call ""nint nint?.Value.get"" + IL_0002: call ""nuint nuint?.Value.get"" IL_0007: ret }"); - conversions(sourceType: "nuint?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i.un", "nuint")); - conversions(sourceType: "float?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "float"), expectedCheckedIL: convFromNullableT("conv.ovf.i", "float")); - conversions(sourceType: "double?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "double"), expectedCheckedIL: convFromNullableT("conv.ovf.i", "double")); - conversions(sourceType: "decimal?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, + conversions(sourceType: "float?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "float"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "float")); + conversions(sourceType: "double?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "double"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "double")); + conversions(sourceType: "decimal?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, @"{ // Code size 14 (0xe) .maxstack 1 IL_0000: ldarga.s V_0 IL_0002: call ""decimal decimal?.Value.get"" - IL_0007: call ""long decimal.op_Explicit(decimal)"" - IL_000c: conv.i + IL_0007: call ""ulong decimal.op_Explicit(decimal)"" + IL_000c: conv.u IL_000d: ret }", @"{ @@ -7664,216 +4816,423 @@ .maxstack 1 .maxstack 1 IL_0000: ldarga.s V_0 IL_0002: call ""decimal decimal?.Value.get"" - IL_0007: call ""long decimal.op_Explicit(decimal)"" - IL_000c: conv.ovf.i + IL_0007: call ""ulong decimal.op_Explicit(decimal)"" + IL_000c: conv.ovf.u.un IL_000d: ret }"); - conversions(sourceType: "System.IntPtr?", destType: "nint", ExplicitNullableIdentity, expectedImplicitIL: null, + conversions(sourceType: "System.IntPtr?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "nint")); + conversions(sourceType: "System.UIntPtr?", destType: "nuint", ExplicitNullableIdentity, expectedImplicitIL: null, @"{ // Code size 8 (0x8) .maxstack 1 IL_0000: ldarga.s V_0 - IL_0002: call ""System.IntPtr System.IntPtr?.Value.get"" + IL_0002: call ""nuint nuint?.Value.get"" IL_0007: ret }"); - conversions(sourceType: "System.UIntPtr?", destType: "nint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "object", destType: "nint?", Unboxing, expectedImplicitIL: null, + + // type to nullable nuint + conversions(sourceType: "object", destType: "nuint?", Unboxing, expectedImplicitIL: null, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: unbox.any ""nint?"" + IL_0001: unbox.any ""nuint?"" IL_0006: ret }"); - conversions(sourceType: "string", destType: "nint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "void*", destType: "nint?", ExplicitNullablePointerToInteger, expectedImplicitIL: null, + conversions(sourceType: "string", destType: "nuint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "void*", destType: "nuint?", ExplicitNullablePointerToInteger, expectedImplicitIL: null, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""nint?..ctor(nint)"" + IL_0001: newobj ""nuint?..ctor(nuint)"" + IL_0006: ret +}"); + conversions(sourceType: "delegate*", destType: "nuint?", ExplicitNullablePointerToInteger, expectedImplicitIL: null, +@"{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: newobj ""nuint?..ctor(nuint)"" + IL_0006: ret +}"); + conversions(sourceType: "E", destType: "nuint?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "bool", destType: "nuint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "char", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nuint"), expectedExplicitIL: convToNullableT("conv.u", "nuint")); + conversions(sourceType: "sbyte", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "byte", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nuint"), expectedExplicitIL: convToNullableT("conv.u", "nuint")); + conversions(sourceType: "short", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "ushort", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nuint"), expectedExplicitIL: convToNullableT("conv.u", "nuint")); + conversions(sourceType: "int", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "uint", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nuint"), expectedExplicitIL: convToNullableT("conv.u", "nuint")); + conversions(sourceType: "long", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "ulong", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u.un", "nuint")); + conversions(sourceType: "nint", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "nuint", destType: "nuint?", ImplicitNullableIdentity, +@"{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: newobj ""nuint?..ctor(nuint)"" IL_0006: ret }", @"{ - // Code size 8 (0x8) + // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: conv.ovf.i.un - IL_0002: newobj ""nint?..ctor(nint)"" - IL_0007: ret + IL_0001: newobj ""nuint?..ctor(nuint)"" + IL_0006: ret }"); - conversions(sourceType: "delegate*", destType: "nint?", ExplicitNullablePointerToInteger, expectedImplicitIL: null, + conversions(sourceType: "float", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "double", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "decimal", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, +@"{ + // Code size 13 (0xd) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: call ""ulong decimal.op_Explicit(decimal)"" + IL_0006: conv.u + IL_0007: newobj ""nuint?..ctor(nuint)"" + IL_000c: ret +}", +@"{ + // Code size 13 (0xd) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: call ""ulong decimal.op_Explicit(decimal)"" + IL_0006: conv.ovf.u.un + IL_0007: newobj ""nuint?..ctor(nuint)"" + IL_000c: ret +}"); + conversions(sourceType: "System.IntPtr", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "System.UIntPtr", destType: "nuint?", ImplicitNullableIdentity, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""nint?..ctor(nint)"" + IL_0001: newobj ""nuint?..ctor(nuint)"" + IL_0006: ret +}", +@"{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: newobj ""nuint?..ctor(nuint)"" + IL_0006: ret +}"); + + // nullable type to nullable nuint + conversions(sourceType: "E?", destType: "nuint?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "E", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "E", "nuint")); + conversions(sourceType: "bool?", destType: "nuint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "char?", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "char", "nuint"), expectedExplicitIL: convFromToNullableT("conv.u", "char", "nuint")); + conversions(sourceType: "sbyte?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "sbyte", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "sbyte", "nuint")); + conversions(sourceType: "byte?", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "byte", "nuint"), expectedExplicitIL: convFromToNullableT("conv.u", "byte", "nuint")); + conversions(sourceType: "short?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "short", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "short", "nuint")); + conversions(sourceType: "ushort?", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "ushort", "nuint"), expectedExplicitIL: convFromToNullableT("conv.u", "ushort", "nuint")); + conversions(sourceType: "int?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "int", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "int", "nuint")); + conversions(sourceType: "uint?", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "uint", "nuint"), expectedExplicitIL: convFromToNullableT("conv.u", "uint", "nuint")); + conversions(sourceType: "long?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "long", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "long", "nuint")); + conversions(sourceType: "ulong?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "ulong", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u.un", "ulong", "nuint")); + conversions(sourceType: "nint?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "nint", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "nint", "nuint")); + conversions(sourceType: "nuint?", destType: "nuint?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + conversions(sourceType: "float?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "float", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "float", "nuint")); + conversions(sourceType: "double?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "double", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "double", "nuint")); + conversions(sourceType: "decimal?", destType: "nuint?", ExplicitNullableNumeric, null, +@"{ + // Code size 40 (0x28) + .maxstack 1 + .locals init (decimal? V_0, + nuint? V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call ""bool decimal?.HasValue.get"" + IL_0009: brtrue.s IL_0015 + IL_000b: ldloca.s V_1 + IL_000d: initobj ""nuint?"" + IL_0013: ldloc.1 + IL_0014: ret + IL_0015: ldloca.s V_0 + IL_0017: call ""decimal decimal?.GetValueOrDefault()"" + IL_001c: call ""ulong decimal.op_Explicit(decimal)"" + IL_0021: conv.u + IL_0022: newobj ""nuint?..ctor(nuint)"" + IL_0027: ret +}", +@"{ + // Code size 40 (0x28) + .maxstack 1 + .locals init (decimal? V_0, + nuint? V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call ""bool decimal?.HasValue.get"" + IL_0009: brtrue.s IL_0015 + IL_000b: ldloca.s V_1 + IL_000d: initobj ""nuint?"" + IL_0013: ldloc.1 + IL_0014: ret + IL_0015: ldloca.s V_0 + IL_0017: call ""decimal decimal?.GetValueOrDefault()"" + IL_001c: call ""ulong decimal.op_Explicit(decimal)"" + IL_0021: conv.ovf.u.un + IL_0022: newobj ""nuint?..ctor(nuint)"" + IL_0027: ret +}"); + conversions(sourceType: "System.IntPtr?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "nint", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "nint", "nuint")); + conversions(sourceType: "System.UIntPtr?", destType: "nuint?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + + // nuint to type + conversions(sourceType: "nuint", destType: "object", Boxing, +@"{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""nuint"" IL_0006: ret }", +@"{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""nuint"" + IL_0006: ret +}"); + conversions(sourceType: "nuint", destType: "string", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "nuint", destType: "void*", ExplicitIntegerToPointer, expectedImplicitIL: null, expectedExplicitIL: convNone); + conversions(sourceType: "nuint", destType: "delegate*", ExplicitIntegerToPointer, expectedImplicitIL: null, expectedExplicitIL: convNone); + conversions(sourceType: "nuint", destType: "E", ExplicitEnumeration, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i4"), expectedCheckedIL: conv("conv.ovf.i4.un")); + conversions(sourceType: "nuint", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "nuint", destType: "char", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u2"), expectedCheckedIL: conv("conv.ovf.u2.un")); + conversions(sourceType: "nuint", destType: "sbyte", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i1"), expectedCheckedIL: conv("conv.ovf.i1.un")); + conversions(sourceType: "nuint", destType: "byte", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u1"), expectedCheckedIL: conv("conv.ovf.u1.un")); + conversions(sourceType: "nuint", destType: "short", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i2"), expectedCheckedIL: conv("conv.ovf.i2.un")); + conversions(sourceType: "nuint", destType: "ushort", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u2"), expectedCheckedIL: conv("conv.ovf.u2.un")); + conversions(sourceType: "nuint", destType: "int", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i4"), expectedCheckedIL: conv("conv.ovf.i4.un")); + conversions(sourceType: "nuint", destType: "uint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u4"), expectedCheckedIL: conv("conv.ovf.u4.un")); + conversions(sourceType: "nuint", destType: "long", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u8"), expectedCheckedIL: conv("conv.ovf.i8.un")); + conversions(sourceType: "nuint", destType: "ulong", ImplicitNumeric, expectedImplicitIL: conv("conv.u8"), expectedExplicitIL: conv("conv.u8")); + conversions(sourceType: "nuint", destType: "float", ImplicitNumeric, expectedImplicitIL: conv("conv.r4"), expectedExplicitIL: conv("conv.r4")); + conversions(sourceType: "nuint", destType: "double", ImplicitNumeric, expectedImplicitIL: conv("conv.r8"), expectedExplicitIL: conv("conv.r8")); + conversions(sourceType: "nuint", destType: "decimal", ImplicitNumeric, @"{ // Code size 8 (0x8) .maxstack 1 IL_0000: ldarg.0 - IL_0001: conv.ovf.i.un - IL_0002: newobj ""nint?..ctor(nint)"" + IL_0001: conv.u8 + IL_0002: call ""decimal decimal.op_Implicit(ulong)"" + IL_0007: ret +}", +@"{ + // Code size 8 (0x8) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: conv.u8 + IL_0002: call ""decimal decimal.op_Implicit(ulong)"" IL_0007: ret }"); - conversions(sourceType: "E", destType: "nint?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint")); - conversions(sourceType: "bool", destType: "nint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nint"), expectedExplicitIL: convToNullableT("conv.u", "nint")); - conversions(sourceType: "sbyte", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.i", "nint"), expectedExplicitIL: convToNullableT("conv.i", "nint")); - conversions(sourceType: "byte", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nint"), expectedExplicitIL: convToNullableT("conv.u", "nint")); - conversions(sourceType: "short", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.i", "nint"), expectedExplicitIL: convToNullableT("conv.i", "nint")); - conversions(sourceType: "ushort", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nint"), expectedExplicitIL: convToNullableT("conv.u", "nint")); - conversions(sourceType: "int", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.i", "nint"), expectedExplicitIL: convToNullableT("conv.i", "nint")); - conversions(sourceType: "uint", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i.un", "nint")); - conversions(sourceType: "long", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i", "nint")); - conversions(sourceType: "ulong", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i.un", "nint")); - conversions(sourceType: "nint", destType: "nint?", ImplicitNullableIdentity, + conversions(sourceType: "nuint", destType: "System.IntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i.un")); + conversions(sourceType: "nuint", destType: "System.UIntPtr", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + + // nuint to nullable type + conversions(sourceType: "nuint", destType: "E?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i4", "E"), expectedCheckedIL: convToNullableT("conv.ovf.i4.un", "E")); + conversions(sourceType: "nuint", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "nuint", destType: "char?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u2", "char"), expectedCheckedIL: convToNullableT("conv.ovf.u2.un", "char")); + conversions(sourceType: "nuint", destType: "sbyte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i1", "sbyte"), expectedCheckedIL: convToNullableT("conv.ovf.i1.un", "sbyte")); + conversions(sourceType: "nuint", destType: "byte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u1", "byte"), expectedCheckedIL: convToNullableT("conv.ovf.u1.un", "byte")); + conversions(sourceType: "nuint", destType: "short?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i2", "short"), expectedCheckedIL: convToNullableT("conv.ovf.i2.un", "short")); + conversions(sourceType: "nuint", destType: "ushort?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u2", "ushort"), expectedCheckedIL: convToNullableT("conv.ovf.u2.un", "ushort")); + conversions(sourceType: "nuint", destType: "int?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i4", "int"), expectedCheckedIL: convToNullableT("conv.ovf.i4.un", "int")); + conversions(sourceType: "nuint", destType: "uint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u4", "uint"), expectedCheckedIL: convToNullableT("conv.ovf.u4.un", "uint")); + conversions(sourceType: "nuint", destType: "long?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u8", "long"), expectedCheckedIL: convToNullableT("conv.ovf.i8.un", "long")); + conversions(sourceType: "nuint", destType: "ulong?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u8", "ulong"), expectedExplicitIL: convToNullableT("conv.u8", "ulong")); + conversions(sourceType: "nuint", destType: "float?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.r4", "float"), expectedExplicitIL: convToNullableT("conv.r4", "float"), null); + conversions(sourceType: "nuint", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.r8", "double"), expectedExplicitIL: convToNullableT("conv.r8", "double"), null); + conversions(sourceType: "nuint", destType: "decimal?", ImplicitNullableNumeric, @"{ - // Code size 7 (0x7) + // Code size 13 (0xd) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""nint?..ctor(nint)"" - IL_0006: ret + IL_0001: conv.u8 + IL_0002: call ""decimal decimal.op_Implicit(ulong)"" + IL_0007: newobj ""decimal?..ctor(decimal)"" + IL_000c: ret }", @"{ - // Code size 7 (0x7) + // Code size 13 (0xd) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""nint?..ctor(nint)"" - IL_0006: ret + IL_0001: conv.u8 + IL_0002: call ""decimal decimal.op_Implicit(ulong)"" + IL_0007: newobj ""decimal?..ctor(decimal)"" + IL_000c: ret }"); - conversions(sourceType: "nuint", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i.un", "nint")); - conversions(sourceType: "float", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i", "nint")); - conversions(sourceType: "double", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i", "nint")); - conversions(sourceType: "decimal", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, + conversions(sourceType: "nuint", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i.un", "nint")); + conversions(sourceType: "nuint", destType: "System.UIntPtr?", ImplicitNullableIdentity, @"{ - // Code size 13 (0xd) + // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""long decimal.op_Explicit(decimal)"" - IL_0006: conv.i - IL_0007: newobj ""nint?..ctor(nint)"" - IL_000c: ret + IL_0001: newobj ""nuint?..ctor(nuint)"" + IL_0006: ret }", @"{ - // Code size 13 (0xd) + // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""long decimal.op_Explicit(decimal)"" - IL_0006: conv.ovf.i - IL_0007: newobj ""nint?..ctor(nint)"" - IL_000c: ret + IL_0001: newobj ""nuint?..ctor(nuint)"" + IL_0006: ret }"); - conversions(sourceType: "System.IntPtr", destType: "nint?", ImplicitNullableIdentity, + + // nullable nuint to type + conversions(sourceType: "nuint?", destType: "object", Boxing, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""nint?..ctor(nint)"" + IL_0001: box ""nuint?"" IL_0006: ret }", @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""nint?..ctor(nint)"" + IL_0001: box ""nuint?"" IL_0006: ret }"); - conversions(sourceType: "System.UIntPtr", destType: "nint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "E?", destType: "nint?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "E", "nint")); - conversions(sourceType: "bool?", destType: "nint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char?", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "char", "nint"), expectedExplicitIL: convFromToNullableT("conv.u", "char", "nint")); - conversions(sourceType: "sbyte?", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.i", "sbyte", "nint"), expectedExplicitIL: convFromToNullableT("conv.i", "sbyte", "nint")); - conversions(sourceType: "byte?", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "byte", "nint"), expectedExplicitIL: convFromToNullableT("conv.u", "byte", "nint")); - conversions(sourceType: "short?", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.i", "short", "nint"), expectedExplicitIL: convFromToNullableT("conv.i", "short", "nint")); - conversions(sourceType: "ushort?", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "ushort", "nint"), expectedExplicitIL: convFromToNullableT("conv.u", "ushort", "nint")); - conversions(sourceType: "int?", destType: "nint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.i", "int", "nint"), expectedExplicitIL: convFromToNullableT("conv.i", "int", "nint")); - conversions(sourceType: "uint?", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "uint", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i.un", "uint", "nint")); - conversions(sourceType: "long?", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "long", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i", "long", "nint")); - conversions(sourceType: "ulong?", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "ulong", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i.un", "ulong", "nint")); - conversions(sourceType: "nint?", destType: "nint?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "nuint?", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "nuint", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i.un", "nuint", "nint")); - conversions(sourceType: "float?", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "float", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i", "float", "nint")); - conversions(sourceType: "double?", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "double", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i", "double", "nint")); - conversions(sourceType: "decimal?", destType: "nint?", ExplicitNullableNumeric, null, + conversions(sourceType: "nuint?", destType: "string", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "nuint?", destType: "void*", ExplicitUserDefined, expectedImplicitIL: null, expectedExplicitIL: convExplicitFromNullableT("nuint", "void* nuint.op_Explicit(nuint)")); + conversions(sourceType: "nuint?", destType: "delegate*", ExplicitUserDefined, expectedImplicitIL: null, expectedExplicitIL: convExplicitFromNullableT("nuint", "void* nuint.op_Explicit(nuint)")); + conversions(sourceType: "nuint?", destType: "E", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i4", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i4.un", "nuint")); + conversions(sourceType: "nuint?", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "nuint?", destType: "char", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u2", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.u2.un", "nuint")); + conversions(sourceType: "nuint?", destType: "sbyte", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i1", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i1.un", "nuint")); + conversions(sourceType: "nuint?", destType: "byte", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u1", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.u1.un", "nuint")); + conversions(sourceType: "nuint?", destType: "short", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i2", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i2.un", "nuint")); + conversions(sourceType: "nuint?", destType: "ushort", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u2", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.u2.un", "nuint")); + conversions(sourceType: "nuint?", destType: "int", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i4", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i4.un", "nuint")); + conversions(sourceType: "nuint?", destType: "uint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u4", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.u4.un", "nuint")); + conversions(sourceType: "nuint?", destType: "long", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u8", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i8.un", "nuint")); + conversions(sourceType: "nuint?", destType: "ulong", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u8", "nuint")); + conversions(sourceType: "nuint?", destType: "float", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.r4", "nuint")); + conversions(sourceType: "nuint?", destType: "double", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.r8", "nuint")); + conversions(sourceType: "nuint?", destType: "decimal", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, +@"{ + // Code size 14 (0xe) + .maxstack 1 + IL_0000: ldarga.s V_0 + IL_0002: call ""nuint nuint?.Value.get"" + IL_0007: conv.u8 + IL_0008: call ""decimal decimal.op_Implicit(ulong)"" + IL_000d: ret +}"); + conversions(sourceType: "nuint?", destType: "System.IntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i.un", "nuint")); + conversions(sourceType: "nuint?", destType: "System.UIntPtr", ExplicitNullableIdentity, expectedImplicitIL: null, +@"{ + // Code size 8 (0x8) + .maxstack 1 + IL_0000: ldarga.s V_0 + IL_0002: call ""nuint nuint?.Value.get"" + IL_0007: ret +}"); + + // nullable nuint to nullable type + conversions(sourceType: "nuint?", destType: "E?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i4", "nuint", "E"), expectedCheckedIL: convFromToNullableT("conv.ovf.i4.un", "nuint", "E")); + conversions(sourceType: "nuint?", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "nuint?", destType: "char?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u2", "nuint", "char"), expectedCheckedIL: convFromToNullableT("conv.ovf.u2.un", "nuint", "char")); + conversions(sourceType: "nuint?", destType: "sbyte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i1", "nuint", "sbyte"), expectedCheckedIL: convFromToNullableT("conv.ovf.i1.un", "nuint", "sbyte")); + conversions(sourceType: "nuint?", destType: "byte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u1", "nuint", "byte"), expectedCheckedIL: convFromToNullableT("conv.ovf.u1.un", "nuint", "byte")); + conversions(sourceType: "nuint?", destType: "short?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i2", "nuint", "short"), expectedCheckedIL: convFromToNullableT("conv.ovf.i2.un", "nuint", "short")); + conversions(sourceType: "nuint?", destType: "ushort?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u2", "nuint", "ushort"), expectedCheckedIL: convFromToNullableT("conv.ovf.u2.un", "nuint", "ushort")); + conversions(sourceType: "nuint?", destType: "int?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i4", "nuint", "int"), expectedCheckedIL: convFromToNullableT("conv.ovf.i4.un", "nuint", "int")); + conversions(sourceType: "nuint?", destType: "uint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u4", "nuint", "uint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u4.un", "nuint", "uint")); + conversions(sourceType: "nuint?", destType: "long?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u8", "nuint", "long"), expectedCheckedIL: convFromToNullableT("conv.ovf.i8.un", "nuint", "long")); + conversions(sourceType: "nuint?", destType: "ulong?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u8", "nuint", "ulong"), expectedExplicitIL: convFromToNullableT("conv.u8", "nuint", "ulong")); + conversions(sourceType: "nuint?", destType: "float?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.r4", "nuint", "float"), expectedExplicitIL: convFromToNullableT("conv.r4", "nuint", "float"), null); + conversions(sourceType: "nuint?", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.r8", "nuint", "double"), expectedExplicitIL: convFromToNullableT("conv.r8", "nuint", "double"), null); + conversions(sourceType: "nuint?", destType: "decimal?", ImplicitNullableNumeric, @"{ // Code size 40 (0x28) .maxstack 1 - .locals init (decimal? V_0, - nint? V_1) + .locals init (nuint? V_0, + decimal? V_1) IL_0000: ldarg.0 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: call ""bool decimal?.HasValue.get"" + IL_0004: call ""bool nuint?.HasValue.get"" IL_0009: brtrue.s IL_0015 IL_000b: ldloca.s V_1 - IL_000d: initobj ""nint?"" + IL_000d: initobj ""decimal?"" IL_0013: ldloc.1 IL_0014: ret IL_0015: ldloca.s V_0 - IL_0017: call ""decimal decimal?.GetValueOrDefault()"" - IL_001c: call ""long decimal.op_Explicit(decimal)"" - IL_0021: conv.i - IL_0022: newobj ""nint?..ctor(nint)"" + IL_0017: call ""nuint nuint?.GetValueOrDefault()"" + IL_001c: conv.u8 + IL_001d: call ""decimal decimal.op_Implicit(ulong)"" + IL_0022: newobj ""decimal?..ctor(decimal)"" IL_0027: ret }", @"{ // Code size 40 (0x28) .maxstack 1 - .locals init (decimal? V_0, - nint? V_1) + .locals init (nuint? V_0, + decimal? V_1) IL_0000: ldarg.0 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: call ""bool decimal?.HasValue.get"" + IL_0004: call ""bool nuint?.HasValue.get"" IL_0009: brtrue.s IL_0015 IL_000b: ldloca.s V_1 - IL_000d: initobj ""nint?"" + IL_000d: initobj ""decimal?"" IL_0013: ldloc.1 IL_0014: ret IL_0015: ldloca.s V_0 - IL_0017: call ""decimal decimal?.GetValueOrDefault()"" - IL_001c: call ""long decimal.op_Explicit(decimal)"" - IL_0021: conv.ovf.i - IL_0022: newobj ""nint?..ctor(nint)"" + IL_0017: call ""nuint nuint?.GetValueOrDefault()"" + IL_001c: conv.u8 + IL_001d: call ""decimal decimal.op_Implicit(ulong)"" + IL_0022: newobj ""decimal?..ctor(decimal)"" IL_0027: ret }"); - conversions(sourceType: "System.IntPtr?", destType: "nint?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "System.UIntPtr?", destType: "nint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nint", destType: "object", Boxing, + conversions(sourceType: "nuint?", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "nuint", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i.un", "nuint", "nint")); + conversions(sourceType: "nuint?", destType: "System.UIntPtr?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + + // System.IntPtr to type + conversions(sourceType: "System.IntPtr", destType: "object", Boxing, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: box ""System.IntPtr"" + IL_0001: box ""nint"" IL_0006: ret }", @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: box ""System.IntPtr"" + IL_0001: box ""nint"" IL_0006: ret }"); - conversions(sourceType: "nint", destType: "string", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nint", destType: "void*", ExplicitIntegerToPointer, expectedImplicitIL: null, expectedExplicitIL: convNone, expectedCheckedIL: conv("conv.ovf.u")); - conversions(sourceType: "nint", destType: "delegate*", ExplicitIntegerToPointer, expectedImplicitIL: null, expectedExplicitIL: convNone, expectedCheckedIL: conv("conv.ovf.u")); - conversions(sourceType: "nint", destType: "E", ExplicitEnumeration, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i4"), expectedCheckedIL: conv("conv.ovf.i4")); - conversions(sourceType: "nint", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nint", destType: "char", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u2"), expectedCheckedIL: conv("conv.ovf.u2")); - conversions(sourceType: "nint", destType: "sbyte", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i1"), expectedCheckedIL: conv("conv.ovf.i1")); - conversions(sourceType: "nint", destType: "byte", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u1"), expectedCheckedIL: conv("conv.ovf.u1")); - conversions(sourceType: "nint", destType: "short", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i2"), expectedCheckedIL: conv("conv.ovf.i2")); - conversions(sourceType: "nint", destType: "ushort", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u2"), expectedCheckedIL: conv("conv.ovf.u2")); - conversions(sourceType: "nint", destType: "int", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i4"), expectedCheckedIL: conv("conv.ovf.i4")); - conversions(sourceType: "nint", destType: "uint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u4"), expectedCheckedIL: conv("conv.ovf.u4")); - conversions(sourceType: "nint", destType: "long", ImplicitNumeric, expectedImplicitIL: conv("conv.i8"), expectedExplicitIL: conv("conv.i8")); - conversions(sourceType: "nint", destType: "ulong", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i8"), expectedCheckedIL: conv("conv.ovf.u8")); - conversions(sourceType: "nint", destType: "float", ImplicitNumeric, expectedImplicitIL: conv("conv.r4"), expectedExplicitIL: conv("conv.r4")); - conversions(sourceType: "nint", destType: "double", ImplicitNumeric, expectedImplicitIL: conv("conv.r8"), expectedExplicitIL: conv("conv.r8")); - conversions(sourceType: "nint", destType: "decimal", ImplicitNumeric, + conversions(sourceType: "System.IntPtr", destType: "string", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "System.IntPtr", destType: "void*", ExplicitIntegerToPointer, expectedImplicitIL: null, expectedExplicitIL: convNone, expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "System.IntPtr", destType: "delegate*", ExplicitIntegerToPointer, expectedImplicitIL: null, expectedExplicitIL: convNone, expectedCheckedIL: conv("conv.ovf.u")); + + conversions(sourceType: "System.IntPtr", destType: "void*", ExplicitIntegerToPointer, expectedImplicitIL: null, expectedExplicitIL: convNone, expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "System.IntPtr", destType: "delegate*", ExplicitIntegerToPointer, expectedImplicitIL: null, expectedExplicitIL: convNone, expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "System.IntPtr", destType: "E", ExplicitEnumeration, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i4"), expectedCheckedIL: conv("conv.ovf.i4")); + conversions(sourceType: "System.IntPtr", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "System.IntPtr", destType: "char", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u2"), expectedCheckedIL: conv("conv.ovf.u2")); + conversions(sourceType: "System.IntPtr", destType: "sbyte", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i1"), expectedCheckedIL: conv("conv.ovf.i1")); + conversions(sourceType: "System.IntPtr", destType: "byte", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u1"), expectedCheckedIL: conv("conv.ovf.u1")); + conversions(sourceType: "System.IntPtr", destType: "short", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i2"), expectedCheckedIL: conv("conv.ovf.i2")); + conversions(sourceType: "System.IntPtr", destType: "ushort", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u2"), expectedCheckedIL: conv("conv.ovf.u2")); + conversions(sourceType: "System.IntPtr", destType: "int", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i4"), expectedCheckedIL: conv("conv.ovf.i4")); + conversions(sourceType: "System.IntPtr", destType: "uint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u4"), expectedCheckedIL: conv("conv.ovf.u4")); + conversions(sourceType: "System.IntPtr", destType: "long", ImplicitNumeric, expectedImplicitIL: conv("conv.i8"), expectedExplicitIL: conv("conv.i8")); + conversions(sourceType: "System.IntPtr", destType: "ulong", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i8"), expectedCheckedIL: conv("conv.ovf.u8")); + conversions(sourceType: "System.IntPtr", destType: "float", ImplicitNumeric, expectedImplicitIL: conv("conv.r4"), expectedExplicitIL: conv("conv.r4")); + conversions(sourceType: "System.IntPtr", destType: "double", ImplicitNumeric, expectedImplicitIL: conv("conv.r8"), expectedExplicitIL: conv("conv.r8")); + conversions(sourceType: "System.IntPtr", destType: "decimal", ImplicitNumeric, @"{ // Code size 8 (0x8) .maxstack 1 @@ -7890,22 +5249,24 @@ .maxstack 1 IL_0002: call ""decimal decimal.op_Implicit(long)"" IL_0007: ret }"); - conversions(sourceType: "nint", destType: "System.IntPtr", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "nint", destType: "System.UIntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nint", destType: "E?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i4", "E"), expectedCheckedIL: convToNullableT("conv.ovf.i4", "E")); - conversions(sourceType: "nint", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nint", destType: "char?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u2", "char"), expectedCheckedIL: convToNullableT("conv.ovf.u2", "char")); - conversions(sourceType: "nint", destType: "sbyte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i1", "sbyte"), expectedCheckedIL: convToNullableT("conv.ovf.i1", "sbyte")); - conversions(sourceType: "nint", destType: "byte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u1", "byte"), expectedCheckedIL: convToNullableT("conv.ovf.u1", "byte")); - conversions(sourceType: "nint", destType: "short?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i2", "short"), expectedCheckedIL: convToNullableT("conv.ovf.i2", "short")); - conversions(sourceType: "nint", destType: "ushort?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u2", "ushort"), expectedCheckedIL: convToNullableT("conv.ovf.u2", "ushort")); - conversions(sourceType: "nint", destType: "int?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i4", "int"), expectedCheckedIL: convToNullableT("conv.ovf.i4", "int")); - conversions(sourceType: "nint", destType: "uint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u4", "uint"), expectedCheckedIL: convToNullableT("conv.ovf.u4", "uint")); - conversions(sourceType: "nint", destType: "long?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.i8", "long"), expectedExplicitIL: convToNullableT("conv.i8", "long")); - conversions(sourceType: "nint", destType: "ulong?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i8", "ulong"), expectedCheckedIL: convToNullableT("conv.ovf.u8", "ulong")); - conversions(sourceType: "nint", destType: "float?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.r4", "float"), expectedExplicitIL: convToNullableT("conv.r4", "float"), null); - conversions(sourceType: "nint", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.r8", "double"), expectedExplicitIL: convToNullableT("conv.r8", "double"), null); - conversions(sourceType: "nint", destType: "decimal?", ImplicitNullableNumeric, + conversions(sourceType: "System.IntPtr", destType: "System.IntPtr", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + conversions(sourceType: "System.IntPtr", destType: "System.UIntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); + + // System.IntPtr to nullable type + conversions(sourceType: "System.IntPtr", destType: "E?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i4", "E"), expectedCheckedIL: convToNullableT("conv.ovf.i4", "E")); + conversions(sourceType: "System.IntPtr", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "System.IntPtr", destType: "char?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u2", "char"), expectedCheckedIL: convToNullableT("conv.ovf.u2", "char")); + conversions(sourceType: "System.IntPtr", destType: "sbyte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i1", "sbyte"), expectedCheckedIL: convToNullableT("conv.ovf.i1", "sbyte")); + conversions(sourceType: "System.IntPtr", destType: "byte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u1", "byte"), expectedCheckedIL: convToNullableT("conv.ovf.u1", "byte")); + conversions(sourceType: "System.IntPtr", destType: "short?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i2", "short"), expectedCheckedIL: convToNullableT("conv.ovf.i2", "short")); + conversions(sourceType: "System.IntPtr", destType: "ushort?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u2", "ushort"), expectedCheckedIL: convToNullableT("conv.ovf.u2", "ushort")); + conversions(sourceType: "System.IntPtr", destType: "int?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i4", "int"), expectedCheckedIL: convToNullableT("conv.ovf.i4", "int")); + conversions(sourceType: "System.IntPtr", destType: "uint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u4", "uint"), expectedCheckedIL: convToNullableT("conv.ovf.u4", "uint")); + conversions(sourceType: "System.IntPtr", destType: "long?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.i8", "long"), expectedExplicitIL: convToNullableT("conv.i8", "long")); + conversions(sourceType: "System.IntPtr", destType: "ulong?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i8", "ulong"), expectedCheckedIL: convToNullableT("conv.ovf.u8", "ulong")); + conversions(sourceType: "System.IntPtr", destType: "float?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.r4", "float"), expectedExplicitIL: convToNullableT("conv.r4", "float"), null); + conversions(sourceType: "System.IntPtr", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.r8", "double"), expectedExplicitIL: convToNullableT("conv.r8", "double"), null); + conversions(sourceType: "System.IntPtr", destType: "decimal?", ImplicitNullableNumeric, @"{ // Code size 13 (0xd) .maxstack 1 @@ -7924,23 +5285,25 @@ .maxstack 1 IL_0007: newobj ""decimal?..ctor(decimal)"" IL_000c: ret }"); - conversions(sourceType: "nint", destType: "System.IntPtr?", ImplicitNullableIdentity, + conversions(sourceType: "System.IntPtr", destType: "System.IntPtr?", ImplicitNullableIdentity, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""System.IntPtr?..ctor(System.IntPtr)"" + IL_0001: newobj ""nint?..ctor(nint)"" IL_0006: ret }", @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""System.IntPtr?..ctor(System.IntPtr)"" + IL_0001: newobj ""nint?..ctor(nint)"" IL_0006: ret }"); - conversions(sourceType: "nint", destType: "System.UIntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nint?", destType: "object", Boxing, + conversions(sourceType: "System.IntPtr", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + + // nullable System.IntPtr to type + conversions(sourceType: "System.IntPtr?", destType: "object", Boxing, @"{ // Code size 7 (0x7) .maxstack 1 @@ -7955,23 +5318,23 @@ .maxstack 1 IL_0001: box ""nint?"" IL_0006: ret }"); - conversions(sourceType: "nint?", destType: "string", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nint?", destType: "void*", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nint?", destType: "delegate*", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nint?", destType: "E", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i4", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.i4", "nint")); - conversions(sourceType: "nint?", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nint?", destType: "char", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u2", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u2", "nint")); - conversions(sourceType: "nint?", destType: "sbyte", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i1", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.i1", "nint")); - conversions(sourceType: "nint?", destType: "byte", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u1", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u1", "nint")); - conversions(sourceType: "nint?", destType: "short", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i2", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.i2", "nint")); - conversions(sourceType: "nint?", destType: "ushort", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u2", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u2", "nint")); - conversions(sourceType: "nint?", destType: "int", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i4", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.i4", "nint")); - conversions(sourceType: "nint?", destType: "uint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u4", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u4", "nint")); - conversions(sourceType: "nint?", destType: "long", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i8", "nint")); - conversions(sourceType: "nint?", destType: "ulong", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i8", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u8", "nint")); - conversions(sourceType: "nint?", destType: "float", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.r4", "nint")); - conversions(sourceType: "nint?", destType: "double", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.r8", "nint")); - conversions(sourceType: "nint?", destType: "decimal", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, + conversions(sourceType: "System.IntPtr?", destType: "string", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "System.IntPtr?", destType: "void*", ExplicitUserDefined, expectedImplicitIL: null, expectedExplicitIL: convExplicitFromNullableT("nint", "void* nint.op_Explicit(nint)")); + conversions(sourceType: "System.IntPtr?", destType: "delegate*", ExplicitUserDefined, expectedImplicitIL: null, expectedExplicitIL: convExplicitFromNullableT("nint", "void* nint.op_Explicit(nint)")); + conversions(sourceType: "System.IntPtr?", destType: "E", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i4", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.i4", "nint")); + conversions(sourceType: "System.IntPtr?", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "System.IntPtr?", destType: "char", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u2", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u2", "nint")); + conversions(sourceType: "System.IntPtr?", destType: "sbyte", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i1", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.i1", "nint")); + conversions(sourceType: "System.IntPtr?", destType: "byte", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u1", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u1", "nint")); + conversions(sourceType: "System.IntPtr?", destType: "short", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i2", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.i2", "nint")); + conversions(sourceType: "System.IntPtr?", destType: "ushort", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u2", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u2", "nint")); + conversions(sourceType: "System.IntPtr?", destType: "int", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i4", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.i4", "nint")); + conversions(sourceType: "System.IntPtr?", destType: "uint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u4", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u4", "nint")); + conversions(sourceType: "System.IntPtr?", destType: "long", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i8", "nint")); + conversions(sourceType: "System.IntPtr?", destType: "ulong", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i8", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u8", "nint")); + conversions(sourceType: "System.IntPtr?", destType: "float", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.r4", "nint")); + conversions(sourceType: "System.IntPtr?", destType: "double", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.r8", "nint")); + conversions(sourceType: "System.IntPtr?", destType: "decimal", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, @"{ // Code size 14 (0xe) .maxstack 1 @@ -7981,7 +5344,7 @@ .maxstack 1 IL_0008: call ""decimal decimal.op_Implicit(long)"" IL_000d: ret }"); - conversions(sourceType: "nint?", destType: "System.IntPtr", ExplicitNullableIdentity, expectedImplicitIL: null, + conversions(sourceType: "System.IntPtr?", destType: "System.IntPtr", ExplicitNullableIdentity, expectedImplicitIL: null, @"{ // Code size 8 (0x8) .maxstack 1 @@ -7989,21 +5352,23 @@ .maxstack 1 IL_0002: call ""nint nint?.Value.get"" IL_0007: ret }"); - conversions(sourceType: "nint?", destType: "System.UIntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nint?", destType: "E?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i4", "nint", "E"), expectedCheckedIL: convFromToNullableT("conv.ovf.i4", "nint", "E")); - conversions(sourceType: "nint?", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nint?", destType: "char?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u2", "nint", "char"), expectedCheckedIL: convFromToNullableT("conv.ovf.u2", "nint", "char")); - conversions(sourceType: "nint?", destType: "sbyte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i1", "nint", "sbyte"), expectedCheckedIL: convFromToNullableT("conv.ovf.i1", "nint", "sbyte")); - conversions(sourceType: "nint?", destType: "byte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u1", "nint", "byte"), expectedCheckedIL: convFromToNullableT("conv.ovf.u1", "nint", "byte")); - conversions(sourceType: "nint?", destType: "short?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i2", "nint", "short"), expectedCheckedIL: convFromToNullableT("conv.ovf.i2", "nint", "short")); - conversions(sourceType: "nint?", destType: "ushort?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u2", "nint", "ushort"), expectedCheckedIL: convFromToNullableT("conv.ovf.u2", "nint", "ushort")); - conversions(sourceType: "nint?", destType: "int?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i4", "nint", "int"), expectedCheckedIL: convFromToNullableT("conv.ovf.i4", "nint", "int")); - conversions(sourceType: "nint?", destType: "uint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u4", "nint", "uint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u4", "nint", "uint")); - conversions(sourceType: "nint?", destType: "long?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.i8", "nint", "long"), expectedExplicitIL: convFromToNullableT("conv.i8", "nint", "long")); - conversions(sourceType: "nint?", destType: "ulong?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i8", "nint", "ulong"), expectedCheckedIL: convFromToNullableT("conv.ovf.u8", "nint", "ulong")); - conversions(sourceType: "nint?", destType: "float?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.r4", "nint", "float"), expectedExplicitIL: convFromToNullableT("conv.r4", "nint", "float"), null); - conversions(sourceType: "nint?", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.r8", "nint", "double"), expectedExplicitIL: convFromToNullableT("conv.r8", "nint", "double"), null); - conversions(sourceType: "nint?", destType: "decimal?", ImplicitNullableNumeric, + conversions(sourceType: "System.IntPtr?", destType: "System.UIntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "nint")); + + // nullable System.IntPtr to nullable type + conversions(sourceType: "System.IntPtr?", destType: "E?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i4", "nint", "E"), expectedCheckedIL: convFromToNullableT("conv.ovf.i4", "nint", "E")); + conversions(sourceType: "System.IntPtr?", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "System.IntPtr?", destType: "char?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u2", "nint", "char"), expectedCheckedIL: convFromToNullableT("conv.ovf.u2", "nint", "char")); + conversions(sourceType: "System.IntPtr?", destType: "sbyte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i1", "nint", "sbyte"), expectedCheckedIL: convFromToNullableT("conv.ovf.i1", "nint", "sbyte")); + conversions(sourceType: "System.IntPtr?", destType: "byte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u1", "nint", "byte"), expectedCheckedIL: convFromToNullableT("conv.ovf.u1", "nint", "byte")); + conversions(sourceType: "System.IntPtr?", destType: "short?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i2", "nint", "short"), expectedCheckedIL: convFromToNullableT("conv.ovf.i2", "nint", "short")); + conversions(sourceType: "System.IntPtr?", destType: "ushort?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u2", "nint", "ushort"), expectedCheckedIL: convFromToNullableT("conv.ovf.u2", "nint", "ushort")); + conversions(sourceType: "System.IntPtr?", destType: "int?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i4", "nint", "int"), expectedCheckedIL: convFromToNullableT("conv.ovf.i4", "nint", "int")); + conversions(sourceType: "System.IntPtr?", destType: "uint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u4", "nint", "uint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u4", "nint", "uint")); + conversions(sourceType: "System.IntPtr?", destType: "long?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.i8", "nint", "long"), expectedExplicitIL: convFromToNullableT("conv.i8", "nint", "long")); + conversions(sourceType: "System.IntPtr?", destType: "ulong?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i8", "nint", "ulong"), expectedCheckedIL: convFromToNullableT("conv.ovf.u8", "nint", "ulong")); + conversions(sourceType: "System.IntPtr?", destType: "float?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.r4", "nint", "float"), expectedExplicitIL: convFromToNullableT("conv.r4", "nint", "float"), null); + conversions(sourceType: "System.IntPtr?", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.r8", "nint", "double"), expectedExplicitIL: convFromToNullableT("conv.r8", "nint", "double"), null); + conversions(sourceType: "System.IntPtr?", destType: "decimal?", ImplicitNullableNumeric, @"{ // Code size 40 (0x28) .maxstack 1 @@ -8043,287 +5408,312 @@ .locals init (nint? V_0, IL_0017: call ""nint nint?.GetValueOrDefault()"" IL_001c: conv.i8 IL_001d: call ""decimal decimal.op_Implicit(long)"" - IL_0022: newobj ""decimal?..ctor(decimal)"" - IL_0027: ret -}"); - conversions(sourceType: "nint?", destType: "System.IntPtr?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "nint?", destType: "System.UIntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "object", destType: "nuint", Unboxing, expectedImplicitIL: null, -@"{ - // Code size 7 (0x7) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: unbox.any ""System.UIntPtr"" - IL_0006: ret -}"); - conversions(sourceType: "string", destType: "nuint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "void*", destType: "nuint", ExplicitPointerToInteger, expectedImplicitIL: null, expectedExplicitIL: convNone); - conversions(sourceType: "delegate*", destType: "nuint", ExplicitPointerToInteger, expectedImplicitIL: null, expectedExplicitIL: convNone); - conversions(sourceType: "E", destType: "nuint", ExplicitEnumeration, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.u")); - conversions(sourceType: "bool", destType: "nuint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char", destType: "nuint", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); - conversions(sourceType: "sbyte", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.u")); - conversions(sourceType: "byte", destType: "nuint", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); - conversions(sourceType: "short", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.u")); - conversions(sourceType: "ushort", destType: "nuint", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); - conversions(sourceType: "int", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.u")); - conversions(sourceType: "uint", destType: "nuint", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); - conversions(sourceType: "long", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); - conversions(sourceType: "ulong", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u.un")); - conversions(sourceType: "nint", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); - conversions(sourceType: "nuint", destType: "nuint", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "float", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); - conversions(sourceType: "double", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); - conversions(sourceType: "decimal", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, + IL_0022: newobj ""decimal?..ctor(decimal)"" + IL_0027: ret +}"); + conversions(sourceType: "System.IntPtr?", destType: "System.IntPtr?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + conversions(sourceType: "System.IntPtr?", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "nint", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "nint", "nuint")); + + // type to System.IntPtr + conversions(sourceType: "object", destType: "System.IntPtr", Unboxing, expectedImplicitIL: null, + @"{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: unbox.any ""nint"" + IL_0006: ret +}"); + conversions(sourceType: "string", destType: "System.IntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "void*", destType: "System.IntPtr", ExplicitPointerToInteger, expectedImplicitIL: null, expectedExplicitIL: convNone, expectedCheckedIL: conv("conv.ovf.i.un")); + conversions(sourceType: "delegate*", destType: "System.IntPtr", ExplicitPointerToInteger, expectedImplicitIL: null, expectedExplicitIL: convNone, expectedCheckedIL: conv("conv.ovf.i.un")); + conversions(sourceType: "E", destType: "System.IntPtr", ExplicitEnumeration, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i")); + conversions(sourceType: "bool", destType: "System.IntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "char", destType: "System.IntPtr", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); + conversions(sourceType: "sbyte", destType: "System.IntPtr", ImplicitNumeric, expectedImplicitIL: conv("conv.i"), expectedExplicitIL: conv("conv.i")); + conversions(sourceType: "byte", destType: "System.IntPtr", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); + conversions(sourceType: "short", destType: "System.IntPtr", ImplicitNumeric, expectedImplicitIL: conv("conv.i"), expectedExplicitIL: conv("conv.i")); + conversions(sourceType: "ushort", destType: "System.IntPtr", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); + conversions(sourceType: "int", destType: "System.IntPtr", ImplicitNumeric, expectedImplicitIL: conv("conv.i"), expectedExplicitIL: conv("conv.i")); + conversions(sourceType: "uint", destType: "System.IntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.i.un")); + conversions(sourceType: "long", destType: "System.IntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i")); + conversions(sourceType: "ulong", destType: "System.IntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i.un")); + conversions(sourceType: "nint", destType: "System.IntPtr", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + conversions(sourceType: "nuint", destType: "System.IntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i.un")); + conversions(sourceType: "float", destType: "System.IntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i")); + conversions(sourceType: "double", destType: "System.IntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i")); + conversions(sourceType: "decimal", destType: "System.IntPtr", ExplicitNumeric, expectedImplicitIL: null, @"{ // Code size 8 (0x8) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""ulong decimal.op_Explicit(decimal)"" - IL_0006: conv.u + IL_0001: call ""long decimal.op_Explicit(decimal)"" + IL_0006: conv.i IL_0007: ret }", @"{ // Code size 8 (0x8) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""ulong decimal.op_Explicit(decimal)"" - IL_0006: conv.ovf.u.un + IL_0001: call ""long decimal.op_Explicit(decimal)"" + IL_0006: conv.ovf.i IL_0007: ret }"); - conversions(sourceType: "System.IntPtr", destType: "nuint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.UIntPtr", destType: "nuint", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "E?", destType: "nuint", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "E"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "E")); - conversions(sourceType: "bool?", destType: "nuint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char?", destType: "nuint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "char")); - conversions(sourceType: "sbyte?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "sbyte"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "sbyte")); - conversions(sourceType: "byte?", destType: "nuint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "byte")); - conversions(sourceType: "short?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "short"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "short")); - conversions(sourceType: "ushort?", destType: "nuint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "ushort")); - conversions(sourceType: "int?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "int"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "int")); - conversions(sourceType: "uint?", destType: "nuint", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "uint")); - conversions(sourceType: "long?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "long"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "long")); - conversions(sourceType: "ulong?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "ulong"), expectedCheckedIL: convFromNullableT("conv.ovf.u.un", "ulong")); - conversions(sourceType: "nint?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "nint")); - conversions(sourceType: "nuint?", destType: "nuint", ExplicitNullableIdentity, expectedImplicitIL: null, + conversions(sourceType: "System.UIntPtr", destType: "System.IntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i.un")); + + // type to nullable System.IntPtr + conversions(sourceType: "object", destType: "System.IntPtr?", Unboxing, expectedImplicitIL: null, @"{ - // Code size 8 (0x8) + // Code size 7 (0x7) .maxstack 1 - IL_0000: ldarga.s V_0 - IL_0002: call ""nuint nuint?.Value.get"" - IL_0007: ret + IL_0000: ldarg.0 + IL_0001: unbox.any ""nint?"" + IL_0006: ret }"); - conversions(sourceType: "float?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "float"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "float")); - conversions(sourceType: "double?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "double"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "double")); - conversions(sourceType: "decimal?", destType: "nuint", ExplicitNullableNumeric, expectedImplicitIL: null, + conversions(sourceType: "string", destType: "System.IntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "void*", destType: "System.IntPtr?", ExplicitNullablePointerToInteger, expectedImplicitIL: null, @"{ - // Code size 14 (0xe) + // Code size 7 (0x7) .maxstack 1 - IL_0000: ldarga.s V_0 - IL_0002: call ""decimal decimal?.Value.get"" - IL_0007: call ""ulong decimal.op_Explicit(decimal)"" - IL_000c: conv.u - IL_000d: ret + IL_0000: ldarg.0 + IL_0001: newobj ""nint?..ctor(nint)"" + IL_0006: ret }", -@"{ - // Code size 14 (0xe) - .maxstack 1 - IL_0000: ldarga.s V_0 - IL_0002: call ""decimal decimal?.Value.get"" - IL_0007: call ""ulong decimal.op_Explicit(decimal)"" - IL_000c: conv.ovf.u.un - IL_000d: ret -}"); - conversions(sourceType: "System.IntPtr?", destType: "nuint", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.UIntPtr?", destType: "nuint", ExplicitNullableIdentity, expectedImplicitIL: null, @"{ // Code size 8 (0x8) .maxstack 1 - IL_0000: ldarga.s V_0 - IL_0002: call ""System.UIntPtr System.UIntPtr?.Value.get"" - IL_0007: ret -}"); - conversions(sourceType: "object", destType: "nuint?", Unboxing, expectedImplicitIL: null, -@"{ - // Code size 7 (0x7) - .maxstack 1 IL_0000: ldarg.0 - IL_0001: unbox.any ""nuint?"" - IL_0006: ret + IL_0001: conv.ovf.i.un + IL_0002: newobj ""nint?..ctor(nint)"" + IL_0007: ret }"); - conversions(sourceType: "string", destType: "nuint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "void*", destType: "nuint?", ExplicitNullablePointerToInteger, expectedImplicitIL: null, + conversions(sourceType: "delegate*", destType: "System.IntPtr?", ExplicitNullablePointerToInteger, expectedImplicitIL: null, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""nuint?..ctor(nuint)"" + IL_0001: newobj ""nint?..ctor(nint)"" IL_0006: ret -}"); - conversions(sourceType: "delegate*", destType: "nuint?", ExplicitNullablePointerToInteger, expectedImplicitIL: null, +}", @"{ - // Code size 7 (0x7) + // Code size 8 (0x8) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""nuint?..ctor(nuint)"" - IL_0006: ret + IL_0001: conv.ovf.i.un + IL_0002: newobj ""nint?..ctor(nint)"" + IL_0007: ret }"); - conversions(sourceType: "E", destType: "nuint?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); - conversions(sourceType: "bool", destType: "nuint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nuint"), expectedExplicitIL: convToNullableT("conv.u", "nuint")); - conversions(sourceType: "sbyte", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); - conversions(sourceType: "byte", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nuint"), expectedExplicitIL: convToNullableT("conv.u", "nuint")); - conversions(sourceType: "short", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); - conversions(sourceType: "ushort", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nuint"), expectedExplicitIL: convToNullableT("conv.u", "nuint")); - conversions(sourceType: "int", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); - conversions(sourceType: "uint", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nuint"), expectedExplicitIL: convToNullableT("conv.u", "nuint")); - conversions(sourceType: "long", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); - conversions(sourceType: "ulong", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u.un", "nuint")); - conversions(sourceType: "nint", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); - conversions(sourceType: "nuint", destType: "nuint?", ImplicitNullableIdentity, + conversions(sourceType: "E", destType: "System.IntPtr?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint")); + conversions(sourceType: "bool", destType: "System.IntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "char", destType: "System.IntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nint"), expectedExplicitIL: convToNullableT("conv.u", "nint")); + conversions(sourceType: "sbyte", destType: "System.IntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.i", "nint"), expectedExplicitIL: convToNullableT("conv.i", "nint")); + conversions(sourceType: "byte", destType: "System.IntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nint"), expectedExplicitIL: convToNullableT("conv.u", "nint")); + conversions(sourceType: "short", destType: "System.IntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.i", "nint"), expectedExplicitIL: convToNullableT("conv.i", "nint")); + conversions(sourceType: "ushort", destType: "System.IntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nint"), expectedExplicitIL: convToNullableT("conv.u", "nint")); + conversions(sourceType: "int", destType: "System.IntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.i", "nint"), expectedExplicitIL: convToNullableT("conv.i", "nint")); + conversions(sourceType: "uint", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i.un", "nint")); + conversions(sourceType: "long", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i", "nint")); + conversions(sourceType: "ulong", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i.un", "nint")); + conversions(sourceType: "nint", destType: "System.IntPtr?", ImplicitNullableIdentity, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""nuint?..ctor(nuint)"" + IL_0001: newobj ""nint?..ctor(nint)"" IL_0006: ret }", @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""nuint?..ctor(nuint)"" + IL_0001: newobj ""nint?..ctor(nint)"" IL_0006: ret }"); - conversions(sourceType: "float", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); - conversions(sourceType: "double", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); - conversions(sourceType: "decimal", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, + conversions(sourceType: "nuint", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i.un", "nint")); + conversions(sourceType: "float", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i", "nint")); + conversions(sourceType: "double", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i", "nint")); + conversions(sourceType: "decimal", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, @"{ // Code size 13 (0xd) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""ulong decimal.op_Explicit(decimal)"" - IL_0006: conv.u - IL_0007: newobj ""nuint?..ctor(nuint)"" + IL_0001: call ""long decimal.op_Explicit(decimal)"" + IL_0006: conv.i + IL_0007: newobj ""nint?..ctor(nint)"" IL_000c: ret }", @"{ // Code size 13 (0xd) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""ulong decimal.op_Explicit(decimal)"" - IL_0006: conv.ovf.u.un - IL_0007: newobj ""nuint?..ctor(nuint)"" + IL_0001: call ""long decimal.op_Explicit(decimal)"" + IL_0006: conv.ovf.i + IL_0007: newobj ""nint?..ctor(nint)"" IL_000c: ret }"); - conversions(sourceType: "System.IntPtr", destType: "nuint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.UIntPtr", destType: "nuint?", ImplicitNullableIdentity, + conversions(sourceType: "System.IntPtr", destType: "System.IntPtr?", ImplicitNullableIdentity, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""nuint?..ctor(nuint)"" + IL_0001: newobj ""nint?..ctor(nint)"" IL_0006: ret }", @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""nuint?..ctor(nuint)"" + IL_0001: newobj ""nint?..ctor(nint)"" IL_0006: ret }"); - conversions(sourceType: "E?", destType: "nuint?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "E", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "E", "nuint")); - conversions(sourceType: "bool?", destType: "nuint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char?", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "char", "nuint"), expectedExplicitIL: convFromToNullableT("conv.u", "char", "nuint")); - conversions(sourceType: "sbyte?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "sbyte", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "sbyte", "nuint")); - conversions(sourceType: "byte?", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "byte", "nuint"), expectedExplicitIL: convFromToNullableT("conv.u", "byte", "nuint")); - conversions(sourceType: "short?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "short", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "short", "nuint")); - conversions(sourceType: "ushort?", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "ushort", "nuint"), expectedExplicitIL: convFromToNullableT("conv.u", "ushort", "nuint")); - conversions(sourceType: "int?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "int", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "int", "nuint")); - conversions(sourceType: "uint?", destType: "nuint?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "uint", "nuint"), expectedExplicitIL: convFromToNullableT("conv.u", "uint", "nuint")); - conversions(sourceType: "long?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "long", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "long", "nuint")); - conversions(sourceType: "ulong?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "ulong", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u.un", "ulong", "nuint")); - conversions(sourceType: "nint?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "nint", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "nint", "nuint")); - conversions(sourceType: "nuint?", destType: "nuint?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "float?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "float", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "float", "nuint")); - conversions(sourceType: "double?", destType: "nuint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "double", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "double", "nuint")); - conversions(sourceType: "decimal?", destType: "nuint?", ExplicitNullableNumeric, null, + conversions(sourceType: "System.UIntPtr", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i.un", "nint")); + + // nullable type to System.IntPtr + conversions(sourceType: "E?", destType: "System.IntPtr", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "E")); + conversions(sourceType: "bool?", destType: "System.IntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "char?", destType: "System.IntPtr", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "char")); + conversions(sourceType: "sbyte?", destType: "System.IntPtr", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "sbyte")); + conversions(sourceType: "byte?", destType: "System.IntPtr", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "byte")); + conversions(sourceType: "short?", destType: "System.IntPtr", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "short")); + conversions(sourceType: "ushort?", destType: "System.IntPtr", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "ushort")); + conversions(sourceType: "int?", destType: "System.IntPtr", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "int")); + conversions(sourceType: "uint?", destType: "System.IntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "uint"), expectedCheckedIL: convFromNullableT("conv.ovf.i.un", "uint")); + conversions(sourceType: "long?", destType: "System.IntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "long"), expectedCheckedIL: convFromNullableT("conv.ovf.i", "long")); + conversions(sourceType: "ulong?", destType: "System.IntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "ulong"), expectedCheckedIL: convFromNullableT("conv.ovf.i.un", "ulong")); + conversions(sourceType: "nint?", destType: "System.IntPtr", ExplicitNullableIdentity, expectedImplicitIL: null, +@"{ + // Code size 8 (0x8) + .maxstack 1 + IL_0000: ldarga.s V_0 + IL_0002: call ""nint nint?.Value.get"" + IL_0007: ret +}"); + conversions(sourceType: "nuint?", destType: "System.IntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i.un", "nuint")); + conversions(sourceType: "float?", destType: "System.IntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "float"), expectedCheckedIL: convFromNullableT("conv.ovf.i", "float")); + conversions(sourceType: "double?", destType: "System.IntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "double"), expectedCheckedIL: convFromNullableT("conv.ovf.i", "double")); + conversions(sourceType: "decimal?", destType: "System.IntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, +@"{ + // Code size 14 (0xe) + .maxstack 1 + IL_0000: ldarga.s V_0 + IL_0002: call ""decimal decimal?.Value.get"" + IL_0007: call ""long decimal.op_Explicit(decimal)"" + IL_000c: conv.i + IL_000d: ret +}", +@"{ + // Code size 14 (0xe) + .maxstack 1 + IL_0000: ldarga.s V_0 + IL_0002: call ""decimal decimal?.Value.get"" + IL_0007: call ""long decimal.op_Explicit(decimal)"" + IL_000c: conv.ovf.i + IL_000d: ret +}"); + conversions(sourceType: "System.IntPtr?", destType: "System.IntPtr", ExplicitNullableIdentity, expectedImplicitIL: null, +@"{ + // Code size 8 (0x8) + .maxstack 1 + IL_0000: ldarga.s V_0 + IL_0002: call ""nint nint?.Value.get"" + IL_0007: ret +}"); + conversions(sourceType: "System.UIntPtr?", destType: "System.IntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i.un", "nuint")); + + // nullable type to nullable System.IntPtr + conversions(sourceType: "E?", destType: "System.IntPtr?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "E", "nint")); + conversions(sourceType: "bool?", destType: "System.IntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "char?", destType: "System.IntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "char", "nint"), expectedExplicitIL: convFromToNullableT("conv.u", "char", "nint")); + conversions(sourceType: "sbyte?", destType: "System.IntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.i", "sbyte", "nint"), expectedExplicitIL: convFromToNullableT("conv.i", "sbyte", "nint")); + conversions(sourceType: "byte?", destType: "System.IntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "byte", "nint"), expectedExplicitIL: convFromToNullableT("conv.u", "byte", "nint")); + conversions(sourceType: "short?", destType: "System.IntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.i", "short", "nint"), expectedExplicitIL: convFromToNullableT("conv.i", "short", "nint")); + conversions(sourceType: "ushort?", destType: "System.IntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "ushort", "nint"), expectedExplicitIL: convFromToNullableT("conv.u", "ushort", "nint")); + conversions(sourceType: "int?", destType: "System.IntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.i", "int", "nint"), expectedExplicitIL: convFromToNullableT("conv.i", "int", "nint")); + conversions(sourceType: "uint?", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "uint", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i.un", "uint", "nint")); + conversions(sourceType: "long?", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "long", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i", "long", "nint")); + conversions(sourceType: "ulong?", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "ulong", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i.un", "ulong", "nint")); + conversions(sourceType: "nint?", destType: "System.IntPtr?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + conversions(sourceType: "nuint?", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "nuint", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i.un", "nuint", "nint")); + conversions(sourceType: "float?", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "float", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i", "float", "nint")); + conversions(sourceType: "double?", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "double", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i", "double", "nint")); + conversions(sourceType: "decimal?", destType: "System.IntPtr?", ExplicitNullableNumeric, null, @"{ // Code size 40 (0x28) .maxstack 1 .locals init (decimal? V_0, - nuint? V_1) + nint? V_1) IL_0000: ldarg.0 IL_0001: stloc.0 IL_0002: ldloca.s V_0 IL_0004: call ""bool decimal?.HasValue.get"" IL_0009: brtrue.s IL_0015 IL_000b: ldloca.s V_1 - IL_000d: initobj ""nuint?"" + IL_000d: initobj ""nint?"" IL_0013: ldloc.1 IL_0014: ret IL_0015: ldloca.s V_0 IL_0017: call ""decimal decimal?.GetValueOrDefault()"" - IL_001c: call ""ulong decimal.op_Explicit(decimal)"" - IL_0021: conv.u - IL_0022: newobj ""nuint?..ctor(nuint)"" + IL_001c: call ""long decimal.op_Explicit(decimal)"" + IL_0021: conv.i + IL_0022: newobj ""nint?..ctor(nint)"" IL_0027: ret }", @"{ // Code size 40 (0x28) .maxstack 1 .locals init (decimal? V_0, - nuint? V_1) + nint? V_1) IL_0000: ldarg.0 IL_0001: stloc.0 IL_0002: ldloca.s V_0 IL_0004: call ""bool decimal?.HasValue.get"" IL_0009: brtrue.s IL_0015 IL_000b: ldloca.s V_1 - IL_000d: initobj ""nuint?"" + IL_000d: initobj ""nint?"" IL_0013: ldloc.1 IL_0014: ret IL_0015: ldloca.s V_0 IL_0017: call ""decimal decimal?.GetValueOrDefault()"" - IL_001c: call ""ulong decimal.op_Explicit(decimal)"" - IL_0021: conv.ovf.u.un - IL_0022: newobj ""nuint?..ctor(nuint)"" + IL_001c: call ""long decimal.op_Explicit(decimal)"" + IL_0021: conv.ovf.i + IL_0022: newobj ""nint?..ctor(nint)"" IL_0027: ret }"); - conversions(sourceType: "System.IntPtr?", destType: "nuint?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.UIntPtr?", destType: "nuint?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "nuint", destType: "object", Boxing, + conversions(sourceType: "System.IntPtr?", destType: "System.IntPtr?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + conversions(sourceType: "System.UIntPtr?", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "nuint", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i.un", "nuint", "nint")); + + // System.UIntPtr to type + conversions(sourceType: "System.UIntPtr", destType: "object", Boxing, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: box ""System.UIntPtr"" + IL_0001: box ""nuint"" IL_0006: ret }", @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: box ""System.UIntPtr"" + IL_0001: box ""nuint"" IL_0006: ret }"); - conversions(sourceType: "nuint", destType: "string", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nuint", destType: "void*", ExplicitIntegerToPointer, expectedImplicitIL: null, expectedExplicitIL: convNone); - conversions(sourceType: "nuint", destType: "delegate*", ExplicitIntegerToPointer, expectedImplicitIL: null, expectedExplicitIL: convNone); - conversions(sourceType: "nuint", destType: "E", ExplicitEnumeration, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i4"), expectedCheckedIL: conv("conv.ovf.i4.un")); - conversions(sourceType: "nuint", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nuint", destType: "char", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u2"), expectedCheckedIL: conv("conv.ovf.u2.un")); - conversions(sourceType: "nuint", destType: "sbyte", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i1"), expectedCheckedIL: conv("conv.ovf.i1.un")); - conversions(sourceType: "nuint", destType: "byte", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u1"), expectedCheckedIL: conv("conv.ovf.u1.un")); - conversions(sourceType: "nuint", destType: "short", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i2"), expectedCheckedIL: conv("conv.ovf.i2.un")); - conversions(sourceType: "nuint", destType: "ushort", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u2"), expectedCheckedIL: conv("conv.ovf.u2.un")); - conversions(sourceType: "nuint", destType: "int", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i4"), expectedCheckedIL: conv("conv.ovf.i4.un")); - conversions(sourceType: "nuint", destType: "uint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u4"), expectedCheckedIL: conv("conv.ovf.u4.un")); - conversions(sourceType: "nuint", destType: "long", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u8"), expectedCheckedIL: conv("conv.ovf.i8.un")); - conversions(sourceType: "nuint", destType: "ulong", ImplicitNumeric, expectedImplicitIL: conv("conv.u8"), expectedExplicitIL: conv("conv.u8")); - conversions(sourceType: "nuint", destType: "float", ImplicitNumeric, expectedImplicitIL: conv("conv.r4"), expectedExplicitIL: conv("conv.r4")); - conversions(sourceType: "nuint", destType: "double", ImplicitNumeric, expectedImplicitIL: conv("conv.r8"), expectedExplicitIL: conv("conv.r8")); - conversions(sourceType: "nuint", destType: "decimal", ImplicitNumeric, + conversions(sourceType: "System.UIntPtr", destType: "string", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "System.UIntPtr", destType: "void*", ExplicitIntegerToPointer, expectedImplicitIL: null, expectedExplicitIL: convNone); + conversions(sourceType: "System.UIntPtr", destType: "delegate*", ExplicitIntegerToPointer, expectedImplicitIL: null, expectedExplicitIL: convNone); + conversions(sourceType: "System.UIntPtr", destType: "E", ExplicitEnumeration, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i4"), expectedCheckedIL: conv("conv.ovf.i4.un")); + conversions(sourceType: "System.UIntPtr", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "System.UIntPtr", destType: "char", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u2"), expectedCheckedIL: conv("conv.ovf.u2.un")); + conversions(sourceType: "System.UIntPtr", destType: "sbyte", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i1"), expectedCheckedIL: conv("conv.ovf.i1.un")); + conversions(sourceType: "System.UIntPtr", destType: "byte", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u1"), expectedCheckedIL: conv("conv.ovf.u1.un")); + conversions(sourceType: "System.UIntPtr", destType: "short", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i2"), expectedCheckedIL: conv("conv.ovf.i2.un")); + conversions(sourceType: "System.UIntPtr", destType: "ushort", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u2"), expectedCheckedIL: conv("conv.ovf.u2.un")); + conversions(sourceType: "System.UIntPtr", destType: "int", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i4"), expectedCheckedIL: conv("conv.ovf.i4.un")); + conversions(sourceType: "System.UIntPtr", destType: "uint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u4"), expectedCheckedIL: conv("conv.ovf.u4.un")); + conversions(sourceType: "System.UIntPtr", destType: "long", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u8"), expectedCheckedIL: conv("conv.ovf.i8.un")); + conversions(sourceType: "System.UIntPtr", destType: "ulong", ImplicitNumeric, expectedImplicitIL: conv("conv.u8"), expectedExplicitIL: conv("conv.u8")); + conversions(sourceType: "System.UIntPtr", destType: "float", ImplicitNumeric, expectedImplicitIL: conv("conv.r4"), expectedExplicitIL: conv("conv.r4")); + conversions(sourceType: "System.UIntPtr", destType: "double", ImplicitNumeric, expectedImplicitIL: conv("conv.r8"), expectedExplicitIL: conv("conv.r8")); + conversions(sourceType: "System.UIntPtr", destType: "decimal", ImplicitNumeric, @"{ // Code size 8 (0x8) .maxstack 1 @@ -8333,29 +5723,31 @@ .maxstack 1 IL_0007: ret }", @"{ - // Code size 8 (0x8) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: conv.u8 - IL_0002: call ""decimal decimal.op_Implicit(ulong)"" - IL_0007: ret -}"); - conversions(sourceType: "nuint", destType: "System.IntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nuint", destType: "System.UIntPtr", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "nuint", destType: "E?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i4", "E"), expectedCheckedIL: convToNullableT("conv.ovf.i4.un", "E")); - conversions(sourceType: "nuint", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nuint", destType: "char?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u2", "char"), expectedCheckedIL: convToNullableT("conv.ovf.u2.un", "char")); - conversions(sourceType: "nuint", destType: "sbyte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i1", "sbyte"), expectedCheckedIL: convToNullableT("conv.ovf.i1.un", "sbyte")); - conversions(sourceType: "nuint", destType: "byte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u1", "byte"), expectedCheckedIL: convToNullableT("conv.ovf.u1.un", "byte")); - conversions(sourceType: "nuint", destType: "short?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i2", "short"), expectedCheckedIL: convToNullableT("conv.ovf.i2.un", "short")); - conversions(sourceType: "nuint", destType: "ushort?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u2", "ushort"), expectedCheckedIL: convToNullableT("conv.ovf.u2.un", "ushort")); - conversions(sourceType: "nuint", destType: "int?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i4", "int"), expectedCheckedIL: convToNullableT("conv.ovf.i4.un", "int")); - conversions(sourceType: "nuint", destType: "uint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u4", "uint"), expectedCheckedIL: convToNullableT("conv.ovf.u4.un", "uint")); - conversions(sourceType: "nuint", destType: "long?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u8", "long"), expectedCheckedIL: convToNullableT("conv.ovf.i8.un", "long")); - conversions(sourceType: "nuint", destType: "ulong?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u8", "ulong"), expectedExplicitIL: convToNullableT("conv.u8", "ulong")); - conversions(sourceType: "nuint", destType: "float?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.r4", "float"), expectedExplicitIL: convToNullableT("conv.r4", "float"), null); - conversions(sourceType: "nuint", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.r8", "double"), expectedExplicitIL: convToNullableT("conv.r8", "double"), null); - conversions(sourceType: "nuint", destType: "decimal?", ImplicitNullableNumeric, + // Code size 8 (0x8) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: conv.u8 + IL_0002: call ""decimal decimal.op_Implicit(ulong)"" + IL_0007: ret +}"); + conversions(sourceType: "System.UIntPtr", destType: "System.IntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.i.un")); + conversions(sourceType: "System.UIntPtr", destType: "System.UIntPtr", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + + // System.UIntPtr to nullable type + conversions(sourceType: "System.UIntPtr", destType: "E?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i4", "E"), expectedCheckedIL: convToNullableT("conv.ovf.i4.un", "E")); + conversions(sourceType: "System.UIntPtr", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "System.UIntPtr", destType: "char?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u2", "char"), expectedCheckedIL: convToNullableT("conv.ovf.u2.un", "char")); + conversions(sourceType: "System.UIntPtr", destType: "sbyte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i1", "sbyte"), expectedCheckedIL: convToNullableT("conv.ovf.i1.un", "sbyte")); + conversions(sourceType: "System.UIntPtr", destType: "byte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u1", "byte"), expectedCheckedIL: convToNullableT("conv.ovf.u1.un", "byte")); + conversions(sourceType: "System.UIntPtr", destType: "short?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i2", "short"), expectedCheckedIL: convToNullableT("conv.ovf.i2.un", "short")); + conversions(sourceType: "System.UIntPtr", destType: "ushort?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u2", "ushort"), expectedCheckedIL: convToNullableT("conv.ovf.u2.un", "ushort")); + conversions(sourceType: "System.UIntPtr", destType: "int?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i4", "int"), expectedCheckedIL: convToNullableT("conv.ovf.i4.un", "int")); + conversions(sourceType: "System.UIntPtr", destType: "uint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u4", "uint"), expectedCheckedIL: convToNullableT("conv.ovf.u4.un", "uint")); + conversions(sourceType: "System.UIntPtr", destType: "long?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u8", "long"), expectedCheckedIL: convToNullableT("conv.ovf.i8.un", "long")); + conversions(sourceType: "System.UIntPtr", destType: "ulong?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u8", "ulong"), expectedExplicitIL: convToNullableT("conv.u8", "ulong")); + conversions(sourceType: "System.UIntPtr", destType: "float?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.r4", "float"), expectedExplicitIL: convToNullableT("conv.r4", "float"), null); + conversions(sourceType: "System.UIntPtr", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.r8", "double"), expectedExplicitIL: convToNullableT("conv.r8", "double"), null); + conversions(sourceType: "System.UIntPtr", destType: "decimal?", ImplicitNullableNumeric, @"{ // Code size 13 (0xd) .maxstack 1 @@ -8374,23 +5766,25 @@ .maxstack 1 IL_0007: newobj ""decimal?..ctor(decimal)"" IL_000c: ret }"); - conversions(sourceType: "nuint", destType: "System.IntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nuint", destType: "System.UIntPtr?", ImplicitNullableIdentity, + conversions(sourceType: "System.UIntPtr", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nint"), expectedCheckedIL: convToNullableT("conv.ovf.i.un", "nint")); + conversions(sourceType: "System.UIntPtr", destType: "System.UIntPtr?", ImplicitNullableIdentity, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""System.UIntPtr?..ctor(System.UIntPtr)"" + IL_0001: newobj ""nuint?..ctor(nuint)"" IL_0006: ret }", @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""System.UIntPtr?..ctor(System.UIntPtr)"" + IL_0001: newobj ""nuint?..ctor(nuint)"" IL_0006: ret }"); - conversions(sourceType: "nuint?", destType: "object", Boxing, + + // nullable System.UIntPtr to type + conversions(sourceType: "System.UIntPtr?", destType: "object", Boxing, @"{ // Code size 7 (0x7) .maxstack 1 @@ -8405,23 +5799,23 @@ .maxstack 1 IL_0001: box ""nuint?"" IL_0006: ret }"); - conversions(sourceType: "nuint?", destType: "string", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nuint?", destType: "void*", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nuint?", destType: "delegate*", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nuint?", destType: "E", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i4", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i4.un", "nuint")); - conversions(sourceType: "nuint?", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nuint?", destType: "char", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u2", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.u2.un", "nuint")); - conversions(sourceType: "nuint?", destType: "sbyte", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i1", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i1.un", "nuint")); - conversions(sourceType: "nuint?", destType: "byte", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u1", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.u1.un", "nuint")); - conversions(sourceType: "nuint?", destType: "short", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i2", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i2.un", "nuint")); - conversions(sourceType: "nuint?", destType: "ushort", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u2", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.u2.un", "nuint")); - conversions(sourceType: "nuint?", destType: "int", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i4", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i4.un", "nuint")); - conversions(sourceType: "nuint?", destType: "uint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u4", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.u4.un", "nuint")); - conversions(sourceType: "nuint?", destType: "long", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u8", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i8.un", "nuint")); - conversions(sourceType: "nuint?", destType: "ulong", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u8", "nuint")); - conversions(sourceType: "nuint?", destType: "float", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.r4", "nuint")); - conversions(sourceType: "nuint?", destType: "double", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.r8", "nuint")); - conversions(sourceType: "nuint?", destType: "decimal", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, + conversions(sourceType: "System.UIntPtr?", destType: "string", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "System.UIntPtr?", destType: "void*", ExplicitUserDefined, expectedImplicitIL: null, expectedExplicitIL: convExplicitFromNullableT("nuint", "void* nuint.op_Explicit(nuint)")); + conversions(sourceType: "System.UIntPtr?", destType: "delegate*", ExplicitUserDefined, expectedImplicitIL: null, expectedExplicitIL: convExplicitFromNullableT("nuint", "void* nuint.op_Explicit(nuint)")); + conversions(sourceType: "System.UIntPtr?", destType: "E", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i4", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i4.un", "nuint")); + conversions(sourceType: "System.UIntPtr?", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "System.UIntPtr?", destType: "char", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u2", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.u2.un", "nuint")); + conversions(sourceType: "System.UIntPtr?", destType: "sbyte", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i1", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i1.un", "nuint")); + conversions(sourceType: "System.UIntPtr?", destType: "byte", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u1", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.u1.un", "nuint")); + conversions(sourceType: "System.UIntPtr?", destType: "short", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i2", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i2.un", "nuint")); + conversions(sourceType: "System.UIntPtr?", destType: "ushort", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u2", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.u2.un", "nuint")); + conversions(sourceType: "System.UIntPtr?", destType: "int", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i4", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i4.un", "nuint")); + conversions(sourceType: "System.UIntPtr?", destType: "uint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u4", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.u4.un", "nuint")); + conversions(sourceType: "System.UIntPtr?", destType: "long", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u8", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i8.un", "nuint")); + conversions(sourceType: "System.UIntPtr?", destType: "ulong", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u8", "nuint")); + conversions(sourceType: "System.UIntPtr?", destType: "float", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.r4", "nuint")); + conversions(sourceType: "System.UIntPtr?", destType: "double", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.r8", "nuint")); + conversions(sourceType: "System.UIntPtr?", destType: "decimal", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, @"{ // Code size 14 (0xe) .maxstack 1 @@ -8431,8 +5825,8 @@ .maxstack 1 IL_0008: call ""decimal decimal.op_Implicit(ulong)"" IL_000d: ret }"); - conversions(sourceType: "nuint?", destType: "System.IntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nuint?", destType: "System.UIntPtr", ExplicitNullableIdentity, expectedImplicitIL: null, + conversions(sourceType: "System.UIntPtr?", destType: "System.IntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "nuint"), expectedCheckedIL: convFromNullableT("conv.ovf.i.un", "nuint")); + conversions(sourceType: "System.UIntPtr?", destType: "System.UIntPtr", ExplicitNullableIdentity, expectedImplicitIL: null, @"{ // Code size 8 (0x8) .maxstack 1 @@ -8440,20 +5834,22 @@ .maxstack 1 IL_0002: call ""nuint nuint?.Value.get"" IL_0007: ret }"); - conversions(sourceType: "nuint?", destType: "E?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i4", "nuint", "E"), expectedCheckedIL: convFromToNullableT("conv.ovf.i4.un", "nuint", "E")); - conversions(sourceType: "nuint?", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nuint?", destType: "char?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u2", "nuint", "char"), expectedCheckedIL: convFromToNullableT("conv.ovf.u2.un", "nuint", "char")); - conversions(sourceType: "nuint?", destType: "sbyte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i1", "nuint", "sbyte"), expectedCheckedIL: convFromToNullableT("conv.ovf.i1.un", "nuint", "sbyte")); - conversions(sourceType: "nuint?", destType: "byte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u1", "nuint", "byte"), expectedCheckedIL: convFromToNullableT("conv.ovf.u1.un", "nuint", "byte")); - conversions(sourceType: "nuint?", destType: "short?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i2", "nuint", "short"), expectedCheckedIL: convFromToNullableT("conv.ovf.i2.un", "nuint", "short")); - conversions(sourceType: "nuint?", destType: "ushort?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u2", "nuint", "ushort"), expectedCheckedIL: convFromToNullableT("conv.ovf.u2.un", "nuint", "ushort")); - conversions(sourceType: "nuint?", destType: "int?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i4", "nuint", "int"), expectedCheckedIL: convFromToNullableT("conv.ovf.i4.un", "nuint", "int")); - conversions(sourceType: "nuint?", destType: "uint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u4", "nuint", "uint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u4.un", "nuint", "uint")); - conversions(sourceType: "nuint?", destType: "long?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u8", "nuint", "long"), expectedCheckedIL: convFromToNullableT("conv.ovf.i8.un", "nuint", "long")); - conversions(sourceType: "nuint?", destType: "ulong?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u8", "nuint", "ulong"), expectedExplicitIL: convFromToNullableT("conv.u8", "nuint", "ulong")); - conversions(sourceType: "nuint?", destType: "float?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.r4", "nuint", "float"), expectedExplicitIL: convFromToNullableT("conv.r4", "nuint", "float"), null); - conversions(sourceType: "nuint?", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.r8", "nuint", "double"), expectedExplicitIL: convFromToNullableT("conv.r8", "nuint", "double"), null); - conversions(sourceType: "nuint?", destType: "decimal?", ImplicitNullableNumeric, + + // nullable System.UIntPtr to nullable type + conversions(sourceType: "System.UIntPtr?", destType: "E?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i4", "nuint", "E"), expectedCheckedIL: convFromToNullableT("conv.ovf.i4.un", "nuint", "E")); + conversions(sourceType: "System.UIntPtr?", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "System.UIntPtr?", destType: "char?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u2", "nuint", "char"), expectedCheckedIL: convFromToNullableT("conv.ovf.u2.un", "nuint", "char")); + conversions(sourceType: "System.UIntPtr?", destType: "sbyte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i1", "nuint", "sbyte"), expectedCheckedIL: convFromToNullableT("conv.ovf.i1.un", "nuint", "sbyte")); + conversions(sourceType: "System.UIntPtr?", destType: "byte?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u1", "nuint", "byte"), expectedCheckedIL: convFromToNullableT("conv.ovf.u1.un", "nuint", "byte")); + conversions(sourceType: "System.UIntPtr?", destType: "short?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i2", "nuint", "short"), expectedCheckedIL: convFromToNullableT("conv.ovf.i2.un", "nuint", "short")); + conversions(sourceType: "System.UIntPtr?", destType: "ushort?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u2", "nuint", "ushort"), expectedCheckedIL: convFromToNullableT("conv.ovf.u2.un", "nuint", "ushort")); + conversions(sourceType: "System.UIntPtr?", destType: "int?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i4", "nuint", "int"), expectedCheckedIL: convFromToNullableT("conv.ovf.i4.un", "nuint", "int")); + conversions(sourceType: "System.UIntPtr?", destType: "uint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u4", "nuint", "uint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u4.un", "nuint", "uint")); + conversions(sourceType: "System.UIntPtr?", destType: "long?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u8", "nuint", "long"), expectedCheckedIL: convFromToNullableT("conv.ovf.i8.un", "nuint", "long")); + conversions(sourceType: "System.UIntPtr?", destType: "ulong?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u8", "nuint", "ulong"), expectedExplicitIL: convFromToNullableT("conv.u8", "nuint", "ulong")); + conversions(sourceType: "System.UIntPtr?", destType: "float?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.r4", "nuint", "float"), expectedExplicitIL: convFromToNullableT("conv.r4", "nuint", "float"), null); + conversions(sourceType: "System.UIntPtr?", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.r8", "nuint", "double"), expectedExplicitIL: convFromToNullableT("conv.r8", "nuint", "double"), null); + conversions(sourceType: "System.UIntPtr?", destType: "decimal?", ImplicitNullableNumeric, @"{ // Code size 40 (0x28) .maxstack 1 @@ -8496,602 +5892,268 @@ .locals init (nuint? V_0, IL_0022: newobj ""decimal?..ctor(decimal)"" IL_0027: ret }"); - conversions(sourceType: "nuint?", destType: "System.IntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "nuint?", destType: "System.UIntPtr?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "System.IntPtr", destType: "object", Boxing, + conversions(sourceType: "System.UIntPtr?", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "nuint", "nint"), expectedCheckedIL: convFromToNullableT("conv.ovf.i.un", "nuint", "nint")); + conversions(sourceType: "System.UIntPtr?", destType: "System.UIntPtr?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + + // type to System.UIntPtr + conversions(sourceType: "object", destType: "System.UIntPtr", Unboxing, expectedImplicitIL: null, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: box ""System.IntPtr"" + IL_0001: unbox.any ""nuint"" IL_0006: ret -}", +}"); + conversions(sourceType: "string", destType: "System.UIntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "void*", destType: "System.UIntPtr", ExplicitPointerToInteger, expectedImplicitIL: null, expectedExplicitIL: convNone); + conversions(sourceType: "delegate*", destType: "System.UIntPtr", ExplicitPointerToInteger, expectedImplicitIL: null, expectedExplicitIL: convNone); + conversions(sourceType: "E", destType: "System.UIntPtr", ExplicitEnumeration, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "bool", destType: "System.UIntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "char", destType: "System.UIntPtr", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); + conversions(sourceType: "sbyte", destType: "System.UIntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "byte", destType: "System.UIntPtr", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); + conversions(sourceType: "short", destType: "System.UIntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "ushort", destType: "System.UIntPtr", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); + conversions(sourceType: "int", destType: "System.UIntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.i"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "uint", destType: "System.UIntPtr", ImplicitNumeric, expectedImplicitIL: conv("conv.u"), expectedExplicitIL: conv("conv.u")); + conversions(sourceType: "long", destType: "System.UIntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "ulong", destType: "System.UIntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u.un")); + conversions(sourceType: "nint", destType: "System.UIntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "nuint", destType: "System.UIntPtr", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + conversions(sourceType: "float", destType: "System.UIntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "double", destType: "System.UIntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "decimal", destType: "System.UIntPtr", ExplicitNumeric, expectedImplicitIL: null, @"{ - // Code size 7 (0x7) + // Code size 8 (0x8) .maxstack 1 IL_0000: ldarg.0 - IL_0001: box ""System.IntPtr"" - IL_0006: ret -}"); - conversions(sourceType: "System.IntPtr", destType: "string", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.IntPtr", destType: "void*", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("void* System.IntPtr.op_Explicit(System.IntPtr)")); - conversions(sourceType: "System.IntPtr", destType: "delegate*", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("void* System.IntPtr.op_Explicit(System.IntPtr)")); - conversions(sourceType: "System.IntPtr", destType: "E", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("int System.IntPtr.op_Explicit(System.IntPtr)")); - conversions(sourceType: "System.IntPtr", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.IntPtr", destType: "char", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("int System.IntPtr.op_Explicit(System.IntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicit("int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u2")); - conversions(sourceType: "System.IntPtr", destType: "sbyte", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("int System.IntPtr.op_Explicit(System.IntPtr)", "conv.i1"), expectedCheckedIL: convAndExplicit("int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.i1")); - conversions(sourceType: "System.IntPtr", destType: "byte", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("int System.IntPtr.op_Explicit(System.IntPtr)", "conv.u1"), expectedCheckedIL: convAndExplicit("int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u1")); - conversions(sourceType: "System.IntPtr", destType: "short", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("int System.IntPtr.op_Explicit(System.IntPtr)", "conv.i2"), expectedCheckedIL: convAndExplicit("int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.i2")); - conversions(sourceType: "System.IntPtr", destType: "ushort", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("int System.IntPtr.op_Explicit(System.IntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicit("int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u2")); - conversions(sourceType: "System.IntPtr", destType: "int", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("int System.IntPtr.op_Explicit(System.IntPtr)")); - conversions(sourceType: "System.IntPtr", destType: "uint", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("int System.IntPtr.op_Explicit(System.IntPtr)"), expectedCheckedIL: convAndExplicit("int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u4")); - conversions(sourceType: "System.IntPtr", destType: "long", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("long System.IntPtr.op_Explicit(System.IntPtr)")); - conversions(sourceType: "System.IntPtr", destType: "ulong", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("long System.IntPtr.op_Explicit(System.IntPtr)"), expectedCheckedIL: convAndExplicit("long System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u8")); - conversions(sourceType: "System.IntPtr", destType: "float", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("long System.IntPtr.op_Explicit(System.IntPtr)", "conv.r4")); - conversions(sourceType: "System.IntPtr", destType: "double", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("long System.IntPtr.op_Explicit(System.IntPtr)", "conv.r8")); - conversions(sourceType: "System.IntPtr", destType: "decimal", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 12 (0xc) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: call ""long System.IntPtr.op_Explicit(System.IntPtr)"" - IL_0006: call ""decimal decimal.op_Implicit(long)"" - IL_000b: ret -}"); - conversions(sourceType: "System.IntPtr", destType: "System.IntPtr", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "System.IntPtr", destType: "System.UIntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.IntPtr", destType: "E?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("E", "int System.IntPtr.op_Explicit(System.IntPtr)")); - conversions(sourceType: "System.IntPtr", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.IntPtr", destType: "char?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("char", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicitToNullableT("char", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u2")); - conversions(sourceType: "System.IntPtr", destType: "sbyte?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("sbyte", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.i1"), expectedCheckedIL: convAndExplicitToNullableT("sbyte", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.i1")); - conversions(sourceType: "System.IntPtr", destType: "byte?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("byte", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.u1"), expectedCheckedIL: convAndExplicitToNullableT("byte", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u1")); - conversions(sourceType: "System.IntPtr", destType: "short?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("short", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.i2"), expectedCheckedIL: convAndExplicitToNullableT("short", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.i2")); - conversions(sourceType: "System.IntPtr", destType: "ushort?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("ushort", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicitToNullableT("ushort", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u2")); - conversions(sourceType: "System.IntPtr", destType: "int?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("int", "int System.IntPtr.op_Explicit(System.IntPtr)")); - conversions(sourceType: "System.IntPtr", destType: "uint?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("uint", "int System.IntPtr.op_Explicit(System.IntPtr)"), expectedCheckedIL: convAndExplicitToNullableT("uint", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u4")); - conversions(sourceType: "System.IntPtr", destType: "long?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("long", "long System.IntPtr.op_Explicit(System.IntPtr)")); - conversions(sourceType: "System.IntPtr", destType: "ulong?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("ulong", "long System.IntPtr.op_Explicit(System.IntPtr)"), expectedCheckedIL: convAndExplicitToNullableT("ulong", "long System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u8")); - conversions(sourceType: "System.IntPtr", destType: "float?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("float", "long System.IntPtr.op_Explicit(System.IntPtr)", "conv.r4")); - conversions(sourceType: "System.IntPtr", destType: "double?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("double", "long System.IntPtr.op_Explicit(System.IntPtr)", "conv.r8")); - conversions(sourceType: "System.IntPtr", destType: "decimal?", IntPtrConversion, expectedImplicitIL: null, + IL_0001: call ""ulong decimal.op_Explicit(decimal)"" + IL_0006: conv.u + IL_0007: ret +}", @"{ - // Code size 17 (0x11) + // Code size 8 (0x8) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""long System.IntPtr.op_Explicit(System.IntPtr)"" - IL_0006: call ""decimal decimal.op_Implicit(long)"" - IL_000b: newobj ""decimal?..ctor(decimal)"" - IL_0010: ret + IL_0001: call ""ulong decimal.op_Explicit(decimal)"" + IL_0006: conv.ovf.u.un + IL_0007: ret }"); - conversions(sourceType: "System.IntPtr", destType: "System.IntPtr?", ImplicitNullableIdentity, + conversions(sourceType: "System.IntPtr", destType: "System.UIntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: conv("conv.u"), expectedCheckedIL: conv("conv.ovf.u")); + conversions(sourceType: "System.UIntPtr", destType: "System.UIntPtr", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + + // type to nullable System.UIntPtr + conversions(sourceType: "object", destType: "System.UIntPtr?", Unboxing, expectedImplicitIL: null, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""System.IntPtr?..ctor(System.IntPtr)"" + IL_0001: unbox.any ""nuint?"" IL_0006: ret -}", +}"); + conversions(sourceType: "string", destType: "System.UIntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "void*", destType: "System.UIntPtr?", ExplicitNullablePointerToInteger, expectedImplicitIL: null, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""System.IntPtr?..ctor(System.IntPtr)"" + IL_0001: newobj ""nuint?..ctor(nuint)"" IL_0006: ret }"); - conversions(sourceType: "System.IntPtr", destType: "System.UIntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.IntPtr?", destType: "E", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.IntPtr", "int System.IntPtr.op_Explicit(System.IntPtr)")); - conversions(sourceType: "System.IntPtr?", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.IntPtr?", destType: "char", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.IntPtr", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicitFromNullableT("System.IntPtr", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u2")); - conversions(sourceType: "System.IntPtr?", destType: "sbyte", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.IntPtr", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.i1"), expectedCheckedIL: convAndExplicitFromNullableT("System.IntPtr", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.i1")); - conversions(sourceType: "System.IntPtr?", destType: "byte", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.IntPtr", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.u1"), expectedCheckedIL: convAndExplicitFromNullableT("System.IntPtr", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u1")); - conversions(sourceType: "System.IntPtr?", destType: "short", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.IntPtr", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.i2"), expectedCheckedIL: convAndExplicitFromNullableT("System.IntPtr", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.i2")); - conversions(sourceType: "System.IntPtr?", destType: "ushort", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.IntPtr", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicitFromNullableT("System.IntPtr", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u2")); - conversions(sourceType: "System.IntPtr?", destType: "int", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.IntPtr", "int System.IntPtr.op_Explicit(System.IntPtr)")); - conversions(sourceType: "System.IntPtr?", destType: "uint", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.IntPtr", "int System.IntPtr.op_Explicit(System.IntPtr)"), expectedCheckedIL: convAndExplicitFromNullableT("System.IntPtr", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u4")); - conversions(sourceType: "System.IntPtr?", destType: "long", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.IntPtr", "long System.IntPtr.op_Explicit(System.IntPtr)")); - conversions(sourceType: "System.IntPtr?", destType: "ulong", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.IntPtr", "long System.IntPtr.op_Explicit(System.IntPtr)"), expectedCheckedIL: convAndExplicitFromNullableT("System.IntPtr", "long System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u8")); - conversions(sourceType: "System.IntPtr?", destType: "float", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.IntPtr", "long System.IntPtr.op_Explicit(System.IntPtr)", "conv.r4")); - conversions(sourceType: "System.IntPtr?", destType: "double", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.IntPtr", "long System.IntPtr.op_Explicit(System.IntPtr)", "conv.r8")); - conversions(sourceType: "System.IntPtr?", destType: "decimal", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 18 (0x12) - .maxstack 1 - IL_0000: ldarga.s V_0 - IL_0002: call ""System.IntPtr System.IntPtr?.Value.get"" - IL_0007: call ""long System.IntPtr.op_Explicit(System.IntPtr)"" - IL_000c: call ""decimal decimal.op_Implicit(long)"" - IL_0011: ret -}"); - conversions(sourceType: "System.IntPtr?", destType: "System.IntPtr", ExplicitNullableIdentity, expectedImplicitIL: null, expectedExplicitIL: -@"{ - // Code size 8 (0x8) - .maxstack 1 - IL_0000: ldarga.s V_0 - IL_0002: call ""System.IntPtr System.IntPtr?.Value.get"" - IL_0007: ret -}"); - conversions(sourceType: "System.IntPtr?", destType: "System.UIntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.IntPtr?", destType: "E?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.IntPtr", "E", "int System.IntPtr.op_Explicit(System.IntPtr)")); - conversions(sourceType: "System.IntPtr?", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.IntPtr?", destType: "char?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.IntPtr", "char", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicitFromToNullableT("System.IntPtr", "char", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u2")); - conversions(sourceType: "System.IntPtr?", destType: "sbyte?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.IntPtr", "sbyte", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.i1"), expectedCheckedIL: convAndExplicitFromToNullableT("System.IntPtr", "sbyte", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.i1")); - conversions(sourceType: "System.IntPtr?", destType: "byte?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.IntPtr", "byte", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.u1"), expectedCheckedIL: convAndExplicitFromToNullableT("System.IntPtr", "byte", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u1")); - conversions(sourceType: "System.IntPtr?", destType: "short?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.IntPtr", "short", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.i2"), expectedCheckedIL: convAndExplicitFromToNullableT("System.IntPtr", "short", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.i2")); - conversions(sourceType: "System.IntPtr?", destType: "ushort?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.IntPtr", "ushort", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicitFromToNullableT("System.IntPtr", "ushort", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u2")); - conversions(sourceType: "System.IntPtr?", destType: "int?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.IntPtr", "int", "int System.IntPtr.op_Explicit(System.IntPtr)")); - conversions(sourceType: "System.IntPtr?", destType: "uint?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.IntPtr", "uint", "int System.IntPtr.op_Explicit(System.IntPtr)"), expectedCheckedIL: convAndExplicitFromToNullableT("System.IntPtr", "uint", "int System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u4")); - conversions(sourceType: "System.IntPtr?", destType: "long?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.IntPtr", "long", "long System.IntPtr.op_Explicit(System.IntPtr)")); - conversions(sourceType: "System.IntPtr?", destType: "ulong?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.IntPtr", "ulong", "long System.IntPtr.op_Explicit(System.IntPtr)"), expectedCheckedIL: convAndExplicitFromToNullableT("System.IntPtr", "ulong", "long System.IntPtr.op_Explicit(System.IntPtr)", "conv.ovf.u8")); - conversions(sourceType: "System.IntPtr?", destType: "float?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.IntPtr", "float", "long System.IntPtr.op_Explicit(System.IntPtr)", "conv.r4")); - conversions(sourceType: "System.IntPtr?", destType: "double?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.IntPtr", "double", "long System.IntPtr.op_Explicit(System.IntPtr)", "conv.r8")); - conversions(sourceType: "System.IntPtr?", destType: "decimal?", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 39 (0x27) - .maxstack 1 - .locals init (System.IntPtr? V_0, - decimal? V_1) - IL_0000: ldarg.0 - IL_0001: stloc.0 - IL_0002: ldloca.s V_0 - IL_0004: call ""bool System.IntPtr?.HasValue.get"" - IL_0009: brtrue.s IL_0015 - IL_000b: ldloca.s V_1 - IL_000d: initobj ""decimal?"" - IL_0013: ldloc.1 - IL_0014: ret - IL_0015: ldloca.s V_0 - IL_0017: call ""System.IntPtr System.IntPtr?.GetValueOrDefault()"" - IL_001c: call ""long System.IntPtr.op_Explicit(System.IntPtr)"" - IL_0021: newobj ""decimal?..ctor(decimal)"" - IL_0026: ret -}"); - conversions(sourceType: "System.IntPtr?", destType: "System.IntPtr?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "System.IntPtr?", destType: "System.UIntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "object", destType: "System.IntPtr", Unboxing, expectedImplicitIL: null, + conversions(sourceType: "delegate*", destType: "System.UIntPtr?", ExplicitNullablePointerToInteger, expectedImplicitIL: null, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: unbox.any ""System.IntPtr"" + IL_0001: newobj ""nuint?..ctor(nuint)"" IL_0006: ret }"); - conversions(sourceType: "string", destType: "System.IntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "void*", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(void*)")); - conversions(sourceType: "delegate*", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(void*)")); - conversions(sourceType: "E", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "bool", destType: "System.IntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "sbyte", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "byte", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "short", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "ushort", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "int", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "uint", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(long)", "conv.u8")); - conversions(sourceType: "long", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(long)")); - conversions(sourceType: "ulong", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(long)"), expectedCheckedIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(long)", "conv.ovf.i8.un")); - conversions(sourceType: "float", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(long)", "conv.i8"), expectedCheckedIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(long)", "conv.ovf.i8")); - conversions(sourceType: "double", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(long)", "conv.i8"), expectedCheckedIL: explicitAndConv("System.IntPtr System.IntPtr.op_Explicit(long)", "conv.ovf.i8")); - conversions(sourceType: "decimal", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 12 (0xc) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: call ""long decimal.op_Explicit(decimal)"" - IL_0006: call ""System.IntPtr System.IntPtr.op_Explicit(long)"" - IL_000b: ret -}"); - conversions(sourceType: "E", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "bool", destType: "System.IntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "sbyte", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "byte", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "short", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "ushort", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "int", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "uint", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.u8")); - conversions(sourceType: "long", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)")); - conversions(sourceType: "ulong", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)"), expectedCheckedIL: explicitAndConvToNullableT("System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.ovf.i8.un")); - conversions(sourceType: "float", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.i8"), expectedCheckedIL: explicitAndConvToNullableT("System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.ovf.i8")); - conversions(sourceType: "double", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.i8"), expectedCheckedIL: explicitAndConvToNullableT("System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.ovf.i8")); - conversions(sourceType: "decimal", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 17 (0x11) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: call ""long decimal.op_Explicit(decimal)"" - IL_0006: call ""System.IntPtr System.IntPtr.op_Explicit(long)"" - IL_000b: newobj ""System.IntPtr?..ctor(System.IntPtr)"" - IL_0010: ret -}"); - conversions(sourceType: "E?", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("E", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "bool?", destType: "System.IntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char?", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("char", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "sbyte?", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("sbyte", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "byte?", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("byte", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "short?", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("short", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "ushort?", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("ushort", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "int?", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("int", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "uint?", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("uint", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.u8")); - conversions(sourceType: "long?", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("long", "System.IntPtr System.IntPtr.op_Explicit(long)")); - conversions(sourceType: "ulong?", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("ulong", "System.IntPtr System.IntPtr.op_Explicit(long)"), expectedCheckedIL: explicitAndConvFromNullableT("ulong", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.ovf.i8.un")); - conversions(sourceType: "float?", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("float", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.i8"), expectedCheckedIL: explicitAndConvFromNullableT("float", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.ovf.i8")); - conversions(sourceType: "double?", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("double", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.i8"), expectedCheckedIL: explicitAndConvFromNullableT("double", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.ovf.i8")); - conversions(sourceType: "decimal?", destType: "System.IntPtr", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 18 (0x12) - .maxstack 1 - IL_0000: ldarga.s V_0 - IL_0002: call ""decimal decimal?.Value.get"" - IL_0007: call ""long decimal.op_Explicit(decimal)"" - IL_000c: call ""System.IntPtr System.IntPtr.op_Explicit(long)"" - IL_0011: ret -}"); - conversions(sourceType: "E?", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("E", "System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "bool?", destType: "System.IntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char?", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("char", "System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "sbyte?", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("sbyte", "System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "byte?", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("byte", "System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "short?", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("short", "System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "ushort?", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("ushort", "System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "int?", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("int", "System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(int)")); - conversions(sourceType: "uint?", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("uint", "System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.u8")); - conversions(sourceType: "long?", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("long", "System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)")); - conversions(sourceType: "ulong?", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("ulong", "System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)"), expectedCheckedIL: explicitAndConvFromToNullableT("ulong", "System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.ovf.i8.un")); - conversions(sourceType: "float?", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("float", "System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.i8"), expectedCheckedIL: explicitAndConvFromToNullableT("float", "System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.ovf.i8")); - conversions(sourceType: "double?", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("double", "System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.i8"), expectedCheckedIL: explicitAndConvFromToNullableT("double", "System.IntPtr", "System.IntPtr System.IntPtr.op_Explicit(long)", "conv.ovf.i8")); - conversions(sourceType: "decimal?", destType: "System.IntPtr?", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 39 (0x27) - .maxstack 1 - .locals init (decimal? V_0, - System.IntPtr? V_1) - IL_0000: ldarg.0 - IL_0001: stloc.0 - IL_0002: ldloca.s V_0 - IL_0004: call ""bool decimal?.HasValue.get"" - IL_0009: brtrue.s IL_0015 - IL_000b: ldloca.s V_1 - IL_000d: initobj ""System.IntPtr?"" - IL_0013: ldloc.1 - IL_0014: ret - IL_0015: ldloca.s V_0 - IL_0017: call ""decimal decimal?.GetValueOrDefault()"" - IL_001c: call ""System.IntPtr System.IntPtr.op_Explicit(long)"" - IL_0021: newobj ""System.IntPtr?..ctor(System.IntPtr)"" - IL_0026: ret -}"); - conversions(sourceType: "System.UIntPtr", destType: "object", Boxing, + conversions(sourceType: "E", destType: "System.UIntPtr?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "bool", destType: "System.UIntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "char", destType: "System.UIntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nuint"), expectedExplicitIL: convToNullableT("conv.u", "nuint")); + conversions(sourceType: "sbyte", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "byte", destType: "System.UIntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nuint"), expectedExplicitIL: convToNullableT("conv.u", "nuint")); + conversions(sourceType: "short", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "ushort", destType: "System.UIntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nuint"), expectedExplicitIL: convToNullableT("conv.u", "nuint")); + conversions(sourceType: "int", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.i", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "uint", destType: "System.UIntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convToNullableT("conv.u", "nuint"), expectedExplicitIL: convToNullableT("conv.u", "nuint")); + conversions(sourceType: "long", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "ulong", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u.un", "nuint")); + conversions(sourceType: "nint", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "nuint", destType: "System.UIntPtr?", ImplicitNullableIdentity, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: box ""System.UIntPtr"" + IL_0001: newobj ""nuint?..ctor(nuint)"" IL_0006: ret }", @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: box ""System.UIntPtr"" + IL_0001: newobj ""nuint?..ctor(nuint)"" IL_0006: ret }"); - conversions(sourceType: "System.UIntPtr", destType: "string", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.UIntPtr", destType: "void*", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("void* System.UIntPtr.op_Explicit(System.UIntPtr)")); - conversions(sourceType: "System.UIntPtr", destType: "delegate*", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("void* System.UIntPtr.op_Explicit(System.UIntPtr)")); - conversions(sourceType: "System.UIntPtr", destType: "E", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("uint System.UIntPtr.op_Explicit(System.UIntPtr)"), expectedCheckedIL: convAndExplicit("uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i4.un")); - conversions(sourceType: "System.UIntPtr", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.UIntPtr", destType: "char", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicit("uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.u2.un")); - conversions(sourceType: "System.UIntPtr", destType: "sbyte", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.i1"), expectedCheckedIL: convAndExplicit("uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i1.un")); - conversions(sourceType: "System.UIntPtr", destType: "byte", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.u1"), expectedCheckedIL: convAndExplicit("uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.u1.un")); - conversions(sourceType: "System.UIntPtr", destType: "short", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.i2"), expectedCheckedIL: convAndExplicit("uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i2.un")); - conversions(sourceType: "System.UIntPtr", destType: "ushort", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicit("uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.u2.un")); - conversions(sourceType: "System.UIntPtr", destType: "int", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("uint System.UIntPtr.op_Explicit(System.UIntPtr)"), expectedCheckedIL: convAndExplicit("uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i4.un")); - conversions(sourceType: "System.UIntPtr", destType: "uint", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("uint System.UIntPtr.op_Explicit(System.UIntPtr)")); - conversions(sourceType: "System.UIntPtr", destType: "long", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("ulong System.UIntPtr.op_Explicit(System.UIntPtr)"), expectedCheckedIL: convAndExplicit("ulong System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i8.un")); - conversions(sourceType: "System.UIntPtr", destType: "ulong", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicit("ulong System.UIntPtr.op_Explicit(System.UIntPtr)")); - conversions(sourceType: "System.UIntPtr", destType: "float", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 9 (0x9) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: call ""ulong System.UIntPtr.op_Explicit(System.UIntPtr)"" - IL_0006: conv.r.un - IL_0007: conv.r4 - IL_0008: ret -}"); - conversions(sourceType: "System.UIntPtr", destType: "double", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 9 (0x9) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: call ""ulong System.UIntPtr.op_Explicit(System.UIntPtr)"" - IL_0006: conv.r.un - IL_0007: conv.r8 - IL_0008: ret -}"); - conversions(sourceType: "System.UIntPtr", destType: "decimal", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 12 (0xc) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: call ""ulong System.UIntPtr.op_Explicit(System.UIntPtr)"" - IL_0006: call ""decimal decimal.op_Implicit(ulong)"" - IL_000b: ret -}"); - conversions(sourceType: "System.UIntPtr", destType: "System.IntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.UIntPtr", destType: "System.UIntPtr", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "System.UIntPtr", destType: "E?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("E", "uint System.UIntPtr.op_Explicit(System.UIntPtr)"), expectedCheckedIL: convAndExplicitToNullableT("E", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i4.un")); - conversions(sourceType: "System.UIntPtr", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.UIntPtr", destType: "char?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("char", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicitToNullableT("char", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.u2.un")); - conversions(sourceType: "System.UIntPtr", destType: "sbyte?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("sbyte", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.i1"), expectedCheckedIL: convAndExplicitToNullableT("sbyte", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i1.un")); - conversions(sourceType: "System.UIntPtr", destType: "byte?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("byte", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.u1"), expectedCheckedIL: convAndExplicitToNullableT("byte", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.u1.un")); - conversions(sourceType: "System.UIntPtr", destType: "short?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("short", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.i2"), expectedCheckedIL: convAndExplicitToNullableT("short", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i2.un")); - conversions(sourceType: "System.UIntPtr", destType: "ushort?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("ushort", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicitToNullableT("ushort", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.u2.un")); - conversions(sourceType: "System.UIntPtr", destType: "int?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("int", "uint System.UIntPtr.op_Explicit(System.UIntPtr)"), expectedCheckedIL: convAndExplicitToNullableT("int", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i4.un")); - conversions(sourceType: "System.UIntPtr", destType: "uint?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("uint", "uint System.UIntPtr.op_Explicit(System.UIntPtr)")); - conversions(sourceType: "System.UIntPtr", destType: "long?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("long", "ulong System.UIntPtr.op_Explicit(System.UIntPtr)"), expectedCheckedIL: convAndExplicitToNullableT("long", "ulong System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i8.un")); - conversions(sourceType: "System.UIntPtr", destType: "ulong?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitToNullableT("ulong", "ulong System.UIntPtr.op_Explicit(System.UIntPtr)")); - conversions(sourceType: "System.UIntPtr", destType: "float?", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 14 (0xe) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: call ""ulong System.UIntPtr.op_Explicit(System.UIntPtr)"" - IL_0006: conv.r.un - IL_0007: conv.r4 - IL_0008: newobj ""float?..ctor(float)"" - IL_000d: ret -}"); - conversions(sourceType: "System.UIntPtr", destType: "double?", IntPtrConversion, expectedImplicitIL: null, + conversions(sourceType: "float", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "double", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); + conversions(sourceType: "decimal", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, @"{ - // Code size 14 (0xe) + // Code size 13 (0xd) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""ulong System.UIntPtr.op_Explicit(System.UIntPtr)"" - IL_0006: conv.r.un - IL_0007: conv.r8 - IL_0008: newobj ""double?..ctor(double)"" - IL_000d: ret -}"); - conversions(sourceType: "System.UIntPtr", destType: "decimal?", IntPtrConversion, expectedImplicitIL: null, + IL_0001: call ""ulong decimal.op_Explicit(decimal)"" + IL_0006: conv.u + IL_0007: newobj ""nuint?..ctor(nuint)"" + IL_000c: ret +}", @"{ - // Code size 17 (0x11) + // Code size 13 (0xd) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""ulong System.UIntPtr.op_Explicit(System.UIntPtr)"" - IL_0006: call ""decimal decimal.op_Implicit(ulong)"" - IL_000b: newobj ""decimal?..ctor(decimal)"" - IL_0010: ret + IL_0001: call ""ulong decimal.op_Explicit(decimal)"" + IL_0006: conv.ovf.u.un + IL_0007: newobj ""nuint?..ctor(nuint)"" + IL_000c: ret }"); - conversions(sourceType: "System.UIntPtr", destType: "System.IntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "System.IntPtr", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convToNullableT("conv.u", "nuint"), expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint")); conversions(sourceType: "System.UIntPtr", destType: "System.UIntPtr?", ImplicitNullableIdentity, @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""System.UIntPtr?..ctor(System.UIntPtr)"" + IL_0001: newobj ""nuint?..ctor(nuint)"" IL_0006: ret }", @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: newobj ""System.UIntPtr?..ctor(System.UIntPtr)"" + IL_0001: newobj ""nuint?..ctor(nuint)"" IL_0006: ret }"); - conversions(sourceType: "System.UIntPtr?", destType: "E", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.UIntPtr", "uint System.UIntPtr.op_Explicit(System.UIntPtr)"), expectedCheckedIL: convAndExplicitFromNullableT("System.UIntPtr", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i4.un")); - conversions(sourceType: "System.UIntPtr?", destType: "bool", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.UIntPtr?", destType: "char", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.UIntPtr", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicitFromNullableT("System.UIntPtr", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.u2.un")); - conversions(sourceType: "System.UIntPtr?", destType: "sbyte", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.UIntPtr", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.i1"), expectedCheckedIL: convAndExplicitFromNullableT("System.UIntPtr", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i1.un")); - conversions(sourceType: "System.UIntPtr?", destType: "byte", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.UIntPtr", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.u1"), expectedCheckedIL: convAndExplicitFromNullableT("System.UIntPtr", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.u1.un")); - conversions(sourceType: "System.UIntPtr?", destType: "short", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.UIntPtr", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.i2"), expectedCheckedIL: convAndExplicitFromNullableT("System.UIntPtr", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i2.un")); - conversions(sourceType: "System.UIntPtr?", destType: "ushort", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.UIntPtr", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicitFromNullableT("System.UIntPtr", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.u2.un")); - conversions(sourceType: "System.UIntPtr?", destType: "int", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.UIntPtr", "uint System.UIntPtr.op_Explicit(System.UIntPtr)"), expectedCheckedIL: convAndExplicitFromNullableT("System.UIntPtr", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i4.un")); - conversions(sourceType: "System.UIntPtr?", destType: "uint", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.UIntPtr", "uint System.UIntPtr.op_Explicit(System.UIntPtr)")); - conversions(sourceType: "System.UIntPtr?", destType: "long", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.UIntPtr", "ulong System.UIntPtr.op_Explicit(System.UIntPtr)"), expectedCheckedIL: convAndExplicitFromNullableT("System.UIntPtr", "ulong System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i8.un")); - conversions(sourceType: "System.UIntPtr?", destType: "ulong", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromNullableT("System.UIntPtr", "ulong System.UIntPtr.op_Explicit(System.UIntPtr)")); - conversions(sourceType: "System.UIntPtr?", destType: "float", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 15 (0xf) - .maxstack 1 - IL_0000: ldarga.s V_0 - IL_0002: call ""System.UIntPtr System.UIntPtr?.Value.get"" - IL_0007: call ""ulong System.UIntPtr.op_Explicit(System.UIntPtr)"" - IL_000c: conv.r.un - IL_000d: conv.r4 - IL_000e: ret -}"); - conversions(sourceType: "System.UIntPtr?", destType: "double", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 15 (0xf) - .maxstack 1 - IL_0000: ldarga.s V_0 - IL_0002: call ""System.UIntPtr System.UIntPtr?.Value.get"" - IL_0007: call ""ulong System.UIntPtr.op_Explicit(System.UIntPtr)"" - IL_000c: conv.r.un - IL_000d: conv.r8 - IL_000e: ret -}"); - conversions(sourceType: "System.UIntPtr?", destType: "decimal", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 18 (0x12) - .maxstack 1 - IL_0000: ldarga.s V_0 - IL_0002: call ""System.UIntPtr System.UIntPtr?.Value.get"" - IL_0007: call ""ulong System.UIntPtr.op_Explicit(System.UIntPtr)"" - IL_000c: call ""decimal decimal.op_Implicit(ulong)"" - IL_0011: ret -}"); - conversions(sourceType: "System.UIntPtr?", destType: "System.IntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.UIntPtr?", destType: "System.UIntPtr", ExplicitNullableIdentity, expectedImplicitIL: null, expectedExplicitIL: + + // nullable type to System.UIntPtr + conversions(sourceType: "E?", destType: "System.UIntPtr", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "E"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "E")); + conversions(sourceType: "bool?", destType: "System.UIntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); + conversions(sourceType: "char?", destType: "System.UIntPtr", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "char")); + conversions(sourceType: "sbyte?", destType: "System.UIntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "sbyte"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "sbyte")); + conversions(sourceType: "byte?", destType: "System.UIntPtr", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "byte")); + conversions(sourceType: "short?", destType: "System.UIntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "short"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "short")); + conversions(sourceType: "ushort?", destType: "System.UIntPtr", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "ushort")); + conversions(sourceType: "int?", destType: "System.UIntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.i", "int"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "int")); + conversions(sourceType: "uint?", destType: "System.UIntPtr", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "uint")); + conversions(sourceType: "long?", destType: "System.UIntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "long"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "long")); + conversions(sourceType: "ulong?", destType: "System.UIntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "ulong"), expectedCheckedIL: convFromNullableT("conv.ovf.u.un", "ulong")); + conversions(sourceType: "nint?", destType: "System.UIntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "nint")); + conversions(sourceType: "nuint?", destType: "System.UIntPtr", ExplicitNullableIdentity, expectedImplicitIL: null, @"{ // Code size 8 (0x8) .maxstack 1 IL_0000: ldarga.s V_0 - IL_0002: call ""System.UIntPtr System.UIntPtr?.Value.get"" + IL_0002: call ""nuint nuint?.Value.get"" IL_0007: ret }"); - conversions(sourceType: "System.UIntPtr?", destType: "E?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.UIntPtr", "E", "uint System.UIntPtr.op_Explicit(System.UIntPtr)"), expectedCheckedIL: convAndExplicitFromToNullableT("System.UIntPtr", "E", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i4.un")); - conversions(sourceType: "System.UIntPtr?", destType: "bool?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.UIntPtr?", destType: "char?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.UIntPtr", "char", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicitFromToNullableT("System.UIntPtr", "char", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.u2.un")); - conversions(sourceType: "System.UIntPtr?", destType: "sbyte?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.UIntPtr", "sbyte", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.i1"), expectedCheckedIL: convAndExplicitFromToNullableT("System.UIntPtr", "sbyte", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i1.un")); - conversions(sourceType: "System.UIntPtr?", destType: "byte?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.UIntPtr", "byte", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.u1"), expectedCheckedIL: convAndExplicitFromToNullableT("System.UIntPtr", "byte", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.u1.un")); - conversions(sourceType: "System.UIntPtr?", destType: "short?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.UIntPtr", "short", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.i2"), expectedCheckedIL: convAndExplicitFromToNullableT("System.UIntPtr", "short", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i2.un")); - conversions(sourceType: "System.UIntPtr?", destType: "ushort?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.UIntPtr", "ushort", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.u2"), expectedCheckedIL: convAndExplicitFromToNullableT("System.UIntPtr", "ushort", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.u2.un")); - conversions(sourceType: "System.UIntPtr?", destType: "int?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.UIntPtr", "int", "uint System.UIntPtr.op_Explicit(System.UIntPtr)"), expectedCheckedIL: convAndExplicitFromToNullableT("System.UIntPtr", "int", "uint System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i4.un")); - conversions(sourceType: "System.UIntPtr?", destType: "uint?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.UIntPtr", "uint", "uint System.UIntPtr.op_Explicit(System.UIntPtr)")); - conversions(sourceType: "System.UIntPtr?", destType: "long?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.UIntPtr", "long", "ulong System.UIntPtr.op_Explicit(System.UIntPtr)"), expectedCheckedIL: convAndExplicitFromToNullableT("System.UIntPtr", "long", "ulong System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.ovf.i8.un")); - conversions(sourceType: "System.UIntPtr?", destType: "ulong?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.UIntPtr", "ulong", "ulong System.UIntPtr.op_Explicit(System.UIntPtr)")); - conversions(sourceType: "System.UIntPtr?", destType: "float?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.UIntPtr", "float", "ulong System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.r4")); - conversions(sourceType: "System.UIntPtr?", destType: "double?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: convAndExplicitFromToNullableT("System.UIntPtr", "double", "ulong System.UIntPtr.op_Explicit(System.UIntPtr)", "conv.r8")); - conversions(sourceType: "System.UIntPtr?", destType: "decimal?", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 39 (0x27) - .maxstack 1 - .locals init (System.UIntPtr? V_0, - decimal? V_1) - IL_0000: ldarg.0 - IL_0001: stloc.0 - IL_0002: ldloca.s V_0 - IL_0004: call ""bool System.UIntPtr?.HasValue.get"" - IL_0009: brtrue.s IL_0015 - IL_000b: ldloca.s V_1 - IL_000d: initobj ""decimal?"" - IL_0013: ldloc.1 - IL_0014: ret - IL_0015: ldloca.s V_0 - IL_0017: call ""System.UIntPtr System.UIntPtr?.GetValueOrDefault()"" - IL_001c: call ""ulong System.UIntPtr.op_Explicit(System.UIntPtr)"" - IL_0021: newobj ""decimal?..ctor(decimal)"" - IL_0026: ret -}"); - conversions(sourceType: "System.UIntPtr?", destType: "System.IntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "System.UIntPtr?", destType: "System.UIntPtr?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); - conversions(sourceType: "object", destType: "System.UIntPtr", Unboxing, expectedImplicitIL: null, + conversions(sourceType: "float?", destType: "System.UIntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "float"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "float")); + conversions(sourceType: "double?", destType: "System.UIntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "double"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "double")); + conversions(sourceType: "decimal?", destType: "System.UIntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, @"{ - // Code size 7 (0x7) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: unbox.any ""System.UIntPtr"" - IL_0006: ret -}"); - conversions(sourceType: "string", destType: "System.UIntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "void*", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(void*)")); - conversions(sourceType: "delegate*", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(void*)")); - conversions(sourceType: "E", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "bool", destType: "System.UIntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "sbyte", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "byte", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "short", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "ushort", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "int", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "uint", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "long", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(ulong)"), expectedCheckedIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "ulong", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(ulong)")); - conversions(sourceType: "float", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.u8"), expectedCheckedIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "double", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.u8"), expectedCheckedIL: explicitAndConv("System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "decimal", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 12 (0xc) + // Code size 14 (0xe) .maxstack 1 - IL_0000: ldarg.0 - IL_0001: call ""ulong decimal.op_Explicit(decimal)"" - IL_0006: call ""System.UIntPtr System.UIntPtr.op_Explicit(ulong)"" - IL_000b: ret -}"); - conversions(sourceType: "E", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "bool", destType: "System.UIntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "sbyte", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "byte", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "short", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "ushort", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "int", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "uint", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "long", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)"), expectedCheckedIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "ulong", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)")); - conversions(sourceType: "float", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.u8"), expectedCheckedIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "double", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.u8"), expectedCheckedIL: explicitAndConvToNullableT("System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "decimal", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, + IL_0000: ldarga.s V_0 + IL_0002: call ""decimal decimal?.Value.get"" + IL_0007: call ""ulong decimal.op_Explicit(decimal)"" + IL_000c: conv.u + IL_000d: ret +}", @"{ - // Code size 17 (0x11) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: call ""ulong decimal.op_Explicit(decimal)"" - IL_0006: call ""System.UIntPtr System.UIntPtr.op_Explicit(ulong)"" - IL_000b: newobj ""System.UIntPtr?..ctor(System.UIntPtr)"" - IL_0010: ret -}"); - conversions(sourceType: "E?", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("E", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConvFromNullableT("E", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "bool?", destType: "System.UIntPtr", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char?", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("char", "System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "sbyte?", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("sbyte", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConvFromNullableT("sbyte", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "byte?", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("byte", "System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "short?", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("short", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConvFromNullableT("short", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "ushort?", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("ushort", "System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "int?", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("int", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConvFromNullableT("int", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "uint?", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("uint", "System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "long?", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("long", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)"), expectedCheckedIL: explicitAndConvFromNullableT("long", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "ulong?", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("ulong", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)")); - conversions(sourceType: "float?", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("float", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.u8"), expectedCheckedIL: explicitAndConvFromNullableT("float", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "double?", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromNullableT("double", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.u8"), expectedCheckedIL: explicitAndConvFromNullableT("double", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "decimal?", destType: "System.UIntPtr", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 18 (0x12) + // Code size 14 (0xe) .maxstack 1 IL_0000: ldarga.s V_0 IL_0002: call ""decimal decimal?.Value.get"" IL_0007: call ""ulong decimal.op_Explicit(decimal)"" - IL_000c: call ""System.UIntPtr System.UIntPtr.op_Explicit(ulong)"" - IL_0011: ret + IL_000c: conv.ovf.u.un + IL_000d: ret +}"); + conversions(sourceType: "System.IntPtr?", destType: "System.UIntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromNullableT("conv.u", "nint"), expectedCheckedIL: convFromNullableT("conv.ovf.u", "nint")); + conversions(sourceType: "System.UIntPtr?", destType: "System.UIntPtr", ExplicitNullableIdentity, expectedImplicitIL: null, +@"{ + // Code size 8 (0x8) + .maxstack 1 + IL_0000: ldarga.s V_0 + IL_0002: call ""nuint nuint?.Value.get"" + IL_0007: ret }"); - conversions(sourceType: "E?", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("E", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConvFromToNullableT("E", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); + + // nullable type to nullable System.UIntPtr + conversions(sourceType: "E?", destType: "System.UIntPtr?", ExplicitNullableEnumeration, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "E", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "E", "nuint")); conversions(sourceType: "bool?", destType: "System.UIntPtr?", NoConversion, expectedImplicitIL: null, expectedExplicitIL: null); - conversions(sourceType: "char?", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("char", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "sbyte?", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("sbyte", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConvFromToNullableT("sbyte", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "byte?", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("byte", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "short?", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("short", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConvFromToNullableT("short", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "ushort?", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("ushort", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "int?", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("int", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConvFromToNullableT("int", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "uint?", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("uint", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(uint)")); - conversions(sourceType: "long?", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("long", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.i8"), expectedCheckedIL: explicitAndConvFromToNullableT("long", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "ulong?", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("ulong", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)")); - conversions(sourceType: "float?", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("float", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.u8"), expectedCheckedIL: explicitAndConvFromToNullableT("float", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - conversions(sourceType: "double?", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, expectedExplicitIL: explicitAndConvFromToNullableT("double", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.u8"), expectedCheckedIL: explicitAndConvFromToNullableT("double", "System.UIntPtr", "System.UIntPtr System.UIntPtr.op_Explicit(ulong)", "conv.ovf.u8")); - // https://github.com/dotnet/roslyn/issues/42834: Invalid code generated for nullable conversions - // involving System.[U]IntPtr: the conversion ulong decimal.op_Explicit(decimal) is dropped. - conversions(sourceType: "decimal?", destType: "System.UIntPtr?", IntPtrConversion, expectedImplicitIL: null, -@"{ - // Code size 39 (0x27) + conversions(sourceType: "char?", destType: "System.UIntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "char", "nuint"), expectedExplicitIL: convFromToNullableT("conv.u", "char", "nuint")); + conversions(sourceType: "sbyte?", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "sbyte", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "sbyte", "nuint")); + conversions(sourceType: "byte?", destType: "System.UIntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "byte", "nuint"), expectedExplicitIL: convFromToNullableT("conv.u", "byte", "nuint")); + conversions(sourceType: "short?", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "short", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "short", "nuint")); + conversions(sourceType: "ushort?", destType: "System.UIntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "ushort", "nuint"), expectedExplicitIL: convFromToNullableT("conv.u", "ushort", "nuint")); + conversions(sourceType: "int?", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.i", "int", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "int", "nuint")); + conversions(sourceType: "uint?", destType: "System.UIntPtr?", ImplicitNullableNumeric, expectedImplicitIL: convFromToNullableT("conv.u", "uint", "nuint"), expectedExplicitIL: convFromToNullableT("conv.u", "uint", "nuint")); + conversions(sourceType: "long?", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "long", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "long", "nuint")); + conversions(sourceType: "ulong?", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "ulong", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u.un", "ulong", "nuint")); + conversions(sourceType: "nint?", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "nint", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "nint", "nuint")); + conversions(sourceType: "nuint?", destType: "System.UIntPtr?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); + conversions(sourceType: "float?", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "float", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "float", "nuint")); + conversions(sourceType: "double?", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "double", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "double", "nuint")); + conversions(sourceType: "decimal?", destType: "System.UIntPtr?", ExplicitNullableNumeric, null, +@"{ + // Code size 40 (0x28) + .maxstack 1 + .locals init (decimal? V_0, + nuint? V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call ""bool decimal?.HasValue.get"" + IL_0009: brtrue.s IL_0015 + IL_000b: ldloca.s V_1 + IL_000d: initobj ""nuint?"" + IL_0013: ldloc.1 + IL_0014: ret + IL_0015: ldloca.s V_0 + IL_0017: call ""decimal decimal?.GetValueOrDefault()"" + IL_001c: call ""ulong decimal.op_Explicit(decimal)"" + IL_0021: conv.u + IL_0022: newobj ""nuint?..ctor(nuint)"" + IL_0027: ret +}", +@"{ + // Code size 40 (0x28) .maxstack 1 .locals init (decimal? V_0, - System.UIntPtr? V_1) + nuint? V_1) IL_0000: ldarg.0 IL_0001: stloc.0 IL_0002: ldloca.s V_0 IL_0004: call ""bool decimal?.HasValue.get"" IL_0009: brtrue.s IL_0015 IL_000b: ldloca.s V_1 - IL_000d: initobj ""System.UIntPtr?"" + IL_000d: initobj ""nuint?"" IL_0013: ldloc.1 IL_0014: ret IL_0015: ldloca.s V_0 IL_0017: call ""decimal decimal?.GetValueOrDefault()"" - IL_001c: call ""System.UIntPtr System.UIntPtr.op_Explicit(ulong)"" - IL_0021: newobj ""System.UIntPtr?..ctor(System.UIntPtr)"" - IL_0026: ret + IL_001c: call ""ulong decimal.op_Explicit(decimal)"" + IL_0021: conv.ovf.u.un + IL_0022: newobj ""nuint?..ctor(nuint)"" + IL_0027: ret }"); + conversions(sourceType: "System.IntPtr?", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL: convFromToNullableT("conv.u", "nint", "nuint"), expectedCheckedIL: convFromToNullableT("conv.ovf.u", "nint", "nuint")); + conversions(sourceType: "System.UIntPtr?", destType: "System.UIntPtr?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone); return; void convert(string sourceType, string destType, string expectedIL, - bool skipTypeChecks, bool useExplicitCast, bool useChecked, - bool verify, ConversionKind[] expectedConversions, ErrorCode expectedErrorCode) { @@ -9103,7 +6165,7 @@ void convert(string sourceType, } var expectedDiagnostics = expectedErrorCode == 0 ? Array.Empty() : - new[] { Diagnostic(expectedErrorCode, value).WithArguments(sourceType, destType) }; + new[] { Diagnostic(expectedErrorCode, value).WithArguments(AsNative(sourceType), AsNative(destType)) }; if (useChecked) { value = $"checked({value})"; @@ -9118,7 +6180,10 @@ void convert(string sourceType, }} enum E {{ }} "; - var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithAllowUnsafe(useUnsafeContext), parseOptions: TestOptions.Regular9); + var mscorlibRef = MscorlibRefWithoutSharingCachedSymbols; + var comp = CreateEmptyCompilation(source, references: new[] { mscorlibRef }, options: TestOptions.ReleaseDll.WithAllowUnsafe(useUnsafeContext), parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(expectedDiagnostics); var tree = comp.SyntaxTrees[0]; @@ -9130,17 +6195,13 @@ enum E {{ }} { var destTypeSymbol = ((MethodSymbol)comp.GetMember("Program.Convert")).ReturnType.GetPublicSymbol(); AssertMatches(expectedConversions, model.ClassifyConversion(expr, destTypeSymbol)); - } - - if (!skipTypeChecks) - { - Assert.Equal(sourceType, typeInfo.Type.ToString()); - Assert.Equal(destType, typeInfo.ConvertedType.ToString()); + Assert.Equal(AsNative(sourceType), typeInfo.Type.ToString()); + Assert.Equal(AsNative(destType), typeInfo.ConvertedType.ToString()); } if (expectedIL != null) { - var verifier = CompileAndVerify(comp, verify: useUnsafeContext || !verify ? Verification.Skipped : Verification.Passes); + var verifier = CompileAndVerify(comp, verify: useUnsafeContext ? Verification.Skipped : Verification.Passes); verifier.VerifyIL("Program.Convert", expectedIL); } @@ -9159,34 +6220,42 @@ static string getComplement(uint value) return result.ToString(); } - void unaryOp(string op, string opType, string expectedSymbol = null, string operand = null, string expectedResult = null, string expectedIL = "", DiagnosticDescription diagnostic = null) + void unifiedUnaryOp(string op, string opType, string expectedSymbol = null, string operand = null, string expectedResult = null, string expectedIL = "", DiagnosticDescription diagnostic = null) + { + Assert.True(opType is "System.IntPtr" or "System.UIntPtr" or "System.IntPtr?" or "System.UIntPtr?"); + unaryOp(op, opType, expectedSymbol, operand, expectedResult, expectedIL, diagnostic); + unaryOp(op, AsNative(opType), expectedSymbol, operand, expectedResult, expectedIL, diagnostic); + } + + void unaryOp(string op, string opType, string expectedSymbol, string operand, string expectedResult, string expectedIL, DiagnosticDescription diagnostic) { operand ??= "default"; if (expectedSymbol == null && diagnostic == null) { - diagnostic = Diagnostic(ErrorCode.ERR_BadUnaryOp, $"{op}operand").WithArguments(op, opType); + diagnostic = Diagnostic(ErrorCode.ERR_BadUnaryOp, $"{op}operand").WithArguments(op, AsNative(opType)); } unaryOperator(op, opType, opType, expectedSymbol, operand, expectedResult, expectedIL, diagnostic != null ? new[] { diagnostic } : Array.Empty()); } - unaryOp("+", "nint", "nint nint.op_UnaryPlus(nint value)", "3", "3", + // unary operator+ + unifiedUnaryOp("+", "System.IntPtr", "nint nint.op_UnaryPlus(nint value)", "3", "3", @"{ // Code size 2 (0x2) .maxstack 1 IL_0000: ldarg.0 IL_0001: ret }"); - unaryOp(" + ", "nuint", "nuint nuint.op_UnaryPlus(nuint value)", "3", "3", + unifiedUnaryOp("+", "System.UIntPtr", "nuint nuint.op_UnaryPlus(nuint value)", "3", "3", @"{ // Code size 2 (0x2) .maxstack 1 IL_0000: ldarg.0 IL_0001: ret }"); - unaryOp("+", "System.IntPtr"); - unaryOp("+", "System.UIntPtr"); - unaryOp("-", "nint", "nint nint.op_UnaryNegation(nint value)", "3", "-3", + + // unary operator- + unifiedUnaryOp("-", "System.IntPtr", "nint nint.op_UnaryNegation(nint value)", "3", "-3", @"{ // Code size 3 (0x3) .maxstack 1 @@ -9194,14 +6263,14 @@ .maxstack 1 IL_0001: neg IL_0002: ret }"); - unaryOp("-", "nuint"); - unaryOp("-", "System.IntPtr"); - unaryOp("-", "System.UIntPtr"); - unaryOp("!", "nint"); - unaryOp("!", "nuint"); - unaryOp("!", "System.IntPtr"); - unaryOp("!", "System.UIntPtr"); - unaryOp("~", "nint", "nint nint.op_OnesComplement(nint value)", "3", "-4", + unifiedUnaryOp("-", "System.UIntPtr"); + + // unary operator! + unifiedUnaryOp("!", "System.IntPtr"); + unifiedUnaryOp("!", "System.UIntPtr"); + + // unary operator~ + unifiedUnaryOp("~", "System.IntPtr", "nint nint.op_OnesComplement(nint value)", "3", "-4", @"{ // Code size 3 (0x3) .maxstack 1 @@ -9209,7 +6278,7 @@ .maxstack 1 IL_0001: not IL_0002: ret }"); - unaryOp("~", "nuint", "nuint nuint.op_OnesComplement(nuint value)", "3", getComplement(3), + unifiedUnaryOp("~", "System.UIntPtr", "nuint nuint.op_OnesComplement(nuint value)", "3", getComplement(3), @"{ // Code size 3 (0x3) .maxstack 1 @@ -9217,10 +6286,9 @@ .maxstack 1 IL_0001: not IL_0002: ret }"); - unaryOp("~", "System.IntPtr"); - unaryOp("~", "System.UIntPtr"); - unaryOp("+", "nint?", "nint nint.op_UnaryPlus(nint value)", "3", "3", + // lifted unary operator+ + unifiedUnaryOp("+", "System.IntPtr?", "nint nint.op_UnaryPlus(nint value)", "3", "3", @"{ // Code size 34 (0x22) .maxstack 1 @@ -9240,7 +6308,7 @@ .locals init (nint? V_0, IL_001c: newobj ""nint?..ctor(nint)"" IL_0021: ret }"); - unaryOp("+", "nuint?", "nuint nuint.op_UnaryPlus(nuint value)", "3", "3", + unifiedUnaryOp("+", "System.UIntPtr?", "nuint nuint.op_UnaryPlus(nuint value)", "3", "3", @"{ // Code size 34 (0x22) .maxstack 1 @@ -9260,9 +6328,9 @@ .locals init (nuint? V_0, IL_001c: newobj ""nuint?..ctor(nuint)"" IL_0021: ret }"); - unaryOp("+", "System.IntPtr?"); - unaryOp("+", "System.UIntPtr?"); - unaryOp("-", "nint?", "nint nint.op_UnaryNegation(nint value)", "3", "-3", + + // lifted unary operator- + unifiedUnaryOp("-", "System.IntPtr?", "nint nint.op_UnaryNegation(nint value)", "3", "-3", @"{ // Code size 35 (0x23) .maxstack 1 @@ -9287,14 +6355,14 @@ .locals init (nint? V_0, // for `-(nuint)value`, but that difference in behavior is consistent with the pair of errors reported for // `-(ulong?)value` and `-(ulong)value`. See the "Special case" in Binder.UnaryOperatorOverloadResolution() // which handles ulong but not ulong?. - unaryOp("-", "nuint?", null, null, null, null, Diagnostic(ErrorCode.ERR_AmbigUnaryOp, "-operand").WithArguments("-", "nuint?")); - unaryOp("-", "System.IntPtr?"); - unaryOp("-", "System.UIntPtr?"); - unaryOp("!", "nint?"); - unaryOp("!", "nuint?"); - unaryOp("!", "System.IntPtr?"); - unaryOp("!", "System.UIntPtr?"); - unaryOp("~", "nint?", "nint nint.op_OnesComplement(nint value)", "3", "-4", + unifiedUnaryOp("-", "System.UIntPtr?", null, null, null, null, Diagnostic(ErrorCode.ERR_AmbigUnaryOp, "-operand").WithArguments("-", "nuint?")); + + // lifted unary operator! + unifiedUnaryOp("!", "System.IntPtr?"); + unifiedUnaryOp("!", "System.UIntPtr?"); + + // lifted unary operator~ + unifiedUnaryOp("~", "System.IntPtr?", "nint nint.op_OnesComplement(nint value)", "3", "-4", @"{ // Code size 35 (0x23) .maxstack 1 @@ -9315,7 +6383,7 @@ .locals init (nint? V_0, IL_001d: newobj ""nint?..ctor(nint)"" IL_0022: ret }"); - unaryOp("~", "nuint?", "nuint nuint.op_OnesComplement(nuint value)", "3", getComplement(3), + unifiedUnaryOp("~", "System.UIntPtr?", "nuint nuint.op_OnesComplement(nuint value)", "3", getComplement(3), @"{ // Code size 35 (0x23) .maxstack 1 @@ -9336,8 +6404,6 @@ .locals init (nuint? V_0, IL_001d: newobj ""nuint?..ctor(nuint)"" IL_0022: ret }"); - unaryOp("~", "System.IntPtr?"); - unaryOp("~", "System.UIntPtr?"); void unaryOperator(string op, string opType, string resultType, string expectedSymbol, string operand, string expectedResult, string expectedIL, DiagnosticDescription[] expectedDiagnostics) { @@ -9353,7 +6419,8 @@ static void Main() System.Console.WriteLine(Evaluate({operand})); }} }}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; comp.VerifyDiagnostics(expectedDiagnostics); var tree = comp.SyntaxTrees[0]; @@ -9373,7 +6440,14 @@ static void Main() [Fact] public void IncrementOperators() { - void incrementOps(string op, string opType, string expectedSymbol = null, bool useChecked = false, string values = null, string expectedResult = null, string expectedIL = "", string expectedLiftedIL = "", DiagnosticDescription diagnostic = null) + void unifiedIncrementOps(string op, string opType, string expectedSymbol = null, bool useChecked = false, string values = null, string expectedResult = null, string expectedIL = "", string expectedLiftedIL = "", DiagnosticDescription diagnostic = null) + { + Assert.True(opType is "System.IntPtr" or "System.UIntPtr" or "System.IntPtr?" or "System.UIntPtr?"); + incrementOps(op, opType, expectedSymbol, useChecked, values, expectedResult, expectedIL, expectedLiftedIL, diagnostic); + incrementOps(op, AsNative(opType), expectedSymbol, useChecked, values, expectedResult, expectedIL, expectedLiftedIL, diagnostic); + } + + void incrementOps(string op, string opType, string expectedSymbol, bool useChecked, string values, string expectedResult, string expectedIL, string expectedLiftedIL, DiagnosticDescription diagnostic) { incrementOperator(op, opType, isPrefix: true, expectedSymbol, useChecked, values, expectedResult, expectedIL, getDiagnostics(opType, isPrefix: true, diagnostic)); incrementOperator(op, opType, isPrefix: false, expectedSymbol, useChecked, values, expectedResult, expectedIL, getDiagnostics(opType, isPrefix: false, diagnostic)); @@ -9391,7 +6465,7 @@ DiagnosticDescription[] getDiagnostics(string opType, bool isPrefix, DiagnosticD } } - incrementOps("++", "nint", "nint nint.op_Increment(nint value)", useChecked: false, + unifiedIncrementOps("++", "System.IntPtr", "nint nint.op_Increment(nint value)", useChecked: false, values: $"{int.MinValue}, -1, 0, {int.MaxValue - 1}, {int.MaxValue}", expectedResult: $"-2147483647, 0, 1, 2147483647, {(IntPtr.Size == 4 ? "-2147483648" : "2147483648")}", @"{ @@ -9427,7 +6501,7 @@ .locals init (nint? V_0, IL_0026: ldarg.0 IL_0027: ret }"); - incrementOps("++", "nuint", "nuint nuint.op_Increment(nuint value)", useChecked: false, + unifiedIncrementOps("++", "System.UIntPtr", "nuint nuint.op_Increment(nuint value)", useChecked: false, values: $"0, {int.MaxValue}, {uint.MaxValue - 1}, {uint.MaxValue}", expectedResult: $"1, 2147483648, 4294967295, {(IntPtr.Size == 4 ? "0" : "4294967296")}", @"{ @@ -9463,9 +6537,7 @@ .locals init (nuint? V_0, IL_0026: ldarg.0 IL_0027: ret }"); - incrementOps("++", "System.IntPtr"); - incrementOps("++", "System.UIntPtr"); - incrementOps("--", "nint", "nint nint.op_Decrement(nint value)", useChecked: false, + unifiedIncrementOps("--", "System.IntPtr", "nint nint.op_Decrement(nint value)", useChecked: false, values: $"{int.MinValue}, {int.MinValue + 1}, 0, 1, {int.MaxValue}", expectedResult: $"{(IntPtr.Size == 4 ? "2147483647" : "-2147483649")}, -2147483648, -1, 0, 2147483646", @"{ @@ -9501,7 +6573,7 @@ .locals init (nint? V_0, IL_0026: ldarg.0 IL_0027: ret }"); - incrementOps("--", "nuint", "nuint nuint.op_Decrement(nuint value)", useChecked: false, + unifiedIncrementOps("--", "System.UIntPtr", "nuint nuint.op_Decrement(nuint value)", useChecked: false, values: $"0, 1, {uint.MaxValue}", expectedResult: $"{(IntPtr.Size == 4 ? uint.MaxValue.ToString() : ulong.MaxValue.ToString())}, 0, 4294967294", @"{ @@ -9537,10 +6609,8 @@ .locals init (nuint? V_0, IL_0026: ldarg.0 IL_0027: ret }"); - incrementOps("--", "System.IntPtr"); - incrementOps("--", "System.UIntPtr"); - incrementOps("++", "nint", "nint nint.op_CheckedIncrement(nint value)", useChecked: true, + unifiedIncrementOps("++", "System.IntPtr", "nint nint.op_CheckedIncrement(nint value)", useChecked: true, values: $"{int.MinValue}, -1, 0, {int.MaxValue - 1}, {int.MaxValue}", expectedResult: $"-2147483647, 0, 1, 2147483647, {(IntPtr.Size == 4 ? "System.OverflowException" : "2147483648")}", @"{ @@ -9576,7 +6646,7 @@ .locals init (nint? V_0, IL_0026: ldarg.0 IL_0027: ret }"); - incrementOps("++", "nuint", "nuint nuint.op_CheckedIncrement(nuint value)", useChecked: true, + unifiedIncrementOps("++", "System.UIntPtr", "nuint nuint.op_CheckedIncrement(nuint value)", useChecked: true, values: $"0, {int.MaxValue}, {uint.MaxValue - 1}, {uint.MaxValue}", expectedResult: $"1, 2147483648, 4294967295, {(IntPtr.Size == 4 ? "System.OverflowException" : "4294967296")}", @"{ @@ -9612,9 +6682,7 @@ .locals init (nuint? V_0, IL_0026: ldarg.0 IL_0027: ret }"); - incrementOps("++", "System.IntPtr", null, useChecked: true); - incrementOps("++", "System.UIntPtr", null, useChecked: true); - incrementOps("--", "nint", "nint nint.op_CheckedDecrement(nint value)", useChecked: true, + unifiedIncrementOps("--", "System.IntPtr", "nint nint.op_CheckedDecrement(nint value)", useChecked: true, values: $"{int.MinValue}, {int.MinValue + 1}, 0, 1, {int.MaxValue}", expectedResult: $"{(IntPtr.Size == 4 ? "System.OverflowException" : "-2147483649")}, -2147483648, -1, 0, 2147483646", @"{ @@ -9650,7 +6718,7 @@ .locals init (nint? V_0, IL_0026: ldarg.0 IL_0027: ret }"); - incrementOps("--", "nuint", "nuint nuint.op_CheckedDecrement(nuint value)", useChecked: true, + unifiedIncrementOps("--", "System.UIntPtr", "nuint nuint.op_CheckedDecrement(nuint value)", useChecked: true, values: $"0, 1, {uint.MaxValue}", expectedResult: $"System.OverflowException, 0, 4294967294", @"{ @@ -9686,8 +6754,6 @@ .locals init (nuint? V_0, IL_0026: ldarg.0 IL_0027: ret }"); - incrementOps("--", "System.IntPtr", null, useChecked: true); - incrementOps("--", "System.UIntPtr", null, useChecked: true); void incrementOperator(string op, string opType, bool isPrefix, string expectedSymbol, bool useChecked, string values, string expectedResult, string expectedIL, DiagnosticDescription[] expectedDiagnostics) { @@ -9727,7 +6793,8 @@ static void Main() }} }} }}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; comp.VerifyDiagnostics(expectedDiagnostics); var tree = comp.SyntaxTrees[0]; @@ -9750,6 +6817,13 @@ static void Main() [Fact] public void IncrementOperators_RefOperand() { + void unifiedIncrementOps(string op, string opType, string expectedSymbol = null, string values = null, string expectedResult = null, string expectedIL = "", string expectedLiftedIL = "", DiagnosticDescription diagnostic = null) + { + Assert.True(opType is "System.IntPtr" or "System.UIntPtr" or "System.IntPtr?" or "System.UIntPtr?"); + incrementOps(op, opType, expectedSymbol, values, expectedResult, expectedIL, expectedLiftedIL, diagnostic); + incrementOps(op, AsNative(opType), expectedSymbol, values, expectedResult, expectedIL, expectedLiftedIL, diagnostic); + } + void incrementOps(string op, string opType, string expectedSymbol = null, string values = null, string expectedResult = null, string expectedIL = "", string expectedLiftedIL = "", DiagnosticDescription diagnostic = null) { incrementOperator(op, opType, expectedSymbol, values, expectedResult, expectedIL, getDiagnostics(opType, diagnostic)); @@ -9766,7 +6840,7 @@ DiagnosticDescription[] getDiagnostics(string opType, DiagnosticDescription diag } } - incrementOps("++", "nint", "nint nint.op_Increment(nint value)", + unifiedIncrementOps("++", "System.IntPtr", "nint nint.op_Increment(nint value)", values: $"{int.MinValue}, -1, 0, {int.MaxValue - 1}, {int.MaxValue}", expectedResult: $"-2147483647, 0, 1, 2147483647, {(IntPtr.Size == 4 ? "-2147483648" : "2147483648")}", @"{ @@ -9804,7 +6878,7 @@ .locals init (nint? V_0, IL_002a: stobj ""nint?"" IL_002f: ret }"); - incrementOps("++", "nuint", "nuint nuint.op_Increment(nuint value)", + unifiedIncrementOps("++", "System.UIntPtr", "nuint nuint.op_Increment(nuint value)", values: $"0, {int.MaxValue}, {uint.MaxValue - 1}, {uint.MaxValue}", expectedResult: $"1, 2147483648, 4294967295, {(IntPtr.Size == 4 ? "0" : "4294967296")}", @"{ @@ -9842,7 +6916,7 @@ .locals init (nuint? V_0, IL_002a: stobj ""nuint?"" IL_002f: ret }"); - incrementOps("--", "nint", "nint nint.op_Decrement(nint value)", + unifiedIncrementOps("--", "System.IntPtr", "nint nint.op_Decrement(nint value)", values: $"{int.MinValue}, {int.MinValue + 1}, 0, 1, {int.MaxValue}", expectedResult: $"{(IntPtr.Size == 4 ? "2147483647" : "-2147483649")}, -2147483648, -1, 0, 2147483646", @"{ @@ -9880,7 +6954,7 @@ .locals init (nint? V_0, IL_002a: stobj ""nint?"" IL_002f: ret }"); - incrementOps("--", "nuint", "nuint nuint.op_Decrement(nuint value)", + unifiedIncrementOps("--", "System.UIntPtr", "nuint nuint.op_Decrement(nuint value)", values: $"0, 1, {uint.MaxValue}", expectedResult: $"{(IntPtr.Size == 4 ? uint.MaxValue.ToString() : ulong.MaxValue.ToString())}, 0, 4294967294", @"{ @@ -9954,7 +7028,8 @@ static void Main() }} }} }}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + var comp = CreateEmptyCompilation(source, new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; comp.VerifyDiagnostics(expectedDiagnostics); var tree = comp.SyntaxTrees[0]; @@ -9977,68 +7052,138 @@ public void UnaryOperators_UserDefined() { string sourceA = @"namespace System -{ - public class Object { } - public class String { } - public abstract class ValueType { } - public struct Void { } - public struct Boolean { } - public struct Int32 { } - public struct Enum { } - public class Attribute { } - public class AttributeUsageAttribute : Attribute - { - public AttributeUsageAttribute(AttributeTargets validOn) { } - public bool AllowMultiple { get; set; } - public bool Inherited { get; set; } - } - public enum AttributeTargets { } - public struct IntPtr { - public static IntPtr operator-(IntPtr i) => i; - } -}"; + public class Object { } + public class String { } + public abstract class ValueType { } + public struct Void { } + public struct Boolean { } + public struct Int32 { } + public struct Enum { } + public class Attribute { } + public class AttributeUsageAttribute : Attribute + { + public AttributeUsageAttribute(AttributeTargets validOn) { } + public bool AllowMultiple { get; set; } + public bool Inherited { get; set; } + } + public enum AttributeTargets { } + public struct IntPtr + { + public static IntPtr operator-(IntPtr i) => i; + } + }"; string sourceB = @"class Program -{ - static System.IntPtr F1(System.IntPtr i) => -i; - static nint F2(nint i) => -i; -}"; + { + static System.IntPtr F1(System.IntPtr i) => -i; + static nint F2(nint i) => -i; + }"; var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9); comp.VerifyDiagnostics(); var verifier = CompileAndVerify(comp, emitOptions: EmitOptions.Default.WithRuntimeMetadataVersion("0.0.0.0"), verify: Verification.Skipped); verifier.VerifyIL("Program.F1", @"{ - // Code size 7 (0x7) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: call ""System.IntPtr System.IntPtr.op_UnaryNegation(System.IntPtr)"" - IL_0006: ret -}"); + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: call ""System.IntPtr System.IntPtr.op_UnaryNegation(System.IntPtr)"" + IL_0006: ret + }"); verifier.VerifyIL("Program.F2", @"{ - // Code size 3 (0x3) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: neg - IL_0002: ret -}"); + // Code size 3 (0x3) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: neg + IL_0002: ret + }"); } - [Theory] - [InlineData("nint")] - [InlineData("nuint")] - [InlineData("nint?")] - [InlineData("nuint?")] - public void UnaryAndBinaryOperators_UserDefinedConversions(string type) - { - string sourceA = + [Fact] + public void UnaryAndBinaryOperators_UserDefinedConversions() + { + verifyBoth("System.IntPtr", + // (5,9): error CS0266: Cannot implicitly convert type 'long' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // ++x; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "++x").WithArguments("long", "MyInt").WithLocation(5, 9), + // (6,9): error CS0266: Cannot implicitly convert type 'long' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // x++; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x++").WithArguments("long", "MyInt").WithLocation(6, 9), + // (7,9): error CS0266: Cannot implicitly convert type 'long' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // --x; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "--x").WithArguments("long", "MyInt").WithLocation(7, 9), + // (8,9): error CS0266: Cannot implicitly convert type 'long' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // x--; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x--").WithArguments("long", "MyInt").WithLocation(8, 9) + ); + + verifyBoth("System.IntPtr?", + // (5,9): error CS0266: Cannot implicitly convert type 'long?' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // ++x; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "++x").WithArguments("long?", "MyInt").WithLocation(5, 9), + // (6,9): error CS0266: Cannot implicitly convert type 'long?' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // x++; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x++").WithArguments("long?", "MyInt").WithLocation(6, 9), + // (7,9): error CS0266: Cannot implicitly convert type 'long?' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // --x; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "--x").WithArguments("long?", "MyInt").WithLocation(7, 9), + // (8,9): error CS0266: Cannot implicitly convert type 'long?' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // x--; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x--").WithArguments("long?", "MyInt").WithLocation(8, 9) + ); + + verifyBoth("System.UIntPtr", + // (5,9): error CS0266: Cannot implicitly convert type 'ulong' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // ++x; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "++x").WithArguments("ulong", "MyInt").WithLocation(5, 9), + // (6,9): error CS0266: Cannot implicitly convert type 'ulong' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // x++; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x++").WithArguments("ulong", "MyInt").WithLocation(6, 9), + // (7,9): error CS0266: Cannot implicitly convert type 'ulong' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // --x; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "--x").WithArguments("ulong", "MyInt").WithLocation(7, 9), + // (8,9): error CS0266: Cannot implicitly convert type 'ulong' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // x--; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x--").WithArguments("ulong", "MyInt").WithLocation(8, 9), + // (10,13): error CS0035: Operator '-' is ambiguous on an operand of type 'MyInt' + // _ = -x; + Diagnostic(ErrorCode.ERR_AmbigUnaryOp, "-x").WithArguments("-", "MyInt").WithLocation(10, 13) + ); + + verifyBoth("System.UIntPtr?", + // (5,9): error CS0266: Cannot implicitly convert type 'ulong?' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // ++x; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "++x").WithArguments("ulong?", "MyInt").WithLocation(5, 9), + // (6,9): error CS0266: Cannot implicitly convert type 'ulong?' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // x++; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x++").WithArguments("ulong?", "MyInt").WithLocation(6, 9), + // (7,9): error CS0266: Cannot implicitly convert type 'ulong?' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // --x; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "--x").WithArguments("ulong?", "MyInt").WithLocation(7, 9), + // (8,9): error CS0266: Cannot implicitly convert type 'ulong?' to 'MyInt'. An explicit conversion exists (are you missing a cast?) + // x--; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x--").WithArguments("ulong?", "MyInt").WithLocation(8, 9), + // (10,13): error CS0035: Operator '-' is ambiguous on an operand of type 'MyInt' + // _ = -x; + Diagnostic(ErrorCode.ERR_AmbigUnaryOp, "-x").WithArguments("-", "MyInt").WithLocation(10, 13) + ); + + void verifyBoth(string type, params DiagnosticDescription[] expected) + { + verify(type, expected); + verify(AsNative(type), expected); + } + + void verify(string type, params DiagnosticDescription[] expected) + { + string sourceA = $@"class MyInt {{ public static implicit operator {type}(MyInt i) => throw null; public static implicit operator MyInt({type} i) => throw null; }}"; - string sourceB = + string sourceB = @"class Program { static void F(MyInt x, MyInt y) @@ -10057,49 +7202,30 @@ static void F(MyInt x, MyInt y) _ = x << 1; } }"; - var comp = CreateCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (5,9): error CS0023: Operator '++' cannot be applied to operand of type 'MyInt' - // ++x; - Diagnostic(ErrorCode.ERR_BadUnaryOp, "++x").WithArguments("++", "MyInt").WithLocation(5, 9), - // (6,9): error CS0023: Operator '++' cannot be applied to operand of type 'MyInt' - // x++; - Diagnostic(ErrorCode.ERR_BadUnaryOp, "x++").WithArguments("++", "MyInt").WithLocation(6, 9), - // (7,9): error CS0023: Operator '--' cannot be applied to operand of type 'MyInt' - // --x; - Diagnostic(ErrorCode.ERR_BadUnaryOp, "--x").WithArguments("--", "MyInt").WithLocation(7, 9), - // (8,9): error CS0023: Operator '--' cannot be applied to operand of type 'MyInt' - // x--; - Diagnostic(ErrorCode.ERR_BadUnaryOp, "x--").WithArguments("--", "MyInt").WithLocation(8, 9), - // (9,13): error CS0023: Operator '+' cannot be applied to operand of type 'MyInt' - // _ = +x; - Diagnostic(ErrorCode.ERR_BadUnaryOp, "+x").WithArguments("+", "MyInt").WithLocation(9, 13), - // (10,13): error CS0023: Operator '-' cannot be applied to operand of type 'MyInt' - // _ = -x; - Diagnostic(ErrorCode.ERR_BadUnaryOp, "-x").WithArguments("-", "MyInt").WithLocation(10, 13), - // (11,13): error CS0023: Operator '~' cannot be applied to operand of type 'MyInt' - // _ = ~x; - Diagnostic(ErrorCode.ERR_BadUnaryOp, "~x").WithArguments("~", "MyInt").WithLocation(11, 13), - // (12,13): error CS0019: Operator '+' cannot be applied to operands of type 'MyInt' and 'MyInt' - // _ = x + y; - Diagnostic(ErrorCode.ERR_BadBinaryOps, "x + y").WithArguments("+", "MyInt", "MyInt").WithLocation(12, 13), - // (13,13): error CS0019: Operator '*' cannot be applied to operands of type 'MyInt' and 'MyInt' - // _ = x * y; - Diagnostic(ErrorCode.ERR_BadBinaryOps, "x * y").WithArguments("*", "MyInt", "MyInt").WithLocation(13, 13), - // (14,13): error CS0019: Operator '<' cannot be applied to operands of type 'MyInt' and 'MyInt' - // _ = x < y; - Diagnostic(ErrorCode.ERR_BadBinaryOps, "x < y").WithArguments("<", "MyInt", "MyInt").WithLocation(14, 13), - // (15,13): error CS0019: Operator '&' cannot be applied to operands of type 'MyInt' and 'MyInt' - // _ = x & y; - Diagnostic(ErrorCode.ERR_BadBinaryOps, "x & y").WithArguments("&", "MyInt", "MyInt").WithLocation(15, 13), - // (16,13): error CS0019: Operator '<<' cannot be applied to operands of type 'MyInt' and 'int' - // _ = x << 1; - Diagnostic(ErrorCode.ERR_BadBinaryOps, "x << 1").WithArguments("<<", "MyInt", "int").WithLocation(16, 13)); + var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(expected); + } } [Fact] public void BinaryOperators() { + void unifiedBinaryOps(string op, string leftType, string rightType, string expectedSymbol1 = null, string expectedSymbol2 = "", DiagnosticDescription[] diagnostics1 = null, DiagnosticDescription[] diagnostics2 = null) + { + binaryOps(op, leftType, rightType, expectedSymbol1, expectedSymbol2, diagnostics1, diagnostics2); + + var fullLeftType = leftType switch + { + "nint" => "System.IntPtr", + "nint?" => "System.IntPtr?", + "nuint" => "System.UIntPtr", + "nuint?" => "System.UIntPtr?", + _ => throw ExceptionUtilities.Unreachable + }; + binaryOps(op, fullLeftType, rightType, expectedSymbol1, expectedSymbol2, diagnostics1, diagnostics2); + } + void binaryOps(string op, string leftType, string rightType, string expectedSymbol1 = null, string expectedSymbol2 = "", DiagnosticDescription[] diagnostics1 = null, DiagnosticDescription[] diagnostics2 = null) { binaryOp(op, leftType, rightType, expectedSymbol1, diagnostics1); @@ -10118,7 +7244,7 @@ void binaryOp(string op, string leftType, string rightType, string expectedSymbo static DiagnosticDescription[] getBadBinaryOpsDiagnostics(string op, string leftType, string rightType, bool includeBadBinaryOps = true, bool includeVoidError = false) { var builder = ArrayBuilder.GetInstance(); - if (includeBadBinaryOps) builder.Add(Diagnostic(ErrorCode.ERR_BadBinaryOps, $"x {op} y").WithArguments(op, leftType, rightType)); + if (includeBadBinaryOps) builder.Add(Diagnostic(ErrorCode.ERR_BadBinaryOps, $"x {op} y").WithArguments(op, AsNative(leftType), AsNative(rightType))); if (includeVoidError) builder.Add(Diagnostic(ErrorCode.ERR_VoidError, $"x {op} y")); return builder.ToArrayAndFree(); } @@ -10130,1838 +7256,1041 @@ static DiagnosticDescription[] getAmbiguousBinaryOpsDiagnostics(string op, strin var arithmeticOperators = new[] { - ("-", "op_Subtraction"), - ("*", "op_Multiply"), - ("/", "op_Division"), - ("%", "op_Modulus"), - }; + ("-", "op_Subtraction"), + ("*", "op_Multiply"), + ("/", "op_Division"), + ("%", "op_Modulus"), + }; var additionOperators = new[] { - ("+", "op_Addition"), - }; + ("+", "op_Addition"), + }; var comparisonOperators = new[] { - ("<", "op_LessThan"), - ("<=", "op_LessThanOrEqual"), - (">", "op_GreaterThan"), - (">=", "op_GreaterThanOrEqual"), - }; + ("<", "op_LessThan"), + ("<=", "op_LessThanOrEqual"), + (">", "op_GreaterThan"), + (">=", "op_GreaterThanOrEqual"), + }; var shiftOperators = new[] { - ("<<", "op_LeftShift"), - (">>", "op_RightShift"), - }; + ("<<", "op_LeftShift"), + (">>", "op_RightShift"), + }; var equalityOperators = new[] { - ("==", "op_Equality"), - ("!=", "op_Inequality"), - }; + ("==", "op_Equality"), + ("!=", "op_Inequality"), + }; var logicalOperators = new[] { - ("&", "op_BitwiseAnd"), - ("|", "op_BitwiseOr"), - ("^", "op_ExclusiveOr"), - }; + ("&", "op_BitwiseAnd"), + ("|", "op_BitwiseOr"), + ("^", "op_ExclusiveOr"), + }; foreach ((string symbol, string name) in arithmeticOperators) { bool includeBadBinaryOps = (symbol != "-"); - binaryOps(symbol, "nint", "object"); - binaryOps(symbol, "nint", "string"); - binaryOps(symbol, "nint", "void*", null, (symbol == "-") ? $"void* void*.{name}(void* left, long right)" : null, getBadBinaryOpsDiagnostics(symbol, "nint", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nint", includeBadBinaryOps: includeBadBinaryOps, includeVoidError: true)); - binaryOps(symbol, "nint", "bool"); - binaryOps(symbol, "nint", "char", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "sbyte", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "byte", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "short", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "ushort", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "int", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "uint", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "nint", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint")); - binaryOps(symbol, "nint", "long", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint")); - binaryOps(symbol, "nint", "float", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nint", "double", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nint", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint", "System.IntPtr", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "System.UIntPtr"); - binaryOps(symbol, "nint", "bool?"); - binaryOps(symbol, "nint", "char?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "sbyte?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "byte?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "short?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "ushort?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "int?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "uint?", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "nint?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint")); - binaryOps(symbol, "nint", "long?", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint")); - binaryOps(symbol, "nint", "float?", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nint", "double?", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nint", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint", "System.IntPtr?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "System.UIntPtr?"); - binaryOps(symbol, "nint", "object"); - binaryOps(symbol, "nint?", "string"); - binaryOps(symbol, "nint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nint?", includeVoidError: true)); - binaryOps(symbol, "nint?", "bool"); - binaryOps(symbol, "nint?", "char", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "sbyte", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "byte", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "short", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "ushort", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "int", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "uint", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "nint", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?")); - binaryOps(symbol, "nint?", "long", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint?")); - binaryOps(symbol, "nint?", "float", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nint?", "double", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nint?", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint?", "System.IntPtr", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "System.UIntPtr"); - binaryOps(symbol, "nint?", "bool?"); - binaryOps(symbol, "nint?", "char?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "sbyte?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "byte?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "short?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "ushort?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "int?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "uint?", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "nint?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?")); - binaryOps(symbol, "nint?", "long?", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint?")); - binaryOps(symbol, "nint?", "float?", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nint?", "double?", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nint?", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint?", "System.IntPtr?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "System.UIntPtr?"); - binaryOps(symbol, "nuint", "object"); - binaryOps(symbol, "nuint", "string"); - binaryOps(symbol, "nuint", "void*", null, (symbol == "-") ? $"void* void*.{name}(void* left, ulong right)" : null, getBadBinaryOpsDiagnostics(symbol, "nuint", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint", includeBadBinaryOps: includeBadBinaryOps, includeVoidError: true)); - binaryOps(symbol, "nuint", "bool"); - binaryOps(symbol, "nuint", "char", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint")); - binaryOps(symbol, "nuint", "byte", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint")); - binaryOps(symbol, "nuint", "ushort", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint")); - binaryOps(symbol, "nuint", "uint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint")); - binaryOps(symbol, "nuint", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint")); - binaryOps(symbol, "nuint", "ulong", $"ulong ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint", "float", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nuint", "double", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nuint", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint", "System.IntPtr"); - binaryOps(symbol, "nuint", "System.UIntPtr", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "bool?"); - binaryOps(symbol, "nuint", "char?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint")); - binaryOps(symbol, "nuint", "byte?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint")); - binaryOps(symbol, "nuint", "ushort?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint")); - binaryOps(symbol, "nuint", "uint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint")); - binaryOps(symbol, "nuint", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint")); - binaryOps(symbol, "nuint", "ulong?", $"ulong ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint", "float?", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nuint", "double?", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nuint", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint", "System.IntPtr?"); - binaryOps(symbol, "nuint", "System.UIntPtr?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "object"); - binaryOps(symbol, "nuint?", "string"); - binaryOps(symbol, "nuint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint?", includeVoidError: true)); - binaryOps(symbol, "nuint?", "bool"); - binaryOps(symbol, "nuint?", "char", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint?")); - binaryOps(symbol, "nuint?", "byte", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint?")); - binaryOps(symbol, "nuint?", "ushort", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint?")); - binaryOps(symbol, "nuint?", "uint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?")); - binaryOps(symbol, "nuint?", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint?")); - binaryOps(symbol, "nuint?", "ulong", $"ulong ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint?", "float", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nuint?", "double", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nuint?", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint?", "System.IntPtr"); - binaryOps(symbol, "nuint?", "System.UIntPtr", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "bool?"); - binaryOps(symbol, "nuint?", "char?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint?")); - binaryOps(symbol, "nuint?", "byte?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint?")); - binaryOps(symbol, "nuint?", "ushort?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint?")); - binaryOps(symbol, "nuint?", "uint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?")); - binaryOps(symbol, "nuint?", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint?")); - binaryOps(symbol, "nuint?", "ulong?", $"ulong ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint?", "float?", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nuint?", "double?", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nuint?", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint?", "System.IntPtr?"); - binaryOps(symbol, "nuint?", "System.UIntPtr?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.IntPtr", "object"); - binaryOps(symbol, "System.IntPtr", "string"); - binaryOps(symbol, "System.IntPtr", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.IntPtr", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.IntPtr", includeVoidError: true)); - binaryOps(symbol, "System.IntPtr", "bool"); - binaryOps(symbol, "System.IntPtr", "char", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr", "sbyte", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr", "byte", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr", "short", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr", "ushort", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr", "int", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr", "uint"); - binaryOps(symbol, "System.IntPtr", "nint", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr", "nuint"); - binaryOps(symbol, "System.IntPtr", "long"); - binaryOps(symbol, "System.IntPtr", "ulong"); - binaryOps(symbol, "System.IntPtr", "float"); - binaryOps(symbol, "System.IntPtr", "double"); - binaryOps(symbol, "System.IntPtr", "decimal"); - binaryOps(symbol, "System.IntPtr", "System.IntPtr"); - binaryOps(symbol, "System.IntPtr", "System.UIntPtr"); - binaryOps(symbol, "System.IntPtr", "bool?"); - binaryOps(symbol, "System.IntPtr", "char?", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr", "sbyte?", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr", "byte?", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr", "short?", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr", "ushort?", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr", "int?", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr", "uint?"); - binaryOps(symbol, "System.IntPtr", "nint?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr", "nuint?"); - binaryOps(symbol, "System.IntPtr", "long?"); - binaryOps(symbol, "System.IntPtr", "ulong?"); - binaryOps(symbol, "System.IntPtr", "float?"); - binaryOps(symbol, "System.IntPtr", "double?"); - binaryOps(symbol, "System.IntPtr", "decimal?"); - binaryOps(symbol, "System.IntPtr", "System.IntPtr?"); - binaryOps(symbol, "System.IntPtr", "System.UIntPtr?"); - binaryOps(symbol, "System.IntPtr", "object"); - binaryOps(symbol, "System.IntPtr?", "string"); - binaryOps(symbol, "System.IntPtr?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.IntPtr?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.IntPtr?", includeVoidError: true)); - binaryOps(symbol, "System.IntPtr?", "bool"); - binaryOps(symbol, "System.IntPtr?", "char", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr?", "sbyte", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr?", "byte", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr?", "short", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr?", "ushort", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr?", "int", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr?", "uint"); - binaryOps(symbol, "System.IntPtr?", "nint", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr?", "nuint"); - binaryOps(symbol, "System.IntPtr?", "long"); - binaryOps(symbol, "System.IntPtr?", "ulong"); - binaryOps(symbol, "System.IntPtr?", "float"); - binaryOps(symbol, "System.IntPtr?", "double"); - binaryOps(symbol, "System.IntPtr?", "decimal"); - binaryOps(symbol, "System.IntPtr?", "System.IntPtr"); - binaryOps(symbol, "System.IntPtr?", "System.UIntPtr"); - binaryOps(symbol, "System.IntPtr?", "bool?"); - binaryOps(symbol, "System.IntPtr?", "char?", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr?", "sbyte?", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr?", "byte?", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr?", "short?", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr?", "ushort?", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr?", "int?", (symbol == "-") ? $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.IntPtr?", "uint?"); - binaryOps(symbol, "System.IntPtr?", "nint?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr?", "nuint?"); - binaryOps(symbol, "System.IntPtr?", "long?"); - binaryOps(symbol, "System.IntPtr?", "ulong?"); - binaryOps(symbol, "System.IntPtr?", "float?"); - binaryOps(symbol, "System.IntPtr?", "double?"); - binaryOps(symbol, "System.IntPtr?", "decimal?"); - binaryOps(symbol, "System.IntPtr?", "System.IntPtr?"); - binaryOps(symbol, "System.IntPtr?", "System.UIntPtr?"); - binaryOps(symbol, "System.UIntPtr", "object"); - binaryOps(symbol, "System.UIntPtr", "string"); - binaryOps(symbol, "System.UIntPtr", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.UIntPtr", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.UIntPtr", includeVoidError: true)); - binaryOps(symbol, "System.UIntPtr", "bool"); - binaryOps(symbol, "System.UIntPtr", "char", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr", "sbyte", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr", "byte", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr", "short", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr", "ushort", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr", "int", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr", "uint"); - binaryOps(symbol, "System.UIntPtr", "nint"); - binaryOps(symbol, "System.UIntPtr", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr", "long"); - binaryOps(symbol, "System.UIntPtr", "ulong"); - binaryOps(symbol, "System.UIntPtr", "float"); - binaryOps(symbol, "System.UIntPtr", "double"); - binaryOps(symbol, "System.UIntPtr", "decimal"); - binaryOps(symbol, "System.UIntPtr", "System.IntPtr"); - binaryOps(symbol, "System.UIntPtr", "System.UIntPtr"); - binaryOps(symbol, "System.UIntPtr", "bool?"); - binaryOps(symbol, "System.UIntPtr", "char?", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr", "sbyte?", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr", "byte?", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr", "short?", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr", "ushort?", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr", "int?", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr", "uint?"); - binaryOps(symbol, "System.UIntPtr", "nint?"); - binaryOps(symbol, "System.UIntPtr", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr", "long?"); - binaryOps(symbol, "System.UIntPtr", "ulong?"); - binaryOps(symbol, "System.UIntPtr", "float?"); - binaryOps(symbol, "System.UIntPtr", "double?"); - binaryOps(symbol, "System.UIntPtr", "decimal?"); - binaryOps(symbol, "System.UIntPtr", "System.IntPtr?"); - binaryOps(symbol, "System.UIntPtr", "System.UIntPtr?"); - binaryOps(symbol, "System.UIntPtr?", "object"); - binaryOps(symbol, "System.UIntPtr?", "string"); - binaryOps(symbol, "System.UIntPtr?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.UIntPtr?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.UIntPtr?", includeVoidError: true)); - binaryOps(symbol, "System.UIntPtr?", "bool"); - binaryOps(symbol, "System.UIntPtr?", "char", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr?", "sbyte", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr?", "byte", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr?", "short", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr?", "ushort", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr?", "int", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr?", "uint"); - binaryOps(symbol, "System.UIntPtr?", "nint"); - binaryOps(symbol, "System.UIntPtr?", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr?", "long"); - binaryOps(symbol, "System.UIntPtr?", "ulong"); - binaryOps(symbol, "System.UIntPtr?", "float"); - binaryOps(symbol, "System.UIntPtr?", "double"); - binaryOps(symbol, "System.UIntPtr?", "decimal"); - binaryOps(symbol, "System.UIntPtr?", "System.IntPtr"); - binaryOps(symbol, "System.UIntPtr?", "System.UIntPtr"); - binaryOps(symbol, "System.UIntPtr?", "bool?"); - binaryOps(symbol, "System.UIntPtr?", "char?", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr?", "sbyte?", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr?", "byte?", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr?", "short?", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr?", "ushort?", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr?", "int?", (symbol == "-") ? $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)" : null, null); - binaryOps(symbol, "System.UIntPtr?", "uint?"); - binaryOps(symbol, "System.UIntPtr?", "nint?"); - binaryOps(symbol, "System.UIntPtr?", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr?", "long?"); - binaryOps(symbol, "System.UIntPtr?", "ulong?"); - binaryOps(symbol, "System.UIntPtr?", "float?"); - binaryOps(symbol, "System.UIntPtr?", "double?"); - binaryOps(symbol, "System.UIntPtr?", "decimal?"); - binaryOps(symbol, "System.UIntPtr?", "System.IntPtr?"); - binaryOps(symbol, "System.UIntPtr?", "System.UIntPtr?"); + + // nint arithmeticOp type + unifiedBinaryOps(symbol, "nint", "object"); + unifiedBinaryOps(symbol, "nint", "string"); + unifiedBinaryOps(symbol, "nint", "void*", null, (symbol == "-") ? $"void* void*.{name}(void* left, long right)" : null, getBadBinaryOpsDiagnostics(symbol, "nint", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nint", includeBadBinaryOps: includeBadBinaryOps, includeVoidError: true)); + unifiedBinaryOps(symbol, "nint", "bool"); + unifiedBinaryOps(symbol, "nint", "char", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "sbyte", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "byte", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "short", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "ushort", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "int", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "uint", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "nint", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint")); + unifiedBinaryOps(symbol, "nint", "long", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint")); + unifiedBinaryOps(symbol, "nint", "float", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint", "double", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint", "System.IntPtr", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "System.UIntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint")); + + // nint arithmeticOp type? + unifiedBinaryOps(symbol, "nint", "bool?"); + unifiedBinaryOps(symbol, "nint", "char?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "sbyte?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "byte?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "short?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "ushort?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "int?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "uint?", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "nint?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint")); + unifiedBinaryOps(symbol, "nint", "long?", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint")); + unifiedBinaryOps(symbol, "nint", "float?", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint", "double?", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint", "System.IntPtr?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "System.UIntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint")); + unifiedBinaryOps(symbol, "nint", "object"); + + // nint? arithmeticOp type + unifiedBinaryOps(symbol, "nint?", "string"); + unifiedBinaryOps(symbol, "nint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nint?", includeVoidError: true)); + unifiedBinaryOps(symbol, "nint?", "bool"); + unifiedBinaryOps(symbol, "nint?", "char", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "sbyte", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "byte", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "short", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "ushort", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "int", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "uint", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "nint", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?")); + unifiedBinaryOps(symbol, "nint?", "long", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint?")); + unifiedBinaryOps(symbol, "nint?", "float", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint?", "double", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint?", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint?", "System.IntPtr", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "System.UIntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?")); + + // nint? arithmeticOp type? + unifiedBinaryOps(symbol, "nint?", "bool?"); + unifiedBinaryOps(symbol, "nint?", "char?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "sbyte?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "byte?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "short?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "ushort?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "int?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "uint?", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "nint?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?")); + unifiedBinaryOps(symbol, "nint?", "long?", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint?")); + unifiedBinaryOps(symbol, "nint?", "float?", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint?", "double?", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint?", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint?", "System.IntPtr?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "System.UIntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?")); + + // nuint arithmeticOp type + unifiedBinaryOps(symbol, "nuint", "object"); + unifiedBinaryOps(symbol, "nuint", "string"); + unifiedBinaryOps(symbol, "nuint", "void*", null, (symbol == "-") ? $"void* void*.{name}(void* left, ulong right)" : null, getBadBinaryOpsDiagnostics(symbol, "nuint", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint", includeBadBinaryOps: includeBadBinaryOps, includeVoidError: true)); + unifiedBinaryOps(symbol, "nuint", "bool"); + unifiedBinaryOps(symbol, "nuint", "char", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint")); + unifiedBinaryOps(symbol, "nuint", "byte", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ushort", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint")); + unifiedBinaryOps(symbol, "nuint", "uint", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint")); + unifiedBinaryOps(symbol, "nuint", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ulong", $"ulong ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint", "float", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint", "double", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint", "System.IntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint")); + unifiedBinaryOps(symbol, "nuint", "System.UIntPtr", $"nuint nuint.{name}(nuint left, nuint right)"); + + // nuint arithmeticOp type? + unifiedBinaryOps(symbol, "nuint", "bool?"); + unifiedBinaryOps(symbol, "nuint", "char?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "byte?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ushort?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "uint?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ulong?", $"ulong ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint", "float?", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint", "double?", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint", "System.IntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "System.UIntPtr?", $"nuint nuint.{name}(nuint left, nuint right)"); + + // nuint? arithmeticOp type + unifiedBinaryOps(symbol, "nuint?", "object"); + unifiedBinaryOps(symbol, "nuint?", "string"); + unifiedBinaryOps(symbol, "nuint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint?", includeVoidError: true)); + unifiedBinaryOps(symbol, "nuint?", "bool"); + unifiedBinaryOps(symbol, "nuint?", "char", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "byte", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ushort", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "uint", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ulong", $"ulong ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint?", "float", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint?", "double", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint?", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint?", "System.IntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "System.UIntPtr", $"nuint nuint.{name}(nuint left, nuint right)"); + + // nuint? arithmeticOp type? + unifiedBinaryOps(symbol, "nuint?", "bool?"); + unifiedBinaryOps(symbol, "nuint?", "char?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "byte?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ushort?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "uint?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ulong?", $"ulong ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint?", "float?", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint?", "double?", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint?", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint?", "System.IntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "System.UIntPtr?", $"nuint nuint.{name}(nuint left, nuint right)"); } foreach ((string symbol, string name) in comparisonOperators) { - binaryOps(symbol, "nint", "object"); - binaryOps(symbol, "nint", "string"); - binaryOps(symbol, "nint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nint")); - binaryOps(symbol, "nint", "bool"); - binaryOps(symbol, "nint", "char", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "sbyte", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "byte", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "short", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "ushort", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "int", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "uint", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "nint", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint")); - binaryOps(symbol, "nint", "long", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint")); - binaryOps(symbol, "nint", "float", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nint", "double", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nint", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint", "System.IntPtr", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "System.UIntPtr"); - binaryOps(symbol, "nint", "bool?"); - binaryOps(symbol, "nint", "char?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "sbyte?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "byte?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "short?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "ushort?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "int?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "uint?", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "nint?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint")); - binaryOps(symbol, "nint", "long?", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint")); - binaryOps(symbol, "nint", "float?", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nint", "double?", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nint", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint", "System.IntPtr?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "System.UIntPtr?"); - binaryOps(symbol, "nint", "object"); - binaryOps(symbol, "nint?", "string"); - binaryOps(symbol, "nint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint?", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nint?")); - binaryOps(symbol, "nint?", "bool"); - binaryOps(symbol, "nint?", "char", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "sbyte", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "byte", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "short", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "ushort", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "int", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "uint", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "nint", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?")); - binaryOps(symbol, "nint?", "long", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint?")); - binaryOps(symbol, "nint?", "float", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nint?", "double", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nint?", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint?", "System.IntPtr", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "System.UIntPtr"); - binaryOps(symbol, "nint?", "bool?"); - binaryOps(symbol, "nint?", "char?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "sbyte?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "byte?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "short?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "ushort?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "int?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "uint?", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "nint?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?")); - binaryOps(symbol, "nint?", "long?", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint?")); - binaryOps(symbol, "nint?", "float?", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nint?", "double?", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nint?", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint?", "System.IntPtr?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "System.UIntPtr?"); - binaryOps(symbol, "nuint", "object"); - binaryOps(symbol, "nuint", "string"); - binaryOps(symbol, "nuint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint")); - binaryOps(symbol, "nuint", "bool"); - binaryOps(symbol, "nuint", "char", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint")); - binaryOps(symbol, "nuint", "byte", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint")); - binaryOps(symbol, "nuint", "ushort", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint")); - binaryOps(symbol, "nuint", "uint", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint")); - binaryOps(symbol, "nuint", "nuint", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint")); - binaryOps(symbol, "nuint", "ulong", $"bool ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint", "float", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nuint", "double", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nuint", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint", "System.IntPtr"); - binaryOps(symbol, "nuint", "System.UIntPtr", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "bool?"); - binaryOps(symbol, "nuint", "char?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint")); - binaryOps(symbol, "nuint", "byte?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint")); - binaryOps(symbol, "nuint", "ushort?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint")); - binaryOps(symbol, "nuint", "uint?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint")); - binaryOps(symbol, "nuint", "nuint?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint")); - binaryOps(symbol, "nuint", "ulong?", $"bool ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint", "float?", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nuint", "double?", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nuint", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint", "System.IntPtr?"); - binaryOps(symbol, "nuint", "System.UIntPtr?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "object"); - binaryOps(symbol, "nuint?", "string"); - binaryOps(symbol, "nuint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint?", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint?")); - binaryOps(symbol, "nuint?", "bool"); - binaryOps(symbol, "nuint?", "char", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint?")); - binaryOps(symbol, "nuint?", "byte", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint?")); - binaryOps(symbol, "nuint?", "ushort", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint?")); - binaryOps(symbol, "nuint?", "uint", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?")); - binaryOps(symbol, "nuint?", "nuint", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint?")); - binaryOps(symbol, "nuint?", "ulong", $"bool ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint?", "float", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nuint?", "double", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nuint?", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint?", "System.IntPtr"); - binaryOps(symbol, "nuint?", "System.UIntPtr", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "bool?"); - binaryOps(symbol, "nuint?", "char?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint?")); - binaryOps(symbol, "nuint?", "byte?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint?")); - binaryOps(symbol, "nuint?", "ushort?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint?")); - binaryOps(symbol, "nuint?", "uint?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?")); - binaryOps(symbol, "nuint?", "nuint?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint?")); - binaryOps(symbol, "nuint?", "ulong?", $"bool ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint?", "float?", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nuint?", "double?", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nuint?", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint?", "System.IntPtr?"); - binaryOps(symbol, "nuint?", "System.UIntPtr?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.IntPtr", "object"); - binaryOps(symbol, "System.IntPtr", "string"); - binaryOps(symbol, "System.IntPtr", "void*"); - binaryOps(symbol, "System.IntPtr", "bool"); - binaryOps(symbol, "System.IntPtr", "char"); - binaryOps(symbol, "System.IntPtr", "sbyte"); - binaryOps(symbol, "System.IntPtr", "byte"); - binaryOps(symbol, "System.IntPtr", "short"); - binaryOps(symbol, "System.IntPtr", "ushort"); - binaryOps(symbol, "System.IntPtr", "int"); - binaryOps(symbol, "System.IntPtr", "uint"); - binaryOps(symbol, "System.IntPtr", "nint", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr", "nuint"); - binaryOps(symbol, "System.IntPtr", "long"); - binaryOps(symbol, "System.IntPtr", "ulong"); - binaryOps(symbol, "System.IntPtr", "float"); - binaryOps(symbol, "System.IntPtr", "double"); - binaryOps(symbol, "System.IntPtr", "decimal"); - binaryOps(symbol, "System.IntPtr", "System.IntPtr"); - binaryOps(symbol, "System.IntPtr", "System.UIntPtr"); - binaryOps(symbol, "System.IntPtr", "bool?"); - binaryOps(symbol, "System.IntPtr", "char?"); - binaryOps(symbol, "System.IntPtr", "sbyte?"); - binaryOps(symbol, "System.IntPtr", "byte?"); - binaryOps(symbol, "System.IntPtr", "short?"); - binaryOps(symbol, "System.IntPtr", "ushort?"); - binaryOps(symbol, "System.IntPtr", "int?"); - binaryOps(symbol, "System.IntPtr", "uint?"); - binaryOps(symbol, "System.IntPtr", "nint?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr", "nuint?"); - binaryOps(symbol, "System.IntPtr", "long?"); - binaryOps(symbol, "System.IntPtr", "ulong?"); - binaryOps(symbol, "System.IntPtr", "float?"); - binaryOps(symbol, "System.IntPtr", "double?"); - binaryOps(symbol, "System.IntPtr", "decimal?"); - binaryOps(symbol, "System.IntPtr", "System.IntPtr?"); - binaryOps(symbol, "System.IntPtr", "System.UIntPtr?"); - binaryOps(symbol, "System.IntPtr", "object"); - binaryOps(symbol, "System.IntPtr?", "string"); - binaryOps(symbol, "System.IntPtr?", "void*"); - binaryOps(symbol, "System.IntPtr?", "bool"); - binaryOps(symbol, "System.IntPtr?", "char"); - binaryOps(symbol, "System.IntPtr?", "sbyte"); - binaryOps(symbol, "System.IntPtr?", "byte"); - binaryOps(symbol, "System.IntPtr?", "short"); - binaryOps(symbol, "System.IntPtr?", "ushort"); - binaryOps(symbol, "System.IntPtr?", "int"); - binaryOps(symbol, "System.IntPtr?", "uint"); - binaryOps(symbol, "System.IntPtr?", "nint", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr?", "nuint"); - binaryOps(symbol, "System.IntPtr?", "long"); - binaryOps(symbol, "System.IntPtr?", "ulong"); - binaryOps(symbol, "System.IntPtr?", "float"); - binaryOps(symbol, "System.IntPtr?", "double"); - binaryOps(symbol, "System.IntPtr?", "decimal"); - binaryOps(symbol, "System.IntPtr?", "System.IntPtr"); - binaryOps(symbol, "System.IntPtr?", "System.UIntPtr"); - binaryOps(symbol, "System.IntPtr?", "bool?"); - binaryOps(symbol, "System.IntPtr?", "char?"); - binaryOps(symbol, "System.IntPtr?", "sbyte?"); - binaryOps(symbol, "System.IntPtr?", "byte?"); - binaryOps(symbol, "System.IntPtr?", "short?"); - binaryOps(symbol, "System.IntPtr?", "ushort?"); - binaryOps(symbol, "System.IntPtr?", "int?"); - binaryOps(symbol, "System.IntPtr?", "uint?"); - binaryOps(symbol, "System.IntPtr?", "nint?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr?", "nuint?"); - binaryOps(symbol, "System.IntPtr?", "long?"); - binaryOps(symbol, "System.IntPtr?", "ulong?"); - binaryOps(symbol, "System.IntPtr?", "float?"); - binaryOps(symbol, "System.IntPtr?", "double?"); - binaryOps(symbol, "System.IntPtr?", "decimal?"); - binaryOps(symbol, "System.IntPtr?", "System.IntPtr?"); - binaryOps(symbol, "System.IntPtr?", "System.UIntPtr?"); - binaryOps(symbol, "System.UIntPtr", "object"); - binaryOps(symbol, "System.UIntPtr", "string"); - binaryOps(symbol, "System.UIntPtr", "void*"); - binaryOps(symbol, "System.UIntPtr", "bool"); - binaryOps(symbol, "System.UIntPtr", "char"); - binaryOps(symbol, "System.UIntPtr", "sbyte"); - binaryOps(symbol, "System.UIntPtr", "byte"); - binaryOps(symbol, "System.UIntPtr", "short"); - binaryOps(symbol, "System.UIntPtr", "ushort"); - binaryOps(symbol, "System.UIntPtr", "int"); - binaryOps(symbol, "System.UIntPtr", "uint"); - binaryOps(symbol, "System.UIntPtr", "nint"); - binaryOps(symbol, "System.UIntPtr", "nuint", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr", "long"); - binaryOps(symbol, "System.UIntPtr", "ulong"); - binaryOps(symbol, "System.UIntPtr", "float"); - binaryOps(symbol, "System.UIntPtr", "double"); - binaryOps(symbol, "System.UIntPtr", "decimal"); - binaryOps(symbol, "System.UIntPtr", "System.IntPtr"); - binaryOps(symbol, "System.UIntPtr", "System.UIntPtr"); - binaryOps(symbol, "System.UIntPtr", "bool?"); - binaryOps(symbol, "System.UIntPtr", "char?"); - binaryOps(symbol, "System.UIntPtr", "sbyte?"); - binaryOps(symbol, "System.UIntPtr", "byte?"); - binaryOps(symbol, "System.UIntPtr", "short?"); - binaryOps(symbol, "System.UIntPtr", "ushort?"); - binaryOps(symbol, "System.UIntPtr", "int?"); - binaryOps(symbol, "System.UIntPtr", "uint?"); - binaryOps(symbol, "System.UIntPtr", "nint?"); - binaryOps(symbol, "System.UIntPtr", "nuint?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr", "long?"); - binaryOps(symbol, "System.UIntPtr", "ulong?"); - binaryOps(symbol, "System.UIntPtr", "float?"); - binaryOps(symbol, "System.UIntPtr", "double?"); - binaryOps(symbol, "System.UIntPtr", "decimal?"); - binaryOps(symbol, "System.UIntPtr", "System.IntPtr?"); - binaryOps(symbol, "System.UIntPtr", "System.UIntPtr?"); - binaryOps(symbol, "System.UIntPtr", "object"); - binaryOps(symbol, "System.UIntPtr?", "string"); - binaryOps(symbol, "System.UIntPtr?", "void*"); - binaryOps(symbol, "System.UIntPtr?", "bool"); - binaryOps(symbol, "System.UIntPtr?", "char"); - binaryOps(symbol, "System.UIntPtr?", "sbyte"); - binaryOps(symbol, "System.UIntPtr?", "byte"); - binaryOps(symbol, "System.UIntPtr?", "short"); - binaryOps(symbol, "System.UIntPtr?", "ushort"); - binaryOps(symbol, "System.UIntPtr?", "int"); - binaryOps(symbol, "System.UIntPtr?", "uint"); - binaryOps(symbol, "System.UIntPtr?", "nint"); - binaryOps(symbol, "System.UIntPtr?", "nuint", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr?", "long"); - binaryOps(symbol, "System.UIntPtr?", "ulong"); - binaryOps(symbol, "System.UIntPtr?", "float"); - binaryOps(symbol, "System.UIntPtr?", "double"); - binaryOps(symbol, "System.UIntPtr?", "decimal"); - binaryOps(symbol, "System.UIntPtr?", "System.IntPtr"); - binaryOps(symbol, "System.UIntPtr?", "System.UIntPtr"); - binaryOps(symbol, "System.UIntPtr?", "bool?"); - binaryOps(symbol, "System.UIntPtr?", "char?"); - binaryOps(symbol, "System.UIntPtr?", "sbyte?"); - binaryOps(symbol, "System.UIntPtr?", "byte?"); - binaryOps(symbol, "System.UIntPtr?", "short?"); - binaryOps(symbol, "System.UIntPtr?", "ushort?"); - binaryOps(symbol, "System.UIntPtr?", "int?"); - binaryOps(symbol, "System.UIntPtr?", "uint?"); - binaryOps(symbol, "System.UIntPtr?", "nint?"); - binaryOps(symbol, "System.UIntPtr?", "nuint?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr?", "long?"); - binaryOps(symbol, "System.UIntPtr?", "ulong?"); - binaryOps(symbol, "System.UIntPtr?", "float?"); - binaryOps(symbol, "System.UIntPtr?", "double?"); - binaryOps(symbol, "System.UIntPtr?", "decimal?"); - binaryOps(symbol, "System.UIntPtr?", "System.IntPtr?"); - binaryOps(symbol, "System.UIntPtr?", "System.UIntPtr?"); + // nint comparisonOp type + unifiedBinaryOps(symbol, "nint", "object"); + unifiedBinaryOps(symbol, "nint", "string"); + unifiedBinaryOps(symbol, "nint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nint")); + unifiedBinaryOps(symbol, "nint", "bool"); + unifiedBinaryOps(symbol, "nint", "char", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "sbyte", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "byte", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "short", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "ushort", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "int", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "uint", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "nint", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint")); + unifiedBinaryOps(symbol, "nint", "long", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint")); + unifiedBinaryOps(symbol, "nint", "float", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint", "double", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint", "System.IntPtr", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "System.UIntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint")); + + // nint comparisonOp type? + unifiedBinaryOps(symbol, "nint", "bool?"); + unifiedBinaryOps(symbol, "nint", "char?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "sbyte?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "byte?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "short?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "ushort?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "int?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "uint?", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "nint?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint")); + unifiedBinaryOps(symbol, "nint", "long?", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint")); + unifiedBinaryOps(symbol, "nint", "float?", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint", "double?", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint", "System.IntPtr?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "System.UIntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint")); + unifiedBinaryOps(symbol, "nint", "object"); + + // nint? comparisonOp type + unifiedBinaryOps(symbol, "nint?", "string"); + unifiedBinaryOps(symbol, "nint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint?", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nint?")); + unifiedBinaryOps(symbol, "nint?", "bool"); + unifiedBinaryOps(symbol, "nint?", "char", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "sbyte", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "byte", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "short", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "ushort", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "int", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "uint", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "nint", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?")); + unifiedBinaryOps(symbol, "nint?", "long", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint?")); + unifiedBinaryOps(symbol, "nint?", "float", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint?", "double", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint?", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint?", "System.IntPtr", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "System.UIntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?")); + + // nint? comparisonOp type? + unifiedBinaryOps(symbol, "nint?", "bool?"); + unifiedBinaryOps(symbol, "nint?", "char?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "sbyte?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "byte?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "short?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "ushort?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "int?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "uint?", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "nint?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?")); + unifiedBinaryOps(symbol, "nint?", "long?", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint?")); + unifiedBinaryOps(symbol, "nint?", "float?", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint?", "double?", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint?", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint?", "System.IntPtr?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "System.UIntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?")); + + // nuint comparisonOp type + unifiedBinaryOps(symbol, "nuint", "object"); + unifiedBinaryOps(symbol, "nuint", "string"); + unifiedBinaryOps(symbol, "nuint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint")); + unifiedBinaryOps(symbol, "nuint", "bool"); + unifiedBinaryOps(symbol, "nuint", "char", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint")); + unifiedBinaryOps(symbol, "nuint", "byte", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ushort", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint")); + unifiedBinaryOps(symbol, "nuint", "uint", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint")); + unifiedBinaryOps(symbol, "nuint", "nuint", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ulong", $"bool ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint", "float", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint", "double", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint", "System.IntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint")); + unifiedBinaryOps(symbol, "nuint", "System.UIntPtr", $"bool nuint.{name}(nuint left, nuint right)"); + + // nuint comparisonOp type? + unifiedBinaryOps(symbol, "nuint", "bool?"); + unifiedBinaryOps(symbol, "nuint", "char?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "byte?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ushort?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "uint?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "nuint?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ulong?", $"bool ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint", "float?", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint", "double?", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint", "System.IntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "System.UIntPtr?", $"bool nuint.{name}(nuint left, nuint right)"); + + // nuint? comparisonOp type + unifiedBinaryOps(symbol, "nuint?", "object"); + unifiedBinaryOps(symbol, "nuint?", "string"); + unifiedBinaryOps(symbol, "nuint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint?", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "bool"); + unifiedBinaryOps(symbol, "nuint?", "char", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "byte", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ushort", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "uint", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "nuint", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ulong", $"bool ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint?", "float", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint?", "double", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint?", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint?", "System.IntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "System.UIntPtr", $"bool nuint.{name}(nuint left, nuint right)"); + + // nuint comparisonOp type? + unifiedBinaryOps(symbol, "nuint?", "bool?"); + unifiedBinaryOps(symbol, "nuint?", "char?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "byte?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ushort?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "uint?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "nuint?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ulong?", $"bool ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint?", "float?", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint?", "double?", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint?", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint?", "System.IntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "System.UIntPtr?", $"bool nuint.{name}(nuint left, nuint right)"); } foreach ((string symbol, string name) in additionOperators) { - binaryOps(symbol, "nint", "object"); - binaryOps(symbol, "nint", "string", $"string string.{name}(object left, string right)", $"string string.{name}(string left, object right)"); - binaryOps(symbol, "nint", "void*", $"void* void*.{name}(long left, void* right)", $"void* void*.{name}(void* left, long right)", new[] { Diagnostic(ErrorCode.ERR_VoidError, "x + y") }); - binaryOps(symbol, "nint", "bool"); - binaryOps(symbol, "nint", "char", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "sbyte", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "byte", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "short", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "ushort", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "int", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "uint", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "nint", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint")); - binaryOps(symbol, "nint", "long", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint")); - binaryOps(symbol, "nint", "float", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nint", "double", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nint", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint", "System.IntPtr", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "System.UIntPtr"); - binaryOps(symbol, "nint", "bool?"); - binaryOps(symbol, "nint", "char?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "sbyte?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "byte?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "short?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "ushort?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "int?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "uint?", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "nint?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint")); - binaryOps(symbol, "nint", "long?", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint")); - binaryOps(symbol, "nint", "float?", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nint", "double?", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nint", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint", "System.IntPtr?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "System.UIntPtr?"); - binaryOps(symbol, "nint", "object"); - binaryOps(symbol, "nint?", "string", $"string string.{name}(object left, string right)", $"string string.{name}(string left, object right)"); - binaryOps(symbol, "nint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nint?", includeVoidError: true)); - binaryOps(symbol, "nint?", "bool"); - binaryOps(symbol, "nint?", "char", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "sbyte", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "byte", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "short", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "ushort", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "int", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "uint", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "nint", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?")); - binaryOps(symbol, "nint?", "long", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint?")); - binaryOps(symbol, "nint?", "float", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nint?", "double", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nint?", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint?", "System.IntPtr", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "System.UIntPtr"); - binaryOps(symbol, "nint?", "bool?"); - binaryOps(symbol, "nint?", "char?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "sbyte?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "byte?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "short?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "ushort?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "int?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "uint?", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "nint?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?")); - binaryOps(symbol, "nint?", "long?", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint?")); - binaryOps(symbol, "nint?", "float?", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nint?", "double?", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nint?", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint?", "System.IntPtr?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "System.UIntPtr?"); - binaryOps(symbol, "nuint", "object"); - binaryOps(symbol, "nuint", "string", $"string string.{name}(object left, string right)", $"string string.{name}(string left, object right)"); - binaryOps(symbol, "nuint", "void*", $"void* void*.{name}(ulong left, void* right)", $"void* void*.{name}(void* left, ulong right)", new[] { Diagnostic(ErrorCode.ERR_VoidError, "x + y") }); - binaryOps(symbol, "nuint", "bool"); - binaryOps(symbol, "nuint", "char", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint")); - binaryOps(symbol, "nuint", "byte", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint")); - binaryOps(symbol, "nuint", "ushort", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint")); - binaryOps(symbol, "nuint", "uint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint")); - binaryOps(symbol, "nuint", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint")); - binaryOps(symbol, "nuint", "ulong", $"ulong ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint", "float", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nuint", "double", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nuint", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint", "System.IntPtr"); - binaryOps(symbol, "nuint", "System.UIntPtr", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "bool?"); - binaryOps(symbol, "nuint", "char?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint")); - binaryOps(symbol, "nuint", "byte?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint")); - binaryOps(symbol, "nuint", "ushort?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint")); - binaryOps(symbol, "nuint", "uint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint")); - binaryOps(symbol, "nuint", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint")); - binaryOps(symbol, "nuint", "ulong?", $"ulong ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint", "float?", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nuint", "double?", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nuint", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint", "System.IntPtr?"); - binaryOps(symbol, "nuint", "System.UIntPtr?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "object"); - binaryOps(symbol, "nuint?", "string", $"string string.{name}(object left, string right)", $"string string.{name}(string left, object right)"); - binaryOps(symbol, "nuint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint?", includeVoidError: true)); - binaryOps(symbol, "nuint?", "bool"); - binaryOps(symbol, "nuint?", "char", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint?")); - binaryOps(symbol, "nuint?", "byte", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint?")); - binaryOps(symbol, "nuint?", "ushort", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint?")); - binaryOps(symbol, "nuint?", "uint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?")); - binaryOps(symbol, "nuint?", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint?")); - binaryOps(symbol, "nuint?", "ulong", $"ulong ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint?", "float", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nuint?", "double", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nuint?", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint?", "System.IntPtr"); - binaryOps(symbol, "nuint?", "System.UIntPtr", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "bool?"); - binaryOps(symbol, "nuint?", "char?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint?")); - binaryOps(symbol, "nuint?", "byte?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint?")); - binaryOps(symbol, "nuint?", "ushort?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint?")); - binaryOps(symbol, "nuint?", "uint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?")); - binaryOps(symbol, "nuint?", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint?")); - binaryOps(symbol, "nuint?", "ulong?", $"ulong ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint?", "float?", $"float float.{name}(float left, float right)"); - binaryOps(symbol, "nuint?", "double?", $"double double.{name}(double left, double right)"); - binaryOps(symbol, "nuint?", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint?", "System.IntPtr?"); - binaryOps(symbol, "nuint?", "System.UIntPtr?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.IntPtr", "object"); - binaryOps(symbol, "System.IntPtr", "string", $"string string.{name}(object left, string right)", $"string string.{name}(string left, object right)"); - binaryOps(symbol, "System.IntPtr", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.IntPtr", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.IntPtr", includeVoidError: true)); - binaryOps(symbol, "System.IntPtr", "bool"); - binaryOps(symbol, "System.IntPtr", "char", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr", "sbyte", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr", "byte", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr", "short", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr", "ushort", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr", "int", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr", "uint"); - binaryOps(symbol, "System.IntPtr", "nint", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr", "nuint"); - binaryOps(symbol, "System.IntPtr", "long"); - binaryOps(symbol, "System.IntPtr", "ulong"); - binaryOps(symbol, "System.IntPtr", "float"); - binaryOps(symbol, "System.IntPtr", "double"); - binaryOps(symbol, "System.IntPtr", "decimal"); - binaryOps(symbol, "System.IntPtr", "System.IntPtr"); - binaryOps(symbol, "System.IntPtr", "System.UIntPtr"); - binaryOps(symbol, "System.IntPtr", "bool?"); - binaryOps(symbol, "System.IntPtr", "char?", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr", "sbyte?", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr", "byte?", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr", "short?", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr", "ushort?", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr", "int?", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr", "uint?"); - binaryOps(symbol, "System.IntPtr", "nint?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr", "nuint?"); - binaryOps(symbol, "System.IntPtr", "long?"); - binaryOps(symbol, "System.IntPtr", "ulong?"); - binaryOps(symbol, "System.IntPtr", "float?"); - binaryOps(symbol, "System.IntPtr", "double?"); - binaryOps(symbol, "System.IntPtr", "decimal?"); - binaryOps(symbol, "System.IntPtr", "System.IntPtr?"); - binaryOps(symbol, "System.IntPtr", "System.UIntPtr?"); - binaryOps(symbol, "System.IntPtr", "object"); - binaryOps(symbol, "System.IntPtr?", "string", $"string string.{name}(object left, string right)", $"string string.{name}(string left, object right)"); - binaryOps(symbol, "System.IntPtr?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.IntPtr?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.IntPtr?", includeVoidError: true)); - binaryOps(symbol, "System.IntPtr?", "bool"); - binaryOps(symbol, "System.IntPtr?", "char", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr?", "sbyte", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr?", "byte", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr?", "short", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr?", "ushort", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr?", "int", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr?", "uint"); - binaryOps(symbol, "System.IntPtr?", "nint", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr?", "nuint"); - binaryOps(symbol, "System.IntPtr?", "long"); - binaryOps(symbol, "System.IntPtr?", "ulong"); - binaryOps(symbol, "System.IntPtr?", "float"); - binaryOps(symbol, "System.IntPtr?", "double"); - binaryOps(symbol, "System.IntPtr?", "decimal"); - binaryOps(symbol, "System.IntPtr?", "System.IntPtr"); - binaryOps(symbol, "System.IntPtr?", "System.UIntPtr"); - binaryOps(symbol, "System.IntPtr?", "bool?"); - binaryOps(symbol, "System.IntPtr?", "char?", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr?", "sbyte?", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr?", "byte?", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr?", "short?", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr?", "ushort?", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr?", "int?", $"System.IntPtr System.IntPtr.{name}(System.IntPtr pointer, int offset)", null); - binaryOps(symbol, "System.IntPtr?", "uint?"); - binaryOps(symbol, "System.IntPtr?", "nint?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr?", "nuint?"); - binaryOps(symbol, "System.IntPtr?", "long?"); - binaryOps(symbol, "System.IntPtr?", "ulong?"); - binaryOps(symbol, "System.IntPtr?", "float?"); - binaryOps(symbol, "System.IntPtr?", "double?"); - binaryOps(symbol, "System.IntPtr?", "decimal?"); - binaryOps(symbol, "System.IntPtr?", "System.IntPtr?"); - binaryOps(symbol, "System.IntPtr?", "System.UIntPtr?"); - binaryOps(symbol, "System.UIntPtr", "object"); - binaryOps(symbol, "System.UIntPtr", "string", $"string string.{name}(object left, string right)", $"string string.{name}(string left, object right)"); - binaryOps(symbol, "System.UIntPtr", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.UIntPtr", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.UIntPtr", includeVoidError: true)); - binaryOps(symbol, "System.UIntPtr", "bool"); - binaryOps(symbol, "System.UIntPtr", "char", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr", "sbyte", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr", "byte", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr", "short", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr", "ushort", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr", "int", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr", "uint"); - binaryOps(symbol, "System.UIntPtr", "nint"); - binaryOps(symbol, "System.UIntPtr", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr", "long"); - binaryOps(symbol, "System.UIntPtr", "ulong"); - binaryOps(symbol, "System.UIntPtr", "float"); - binaryOps(symbol, "System.UIntPtr", "double"); - binaryOps(symbol, "System.UIntPtr", "decimal"); - binaryOps(symbol, "System.UIntPtr", "System.IntPtr"); - binaryOps(symbol, "System.UIntPtr", "System.UIntPtr"); - binaryOps(symbol, "System.UIntPtr", "bool?"); - binaryOps(symbol, "System.UIntPtr", "char?", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr", "sbyte?", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr", "byte?", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr", "short?", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr", "ushort?", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr", "int?", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr", "uint?"); - binaryOps(symbol, "System.UIntPtr", "nint?"); - binaryOps(symbol, "System.UIntPtr", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr", "long?"); - binaryOps(symbol, "System.UIntPtr", "ulong?"); - binaryOps(symbol, "System.UIntPtr", "float?"); - binaryOps(symbol, "System.UIntPtr", "double?"); - binaryOps(symbol, "System.UIntPtr", "decimal?"); - binaryOps(symbol, "System.UIntPtr", "System.IntPtr?"); - binaryOps(symbol, "System.UIntPtr", "System.UIntPtr?"); - binaryOps(symbol, "System.UIntPtr", "object"); - binaryOps(symbol, "System.UIntPtr?", "string", $"string string.{name}(object left, string right)", $"string string.{name}(string left, object right)"); - binaryOps(symbol, "System.UIntPtr?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.UIntPtr?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.UIntPtr?", includeVoidError: true)); - binaryOps(symbol, "System.UIntPtr?", "bool"); - binaryOps(symbol, "System.UIntPtr?", "char", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr?", "sbyte", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr?", "byte", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr?", "short", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr?", "ushort", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr?", "int", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr?", "uint"); - binaryOps(symbol, "System.UIntPtr?", "nint"); - binaryOps(symbol, "System.UIntPtr?", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr?", "long"); - binaryOps(symbol, "System.UIntPtr?", "ulong"); - binaryOps(symbol, "System.UIntPtr?", "float"); - binaryOps(symbol, "System.UIntPtr?", "double"); - binaryOps(symbol, "System.UIntPtr?", "decimal"); - binaryOps(symbol, "System.UIntPtr?", "System.IntPtr"); - binaryOps(symbol, "System.UIntPtr?", "System.UIntPtr"); - binaryOps(symbol, "System.UIntPtr?", "bool?"); - binaryOps(symbol, "System.UIntPtr?", "char?", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr?", "sbyte?", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr?", "byte?", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr?", "short?", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr?", "ushort?", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr?", "int?", $"System.UIntPtr System.UIntPtr.{name}(System.UIntPtr pointer, int offset)", null); - binaryOps(symbol, "System.UIntPtr?", "uint?"); - binaryOps(symbol, "System.UIntPtr?", "nint?"); - binaryOps(symbol, "System.UIntPtr?", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr?", "long?"); - binaryOps(symbol, "System.UIntPtr?", "ulong?"); - binaryOps(symbol, "System.UIntPtr?", "float?"); - binaryOps(symbol, "System.UIntPtr?", "double?"); - binaryOps(symbol, "System.UIntPtr?", "decimal?"); - binaryOps(symbol, "System.UIntPtr?", "System.IntPtr?"); - binaryOps(symbol, "System.UIntPtr?", "System.UIntPtr?"); + // nint additionOperator type + unifiedBinaryOps(symbol, "nint", "object"); + unifiedBinaryOps(symbol, "nint", "string", $"string string.{name}(object left, string right)", $"string string.{name}(string left, object right)"); + unifiedBinaryOps(symbol, "nint", "void*", $"void* void*.{name}(long left, void* right)", $"void* void*.{name}(void* left, long right)", new[] { Diagnostic(ErrorCode.ERR_VoidError, "x + y") }); + unifiedBinaryOps(symbol, "nint", "bool"); + unifiedBinaryOps(symbol, "nint", "char", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "sbyte", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "byte", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "short", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "ushort", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "int", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "uint", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "nint", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint")); + unifiedBinaryOps(symbol, "nint", "long", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint")); + unifiedBinaryOps(symbol, "nint", "float", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint", "double", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint", "System.IntPtr", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "System.UIntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint")); + + // nint additionOperator type? + unifiedBinaryOps(symbol, "nint", "bool?"); + unifiedBinaryOps(symbol, "nint", "char?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "sbyte?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "byte?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "short?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "ushort?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "int?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "uint?", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "nint?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint")); + unifiedBinaryOps(symbol, "nint", "long?", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint")); + unifiedBinaryOps(symbol, "nint", "float?", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint", "double?", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint", "System.IntPtr?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "System.UIntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint")); + unifiedBinaryOps(symbol, "nint", "object"); + + // nint? additionOperator type + unifiedBinaryOps(symbol, "nint?", "string", $"string string.{name}(object left, string right)", $"string string.{name}(string left, object right)"); + unifiedBinaryOps(symbol, "nint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nint?", includeVoidError: true)); + unifiedBinaryOps(symbol, "nint?", "bool"); + unifiedBinaryOps(symbol, "nint?", "char", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "sbyte", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "byte", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "short", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "ushort", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "int", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "uint", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "nint", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?")); + unifiedBinaryOps(symbol, "nint?", "long", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint?")); + unifiedBinaryOps(symbol, "nint?", "float", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint?", "double", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint?", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint?", "System.IntPtr", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "System.UIntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?")); + + // nint? additionOperator type? + unifiedBinaryOps(symbol, "nint?", "bool?"); + unifiedBinaryOps(symbol, "nint?", "char?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "sbyte?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "byte?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "short?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "ushort?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "int?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "uint?", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "nint?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?")); + unifiedBinaryOps(symbol, "nint?", "long?", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint?")); + unifiedBinaryOps(symbol, "nint?", "float?", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint?", "double?", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint?", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint?", "System.IntPtr?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "System.UIntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?")); + + // nuint additionOperator type + unifiedBinaryOps(symbol, "nuint", "object"); + unifiedBinaryOps(symbol, "nuint", "string", $"string string.{name}(object left, string right)", $"string string.{name}(string left, object right)"); + unifiedBinaryOps(symbol, "nuint", "void*", $"void* void*.{name}(ulong left, void* right)", $"void* void*.{name}(void* left, ulong right)", new[] { Diagnostic(ErrorCode.ERR_VoidError, "x + y") }); + unifiedBinaryOps(symbol, "nuint", "bool"); + unifiedBinaryOps(symbol, "nuint", "char", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint")); + unifiedBinaryOps(symbol, "nuint", "byte", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ushort", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint")); + unifiedBinaryOps(symbol, "nuint", "uint", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint")); + unifiedBinaryOps(symbol, "nuint", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ulong", $"ulong ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint", "float", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint", "double", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint", "System.IntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint")); + unifiedBinaryOps(symbol, "nuint", "System.UIntPtr", $"nuint nuint.{name}(nuint left, nuint right)"); + + // nuint additionOperator type? + unifiedBinaryOps(symbol, "nuint", "bool?"); + unifiedBinaryOps(symbol, "nuint", "char?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "byte?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ushort?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "uint?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ulong?", $"ulong ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint", "float?", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint", "double?", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint", "System.IntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "System.UIntPtr?", $"nuint nuint.{name}(nuint left, nuint right)"); + + // nuint? additionOperator type + unifiedBinaryOps(symbol, "nuint?", "object"); + unifiedBinaryOps(symbol, "nuint?", "string", $"string string.{name}(object left, string right)", $"string string.{name}(string left, object right)"); + unifiedBinaryOps(symbol, "nuint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint?", includeVoidError: true)); + unifiedBinaryOps(symbol, "nuint?", "bool"); + unifiedBinaryOps(symbol, "nuint?", "char", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "byte", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ushort", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "uint", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ulong", $"ulong ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint?", "float", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint?", "double", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint?", "decimal", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint?", "System.IntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "System.UIntPtr", $"nuint nuint.{name}(nuint left, nuint right)"); + + // nuint? additionOperator type? + unifiedBinaryOps(symbol, "nuint?", "bool?"); + unifiedBinaryOps(symbol, "nuint?", "char?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "byte?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ushort?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "uint?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ulong?", $"ulong ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint?", "float?", $"float float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint?", "double?", $"double double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint?", "decimal?", $"decimal decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint?", "System.IntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "System.UIntPtr?", $"nuint nuint.{name}(nuint left, nuint right)"); } foreach ((string symbol, string name) in shiftOperators) { - binaryOps(symbol, "nint", "object"); - binaryOps(symbol, "nint", "string"); - binaryOps(symbol, "nint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nint", includeVoidError: true)); - binaryOps(symbol, "nint", "bool"); - binaryOps(symbol, "nint", "char", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint", "sbyte", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint", "byte", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint", "short", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint", "ushort", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint", "int", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint", "uint"); - binaryOps(symbol, "nint", "nint"); - binaryOps(symbol, "nint", "nuint"); - binaryOps(symbol, "nint", "long"); - binaryOps(symbol, "nint", "ulong"); - binaryOps(symbol, "nint", "float"); - binaryOps(symbol, "nint", "double"); - binaryOps(symbol, "nint", "decimal"); - binaryOps(symbol, "nint", "System.IntPtr"); - binaryOps(symbol, "nint", "System.UIntPtr"); - binaryOps(symbol, "nint", "bool?"); - binaryOps(symbol, "nint", "char?", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint", "sbyte?", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint", "byte?", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint", "short?", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint", "ushort?", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint", "int?", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint", "uint?"); - binaryOps(symbol, "nint", "nint?"); - binaryOps(symbol, "nint", "nuint?"); - binaryOps(symbol, "nint", "long?"); - binaryOps(symbol, "nint", "ulong?"); - binaryOps(symbol, "nint", "float?"); - binaryOps(symbol, "nint", "double?"); - binaryOps(symbol, "nint", "decimal?"); - binaryOps(symbol, "nint", "System.IntPtr?"); - binaryOps(symbol, "nint", "System.UIntPtr?"); - binaryOps(symbol, "nint", "object"); - binaryOps(symbol, "nint?", "string"); - binaryOps(symbol, "nint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nint?", includeVoidError: true)); - binaryOps(symbol, "nint?", "bool"); - binaryOps(symbol, "nint?", "char", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint?", "sbyte", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint?", "byte", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint?", "short", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint?", "ushort", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint?", "int", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint?", "uint"); - binaryOps(symbol, "nint?", "nint"); - binaryOps(symbol, "nint?", "nuint"); - binaryOps(symbol, "nint?", "long"); - binaryOps(symbol, "nint?", "ulong"); - binaryOps(symbol, "nint?", "float"); - binaryOps(symbol, "nint?", "double"); - binaryOps(symbol, "nint?", "decimal"); - binaryOps(symbol, "nint?", "System.IntPtr"); - binaryOps(symbol, "nint?", "System.UIntPtr"); - binaryOps(symbol, "nint?", "bool?"); - binaryOps(symbol, "nint?", "char?", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint?", "sbyte?", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint?", "byte?", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint?", "short?", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint?", "ushort?", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint?", "int?", $"nint nint.{name}(nint left, int right)", null); - binaryOps(symbol, "nint?", "uint?"); - binaryOps(symbol, "nint?", "nint?"); - binaryOps(symbol, "nint?", "nuint?"); - binaryOps(symbol, "nint?", "long?"); - binaryOps(symbol, "nint?", "ulong?"); - binaryOps(symbol, "nint?", "float?"); - binaryOps(symbol, "nint?", "double?"); - binaryOps(symbol, "nint?", "decimal?"); - binaryOps(symbol, "nint?", "System.IntPtr?"); - binaryOps(symbol, "nint?", "System.UIntPtr?"); - binaryOps(symbol, "nuint", "object"); - binaryOps(symbol, "nuint", "string"); - binaryOps(symbol, "nuint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint", includeVoidError: true)); - binaryOps(symbol, "nuint", "bool"); - binaryOps(symbol, "nuint", "char", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint", "sbyte", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint", "byte", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint", "short", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint", "ushort", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint", "int", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint", "uint"); - binaryOps(symbol, "nuint", "nint"); - binaryOps(symbol, "nuint", "nuint"); - binaryOps(symbol, "nuint", "long"); - binaryOps(symbol, "nuint", "ulong"); - binaryOps(symbol, "nuint", "float"); - binaryOps(symbol, "nuint", "double"); - binaryOps(symbol, "nuint", "decimal"); - binaryOps(symbol, "nuint", "System.IntPtr"); - binaryOps(symbol, "nuint", "System.UIntPtr"); - binaryOps(symbol, "nuint", "bool?"); - binaryOps(symbol, "nuint", "char?", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint", "sbyte?", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint", "byte?", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint", "short?", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint", "ushort?", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint", "int?", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint", "uint?"); - binaryOps(symbol, "nuint", "nint?"); - binaryOps(symbol, "nuint", "nuint?"); - binaryOps(symbol, "nuint", "long?"); - binaryOps(symbol, "nuint", "ulong?"); - binaryOps(symbol, "nuint", "float?"); - binaryOps(symbol, "nuint", "double?"); - binaryOps(symbol, "nuint", "decimal?"); - binaryOps(symbol, "nuint", "System.IntPtr?"); - binaryOps(symbol, "nuint", "System.UIntPtr?"); - binaryOps(symbol, "nuint?", "object"); - binaryOps(symbol, "nuint?", "string"); - binaryOps(symbol, "nuint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint?", includeVoidError: true)); - binaryOps(symbol, "nuint?", "bool"); - binaryOps(symbol, "nuint?", "char", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint?", "sbyte", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint?", "byte", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint?", "short", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint?", "ushort", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint?", "int", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint?", "uint"); - binaryOps(symbol, "nuint?", "nint"); - binaryOps(symbol, "nuint?", "nuint"); - binaryOps(symbol, "nuint?", "long"); - binaryOps(symbol, "nuint?", "ulong"); - binaryOps(symbol, "nuint?", "float"); - binaryOps(symbol, "nuint?", "double"); - binaryOps(symbol, "nuint?", "decimal"); - binaryOps(symbol, "nuint?", "System.IntPtr"); - binaryOps(symbol, "nuint?", "System.UIntPtr"); - binaryOps(symbol, "nuint?", "bool?"); - binaryOps(symbol, "nuint?", "char?", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint?", "sbyte?", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint?", "byte?", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint?", "short?", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint?", "ushort?", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint?", "int?", $"nuint nuint.{name}(nuint left, int right)", null); - binaryOps(symbol, "nuint?", "uint?"); - binaryOps(symbol, "nuint?", "nint?"); - binaryOps(symbol, "nuint?", "nuint?"); - binaryOps(symbol, "nuint?", "long?"); - binaryOps(symbol, "nuint?", "ulong?"); - binaryOps(symbol, "nuint?", "float?"); - binaryOps(symbol, "nuint?", "double?"); - binaryOps(symbol, "nuint?", "decimal?"); - binaryOps(symbol, "nuint?", "System.IntPtr?"); - binaryOps(symbol, "nuint?", "System.UIntPtr?"); - binaryOps(symbol, "System.IntPtr", "object"); - binaryOps(symbol, "System.IntPtr", "string"); - binaryOps(symbol, "System.IntPtr", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.IntPtr", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.IntPtr", includeVoidError: true)); - binaryOps(symbol, "System.IntPtr", "bool"); - binaryOps(symbol, "System.IntPtr", "char"); - binaryOps(symbol, "System.IntPtr", "sbyte"); - binaryOps(symbol, "System.IntPtr", "byte"); - binaryOps(symbol, "System.IntPtr", "short"); - binaryOps(symbol, "System.IntPtr", "ushort"); - binaryOps(symbol, "System.IntPtr", "int"); - binaryOps(symbol, "System.IntPtr", "uint"); - binaryOps(symbol, "System.IntPtr", "nint"); - binaryOps(symbol, "System.IntPtr", "nuint"); - binaryOps(symbol, "System.IntPtr", "long"); - binaryOps(symbol, "System.IntPtr", "ulong"); - binaryOps(symbol, "System.IntPtr", "float"); - binaryOps(symbol, "System.IntPtr", "double"); - binaryOps(symbol, "System.IntPtr", "decimal"); - binaryOps(symbol, "System.IntPtr", "System.IntPtr"); - binaryOps(symbol, "System.IntPtr", "System.UIntPtr"); - binaryOps(symbol, "System.IntPtr", "bool?"); - binaryOps(symbol, "System.IntPtr", "char?"); - binaryOps(symbol, "System.IntPtr", "sbyte?"); - binaryOps(symbol, "System.IntPtr", "byte?"); - binaryOps(symbol, "System.IntPtr", "short?"); - binaryOps(symbol, "System.IntPtr", "ushort?"); - binaryOps(symbol, "System.IntPtr", "int?"); - binaryOps(symbol, "System.IntPtr", "uint?"); - binaryOps(symbol, "System.IntPtr", "nint?"); - binaryOps(symbol, "System.IntPtr", "nuint?"); - binaryOps(symbol, "System.IntPtr", "long?"); - binaryOps(symbol, "System.IntPtr", "ulong?"); - binaryOps(symbol, "System.IntPtr", "float?"); - binaryOps(symbol, "System.IntPtr", "double?"); - binaryOps(symbol, "System.IntPtr", "decimal?"); - binaryOps(symbol, "System.IntPtr", "System.IntPtr?"); - binaryOps(symbol, "System.IntPtr", "System.UIntPtr?"); - binaryOps(symbol, "System.IntPtr", "object"); - binaryOps(symbol, "System.IntPtr?", "string"); - binaryOps(symbol, "System.IntPtr?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.IntPtr?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.IntPtr?", includeVoidError: true)); - binaryOps(symbol, "System.IntPtr?", "bool"); - binaryOps(symbol, "System.IntPtr?", "char"); - binaryOps(symbol, "System.IntPtr?", "sbyte"); - binaryOps(symbol, "System.IntPtr?", "byte"); - binaryOps(symbol, "System.IntPtr?", "short"); - binaryOps(symbol, "System.IntPtr?", "ushort"); - binaryOps(symbol, "System.IntPtr?", "int"); - binaryOps(symbol, "System.IntPtr?", "uint"); - binaryOps(symbol, "System.IntPtr?", "nint"); - binaryOps(symbol, "System.IntPtr?", "nuint"); - binaryOps(symbol, "System.IntPtr?", "long"); - binaryOps(symbol, "System.IntPtr?", "ulong"); - binaryOps(symbol, "System.IntPtr?", "float"); - binaryOps(symbol, "System.IntPtr?", "double"); - binaryOps(symbol, "System.IntPtr?", "decimal"); - binaryOps(symbol, "System.IntPtr?", "System.IntPtr"); - binaryOps(symbol, "System.IntPtr?", "System.UIntPtr"); - binaryOps(symbol, "System.IntPtr?", "bool?"); - binaryOps(symbol, "System.IntPtr?", "char?"); - binaryOps(symbol, "System.IntPtr?", "sbyte?"); - binaryOps(symbol, "System.IntPtr?", "byte?"); - binaryOps(symbol, "System.IntPtr?", "short?"); - binaryOps(symbol, "System.IntPtr?", "ushort?"); - binaryOps(symbol, "System.IntPtr?", "int?"); - binaryOps(symbol, "System.IntPtr?", "uint?"); - binaryOps(symbol, "System.IntPtr?", "nint?"); - binaryOps(symbol, "System.IntPtr?", "nuint?"); - binaryOps(symbol, "System.IntPtr?", "long?"); - binaryOps(symbol, "System.IntPtr?", "ulong?"); - binaryOps(symbol, "System.IntPtr?", "float?"); - binaryOps(symbol, "System.IntPtr?", "double?"); - binaryOps(symbol, "System.IntPtr?", "decimal?"); - binaryOps(symbol, "System.IntPtr?", "System.IntPtr?"); - binaryOps(symbol, "System.IntPtr?", "System.UIntPtr?"); - binaryOps(symbol, "System.UIntPtr", "object"); - binaryOps(symbol, "System.UIntPtr", "string"); - binaryOps(symbol, "System.UIntPtr", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.UIntPtr", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.UIntPtr", includeVoidError: true)); - binaryOps(symbol, "System.UIntPtr", "bool"); - binaryOps(symbol, "System.UIntPtr", "char"); - binaryOps(symbol, "System.UIntPtr", "sbyte"); - binaryOps(symbol, "System.UIntPtr", "byte"); - binaryOps(symbol, "System.UIntPtr", "short"); - binaryOps(symbol, "System.UIntPtr", "ushort"); - binaryOps(symbol, "System.UIntPtr", "int"); - binaryOps(symbol, "System.UIntPtr", "uint"); - binaryOps(symbol, "System.UIntPtr", "nint"); - binaryOps(symbol, "System.UIntPtr", "nuint"); - binaryOps(symbol, "System.UIntPtr", "long"); - binaryOps(symbol, "System.UIntPtr", "ulong"); - binaryOps(symbol, "System.UIntPtr", "float"); - binaryOps(symbol, "System.UIntPtr", "double"); - binaryOps(symbol, "System.UIntPtr", "decimal"); - binaryOps(symbol, "System.UIntPtr", "System.IntPtr"); - binaryOps(symbol, "System.UIntPtr", "System.UIntPtr"); - binaryOps(symbol, "System.UIntPtr", "bool?"); - binaryOps(symbol, "System.UIntPtr", "char?"); - binaryOps(symbol, "System.UIntPtr", "sbyte?"); - binaryOps(symbol, "System.UIntPtr", "byte?"); - binaryOps(symbol, "System.UIntPtr", "short?"); - binaryOps(symbol, "System.UIntPtr", "ushort?"); - binaryOps(symbol, "System.UIntPtr", "int?"); - binaryOps(symbol, "System.UIntPtr", "uint?"); - binaryOps(symbol, "System.UIntPtr", "nint?"); - binaryOps(symbol, "System.UIntPtr", "nuint?"); - binaryOps(symbol, "System.UIntPtr", "long?"); - binaryOps(symbol, "System.UIntPtr", "ulong?"); - binaryOps(symbol, "System.UIntPtr", "float?"); - binaryOps(symbol, "System.UIntPtr", "double?"); - binaryOps(symbol, "System.UIntPtr", "decimal?"); - binaryOps(symbol, "System.UIntPtr", "System.IntPtr?"); - binaryOps(symbol, "System.UIntPtr", "System.UIntPtr?"); - binaryOps(symbol, "System.UIntPtr", "object"); - binaryOps(symbol, "System.UIntPtr?", "string"); - binaryOps(symbol, "System.UIntPtr?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.UIntPtr?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.UIntPtr?", includeVoidError: true)); - binaryOps(symbol, "System.UIntPtr?", "bool"); - binaryOps(symbol, "System.UIntPtr?", "char"); - binaryOps(symbol, "System.UIntPtr?", "sbyte"); - binaryOps(symbol, "System.UIntPtr?", "byte"); - binaryOps(symbol, "System.UIntPtr?", "short"); - binaryOps(symbol, "System.UIntPtr?", "ushort"); - binaryOps(symbol, "System.UIntPtr?", "int"); - binaryOps(symbol, "System.UIntPtr?", "uint"); - binaryOps(symbol, "System.UIntPtr?", "nint"); - binaryOps(symbol, "System.UIntPtr?", "nuint"); - binaryOps(symbol, "System.UIntPtr?", "long"); - binaryOps(symbol, "System.UIntPtr?", "ulong"); - binaryOps(symbol, "System.UIntPtr?", "float"); - binaryOps(symbol, "System.UIntPtr?", "double"); - binaryOps(symbol, "System.UIntPtr?", "decimal"); - binaryOps(symbol, "System.UIntPtr?", "System.IntPtr"); - binaryOps(symbol, "System.UIntPtr?", "System.UIntPtr"); - binaryOps(symbol, "System.UIntPtr?", "bool?"); - binaryOps(symbol, "System.UIntPtr?", "char?"); - binaryOps(symbol, "System.UIntPtr?", "sbyte?"); - binaryOps(symbol, "System.UIntPtr?", "byte?"); - binaryOps(symbol, "System.UIntPtr?", "short?"); - binaryOps(symbol, "System.UIntPtr?", "ushort?"); - binaryOps(symbol, "System.UIntPtr?", "int?"); - binaryOps(symbol, "System.UIntPtr?", "uint?"); - binaryOps(symbol, "System.UIntPtr?", "nint?"); - binaryOps(symbol, "System.UIntPtr?", "nuint?"); - binaryOps(symbol, "System.UIntPtr?", "long?"); - binaryOps(symbol, "System.UIntPtr?", "ulong?"); - binaryOps(symbol, "System.UIntPtr?", "float?"); - binaryOps(symbol, "System.UIntPtr?", "double?"); - binaryOps(symbol, "System.UIntPtr?", "decimal?"); - binaryOps(symbol, "System.UIntPtr?", "System.IntPtr?"); - binaryOps(symbol, "System.UIntPtr?", "System.UIntPtr?"); + // nint shiftOp type + unifiedBinaryOps(symbol, "nint", "object"); + unifiedBinaryOps(symbol, "nint", "string"); + unifiedBinaryOps(symbol, "nint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nint", includeVoidError: true)); + unifiedBinaryOps(symbol, "nint", "bool"); + unifiedBinaryOps(symbol, "nint", "char", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint", "sbyte", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint", "byte", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint", "short", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint", "ushort", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint", "int", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint", "uint"); + unifiedBinaryOps(symbol, "nint", "nint"); + unifiedBinaryOps(symbol, "nint", "nuint"); + unifiedBinaryOps(symbol, "nint", "long"); + unifiedBinaryOps(symbol, "nint", "ulong"); + unifiedBinaryOps(symbol, "nint", "float"); + unifiedBinaryOps(symbol, "nint", "double"); + unifiedBinaryOps(symbol, "nint", "decimal"); + unifiedBinaryOps(symbol, "nint", "System.IntPtr"); + unifiedBinaryOps(symbol, "nint", "System.UIntPtr"); + + // nint shiftOp type? + unifiedBinaryOps(symbol, "nint", "bool?"); + unifiedBinaryOps(symbol, "nint", "char?", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint", "sbyte?", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint", "byte?", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint", "short?", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint", "ushort?", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint", "int?", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint", "uint?"); + unifiedBinaryOps(symbol, "nint", "nint?"); + unifiedBinaryOps(symbol, "nint", "nuint?"); + unifiedBinaryOps(symbol, "nint", "long?"); + unifiedBinaryOps(symbol, "nint", "ulong?"); + unifiedBinaryOps(symbol, "nint", "float?"); + unifiedBinaryOps(symbol, "nint", "double?"); + unifiedBinaryOps(symbol, "nint", "decimal?"); + unifiedBinaryOps(symbol, "nint", "System.IntPtr?"); + unifiedBinaryOps(symbol, "nint", "System.UIntPtr?"); + unifiedBinaryOps(symbol, "nint", "object"); + + // nint? shiftOp type + unifiedBinaryOps(symbol, "nint?", "string"); + unifiedBinaryOps(symbol, "nint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nint?", includeVoidError: true)); + unifiedBinaryOps(symbol, "nint?", "bool"); + unifiedBinaryOps(symbol, "nint?", "char", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint?", "sbyte", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint?", "byte", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint?", "short", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint?", "ushort", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint?", "int", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint?", "uint"); + unifiedBinaryOps(symbol, "nint?", "nint"); + unifiedBinaryOps(symbol, "nint?", "nuint"); + unifiedBinaryOps(symbol, "nint?", "long"); + unifiedBinaryOps(symbol, "nint?", "ulong"); + unifiedBinaryOps(symbol, "nint?", "float"); + unifiedBinaryOps(symbol, "nint?", "double"); + unifiedBinaryOps(symbol, "nint?", "decimal"); + unifiedBinaryOps(symbol, "nint?", "System.IntPtr"); + unifiedBinaryOps(symbol, "nint?", "System.UIntPtr"); + + // nint? shiftOp type? + unifiedBinaryOps(symbol, "nint?", "bool?"); + unifiedBinaryOps(symbol, "nint?", "char?", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint?", "sbyte?", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint?", "byte?", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint?", "short?", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint?", "ushort?", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint?", "int?", $"nint nint.{name}(nint left, int right)", null); + unifiedBinaryOps(symbol, "nint?", "uint?"); + unifiedBinaryOps(symbol, "nint?", "nint?"); + unifiedBinaryOps(symbol, "nint?", "nuint?"); + unifiedBinaryOps(symbol, "nint?", "long?"); + unifiedBinaryOps(symbol, "nint?", "ulong?"); + unifiedBinaryOps(symbol, "nint?", "float?"); + unifiedBinaryOps(symbol, "nint?", "double?"); + unifiedBinaryOps(symbol, "nint?", "decimal?"); + unifiedBinaryOps(symbol, "nint?", "System.IntPtr?"); + unifiedBinaryOps(symbol, "nint?", "System.UIntPtr?"); + + // nuint shiftOp type + unifiedBinaryOps(symbol, "nuint", "object"); + unifiedBinaryOps(symbol, "nuint", "string"); + unifiedBinaryOps(symbol, "nuint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint", includeVoidError: true)); + unifiedBinaryOps(symbol, "nuint", "bool"); + unifiedBinaryOps(symbol, "nuint", "char", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint", "sbyte", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint", "byte", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint", "short", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint", "ushort", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint", "int", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint", "uint"); + unifiedBinaryOps(symbol, "nuint", "nint"); + unifiedBinaryOps(symbol, "nuint", "nuint"); + unifiedBinaryOps(symbol, "nuint", "long"); + unifiedBinaryOps(symbol, "nuint", "ulong"); + unifiedBinaryOps(symbol, "nuint", "float"); + unifiedBinaryOps(symbol, "nuint", "double"); + unifiedBinaryOps(symbol, "nuint", "decimal"); + unifiedBinaryOps(symbol, "nuint", "System.IntPtr"); + unifiedBinaryOps(symbol, "nuint", "System.UIntPtr"); + + // nuint shiftOp type? + unifiedBinaryOps(symbol, "nuint", "bool?"); + unifiedBinaryOps(symbol, "nuint", "char?", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint", "sbyte?", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint", "byte?", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint", "short?", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint", "ushort?", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint", "int?", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint", "uint?"); + unifiedBinaryOps(symbol, "nuint", "nint?"); + unifiedBinaryOps(symbol, "nuint", "nuint?"); + unifiedBinaryOps(symbol, "nuint", "long?"); + unifiedBinaryOps(symbol, "nuint", "ulong?"); + unifiedBinaryOps(symbol, "nuint", "float?"); + unifiedBinaryOps(symbol, "nuint", "double?"); + unifiedBinaryOps(symbol, "nuint", "decimal?"); + unifiedBinaryOps(symbol, "nuint", "System.IntPtr?"); + unifiedBinaryOps(symbol, "nuint", "System.UIntPtr?"); + + // nuint? shiftOp type + unifiedBinaryOps(symbol, "nuint?", "object"); + unifiedBinaryOps(symbol, "nuint?", "string"); + unifiedBinaryOps(symbol, "nuint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint?", includeVoidError: true)); + unifiedBinaryOps(symbol, "nuint?", "bool"); + unifiedBinaryOps(symbol, "nuint?", "char", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint?", "sbyte", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint?", "byte", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint?", "short", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint?", "ushort", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint?", "int", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint?", "uint"); + unifiedBinaryOps(symbol, "nuint?", "nint"); + unifiedBinaryOps(symbol, "nuint?", "nuint"); + unifiedBinaryOps(symbol, "nuint?", "long"); + unifiedBinaryOps(symbol, "nuint?", "ulong"); + unifiedBinaryOps(symbol, "nuint?", "float"); + unifiedBinaryOps(symbol, "nuint?", "double"); + unifiedBinaryOps(symbol, "nuint?", "decimal"); + unifiedBinaryOps(symbol, "nuint?", "System.IntPtr"); + unifiedBinaryOps(symbol, "nuint?", "System.UIntPtr"); + + // nuint? shiftOp type? + unifiedBinaryOps(symbol, "nuint?", "bool?"); + unifiedBinaryOps(symbol, "nuint?", "char?", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint?", "sbyte?", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint?", "byte?", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint?", "short?", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint?", "ushort?", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint?", "int?", $"nuint nuint.{name}(nuint left, int right)", null); + unifiedBinaryOps(symbol, "nuint?", "uint?"); + unifiedBinaryOps(symbol, "nuint?", "nint?"); + unifiedBinaryOps(symbol, "nuint?", "nuint?"); + unifiedBinaryOps(symbol, "nuint?", "long?"); + unifiedBinaryOps(symbol, "nuint?", "ulong?"); + unifiedBinaryOps(symbol, "nuint?", "float?"); + unifiedBinaryOps(symbol, "nuint?", "double?"); + unifiedBinaryOps(symbol, "nuint?", "decimal?"); + unifiedBinaryOps(symbol, "nuint?", "System.IntPtr?"); + unifiedBinaryOps(symbol, "nuint?", "System.UIntPtr?"); } foreach ((string symbol, string name) in equalityOperators) { - binaryOps(symbol, "nint", "object"); - binaryOps(symbol, "nint", "string"); - binaryOps(symbol, "nint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nint")); - binaryOps(symbol, "nint", "bool"); - binaryOps(symbol, "nint", "char", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "sbyte", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "byte", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "short", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "ushort", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "int", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "uint", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "nint", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint")); - binaryOps(symbol, "nint", "long", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint")); - binaryOps(symbol, "nint", "float", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nint", "double", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nint", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint", "System.IntPtr", $"bool System.IntPtr.{name}(System.IntPtr value1, System.IntPtr value2)"); - binaryOps(symbol, "nint", "System.UIntPtr"); - binaryOps(symbol, "nint", "bool?"); - binaryOps(symbol, "nint", "char?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "sbyte?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "byte?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "short?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "ushort?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "int?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "uint?", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "nint?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint")); - binaryOps(symbol, "nint", "long?", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint")); - binaryOps(symbol, "nint", "float?", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nint", "double?", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nint", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint", "System.IntPtr?", $"bool System.IntPtr.{name}(System.IntPtr value1, System.IntPtr value2)"); - binaryOps(symbol, "nint", "System.UIntPtr?"); - binaryOps(symbol, "nint", "object"); - binaryOps(symbol, "nint?", "string"); - binaryOps(symbol, "nint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint?", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nint?")); - binaryOps(symbol, "nint?", "bool"); - binaryOps(symbol, "nint?", "char", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "sbyte", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "byte", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "short", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "ushort", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "int", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "uint", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "nint", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?")); - binaryOps(symbol, "nint?", "long", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint?")); - binaryOps(symbol, "nint?", "float", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nint?", "double", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nint?", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint?", "System.IntPtr", $"bool System.IntPtr.{name}(System.IntPtr value1, System.IntPtr value2)"); - binaryOps(symbol, "nint?", "System.UIntPtr"); - binaryOps(symbol, "nint?", "bool?"); - binaryOps(symbol, "nint?", "char?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "sbyte?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "byte?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "short?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "ushort?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "int?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "uint?", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "nint?", $"bool nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?")); - binaryOps(symbol, "nint?", "long?", $"bool long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint?")); - binaryOps(symbol, "nint?", "float?", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nint?", "double?", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nint?", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nint?", "System.IntPtr?", $"bool System.IntPtr.{name}(System.IntPtr value1, System.IntPtr value2)"); - binaryOps(symbol, "nint?", "System.UIntPtr?"); - binaryOps(symbol, "nuint", "object"); - binaryOps(symbol, "nuint", "string"); - binaryOps(symbol, "nuint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint")); - binaryOps(symbol, "nuint", "bool"); - binaryOps(symbol, "nuint", "char", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint")); - binaryOps(symbol, "nuint", "byte", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint")); - binaryOps(symbol, "nuint", "ushort", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint")); - binaryOps(symbol, "nuint", "uint", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint")); - binaryOps(symbol, "nuint", "nuint", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint")); - binaryOps(symbol, "nuint", "ulong", $"bool ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint", "float", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nuint", "double", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nuint", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint", "System.IntPtr"); - binaryOps(symbol, "nuint", "System.UIntPtr", $"bool System.UIntPtr.{name}(System.UIntPtr value1, System.UIntPtr value2)"); - binaryOps(symbol, "nuint", "bool?"); - binaryOps(symbol, "nuint", "char?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint")); - binaryOps(symbol, "nuint", "byte?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint")); - binaryOps(symbol, "nuint", "ushort?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint")); - binaryOps(symbol, "nuint", "uint?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint")); - binaryOps(symbol, "nuint", "nuint?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint")); - binaryOps(symbol, "nuint", "ulong?", $"bool ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint", "float?", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nuint", "double?", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nuint", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint", "System.IntPtr?"); - binaryOps(symbol, "nuint", "System.UIntPtr?", $"bool System.UIntPtr.{name}(System.UIntPtr value1, System.UIntPtr value2)"); - binaryOps(symbol, "nuint?", "object"); - binaryOps(symbol, "nuint?", "string"); - binaryOps(symbol, "nuint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint?", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint?")); - binaryOps(symbol, "nuint?", "bool"); - binaryOps(symbol, "nuint?", "char", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint?")); - binaryOps(symbol, "nuint?", "byte", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint?")); - binaryOps(symbol, "nuint?", "ushort", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint?")); - binaryOps(symbol, "nuint?", "uint", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?")); - binaryOps(symbol, "nuint?", "nuint", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint?")); - binaryOps(symbol, "nuint?", "ulong", $"bool ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint?", "float", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nuint?", "double", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nuint?", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint?", "System.IntPtr"); - binaryOps(symbol, "nuint?", "System.UIntPtr", $"bool System.UIntPtr.{name}(System.UIntPtr value1, System.UIntPtr value2)"); - binaryOps(symbol, "nuint?", "bool?"); - binaryOps(symbol, "nuint?", "char?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint?")); - binaryOps(symbol, "nuint?", "byte?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint?")); - binaryOps(symbol, "nuint?", "ushort?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint?")); - binaryOps(symbol, "nuint?", "uint?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?")); - binaryOps(symbol, "nuint?", "nuint?", $"bool nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint?")); - binaryOps(symbol, "nuint?", "ulong?", $"bool ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint?", "float?", $"bool float.{name}(float left, float right)"); - binaryOps(symbol, "nuint?", "double?", $"bool double.{name}(double left, double right)"); - binaryOps(symbol, "nuint?", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); - binaryOps(symbol, "nuint?", "System.IntPtr?"); - binaryOps(symbol, "nuint?", "System.UIntPtr?", $"bool System.UIntPtr.{name}(System.UIntPtr value1, System.UIntPtr value2)"); - binaryOps(symbol, "System.IntPtr", "object"); - binaryOps(symbol, "System.IntPtr", "string"); - binaryOps(symbol, "System.IntPtr", "void*"); - binaryOps(symbol, "System.IntPtr", "bool"); - binaryOps(symbol, "System.IntPtr", "char"); - binaryOps(symbol, "System.IntPtr", "sbyte"); - binaryOps(symbol, "System.IntPtr", "byte"); - binaryOps(symbol, "System.IntPtr", "short"); - binaryOps(symbol, "System.IntPtr", "ushort"); - binaryOps(symbol, "System.IntPtr", "int"); - binaryOps(symbol, "System.IntPtr", "uint"); - binaryOps(symbol, "System.IntPtr", "nint", $"bool System.IntPtr.{name}(System.IntPtr value1, System.IntPtr value2)"); - binaryOps(symbol, "System.IntPtr", "nuint"); - binaryOps(symbol, "System.IntPtr", "long"); - binaryOps(symbol, "System.IntPtr", "ulong"); - binaryOps(symbol, "System.IntPtr", "float"); - binaryOps(symbol, "System.IntPtr", "double"); - binaryOps(symbol, "System.IntPtr", "decimal"); - binaryOps(symbol, "System.IntPtr", "System.IntPtr", $"bool System.IntPtr.{name}(System.IntPtr value1, System.IntPtr value2)"); - binaryOps(symbol, "System.IntPtr", "System.UIntPtr"); - binaryOps(symbol, "System.IntPtr", "bool?"); - binaryOps(symbol, "System.IntPtr", "char?"); - binaryOps(symbol, "System.IntPtr", "sbyte?"); - binaryOps(symbol, "System.IntPtr", "byte?"); - binaryOps(symbol, "System.IntPtr", "short?"); - binaryOps(symbol, "System.IntPtr", "ushort?"); - binaryOps(symbol, "System.IntPtr", "int?"); - binaryOps(symbol, "System.IntPtr", "uint?"); - binaryOps(symbol, "System.IntPtr", "nint?", $"bool System.IntPtr.{name}(System.IntPtr value1, System.IntPtr value2)"); - binaryOps(symbol, "System.IntPtr", "nuint?"); - binaryOps(symbol, "System.IntPtr", "long?"); - binaryOps(symbol, "System.IntPtr", "ulong?"); - binaryOps(symbol, "System.IntPtr", "float?"); - binaryOps(symbol, "System.IntPtr", "double?"); - binaryOps(symbol, "System.IntPtr", "decimal?"); - binaryOps(symbol, "System.IntPtr", "System.IntPtr?", $"bool System.IntPtr.{name}(System.IntPtr value1, System.IntPtr value2)"); - binaryOps(symbol, "System.IntPtr", "System.UIntPtr?"); - binaryOps(symbol, "System.IntPtr", "object"); - binaryOps(symbol, "System.IntPtr?", "string"); - binaryOps(symbol, "System.IntPtr?", "void*"); - binaryOps(symbol, "System.IntPtr?", "bool"); - binaryOps(symbol, "System.IntPtr?", "char"); - binaryOps(symbol, "System.IntPtr?", "sbyte"); - binaryOps(symbol, "System.IntPtr?", "byte"); - binaryOps(symbol, "System.IntPtr?", "short"); - binaryOps(symbol, "System.IntPtr?", "ushort"); - binaryOps(symbol, "System.IntPtr?", "int"); - binaryOps(symbol, "System.IntPtr?", "uint"); - binaryOps(symbol, "System.IntPtr?", "nint", $"bool System.IntPtr.{name}(System.IntPtr value1, System.IntPtr value2)"); - binaryOps(symbol, "System.IntPtr?", "nuint"); - binaryOps(symbol, "System.IntPtr?", "long"); - binaryOps(symbol, "System.IntPtr?", "ulong"); - binaryOps(symbol, "System.IntPtr?", "float"); - binaryOps(symbol, "System.IntPtr?", "double"); - binaryOps(symbol, "System.IntPtr?", "decimal"); - binaryOps(symbol, "System.IntPtr?", "System.IntPtr", $"bool System.IntPtr.{name}(System.IntPtr value1, System.IntPtr value2)"); - binaryOps(symbol, "System.IntPtr?", "System.UIntPtr"); - binaryOps(symbol, "System.IntPtr?", "bool?"); - binaryOps(symbol, "System.IntPtr?", "char?"); - binaryOps(symbol, "System.IntPtr?", "sbyte?"); - binaryOps(symbol, "System.IntPtr?", "byte?"); - binaryOps(symbol, "System.IntPtr?", "short?"); - binaryOps(symbol, "System.IntPtr?", "ushort?"); - binaryOps(symbol, "System.IntPtr?", "int?"); - binaryOps(symbol, "System.IntPtr?", "uint?"); - binaryOps(symbol, "System.IntPtr?", "nint?", $"bool System.IntPtr.{name}(System.IntPtr value1, System.IntPtr value2)"); - binaryOps(symbol, "System.IntPtr?", "nuint?"); - binaryOps(symbol, "System.IntPtr?", "long?"); - binaryOps(symbol, "System.IntPtr?", "ulong?"); - binaryOps(symbol, "System.IntPtr?", "float?"); - binaryOps(symbol, "System.IntPtr?", "double?"); - binaryOps(symbol, "System.IntPtr?", "decimal?"); - binaryOps(symbol, "System.IntPtr?", "System.IntPtr?", $"bool System.IntPtr.{name}(System.IntPtr value1, System.IntPtr value2)"); - binaryOps(symbol, "System.IntPtr?", "System.UIntPtr?"); - binaryOps(symbol, "System.UIntPtr", "object"); - binaryOps(symbol, "System.UIntPtr", "string"); - binaryOps(symbol, "System.UIntPtr", "void*"); - binaryOps(symbol, "System.UIntPtr", "bool"); - binaryOps(symbol, "System.UIntPtr", "char"); - binaryOps(symbol, "System.UIntPtr", "sbyte"); - binaryOps(symbol, "System.UIntPtr", "byte"); - binaryOps(symbol, "System.UIntPtr", "short"); - binaryOps(symbol, "System.UIntPtr", "ushort"); - binaryOps(symbol, "System.UIntPtr", "int"); - binaryOps(symbol, "System.UIntPtr", "uint"); - binaryOps(symbol, "System.UIntPtr", "nint"); - binaryOps(symbol, "System.UIntPtr", "nuint", $"bool System.UIntPtr.{name}(System.UIntPtr value1, System.UIntPtr value2)"); - binaryOps(symbol, "System.UIntPtr", "long"); - binaryOps(symbol, "System.UIntPtr", "ulong"); - binaryOps(symbol, "System.UIntPtr", "float"); - binaryOps(symbol, "System.UIntPtr", "double"); - binaryOps(symbol, "System.UIntPtr", "decimal"); - binaryOps(symbol, "System.UIntPtr", "System.IntPtr"); - binaryOps(symbol, "System.UIntPtr", "System.UIntPtr", $"bool System.UIntPtr.{name}(System.UIntPtr value1, System.UIntPtr value2)"); - binaryOps(symbol, "System.UIntPtr", "bool?"); - binaryOps(symbol, "System.UIntPtr", "char?"); - binaryOps(symbol, "System.UIntPtr", "sbyte?"); - binaryOps(symbol, "System.UIntPtr", "byte?"); - binaryOps(symbol, "System.UIntPtr", "short?"); - binaryOps(symbol, "System.UIntPtr", "ushort?"); - binaryOps(symbol, "System.UIntPtr", "int?"); - binaryOps(symbol, "System.UIntPtr", "uint?"); - binaryOps(symbol, "System.UIntPtr", "nint?"); - binaryOps(symbol, "System.UIntPtr", "nuint?", $"bool System.UIntPtr.{name}(System.UIntPtr value1, System.UIntPtr value2)"); - binaryOps(symbol, "System.UIntPtr", "long?"); - binaryOps(symbol, "System.UIntPtr", "ulong?"); - binaryOps(symbol, "System.UIntPtr", "float?"); - binaryOps(symbol, "System.UIntPtr", "double?"); - binaryOps(symbol, "System.UIntPtr", "decimal?"); - binaryOps(symbol, "System.UIntPtr", "System.IntPtr?"); - binaryOps(symbol, "System.UIntPtr", "System.UIntPtr?", $"bool System.UIntPtr.{name}(System.UIntPtr value1, System.UIntPtr value2)"); - binaryOps(symbol, "System.UIntPtr", "object"); - binaryOps(symbol, "System.UIntPtr?", "string"); - binaryOps(symbol, "System.UIntPtr?", "void*"); - binaryOps(symbol, "System.UIntPtr?", "bool"); - binaryOps(symbol, "System.UIntPtr?", "char"); - binaryOps(symbol, "System.UIntPtr?", "sbyte"); - binaryOps(symbol, "System.UIntPtr?", "byte"); - binaryOps(symbol, "System.UIntPtr?", "short"); - binaryOps(symbol, "System.UIntPtr?", "ushort"); - binaryOps(symbol, "System.UIntPtr?", "int"); - binaryOps(symbol, "System.UIntPtr?", "uint"); - binaryOps(symbol, "System.UIntPtr?", "nint"); - binaryOps(symbol, "System.UIntPtr?", "nuint", $"bool System.UIntPtr.{name}(System.UIntPtr value1, System.UIntPtr value2)"); - binaryOps(symbol, "System.UIntPtr?", "long"); - binaryOps(symbol, "System.UIntPtr?", "ulong"); - binaryOps(symbol, "System.UIntPtr?", "float"); - binaryOps(symbol, "System.UIntPtr?", "double"); - binaryOps(symbol, "System.UIntPtr?", "decimal"); - binaryOps(symbol, "System.UIntPtr?", "System.IntPtr"); - binaryOps(symbol, "System.UIntPtr?", "System.UIntPtr", $"bool System.UIntPtr.{name}(System.UIntPtr value1, System.UIntPtr value2)"); - binaryOps(symbol, "System.UIntPtr?", "bool?"); - binaryOps(symbol, "System.UIntPtr?", "char?"); - binaryOps(symbol, "System.UIntPtr?", "sbyte?"); - binaryOps(symbol, "System.UIntPtr?", "byte?"); - binaryOps(symbol, "System.UIntPtr?", "short?"); - binaryOps(symbol, "System.UIntPtr?", "ushort?"); - binaryOps(symbol, "System.UIntPtr?", "int?"); - binaryOps(symbol, "System.UIntPtr?", "uint?"); - binaryOps(symbol, "System.UIntPtr?", "nint?"); - binaryOps(symbol, "System.UIntPtr?", "nuint?", $"bool System.UIntPtr.{name}(System.UIntPtr value1, System.UIntPtr value2)"); - binaryOps(symbol, "System.UIntPtr?", "long?"); - binaryOps(symbol, "System.UIntPtr?", "ulong?"); - binaryOps(symbol, "System.UIntPtr?", "float?"); - binaryOps(symbol, "System.UIntPtr?", "double?"); - binaryOps(symbol, "System.UIntPtr?", "decimal?"); - binaryOps(symbol, "System.UIntPtr?", "System.IntPtr?"); - binaryOps(symbol, "System.UIntPtr?", "System.UIntPtr?", $"bool System.UIntPtr.{name}(System.UIntPtr value1, System.UIntPtr value2)"); + // nint equalityOp type + unifiedBinaryOps(symbol, "nint", "object"); + unifiedBinaryOps(symbol, "nint", "string"); + unifiedBinaryOps(symbol, "nint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nint")); + unifiedBinaryOps(symbol, "nint", "bool"); + unifiedBinaryOps(symbol, "nint", "char", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "sbyte", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "byte", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "short", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "ushort", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "int", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "uint", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "nint", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint")); + unifiedBinaryOps(symbol, "nint", "long", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint")); + unifiedBinaryOps(symbol, "nint", "float", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint", "double", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint", "System.IntPtr", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "System.UIntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint")); + + // nint equalityOp type? + unifiedBinaryOps(symbol, "nint", "bool?"); + unifiedBinaryOps(symbol, "nint", "char?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "sbyte?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "byte?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "short?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "ushort?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "int?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "uint?", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "nint?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint")); + unifiedBinaryOps(symbol, "nint", "long?", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint")); + unifiedBinaryOps(symbol, "nint", "float?", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint", "double?", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint", "System.IntPtr?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "System.UIntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint")); + unifiedBinaryOps(symbol, "nint", "object"); + + // nint? equalityOp type + unifiedBinaryOps(symbol, "nint?", "string"); + unifiedBinaryOps(symbol, "nint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint?", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nint?")); + unifiedBinaryOps(symbol, "nint?", "bool"); + unifiedBinaryOps(symbol, "nint?", "char", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "sbyte", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "byte", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "short", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "ushort", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "int", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "uint", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "nint", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "nuint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?")); + unifiedBinaryOps(symbol, "nint?", "long", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "ulong", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong", "nint?")); + unifiedBinaryOps(symbol, "nint?", "float", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint?", "double", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint?", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint?", "System.IntPtr", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "System.UIntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?")); + + // nint? equalityOp type? + unifiedBinaryOps(symbol, "nint?", "bool?"); + unifiedBinaryOps(symbol, "nint?", "char?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "sbyte?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "byte?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "short?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "ushort?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "int?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "uint?", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "nint?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "nuint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?")); + unifiedBinaryOps(symbol, "nint?", "long?", $"bool long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "ulong?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "ulong?"), getAmbiguousBinaryOpsDiagnostics(symbol, "ulong?", "nint?")); + unifiedBinaryOps(symbol, "nint?", "float?", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nint?", "double?", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nint?", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nint?", "System.IntPtr?", $"bool nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "System.UIntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?")); + + // nuint equalityOp type + unifiedBinaryOps(symbol, "nuint", "object"); + unifiedBinaryOps(symbol, "nuint", "string"); + unifiedBinaryOps(symbol, "nuint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint")); + unifiedBinaryOps(symbol, "nuint", "bool"); + unifiedBinaryOps(symbol, "nuint", "char", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint")); + unifiedBinaryOps(symbol, "nuint", "byte", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ushort", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint")); + unifiedBinaryOps(symbol, "nuint", "uint", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint")); + unifiedBinaryOps(symbol, "nuint", "nuint", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ulong", $"bool ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint", "float", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint", "double", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint", "System.IntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint")); + unifiedBinaryOps(symbol, "nuint", "System.UIntPtr", $"bool nuint.{name}(nuint left, nuint right)"); + + // nuint equalityOp type? + unifiedBinaryOps(symbol, "nuint", "bool?"); + unifiedBinaryOps(symbol, "nuint", "char?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "byte?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ushort?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "uint?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "nuint?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "ulong?", $"bool ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint", "float?", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint", "double?", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint", "System.IntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint")); + unifiedBinaryOps(symbol, "nuint", "System.UIntPtr?", $"bool nuint.{name}(nuint left, nuint right)"); + + // nuint? equalityOp type + unifiedBinaryOps(symbol, "nuint?", "object"); + unifiedBinaryOps(symbol, "nuint?", "string"); + unifiedBinaryOps(symbol, "nuint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint?", "void*"), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "bool"); + unifiedBinaryOps(symbol, "nuint?", "char", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "sbyte", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "byte", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "short", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short"), getAmbiguousBinaryOpsDiagnostics(symbol, "short", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ushort", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "int", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int"), getAmbiguousBinaryOpsDiagnostics(symbol, "int", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "uint", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "nint", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "nuint", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "long", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long"), getAmbiguousBinaryOpsDiagnostics(symbol, "long", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ulong", $"bool ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint?", "float", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint?", "double", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint?", "decimal", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint?", "System.IntPtr", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "System.UIntPtr", $"bool nuint.{name}(nuint left, nuint right)"); + + // nuint? equalityOp type? + unifiedBinaryOps(symbol, "nuint?", "bool?"); + unifiedBinaryOps(symbol, "nuint?", "char?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "sbyte?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "sbyte?"), getAmbiguousBinaryOpsDiagnostics(symbol, "sbyte?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "byte?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "short?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "short?"), getAmbiguousBinaryOpsDiagnostics(symbol, "short?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ushort?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "int?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "int?"), getAmbiguousBinaryOpsDiagnostics(symbol, "int?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "uint?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "nint?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "nuint?", $"bool nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "long?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "long?"), getAmbiguousBinaryOpsDiagnostics(symbol, "long?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "ulong?", $"bool ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint?", "float?", $"bool float.{name}(float left, float right)"); + unifiedBinaryOps(symbol, "nuint?", "double?", $"bool double.{name}(double left, double right)"); + unifiedBinaryOps(symbol, "nuint?", "decimal?", $"bool decimal.{name}(decimal left, decimal right)"); + unifiedBinaryOps(symbol, "nuint?", "System.IntPtr?", null, null, getAmbiguousBinaryOpsDiagnostics(symbol, "nuint?", "nint?"), getAmbiguousBinaryOpsDiagnostics(symbol, "nint?", "nuint?")); + unifiedBinaryOps(symbol, "nuint?", "System.UIntPtr?", $"bool nuint.{name}(nuint left, nuint right)"); } foreach ((string symbol, string name) in logicalOperators) { - binaryOps(symbol, "nint", "object"); - binaryOps(symbol, "nint", "string"); - binaryOps(symbol, "nint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nint", includeVoidError: true)); - binaryOps(symbol, "nint", "bool"); - binaryOps(symbol, "nint", "char", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "sbyte", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "byte", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "short", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "ushort", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "int", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "uint", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "nint", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "nuint"); - binaryOps(symbol, "nint", "long", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "ulong"); - binaryOps(symbol, "nint", "float"); - binaryOps(symbol, "nint", "double"); - binaryOps(symbol, "nint", "decimal"); - binaryOps(symbol, "nint", "System.IntPtr", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "System.UIntPtr"); - binaryOps(symbol, "nint", "bool?"); - binaryOps(symbol, "nint", "char?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "sbyte?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "byte?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "short?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "ushort?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "int?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "uint?", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "nint?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "nuint?"); - binaryOps(symbol, "nint", "long?", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint", "ulong?"); - binaryOps(symbol, "nint", "float?"); - binaryOps(symbol, "nint", "double?"); - binaryOps(symbol, "nint", "decimal?"); - binaryOps(symbol, "nint", "System.IntPtr?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint", "System.UIntPtr?"); - binaryOps(symbol, "nint", "object"); - binaryOps(symbol, "nint?", "string"); - binaryOps(symbol, "nint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nint?", includeVoidError: true)); - binaryOps(symbol, "nint?", "bool"); - binaryOps(symbol, "nint?", "char", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "sbyte", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "byte", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "short", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "ushort", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "int", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "uint", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "nint", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "nuint"); - binaryOps(symbol, "nint?", "long", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "ulong"); - binaryOps(symbol, "nint?", "float"); - binaryOps(symbol, "nint?", "double"); - binaryOps(symbol, "nint?", "decimal"); - binaryOps(symbol, "nint?", "System.IntPtr", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "System.UIntPtr"); - binaryOps(symbol, "nint?", "bool?"); - binaryOps(symbol, "nint?", "char?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "sbyte?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "byte?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "short?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "ushort?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "int?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "uint?", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "nint?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "nuint?"); - binaryOps(symbol, "nint?", "long?", $"long long.{name}(long left, long right)"); - binaryOps(symbol, "nint?", "ulong?"); - binaryOps(symbol, "nint?", "float?"); - binaryOps(symbol, "nint?", "double?"); - binaryOps(symbol, "nint?", "decimal?"); - binaryOps(symbol, "nint?", "System.IntPtr?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "nint?", "System.UIntPtr?"); - binaryOps(symbol, "nuint", "object"); - binaryOps(symbol, "nuint", "string"); - binaryOps(symbol, "nuint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint", includeVoidError: true)); - binaryOps(symbol, "nuint", "bool"); - binaryOps(symbol, "nuint", "char", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "sbyte"); - binaryOps(symbol, "nuint", "byte", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "short"); - binaryOps(symbol, "nuint", "ushort", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "int"); - binaryOps(symbol, "nuint", "uint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "nint"); - binaryOps(symbol, "nuint", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "long"); - binaryOps(symbol, "nuint", "ulong", $"ulong ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint", "float"); - binaryOps(symbol, "nuint", "double"); - binaryOps(symbol, "nuint", "decimal"); - binaryOps(symbol, "nuint", "System.IntPtr"); - binaryOps(symbol, "nuint", "System.UIntPtr", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "bool?"); - binaryOps(symbol, "nuint", "char?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "sbyte?"); - binaryOps(symbol, "nuint", "byte?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "short?"); - binaryOps(symbol, "nuint", "ushort?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "int?"); - binaryOps(symbol, "nuint", "uint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "nint?"); - binaryOps(symbol, "nuint", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint", "long?"); - binaryOps(symbol, "nuint", "ulong?", $"ulong ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint", "float?"); - binaryOps(symbol, "nuint", "double?"); - binaryOps(symbol, "nuint", "decimal?"); - binaryOps(symbol, "nuint", "System.IntPtr?"); - binaryOps(symbol, "nuint", "System.UIntPtr?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "object"); - binaryOps(symbol, "nuint?", "string"); - binaryOps(symbol, "nuint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint?", includeVoidError: true)); - binaryOps(symbol, "nuint?", "bool"); - binaryOps(symbol, "nuint?", "char", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "sbyte"); - binaryOps(symbol, "nuint?", "byte", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "short"); - binaryOps(symbol, "nuint?", "ushort", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "int"); - binaryOps(symbol, "nuint?", "uint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "nint"); - binaryOps(symbol, "nuint?", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "long"); - binaryOps(symbol, "nuint?", "ulong", $"ulong ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint?", "float"); - binaryOps(symbol, "nuint?", "double"); - binaryOps(symbol, "nuint?", "decimal"); - binaryOps(symbol, "nuint?", "System.IntPtr"); - binaryOps(symbol, "nuint?", "System.UIntPtr", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "bool?"); - binaryOps(symbol, "nuint?", "char?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "sbyte?"); - binaryOps(symbol, "nuint?", "byte?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "short?"); - binaryOps(symbol, "nuint?", "ushort?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "int?"); - binaryOps(symbol, "nuint?", "uint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "nint?"); - binaryOps(symbol, "nuint?", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "nuint?", "long?"); - binaryOps(symbol, "nuint?", "ulong?", $"ulong ulong.{name}(ulong left, ulong right)"); - binaryOps(symbol, "nuint?", "float?"); - binaryOps(symbol, "nuint?", "double?"); - binaryOps(symbol, "nuint?", "decimal?"); - binaryOps(symbol, "nuint?", "System.IntPtr?"); - binaryOps(symbol, "nuint?", "System.UIntPtr?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.IntPtr", "object"); - binaryOps(symbol, "System.IntPtr", "string"); - binaryOps(symbol, "System.IntPtr", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.IntPtr", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.IntPtr", includeVoidError: true)); - binaryOps(symbol, "System.IntPtr", "bool"); - binaryOps(symbol, "System.IntPtr", "char"); - binaryOps(symbol, "System.IntPtr", "sbyte"); - binaryOps(symbol, "System.IntPtr", "byte"); - binaryOps(symbol, "System.IntPtr", "short"); - binaryOps(symbol, "System.IntPtr", "ushort"); - binaryOps(symbol, "System.IntPtr", "int"); - binaryOps(symbol, "System.IntPtr", "uint"); - binaryOps(symbol, "System.IntPtr", "nint", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr", "nuint"); - binaryOps(symbol, "System.IntPtr", "long"); - binaryOps(symbol, "System.IntPtr", "ulong"); - binaryOps(symbol, "System.IntPtr", "float"); - binaryOps(symbol, "System.IntPtr", "double"); - binaryOps(symbol, "System.IntPtr", "decimal"); - binaryOps(symbol, "System.IntPtr", "System.IntPtr"); - binaryOps(symbol, "System.IntPtr", "System.UIntPtr"); - binaryOps(symbol, "System.IntPtr", "bool?"); - binaryOps(symbol, "System.IntPtr", "char?"); - binaryOps(symbol, "System.IntPtr", "sbyte?"); - binaryOps(symbol, "System.IntPtr", "byte?"); - binaryOps(symbol, "System.IntPtr", "short?"); - binaryOps(symbol, "System.IntPtr", "ushort?"); - binaryOps(symbol, "System.IntPtr", "int?"); - binaryOps(symbol, "System.IntPtr", "uint?"); - binaryOps(symbol, "System.IntPtr", "nint?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr", "nuint?"); - binaryOps(symbol, "System.IntPtr", "long?"); - binaryOps(symbol, "System.IntPtr", "ulong?"); - binaryOps(symbol, "System.IntPtr", "float?"); - binaryOps(symbol, "System.IntPtr", "double?"); - binaryOps(symbol, "System.IntPtr", "decimal?"); - binaryOps(symbol, "System.IntPtr", "System.IntPtr?"); - binaryOps(symbol, "System.IntPtr", "System.UIntPtr?"); - binaryOps(symbol, "System.IntPtr", "object"); - binaryOps(symbol, "System.IntPtr?", "string"); - binaryOps(symbol, "System.IntPtr?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.IntPtr?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.IntPtr?", includeVoidError: true)); - binaryOps(symbol, "System.IntPtr?", "bool"); - binaryOps(symbol, "System.IntPtr?", "char"); - binaryOps(symbol, "System.IntPtr?", "sbyte"); - binaryOps(symbol, "System.IntPtr?", "byte"); - binaryOps(symbol, "System.IntPtr?", "short"); - binaryOps(symbol, "System.IntPtr?", "ushort"); - binaryOps(symbol, "System.IntPtr?", "int"); - binaryOps(symbol, "System.IntPtr?", "uint"); - binaryOps(symbol, "System.IntPtr?", "nint", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr?", "nuint"); - binaryOps(symbol, "System.IntPtr?", "long"); - binaryOps(symbol, "System.IntPtr?", "ulong"); - binaryOps(symbol, "System.IntPtr?", "float"); - binaryOps(symbol, "System.IntPtr?", "double"); - binaryOps(symbol, "System.IntPtr?", "decimal"); - binaryOps(symbol, "System.IntPtr?", "System.IntPtr"); - binaryOps(symbol, "System.IntPtr?", "System.UIntPtr"); - binaryOps(symbol, "System.IntPtr?", "bool?"); - binaryOps(symbol, "System.IntPtr?", "char?"); - binaryOps(symbol, "System.IntPtr?", "sbyte?"); - binaryOps(symbol, "System.IntPtr?", "byte?"); - binaryOps(symbol, "System.IntPtr?", "short?"); - binaryOps(symbol, "System.IntPtr?", "ushort?"); - binaryOps(symbol, "System.IntPtr?", "int?"); - binaryOps(symbol, "System.IntPtr?", "uint?"); - binaryOps(symbol, "System.IntPtr?", "nint?", $"nint nint.{name}(nint left, nint right)"); - binaryOps(symbol, "System.IntPtr?", "nuint?"); - binaryOps(symbol, "System.IntPtr?", "long?"); - binaryOps(symbol, "System.IntPtr?", "ulong?"); - binaryOps(symbol, "System.IntPtr?", "float?"); - binaryOps(symbol, "System.IntPtr?", "double?"); - binaryOps(symbol, "System.IntPtr?", "decimal?"); - binaryOps(symbol, "System.IntPtr?", "System.IntPtr?"); - binaryOps(symbol, "System.IntPtr?", "System.UIntPtr?"); - binaryOps(symbol, "System.UIntPtr", "object"); - binaryOps(symbol, "System.UIntPtr", "string"); - binaryOps(symbol, "System.UIntPtr", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.UIntPtr", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.UIntPtr", includeVoidError: true)); - binaryOps(symbol, "System.UIntPtr", "bool"); - binaryOps(symbol, "System.UIntPtr", "char"); - binaryOps(symbol, "System.UIntPtr", "sbyte"); - binaryOps(symbol, "System.UIntPtr", "byte"); - binaryOps(symbol, "System.UIntPtr", "short"); - binaryOps(symbol, "System.UIntPtr", "ushort"); - binaryOps(symbol, "System.UIntPtr", "int"); - binaryOps(symbol, "System.UIntPtr", "uint"); - binaryOps(symbol, "System.UIntPtr", "nint"); - binaryOps(symbol, "System.UIntPtr", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr", "long"); - binaryOps(symbol, "System.UIntPtr", "ulong"); - binaryOps(symbol, "System.UIntPtr", "float"); - binaryOps(symbol, "System.UIntPtr", "double"); - binaryOps(symbol, "System.UIntPtr", "decimal"); - binaryOps(symbol, "System.UIntPtr", "System.IntPtr"); - binaryOps(symbol, "System.UIntPtr", "System.UIntPtr"); - binaryOps(symbol, "System.UIntPtr", "bool?"); - binaryOps(symbol, "System.UIntPtr", "char?"); - binaryOps(symbol, "System.UIntPtr", "sbyte?"); - binaryOps(symbol, "System.UIntPtr", "byte?"); - binaryOps(symbol, "System.UIntPtr", "short?"); - binaryOps(symbol, "System.UIntPtr", "ushort?"); - binaryOps(symbol, "System.UIntPtr", "int?"); - binaryOps(symbol, "System.UIntPtr", "uint?"); - binaryOps(symbol, "System.UIntPtr", "nint?"); - binaryOps(symbol, "System.UIntPtr", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr", "long?"); - binaryOps(symbol, "System.UIntPtr", "ulong?"); - binaryOps(symbol, "System.UIntPtr", "float?"); - binaryOps(symbol, "System.UIntPtr", "double?"); - binaryOps(symbol, "System.UIntPtr", "decimal?"); - binaryOps(symbol, "System.UIntPtr", "System.IntPtr?"); - binaryOps(symbol, "System.UIntPtr", "System.UIntPtr?"); - binaryOps(symbol, "System.UIntPtr", "object"); - binaryOps(symbol, "System.UIntPtr?", "string"); - binaryOps(symbol, "System.UIntPtr?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "System.UIntPtr?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "System.UIntPtr?", includeVoidError: true)); - binaryOps(symbol, "System.UIntPtr?", "bool"); - binaryOps(symbol, "System.UIntPtr?", "char"); - binaryOps(symbol, "System.UIntPtr?", "sbyte"); - binaryOps(symbol, "System.UIntPtr?", "byte"); - binaryOps(symbol, "System.UIntPtr?", "short"); - binaryOps(symbol, "System.UIntPtr?", "ushort"); - binaryOps(symbol, "System.UIntPtr?", "int"); - binaryOps(symbol, "System.UIntPtr?", "uint"); - binaryOps(symbol, "System.UIntPtr?", "nint"); - binaryOps(symbol, "System.UIntPtr?", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr?", "long"); - binaryOps(symbol, "System.UIntPtr?", "ulong"); - binaryOps(symbol, "System.UIntPtr?", "float"); - binaryOps(symbol, "System.UIntPtr?", "double"); - binaryOps(symbol, "System.UIntPtr?", "decimal"); - binaryOps(symbol, "System.UIntPtr?", "System.IntPtr"); - binaryOps(symbol, "System.UIntPtr?", "System.UIntPtr"); - binaryOps(symbol, "System.UIntPtr?", "bool?"); - binaryOps(symbol, "System.UIntPtr?", "char?"); - binaryOps(symbol, "System.UIntPtr?", "sbyte?"); - binaryOps(symbol, "System.UIntPtr?", "byte?"); - binaryOps(symbol, "System.UIntPtr?", "short?"); - binaryOps(symbol, "System.UIntPtr?", "ushort?"); - binaryOps(symbol, "System.UIntPtr?", "int?"); - binaryOps(symbol, "System.UIntPtr?", "uint?"); - binaryOps(symbol, "System.UIntPtr?", "nint?"); - binaryOps(symbol, "System.UIntPtr?", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); - binaryOps(symbol, "System.UIntPtr?", "long?"); - binaryOps(symbol, "System.UIntPtr?", "ulong?"); - binaryOps(symbol, "System.UIntPtr?", "float?"); - binaryOps(symbol, "System.UIntPtr?", "double?"); - binaryOps(symbol, "System.UIntPtr?", "decimal?"); - binaryOps(symbol, "System.UIntPtr?", "System.IntPtr?"); - binaryOps(symbol, "System.UIntPtr?", "System.UIntPtr?"); + // nint logicalOp type + unifiedBinaryOps(symbol, "nint", "object"); + unifiedBinaryOps(symbol, "nint", "string"); + unifiedBinaryOps(symbol, "nint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nint", includeVoidError: true)); + unifiedBinaryOps(symbol, "nint", "bool"); + unifiedBinaryOps(symbol, "nint", "char", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "sbyte", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "byte", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "short", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "ushort", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "int", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "uint", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "nint", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "nuint"); + unifiedBinaryOps(symbol, "nint", "long", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "ulong"); + unifiedBinaryOps(symbol, "nint", "float"); + unifiedBinaryOps(symbol, "nint", "double"); + unifiedBinaryOps(symbol, "nint", "decimal"); + unifiedBinaryOps(symbol, "nint", "System.IntPtr", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "System.UIntPtr"); + + // nint logicalOp type? + unifiedBinaryOps(symbol, "nint", "bool?"); + unifiedBinaryOps(symbol, "nint", "char?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "sbyte?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "byte?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "short?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "ushort?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "int?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "uint?", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "nint?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "nuint?"); + unifiedBinaryOps(symbol, "nint", "long?", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint", "ulong?"); + unifiedBinaryOps(symbol, "nint", "float?"); + unifiedBinaryOps(symbol, "nint", "double?"); + unifiedBinaryOps(symbol, "nint", "decimal?"); + unifiedBinaryOps(symbol, "nint", "System.IntPtr?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint", "System.UIntPtr?"); + unifiedBinaryOps(symbol, "nint", "object"); + + // nint? logicalOp type + unifiedBinaryOps(symbol, "nint?", "string"); + unifiedBinaryOps(symbol, "nint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nint?", includeVoidError: true)); + unifiedBinaryOps(symbol, "nint?", "bool"); + unifiedBinaryOps(symbol, "nint?", "char", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "sbyte", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "byte", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "short", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "ushort", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "int", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "uint", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "nint", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "nuint"); + unifiedBinaryOps(symbol, "nint?", "long", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "ulong"); + unifiedBinaryOps(symbol, "nint?", "float"); + unifiedBinaryOps(symbol, "nint?", "double"); + unifiedBinaryOps(symbol, "nint?", "decimal"); + unifiedBinaryOps(symbol, "nint?", "System.IntPtr", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "System.UIntPtr"); + + // nint? logicalOp type? + unifiedBinaryOps(symbol, "nint?", "bool?"); + unifiedBinaryOps(symbol, "nint?", "char?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "sbyte?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "byte?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "short?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "ushort?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "int?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "uint?", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "nint?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "nuint?"); + unifiedBinaryOps(symbol, "nint?", "long?", $"long long.{name}(long left, long right)"); + unifiedBinaryOps(symbol, "nint?", "ulong?"); + unifiedBinaryOps(symbol, "nint?", "float?"); + unifiedBinaryOps(symbol, "nint?", "double?"); + unifiedBinaryOps(symbol, "nint?", "decimal?"); + unifiedBinaryOps(symbol, "nint?", "System.IntPtr?", $"nint nint.{name}(nint left, nint right)"); + unifiedBinaryOps(symbol, "nint?", "System.UIntPtr?"); + + // nuint logicalOp type + unifiedBinaryOps(symbol, "nuint", "object"); + unifiedBinaryOps(symbol, "nuint", "string"); + unifiedBinaryOps(symbol, "nuint", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint", includeVoidError: true)); + unifiedBinaryOps(symbol, "nuint", "bool"); + unifiedBinaryOps(symbol, "nuint", "char", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "sbyte"); + unifiedBinaryOps(symbol, "nuint", "byte", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "short"); + unifiedBinaryOps(symbol, "nuint", "ushort", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "int"); + unifiedBinaryOps(symbol, "nuint", "uint", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "nint"); + unifiedBinaryOps(symbol, "nuint", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "long"); + unifiedBinaryOps(symbol, "nuint", "ulong", $"ulong ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint", "float"); + unifiedBinaryOps(symbol, "nuint", "double"); + unifiedBinaryOps(symbol, "nuint", "decimal"); + unifiedBinaryOps(symbol, "nuint", "System.IntPtr"); + unifiedBinaryOps(symbol, "nuint", "System.UIntPtr", $"nuint nuint.{name}(nuint left, nuint right)"); + + // nuint logicalOp type? + unifiedBinaryOps(symbol, "nuint", "bool?"); + unifiedBinaryOps(symbol, "nuint", "char?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "sbyte?"); + unifiedBinaryOps(symbol, "nuint", "byte?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "short?"); + unifiedBinaryOps(symbol, "nuint", "ushort?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "int?"); + unifiedBinaryOps(symbol, "nuint", "uint?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "nint?"); + unifiedBinaryOps(symbol, "nuint", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint", "long?"); + unifiedBinaryOps(symbol, "nuint", "ulong?", $"ulong ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint", "float?"); + unifiedBinaryOps(symbol, "nuint", "double?"); + unifiedBinaryOps(symbol, "nuint", "decimal?"); + unifiedBinaryOps(symbol, "nuint", "System.IntPtr?"); + unifiedBinaryOps(symbol, "nuint", "System.UIntPtr?", $"nuint nuint.{name}(nuint left, nuint right)"); + + // nuint? logicalOp type + unifiedBinaryOps(symbol, "nuint?", "object"); + unifiedBinaryOps(symbol, "nuint?", "string"); + unifiedBinaryOps(symbol, "nuint?", "void*", null, null, getBadBinaryOpsDiagnostics(symbol, "nuint?", "void*", includeVoidError: true), getBadBinaryOpsDiagnostics(symbol, "void*", "nuint?", includeVoidError: true)); + unifiedBinaryOps(symbol, "nuint?", "bool"); + unifiedBinaryOps(symbol, "nuint?", "char", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "sbyte"); + unifiedBinaryOps(symbol, "nuint?", "byte", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "short"); + unifiedBinaryOps(symbol, "nuint?", "ushort", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "int"); + unifiedBinaryOps(symbol, "nuint?", "uint", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "nint"); + unifiedBinaryOps(symbol, "nuint?", "nuint", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "long"); + unifiedBinaryOps(symbol, "nuint?", "ulong", $"ulong ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint?", "float"); + unifiedBinaryOps(symbol, "nuint?", "double"); + unifiedBinaryOps(symbol, "nuint?", "decimal"); + unifiedBinaryOps(symbol, "nuint?", "System.IntPtr"); + unifiedBinaryOps(symbol, "nuint?", "System.UIntPtr", $"nuint nuint.{name}(nuint left, nuint right)"); + + // nuint? logicalOp type? + unifiedBinaryOps(symbol, "nuint?", "bool?"); + unifiedBinaryOps(symbol, "nuint?", "char?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "sbyte?"); + unifiedBinaryOps(symbol, "nuint?", "byte?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "short?"); + unifiedBinaryOps(symbol, "nuint?", "ushort?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "int?"); + unifiedBinaryOps(symbol, "nuint?", "uint?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "nint?"); + unifiedBinaryOps(symbol, "nuint?", "nuint?", $"nuint nuint.{name}(nuint left, nuint right)"); + unifiedBinaryOps(symbol, "nuint?", "long?"); + unifiedBinaryOps(symbol, "nuint?", "ulong?", $"ulong ulong.{name}(ulong left, ulong right)"); + unifiedBinaryOps(symbol, "nuint?", "float?"); + unifiedBinaryOps(symbol, "nuint?", "double?"); + unifiedBinaryOps(symbol, "nuint?", "decimal?"); + unifiedBinaryOps(symbol, "nuint?", "System.IntPtr?"); + unifiedBinaryOps(symbol, "nuint?", "System.UIntPtr?", $"nuint nuint.{name}(nuint left, nuint right)"); } void binaryOperator(string op, string leftType, string rightType, string expectedSymbol, DiagnosticDescription[] expectedDiagnostics) @@ -11975,7 +8304,8 @@ void binaryOperator(string op, string leftType, string rightType, string expecte return x {op} y; }} }}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithAllowUnsafe(useUnsafeContext), parseOptions: TestOptions.Regular9); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseDll.WithAllowUnsafe(useUnsafeContext), parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; comp.VerifyDiagnostics(expectedDiagnostics); var tree = comp.SyntaxTrees[0]; @@ -12036,7 +8366,9 @@ static void Main() Console.WriteLine(ShiftRight(35, 4)); } }"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + var verifier = CompileAndVerify(comp, expectedOutput: @"7 -1 @@ -12213,22 +8545,22 @@ public void BinaryOperators_NUInt() @"using System; class Program { - static nuint Add(nuint x, nuint y) => x + y; - static nuint Subtract(nuint x, nuint y) => x - y; - static nuint Multiply(nuint x, nuint y) => x * y; - static nuint Divide(nuint x, nuint y) => x / y; - static nuint Mod(nuint x, nuint y) => x % y; - static bool Equals(nuint x, nuint y) => x == y; - static bool NotEquals(nuint x, nuint y) => x != y; - static bool LessThan(nuint x, nuint y) => x < y; - static bool LessThanOrEqual(nuint x, nuint y) => x <= y; - static bool GreaterThan(nuint x, nuint y) => x > y; - static bool GreaterThanOrEqual(nuint x, nuint y) => x >= y; - static nuint And(nuint x, nuint y) => x & y; - static nuint Or(nuint x, nuint y) => x | y; - static nuint Xor(nuint x, nuint y) => x ^ y; - static nuint ShiftLeft(nuint x, int y) => x << y; - static nuint ShiftRight(nuint x, int y) => x >> y; + static UIntPtr Add(UIntPtr x, UIntPtr y) => x + y; + static UIntPtr Subtract(UIntPtr x, UIntPtr y) => x - y; + static UIntPtr Multiply(UIntPtr x, UIntPtr y) => x * y; + static UIntPtr Divide(UIntPtr x, UIntPtr y) => x / y; + static UIntPtr Mod(UIntPtr x, UIntPtr y) => x % y; + static bool Equals(UIntPtr x, UIntPtr y) => x == y; + static bool NotEquals(UIntPtr x, UIntPtr y) => x != y; + static bool LessThan(UIntPtr x, UIntPtr y) => x < y; + static bool LessThanOrEqual(UIntPtr x, UIntPtr y) => x <= y; + static bool GreaterThan(UIntPtr x, UIntPtr y) => x > y; + static bool GreaterThanOrEqual(UIntPtr x, UIntPtr y) => x >= y; + static UIntPtr And(UIntPtr x, UIntPtr y) => x & y; + static UIntPtr Or(UIntPtr x, UIntPtr y) => x | y; + static UIntPtr Xor(UIntPtr x, UIntPtr y) => x ^ y; + static UIntPtr ShiftLeft(UIntPtr x, int y) => x << y; + static UIntPtr ShiftRight(UIntPtr x, int y) => x >> y; static void Main() { Console.WriteLine(Add(3, 4)); @@ -12249,7 +8581,9 @@ static void Main() Console.WriteLine(ShiftRight(35, 4)); } }"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + var verifier = CompileAndVerify(comp, expectedOutput: @"7 1 @@ -12323,1029 +8657,1338 @@ .maxstack 2 }"); verifier.VerifyIL("Program.NotEquals", @"{ - // Code size 8 (0x8) + // Code size 8 (0x8) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ceq + IL_0004: ldc.i4.0 + IL_0005: ceq + IL_0007: ret +}"); + verifier.VerifyIL("Program.LessThan", +@"{ + // Code size 5 (0x5) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: clt.un + IL_0004: ret +}"); + verifier.VerifyIL("Program.LessThanOrEqual", +@"{ + // Code size 8 (0x8) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: cgt.un + IL_0004: ldc.i4.0 + IL_0005: ceq + IL_0007: ret +}"); + verifier.VerifyIL("Program.GreaterThan", +@"{ + // Code size 5 (0x5) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: cgt.un + IL_0004: ret +}"); + verifier.VerifyIL("Program.GreaterThanOrEqual", +@"{ + // Code size 8 (0x8) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: clt.un + IL_0004: ldc.i4.0 + IL_0005: ceq + IL_0007: ret +}"); + verifier.VerifyIL("Program.And", +@"{ + // Code size 4 (0x4) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: and + IL_0003: ret +}"); + verifier.VerifyIL("Program.Or", +@"{ + // Code size 4 (0x4) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: or + IL_0003: ret +}"); + verifier.VerifyIL("Program.Xor", +@"{ + // Code size 4 (0x4) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: xor + IL_0003: ret +}"); + verifier.VerifyIL("Program.ShiftLeft", +@"{ + // Code size 4 (0x4) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: shl + IL_0003: ret +}"); + verifier.VerifyIL("Program.ShiftRight", +@"{ + // Code size 4 (0x4) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: shr.un + IL_0003: ret +}"); + } + + [Fact] + public void BinaryOperators_NInt_Checked() + { + var source = +@"using System; +class Program +{ + static IntPtr Add(IntPtr x, IntPtr y) => checked(x + y); + static IntPtr Subtract(IntPtr x, IntPtr y) => checked(x - y); + static IntPtr Multiply(IntPtr x, IntPtr y) => checked(x * y); + static IntPtr Divide(IntPtr x, IntPtr y) => checked(x / y); + static IntPtr Mod(IntPtr x, IntPtr y) => checked(x % y); + static void Main() + { + Console.WriteLine(Add(3, 4)); + Console.WriteLine(Subtract(3, 4)); + Console.WriteLine(Multiply(3, 4)); + Console.WriteLine(Divide(5, 2)); + Console.WriteLine(Mod(5, 2)); + } +}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + + var verifier = CompileAndVerify(comp, expectedOutput: +@"7 +-1 +12 +2 +1"); + verifier.VerifyIL("Program.Add", +@"{ + // Code size 4 (0x4) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: ceq - IL_0004: ldc.i4.0 - IL_0005: ceq - IL_0007: ret + IL_0002: add.ovf + IL_0003: ret }"); - verifier.VerifyIL("Program.LessThan", + verifier.VerifyIL("Program.Subtract", @"{ - // Code size 5 (0x5) + // Code size 4 (0x4) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: clt.un - IL_0004: ret + IL_0002: sub.ovf + IL_0003: ret }"); - verifier.VerifyIL("Program.LessThanOrEqual", + verifier.VerifyIL("Program.Multiply", @"{ - // Code size 8 (0x8) + // Code size 4 (0x4) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: cgt.un - IL_0004: ldc.i4.0 - IL_0005: ceq - IL_0007: ret + IL_0002: mul.ovf + IL_0003: ret }"); - verifier.VerifyIL("Program.GreaterThan", + verifier.VerifyIL("Program.Divide", @"{ - // Code size 5 (0x5) + // Code size 4 (0x4) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: cgt.un - IL_0004: ret + IL_0002: div + IL_0003: ret }"); - verifier.VerifyIL("Program.GreaterThanOrEqual", + verifier.VerifyIL("Program.Mod", @"{ - // Code size 8 (0x8) + // Code size 4 (0x4) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: clt.un - IL_0004: ldc.i4.0 - IL_0005: ceq - IL_0007: ret + IL_0002: rem + IL_0003: ret }"); - verifier.VerifyIL("Program.And", + } + + [Fact] + public void BinaryOperators_NUInt_Checked() + { + var source = +@"using System; +class Program +{ + static UIntPtr Add(UIntPtr x, UIntPtr y) => checked(x + y); + static UIntPtr Subtract(UIntPtr x, UIntPtr y) => checked(x - y); + static UIntPtr Multiply(UIntPtr x, UIntPtr y) => checked(x * y); + static UIntPtr Divide(UIntPtr x, UIntPtr y) => checked(x / y); + static UIntPtr Mod(UIntPtr x, UIntPtr y) => checked(x % y); + static void Main() + { + Console.WriteLine(Add(3, 4)); + Console.WriteLine(Subtract(4, 3)); + Console.WriteLine(Multiply(3, 4)); + Console.WriteLine(Divide(5, 2)); + Console.WriteLine(Mod(5, 2)); + } +}"; + var comp = CreateEmptyCompilation(source, new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + + var verifier = CompileAndVerify(comp, expectedOutput: +@"7 +1 +12 +2 +1"); + verifier.VerifyIL("Program.Add", @"{ // Code size 4 (0x4) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: and + IL_0002: add.ovf.un IL_0003: ret }"); - verifier.VerifyIL("Program.Or", + verifier.VerifyIL("Program.Subtract", @"{ // Code size 4 (0x4) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: or + IL_0002: sub.ovf.un IL_0003: ret }"); - verifier.VerifyIL("Program.Xor", + verifier.VerifyIL("Program.Multiply", @"{ // Code size 4 (0x4) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: xor + IL_0002: mul.ovf.un IL_0003: ret }"); - verifier.VerifyIL("Program.ShiftLeft", + verifier.VerifyIL("Program.Divide", @"{ // Code size 4 (0x4) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: shl + IL_0002: div.un IL_0003: ret }"); - verifier.VerifyIL("Program.ShiftRight", + verifier.VerifyIL("Program.Mod", @"{ // Code size 4 (0x4) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: shr.un + IL_0002: rem.un IL_0003: ret }"); } [Fact] - public void BinaryOperators_NInt_Checked() + public void ConstantFolding_01() + { + const string intMinValue = "-2147483648"; + const string intMaxValue = "2147483647"; + const string uintMaxValue = "4294967295"; + const string ulongMaxValue = "18446744073709551615"; + + unaryOperator("System.IntPtr", "+", intMinValue, intMinValue); + unaryOperator("System.IntPtr", "+", intMaxValue, intMaxValue); + unaryOperator("System.UIntPtr", "+", "0", "0"); + unaryOperator("System.UIntPtr", "+", uintMaxValue, uintMaxValue); + + unaryOperator("System.IntPtr", "-", "-1", "1"); + unaryOperatorCheckedOverflow("System.IntPtr", "-", intMinValue, IntPtr.Size == 4 ? "-2147483648" : "2147483648", IntPtr.Size == 4 ? "System.OverflowException" : "2147483648"); + unaryOperator("System.IntPtr", "-", "-2147483647", intMaxValue); + unaryOperator("System.IntPtr", "-", intMaxValue, "-2147483647"); + unaryOperator("System.UIntPtr", "-", "0", null, getBadUnaryOpDiagnostics); + unaryOperator("System.UIntPtr", "-", "1", null, getBadUnaryOpDiagnostics); + unaryOperator("System.UIntPtr", "-", uintMaxValue, null, getBadUnaryOpDiagnostics); + + unaryOperatorNotConstant("System.IntPtr", "~", "0", "-1"); + unaryOperatorNotConstant("System.IntPtr", "~", "-1", "0"); + unaryOperatorNotConstant("System.IntPtr", "~", intMinValue, "2147483647"); + unaryOperatorNotConstant("System.IntPtr", "~", intMaxValue, "-2147483648"); + unaryOperatorNotConstant("System.UIntPtr", "~", "0", IntPtr.Size == 4 ? uintMaxValue : ulongMaxValue); + unaryOperatorNotConstant("System.UIntPtr", "~", uintMaxValue, IntPtr.Size == 4 ? "0" : "18446744069414584320"); + + binaryOperatorCheckedOverflow("System.IntPtr", "+", "System.IntPtr", intMinValue, "System.IntPtr", "-1", IntPtr.Size == 4 ? "2147483647" : "-2147483649", IntPtr.Size == 4 ? "System.OverflowException" : "-2147483649"); + binaryOperator("System.IntPtr", "+", "System.IntPtr", "-2147483647", "System.IntPtr", "-1", intMinValue); + binaryOperatorCheckedOverflow("System.IntPtr", "+", "System.IntPtr", "1", "System.IntPtr", intMaxValue, IntPtr.Size == 4 ? "-2147483648" : "2147483648", IntPtr.Size == 4 ? "System.OverflowException" : "2147483648"); + binaryOperator("System.IntPtr", "+", "System.IntPtr", "1", "System.IntPtr", "2147483646", intMaxValue); + binaryOperatorCheckedOverflow("System.UIntPtr", "+", "System.UIntPtr", "1", "System.UIntPtr", uintMaxValue, IntPtr.Size == 4 ? "0" : "4294967296", IntPtr.Size == 4 ? "System.OverflowException" : "4294967296"); + binaryOperator("System.UIntPtr", "+", "System.UIntPtr", "1", "System.UIntPtr", "4294967294", uintMaxValue); + + binaryOperatorCheckedOverflow("System.IntPtr", "-", "System.IntPtr", intMinValue, "System.IntPtr", "1", IntPtr.Size == 4 ? "2147483647" : "-2147483649", IntPtr.Size == 4 ? "System.OverflowException" : "-2147483649"); + binaryOperator("System.IntPtr", "-", "System.IntPtr", intMinValue, "System.IntPtr", "-1", "-2147483647"); + binaryOperator("System.IntPtr", "-", "System.IntPtr", "-1", "System.IntPtr", intMaxValue, intMinValue); + binaryOperatorCheckedOverflow("System.IntPtr", "-", "System.IntPtr", "-2", "System.IntPtr", intMaxValue, IntPtr.Size == 4 ? "2147483647" : "-2147483649", IntPtr.Size == 4 ? "System.OverflowException" : "-2147483649"); + binaryOperatorCheckedOverflow("System.UIntPtr", "-", "System.UIntPtr", "0", "System.UIntPtr", "1", IntPtr.Size == 4 ? uintMaxValue : ulongMaxValue, "System.OverflowException"); + binaryOperator("System.UIntPtr", "-", "System.UIntPtr", uintMaxValue, "System.UIntPtr", uintMaxValue, "0"); + + binaryOperatorCheckedOverflow("System.IntPtr", "*", "System.IntPtr", intMinValue, "System.IntPtr", "2", IntPtr.Size == 4 ? "0" : "-4294967296", IntPtr.Size == 4 ? "System.OverflowException" : "-4294967296"); + binaryOperatorCheckedOverflow("System.IntPtr", "*", "System.IntPtr", intMinValue, "System.IntPtr", "-1", IntPtr.Size == 4 ? "-2147483648" : "2147483648", IntPtr.Size == 4 ? "System.OverflowException" : "2147483648"); + binaryOperator("System.IntPtr", "*", "System.IntPtr", "-1", "System.IntPtr", intMaxValue, "-2147483647"); + binaryOperatorCheckedOverflow("System.IntPtr", "*", "System.IntPtr", "2", "System.IntPtr", intMaxValue, IntPtr.Size == 4 ? "-2" : "4294967294", IntPtr.Size == 4 ? "System.OverflowException" : "4294967294"); + binaryOperatorCheckedOverflow("System.UIntPtr", "*", "System.UIntPtr", uintMaxValue, "System.UIntPtr", "2", IntPtr.Size == 4 ? "4294967294" : "8589934590", IntPtr.Size == 4 ? "System.OverflowException" : "8589934590"); + binaryOperator("System.UIntPtr", "*", "System.UIntPtr", intMaxValue, "System.UIntPtr", "2", "4294967294"); + + binaryOperator("System.IntPtr", "/", "System.IntPtr", intMinValue, "System.IntPtr", "1", intMinValue); + binaryOperatorCheckedOverflow("System.IntPtr", "/", "System.IntPtr", intMinValue, "System.IntPtr", "-1", IntPtr.Size == 4 ? "System.OverflowException" : "2147483648", IntPtr.Size == 4 ? "System.OverflowException" : "2147483648"); + binaryOperator("System.IntPtr", "/", "System.IntPtr", "1", "System.IntPtr", "0", null, getIntDivByZeroDiagnostics); + binaryOperator("System.IntPtr", "/", "System.IntPtr", "0", "System.IntPtr", "0", null, getIntDivByZeroDiagnostics); + binaryOperator("System.UIntPtr", "/", "System.UIntPtr", uintMaxValue, "System.UIntPtr", "1", uintMaxValue); + binaryOperator("System.UIntPtr", "/", "System.UIntPtr", uintMaxValue, "System.UIntPtr", "2", intMaxValue); + binaryOperator("System.UIntPtr", "/", "System.UIntPtr", "1", "System.UIntPtr", "0", null, getIntDivByZeroDiagnostics); + binaryOperator("System.UIntPtr", "/", "System.UIntPtr", "0", "System.UIntPtr", "0", null, getIntDivByZeroDiagnostics); + + binaryOperator("System.IntPtr", "%", "System.IntPtr", intMinValue, "System.IntPtr", "2", "0"); + binaryOperator("System.IntPtr", "%", "System.IntPtr", intMinValue, "System.IntPtr", "-2", "0"); + binaryOperatorCheckedOverflow("System.IntPtr", "%", "System.IntPtr", intMinValue, "System.IntPtr", "-1", IntPtr.Size == 4 ? "System.OverflowException" : "0", IntPtr.Size == 4 ? "System.OverflowException" : "0"); + binaryOperator("System.IntPtr", "%", "System.IntPtr", "1", "System.IntPtr", "0", null, getIntDivByZeroDiagnostics); + binaryOperator("System.IntPtr", "%", "System.IntPtr", "0", "System.IntPtr", "0", null, getIntDivByZeroDiagnostics); + binaryOperator("System.UIntPtr", "%", "System.UIntPtr", uintMaxValue, "System.UIntPtr", "1", "0"); + binaryOperator("System.UIntPtr", "%", "System.UIntPtr", uintMaxValue, "System.UIntPtr", "2", "1"); + binaryOperator("System.UIntPtr", "%", "System.UIntPtr", "1", "System.UIntPtr", "0", null, getIntDivByZeroDiagnostics); + binaryOperator("System.UIntPtr", "%", "System.UIntPtr", "0", "System.UIntPtr", "0", null, getIntDivByZeroDiagnostics); + + binaryOperator("bool", "<", "System.IntPtr", intMinValue, "System.IntPtr", intMinValue, "False"); + binaryOperator("bool", "<", "System.IntPtr", intMinValue, "System.IntPtr", intMaxValue, "True"); + binaryOperator("bool", "<", "System.IntPtr", intMaxValue, "System.IntPtr", intMaxValue, "False"); + binaryOperator("bool", "<", "System.UIntPtr", "0", "System.UIntPtr", "0", "False"); + binaryOperator("bool", "<", "System.UIntPtr", "0", "System.UIntPtr", uintMaxValue, "True"); + binaryOperator("bool", "<", "System.UIntPtr", uintMaxValue, "System.UIntPtr", uintMaxValue, "False"); + + binaryOperator("bool", "<=", "System.IntPtr", intMinValue, "System.IntPtr", intMinValue, "True"); + binaryOperator("bool", "<=", "System.IntPtr", intMaxValue, "System.IntPtr", intMinValue, "False"); + binaryOperator("bool", "<=", "System.IntPtr", intMaxValue, "System.IntPtr", intMaxValue, "True"); + binaryOperator("bool", "<=", "System.UIntPtr", "0", "System.UIntPtr", "0", "True"); + binaryOperator("bool", "<=", "System.UIntPtr", uintMaxValue, "System.UIntPtr", "0", "False"); + binaryOperator("bool", "<=", "System.UIntPtr", uintMaxValue, "System.UIntPtr", uintMaxValue, "True"); + + binaryOperator("bool", ">", "System.IntPtr", intMinValue, "System.IntPtr", intMinValue, "False"); + binaryOperator("bool", ">", "System.IntPtr", intMaxValue, "System.IntPtr", intMinValue, "True"); + binaryOperator("bool", ">", "System.IntPtr", intMaxValue, "System.IntPtr", intMaxValue, "False"); + binaryOperator("bool", ">", "System.UIntPtr", "0", "System.UIntPtr", "0", "False"); + binaryOperator("bool", ">", "System.UIntPtr", uintMaxValue, "System.UIntPtr", "0", "True"); + binaryOperator("bool", ">", "System.UIntPtr", uintMaxValue, "System.UIntPtr", uintMaxValue, "False"); + + binaryOperator("bool", ">=", "System.IntPtr", intMinValue, "System.IntPtr", intMinValue, "True"); + binaryOperator("bool", ">=", "System.IntPtr", intMinValue, "System.IntPtr", intMaxValue, "False"); + binaryOperator("bool", ">=", "System.IntPtr", intMaxValue, "System.IntPtr", intMaxValue, "True"); + binaryOperator("bool", ">=", "System.UIntPtr", "0", "System.UIntPtr", "0", "True"); + binaryOperator("bool", ">=", "System.UIntPtr", "0", "System.UIntPtr", uintMaxValue, "False"); + binaryOperator("bool", ">=", "System.UIntPtr", uintMaxValue, "System.UIntPtr", uintMaxValue, "True"); + + binaryOperator("bool", "==", "System.IntPtr", intMinValue, "System.IntPtr", intMinValue, "True"); + binaryOperator("bool", "==", "System.IntPtr", intMinValue, "System.IntPtr", intMaxValue, "False"); + binaryOperator("bool", "==", "System.IntPtr", intMaxValue, "System.IntPtr", intMaxValue, "True"); + binaryOperator("bool", "==", "System.UIntPtr", "0", "System.UIntPtr", "0", "True"); + binaryOperator("bool", "==", "System.UIntPtr", "0", "System.UIntPtr", uintMaxValue, "False"); + binaryOperator("bool", "==", "System.UIntPtr", uintMaxValue, "System.UIntPtr", uintMaxValue, "True"); + + binaryOperator("bool", "!=", "System.IntPtr", intMinValue, "System.IntPtr", intMinValue, "False"); + binaryOperator("bool", "!=", "System.IntPtr", intMinValue, "System.IntPtr", intMaxValue, "True"); + binaryOperator("bool", "!=", "System.IntPtr", intMaxValue, "System.IntPtr", intMaxValue, "False"); + binaryOperator("bool", "!=", "System.UIntPtr", "0", "System.UIntPtr", "0", "False"); + binaryOperator("bool", "!=", "System.UIntPtr", "0", "System.UIntPtr", uintMaxValue, "True"); + binaryOperator("bool", "!=", "System.UIntPtr", uintMaxValue, "System.UIntPtr", uintMaxValue, "False"); + + binaryOperator("System.IntPtr", "<<", "System.IntPtr", intMinValue, "int", "0", intMinValue); + binaryOperatorNotConstant("System.IntPtr", "<<", "System.IntPtr", intMinValue, "int", "1", IntPtr.Size == 4 ? "0" : "-4294967296"); + binaryOperator("System.IntPtr", "<<", "System.IntPtr", "-1", "int", "31", intMinValue); + binaryOperatorNotConstant("System.IntPtr", "<<", "System.IntPtr", "-1", "int", "32", IntPtr.Size == 4 ? "-1" : "-4294967296"); + binaryOperator("System.UIntPtr", "<<", "System.UIntPtr", "0", "int", "1", "0"); + binaryOperatorNotConstant("System.UIntPtr", "<<", "System.UIntPtr", uintMaxValue, "int", "1", IntPtr.Size == 4 ? "4294967294" : "8589934590"); + binaryOperator("System.UIntPtr", "<<", "System.UIntPtr", "1", "int", "31", "2147483648"); + binaryOperatorNotConstant("System.UIntPtr", "<<", "System.UIntPtr", "1", "int", "32", IntPtr.Size == 4 ? "1" : "4294967296"); + + binaryOperator("System.IntPtr", ">>", "System.IntPtr", intMinValue, "int", "0", intMinValue); + binaryOperator("System.IntPtr", ">>", "System.IntPtr", intMinValue, "int", "1", "-1073741824"); + binaryOperator("System.IntPtr", ">>", "System.IntPtr", "-1", "int", "31", "-1"); + binaryOperator("System.IntPtr", ">>", "System.IntPtr", "-1", "int", "32", "-1"); + binaryOperator("System.UIntPtr", ">>", "System.UIntPtr", "0", "int", "1", "0"); + binaryOperator("System.UIntPtr", ">>", "System.UIntPtr", uintMaxValue, "int", "1", intMaxValue); + binaryOperator("System.UIntPtr", ">>", "System.UIntPtr", "1", "int", "31", "0"); + binaryOperator("System.UIntPtr", ">>", "System.UIntPtr", "1", "int", "32", "1"); + + binaryOperator("System.IntPtr", "&", "System.IntPtr", intMinValue, "System.IntPtr", "0", "0"); + binaryOperator("System.IntPtr", "&", "System.IntPtr", intMinValue, "System.IntPtr", "-1", intMinValue); + binaryOperator("System.IntPtr", "&", "System.IntPtr", intMinValue, "System.IntPtr", intMaxValue, "0"); + binaryOperator("System.UIntPtr", "&", "System.UIntPtr", "0", "System.UIntPtr", uintMaxValue, "0"); + binaryOperator("System.UIntPtr", "&", "System.UIntPtr", intMaxValue, "System.UIntPtr", uintMaxValue, intMaxValue); + binaryOperator("System.UIntPtr", "&", "System.UIntPtr", intMaxValue, "System.UIntPtr", "2147483648", "0"); + + binaryOperator("System.IntPtr", "|", "System.IntPtr", intMinValue, "System.IntPtr", "0", intMinValue); + binaryOperator("System.IntPtr", "|", "System.IntPtr", intMinValue, "System.IntPtr", "-1", "-1"); + binaryOperator("System.IntPtr", "|", "System.IntPtr", intMaxValue, "System.IntPtr", intMaxValue, intMaxValue); + binaryOperator("System.UIntPtr", "|", "System.UIntPtr", "0", "System.UIntPtr", uintMaxValue, uintMaxValue); + binaryOperator("System.UIntPtr", "|", "System.UIntPtr", intMaxValue, "System.UIntPtr", intMaxValue, intMaxValue); + binaryOperator("System.UIntPtr", "|", "System.UIntPtr", intMaxValue, "System.UIntPtr", "2147483648", uintMaxValue); + + binaryOperator("System.IntPtr", "^", "System.IntPtr", intMinValue, "System.IntPtr", "0", intMinValue); + binaryOperator("System.IntPtr", "^", "System.IntPtr", intMinValue, "System.IntPtr", "-1", intMaxValue); + binaryOperator("System.IntPtr", "^", "System.IntPtr", intMaxValue, "System.IntPtr", intMaxValue, "0"); + binaryOperator("System.UIntPtr", "^", "System.UIntPtr", "0", "System.UIntPtr", uintMaxValue, uintMaxValue); + binaryOperator("System.UIntPtr", "^", "System.UIntPtr", intMaxValue, "System.UIntPtr", intMaxValue, "0"); + binaryOperator("System.UIntPtr", "^", "System.UIntPtr", intMaxValue, "System.UIntPtr", "2147483648", uintMaxValue); + + static DiagnosticDescription[] getNoDiagnostics(string opType, string op, string operand) => Array.Empty(); + static DiagnosticDescription[] getBadUnaryOpDiagnostics(string opType, string op, string operand) => new[] { Diagnostic(ErrorCode.ERR_BadUnaryOp, operand).WithArguments(op, AsNative(opType)) }; + + static DiagnosticDescription[] getIntDivByZeroDiagnostics(string opType, string op, string operand) => new[] { Diagnostic(ErrorCode.ERR_IntDivByZero, operand) }; + + void unaryOperator(string opType, string op, string operand, string expectedResult, Func getDiagnostics = null) + { + getDiagnostics ??= getNoDiagnostics; + + var declarations = $"const {opType} A = {operand};"; + var expr = $"{op}A"; + var diagnostics = getDiagnostics(opType, op, expr); + constantDeclaration(opType, declarations, expr, expectedResult, diagnostics); + constantDeclaration(opType, declarations, $"checked({expr})", expectedResult, diagnostics); + constantDeclaration(opType, declarations, $"unchecked({expr})", expectedResult, diagnostics); + + expr = $"{op}({opType})({operand})"; + diagnostics = getDiagnostics(opType, op, expr); + constantExpression(opType, expr, expectedResult, diagnostics); + constantExpression(opType, $"checked({expr})", expectedResult, diagnostics); + constantExpression(opType, $"unchecked({expr})", expectedResult, diagnostics); + } + + void unaryOperatorCheckedOverflow(string opType, string op, string operand, string expectedResultUnchecked, string expectedResultChecked) + { + var declarations = $"const {opType} A = {operand};"; + var expr = $"{op}A"; + constantDeclaration(opType, declarations, expr, null, + new[] { + Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(AsNative( opType)), + Diagnostic(ErrorCode.ERR_NotConstantExpression, expr).WithArguments("Library.F") + }); + constantDeclaration(opType, declarations, $"checked({expr})", null, + new[] { + Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(AsNative(opType)), + Diagnostic(ErrorCode.ERR_NotConstantExpression, $"checked({expr})").WithArguments("Library.F") + }); + constantDeclaration(opType, declarations, $"unchecked({expr})", null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, $"unchecked({expr})").WithArguments("Library.F") }); + + expr = $"{op}({opType})({operand})"; + constantExpression(opType, expr, expectedResultUnchecked, new[] { Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(AsNative(opType)) }); + constantExpression(opType, $"checked({expr})", expectedResultChecked, new[] { Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(AsNative(opType)) }); + constantExpression(opType, $"unchecked({expr})", expectedResultUnchecked, Array.Empty()); + } + + void unaryOperatorNotConstant(string opType, string op, string operand, string expectedResult) + { + var declarations = $"const {opType} A = {operand};"; + var expr = $"{op}A"; + constantDeclaration(opType, declarations, expr, null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, expr).WithArguments("Library.F") }); + constantDeclaration(opType, declarations, $"checked({expr})", null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, $"checked({expr})").WithArguments("Library.F") }); + constantDeclaration(opType, declarations, $"unchecked({expr})", null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, $"unchecked({expr})").WithArguments("Library.F") }); + + expr = $"{op}({opType})({operand})"; + constantExpression(opType, expr, expectedResult, Array.Empty()); + constantExpression(opType, $"checked({expr})", expectedResult, Array.Empty()); + constantExpression(opType, $"unchecked({expr})", expectedResult, Array.Empty()); + } + + void binaryOperator(string opType, string op, string leftType, string leftOperand, string rightType, string rightOperand, string expectedResult, Func getDiagnostics = null) + { + getDiagnostics ??= getNoDiagnostics; + + var declarations = $"const {leftType} A = {leftOperand}; const {rightType} B = {rightOperand};"; + var expr = $"A {op} B"; + var diagnostics = getDiagnostics(opType, op, expr); + constantDeclaration(opType, declarations, expr, expectedResult, diagnostics); + constantDeclaration(opType, declarations, $"checked({expr})", expectedResult, diagnostics); + constantDeclaration(opType, declarations, $"unchecked({expr})", expectedResult, diagnostics); + + expr = $"(({leftType})({leftOperand})) {op} (({rightType})({rightOperand}))"; + diagnostics = getDiagnostics(opType, op, expr); + constantExpression(opType, expr, expectedResult, diagnostics); + constantExpression(opType, $"checked({expr})", expectedResult, diagnostics); + constantExpression(opType, $"unchecked({expr})", expectedResult, diagnostics); + } + + void binaryOperatorCheckedOverflow(string opType, string op, string leftType, string leftOperand, string rightType, string rightOperand, string expectedResultUnchecked, string expectedResultChecked) + { + var declarations = $"const {leftType} A = {leftOperand}; const {rightType} B = {rightOperand};"; + var expr = $"A {op} B"; + constantDeclaration(opType, declarations, expr, null, + new[] { + Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(AsNative(opType)), + Diagnostic(ErrorCode.ERR_NotConstantExpression, expr).WithArguments("Library.F") + }); + constantDeclaration(opType, declarations, $"checked({expr})", null, + new[] { + Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(AsNative(opType)), + Diagnostic(ErrorCode.ERR_NotConstantExpression, $"checked({expr})").WithArguments("Library.F") + }); + constantDeclaration(opType, declarations, $"unchecked({expr})", null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, $"unchecked({expr})").WithArguments("Library.F") }); + + expr = $"(({leftType})({leftOperand})) {op} (({rightType})({rightOperand}))"; + constantExpression(opType, expr, expectedResultUnchecked, new[] { Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(AsNative(opType)) }); + constantExpression(opType, $"checked({expr})", expectedResultChecked, new[] { Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(AsNative(opType)) }); + constantExpression(opType, $"unchecked({expr})", expectedResultUnchecked, Array.Empty()); + } + + void binaryOperatorNotConstant(string opType, string op, string leftType, string leftOperand, string rightType, string rightOperand, string expectedResult) + { + var declarations = $"const {leftType} A = {leftOperand}; const {rightType} B = {rightOperand};"; + var expr = $"A {op} B"; + constantDeclaration(opType, declarations, expr, null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, expr).WithArguments("Library.F") }); + constantDeclaration(opType, declarations, $"checked({expr})", null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, $"checked({expr})").WithArguments("Library.F") }); + constantDeclaration(opType, declarations, $"unchecked({expr})", null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, $"unchecked({expr})").WithArguments("Library.F") }); + + expr = $"(({leftType})({leftOperand})) {op} (({rightType})({rightOperand}))"; + constantExpression(opType, expr, expectedResult, Array.Empty()); + constantExpression(opType, $"checked({expr})", expectedResult, Array.Empty()); + constantExpression(opType, $"unchecked({expr})", expectedResult, Array.Empty()); + } + + void constantDeclaration(string opType, string declarations, string expr, string expectedResult, DiagnosticDescription[] expectedDiagnostics) + { + string sourceA = +$@"public class Library +{{ + {declarations} + public const {opType} F = {expr}; +}}"; + var comp = CreateEmptyCompilation(sourceA, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + + comp.VerifyDiagnostics(expectedDiagnostics); + + if (expectedDiagnostics.Any(d => ErrorFacts.GetSeverity((ErrorCode)d.Code) == DiagnosticSeverity.Error)) + { + Assert.Null(expectedResult); + return; + } + + string sourceB = +@"class Program +{ + static void Main() + { + System.Console.WriteLine(Library.F); + } +}"; + var refA = comp.EmitToImageReference(); + comp = CreateEmptyCompilation(sourceB, references: new[] { refA, MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + + CompileAndVerify(comp, expectedOutput: expectedResult); + Assert.NotNull(expectedResult); + } + + void constantExpression(string opType, string expr, string expectedResult, DiagnosticDescription[] expectedDiagnostics) + { + string source = +$@"using System; +class Program +{{ + static void Main() + {{ + object result; + try + {{ + {opType} value = {expr}; + result = value; + }} + catch (Exception e) + {{ + result = e.GetType().FullName; + }} + Console.WriteLine(result); + }} +}}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + + if (expectedDiagnostics.Any(d => ErrorFacts.GetSeverity((ErrorCode)d.Code) == DiagnosticSeverity.Error)) + { + comp.VerifyDiagnostics(expectedDiagnostics); + Assert.Null(expectedResult); + return; + } + + CompileAndVerify(comp, expectedOutput: expectedResult).VerifyDiagnostics(expectedDiagnostics); + Assert.NotNull(expectedResult); + } + } + + [Fact] + public void ConstantFolding_02() { - var source = -@"using System; + var source = @" +using System; + class Program { - static nint Add(nint x, nint y) => checked(x + y); - static nint Subtract(nint x, nint y) => checked(x - y); - static nint Multiply(nint x, nint y) => checked(x * y); - static nint Divide(nint x, nint y) => checked(x / y); - static nint Mod(nint x, nint y) => checked(x % y); static void Main() { - Console.WriteLine(Add(3, 4)); - Console.WriteLine(Subtract(3, 4)); - Console.WriteLine(Multiply(3, 4)); - Console.WriteLine(Divide(5, 2)); - Console.WriteLine(Mod(5, 2)); + const UIntPtr x = unchecked(uint.MaxValue + (UIntPtr)42); + const UIntPtr y = checked(uint.MaxValue + (UIntPtr)42); } }"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - var verifier = CompileAndVerify(comp, expectedOutput: -@"7 --1 -12 -2 -1"); - verifier.VerifyIL("Program.Add", -@"{ - // Code size 4 (0x4) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: add.ovf - IL_0003: ret -}"); - verifier.VerifyIL("Program.Subtract", -@"{ - // Code size 4 (0x4) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: sub.ovf - IL_0003: ret -}"); - verifier.VerifyIL("Program.Multiply", -@"{ - // Code size 4 (0x4) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: mul.ovf - IL_0003: ret -}"); - verifier.VerifyIL("Program.Divide", -@"{ - // Code size 4 (0x4) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: div - IL_0003: ret -}"); - verifier.VerifyIL("Program.Mod", -@"{ - // Code size 4 (0x4) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: rem - IL_0003: ret -}"); + var mscorLibRef = MscorlibRefWithoutSharingCachedSymbols; + var comp = CreateEmptyCompilation(source, references: new[] { mscorLibRef }, options: TestOptions.ReleaseExe); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + + comp.VerifyDiagnostics( + // (8,27): error CS0133: The expression being assigned to 'x' must be constant + // const UIntPtr x = unchecked(uint.MaxValue + (UIntPtr)42); + Diagnostic(ErrorCode.ERR_NotConstantExpression, "unchecked(uint.MaxValue + (UIntPtr)42)").WithArguments("x").WithLocation(8, 27), + // (9,27): error CS0133: The expression being assigned to 'y' must be constant + // const UIntPtr y = checked(uint.MaxValue + (UIntPtr)42); + Diagnostic(ErrorCode.ERR_NotConstantExpression, "checked(uint.MaxValue + (UIntPtr)42)").WithArguments("y").WithLocation(9, 27), + // (9,35): warning CS8973: The operation may overflow 'nuint' at runtime (use 'unchecked' syntax to override) + // const UIntPtr y = checked(uint.MaxValue + (UIntPtr)42); + Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, "uint.MaxValue + (UIntPtr)42").WithArguments("nuint").WithLocation(9, 35) + ); + + source = @" +using System; + +class Program +{ + static void Main() + { + try + { + var y = checked(uint.MaxValue + (UIntPtr)42); + System.Console.WriteLine(y); + } + catch (System.Exception e) + { + System.Console.WriteLine(e.GetType()); + } + } +}"; + mscorLibRef = MscorlibRefWithoutSharingCachedSymbols; + comp = CreateEmptyCompilation(source, references: new[] { mscorLibRef }, options: TestOptions.ReleaseExe); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + CompileAndVerify(comp, expectedOutput: IntPtr.Size == 4 ? "System.OverflowException" : "4294967337").VerifyDiagnostics( + // (10,29): warning CS8973: The operation may overflow 'nuint' at runtime (use 'unchecked' syntax to override) + // var y = checked(uint.MaxValue + (UIntPtr)42); + Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, "uint.MaxValue + (UIntPtr)42").WithArguments("nuint").WithLocation(10, 29) + ); + + source = @" +using System; + +class Program +{ + static void Main() + { + var y = unchecked(uint.MaxValue + (UIntPtr)42); + System.Console.WriteLine(y); + } +}"; + mscorLibRef = MscorlibRefWithoutSharingCachedSymbols; + comp = CreateEmptyCompilation(source, references: new[] { mscorLibRef }, options: TestOptions.ReleaseExe); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + CompileAndVerify(comp, expectedOutput: IntPtr.Size == 4 ? "41" : "4294967337").VerifyDiagnostics(); } [Fact] - public void BinaryOperators_NUInt_Checked() + public void ConstantFolding_03() { - var source = + var source = @" +using System; + +class Program +{ + static void Main() + { + const IntPtr x = unchecked(-(IntPtr)int.MinValue); + const IntPtr y = checked(-(IntPtr)int.MinValue); + } +}"; + var mscorLibRef = MscorlibRefWithoutSharingCachedSymbols; + var comp = CreateEmptyCompilation(source, references: new[] { mscorLibRef }, options: TestOptions.ReleaseExe); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics( + // (8,26): error CS0133: The expression being assigned to 'x' must be constant + // const IntPtr x = unchecked(-(IntPtr)int.MinValue); + Diagnostic(ErrorCode.ERR_NotConstantExpression, "unchecked(-(IntPtr)int.MinValue)").WithArguments("x").WithLocation(8, 26), + // (9,26): error CS0133: The expression being assigned to 'y' must be constant + // const IntPtr y = checked(-(IntPtr)int.MinValue); + Diagnostic(ErrorCode.ERR_NotConstantExpression, "checked(-(IntPtr)int.MinValue)").WithArguments("y").WithLocation(9, 26), + // (9,34): warning CS8973: The operation may overflow 'nint' at runtime (use 'unchecked' syntax to override) + // const IntPtr y = checked(-(IntPtr)int.MinValue); + Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, "-(IntPtr)int.MinValue").WithArguments("nint").WithLocation(9, 34) + ); + + source = @" +using System; + +class Program +{ + static void Main() + { + try + { + var y = checked(-(IntPtr)int.MinValue); + System.Console.WriteLine(y); + } + catch (System.Exception e) + { + System.Console.WriteLine(e.GetType()); + } + } +}"; + mscorLibRef = MscorlibRefWithoutSharingCachedSymbols; + comp = CreateEmptyCompilation(source, references: new[] { mscorLibRef }, options: TestOptions.ReleaseExe); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + CompileAndVerify(comp, expectedOutput: IntPtr.Size == 4 ? "System.OverflowException" : "2147483648").VerifyDiagnostics( + // (10,29): warning CS8973: The operation may overflow 'nint' at runtime (use 'unchecked' syntax to override) + // var y = checked(-(IntPtr)int.MinValue); + Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, "-(IntPtr)int.MinValue").WithArguments("nint").WithLocation(10, 29) + ); + + source = @" +using System; + +class Program +{ + static void Main() + { + var y = unchecked(-(IntPtr)int.MinValue); + System.Console.WriteLine(y); + } +}"; + mscorLibRef = MscorlibRefWithoutSharingCachedSymbols; + comp = CreateEmptyCompilation(source, references: new[] { mscorLibRef }, options: TestOptions.ReleaseExe); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + CompileAndVerify(comp, expectedOutput: IntPtr.Size == 4 ? "-2147483648" : "2147483648").VerifyDiagnostics(); + } + + // OverflowException behavior is consistent with unchecked int division. + [Fact] + public void UncheckedIntegerDivision() + { + string source = @"using System; class Program { - static nuint Add(nuint x, nuint y) => checked(x + y); - static nuint Subtract(nuint x, nuint y) => checked(x - y); - static nuint Multiply(nuint x, nuint y) => checked(x * y); - static nuint Divide(nuint x, nuint y) => checked(x / y); - static nuint Mod(nuint x, nuint y) => checked(x % y); static void Main() { - Console.WriteLine(Add(3, 4)); - Console.WriteLine(Subtract(4, 3)); - Console.WriteLine(Multiply(3, 4)); - Console.WriteLine(Divide(5, 2)); - Console.WriteLine(Mod(5, 2)); + Console.WriteLine(Execute(() => IntDivision(int.MinValue + 1, -1))); + Console.WriteLine(Execute(() => IntDivision(int.MinValue, -1))); + Console.WriteLine(Execute(() => IntRemainder(int.MinValue + 1, -1))); + Console.WriteLine(Execute(() => IntRemainder(int.MinValue, -1))); + Console.WriteLine(Execute(() => NativeIntDivision(int.MinValue + 1, -1))); + Console.WriteLine(Execute(() => NativeIntDivision(int.MinValue, -1))); + Console.WriteLine(Execute(() => NativeIntRemainder(int.MinValue + 1, -1))); + Console.WriteLine(Execute(() => NativeIntRemainder(int.MinValue, -1))); + } + static object Execute(Func f) + { + try + { + return f(); + } + catch (Exception e) + { + return e.GetType().FullName; + } } + static int IntDivision(int x, int y) => unchecked(x / y); + static int IntRemainder(int x, int y) => unchecked(x % y); + static nint NativeIntDivision(IntPtr x, IntPtr y) => unchecked(x / y); + static nint NativeIntRemainder(IntPtr x, IntPtr y) => unchecked(x % y); }"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - var verifier = CompileAndVerify(comp, expectedOutput: -@"7 -1 -12 -2 -1"); - verifier.VerifyIL("Program.Add", -@"{ - // Code size 4 (0x4) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: add.ovf.un - IL_0003: ret -}"); - verifier.VerifyIL("Program.Subtract", -@"{ - // Code size 4 (0x4) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: sub.ovf.un - IL_0003: ret -}"); - verifier.VerifyIL("Program.Multiply", -@"{ - // Code size 4 (0x4) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: mul.ovf.un - IL_0003: ret -}"); - verifier.VerifyIL("Program.Divide", -@"{ - // Code size 4 (0x4) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: div.un - IL_0003: ret -}"); - verifier.VerifyIL("Program.Mod", -@"{ - // Code size 4 (0x4) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: rem.un - IL_0003: ret -}"); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + + CompileAndVerify(comp, expectedOutput: +$@"2147483647 +System.OverflowException +0 +System.OverflowException +2147483647 +{(IntPtr.Size == 4 ? "System.OverflowException" : "2147483648")} +0 +{(IntPtr.Size == 4 ? "System.OverflowException" : "0")}"); + } + + [Fact] + public void UncheckedLeftShift_01() + { + string source = +@"using System; +class Program +{ + static void Main() + { + const nint x = 0x7fffffff; + Report(x << 1); + Report(LeftShift(x, 1)); + } + static nint LeftShift(nint x, int y) => unchecked(x << y); + static void Report(long l) => Console.WriteLine(""{0:x}"", l); +}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + + var expectedValue = IntPtr.Size == 4 ? "fffffffffffffffe" : "fffffffe"; + CompileAndVerify(comp, expectedOutput: +$@"{expectedValue} +{expectedValue}"); } [Fact] - public void ConstantFolding_01() + public void UncheckedLeftShift_02() { - const string intMinValue = "-2147483648"; - const string intMaxValue = "2147483647"; - const string uintMaxValue = "4294967295"; - const string ulongMaxValue = "18446744073709551615"; - - unaryOperator("nint", "+", intMinValue, intMinValue); - unaryOperator("nint", "+", intMaxValue, intMaxValue); - unaryOperator("nuint", "+", "0", "0"); - unaryOperator("nuint", "+", uintMaxValue, uintMaxValue); - - unaryOperator("nint", "-", "-1", "1"); - unaryOperatorCheckedOverflow("nint", "-", intMinValue, IntPtr.Size == 4 ? "-2147483648" : "2147483648", IntPtr.Size == 4 ? "System.OverflowException" : "2147483648"); - unaryOperator("nint", "-", "-2147483647", intMaxValue); - unaryOperator("nint", "-", intMaxValue, "-2147483647"); - unaryOperator("nuint", "-", "0", null, getBadUnaryOpDiagnostics); - unaryOperator("nuint", "-", "1", null, getBadUnaryOpDiagnostics); - unaryOperator("nuint", "-", uintMaxValue, null, getBadUnaryOpDiagnostics); - - unaryOperatorNotConstant("nint", "~", "0", "-1"); - unaryOperatorNotConstant("nint", "~", "-1", "0"); - unaryOperatorNotConstant("nint", "~", intMinValue, "2147483647"); - unaryOperatorNotConstant("nint", "~", intMaxValue, "-2147483648"); - unaryOperatorNotConstant("nuint", "~", "0", IntPtr.Size == 4 ? uintMaxValue : ulongMaxValue); - unaryOperatorNotConstant("nuint", "~", uintMaxValue, IntPtr.Size == 4 ? "0" : "18446744069414584320"); - - binaryOperatorCheckedOverflow("nint", "+", "nint", intMinValue, "nint", "-1", IntPtr.Size == 4 ? "2147483647" : "-2147483649", IntPtr.Size == 4 ? "System.OverflowException" : "-2147483649"); - binaryOperator("nint", "+", "nint", "-2147483647", "nint", "-1", intMinValue); - binaryOperatorCheckedOverflow("nint", "+", "nint", "1", "nint", intMaxValue, IntPtr.Size == 4 ? "-2147483648" : "2147483648", IntPtr.Size == 4 ? "System.OverflowException" : "2147483648"); - binaryOperator("nint", "+", "nint", "1", "nint", "2147483646", intMaxValue); - binaryOperatorCheckedOverflow("nuint", "+", "nuint", "1", "nuint", uintMaxValue, IntPtr.Size == 4 ? "0" : "4294967296", IntPtr.Size == 4 ? "System.OverflowException" : "4294967296"); - binaryOperator("nuint", "+", "nuint", "1", "nuint", "4294967294", uintMaxValue); - - binaryOperatorCheckedOverflow("nint", "-", "nint", intMinValue, "nint", "1", IntPtr.Size == 4 ? "2147483647" : "-2147483649", IntPtr.Size == 4 ? "System.OverflowException" : "-2147483649"); - binaryOperator("nint", "-", "nint", intMinValue, "nint", "-1", "-2147483647"); - binaryOperator("nint", "-", "nint", "-1", "nint", intMaxValue, intMinValue); - binaryOperatorCheckedOverflow("nint", "-", "nint", "-2", "nint", intMaxValue, IntPtr.Size == 4 ? "2147483647" : "-2147483649", IntPtr.Size == 4 ? "System.OverflowException" : "-2147483649"); - binaryOperatorCheckedOverflow("nuint", "-", "nuint", "0", "nuint", "1", IntPtr.Size == 4 ? uintMaxValue : ulongMaxValue, "System.OverflowException"); - binaryOperator("nuint", "-", "nuint", uintMaxValue, "nuint", uintMaxValue, "0"); - - binaryOperatorCheckedOverflow("nint", "*", "nint", intMinValue, "nint", "2", IntPtr.Size == 4 ? "0" : "-4294967296", IntPtr.Size == 4 ? "System.OverflowException" : "-4294967296"); - binaryOperatorCheckedOverflow("nint", "*", "nint", intMinValue, "nint", "-1", IntPtr.Size == 4 ? "-2147483648" : "2147483648", IntPtr.Size == 4 ? "System.OverflowException" : "2147483648"); - binaryOperator("nint", "*", "nint", "-1", "nint", intMaxValue, "-2147483647"); - binaryOperatorCheckedOverflow("nint", "*", "nint", "2", "nint", intMaxValue, IntPtr.Size == 4 ? "-2" : "4294967294", IntPtr.Size == 4 ? "System.OverflowException" : "4294967294"); - binaryOperatorCheckedOverflow("nuint", "*", "nuint", uintMaxValue, "nuint", "2", IntPtr.Size == 4 ? "4294967294" : "8589934590", IntPtr.Size == 4 ? "System.OverflowException" : "8589934590"); - binaryOperator("nuint", "*", "nuint", intMaxValue, "nuint", "2", "4294967294"); - - binaryOperator("nint", "/", "nint", intMinValue, "nint", "1", intMinValue); - binaryOperatorCheckedOverflow("nint", "/", "nint", intMinValue, "nint", "-1", IntPtr.Size == 4 ? "System.OverflowException" : "2147483648", IntPtr.Size == 4 ? "System.OverflowException" : "2147483648"); - binaryOperator("nint", "/", "nint", "1", "nint", "0", null, getIntDivByZeroDiagnostics); - binaryOperator("nint", "/", "nint", "0", "nint", "0", null, getIntDivByZeroDiagnostics); - binaryOperator("nuint", "/", "nuint", uintMaxValue, "nuint", "1", uintMaxValue); - binaryOperator("nuint", "/", "nuint", uintMaxValue, "nuint", "2", intMaxValue); - binaryOperator("nuint", "/", "nuint", "1", "nuint", "0", null, getIntDivByZeroDiagnostics); - binaryOperator("nuint", "/", "nuint", "0", "nuint", "0", null, getIntDivByZeroDiagnostics); - - binaryOperator("nint", "%", "nint", intMinValue, "nint", "2", "0"); - binaryOperator("nint", "%", "nint", intMinValue, "nint", "-2", "0"); - binaryOperatorCheckedOverflow("nint", "%", "nint", intMinValue, "nint", "-1", IntPtr.Size == 4 ? "System.OverflowException" : "0", IntPtr.Size == 4 ? "System.OverflowException" : "0"); - binaryOperator("nint", "%", "nint", "1", "nint", "0", null, getIntDivByZeroDiagnostics); - binaryOperator("nint", "%", "nint", "0", "nint", "0", null, getIntDivByZeroDiagnostics); - binaryOperator("nuint", "%", "nuint", uintMaxValue, "nuint", "1", "0"); - binaryOperator("nuint", "%", "nuint", uintMaxValue, "nuint", "2", "1"); - binaryOperator("nuint", "%", "nuint", "1", "nuint", "0", null, getIntDivByZeroDiagnostics); - binaryOperator("nuint", "%", "nuint", "0", "nuint", "0", null, getIntDivByZeroDiagnostics); - - binaryOperator("bool", "<", "nint", intMinValue, "nint", intMinValue, "False"); - binaryOperator("bool", "<", "nint", intMinValue, "nint", intMaxValue, "True"); - binaryOperator("bool", "<", "nint", intMaxValue, "nint", intMaxValue, "False"); - binaryOperator("bool", "<", "nuint", "0", "nuint", "0", "False"); - binaryOperator("bool", "<", "nuint", "0", "nuint", uintMaxValue, "True"); - binaryOperator("bool", "<", "nuint", uintMaxValue, "nuint", uintMaxValue, "False"); - - binaryOperator("bool", "<=", "nint", intMinValue, "nint", intMinValue, "True"); - binaryOperator("bool", "<=", "nint", intMaxValue, "nint", intMinValue, "False"); - binaryOperator("bool", "<=", "nint", intMaxValue, "nint", intMaxValue, "True"); - binaryOperator("bool", "<=", "nuint", "0", "nuint", "0", "True"); - binaryOperator("bool", "<=", "nuint", uintMaxValue, "nuint", "0", "False"); - binaryOperator("bool", "<=", "nuint", uintMaxValue, "nuint", uintMaxValue, "True"); - - binaryOperator("bool", ">", "nint", intMinValue, "nint", intMinValue, "False"); - binaryOperator("bool", ">", "nint", intMaxValue, "nint", intMinValue, "True"); - binaryOperator("bool", ">", "nint", intMaxValue, "nint", intMaxValue, "False"); - binaryOperator("bool", ">", "nuint", "0", "nuint", "0", "False"); - binaryOperator("bool", ">", "nuint", uintMaxValue, "nuint", "0", "True"); - binaryOperator("bool", ">", "nuint", uintMaxValue, "nuint", uintMaxValue, "False"); - - binaryOperator("bool", ">=", "nint", intMinValue, "nint", intMinValue, "True"); - binaryOperator("bool", ">=", "nint", intMinValue, "nint", intMaxValue, "False"); - binaryOperator("bool", ">=", "nint", intMaxValue, "nint", intMaxValue, "True"); - binaryOperator("bool", ">=", "nuint", "0", "nuint", "0", "True"); - binaryOperator("bool", ">=", "nuint", "0", "nuint", uintMaxValue, "False"); - binaryOperator("bool", ">=", "nuint", uintMaxValue, "nuint", uintMaxValue, "True"); - - binaryOperator("bool", "==", "nint", intMinValue, "nint", intMinValue, "True"); - binaryOperator("bool", "==", "nint", intMinValue, "nint", intMaxValue, "False"); - binaryOperator("bool", "==", "nint", intMaxValue, "nint", intMaxValue, "True"); - binaryOperator("bool", "==", "nuint", "0", "nuint", "0", "True"); - binaryOperator("bool", "==", "nuint", "0", "nuint", uintMaxValue, "False"); - binaryOperator("bool", "==", "nuint", uintMaxValue, "nuint", uintMaxValue, "True"); - - binaryOperator("bool", "!=", "nint", intMinValue, "nint", intMinValue, "False"); - binaryOperator("bool", "!=", "nint", intMinValue, "nint", intMaxValue, "True"); - binaryOperator("bool", "!=", "nint", intMaxValue, "nint", intMaxValue, "False"); - binaryOperator("bool", "!=", "nuint", "0", "nuint", "0", "False"); - binaryOperator("bool", "!=", "nuint", "0", "nuint", uintMaxValue, "True"); - binaryOperator("bool", "!=", "nuint", uintMaxValue, "nuint", uintMaxValue, "False"); - - binaryOperator("nint", "<<", "nint", intMinValue, "int", "0", intMinValue); - binaryOperatorNotConstant("nint", "<<", "nint", intMinValue, "int", "1", IntPtr.Size == 4 ? "0" : "-4294967296"); - binaryOperator("nint", "<<", "nint", "-1", "int", "31", intMinValue); - binaryOperatorNotConstant("nint", "<<", "nint", "-1", "int", "32", IntPtr.Size == 4 ? "-1" : "-4294967296"); - binaryOperator("nuint", "<<", "nuint", "0", "int", "1", "0"); - binaryOperatorNotConstant("nuint", "<<", "nuint", uintMaxValue, "int", "1", IntPtr.Size == 4 ? "4294967294" : "8589934590"); - binaryOperator("nuint", "<<", "nuint", "1", "int", "31", "2147483648"); - binaryOperatorNotConstant("nuint", "<<", "nuint", "1", "int", "32", IntPtr.Size == 4 ? "1" : "4294967296"); - - binaryOperator("nint", ">>", "nint", intMinValue, "int", "0", intMinValue); - binaryOperator("nint", ">>", "nint", intMinValue, "int", "1", "-1073741824"); - binaryOperator("nint", ">>", "nint", "-1", "int", "31", "-1"); - binaryOperator("nint", ">>", "nint", "-1", "int", "32", "-1"); - binaryOperator("nuint", ">>", "nuint", "0", "int", "1", "0"); - binaryOperator("nuint", ">>", "nuint", uintMaxValue, "int", "1", intMaxValue); - binaryOperator("nuint", ">>", "nuint", "1", "int", "31", "0"); - binaryOperator("nuint", ">>", "nuint", "1", "int", "32", "1"); - - binaryOperator("nint", "&", "nint", intMinValue, "nint", "0", "0"); - binaryOperator("nint", "&", "nint", intMinValue, "nint", "-1", intMinValue); - binaryOperator("nint", "&", "nint", intMinValue, "nint", intMaxValue, "0"); - binaryOperator("nuint", "&", "nuint", "0", "nuint", uintMaxValue, "0"); - binaryOperator("nuint", "&", "nuint", intMaxValue, "nuint", uintMaxValue, intMaxValue); - binaryOperator("nuint", "&", "nuint", intMaxValue, "nuint", "2147483648", "0"); - - binaryOperator("nint", "|", "nint", intMinValue, "nint", "0", intMinValue); - binaryOperator("nint", "|", "nint", intMinValue, "nint", "-1", "-1"); - binaryOperator("nint", "|", "nint", intMaxValue, "nint", intMaxValue, intMaxValue); - binaryOperator("nuint", "|", "nuint", "0", "nuint", uintMaxValue, uintMaxValue); - binaryOperator("nuint", "|", "nuint", intMaxValue, "nuint", intMaxValue, intMaxValue); - binaryOperator("nuint", "|", "nuint", intMaxValue, "nuint", "2147483648", uintMaxValue); - - binaryOperator("nint", "^", "nint", intMinValue, "nint", "0", intMinValue); - binaryOperator("nint", "^", "nint", intMinValue, "nint", "-1", intMaxValue); - binaryOperator("nint", "^", "nint", intMaxValue, "nint", intMaxValue, "0"); - binaryOperator("nuint", "^", "nuint", "0", "nuint", uintMaxValue, uintMaxValue); - binaryOperator("nuint", "^", "nuint", intMaxValue, "nuint", intMaxValue, "0"); - binaryOperator("nuint", "^", "nuint", intMaxValue, "nuint", "2147483648", uintMaxValue); - - static DiagnosticDescription[] getNoDiagnostics(string opType, string op, string operand) => Array.Empty(); - static DiagnosticDescription[] getBadUnaryOpDiagnostics(string opType, string op, string operand) => new[] { Diagnostic(ErrorCode.ERR_BadUnaryOp, operand).WithArguments(op, opType) }; - - static DiagnosticDescription[] getIntDivByZeroDiagnostics(string opType, string op, string operand) => new[] { Diagnostic(ErrorCode.ERR_IntDivByZero, operand) }; - - void unaryOperator(string opType, string op, string operand, string expectedResult, Func getDiagnostics = null) - { - getDiagnostics ??= getNoDiagnostics; + string source = +@"using System; +class Program +{ + static void Main() + { + const nuint x = 0xffffffff; + Report(x << 1); + Report(LeftShift(x, 1)); + } + static nuint LeftShift(nuint x, int y) => unchecked(x << y); + static void Report(ulong u) => Console.WriteLine(""{0:x}"", u); +}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - var declarations = $"const {opType} A = {operand};"; - var expr = $"{op}A"; - var diagnostics = getDiagnostics(opType, op, expr); - constantDeclaration(opType, declarations, expr, expectedResult, diagnostics); - constantDeclaration(opType, declarations, $"checked({expr})", expectedResult, diagnostics); - constantDeclaration(opType, declarations, $"unchecked({expr})", expectedResult, diagnostics); + var expectedValue = IntPtr.Size == 4 ? "fffffffe" : "1fffffffe"; + CompileAndVerify(comp, expectedOutput: +$@"{expectedValue} +{expectedValue}"); + } - expr = $"{op}({opType})({operand})"; - diagnostics = getDiagnostics(opType, op, expr); - constantExpression(opType, expr, expectedResult, diagnostics); - constantExpression(opType, $"checked({expr})", expectedResult, diagnostics); - constantExpression(opType, $"unchecked({expr})", expectedResult, diagnostics); - } + [Fact] + public void ExplicitImplementationReturnTypeDifferences() + { + string source = +@"struct S +{ +} +interface I +{ + S F1(); + S F2(); + S F3(); + S F4(); +} +class C : I +{ + S I.F1() => default; + S I.F2() => default; + S I.F3() => default; + S I.F4() => default; +}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - void unaryOperatorCheckedOverflow(string opType, string op, string operand, string expectedResultUnchecked, string expectedResultChecked) - { - var declarations = $"const {opType} A = {operand};"; - var expr = $"{op}A"; - constantDeclaration(opType, declarations, expr, null, - new[] { - Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(opType), - Diagnostic(ErrorCode.ERR_NotConstantExpression, expr).WithArguments("Library.F") - }); - constantDeclaration(opType, declarations, $"checked({expr})", null, - new[] { - Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(opType), - Diagnostic(ErrorCode.ERR_NotConstantExpression, $"checked({expr})").WithArguments("Library.F") - }); - constantDeclaration(opType, declarations, $"unchecked({expr})", null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, $"unchecked({expr})").WithArguments("Library.F") }); + comp.VerifyEmitDiagnostics(); - expr = $"{op}({opType})({operand})"; - constantExpression(opType, expr, expectedResultUnchecked, new[] { Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(opType) }); - constantExpression(opType, $"checked({expr})", expectedResultChecked, new[] { Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(opType) }); - constantExpression(opType, $"unchecked({expr})", expectedResultUnchecked, Array.Empty()); - } + var type = comp.GetTypeByMetadataName("I"); + Assert.Equal("S I.F1()", type.GetMember("F1").ToTestDisplayString()); + Assert.Equal("S I.F2()", type.GetMember("F2").ToTestDisplayString()); + Assert.Equal("S I.F3()", type.GetMember("F3").ToTestDisplayString()); + Assert.Equal("S I.F4()", type.GetMember("F4").ToTestDisplayString()); - void unaryOperatorNotConstant(string opType, string op, string operand, string expectedResult) - { - var declarations = $"const {opType} A = {operand};"; - var expr = $"{op}A"; - constantDeclaration(opType, declarations, expr, null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, expr).WithArguments("Library.F") }); - constantDeclaration(opType, declarations, $"checked({expr})", null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, $"checked({expr})").WithArguments("Library.F") }); - constantDeclaration(opType, declarations, $"unchecked({expr})", null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, $"unchecked({expr})").WithArguments("Library.F") }); + type = comp.GetTypeByMetadataName("C"); + Assert.Equal("S C.I.F1()", type.GetMember("I.F1").ToTestDisplayString()); + Assert.Equal("S C.I.F2()", type.GetMember("I.F2").ToTestDisplayString()); + Assert.Equal("S C.I.F3()", type.GetMember("I.F3").ToTestDisplayString()); + Assert.Equal("S C.I.F4()", type.GetMember("I.F4").ToTestDisplayString()); + } - expr = $"{op}({opType})({operand})"; - constantExpression(opType, expr, expectedResult, Array.Empty()); - constantExpression(opType, $"checked({expr})", expectedResult, Array.Empty()); - constantExpression(opType, $"unchecked({expr})", expectedResult, Array.Empty()); - } + [Fact] + public void OverrideReturnTypeDifferences() + { + string source = +@"class A +{ + public virtual nint[] F1() => null; + public virtual System.IntPtr[] F2() => null; + public virtual nint[] F3() => null; + public virtual System.IntPtr[] F4() => null; +} +class B : A +{ + public override System.IntPtr[] F1() => null; + public override nint[] F2() => null; + public override nint[] F3() => null; + public override System.IntPtr[] F4() => null; +}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyEmitDiagnostics(); - void binaryOperator(string opType, string op, string leftType, string leftOperand, string rightType, string rightOperand, string expectedResult, Func getDiagnostics = null) - { - getDiagnostics ??= getNoDiagnostics; + var type = comp.GetTypeByMetadataName("A"); + Assert.Equal("nint[] A.F1()", type.GetMember("F1").ToTestDisplayString()); + Assert.Equal("nint[] A.F2()", type.GetMember("F2").ToTestDisplayString()); + Assert.Equal("nint[] A.F3()", type.GetMember("F3").ToTestDisplayString()); + Assert.Equal("nint[] A.F4()", type.GetMember("F4").ToTestDisplayString()); - var declarations = $"const {leftType} A = {leftOperand}; const {rightType} B = {rightOperand};"; - var expr = $"A {op} B"; - var diagnostics = getDiagnostics(opType, op, expr); - constantDeclaration(opType, declarations, expr, expectedResult, diagnostics); - constantDeclaration(opType, declarations, $"checked({expr})", expectedResult, diagnostics); - constantDeclaration(opType, declarations, $"unchecked({expr})", expectedResult, diagnostics); + type = comp.GetTypeByMetadataName("B"); + Assert.Equal("nint[] B.F1()", type.GetMember("F1").ToTestDisplayString()); + Assert.Equal("nint[] B.F2()", type.GetMember("F2").ToTestDisplayString()); + Assert.Equal("nint[] B.F3()", type.GetMember("F3").ToTestDisplayString()); + Assert.Equal("nint[] B.F4()", type.GetMember("F4").ToTestDisplayString()); + } - expr = $"(({leftType})({leftOperand})) {op} (({rightType})({rightOperand}))"; - diagnostics = getDiagnostics(opType, op, expr); - constantExpression(opType, expr, expectedResult, diagnostics); - constantExpression(opType, $"checked({expr})", expectedResult, diagnostics); - constantExpression(opType, $"unchecked({expr})", expectedResult, diagnostics); - } + [Fact] + public void Int64Conversions() + { + convert(fromType: "nint", toType: "ulong", "int.MinValue", "18446744071562067968", "conv.i8", "System.OverflowException", "conv.ovf.u8"); + convert(fromType: "nint", toType: "ulong", "int.MaxValue", "2147483647", "conv.i8", "2147483647", "conv.ovf.u8"); + convert(fromType: "nint", toType: "nuint", "int.MinValue", IntPtr.Size == 4 ? "2147483648" : "18446744071562067968", "conv.u", "System.OverflowException", "conv.ovf.u"); + convert(fromType: "nint", toType: "nuint", "int.MaxValue", "2147483647", "conv.u", "2147483647", "conv.ovf.u"); - void binaryOperatorCheckedOverflow(string opType, string op, string leftType, string leftOperand, string rightType, string rightOperand, string expectedResultUnchecked, string expectedResultChecked) - { - var declarations = $"const {leftType} A = {leftOperand}; const {rightType} B = {rightOperand};"; - var expr = $"A {op} B"; - constantDeclaration(opType, declarations, expr, null, - new[] { - Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(opType), - Diagnostic(ErrorCode.ERR_NotConstantExpression, expr).WithArguments("Library.F") - }); - constantDeclaration(opType, declarations, $"checked({expr})", null, - new[] { - Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(opType), - Diagnostic(ErrorCode.ERR_NotConstantExpression, $"checked({expr})").WithArguments("Library.F") - }); - constantDeclaration(opType, declarations, $"unchecked({expr})", null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, $"unchecked({expr})").WithArguments("Library.F") }); + convert(fromType: "nuint", toType: "long", "uint.MaxValue", "4294967295", "conv.u8", "4294967295", "conv.ovf.i8.un"); + convert(fromType: "nuint", toType: "nint", "uint.MaxValue", IntPtr.Size == 4 ? "-1" : "4294967295", "conv.i", IntPtr.Size == 4 ? "System.OverflowException" : "4294967295", "conv.ovf.i.un"); - expr = $"(({leftType})({leftOperand})) {op} (({rightType})({rightOperand}))"; - constantExpression(opType, expr, expectedResultUnchecked, new[] { Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(opType) }); - constantExpression(opType, $"checked({expr})", expectedResultChecked, new[] { Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, expr).WithArguments(opType) }); - constantExpression(opType, $"unchecked({expr})", expectedResultUnchecked, Array.Empty()); - } + string nintMinValue = IntPtr.Size == 4 ? int.MinValue.ToString() : long.MinValue.ToString(); + string nintMaxValue = IntPtr.Size == 4 ? int.MaxValue.ToString() : long.MaxValue.ToString(); + string nuintMaxValue = IntPtr.Size == 4 ? uint.MaxValue.ToString() : ulong.MaxValue.ToString(); - void binaryOperatorNotConstant(string opType, string op, string leftType, string leftOperand, string rightType, string rightOperand, string expectedResult) - { - var declarations = $"const {leftType} A = {leftOperand}; const {rightType} B = {rightOperand};"; - var expr = $"A {op} B"; - constantDeclaration(opType, declarations, expr, null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, expr).WithArguments("Library.F") }); - constantDeclaration(opType, declarations, $"checked({expr})", null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, $"checked({expr})").WithArguments("Library.F") }); - constantDeclaration(opType, declarations, $"unchecked({expr})", null, new[] { Diagnostic(ErrorCode.ERR_NotConstantExpression, $"unchecked({expr})").WithArguments("Library.F") }); + convert(fromType: "nint", toType: "ulong", nintMinValue, IntPtr.Size == 4 ? "18446744071562067968" : "9223372036854775808", "conv.i8", "System.OverflowException", "conv.ovf.u8"); + convert(fromType: "nint", toType: "ulong", nintMaxValue, IntPtr.Size == 4 ? "2147483647" : "9223372036854775807", "conv.i8", IntPtr.Size == 4 ? "2147483647" : "9223372036854775807", "conv.ovf.u8"); + convert(fromType: "nint", toType: "nuint", nintMinValue, IntPtr.Size == 4 ? "2147483648" : "9223372036854775808", "conv.u", "System.OverflowException", "conv.ovf.u"); + convert(fromType: "nint", toType: "nuint", nintMaxValue, IntPtr.Size == 4 ? "2147483647" : "9223372036854775807", "conv.u", IntPtr.Size == 4 ? "2147483647" : "9223372036854775807", "conv.ovf.u"); - expr = $"(({leftType})({leftOperand})) {op} (({rightType})({rightOperand}))"; - constantExpression(opType, expr, expectedResult, Array.Empty()); - constantExpression(opType, $"checked({expr})", expectedResult, Array.Empty()); - constantExpression(opType, $"unchecked({expr})", expectedResult, Array.Empty()); - } + convert(fromType: "nuint", toType: "long", nuintMaxValue, IntPtr.Size == 4 ? "4294967295" : "-1", "conv.u8", IntPtr.Size == 4 ? "4294967295" : "System.OverflowException", "conv.ovf.i8.un"); + convert(fromType: "nuint", toType: "nint", nuintMaxValue, "-1", "conv.i", "System.OverflowException", "conv.ovf.i.un"); - void constantDeclaration(string opType, string declarations, string expr, string expectedResult, DiagnosticDescription[] expectedDiagnostics) + void convert(string fromType, string toType, string fromValue, string toValueUnchecked, string toConvUnchecked, string toValueChecked, string toConvChecked) { - string sourceA = -$@"public class Library + string source = +$@"using System; +class Program {{ - {declarations} - public const {opType} F = {expr}; + static {toType} Convert({fromType} value) => ({toType})(value); + static {toType} ConvertChecked({fromType} value) => checked(({toType})(value)); + static object Execute(Func f) + {{ + try + {{ + return f(); + }} + catch (Exception e) + {{ + return e.GetType().FullName; + }} + }} + static void Main() + {{ + {fromType} value = ({fromType})({fromValue}); + Console.WriteLine(Execute(() => Convert(value))); + Console.WriteLine(Execute(() => ConvertChecked(value))); + }} }}"; - var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(expectedDiagnostics); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.UnsafeReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - if (expectedDiagnostics.Any(d => ErrorFacts.GetSeverity((ErrorCode)d.Code) == DiagnosticSeverity.Error)) - { - Assert.Null(expectedResult); - return; - } + var verifier = CompileAndVerify(comp, expectedOutput: +$@"{toValueUnchecked} +{toValueChecked}"); - string sourceB = -@"class Program -{ - static void Main() - { - System.Console.WriteLine(Library.F); - } -}"; - var refA = comp.EmitToImageReference(); - comp = CreateCompilation(sourceB, references: new[] { refA }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - CompileAndVerify(comp, expectedOutput: expectedResult); - Assert.NotNull(expectedResult); + verifier.VerifyIL("Program.Convert", +$@"{{ + // Code size 3 (0x3) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: {toConvUnchecked} + IL_0002: ret +}}"); + verifier.VerifyIL("Program.ConvertChecked", +$@"{{ + // Code size 3 (0x3) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: {toConvChecked} + IL_0002: ret +}}"); } + } - void constantExpression(string opType, string expr, string expectedResult, DiagnosticDescription[] expectedDiagnostics) - { - string source = + [Theory] + [InlineData("void*")] + [InlineData("byte*")] + [InlineData("delegate*")] + public void PointerConversions(string pointerType) + { + string source = $@"using System; -class Program +unsafe class Program {{ - static void Main() + static {pointerType} ToPointer1(nint i) => ({pointerType})i; + static {pointerType} ToPointer2(nuint u) => ({pointerType})u; + static {pointerType} ToPointer3(nint i) => checked(({pointerType})i); + static {pointerType} ToPointer4(nuint u) => checked(({pointerType})u); + static nint FromPointer1({pointerType} p) => (nint)p; + static nuint FromPointer2({pointerType} p) => (nuint)p; + static nint FromPointer3({pointerType} p) => checked((nint)p); + static nuint FromPointer4({pointerType} p) => checked((nuint)p); + static object Execute(Func f) {{ - object result; try {{ - {opType} value = {expr}; - result = value; + return f(); }} catch (Exception e) {{ - result = e.GetType().FullName; + return e.GetType().FullName; }} - Console.WriteLine(result); }} -}}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - - if (expectedDiagnostics.Any(d => ErrorFacts.GetSeverity((ErrorCode)d.Code) == DiagnosticSeverity.Error)) - { - comp.VerifyDiagnostics(expectedDiagnostics); - Assert.Null(expectedResult); - return; - } - - CompileAndVerify(comp, expectedOutput: expectedResult).VerifyDiagnostics(expectedDiagnostics); - Assert.NotNull(expectedResult); - } - } - - [Fact] - [WorkItem(51714, "https://github.com/dotnet/roslyn/issues/51714")] - public void ConstantFolding_02() - { - var source = -@" -class Program -{ - static void Main() - { - const nuint x = unchecked(uint.MaxValue + (nuint)42); - const nuint y = checked(uint.MaxValue + (nuint)42); - } -}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe); - comp.VerifyDiagnostics( - // (6,25): error CS0133: The expression being assigned to 'x' must be constant - // const nuint x = unchecked(uint.MaxValue + (nuint)42); - Diagnostic(ErrorCode.ERR_NotConstantExpression, "unchecked(uint.MaxValue + (nuint)42)").WithArguments("x").WithLocation(6, 25), - // (7,25): error CS0133: The expression being assigned to 'y' must be constant - // const nuint y = checked(uint.MaxValue + (nuint)42); - Diagnostic(ErrorCode.ERR_NotConstantExpression, "checked(uint.MaxValue + (nuint)42)").WithArguments("y").WithLocation(7, 25), - // (7,33): warning CS8973: The operation may overflow 'nuint' at runtime (use 'unchecked' syntax to override) - // const nuint y = checked(uint.MaxValue + (nuint)42); - Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, "uint.MaxValue + (nuint)42").WithArguments("nuint").WithLocation(7, 33) - ); - - source = -@" -class Program -{ - static void Main() - { - try - { - var y = checked(uint.MaxValue + (nuint)42); - System.Console.WriteLine(y); - } - catch (System.Exception e) - { - System.Console.WriteLine(e.GetType()); - } - } -}"; - comp = CreateCompilation(source, options: TestOptions.ReleaseExe); - CompileAndVerify(comp, expectedOutput: IntPtr.Size == 4 ? "System.OverflowException" : "4294967337").VerifyDiagnostics( - // (8,29): warning CS8973: The operation may overflow 'nuint' at runtime (use 'unchecked' syntax to override) - // var y = checked(uint.MaxValue + (nuint)42); - Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, "uint.MaxValue + (nuint)42").WithArguments("nuint").WithLocation(8, 29) - ); - - source = -@" -class Program -{ - static void Main() - { - var y = unchecked(uint.MaxValue + (nuint)42); - System.Console.WriteLine(y); - } -}"; - comp = CreateCompilation(source, options: TestOptions.ReleaseExe); - CompileAndVerify(comp, expectedOutput: IntPtr.Size == 4 ? "41" : "4294967337").VerifyDiagnostics(); - } - - [Fact] - [WorkItem(51714, "https://github.com/dotnet/roslyn/issues/51714")] - public void ConstantFolding_03() - { - var source = -@" -class Program -{ - static void Main() - { - const nint x = unchecked(-(nint)int.MinValue); - const nint y = checked(-(nint)int.MinValue); - } -}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe); - comp.VerifyDiagnostics( - // (6,24): error CS0133: The expression being assigned to 'x' must be constant - // const nint x = unchecked(-(nint)int.MinValue); - Diagnostic(ErrorCode.ERR_NotConstantExpression, "unchecked(-(nint)int.MinValue)").WithArguments("x").WithLocation(6, 24), - // (7,24): error CS0133: The expression being assigned to 'y' must be constant - // const nint y = checked(-(nint)int.MinValue); - Diagnostic(ErrorCode.ERR_NotConstantExpression, "checked(-(nint)int.MinValue)").WithArguments("y").WithLocation(7, 24), - // (7,32): warning CS8973: The operation may overflow 'nint' at runtime (use 'unchecked' syntax to override) - // const nint y = checked(-(nint)int.MinValue); - Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, "-(nint)int.MinValue").WithArguments("nint").WithLocation(7, 32) - ); - - source = -@" -class Program -{ - static void Main() - { - try - { - var y = checked(-(nint)int.MinValue); - System.Console.WriteLine(y); - } - catch (System.Exception e) - { - System.Console.WriteLine(e.GetType()); - } - } -}"; - comp = CreateCompilation(source, options: TestOptions.ReleaseExe); - CompileAndVerify(comp, expectedOutput: IntPtr.Size == 4 ? "System.OverflowException" : "2147483648").VerifyDiagnostics( - // (8,29): warning CS8973: The operation may overflow 'nint' at runtime (use 'unchecked' syntax to override) - // var y = checked(-(nint)int.MinValue); - Diagnostic(ErrorCode.WRN_CompileTimeCheckedOverflow, "-(nint)int.MinValue").WithArguments("nint").WithLocation(8, 29) - ); - - source = -@" -class Program -{ + static void Execute({pointerType} p) + {{ + Console.WriteLine((int)p); + Console.WriteLine(Execute(() => FromPointer1(p))); + Console.WriteLine(Execute(() => FromPointer2(p))); + Console.WriteLine(Execute(() => FromPointer3(p))); + Console.WriteLine(Execute(() => FromPointer4(p))); + }} static void Main() - { - var y = unchecked(-(nint)int.MinValue); - System.Console.WriteLine(y); - } -}"; - comp = CreateCompilation(source, options: TestOptions.ReleaseExe); - CompileAndVerify(comp, expectedOutput: IntPtr.Size == 4 ? "-2147483648" : "2147483648").VerifyDiagnostics(); + {{ + Execute(ToPointer1(-42)); + Execute(ToPointer2(42)); + Execute(ToPointer1(int.MinValue)); + Execute(ToPointer2(uint.MaxValue)); + Console.WriteLine(Execute(() => (ulong)ToPointer3(-42))); + Console.WriteLine(Execute(() => (ulong)ToPointer4(42))); + Console.WriteLine(Execute(() => (ulong)ToPointer3(int.MinValue))); + Console.WriteLine(Execute(() => (ulong)ToPointer4(uint.MaxValue))); + }} +}}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.UnsafeReleaseExe, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + string expectedOutput = +$@"-42 +-42 +{(IntPtr.Size == 4 ? "4294967254" : "18446744073709551574")} +System.OverflowException +{(IntPtr.Size == 4 ? "4294967254" : "18446744073709551574")} +42 +42 +42 +42 +42 +-2147483648 +-2147483648 +{(IntPtr.Size == 4 ? "2147483648" : "18446744071562067968")} +System.OverflowException +{(IntPtr.Size == 4 ? "2147483648" : "18446744071562067968")} +-1 +{(IntPtr.Size == 4 ? "-1" : "4294967295")} +4294967295 +{(IntPtr.Size == 4 ? "System.OverflowException" : "4294967295")} +4294967295 +System.OverflowException +42 +System.OverflowException +4294967295"; + var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: expectedOutput); + verifier.VerifyIL("Program.ToPointer1", +@"{ + // Code size 2 (0x2) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ret +}"); + verifier.VerifyIL("Program.ToPointer2", +@"{ + // Code size 2 (0x2) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ret +}"); + verifier.VerifyIL("Program.ToPointer3", +@"{ + // Code size 3 (0x3) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: conv.ovf.u + IL_0002: ret +}"); + verifier.VerifyIL("Program.ToPointer4", +@"{ + // Code size 2 (0x2) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ret +}"); + verifier.VerifyIL("Program.FromPointer1", +@"{ + // Code size 2 (0x2) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ret +}"); + verifier.VerifyIL("Program.FromPointer2", +@"{ + // Code size 2 (0x2) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ret +}"); + verifier.VerifyIL("Program.FromPointer3", +@"{ + // Code size 3 (0x3) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: conv.ovf.i.un + IL_0002: ret +}"); + verifier.VerifyIL("Program.FromPointer4", +@"{ + // Code size 2 (0x2) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ret +}"); } - // OverflowException behavior is consistent with unchecked int division. - [Fact] - public void UncheckedIntegerDivision() + [Theory] + [InlineData(null)] + [InlineData("sbyte")] + [InlineData("byte")] + [InlineData("short")] + [InlineData("ushort")] + [InlineData("int")] + [InlineData("uint")] + [InlineData("long")] + [InlineData("ulong")] + public void EnumConversions_01(string baseType) { - string source = -@"using System; + if (baseType != null) baseType = " : " + baseType; + string sourceA = +$@"enum E{baseType} {{ A = 0, B = 1 }}"; + + string sourceB = +@"#pragma warning disable 219 class Program { - static void Main() + static void F1() { - Console.WriteLine(Execute(() => IntDivision(int.MinValue + 1, -1))); - Console.WriteLine(Execute(() => IntDivision(int.MinValue, -1))); - Console.WriteLine(Execute(() => IntRemainder(int.MinValue + 1, -1))); - Console.WriteLine(Execute(() => IntRemainder(int.MinValue, -1))); - Console.WriteLine(Execute(() => NativeIntDivision(int.MinValue + 1, -1))); - Console.WriteLine(Execute(() => NativeIntDivision(int.MinValue, -1))); - Console.WriteLine(Execute(() => NativeIntRemainder(int.MinValue + 1, -1))); - Console.WriteLine(Execute(() => NativeIntRemainder(int.MinValue, -1))); + E e; + const nint i0 = 0; + const nint i1 = 1; + e = i0; + e = i1; } - static object Execute(Func f) + static void F2() { - try - { - return f(); - } - catch (Exception e) - { - return e.GetType().FullName; - } - } - static int IntDivision(int x, int y) => unchecked(x / y); - static int IntRemainder(int x, int y) => unchecked(x % y); - static nint NativeIntDivision(nint x, nint y) => unchecked(x / y); - static nint NativeIntRemainder(nint x, nint y) => unchecked(x % y); -}"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - CompileAndVerify(comp, expectedOutput: -$@"2147483647 -System.OverflowException -0 -System.OverflowException -2147483647 -{(IntPtr.Size == 4 ? "System.OverflowException" : "2147483648")} -0 -{(IntPtr.Size == 4 ? "System.OverflowException" : "0")}"); + E e; + const nuint u0 = 0; + const nuint u1 = 1; + e = u0; + e = u1; } - - [WorkItem(42460, "https://github.com/dotnet/roslyn/issues/42460")] - [Fact] - public void UncheckedLeftShift_01() + static void F3() { - string source = -@"using System; -class Program -{ - static void Main() + nint i; + i = default(E); + i = E.A; + i = E.B; + } + static void F4() { - const nint x = 0x7fffffff; - Report(x << 1); - Report(LeftShift(x, 1)); + nuint u; + u = default(E); + u = E.A; + u = E.B; } - static nint LeftShift(nint x, int y) => unchecked(x << y); - static void Report(long l) => Console.WriteLine(""{0:x}"", l); }"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - var expectedValue = IntPtr.Size == 4 ? "fffffffffffffffe" : "fffffffe"; - CompileAndVerify(comp, expectedOutput: -$@"{expectedValue} -{expectedValue}"); + var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics( + // (10,13): error CS0266: Cannot implicitly convert type 'nint' to 'E'. An explicit conversion exists (are you missing a cast?) + // e = i1; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "i1").WithArguments("nint", "E").WithLocation(10, 13), + // (18,13): error CS0266: Cannot implicitly convert type 'nuint' to 'E'. An explicit conversion exists (are you missing a cast?) + // e = u1; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "u1").WithArguments("nuint", "E").WithLocation(18, 13), + // (23,13): error CS0266: Cannot implicitly convert type 'E' to 'nint'. An explicit conversion exists (are you missing a cast?) + // i = default(E); + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "default(E)").WithArguments("E", "nint").WithLocation(23, 13), + // (24,13): error CS0266: Cannot implicitly convert type 'E' to 'nint'. An explicit conversion exists (are you missing a cast?) + // i = E.A; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "E.A").WithArguments("E", "nint").WithLocation(24, 13), + // (25,13): error CS0266: Cannot implicitly convert type 'E' to 'nint'. An explicit conversion exists (are you missing a cast?) + // i = E.B; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "E.B").WithArguments("E", "nint").WithLocation(25, 13), + // (30,13): error CS0266: Cannot implicitly convert type 'E' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // u = default(E); + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "default(E)").WithArguments("E", "nuint").WithLocation(30, 13), + // (31,13): error CS0266: Cannot implicitly convert type 'E' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // u = E.A; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "E.A").WithArguments("E", "nuint").WithLocation(31, 13), + // (32,13): error CS0266: Cannot implicitly convert type 'E' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // u = E.B; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "E.B").WithArguments("E", "nuint").WithLocation(32, 13)); } - [WorkItem(42460, "https://github.com/dotnet/roslyn/issues/42460")] - [Fact] - public void UncheckedLeftShift_02() + [Theory] + [InlineData(null)] + [InlineData("sbyte")] + [InlineData("short")] + [InlineData("int")] + [InlineData("long")] + public void EnumConversions_02(string baseType) { - string source = -@"using System; + if (baseType != null) baseType = " : " + baseType; + string sourceA = +$@"enum E{baseType} {{ A = -1, B = 1 }}"; + + string sourceB = +@"using static System.Console; class Program { + static E F1(nint i) => (E)i; + static E F2(nuint u) => (E)u; + static nint F3(E e) => (nint)e; + static nuint F4(E e) => (nuint)e; static void Main() { - const nuint x = 0xffffffff; - Report(x << 1); - Report(LeftShift(x, 1)); + WriteLine(F1(-1)); + WriteLine(F2(1)); + WriteLine(F3(E.A)); + WriteLine(F4(E.B)); } - static nuint LeftShift(nuint x, int y) => unchecked(x << y); - static void Report(ulong u) => Console.WriteLine(""{0:x}"", u); }"; - var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9); - var expectedValue = IntPtr.Size == 4 ? "fffffffe" : "1fffffffe"; + var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; CompileAndVerify(comp, expectedOutput: -$@"{expectedValue} -{expectedValue}"); - } - - [WorkItem(42500, "https://github.com/dotnet/roslyn/issues/42500")] - [Fact] - public void ExplicitImplementationReturnTypeDifferences() - { - string source = -@"struct S -{ -} -interface I -{ - S F1(); - S F2(); - S F3(); - S F4(); -} -class C : I -{ - S I.F1() => default; - S I.F2() => default; - S I.F3() => default; - S I.F4() => default; -}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(); - - var type = comp.GetTypeByMetadataName("I"); - Assert.Equal("S I.F1()", type.GetMember("F1").ToTestDisplayString()); - Assert.Equal("S I.F2()", type.GetMember("F2").ToTestDisplayString()); - Assert.Equal("S I.F3()", type.GetMember("F3").ToTestDisplayString()); - Assert.Equal("S I.F4()", type.GetMember("F4").ToTestDisplayString()); - - type = comp.GetTypeByMetadataName("C"); - Assert.Equal("S C.I.F1()", type.GetMember("I.F1").ToTestDisplayString()); - Assert.Equal("S C.I.F2()", type.GetMember("I.F2").ToTestDisplayString()); - Assert.Equal("S C.I.F3()", type.GetMember("I.F3").ToTestDisplayString()); - Assert.Equal("S C.I.F4()", type.GetMember("I.F4").ToTestDisplayString()); - } - - [WorkItem(42500, "https://github.com/dotnet/roslyn/issues/42500")] - [WorkItem(44358, "https://github.com/dotnet/roslyn/issues/44358")] - [Fact] - public void OverrideReturnTypeDifferences() - { - string source = -@"class A -{ - public virtual nint[] F1() => null; - public virtual System.IntPtr[] F2() => null; - public virtual nint[] F3() => null; - public virtual System.IntPtr[] F4() => null; -} -class B : A -{ - public override System.IntPtr[] F1() => null; - public override nint[] F2() => null; - public override nint[] F3() => null; - public override System.IntPtr[] F4() => null; -}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(); - - var type = comp.GetTypeByMetadataName("A"); - Assert.Equal("nint[] A.F1()", type.GetMember("F1").ToTestDisplayString()); - Assert.Equal("System.IntPtr[] A.F2()", type.GetMember("F2").ToTestDisplayString()); - Assert.Equal("nint[] A.F3()", type.GetMember("F3").ToTestDisplayString()); - Assert.Equal("System.IntPtr[] A.F4()", type.GetMember("F4").ToTestDisplayString()); - - type = comp.GetTypeByMetadataName("B"); - Assert.Equal("System.IntPtr[] B.F1()", type.GetMember("F1").ToTestDisplayString()); - Assert.Equal("nint[] B.F2()", type.GetMember("F2").ToTestDisplayString()); - Assert.Equal("nint[] B.F3()", type.GetMember("F3").ToTestDisplayString()); - Assert.Equal("System.IntPtr[] B.F4()", type.GetMember("F4").ToTestDisplayString()); - } - - [WorkItem(42500, "https://github.com/dotnet/roslyn/issues/42500")] - [Fact] - public void OverrideParameterTypeCustomModifierDifferences() - { - var sourceA = -@".class private System.Runtime.CompilerServices.NativeIntegerAttribute extends [mscorlib]System.Attribute -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} -.class public A -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } - .method public virtual void F1(native int modopt(int32) i) - { - .param [1] - .custom instance void System.Runtime.CompilerServices.NativeIntegerAttribute::.ctor() = ( 01 00 00 00 ) - ret - } - .method public virtual void F2(native int modopt(int32) i) - { - ret - } - .method public virtual void F3(native int modopt(int32) i) - { - .param [1] - .custom instance void System.Runtime.CompilerServices.NativeIntegerAttribute::.ctor() = ( 01 00 00 00 ) - ret - } - .method public virtual void F4(native int modopt(int32) i) - { - ret - } -}"; - var refA = CompileIL(sourceA); - - var sourceB = -@"class B : A -{ - public override void F1(System.IntPtr i) { } - public override void F2(nint i) { } - public override void F3(nint i) { } - public override void F4(System.IntPtr i) { } -}"; - var comp = CreateCompilation(sourceB, new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(); - - var type = comp.GetTypeByMetadataName("A"); - Assert.Equal("void A.F1(nint modopt(System.Int32) i)", type.GetMember("F1").ToTestDisplayString()); - Assert.Equal("void A.F2(System.IntPtr modopt(System.Int32) i)", type.GetMember("F2").ToTestDisplayString()); - Assert.Equal("void A.F3(nint modopt(System.Int32) i)", type.GetMember("F3").ToTestDisplayString()); - Assert.Equal("void A.F4(System.IntPtr modopt(System.Int32) i)", type.GetMember("F4").ToTestDisplayString()); - - type = comp.GetTypeByMetadataName("B"); - Assert.Equal("void B.F1(System.IntPtr modopt(System.Int32) i)", type.GetMember("F1").ToTestDisplayString()); - Assert.Equal("void B.F2(nint modopt(System.Int32) i)", type.GetMember("F2").ToTestDisplayString()); - Assert.Equal("void B.F3(nint modopt(System.Int32) i)", type.GetMember("F3").ToTestDisplayString()); - Assert.Equal("void B.F4(System.IntPtr modopt(System.Int32) i)", type.GetMember("F4").ToTestDisplayString()); +@"A +B +-1 +1"); } - [WorkItem(42500, "https://github.com/dotnet/roslyn/issues/42500")] [Fact] - public void OverrideReturnTypeCustomModifierDifferences() + public void EnumConversions_03() { - var sourceA = -@".class private System.Runtime.CompilerServices.NativeIntegerAttribute extends [mscorlib]System.Attribute -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } -} -.class public A -{ - .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } - .method public virtual native int[] modopt(int32) F1() - { - .param [0] - .custom instance void System.Runtime.CompilerServices.NativeIntegerAttribute::.ctor() = ( 01 00 00 00 ) - ldnull - throw - } - .method public virtual native int[] modopt(int32) F2() - { - ldnull - throw - } - .method public virtual native int[] modopt(int32) F3() - { - .param [0] - .custom instance void System.Runtime.CompilerServices.NativeIntegerAttribute::.ctor() = ( 01 00 00 00 ) - ldnull - throw - } - .method public virtual native int[] modopt(int32) F4() - { - ldnull - throw - } -}"; - var refA = CompileIL(sourceA); + convert(baseType: null, fromType: "E", toType: "nint", "int.MinValue", "-2147483648", "conv.i", "-2147483648", "conv.i"); + convert(baseType: null, fromType: "E", toType: "nint", "int.MaxValue", "2147483647", "conv.i", "2147483647", "conv.i"); + convert(baseType: null, fromType: "E", toType: "nuint", "int.MinValue", IntPtr.Size == 4 ? "2147483648" : "18446744071562067968", "conv.i", "System.OverflowException", "conv.ovf.u"); + convert(baseType: null, fromType: "E", toType: "nuint", "int.MaxValue", "2147483647", "conv.i", "2147483647", "conv.ovf.u"); + convert(baseType: null, fromType: "nint", toType: "E", "int.MinValue", "-2147483648", "conv.i4", "-2147483648", "conv.ovf.i4"); + convert(baseType: null, fromType: "nint", toType: "E", "int.MaxValue", "2147483647", "conv.i4", "2147483647", "conv.ovf.i4"); + convert(baseType: null, fromType: "nuint", toType: "E", "uint.MaxValue", "-1", "conv.i4", "System.OverflowException", "conv.ovf.i4.un"); + convert(baseType: null, fromType: "System.IntPtr", toType: "E", "int.MinValue", "-2147483648", "conv.i4", "-2147483648", "conv.ovf.i4"); + convert(baseType: null, fromType: "System.IntPtr", toType: "E", "int.MaxValue", "2147483647", "conv.i4", "2147483647", "conv.ovf.i4"); + convert(baseType: null, fromType: "System.UIntPtr", toType: "E", "uint.MaxValue", "-1", "conv.i4", "System.OverflowException", "conv.ovf.i4.un"); - var sourceB = -@"class B : A -{ - public override System.IntPtr[] F1() => default; - public override nint[] F2() => default; - public override nint[] F3() => default; - public override System.IntPtr[] F4() => default; -}"; - var comp = CreateCompilation(sourceB, new[] { refA }, parseOptions: TestOptions.Regular9); - comp.VerifyEmitDiagnostics(); + convert(baseType: "sbyte", fromType: "E", toType: "nint", "sbyte.MinValue", "-128", "conv.i", "-128", "conv.i"); + convert(baseType: "sbyte", fromType: "E", toType: "nint", "sbyte.MaxValue", "127", "conv.i", "127", "conv.i"); + convert(baseType: "sbyte", fromType: "E", toType: "nuint", "sbyte.MinValue", IntPtr.Size == 4 ? "4294967168" : "18446744073709551488", "conv.i", "System.OverflowException", "conv.ovf.u"); + convert(baseType: "sbyte", fromType: "E", toType: "nuint", "sbyte.MaxValue", "127", "conv.i", "127", "conv.ovf.u"); + convert(baseType: "sbyte", fromType: "nint", toType: "E", "int.MinValue", "A", "conv.i1", "System.OverflowException", "conv.ovf.i1"); + convert(baseType: "sbyte", fromType: "nint", toType: "E", "int.MaxValue", "-1", "conv.i1", "System.OverflowException", "conv.ovf.i1"); + convert(baseType: "sbyte", fromType: "nuint", toType: "E", "uint.MaxValue", "-1", "conv.i1", "System.OverflowException", "conv.ovf.i1.un"); + convert(baseType: "sbyte", fromType: "System.IntPtr", toType: "E", "int.MinValue", "A", "conv.i1", "System.OverflowException", "conv.ovf.i1"); + convert(baseType: "sbyte", fromType: "System.IntPtr", toType: "E", "int.MaxValue", "-1", "conv.i1", "System.OverflowException", "conv.ovf.i1"); + convert(baseType: "sbyte", fromType: "System.UIntPtr", toType: "E", "uint.MaxValue", "-1", "conv.i1", "System.OverflowException", "conv.ovf.i1.un"); - var type = comp.GetTypeByMetadataName("A"); - Assert.Equal("nint[] modopt(System.Int32) A.F1()", type.GetMember("F1").ToTestDisplayString()); - Assert.Equal("System.IntPtr[] modopt(System.Int32) A.F2()", type.GetMember("F2").ToTestDisplayString()); - Assert.Equal("nint[] modopt(System.Int32) A.F3()", type.GetMember("F3").ToTestDisplayString()); - Assert.Equal("System.IntPtr[] modopt(System.Int32) A.F4()", type.GetMember("F4").ToTestDisplayString()); + convert(baseType: "byte", fromType: "E", toType: "nint", "byte.MaxValue", "255", "conv.u", "255", "conv.u"); + convert(baseType: "byte", fromType: "E", toType: "nuint", "byte.MaxValue", "255", "conv.u", "255", "conv.u"); + convert(baseType: "byte", fromType: "nint", toType: "E", "int.MinValue", "A", "conv.u1", "System.OverflowException", "conv.ovf.u1"); + convert(baseType: "byte", fromType: "nint", toType: "E", "int.MaxValue", "255", "conv.u1", "System.OverflowException", "conv.ovf.u1"); + convert(baseType: "byte", fromType: "nuint", toType: "E", "uint.MaxValue", "255", "conv.u1", "System.OverflowException", "conv.ovf.u1.un"); + convert(baseType: "byte", fromType: "System.IntPtr", toType: "E", "int.MinValue", "A", "conv.u1", "System.OverflowException", "conv.ovf.u1"); + convert(baseType: "byte", fromType: "System.IntPtr", toType: "E", "int.MaxValue", "255", "conv.u1", "System.OverflowException", "conv.ovf.u1"); + convert(baseType: "byte", fromType: "System.UIntPtr", toType: "E", "uint.MaxValue", "255", "conv.u1", "System.OverflowException", "conv.ovf.u1.un"); - type = comp.GetTypeByMetadataName("B"); - Assert.Equal("System.IntPtr[] modopt(System.Int32) B.F1()", type.GetMember("F1").ToTestDisplayString()); - Assert.Equal("nint[] modopt(System.Int32) B.F2()", type.GetMember("F2").ToTestDisplayString()); - Assert.Equal("nint[] modopt(System.Int32) B.F3()", type.GetMember("F3").ToTestDisplayString()); - Assert.Equal("System.IntPtr[] modopt(System.Int32) B.F4()", type.GetMember("F4").ToTestDisplayString()); - } + convert(baseType: "short", fromType: "E", toType: "nint", "short.MinValue", "-32768", "conv.i", "-32768", "conv.i"); + convert(baseType: "short", fromType: "E", toType: "nint", "short.MaxValue", "32767", "conv.i", "32767", "conv.i"); + convert(baseType: "short", fromType: "E", toType: "nuint", "short.MinValue", IntPtr.Size == 4 ? "4294934528" : "18446744073709518848", "conv.i", "System.OverflowException", "conv.ovf.u"); + convert(baseType: "short", fromType: "E", toType: "nuint", "short.MaxValue", "32767", "conv.i", "32767", "conv.ovf.u"); + convert(baseType: "short", fromType: "nint", toType: "E", "int.MinValue", "A", "conv.i2", "System.OverflowException", "conv.ovf.i2"); + convert(baseType: "short", fromType: "nint", toType: "E", "int.MaxValue", "-1", "conv.i2", "System.OverflowException", "conv.ovf.i2"); + convert(baseType: "short", fromType: "nuint", toType: "E", "uint.MaxValue", "-1", "conv.i2", "System.OverflowException", "conv.ovf.i2.un"); + convert(baseType: "short", fromType: "System.IntPtr", toType: "E", "int.MinValue", "A", "conv.i2", "System.OverflowException", "conv.ovf.i2"); + convert(baseType: "short", fromType: "System.IntPtr", toType: "E", "int.MaxValue", "-1", "conv.i2", "System.OverflowException", "conv.ovf.i2"); + convert(baseType: "short", fromType: "System.UIntPtr", toType: "E", "uint.MaxValue", "-1", "conv.i2", "System.OverflowException", "conv.ovf.i2.un"); - [WorkItem(42457, "https://github.com/dotnet/roslyn/issues/42457")] - [Fact] - public void Int64Conversions() - { - convert(fromType: "nint", toType: "ulong", "int.MinValue", "18446744071562067968", "conv.i8", "System.OverflowException", "conv.ovf.u8"); - convert(fromType: "nint", toType: "ulong", "int.MaxValue", "2147483647", "conv.i8", "2147483647", "conv.ovf.u8"); - convert(fromType: "nint", toType: "nuint", "int.MinValue", IntPtr.Size == 4 ? "2147483648" : "18446744071562067968", "conv.u", "System.OverflowException", "conv.ovf.u"); - convert(fromType: "nint", toType: "nuint", "int.MaxValue", "2147483647", "conv.u", "2147483647", "conv.ovf.u"); + convert(baseType: "ushort", fromType: "E", toType: "nint", "ushort.MaxValue", "65535", "conv.u", "65535", "conv.u"); + convert(baseType: "ushort", fromType: "E", toType: "nuint", "ushort.MaxValue", "65535", "conv.u", "65535", "conv.u"); + convert(baseType: "ushort", fromType: "nint", toType: "E", "int.MinValue", "A", "conv.u2", "System.OverflowException", "conv.ovf.u2"); + convert(baseType: "ushort", fromType: "nint", toType: "E", "int.MaxValue", "65535", "conv.u2", "System.OverflowException", "conv.ovf.u2"); + convert(baseType: "ushort", fromType: "nuint", toType: "E", "uint.MaxValue", "65535", "conv.u2", "System.OverflowException", "conv.ovf.u2.un"); + convert(baseType: "ushort", fromType: "System.IntPtr", toType: "E", "int.MinValue", "A", "conv.u2", "System.OverflowException", "conv.ovf.u2"); + convert(baseType: "ushort", fromType: "System.IntPtr", toType: "E", "int.MaxValue", "65535", "conv.u2", "System.OverflowException", "conv.ovf.u2"); + convert(baseType: "ushort", fromType: "System.UIntPtr", toType: "E", "uint.MaxValue", "65535", "conv.u2", "System.OverflowException", "conv.ovf.u2.un"); - convert(fromType: "nuint", toType: "long", "uint.MaxValue", "4294967295", "conv.u8", "4294967295", "conv.ovf.i8.un"); - convert(fromType: "nuint", toType: "nint", "uint.MaxValue", IntPtr.Size == 4 ? "-1" : "4294967295", "conv.i", IntPtr.Size == 4 ? "System.OverflowException" : "4294967295", "conv.ovf.i.un"); + convert(baseType: "int", fromType: "E", toType: "nint", "int.MinValue", "-2147483648", "conv.i", "-2147483648", "conv.i"); + convert(baseType: "int", fromType: "E", toType: "nint", "int.MaxValue", "2147483647", "conv.i", "2147483647", "conv.i"); + convert(baseType: "int", fromType: "E", toType: "nuint", "int.MinValue", IntPtr.Size == 4 ? "2147483648" : "18446744071562067968", "conv.i", "System.OverflowException", "conv.ovf.u"); + convert(baseType: "int", fromType: "E", toType: "nuint", "int.MaxValue", "2147483647", "conv.i", "2147483647", "conv.ovf.u"); + convert(baseType: "int", fromType: "nint", toType: "E", "int.MinValue", "-2147483648", "conv.i4", "-2147483648", "conv.ovf.i4"); + convert(baseType: "int", fromType: "nint", toType: "E", "int.MaxValue", "2147483647", "conv.i4", "2147483647", "conv.ovf.i4"); + convert(baseType: "int", fromType: "nuint", toType: "E", "uint.MaxValue", "-1", "conv.i4", "System.OverflowException", "conv.ovf.i4.un"); + convert(baseType: "int", fromType: "System.IntPtr", toType: "E", "int.MinValue", "-2147483648", "conv.i4", "-2147483648", "conv.ovf.i4"); + convert(baseType: "int", fromType: "System.IntPtr", toType: "E", "int.MaxValue", "2147483647", "conv.i4", "2147483647", "conv.ovf.i4"); + convert(baseType: "int", fromType: "System.UIntPtr", toType: "E", "uint.MaxValue", "-1", "conv.i4", "System.OverflowException", "conv.ovf.i4.un"); - string nintMinValue = IntPtr.Size == 4 ? int.MinValue.ToString() : long.MinValue.ToString(); - string nintMaxValue = IntPtr.Size == 4 ? int.MaxValue.ToString() : long.MaxValue.ToString(); - string nuintMaxValue = IntPtr.Size == 4 ? uint.MaxValue.ToString() : ulong.MaxValue.ToString(); + convert(baseType: "uint", fromType: "E", toType: "nint", "uint.MaxValue", IntPtr.Size == 4 ? "-1" : "4294967295", "conv.u", IntPtr.Size == 4 ? "System.OverflowException" : "4294967295", "conv.ovf.i.un"); + convert(baseType: "uint", fromType: "E", toType: "nuint", "uint.MaxValue", "4294967295", "conv.u", "4294967295", "conv.u"); + convert(baseType: "uint", fromType: "nint", toType: "E", "int.MinValue", "2147483648", "conv.u4", "System.OverflowException", "conv.ovf.u4"); + convert(baseType: "uint", fromType: "nint", toType: "E", "int.MaxValue", "2147483647", "conv.u4", "2147483647", "conv.ovf.u4"); + convert(baseType: "uint", fromType: "nuint", toType: "E", "uint.MaxValue", "4294967295", "conv.u4", "4294967295", "conv.ovf.u4.un"); + convert(baseType: "uint", fromType: "System.IntPtr", toType: "E", "int.MinValue", "2147483648", "conv.u4", "System.OverflowException", "conv.ovf.u4"); + convert(baseType: "uint", fromType: "System.IntPtr", toType: "E", "int.MaxValue", "2147483647", "conv.u4", "2147483647", "conv.ovf.u4"); + convert(baseType: "uint", fromType: "System.UIntPtr", toType: "E", "uint.MaxValue", "4294967295", "conv.u4", "4294967295", "conv.ovf.u4.un"); - convert(fromType: "nint", toType: "ulong", nintMinValue, IntPtr.Size == 4 ? "18446744071562067968" : "9223372036854775808", "conv.i8", "System.OverflowException", "conv.ovf.u8"); - convert(fromType: "nint", toType: "ulong", nintMaxValue, IntPtr.Size == 4 ? "2147483647" : "9223372036854775807", "conv.i8", IntPtr.Size == 4 ? "2147483647" : "9223372036854775807", "conv.ovf.u8"); - convert(fromType: "nint", toType: "nuint", nintMinValue, IntPtr.Size == 4 ? "2147483648" : "9223372036854775808", "conv.u", "System.OverflowException", "conv.ovf.u"); - convert(fromType: "nint", toType: "nuint", nintMaxValue, IntPtr.Size == 4 ? "2147483647" : "9223372036854775807", "conv.u", IntPtr.Size == 4 ? "2147483647" : "9223372036854775807", "conv.ovf.u"); + convert(baseType: "long", fromType: "E", toType: "nint", "long.MinValue", IntPtr.Size == 4 ? "0" : "-9223372036854775808", "conv.i", IntPtr.Size == 4 ? "System.OverflowException" : "-9223372036854775808", "conv.ovf.i"); + convert(baseType: "long", fromType: "E", toType: "nint", "long.MaxValue", IntPtr.Size == 4 ? "-1" : "9223372036854775807", "conv.i", IntPtr.Size == 4 ? "System.OverflowException" : "9223372036854775807", "conv.ovf.i"); + convert(baseType: "long", fromType: "E", toType: "nuint", "long.MinValue", IntPtr.Size == 4 ? "0" : "9223372036854775808", "conv.u", "System.OverflowException", "conv.ovf.u"); + convert(baseType: "long", fromType: "E", toType: "nuint", "long.MaxValue", IntPtr.Size == 4 ? "4294967295" : "9223372036854775807", "conv.u", IntPtr.Size == 4 ? "System.OverflowException" : "9223372036854775807", "conv.ovf.u"); + convert(baseType: "long", fromType: "nint", toType: "E", "int.MinValue", "-2147483648", "conv.i8", "-2147483648", "conv.i8"); + convert(baseType: "long", fromType: "nint", toType: "E", "int.MaxValue", "2147483647", "conv.i8", "2147483647", "conv.i8"); + convert(baseType: "long", fromType: "nuint", toType: "E", "uint.MaxValue", "4294967295", "conv.u8", "4294967295", "conv.ovf.i8.un"); + convert(baseType: "long", fromType: "System.IntPtr", toType: "E", "int.MinValue", "-2147483648", "conv.i8", "-2147483648", "conv.i8"); + convert(baseType: "long", fromType: "System.IntPtr", toType: "E", "int.MaxValue", "2147483647", "conv.i8", "2147483647", "conv.i8"); + convert(baseType: "long", fromType: "System.UIntPtr", toType: "E", "uint.MaxValue", "4294967295", "conv.u8", "4294967295", "conv.ovf.i8.un"); - convert(fromType: "nuint", toType: "long", nuintMaxValue, IntPtr.Size == 4 ? "4294967295" : "-1", "conv.u8", IntPtr.Size == 4 ? "4294967295" : "System.OverflowException", "conv.ovf.i8.un"); - convert(fromType: "nuint", toType: "nint", nuintMaxValue, "-1", "conv.i", "System.OverflowException", "conv.ovf.i.un"); + convert(baseType: "ulong", fromType: "E", toType: "nint", "ulong.MaxValue", "-1", "conv.i", "System.OverflowException", "conv.ovf.i.un"); + convert(baseType: "ulong", fromType: "E", toType: "nuint", "ulong.MaxValue", IntPtr.Size == 4 ? "4294967295" : "18446744073709551615", "conv.u", IntPtr.Size == 4 ? "System.OverflowException" : "18446744073709551615", "conv.ovf.u.un"); + convert(baseType: "ulong", fromType: "nint", toType: "E", "int.MinValue", "18446744071562067968", "conv.i8", "System.OverflowException", "conv.ovf.u8"); + convert(baseType: "ulong", fromType: "nint", toType: "E", "int.MaxValue", "2147483647", "conv.i8", "2147483647", "conv.ovf.u8"); + convert(baseType: "ulong", fromType: "nuint", toType: "E", "uint.MaxValue", "4294967295", "conv.u8", "4294967295", "conv.u8"); + convert(baseType: "ulong", fromType: "System.IntPtr", toType: "E", "int.MinValue", "18446744071562067968", "conv.i8", "System.OverflowException", "conv.ovf.u8"); + convert(baseType: "ulong", fromType: "System.IntPtr", toType: "E", "int.MaxValue", "2147483647", "conv.i8", "2147483647", "conv.ovf.u8"); + convert(baseType: "ulong", fromType: "System.UIntPtr", toType: "E", "uint.MaxValue", "4294967295", "conv.u8", "4294967295", "conv.u8"); - void convert(string fromType, string toType, string fromValue, string toValueUnchecked, string toConvUnchecked, string toValueChecked, string toConvChecked) + void convert(string baseType, string fromType, string toType, string fromValue, string toValueUnchecked, string toConvUnchecked, string toValueChecked, string toConvChecked) { + if (baseType != null) baseType = " : " + baseType; string source = $@"using System; +enum E{baseType} {{ A, B }} class Program {{ static {toType} Convert({fromType} value) => ({toType})(value); @@ -13368,9 +10011,13 @@ static void Main() Console.WriteLine(Execute(() => ConvertChecked(value))); }} }}"; - var verifier = CompileAndVerify(source, parseOptions: TestOptions.Regular9, expectedOutput: + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + + var verifier = CompileAndVerify(comp, expectedOutput: $@"{toValueUnchecked} {toValueChecked}"); + verifier.VerifyIL("Program.Convert", $@"{{ // Code size 3 (0x3) @@ -13390,1266 +10037,1088 @@ .maxstack 1 } } - [WorkItem(44810, "https://github.com/dotnet/roslyn/issues/44810")] [Theory] - [InlineData("void*")] - [InlineData("byte*")] - [InlineData("delegate*")] - public void PointerConversions(string pointerType) + [InlineData("nint", "System.IntPtr")] + [InlineData("nuint", "System.UIntPtr")] + public void MethodTypeInference(string nativeIntegerType, string underlyingType) { - string source = -$@"using System; + var source = +$@"interface I +{{ + T P {{ get; }} +}} unsafe class Program {{ - static {pointerType} ToPointer1(nint i) => ({pointerType})i; - static {pointerType} ToPointer2(nuint u) => ({pointerType})u; - static {pointerType} ToPointer3(nint i) => checked(({pointerType})i); - static {pointerType} ToPointer4(nuint u) => checked(({pointerType})u); - static nint FromPointer1({pointerType} p) => (nint)p; - static nuint FromPointer2({pointerType} p) => (nuint)p; - static nint FromPointer3({pointerType} p) => checked((nint)p); - static nuint FromPointer4({pointerType} p) => checked((nuint)p); - static object Execute(Func f) + static T F0(T x, T y) => x; + static void F1({nativeIntegerType} x, {underlyingType} y) {{ - try - {{ - return f(); - }} - catch (Exception e) - {{ - return e.GetType().FullName; - }} + var z = ({nativeIntegerType})y; + F0(x, z).ToPointer(); + F0(x, y).ToPointer(); + F0(y, x).ToPointer(); + F0<{nativeIntegerType}>(x, y). + ToPointer(); + F0<{underlyingType}>(x, y). + ToPointer(); }} - static void Execute({pointerType} p) + static void F2({nativeIntegerType}[] x, {underlyingType}[] y) {{ - Console.WriteLine((int)p); - Console.WriteLine(Execute(() => FromPointer1(p))); - Console.WriteLine(Execute(() => FromPointer2(p))); - Console.WriteLine(Execute(() => FromPointer3(p))); - Console.WriteLine(Execute(() => FromPointer4(p))); + var z = ({nativeIntegerType}[])y; + F0(x, z)[0].ToPointer(); + F0(x, y)[0].ToPointer(); + F0(y, x)[0].ToPointer(); + F0<{nativeIntegerType}[]>(x, y)[0]. + ToPointer(); + F0<{underlyingType}[]>(x, y)[0]. + ToPointer(); }} - static void Main() + static void F3(I<{nativeIntegerType}> x, I<{underlyingType}> y) {{ - Execute(ToPointer1(-42)); - Execute(ToPointer2(42)); - Execute(ToPointer1(int.MinValue)); - Execute(ToPointer2(uint.MaxValue)); - Console.WriteLine(Execute(() => (ulong)ToPointer3(-42))); - Console.WriteLine(Execute(() => (ulong)ToPointer4(42))); - Console.WriteLine(Execute(() => (ulong)ToPointer3(int.MinValue))); - Console.WriteLine(Execute(() => (ulong)ToPointer4(uint.MaxValue))); + var z = (I<{nativeIntegerType}>)y; + F0(x, z).P.ToPointer(); + F0(x, y).P.ToPointer(); + F0(y, x).P.ToPointer(); + F0>(x, y).P. + ToPointer(); + F0>(x, y).P. + ToPointer(); }} }}"; - var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseExe, parseOptions: TestOptions.Regular9); - string expectedOutput = -$@"-42 --42 -{(IntPtr.Size == 4 ? "4294967254" : "18446744073709551574")} -System.OverflowException -{(IntPtr.Size == 4 ? "4294967254" : "18446744073709551574")} -42 -42 -42 -42 -42 --2147483648 --2147483648 -{(IntPtr.Size == 4 ? "2147483648" : "18446744071562067968")} -System.OverflowException -{(IntPtr.Size == 4 ? "2147483648" : "18446744071562067968")} --1 -{(IntPtr.Size == 4 ? "-1" : "4294967295")} -4294967295 -{(IntPtr.Size == 4 ? "System.OverflowException" : "4294967295")} -4294967295 -System.OverflowException -42 -System.OverflowException -4294967295"; - var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: expectedOutput); - verifier.VerifyIL("Program.ToPointer1", -@"{ - // Code size 2 (0x2) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: ret -}"); - verifier.VerifyIL("Program.ToPointer2", -@"{ - // Code size 2 (0x2) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: ret -}"); - verifier.VerifyIL("Program.ToPointer3", -@"{ - // Code size 3 (0x3) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: conv.ovf.u - IL_0002: ret -}"); - verifier.VerifyIL("Program.ToPointer4", -@"{ - // Code size 2 (0x2) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: ret -}"); - verifier.VerifyIL("Program.FromPointer1", -@"{ - // Code size 2 (0x2) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: ret -}"); - verifier.VerifyIL("Program.FromPointer2", -@"{ - // Code size 2 (0x2) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: ret -}"); - verifier.VerifyIL("Program.FromPointer3", -@"{ - // Code size 3 (0x3) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: conv.ovf.i.un - IL_0002: ret -}"); - verifier.VerifyIL("Program.FromPointer4", -@"{ - // Code size 2 (0x2) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: ret -}"); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9, options: TestOptions.UnsafeReleaseDll); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(); } - [WorkItem(48035, "https://github.com/dotnet/roslyn/issues/48035")] - [Theory] - [InlineData(null)] - [InlineData("sbyte")] - [InlineData("byte")] - [InlineData("short")] - [InlineData("ushort")] - [InlineData("int")] - [InlineData("uint")] - [InlineData("long")] - [InlineData("ulong")] - public void EnumConversions_01(string baseType) - { - if (baseType != null) baseType = " : " + baseType; - string sourceA = -$@"enum E{baseType} {{ A = 0, B = 1 }}"; - string sourceB = -@"#pragma warning disable 219 -class Program -{ - static void F1() - { - E e; - const nint i0 = 0; - const nint i1 = 1; - e = i0; - e = i1; - } - static void F2() + [Fact] + public void DuplicateConstraint() { - E e; - const nuint u0 = 0; - const nuint u1 = 1; - e = u0; - e = u1; + var source = +@"interface I { } +class C1 where U : I, I { } +class C2 where U : I, I { } +class C3 where U : I, I, I { } + "; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics( + // (2,35): error CS0405: Duplicate constraint 'I' for type parameter 'U' + // class C1 where U : I, I { } + Diagnostic(ErrorCode.ERR_DuplicateBound, "I").WithArguments("I", "U").WithLocation(2, 35), + // (3,35): error CS0405: Duplicate constraint 'I' for type parameter 'U' + // class C2 where U : I, I { } + Diagnostic(ErrorCode.ERR_DuplicateBound, "I").WithArguments("I", "U").WithLocation(3, 35), + // (4,63): error CS0405: Duplicate constraint 'I' for type parameter 'U' + // class C3 where U : I, I, I { } + Diagnostic(ErrorCode.ERR_DuplicateBound, "I").WithArguments("I", "U").WithLocation(4, 63)); } - static void F3() + + [Fact] + public void DuplicateInterface_01() { - nint i; - i = default(E); - i = E.A; - i = E.B; + var source = +@"interface I { } +class C1 : I, I { } +class C2 : I, I { } +class C3 : I, I, I { } + "; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, parseOptions: TestOptions.Regular9); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics( + // (2,21): error CS0528: 'I' is already listed in interface list + // class C1 : I, I { } + Diagnostic(ErrorCode.ERR_DuplicateInterfaceInBaseList, "I").WithArguments("I").WithLocation(2, 21), + // (3,21): error CS0528: 'I' is already listed in interface list + // class C2 : I, I { } + Diagnostic(ErrorCode.ERR_DuplicateInterfaceInBaseList, "I").WithArguments("I").WithLocation(3, 21), + // (4,49): error CS0528: 'I' is already listed in interface list + // class C3 : I, I, I { } + Diagnostic(ErrorCode.ERR_DuplicateInterfaceInBaseList, "I").WithArguments("I").WithLocation(4, 49)); } - static void F4() + + [Theory] + [InlineData("nuint")] + [InlineData("System.UIntPtr")] + public void SignedToUnsignedConversions_Implicit(string type) { - nuint u; - u = default(E); - u = E.A; - u = E.B; - } -}"; - var comp = CreateCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9); + string source = +$@"static class NativeInts +{{ + static {type} Implicit1(sbyte x) => x; // 1 + static {type} Implicit2(short x) => x; // 2 + static {type} Implicit3(int x) => x; // 3 + static {type} Implicit4(long x) => x; // 4 + static {type} Implicit5(nint x) => x; // 5 + static {type} Checked1(sbyte x) => checked(x); // 6 + static {type} Checked2(short x) => checked(x); // 7 + static {type} Checked3(int x) => checked(x); // 8 + static {type} Checked4(long x) => checked(x); // 9 + static {type} Checked5(nint x) => checked(x); // 10 +}}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; comp.VerifyDiagnostics( - // (10,13): error CS0266: Cannot implicitly convert type 'nint' to 'E'. An explicit conversion exists (are you missing a cast?) - // e = i1; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "i1").WithArguments("nint", "E").WithLocation(10, 13), - // (18,13): error CS0266: Cannot implicitly convert type 'nuint' to 'E'. An explicit conversion exists (are you missing a cast?) - // e = u1; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "u1").WithArguments("nuint", "E").WithLocation(18, 13), - // (23,13): error CS0266: Cannot implicitly convert type 'E' to 'nint'. An explicit conversion exists (are you missing a cast?) - // i = default(E); - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "default(E)").WithArguments("E", "nint").WithLocation(23, 13), - // (24,13): error CS0266: Cannot implicitly convert type 'E' to 'nint'. An explicit conversion exists (are you missing a cast?) - // i = E.A; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "E.A").WithArguments("E", "nint").WithLocation(24, 13), - // (25,13): error CS0266: Cannot implicitly convert type 'E' to 'nint'. An explicit conversion exists (are you missing a cast?) - // i = E.B; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "E.B").WithArguments("E", "nint").WithLocation(25, 13), - // (30,13): error CS0266: Cannot implicitly convert type 'E' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // u = default(E); - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "default(E)").WithArguments("E", "nuint").WithLocation(30, 13), - // (31,13): error CS0266: Cannot implicitly convert type 'E' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // u = E.A; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "E.A").WithArguments("E", "nuint").WithLocation(31, 13), - // (32,13): error CS0266: Cannot implicitly convert type 'E' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // u = E.B; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "E.B").WithArguments("E", "nuint").WithLocation(32, 13)); + // (3,40): error CS0266: Cannot implicitly convert type 'sbyte' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // static nuint Implicit1(sbyte x) => x; // 1 + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("sbyte", "nuint"), + // (4,40): error CS0266: Cannot implicitly convert type 'short' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // static nuint Implicit2(short x) => x; // 2 + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("short", "nuint"), + // (5,38): error CS0266: Cannot implicitly convert type 'int' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // static nuint Implicit3(int x) => x; // 3 + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("int", "nuint"), + // (6,39): error CS0266: Cannot implicitly convert type 'long' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // static nuint Implicit4(long x) => x; // 4 + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("long", "nuint"), + // (7,39): error CS0266: Cannot implicitly convert type 'nint' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // static nuint Implicit5(nint x) => x; // 5 + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("nint", "nuint"), + // (8,47): error CS0266: Cannot implicitly convert type 'sbyte' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // static nuint Checked1(sbyte x) => checked(x); // 6 + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("sbyte", "nuint"), + // (9,47): error CS0266: Cannot implicitly convert type 'short' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // static nuint Checked2(short x) => checked(x); // 7 + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("short", "nuint"), + // (10,45): error CS0266: Cannot implicitly convert type 'int' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // static nuint Checked3(int x) => checked(x); // 8 + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("int", "nuint"), + // (11,46): error CS0266: Cannot implicitly convert type 'long' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // static nuint Checked4(long x) => checked(x); // 9 + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("long", "nuint"), + // (12,46): error CS0266: Cannot implicitly convert type 'nint' to 'nuint'. An explicit conversion exists (are you missing a cast?) + // static nuint Checked5(nint x) => checked(x); // 10 + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("nint", "nuint")); } - [WorkItem(48035, "https://github.com/dotnet/roslyn/issues/48035")] [Theory] - [InlineData(null)] - [InlineData("sbyte")] - [InlineData("short")] - [InlineData("int")] - [InlineData("long")] - public void EnumConversions_02(string baseType) - { - if (baseType != null) baseType = " : " + baseType; - string sourceA = -$@"enum E{baseType} {{ A = -1, B = 1 }}"; - string sourceB = -@"using static System.Console; -class Program -{ - static E F1(nint i) => (E)i; - static E F2(nuint u) => (E)u; - static nint F3(E e) => (nint)e; - static nuint F4(E e) => (nuint)e; - static void Main() + [InlineData("nuint")] + [InlineData("System.UIntPtr")] + public void SignedToUnsignedConversions_Explicit(string type) { - WriteLine(F1(-1)); - WriteLine(F2(1)); - WriteLine(F3(E.A)); - WriteLine(F4(E.B)); - } + string source = +$@"static class NativeInts +{{ + static {type} Explicit1(sbyte x) => ({type})x; + static {type} Explicit2(short x) => ({type})x; + static {type} Explicit3(int x) => ({type})x; + static {type} Explicit4(long x) => ({type})x; + static {type} Explicit5(nint x) => ({type})x; + static {type} Checked1(sbyte x) => checked(({type})x); + static {type} Checked2(short x) => checked(({type})x); + static {type} Checked3(int x) => checked(({type})x); + static {type} Checked4(long x) => checked(({type})x); + static {type} Checked5(nint x) => checked(({type})x); +}}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + var verifier = CompileAndVerify(comp); + string expectedExplicitILA = +@"{ + // Code size 3 (0x3) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: conv.i + IL_0002: ret }"; - CompileAndVerify(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9, expectedOutput: -@"A -B --1 -1"); + string expectedExplicitILB = +@"{ + // Code size 3 (0x3) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: conv.u + IL_0002: ret +}"; + string expectedCheckedIL = +@"{ + // Code size 3 (0x3) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: conv.ovf.u + IL_0002: ret +}"; + verifier.VerifyIL("NativeInts.Explicit1", expectedExplicitILA); + verifier.VerifyIL("NativeInts.Explicit2", expectedExplicitILA); + verifier.VerifyIL("NativeInts.Explicit3", expectedExplicitILA); + verifier.VerifyIL("NativeInts.Explicit4", expectedExplicitILB); + verifier.VerifyIL("NativeInts.Explicit5", expectedExplicitILB); + verifier.VerifyIL("NativeInts.Checked1", expectedCheckedIL); + verifier.VerifyIL("NativeInts.Checked2", expectedCheckedIL); + verifier.VerifyIL("NativeInts.Checked3", expectedCheckedIL); + verifier.VerifyIL("NativeInts.Checked4", expectedCheckedIL); + verifier.VerifyIL("NativeInts.Checked5", expectedCheckedIL); } - [WorkItem(48035, "https://github.com/dotnet/roslyn/issues/48035")] [Fact] - public void EnumConversions_03() + public void StandardConversions() { - convert(baseType: null, fromType: "E", toType: "nint", "int.MinValue", "-2147483648", "conv.i", "-2147483648", "conv.i"); - convert(baseType: null, fromType: "E", toType: "nint", "int.MaxValue", "2147483647", "conv.i", "2147483647", "conv.i"); - convert(baseType: null, fromType: "E", toType: "nuint", "int.MinValue", IntPtr.Size == 4 ? "2147483648" : "18446744071562067968", "conv.i", "System.OverflowException", "conv.ovf.u"); - convert(baseType: null, fromType: "E", toType: "nuint", "int.MaxValue", "2147483647", "conv.i", "2147483647", "conv.ovf.u"); - convert(baseType: null, fromType: "nint", toType: "E", "int.MinValue", "-2147483648", "conv.i4", "-2147483648", "conv.ovf.i4"); - convert(baseType: null, fromType: "nint", toType: "E", "int.MaxValue", "2147483647", "conv.i4", "2147483647", "conv.ovf.i4"); - convert(baseType: null, fromType: "nuint", toType: "E", "uint.MaxValue", "-1", "conv.i4", "System.OverflowException", "conv.ovf.i4.un"); + // Note: A standard explicit conversion is derived from opposite standard implicit conversion - convert(baseType: "sbyte", fromType: "E", toType: "nint", "sbyte.MinValue", "-128", "conv.i", "-128", "conv.i"); - convert(baseType: "sbyte", fromType: "E", toType: "nint", "sbyte.MaxValue", "127", "conv.i", "127", "conv.i"); - convert(baseType: "sbyte", fromType: "E", toType: "nuint", "sbyte.MinValue", IntPtr.Size == 4 ? "4294967168" : "18446744073709551488", "conv.i", "System.OverflowException", "conv.ovf.u"); - convert(baseType: "sbyte", fromType: "E", toType: "nuint", "sbyte.MaxValue", "127", "conv.i", "127", "conv.ovf.u"); - convert(baseType: "sbyte", fromType: "nint", toType: "E", "int.MinValue", "A", "conv.i1", "System.OverflowException", "conv.ovf.i1"); - convert(baseType: "sbyte", fromType: "nint", toType: "E", "int.MaxValue", "-1", "conv.i1", "System.OverflowException", "conv.ovf.i1"); - convert(baseType: "sbyte", fromType: "nuint", toType: "E", "uint.MaxValue", "-1", "conv.i1", "System.OverflowException", "conv.ovf.i1.un"); + // type to nint + verify(sourceType: "object", destType: "nint", isExplicit: true); + verify(sourceType: "string", destType: "nint", noConversion: true); + verify(sourceType: "void*", destType: "nint", noConversion: true); + verify(sourceType: "delegate*", destType: "nint", noConversion: true); + verify(sourceType: "E", destType: "nint", noConversion: true); + verify(sourceType: "bool", destType: "nint", noConversion: true); + verify(sourceType: "sbyte", destType: "nint"); + verify(sourceType: "byte", destType: "nint"); + verify(sourceType: "short", destType: "nint"); + verify(sourceType: "ushort", destType: "nint"); + verify(sourceType: "int", destType: "nint"); + verify(sourceType: "uint", destType: "nint", noConversion: true); + verify(sourceType: "long", destType: "nint", isExplicit: true); + verify(sourceType: "ulong", destType: "nint", noConversion: true); + verify(sourceType: "char", destType: "nint"); + verify(sourceType: "float", destType: "nint", isExplicit: true); + verify(sourceType: "double", destType: "nint", isExplicit: true); + verify(sourceType: "decimal", destType: "nint", isExplicit: true); + verify(sourceType: "nint", destType: "nint"); + verify(sourceType: "nuint", destType: "nint", noConversion: true); + verify(sourceType: "System.IntPtr", destType: "nint"); + verify(sourceType: "System.UIntPtr", destType: "nint", noConversion: true); - convert(baseType: "byte", fromType: "E", toType: "nint", "byte.MaxValue", "255", "conv.u", "255", "conv.u"); - convert(baseType: "byte", fromType: "E", toType: "nuint", "byte.MaxValue", "255", "conv.u", "255", "conv.u"); - convert(baseType: "byte", fromType: "nint", toType: "E", "int.MinValue", "A", "conv.u1", "System.OverflowException", "conv.ovf.u1"); - convert(baseType: "byte", fromType: "nint", toType: "E", "int.MaxValue", "255", "conv.u1", "System.OverflowException", "conv.ovf.u1"); - convert(baseType: "byte", fromType: "nuint", toType: "E", "uint.MaxValue", "255", "conv.u1", "System.OverflowException", "conv.ovf.u1.un"); + // nint to type + verify(sourceType: "nint", destType: "string", noConversion: true); + verify(sourceType: "nint", destType: "void*", noConversion: true); + verify(sourceType: "nint", destType: "delegate*", noConversion: true); + verify(sourceType: "nint", destType: "E", noConversion: true); + verify(sourceType: "nint", destType: "bool", noConversion: true); + verify(sourceType: "nint", destType: "sbyte", isExplicit: true); + verify(sourceType: "nint", destType: "byte", isExplicit: true); + verify(sourceType: "nint", destType: "short", isExplicit: true); + verify(sourceType: "nint", destType: "ushort", isExplicit: true); + verify(sourceType: "nint", destType: "int", isExplicit: true); + verify(sourceType: "nint", destType: "uint", noConversion: true); + verify(sourceType: "nint", destType: "long"); + verify(sourceType: "nint", destType: "ulong", noConversion: true); + verify(sourceType: "nint", destType: "char", isExplicit: true); + verify(sourceType: "nint", destType: "float"); + verify(sourceType: "nint", destType: "double"); + verify(sourceType: "nint", destType: "decimal"); + verify(sourceType: "nint", destType: "nint"); + verify(sourceType: "nint", destType: "nuint", noConversion: true); + verify(sourceType: "nint", destType: "System.IntPtr"); + verify(sourceType: "nint", destType: "System.UIntPtr", noConversion: true); - convert(baseType: "short", fromType: "E", toType: "nint", "short.MinValue", "-32768", "conv.i", "-32768", "conv.i"); - convert(baseType: "short", fromType: "E", toType: "nint", "short.MaxValue", "32767", "conv.i", "32767", "conv.i"); - convert(baseType: "short", fromType: "E", toType: "nuint", "short.MinValue", IntPtr.Size == 4 ? "4294934528" : "18446744073709518848", "conv.i", "System.OverflowException", "conv.ovf.u"); - convert(baseType: "short", fromType: "E", toType: "nuint", "short.MaxValue", "32767", "conv.i", "32767", "conv.ovf.u"); - convert(baseType: "short", fromType: "nint", toType: "E", "int.MinValue", "A", "conv.i2", "System.OverflowException", "conv.ovf.i2"); - convert(baseType: "short", fromType: "nint", toType: "E", "int.MaxValue", "-1", "conv.i2", "System.OverflowException", "conv.ovf.i2"); - convert(baseType: "short", fromType: "nuint", toType: "E", "uint.MaxValue", "-1", "conv.i2", "System.OverflowException", "conv.ovf.i2.un"); + // type to nuint + verify(sourceType: "object", destType: "nuint", isExplicit: true); + verify(sourceType: "string", destType: "nuint", noConversion: true); + verify(sourceType: "void*", destType: "nuint", noConversion: true); + verify(sourceType: "delegate*", destType: "nuint", noConversion: true); + verify(sourceType: "E", destType: "nuint", noConversion: true); + verify(sourceType: "bool", destType: "nuint", noConversion: true); + verify(sourceType: "sbyte", destType: "nuint", noConversion: true); + verify(sourceType: "byte", destType: "nuint"); + verify(sourceType: "short", destType: "nuint", noConversion: true); + verify(sourceType: "ushort", destType: "nuint"); + verify(sourceType: "int", destType: "nuint", noConversion: true); + verify(sourceType: "uint", destType: "nuint"); + verify(sourceType: "long", destType: "nuint", noConversion: true); + verify(sourceType: "ulong", destType: "nuint", isExplicit: true); + verify(sourceType: "char", destType: "nuint"); + verify(sourceType: "float", destType: "nuint", isExplicit: true); + verify(sourceType: "double", destType: "nuint", isExplicit: true); + verify(sourceType: "decimal", destType: "nuint", isExplicit: true); + verify(sourceType: "nint", destType: "nuint", noConversion: true); + verify(sourceType: "nuint", destType: "nuint"); + verify(sourceType: "System.IntPtr", destType: "nuint", noConversion: true); + verify(sourceType: "System.UIntPtr", destType: "nuint"); + + // nuint to type + verify(sourceType: "nuint", destType: "string", noConversion: true); + verify(sourceType: "nuint", destType: "void*", noConversion: true); + verify(sourceType: "nuint", destType: "delegate*", noConversion: true); + verify(sourceType: "nuint", destType: "E", noConversion: true); + verify(sourceType: "nuint", destType: "bool", noConversion: true); + verify(sourceType: "nuint", destType: "sbyte", noConversion: true); + verify(sourceType: "nuint", destType: "byte", isExplicit: true); + verify(sourceType: "nuint", destType: "short", noConversion: true); + verify(sourceType: "nuint", destType: "ushort", isExplicit: true); + verify(sourceType: "nuint", destType: "int", noConversion: true); + verify(sourceType: "nuint", destType: "uint", isExplicit: true); + verify(sourceType: "nuint", destType: "long", noConversion: true); + verify(sourceType: "nuint", destType: "ulong"); + verify(sourceType: "nuint", destType: "char", isExplicit: true); + verify(sourceType: "nuint", destType: "float"); + verify(sourceType: "nuint", destType: "double"); + verify(sourceType: "nuint", destType: "decimal"); + verify(sourceType: "nuint", destType: "nint", noConversion: true); + verify(sourceType: "nuint", destType: "nuint"); + verify(sourceType: "nuint", destType: "System.IntPtr", noConversion: true); + verify(sourceType: "nuint", destType: "System.UIntPtr"); - convert(baseType: "ushort", fromType: "E", toType: "nint", "ushort.MaxValue", "65535", "conv.u", "65535", "conv.u"); - convert(baseType: "ushort", fromType: "E", toType: "nuint", "ushort.MaxValue", "65535", "conv.u", "65535", "conv.u"); - convert(baseType: "ushort", fromType: "nint", toType: "E", "int.MinValue", "A", "conv.u2", "System.OverflowException", "conv.ovf.u2"); - convert(baseType: "ushort", fromType: "nint", toType: "E", "int.MaxValue", "65535", "conv.u2", "System.OverflowException", "conv.ovf.u2"); - convert(baseType: "ushort", fromType: "nuint", toType: "E", "uint.MaxValue", "65535", "conv.u2", "System.OverflowException", "conv.ovf.u2.un"); - convert(baseType: "int", fromType: "E", toType: "nint", "int.MinValue", "-2147483648", "conv.i", "-2147483648", "conv.i"); - convert(baseType: "int", fromType: "E", toType: "nint", "int.MaxValue", "2147483647", "conv.i", "2147483647", "conv.i"); - convert(baseType: "int", fromType: "E", toType: "nuint", "int.MinValue", IntPtr.Size == 4 ? "2147483648" : "18446744071562067968", "conv.i", "System.OverflowException", "conv.ovf.u"); - convert(baseType: "int", fromType: "E", toType: "nuint", "int.MaxValue", "2147483647", "conv.i", "2147483647", "conv.ovf.u"); - convert(baseType: "int", fromType: "nint", toType: "E", "int.MinValue", "-2147483648", "conv.i4", "-2147483648", "conv.ovf.i4"); - convert(baseType: "int", fromType: "nint", toType: "E", "int.MaxValue", "2147483647", "conv.i4", "2147483647", "conv.ovf.i4"); - convert(baseType: "int", fromType: "nuint", toType: "E", "uint.MaxValue", "-1", "conv.i4", "System.OverflowException", "conv.ovf.i4.un"); + // type to IntPtr + verify(sourceType: "object", destType: "System.IntPtr", isExplicit: true); + verify(sourceType: "string", destType: "System.IntPtr", noConversion: true); + verify(sourceType: "void*", destType: "System.IntPtr", noConversion: true); + verify(sourceType: "delegate*", destType: "System.IntPtr", noConversion: true); + verify(sourceType: "E", destType: "System.IntPtr", noConversion: true); + verify(sourceType: "bool", destType: "System.IntPtr", noConversion: true); + verify(sourceType: "sbyte", destType: "System.IntPtr"); + verify(sourceType: "byte", destType: "System.IntPtr"); + verify(sourceType: "short", destType: "System.IntPtr"); + verify(sourceType: "ushort", destType: "System.IntPtr"); + verify(sourceType: "int", destType: "System.IntPtr"); + verify(sourceType: "uint", destType: "System.IntPtr", noConversion: true); + verify(sourceType: "long", destType: "System.IntPtr", isExplicit: true); + verify(sourceType: "ulong", destType: "System.IntPtr", noConversion: true); + verify(sourceType: "char", destType: "System.IntPtr"); + verify(sourceType: "float", destType: "System.IntPtr", isExplicit: true); + verify(sourceType: "double", destType: "System.IntPtr", isExplicit: true); + verify(sourceType: "decimal", destType: "System.IntPtr", isExplicit: true); + verify(sourceType: "nint", destType: "System.IntPtr"); + verify(sourceType: "nuint", destType: "System.IntPtr", noConversion: true); + verify(sourceType: "System.IntPtr", destType: "System.IntPtr"); + verify(sourceType: "System.UIntPtr", destType: "System.IntPtr", noConversion: true); - convert(baseType: "uint", fromType: "E", toType: "nint", "uint.MaxValue", IntPtr.Size == 4 ? "-1" : "4294967295", "conv.u", IntPtr.Size == 4 ? "System.OverflowException" : "4294967295", "conv.ovf.i.un"); - convert(baseType: "uint", fromType: "E", toType: "nuint", "uint.MaxValue", "4294967295", "conv.u", "4294967295", "conv.u"); - convert(baseType: "uint", fromType: "nint", toType: "E", "int.MinValue", "2147483648", "conv.u4", "System.OverflowException", "conv.ovf.u4"); - convert(baseType: "uint", fromType: "nint", toType: "E", "int.MaxValue", "2147483647", "conv.u4", "2147483647", "conv.ovf.u4"); - convert(baseType: "uint", fromType: "nuint", toType: "E", "uint.MaxValue", "4294967295", "conv.u4", "4294967295", "conv.ovf.u4.un"); + // IntPtr to type + verify(sourceType: "System.IntPtr", destType: "string", noConversion: true); + verify(sourceType: "System.IntPtr", destType: "void*", noConversion: true); + verify(sourceType: "System.IntPtr", destType: "delegate*", noConversion: true); + verify(sourceType: "System.IntPtr", destType: "E", noConversion: true); + verify(sourceType: "System.IntPtr", destType: "bool", noConversion: true); + verify(sourceType: "System.IntPtr", destType: "sbyte", isExplicit: true); + verify(sourceType: "System.IntPtr", destType: "byte", isExplicit: true); + verify(sourceType: "System.IntPtr", destType: "short", isExplicit: true); + verify(sourceType: "System.IntPtr", destType: "ushort", isExplicit: true); + verify(sourceType: "System.IntPtr", destType: "int", isExplicit: true); + verify(sourceType: "System.IntPtr", destType: "uint", noConversion: true); + verify(sourceType: "System.IntPtr", destType: "long"); + verify(sourceType: "System.IntPtr", destType: "ulong", noConversion: true); + verify(sourceType: "System.IntPtr", destType: "char", isExplicit: true); + verify(sourceType: "System.IntPtr", destType: "float"); + verify(sourceType: "System.IntPtr", destType: "double"); + verify(sourceType: "System.IntPtr", destType: "decimal"); + verify(sourceType: "System.IntPtr", destType: "nint"); + verify(sourceType: "System.IntPtr", destType: "nuint", noConversion: true); + verify(sourceType: "System.IntPtr", destType: "System.IntPtr"); + verify(sourceType: "System.IntPtr", destType: "System.UIntPtr", noConversion: true); - convert(baseType: "long", fromType: "E", toType: "nint", "long.MinValue", IntPtr.Size == 4 ? "0" : "-9223372036854775808", "conv.i", IntPtr.Size == 4 ? "System.OverflowException" : "-9223372036854775808", "conv.ovf.i"); - convert(baseType: "long", fromType: "E", toType: "nint", "long.MaxValue", IntPtr.Size == 4 ? "-1" : "9223372036854775807", "conv.i", IntPtr.Size == 4 ? "System.OverflowException" : "9223372036854775807", "conv.ovf.i"); - convert(baseType: "long", fromType: "E", toType: "nuint", "long.MinValue", IntPtr.Size == 4 ? "0" : "9223372036854775808", "conv.u", "System.OverflowException", "conv.ovf.u"); - convert(baseType: "long", fromType: "E", toType: "nuint", "long.MaxValue", IntPtr.Size == 4 ? "4294967295" : "9223372036854775807", "conv.u", IntPtr.Size == 4 ? "System.OverflowException" : "9223372036854775807", "conv.ovf.u"); - convert(baseType: "long", fromType: "nint", toType: "E", "int.MinValue", "-2147483648", "conv.i8", "-2147483648", "conv.i8"); - convert(baseType: "long", fromType: "nint", toType: "E", "int.MaxValue", "2147483647", "conv.i8", "2147483647", "conv.i8"); - convert(baseType: "long", fromType: "nuint", toType: "E", "uint.MaxValue", "4294967295", "conv.u8", "4294967295", "conv.ovf.i8.un"); + // type to UIntPtr + verify(sourceType: "object", destType: "System.UIntPtr", isExplicit: true); + verify(sourceType: "string", destType: "System.UIntPtr", noConversion: true); + verify(sourceType: "void*", destType: "System.UIntPtr", noConversion: true); + verify(sourceType: "delegate*", destType: "System.UIntPtr", noConversion: true); + verify(sourceType: "E", destType: "System.UIntPtr", noConversion: true); + verify(sourceType: "bool", destType: "System.UIntPtr", noConversion: true); + verify(sourceType: "sbyte", destType: "System.UIntPtr", noConversion: true); + verify(sourceType: "byte", destType: "System.UIntPtr"); + verify(sourceType: "short", destType: "System.UIntPtr", noConversion: true); + verify(sourceType: "ushort", destType: "System.UIntPtr"); + verify(sourceType: "int", destType: "System.UIntPtr", noConversion: true); + verify(sourceType: "uint", destType: "System.UIntPtr"); + verify(sourceType: "long", destType: "System.UIntPtr", noConversion: true); + verify(sourceType: "ulong", destType: "System.UIntPtr", isExplicit: true); + verify(sourceType: "char", destType: "System.UIntPtr"); + verify(sourceType: "float", destType: "System.UIntPtr", isExplicit: true); + verify(sourceType: "double", destType: "System.UIntPtr", isExplicit: true); + verify(sourceType: "decimal", destType: "System.UIntPtr", isExplicit: true); + verify(sourceType: "nint", destType: "System.UIntPtr", noConversion: true); + verify(sourceType: "nuint", destType: "System.UIntPtr"); + verify(sourceType: "System.IntPtr", destType: "System.UIntPtr", noConversion: true); + verify(sourceType: "System.UIntPtr", destType: "System.UIntPtr"); - convert(baseType: "ulong", fromType: "E", toType: "nint", "ulong.MaxValue", "-1", "conv.i", "System.OverflowException", "conv.ovf.i.un"); - convert(baseType: "ulong", fromType: "E", toType: "nuint", "ulong.MaxValue", IntPtr.Size == 4 ? "4294967295" : "18446744073709551615", "conv.u", IntPtr.Size == 4 ? "System.OverflowException" : "18446744073709551615", "conv.ovf.u.un"); - convert(baseType: "ulong", fromType: "nint", toType: "E", "int.MinValue", "18446744071562067968", "conv.i8", "System.OverflowException", "conv.ovf.u8"); - convert(baseType: "ulong", fromType: "nint", toType: "E", "int.MaxValue", "2147483647", "conv.i8", "2147483647", "conv.ovf.u8"); - convert(baseType: "ulong", fromType: "nuint", toType: "E", "uint.MaxValue", "4294967295", "conv.u8", "4294967295", "conv.u8"); + // UIntPtr to type + verify(sourceType: "System.UIntPtr", destType: "string", noConversion: true); + verify(sourceType: "System.UIntPtr", destType: "void*", noConversion: true); + verify(sourceType: "System.UIntPtr", destType: "delegate*", noConversion: true); + verify(sourceType: "System.UIntPtr", destType: "E", noConversion: true); + verify(sourceType: "System.UIntPtr", destType: "bool", noConversion: true); + verify(sourceType: "System.UIntPtr", destType: "sbyte", noConversion: true); + verify(sourceType: "System.UIntPtr", destType: "byte", isExplicit: true); + verify(sourceType: "System.UIntPtr", destType: "short", noConversion: true); + verify(sourceType: "System.UIntPtr", destType: "ushort", isExplicit: true); + verify(sourceType: "System.UIntPtr", destType: "int", noConversion: true); + verify(sourceType: "System.UIntPtr", destType: "uint", isExplicit: true); + verify(sourceType: "System.UIntPtr", destType: "long", noConversion: true); + verify(sourceType: "System.UIntPtr", destType: "ulong"); + verify(sourceType: "System.UIntPtr", destType: "char", isExplicit: true); + verify(sourceType: "System.UIntPtr", destType: "float"); + verify(sourceType: "System.UIntPtr", destType: "double"); + verify(sourceType: "System.UIntPtr", destType: "decimal"); + verify(sourceType: "System.UIntPtr", destType: "nint", noConversion: true); + verify(sourceType: "System.UIntPtr", destType: "nuint"); + verify(sourceType: "System.UIntPtr", destType: "System.IntPtr", noConversion: true); + verify(sourceType: "System.UIntPtr", destType: "System.UIntPtr"); - void convert(string baseType, string fromType, string toType, string fromValue, string toValueUnchecked, string toConvUnchecked, string toValueChecked, string toConvChecked) + void verify(string sourceType, string destType, bool noConversion = false, bool isExplicit = false) { - if (baseType != null) baseType = " : " + baseType; - string source = -$@"using System; -enum E{baseType} {{ A, B }} -class Program -{{ - static {toType} Convert({fromType} value) => ({toType})(value); - static {toType} ConvertChecked({fromType} value) => checked(({toType})(value)); - static object Execute(Func f) - {{ - try - {{ - return f(); - }} - catch (Exception e) - {{ - return e.GetType().FullName; - }} - }} - static void Main() - {{ - {fromType} value = ({fromType})({fromValue}); - Console.WriteLine(Execute(() => Convert(value))); - Console.WriteLine(Execute(() => ConvertChecked(value))); - }} -}}"; - var verifier = CompileAndVerify(source, parseOptions: TestOptions.Regular9, expectedOutput: -$@"{toValueUnchecked} -{toValueChecked}"); - verifier.VerifyIL("Program.Convert", -$@"{{ - // Code size 3 (0x3) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: {toConvUnchecked} - IL_0002: ret -}}"); - verifier.VerifyIL("Program.ConvertChecked", -$@"{{ - // Code size 3 (0x3) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: {toConvChecked} - IL_0002: ret -}}"); - } - } - - [Theory] - [InlineData("nint", "System.IntPtr")] - [InlineData("nuint", "System.UIntPtr")] - public void IdentityConversions(string nativeIntegerType, string underlyingType) - { - var source = -$@"#pragma warning disable 219 -class A {{ }} -class Program -{{ - static void F1({nativeIntegerType} x1, {nativeIntegerType}? x2, {nativeIntegerType}[] x3, A<{nativeIntegerType}> x4) - {{ - {underlyingType} y1 = x1; - {underlyingType}? y2 = x2; - {underlyingType}[] y3 = x3; - A<{underlyingType}> y4 = x4; - ({underlyingType}, {underlyingType}[]) y = (x1, x3); - }} - static void F2({underlyingType} y1, {underlyingType}? y2, {underlyingType}[] y3, A<{underlyingType}> y4) - {{ - {nativeIntegerType} x1 = y1; - {nativeIntegerType}? x2 = y2; - {nativeIntegerType}[] x3 = y3; - A<{nativeIntegerType}> x4 = y4; - ({nativeIntegerType}, {nativeIntegerType}[]) x = (y1, y3); - }} -}}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); - } + var source = $$""" +unsafe class FinalType +{ + FinalType M({{sourceType}} x) => x; + FinalType M2({{sourceType}} x) => (FinalType)x; + public static implicit operator FinalType({{destType}} i) => throw null; +} +enum E { } +"""; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }, options: TestOptions.UnsafeDebugDll); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - [Theory] - [InlineData("nint", "System.IntPtr")] - [InlineData("nuint", "System.UIntPtr")] - public void BestType_01(string nativeIntegerType, string underlyingType) - { - var source = -$@"using System; -class Program -{{ - static T F0(Func f) => f(); - static void F1(bool b, {nativeIntegerType} x, {underlyingType} y) - {{ - {nativeIntegerType} z = y; - (new[] {{ x, z }})[0].ToPointer(); - (new[] {{ x, y }})[0].ToPointer(); - (new[] {{ y, x }})[0].ToPointer(); - (b ? x : z).ToPointer(); - (b ? x : y).ToPointer(); - (b ? y : x).ToPointer(); - F0(() => {{ if (b) return x; return z; }}).ToPointer(); - F0(() => {{ if (b) return x; return y; }}).ToPointer(); - F0(() => {{ if (b) return y; return x; }}).ToPointer(); - }} -}}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (8,29): error CS1061: 'nint' does not contain a definition for 'ToPointer' and no accessible extension method 'ToPointer' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // (new[] { x, z })[0].ToPointer(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToPointer").WithArguments($"{nativeIntegerType}", "ToPointer").WithLocation(8, 29), - // (9,10): error CS0826: No best type found for implicitly-typed array - // (new[] { x, y })[0].ToPointer(); - Diagnostic(ErrorCode.ERR_ImplicitlyTypedArrayNoBestType, "new[] { x, y }").WithLocation(9, 10), - // (10,10): error CS0826: No best type found for implicitly-typed array - // (new[] { y, x })[0].ToPointer(); - Diagnostic(ErrorCode.ERR_ImplicitlyTypedArrayNoBestType, "new[] { y, x }").WithLocation(10, 10), - // (11,21): error CS1061: 'nint' does not contain a definition for 'ToPointer' and no accessible extension method 'ToPointer' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // (b ? x : z).ToPointer(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToPointer").WithArguments($"{nativeIntegerType}", "ToPointer").WithLocation(11, 21), - // (12,10): error CS0172: Type of conditional expression cannot be determined because 'nint' and 'IntPtr' implicitly convert to one another - // (b ? x : y).ToPointer(); - Diagnostic(ErrorCode.ERR_AmbigQM, "b ? x : y").WithArguments($"{nativeIntegerType}", $"{underlyingType}").WithLocation(12, 10), - // (13,10): error CS0172: Type of conditional expression cannot be determined because 'IntPtr' and 'nint' implicitly convert to one another - // (b ? y : x).ToPointer(); - Diagnostic(ErrorCode.ERR_AmbigQM, "b ? y : x").WithArguments($"{underlyingType}", $"{nativeIntegerType}").WithLocation(13, 10), - // (14,50): error CS1061: 'nint' does not contain a definition for 'ToPointer' and no accessible extension method 'ToPointer' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // F0(() => { if (b) return x; return z; }).ToPointer(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToPointer").WithArguments($"{nativeIntegerType}", "ToPointer").WithLocation(14, 50), - // (15,9): error CS0411: The type arguments for method 'Program.F0(Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly. - // F0(() => { if (b) return x; return y; }).ToPointer(); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "F0").WithArguments("Program.F0(System.Func)").WithLocation(15, 9), - // (16,9): error CS0411: The type arguments for method 'Program.F0(Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly. - // F0(() => { if (b) return y; return x; }).ToPointer(); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "F0").WithArguments("Program.F0(System.Func)").WithLocation(16, 9)); + if (noConversion) + { + comp.VerifyDiagnostics( + // (3,30): error CS0029: Cannot implicitly convert type 'sourceType' to 'FinalType' + // FinalType M(sourceType x) => x; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments(AsNative(sourceType), "FinalType"), + // (4,31): error CS0030: Cannot convert type 'sourceType' to 'FinalType' + // FinalType M2(sourceType x) => (FinalType)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(FinalType)x").WithArguments(AsNative(sourceType), "FinalType") + ); + } + else if (isExplicit) + { + comp.VerifyDiagnostics( + // (3,30): error CS0266: Cannot implicitly convert type 'sourceType' to 'FinalType'. An explicit conversion exists (are you missing a cast?) + // FinalType M(sourceType x) => x; + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments(AsNative(sourceType), "FinalType") + ); + } + else + { + comp.VerifyDiagnostics(); + } + } } [Theory] - [InlineData("nint", "System.IntPtr")] - [InlineData("nuint", "System.UIntPtr")] - public void BestType_02(string nativeIntegerType, string underlyingType) + [InlineData(true)] + [InlineData(false)] + public void VerifyUnifiedSymbols(bool useCSharp11) { - var source = -$@"using System; -interface I {{ }} -class Program -{{ - static void F0(Func f) => f(); - static void F1(bool b, {nativeIntegerType}[] x, {underlyingType}[] y) - {{ - _ = new[] {{ x, y }}; - _ = b ? x : y; - F0(() => {{ if (b) return x; return y; }}); - }} - static void F2(bool b, I<{nativeIntegerType}> x, I<{underlyingType}> y) - {{ - _ = new[] {{ x, y }}; - _ = b ? x : y; - F0(() => {{ if (b) return x; return y; }}); - }} -}}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (8,13): error CS0826: No best type found for implicitly-typed array - // _ = new[] { x, y }; - Diagnostic(ErrorCode.ERR_ImplicitlyTypedArrayNoBestType, "new[] { x, y }").WithLocation(8, 13), - // (9,13): error CS0172: Type of conditional expression cannot be determined because 'nint[]' and 'IntPtr[]' implicitly convert to one another - // _ = b ? x : y; - Diagnostic(ErrorCode.ERR_AmbigQM, "b ? x : y").WithArguments($"{nativeIntegerType}[]", $"{underlyingType}[]").WithLocation(9, 13), - // (10,9): error CS0411: The type arguments for method 'Program.F0(Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly. - // F0(() => { if (b) return x; return y; }); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "F0").WithArguments("Program.F0(System.Func)").WithLocation(10, 9), - // (14,13): error CS0826: No best type found for implicitly-typed array - // _ = new[] { x, y }; - Diagnostic(ErrorCode.ERR_ImplicitlyTypedArrayNoBestType, "new[] { x, y }").WithLocation(14, 13), - // (15,13): error CS0172: Type of conditional expression cannot be determined because 'I' and 'I' implicitly convert to one another - // _ = b ? x : y; - Diagnostic(ErrorCode.ERR_AmbigQM, "b ? x : y").WithArguments($"I<{nativeIntegerType}>", $"I<{underlyingType}>").WithLocation(15, 13), - // (16,9): error CS0411: The type arguments for method 'Program.F0(Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly. - // F0(() => { if (b) return x; return y; }); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "F0").WithArguments("Program.F0(System.Func)").WithLocation(16, 9)); - } + var corlib_cs = RuntimeFeature_NumericIntPtr + @" +namespace System +{ + public struct IntPtr { } + public struct UIntPtr { } - [Theory] - [InlineData("nint", "System.IntPtr")] - [InlineData("nuint", "System.UIntPtr")] - public void MethodTypeInference(string nativeIntegerType, string underlyingType) - { - var source = -$@"interface I -{{ - T P {{ get; }} -}} -unsafe class Program -{{ - static T F0(T x, T y) => x; - static void F1({nativeIntegerType} x, {underlyingType} y) - {{ - var z = ({nativeIntegerType})y; - F0(x, z).ToPointer(); - F0(x, y).ToPointer(); - F0(y, x).ToPointer(); - F0<{nativeIntegerType}>(x, y). - ToPointer(); - F0<{underlyingType}>(x, y). - ToPointer(); - }} - static void F2({nativeIntegerType}[] x, {underlyingType}[] y) - {{ - var z = ({nativeIntegerType}[])y; - F0(x, z)[0].ToPointer(); - F0(x, y)[0].ToPointer(); - F0(y, x)[0].ToPointer(); - F0<{nativeIntegerType}[]>(x, y)[0]. - ToPointer(); - F0<{underlyingType}[]>(x, y)[0]. - ToPointer(); - }} - static void F3(I<{nativeIntegerType}> x, I<{underlyingType}> y) - {{ - var z = (I<{nativeIntegerType}>)y; - F0(x, z).P.ToPointer(); - F0(x, y).P.ToPointer(); - F0(y, x).P.ToPointer(); - F0>(x, y).P. - ToPointer(); - F0>(x, y).P. - ToPointer(); - }} -}}"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9, options: TestOptions.UnsafeReleaseDll); - comp.VerifyDiagnostics( - // (11,18): error CS1061: 'nint' does not contain a definition for 'ToPointer' and no accessible extension method 'ToPointer' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // F0(x, z).ToPointer(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToPointer").WithArguments($"{nativeIntegerType}", "ToPointer").WithLocation(11, 18), - // (12,9): error CS0411: The type arguments for method 'Program.F0(T, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly. - // F0(x, y).ToPointer(); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "F0").WithArguments("Program.F0(T, T)").WithLocation(12, 9), - // (13,9): error CS0411: The type arguments for method 'Program.F0(T, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly. - // F0(y, x).ToPointer(); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "F0").WithArguments("Program.F0(T, T)").WithLocation(13, 9), - // (15,13): error CS1061: 'nint' does not contain a definition for 'ToPointer' and no accessible extension method 'ToPointer' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // ToPointer(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToPointer").WithArguments($"{nativeIntegerType}", "ToPointer").WithLocation(15, 13), - // (22,21): error CS1061: 'nint' does not contain a definition for 'ToPointer' and no accessible extension method 'ToPointer' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // F0(x, z)[0].ToPointer(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToPointer").WithArguments($"{nativeIntegerType}", "ToPointer").WithLocation(22, 21), - // (23,9): error CS0411: The type arguments for method 'Program.F0(T, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly. - // F0(x, y)[0].ToPointer(); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "F0").WithArguments("Program.F0(T, T)").WithLocation(23, 9), - // (24,9): error CS0411: The type arguments for method 'Program.F0(T, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly. - // F0(y, x)[0].ToPointer(); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "F0").WithArguments("Program.F0(T, T)").WithLocation(24, 9), - // (26,13): error CS1061: 'nint' does not contain a definition for 'ToPointer' and no accessible extension method 'ToPointer' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // ToPointer(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToPointer").WithArguments($"{nativeIntegerType}", "ToPointer").WithLocation(26, 13), - // (33,20): error CS1061: 'nint' does not contain a definition for 'ToPointer' and no accessible extension method 'ToPointer' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // F0(x, z).P.ToPointer(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToPointer").WithArguments($"{nativeIntegerType}", "ToPointer").WithLocation(33, 20), - // (34,9): error CS0411: The type arguments for method 'Program.F0(T, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly. - // F0(x, y).P.ToPointer(); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "F0").WithArguments("Program.F0(T, T)").WithLocation(34, 9), - // (35,9): error CS0411: The type arguments for method 'Program.F0(T, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly. - // F0(y, x).P.ToPointer(); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "F0").WithArguments("Program.F0(T, T)").WithLocation(35, 9), - // (37,13): error CS1061: 'nint' does not contain a definition for 'ToPointer' and no accessible extension method 'ToPointer' accepting a first argument of type 'nint' could be found (are you missing a using directive or an assembly reference?) - // ToPointer(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ToPointer").WithArguments($"{nativeIntegerType}", "ToPointer").WithLocation(37, 13)); + public class Object { } + public class String { } + public class ValueType { } + public struct Void { } +} +"; + + var source = @" +interface I +{ + void M(nint x1, System.IntPtr x2, nuint x3, System.UIntPtr x4); +} +"; + var parseOptions = useCSharp11 ? TestOptions.RegularNext : TestOptions.Regular10; + + var comp = CreateEmptyCompilation(new[] { source, corlib_cs }, parseOptions: parseOptions); + verify(comp); + + var corlib = CreateEmptyCompilation(corlib_cs, parseOptions: parseOptions); + corlib.VerifyDiagnostics(); + + comp = CreateEmptyCompilation(source, references: new[] { corlib.ToMetadataReference() }, parseOptions: parseOptions); + verify(comp); + + comp = CreateEmptyCompilation(source, references: new[] { corlib.EmitToImageReference() }, parseOptions: parseOptions); + verify(comp); + + void verify(CSharpCompilation comp) + { + comp.VerifyDiagnostics(); + + var emitOptions = new EmitOptions(runtimeMetadataVersion: "v5.1"); + comp.VerifyEmitDiagnostics(emitOptions); + + var method = (MethodSymbol)comp.GlobalNamespace.GetMember("I.M"); + + var nintType = method.Parameters[0].Type; + verifyIntPtr(nintType); + verifyCommon(nintType); + + var intPtrType = method.Parameters[1].Type; + verifyIntPtr(intPtrType); + verifyCommon(nintType); + Assert.Same(nintType, intPtrType); + Assert.Same(nintType, comp.GetSpecialType(SpecialType.System_IntPtr)); + var fromAPI = comp.CreateNativeIntegerTypeSymbol(signed: true); + Assert.Same(nintType, fromAPI); + Assert.False(fromAPI.IsNativeIntegerWrapperType); + + var nuintType = method.Parameters[2].Type; + verifyUIntPtr(nuintType); + verifyCommon(nintType); + + var uintPtrType = method.Parameters[3].Type; + verifyUIntPtr(uintPtrType); + verifyCommon(nintType); + Assert.Same(nuintType, uintPtrType); + Assert.Same(nuintType, comp.GetSpecialType(SpecialType.System_UIntPtr)); + fromAPI = comp.CreateNativeIntegerTypeSymbol(signed: false); + Assert.Same(nuintType, fromAPI); + Assert.False(fromAPI.IsNativeIntegerWrapperType); + + VerifyNoNativeIntegerAttributeEmitted(comp); + } + + static void verifyIntPtr(TypeSymbol type) + { + Assert.Equal(SpecialType.System_IntPtr, type.SpecialType); + Assert.Equal("nint", type.ToTestDisplayString()); + Assert.Equal("nint", type.ToDisplayString(SymbolDisplayFormat.TestFormat)); + Assert.Equal("System.IntPtr", type.ToDisplayString(SymbolDisplayFormat.TestFormat.WithCompilerInternalOptions(SymbolDisplayCompilerInternalOptions.UseNativeIntegerUnderlyingType))); + Assert.Equal("nint", type.ToDisplayString(SymbolDisplayFormat.TestFormat.WithMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.UseSpecialTypes))); + } + + static void verifyUIntPtr(TypeSymbol type) + { + Assert.Equal(SpecialType.System_UIntPtr, type.SpecialType); + Assert.Equal("nuint", type.ToTestDisplayString()); + Assert.Equal("nuint", type.ToDisplayString(SymbolDisplayFormat.TestFormat)); + Assert.Equal("System.UIntPtr", type.ToDisplayString(SymbolDisplayFormat.TestFormat.WithCompilerInternalOptions(SymbolDisplayCompilerInternalOptions.UseNativeIntegerUnderlyingType))); + Assert.Equal("nuint", type.ToDisplayString(SymbolDisplayFormat.TestFormat.WithMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.UseSpecialTypes))); + } + + static void verifyCommon(TypeSymbol type) + { + Assert.True(type.IsDefinition); + Assert.False(type.IsNativeIntegerWrapperType); + Assert.Null(((NamedTypeSymbol)type).NativeIntegerUnderlyingType); + } } [Fact] - public void DuplicateConstraint() + public void NoAttributesEmitted() { - var source = -@"interface I { } -class C1 where U : I, I { } -class C2 where U : I, I { } -class C3 where U : I, I, I { } -"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (2,35): error CS0405: Duplicate constraint 'I' for type parameter 'U' - // class C1 where U : I, I { } - Diagnostic(ErrorCode.ERR_DuplicateBound, "I").WithArguments("I", "U").WithLocation(2, 35), - // (3,35): error CS0405: Duplicate constraint 'I' for type parameter 'U' - // class C2 where U : I, I { } - Diagnostic(ErrorCode.ERR_DuplicateBound, "I").WithArguments("I", "U").WithLocation(3, 35), - // (4,63): error CS0405: Duplicate constraint 'I' for type parameter 'U' - // class C3 where U : I, I, I { } - Diagnostic(ErrorCode.ERR_DuplicateBound, "I").WithArguments("I", "U").WithLocation(4, 63)); + var source = @" +interface I { } + +class C1 : I { } +class C2 : I { } +class C3 : I { } +class C4 : I { } + +class Base { } + +class D1 : Base { } +class D2 : Base { } +class D3 : Base { } +class D4 : Base { } + +class Misc +{ + Misc(nint x1, System.IntPtr x2, nuint x3, System.UIntPtr x4) { } + + nint M1() => throw null; + System.IntPtr M2() => throw null; + nuint M3() => throw null; + System.UIntPtr M4() => throw null; + + void Lambdas() + { + var lambda1 = nint () => throw null; + var lambda2 = System.IntPtr () => throw null; + var lambda3 = nuint () => throw null; + var lambda4 = System.UIntPtr () => throw null; + + var lambda5 = void (nint x1, System.IntPtr x2, nuint x3, System.UIntPtr x4) => throw null; } - [Fact] - public void DuplicateInterface_01() + void LocalFunctions() { - var source = -@"interface I { } -class C1 : I, I { } -class C2 : I, I { } -class C3 : I, I, I { } + local1(); + local2(); + local3(); + local4(); + local5(0, 0, 0, 0); + + nint local1() => throw null; + System.IntPtr local2() => throw null; + nuint local3() => throw null; + System.UIntPtr local4() => throw null; + + void local5(nint x1, System.IntPtr x2, nuint x3, System.UIntPtr x4) { } + } +} + +delegate nint Delegate1(nint x); +delegate System.IntPtr Delegate2(System.IntPtr x); +delegate nuint Delegate3(nuint x); +delegate System.UIntPtr Delegate4(System.UIntPtr x); + +class Operators +{ + public static implicit operator Operators(nint x) => throw null; + public static implicit operator Operators(nuint x) => throw null; +} +class Operators2 +{ + public static implicit operator Operators2(System.IntPtr x) => throw null; + public static implicit operator Operators2(System.UIntPtr x) => throw null; +} + +class Constraints + where T1 : I + where T2 : I + where T3 : I + where T4 : I +{ +} + +class Properties +{ + nint Property1 { get; set; } + System.IntPtr Property2 { get; set; } + nuint Property3 { get; set; } + System.UIntPtr Property4 { get; set; } +} + +class Indexers +{ + nint this[nint x] => throw null; + nuint this[nuint x] => throw null; +} +class Indexers2 +{ + System.IntPtr Property2 => throw null; + System.UIntPtr Property4 => throw null; +} "; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (2,21): error CS0528: 'I' is already listed in interface list - // class C1 : I, I { } - Diagnostic(ErrorCode.ERR_DuplicateInterfaceInBaseList, "I").WithArguments("I").WithLocation(2, 21), - // (3,7): error CS8779: 'I' is already listed in the interface list on type 'C2' as 'I'. - // class C2 : I, I { } - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C2").WithArguments("I", "I", "C2").WithLocation(3, 7), - // (4,7): error CS8779: 'I' is already listed in the interface list on type 'C3' as 'I'. - // class C3 : I, I, I { } - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C3").WithArguments("I", "I", "C3").WithLocation(4, 7)); + var comp = CreateEmptyCompilation(new[] { source }, references: new[] { MscorlibRefWithoutSharingCachedSymbols }); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + + comp.VerifyDiagnostics(); + VerifyNoNativeIntegerAttributeEmitted(comp); } [Fact] - public void DuplicateInterface_02() + public void UserDefinedConversionOnSystemIntPtr() { - var source = -@"interface I { } -#nullable enable -class C1 : - I, - I -{ } -class C2 : - I, -#nullable disable - I -{ } -class C3 : - I, -#nullable enable - I -{ }"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (3,7): error CS8779: 'I' is already listed in the interface list on type 'C1' as 'I'. - // class C1 : - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C1").WithArguments("I", "I", "C1").WithLocation(3, 7), - // (7,7): error CS8779: 'I' is already listed in the interface list on type 'C2' as 'I'. - // class C2 : - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C2").WithArguments("I", "I", "C2").WithLocation(7, 7), - // (12,7): error CS8779: 'I' is already listed in the interface list on type 'C3' as 'I'. - // class C3 : - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C3").WithArguments("I", "I", "C3").WithLocation(12, 7)); + var corlib_cs = RuntimeFeature_NumericIntPtr + @" +namespace System +{ + public struct IntPtr + { + public static implicit operator IntPtr(String s) { return 0; } + } + public struct UIntPtr + { + public static implicit operator UIntPtr(String s) { return 0; } } - [Fact] - public void DuplicateInterface_03() + public class Object { } + public class String { } + public class ValueType { } + public struct Void { } + public struct Int32 { } + + public class Exception { } +} +"; + var source = @" +class C +{ + nint M1(string s) { - var source = -@"#nullable enable -interface I { } -class C0 : I<(System.IntPtr, object)>, I<(System.IntPtr, object)> { } // differences: none -class C1 : I<(System.IntPtr X, object Y)>, I<(System.IntPtr, object)> { } // differences: names -class C2 : I<(System.IntPtr, object)>, I<(nint, object)> { } // differences: nint -class C3 : I<(System.IntPtr, object)>, I<(System.IntPtr, dynamic)> { } // differences: dynamic -class C4 : I<(System.IntPtr, object?)>, I<(System.IntPtr, object)> { } // differences: nullable -class C5 : I<(System.IntPtr X, object Y)>, I<(nint, object)> { } // differences: names, nint -class C6 : I<(System.IntPtr X, object Y)>, I<(System.IntPtr, dynamic)> { } // differences: names, dynamic -class C7 : I<(System.IntPtr X, object? Y)>, I<(System.IntPtr, object)> { } // differences: names, nullable -class C8 : I<(System.IntPtr, object)>, I<(nint, dynamic)> { } // differences: nint, dynamic -class C9 : I<(System.IntPtr, object?)>, I<(nint, object)> { } // differences: nint, nullable -class CA : I<(System.IntPtr, object?)>, I<(nint, dynamic)> { } // differences: dynamic, nullable -class CB : I<(System.IntPtr X, object Y)>, I<(nint, dynamic)> { } // differences: names, nint, dynamic -class CC : I<(System.IntPtr X, object? Y)>, I<(nint, object)> { } // differences: names, nint, nullable -class CD : I<(System.IntPtr, object?)>, I<(nint, dynamic)> { } // differences: nint, dynamic, nullable -class CE : I<(System.IntPtr X, object? Y)>, I<(nint, dynamic)> { } // differences: names, dynamic, nullable -class CF : I<(System.IntPtr X, object? Y)>, I<(nint, dynamic)> { } // differences: names, nint, dynamic, nullable + return s; + } + nuint M2(string s) + { + return s; + } +} "; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (3,40): error CS0528: 'I<(IntPtr, object)>' is already listed in interface list - // class C0 : I<(System.IntPtr, object)>, I<(System.IntPtr, object)> { } // differences: none - Diagnostic(ErrorCode.ERR_DuplicateInterfaceInBaseList, "I<(System.IntPtr, object)>").WithArguments("I<(System.IntPtr, object)>").WithLocation(3, 40), - // (4,7): error CS8140: 'I<(IntPtr, object)>' is already listed in the interface list on type 'C1' with different tuple element names, as 'I<(IntPtr X, object Y)>'. - // class C1 : I<(System.IntPtr X, object Y)>, I<(System.IntPtr, object)> { } // differences: names - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithTupleNamesInBaseList, "C1").WithArguments("I<(System.IntPtr, object)>", "I<(System.IntPtr X, object Y)>", "C1").WithLocation(4, 7), - // (5,7): error CS8779: 'I<(nint, object)>' is already listed in the interface list on type 'C2' as 'I<(IntPtr, object)>'. - // class C2 : I<(System.IntPtr, object)>, I<(nint, object)> { } // differences: nint - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C2").WithArguments("I<(nint, object)>", "I<(System.IntPtr, object)>", "C2").WithLocation(5, 7), - // (6,7): error CS8779: 'I<(IntPtr, dynamic)>' is already listed in the interface list on type 'C3' as 'I<(IntPtr, object)>'. - // class C3 : I<(System.IntPtr, object)>, I<(System.IntPtr, dynamic)> { } // differences: dynamic - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C3").WithArguments("I<(System.IntPtr, dynamic)>", "I<(System.IntPtr, object)>", "C3").WithLocation(6, 7), - // (6,40): error CS1966: 'C3': cannot implement a dynamic interface 'I<(IntPtr, dynamic)>' - // class C3 : I<(System.IntPtr, object)>, I<(System.IntPtr, dynamic)> { } // differences: dynamic - Diagnostic(ErrorCode.ERR_DeriveFromConstructedDynamic, "I<(System.IntPtr, dynamic)>").WithArguments("C3", "I<(System.IntPtr, dynamic)>").WithLocation(6, 40), - // (7,7): warning CS8645: 'I<(IntPtr, object)>' is already listed in the interface list on type 'C4' with different nullability of reference types. - // class C4 : I<(System.IntPtr, object?)>, I<(System.IntPtr, object)> { } // differences: nullable - Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "C4").WithArguments("I<(System.IntPtr, object)>", "C4").WithLocation(7, 7), - // (8,7): error CS8779: 'I<(nint, object)>' is already listed in the interface list on type 'C5' as 'I<(IntPtr X, object Y)>'. - // class C5 : I<(System.IntPtr X, object Y)>, I<(nint, object)> { } // differences: names, nint - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C5").WithArguments("I<(nint, object)>", "I<(System.IntPtr X, object Y)>", "C5").WithLocation(8, 7), - // (9,7): error CS8779: 'I<(IntPtr, dynamic)>' is already listed in the interface list on type 'C6' as 'I<(IntPtr X, object Y)>'. - // class C6 : I<(System.IntPtr X, object Y)>, I<(System.IntPtr, dynamic)> { } // differences: names, dynamic - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C6").WithArguments("I<(System.IntPtr, dynamic)>", "I<(System.IntPtr X, object Y)>", "C6").WithLocation(9, 7), - // (9,44): error CS1966: 'C6': cannot implement a dynamic interface 'I<(IntPtr, dynamic)>' - // class C6 : I<(System.IntPtr X, object Y)>, I<(System.IntPtr, dynamic)> { } // differences: names, dynamic - Diagnostic(ErrorCode.ERR_DeriveFromConstructedDynamic, "I<(System.IntPtr, dynamic)>").WithArguments("C6", "I<(System.IntPtr, dynamic)>").WithLocation(9, 44), - // (10,7): error CS8140: 'I<(IntPtr, object)>' is already listed in the interface list on type 'C7' with different tuple element names, as 'I<(IntPtr X, object? Y)>'. - // class C7 : I<(System.IntPtr X, object? Y)>, I<(System.IntPtr, object)> { } // differences: names, nullable - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithTupleNamesInBaseList, "C7").WithArguments("I<(System.IntPtr, object)>", "I<(System.IntPtr X, object? Y)>", "C7").WithLocation(10, 7), - // (11,7): error CS8779: 'I<(nint, dynamic)>' is already listed in the interface list on type 'C8' as 'I<(IntPtr, object)>'. - // class C8 : I<(System.IntPtr, object)>, I<(nint, dynamic)> { } // differences: nint, dynamic - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C8").WithArguments("I<(nint, dynamic)>", "I<(System.IntPtr, object)>", "C8").WithLocation(11, 7), - // (11,40): error CS1966: 'C8': cannot implement a dynamic interface 'I<(nint, dynamic)>' - // class C8 : I<(System.IntPtr, object)>, I<(nint, dynamic)> { } // differences: nint, dynamic - Diagnostic(ErrorCode.ERR_DeriveFromConstructedDynamic, "I<(nint, dynamic)>").WithArguments("C8", "I<(nint, dynamic)>").WithLocation(11, 40), - // (12,7): error CS8779: 'I<(nint, object)>' is already listed in the interface list on type 'C9' as 'I<(IntPtr, object?)>'. - // class C9 : I<(System.IntPtr, object?)>, I<(nint, object)> { } // differences: nint, nullable - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C9").WithArguments("I<(nint, object)>", "I<(System.IntPtr, object?)>", "C9").WithLocation(12, 7), - // (13,7): error CS8779: 'I<(nint, dynamic)>' is already listed in the interface list on type 'CA' as 'I<(IntPtr, object?)>'. - // class CA : I<(System.IntPtr, object?)>, I<(nint, dynamic)> { } // differences: dynamic, nullable - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "CA").WithArguments("I<(nint, dynamic)>", "I<(System.IntPtr, object?)>", "CA").WithLocation(13, 7), - // (13,41): error CS1966: 'CA': cannot implement a dynamic interface 'I<(nint, dynamic)>' - // class CA : I<(System.IntPtr, object?)>, I<(nint, dynamic)> { } // differences: dynamic, nullable - Diagnostic(ErrorCode.ERR_DeriveFromConstructedDynamic, "I<(nint, dynamic)>").WithArguments("CA", "I<(nint, dynamic)>").WithLocation(13, 41), - // (14,7): error CS8779: 'I<(nint, dynamic)>' is already listed in the interface list on type 'CB' as 'I<(IntPtr X, object Y)>'. - // class CB : I<(System.IntPtr X, object Y)>, I<(nint, dynamic)> { } // differences: names, nint, dynamic - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "CB").WithArguments("I<(nint, dynamic)>", "I<(System.IntPtr X, object Y)>", "CB").WithLocation(14, 7), - // (14,44): error CS1966: 'CB': cannot implement a dynamic interface 'I<(nint, dynamic)>' - // class CB : I<(System.IntPtr X, object Y)>, I<(nint, dynamic)> { } // differences: names, nint, dynamic - Diagnostic(ErrorCode.ERR_DeriveFromConstructedDynamic, "I<(nint, dynamic)>").WithArguments("CB", "I<(nint, dynamic)>").WithLocation(14, 44), - // (15,7): error CS8779: 'I<(nint, object)>' is already listed in the interface list on type 'CC' as 'I<(IntPtr X, object? Y)>'. - // class CC : I<(System.IntPtr X, object? Y)>, I<(nint, object)> { } // differences: names, nint, nullable - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "CC").WithArguments("I<(nint, object)>", "I<(System.IntPtr X, object? Y)>", "CC").WithLocation(15, 7), - // (16,7): error CS8779: 'I<(nint, dynamic)>' is already listed in the interface list on type 'CD' as 'I<(IntPtr, object?)>'. - // class CD : I<(System.IntPtr, object?)>, I<(nint, dynamic)> { } // differences: nint, dynamic, nullable - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "CD").WithArguments("I<(nint, dynamic)>", "I<(System.IntPtr, object?)>", "CD").WithLocation(16, 7), - // (16,41): error CS1966: 'CD': cannot implement a dynamic interface 'I<(nint, dynamic)>' - // class CD : I<(System.IntPtr, object?)>, I<(nint, dynamic)> { } // differences: nint, dynamic, nullable - Diagnostic(ErrorCode.ERR_DeriveFromConstructedDynamic, "I<(nint, dynamic)>").WithArguments("CD", "I<(nint, dynamic)>").WithLocation(16, 41), - // (17,7): error CS8779: 'I<(nint, dynamic)>' is already listed in the interface list on type 'CE' as 'I<(IntPtr X, object? Y)>'. - // class CE : I<(System.IntPtr X, object? Y)>, I<(nint, dynamic)> { } // differences: names, dynamic, nullable - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "CE").WithArguments("I<(nint, dynamic)>", "I<(System.IntPtr X, object? Y)>", "CE").WithLocation(17, 7), - // (17,45): error CS1966: 'CE': cannot implement a dynamic interface 'I<(nint, dynamic)>' - // class CE : I<(System.IntPtr X, object? Y)>, I<(nint, dynamic)> { } // differences: names, dynamic, nullable - Diagnostic(ErrorCode.ERR_DeriveFromConstructedDynamic, "I<(nint, dynamic)>").WithArguments("CE", "I<(nint, dynamic)>").WithLocation(17, 45), - // (18,7): error CS8779: 'I<(nint, dynamic)>' is already listed in the interface list on type 'CF' as 'I<(IntPtr X, object? Y)>'. - // class CF : I<(System.IntPtr X, object? Y)>, I<(nint, dynamic)> { } // differences: names, nint, dynamic, nullable - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "CF").WithArguments("I<(nint, dynamic)>", "I<(System.IntPtr X, object? Y)>", "CF").WithLocation(18, 7), - // (18,45): error CS1966: 'CF': cannot implement a dynamic interface 'I<(nint, dynamic)>' - // class CF : I<(System.IntPtr X, object? Y)>, I<(nint, dynamic)> { } // differences: names, nint, dynamic, nullable - Diagnostic(ErrorCode.ERR_DeriveFromConstructedDynamic, "I<(nint, dynamic)>").WithArguments("CF", "I<(nint, dynamic)>").WithLocation(18, 45)); + var comp = CreateEmptyCompilation(new[] { source, corlib_cs }); + comp.VerifyDiagnostics(); + var tree = comp.SyntaxTrees[0]; + var model = comp.GetSemanticModel(tree); + var returnStatements = tree.GetRoot().DescendantNodes().OfType().ToArray(); + Assert.Equal("nint nint.op_Implicit(System.String s)", model.GetConversion(returnStatements[0].Expression).Method.ToTestDisplayString()); + Assert.Equal("nuint nuint.op_Implicit(System.String s)", model.GetConversion(returnStatements[1].Expression).Method.ToTestDisplayString()); } [Fact] - public void DuplicateInterface_04() + public void GenericAttribute_AttributeDependentTypes() { - var source = -@"interface IA { } -interface IB1 : IA { } -interface IB2 : IA { } -class C1 : IA, IB1 { } -class C2 : IB2, IA { } -class C3 : IB1, IB2 { } -class C4 : IB1, IB2 { } + var source = @" +#nullable enable +using System; + +[AttributeUsage(AttributeTargets.All, AllowMultiple = true)] +class Attr : Attribute { } + +[Attr] +[Attr>] +[Attr] +[Attr>] +class C1 { } + +[Attr] +[Attr>] +[Attr] +[Attr>] +class C2 { } + +class D { } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (4,7): error CS8779: 'IA' is already listed in the interface list on type 'C1' as 'IA'. - // class C1 : IA, IB1 { } - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C1").WithArguments("IA", "IA", "C1").WithLocation(4, 7), - // (5,7): error CS8779: 'IA' is already listed in the interface list on type 'C2' as 'IA'. - // class C2 : IB2, IA { } - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C2").WithArguments("IA", "IA", "C2").WithLocation(5, 7), - // (6,7): error CS8779: 'IA' is already listed in the interface list on type 'C3' as 'IA'. - // class C3 : IB1, IB2 { } - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C3").WithArguments("IA", "IA", "C3").WithLocation(6, 7)); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + comp.VerifyDiagnostics(); } [Fact] - public void DuplicateInterface_05() + public void UnmanagedConstraint() { - var source = -@"interface IA { } -interface IB1 : IA { } -interface IB2 : IA { } -partial class C1 : IA { } -partial class C1 : IB1 { } -partial class C2 : IB2 { } -partial class C2 : IA { } -partial class C3 : IB1 { } -partial class C3 : IB2 { } -partial class C4 : IB1 { } -partial class C4 : IB2 { } + var source = @" +class C where T : unmanaged { } +class D : C { } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (4,15): error CS8779: 'IA' is already listed in the interface list on type 'C1' as 'IA'. - // partial class C1 : IA { } - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C1").WithArguments("IA", "IA", "C1").WithLocation(4, 15), - // (6,15): error CS8779: 'IA' is already listed in the interface list on type 'C2' as 'IA'. - // partial class C2 : IB2 { } - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C2").WithArguments("IA", "IA", "C2").WithLocation(6, 15), - // (8,15): error CS8779: 'IA' is already listed in the interface list on type 'C3' as 'IA'. - // partial class C3 : IB1 { } - Diagnostic(ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList, "C3").WithArguments("IA", "IA", "C3").WithLocation(8, 15)); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + + comp.VerifyDiagnostics(); + } + + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void RecordStructIntPtr(bool useCompilationReference) + { + var sourceA = +@"namespace System +{ + public class Object + { + public virtual bool Equals(object other) => default; + public virtual int GetHashCode() => default; + public virtual string ToString() => default; + } + public class String { } + public abstract class ValueType { } + public struct Void { } + public struct Boolean { } + public struct Int32 { } + public struct Char { } + public class Exception { } + public interface IEquatable + { + bool Equals(T other); + } + public class Attribute { } + public class AttributeUsageAttribute : Attribute + { + public AttributeUsageAttribute(AttributeTargets validOn) { } + public bool AllowMultiple { get; set; } + public bool Inherited { get; set; } + } + public class Enum { } + public enum AttributeTargets { } + public record struct IntPtr + { + public static readonly IntPtr Zero; + public static int Size => 0; + public static IntPtr MaxValue => default; + public static IntPtr MinValue => default; + public static IntPtr Add(IntPtr ptr, int offset) => default; + public static IntPtr Subtract(IntPtr ptr, int offset) => default; + public static IntPtr Parse(string s) => default; + public static bool TryParse(string s, out IntPtr value) + { + value = default; + return false; + } + } + public record struct UIntPtr + { + public static readonly UIntPtr Zero; + public static int Size => 0; + public static UIntPtr MaxValue => default; + public static UIntPtr MinValue => default; + public static UIntPtr Add(UIntPtr ptr, int offset) => default; + public static UIntPtr Subtract(UIntPtr ptr, int offset) => default; + public static UIntPtr Parse(string s) => default; + public static bool TryParse(string s, out UIntPtr value) + { + value = default; + return false; + } + } +} +namespace System.Text +{ + public class StringBuilder + { + public StringBuilder Append(string s) => null; + public StringBuilder Append(char c) => null; + public StringBuilder Append(object o) => null; + } +} +" + RuntimeFeature_NumericIntPtr; + + var comp = CreateEmptyCompilation(sourceA); + comp.VerifyDiagnostics(); + var refA = AsReference(comp, useCompilationReference); + + var sourceB = +@"class Program +{ + static nint F1() => throw null; + static nuint F2() => throw null; + static System.IntPtr F3() => throw null; + static System.UIntPtr F4() => throw null; +}"; + + comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9); + comp.VerifyDiagnostics(); + + var tree = comp.SyntaxTrees[0]; + var model = comp.GetSemanticModel(tree); + var methods = tree.GetRoot().DescendantNodes().OfType().ToArray(); + Assert.Equal(4, methods.Count()); + foreach (var method in methods) + { + var returnType = model.GetDeclaredSymbol(method).ReturnType; + // record structs are erased in metadata + Assert.Equal(useCompilationReference || returnType.IsReferenceType, returnType.IsRecord); + } } [Fact] - public void TypeUnification_01() + public void ArrayAccess() { - var source = -@"interface I { } -class C1 : I, I { } -class C2 : I<(nint, T)>, I<(T, System.IntPtr)> { } -class C3 : I<(T, T)>, I<(System.UIntPtr, nuint)> { } -class C4 : I<(T, T)>, I<(nint, nuint)> { } + var source = @" +var array = new[] { 1, 2, 3, 4 }; +nint x1 = 0; +System.IntPtr x2 = 1; +nuint x3 = 2; +System.UIntPtr x4 = 3; + +System.Console.Write($""{array[x1]}, {array[x2]}, {array[x3]}, {array[x4]}""); "; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (2,7): error CS0695: 'C1' cannot implement both 'I' and 'I' because they may unify for some type parameter substitutions - // class C1 : I, I { } - Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C1").WithArguments("C1", "I", "I").WithLocation(2, 7), - // (3,7): error CS0695: 'C2' cannot implement both 'I<(nint, T)>' and 'I<(T, IntPtr)>' because they may unify for some type parameter substitutions - // class C2 : I<(nint, T)>, I<(T, System.IntPtr)> { } - Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C2").WithArguments("C2", "I<(nint, T)>", "I<(T, System.IntPtr)>").WithLocation(3, 7), - // (4,7): error CS0695: 'C3' cannot implement both 'I<(T, T)>' and 'I<(UIntPtr, nuint)>' because they may unify for some type parameter substitutions - // class C3 : I<(T, T)>, I<(System.UIntPtr, nuint)> { } - Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C3").WithArguments("C3", "I<(T, T)>", "I<(System.UIntPtr, nuint)>").WithLocation(4, 7)); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + + CompileAndVerify(comp, expectedOutput: "1, 2, 3, 4"); } [Fact] - public void TypeUnification_02() + public void NativeIntegerAttributeFromMetadata() { - var source = -@"interface IA { } -interface IB1 : IA { } -interface IB2 : IA { } -class C1 : IB1, IB2 { } -class C2 : IB1<(nint, T)>, IB2<(T, System.IntPtr)> { } -class C3 : IB1<(T, T)>, IB2<(System.UIntPtr, nuint)> { } -class C4 : IB1<(T, T)>, IB2<(nint, nuint)> { } -"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (4,7): error CS0695: 'C1' cannot implement both 'IA' and 'IA' because they may unify for some type parameter substitutions - // class C1 : IB1, IB2 { } - Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C1").WithArguments("C1", "IA", "IA").WithLocation(4, 7), - // (5,7): error CS0695: 'C2' cannot implement both 'IA<(nint, T)>' and 'IA<(T, IntPtr)>' because they may unify for some type parameter substitutions - // class C2 : IB1<(nint, T)>, IB2<(T, System.IntPtr)> { } - Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C2").WithArguments("C2", "IA<(nint, T)>", "IA<(T, System.IntPtr)>").WithLocation(5, 7), - // (6,7): error CS0695: 'C3' cannot implement both 'IA<(T, T)>' and 'IA<(UIntPtr, nuint)>' because they may unify for some type parameter substitutions - // class C3 : IB1<(T, T)>, IB2<(System.UIntPtr, nuint)> { } - Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C3").WithArguments("C3", "IA<(T, T)>", "IA<(System.UIntPtr, nuint)>").WithLocation(6, 7)); + var source = @" +public class C +{ + public nint M() { throw null; } +}"; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }); + var image = comp.EmitToImageReference(); + + var comp2 = CreateEmptyCompilation(source, references: new[] { image, MscorlibRefWithoutSharingCachedSymbols }); + comp2.Assembly.RuntimeSupportsNumericIntPtr = true; + + CompileAndVerify(comp2, sourceSymbolValidator: verify, symbolValidator: verify); + + static void verify(ModuleSymbol module) + { + var m = (MethodSymbol)module.GlobalNamespace.GetMember("C.M"); + Assert.Equal("nint C.M()", m.ToTestDisplayString()); + Assert.False(m.ReturnType.IsNativeIntegerWrapperType); + } } [Fact] - public void TypeUnification_03() + public void PatternExplainer() { - var source = -@"interface IA { } -interface IB1 : IA { } -interface IB2 : IA { } -partial class C1 : IB1 { } -partial class C1 : IB2 { } -partial class C2 : IB1<(nint, T)> { } -partial class C2 : IB2<(T, System.IntPtr)> { } -partial class C3 : IB1<(T, T)> { } -partial class C3 : IB2<(System.UIntPtr, nuint)> { } -partial class C4 : IB1<(T, T)> { } -partial class C4 : IB2<(nint, nuint)> { } + var source = @" +nint x = 0; +_ = x switch // 1 +{ + <= int.MaxValue => 0 +}; + +_ = x switch // 2 +{ + >= int.MinValue => 0 +}; + +nuint y = 0; +_ = y switch // 3 +{ + <= uint.MaxValue => 0 +}; + "; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; comp.VerifyDiagnostics( - // (4,15): error CS0695: 'C1' cannot implement both 'IA' and 'IA' because they may unify for some type parameter substitutions - // partial class C1 : IB1 { } - Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C1").WithArguments("C1", "IA", "IA").WithLocation(4, 15), - // (6,15): error CS0695: 'C2' cannot implement both 'IA<(nint, T)>' and 'IA<(T, IntPtr)>' because they may unify for some type parameter substitutions - // partial class C2 : IB1<(nint, T)> { } - Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C2").WithArguments("C2", "IA<(nint, T)>", "IA<(T, System.IntPtr)>").WithLocation(6, 15), - // (8,15): error CS0695: 'C3' cannot implement both 'IA<(T, T)>' and 'IA<(UIntPtr, nuint)>' because they may unify for some type parameter substitutions - // partial class C3 : IB1<(T, T)> { } - Diagnostic(ErrorCode.ERR_UnifyingInterfaceInstantiations, "C3").WithArguments("C3", "IA<(T, T)>", "IA<(System.UIntPtr, nuint)>").WithLocation(8, 15)); + // (3,7): warning CS8509: The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern '> (nint)int.MaxValue' is not covered. + // _ = x switch // 1 + Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithArguments("> (nint)int.MaxValue").WithLocation(3, 7), + // (8,7): warning CS8509: The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern '< (nint)int.MinValue' is not covered. + // _ = x switch // 2 + Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithArguments("< (nint)int.MinValue").WithLocation(8, 7), + // (14,7): warning CS8509: The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern '> (nuint)uint.MaxValue' is not covered. + // _ = y switch // 3 + Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithArguments("> (nuint)uint.MaxValue").WithLocation(14, 7) + ); } - [Fact] - public void TypeUnification_04() + [Theory, CombinatorialData] + public void BetterConversionTarget(bool nullable1, bool nullable2) { - var source = -@"#nullable enable -interface I { } -class C1 : I { } -class C2 : I { } -class C3 : I { } -class C4 : I<(nint, nuint[])> { } -class C5 : I<(System.IntPtr A, System.UIntPtr[]? B)> { } -"; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics(); + // Given two types T1 and T2, T1 is a better conversion target than T2 if one of the following holds: + // 1. An implicit conversion from T1 to T2 exists and no implicit conversion from T2 to T1 exists + // ... + // 3. T1 is S1 or S1? where S1 is a signed integral type, and T2 is S2 or S2? where S2 is an unsigned integral type. + + string s1Nullable = nullable1 ? "?" : ""; + string s2Nullable = nullable2 ? "?" : ""; + + string source = $$""" +using static System.Console; + +C.M1(0); +C.M2(0); +C.M3(0); +C.M4(0); +C.M5(0); +C.M6(0); +C.M7(0); +C.M8(0); + +public class C +{ + public static void M1(sbyte{{s1Nullable}} x) { Write("M1 "); } + public static void M1(nuint{{s2Nullable}} x) { } + + public static void M2(short{{s1Nullable}} x) { Write("M2 "); } + public static void M2(nuint{{s2Nullable}} x) { } + + public static void M3(int{{s1Nullable}} x) { Write("M3 "); } + public static void M3(nuint{{s2Nullable}} x) { } + + public static void M4(long{{s1Nullable}} x) { Write("M4 "); } + public static void M4(nuint{{s2Nullable}} x) { } + + public static void M5(nint{{s1Nullable}} x) { Write("M5(nint) "); } + public static void M5(ushort{{s2Nullable}} x) { Write("M5(ushort) "); } + + public static void M6(nint{{s1Nullable}} x) { Write("M6 "); } + public static void M6(uint{{s2Nullable}} x) { } - var type1 = getInterface(comp, "C1"); - var type2 = getInterface(comp, "C2"); - var type3 = getInterface(comp, "C3"); - var type4 = getInterface(comp, "C4"); - var type5 = getInterface(comp, "C5"); + public static void M7(nint{{s1Nullable}} x) { Write("M7 "); } + public static void M7(ulong{{s2Nullable}} x) { } - Assert.False(TypeUnification.CanUnify(type1, type2)); - Assert.True(TypeUnification.CanUnify(type1, type3)); - Assert.True(TypeUnification.CanUnify(type4, type5)); + public static void M8(nint{{s1Nullable}} x) { Write("M8"); } + public static void M8(nuint{{s2Nullable}} x) { } +} +"""; + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; - static TypeSymbol getInterface(CSharpCompilation comp, string typeName) => - comp.GetMember(typeName).InterfacesNoUseSiteDiagnostics().Single(); + // Note: conversions ushort->nint, ushort?->nint?, ushort->nint? are implicit (so rule 1 kicks in), but ushort?->nint is explicit (so rule 3 kicks in) + var expected = (nullable1, nullable2) is (false, true) + ? "M1 M2 M3 M4 M5(nint) M6 M7 M8" + : "M1 M2 M3 M4 M5(ushort) M6 M7 M8"; + CompileAndVerify(comp, expectedOutput: expected); } - [WorkItem(49596, "https://github.com/dotnet/roslyn/issues/49596")] - [Fact] - public void SignedToUnsignedConversions_Implicit() + [Theory, CombinatorialData] + public void BetterConversionTarget_IntPtr(bool nullable1, bool nullable2) { - string source = -@"static class NativeInts -{ - static nuint Implicit1(sbyte x) => x; - static nuint Implicit2(short x) => x; - static nuint Implicit3(int x) => x; - static nuint Implicit4(long x) => x; - static nuint Implicit5(nint x) => x; - static nuint Checked1(sbyte x) => checked(x); - static nuint Checked2(short x) => checked(x); - static nuint Checked3(int x) => checked(x); - static nuint Checked4(long x) => checked(x); - static nuint Checked5(nint x) => checked(x); -}"; - var comp = CreateCompilation(source); - comp.VerifyDiagnostics( - // (3,40): error CS0266: Cannot implicitly convert type 'sbyte' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // static nuint Implicit1(sbyte x) => x; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("sbyte", "nuint").WithLocation(3, 40), - // (4,40): error CS0266: Cannot implicitly convert type 'short' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // static nuint Implicit2(short x) => x; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("short", "nuint").WithLocation(4, 40), - // (5,38): error CS0266: Cannot implicitly convert type 'int' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // static nuint Implicit3(int x) => x; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("int", "nuint").WithLocation(5, 38), - // (6,39): error CS0266: Cannot implicitly convert type 'long' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // static nuint Implicit4(long x) => x; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("long", "nuint").WithLocation(6, 39), - // (7,39): error CS0266: Cannot implicitly convert type 'nint' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // static nuint Implicit5(nint x) => x; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("nint", "nuint").WithLocation(7, 39), - // (8,47): error CS0266: Cannot implicitly convert type 'sbyte' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // static nuint Checked1(sbyte x) => checked(x); - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("sbyte", "nuint").WithLocation(8, 47), - // (9,47): error CS0266: Cannot implicitly convert type 'short' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // static nuint Checked2(short x) => checked(x); - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("short", "nuint").WithLocation(9, 47), - // (10,45): error CS0266: Cannot implicitly convert type 'int' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // static nuint Checked3(int x) => checked(x); - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("int", "nuint").WithLocation(10, 45), - // (11,46): error CS0266: Cannot implicitly convert type 'long' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // static nuint Checked4(long x) => checked(x); - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("long", "nuint").WithLocation(11, 46), - // (12,46): error CS0266: Cannot implicitly convert type 'nint' to 'nuint'. An explicit conversion exists (are you missing a cast?) - // static nuint Checked5(nint x) => checked(x); - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments("nint", "nuint").WithLocation(12, 46)); - } + // Given two types T1 and T2, T1 is a better conversion target than T2 if one of the following holds: + // 1. An implicit conversion from T1 to T2 exists and no implicit conversion from T2 to T1 exists + // ... + // 3. T1 is S1 or S1? where S1 is a signed integral type, and T2 is S2 or S2? where S2 is an unsigned integral type. - [Fact] - public void SignedToUnsignedConversions_Explicit() - { - string source = -@"static class NativeInts -{ - static nuint Explicit1(sbyte x) => (nuint)x; - static nuint Explicit2(short x) => (nuint)x; - static nuint Explicit3(int x) => (nuint)x; - static nuint Explicit4(long x) => (nuint)x; - static nuint Explicit5(nint x) => (nuint)x; - static nuint Checked1(sbyte x) => checked((nuint)x); - static nuint Checked2(short x) => checked((nuint)x); - static nuint Checked3(int x) => checked((nuint)x); - static nuint Checked4(long x) => checked((nuint)x); - static nuint Checked5(nint x) => checked((nuint)x); -}"; - var comp = CreateCompilation(source); - var verifier = CompileAndVerify(source); - string expectedExplicitILA = -@"{ - // Code size 3 (0x3) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: conv.i - IL_0002: ret -}"; - string expectedExplicitILB = -@"{ - // Code size 3 (0x3) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: conv.u - IL_0002: ret -}"; - string expectedCheckedIL = -@"{ - // Code size 3 (0x3) - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: conv.ovf.u - IL_0002: ret -}"; - verifier.VerifyIL("NativeInts.Explicit1", expectedExplicitILA); - verifier.VerifyIL("NativeInts.Explicit2", expectedExplicitILA); - verifier.VerifyIL("NativeInts.Explicit3", expectedExplicitILA); - verifier.VerifyIL("NativeInts.Explicit4", expectedExplicitILB); - verifier.VerifyIL("NativeInts.Explicit5", expectedExplicitILB); - verifier.VerifyIL("NativeInts.Checked1", expectedCheckedIL); - verifier.VerifyIL("NativeInts.Checked2", expectedCheckedIL); - verifier.VerifyIL("NativeInts.Checked3", expectedCheckedIL); - verifier.VerifyIL("NativeInts.Checked4", expectedCheckedIL); - verifier.VerifyIL("NativeInts.Checked5", expectedCheckedIL); - } + string s1Nullable = nullable1 ? "?" : ""; + string s2Nullable = nullable2 ? "?" : ""; - [Fact] - public void StandardConversions() - { - // Note: A standard explicit conversion is derived from opposite standard implicit conversion + string source = $$""" +using System; +using static System.Console; - // type to nint - verify(sourceType: "object", destType: "nint", isExplicit: true); - verify(sourceType: "string", destType: "nint", noConversion: true); - verify(sourceType: "void*", destType: "nint", noConversion: true); - verify(sourceType: "delegate*", destType: "nint", noConversion: true); - verify(sourceType: "E", destType: "nint", noConversion: true); - verify(sourceType: "bool", destType: "nint", noConversion: true); - verify(sourceType: "sbyte", destType: "nint"); - verify(sourceType: "byte", destType: "nint"); - verify(sourceType: "short", destType: "nint"); - verify(sourceType: "ushort", destType: "nint"); - verify(sourceType: "int", destType: "nint"); - verify(sourceType: "uint", destType: "nint", noConversion: true); - verify(sourceType: "long", destType: "nint", isExplicit: true); - verify(sourceType: "ulong", destType: "nint", noConversion: true); - verify(sourceType: "char", destType: "nint"); - verify(sourceType: "float", destType: "nint", isExplicit: true); - verify(sourceType: "double", destType: "nint", isExplicit: true); - verify(sourceType: "decimal", destType: "nint", isExplicit: true); - verify(sourceType: "nint", destType: "nint"); - verify(sourceType: "nuint", destType: "nint", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "nint"); - verify(sourceType: "System.UIntPtr", destType: "nint", noConversion: true); +C.M1(0); +C.M2(0); +C.M3(0); +C.M4(0); +C.M5(0); +C.M6(0); +C.M7(0); +C.M8(0); +C.M9(0); - // nint to type - verify(sourceType: "nint", destType: "string", noConversion: true); - verify(sourceType: "nint", destType: "void*", noConversion: true); - verify(sourceType: "nint", destType: "delegate*", noConversion: true); - verify(sourceType: "nint", destType: "E", noConversion: true); - verify(sourceType: "nint", destType: "bool", noConversion: true); - verify(sourceType: "nint", destType: "sbyte", isExplicit: true); - verify(sourceType: "nint", destType: "byte", isExplicit: true); - verify(sourceType: "nint", destType: "short", isExplicit: true); - verify(sourceType: "nint", destType: "ushort", isExplicit: true); - verify(sourceType: "nint", destType: "int", isExplicit: true); - verify(sourceType: "nint", destType: "uint", noConversion: true); - verify(sourceType: "nint", destType: "long"); - verify(sourceType: "nint", destType: "ulong", noConversion: true); - verify(sourceType: "nint", destType: "char", isExplicit: true); - verify(sourceType: "nint", destType: "float"); - verify(sourceType: "nint", destType: "double"); - verify(sourceType: "nint", destType: "decimal"); - verify(sourceType: "nint", destType: "nint"); - verify(sourceType: "nint", destType: "nuint", noConversion: true); - verify(sourceType: "nint", destType: "System.IntPtr"); - verify(sourceType: "nint", destType: "System.UIntPtr", noConversion: true); +public class C +{ + public static void M1(sbyte{{s1Nullable}} x) { Write("M1 "); } + public static void M1(UIntPtr{{s2Nullable}} x) { } - // type to nuint - verify(sourceType: "object", destType: "nuint", isExplicit: true); - verify(sourceType: "string", destType: "nuint", noConversion: true); - verify(sourceType: "void*", destType: "nuint", noConversion: true); - verify(sourceType: "delegate*", destType: "nuint", noConversion: true); - verify(sourceType: "E", destType: "nuint", noConversion: true); - verify(sourceType: "bool", destType: "nuint", noConversion: true); - verify(sourceType: "sbyte", destType: "nuint", noConversion: true); - verify(sourceType: "byte", destType: "nuint"); - verify(sourceType: "short", destType: "nuint", noConversion: true); - verify(sourceType: "ushort", destType: "nuint"); - verify(sourceType: "int", destType: "nuint", noConversion: true); - verify(sourceType: "uint", destType: "nuint"); - verify(sourceType: "long", destType: "nuint", noConversion: true); - verify(sourceType: "ulong", destType: "nuint", isExplicit: true); - verify(sourceType: "char", destType: "nuint"); - verify(sourceType: "float", destType: "nuint", isExplicit: true); - verify(sourceType: "double", destType: "nuint", isExplicit: true); - verify(sourceType: "decimal", destType: "nuint", isExplicit: true); - verify(sourceType: "nint", destType: "nuint", noConversion: true); - verify(sourceType: "nuint", destType: "nuint"); - verify(sourceType: "System.IntPtr", destType: "nuint", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "nuint"); + public static void M2(short{{s1Nullable}} x) { Write("M2 "); } + public static void M2(UIntPtr{{s2Nullable}} x) { } - // nuint to type - verify(sourceType: "nuint", destType: "string", noConversion: true); - verify(sourceType: "nuint", destType: "void*", noConversion: true); - verify(sourceType: "nuint", destType: "delegate*", noConversion: true); - verify(sourceType: "nuint", destType: "E", noConversion: true); - verify(sourceType: "nuint", destType: "bool", noConversion: true); - verify(sourceType: "nuint", destType: "sbyte", noConversion: true); - verify(sourceType: "nuint", destType: "byte", isExplicit: true); - verify(sourceType: "nuint", destType: "short", noConversion: true); - verify(sourceType: "nuint", destType: "ushort", isExplicit: true); - verify(sourceType: "nuint", destType: "int", noConversion: true); - verify(sourceType: "nuint", destType: "uint", isExplicit: true); - verify(sourceType: "nuint", destType: "long", noConversion: true); - verify(sourceType: "nuint", destType: "ulong"); - verify(sourceType: "nuint", destType: "char", isExplicit: true); - verify(sourceType: "nuint", destType: "float"); - verify(sourceType: "nuint", destType: "double"); - verify(sourceType: "nuint", destType: "decimal"); - verify(sourceType: "nuint", destType: "nint", noConversion: true); - verify(sourceType: "nuint", destType: "nuint"); - verify(sourceType: "nuint", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "nuint", destType: "System.UIntPtr"); + public static void M3(int{{s1Nullable}} x) { Write("M3 "); } + public static void M3(UIntPtr{{s2Nullable}} x) { } + public static void M4(long{{s1Nullable}} x) { Write("M4 "); } + public static void M4(UIntPtr{{s2Nullable}} x) { } - // type to System.IntPtr - verify(sourceType: "object", destType: "System.IntPtr", isExplicit: true); - verify(sourceType: "string", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "void*", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "delegate*", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "E", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "bool", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "sbyte", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "byte", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "short", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "ushort", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "int", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "uint", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "long", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "ulong", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "char", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "float", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "double", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "decimal", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "nint", destType: "System.IntPtr"); - verify(sourceType: "nuint", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "System.IntPtr"); - verify(sourceType: "System.UIntPtr", destType: "System.IntPtr", noConversion: true); + public static void M5(nint{{s1Nullable}} x) { Write("M5 "); } + public static void M5(UIntPtr{{s2Nullable}} x) { } - // System.IntPtr to type - verify(sourceType: "System.IntPtr", destType: "string", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "void*", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "delegate*", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "E", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "bool", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "sbyte", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "byte", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "short", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "ushort", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "int", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "uint", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "long", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "ulong", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "char", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "float", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "double", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "decimal", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "nint"); - verify(sourceType: "System.IntPtr", destType: "nuint", noConversion: true); - verify(sourceType: "System.IntPtr", destType: "System.IntPtr"); - verify(sourceType: "System.IntPtr", destType: "System.UIntPtr", noConversion: true); + public static void M6(IntPtr{{s1Nullable}} x) { Write("M6(IntPtr) "); } + public static void M6(ushort{{s2Nullable}} x) { Write("M6(ushort) "); } - // type to System.UIntPtr - verify(sourceType: "object", destType: "System.UIntPtr", isExplicit: true); - verify(sourceType: "string", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "void*", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "delegate*", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "E", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "bool", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "sbyte", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "byte", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "short", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "ushort", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "int", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "uint", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "long", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "ulong", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "char", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "float", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "double", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "decimal", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "nint", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "nuint", destType: "System.UIntPtr"); - verify(sourceType: "System.IntPtr", destType: "System.UIntPtr", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "System.UIntPtr"); + public static void M7(IntPtr{{s1Nullable}} x) { Write("M7 "); } + public static void M7(uint{{s2Nullable}} x) { } - // System.UIntPtr to type - verify(sourceType: "System.UIntPtr", destType: "string", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "void*", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "delegate*", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "E", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "bool", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "sbyte", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "byte", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "short", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "ushort", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "int", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "uint", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "long", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "ulong", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "char", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "float", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "double", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "decimal", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "nint", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "nuint"); - verify(sourceType: "System.UIntPtr", destType: "System.IntPtr", noConversion: true); - verify(sourceType: "System.UIntPtr", destType: "System.UIntPtr"); + public static void M8(IntPtr{{s1Nullable}} x) { Write("M8 "); } + public static void M8(ulong{{s2Nullable}} x) { } - void verify(string sourceType, string destType, bool noConversion = false, bool isExplicit = false) - { - var source = $$""" -unsafe class FinalType -{ - FinalType M({{sourceType}} x) => x; - FinalType M2({{sourceType}} x) => (FinalType)x; - public static implicit operator FinalType({{destType}} i) => throw null; + public static void M9(IntPtr{{s1Nullable}} x) { Write("M9"); } + public static void M9(nuint{{s2Nullable}} x) { } } -enum E { } """; - var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll); - if (noConversion) - { - comp.VerifyDiagnostics( - // (3,30): error CS0029: Cannot implicitly convert type 'sourceType' to 'FinalType' - // FinalType M(sourceType x) => x; - Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments(sourceType, "FinalType"), - // (4,31): error CS0030: Cannot convert type 'sourceType' to 'FinalType' - // FinalType M2(sourceType x) => (FinalType)x; - Diagnostic(ErrorCode.ERR_NoExplicitConv, "(FinalType)x").WithArguments(sourceType, "FinalType") - ); - } - else if (isExplicit) - { - comp.VerifyDiagnostics( - // (3,30): error CS0266: Cannot implicitly convert type 'sourceType' to 'FinalType'. An explicit conversion exists (are you missing a cast?) - // FinalType M(sourceType x) => x; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "x").WithArguments(sourceType, "FinalType") - ); - } - else - { - comp.VerifyDiagnostics(); - } + var comp = CreateEmptyCompilation(source, references: new[] { MscorlibRefWithoutSharingCachedSymbols }); + comp.Assembly.RuntimeSupportsNumericIntPtr = true; + + // Note: conversions ushort->nint, ushort?->nint?, ushort->nint? are implicit (so rule 1 kicks in), but ushort?->nint is explicit (so rule 3 kicks in) + var expected = (nullable1, nullable2) is (false, true) + ? "M1 M2 M3 M4 M5 M6(IntPtr) M7 M8 M9" + : "M1 M2 M3 M4 M5 M6(ushort) M7 M8 M9"; + CompileAndVerify(comp, expectedOutput: expected); + } + + private void VerifyNoNativeIntegerAttributeEmitted(CSharpCompilation comp) + { + CompileAndVerify(comp, + emitOptions: new EmitOptions(runtimeMetadataVersion: "v5.1"), + symbolValidator: module => Assert.Equal("", NativeIntegerAttributesVisitor.GetString((PEModuleSymbol)module))); + } + + private static MetadataReference MscorlibRefWithoutSharingCachedSymbols + { + get + { + // Avoid sharing mscorlib symbols with other tests since we are about to change + // RuntimeSupportsNumericIntPtr property for it. + + return ((AssemblyMetadata)((MetadataImageReference)MscorlibRef).GetMetadata()).CopyWithoutSharingCachedSymbols(). + GetReference(display: "mscorlib.v4_0_30319.dll"); } } + + const string RuntimeFeature_NumericIntPtr = @" +namespace System.Runtime.CompilerServices +{ + public static class RuntimeFeature + { + public const string NumericIntPtr = nameof(NumericIntPtr); + } +} +"; + + static string AsNative(string type) => type switch + { + "IntPtr" or "System.IntPtr" => "nint", + "IntPtr?" or "System.IntPtr?" => "nint?", + "UIntPtr" or "System.UIntPtr" => "nuint", + "UIntPtr?" or "System.UIntPtr?" => "nuint?", + var t => t + }; } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NativeIntegerTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NativeIntegerTests.cs index 8a766a266d179..6e7a38c7bda2e 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NativeIntegerTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NativeIntegerTests.cs @@ -68,6 +68,7 @@ public void LanguageVersion() }"; var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); + Assert.False(comp.Assembly.RuntimeSupportsNumericIntPtr); comp.VerifyDiagnostics( // (3,5): error CS8400: Feature 'native-sized integers' is not available in C# 8.0. Please use language version 9.0 or greater. // nint Add(nint x, nuint y); @@ -80,6 +81,7 @@ public void LanguageVersion() Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "nuint").WithArguments("native-sized integers", "9.0").WithLocation(3, 22)); comp = CreateCompilation(source, parseOptions: TestOptions.Regular9); + Assert.False(comp.Assembly.RuntimeSupportsNumericIntPtr); comp.VerifyDiagnostics(); } @@ -168,19 +170,23 @@ public struct UIntPtr : IEquatable void F2(System.UIntPtr x, nuint y); }"; var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9); + Assert.False(comp.Assembly.RuntimeSupportsNumericIntPtr); comp.VerifyDiagnostics(); verify(comp); comp = CreateEmptyCompilation(sourceA); + Assert.False(comp.Assembly.RuntimeSupportsNumericIntPtr); comp.VerifyDiagnostics(); var ref1 = comp.ToMetadataReference(); var ref2 = comp.EmitToImageReference(); comp = CreateEmptyCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular9); + Assert.False(comp.Assembly.RuntimeSupportsNumericIntPtr); comp.VerifyDiagnostics(); verify(comp); comp = CreateEmptyCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular9); + Assert.False(comp.Assembly.RuntimeSupportsNumericIntPtr); comp.VerifyDiagnostics(); verify(comp); @@ -210,7 +216,7 @@ private static void VerifyType(NamedTypeSymbol type, bool signed, bool isNativeI Assert.Equal(SymbolKind.NamedType, type.Kind); Assert.Equal(TypeKind.Struct, type.TypeKind); Assert.Same(type, type.ConstructedFrom); - Assert.Equal(isNativeInt, type.IsNativeIntegerType); + Assert.Equal(isNativeInt, type.IsNativeIntegerWrapperType); Assert.Equal(signed ? "IntPtr" : "UIntPtr", type.Name); if (isNativeInt) @@ -589,7 +595,7 @@ void verifyTypes(TypeWithAnnotations fromMember, TypeWithAnnotations fromUnderly bool containsType(TypeWithAnnotations type, bool useNativeInteger) { - return type.Type.VisitType((type, unused1, unused2) => type.SpecialType == specialType && useNativeInteger == type.IsNativeIntegerType, (object)null) is { }; + return type.Type.VisitType((type, unused1, unused2) => type.SpecialType == specialType && useNativeInteger == type.IsNativeIntegerWrapperType, (object)null) is { }; } static Symbol getUnderlyingMember(Symbol nativeIntegerMember) @@ -712,7 +718,7 @@ private static void VerifyErrorType(NamedTypeSymbol type, SpecialType specialTyp { Assert.Equal(SymbolKind.ErrorType, type.Kind); Assert.Equal(TypeKind.Error, type.TypeKind); - Assert.Equal(isNativeInt, type.IsNativeIntegerType); + Assert.Equal(isNativeInt, type.IsNativeIntegerWrapperType); Assert.Equal(specialType, type.SpecialType); } @@ -798,7 +804,7 @@ static void verifyField(FieldSymbol field, string expectedSymbol, AssemblySymbol Assert.IsType(field); Assert.Equal(expectedSymbol, field.ToTestDisplayString()); var type = (NamedTypeSymbol)field.Type; - Assert.True(type.IsNativeIntegerType); + Assert.True(type.IsNativeIntegerWrapperType); Assert.IsType(type); Assert.Equal(expectedAssembly, type.NativeIntegerUnderlyingType.ContainingAssembly); } @@ -893,7 +899,7 @@ static void verifyField(FieldSymbol field, string expectedSymbol, AssemblySymbol Assert.IsType(field); Assert.Equal(expectedSymbol, field.ToTestDisplayString()); var type = (NamedTypeSymbol)field.Type; - Assert.True(type.IsNativeIntegerType); + Assert.True(type.IsNativeIntegerWrapperType); Assert.IsType(type); Assert.Equal(expectedAssembly, type.NativeIntegerUnderlyingType.ContainingAssembly); } @@ -982,7 +988,7 @@ static void verifyField(FieldSymbol field, string expectedSymbol, AssemblySymbol Assert.IsType(field); Assert.Equal(expectedSymbol, field.ToTestDisplayString()); var type = (NamedTypeSymbol)field.Type; - Assert.True(type.IsNativeIntegerType); + Assert.True(type.IsNativeIntegerWrapperType); Assert.IsType(type); Assert.Equal(expectedAssembly, type.NativeIntegerUnderlyingType.ContainingAssembly); } @@ -1054,7 +1060,7 @@ static void verifyField(FieldSymbol field, string expectedSymbol) Assert.IsType(field); Assert.Equal(expectedSymbol, field.ToTestDisplayString()); var type = (NamedTypeSymbol)field.Type; - Assert.True(type.IsNativeIntegerType); + Assert.True(type.IsNativeIntegerWrapperType); Assert.IsType(type); } } @@ -1102,7 +1108,7 @@ public override void F() { } var refA = AsReference(comp, useCompilationReference); var type1 = getConstraintType(comp); - Assert.True(type1.IsNativeIntegerType); + Assert.True(type1.IsNativeIntegerWrapperType); Assert.False(type1.IsErrorType()); var sourceB = @@ -1123,7 +1129,7 @@ public override void F() { } var type2 = getConstraintType(comp); Assert.True(type2.ContainingAssembly.IsMissing); - Assert.False(type2.IsNativeIntegerType); + Assert.False(type2.IsNativeIntegerWrapperType); Assert.True(type2.IsErrorType()); static TypeSymbol getConstraintType(CSharpCompilation comp) => @@ -1177,7 +1183,7 @@ public AttributeUsageAttribute(AttributeTargets validOn) var refA = comp.ToMetadataReference(); var typeA = comp.GetMember("A").BaseTypeNoUseSiteDiagnostics; - Assert.True(typeA.IsNativeIntegerType); + Assert.True(typeA.IsNativeIntegerWrapperType); Assert.False(typeA.IsErrorType()); var sourceB = @@ -1195,7 +1201,7 @@ public AttributeUsageAttribute(AttributeTargets validOn) var typeB = comp.GetMember("A").BaseTypeNoUseSiteDiagnostics; Assert.True(typeB.ContainingAssembly.IsMissing); - Assert.False(typeB.IsNativeIntegerType); + Assert.False(typeB.IsNativeIntegerWrapperType); Assert.True(typeB.IsErrorType()); } @@ -1493,7 +1499,7 @@ static void verifyInterfaces(CSharpCompilation comp, NamedTypeSymbol type, Speci { var underlyingType = type.NativeIntegerUnderlyingType; - Assert.True(type.IsNativeIntegerType); + Assert.True(type.IsNativeIntegerWrapperType); Assert.Equal(specialType, underlyingType.SpecialType); var interfaces = type.InterfacesNoUseSiteDiagnostics(null); @@ -1740,7 +1746,7 @@ static nuint F2() static void verifyType(NamedTypeSymbol type, bool signed) { - Assert.True(type.IsNativeIntegerType); + Assert.True(type.IsNativeIntegerWrapperType); VerifyType(type, signed: signed, isNativeInt: true); VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); @@ -1896,7 +1902,7 @@ unsafe static void F2(nuint u) static void verifyType(NamedTypeSymbol type, bool signed) { - Assert.True(type.IsNativeIntegerType); + Assert.True(type.IsNativeIntegerWrapperType); VerifyType(type, signed: signed, isNativeInt: true); VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); @@ -2057,7 +2063,7 @@ unsafe static void F2(nuint x, nuint y) static void verifyType(NamedTypeSymbol type, bool signed) { - Assert.True(type.IsNativeIntegerType); + Assert.True(type.IsNativeIntegerWrapperType); VerifyType(type, signed: signed, isNativeInt: true); VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); @@ -2144,7 +2150,7 @@ static void F2(nuint x, nuint y) static void verifyType(NamedTypeSymbol type, bool signed) { - Assert.True(type.IsNativeIntegerType); + Assert.True(type.IsNativeIntegerWrapperType); VerifyType(type, signed: signed, isNativeInt: true); VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); @@ -2262,7 +2268,7 @@ static void M2(nuint y) static void verifyType(NamedTypeSymbol type, bool signed) { - Assert.True(type.IsNativeIntegerType); + Assert.True(type.IsNativeIntegerWrapperType); VerifyType(type, signed: signed, isNativeInt: true); VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); @@ -2382,7 +2388,7 @@ static void M2(nuint y) static void verifyType(NamedTypeSymbol type, bool signed) { - Assert.True(type.IsNativeIntegerType); + Assert.True(type.IsNativeIntegerWrapperType); VerifyType(type, signed: signed, isNativeInt: true); VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); @@ -2529,7 +2535,7 @@ static void F2(nuint y) static void verifyType(NamedTypeSymbol type, bool signed) { - Assert.True(type.IsNativeIntegerType); + Assert.True(type.IsNativeIntegerWrapperType); VerifyType(type, signed: signed, isNativeInt: true); VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); @@ -2623,7 +2629,7 @@ static void F2(nuint y) static void verifyType(NamedTypeSymbol type, bool signed) { - Assert.True(type.IsNativeIntegerType); + Assert.True(type.IsNativeIntegerWrapperType); VerifyType(type, signed: signed, isNativeInt: true); VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); @@ -2763,7 +2769,7 @@ static void F2(nuint u) static void verifyType(NamedTypeSymbol type, bool signed) { - Assert.True(type.IsNativeIntegerType); + Assert.True(type.IsNativeIntegerWrapperType); VerifyType(type, signed: signed, isNativeInt: true); VerifyType(type.GetPublicSymbol(), signed: signed, isNativeInt: true); @@ -3528,9 +3534,9 @@ static void verify(CSharpCompilation comp) var underlyingType0 = method.Parameters[0].Type.GetSymbol(); var underlyingType1 = method.Parameters[1].Type.GetSymbol(); Assert.Equal(SpecialType.None, underlyingType0.SpecialType); - Assert.False(underlyingType0.IsNativeIntegerType); + Assert.False(underlyingType0.IsNativeIntegerWrapperType); Assert.Equal(SpecialType.System_UIntPtr, underlyingType1.SpecialType); - Assert.True(underlyingType1.IsNativeIntegerType); + Assert.True(underlyingType1.IsNativeIntegerWrapperType); } } @@ -3570,9 +3576,9 @@ void verify(CSharpCompilation comp) var underlyingType0 = (NamedTypeSymbol)method.Parameters[0].Type; var underlyingType1 = (NamedTypeSymbol)method.Parameters[1].Type; Assert.Equal(SpecialType.System_Int16, underlyingType0.SpecialType); - Assert.False(underlyingType0.IsNativeIntegerType); + Assert.False(underlyingType0.IsNativeIntegerWrapperType); Assert.Equal(SpecialType.System_Object, underlyingType1.SpecialType); - Assert.False(underlyingType1.IsNativeIntegerType); + Assert.False(underlyingType1.IsNativeIntegerWrapperType); } } @@ -3604,9 +3610,9 @@ static void verify(CSharpCompilation comp) var underlyingType0 = (NamedTypeSymbol)method.Parameters[0].Type; var underlyingType1 = (NamedTypeSymbol)method.Parameters[1].Type; Assert.Equal(SpecialType.System_Int16, underlyingType0.SpecialType); - Assert.False(underlyingType0.IsNativeIntegerType); + Assert.False(underlyingType0.IsNativeIntegerWrapperType); Assert.Equal(SpecialType.System_UIntPtr, underlyingType1.SpecialType); - Assert.True(underlyingType1.IsNativeIntegerType); + Assert.True(underlyingType1.IsNativeIntegerWrapperType); } } @@ -3638,9 +3644,9 @@ static void verify(CSharpCompilation comp) var underlyingType0 = (NamedTypeSymbol)method.Parameters[0].Type; var underlyingType1 = (NamedTypeSymbol)method.Parameters[1].Type; Assert.Equal(SpecialType.System_Int16, underlyingType0.SpecialType); - Assert.False(underlyingType0.IsNativeIntegerType); + Assert.False(underlyingType0.IsNativeIntegerWrapperType); Assert.Equal(SpecialType.System_UIntPtr, underlyingType1.SpecialType); - Assert.True(underlyingType1.IsNativeIntegerType); + Assert.True(underlyingType1.IsNativeIntegerWrapperType); } } @@ -4599,7 +4605,7 @@ static void verifyOperators(ImmutableArray operators, Func static bool isNativeInt(TypeSymbol type, bool signed) { - return type.IsNativeIntegerType && + return type.IsNativeIntegerWrapperType && type.SpecialType == (signed ? SpecialType.System_IntPtr : SpecialType.System_UIntPtr); } @@ -14680,5 +14686,124 @@ enum E { } } } } + + [Theory, CombinatorialData] + public void BetterConversionTarget(bool nullable1, bool nullable2) + { + // Given two types T1 and T2, T1 is a better conversion target than T2 if one of the following holds: + // 1. An implicit conversion from T1 to T2 exists and no implicit conversion from T2 to T1 exists + // ... + // 3. T1 is S1 or S1? where S1 is a signed integral type, and T2 is S2 or S2? where S2 is an unsigned integral type. + + string s1Nullable = nullable1 ? "?" : ""; + string s2Nullable = nullable2 ? "?" : ""; + + string source = $$""" +using static System.Console; + +C.M1(0); +C.M2(0); +C.M3(0); +C.M4(0); +C.M5(0); +C.M6(0); +C.M7(0); +C.M8(0); + +public class C +{ + public static void M1(sbyte{{s1Nullable}} x) { Write("M1 "); } + public static void M1(nuint{{s2Nullable}} x) { } + + public static void M2(short{{s1Nullable}} x) { Write("M2 "); } + public static void M2(nuint{{s2Nullable}} x) { } + + public static void M3(int{{s1Nullable}} x) { Write("M3 "); } + public static void M3(nuint{{s2Nullable}} x) { } + + public static void M4(long{{s1Nullable}} x) { Write("M4 "); } + public static void M4(nuint{{s2Nullable}} x) { } + + public static void M5(nint{{s1Nullable}} x) { Write("M5(nint) "); } + public static void M5(ushort{{s2Nullable}} x) { Write("M5(ushort) "); } + + public static void M6(nint{{s1Nullable}} x) { Write("M6 "); } + public static void M6(uint{{s2Nullable}} x) { } + + public static void M7(nint{{s1Nullable}} x) { Write("M7 "); } + public static void M7(ulong{{s2Nullable}} x) { } + + public static void M8(nint{{s1Nullable}} x) { Write("M8"); } + public static void M8(nuint{{s2Nullable}} x) { } +} +"""; + var comp = CreateCompilation(source); + + // Note: conversions ushort->nint, ushort?->nint?, ushort->nint? are implicit (so rule 1 kicks in), but ushort?->nint is explicit (so rule 3 kicks in) + var expected = (nullable1, nullable2) is (false, true) + ? "M1 M2 M3 M4 M5(nint) M6 M7 M8" + : "M1 M2 M3 M4 M5(ushort) M6 M7 M8"; + CompileAndVerify(comp, expectedOutput: expected); + } + + [Theory, CombinatorialData] + public void BetterConversionTarget_IntPtr(bool nullable1, bool nullable2) + { + // Given two types T1 and T2, T1 is a better conversion target than T2 if one of the following holds: + // 1. An implicit conversion from T1 to T2 exists and no implicit conversion from T2 to T1 exists + // ... + // 3. T1 is S1 or S1? where S1 is a signed integral type, and T2 is S2 or S2? where S2 is an unsigned integral type. + + string s1Nullable = nullable1 ? "?" : ""; + string s2Nullable = nullable2 ? "?" : ""; + + string source = $$""" +using System; +using static System.Console; + +C.M1(0); +C.M2(0); +C.M3(0); +C.M4(0); +C.M5(0); +C.M6(0); +C.M7(0); +C.M8(0); +C.M9(0); + +public class C +{ + public static void M1(sbyte{{s1Nullable}} x) { Write("M1 "); } + public static void M1(UIntPtr{{s2Nullable}} x) { } + + public static void M2(short{{s1Nullable}} x) { Write("M2 "); } + public static void M2(UIntPtr{{s2Nullable}} x) { } + + public static void M3(int{{s1Nullable}} x) { Write("M3 "); } + public static void M3(UIntPtr{{s2Nullable}} x) { } + + public static void M4(long{{s1Nullable}} x) { Write("M4 "); } + public static void M4(UIntPtr{{s2Nullable}} x) { } + + public static void M5(nint{{s1Nullable}} x) { Write("M5 "); } + public static void M5(UIntPtr{{s2Nullable}} x) { } + + public static void M6(IntPtr{{s1Nullable}} x) { } + public static void M6(ushort{{s2Nullable}} x) { Write("M6 "); } + + public static void M7(IntPtr{{s1Nullable}} x) { } + public static void M7(uint{{s2Nullable}} x) { Write("M7 "); } + + public static void M8(IntPtr{{s1Nullable}} x) { } + public static void M8(ulong{{s2Nullable}} x) { Write("M8 "); } + + public static void M9(IntPtr{{s1Nullable}} x) { } + public static void M9(nuint{{s2Nullable}} x) { Write("M9"); } +} +"""; + var comp = CreateCompilation(source); + + CompileAndVerify(comp, expectedOutput: "M1 M2 M3 M4 M5 M6 M7 M8 M9"); + } } } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs index 5d5f33aa3a9d3..47c00c9b565f4 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs @@ -544,6 +544,7 @@ public void AllSpecialTypeMembers() || special == SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__CovariantReturnsOfClasses || special == SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__VirtualStaticsInInterfaces || special == SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__UnmanagedSignatureCallingConvention + || special == SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__NumericIntPtr || special == SpecialMember.System_Runtime_CompilerServices_PreserveBaseOverridesAttribute__ctor) { Assert.Null(symbol); // Not available diff --git a/src/Compilers/Core/Portable/SpecialMember.cs b/src/Compilers/Core/Portable/SpecialMember.cs index 4c002b07f7dca..101aca124c118 100644 --- a/src/Compilers/Core/Portable/SpecialMember.cs +++ b/src/Compilers/Core/Portable/SpecialMember.cs @@ -152,6 +152,7 @@ internal enum SpecialMember System_Runtime_CompilerServices_RuntimeFeature__UnmanagedSignatureCallingConvention, System_Runtime_CompilerServices_RuntimeFeature__CovariantReturnsOfClasses, System_Runtime_CompilerServices_RuntimeFeature__VirtualStaticsInInterfaces, + System_Runtime_CompilerServices_RuntimeFeature__NumericIntPtr, System_Runtime_CompilerServices_PreserveBaseOverridesAttribute__ctor, diff --git a/src/Compilers/Core/Portable/SpecialMembers.cs b/src/Compilers/Core/Portable/SpecialMembers.cs index c8df5bb8ebe15..e3435bc85c51c 100644 --- a/src/Compilers/Core/Portable/SpecialMembers.cs +++ b/src/Compilers/Core/Portable/SpecialMembers.cs @@ -1025,7 +1025,13 @@ static SpecialMembers() (byte)SpecialType.System_Runtime_CompilerServices_RuntimeFeature, // DeclaringTypeId 0, // Arity (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_String, // Field Signature - + + // System_Runtime_CompilerServices_RuntimeFeature__NumericIntPtr + (byte)(MemberFlags.Field | MemberFlags.Static), // Flags + (byte)SpecialType.System_Runtime_CompilerServices_RuntimeFeature, // DeclaringTypeId + 0, // Arity + (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_String, // Field Signature + // System_Runtime_CompilerServices_PreserveBaseOverridesAttribute__ctor (byte)MemberFlags.Constructor, // Flags (byte)SpecialType.System_Runtime_CompilerServices_PreserveBaseOverridesAttribute, // DeclaringTypeId @@ -1159,7 +1165,8 @@ static SpecialMembers() "DefaultImplementationsOfInterfaces", // System_Runtime_CompilerServices_RuntimeFeature__DefaultImplementationsOfInterfaces "UnmanagedSignatureCallingConvention", // System_Runtime_CompilerServices_RuntimeFeature__UnmanagedSignatureCallingConvention "CovariantReturnsOfClasses", // System_Runtime_CompilerServices_RuntimeFeature__CovariantReturnsOfClasses - "VirtualStaticsInInterfaces", // System_Runtime_CompilerServices_RuntimeFeature__VirtualStaticsInInterfaces + "VirtualStaticsInInterfaces", // System_Runtime_CompilerServices_RuntimeFeature__VirtualStaticsInInterfaces + "NumericIntPtr", // System_Runtime_CompilerServices_RuntimeFeature__NumericIntPtr ".ctor", // System_Runtime_CompilerServices_PreserveBaseOverridesAttribute__ctor }; diff --git a/src/Compilers/Test/Utilities/CSharp/NativeIntegerAttributesVisitor.cs b/src/Compilers/Test/Utilities/CSharp/NativeIntegerAttributesVisitor.cs index d0d3b72a54158..eeb50f47b83b0 100644 --- a/src/Compilers/Test/Utilities/CSharp/NativeIntegerAttributesVisitor.cs +++ b/src/Compilers/Test/Utilities/CSharp/NativeIntegerAttributesVisitor.cs @@ -169,22 +169,6 @@ private void ReportSymbol(Symbol symbol) _reported.Add(symbol); } - private static Symbol GetAccessSymbol(Symbol symbol) - { - while (true) - { - switch (symbol.Kind) - { - case SymbolKind.Parameter: - case SymbolKind.TypeParameter: - symbol = symbol.ContainingSymbol; - break; - default: - return symbol; - } - } - } - private static string ReportAttribute(CSharpAttributeData attribute) { var builder = new StringBuilder(); diff --git a/src/Compilers/VisualBasic/Portable/Symbols/TypeSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/TypeSymbol.vb index 8ee0405eb018b..e4d95b74e5600 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/TypeSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/TypeSymbol.vb @@ -573,7 +573,7 @@ Done: End Get End Property - Private ReadOnly Property ITypeSymbol_TypeKind As TYPEKIND Implements ITypeSymbol.TypeKind, ITypeSymbolInternal.TypeKind + Private ReadOnly Property ITypeSymbol_TypeKind As TypeKind Implements ITypeSymbol.TypeKind, ITypeSymbolInternal.TypeKind Get Return Me.TypeKind End Get diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WellKnownTypeValidationTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WellKnownTypeValidationTests.vb index 835e206b701bb..88333f788a37a 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WellKnownTypeValidationTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WellKnownTypeValidationTests.vb @@ -487,6 +487,7 @@ End Namespace special = SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__UnmanagedSignatureCallingConvention OrElse special = SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__CovariantReturnsOfClasses OrElse special = SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__VirtualStaticsInInterfaces OrElse + special = SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__NumericIntPtr OrElse special = SpecialMember.System_Runtime_CompilerServices_PreserveBaseOverridesAttribute__ctor Then Assert.Null(symbol) ' Not available Else diff --git a/src/Workspaces/Core/Portable/CodeGeneration/Symbols/CodeGenerationTypeSymbol.cs b/src/Workspaces/Core/Portable/CodeGeneration/Symbols/CodeGenerationTypeSymbol.cs index efaa88336e672..c4703fa21865c 100644 --- a/src/Workspaces/Core/Portable/CodeGeneration/Symbols/CodeGenerationTypeSymbol.cs +++ b/src/Workspaces/Core/Portable/CodeGeneration/Symbols/CodeGenerationTypeSymbol.cs @@ -48,6 +48,8 @@ public ImmutableArray AllInterfaces public bool IsNativeIntegerType => false; + public bool IsNativeIntegerTypeOrNumericIntPtr => false; + public static ImmutableArray TupleElementTypes => default; public static ImmutableArray TupleElementNames => default;