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:
Svetlana Isakova
2014-11-11 17:45:49 +03:00
parent 8ad017c071
commit 8109b1f997
9 changed files with 250 additions and 4 deletions
@@ -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)
@@ -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");
@@ -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)) {