Intersection types are no more allowed in signatures #KT-10244 Fixed
This commit is contained in:
@@ -404,10 +404,11 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
TypeConstructor constructor = jetType.getConstructor();
|
||||
DeclarationDescriptor descriptor = constructor.getDeclarationDescriptor();
|
||||
if (constructor instanceof IntersectionTypeConstructor) {
|
||||
jetType = CommonSupertypes.commonSupertype(new ArrayList<KotlinType>(constructor.getSupertypes()));
|
||||
constructor = jetType.getConstructor();
|
||||
}
|
||||
DeclarationDescriptor descriptor = constructor.getDeclarationDescriptor();
|
||||
|
||||
if (descriptor == null) {
|
||||
throw new UnsupportedOperationException("no descriptor for type constructor of " + jetType);
|
||||
|
||||
@@ -727,6 +727,7 @@ public interface Errors {
|
||||
DiagnosticFactory2<KtElement, KotlinType, KotlinType> INCOMPATIBLE_TYPES = DiagnosticFactory2.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<PsiElement> IMPLICIT_NOTHING_RETURN_TYPE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, KotlinType> IMPLICIT_INTERSECTION_TYPE = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
// Context tracking
|
||||
|
||||
|
||||
+1
@@ -527,6 +527,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(TYPE_MISMATCH_IN_CONDITION, "Condition must be of type kotlin.Boolean, but is of type {0}", RENDER_TYPE);
|
||||
MAP.put(INCOMPATIBLE_TYPES, "Incompatible types: {0} and {1}", RENDER_TYPE, RENDER_TYPE);
|
||||
MAP.put(IMPLICIT_NOTHING_RETURN_TYPE, "''Nothing'' return type needs to be specified explicitly");
|
||||
MAP.put(IMPLICIT_INTERSECTION_TYPE, "Inferred type {0} is an intersection, please specify the required type explicitly", RENDER_TYPE);
|
||||
MAP.put(EXPECTED_CONDITION, "Expected condition of type kotlin.Boolean");
|
||||
|
||||
MAP.put(CANNOT_CHECK_FOR_ERASED, "Cannot check for instance of erased type: {0}", RENDER_TYPE);
|
||||
|
||||
@@ -95,6 +95,7 @@ public object Renderers {
|
||||
|
||||
public val RENDER_CLASS_OR_OBJECT_NAME: Renderer<ClassDescriptor> = Renderer { it.renderKindWithName() }
|
||||
|
||||
@JvmField
|
||||
public val RENDER_TYPE: Renderer<KotlinType> = Renderer { DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(it) }
|
||||
|
||||
public val RENDER_POSITION_VARIANCE: Renderer<Variance> = Renderer {
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.resolve.BindingContext.TYPE
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.TYPE_PARAMETER
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractMembers
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveOpenMembers
|
||||
import org.jetbrains.kotlin.types.IntersectionTypeConstructor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.SubstitutionUtils
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
@@ -434,6 +435,13 @@ class DeclarationsChecker(
|
||||
checkTypeParameterConstraints(property)
|
||||
checkPropertyExposedType(property, propertyDescriptor)
|
||||
checkPropertyTypeParametersAreUsedInReceiverType(propertyDescriptor)
|
||||
propertyDescriptor.returnType?.let {
|
||||
if (property.typeReference == null) {
|
||||
if (it.constructor is IntersectionTypeConstructor) {
|
||||
trace.report(IMPLICIT_INTERSECTION_TYPE.on(property.nameIdentifier ?: property, it))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkPropertyTypeParametersAreUsedInReceiverType(descriptor: PropertyDescriptor) {
|
||||
@@ -649,8 +657,13 @@ class DeclarationsChecker(
|
||||
trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor))
|
||||
}
|
||||
functionDescriptor.returnType?.let {
|
||||
if (it.isNothing() && !function.hasDeclaredReturnType()) {
|
||||
trace.report(IMPLICIT_NOTHING_RETURN_TYPE.on(nameIdentifier ?: function))
|
||||
if (!function.hasDeclaredReturnType()) {
|
||||
if (it.isNothing()) {
|
||||
trace.report(IMPLICIT_NOTHING_RETURN_TYPE.on(nameIdentifier ?: function))
|
||||
}
|
||||
if (it.constructor is IntersectionTypeConstructor) {
|
||||
trace.report(IMPLICIT_INTERSECTION_TYPE.on(nameIdentifier ?: function, it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// See KT-10244: no intersection types in signatures
|
||||
open class B
|
||||
interface A
|
||||
interface C
|
||||
|
||||
// Error!
|
||||
fun <!IMPLICIT_INTERSECTION_TYPE!>foo<!>(b: B) = if (b is A && b is C) b else null
|
||||
|
||||
// Ok: given explicitly
|
||||
fun gav(b: B): A? = if (b is A && b is C) <!DEBUG_INFO_SMARTCAST!>b<!> else null
|
||||
|
||||
class My(b: B) {
|
||||
// Error!
|
||||
val <!IMPLICIT_INTERSECTION_TYPE!>x<!> = if (b is A && b is C) b else null
|
||||
// Ok: given explicitly
|
||||
val y: C? = if (b is A && b is C) <!DEBUG_INFO_SMARTCAST!>b<!> else null
|
||||
}
|
||||
|
||||
fun bar(b: B): String {
|
||||
// Ok: local variable
|
||||
val tmp = if (b is A && b is C) b else null
|
||||
return tmp.toString()
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package
|
||||
|
||||
public fun bar(/*0*/ b: B): kotlin.String
|
||||
public fun foo(/*0*/ b: B): {C & A & B}?
|
||||
public fun gav(/*0*/ b: B): A?
|
||||
|
||||
public interface A {
|
||||
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 open class B {
|
||||
public constructor B()
|
||||
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 C {
|
||||
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 My {
|
||||
public constructor My(/*0*/ b: B)
|
||||
public final val x: {C & A & B}?
|
||||
public final val y: C?
|
||||
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
|
||||
}
|
||||
@@ -289,6 +289,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("implicitIntersection.kt")
|
||||
public void testImplicitIntersection() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/implicitIntersection.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("implicitNothing.kt")
|
||||
public void testImplicitNothing() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/implicitNothing.kt");
|
||||
|
||||
Reference in New Issue
Block a user