KT-14498: Properly check variance in expanded types.

This commit is contained in:
Dmitry Petrov
2016-10-27 16:28:34 +03:00
parent 49bf1e5917
commit ed60674d13
14 changed files with 234 additions and 59 deletions
@@ -118,6 +118,8 @@ public interface Errors {
DiagnosticFactory1<KtTypeProjection, ClassifierDescriptor> REDUNDANT_PROJECTION = DiagnosticFactory1.create(WARNING, VARIANCE_IN_PROJECTION); DiagnosticFactory1<KtTypeProjection, ClassifierDescriptor> REDUNDANT_PROJECTION = DiagnosticFactory1.create(WARNING, VARIANCE_IN_PROJECTION);
DiagnosticFactory1<PsiElement, VarianceConflictDiagnosticData> TYPE_VARIANCE_CONFLICT = DiagnosticFactory1<PsiElement, VarianceConflictDiagnosticData> TYPE_VARIANCE_CONFLICT =
DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
DiagnosticFactory1<PsiElement, VarianceConflictDiagnosticData> TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE =
DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
DiagnosticFactory0<PsiElement> FINITE_BOUNDS_VIOLATION = DiagnosticFactory0.create(ERROR); DiagnosticFactory0<PsiElement> FINITE_BOUNDS_VIOLATION = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<PsiElement, String> FINITE_BOUNDS_VIOLATION_IN_JAVA = DiagnosticFactory1.create(WARNING); DiagnosticFactory1<PsiElement, String> FINITE_BOUNDS_VIOLATION_IN_JAVA = DiagnosticFactory1.create(WARNING);
DiagnosticFactory0<PsiElement> EXPANSIVE_INHERITANCE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0<PsiElement> EXPANSIVE_INHERITANCE = DiagnosticFactory0.create(ERROR);
@@ -546,21 +546,25 @@ public class DefaultErrorMessages {
MAP.put(MISPLACED_TYPE_PARAMETER_CONSTRAINTS, "If a type parameter has multiple constraints, they all need to be placed in the 'where' clause"); MAP.put(MISPLACED_TYPE_PARAMETER_CONSTRAINTS, "If a type parameter has multiple constraints, they all need to be placed in the 'where' clause");
MultiRenderer<VarianceConflictDiagnosticData> varianceConflictDataRenderer = new MultiRenderer<VarianceConflictDiagnosticData>() {
@NotNull
@Override
public String[] render(@NotNull VarianceConflictDiagnosticData data) {
RenderingContext context =
of(data.getTypeParameter(), data.getTypeParameter().getVariance(), data.getOccurrencePosition(),
data.getContainingType());
return new String[] {
NAME.render(data.getTypeParameter(), context),
RENDER_POSITION_VARIANCE.render(data.getTypeParameter().getVariance(), context),
RENDER_POSITION_VARIANCE.render(data.getOccurrencePosition(), context),
RENDER_TYPE.render(data.getContainingType(), context)
};
}
};
MAP.put(TYPE_VARIANCE_CONFLICT, "Type parameter {0} is declared as ''{1}'' but occurs in ''{2}'' position in type {3}", MAP.put(TYPE_VARIANCE_CONFLICT, "Type parameter {0} is declared as ''{1}'' but occurs in ''{2}'' position in type {3}",
new MultiRenderer<VarianceConflictDiagnosticData>() { varianceConflictDataRenderer);
@NotNull MAP.put(TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE, "Type parameter {0} is declared as ''{1}'' but occurs in ''{2}'' position in abbreviated type {3}",
@Override varianceConflictDataRenderer);
public String[] render(@NotNull VarianceConflictDiagnosticData data) {
RenderingContext context =
of(data.getTypeParameter(), data.getTypeParameter().getVariance(), data.getOccurrencePosition(), data.getContainingType());
return new String[] {
NAME.render(data.getTypeParameter(), context),
RENDER_POSITION_VARIANCE.render(data.getTypeParameter().getVariance(), context),
RENDER_POSITION_VARIANCE.render(data.getOccurrencePosition(), context),
RENDER_TYPE.render(data.getContainingType(), context)
};
}
});
MAP.put(FINITE_BOUNDS_VIOLATION, "This type parameter violates the Finite Bound Restriction"); MAP.put(FINITE_BOUNDS_VIOLATION, "This type parameter violates the Finite Bound Restriction");
MAP.put(FINITE_BOUNDS_VIOLATION_IN_JAVA, "Violation of Finite Bound Restriction for {0}", STRING); MAP.put(FINITE_BOUNDS_VIOLATION_IN_JAVA, "Violation of Finite Bound Restriction for {0}", STRING);
@@ -18,9 +18,7 @@ package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations
import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
@@ -28,20 +28,27 @@ import org.jetbrains.kotlin.types.*
interface TypeBinding<out P : PsiElement> : TypeHolder<TypeBinding<P>> { interface TypeBinding<out P : PsiElement> : TypeHolder<TypeBinding<P>> {
val psiElement: P val psiElement: P
val isInAbbreviation: Boolean
override val arguments: List<TypeArgumentBinding<P>?> override val arguments: List<TypeArgumentBinding<P>?>
} }
interface TypeArgumentBinding<out P: PsiElement> : TypeHolderArgument<TypeBinding<P>> interface TypeArgumentBinding<out P: PsiElement> : TypeHolderArgument<TypeBinding<P>>
fun KtTypeReference.createTypeBinding(trace: BindingContext): TypeBinding<KtTypeElement>? { fun KtTypeReference.createTypeBinding(trace: BindingContext): TypeBinding<KtTypeElement>? {
val jetType = trace[BindingContext.TYPE, this] val type = trace[BindingContext.TYPE, this]
val psiElement = typeElement val psiElement = typeElement
if (jetType == null || psiElement == null) { return if (type == null || psiElement == null)
return null null
} else
else { createTypeBindingFromPsi(trace, psiElement, type)
return ExplicitTypeBinding(trace, psiElement, jetType) }
}
private fun createTypeBindingFromPsi(trace: BindingContext, psiElement: KtTypeElement, type: KotlinType): TypeBinding<KtTypeElement> {
val abbreviatedType = type.getAbbreviatedType()
return if (abbreviatedType != null)
AbbreviatedTypeBinding(type, psiElement)
else
ExplicitTypeBinding(trace, psiElement, type)
} }
fun KtCallableDeclaration.createTypeBindingForReturnType(trace: BindingContext): TypeBinding<PsiElement>? { fun KtCallableDeclaration.createTypeBindingForReturnType(trace: BindingContext): TypeBinding<PsiElement>? {
@@ -65,30 +72,30 @@ private class ExplicitTypeBinding(
override val psiElement: KtTypeElement, override val psiElement: KtTypeElement,
override val type: KotlinType override val type: KotlinType
) : TypeBinding<KtTypeElement> { ) : TypeBinding<KtTypeElement> {
override val isInAbbreviation: Boolean get() = false
override val arguments: List<TypeArgumentBinding<KtTypeElement>?> override val arguments: List<TypeArgumentBinding<KtTypeElement>?>
get() { get() {
val psiTypeArguments = psiElement.typeArgumentsAsTypes val psiTypeArguments = psiElement.typeArgumentsAsTypes
assert(type.getAbbreviatedType() == null) { "Non-abbreviated type expected: $type" }
val isErrorBinding = run { val isErrorBinding = run {
val sizeIsEqual = psiTypeArguments.size == type.arguments.size val sizeIsEqual = psiTypeArguments.size == type.arguments.size
&& psiTypeArguments.size == type.constructor.parameters.size && psiTypeArguments.size == type.constructor.parameters.size
type.isError || !sizeIsEqual type.isError || !sizeIsEqual
} }
return psiTypeArguments.indices.map { index: Int -> return psiTypeArguments.indices.map { index: Int ->
// todo fix for List<*> // todo fix for List<*>
val jetTypeReference = psiTypeArguments[index] val jetTypeReference = psiTypeArguments[index]
val jetTypeElement = jetTypeReference?.typeElement val jetTypeElement = jetTypeReference?.typeElement ?: return@map null
if (jetTypeElement == null) return@map null
if (isErrorBinding) { if (isErrorBinding) {
val nextJetType = trace[BindingContext.TYPE, jetTypeReference] val nextJetType = trace[BindingContext.TYPE, jetTypeReference] ?: return@map null
if (nextJetType == null) return@map null
return@map TypeArgumentBindingImpl( return@map TypeArgumentBindingImpl(
TypeProjectionImpl(nextJetType), TypeProjectionImpl(nextJetType),
null, null,
ExplicitTypeBinding(trace, jetTypeElement, nextJetType) createTypeBindingFromPsi(trace, jetTypeElement, nextJetType)
) )
} }
@@ -96,17 +103,34 @@ private class ExplicitTypeBinding(
return@map TypeArgumentBindingImpl( return@map TypeArgumentBindingImpl(
typeProjection, typeProjection,
type.constructor.parameters[index], type.constructor.parameters[index],
ExplicitTypeBinding(trace, jetTypeElement, typeProjection.type) createTypeBindingFromPsi(trace, jetTypeElement, typeProjection.type)
) )
} }
} }
} }
private class AbbreviatedTypeBinding(
override val type: KotlinType,
override val psiElement: KtTypeElement
): TypeBinding<KtTypeElement> {
override val isInAbbreviation: Boolean get() = true
override val arguments: List<TypeArgumentBinding<KtTypeElement>?>
get() = type.arguments.mapIndexed { index, argument ->
TypeArgumentBindingImpl(
argument,
type.constructor.parameters[index],
AbbreviatedTypeBinding(argument.type, psiElement)
)
}
}
private class NoTypeElementBinding<out P : PsiElement>( private class NoTypeElementBinding<out P : PsiElement>(
private val trace: BindingContext, private val trace: BindingContext,
override val psiElement: P, override val psiElement: P,
override val type: KotlinType override val type: KotlinType
): TypeBinding<P> { ): TypeBinding<P> {
override val isInAbbreviation: Boolean get() = false
override val arguments: List<TypeArgumentBinding<P>?> override val arguments: List<TypeArgumentBinding<P>?>
get() { get() {
@@ -16,30 +16,23 @@
package org.jetbrains.kotlin.resolve package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure.EnrichedProjectionKind.*
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure.*
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.resolve.typeBinding.TypeBinding
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyAccessorDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.resolve.typeBinding.TypeBinding
import org.jetbrains.kotlin.resolve.typeBinding.createTypeBinding import org.jetbrains.kotlin.resolve.typeBinding.createTypeBinding
import org.jetbrains.kotlin.resolve.typeBinding.createTypeBindingForReturnType import org.jetbrains.kotlin.resolve.typeBinding.createTypeBindingForReturnType
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.Variance.* import org.jetbrains.kotlin.types.Variance.*
import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.types.checkTypePosition
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.types.getAbbreviatedType
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyAccessorDescriptorImpl
import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.types.*
class ManualVariance(val descriptor: TypeParameterDescriptor, val variance: Variance) class ManualVariance(val descriptor: TypeParameterDescriptor, val variance: Variance)
@@ -167,12 +160,9 @@ class VarianceCheckerCore(
checkTypePosition( checkTypePosition(
position, position,
{ typeParameterDescriptor, typeBinding, errorPosition -> { typeParameterDescriptor, typeBinding, errorPosition ->
diagnosticSink.report( val varianceConflictDiagnosticData = VarianceConflictDiagnosticData(containingType, typeParameterDescriptor, errorPosition)
Errors.TYPE_VARIANCE_CONFLICT.on( val diagnostic = if (typeBinding.isInAbbreviation) Errors.TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE else Errors.TYPE_VARIANCE_CONFLICT
typeBinding.psiElement, diagnosticSink.report(diagnostic.on(typeBinding.psiElement, varianceConflictDiagnosticData))
VarianceConflictDiagnosticData(containingType, typeParameterDescriptor, errorPosition)
)
)
}, },
customVariance = { it.varianceWithManual() } customVariance = { it.varianceWithManual() }
) )
@@ -0,0 +1,17 @@
// !DIAGNOSTICS: -UNUSED_TYPEALIAS_PARAMETER
interface I1<S>
interface Out<out T>
interface InvOut<T1, out T2>
typealias A1<S> = I1<S>
typealias A2<T, S> = I1<S>
typealias AOut<T> = Out<T>
typealias AInvOut<T1, T2> = InvOut<T1, T2>
typealias AInvOutTT<T> = AInvOut<T, T>
class Test1<out S> : <!TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE!>A1<S><!>
class Test2<out S> : <!TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE!>A2<Any, S><!>
class Test3<out S> : AOut<S>
class Test4<out S> : <!TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE!>AInvOut<S, S><!>
class Test5<out S> : <!TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE!>AInvOutTT<S><!>
@@ -0,0 +1,59 @@
package
public interface I1</*0*/ S> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface InvOut</*0*/ T1, /*1*/ out T2> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Out</*0*/ out T> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Test1</*0*/ out S> : A1<S> /* = I1<S> */ {
public constructor Test1</*0*/ out S>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Test2</*0*/ out S> : A2<kotlin.Any, S> /* = I1<S> */ {
public constructor Test2</*0*/ out S>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Test3</*0*/ out S> : AOut<S> /* = Out<out S> */ {
public constructor Test3</*0*/ out S>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Test4</*0*/ out S> : AInvOut<S, S> /* = InvOut<S, out S> */ {
public constructor Test4</*0*/ out S>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Test5</*0*/ out S> : AInvOutTT<S> /* = InvOut<S, out S> */ {
public constructor Test5</*0*/ out S>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public typealias A1</*0*/ S> = I1<S>
public typealias A2</*0*/ T, /*1*/ S> = I1<S>
public typealias AInvOut</*0*/ T1, /*1*/ T2> = InvOut<T1, T2>
public typealias AInvOutTT</*0*/ T> = AInvOut<T, T>
public typealias AOut</*0*/ T> = Out<T>
@@ -0,0 +1,11 @@
interface Out<out R>
interface Inv<E>
typealias A1<E> = Out<Out<E>>
typealias A2<E> = Out<Out<E>>
typealias A3<E> = Inv<Out<E>>
typealias A4<E> = Out<Inv<E>>
interface Q1<out S> : Out<A1<S>>
interface Q2<out S> : Out<A2<S>>
interface Q3<out S> : Out<<!TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE!>A3<S><!>>
interface Q4<out S> : Out<<!TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE!>A4<S><!>>
@@ -0,0 +1,41 @@
package
public interface Inv</*0*/ E> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Out</*0*/ out R> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Q1</*0*/ out S> : Out<A1<S> /* = Out<Out<out S>> */> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Q2</*0*/ out S> : Out<A2<S> /* = Out<Out<out S>> */> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Q3</*0*/ out S> : Out<A3<S> /* = Inv<Out<out S>> */> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Q4</*0*/ out S> : Out<A4<S> /* = Out<Inv<S>> */> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public typealias A1</*0*/ E> = Out<Out<E>>
public typealias A2</*0*/ E> = Out<Out<E>>
public typealias A3</*0*/ E> = Inv<Out<E>>
public typealias A4</*0*/ E> = Out<Inv<E>>
@@ -20736,6 +20736,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("kt14498.kt")
public void testKt14498() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/kt14498.kt");
doTest(fileName);
}
@TestMetadata("kt14498a.kt")
public void testKt14498a() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/kt14498a.kt");
doTest(fileName);
}
@TestMetadata("localTypeAlias.kt") @TestMetadata("localTypeAlias.kt")
public void testLocalTypeAlias() throws Exception { public void testLocalTypeAlias() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/localTypeAlias.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/localTypeAlias.kt");
@@ -38,7 +38,6 @@ fun <D : TypeHolder<D>> D.checkTypePosition(
reportError: (TypeParameterDescriptor, D, Variance) -> Unit = DO_NOTHING_3, reportError: (TypeParameterDescriptor, D, Variance) -> Unit = DO_NOTHING_3,
customVariance: (TypeParameterDescriptor) -> Variance? = { null } customVariance: (TypeParameterDescriptor) -> Variance? = { null }
): Boolean { ): Boolean {
flexibleBounds?.let { flexibleBounds?.let {
return it.first.checkTypePosition(position, reportError, customVariance) and return it.first.checkTypePosition(position, reportError, customVariance) and
it.second.checkTypePosition(position, reportError, customVariance) it.second.checkTypePosition(position, reportError, customVariance)
@@ -0,0 +1,10 @@
// !DIAGNOSTICS_NUMBER: 1
// !DIAGNOSTICS: TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE
// !MESSAGE_TYPE: TEXT
interface InvOut<T1, out T2>
typealias AInvOut<T1, T2> = InvOut<T1, T2>
typealias AInvOutTT<T> = AInvOut<T, T>
class Test<out S> : AInvOutTT<S>
@@ -0,0 +1,2 @@
<!-- typeVarianceConflictInTypeAliasExpansion1 -->
Type parameter S is declared as 'out' but occurs in 'invariant' position in abbreviated type AInvOutTT<S> /* = InvOut<S, out S> */
@@ -275,6 +275,12 @@ public class DiagnosticMessageTestGenerated extends AbstractDiagnosticMessageTes
doTest(fileName); doTest(fileName);
} }
@TestMetadata("typeVarianceConflictInTypeAliasExpansion.kt")
public void testTypeVarianceConflictInTypeAliasExpansion() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/diagnosticMessage/typeVarianceConflictInTypeAliasExpansion.kt");
doTest(fileName);
}
@TestMetadata("unsupportedFeature.kt") @TestMetadata("unsupportedFeature.kt")
public void testUnsupportedFeature() throws Exception { public void testUnsupportedFeature() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/diagnosticMessage/unsupportedFeature.kt"); String fileName = KotlinTestUtils.navigationMetadata("idea/testData/diagnosticMessage/unsupportedFeature.kt");