diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/InsertHandlerProvider.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/InsertHandlerProvider.kt index b08911a174e..c9a3d98a5b8 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/InsertHandlerProvider.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/InsertHandlerProvider.kt @@ -26,8 +26,8 @@ import org.jetbrains.kotlin.idea.core.ExpectedInfo import org.jetbrains.kotlin.idea.core.fuzzyType import org.jetbrains.kotlin.idea.util.CallType import org.jetbrains.kotlin.idea.util.fuzzyReturnType -import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue import org.jetbrains.kotlin.resolve.calls.util.getValueParametersCountFromFunctionType +import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue import org.jetbrains.kotlin.types.KotlinType import java.util.* @@ -94,8 +94,11 @@ class InsertHandlerProvider( fun addPotentiallyInferred(type: KotlinType) { val descriptor = type.constructor.declarationDescriptor as? TypeParameterDescriptor - if (descriptor != null && descriptor in typeParameters) { + if (descriptor != null && descriptor in typeParameters && descriptor !in potentiallyInferred) { potentiallyInferred.add(descriptor) + // Add possible inferred by type-arguments of upper-bound of parameter + // e.g. >, so T inferred from C + descriptor.upperBounds.filter { it.arguments.isNotEmpty() }.forEach(::addPotentiallyInferred) } if (type.isFunctionType && getValueParametersCountFromFunctionType(type) <= 1) { diff --git a/idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt b/idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt new file mode 100644 index 00000000000..be1703aeee5 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt @@ -0,0 +1,12 @@ +class Cn + +fun > C.some(arg: (T) -> Unit): C { + return this +} + +fun main(args: Array) { + val x = Cn() + x. +} + +//ELEMENT: some diff --git a/idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt.after b/idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt.after new file mode 100644 index 00000000000..7a28ebbad82 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt.after @@ -0,0 +1,12 @@ +class Cn + +fun > C.some(arg: (T) -> Unit): C { + return this +} + +fun main(args: Array) { + val x = Cn() + x.some { } +} + +//ELEMENT: some diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java index 77500a77006..18d7e51acdc 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java @@ -216,6 +216,12 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion doTest(fileName); } + @TestMetadata("TypeInferedFromWrapperType.kt") + public void testTypeInferedFromWrapperType() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt"); + doTest(fileName); + } + @TestMetadata("TypeParameter.kt") public void testTypeParameter() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/TypeParameter.kt");