mirror of
https://github.com/github/codeql.git
synced 2026-04-30 03:05:15 +02:00
C#: Address review comments.
This commit is contained in:
@@ -535,7 +535,7 @@ predicate convSpan(Type fromType, Type toType) {
|
||||
|
|
||||
convIdentity(fromElementType, toElementType)
|
||||
or
|
||||
convCovariance(fromElementType, toElementType)
|
||||
convVariance(fromElementType, toElementType)
|
||||
)
|
||||
or
|
||||
fromType instanceof SystemStringClass and
|
||||
@@ -835,8 +835,8 @@ predicate convConversionOperator(Type fromType, Type toType) {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate convVarianceAux(UnboundGenericType ugt, GenericType fromType, GenericType toType) {
|
||||
/** 13.1.3.2: Variance conversion. */
|
||||
private predicate convVariance(GenericType fromType, GenericType toType) {
|
||||
// Semantically equivalent with
|
||||
// ```ql
|
||||
// ugt = fromType.getUnboundGeneric()
|
||||
@@ -856,23 +856,10 @@ private predicate convVarianceAux(UnboundGenericType ugt, GenericType fromType,
|
||||
// ```
|
||||
// but performance is improved by explicitly evaluating the `i`th argument
|
||||
// only when all preceding arguments are convertible.
|
||||
Variance::convVarianceSingle(ugt, fromType, toType)
|
||||
Variance::convVarianceSingle(_, fromType, toType)
|
||||
or
|
||||
Variance::convVarianceMultiple(ugt, fromType, toType, ugt.getNumberOfTypeParameters() - 1)
|
||||
}
|
||||
|
||||
/** 13.1.3.2: Variance conversion. */
|
||||
private predicate convVariance(GenericType fromType, GenericType toType) {
|
||||
convVarianceAux(_, fromType, toType)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds, if `fromType` is covariance convertible to `toType`.
|
||||
*/
|
||||
private predicate convCovariance(GenericType fromType, GenericType toType) {
|
||||
exists(UnboundGenericType ugt |
|
||||
convVarianceAux(ugt, fromType, toType) and
|
||||
forall(TypeParameter tp | tp = ugt.getATypeParameter() | tp.isOut())
|
||||
Variance::convVarianceMultiple(ugt, fromType, toType, ugt.getNumberOfTypeParameters() - 1)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,11 @@ using System.Collections.Generic;
|
||||
|
||||
public interface CovariantInterface<out T> { }
|
||||
|
||||
public interface ContravariantInterface<in T> { }
|
||||
|
||||
public interface InvariantInterface<T> { }
|
||||
|
||||
public interface Interface<out T1, T2> { }
|
||||
public interface MixedInterface<out T1, in T2> { }
|
||||
|
||||
public class Base { }
|
||||
|
||||
@@ -16,14 +18,14 @@ public class C
|
||||
public void M()
|
||||
{
|
||||
string[] stringArray = [];
|
||||
string[][] stringArrayArray;
|
||||
string[,] stringArray2D;
|
||||
string[][] stringArrayArray = [];
|
||||
string[,] stringArray2D = new string[0, 0];
|
||||
|
||||
Span<string> stringSpan = stringArray; // string[] -> Span<string>;
|
||||
|
||||
// Covariant conversions to ReadOnlySpan
|
||||
// Assignments are included to illustrate that this compiles.
|
||||
// Assignments are included to illustrate that it compiles.
|
||||
// Only the use of the types matter in terms of test output.
|
||||
// Covariant conversions to ReadOnlySpan
|
||||
ReadOnlySpan<CovariantInterface<Base>> covariantInterfaceBaseReadOnlySpan;
|
||||
ReadOnlySpan<CovariantInterface<Derived>> covariantInterfaceDerivedReadOnlySpan = default;
|
||||
Span<CovariantInterface<Derived>> covariantInterfaceDerivedSpan = default;
|
||||
@@ -37,18 +39,32 @@ public class C
|
||||
stringReadOnlySpan = stringSpan; // Span<string> -> ReadOnlySpan<string>;
|
||||
stringReadOnlySpan = stringArray; // string[] -> ReadOnlySpan<string>;
|
||||
|
||||
// Contravariant conversions to ReadOnlySpan
|
||||
ReadOnlySpan<ContravariantInterface<Derived>> contravariantInterfaceDerivedReadOnlySpan;
|
||||
ReadOnlySpan<ContravariantInterface<Base>> contravariantInterfaceBaseReadOnlySpan = default;
|
||||
Span<ContravariantInterface<Base>> contravariantInterfaceBaseSpan = default;
|
||||
ContravariantInterface<Base>[] contravariantInterfaceBaseArray = [];
|
||||
contravariantInterfaceDerivedReadOnlySpan = contravariantInterfaceBaseReadOnlySpan; // ReadOnlySpan<ContravariantInterface<Base>> -> ReadOnlySpan<ContravariantInterface<Derived>>
|
||||
contravariantInterfaceDerivedReadOnlySpan = contravariantInterfaceBaseSpan; // Span<ContravariantInterface<Base>> -> ReadOnlySpan<ContravariantInterface<Derived>>
|
||||
contravariantInterfaceDerivedReadOnlySpan = contravariantInterfaceBaseArray; // ContravariantInterface<Base>[] -> ReadOnlySpan<ContravariantInterface<Derived>>
|
||||
|
||||
// Mixed variance conversions to ReadOnlySpan
|
||||
ReadOnlySpan<MixedInterface<Base, Derived>> mixedInterfaceBaseReadOnlySpan;
|
||||
ReadOnlySpan<MixedInterface<Derived, Base>> mixedInterfaceDerivedReadOnlySpan = default;
|
||||
Span<MixedInterface<Derived, Base>> mixedInterfaceDerivedSpan = default;
|
||||
MixedInterface<Derived, Base>[] mixedInterfaceDerivedArray = [];
|
||||
mixedInterfaceBaseReadOnlySpan = mixedInterfaceDerivedReadOnlySpan; // ReadOnlySpan<MixedInterface<Derived, Base>> -> ReadOnlySpan<MixedInterface<Base, Derived>>
|
||||
mixedInterfaceBaseReadOnlySpan = mixedInterfaceDerivedSpan; // Span<MixedInterface<Derived, Base>> -> ReadOnlySpan<MixedInterface<Base, Derived>>
|
||||
mixedInterfaceBaseReadOnlySpan = mixedInterfaceDerivedArray; // MixedInterface<Derived, Base>[] -> ReadOnlySpan<MixedInterface<Base, Derived>>
|
||||
|
||||
// Convert string to ReadOnlySpan<char>
|
||||
string s = "";
|
||||
ReadOnlySpan<char> charReadOnlySpan = s; // string -> ReadOnlySpan<char>
|
||||
|
||||
// Use the non-covariant interfaces to show that no conversion is possible.
|
||||
// No conversion possible except for identity.
|
||||
ReadOnlySpan<InvariantInterface<Base>> invariantInterfaceBaseReadOnlySpan;
|
||||
ReadOnlySpan<InvariantInterface<Derived>> invariantInterfaceDerivedReadOnlySpan;
|
||||
Span<InvariantInterface<Derived>> invariantInterfaceDerivedSpan;
|
||||
InvariantInterface<Derived>[] invariantInterfaceDerivedArray;
|
||||
ReadOnlySpan<Interface<Base, string>> interfaceBaseReadOnlySpan;
|
||||
ReadOnlySpan<Interface<Derived, string>> interfaceDerivedReadOnlySpan;
|
||||
Span<Interface<Derived, string>> interfaceDerivedSpan;
|
||||
Interface<Derived, string>[] interfaceDerivedArray;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
| ContravariantInterface<Base>[] | ReadOnlySpan<ContravariantInterface<Base>> |
|
||||
| ContravariantInterface<Base>[] | ReadOnlySpan<ContravariantInterface<Derived>> |
|
||||
| ContravariantInterface<Base>[] | Span<ContravariantInterface<Base>> |
|
||||
| CovariantInterface<Derived>[] | ReadOnlySpan<CovariantInterface<Base>> |
|
||||
| CovariantInterface<Derived>[] | ReadOnlySpan<CovariantInterface<Derived>> |
|
||||
| CovariantInterface<Derived>[] | Span<CovariantInterface<Derived>> |
|
||||
| Interface<Derived,String>[] | ReadOnlySpan<Interface<Derived, string>> |
|
||||
| Interface<Derived,String>[] | Span<Interface<Derived, string>> |
|
||||
| InvariantInterface<Derived>[] | ReadOnlySpan<InvariantInterface<Derived>> |
|
||||
| InvariantInterface<Derived>[] | Span<InvariantInterface<Derived>> |
|
||||
| MixedInterface<Derived,Base>[] | ReadOnlySpan<MixedInterface<Base, Derived>> |
|
||||
| MixedInterface<Derived,Base>[] | ReadOnlySpan<MixedInterface<Derived, Base>> |
|
||||
| MixedInterface<Derived,Base>[] | Span<MixedInterface<Derived, Base>> |
|
||||
| ReadOnlySpan<ContravariantInterface<Base>> | ReadOnlySpan<ContravariantInterface<Derived>> |
|
||||
| ReadOnlySpan<CovariantInterface<Derived>> | ReadOnlySpan<CovariantInterface<Base>> |
|
||||
| ReadOnlySpan<MixedInterface<Derived, Base>> | ReadOnlySpan<MixedInterface<Base, Derived>> |
|
||||
| Span<ContravariantInterface<Base>> | ReadOnlySpan<ContravariantInterface<Base>> |
|
||||
| Span<ContravariantInterface<Base>> | ReadOnlySpan<ContravariantInterface<Derived>> |
|
||||
| Span<CovariantInterface<Derived>> | ReadOnlySpan<CovariantInterface<Base>> |
|
||||
| Span<CovariantInterface<Derived>> | ReadOnlySpan<CovariantInterface<Derived>> |
|
||||
| Span<Interface<Derived, string>> | ReadOnlySpan<Interface<Derived, string>> |
|
||||
| Span<InvariantInterface<Derived>> | ReadOnlySpan<InvariantInterface<Derived>> |
|
||||
| Span<MixedInterface<Derived, Base>> | ReadOnlySpan<MixedInterface<Base, Derived>> |
|
||||
| Span<MixedInterface<Derived, Base>> | ReadOnlySpan<MixedInterface<Derived, Base>> |
|
||||
| Span<string> | ReadOnlySpan<string> |
|
||||
| String[] | ReadOnlySpan<string> |
|
||||
| String[] | Span<string> |
|
||||
|
||||
Reference in New Issue
Block a user