Do not compare local classes by FqNames

This commit is contained in:
Andrey Breslav
2014-05-30 12:45:05 +04:00
parent 93031c1245
commit e50a17e668
9 changed files with 142 additions and 2 deletions
@@ -0,0 +1,5 @@
// !DIAGNOSTICS: -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE
fun test() {
var x = object {}
x = <!TYPE_MISMATCH!>object<!> {}
}
@@ -0,0 +1,22 @@
// !DIAGNOSTICS: -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER
package p
fun run<T>(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 = <!TYPE_MISMATCH!>foo()<!>
}
@@ -0,0 +1,6 @@
class Test {
private var x = object {};
{
x = <!TYPE_MISMATCH!>object<!> {}
}
}
@@ -0,0 +1,26 @@
// !DIAGNOSTICS: -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER
package p
fun run<T>(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 = <!TYPE_MISMATCH!>foo()<!>
}
@@ -0,0 +1,26 @@
// !DIAGNOSTICS: -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER
package p
fun run<T>(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 = <!TYPE_MISMATCH!>foo()<!>
}
@@ -0,0 +1,6 @@
private var x = object {}
fun test() {
// No error, because the type of x is normalized to Any
x = object {}
}
@@ -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")
@@ -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);
@@ -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);
}
}