diff --git a/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/functionGenericsInParamsReturnFooT.kt b/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/functionGenericsInParamsReturnFooT.kt new file mode 100644 index 00000000000..332423ddc53 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/functionGenericsInParamsReturnFooT.kt @@ -0,0 +1,44 @@ +// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL + +// MODULE: m1 +// FILE: a.kt +package p + +public trait Foo + +public trait B { + public fun foo(a: T): Foo +} + +// MODULE: m2(m1) +// FILE: b.kt +package p + +public trait C : B { + override fun foo(a: T): Foo + +} + +// MODULE: m3 +// FILE: b.kt +package p + +public trait Foo + +public trait B { + public fun foo(a: T): Foo +} + +// MODULE: m4(m3, m2) +// FILE: c.kt +import p.* + +fun test(b: B?) { + if (b !is C) return + b?.foo("") +} + +fun test1(b: B?) { + if (b !is C) return + b?.foo("") +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/functionGenericsInParamsReturnT.kt b/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/functionGenericsInParamsReturnT.kt new file mode 100644 index 00000000000..6ba80e80454 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/functionGenericsInParamsReturnT.kt @@ -0,0 +1,40 @@ +// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL + +// MODULE: m1 +// FILE: a.kt +package p + +public trait B { + public fun foo(a: T): T +} + +// MODULE: m2(m1) +// FILE: b.kt +package p + +public trait C : B { + override fun foo(a: T): T + +} + +// MODULE: m3 +// FILE: b.kt +package p + +public trait B { + public fun foo(a: T): T +} + +// MODULE: m4(m3, m2) +// FILE: c.kt +import p.* + +fun test(b: B?) { + if (b !is C) return + b?.foo("") +} + +fun test1(b: B?) { + if (b !is C) return + b?.foo("") +} \ 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 efb95e3e568..4a50cdba1b6 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -4847,6 +4847,16 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/functionGenericsInParamsNotIs.kt"); } + @TestMetadata("functionGenericsInParamsReturnFooT.kt") + public void testFunctionGenericsInParamsReturnFooT() throws Exception { + doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/functionGenericsInParamsReturnFooT.kt"); + } + + @TestMetadata("functionGenericsInParamsReturnT.kt") + public void testFunctionGenericsInParamsReturnT() throws Exception { + doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/functionGenericsInParamsReturnT.kt"); + } + @TestMetadata("noGenericsInParams.kt") public void testNoGenericsInParams() throws Exception { doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/noGenericsInParams.kt"); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java index 7bbff95999a..74d5a208bc6 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java @@ -321,7 +321,7 @@ public class ConstraintSystemImpl implements ConstraintSystem { public boolean assertEqualTypeConstructors( @NotNull TypeConstructor a, @NotNull TypeConstructor b ) { - throw new IllegalStateException("'assertEqualTypeConstructors' shouldn't be invoked inside 'isSubtypeOf'"); + return a.equals(b); } @Override diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/checker/JetTypeChecker.java b/core/descriptors/src/org/jetbrains/jet/lang/types/checker/JetTypeChecker.java index 28e7d5e2183..9008697b8df 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/checker/JetTypeChecker.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/checker/JetTypeChecker.java @@ -57,27 +57,4 @@ public class JetTypeChecker { } private static final TypeCheckingProcedure TYPE_CHECKER = new TypeCheckingProcedure(new TypeCheckerTypingConstraints()); - - private static class TypeCheckerTypingConstraints implements TypingConstraints { - @Override - public boolean assertEqualTypes(@NotNull JetType a, @NotNull JetType b, @NotNull TypeCheckingProcedure typeCheckingProcedure) { - return typeCheckingProcedure.equalTypes(a, b); -// return TypeUtils.equalTypes(a, b); - } - - @Override - public boolean assertEqualTypeConstructors(@NotNull TypeConstructor a, @NotNull TypeConstructor b) { - return a.equals(b); - } - - @Override - public boolean assertSubtype(@NotNull JetType subtype, @NotNull JetType supertype, @NotNull TypeCheckingProcedure typeCheckingProcedure) { - return typeCheckingProcedure.isSubtypeOf(subtype, supertype); - } - - @Override - public boolean noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype) { - return false; // type checking fails - } - } } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckerTypingConstraints.java b/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckerTypingConstraints.java new file mode 100644 index 00000000000..498f919eb36 --- /dev/null +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckerTypingConstraints.java @@ -0,0 +1,43 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.types.checker; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeConstructor; + +class TypeCheckerTypingConstraints implements TypingConstraints { + @Override + public boolean assertEqualTypes(@NotNull JetType a, @NotNull JetType b, @NotNull TypeCheckingProcedure typeCheckingProcedure) { + return typeCheckingProcedure.equalTypes(a, b); + } + + @Override + public boolean assertEqualTypeConstructors(@NotNull TypeConstructor a, @NotNull TypeConstructor b) { + return a.equals(b); + } + + @Override + public boolean assertSubtype(@NotNull JetType subtype, @NotNull JetType supertype, @NotNull TypeCheckingProcedure typeCheckingProcedure) { + return typeCheckingProcedure.isSubtypeOf(subtype, supertype); + } + + @Override + public boolean noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype) { + return false; // type checking fails + } +} diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java b/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java index cbeb22a6d00..cacaf3edd7b 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java @@ -32,12 +32,19 @@ public class TypeCheckingProcedure { // as the second parameter, applying the substitution of type arguments to it @Nullable public static JetType findCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype) { + return findCorrespondingSupertype(subtype, supertype, new TypeCheckerTypingConstraints()); + } + + // This method returns the supertype of the first parameter that has the same constructor + // as the second parameter, applying the substitution of type arguments to it + @Nullable + public static JetType findCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype, @NotNull TypingConstraints typingConstraints) { TypeConstructor constructor = subtype.getConstructor(); - if (constructor.equals(supertype.getConstructor())) { + if (typingConstraints.assertEqualTypeConstructors(constructor, supertype.getConstructor())) { return subtype; } for (JetType immediateSupertype : constructor.getSupertypes()) { - JetType correspondingSupertype = findCorrespondingSupertype(immediateSupertype, supertype); + JetType correspondingSupertype = findCorrespondingSupertype(immediateSupertype, supertype, typingConstraints); if (correspondingSupertype != null) { return TypeSubstitutor.create(subtype).safeSubstitute(correspondingSupertype, Variance.INVARIANT); } @@ -167,7 +174,7 @@ public class TypeCheckingProcedure { if (KotlinBuiltIns.getInstance().isNothingOrNullableNothing(subtype)) { return true; } - @Nullable JetType closestSupertype = findCorrespondingSupertype(subtype, supertype); + @Nullable JetType closestSupertype = findCorrespondingSupertype(subtype, supertype, constraints); if (closestSupertype == null) { return constraints.noCorrespondingSupertype(subtype, supertype); // if this returns true, there still isn't any supertype to continue with } @@ -177,7 +184,7 @@ public class TypeCheckingProcedure { private boolean checkSubtypeForTheSameConstructor(@NotNull JetType subtype, @NotNull JetType supertype) { TypeConstructor constructor = subtype.getConstructor(); - assert constructor.equals(supertype.getConstructor()) : constructor + " is not " + supertype.getConstructor(); + assert constraints.assertEqualTypeConstructors(constructor, supertype.getConstructor()) : constructor + " is not " + supertype.getConstructor(); List subArguments = subtype.getArguments(); List superArguments = supertype.getArguments();