diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/CommonSupertypes.java b/compiler/frontend/src/org/jetbrains/kotlin/types/CommonSupertypes.java index e976b169711..f26c0ae4179 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/CommonSupertypes.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/CommonSupertypes.java @@ -100,7 +100,7 @@ public class CommonSupertypes { @NotNull private static SimpleType commonSuperTypeForInflexible(@NotNull Collection types, int recursionDepth, int maxDepth) { assert !types.isEmpty(); - Collection typeSet = new HashSet<>(types); + Collection typeSet = new LinkedHashSet<>(types); // If any of the types is nullable, the result must be nullable // This also removed Nothing and Nothing? because they are subtypes of everything else @@ -132,7 +132,7 @@ public class CommonSupertypes { // constructor of the supertype -> all of its instantiations occurring as supertypes Map> commonSupertypes = computeCommonRawSupertypes(typeSet); while (commonSupertypes.size() > 1) { - Set merge = new HashSet<>(); + Set merge = new LinkedHashSet<>(); for (Set supertypes : commonSupertypes.values()) { merge.addAll(supertypes); } @@ -244,7 +244,7 @@ public class CommonSupertypes { List parameters = constructor.getParameters(); List newProjections = new ArrayList<>(parameters.size()); for (TypeParameterDescriptor parameterDescriptor : parameters) { - Set typeProjections = new HashSet<>(); + Set typeProjections = new LinkedHashSet<>(); for (KotlinType type : types) { typeProjections.add(type.getArguments().get(parameterDescriptor.getIndex())); } @@ -287,8 +287,8 @@ public class CommonSupertypes { return TypeUtils.makeStarProjection(parameterDescriptor); } - Set ins = new HashSet<>(); - Set outs = new HashSet<>(); + Set ins = new LinkedHashSet<>(); + Set outs = new LinkedHashSet<>(); Variance variance = parameterDescriptor.getVariance(); switch (variance) { diff --git a/compiler/testData/codegen/bytecodeText/nullCheckOptimization/deterministicNotNullChecks.kt b/compiler/testData/codegen/bytecodeText/nullCheckOptimization/deterministicNotNullChecks.kt new file mode 100644 index 00000000000..3f3edaca1e8 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/nullCheckOptimization/deterministicNotNullChecks.kt @@ -0,0 +1,109 @@ +// FILE: test/DeclarationDescriptor.java + +package test; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +public interface DeclarationDescriptor { + @NotNull + DeclarationDescriptor getOriginal(); + + @Nullable + DeclarationDescriptor getContainingDeclaration(); +} + +// FILE: test/DeclarationDescriptorWithVisibility.java +package test; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +public interface DeclarationDescriptorWithVisibility extends DeclarationDescriptor { +} + +// FILE: test/DeclarationDescriptorWithSource.java +package test; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +public interface DeclarationDescriptorWithSource extends DeclarationDescriptor { + @Override + @NotNull + DeclarationDescriptorWithSource getOriginal(); +} + +// FILE: test/DeclarationDescriptorNonRoot.java +package test; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +public interface DeclarationDescriptorNonRoot extends DeclarationDescriptorWithSource { +} + +// FILE: test/CallableDescriptor.java +package test; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +public interface CallableDescriptor extends DeclarationDescriptorWithVisibility, DeclarationDescriptorNonRoot { + @NotNull + @Override + CallableDescriptor getOriginal(); + + @NotNull + Collection getOverriddenDescriptors(); +} + +// FILE: test/k.kt +package test + +fun D.overriddenTreeUniqueAsSequenceA(useOriginal: Boolean): Sequence { + val set = hashSetOf() + + @Suppress("UNCHECKED_CAST") + fun D.doBuildOverriddenTreeAsSequence(): Sequence { + return with(if (useOriginal) original as D else this) { + if (original in set) + emptySequence() + else { + emptySequence() + } + } + } + + return doBuildOverriddenTreeAsSequence() +} + +fun D.overriddenTreeUniqueAsSequenceB(useOriginal: Boolean): Sequence { + val set = hashSetOf() + + @Suppress("UNCHECKED_CAST") + fun D.doBuildOverriddenTreeAsSequence(): Sequence { + return with(if (useOriginal) original as D else this) { + if (original in set) + emptySequence() + else { + emptySequence() + } + } + } + + return doBuildOverriddenTreeAsSequence() +} + +// @KKt.class: +// 0 checkExpressionValueIsNotNull diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index d58126457d2..38959510ab5 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -2344,6 +2344,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/nullCheckOptimization/alreadyCheckedForNull.kt"); } + @TestMetadata("deterministicNotNullChecks.kt") + public void testDeterministicNotNullChecks() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/nullCheckOptimization/deterministicNotNullChecks.kt"); + doTest(fileName); + } + @TestMetadata("expressionValueIsNotNull.kt") public void testExpressionValueIsNotNull() throws Exception { runTest("compiler/testData/codegen/bytecodeText/nullCheckOptimization/expressionValueIsNotNull.kt");