KT-14498: Properly check variance in expanded types.
This commit is contained in:
@@ -118,6 +118,8 @@ public interface Errors {
|
||||
DiagnosticFactory1<KtTypeProjection, ClassifierDescriptor> REDUNDANT_PROJECTION = DiagnosticFactory1.create(WARNING, VARIANCE_IN_PROJECTION);
|
||||
DiagnosticFactory1<PsiElement, VarianceConflictDiagnosticData> TYPE_VARIANCE_CONFLICT =
|
||||
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);
|
||||
DiagnosticFactory1<PsiElement, String> FINITE_BOUNDS_VIOLATION_IN_JAVA = DiagnosticFactory1.create(WARNING);
|
||||
DiagnosticFactory0<PsiElement> EXPANSIVE_INHERITANCE = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
+18
-14
@@ -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");
|
||||
|
||||
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}",
|
||||
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)
|
||||
};
|
||||
}
|
||||
});
|
||||
varianceConflictDataRenderer);
|
||||
MAP.put(TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE, "Type parameter {0} is declared as ''{1}'' but occurs in ''{2}'' position in abbreviated type {3}",
|
||||
varianceConflictDataRenderer);
|
||||
|
||||
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);
|
||||
|
||||
@@ -18,9 +18,7 @@ package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
|
||||
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.AnnotationsImpl
|
||||
import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.types.*
|
||||
|
||||
@@ -28,20 +28,27 @@ import org.jetbrains.kotlin.types.*
|
||||
|
||||
interface TypeBinding<out P : PsiElement> : TypeHolder<TypeBinding<P>> {
|
||||
val psiElement: P
|
||||
val isInAbbreviation: Boolean
|
||||
override val arguments: List<TypeArgumentBinding<P>?>
|
||||
}
|
||||
|
||||
interface TypeArgumentBinding<out P: PsiElement> : TypeHolderArgument<TypeBinding<P>>
|
||||
|
||||
fun KtTypeReference.createTypeBinding(trace: BindingContext): TypeBinding<KtTypeElement>? {
|
||||
val jetType = trace[BindingContext.TYPE, this]
|
||||
val type = trace[BindingContext.TYPE, this]
|
||||
val psiElement = typeElement
|
||||
if (jetType == null || psiElement == null) {
|
||||
return null
|
||||
}
|
||||
else {
|
||||
return ExplicitTypeBinding(trace, psiElement, jetType)
|
||||
}
|
||||
return if (type == null || psiElement == null)
|
||||
null
|
||||
else
|
||||
createTypeBindingFromPsi(trace, psiElement, type)
|
||||
}
|
||||
|
||||
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>? {
|
||||
@@ -65,30 +72,30 @@ private class ExplicitTypeBinding(
|
||||
override val psiElement: KtTypeElement,
|
||||
override val type: KotlinType
|
||||
) : TypeBinding<KtTypeElement> {
|
||||
override val isInAbbreviation: Boolean get() = false
|
||||
|
||||
override val arguments: List<TypeArgumentBinding<KtTypeElement>?>
|
||||
get() {
|
||||
val psiTypeArguments = psiElement.typeArgumentsAsTypes
|
||||
assert(type.getAbbreviatedType() == null) { "Non-abbreviated type expected: $type" }
|
||||
val isErrorBinding = run {
|
||||
val sizeIsEqual = psiTypeArguments.size == type.arguments.size
|
||||
&& psiTypeArguments.size == type.constructor.parameters.size
|
||||
type.isError || !sizeIsEqual
|
||||
}
|
||||
|
||||
return psiTypeArguments.indices.map { index: Int ->
|
||||
// todo fix for List<*>
|
||||
val jetTypeReference = psiTypeArguments[index]
|
||||
val jetTypeElement = jetTypeReference?.typeElement
|
||||
if (jetTypeElement == null) return@map null
|
||||
return psiTypeArguments.indices.map { index: Int ->
|
||||
// todo fix for List<*>
|
||||
val jetTypeReference = psiTypeArguments[index]
|
||||
val jetTypeElement = jetTypeReference?.typeElement ?: return@map null
|
||||
|
||||
if (isErrorBinding) {
|
||||
val nextJetType = trace[BindingContext.TYPE, jetTypeReference]
|
||||
if (nextJetType == null) return@map null
|
||||
if (isErrorBinding) {
|
||||
val nextJetType = trace[BindingContext.TYPE, jetTypeReference] ?: return@map null
|
||||
|
||||
return@map TypeArgumentBindingImpl(
|
||||
TypeProjectionImpl(nextJetType),
|
||||
null,
|
||||
ExplicitTypeBinding(trace, jetTypeElement, nextJetType)
|
||||
createTypeBindingFromPsi(trace, jetTypeElement, nextJetType)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -96,17 +103,34 @@ private class ExplicitTypeBinding(
|
||||
return@map TypeArgumentBindingImpl(
|
||||
typeProjection,
|
||||
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 val trace: BindingContext,
|
||||
override val psiElement: P,
|
||||
override val type: KotlinType
|
||||
): TypeBinding<P> {
|
||||
override val isInAbbreviation: Boolean get() = false
|
||||
|
||||
override val arguments: List<TypeArgumentBinding<P>?>
|
||||
get() {
|
||||
|
||||
@@ -16,30 +16,23 @@
|
||||
|
||||
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 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.createTypeBindingForReturnType
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.Variance.*
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
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.*
|
||||
import org.jetbrains.kotlin.types.checkTypePosition
|
||||
import org.jetbrains.kotlin.types.getAbbreviatedType
|
||||
|
||||
class ManualVariance(val descriptor: TypeParameterDescriptor, val variance: Variance)
|
||||
|
||||
@@ -167,12 +160,9 @@ class VarianceCheckerCore(
|
||||
checkTypePosition(
|
||||
position,
|
||||
{ typeParameterDescriptor, typeBinding, errorPosition ->
|
||||
diagnosticSink.report(
|
||||
Errors.TYPE_VARIANCE_CONFLICT.on(
|
||||
typeBinding.psiElement,
|
||||
VarianceConflictDiagnosticData(containingType, typeParameterDescriptor, errorPosition)
|
||||
)
|
||||
)
|
||||
val varianceConflictDiagnosticData = VarianceConflictDiagnosticData(containingType, typeParameterDescriptor, errorPosition)
|
||||
val diagnostic = if (typeBinding.isInAbbreviation) Errors.TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE else Errors.TYPE_VARIANCE_CONFLICT
|
||||
diagnosticSink.report(diagnostic.on(typeBinding.psiElement, varianceConflictDiagnosticData))
|
||||
},
|
||||
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);
|
||||
}
|
||||
|
||||
@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")
|
||||
public void testLocalTypeAlias() throws Exception {
|
||||
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,
|
||||
customVariance: (TypeParameterDescriptor) -> Variance? = { null }
|
||||
): Boolean {
|
||||
|
||||
flexibleBounds?.let {
|
||||
return it.first.checkTypePosition(position, reportError, customVariance) and
|
||||
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);
|
||||
}
|
||||
|
||||
@TestMetadata("typeVarianceConflictInTypeAliasExpansion.kt")
|
||||
public void testTypeVarianceConflictInTypeAliasExpansion() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/diagnosticMessage/typeVarianceConflictInTypeAliasExpansion.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("unsupportedFeature.kt")
|
||||
public void testUnsupportedFeature() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/diagnosticMessage/unsupportedFeature.kt");
|
||||
|
||||
Reference in New Issue
Block a user