Skip to content

Commit

Permalink
Support for overloading and overriding signatures with function point…
Browse files Browse the repository at this point in the history
…ers.
  • Loading branch information
333fred committed May 14, 2020
1 parent 3f94e67 commit 447d87f
Show file tree
Hide file tree
Showing 9 changed files with 952 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2966,26 +2966,28 @@ internal bool HasImplicitPointerConversion(TypeSymbol? source, TypeSymbol? desti
return false;
}

if (!hasConversion(sourceParam.RefKind, destinationSig.Parameters[i].Type, sourceSig.Parameters[i].Type, ref useSiteDiagnostics))
if (!hasConversion(sourceParam.RefKind, destinationSig.Parameters[i].TypeWithAnnotations, sourceSig.Parameters[i].TypeWithAnnotations, ref useSiteDiagnostics))
{
return false;
}
}

return sourceSig.RefKind == destinationSig.RefKind
&& hasConversion(sourceSig.RefKind, sourceSig.ReturnType, destinationSig.ReturnType, ref useSiteDiagnostics);
&& hasConversion(sourceSig.RefKind, sourceSig.ReturnTypeWithAnnotations, destinationSig.ReturnTypeWithAnnotations, ref useSiteDiagnostics);

bool hasConversion(RefKind refKind, TypeSymbol sourceType, TypeSymbol destinationType, ref HashSet<DiagnosticInfo>? useSiteDiagnostics)
bool hasConversion(RefKind refKind, TypeWithAnnotations sourceType, TypeWithAnnotations destinationType, ref HashSet<DiagnosticInfo>? useSiteDiagnostics)
{
switch (refKind)
{
case RefKind.None:
return HasIdentityOrImplicitReferenceConversion(sourceType, destinationType, ref useSiteDiagnostics)
|| HasImplicitPointerToVoidConversion(sourceType, destinationType)
|| HasImplicitPointerConversion(sourceType, destinationType, ref useSiteDiagnostics);
return (!IncludeNullability || HasTopLevelNullabilityImplicitConversion(sourceType, destinationType))
&& (HasIdentityOrImplicitReferenceConversion(sourceType.Type, destinationType.Type, ref useSiteDiagnostics)
|| HasImplicitPointerToVoidConversion(sourceType.Type, destinationType.Type)
|| HasImplicitPointerConversion(sourceType.Type, destinationType.Type, ref useSiteDiagnostics));

default:
return HasIdentityConversion(sourceType, destinationType);
return (!IncludeNullability || HasTopLevelNullabilityIdentityConversion(sourceType, destinationType))
&& HasIdentityConversion(sourceType.Type, destinationType.Type);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ internal bool Equals(FunctionPointerMethodSymbol other, TypeCompareKind compareK

private bool EqualsNoParameters(FunctionPointerMethodSymbol other, TypeCompareKind compareKind, IReadOnlyDictionary<TypeParameterSymbol, bool>? isValueTypeOverride)
=> CallingConvention == other.CallingConvention
&& RefKind == other.RefKind
&& FunctionPointerTypeSymbol.RefKindEquals(compareKind, RefKind, other.RefKind)
&& ((compareKind & TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds) != 0
|| RefCustomModifiers.SequenceEqual(other.RefCustomModifiers))
&& ReturnTypeWithAnnotations.Equals(other.ReturnTypeWithAnnotations, compareKind, isValueTypeOverride);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ internal bool Equals(FunctionPointerParameterSymbol other, TypeCompareKind compa
&& _containingSymbol.Equals(other._containingSymbol, compareKind, isValueTypeOverride);

internal bool MethodEqualityChecks(FunctionPointerParameterSymbol other, TypeCompareKind compareKind, IReadOnlyDictionary<TypeParameterSymbol, bool>? isValueTypeOverride)
=> RefKind == other.RefKind
=> FunctionPointerTypeSymbol.RefKindEquals(compareKind, RefKind, other.RefKind)
&& ((compareKind & TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds) != 0
|| RefCustomModifiers.SequenceEqual(other.RefCustomModifiers))
&& TypeWithAnnotations.Equals(other.TypeWithAnnotations, compareKind, isValueTypeOverride);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,5 +157,22 @@ internal override TypeSymbol SetNullabilityForReferenceTypes(Func<TypeWithAnnota
return this;
}

internal static bool RefKindEquals(TypeCompareKind compareKind, RefKind refKind1, RefKind refKind2)
{
if ((compareKind & TypeCompareKind.FunctionPointerRefMatchesOutInRefReadonly) != 0)
{
return (refKind1, refKind2) switch
{
(RefKind.None, RefKind.None) => true,
(RefKind.None, _) => false,
(_, RefKind.None) => false,
_ => true
};
}
else
{
return refKind1 == refKind2;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ internal class MemberSignatureComparer : IEqualityComparer<Symbol>
considerTypeConstraints: false,
considerCallingConvention: false,
considerRefKindDifferences: false,
typeComparison: TypeCompareKind.AllIgnoreOptions); //shouldn't actually matter for source members
typeComparison: TypeCompareKind.AllIgnoreOptions);

/// <summary>
/// This instance is used to determine if a partial method implementation matches the definition.
Expand Down Expand Up @@ -313,6 +313,10 @@ private MemberSignatureComparer(
_considerCallingConvention = considerCallingConvention;
_considerRefKindDifferences = considerRefKindDifferences;
_typeComparison = typeComparison;
if (!considerRefKindDifferences)
{
_typeComparison |= TypeCompareKind.FunctionPointerRefMatchesOutInRefReadonly;
}
}

#region IEqualityComparer<Symbol> Members
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ internal static TypeSymbol CopyTypeCustomModifiers(TypeSymbol sourceType, TypeSy

Debug.Assert(resultType.Equals(sourceType, TypeCompareKind.IgnoreDynamicAndTupleNames | TypeCompareKind.IgnoreNullableModifiersForReferenceTypes)); // Same custom modifiers as source type.

Debug.Assert(resultType.Equals(destinationType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds)); // Same object/dynamic, nullability and tuple names as destination type.
// Same object/dynamic, nullability and tuple names as destination type.
Debug.Assert(resultType.Equals(destinationType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds | TypeCompareKind.IgnoreNativeIntegers));

return resultType;
}
Expand Down
Loading

0 comments on commit 447d87f

Please sign in to comment.