Skip to content

Commit f8e2cc1

Browse files
committed
Properly flag and structurally compare marker type references
1 parent 24698dd commit f8e2cc1

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

src/compiler/checker.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8948,7 +8948,7 @@ namespace ts {
89488948

89498949
if (isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True;
89508950

8951-
if (source.flags & TypeFlags.MarkerType && target.flags & TypeFlags.MarkerType) {
8951+
if (source.flags & TypeFlags.MarkerType && target.flags & TypeFlags.MarkerType && !(source.flags & TypeFlags.Object || target.flags & TypeFlags.Object)) {
89528952
return source === markerSubType && target === markerSuperType ? Ternary.True : Ternary.False;
89538953
}
89548954

@@ -9414,9 +9414,11 @@ namespace ts {
94149414
}
94159415
}
94169416
else {
9417-
if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (<TypeReference>source).target === (<TypeReference>target).target) {
9418-
// We have type references to the same generic type. Obtain the variance information for the
9419-
// type parameters and relate the type arguments accordingly.
9417+
if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (<TypeReference>source).target === (<TypeReference>target).target &&
9418+
!(source.flags & TypeFlags.MarkerType || target.flags & TypeFlags.MarkerType)) {
9419+
// We have type references to the same generic type, and the type references are not marker
9420+
// type references (which we always compare structurally). Obtain the variance information
9421+
// for the type parameters and relate the type arguments accordingly.
94209422
const variances = getVariances((<TypeReference>source).target);
94219423
if (result = typeArgumentsRelatedTo(<TypeReference>source, <TypeReference>target, variances, reportErrors)) {
94229424
return result;
@@ -9841,8 +9843,12 @@ namespace ts {
98419843
}
98429844
}
98439845

9844-
function getVarianceType(type: GenericType, source: TypeParameter, target: Type) {
9845-
return createTypeReference(type, map(type.typeParameters, t => t === source ? target : t));
9846+
// Return a type reference where the source type parameter is replaced with the target marker
9847+
// type, and flag the result as a marker type reference.
9848+
function getMarkerTypeReference(type: GenericType, source: TypeParameter, target: Type) {
9849+
const result = createTypeReference(type, map(type.typeParameters, t => t === source ? target : t));
9850+
result.flags |= TypeFlags.MarkerType;
9851+
return result;
98469852
}
98479853

98489854
// Return an array containing the variance of each type parameter. The variance is effectively
@@ -9867,15 +9873,15 @@ namespace ts {
98679873
// We first compare instantiations where the type parameter is replaced with
98689874
// marker types that have a known subtype relationship. From this we can infer
98699875
// invariance, covariance, contravariance or bivariance.
9870-
const typeWithSuper = getVarianceType(type, tp, markerSuperType);
9871-
const typeWithSub = getVarianceType(type, tp, markerSubType);
9876+
const typeWithSuper = getMarkerTypeReference(type, tp, markerSuperType);
9877+
const typeWithSub = getMarkerTypeReference(type, tp, markerSubType);
98729878
let variance = (isTypeAssignableTo(typeWithSub, typeWithSuper) ? Variance.Covariant : 0) |
98739879
(isTypeAssignableTo(typeWithSuper, typeWithSub) ? Variance.Contravariant : 0);
98749880
// If the instantiations appear to be related bivariantly, it may be because the
98759881
// type parameter is omnivariant (i.e. it isn't witnessed anywhere in the generic
98769882
// type). To determine this we compare instantiations where the type parameter is
98779883
// replaced with marker types that are known to be unrelated.
9878-
if (variance === Variance.Bivariant && isTypeAssignableTo(getVarianceType(type, tp, markerOtherType), typeWithSuper)) {
9884+
if (variance === Variance.Bivariant && isTypeAssignableTo(getMarkerTypeReference(type, tp, markerOtherType), typeWithSuper)) {
98799885
variance = Variance.Omnivariant;
98809886
}
98819887
variances.push(variance);

0 commit comments

Comments
 (0)