[x] Overridiing, interface implementation, hiding consider native integers and underlying types as equivalent
[x] Overrides and interface implementations may differ by native integers and underlying types alone [NativeIntegerTests.Overrides_*]
[x] Overloads cannot differ by native integers and underlying types alone [NativeIntegerTests.Overloads_*]
[x] Methods hide other methods that differ by native integers and underlying types alone [NativeIntegerTests.Overloads_*]
[x] Type members from underlying types:
[x] Constructors from underlying types are hidden for nint and nuint [NativeIntegerTests.ConstructorsAndOperators]
[x] Operators from underlying types (including implicit and explicit conversion operators) are hidden for nint and nuint [NativeIntegerTests.ConstructorsAndOperators]
[x] Instance and static members from underlying types are hidden except for an explicit opt-in list [NativeIntegerTests.{InstanceMembers, StaticMembers}]
[x] Interfaces implemented by underlying types are implemented, with substitution for generic interfaces such as IEquatable<IntPtr> [NativeIntegerTests.Interfaces]
[x] RequestIComparable<nint> etc and we can expose it
[x] Type unification of interfaces that differ by native integers and underlying types
[x] No changes for dynamic: runtime binding to underlying types only
[x] Can be used as default parameter value [NativeIntegerTests.Constants_ParameterDefaults]
[x] Cannot be used as attribute argument (neither positional nor named arguments) [NativeIntegerTests.AttributeValue_*]
[ ] Native integers cannot be used as enum base type
[x] Native integer fields may be marked volatile
[x] typeof(nint) is typeof(IntPtr)
[x] sizeof(nint) is supported in unsafe context only and is defined as sizeof(IntPtr) not IntPtr.Size [NativeIntegerTests.SizeOf_*]
[x] Compiler diagnostics refer to nint and nuint rather than underlying types [NativeIntegerTests.ConstantConversions_*]
[x] SymbolDisplay uses nint and nuint always regardless of SymbolDisplayFormat [NativeIntegerTests.TypeDefinitions_FromMetadata]
[x] Metadata representation uses System.IntPtr and System.UIntPtr with additional NativeIntegerAttribute on containing type reference [AttributeTests_NativeInteger]
[x] determine if ITypeSymbol is native integer: ITypeSymbol.IsNativeInteger [NativeIntegerTests.TypeDefinitions_FromMetadata]
[x] get underlying INamedTypeSymbol for native integer: INamedTypeSymbol.NativeIntegerUnderlyingType [NativeIntegerTests.TypeDefinitions_FromMetadata]
[x] get signed and unsigned native integer INamedTypeSymbol instances from compilation: Compilation.CreateNativeIntegerTypeSymbol() [NativeIntegerTests.CreateNativeIntegerTypeSymbol_FromMetadata]
[ ] The semantic model GetTypeInfo API should return the new types when appropriate, even** when compiling at an older language version. Language behavior agrees with semantic model.
[x] The set of members of nint and nuint as seen through the language is tested to be as specified.
[x] The set of built-in operators as seen through the language is tested to be as specified.
[x] When using the built-in operators, they obey the appropriate checked/unchecked context for overflow, on platforms with 32-bit nints and 64-bit nints. [NativeIntegerTests.{UnaryOperators, BinaryOperators}]
[x] Test that constant folding works as specified (including checked/unchecked) [NativeIntegerTests.ConstantFolding]
[ ] Test pattern-matching for nint constants, e.g. o is (nint)1
[ ] Test switching on a value of type nint. Do we generate an IL switch instruction?
[x] Test decoding of nint in a modreq (we don't do it, intentional)
BCL
[ ] we should consider what Interlocked overloads the BCL/runtime should provide for those new types.
Test plan for "native ints" #38821
Championed issue
dotnet/csharplang
nint
/nuint
operators?nint
andnuint
contextual keywordsnint x = 3;
_ = nameof(nint);
_ = nint.Equals(x, 3);
[MemberName_02]int
anduint
ranges [NativeIntegerTests.Constants_FromMetadata]checked
andunchecked
contexts withinint
/uint
rangesunchecked
context otherwise (we have an open issue)System.IntPtr
andnint
, and betweenSystem.UIntPtr
andnuint
[NativeIntegerTests.Conversions]nint
andIntPtr
?A<nint>
andA<IntPtr>
?nint
andIntPtr
are both boundsNullable<>
, constructed types, tuples that differ only by native integers and underlying typesobject
and native integer types [NativeIntegerTests.Conversions]IEquatable<nint>
void*
and native integer types [NativeIntegerTests.Conversions]A
toB?
if implicit/explict conversion fromA
toB
[NativeIntegerTests.Conversions]A?
toB
if identity or implicit/explicit conversion fromA
toB
[NativeIntegerTests.Conversions]A?
toB?
if implicit/explicit conversion fromA
toB
[NativeIntegerTests.Conversions]++
,--
,+
,-
,~
}, binary {+
,-
,*
,/
,%
,<
,<=
,>
,>=
,<<
,>>
,==
,!=
,|
,&
,^
}nint
andnuint
[NativeIntegerTests.ConstructorsAndOperators]nint
andnuint
[NativeIntegerTests.ConstructorsAndOperators]IEquatable<IntPtr>
[NativeIntegerTests.Interfaces]IComparable<nint>
etc and we can expose itdynamic
: runtime binding to underlying types onlyenum
base typevolatile
typeof(nint)
istypeof(IntPtr)
sizeof(nint)
is supported in unsafe context only and is defined assizeof(IntPtr)
notIntPtr.Size
[NativeIntegerTests.SizeOf_*]nint
andnuint
rather than underlying types [NativeIntegerTests.ConstantConversions_*]SymbolDisplay
usesnint
andnuint
always regardless ofSymbolDisplayFormat
[NativeIntegerTests.TypeDefinitions_FromMetadata]System.IntPtr
andSystem.UIntPtr
with additionalNativeIntegerAttribute
on containing type reference [AttributeTests_NativeInteger]ITypeSymbol
is native integer:ITypeSymbol.IsNativeInteger
[NativeIntegerTests.TypeDefinitions_FromMetadata]INamedTypeSymbol
for native integer:INamedTypeSymbol.NativeIntegerUnderlyingType
[NativeIntegerTests.TypeDefinitions_FromMetadata]INamedTypeSymbol
instances from compilation:Compilation.CreateNativeIntegerTypeSymbol()
[NativeIntegerTests.CreateNativeIntegerTypeSymbol_FromMetadata]Add(see https://github.com/dotnet/runtime/issues/38683)NativeIntegerAttribute
definition to .NET 5.0nint
andnuint
as seen through the language is tested to be as specified.o is (nint)1
nint
. Do we generate an ILswitch
instruction?nint
in a modreq (we don't do it, intentional)BCL
we should consider what Interlocked overloads the BCL/runtime should provide for those new types.IDE Scenarios
IntPtr
)