File: Emit\NumericIntPtrTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Emit2\Microsoft.CodeAnalysis.CSharp.Emit2.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Emit2.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
using Microsoft.CodeAnalysis.CSharp.Symbols.Retargeting;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.CSharp.UnitTests;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Semantics
{
    public class NumericIntPtrTests : CSharpTestBase
    {
        private static string IncludeExpectedOutput(string expectedOutput) => ExecutionConditionUtil.IsMonoOrCoreClr ? expectedOutput : null;
 
        internal static readonly ConversionKind[] Identity = new[] { ConversionKind.Identity };
        internal static readonly ConversionKind[] NoConversion = new[] { ConversionKind.NoConversion };
        internal static readonly ConversionKind[] Boxing = new[] { ConversionKind.Boxing };
        internal static readonly ConversionKind[] Unboxing = new[] { ConversionKind.Unboxing };
        internal static readonly ConversionKind[] IntPtrConversion = new[] { ConversionKind.IntPtr };
        internal static readonly ConversionKind[] ImplicitNumeric = new[] { ConversionKind.ImplicitNumeric };
        internal static readonly ConversionKind[] ExplicitIntegerToPointer = new[] { ConversionKind.ExplicitIntegerToPointer };
        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 };
 
        internal static readonly ConversionKind[] ExplicitNullableEnumeration = new[] { ConversionKind.ExplicitNullable, ConversionKind.ExplicitEnumeration };
        internal static readonly ConversionKind[] ExplicitNullableImplicitNumeric = new[] { ConversionKind.ExplicitNullable, ConversionKind.ImplicitNumeric };
        internal static readonly ConversionKind[] ExplicitNullableNumeric = new[] { ConversionKind.ExplicitNullable, ConversionKind.ExplicitNumeric };
        internal static readonly ConversionKind[] ExplicitNullablePointerToInteger = new[] { ConversionKind.ExplicitNullable, ConversionKind.ExplicitPointerToInteger };
        internal static readonly ConversionKind[] ExplicitNullableIdentity = new[] { ConversionKind.ExplicitNullable, ConversionKind.Identity };
 
        internal static bool IsNoConversion(ConversionKind[] conversionKinds)
        {
            return conversionKinds is [ConversionKind.NoConversion];
        }
 
        internal static void AssertMatches(ConversionKind[] expected, Conversion conversion)
        {
            IEnumerable<ConversionKind> actualConversionKinds = new[] { conversion.Kind };
            if (!conversion.UnderlyingConversions.IsDefault)
            {
                actualConversionKinds = actualConversionKinds.Concat(conversion.UnderlyingConversions.Select(c => c.Kind));
            }
            Assert.Equal(expected, actualConversionKinds);
        }
 
        private static int SymbolComparison(Symbol x, Symbol 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");
        }
 
        [Theory]
        [InlineData("System.IntPtr")]
        [InlineData("nint")]
        public void Interfaces(string 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<T>
    {
        bool Equals(T other);
    }
    public interface IOther<T> { }
    public struct IntPtr : ISerializable, IEquatable<IntPtr>, IOther<IntPtr>
    {
        bool IEquatable<IntPtr>.Equals(IntPtr other) => false;
    }
}
" + RuntimeFeature_NumericIntPtr;
 
            var sourceB = $$"""
using System;
class Program
{
    static void F0(ISerializable i) { }
    static object F1(IEquatable<IntPtr> i) => default;
    static void F2(IEquatable<nint> i) { }
    static void F3<T>(IOther<T> i) { }
    static void Main()
    {
        {{type}} n = 42;
        F0(n);
        F1(n);
        F2(n);
        F3<nint>(n);
        F3<IntPtr>(n);
    }
}
""";
            var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics();
        }
 
        [Theory]
        [InlineData("System.UIntPtr")]
        [InlineData("nuint")]
        public void Interfaces_UIntPtr(string 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<T>
    {
        bool Equals(T other);
    }
    public interface IOther<T> { }
    public struct UIntPtr : ISerializable, IEquatable<UIntPtr>, IOther<UIntPtr>
    {
        bool IEquatable<UIntPtr>.Equals(UIntPtr other) => false;
    }
}
" + RuntimeFeature_NumericIntPtr;
 
            var sourceB = $$"""
using System;
class Program
{
    static void F0(ISerializable i) { }
    static object F1(IEquatable<UIntPtr> i) => default;
    static void F2(IEquatable<nuint> i) { }
    static void F3<T>(IOther<T> i) { }
    static void Main()
    {
        {{type}} n = 42;
        F0(n);
        F1(n);
        F2(n);
        F3<nuint>(n);
        F3<UIntPtr>(n);
    }
}
""";
            var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics();
        }
 
        [Theory]
        [InlineData(false)]
        [InlineData(true)]
        public void StaticMembers(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 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
    {
        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;
        }
    }
    public class Attribute { }
    public class AttributeUsageAttribute : Attribute
    {
        public AttributeUsageAttribute(AttributeTargets validOn) { }
        public bool AllowMultiple { get; set; }
        public bool Inherited { get; set; }
    }
    public struct Enum { }
    public enum AttributeTargets { }
}
" + RuntimeFeature_NumericIntPtr;
 
            var comp = CreateEmptyCompilation(sourceA);
            comp.VerifyDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"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()
    {
        _ = 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;
    }
}";
 
            comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics();
        }
 
        [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 { }
    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
    {
        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;
    }
    public class Attribute { }
    public class AttributeUsageAttribute : Attribute
    {
        public AttributeUsageAttribute(AttributeTargets t) { }
        public bool AllowMultiple { get; set; }
        public bool Inherited { get; set; }
    }
    public struct Enum { }
    public enum AttributeTargets { }
}
" + RuntimeFeature_NumericIntPtr;
 
            var comp = CreateEmptyCompilation(sourceA, options: TestOptions.UnsafeReleaseDll);
            comp.VerifyDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"using System;
class Program
{
    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)
    {
        _ = 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 = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9, options: TestOptions.UnsafeReleaseDll);
            comp.VerifyDiagnostics();
        }
 
        [Theory]
        [InlineData(false)]
        [InlineData(true)]
        public void ConstructorsAndOperators(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 unsafe struct IntPtr
    {
        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;
    }
    public unsafe struct UIntPtr
    {
        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;
    }
    public class Attribute { }
    public class AttributeUsageAttribute : Attribute
    {
        public AttributeUsageAttribute(AttributeTargets t) { }
        public bool AllowMultiple { get; set; }
        public bool Inherited { get; set; }
    }
    public struct Enum { }
    public enum AttributeTargets { }
}
" + 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
{
    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;
    }
}";
            comp = CreateEmptyCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9, options: TestOptions.UnsafeReleaseDll);
            comp.VerifyDiagnostics();
        }
 
        /// <summary>
        /// Overrides from IntPtr and UIntPtr are implicitly included on nint and nuint.
        /// </summary>
        [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
    {
        public override string ToString() => null;
        public override int GetHashCode() => 0;
        public override bool Equals(object obj) => false;
    }
    public class Attribute { }
    public class AttributeUsageAttribute : Attribute
    {
        public AttributeUsageAttribute(AttributeTargets t) { }
        public bool AllowMultiple { get; set; }
        public bool Inherited { get; set; }
    }
    public struct Enum { }
    public enum AttributeTargets { }
}
" + RuntimeFeature_NumericIntPtr;
 
            var comp = CreateEmptyCompilation(sourceA);
            comp.VerifyDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            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();
 
            verifyType((NamedTypeSymbol)comp.GetMember<MethodSymbol>("Program.F1").Parameters[0].Type, signed: true);
            verifyType((NamedTypeSymbol)comp.GetMember<MethodSymbol>("Program.F2").Parameters[0].Type, signed: false);
 
            static void verifyType(NamedTypeSymbol type, bool signed)
            {
                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 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>
    {
        T P { get; }
        T F();
    }
    public struct IntPtr : I<IntPtr>
    {
        IntPtr I<IntPtr>.P => this;
        IntPtr I<IntPtr>.F() => this;
    }
    public struct UIntPtr : I<UIntPtr>
    {
        UIntPtr I<UIntPtr>.P => this;
        UIntPtr I<UIntPtr>.F() => this;
    }
    public class Attribute { }
    public class AttributeUsageAttribute : Attribute
    {
        public AttributeUsageAttribute(AttributeTargets t) { }
        public bool AllowMultiple { get; set; }
        public bool Inherited { get; set; }
    }
    public struct Enum { }
    public enum AttributeTargets { }
}
" + RuntimeFeature_NumericIntPtr;
 
            var comp = CreateEmptyCompilation(sourceA);
            comp.VerifyDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"using System;
class Program
{
    static T F1<T>(I<T> t)
    {
        return default;
    }
    static I<T> F2<T>(I<T> 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(
                // (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));
 
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var actualLocals = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().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]
        public void NonPublicMembers_InternalUse()
        {
            var source =
@"namespace System
{
    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()
        {
            nint i = 0;
            _ = nint.F1();
            _ = i.F2();
            return nint.F3();
        }
        public static nint F4()
        {
            IntPtr i = 0;
            _ = IntPtr.F1();
            _ = i.F2();
            return IntPtr.F3();
        }
    }
    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 comp = CreateEmptyCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics();
        }
 
        [Theory]
        [InlineData(false)]
        [InlineData(true)]
        public void NonPublicMembers(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 IntPtr
    {
        private static IntPtr F1() => default;
        internal IntPtr F2() => default;
        public static IntPtr F3() => default;
    }
    public struct UIntPtr
    {
        private static UIntPtr F1() => default;
        internal UIntPtr F2() => default;
        public static UIntPtr F3() => default;
    }
    public class Attribute { }
    public class AttributeUsageAttribute : Attribute
    {
        public AttributeUsageAttribute(AttributeTargets t) { }
        public bool AllowMultiple { get; set; }
        public bool Inherited { get; set; }
    }
    public struct Enum { }
    public enum AttributeTargets { }
}
" + RuntimeFeature_NumericIntPtr;
 
            var comp = CreateEmptyCompilation(sourceA);
            comp.VerifyDiagnostics();
            var refA = AsReference(comp, useCompilationReference);
 
            var sourceB =
@"using System;
class Program
{
    static void F1(nint x)
    {
        _ = 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();
    }
}";
            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 Overrides_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
{
    void IA.F1(System.IntPtr x, nuint y) { }
}";
 
            var comp = CreateCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            var ref1 = comp.ToMetadataReference();
            var ref2 = comp.EmitToImageReference();
 
            comp = CreateCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void Overloads_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
{
    public new void F1(nuint x) { }
    public new void F2(System.IntPtr y) { }
}
class B4 : A
{
    public new void F1(nint x) {  base.F1(x); }
    public new void F2(System.UIntPtr y) { base.F2(y); }
}";
 
            var diagnostics = new[]
            {
                // (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 = CreateCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(diagnostics);
 
            comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            var ref1 = comp.ToMetadataReference();
            var ref2 = comp.EmitToImageReference();
 
            comp = CreateCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(diagnostics);
 
            comp = CreateCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(diagnostics);
        }
 
        [Fact]
        public void Partial_01()
        {
            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, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(6), parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [Fact, WorkItem(63860, "https://github.com/dotnet/roslyn/issues/63860")]
        public void AddUIntPtrAndInt()
        {
            var source = @"
using System;
 
class C
{
    UIntPtr M(UIntPtr i, int j) => i + j;
}
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (6,36): error CS0034: Operator '+' is ambiguous on operands of type 'nuint' and 'int'
                //     UIntPtr M(UIntPtr i, int j) => i + j;
                Diagnostic(ErrorCode.ERR_AmbigBinaryOps, "i + j").WithArguments("+", "nuint", "int").WithLocation(6, 36)
                );
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
            var verifier = CompileAndVerify(comp);
            verifier.VerifyIL("C.M", @"
{
  // Code size        8 (0x8)
  .maxstack  2
  IL_0000:  ldarg.1
  IL_0001:  ldarg.2
  IL_0002:  call       ""System.UIntPtr System.UIntPtr.op_Addition(System.UIntPtr, int)""
  IL_0007:  ret
}
");
        }
 
        [Fact, WorkItem(63860, "https://github.com/dotnet/roslyn/issues/63860")]
        public void AddNUIntAndInt()
        {
            var source = @"
class C
{
    nuint M(nuint i, int j) => i + j;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (4,32): error CS0034: Operator '+' is ambiguous on operands of type 'nuint' and 'int'
                //     nuint M(nuint i, int j) => i + j;
                Diagnostic(ErrorCode.ERR_AmbigBinaryOps, "i + j").WithArguments("+", "nuint", "int").WithLocation(4, 32)
                );
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (4,32): error CS0034: Operator '+' is ambiguous on operands of type 'nuint' and 'int'
                //     nuint M(nuint i, int j) => i + j;
                Diagnostic(ErrorCode.ERR_AmbigBinaryOps, "i + j").WithArguments("+", "nuint", "int").WithLocation(4, 32)
                );
        }
 
        [Fact, WorkItem(63860, "https://github.com/dotnet/roslyn/issues/63860")]
        public void AddIntPtrAndInt()
        {
            var source = @"
using System;
 
class C
{
    IntPtr M(IntPtr i, int j) => i + j;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify);
            verifier.VerifyIL("C.M", @"
{
  // Code size        5 (0x5)
  .maxstack  2
  IL_0000:  ldarg.1
  IL_0001:  ldarg.2
  IL_0002:  conv.i
  IL_0003:  add
  IL_0004:  ret
}
");
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
 
            verifier = CompileAndVerify(comp);
            verifier.VerifyIL("C.M", @"
{
  // Code size        8 (0x8)
  .maxstack  2
  IL_0000:  ldarg.1
  IL_0001:  ldarg.2
  IL_0002:  call       ""System.IntPtr System.IntPtr.op_Addition(System.IntPtr, int)""
  IL_0007:  ret
}
");
        }
 
        [Fact, WorkItem(63860, "https://github.com/dotnet/roslyn/issues/63860")]
        public void AddNIntAndInt()
        {
            var source = @"
class C
{
    nint M(nint i, int j) => i + j;
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify);
            verifier.VerifyIL("C.M", @"
{
  // Code size        5 (0x5)
  .maxstack  2
  IL_0000:  ldarg.1
  IL_0001:  ldarg.2
  IL_0002:  conv.i
  IL_0003:  add
  IL_0004:  ret
}
");
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
            verifier = CompileAndVerify(comp);
            verifier.VerifyIL("C.M", @"
{
  // Code size        5 (0x5)
  .maxstack  2
  IL_0000:  ldarg.1
  IL_0001:  ldarg.2
  IL_0002:  conv.i
  IL_0003:  add
  IL_0004:  ret
}
");
        }
 
        [Fact]
        public void Constraints_01()
        {
            var sourceA =
@"public class A<T>
{
    public static void F<U>() where U : T { }
}
public class B1 : A<nint> { }
public class B2 : A<nuint> { }
public class B3 : A<System.IntPtr> { }
public class B4 : A<System.UIntPtr> { }
";
            var sourceB =
@"class Program
{
    static void Main()
    {
        B1.F<System.IntPtr>();
        B2.F<System.UIntPtr>();
        B3.F<nint>();
        B4.F<nuint>();
    }
}";
 
            var comp = CreateCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            var ref1 = comp.ToMetadataReference();
            var ref2 = comp.EmitToImageReference();
 
            comp = CreateCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void AttributeType_01()
        {
            var source =
@"[nint]
[A, nuint()]
class Program
{
}
class AAttribute : System.Attribute
{
}";
            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)
            };
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(expectedDiagnostics);
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(expectedDiagnostics);
        }
 
        [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, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            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_04()
        {
            var source =
@"class Program
{
    static void F(int @nint, uint @nuint)
    {
        _ = nameof(@nint);
        _ = nameof(@nuint);
    }
}";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [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, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            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));
        }
 
        [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, targetFramework: TargetFramework.Net70);
            int size = IntPtr.Size;
            var verifier = CompileAndVerify(comp, expectedOutput: IncludeExpectedOutput($"{size}{size}{size}{size}"), verify: Verification.FailsPEVerify);
            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
}");
        }
 
        [Fact]
        public void SizeOf_03()
        {
            var source =
@"using System.Collections.Generic;
unsafe class Program
{
    static IEnumerable<int> F()
    {
        yield return sizeof(nint);
        yield return sizeof(nuint);
        yield return sizeof(System.IntPtr);
        yield return sizeof(System.UIntPtr);
    }
}";
            // https://github.com/dotnet/roslyn/issues/73280 - should not be a langversion error since this remains an error in C# 13
            CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70).VerifyDiagnostics(
                // (6,22): error CS8773: Feature 'ref and unsafe in async and iterator methods' is not available in C# 9.0. Please use language version 13.0 or greater.
                //         yield return sizeof(nint);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion9, "sizeof(nint)").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(6, 22),
                // (7,22): error CS8773: Feature 'ref and unsafe in async and iterator methods' is not available in C# 9.0. Please use language version 13.0 or greater.
                //         yield return sizeof(nuint);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion9, "sizeof(nuint)").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(7, 22),
                // (8,22): error CS8773: Feature 'ref and unsafe in async and iterator methods' is not available in C# 9.0. Please use language version 13.0 or greater.
                //         yield return sizeof(System.IntPtr);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion9, "sizeof(System.IntPtr)").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(8, 22),
                // (9,22): error CS8773: Feature 'ref and unsafe in async and iterator methods' is not available in C# 9.0. Please use language version 13.0 or greater.
                //         yield return sizeof(System.UIntPtr);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion9, "sizeof(System.UIntPtr)").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(9, 22)
                );
            CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net70).VerifyDiagnostics(
                // (6,22): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
                //         yield return sizeof(nint);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "sizeof(nint)").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(6, 22),
                // (7,22): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
                //         yield return sizeof(nuint);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "sizeof(nuint)").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(7, 22),
                // (8,22): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
                //         yield return sizeof(System.IntPtr);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "sizeof(System.IntPtr)").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(8, 22),
                // (9,22): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
                //         yield return sizeof(System.UIntPtr);
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "sizeof(System.UIntPtr)").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(9, 22)
                );
 
            var expectedDiagnostics = new[]
            {
                // (6,22): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context
                //         yield return sizeof(nint);
                Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(6, 22),
                // (7,22): error CS0233: 'nuint' does not have a predefined size, therefore sizeof can only be used in an unsafe context
                //         yield return sizeof(nuint);
                Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nuint)").WithArguments("nuint").WithLocation(7, 22),
                // (8,22): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context
                //         yield return sizeof(System.IntPtr);
                Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(System.IntPtr)").WithArguments("nint").WithLocation(8, 22),
                // (9,22): error CS0233: 'nuint' does not have a predefined size, therefore sizeof can only be used in an unsafe context
                //         yield return sizeof(System.UIntPtr);
                Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(System.UIntPtr)").WithArguments("nuint").WithLocation(9, 22)
            };
 
            CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular13, targetFramework: TargetFramework.Net70).VerifyDiagnostics(expectedDiagnostics);
            CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70).VerifyDiagnostics(expectedDiagnostics);
        }
 
        [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, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
@"System.IntPtr
System.UIntPtr
False
True
True"));
        }
 
        [Fact]
        public void Volatile()
        {
            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 = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, expectedOutput: IncludeExpectedOutput(@"1"), verify: Verification.FailsPEVerify);
            verifier.VerifyIL("Program.F",
@"{
  // Code size       16 (0x10)
  .maxstack  2
  IL_0000:  volatile.
  IL_0002:  ldsfld     ""nint Program.F1""
  IL_0007:  volatile.
  IL_0009:  ldsfld     ""nuint Program.F2""
  IL_000e:  add
  IL_000f:  ret
}");
        }
 
        [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, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
@"-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
}");
        }
 
        /// <summary>
        /// Verify there is the number of built in operators for { IntPtr, UIntPtr, IntPtr?, UIntPtr? }
        /// for each operator kind.
        /// </summary>
        [Fact]
        public void BuiltInOperators()
        {
            var comp = CreateCompilation("", parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            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<UnaryOperatorSignature>.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<BinaryOperatorSignature>.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<T>(ImmutableArray<T> operators, Func<T, bool, bool> 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.SpecialType == (signed ? SpecialType.System_IntPtr : SpecialType.System_UIntPtr);
                }
 
                static bool isNullableNativeInt(TypeSymbol type, bool signed)
                {
                    return type.IsNullableType() && isNativeInt(type.GetNullableUnderlyingType(), signed);
                }
            }
        }
 
        [Theory, CombinatorialData]
        public void BuiltInConversions_NativeIntegers(bool useCompilationReference, bool useLatest, bool useSystemTypes)
        {
            var nintType = useSystemTypes ? "System.IntPtr" : "nint";
            var nuintType = useSystemTypes ? "System.UIntPtr" : "nuint";
 
            var sourceA = $$"""
public class A
{
    public static {{nintType}} F1;
    public static {{nuintType}} F2;
    public static {{nintType}}? F3;
    public static {{nuintType}}? F4;
}
""";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            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, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify);
            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       ""readonly bool nint?.HasValue.get""
  IL_0019:  brfalse.s  IL_0023
  IL_001b:  ldloca.s   V_0
  IL_001d:  call       ""readonly 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       ""readonly bool nuint?.HasValue.get""
  IL_0030:  brfalse.s  IL_003a
  IL_0032:  ldloca.s   V_1
  IL_0034:  call       ""readonly 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       ""readonly 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       ""readonly 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       ""readonly 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       ""readonly uint uint?.GetValueOrDefault()""
  IL_0053:  conv.u
  IL_0054:  newobj     ""nuint?..ctor(nuint)""
  IL_0059:  stsfld     ""nuint? A.F4""
  IL_005e:  ret
}");
        }
 
        [Theory, CombinatorialData]
        public void BuiltInOperators_NativeIntegers(bool useCSharp9, bool useCompilationReference, bool useSystemTypes)
        {
            var nintType = useSystemTypes ? "System.IntPtr" : "nint";
            var nuintType = useSystemTypes ? "System.UIntPtr" : "nuint";
 
            var sourceA = $$"""
public class A
{
    public static {{nintType}} F1;
    public static {{nuintType}} F2;
    public static {{nintType}}? F3;
    public static {{nuintType}}? F4;
}
""";
            var comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            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: useCSharp9 ? TestOptions.Regular9 : TestOptions.Regular8, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify);
            verifier.VerifyIL("B.Main",
@"{
  // Code size      247 (0xf7)
  .maxstack  2
  .locals init (nint? V_0,
                nint? V_1,
                nuint? V_2,
                nuint? V_3,
                nint V_4,
                nuint 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       ""readonly 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       ""readonly 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       ""readonly 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       ""readonly 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       ""readonly 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       ""readonly 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       ""readonly 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       ""readonly 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
}");
        }
 
        [Fact, WorkItem(63860, "https://github.com/dotnet/roslyn/issues/63860")]
        public void IntPtrOperator_OnPlatformWithNumericIntPtr()
        {
            var source = """
using System;
 
class C
{
    public static void M()
    {
        IntPtr a = default;
        bool b = a == IntPtr.Zero;
        a += 1;
        _ = a + 1;
    }
}
""";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [Fact, WorkItem(63860, "https://github.com/dotnet/roslyn/issues/63860")]
        public void IntPtrOperator_OnPlatformWithoutNumericIntPtr()
        {
            var source = """
using System;
 
class C
{
    public static void M()
    {
        IntPtr a = default;
        bool b = a == IntPtr.Zero;
        a += 1;
        _ = a + 1;
    }
}
""";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3);
            comp.VerifyDiagnostics();
 
            comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }
 
        [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, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var nodes = tree.GetRoot().DescendantNodes().OfType<PrefixUnaryExpressionSyntax>();
            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)]
        [InlineData("System.IntPtr", false)]
        [InlineData("System.UIntPtr", false)]
        [InlineData("System.IntPtr", true)]
        [InlineData("System.UIntPtr", 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, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
            var nodes = tree.GetRoot().DescendantNodes().OfType<BinaryExpressionSyntax>();
            var actualOperators = nodes.Select(n => model.GetSymbolInfo(n).Symbol.ToTestDisplayString()).ToArray();
            var nativeType = AsNative(type);
            var expectedOperators = new[]
            {
                $"{nativeType} {nativeType}.op_Addition({nativeType} left, {nativeType} right)",
                $"{nativeType} {nativeType}.op_Subtraction({nativeType} left, {nativeType} right)",
                $"{nativeType} {nativeType}.op_Multiply({nativeType} left, {nativeType} right)",
                $"{nativeType} {nativeType}.op_Division({nativeType} left, {nativeType} right)",
                $"{nativeType} {nativeType}.op_Modulus({nativeType} left, {nativeType} right)",
                $"System.Boolean {nativeType}.op_LessThan({nativeType} left, {nativeType} right)",
                $"System.Boolean {nativeType}.op_LessThanOrEqual({nativeType} left, {nativeType} right)",
                $"System.Boolean {nativeType}.op_GreaterThan({nativeType} left, {nativeType} right)",
                $"System.Boolean {nativeType}.op_GreaterThanOrEqual({nativeType} left, {nativeType} right)",
                $"System.Boolean {nativeType}.op_Equality({nativeType} left, {nativeType} right)",
                $"System.Boolean {nativeType}.op_Inequality({nativeType} left, {nativeType} right)",
                $"{nativeType} {nativeType}.op_BitwiseAnd({nativeType} left, {nativeType} right)",
                $"{nativeType} {nativeType}.op_BitwiseOr({nativeType} left, {nativeType} right)",
                $"{nativeType} {nativeType}.op_ExclusiveOr({nativeType} left, {nativeType} right)",
                $"{nativeType} {nativeType}.op_LeftShift({nativeType} left, System.Int32 right)",
                $"{nativeType} {nativeType}.op_RightShift({nativeType} 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()
    {{
        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;
        }}
    }}
}}";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            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 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;
        }}
    }}
}}";
 
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            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 ConstantConversions_01()
        {
            var source =
@"using System;
class Program
{
    static void Main()
    {
        const long x = 0xFFFFFFFFFFFFFFFL;
        const IntPtr y = checked((IntPtr)x);
        Console.WriteLine(y);
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            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()
    {
        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, targetFramework: TargetFramework.Net70);
            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: IncludeExpectedOutput(IntPtr.Size == 4 ? "System.OverflowException" : "1152921504606846975"), verify: Verification.FailsPEVerify);
        }
 
        [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 IntPtr y = unchecked((IntPtr)x);
        Console.WriteLine(y);
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            comp.VerifyDiagnostics(
                // (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));
 
            source =
@"using System;
class Program
{
    static void Main()
    {
        const long x = 0xFFFFFFFFFFFFFFFL;
        IntPtr y = unchecked((IntPtr)x);
        Console.WriteLine(y);
    }
}";
            comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(IntPtr.Size == 4 ? "-1" : "1152921504606846975"));
        }
 
        [Fact]
        public void ConstantConversions_03()
        {
            using var _ = new EnsureInvariantCulture();
 
            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));
 
            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, targetFramework: TargetFramework.Net70);
 
                comp.VerifyDiagnostics(expectedError is null ? Array.Empty<DiagnosticDescription>() : new[] { expectedError });
                if (expectedError == null || ErrorFacts.IsWarning((ErrorCode)expectedError.Code))
                {
                    CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(expectedOutput));
                }
            }
        }
 
        [Theory]
        [InlineData("nint")]
        [InlineData("System.IntPtr")]
        public void Constants_NInt(string type)
        {
            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({type} n)
    {{
        System.Console.WriteLine(n);
    }}
}}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            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: IncludeExpectedOutput(expectedOutput), verify: Verification.FailsPEVerify);
            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);
        }
 
        [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 = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            string expectedOutput =
@"0
0
1
2
3
4
5
6
7
8
9
255
65535
65535
2147483647
2147483648
4294967295";
            var verifier = CompileAndVerify(comp, expectedOutput: IncludeExpectedOutput(expectedOutput), verify: Verification.FailsPEVerify);
            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<ushort>(sbyte.MaxValue); // 1
        F<ushort>(short.MaxValue); // 2
        F<ushort>(int.MaxValue); // 3
        F<ushort>(long.MaxValue); // 4
        F<uint>(sbyte.MaxValue); // 5
        F<uint>(short.MaxValue); // 6
        F<uint>(int.MaxValue); // 7
        F<uint>(long.MaxValue); // 8
        F<System.UIntPtr>(sbyte.MaxValue); // 9
        F<System.UIntPtr>(short.MaxValue); // 10
        F<System.UIntPtr>(int.MaxValue); // 11
        F<System.UIntPtr>(long.MaxValue); // 12
        F<nuint>(sbyte.MaxValue); // 13
        F<nuint>(short.MaxValue); // 14
        F<nuint>(int.MaxValue); // 15
        F<nuint>(long.MaxValue); // 16
        F<ulong>(sbyte.MaxValue); // 17
        F<ulong>(short.MaxValue); // 18
        F<ulong>(int.MaxValue); // 19
        F<ulong>(long.MaxValue); // 20
    }
    static void F<T>(T n)
    {
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (5,19): error CS1503: Argument 1: cannot convert from 'sbyte' to 'ushort'
                //         F<ushort>(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<ushort>(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<ushort>(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<ushort>(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<uint>(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<uint>(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<uint>(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<System.UIntPtr>(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<System.UIntPtr>(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<System.UIntPtr>(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<nuint>(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<nuint>(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<nuint>(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<ulong>(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<ulong>(short.MaxValue); // 18
                Diagnostic(ErrorCode.ERR_BadArgType, "short.MaxValue").WithArguments("1", "short", "ulong").WithLocation(22, 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, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [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);
 
    public static void Main()
    {
        System.Console.Write($""{A}, {B}, {C}, {D}"");
    }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
 
            comp.VerifyDiagnostics();
            CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput("0, 0, 0, 0"));
        }
 
        [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, targetFramework: TargetFramework.Net70);
            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, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
@"-42
42"));
        }
 
        [Fact]
        public void Constants_ParameterDefaults()
        {
            var source0 =
@"public class A
{
    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 comp = CreateCompilation(source0, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            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, targetFramework: TargetFramework.Net70);
 
            CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
@"-42
-42
42
42"));
        }
 
        [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 = CreateCompilation(source, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            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);
            }
        }
 
        /// <summary>
        /// Native integers cannot be used as attribute values.
        /// </summary>
        [Fact]
        public void AttributeValue_01()
        {
            var source0 =
@"using System;
class A : System.Attribute
{
    public A() { }
    public A(object value) { }
    public object Value;
}
[A((IntPtr)1)]
[A(new IntPtr[0])]
[A(Value = (IntPtr)3)]
[A(Value = new[] { (IntPtr)4 })]
class B
{
}";
            var comp = CreateCompilation(source0, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            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 AttributeValue_02()
        {
            var source0 =
@"using System;
class A : System.Attribute
{
    public A() { }
    public A(IntPtr value) { }
    public IntPtr[] Value;
}
[A(1)]
[A(Value = default)]
class B
{
}";
            var comp = CreateCompilation(source0, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            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 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 =
@"using System;
public class A
{
    public static void F0(IntPtr x = default, UIntPtr y = default)
    {
        Report(x);
        Report(y);
    }
    public static void F1(IntPtr x = -1, UIntPtr y = 2)
    {
        Report(x);
        Report(y);
    }
    public static void F2(IntPtr? x = null, UIntPtr? y = null)
    {
        Report(x);
        Report(y);
    }
    public static void F3(IntPtr? x = -3, UIntPtr? 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, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, expectedOutput: IncludeExpectedOutput(expectedOutput), verify: Verification.FailsPEVerify);
 
            comp = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            var ref1 = comp.ToMetadataReference();
            var ref2 = comp.EmitToImageReference();
 
            comp = CreateCompilation(sourceB, references: new[] { ref1 }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, expectedOutput: IncludeExpectedOutput(expectedOutput), verify: Verification.FailsPEVerify);
 
            comp = CreateCompilation(sourceB, references: new[] { ref2 }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, expectedOutput: IncludeExpectedOutput(expectedOutput), verify: Verification.FailsPEVerify);
 
            comp = CreateCompilation(sourceB, references: new[] { ref1 }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular8, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, expectedOutput: IncludeExpectedOutput(expectedOutput), verify: Verification.FailsPEVerify);
 
            comp = CreateCompilation(sourceB, references: new[] { ref2 }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular8, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, expectedOutput: IncludeExpectedOutput(expectedOutput), verify: Verification.FailsPEVerify);
        }
 
        [Fact]
        public void SwitchStatement_01()
        {
            var source =
@"using System;
class Program
{
   static IntPtr M(IntPtr 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, targetFramework: TargetFramework.Net70);
 
            var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
@"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 UIntPtr M(UIntPtr 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, targetFramework: TargetFramework.Net70);
 
            var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
@"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
    }
");
        }
 
        [Fact]
        public void Conversions()
        {
            const string convNone =
@"{
  // Code size        2 (0x2)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ret
}";
            static string conv(string conversion) =>
$@"{{
  // Code size        3 (0x3)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  {conversion}
  IL_0002:  ret
}}";
            static string convRUn(string conversion) =>
$@"{{
      // Code size        4 (0x4)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  conv.r.un
  IL_0002:  {conversion}
  IL_0003:  ret
}}";
            static string convFromNullableT(string conversion, string sourceType) =>
$@"{{
  // Code size        9 (0x9)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly {sourceType} {sourceType}?.Value.get""
  IL_0007:  {conversion}
  IL_0008:  ret
}}";
            static string convRUnFromNullableT(string conversion, string sourceType) =>
$@"{{
  // Code size       10 (0xa)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly {sourceType} {sourceType}?.Value.get""
  IL_0007:  conv.r.un
  IL_0008:  {conversion}
  IL_0009:  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 convRUnToNullableT(string conversion, string destType) =>
$@"{{
  // Code size        9 (0x9)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  conv.r.un
  IL_0002:  {conversion}
  IL_0003:  newobj     ""{destType}?..ctor({destType})""
  IL_0008:  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       ""readonly 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       ""readonly {sourceType} {sourceType}?.GetValueOrDefault()""
  IL_001c:  {conversion}
  IL_001d:  newobj     ""{destType}?..ctor({destType})""
  IL_0022:  ret
}}";
            static string convRUnFromToNullableT(string conversion, string sourceType, string destType) =>
$@"{{
  // Code size       36 (0x24)
  .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       ""readonly 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       ""readonly {sourceType} {sourceType}?.GetValueOrDefault()""
  IL_001c:  conv.r.un
  IL_001d:  {conversion}
  IL_001e:  newobj     ""{destType}?..ctor({destType})""
  IL_0023:  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       ""readonly 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       ""readonly {sourceType} {sourceType}?.GetValueOrDefault()""
  IL_0015:  call       ""{method}""
  IL_001a:  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));
                }
 
                convert(
                    sourceType,
                    destType,
                    expectedImplicitIL,
                    useExplicitCast: false,
                    useChecked: false,
                    expectedConversions: expectedConversions,
                    expectedErrorCode: expectedImplicitIL is null ?
                        expectedExplicitIL is null ? ErrorCode.ERR_NoImplicitConv : ErrorCode.ERR_NoImplicitConvCast :
                        0);
 
                // Explicit cast
                convert(
                    sourceType,
                    destType,
                    expectedExplicitIL,
                    useExplicitCast: true,
                    useChecked: false,
                    expectedConversions: null,
                    expectedErrorCode: expectedExplicitIL is null ? ErrorCode.ERR_NoExplicitConv : 0);
 
                // Explicit cast and checked
                expectedCheckedIL ??= expectedExplicitIL;
                convert(
                    sourceType,
                    destType,
                    expectedCheckedIL,
                    useExplicitCast: true,
                    useChecked: true,
                    expectedConversions: null,
                    expectedErrorCode: expectedCheckedIL is null ? ErrorCode.ERR_NoExplicitConv : 0);
            }
 
            // Test start:
            // type to nint
            conversions(sourceType: "object", destType: "nint", 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: "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*<void>", 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: convNone, 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:  ldarg.0
  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       ""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: convNone, expectedCheckedIL: conv("conv.ovf.i.un"));
 
            // 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        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nint nint?.Value.get""
  IL_0007:  ret
}");
            conversions(sourceType: "nuint?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nuint nuint?.Value.get""
  IL_0007:  ret
}
",
                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       ""readonly 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       ""readonly 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       ""readonly nint nint?.Value.get""
  IL_0007:  ret
}");
            conversions(sourceType: "System.UIntPtr?", destType: "nint", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nuint nuint?.Value.get""
  IL_0007:  ret
}
",
                expectedCheckedIL: convFromNullableT("conv.ovf.i.un", "nuint"));
 
            // type to nullable nint
            conversions(sourceType: "object", destType: "nint?", 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: "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:  newobj     ""nint?..ctor(nint)""
  IL_0006:  ret
}",
@"{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  conv.ovf.i.un
  IL_0002:  newobj     ""nint?..ctor(nint)""
  IL_0007:  ret
}");
            conversions(sourceType: "delegate*<void>", 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:  conv.ovf.i.un
  IL_0002:  newobj     ""nint?..ctor(nint)""
  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,
@"{
  // 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: "nuint", destType: "nint?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  newobj     ""nint?..ctor(nint)""
  IL_0006:  ret
}
",
                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:
@"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  newobj     ""nint?..ctor(nint)""
  IL_0006:  ret
}
",
                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:
@"
{
  // Code size       34 (0x22)
  .maxstack  1
  .locals init (nuint? V_0,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nuint?.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       ""readonly nuint nuint?.GetValueOrDefault()""
  IL_001c:  newobj     ""nint?..ctor(nint)""
  IL_0021:  ret
}
",
                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       ""readonly 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       ""readonly 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       ""readonly 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       ""readonly 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:
@"
{
  // Code size       34 (0x22)
  .maxstack  1
  .locals init (nuint? V_0,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nuint?.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       ""readonly nuint nuint?.GetValueOrDefault()""
  IL_001c:  newobj     ""nint?..ctor(nint)""
  IL_0021:  ret
}
",
                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:  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"));
            conversions(sourceType: "nint", destType: "delegate*<void>", 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:  conv.i8
  IL_0002:  call       ""decimal decimal.op_Implicit(long)""
  IL_0007:  ret
}",
@"{
  // Code size        8 (0x8)
  .maxstack  1
  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: convNone, 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:  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:  conv.i8
  IL_0002:  call       ""decimal decimal.op_Implicit(long)""
  IL_0007:  newobj     ""decimal?..ctor(decimal)""
  IL_000c:  ret
}");
            conversions(sourceType: "nint", destType: "System.IntPtr?", 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: "nint", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  newobj     ""nuint?..ctor(nuint)""
  IL_0006:  ret
}
",
                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:  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*", ExplicitUserDefined, expectedImplicitIL: null, expectedExplicitIL: convExplicitFromNullableT("nint", "void* nint.op_Explicit(nint)"));
            conversions(sourceType: "nint?", destType: "delegate*<void>", 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       ""readonly nint nint?.Value.get""
  IL_0007:  conv.i8
  IL_0008:  call       ""decimal decimal.op_Implicit(long)""
  IL_000d:  ret
}");
            conversions(sourceType: "nint?", destType: "System.IntPtr", ExplicitNullableIdentity, expectedImplicitIL: null,
@"{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nint nint?.Value.get""
  IL_0007:  ret
}");
            conversions(sourceType: "nint?", destType: "System.UIntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nint nint?.Value.get""
  IL_0007:  ret
}
",
                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:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly 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       ""readonly 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 (nint? V_0,
                decimal? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly 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       ""readonly 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:
@"
{
  // Code size       34 (0x22)
  .maxstack  1
  .locals init (nint? V_0,
                nuint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nint?.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       ""readonly nint nint?.GetValueOrDefault()""
  IL_001c:  newobj     ""nuint?..ctor(nuint)""
  IL_0021:  ret
}
",
                expectedCheckedIL: convFromToNullableT("conv.ovf.u", "nint", "nuint"));
 
            // 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  ""nuint""
  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*<void>", 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: convNone, 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       ""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       ""ulong decimal.op_Explicit(decimal)""
  IL_0006:  conv.ovf.u.un
  IL_0007:  ret
}");
            conversions(sourceType: "System.IntPtr", destType: "nuint", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convNone, 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:
@"
{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nint nint?.Value.get""
  IL_0007:  ret
}
",
                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       ""readonly nuint nuint?.Value.get""
  IL_0007:  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,
@"{
  // Code size       14 (0xe)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly decimal decimal?.Value.get""
  IL_0007:  call       ""ulong decimal.op_Explicit(decimal)""
  IL_000c:  conv.u
  IL_000d:  ret
}",
@"{
  // Code size       14 (0xe)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly 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", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nint nint?.Value.get""
  IL_0007:  ret
}",
                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       ""readonly nuint nuint?.Value.get""
  IL_0007:  ret
}");
 
            // 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  ""nuint?""
  IL_0006:  ret
}");
            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     ""nuint?..ctor(nuint)""
  IL_0006:  ret
}");
            conversions(sourceType: "delegate*<void>", 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:
@"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  newobj     ""nuint?..ctor(nuint)""
  IL_0006:  ret
}
",
                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        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  newobj     ""nuint?..ctor(nuint)""
  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,
@"{
  // 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:
@"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  newobj     ""nuint?..ctor(nuint)""
  IL_0006:  ret
}
",
                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     ""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:
@"
{
  // Code size       34 (0x22)
  .maxstack  1
  .locals init (nint? V_0,
                nuint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nint?.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       ""readonly nint nint?.GetValueOrDefault()""
  IL_001c:  newobj     ""nuint?..ctor(nuint)""
  IL_0021:  ret
}
",
                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       ""readonly 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       ""readonly 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       ""readonly 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       ""readonly 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:
@"
{
  // Code size       34 (0x22)
  .maxstack  1
  .locals init (nint? V_0,
                nuint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nint?.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       ""readonly nint nint?.GetValueOrDefault()""
  IL_001c:  newobj     ""nuint?..ctor(nuint)""
  IL_0021:  ret
}
",
                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*<void>", 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: convRUn("conv.r4"), expectedExplicitIL: convRUn("conv.r4"));
            conversions(sourceType: "nuint", destType: "double", ImplicitNumeric, expectedImplicitIL: convRUn("conv.r8"), expectedExplicitIL: convRUn("conv.r8"));
            conversions(sourceType: "nuint", destType: "decimal", ImplicitNumeric,
@"{
  // 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
}",
@"{
  // 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", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convNone, 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: convRUnToNullableT("conv.r4", "float"), expectedExplicitIL: convRUnToNullableT("conv.r4", "float"), null);
            conversions(sourceType: "nuint", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convRUnToNullableT("conv.r8", "double"), expectedExplicitIL: convRUnToNullableT("conv.r8", "double"), null);
            conversions(sourceType: "nuint", destType: "decimal?", ImplicitNullableNumeric,
@"{
  // Code size       13 (0xd)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  conv.u8
  IL_0002:  call       ""decimal decimal.op_Implicit(ulong)""
  IL_0007:  newobj     ""decimal?..ctor(decimal)""
  IL_000c:  ret
}",
@"{
  // Code size       13 (0xd)
  .maxstack  1
  IL_0000:  ldarg.0
  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: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  newobj     ""nint?..ctor(nint)""
  IL_0006:  ret
}
",
                expectedCheckedIL: convToNullableT("conv.ovf.i.un", "nint"));
            conversions(sourceType: "nuint", destType: "System.UIntPtr?", ImplicitNullableIdentity,
@"{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  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 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*", ExplicitUserDefined, expectedImplicitIL: null, expectedExplicitIL: convExplicitFromNullableT("nuint", "void* nuint.op_Explicit(nuint)"));
            conversions(sourceType: "nuint?", destType: "delegate*<void>", 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: convRUnFromNullableT("conv.r4", "nuint"));
            conversions(sourceType: "nuint?", destType: "double", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convRUnFromNullableT("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       ""readonly 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:
@"
{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nuint nuint?.Value.get""
  IL_0007:  ret
}
",
                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       ""readonly 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: convRUnFromToNullableT("conv.r4", "nuint", "float"), expectedExplicitIL: convRUnFromToNullableT("conv.r4", "nuint", "float"), null);
            conversions(sourceType: "nuint?", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convRUnFromToNullableT("conv.r8", "nuint", "double"), expectedExplicitIL: convRUnFromToNullableT("conv.r8", "nuint", "double"), null);
            conversions(sourceType: "nuint?", destType: "decimal?", ImplicitNullableNumeric,
@"{
  // Code size       40 (0x28)
  .maxstack  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       ""readonly bool nuint?.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       ""readonly 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 (nuint? V_0,
                decimal? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nuint?.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       ""readonly 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: "nuint?", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size       34 (0x22)
  .maxstack  1
  .locals init (nuint? V_0,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nuint?.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       ""readonly nuint nuint?.GetValueOrDefault()""
  IL_001c:  newobj     ""nint?..ctor(nint)""
  IL_0021:  ret
}
",
                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        ""nint""
  IL_0006:  ret
}",
@"{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  box        ""nint""
  IL_0006:  ret
}");
            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*<void>", 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*<void>", 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
  IL_0000:  ldarg.0
  IL_0001:  conv.i8
  IL_0002:  call       ""decimal decimal.op_Implicit(long)""
  IL_0007:  ret
}",
@"{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  conv.i8
  IL_0002:  call       ""decimal decimal.op_Implicit(long)""
  IL_0007:  ret
}");
            conversions(sourceType: "System.IntPtr", destType: "System.IntPtr", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone);
            conversions(sourceType: "System.IntPtr", destType: "System.UIntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convNone, 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
  IL_0000:  ldarg.0
  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:  conv.i8
  IL_0002:  call       ""decimal decimal.op_Implicit(long)""
  IL_0007:  newobj     ""decimal?..ctor(decimal)""
  IL_000c:  ret
}");
            conversions(sourceType: "System.IntPtr", destType: "System.IntPtr?", 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.IntPtr", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  newobj     ""nuint?..ctor(nuint)""
  IL_0006:  ret
}
",
                expectedCheckedIL: convToNullableT("conv.ovf.u", "nuint"));
 
            // nullable System.IntPtr to type
            conversions(sourceType: "System.IntPtr?", destType: "object", Boxing,
@"{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  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: "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*<void>", 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
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nint nint?.Value.get""
  IL_0007:  conv.i8
  IL_0008:  call       ""decimal decimal.op_Implicit(long)""
  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       ""readonly nint nint?.Value.get""
  IL_0007:  ret
}");
            conversions(sourceType: "System.IntPtr?", destType: "System.UIntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nint nint?.Value.get""
  IL_0007:  ret
}
",
                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
  .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       ""readonly 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       ""readonly 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 (nint? V_0,
                decimal? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly 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       ""readonly 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: "System.IntPtr?", destType: "System.IntPtr?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone);
            conversions(sourceType: "System.IntPtr?", destType: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size       34 (0x22)
  .maxstack  1
  .locals init (nint? V_0,
                nuint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nint?.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       ""readonly nint nint?.GetValueOrDefault()""
  IL_001c:  newobj     ""nuint?..ctor(nuint)""
  IL_0021:  ret
}
",
                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*<void>", 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: convNone, 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       ""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       ""long decimal.op_Explicit(decimal)""
  IL_0006:  conv.ovf.i
  IL_0007:  ret
}");
            conversions(sourceType: "System.UIntPtr", destType: "System.IntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convNone, expectedCheckedIL: conv("conv.ovf.i.un"));
 
            // type to nullable 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?", 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:  conv.ovf.i.un
  IL_0002:  newobj     ""nint?..ctor(nint)""
  IL_0007:  ret
}");
            conversions(sourceType: "delegate*<void>", destType: "System.IntPtr?", 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:  conv.ovf.i.un
  IL_0002:  newobj     ""nint?..ctor(nint)""
  IL_0007:  ret
}");
            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     ""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: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  newobj     ""nint?..ctor(nint)""
  IL_0006:  ret
}
",
                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       ""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: "System.IntPtr?", 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: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  newobj     ""nint?..ctor(nint)""
  IL_0006:  ret
}
",
                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       ""readonly nint nint?.Value.get""
  IL_0007:  ret
}");
            conversions(sourceType: "nuint?", destType: "System.IntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nuint nuint?.Value.get""
  IL_0007:  ret
}
",
                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       ""readonly 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       ""readonly 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       ""readonly nint nint?.Value.get""
  IL_0007:  ret
}");
            conversions(sourceType: "System.UIntPtr?", destType: "System.IntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nuint nuint?.Value.get""
  IL_0007:  ret
}
",
                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:
@"
{
  // Code size       34 (0x22)
  .maxstack  1
  .locals init (nuint? V_0,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nuint?.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       ""readonly nuint nuint?.GetValueOrDefault()""
  IL_001c:  newobj     ""nint?..ctor(nint)""
  IL_0021:  ret
}
",
                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,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly 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       ""readonly 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       ""readonly 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       ""readonly 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: "System.IntPtr?", Identity, expectedImplicitIL: convNone, expectedExplicitIL: convNone);
            conversions(sourceType: "System.UIntPtr?", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size       34 (0x22)
  .maxstack  1
  .locals init (nuint? V_0,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nuint?.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       ""readonly nuint nuint?.GetValueOrDefault()""
  IL_001c:  newobj     ""nint?..ctor(nint)""
  IL_0021:  ret
}
",
                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        ""nuint""
  IL_0006:  ret
}",
@"{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  box        ""nuint""
  IL_0006:  ret
}");
            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*<void>", 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: convRUn("conv.r4"), expectedExplicitIL: convRUn("conv.r4"));
            conversions(sourceType: "System.UIntPtr", destType: "double", ImplicitNumeric, expectedImplicitIL: convRUn("conv.r8"), expectedExplicitIL: convRUn("conv.r8"));
            conversions(sourceType: "System.UIntPtr", destType: "decimal", ImplicitNumeric,
@"{
  // 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
}",
@"{
  // 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: convNone, 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: convRUnToNullableT("conv.r4", "float"), expectedExplicitIL: convRUnToNullableT("conv.r4", "float"), null);
            conversions(sourceType: "System.UIntPtr", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convRUnToNullableT("conv.r8", "double"), expectedExplicitIL: convRUnToNullableT("conv.r8", "double"), null);
            conversions(sourceType: "System.UIntPtr", destType: "decimal?", ImplicitNullableNumeric,
@"{
  // Code size       13 (0xd)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  conv.u8
  IL_0002:  call       ""decimal decimal.op_Implicit(ulong)""
  IL_0007:  newobj     ""decimal?..ctor(decimal)""
  IL_000c:  ret
}",
@"{
  // Code size       13 (0xd)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  conv.u8
  IL_0002:  call       ""decimal decimal.op_Implicit(ulong)""
  IL_0007:  newobj     ""decimal?..ctor(decimal)""
  IL_000c:  ret
}");
            conversions(sourceType: "System.UIntPtr", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  newobj     ""nint?..ctor(nint)""
  IL_0006:  ret
}
",
                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     ""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 System.UIntPtr to type
            conversions(sourceType: "System.UIntPtr?", 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: "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*<void>", 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: convRUnFromNullableT("conv.r4", "nuint"));
            conversions(sourceType: "System.UIntPtr?", destType: "double", ExplicitNullableImplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convRUnFromNullableT("conv.r8", "nuint"));
            conversions(sourceType: "System.UIntPtr?", destType: "decimal", ExplicitNullableImplicitNumeric, expectedImplicitIL: null,
@"{
  // Code size       14 (0xe)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nuint nuint?.Value.get""
  IL_0007:  conv.u8
  IL_0008:  call       ""decimal decimal.op_Implicit(ulong)""
  IL_000d:  ret
}");
            conversions(sourceType: "System.UIntPtr?", destType: "System.IntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nuint nuint?.Value.get""
  IL_0007:  ret
}
",
                expectedCheckedIL: convFromNullableT("conv.ovf.i.un", "nuint"));
            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       ""readonly nuint nuint?.Value.get""
  IL_0007:  ret
}");
 
            // 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: convRUnFromToNullableT("conv.r4", "nuint", "float"), expectedExplicitIL: convRUnFromToNullableT("conv.r4", "nuint", "float"), null);
            conversions(sourceType: "System.UIntPtr?", destType: "double?", ImplicitNullableNumeric, expectedImplicitIL: convRUnFromToNullableT("conv.r8", "nuint", "double"), expectedExplicitIL: convRUnFromToNullableT("conv.r8", "nuint", "double"), null);
            conversions(sourceType: "System.UIntPtr?", destType: "decimal?", ImplicitNullableNumeric,
@"{
  // Code size       40 (0x28)
  .maxstack  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       ""readonly bool nuint?.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       ""readonly 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 (nuint? V_0,
                decimal? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nuint?.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       ""readonly 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.UIntPtr?", destType: "System.IntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size       34 (0x22)
  .maxstack  1
  .locals init (nuint? V_0,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nuint?.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       ""readonly nuint nuint?.GetValueOrDefault()""
  IL_001c:  newobj     ""nint?..ctor(nint)""
  IL_0021:  ret
}
",
                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:  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*<void>", 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: convNone, 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        8 (0x8)
  .maxstack  1
  IL_0000:  ldarg.0
  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       ""ulong decimal.op_Explicit(decimal)""
  IL_0006:  conv.ovf.u.un
  IL_0007:  ret
}");
            conversions(sourceType: "System.IntPtr", destType: "System.UIntPtr", ExplicitNumeric, expectedImplicitIL: null, expectedExplicitIL: convNone, 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:  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     ""nuint?..ctor(nuint)""
  IL_0006:  ret
}");
            conversions(sourceType: "delegate*<void>", destType: "System.UIntPtr?", 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: "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:
@"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  newobj     ""nuint?..ctor(nuint)""
  IL_0006:  ret
}
",
                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:  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
}");
            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       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: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  newobj     ""nuint?..ctor(nuint)""
  IL_0006:  ret
}
",
                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     ""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 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:
@"
{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nint nint?.Value.get""
  IL_0007:  ret
}
",
                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       ""readonly nuint nuint?.Value.get""
  IL_0007:  ret
}");
            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       14 (0xe)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly decimal decimal?.Value.get""
  IL_0007:  call       ""ulong decimal.op_Explicit(decimal)""
  IL_000c:  conv.u
  IL_000d:  ret
}",
@"{
  // Code size       14 (0xe)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly 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: "System.UIntPtr", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarga.s   V_0
  IL_0002:  call       ""readonly nint nint?.Value.get""
  IL_0007:  ret
}
",
                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       ""readonly nuint nuint?.Value.get""
  IL_0007:  ret
}");
 
            // 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?", 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:
@"
{
  // Code size       34 (0x22)
  .maxstack  1
  .locals init (nint? V_0,
                nuint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nint?.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       ""readonly nint nint?.GetValueOrDefault()""
  IL_001c:  newobj     ""nuint?..ctor(nuint)""
  IL_0021:  ret
}
",
                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       ""readonly 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       ""readonly 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       ""readonly 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       ""readonly 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: "System.UIntPtr?", ExplicitNullableNumeric, expectedImplicitIL: null, expectedExplicitIL:
@"
{
  // Code size       34 (0x22)
  .maxstack  1
  .locals init (nint? V_0,
                nuint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nint?.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       ""readonly nint nint?.GetValueOrDefault()""
  IL_001c:  newobj     ""nuint?..ctor(nuint)""
  IL_0021:  ret
}
",
                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 useExplicitCast,
                bool useChecked,
                ConversionKind[] expectedConversions,
                ErrorCode expectedErrorCode)
            {
                bool useUnsafeContext = useUnsafe(sourceType) || useUnsafe(destType);
                string value = "value";
                if (useExplicitCast)
                {
                    value = $"({destType})value";
                }
                var expectedDiagnostics = expectedErrorCode == 0 ?
                    Array.Empty<DiagnosticDescription>() :
                    new[] { Diagnostic(expectedErrorCode, value).WithArguments(AsNative(sourceType), AsNative(destType)) };
                if (useChecked)
                {
                    value = $"checked({value})";
                }
                string source =
$@"class Program
{{
    static {(useUnsafeContext ? "unsafe " : "")}{destType} Convert({sourceType} value)
    {{
        return {value};
    }}
}}
enum E {{ }}
";
                var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithAllowUnsafe(useUnsafeContext), parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
                comp.VerifyDiagnostics(expectedDiagnostics);
 
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var expr = tree.GetRoot().DescendantNodes().OfType<ReturnStatementSyntax>().Single().Expression;
                var typeInfo = model.GetTypeInfo(expr);
 
                if (!useExplicitCast)
                {
                    var destTypeSymbol = ((MethodSymbol)comp.GetMember("Program.Convert")).ReturnType.GetPublicSymbol();
                    AssertMatches(expectedConversions, model.ClassifyConversion(expr, destTypeSymbol));
                    Assert.Equal(AsNative(sourceType), typeInfo.Type.ToString());
                    Assert.Equal(AsNative(destType), typeInfo.ConvertedType.ToString());
                }
 
                if (expectedIL != null)
                {
                    var verifier = CompileAndVerify(comp, verify: useUnsafeContext ? Verification.Skipped : Verification.FailsPEVerify);
                    verifier.VerifyIL("Program.Convert", expectedIL);
                }
 
                static bool useUnsafe(string type) => type == "void*" || type == "delegate*<void>";
            }
        }
 
        [Fact]
        public void UnaryOperators()
        {
            static string getComplement(uint value)
            {
                object result = (IntPtr.Size == 4) ?
                    (object)~value :
                    (object)~(ulong)value;
                return result.ToString();
            }
 
            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, AsNative(opType));
                }
 
                unaryOperator(op, opType, opType, expectedSymbol, operand, expectedResult, expectedIL, diagnostic != null ? new[] { diagnostic } : Array.Empty<DiagnosticDescription>());
            }
 
            // 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
}");
            unifiedUnaryOp("+", "System.UIntPtr", "nuint nuint.op_UnaryPlus(nuint value)", "3", "3",
@"{
  // Code size        2 (0x2)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ret
}");
 
            // unary operator-
            unifiedUnaryOp("-", "System.IntPtr", "nint nint.op_UnaryNegation(nint value)", "3", "-3",
@"{
  // Code size        3 (0x3)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  neg
  IL_0002:  ret
}");
            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
  IL_0000:  ldarg.0
  IL_0001:  not
  IL_0002:  ret
}");
            unifiedUnaryOp("~", "System.UIntPtr", "nuint nuint.op_OnesComplement(nuint value)", "3", getComplement(3),
@"{
  // Code size        3 (0x3)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  not
  IL_0002:  ret
}");
 
            // lifted unary operator+
            unifiedUnaryOp("+", "System.IntPtr?", "nint nint.op_UnaryPlus(nint value)", "3", "3",
@"{
  // Code size       34 (0x22)
  .maxstack  1
  .locals init (nint? V_0,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nint?.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       ""readonly nint nint?.GetValueOrDefault()""
  IL_001c:  newobj     ""nint?..ctor(nint)""
  IL_0021:  ret
}");
            unifiedUnaryOp("+", "System.UIntPtr?", "nuint nuint.op_UnaryPlus(nuint value)", "3", "3",
@"{
  // Code size       34 (0x22)
  .maxstack  1
  .locals init (nuint? V_0,
                nuint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nuint?.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       ""readonly nuint nuint?.GetValueOrDefault()""
  IL_001c:  newobj     ""nuint?..ctor(nuint)""
  IL_0021:  ret
}");
 
            // lifted unary operator-
            unifiedUnaryOp("-", "System.IntPtr?", "nint nint.op_UnaryNegation(nint value)", "3", "-3",
@"{
  // Code size       35 (0x23)
  .maxstack  1
  .locals init (nint? V_0,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nint?.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       ""readonly nint nint?.GetValueOrDefault()""
  IL_001c:  neg
  IL_001d:  newobj     ""nint?..ctor(nint)""
  IL_0022:  ret
}");
            // Reporting ERR_AmbigUnaryOp for `-(nuint?)value` is inconsistent with the ERR_BadUnaryOp reported
            // 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?.
            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
  .locals init (nint? V_0,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nint?.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       ""readonly nint nint?.GetValueOrDefault()""
  IL_001c:  not
  IL_001d:  newobj     ""nint?..ctor(nint)""
  IL_0022:  ret
}");
            unifiedUnaryOp("~", "System.UIntPtr?", "nuint nuint.op_OnesComplement(nuint value)", "3", getComplement(3),
@"{
  // Code size       35 (0x23)
  .maxstack  1
  .locals init (nuint? V_0,
                nuint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nuint?.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       ""readonly nuint nuint?.GetValueOrDefault()""
  IL_001c:  not
  IL_001d:  newobj     ""nuint?..ctor(nuint)""
  IL_0022:  ret
}");
 
            void unaryOperator(string op, string opType, string resultType, string expectedSymbol, string operand, string expectedResult, string expectedIL, DiagnosticDescription[] expectedDiagnostics)
            {
                string source =
$@"class Program
{{
    static {resultType} Evaluate({opType} operand)
    {{
        return {op}operand;
    }}
    static void Main()
    {{
        System.Console.WriteLine(Evaluate({operand}));
    }}
}}";
                var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
                comp.VerifyDiagnostics(expectedDiagnostics);
 
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var expr = tree.GetRoot().DescendantNodes().OfType<PrefixUnaryExpressionSyntax>().Single();
                var symbolInfo = model.GetSymbolInfo(expr);
                Assert.Equal(expectedSymbol, symbolInfo.Symbol?.ToDisplayString(SymbolDisplayFormat.TestFormat.WithMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.UseSpecialTypes)));
 
                if (expectedDiagnostics.Length == 0)
                {
                    var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(expectedResult));
                    verifier.VerifyIL("Program.Evaluate", expectedIL);
                }
            }
        }
 
        [Fact]
        public void IncrementOperators()
        {
            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));
                opType += "?";
                incrementOperator(op, opType, isPrefix: true, expectedSymbol, useChecked, values, expectedResult, expectedLiftedIL, getDiagnostics(opType, isPrefix: true, diagnostic));
                incrementOperator(op, opType, isPrefix: false, expectedSymbol, useChecked, values, expectedResult, expectedLiftedIL, getDiagnostics(opType, isPrefix: false, diagnostic));
 
                DiagnosticDescription[] getDiagnostics(string opType, bool isPrefix, DiagnosticDescription diagnostic)
                {
                    if (expectedSymbol == null && diagnostic == null)
                    {
                        diagnostic = Diagnostic(ErrorCode.ERR_BadUnaryOp, isPrefix ? op + "operand" : "operand" + op).WithArguments(op, opType);
                    }
                    return diagnostic != null ? new[] { diagnostic } : Array.Empty<DiagnosticDescription>();
                }
            }
 
            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")}",
@"{
  // Code size        7 (0x7)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  add
  IL_0003:  starg.s    V_0
  IL_0005:  ldarg.0
  IL_0006:  ret
}",
@"{
  // Code size       40 (0x28)
  .maxstack  2
  .locals init (nint? V_0,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nint?.HasValue.get""
  IL_0009:  brtrue.s   IL_0016
  IL_000b:  ldloca.s   V_1
  IL_000d:  initobj    ""nint?""
  IL_0013:  ldloc.1
  IL_0014:  br.s       IL_0024
  IL_0016:  ldloca.s   V_0
  IL_0018:  call       ""readonly nint nint?.GetValueOrDefault()""
  IL_001d:  ldc.i4.1
  IL_001e:  add
  IL_001f:  newobj     ""nint?..ctor(nint)""
  IL_0024:  starg.s    V_0
  IL_0026:  ldarg.0
  IL_0027:  ret
}");
            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")}",
@"{
  // Code size        7 (0x7)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  add
  IL_0003:  starg.s    V_0
  IL_0005:  ldarg.0
  IL_0006:  ret
}",
@"{
  // Code size       40 (0x28)
  .maxstack  2
  .locals init (nuint? V_0,
                nuint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nuint?.HasValue.get""
  IL_0009:  brtrue.s   IL_0016
  IL_000b:  ldloca.s   V_1
  IL_000d:  initobj    ""nuint?""
  IL_0013:  ldloc.1
  IL_0014:  br.s       IL_0024
  IL_0016:  ldloca.s   V_0
  IL_0018:  call       ""readonly nuint nuint?.GetValueOrDefault()""
  IL_001d:  ldc.i4.1
  IL_001e:  add
  IL_001f:  newobj     ""nuint?..ctor(nuint)""
  IL_0024:  starg.s    V_0
  IL_0026:  ldarg.0
  IL_0027:  ret
}");
            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",
@"{
  // Code size        7 (0x7)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  sub
  IL_0003:  starg.s    V_0
  IL_0005:  ldarg.0
  IL_0006:  ret
}",
@"{
  // Code size       40 (0x28)
  .maxstack  2
  .locals init (nint? V_0,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nint?.HasValue.get""
  IL_0009:  brtrue.s   IL_0016
  IL_000b:  ldloca.s   V_1
  IL_000d:  initobj    ""nint?""
  IL_0013:  ldloc.1
  IL_0014:  br.s       IL_0024
  IL_0016:  ldloca.s   V_0
  IL_0018:  call       ""readonly nint nint?.GetValueOrDefault()""
  IL_001d:  ldc.i4.1
  IL_001e:  sub
  IL_001f:  newobj     ""nint?..ctor(nint)""
  IL_0024:  starg.s    V_0
  IL_0026:  ldarg.0
  IL_0027:  ret
}");
            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",
@"{
  // Code size        7 (0x7)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  sub
  IL_0003:  starg.s    V_0
  IL_0005:  ldarg.0
  IL_0006:  ret
}",
@"{
  // Code size       40 (0x28)
  .maxstack  2
  .locals init (nuint? V_0,
                nuint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nuint?.HasValue.get""
  IL_0009:  brtrue.s   IL_0016
  IL_000b:  ldloca.s   V_1
  IL_000d:  initobj    ""nuint?""
  IL_0013:  ldloc.1
  IL_0014:  br.s       IL_0024
  IL_0016:  ldloca.s   V_0
  IL_0018:  call       ""readonly nuint nuint?.GetValueOrDefault()""
  IL_001d:  ldc.i4.1
  IL_001e:  sub
  IL_001f:  newobj     ""nuint?..ctor(nuint)""
  IL_0024:  starg.s    V_0
  IL_0026:  ldarg.0
  IL_0027:  ret
}");
 
            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")}",
@"{
  // Code size        7 (0x7)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  add.ovf
  IL_0003:  starg.s    V_0
  IL_0005:  ldarg.0
  IL_0006:  ret
}",
@"{
  // Code size       40 (0x28)
  .maxstack  2
  .locals init (nint? V_0,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nint?.HasValue.get""
  IL_0009:  brtrue.s   IL_0016
  IL_000b:  ldloca.s   V_1
  IL_000d:  initobj    ""nint?""
  IL_0013:  ldloc.1
  IL_0014:  br.s       IL_0024
  IL_0016:  ldloca.s   V_0
  IL_0018:  call       ""readonly nint nint?.GetValueOrDefault()""
  IL_001d:  ldc.i4.1
  IL_001e:  add.ovf
  IL_001f:  newobj     ""nint?..ctor(nint)""
  IL_0024:  starg.s    V_0
  IL_0026:  ldarg.0
  IL_0027:  ret
}");
            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")}",
@"{
  // Code size        7 (0x7)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  add.ovf.un
  IL_0003:  starg.s    V_0
  IL_0005:  ldarg.0
  IL_0006:  ret
}",
@"{
  // Code size       40 (0x28)
  .maxstack  2
  .locals init (nuint? V_0,
                nuint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nuint?.HasValue.get""
  IL_0009:  brtrue.s   IL_0016
  IL_000b:  ldloca.s   V_1
  IL_000d:  initobj    ""nuint?""
  IL_0013:  ldloc.1
  IL_0014:  br.s       IL_0024
  IL_0016:  ldloca.s   V_0
  IL_0018:  call       ""readonly nuint nuint?.GetValueOrDefault()""
  IL_001d:  ldc.i4.1
  IL_001e:  add.ovf.un
  IL_001f:  newobj     ""nuint?..ctor(nuint)""
  IL_0024:  starg.s    V_0
  IL_0026:  ldarg.0
  IL_0027:  ret
}");
            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",
@"{
  // Code size        7 (0x7)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  sub.ovf
  IL_0003:  starg.s    V_0
  IL_0005:  ldarg.0
  IL_0006:  ret
}",
@"{
  // Code size       40 (0x28)
  .maxstack  2
  .locals init (nint? V_0,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nint?.HasValue.get""
  IL_0009:  brtrue.s   IL_0016
  IL_000b:  ldloca.s   V_1
  IL_000d:  initobj    ""nint?""
  IL_0013:  ldloc.1
  IL_0014:  br.s       IL_0024
  IL_0016:  ldloca.s   V_0
  IL_0018:  call       ""readonly nint nint?.GetValueOrDefault()""
  IL_001d:  ldc.i4.1
  IL_001e:  sub.ovf
  IL_001f:  newobj     ""nint?..ctor(nint)""
  IL_0024:  starg.s    V_0
  IL_0026:  ldarg.0
  IL_0027:  ret
}");
            unifiedIncrementOps("--", "System.UIntPtr", "nuint nuint.op_CheckedDecrement(nuint value)", useChecked: true,
                values: $"0, 1, {uint.MaxValue}",
                expectedResult: $"System.OverflowException, 0, 4294967294",
@"{
  // Code size        7 (0x7)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  sub.ovf.un
  IL_0003:  starg.s    V_0
  IL_0005:  ldarg.0
  IL_0006:  ret
}",
@"{
  // Code size       40 (0x28)
  .maxstack  2
  .locals init (nuint? V_0,
                nuint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool nuint?.HasValue.get""
  IL_0009:  brtrue.s   IL_0016
  IL_000b:  ldloca.s   V_1
  IL_000d:  initobj    ""nuint?""
  IL_0013:  ldloc.1
  IL_0014:  br.s       IL_0024
  IL_0016:  ldloca.s   V_0
  IL_0018:  call       ""readonly nuint nuint?.GetValueOrDefault()""
  IL_001d:  ldc.i4.1
  IL_001e:  sub.ovf.un
  IL_001f:  newobj     ""nuint?..ctor(nuint)""
  IL_0024:  starg.s    V_0
  IL_0026:  ldarg.0
  IL_0027:  ret
}");
 
            void incrementOperator(string op, string opType, bool isPrefix, string expectedSymbol, bool useChecked, string values, string expectedResult, string expectedIL, DiagnosticDescription[] expectedDiagnostics)
            {
                var source =
$@"using System;
class Program
{{
    static {opType} Evaluate({opType} operand)
    {{
        {(useChecked ? "checked" : "unchecked")}
        {{
            {(isPrefix ? op + "operand" : "operand" + op)};
            return operand;
        }}
    }}
    static void EvaluateAndReport({opType} operand)
    {{
        object result;
        try
        {{
            result = Evaluate(operand);
        }}
        catch (Exception e)
        {{
            result = e.GetType();
        }}
        Console.Write(result);
    }}
    static void Main()
    {{
        bool separator = false;
        foreach (var value in new {opType}[] {{ {values} }})
        {{
            if (separator) Console.Write("", "");
            separator = true;
            EvaluateAndReport(value);
        }}
    }}
}}";
                var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
                comp.VerifyDiagnostics(expectedDiagnostics);
 
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var kind = (op == "++") ?
                    isPrefix ? SyntaxKind.PreIncrementExpression : SyntaxKind.PostIncrementExpression :
                    isPrefix ? SyntaxKind.PreDecrementExpression : SyntaxKind.PostDecrementExpression;
                var expr = tree.GetRoot().DescendantNodes().Single(n => n.Kind() == kind);
                var symbolInfo = model.GetSymbolInfo(expr);
                Assert.Equal(expectedSymbol, symbolInfo.Symbol?.ToDisplayString(SymbolDisplayFormat.TestFormat.WithMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.UseSpecialTypes)));
 
                if (expectedDiagnostics.Length == 0)
                {
                    var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(expectedResult));
                    verifier.VerifyIL("Program.Evaluate", expectedIL);
                }
            }
        }
 
        [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));
                opType += "?";
                incrementOperator(op, opType, expectedSymbol, values, expectedResult, expectedLiftedIL, getDiagnostics(opType, diagnostic));
 
                DiagnosticDescription[] getDiagnostics(string opType, DiagnosticDescription diagnostic)
                {
                    if (expectedSymbol == null && diagnostic == null)
                    {
                        diagnostic = Diagnostic(ErrorCode.ERR_BadUnaryOp, op + "operand").WithArguments(op, opType);
                    }
                    return diagnostic != null ? new[] { diagnostic } : Array.Empty<DiagnosticDescription>();
                }
            }
 
            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")}",
@"{
  // Code size        7 (0x7)
  .maxstack  3
  IL_0000:  ldarg.0
  IL_0001:  ldarg.0
  IL_0002:  ldind.i
  IL_0003:  ldc.i4.1
  IL_0004:  add
  IL_0005:  stind.i
  IL_0006:  ret
}",
@"{
  // Code size       48 (0x30)
  .maxstack  3
  .locals init (nint? V_0,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  ldarg.0
  IL_0002:  ldobj      ""nint?""
  IL_0007:  stloc.0
  IL_0008:  ldloca.s   V_0
  IL_000a:  call       ""readonly bool nint?.HasValue.get""
  IL_000f:  brtrue.s   IL_001c
  IL_0011:  ldloca.s   V_1
  IL_0013:  initobj    ""nint?""
  IL_0019:  ldloc.1
  IL_001a:  br.s       IL_002a
  IL_001c:  ldloca.s   V_0
  IL_001e:  call       ""readonly nint nint?.GetValueOrDefault()""
  IL_0023:  ldc.i4.1
  IL_0024:  add
  IL_0025:  newobj     ""nint?..ctor(nint)""
  IL_002a:  stobj      ""nint?""
  IL_002f:  ret
}");
            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")}",
@"{
  // Code size        7 (0x7)
  .maxstack  3
  IL_0000:  ldarg.0
  IL_0001:  ldarg.0
  IL_0002:  ldind.i
  IL_0003:  ldc.i4.1
  IL_0004:  add
  IL_0005:  stind.i
  IL_0006:  ret
}",
@"{
  // Code size       48 (0x30)
  .maxstack  3
  .locals init (nuint? V_0,
                nuint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  ldarg.0
  IL_0002:  ldobj      ""nuint?""
  IL_0007:  stloc.0
  IL_0008:  ldloca.s   V_0
  IL_000a:  call       ""readonly bool nuint?.HasValue.get""
  IL_000f:  brtrue.s   IL_001c
  IL_0011:  ldloca.s   V_1
  IL_0013:  initobj    ""nuint?""
  IL_0019:  ldloc.1
  IL_001a:  br.s       IL_002a
  IL_001c:  ldloca.s   V_0
  IL_001e:  call       ""readonly nuint nuint?.GetValueOrDefault()""
  IL_0023:  ldc.i4.1
  IL_0024:  add
  IL_0025:  newobj     ""nuint?..ctor(nuint)""
  IL_002a:  stobj      ""nuint?""
  IL_002f:  ret
}");
            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",
@"{
  // Code size        7 (0x7)
  .maxstack  3
  IL_0000:  ldarg.0
  IL_0001:  ldarg.0
  IL_0002:  ldind.i
  IL_0003:  ldc.i4.1
  IL_0004:  sub
  IL_0005:  stind.i
  IL_0006:  ret
}",
@"{
  // Code size       48 (0x30)
  .maxstack  3
  .locals init (nint? V_0,
                nint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  ldarg.0
  IL_0002:  ldobj      ""nint?""
  IL_0007:  stloc.0
  IL_0008:  ldloca.s   V_0
  IL_000a:  call       ""readonly bool nint?.HasValue.get""
  IL_000f:  brtrue.s   IL_001c
  IL_0011:  ldloca.s   V_1
  IL_0013:  initobj    ""nint?""
  IL_0019:  ldloc.1
  IL_001a:  br.s       IL_002a
  IL_001c:  ldloca.s   V_0
  IL_001e:  call       ""readonly nint nint?.GetValueOrDefault()""
  IL_0023:  ldc.i4.1
  IL_0024:  sub
  IL_0025:  newobj     ""nint?..ctor(nint)""
  IL_002a:  stobj      ""nint?""
  IL_002f:  ret
}");
            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",
@"{
  // Code size        7 (0x7)
  .maxstack  3
  IL_0000:  ldarg.0
  IL_0001:  ldarg.0
  IL_0002:  ldind.i
  IL_0003:  ldc.i4.1
  IL_0004:  sub
  IL_0005:  stind.i
  IL_0006:  ret
}",
@"{
  // Code size       48 (0x30)
  .maxstack  3
  .locals init (nuint? V_0,
                nuint? V_1)
  IL_0000:  ldarg.0
  IL_0001:  ldarg.0
  IL_0002:  ldobj      ""nuint?""
  IL_0007:  stloc.0
  IL_0008:  ldloca.s   V_0
  IL_000a:  call       ""readonly bool nuint?.HasValue.get""
  IL_000f:  brtrue.s   IL_001c
  IL_0011:  ldloca.s   V_1
  IL_0013:  initobj    ""nuint?""
  IL_0019:  ldloc.1
  IL_001a:  br.s       IL_002a
  IL_001c:  ldloca.s   V_0
  IL_001e:  call       ""readonly nuint nuint?.GetValueOrDefault()""
  IL_0023:  ldc.i4.1
  IL_0024:  sub
  IL_0025:  newobj     ""nuint?..ctor(nuint)""
  IL_002a:  stobj      ""nuint?""
  IL_002f:  ret
}");
 
            void incrementOperator(string op, string opType, string expectedSymbol, string values, string expectedResult, string expectedIL, DiagnosticDescription[] expectedDiagnostics)
            {
                string source =
$@"using System;
class Program
{{
    static void Evaluate(ref {opType} operand)
    {{
        {op}operand;
    }}
    static void EvaluateAndReport({opType} operand)
    {{
        object result;
        try
        {{
            Evaluate(ref operand);
            result = operand;
        }}
        catch (Exception e)
        {{
            result = e.GetType();
        }}
        Console.Write(result);
    }}
    static void Main()
    {{
        bool separator = false;
        foreach (var value in new {opType}[] {{ {values} }})
        {{
            if (separator) Console.Write("", "");
            separator = true;
            EvaluateAndReport(value);
        }}
    }}
}}";
                var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
                comp.VerifyDiagnostics(expectedDiagnostics);
 
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var kind = (op == "++") ? SyntaxKind.PreIncrementExpression : SyntaxKind.PreDecrementExpression;
                var expr = tree.GetRoot().DescendantNodes().Single(n => n.Kind() == kind);
                var symbolInfo = model.GetSymbolInfo(expr);
                Assert.Equal(expectedSymbol, symbolInfo.Symbol?.ToDisplayString(SymbolDisplayFormat.TestFormat.WithMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.UseSpecialTypes)));
 
                if (expectedDiagnostics.Length == 0)
                {
                    var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(expectedResult));
                    verifier.VerifyIL("Program.Evaluate", expectedIL);
                }
            }
        }
 
        [Fact]
        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;
    }
}";
            string sourceB =
@"class Program
{
    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
}");
            verifier.VerifyIL("Program.F2",
@"{
  // Code size        3 (0x3)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  neg
  IL_0002:  ret
}");
        }
 
        [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 =
@"class Program
{
    static void F(MyInt x, MyInt y)
    {
        ++x;
        x++;
        --x;
        x--;
        _ = +x;
        _ = -x;
        _ = ~x;
        _ = x + y;
        _ = x * y;
        _ = x < y;
        _ = x & y;
        _ = x << 1;
    }
}";
                var comp = CreateCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
                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);
                binaryOp(op, rightType, leftType, expectedSymbol2 == "" ? expectedSymbol1 : expectedSymbol2, diagnostics2 ?? diagnostics1);
            }
 
            void binaryOp(string op, string leftType, string rightType, string expectedSymbol, DiagnosticDescription[] diagnostics)
            {
                if (expectedSymbol == null && diagnostics == null)
                {
                    diagnostics = getBadBinaryOpsDiagnostics(op, leftType, rightType);
                }
                binaryOperator(op, leftType, rightType, expectedSymbol, diagnostics ?? Array.Empty<DiagnosticDescription>());
            }
 
            static DiagnosticDescription[] getBadBinaryOpsDiagnostics(string op, string leftType, string rightType, bool includeBadBinaryOps = true, bool includeVoidError = false)
            {
                var builder = ArrayBuilder<DiagnosticDescription>.GetInstance();
                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();
            }
 
            static DiagnosticDescription[] getAmbiguousBinaryOpsDiagnostics(string op, string leftType, string rightType)
            {
                return new[] { Diagnostic(ErrorCode.ERR_AmbigBinaryOps, $"x {op} y").WithArguments(op, leftType, rightType) };
            }
 
            var arithmeticOperators = new[]
            {
                ("-", "op_Subtraction"),
                ("*", "op_Multiply"),
                ("/", "op_Division"),
                ("%", "op_Modulus"),
            };
            var additionOperators = new[]
            {
                ("+", "op_Addition"),
            };
            var comparisonOperators = new[]
            {
                ("<", "op_LessThan"),
                ("<=", "op_LessThanOrEqual"),
                (">", "op_GreaterThan"),
                (">=", "op_GreaterThanOrEqual"),
            };
            var shiftOperators = new[]
            {
                ("<<", "op_LeftShift"),
                (">>", "op_RightShift"),
            };
            var equalityOperators = new[]
            {
                ("==", "op_Equality"),
                ("!=", "op_Inequality"),
            };
            var logicalOperators = new[]
            {
                ("&", "op_BitwiseAnd"),
                ("|", "op_BitwiseOr"),
                ("^", "op_ExclusiveOr"),
            };
 
            foreach ((string symbol, string name) in arithmeticOperators)
            {
                bool includeBadBinaryOps = (symbol != "-");
 
                // 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)
            {
                // 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)
            {
                // 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)
            {
                // 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)
            {
                // 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)
            {
                // 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)
            {
                bool useUnsafeContext = useUnsafe(leftType) || useUnsafe(rightType);
                string source =
$@"class Program
{{
    static {(useUnsafeContext ? "unsafe " : "")}object Evaluate({leftType} x, {rightType} y)
    {{
        return x {op} y;
    }}
}}";
                var comp = CreateCompilation(source, options: TestOptions.ReleaseDll.WithAllowUnsafe(useUnsafeContext), parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
                comp.VerifyDiagnostics(expectedDiagnostics);
 
                var tree = comp.SyntaxTrees[0];
                var model = comp.GetSemanticModel(tree);
                var expr = tree.GetRoot().DescendantNodes().OfType<BinaryExpressionSyntax>().Single();
                var symbolInfo = model.GetSymbolInfo(expr);
                Assert.Equal(expectedSymbol, symbolInfo.Symbol?.ToDisplayString(SymbolDisplayFormat.TestFormat.WithMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.UseSpecialTypes)));
 
                if (expectedDiagnostics.Length == 0)
                {
                    CompileAndVerify(comp, verify: Verification.FailsPEVerify);
                }
 
                static bool useUnsafe(string type) => type == "void*";
            }
        }
 
        [Fact]
        public void BinaryOperators_NInt()
        {
            var source =
@"using System;
class Program
{
    static nint Add(nint x, nint y) => x + y;
    static nint Subtract(nint x, nint y) => x - y;
    static nint Multiply(nint x, nint y) => x * y;
    static nint Divide(nint x, nint y) => x / y;
    static nint Mod(nint x, nint y) => x % y;
    static bool Equals(nint x, nint y) => x == y;
    static bool NotEquals(nint x, nint y) => x != y;
    static bool LessThan(nint x, nint y) => x < y;
    static bool LessThanOrEqual(nint x, nint y) => x <= y;
    static bool GreaterThan(nint x, nint y) => x > y;
    static bool GreaterThanOrEqual(nint x, nint y) => x >= y;
    static nint And(nint x, nint y) => x & y;
    static nint Or(nint x, nint y) => x | y;
    static nint Xor(nint x, nint y) => x ^ y;
    static nint ShiftLeft(nint x, int y) => x << y;
    static nint ShiftRight(nint x, int y) => 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));
        Console.WriteLine(Equals(3, 4));
        Console.WriteLine(NotEquals(3, 4));
        Console.WriteLine(LessThan(3, 4));
        Console.WriteLine(LessThanOrEqual(3, 4));
        Console.WriteLine(GreaterThan(3, 4));
        Console.WriteLine(GreaterThanOrEqual(3, 4));
        Console.WriteLine(And(3, 5));
        Console.WriteLine(Or(3, 5));
        Console.WriteLine(Xor(3, 5));
        Console.WriteLine(ShiftLeft(35, 4));
        Console.WriteLine(ShiftRight(35, 4));
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
@"7
-1
12
2
1
False
True
True
True
False
False
1
7
6
560
2"));
            verifier.VerifyIL("Program.Add",
@"{
  // Code size        4 (0x4)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  add
  IL_0003:  ret
}");
            verifier.VerifyIL("Program.Subtract",
@"{
  // Code size        4 (0x4)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  sub
  IL_0003:  ret
}");
            verifier.VerifyIL("Program.Multiply",
@"{
  // Code size        4 (0x4)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  mul
  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
}");
            verifier.VerifyIL("Program.Equals",
@"{
  // Code size        5 (0x5)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  ceq
  IL_0004:  ret
}");
            verifier.VerifyIL("Program.NotEquals",
@"{
  // 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
  IL_0004:  ret
}");
            verifier.VerifyIL("Program.LessThanOrEqual",
@"{
  // Code size        8 (0x8)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  cgt
  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
  IL_0004:  ret
}");
            verifier.VerifyIL("Program.GreaterThanOrEqual",
@"{
  // Code size        8 (0x8)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  clt
  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       15 (0xf)
  .maxstack  4
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  sizeof     ""nint""
  IL_0008:  ldc.i4.8
  IL_0009:  mul
  IL_000a:  ldc.i4.1
  IL_000b:  sub
  IL_000c:  and
  IL_000d:  shl
  IL_000e:  ret
}");
            verifier.VerifyIL("Program.ShiftRight",
@"{
  // Code size       15 (0xf)
  .maxstack  4
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  sizeof     ""nint""
  IL_0008:  ldc.i4.8
  IL_0009:  mul
  IL_000a:  ldc.i4.1
  IL_000b:  sub
  IL_000c:  and
  IL_000d:  shr
  IL_000e:  ret
}");
        }
 
        [Fact]
        public void BinaryOperators_NUInt()
        {
            var source =
@"using System;
class Program
{
    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));
        Console.WriteLine(Subtract(4, 3));
        Console.WriteLine(Multiply(3, 4));
        Console.WriteLine(Divide(5, 2));
        Console.WriteLine(Mod(5, 2));
        Console.WriteLine(Equals(3, 4));
        Console.WriteLine(NotEquals(3, 4));
        Console.WriteLine(LessThan(3, 4));
        Console.WriteLine(LessThanOrEqual(3, 4));
        Console.WriteLine(GreaterThan(3, 4));
        Console.WriteLine(GreaterThanOrEqual(3, 4));
        Console.WriteLine(And(3, 5));
        Console.WriteLine(Or(3, 5));
        Console.WriteLine(Xor(3, 5));
        Console.WriteLine(ShiftLeft(35, 4));
        Console.WriteLine(ShiftRight(35, 4));
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
@"7
1
12
2
1
False
True
True
True
False
False
1
7
6
560
2"));
            verifier.VerifyIL("Program.Add",
@"{
  // Code size        4 (0x4)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  add
  IL_0003:  ret
}");
            verifier.VerifyIL("Program.Subtract",
@"{
  // Code size        4 (0x4)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  sub
  IL_0003:  ret
}");
            verifier.VerifyIL("Program.Multiply",
@"{
  // Code size        4 (0x4)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  mul
  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
}");
            verifier.VerifyIL("Program.Equals",
@"{
  // Code size        5 (0x5)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  ceq
  IL_0004:  ret
}");
            verifier.VerifyIL("Program.NotEquals",
@"{
  // 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       15 (0xf)
  .maxstack  4
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  sizeof     ""nuint""
  IL_0008:  ldc.i4.8
  IL_0009:  mul
  IL_000a:  ldc.i4.1
  IL_000b:  sub
  IL_000c:  and
  IL_000d:  shl
  IL_000e:  ret
}");
            verifier.VerifyIL("Program.ShiftRight",
@"{
  // Code size       15 (0xf)
  .maxstack  4
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  sizeof     ""nuint""
  IL_0008:  ldc.i4.8
  IL_0009:  mul
  IL_000a:  ldc.i4.1
  IL_000b:  sub
  IL_000c:  and
  IL_000d:  shr.un
  IL_000e:  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 = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
@"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
}");
        }
 
        [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 = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
@"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
}");
        }
 
        [Fact]
        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<DiagnosticDescription>();
            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<string, string, string, DiagnosticDescription[]> 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<DiagnosticDescription>());
            }
 
            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<DiagnosticDescription>());
                constantExpression(opType, $"checked({expr})", expectedResult, Array.Empty<DiagnosticDescription>());
                constantExpression(opType, $"unchecked({expr})", expectedResult, Array.Empty<DiagnosticDescription>());
            }
 
            void binaryOperator(string opType, string op, string leftType, string leftOperand, string rightType, string rightOperand, string expectedResult, Func<string, string, string, DiagnosticDescription[]> 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<DiagnosticDescription>());
            }
 
            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<DiagnosticDescription>());
                constantExpression(opType, $"checked({expr})", expectedResult, Array.Empty<DiagnosticDescription>());
                constantExpression(opType, $"unchecked({expr})", expectedResult, Array.Empty<DiagnosticDescription>());
            }
 
            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 = CreateCompilation(sourceA, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
                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 = CreateCompilation(sourceB, references: new[] { refA }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
                // Investigating flaky IL verification issue. Tracked by https://github.com/dotnet/roslyn/issues/63782
                CompileAndVerify(comp, verify: new Verification() { Status = VerificationStatus.PassesOrFailFast | VerificationStatus.FailsPEVerify }, expectedOutput: IncludeExpectedOutput(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 = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
                if (expectedDiagnostics.Any(d => ErrorFacts.GetSeverity((ErrorCode)d.Code) == DiagnosticSeverity.Error))
                {
                    comp.VerifyDiagnostics(expectedDiagnostics);
                    Assert.Null(expectedResult);
                    return;
                }
 
                // Investigating flaky IL verification issue. Tracked by https://github.com/dotnet/roslyn/issues/63782
                CompileAndVerify(comp, verify: new Verification() { Status = VerificationStatus.FailsPEVerify | VerificationStatus.PassesOrFailFast }, expectedOutput: IncludeExpectedOutput(expectedResult)).VerifyDiagnostics(expectedDiagnostics);
                Assert.NotNull(expectedResult);
            }
        }
 
        [Fact]
        public void ConstantFolding_02()
        {
            var source = @"
using System;
 
class Program
{
    static void Main()
    {
        const UIntPtr x = unchecked(uint.MaxValue + (UIntPtr)42);
        const UIntPtr y = checked(uint.MaxValue + (UIntPtr)42);
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
 
            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());
        }
    }
}";
            comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(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);
    }
}";
            comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(IntPtr.Size == 4 ? "41" : "4294967337")).VerifyDiagnostics();
        }
 
        [Fact]
        public void ConstantFolding_03()
        {
            var source = @"
using System;
 
class Program
{
    static void Main()
    {
        const IntPtr x = unchecked(-(IntPtr)int.MinValue);
        const IntPtr y = checked(-(IntPtr)int.MinValue);
    }
}";
            var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            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());
        }
    }
}";
            comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(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);
    }
}";
            comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(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 void Main()
    {
        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<object> 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, targetFramework: TargetFramework.Net70);
 
            CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
$@"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 = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            var expectedValue = IntPtr.Size == 4 ? "fffffffffffffffe" : "fffffffe";
            CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
$@"{expectedValue}
{expectedValue}"));
        }
 
        [Fact]
        public void UncheckedLeftShift_02()
        {
            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 = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            var expectedValue = IntPtr.Size == 4 ? "fffffffe" : "1fffffffe";
            CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
$@"{expectedValue}
{expectedValue}"));
        }
 
        [Fact]
        public void ExplicitImplementationReturnTypeDifferences()
        {
            string source =
@"struct S<T>
{
}
interface I
{
    S<nint> F1();
    S<System.IntPtr> F2();
    S<nint> F3();
    S<System.IntPtr> F4();
}
class C : I
{
    S<System.IntPtr> I.F1() => default;
    S<nint> I.F2() => default;
    S<nint> I.F3() => default;
    S<System.IntPtr> I.F4() => default;
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
            comp.VerifyEmitDiagnostics();
 
            var type = comp.GetTypeByMetadataName("I");
            Assert.Equal("S<nint> I.F1()", type.GetMember("F1").ToTestDisplayString());
            Assert.Equal("S<nint> I.F2()", type.GetMember("F2").ToTestDisplayString());
            Assert.Equal("S<nint> I.F3()", type.GetMember("F3").ToTestDisplayString());
            Assert.Equal("S<nint> I.F4()", type.GetMember("F4").ToTestDisplayString());
 
            type = comp.GetTypeByMetadataName("C");
            Assert.Equal("S<nint> C.I.F1()", type.GetMember("I.F1").ToTestDisplayString());
            Assert.Equal("S<nint> C.I.F2()", type.GetMember("I.F2").ToTestDisplayString());
            Assert.Equal("S<nint> C.I.F3()", type.GetMember("I.F3").ToTestDisplayString());
            Assert.Equal("S<nint> C.I.F4()", type.GetMember("I.F4").ToTestDisplayString());
        }
 
        [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, targetFramework: TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
 
            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());
 
            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());
        }
 
        [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", null, "System.OverflowException", "conv.ovf.u");
            convert(fromType: "nint", toType: "nuint", "int.MaxValue", "2147483647", null, "2147483647", "conv.ovf.u");
 
            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", null, IntPtr.Size == 4 ? "System.OverflowException" : "4294967295", "conv.ovf.i.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(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", null, "System.OverflowException", "conv.ovf.u");
            convert(fromType: "nint", toType: "nuint", nintMaxValue, IntPtr.Size == 4 ? "2147483647" : "9223372036854775807", null, IntPtr.Size == 4 ? "2147483647" : "9223372036854775807", "conv.ovf.u");
 
            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", null, "System.OverflowException", "conv.ovf.i.un");
 
            void convert(string fromType, string toType, string fromValue, string toValueUnchecked, string toConvUnchecked, string toValueChecked, string toConvChecked)
            {
                string source =
$@"using System;
class Program
{{
    static {toType} Convert({fromType} value) => ({toType})(value);
    static {toType} ConvertChecked({fromType} value) => checked(({toType})(value));
    static object Execute(Func<object> 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(source, options: TestOptions.UnsafeReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
 
                var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
$@"{toValueUnchecked}
{toValueChecked}"));
 
                verifier.VerifyIL("Program.Convert", toConvUnchecked is null ?
@"
{
  // Code size        2 (0x2)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ret
}" :
$@"{{
  // 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("void*")]
        [InlineData("byte*")]
        [InlineData("delegate*<void>")]
        public void PointerConversions(string pointerType)
        {
            string source =
$@"using System;
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<object> f)
    {{
        try
        {{
            return f();
        }}
        catch (Exception e)
        {{
            return e.GetType().FullName;
        }}
    }}
    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()
    {{
        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 = CreateCompilation(source, options: TestOptions.UnsafeReleaseExe, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            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: IncludeExpectedOutput(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
}");
        }
 
        [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()
    {
        E e;
        const nuint u0 = 0;
        const nuint u1 = 1;
        e = u0;
        e = u1;
    }
    static void F3()
    {
        nint i;
        i = default(E);
        i = E.A;
        i = E.B;
    }
    static void F4()
    {
        nuint u;
        u = default(E);
        u = E.A;
        u = E.B;
    }
}";
            var comp = CreateCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            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));
        }
 
        [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()
    {
        WriteLine(F1(-1));
        WriteLine(F2(1));
        WriteLine(F3(E.A));
        WriteLine(F4(E.B));
    }
}";
            var comp = CreateCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
            CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
@"A
B
-1
1"));
        }
 
        [Fact]
        public void EnumConversions_03()
        {
            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");
 
            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");
 
            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");
 
            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");
 
            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(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");
 
            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(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(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 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);
    static {toType} ConvertChecked({fromType} value) => checked(({toType})(value));
    static object Execute(Func<object> 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(source, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
 
                var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput(
$@"{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 MethodTypeInference(string nativeIntegerType, string underlyingType)
        {
            var source =
$@"interface I<T>
{{
    T P {{ get; }}
}}
unsafe class Program
{{
    static T F0<T>(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<I<{nativeIntegerType}>>(x, y).P.
            ToPointer();
        F0<I<{underlyingType}>>(x, y).P.
            ToPointer();
    }}
}}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void DuplicateConstraint()
        {
            var source =
@"interface I<T> { }
class C1<T, U> where U : I<nint>, I<nint> { }
class C2<T, U> where U : I<nint>, I<System.IntPtr> { }
class C3<T, U> where U : I<System.UIntPtr>, I<System.IntPtr>, I<nuint> { }
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (2,35): error CS0405: Duplicate constraint 'I<nint>' for type parameter 'U'
                // class C1<T, U> where U : I<nint>, I<nint> { }
                Diagnostic(ErrorCode.ERR_DuplicateBound, "I<nint>").WithArguments("I<nint>", "U").WithLocation(2, 35),
                // (3,35): error CS0405: Duplicate constraint 'I<nint>' for type parameter 'U'
                // class C2<T, U> where U : I<nint>, I<System.IntPtr> { }
                Diagnostic(ErrorCode.ERR_DuplicateBound, "I<System.IntPtr>").WithArguments("I<nint>", "U").WithLocation(3, 35),
                // (4,63): error CS0405: Duplicate constraint 'I<nuint>' for type parameter 'U'
                // class C3<T, U> where U : I<System.UIntPtr>, I<System.IntPtr>, I<nuint> { }
                Diagnostic(ErrorCode.ERR_DuplicateBound, "I<nuint>").WithArguments("I<nuint>", "U").WithLocation(4, 63));
        }
 
        [Fact]
        public void DuplicateInterface_01()
        {
            var source =
@"interface I<T> { }
class C1 : I<nint>, I<nint> { }
class C2 : I<nint>, I<System.IntPtr> { }
class C3 : I<System.UIntPtr>, I<System.IntPtr>, I<nuint> { }
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (2,21): error CS0528: 'I<nint>' is already listed in interface list
                // class C1 : I<nint>, I<nint> { }
                Diagnostic(ErrorCode.ERR_DuplicateInterfaceInBaseList, "I<nint>").WithArguments("I<nint>").WithLocation(2, 21),
                // (3,21): error CS0528: 'I<nint>' is already listed in interface list
                // class C2 : I<nint>, I<System.IntPtr> { }
                Diagnostic(ErrorCode.ERR_DuplicateInterfaceInBaseList, "I<System.IntPtr>").WithArguments("I<nint>").WithLocation(3, 21),
                // (4,49): error CS0528: 'I<nuint>' is already listed in interface list
                // class C3 : I<System.UIntPtr>, I<System.IntPtr>, I<nuint> { }
                Diagnostic(ErrorCode.ERR_DuplicateInterfaceInBaseList, "I<nuint>").WithArguments("I<nuint>").WithLocation(4, 49));
        }
 
        [Theory]
        [InlineData("nuint")]
        [InlineData("System.UIntPtr")]
        public void SignedToUnsignedConversions_Implicit(string type)
        {
            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 = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            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; // 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"));
        }
 
        [Theory]
        [InlineData("nuint")]
        [InlineData("System.UIntPtr")]
        public void SignedToUnsignedConversions_Explicit(string type)
        {
            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 = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify);
            string expectedExplicitILNop =
@"{
  // Code size        2 (0x2)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ret
}";
            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", expectedExplicitILNop);
            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);
        }
 
        [Fact]
        public void StandardConversions()
        {
            // Note: A standard explicit conversion is derived from opposite standard implicit conversion
 
            // 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*<void>", 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);
 
            // nint to type
            verify(sourceType: "nint", destType: "string", noConversion: true);
            verify(sourceType: "nint", destType: "void*", noConversion: true);
            verify(sourceType: "nint", destType: "delegate*<void>", 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);
 
            // 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*<void>", 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*<void>", 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");
 
            // 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*<void>", 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);
 
            // 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*<void>", 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);
 
            // 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*<void>", 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");
 
            // 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*<void>", 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 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;
}
enum E { }
""";
                var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll, targetFramework: TargetFramework.Net70);
 
                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(true)]
        [InlineData(false)]
        public void VerifyUnifiedSymbols(bool useCSharp11)
        {
            var corlib_cs = RuntimeFeature_NumericIntPtr + @"
namespace System
{
    public struct IntPtr { }
    public struct UIntPtr { }
 
    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.Regular11 : TestOptions.Regular10).WithNoRefSafetyRulesAttribute();
 
            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", debugInformationFormat: DebugInformationFormat.PortablePdb);
                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 NoAttributesEmitted()
        {
            var source = @"
interface I<T> { }
 
class C1 : I<nint> { }
class C2 : I<System.IntPtr> { }
class C3 : I<nuint> { }
class C4 : I<System.UIntPtr> { }
 
class Base<T> { }
 
class D1 : Base<nint> { }
class D2 : Base<System.IntPtr> { }
class D3 : Base<nuint> { }
class D4 : Base<System.UIntPtr> { }
 
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;
    }
 
    void LocalFunctions()
    {
        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<T1, T2, T3, T4>
    where T1 : I<nint>
    where T2 : I<System.IntPtr>
    where T3 : I<nuint>
    where T4 : I<System.UIntPtr>
{
}
 
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(new[] { source }, targetFramework: TargetFramework.Net70);
 
            comp.VerifyDiagnostics();
            VerifyNoNativeIntegerAttributeEmitted(comp);
        }
 
        [Fact]
        public void UserDefinedConversionOnSystemIntPtr()
        {
            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; }
    }
 
    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)
    {
        return s;
    }
    nuint M2(string s)
    {
        return s;
    }
}
";
            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<ReturnStatementSyntax>().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 GenericAttribute_AttributeDependentTypes()
        {
            var source = @"
#nullable enable
using System;
 
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
class Attr<T> : Attribute { }
 
[Attr<nint>]
[Attr<D<nint>>]
[Attr<nuint>]
[Attr<D<nuint>>]
class C1 { }
 
[Attr<IntPtr>]
[Attr<D<IntPtr>>]
[Attr<UIntPtr>]
[Attr<D<UIntPtr>>]
class C2 { }
 
class D<T> { }
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
        }
 
        [Fact]
        public void UnmanagedConstraint()
        {
            var source = @"
class C<T> where T : unmanaged { }
class D : C<System.IntPtr> { }
";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
 
            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<T>
    {
        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<MethodDeclarationSyntax>().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 ArrayAccess()
        {
            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, targetFramework: TargetFramework.Net70);
 
            CompileAndVerify(comp, expectedOutput: IncludeExpectedOutput("1, 2, 3, 4"), verify: Verification.FailsPEVerify);
        }
 
        [Fact]
        public void NativeIntegerAttributeFromMetadata()
        {
            var source = @"
public class C
{
    public nint M() { throw null; }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            var image = comp.EmitToImageReference();
 
            var comp2 = CreateCompilation(source, references: new[] { image }, targetFramework: TargetFramework.Net70);
 
            CompileAndVerify(comp2, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.FailsPEVerify);
 
            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 PatternExplainer()
        {
            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, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (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)
                );
        }
 
        [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);
C.M9(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) { }
 
    public static void M9(nint{{s1Nullable}} x) { Write("M9(nint)"); }
    public static void M9(byte{{s2Nullable}} x) { Write("M9(byte)"); }
}
""";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
 
            // 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 M9(nint)"
                : "M1 M2 M3 M4 M5(ushort) M6 M7 M8 M9(byte)";
            CompileAndVerify(comp, expectedOutput: IncludeExpectedOutput(expected), verify: Verification.FailsPEVerify);
        }
 
        [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);
C.M10(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) { Write("M6(IntPtr) "); }
    public static void M6(ushort{{s2Nullable}} x) { Write("M6(ushort) "); }
 
    public static void M7(IntPtr{{s1Nullable}} x) { Write("M7 "); }
    public static void M7(uint{{s2Nullable}} x) { }
 
    public static void M8(IntPtr{{s1Nullable}} x) { Write("M8 "); }
    public static void M8(ulong{{s2Nullable}} x) { }
 
    public static void M9(IntPtr{{s1Nullable}} x) { Write("M9 "); }
    public static void M9(nuint{{s2Nullable}} x) { }
 
    public static void M10(IntPtr{{s1Nullable}} x) { Write("M10(IntPtr)"); }
    public static void M10(byte{{s2Nullable}} x) { Write("M10(byte)"); }
}
""";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
 
            // 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 M10(IntPtr)"
                : "M1 M2 M3 M4 M5 M6(ushort) M7 M8 M9 M10(byte)";
            CompileAndVerify(comp, expectedOutput: IncludeExpectedOutput(expected), verify: Verification.FailsPEVerify);
        }
 
        [Fact]
        public void RetargetingFromNonNumericToNumericIntPtrCorlib()
        {
            string lib_cs = """
public class Base
{
    public virtual nint M() => 0;
}
""";
            var libComp = CreateEmptyCompilation(lib_cs, references: new[] { MscorlibRef_v20 }, assemblyName: "lib");
            libComp.VerifyDiagnostics();
 
            string source = """
public class Derived : Base
{
    public override nint M() => 0;
}
""";
            var comp = CreateCompilation(source, references: new[] { libComp.ToMetadataReference() }, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
 
            var baseM = (RetargetingMethodSymbol)comp.GlobalNamespace.GetMember("Base.M");
            var baseNint = (PENamedTypeSymbol)baseM.ReturnType;
 
            var derivedM = (MethodSymbol)comp.GlobalNamespace.GetMember("Derived.M");
            var derivedNint = (PENamedTypeSymbol)derivedM.ReturnType;
 
            Assert.Equal("nint", derivedNint.ToTestDisplayString());
            Assert.Same(baseNint, derivedNint);
        }
 
        [Fact]
        public void RetargetingFromNumericIntPtrToNonNumericCorlib()
        {
            string lib_cs = """
public class Base
{
    public virtual nint M() => 0;
}
""";
            var libComp = CreateCompilation(lib_cs, assemblyName: "lib", targetFramework: TargetFramework.Net70);
            libComp.VerifyDiagnostics();
 
            string source = """
public class Derived : Base
{
    public override nint M() => 0;
}
""";
            var comp = CreateEmptyCompilation(source, references: new[] { libComp.ToMetadataReference(), MscorlibRef_v46 });
            comp.VerifyDiagnostics(
                // (1,24): error CS0012: The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
                // public class Derived : Base
                Diagnostic(ErrorCode.ERR_NoTypeDef, "Base").WithArguments("System.Object", "System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a").WithLocation(1, 24)
                );
 
            var baseM = (RetargetingMethodSymbol)comp.GlobalNamespace.GetMember("Base.M");
            var baseNint = (PENamedTypeSymbol)baseM.ReturnType;
 
            var derivedM = (MethodSymbol)comp.GlobalNamespace.GetMember("Derived.M");
            var derivedNint = (NativeIntegerTypeSymbol)derivedM.ReturnType;
 
            Assert.Equal("System.IntPtr", baseNint.ToTestDisplayString());
            Assert.Equal("nint", derivedNint.ToTestDisplayString());
            Assert.Same(baseNint, derivedNint.UnderlyingNamedType);
        }
 
        [Fact]
        public void UnsignedRightShift()
        {
            string source = """
public class C
{
    nint M1(nint x, int count) => x >>> count;
    nuint M2(nuint x, int count) => x >>> count;
    nint M3(nint x, int count) => checked(x >>> count);
    nuint M4(nuint x, int count) => checked(x >>> count);
 
    System.IntPtr M5(System.IntPtr x, int count) => x >>> count;
    System.UIntPtr M6(System.UIntPtr x, int count) => x >>> count;
}
""";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify);
            verifier.VerifyIL("C.M1", shiftRight("nint"));
            verifier.VerifyIL("C.M2", shiftRight("nuint"));
            verifier.VerifyIL("C.M3", shiftRight("nint"));
            verifier.VerifyIL("C.M4", shiftRight("nuint"));
            verifier.VerifyIL("C.M5", shiftRight("nint"));
            verifier.VerifyIL("C.M6", shiftRight("nuint"));
 
            return;
 
            static string shiftRight(string type)
            {
                return $$"""
{
  // Code size       15 (0xf)
  .maxstack  4
  IL_0000:  ldarg.1
  IL_0001:  ldarg.2
  IL_0002:  sizeof     "{{type}}"
  IL_0008:  ldc.i4.8
  IL_0009:  mul
  IL_000a:  ldc.i4.1
  IL_000b:  sub
  IL_000c:  and
  IL_000d:  shr.un
  IL_000e:  ret
}
""";
            }
        }
 
        [Fact]
        public void OverflowPointerConversion()
        {
            // Breaking change
            string source = """
using System;
class C
{
    public unsafe static void Main()
    {
        void* ptr = (void*)ulong.MaxValue;
 
        try
        {
            IntPtr i = checked((IntPtr)ptr);
        }
        catch (System.OverflowException)
        {
            Console.Write("OVERFLOW ");
        }
 
        IntPtr j = unchecked((IntPtr)ptr);
        if (j == (IntPtr)(-1))
        {
            Console.Write("RAN");
        }
    }
}
""";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            CompileAndVerify(comp, expectedOutput: IncludeExpectedOutput("OVERFLOW RAN"), verify: Verification.Skipped);
 
            comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseExe);
            comp.VerifyDiagnostics();
            CompileAndVerify(comp, expectedOutput: IncludeExpectedOutput("RAN"), verify: Verification.Skipped);
        }
 
        [Fact]
        public void VariousMembersToDecodeOnRuntimeFeatureType()
        {
            var corlib_cs = @"
namespace System
{
    public struct IntPtr { }
    public struct UIntPtr { }
 
    public struct Boolean { }
    public class Object { }
    public class String { }
    public class ValueType { }
    public struct Void { }
    public struct Int32 { }
 
    public class Exception { }
 
    public class Delegate
    {
        public static Delegate CreateDelegate(Type type, object firstArgument, Reflection.MethodInfo method) => null;
        public static Delegate Combine(Delegate a, Delegate b) => null;
        public static Delegate Remove(Delegate source, Delegate value) => null;
    }
    public class Type
    {
        public Reflection.FieldInfo GetField(string name) => null;
        public static Type GetType(string name) => null;
        public static Type GetTypeFromHandle(RuntimeTypeHandle handle) => null;
    }
    public struct RuntimeMethodHandle { }
    public struct RuntimeTypeHandle { }
    public class MulticastDelegate : Delegate { }
    public class Attribute { }
    public class AttributeUsageAttribute : Attribute
    {
        public AttributeUsageAttribute(AttributeTargets t) { }
        public bool AllowMultiple { get; set; }
        public bool Inherited { get; set; }
    }
    public class Enum { }
    public enum AttributeTargets { }
 
    public delegate void Action();
 
    namespace Reflection
    {
        public class AssemblyVersionAttribute : Attribute
        {
            public AssemblyVersionAttribute(string version) { }
        }
        public class DefaultMemberAttribute : Attribute
        {
            public DefaultMemberAttribute(string name) { }
        }
        public abstract class MemberInfo { }
        public abstract class MethodBase : MemberInfo
        {
            public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle) => throw null;
        }
        public abstract class MethodInfo : MethodBase
        {
            public virtual Delegate CreateDelegate(Type delegateType, object target) => throw null;
        }
        public abstract class FieldInfo : MemberInfo
        {
            public abstract object GetValue(object obj);
        }
    }
}
namespace System.Runtime.CompilerServices
{
    public static class RuntimeFeature
    {
        public const string NumericIntPtr = nameof(NumericIntPtr);
        public static bool IsDynamicCodeCompiled => false;
        public static event Action MyEvent;
        public static bool Method(bool x) => true;
 
        class Nested
        {
            public const string A = nameof(NumericIntPtr);
            public static bool B => false;
            public static event Action C;
            public static bool D(bool x) => true;
        }
    }
}
";
            var source = @"
public class C
{
    public nint field;
    public nuint field2;
}
";
            var corlib = CreateEmptyCompilation(corlib_cs);
            var comp = CreateEmptyCompilation(source, references: new[] { corlib.EmitToImageReference() });
            comp.VerifyDiagnostics();
        }
 
        [Theory]
        [InlineData("nint")]
        [InlineData("nuint")]
        [InlineData("System.IntPtr")]
        [InlineData("System.UIntPtr")]
        public void XmlDoc_Cref(string type)
        {
            var src = $$"""
/// <summary>Summary <see cref="{{type}}"/>.</summary>
class C { }
""";
            var comp = CreateCompilation(src, parseOptions: TestOptions.RegularWithDocumentationComments, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
 
            var tree = comp.SyntaxTrees.Single();
            var docComments = tree.GetCompilationUnitRoot().DescendantTrivia().Select(trivia => trivia.GetStructure()).OfType<DocumentationCommentTriviaSyntax>();
            var cref = docComments.First().DescendantNodes().OfType<XmlCrefAttributeSyntax>().First().Cref;
            Assert.Equal(type, cref.ToString());
 
            var model = comp.GetSemanticModel(tree, ignoreAccessibility: false);
            var nintSymbol = (INamedTypeSymbol)model.GetSymbolInfo(cref).Symbol;
            Assert.True(nintSymbol.IsNativeIntegerType);
        }
 
        [Fact]
        public void XmlDoc_Cref_Alias()
        {
            var src = """
using @nint = System.String;
 
/// <summary>Summary <see cref="nint"/>.</summary>
class C { }
""";
 
            var comp = CreateCompilation(src, parseOptions: TestOptions.RegularWithDocumentationComments, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
 
            var tree = comp.SyntaxTrees.Single();
            var docComments = tree.GetCompilationUnitRoot().DescendantTrivia().Select(trivia => trivia.GetStructure()).OfType<DocumentationCommentTriviaSyntax>();
            var cref = docComments.First().DescendantNodes().OfType<XmlCrefAttributeSyntax>().First().Cref;
            Assert.Equal("nint", cref.ToString());
 
            var model = comp.GetSemanticModel(tree, ignoreAccessibility: false);
            var symbol = (INamedTypeSymbol)model.GetSymbolInfo(cref).Symbol;
            Assert.False(symbol.IsNativeIntegerType);
            Assert.Equal("System.String", symbol.ToTestDisplayString());
        }
 
        [Theory]
        [InlineData("nint")]
        [InlineData("nuint")]
        public void XmlDoc_Cref_Member(string fieldName)
        {
            var src = $$"""
/// <summary>Summary <see cref="{{fieldName}}"/>.</summary>
public class C
{
    /// <summary></summary>
    public int {{fieldName}};
}
""";
 
            var comp = CreateCompilation(src, parseOptions: TestOptions.RegularWithDocumentationComments, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
 
            var tree = comp.SyntaxTrees.Single();
            var docComments = tree.GetCompilationUnitRoot().DescendantTrivia().Select(trivia => trivia.GetStructure()).OfType<DocumentationCommentTriviaSyntax>();
            var cref = docComments.First().DescendantNodes().OfType<XmlCrefAttributeSyntax>().First().Cref;
            Assert.Equal(fieldName, cref.ToString());
 
            var model = comp.GetSemanticModel(tree, ignoreAccessibility: false);
            var symbol = (IFieldSymbol)model.GetSymbolInfo(cref).Symbol;
            Assert.Equal($"System.Int32 C.{fieldName}", symbol.ToTestDisplayString());
        }
 
        [Fact]
        public void XmlDoc_Cref_Member_Escaped()
        {
            var src = """
/// <summary>Summary <see cref="@nint"/>.</summary>
public class C
{
    /// <summary></summary>
    public int nint;
}
""";
 
            var comp = CreateCompilation(src, parseOptions: TestOptions.RegularWithDocumentationComments, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
 
            var tree = comp.SyntaxTrees.Single();
            var docComments = tree.GetCompilationUnitRoot().DescendantTrivia().Select(trivia => trivia.GetStructure()).OfType<DocumentationCommentTriviaSyntax>();
            var cref = docComments.First().DescendantNodes().OfType<XmlCrefAttributeSyntax>().First().Cref;
            Assert.Equal("@nint", cref.ToString());
 
            var model = comp.GetSemanticModel(tree, ignoreAccessibility: false);
            var symbol = (IFieldSymbol)model.GetSymbolInfo(cref).Symbol;
            Assert.Equal("System.Int32 C.nint", symbol.ToTestDisplayString());
        }
 
        [Theory]
        [InlineData("@nint")]
        [InlineData("@nuint")]
        public void XmlDoc_Cref_Escaped(string type)
        {
            var src = $$"""
/// <summary>Summary <see cref="{{type}}"/>.</summary>
public class C
{
}
""";
 
            var comp = CreateCompilation(src, parseOptions: TestOptions.RegularWithDocumentationComments, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics(
                // (1,33): warning CS1574: XML comment has cref attribute 'type' that could not be resolved
                // /// <summary>Summary <see cref="type"/>.</summary>
                Diagnostic(ErrorCode.WRN_BadXMLRef, type).WithArguments(type).WithLocation(1, 33)
                );
        }
 
        [Fact]
        public void XmlDoc_Cref_Member_NintZero()
        {
            var src = """
/// <summary>Summary <see cref="nint.Zero"/>.</summary>
public class C
{
    /// <summary></summary>
    public int nint;
}
""";
 
            var comp = CreateCompilation(src, parseOptions: TestOptions.RegularWithDocumentationComments, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
 
            var tree = comp.SyntaxTrees.Single();
            var docComments = tree.GetCompilationUnitRoot().DescendantTrivia().Select(trivia => trivia.GetStructure()).OfType<DocumentationCommentTriviaSyntax>();
            var cref = docComments.First().DescendantNodes().OfType<XmlCrefAttributeSyntax>().First().Cref;
            Assert.Equal("nint.Zero", cref.ToString());
 
            var model = comp.GetSemanticModel(tree, ignoreAccessibility: false);
            var symbol = (IFieldSymbol)model.GetSymbolInfo(cref).Symbol;
            Assert.Equal("nint nint.Zero", symbol.ToTestDisplayString());
        }
 
        [Fact, WorkItem(43347, "https://github.com/dotnet/roslyn/issues/43347")]
        public void MaskShiftCount()
        {
            // positive nint shift right
            validate("nint", "NIntMaxValue", ">> 0", "0x7FFF_FFFF", "0x7FFF_FFFF_FFFF_FFFF", nint_shr(0));
            validate("nint", "NIntMaxValue", ">> 1", "0x3FFF_FFFF", "0x3FFF_FFFF_FFFF_FFFF", nint_shr(1));
            validate("nint", "NIntMaxValue", ">> 31", "0x0", "0xFFFF_FFFF", nint_shr(31));
            validate("nint", "NIntMaxValue", ">> 32", "0x7FFF_FFFF", "0x7FFF_FFFF", nint_shr(32));
            validate("nint", "NIntMaxValue", ">> 33", "0x3FFF_FFFF", "0x3FFF_FFFF", nint_shr(33));
            validate("nint", "NIntMaxValue", ">> 63", "0x0", "0x0", nint_shr(63));
            validate("nint", "NIntMaxValue", ">> 64", "0x7FFF_FFFF", "0x7FFF_FFFF_FFFF_FFFF", nint_shr(64));
            validate("nint", "NIntMaxValue", ">> 65", "0x3FFF_FFFF", "0x3FFF_FFFF_FFFF_FFFF", nint_shr(65));
 
            // negative nint shift right
            validate("nint", "NIntNegativeValue", ">> 1", "0xE000_0000", "0xE000_0000_0000_0000", nint_shr(1));
            validate("nint", "NIntNegativeValue", ">> 31", "0xFFFF_FFFF", "0xFFFF_FFFF_8000_0000", nint_shr(31));
            validate("nint", "NIntNegativeValue", ">> 32", "0xC000_0001", "0xFFFF_FFFF_C000_0000", nint_shr(32));
            validate("nint", "NIntNegativeValue", ">> 33", "0xE000_0000", "0xFFFF_FFFF_E000_0000", nint_shr(33));
            validate("nint", "NIntNegativeValue", ">> 63", "0xFFFF_FFFF", "0xFFFF_FFFF_FFFF_FFFF", nint_shr(63));
            validate("nint", "NIntNegativeValue", ">> 64", "0xC000_0001", "0xC000_0000_0000_0001", nint_shr(64));
 
            // positive nint shift left
            validate("nint", "NIntMaxValue", "<< 0", "0x7FFF_FFFF", "0x7FFF_FFFF_FFFF_FFFF", nint_shl(0));
            validate("nint", "NIntMaxValue", "<< 1", "0xFFFF_FFFE", "0xFFFF_FFFF_FFFF_FFFE", nint_shl(1));
            validate("nint", "NIntMaxValue", "<< 31", "0x8000_0000", "0xFFFF_FFFF_8000_0000", nint_shl(31));
            validate("nint", "NIntMaxValue", "<< 32", "0x7FFF_FFFF", "0xFFFF_FFFF_0000_0000", nint_shl(32));
            validate("nint", "NIntMaxValue", "<< 63", "0x8000_0000", "0x8000_0000_0000_0000", nint_shl(63));
            validate("nint", "NIntMaxValue", "<< 64", "0x7FFF_FFFF", "0x7FFF_FFFF_FFFF_FFFF", nint_shl(64));
 
            // negative nint shift left
            validate("nint", "NIntNegativeValue", "<< 63", "0x8000_0000", "0x8000_0000_0000_0000", nint_shl(63));
 
            // nuint shift right
            validate("nuint", "NUintMaxValue", ">> 0", "0xFFFF_FFFF", "0xFFFF_FFFF_FFFF_FFFF", nuint_shr_un(0));
            validate("nuint", "NUintMaxValue", ">> 1", "0x7FFF_FFFF", "0x7FFF_FFFF_FFFF_FFFF", nuint_shr_un(1));
            validate("nuint", "NUintMaxValue", ">> 31", "0x0000_0001", "0x0000_0001_FFFF_FFFF", nuint_shr_un(31));
            validate("nuint", "NUintMaxValue", ">> 32", "0xFFFF_FFFF", "0x0000_0000_FFFF_FFFF", nuint_shr_un(32));
            validate("nuint", "NUintMaxValue", ">> 63", "0x0000_0001", "0x0000_0000_0000_0001", nuint_shr_un(63));
            validate("nuint", "NUintMaxValue", ">> 64", "0xFFFF_FFFF", "0xFFFF_FFFF_FFFF_FFFF", nuint_shr_un(64));
 
            // nuint shift left
            validate("nuint", "NUintMaxValue", "<< 0", "0xFFFF_FFFF", "0xFFFF_FFFF_FFFF_FFFF", nuint_shl(0));
            validate("nuint", "NUintMaxValue", "<< 1", "0xFFFF_FFFE", "0xFFFF_FFFF_FFFF_FFFE", nuint_shl(1));
            validate("nuint", "NUintMaxValue", "<< 31", "0x8000_0000", "0xFFFF_FFFF_8000_0000", nuint_shl(31));
            validate("nuint", "NUintMaxValue", "<< 32", "0xFFFF_FFFF", "0xFFFF_FFFF_0000_0000", nuint_shl(32));
            validate("nuint", "NUintMaxValue", "<< 63", "0x8000_0000", "0x8000_0000_0000_0000", nuint_shl(63));
            validate("nuint", "NUintMaxValue", "<< 64", "0xFFFF_FFFF", "0xFFFF_FFFF_FFFF_FFFF", nuint_shl(64));
 
            // positive nint unsigned shift right
            validate("nint", "NIntMaxValue", ">>> 0", "0x7FFF_FFFF", "0x7FFF_FFFF_FFFF_FFFF", nint_shr_un(0));
            validate("nint", "NIntMaxValue", ">>> 1", "0x3FFF_FFFF", "0x3FFF_FFFF_FFFF_FFFF", nint_shr_un(1));
            validate("nint", "NIntMaxValue", ">>> 31", "0x0", "0xFFFF_FFFF", nint_shr_un(31));
            validate("nint", "NIntMaxValue", ">>> 32", "0x7FFF_FFFF", "0x7FFF_FFFF", nint_shr_un(32));
            validate("nint", "NIntMaxValue", ">>> 63", "0x0", "0x0", nint_shr_un(63));
            validate("nint", "NIntMaxValue", ">>> 64", "0x7FFF_FFFF", "0x7FFF_FFFF_FFFF_FFFF", nint_shr_un(64));
 
            // negative nint unsigned shift right
            validate("nint", "NIntNegativeValue", ">>> 0", "0xC000_0001", "0xC000_0000_0000_0001", nint_shr_un(0));
            validate("nint", "NIntNegativeValue", ">>> 1", "0x6000_0000", "0x6000_0000_0000_0000", nint_shr_un(1));
            validate("nint", "NIntNegativeValue", ">>> 31", "0x1", "0x0000_0001_8000_0000", nint_shr_un(31));
            validate("nint", "NIntNegativeValue", ">>> 32", "0xC000_0001", "0x0000_0000_C000_0000", nint_shr_un(32));
            validate("nint", "NIntNegativeValue", ">>> 63", "0x1", "0x1", nint_shr_un(63));
            validate("nint", "NIntNegativeValue", ">>> 64", "0xC000_0001", "0xC000_0000_0000_0001", nint_shr_un(64));
 
            // nuint unsigned shift right
            validate("nuint", "NUintMaxValue", ">>> 0", "0xFFFF_FFFF", "0xFFFF_FFFF_FFFF_FFFF", nuint_shr_un(0));
            validate("nuint", "NUintMaxValue", ">>> 1", "0x7FFF_FFFF", "0x7FFF_FFFF_FFFF_FFFF", nuint_shr_un(1));
            validate("nuint", "NUintMaxValue", ">>> 31", "0x0000_0001", "0x0000_0001_FFFF_FFFF", nuint_shr_un(31));
            validate("nuint", "NUintMaxValue", ">>> 32", "0xFFFF_FFFF", "0x0000_0000_FFFF_FFFF", nuint_shr_un(32));
            validate("nuint", "NUintMaxValue", ">>> 63", "0x0000_0001", "0x0000_0000_0000_0001", nuint_shr_un(63));
            validate("nuint", "NUintMaxValue", ">>> 64", "0xFFFF_FFFF", "0xFFFF_FFFF_FFFF_FFFF", nuint_shr_un(64));
 
            // lifted value
            validate("nint?", "NIntMaxValue", ">> 0", "0x7FFF_FFFF", "0x7FFF_FFFF_FFFF_FFFF", liftedValue(0, "nint?", "shr"));
            validate("nint?", "NIntMaxValue", ">> 1", "0x3FFF_FFFF", "0x3FFF_FFFF_FFFF_FFFF", liftedValue(1, "nint?", "shr"));
            validate("nint?", "NIntMaxValue", ">> 65", "0x3FFF_FFFF", "0x3FFF_FFFF_FFFF_FFFF", liftedValue(65, "nint?", "shr"));
            validate("nint?", "NIntNegativeValue", ">> 65", "0xE000_0000", "0xE000_0000_0000_0000", liftedValue(65, "nint?", "shr"));
            validate("nint?", "NIntMaxValue", "<< 65", "0xFFFF_FFFE", "0xFFFF_FFFF_FFFF_FFFE", liftedValue(65, "nint?", "shl"));
            validate("nint?", "NIntNegativeValue", "<< 65", "0x8000_0002", "0x8000_0000_0000_0002", liftedValue(65, "nint?", "shl"));
 
            validate("nuint?", "NUintMaxValue", ">> 65", "0x7FFF_FFFF", "0x7FFF_FFFF_FFFF_FFFF", liftedValue(65, "nuint?", "shr.un"));
            validate("nuint?", "NUintMaxValue", "<< 65", "0xFFFF_FFFE", "0xFFFF_FFFF_FFFF_FFFE", liftedValue(65, "nuint?", "shl"));
 
            validate("nint?", "NIntMaxValue", ">>> 65", "0x3FFF_FFFF", "0x3FFF_FFFF_FFFF_FFFF", liftedValue(65, "nint?", "shr.un"));
            validate("nint?", "NIntNegativeValue", ">>> 65", "0x6000_0000", "0x6000_0000_0000_0000", liftedValue(65, "nint?", "shr.un"));
            validate("nuint?", "NUintMaxValue", ">>> 65", "0x7FFF_FFFF", "0x7FFF_FFFF_FFFF_FFFF", liftedValue(65, "nuint?", "shr.un"));
 
            // lifted count
            compileAndVerify("""
class C
{
    nint? M(nint value, int? count) => value >> count;
}
""")
                .VerifyIL("C.M", @"
{
  // Code size       49 (0x31)
  .maxstack  4
  .locals init (nint V_0,
                int? V_1,
                nint? V_2)
  IL_0000:  ldarg.1
  IL_0001:  stloc.0
  IL_0002:  ldarg.2
  IL_0003:  stloc.1
  IL_0004:  ldloca.s   V_1
  IL_0006:  call       ""readonly bool int?.HasValue.get""
  IL_000b:  brtrue.s   IL_0017
  IL_000d:  ldloca.s   V_2
  IL_000f:  initobj    ""nint?""
  IL_0015:  ldloc.2
  IL_0016:  ret
  IL_0017:  ldloc.0
  IL_0018:  ldloca.s   V_1
  IL_001a:  call       ""readonly int int?.GetValueOrDefault()""
  IL_001f:  sizeof     ""nint""
  IL_0025:  ldc.i4.8
  IL_0026:  mul
  IL_0027:  ldc.i4.1
  IL_0028:  sub
  IL_0029:  and
  IL_002a:  shr
  IL_002b:  newobj     ""nint?..ctor(nint)""
  IL_0030:  ret
}
");
 
            // lifted value and lifted count
            compileAndVerify("""
class C
{
    nint? M(nint? value, int? count) => value >> count;
}
""")
                .VerifyIL("C.M", @"
{
  // Code size       63 (0x3f)
  .maxstack  4
  .locals init (nint? V_0,
                int? V_1,
                nint? V_2)
  IL_0000:  ldarg.1
  IL_0001:  stloc.0
  IL_0002:  ldarg.2
  IL_0003:  stloc.1
  IL_0004:  ldloca.s   V_0
  IL_0006:  call       ""readonly bool nint?.HasValue.get""
  IL_000b:  ldloca.s   V_1
  IL_000d:  call       ""readonly bool int?.HasValue.get""
  IL_0012:  and
  IL_0013:  brtrue.s   IL_001f
  IL_0015:  ldloca.s   V_2
  IL_0017:  initobj    ""nint?""
  IL_001d:  ldloc.2
  IL_001e:  ret
  IL_001f:  ldloca.s   V_0
  IL_0021:  call       ""readonly nint nint?.GetValueOrDefault()""
  IL_0026:  ldloca.s   V_1
  IL_0028:  call       ""readonly int int?.GetValueOrDefault()""
  IL_002d:  sizeof     ""nint""
  IL_0033:  ldc.i4.8
  IL_0034:  mul
  IL_0035:  ldc.i4.1
  IL_0036:  sub
  IL_0037:  and
  IL_0038:  shr
  IL_0039:  newobj     ""nint?..ctor(nint)""
  IL_003e:  ret
}
");
            return;
 
            static string nint_shr(int count) => shift(count, "nint", "shr");
            static string nint_shr_un(int count) => shift(count, "nint", "shr.un");
            static string nint_shl(int count) => shift(count, "nint", "shl");
            static string nuint_shr_un(int count) => shift(count, "nuint", "shr.un");
            static string nuint_shl(int count) => shift(count, "nuint", "shl");
 
            static string shift(int count, string type, string op)
            {
                if (count == 0)
                {
                    return $@"
{{
  // Code size        2 (0x2)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ret
}}
";
                }
 
                if (count == 1)
                {
                    return $@"
{{
  // Code size        4 (0x4)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  {op}
  IL_0003:  ret
}}
";
                }
 
                if (count <= 31)
                {
                    return $@"
{{
  // Code size        5 (0x5)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.s   {count}
  IL_0003:  {op}
  IL_0004:  ret
}}
";
                }
 
                return $@"
{{
  // Code size       16 (0x10)
  .maxstack  4
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.s   {count}
  IL_0003:  sizeof     ""{type}""
  IL_0009:  ldc.i4.8
  IL_000a:  mul
  IL_000b:  ldc.i4.1
  IL_000c:  sub
  IL_000d:  and
  IL_000e:  {op}
  IL_000f:  ret
}}
";
            }
 
            static string liftedValue(int count, string type, string op)
            {
                var strippedType = type.Trim('?');
                if (count == 0)
                {
                    return $@"
{{
  // Code size       34 (0x22)
  .maxstack  1
  .locals init ({type} V_0,
                {type} V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool {type}.HasValue.get""
  IL_0009:  brtrue.s   IL_0015
  IL_000b:  ldloca.s   V_1
  IL_000d:  initobj    ""{type}""
  IL_0013:  ldloc.1
  IL_0014:  ret
  IL_0015:  ldloca.s   V_0
  IL_0017:  call       ""readonly {strippedType} {type}.GetValueOrDefault()""
  IL_001c:  newobj     ""{type}..ctor({strippedType})""
  IL_0021:  ret
}}";
                }
 
                if (count == 1)
                {
                    return $@"
{{
  // Code size       36 (0x24)
  .maxstack  2
  .locals init ({type} V_0,
                {type} V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool {type}.HasValue.get""
  IL_0009:  brtrue.s   IL_0015
  IL_000b:  ldloca.s   V_1
  IL_000d:  initobj    ""{type}""
  IL_0013:  ldloc.1
  IL_0014:  ret
  IL_0015:  ldloca.s   V_0
  IL_0017:  call       ""readonly {strippedType} {type}.GetValueOrDefault()""
  IL_001c:  ldc.i4.1
  IL_001d:  {op}
  IL_001e:  newobj     ""{type}..ctor({strippedType})""
  IL_0023:  ret
}}
";
                }
 
                Assert.True(count == 65);
 
                return $@"
{{
  // Code size       48 (0x30)
  .maxstack  4
  .locals init ({type} V_0,
                {type} V_1)
  IL_0000:  ldarg.0
  IL_0001:  stloc.0
  IL_0002:  ldloca.s   V_0
  IL_0004:  call       ""readonly bool {type}.HasValue.get""
  IL_0009:  brtrue.s   IL_0015
  IL_000b:  ldloca.s   V_1
  IL_000d:  initobj    ""{type}""
  IL_0013:  ldloc.1
  IL_0014:  ret
  IL_0015:  ldloca.s   V_0
  IL_0017:  call       ""readonly {strippedType} {type}.GetValueOrDefault()""
  IL_001c:  ldc.i4.s   {count}
  IL_001e:  sizeof     ""{strippedType}""
  IL_0024:  ldc.i4.8
  IL_0025:  mul
  IL_0026:  ldc.i4.1
  IL_0027:  sub
  IL_0028:  and
  IL_0029:  {op}
  IL_002a:  newobj     ""{type}..ctor({strippedType})""
  IL_002f:  ret
}}
";
            }
 
            CompilationVerifier compileAndVerify(CSharpTestSource source)
            {
                var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
                return CompileAndVerify(comp, verify: Verification.FailsPEVerify);
            }
 
            void validate(string type, string value, string binaryOp, string result32Bits, string result64Bits, string expectedIL)
            {
                validateWithCheckedOrUnchecked(type, value, binaryOp, expectedIL, result32Bits, result64Bits, isChecked: true);
                validateWithCheckedOrUnchecked(type, value, binaryOp, expectedIL, result32Bits, result64Bits, isChecked: false);
            }
 
            void validateWithCheckedOrUnchecked(string type, string value, string binaryOp, string expectedIL, string result32Bits, string result64Bits, bool isChecked)
            {
                var checkedKeyword = isChecked ? "checked" : "unchecked";
                var strippedType = type.Trim('?');
 
                var source = $$"""
class C
{
    public static unsafe nint NIntMaxValue
        => (sizeof(nint) == 4) ? (nint)0x7FFF_FFFF : (nint)0x7FFF_FFFF_FFFF_FFFF;
 
    public static unsafe nint NIntNegativeValue
        => (sizeof(nint) == 4) ? (nint)0xC000_0001 : unchecked((nint)0xC000_0000_0000_0001);
 
    public static unsafe nuint NUintMaxValue
        => (sizeof(nint) == 4) ? (nuint)0xFFFF_FFFF : (nuint)0xFFFF_FFFF_FFFF_FFFF;
 
    public static {{type}} M({{type}} value)
    {
        return {{checkedKeyword}}(value {{binaryOp}});
    }
    public static unsafe void Main()
    {
        if (sizeof(nint) == 4)
        {
            if (unchecked(({{type}}){{result32Bits}}) == ({{value}} {{binaryOp}}))
            {
                System.Console.Write("RAN");
            }
            else
            {
                System.Console.Write($"Actual for '{{value}} {{binaryOp}}' (32-bit): {{{value}} {{binaryOp}}}");
            }
        }
        else if (sizeof(nint) == 8)
        {
            if (unchecked(({{type}}){{result64Bits}}) == ({{value}} {{binaryOp}}))
            {
                System.Console.Write("RAN");
            }
            else
            {
                System.Console.Write($"Actual for '{{value}} {{binaryOp}}' (64-bit): {{{value}} {{binaryOp}}}");
            }
        }
    }
}
""";
                var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseExe, targetFramework: TargetFramework.Net70);
                var verifier = CompileAndVerify(comp, verify: Verification.FailsPEVerify, expectedOutput: IncludeExpectedOutput("RAN"));
                verifier.VerifyIL("C.M", expectedIL);
            }
        }
 
        [Fact]
        public void MaskShiftCount_NegativeCount()
        {
            var source = """
System.Console.WriteLine(C.ShiftRight(255));
 
static class C
{
    public static nint ShiftRight(nint x) => x >> (-62);
}
""";
            var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseExe, targetFramework: TargetFramework.Net70);
            comp.VerifyDiagnostics();
            var verifier = CompileAndVerify(comp, expectedOutput: IncludeExpectedOutput("63"), verify: Verification.FailsPEVerify);
            verifier.VerifyIL("C.ShiftRight", @"
{
  // Code size       16 (0x10)
  .maxstack  4
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.s   -62
  IL_0003:  sizeof     ""nint""
  IL_0009:  ldc.i4.8
  IL_000a:  mul
  IL_000b:  ldc.i4.1
  IL_000c:  sub
  IL_000d:  and
  IL_000e:  shr
  IL_000f:  ret
}
");
        }
 
        [WorkItem(63348, "https://github.com/dotnet/roslyn/issues/63348")]
        [Fact]
        public void ConditionalStackalloc()
        {
            var source =
@"using System;
class Program
{
    static int F(int n)
    {
        Span<char> s = n < 10 ? stackalloc char[n] : new char[n];
        return s[n - 1];
    }
    static void Main()
    {
        Console.Write(F(1));
        Console.Write(F(11));
    }
}";
 
            var comp = CreateCompilation(new[] { TestSources.Span, source }, options: TestOptions.UnsafeReleaseExe);
            verify(comp);
 
            comp = CreateCompilation(new[] { source }, options: TestOptions.UnsafeReleaseExe, targetFramework: TargetFramework.Net70);
            verify(comp);
 
            void verify(CSharpCompilation comp)
            {
                comp.VerifyEmitDiagnostics();
                var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("00"));
                verifier.VerifyIL("Program.F", """
{
  // Code size       48 (0x30)
  .maxstack  3
  .locals init (System.Span<char> V_0, //s
                System.Span<char> V_1,
                int V_2)
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.s   10
  IL_0003:  bge.s      IL_0016
  IL_0005:  ldarg.0
  IL_0006:  stloc.2
  IL_0007:  ldloc.2
  IL_0008:  conv.u
  IL_0009:  ldc.i4.2
  IL_000a:  mul.ovf.un
  IL_000b:  localloc
  IL_000d:  ldloc.2
  IL_000e:  newobj     "System.Span<char>..ctor(void*, int)"
  IL_0013:  stloc.1
  IL_0014:  br.s       IL_0022
  IL_0016:  ldarg.0
  IL_0017:  newarr     "char"
  IL_001c:  call       "System.Span<char> System.Span<char>.op_Implicit(char[])"
  IL_0021:  stloc.1
  IL_0022:  ldloc.1
  IL_0023:  stloc.0
  IL_0024:  ldloca.s   V_0
  IL_0026:  ldarg.0
  IL_0027:  ldc.i4.1
  IL_0028:  sub
  IL_0029:  call       "ref char System.Span<char>.this[int].get"
  IL_002e:  ldind.u2
  IL_002f:  ret
}
""");
            }
        }
 
        [WorkItem(67041, "https://github.com/dotnet/roslyn/issues/67041")]
        [Theory]
        [CombinatorialData]
        public void PointerSubtraction(bool useNumericIntPtr)
        {
            var source = """
                class Program
                {
                    static unsafe long F(int* p1)
                    {
                        byte* p2 = (byte*)p1;
                        p2++;
                        return p2 - (byte*)p1;
                    }
                }
                """;
            var comp = CreateCompilation(
                source,
                options: TestOptions.UnsafeReleaseDll,
                targetFramework: useNumericIntPtr ? TargetFramework.Net60 : TargetFramework.Net70);
            comp.VerifyEmitDiagnostics();
        }
 
        private void VerifyNoNativeIntegerAttributeEmitted(CSharpCompilation comp)
        {
            // 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).
            CompileAndVerify(comp,
                emitOptions: new EmitOptions(runtimeMetadataVersion: "v5.1", debugInformationFormat: DebugInformationFormat.PortablePdb),
                symbolValidator: module => Assert.Equal("", NativeIntegerAttributesVisitor.GetString((PEModuleSymbol)module)),
                verify: Verification.Skipped);
        }
 
        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
        };
    }
}