// 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.
using System;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Symbols;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Semantics
{
public class NativeIntegerTests : CSharpTestBase
{
[Fact]
public void LanguageVersion()
{
var source =
@"interface I
{
nint Add(nint x, nuint y);
}";
var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8);
comp.VerifyDiagnostics(
// (3,5): error CS8652: The feature 'native-sized integers' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// nint Add(nint x, nuint y);
Diagnostic(ErrorCode.ERR_FeatureInPreview, "nint").WithArguments("native-sized integers").WithLocation(3, 5),
// (3,14): error CS8652: The feature 'native-sized integers' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// nint Add(nint x, nuint y);
Diagnostic(ErrorCode.ERR_FeatureInPreview, "nint").WithArguments("native-sized integers").WithLocation(3, 14),
// (3,22): error CS8652: The feature 'native-sized integers' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// nint Add(nint x, nuint y);
Diagnostic(ErrorCode.ERR_FeatureInPreview, "nuint").WithArguments("native-sized integers").WithLocation(3, 22));
comp = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics();
}
///
/// System.IntPtr and System.UIntPtr definitions from metadata.
///
[Fact]
public void TypeDefinitions_FromMetadata()
{
var source =
@"interface I
{
void F1(System.IntPtr x, nint y);
void F2(System.UIntPtr x, nuint y);
}";
var comp = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics();
var type = comp.GetTypeByMetadataName("System.IntPtr");
VerifyType(type, signed: true, isNativeInt: false);
VerifyType(type.GetPublicSymbol(), signed: true, isNativeInt: false);
type = comp.GetTypeByMetadataName("System.UIntPtr");
VerifyType(type, signed: false, isNativeInt: false);
VerifyType(type.GetPublicSymbol(), signed: false, isNativeInt: false);
var method = comp.GetMember("I.F1");
Assert.Equal("void I.F1(System.IntPtr x, nint y)", method.ToTestDisplayString());
Assert.Equal("Sub I.F1(x As System.IntPtr, y As System.IntPtr)", VisualBasic.SymbolDisplay.ToDisplayString(method.GetPublicSymbol(), SymbolDisplayFormat.TestFormat));
VerifyTypes((NamedTypeSymbol)method.Parameters[0].Type, (NamedTypeSymbol)method.Parameters[1].Type, signed: true);
method = comp.GetMember("I.F2");
Assert.Equal("void I.F2(System.UIntPtr x, nuint y)", method.ToTestDisplayString());
Assert.Equal("Sub I.F2(x As System.UIntPtr, y As System.UIntPtr)", VisualBasic.SymbolDisplay.ToDisplayString(method.GetPublicSymbol(), SymbolDisplayFormat.TestFormat));
VerifyTypes((NamedTypeSymbol)method.Parameters[0].Type, (NamedTypeSymbol)method.Parameters[1].Type, signed: false);
}
///
/// System.IntPtr and System.UIntPtr definitions from source.
///
[Fact]
public void TypeDefinitions_FromSource()
{
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 interface IEquatable
{
bool Equals(T other);
}
public struct IntPtr : IEquatable
{
public override string ToString() => null;
public override int GetHashCode() => 0;
public override bool Equals(object obj) => false;
bool IEquatable.Equals(IntPtr other) => false;
}
public struct UIntPtr : IEquatable
{
public override string ToString() => null;
public override int GetHashCode() => 0;
public override bool Equals(object obj) => false;
bool IEquatable.Equals(UIntPtr other) => false;
}
}";
var sourceB =
@"interface I
{
void F1(System.IntPtr x, nint y);
void F2(System.UIntPtr x, nuint y);
}";
var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics();
verify(comp);
comp = CreateEmptyCompilation(sourceA);
comp.VerifyDiagnostics();
var ref1 = comp.ToMetadataReference();
var ref2 = comp.EmitToImageReference();
comp = CreateEmptyCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics();
verify(comp);
comp = CreateEmptyCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics();
verify(comp);
static void verify(CSharpCompilation comp)
{
var type = comp.GetTypeByMetadataName("System.IntPtr");
VerifyType(type, signed: true, isNativeInt: false);
VerifyType(type.GetPublicSymbol(), signed: true, isNativeInt: false);
type = comp.GetTypeByMetadataName("System.UIntPtr");
VerifyType(type, signed: false, isNativeInt: false);
VerifyType(type.GetPublicSymbol(), signed: false, isNativeInt: false);
var method = comp.GetMember("I.F1");
Assert.Equal("void I.F1(System.IntPtr x, nint y)", method.ToTestDisplayString());
VerifyTypes((NamedTypeSymbol)method.Parameters[0].Type, (NamedTypeSymbol)method.Parameters[1].Type, signed: true);
method = comp.GetMember("I.F2");
Assert.Equal("void I.F2(System.UIntPtr x, nuint y)", method.ToTestDisplayString());
VerifyTypes((NamedTypeSymbol)method.Parameters[0].Type, (NamedTypeSymbol)method.Parameters[1].Type, signed: false);
}
}
private static void VerifyType(NamedTypeSymbol type, bool signed, bool isNativeInt)
{
Assert.Equal(signed ? SpecialType.System_IntPtr : SpecialType.System_UIntPtr, type.SpecialType);
Assert.Equal(SymbolKind.NamedType, type.Kind);
Assert.Equal(TypeKind.Struct, type.TypeKind);
Assert.Same(type, type.ConstructedFrom);
Assert.Equal(isNativeInt, type.IsNativeIntegerType);
Assert.Equal(signed ? "IntPtr" : "UIntPtr", type.Name);
if (isNativeInt)
{
VerifyMembers(type);
}
}
private static void VerifyType(INamedTypeSymbol type, bool signed, bool isNativeInt)
{
Assert.Equal(signed ? SpecialType.System_IntPtr : SpecialType.System_UIntPtr, type.SpecialType);
Assert.Equal(SymbolKind.NamedType, type.Kind);
Assert.Equal(TypeKind.Struct, type.TypeKind);
Assert.Same(type, type.ConstructedFrom);
Assert.Equal(isNativeInt, type.IsNativeIntegerType);
Assert.Equal(signed ? "IntPtr" : "UIntPtr", type.Name);
}
private static void VerifyTypes(INamedTypeSymbol underlyingType, INamedTypeSymbol nativeIntegerType, bool signed)
{
VerifyType(underlyingType, signed, isNativeInt: false);
VerifyType(nativeIntegerType, signed, isNativeInt: true);
Assert.Same(underlyingType.ContainingSymbol, nativeIntegerType.ContainingSymbol);
Assert.Same(underlyingType.Name, nativeIntegerType.Name);
Assert.Empty(nativeIntegerType.GetTypeMembers());
var memberNames = nativeIntegerType.MemberNames;
var members = nativeIntegerType.GetMembers();
Assert.Equal(members.SelectAsArray(m => m.Name), memberNames);
var baseMembers = members.SelectAsArray(m => ((IMethodSymbol)m).OverriddenMethod);
Assert.Empty(baseMembers);
verifyInterfaces(underlyingType, underlyingType.Interfaces, nativeIntegerType, nativeIntegerType.Interfaces);
Assert.NotSame(underlyingType, nativeIntegerType);
Assert.Same(underlyingType, nativeIntegerType.NativeIntegerUnderlyingType);
Assert.Equal(underlyingType, nativeIntegerType);
Assert.Equal(nativeIntegerType, underlyingType);
Assert.True(underlyingType.Equals(nativeIntegerType));
Assert.True(((IEquatable)underlyingType).Equals(nativeIntegerType));
Assert.True(underlyingType.Equals(nativeIntegerType, SymbolEqualityComparer.Default));
Assert.True(underlyingType.Equals(nativeIntegerType, SymbolEqualityComparer.IncludeNullability));
Assert.True(underlyingType.Equals(nativeIntegerType, SymbolEqualityComparer.ConsiderEverything));
Assert.Equal(underlyingType.GetHashCode(), nativeIntegerType.GetHashCode());
static void verifyInterfaces(INamedTypeSymbol underlyingType, ImmutableArray underlyingInterfaces, INamedTypeSymbol nativeIntegerType, ImmutableArray nativeIntegerInterfaces)
{
underlyingInterfaces = underlyingInterfaces.WhereAsArray(t => t.Name == "IEquatable" && t.ContainingNamespace.Name == "System");
Assert.Equal(underlyingInterfaces.Length, nativeIntegerInterfaces.Length);
for (int i = 0; i < underlyingInterfaces.Length; i++)
{
verifyInterface(underlyingInterfaces[i], nativeIntegerInterfaces[i]);
}
void verifyInterface(INamedTypeSymbol underlyingInterface, INamedTypeSymbol nativeIntegerInterface)
{
Assert.Equal(underlyingInterface, nativeIntegerInterface);
for (int i = 0; i < underlyingInterface.TypeArguments.Length; i++)
{
var underlyingTypeArgument = underlyingInterface.TypeArguments[i];
var nativeIntegerTypeArgument = nativeIntegerInterface.TypeArguments[i];
if (underlyingTypeArgument.Equals(underlyingType, TypeCompareKind.AllIgnoreOptions))
{
Assert.True(nativeIntegerTypeArgument.IsNativeIntegerType);
}
}
}
}
}
private static void VerifyTypes(NamedTypeSymbol underlyingType, NamedTypeSymbol nativeIntegerType, bool signed)
{
VerifyType(underlyingType, signed, isNativeInt: false);
VerifyType(nativeIntegerType, signed, isNativeInt: true);
Assert.Same(underlyingType.ContainingSymbol, nativeIntegerType.ContainingSymbol);
Assert.Same(underlyingType.Name, nativeIntegerType.Name);
Assert.Empty(nativeIntegerType.GetTypeMembers());
var memberNames = nativeIntegerType.MemberNames;
var members = nativeIntegerType.GetMembers();
Assert.Equal(members.SelectAsArray(m => m.Name), memberNames);
var baseMembers = members.SelectAsArray(m => ((MethodSymbol)m).OverriddenMethod);
Assert.Empty(baseMembers);
verifyInterfaces(underlyingType, underlyingType.InterfacesNoUseSiteDiagnostics(), nativeIntegerType, nativeIntegerType.InterfacesNoUseSiteDiagnostics());
verifyInterfaces(underlyingType, underlyingType.GetDeclaredInterfaces(null), nativeIntegerType, nativeIntegerType.GetDeclaredInterfaces(null));
Assert.Null(underlyingType.NativeIntegerUnderlyingType);
Assert.Same(nativeIntegerType, underlyingType.AsNativeInteger());
Assert.Same(underlyingType, nativeIntegerType.NativeIntegerUnderlyingType);
verifyEqualButDistinct(underlyingType, underlyingType.AsNativeInteger());
verifyEqualButDistinct(nativeIntegerType, nativeIntegerType.NativeIntegerUnderlyingType);
verifyEqualButDistinct(underlyingType, nativeIntegerType);
VerifyTypes(underlyingType.GetPublicSymbol(), nativeIntegerType.GetPublicSymbol(), signed);
static void verifyEqualButDistinct(NamedTypeSymbol underlyingType, NamedTypeSymbol nativeIntegerType)
{
Assert.NotSame(underlyingType, nativeIntegerType);
Assert.Equal(underlyingType, nativeIntegerType);
Assert.Equal(nativeIntegerType, underlyingType);
Assert.True(underlyingType.Equals(nativeIntegerType, TypeCompareKind.ConsiderEverything));
Assert.True(nativeIntegerType.Equals(underlyingType, TypeCompareKind.ConsiderEverything));
Assert.Equal(underlyingType.GetHashCode(), nativeIntegerType.GetHashCode());
}
static void verifyInterfaces(NamedTypeSymbol underlyingType, ImmutableArray underlyingInterfaces, NamedTypeSymbol nativeIntegerType, ImmutableArray nativeIntegerInterfaces)
{
underlyingInterfaces = underlyingInterfaces.WhereAsArray(t => t.Name == "IEquatable" && t.ContainingNamespace.Name == "System");
Assert.Equal(underlyingInterfaces.Length, nativeIntegerInterfaces.Length);
for (int i = 0; i < underlyingInterfaces.Length; i++)
{
verifyInterface(underlyingInterfaces[i], nativeIntegerInterfaces[i]);
}
void verifyInterface(NamedTypeSymbol underlyingInterface, NamedTypeSymbol nativeIntegerInterface)
{
Assert.Equal(underlyingInterface, nativeIntegerInterface);
for (int i = 0; i < underlyingInterface.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics.Length; i++)
{
var underlyingTypeArgument = underlyingInterface.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics[i].Type;
var nativeIntegerTypeArgument = nativeIntegerInterface.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics[i].Type;
if (underlyingTypeArgument.Equals(underlyingType, TypeCompareKind.AllIgnoreOptions))
{
Assert.True(nativeIntegerTypeArgument.IsNativeIntegerType);
}
}
}
}
}
private static void VerifyMembers(NamedTypeSymbol type)
{
var memberNames = type.MemberNames;
var allMembers = type.GetMembers();
Assert.Equal(allMembers, type.GetMembers(), ReferenceEqualityComparer.Instance);
foreach (var member in allMembers)
{
Assert.Contains(member.Name, memberNames);
verifyMember(type, member);
}
var unorderedMembers = type.GetMembersUnordered();
Assert.Equal(allMembers.Length, unorderedMembers.Length);
verifyMembers(type, allMembers, unorderedMembers);
foreach (var memberName in memberNames)
{
var members = type.GetMembers(memberName);
Assert.False(members.IsDefaultOrEmpty);
verifyMembers(type, allMembers, members);
}
static void verifyMembers(NamedTypeSymbol type, ImmutableArray allMembers, ImmutableArray members)
{
foreach (var member in members)
{
Assert.Contains(member, allMembers);
verifyMember(type, member);
}
}
static void verifyMember(NamedTypeSymbol type, Symbol member)
{
Assert.Same(type, member.ContainingSymbol);
Assert.Same(type, member.ContainingType);
}
}
[Fact]
public void MissingTypes()
{
var sourceA =
@"namespace System
{
public class Object { }
public abstract class ValueType { }
public struct Void { }
}";
var sourceB =
@"interface I
{
void F1(System.IntPtr x, nint y);
void F2(System.UIntPtr x, nuint y);
}";
var diagnostics = new[]
{
// (3,20): error CS0234: The underlyingType or namespace name 'IntPtr' does not exist in the namespace 'System' (are you missing an assembly reference?)
// void F1(System.IntPtr x, nint y);
Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "IntPtr").WithArguments("IntPtr", "System").WithLocation(3, 20),
// (3,30): error CS0518: Predefined underlyingType 'System.IntPtr' is not defined or imported
// void F1(System.IntPtr x, nint y);
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "nint").WithArguments("System.IntPtr").WithLocation(3, 30),
// (4,20): error CS0234: The underlyingType or namespace name 'UIntPtr' does not exist in the namespace 'System' (are you missing an assembly reference?)
// void F2(System.UIntPtr x, nuint y);
Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "UIntPtr").WithArguments("UIntPtr", "System").WithLocation(4, 20),
// (4,31): error CS0518: Predefined underlyingType 'System.UIntPtr' is not defined or imported
// void F2(System.UIntPtr x, nuint y);
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "nuint").WithArguments("System.UIntPtr").WithLocation(4, 31)
};
var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics(diagnostics);
verify(comp);
comp = CreateEmptyCompilation(sourceA);
comp.VerifyDiagnostics();
var ref1 = comp.ToMetadataReference();
var ref2 = comp.EmitToImageReference();
comp = CreateEmptyCompilation(sourceB, references: new[] { ref1 }, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics(diagnostics);
verify(comp);
comp = CreateEmptyCompilation(sourceB, references: new[] { ref2 }, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics(diagnostics);
verify(comp);
static void verify(CSharpCompilation comp)
{
var method = comp.GetMember("I.F1");
Assert.Equal("void I.F1(System.IntPtr x, nint y)", method.ToTestDisplayString());
VerifyErrorTypes((NamedTypeSymbol)method.Parameters[0].Type, (NamedTypeSymbol)method.Parameters[1].Type, signed: true);
method = comp.GetMember("I.F2");
Assert.Equal("void I.F2(System.UIntPtr x, nuint y)", method.ToTestDisplayString());
VerifyErrorTypes((NamedTypeSymbol)method.Parameters[0].Type, (NamedTypeSymbol)method.Parameters[1].Type, signed: false);
}
}
private static void VerifyErrorType(NamedTypeSymbol type, SpecialType specialType, bool isNativeInt)
{
Assert.Equal(SymbolKind.ErrorType, type.Kind);
Assert.Equal(TypeKind.Error, type.TypeKind);
Assert.Equal(isNativeInt, type.IsNativeIntegerType);
Assert.Equal(specialType, type.SpecialType);
}
private static void VerifyErrorType(INamedTypeSymbol type, SpecialType specialType, bool isNativeInt)
{
Assert.Equal(SymbolKind.ErrorType, type.Kind);
Assert.Equal(TypeKind.Error, type.TypeKind);
Assert.Equal(isNativeInt, type.IsNativeIntegerType);
Assert.Equal(specialType, type.SpecialType);
}
private static void VerifyErrorTypes(NamedTypeSymbol underlyingType, NamedTypeSymbol nativeIntegerType, bool signed)
{
var specialType = signed ? SpecialType.System_IntPtr : SpecialType.System_UIntPtr;
VerifyErrorType(underlyingType, SpecialType.None, isNativeInt: false);
VerifyErrorType(nativeIntegerType, specialType, isNativeInt: true);
Assert.Null(underlyingType.NativeIntegerUnderlyingType);
VerifyErrorType(nativeIntegerType.NativeIntegerUnderlyingType, specialType, isNativeInt: false);
VerifyErrorTypes(underlyingType.GetPublicSymbol(), nativeIntegerType.GetPublicSymbol(), signed);
}
private static void VerifyErrorTypes(INamedTypeSymbol underlyingType, INamedTypeSymbol nativeIntegerType, bool signed)
{
var specialType = signed ? SpecialType.System_IntPtr : SpecialType.System_UIntPtr;
VerifyErrorType(underlyingType, SpecialType.None, isNativeInt: false);
VerifyErrorType(nativeIntegerType, specialType, isNativeInt: true);
Assert.Null(underlyingType.NativeIntegerUnderlyingType);
VerifyErrorType(nativeIntegerType.NativeIntegerUnderlyingType, specialType, isNativeInt: false);
}
[Fact]
public void Interfaces()
{
var sourceA =
@"namespace System
{
public class Object { }
public class String { }
public abstract class ValueType { }
public struct Void { }
public struct Boolean { }
public struct Int32 { }
public interface ISerializable { }
public interface IEquatable
{
bool Equals(T other);
}
public interface IOther { }
public struct IntPtr : ISerializable, IEquatable, IOther
{
bool IEquatable.Equals(IntPtr other) => false;
}
}";
var sourceB =
@"using System;
class Program
{
static void F0(ISerializable i) { }
static object F1(IEquatable i) => default;
static void F2(IEquatable i) { }
static void F3(IOther i) { }
static void Main()
{
nint n = 42;
F0(n);
F1(n);
_ = F2(n);
F3(n);
F3(n);
F3((IntPtr)n);
}
}";
var comp = CreateEmptyCompilation(new[] { sourceA, sourceB }, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics(
// (11,12): error CS1503: Argument 1: cannot convert from 'nint' to 'System.ISerializable'
// F0(n);
Diagnostic(ErrorCode.ERR_BadArgType, "n").WithArguments("1", "nint", "System.ISerializable").WithLocation(11, 12),
// (13,9): error CS8209: A value of type 'void' may not be assigned.
// _ = F2(n);
Diagnostic(ErrorCode.ERR_VoidAssignment, "_").WithLocation(13, 9),
// (14,18): error CS1503: Argument 1: cannot convert from 'nint' to 'System.IOther'
// F3(n);
Diagnostic(ErrorCode.ERR_BadArgType, "n").WithArguments("1", "nint", "System.IOther").WithLocation(14, 18),
// (15,20): error CS1503: Argument 1: cannot convert from 'nint' to 'System.IOther'
// F3(n);
Diagnostic(ErrorCode.ERR_BadArgType, "n").WithArguments("1", "nint", "System.IOther").WithLocation(15, 20));
}
[Fact]
public void IEquatable()
{
// Minimal definitions.
verifyAll(includesIEquatable: true,
@"namespace System
{
public class Object { }
public class String { }
public abstract class ValueType { }
public struct Void { }
public struct Boolean { }
public struct Int32 { }
public interface IEquatable { }
public struct IntPtr : IEquatable { }
public struct UIntPtr : IEquatable { }
}");
// IEquatable in global namespace.
verifyAll(includesIEquatable: false,
@"public interface IEquatable { }
namespace System
{
public class Object { }
public class String { }
public abstract class ValueType { }
public struct Void { }
public struct Boolean { }
public struct Int32 { }
public struct IntPtr : IEquatable { }
public struct UIntPtr : IEquatable { }
}");
// IEquatable in other namespace.
verifyAll(includesIEquatable: false,
@"namespace Other
{
public interface IEquatable { }
}
namespace System
{
public class Object { }
public class String { }
public abstract class ValueType { }
public struct Void { }
public struct Boolean { }
public struct Int32 { }
public struct IntPtr : Other.IEquatable { }
public struct UIntPtr : Other.IEquatable { }
}");
// IEquatable nested in "System" type.
verifyAll(includesIEquatable: false,
@"namespace System
{
public class Object { }
public class String { }
public abstract class ValueType { }
public struct Void { }
public struct Boolean { }
public struct Int32 { }
public class System
{
public interface IEquatable { }
}
public struct IntPtr : System.IEquatable { }
public struct UIntPtr : System.IEquatable { }
}");
// IEquatable nested in other type.
verifyAll(includesIEquatable: false,
@"namespace System
{
public class Object { }
public class String { }
public abstract class ValueType { }
public struct Void { }
public struct Boolean { }
public struct Int32 { }
public class Other
{
public interface IEquatable { }
}
public struct IntPtr : Other.IEquatable { }
public struct UIntPtr : Other.IEquatable { }
}");
// IEquatable.
verifyAll(includesIEquatable: false,
@"namespace System
{
public class Object { }
public class String { }
public abstract class ValueType { }
public struct Void { }
public struct Boolean { }
public struct Int32 { }
public interface IEquatable { }
public struct IntPtr : IEquatable { }
public struct UIntPtr : IEquatable { }
}");
// IEquatable.
verifyAll(includesIEquatable: false,
@"namespace System
{
public class Object { }
public class String { }
public abstract class ValueType { }
public struct Void { }
public struct Boolean { }
public struct Int32 { }
public interface IEquatable { }
public struct IntPtr : IEquatable { }
public struct UIntPtr : IEquatable { }
}");
// IEquatable