From de37cb8f40183b7a2e2c2944f9fe8bc02b8e8e5d Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 30 Nov 2015 12:05:23 +0300 Subject: [PATCH] Generic types may not extend kotlin.Throwable #KT-9816 Fixed --- .../jetbrains/kotlin/diagnostics/Errors.java | 1 + .../rendering/DefaultErrorMessages.java | 1 + .../kotlin/resolve/BodyResolver.java | 10 +++++++- .../tests/controlStructures/catchGenerics.kt | 12 +++------ .../tests/controlStructures/catchGenerics.txt | 25 +++++++++++++++++-- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index abfa420c94b..edfc2561b61 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -107,6 +107,7 @@ public interface Errors { DiagnosticFactory0 TYPE_ARGUMENTS_FOR_OUTER_CLASS_WHEN_NESTED_REFERENCED = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 REIFIED_TYPE_IN_CATCH_CLAUSE = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 GENERIC_THROWABLE_SUBCLASS = DiagnosticFactory0.create(ERROR); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index eb8a35ce1da..93da447ef41 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -517,6 +517,7 @@ public class DefaultErrorMessages { MAP.put(TYPE_ARGUMENTS_FOR_OUTER_CLASS_WHEN_NESTED_REFERENCED, "Type arguments for outer class are redundant when nested class is referenced"); MAP.put(REIFIED_TYPE_IN_CATCH_CLAUSE, "Reified type is forbidden for catch parameter"); + MAP.put(GENERIC_THROWABLE_SUBCLASS, "Subclass of 'kotlin.Throwable' may not have type parameters"); MAP.put(TYPE_MISMATCH_IN_FOR_LOOP, "The loop iterates over values of type {0} but the parameter is declared to be {1}", RENDER_TYPE, RENDER_TYPE); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java index eee7a4bdf8c..3cb6e6cb2f1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java @@ -67,6 +67,7 @@ public class BodyResolver { @NotNull private final FunctionAnalyzerExtension functionAnalyzerExtension; @NotNull private final ValueParameterResolver valueParameterResolver; @NotNull private final BodyResolveCache bodyResolveCache; + @NotNull private final KotlinBuiltIns builtIns; public BodyResolver( @NotNull AnnotationResolver annotationResolver, @@ -79,7 +80,8 @@ public class BodyResolver { @NotNull FunctionAnalyzerExtension functionAnalyzerExtension, @NotNull BindingTrace trace, @NotNull ValueParameterResolver valueParameterResolver, - @NotNull AnnotationChecker annotationChecker + @NotNull AnnotationChecker annotationChecker, + @NotNull KotlinBuiltIns builtIns ) { this.annotationResolver = annotationResolver; this.bodyResolveCache = bodyResolveCache; @@ -92,6 +94,7 @@ public class BodyResolver { this.annotationChecker = annotationChecker; this.trace = new ObservableBindingTrace(trace); this.valueParameterResolver = valueParameterResolver; + this.builtIns = builtIns; } private void resolveBehaviorDeclarationBodies(@NotNull BodiesResolveContext c) { @@ -457,6 +460,11 @@ public class BodyResolver { trace.report(DATA_CLASS_CANNOT_HAVE_CLASS_SUPERTYPES.on(typeReference)); addSupertype = false; } + else if (DescriptorUtils.isSubclass(classDescriptor, builtIns.getThrowable()) && + !supertypeOwner.getDeclaredTypeParameters().isEmpty()) { + trace.report(GENERIC_THROWABLE_SUBCLASS.on(jetClass.getTypeParameterList())); + addSupertype = false; + } if (classAppeared) { trace.report(MANY_CLASSES_IN_SUPERTYPE_LIST.on(typeReference)); diff --git a/compiler/testData/diagnostics/tests/controlStructures/catchGenerics.kt b/compiler/testData/diagnostics/tests/controlStructures/catchGenerics.kt index 8ff699f12f2..c55ab91ea5f 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/catchGenerics.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/catchGenerics.kt @@ -1,15 +1,11 @@ // See KT-9816, KT-9742 // Not allowed in Java -open class ZException(val p: T) : Exception() +class ZException(val p: T) : Exception() -fun foo(): String { - try { - throw ZException(11) - } catch (e: ZException) { - return e.p - } -} +class YException(val p: T): java.lang.RuntimeException() + +class XException(val p: T): Throwable() fun bar() { try { diff --git a/compiler/testData/diagnostics/tests/controlStructures/catchGenerics.txt b/compiler/testData/diagnostics/tests/controlStructures/catchGenerics.txt index fa5e2c403df..64af50fe226 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/catchGenerics.txt +++ b/compiler/testData/diagnostics/tests/controlStructures/catchGenerics.txt @@ -1,10 +1,31 @@ package public fun bar(): kotlin.Unit -public fun foo(): kotlin.String public inline fun tryCatch(/*0*/ lazy: () -> R, /*1*/ failure: (E) -> R): R -public open class ZException : java.lang.Exception { +public final class XException : kotlin.Throwable { + public constructor XException(/*0*/ p: T) + public final override /*1*/ /*fake_override*/ val cause: kotlin.Throwable? + public final override /*1*/ /*fake_override*/ val message: kotlin.String? + public final val p: 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 final override /*1*/ /*fake_override*/ fun printStackTrace(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class YException : java.lang.RuntimeException { + public constructor YException(/*0*/ p: T) + public final override /*1*/ /*fake_override*/ val cause: kotlin.Throwable? + public final override /*1*/ /*fake_override*/ val message: kotlin.String? + public final val p: 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 final override /*1*/ /*fake_override*/ fun printStackTrace(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class ZException : java.lang.Exception { public constructor ZException(/*0*/ p: T) public final override /*1*/ /*fake_override*/ val cause: kotlin.Throwable? public final override /*1*/ /*fake_override*/ val message: kotlin.String?