@ -165,7 +165,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -165,7 +165,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
private Conversion ImplicitConversion ( IType fromType , IType toType , bool allowUserDefined , bool allowTuple )
{
// C# 4.0 spec: §6.1
// C# spec (draft-v11): §10.2 Implicit conversions
var c = StandardImplicitConversion ( fromType , toType , allowTuple ) ;
if ( c = = Conversion . None & & allowUserDefined )
{
@ -234,7 +234,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -234,7 +234,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
if ( allowTupleConversion )
{
// TODO are tuple conversions really standard implicit conversions?
// the C# 9.0 spec doesn't list them as standard implicit conversions.
// The C# spec (draft-v11, §10.4.2) doesn't list them as standard implicit conversions.
c = TupleConversion ( fromType , toType , isExplicit : false ) ;
if ( c ! = Conversion . None )
return c ;
@ -256,7 +256,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -256,7 +256,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// <summary>
/// Gets whether the type 'fromType' is convertible to 'toType'
/// using one of the conversions allowed when satisfying constraints (§4.4.4 )
/// using one of the conversions allowed when satisfying constraints (§8.4.5 )
/// </summary>
public bool IsConstraintConvertible ( IType fromType , IType toType )
{
@ -366,7 +366,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -366,7 +366,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// </summary>
public bool IdentityConversion ( IType fromType , IType toType )
{
// C# 4.0 spec: §6.1.1
// C# spec (draft-v11): §10.2.2 Identity conversion
fromType = fromType . AcceptVisitor ( NormalizeTypeVisitor . TypeErasure ) ;
toType = toType . AcceptVisitor ( NormalizeTypeVisitor . TypeErasure ) ;
return fromType . Equals ( toType ) ;
@ -450,7 +450,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -450,7 +450,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
bool AnyNumericConversion ( IType fromType , IType toType )
{
// C# 4.0 spec: §6.1.2 + §6.2.1
// C# spec (draft-v11): §10.2.3 + §10.3.2 (numeric conversions)
return IsNumericType ( fromType ) & & IsNumericType ( toType ) ;
}
#endregion
@ -473,7 +473,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -473,7 +473,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
bool ExplicitEnumerationConversion ( IType fromType , IType toType )
{
// C# 4.0 spec: §6.2.2
// C# spec (draft-v11): §10.3.3 Explicit enumeration conversions
if ( fromType . Kind = = TypeKind . Enum )
{
return toType . Kind = = TypeKind . Enum | | IsNumericType ( toType ) ;
@ -504,7 +504,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -504,7 +504,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
Conversion ExplicitNullableConversion ( IType fromType , IType toType )
{
// C# 4.0 spec: §6.1.4
// C# spec (draft-v11): §10.3.4 Explicit nullable conversions
if ( NullableType . IsNullable ( toType ) | | NullableType . IsNullable ( fromType ) )
{
IType t = NullableType . GetUnderlyingType ( toType ) ;
@ -638,7 +638,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -638,7 +638,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
ParameterizedType pt = t as ParameterizedType ;
if ( ps ! = null & & pt ! = null )
{
// C# 4.0 spec: §13.1.3.2 Variance C onversion
// C# spec (draft-v11): §19.2.3.3 Variance c onversion
for ( int i = 0 ; i < def . TypeParameters . Count ; i + + )
{
IType si = ps . GetTypeArgument ( i ) ;
@ -678,7 +678,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -678,7 +678,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
#region Explicit Reference Conversion
bool ExplicitReferenceConversion ( IType fromType , IType toType )
{
// C# 4.0 spec: §6.2.4
// C# spec (draft-v11): §10.3.5 Explicit reference conversions
// test that the types are reference types:
if ( toType . IsReferenceType ! = true )
@ -811,7 +811,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -811,7 +811,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
bool UnboxingConversion ( IType fromType , IType toType )
{
// C# 4.0 spec: §6.2.5
// C# spec (draft-v11): §10.3.7 Unboxing conversions
toType = NullableType . GetUnderlyingType ( toType ) ;
if ( fromType . IsReferenceType = = true & & toType . IsReferenceType = = false )
return IsSubtypeOf ( toType , fromType , 0 ) ;
@ -898,7 +898,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -898,7 +898,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
#region Pointer Conversions
bool ImplicitPointerConversion ( IType fromType , IType toType )
{
// C# 4.0 spec: §18.4 Pointer conversions
// C# spec (draft-v11): §24.5 Pointer conversions
if ( fromType . Kind . IsAnyPointer ( ) & & toType is PointerType & & toType . ReflectionName = = "System.Void*" )
return true ;
if ( fromType . Kind = = TypeKind . Null & & toType . Kind . IsAnyPointer ( ) )
@ -929,7 +929,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -929,7 +929,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
bool ExplicitPointerConversion ( IType fromType , IType toType )
{
// C# 4.0 spec: §18.4 Pointer conversions
// C# spec (draft-v11): §24.5 Pointer conversions
if ( fromType . Kind . IsAnyPointer ( ) )
{
return toType . Kind . IsAnyPointer ( ) | | IsIntegerType ( toType ) ;
@ -1029,7 +1029,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -1029,7 +1029,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
Conversion UserDefinedImplicitConversion ( ResolveResult fromResult , IType fromType , IType toType )
{
// C# 4.0 spec §6.4 .4 User-defined implicit conversions
// C# spec (draft-v11): §10.5 .4 User-defined implicit conversions
// user-defined conversions are not supported with interfaces
if ( fromType . Kind = = TypeKind . Interface | | toType . Kind = = TypeKind . Interface )
@ -1078,7 +1078,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -1078,7 +1078,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
Conversion UserDefinedExplicitConversion ( ResolveResult fromResult , IType fromType , IType toType )
{
// C# 4.0 spec §6.4 .5 User-defined explicit conversions
// C# spec (draft-v11): §10.5 .5 User-defined explicit conversions
// user-defined conversions are not supported with interfaces
if ( fromType . Kind = = TypeKind . Interface | | toType . Kind = = TypeKind . Interface )
@ -1414,7 +1414,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -1414,7 +1414,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// <summary>
/// Gets whether a <paramref name="method"/> is compatible with a delegate type.
/// §15.2 Delegate compatibility
/// C# spec (draft-v11): §21.4 Delegate compatibility
/// </summary>
/// <param name="method">The method to test for compatibility</param>
/// <param name="delegateType">The delegate type</param>
@ -1439,7 +1439,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -1439,7 +1439,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// If this parameter is true, the first parameter of <paramref name="m"/> will be ignored.</param>
bool IsDelegateCompatible ( IMethod m , IMethod d , bool isExtensionMethodInvocation )
{
// C# 9.0 §20 .4 Delegate compatibility
// C# spec (draft-v11): §21 .4 Delegate compatibility
if ( m = = null )
throw new ArgumentNullException ( nameof ( m ) ) ;
if ( d = = null )
@ -1479,7 +1479,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -1479,7 +1479,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
#region Tuple Conversion
Conversion TupleConversion ( TupleResolveResult fromRR , IType toType , bool isExplicit )
{
// C# 9.0 spec: §10.2.13 (implicit tuple conversions) + $ 10.3.6 (explicit tuple conversions)
// C# 9.0 spec: §10.2.13 (implicit tuple conversions) + § 10.3.6 (explicit tuple conversions)
var fromElements = fromRR . Elements ;
var toElements = TupleType . GetTupleElementTypes ( toType ) ;
if ( toElements . IsDefault | | fromElements . Length ! = toElements . Length )
@ -1505,7 +1505,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -1505,7 +1505,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
Conversion TupleConversion ( IType fromType , IType toType , bool isExplicit )
{
// C# 9.0 spec: §10.2.13 (implicit tuple conversions) + $ 10.3.6 (explicit tuple conversions)
// C# 9.0 spec: §10.2.13 (implicit tuple conversions) + § 10.3.6 (explicit tuple conversions)
var fromElements = TupleType . GetTupleElementTypes ( fromType ) ;
if ( fromElements . IsDefaultOrEmpty )
return Conversion . None ;
@ -1659,7 +1659,8 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
@@ -1659,7 +1659,8 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
}
/// <summary>
/// Gets the better conversion (from type) (C# 4.0 spec, §7.5.3.4)
/// Gets the better conversion (from type) (C# 4.0 spec, §7.5.3.4; the current standard
/// no longer has this subclause, it was folded into §12.6.4.5-§12.6.4.7)
/// </summary>
/// <returns>0 = neither is better; 1 = t1 is better; 2 = t2 is better</returns>
public int BetterConversion ( IType s , IType t1 , IType t2 )