diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java index ff231209d09..ace7885a16f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -1470,14 +1470,31 @@ public class DescriptorResolver { @NotNull BindingTrace trace, @NotNull PsiElement reportErrorsOn, @NotNull ClassDescriptor target + ) { + return checkHasOuterClassInstance(scope, trace, reportErrorsOn, target, true); + } + + public static boolean checkHasOuterClassInstance( + @NotNull JetScope scope, + @NotNull BindingTrace trace, + @NotNull PsiElement reportErrorsOn, + @NotNull ClassDescriptor target, + boolean doSuperClassCheck ) { DeclarationDescriptor descriptor = getContainingClass(scope); + while (descriptor != null) { if (descriptor instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) descriptor; - if (isSubclass(classDescriptor, target)) { + + if (classDescriptor == target) { return true; } + + if (doSuperClassCheck && isSubclass(classDescriptor, target)) { + return true; + } + if (isStaticNestedClass(classDescriptor)) { trace.report(INACCESSIBLE_OUTER_CLASS_EXPRESSION.on(reportErrorsOn, classDescriptor)); return false; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java index 8c2e1ae7c59..bf001ecf9bd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -123,7 +123,8 @@ public class TypeResolver { DeclarationDescriptor containing = typeParameterDescriptor.getContainingDeclaration(); if (containing instanceof ClassDescriptor) { - DescriptorResolver.checkHasOuterClassInstance(scope, trace, referenceExpression, (ClassDescriptor) containing); + // Type parameter can't be inherited from member of parent class, so we can skip subclass check + DescriptorResolver.checkHasOuterClassInstance(scope, trace, referenceExpression, (ClassDescriptor) containing, false); } } else if (classifierDescriptor instanceof ClassDescriptor) { diff --git a/compiler/testData/diagnostics/tests/inner/deepInnerClass.kt b/compiler/testData/diagnostics/tests/inner/deepInnerClass.kt new file mode 100644 index 00000000000..2ce0546c66b --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/deepInnerClass.kt @@ -0,0 +1,14 @@ +trait P + +class A { + class B { + fun test() { + class C() : PT> { + class object : P<W, T> { + } + + inner class D : PT> + } + } + } +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index c32e00daae0..6da64048a60 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -3017,6 +3017,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/inner/constructorAccess.kt"); } + @TestMetadata("deepInnerClass.kt") + public void testDeepInnerClass() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/deepInnerClass.kt"); + } + @TestMetadata("enumEntries.kt") public void testEnumEntries() throws Exception { doTest("compiler/testData/diagnostics/tests/inner/enumEntries.kt");