diff --git a/compiler/testData/diagnostics/tests/subtyping/localAnonymousObjects.kt b/compiler/testData/diagnostics/tests/subtyping/localAnonymousObjects.kt new file mode 100644 index 00000000000..50474190430 --- /dev/null +++ b/compiler/testData/diagnostics/tests/subtyping/localAnonymousObjects.kt @@ -0,0 +1,5 @@ +// !DIAGNOSTICS: -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE +fun test() { + var x = object {} + x = object {} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/subtyping/localClasses.kt b/compiler/testData/diagnostics/tests/subtyping/localClasses.kt new file mode 100644 index 00000000000..cba517113e2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/subtyping/localClasses.kt @@ -0,0 +1,22 @@ +// !DIAGNOSTICS: -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER + +package p + +fun run(f: () -> T): T { + return f() +} + +fun foo(a: Int) = run { + class A + A() +} + +fun foo() = run { + class A + A() +} + +fun test() { + var x = foo(1) + x = foo() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/subtyping/memberAnonymousObjects.kt b/compiler/testData/diagnostics/tests/subtyping/memberAnonymousObjects.kt new file mode 100644 index 00000000000..63539f6e7aa --- /dev/null +++ b/compiler/testData/diagnostics/tests/subtyping/memberAnonymousObjects.kt @@ -0,0 +1,6 @@ +class Test { + private var x = object {}; + { + x = object {} + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/subtyping/nestedIntoLocalClasses.kt b/compiler/testData/diagnostics/tests/subtyping/nestedIntoLocalClasses.kt new file mode 100644 index 00000000000..29a83e8f77d --- /dev/null +++ b/compiler/testData/diagnostics/tests/subtyping/nestedIntoLocalClasses.kt @@ -0,0 +1,26 @@ +// !DIAGNOSTICS: -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER + +package p + +fun run(f: () -> T): T { + return f() +} + +fun foo(a: Int) = run { + object { + inner class A + fun foo() = A() + }.foo() +} + +fun foo() = run { + object { + inner class A + fun foo() = A() + }.foo() +} + +fun test() { + var x = foo(1) + x = foo() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/subtyping/nestedLocalClasses.kt b/compiler/testData/diagnostics/tests/subtyping/nestedLocalClasses.kt new file mode 100644 index 00000000000..61f73e2d348 --- /dev/null +++ b/compiler/testData/diagnostics/tests/subtyping/nestedLocalClasses.kt @@ -0,0 +1,26 @@ +// !DIAGNOSTICS: -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER + +package p + +fun run(f: () -> T): T { + return f() +} + +fun foo(a: Int) = run { + class A { + inner class B + } + A().B() +} + +fun foo() = run { + class A { + inner class B + } + A().B() +} + +fun test() { + var x = foo(1) + x = foo() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/subtyping/topLevelAnonymousObjects.kt b/compiler/testData/diagnostics/tests/subtyping/topLevelAnonymousObjects.kt new file mode 100644 index 00000000000..ffb3be8356c --- /dev/null +++ b/compiler/testData/diagnostics/tests/subtyping/topLevelAnonymousObjects.kt @@ -0,0 +1,6 @@ +private var x = object {} + +fun test() { + // No error, because the type of x is normalized to Any + x = object {} +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 3b1ba774e8d..efb95e3e568 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -6917,6 +6917,36 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest("compiler/testData/diagnostics/tests/subtyping/kt-1457.kt"); } + @TestMetadata("localAnonymousObjects.kt") + public void testLocalAnonymousObjects() throws Exception { + doTest("compiler/testData/diagnostics/tests/subtyping/localAnonymousObjects.kt"); + } + + @TestMetadata("localClasses.kt") + public void testLocalClasses() throws Exception { + doTest("compiler/testData/diagnostics/tests/subtyping/localClasses.kt"); + } + + @TestMetadata("memberAnonymousObjects.kt") + public void testMemberAnonymousObjects() throws Exception { + doTest("compiler/testData/diagnostics/tests/subtyping/memberAnonymousObjects.kt"); + } + + @TestMetadata("nestedIntoLocalClasses.kt") + public void testNestedIntoLocalClasses() throws Exception { + doTest("compiler/testData/diagnostics/tests/subtyping/nestedIntoLocalClasses.kt"); + } + + @TestMetadata("nestedLocalClasses.kt") + public void testNestedLocalClasses() throws Exception { + doTest("compiler/testData/diagnostics/tests/subtyping/nestedLocalClasses.kt"); + } + + @TestMetadata("topLevelAnonymousObjects.kt") + public void testTopLevelAnonymousObjects() throws Exception { + doTest("compiler/testData/diagnostics/tests/subtyping/topLevelAnonymousObjects.kt"); + } + } @TestMetadata("compiler/testData/diagnostics/tests/suppress") diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 9205806bb2c..304d417863b 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -101,6 +101,20 @@ public class DescriptorUtils { return false; } + /** + * descriptor may be local itself or have a local ancestor + */ + public static boolean isLocal(@NotNull DeclarationDescriptor descriptor) { + DeclarationDescriptor current = descriptor; + while (current instanceof MemberDescriptor) { + if (isAnonymousObject(current) || ((DeclarationDescriptorWithVisibility) current).getVisibility() == Visibilities.LOCAL) { + return true; + } + current = current.getContainingDeclaration(); + } + return false; + } + @NotNull public static FqNameUnsafe getFqName(@NotNull DeclarationDescriptor descriptor) { FqName safe = getFqNameSafeIfPossible(descriptor); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractClassTypeConstructor.java b/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractClassTypeConstructor.java index 6bb5ffe86e0..2def3268254 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractClassTypeConstructor.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractClassTypeConstructor.java @@ -41,8 +41,8 @@ public abstract class AbstractClassTypeConstructor implements TypeConstructor { ClassifierDescriptor otherDescriptor = ((TypeConstructor) other).getDeclarationDescriptor(); // All error types have the same descriptor - if (myDescriptor != null && ErrorUtils.isError(myDescriptor) - || otherDescriptor != null && ErrorUtils.isError(otherDescriptor)) { + if (myDescriptor != null && !hasMeaningfulFqName(myDescriptor) || + otherDescriptor != null && !hasMeaningfulFqName(otherDescriptor)) { return me == other; } @@ -65,4 +65,9 @@ public abstract class AbstractClassTypeConstructor implements TypeConstructor { } return System.identityHashCode(me); } + + private static boolean hasMeaningfulFqName(@NotNull ClassifierDescriptor descriptor) { + return !ErrorUtils.isError(descriptor) && + !DescriptorUtils.isLocal(descriptor); + } }