diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java index 16493038736..b6d8e00ac16 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java @@ -246,7 +246,7 @@ public class CandidateResolver { JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument); JetType expectedType = constraintSystem.getCurrentSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT); - if (expectedType == null || expectedType == DONT_CARE) { + if (expectedType == null || TypeUtils.isDontCarePlaceholder(expectedType)) { expectedType = argumentTypeResolver.getShapeTypeOfFunctionLiteral(functionLiteralExpression, context.scope, context.trace, false); } if (expectedType == null || !KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(expectedType) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java index 7a8f1f64961..dbf8374ddec 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java @@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import kotlin.Function0; +import kotlin.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; @@ -232,7 +233,13 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { } } else { - if (expectedType == null || expectedType == DONT_CARE || ErrorUtils.isUninferredParameter(expectedType)) { + boolean containsUninferredParameter = TypeUtils.containsSpecialType(expectedType, new Function1() { + @Override + public Boolean invoke(JetType type) { + return TypeUtils.isDontCarePlaceholder(type) || ErrorUtils.isUninferredParameter(type); + } + }); + if (expectedType == null || containsUninferredParameter) { context.trace.report(CANNOT_INFER_PARAMETER_TYPE.on(declaredParameter)); } if (expectedType != null) { diff --git a/compiler/testData/diagnostics/tests/inference/kt6175.kt b/compiler/testData/diagnostics/tests/inference/kt6175.kt new file mode 100644 index 00000000000..9a52a3eb0e2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/kt6175.kt @@ -0,0 +1,48 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun foo(body: (R?) -> T): T = fail() + +fun test1() { + foo { + true + } + foo { x -> + true + } +} + + +fun bar(body: (R) -> T): T = fail() + +fun test2() { + bar { + true + } + bar { x -> + true + } +} + +fun baz(body: (List) -> T): T = fail() + +fun test3() { + baz { + true + } + baz { x -> + true + } +} + +fun brr(body: (List) -> T): T = fail() + +fun test4() { + brr { + true + } + brr { x -> + true + } +} + +fun fail() = throw Exception() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/kt6175.lazy.log b/compiler/testData/diagnostics/tests/inference/kt6175.lazy.log new file mode 100644 index 00000000000..421e7fe4edf --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/kt6175.lazy.log @@ -0,0 +1,170 @@ +DescriptorResolver@0 { + = JetTypeImpl@1['Nothing'] +} + +LazyJavaClassDescriptor@2['Exception'] { + constructors = ArrayList@3[5] { JavaConstructorDescriptor@4[''], JavaConstructorDescriptor@5[''], JavaConstructorDescriptor@6[''], ... } // through LazyJavaClassMemberScope@7 + defaultType = JetTypeImpl@8['Exception'] + functionTypeForSamInterface = null + typeConstructor = LazyJavaClassTypeConstructor@9['Exception'] +} + +LazyJavaClassTypeConstructor@9['Exception'] { + parameters = ArrayList@10[empty] + supertypes = ArrayList@11[1] { LazyJavaClassifierType@12['Throwable'] } +} + +LazyJavaClassifierType@13['String'] { + arguments = ArrayList@14[empty] + classifier = JavaClassImpl@15['String'] + nullable = 'false': Boolean@16 + typeConstructor = DeserializedClassTypeConstructor@17 +} + +LazyJavaClassifierType@18['String'] { + arguments = ArrayList@19[empty] + classifier = JavaClassImpl@20['String'] + nullable = 'false': Boolean@16 + typeConstructor = DeserializedClassTypeConstructor@17 +} + +LazyJavaClassifierType@21['String'] { + arguments = ArrayList@22[empty] + classifier = JavaClassImpl@23['String'] + nullable = 'false': Boolean@16 + typeConstructor = DeserializedClassTypeConstructor@17 +} + +LazyJavaClassifierType@24['String'] { + arguments = ArrayList@25[empty] + classifier = JavaClassImpl@23['String'] + nullable = 'true': Boolean@26 + typeConstructor = DeserializedClassTypeConstructor@17 +} + +LazyJavaClassifierType@27['String'] { + arguments = ArrayList@28[empty] + classifier = JavaClassImpl@15['String'] + nullable = 'true': Boolean@26 + typeConstructor = DeserializedClassTypeConstructor@17 +} + +LazyJavaClassifierType@29['String'] { + arguments = ArrayList@30[empty] + classifier = JavaClassImpl@20['String'] + nullable = 'true': Boolean@26 + typeConstructor = DeserializedClassTypeConstructor@17 +} + +LazyJavaClassifierType@31['Throwable'] { + arguments = ArrayList@32[empty] + classifier = JavaClassImpl@33['Throwable'] + nullable = 'false': Boolean@16 + typeConstructor = DeserializedClassTypeConstructor@34 +} + +LazyJavaClassifierType@35['Throwable'] { + arguments = ArrayList@36[empty] + classifier = JavaClassImpl@37['Throwable'] + nullable = 'false': Boolean@16 + typeConstructor = DeserializedClassTypeConstructor@34 +} + +LazyJavaClassifierType@38['Throwable'] { + arguments = ArrayList@39[empty] + classifier = JavaClassImpl@40['Throwable'] + nullable = 'false': Boolean@16 + typeConstructor = DeserializedClassTypeConstructor@34 +} + +LazyJavaClassifierType@41['Throwable'] { + arguments = ArrayList@42[empty] + classifier = JavaClassImpl@33['Throwable'] + nullable = 'true': Boolean@26 + typeConstructor = DeserializedClassTypeConstructor@34 +} + +LazyJavaClassifierType@43['Throwable'] { + arguments = ArrayList@44[empty] + classifier = JavaClassImpl@37['Throwable'] + nullable = 'true': Boolean@26 + typeConstructor = DeserializedClassTypeConstructor@34 +} + +LazyJavaClassifierType@45['Throwable'] { + arguments = ArrayList@46[empty] + classifier = JavaClassImpl@40['Throwable'] + nullable = 'true': Boolean@26 + typeConstructor = DeserializedClassTypeConstructor@34 +} + +LazyJavaClassifierType@12['Throwable'] { + arguments = ArrayList@47[empty] + classifier = JavaClassImpl@48['Throwable'] + typeConstructor = DeserializedClassTypeConstructor@34 +} + +LazyJavaPackageFragmentProvider@49 { + packageFragments('': FqName@50) = LazyJavaPackageFragment@51[''] + packageFragments('Any': FqName@52) = null + packageFragments('List': FqName@53) = null + packageFragments('R': FqName@54) = null + packageFragments('T': FqName@55) = null + packageFragments('java': FqName@56) = LazyJavaPackageFragment@57['java'] + packageFragments('java.lang': FqName@58) = LazyJavaPackageFragment@59['lang'] + packageFragments('java.lang.Any': FqName@60) = null + packageFragments('java.lang.List': FqName@61) = null + packageFragments('java.lang.R': FqName@62) = null + packageFragments('java.lang.T': FqName@63) = null + packageFragments('kotlin': FqName@64) = null + packageFragments('kotlin.Any': FqName@65) = null + packageFragments('kotlin.List': FqName@66) = null + packageFragments('kotlin.R': FqName@67) = null + packageFragments('kotlin.T': FqName@68) = null + packageFragments('kotlin.io': FqName@69) = null + packageFragments('kotlin.jvm': FqName@70) = null + topLevelClasses(JavaClassImpl@71['Exception']) = LazyJavaClassDescriptor@2['Exception'] +} + +LazyJavaPackageFragment@51[''] { + classes('Any': Name@72) = null // through LazyPackageFragmentScopeForJavaPackage@73 + classes('Exception': Name@74) = null // through LazyPackageFragmentScopeForJavaPackage@73 + classes('List': Name@75) = null // through LazyPackageFragmentScopeForJavaPackage@73 + classes('bar': Name@76) = null // through LazyPackageFragmentScopeForJavaPackage@73 + classes('baz': Name@77) = null // through LazyPackageFragmentScopeForJavaPackage@73 + classes('brr': Name@78) = null // through LazyPackageFragmentScopeForJavaPackage@73 + classes('fail': Name@79) = null // through LazyPackageFragmentScopeForJavaPackage@73 + classes('foo': Name@80) = null // through LazyPackageFragmentScopeForJavaPackage@73 + deserializedPackageScope = Empty@81 // through LazyPackageFragmentScopeForJavaPackage@73 + functions('Exception': Name@74) = EmptyList@82[empty] // through LazyPackageFragmentScopeForJavaPackage@73 + functions('bar': Name@76) = EmptyList@82[empty] // through LazyPackageFragmentScopeForJavaPackage@73 + functions('baz': Name@77) = EmptyList@82[empty] // through LazyPackageFragmentScopeForJavaPackage@73 + functions('brr': Name@78) = EmptyList@82[empty] // through LazyPackageFragmentScopeForJavaPackage@73 + functions('fail': Name@79) = EmptyList@82[empty] // through LazyPackageFragmentScopeForJavaPackage@73 + functions('foo': Name@80) = EmptyList@82[empty] // through LazyPackageFragmentScopeForJavaPackage@73 + memberIndex = computeMemberIndex$1@83 // through LazyPackageFragmentScopeForJavaPackage@73 +} + +LazyJavaPackageFragment@57['java'] { + classes('lang': Name@84) = null // through LazyPackageFragmentScopeForJavaPackage@85 + deserializedPackageScope = Empty@81 // through LazyPackageFragmentScopeForJavaPackage@85 + functions('lang': Name@86) = EmptyList@82[empty] // through LazyPackageFragmentScopeForJavaPackage@85 + memberIndex = computeMemberIndex$1@87 // through LazyPackageFragmentScopeForJavaPackage@85 +} + +LazyJavaPackageFragment@59['lang'] { + classes('Exception': Name@74) = LazyJavaClassDescriptor@2['Exception'] // through LazyPackageFragmentScopeForJavaPackage@88 + classes('bar': Name@76) = null // through LazyPackageFragmentScopeForJavaPackage@88 + classes('baz': Name@77) = null // through LazyPackageFragmentScopeForJavaPackage@88 + classes('brr': Name@78) = null // through LazyPackageFragmentScopeForJavaPackage@88 + classes('fail': Name@79) = null // through LazyPackageFragmentScopeForJavaPackage@88 + classes('foo': Name@80) = null // through LazyPackageFragmentScopeForJavaPackage@88 + deserializedPackageScope = Empty@81 // through LazyPackageFragmentScopeForJavaPackage@88 + functions('Exception': Name@74) = EmptyList@82[empty] // through LazyPackageFragmentScopeForJavaPackage@88 + functions('bar': Name@76) = EmptyList@82[empty] // through LazyPackageFragmentScopeForJavaPackage@88 + functions('baz': Name@77) = EmptyList@82[empty] // through LazyPackageFragmentScopeForJavaPackage@88 + functions('brr': Name@78) = EmptyList@82[empty] // through LazyPackageFragmentScopeForJavaPackage@88 + functions('fail': Name@79) = EmptyList@82[empty] // through LazyPackageFragmentScopeForJavaPackage@88 + functions('foo': Name@80) = EmptyList@82[empty] // through LazyPackageFragmentScopeForJavaPackage@88 + memberIndex = computeMemberIndex$1@89 // through LazyPackageFragmentScopeForJavaPackage@88 +} diff --git a/compiler/testData/diagnostics/tests/inference/kt6175.txt b/compiler/testData/diagnostics/tests/inference/kt6175.txt new file mode 100644 index 00000000000..2d8cbe63848 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/kt6175.txt @@ -0,0 +1,11 @@ +package + +internal fun bar(/*0*/ body: (R) -> T): T +internal fun baz(/*0*/ body: (kotlin.List) -> T): T +internal fun brr(/*0*/ body: (kotlin.List) -> T): T +internal fun fail(): kotlin.Nothing +internal fun foo(/*0*/ body: (R?) -> T): T +internal fun test1(): kotlin.Unit +internal fun test2(): kotlin.Unit +internal fun test3(): kotlin.Unit +internal fun test4(): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index a9dd609b424..25eb6f5d447 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -4915,6 +4915,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("kt6175.kt") + public void testKt6175() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/kt6175.kt"); + doTest(fileName); + } + @TestMetadata("kt619.kt") public void testKt619() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/kt619.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 0d5fb1fc1e6..3286ff61247 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 @@ -343,7 +343,7 @@ public class ConstraintSystemImpl implements ConstraintSystem { } private boolean isErrorOrSpecialType(@Nullable JetType type) { - if (type == DONT_CARE || ErrorUtils.isUninferredParameter(type)) { + if (TypeUtils.isDontCarePlaceholder(type) || ErrorUtils.isUninferredParameter(type)) { return true; } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java index 16b5908d312..67ba5be0b5f 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -105,6 +105,10 @@ public class TypeUtils { return type == NO_EXPECTED_TYPE || type == UNIT_EXPECTED_TYPE; } + public static boolean isDontCarePlaceholder(@Nullable JetType type) { + return type != null && type.getConstructor() == DONT_CARE.getConstructor(); + } + @NotNull public static JetType makeNullable(@NotNull JetType type) { return makeNullableAsSpecified(type, true); diff --git a/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java b/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java index b8fe455d731..ef15dbabae7 100644 --- a/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java +++ b/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java @@ -338,7 +338,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer { private String renderInflexibleType(@NotNull JetType type) { assert !TypesPackage.isFlexible(type) : "Flexible types not allowed here: " + renderNormalizedType(type); - if (type == CANT_INFER_LAMBDA_PARAM_TYPE || type == DONT_CARE) { + if (type == CANT_INFER_LAMBDA_PARAM_TYPE || TypeUtils.isDontCarePlaceholder(type)) { return "???"; } if (ErrorUtils.isUninferredParameter(type)) {