DONT_CARE placeholder can be nullable after a substitution
Interpret it as DONT_CARE as well (not as an error type where an error was generated before) #KT-6175 Fixed
This commit is contained in:
@@ -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)
|
||||
|
||||
+8
-1
@@ -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<JetType, Boolean>() {
|
||||
@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) {
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun <T, R : Any> foo(body: (R?) -> T): T = fail()
|
||||
|
||||
fun test1() {
|
||||
<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!> {
|
||||
true
|
||||
}
|
||||
<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!> { <!CANNOT_INFER_PARAMETER_TYPE!>x<!> ->
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun <T, R> bar(body: (R) -> T): T = fail()
|
||||
|
||||
fun test2() {
|
||||
<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar<!> {
|
||||
true
|
||||
}
|
||||
<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar<!> { <!CANNOT_INFER_PARAMETER_TYPE!>x<!> ->
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fun <T, R> baz(body: (List<R>) -> T): T = fail()
|
||||
|
||||
fun test3() {
|
||||
<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>baz<!> {
|
||||
true
|
||||
}
|
||||
<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>baz<!> { <!CANNOT_INFER_PARAMETER_TYPE!>x<!> ->
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fun <T, R : Any> brr(body: (List<R?>) -> T): T = fail()
|
||||
|
||||
fun test4() {
|
||||
<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>brr<!> {
|
||||
true
|
||||
}
|
||||
<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>brr<!> { <!CANNOT_INFER_PARAMETER_TYPE!>x<!> ->
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fun fail() = throw Exception()
|
||||
@@ -0,0 +1,170 @@
|
||||
DescriptorResolver@0 {
|
||||
<name not found> = JetTypeImpl@1['Nothing']
|
||||
}
|
||||
|
||||
LazyJavaClassDescriptor@2['Exception'] {
|
||||
constructors = ArrayList@3[5] { JavaConstructorDescriptor@4['<init>'], JavaConstructorDescriptor@5['<init>'], JavaConstructorDescriptor@6['<init>'], ... } // 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('<root>': FqName@50) = LazyJavaPackageFragment@51['<root>']
|
||||
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['<root>'] {
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
internal fun </*0*/ T, /*1*/ R> bar(/*0*/ body: (R) -> T): T
|
||||
internal fun </*0*/ T, /*1*/ R> baz(/*0*/ body: (kotlin.List<R>) -> T): T
|
||||
internal fun </*0*/ T, /*1*/ R : kotlin.Any> brr(/*0*/ body: (kotlin.List<R?>) -> T): T
|
||||
internal fun fail(): kotlin.Nothing
|
||||
internal fun </*0*/ T, /*1*/ R : kotlin.Any> 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
|
||||
@@ -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");
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user