Implicit nothing type argument: handle nullable case properly

#KT-41620 Fixed
This commit is contained in:
Mikhail Glukhikh
2021-04-07 12:57:02 +03:00
parent 115e2673ae
commit c75331bf2a
9 changed files with 66 additions and 5 deletions

View File

@@ -13418,6 +13418,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/inference/nothingType/generateConstraintWithInnerNothingType.kt");
}
@Test
@TestMetadata("genericOverride.kt")
public void testGenericOverride() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/genericOverride.kt");
}
@Test
@TestMetadata("implicitInferenceTToFlexibleNothing.kt")
public void testImplicitInferenceTToFlexibleNothing() throws Exception {

View File

@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.typeUtil.isNothing
import org.jetbrains.kotlin.types.typeUtil.isNothingOrNullableNothing
import org.jetbrains.kotlin.types.typeUtil.isNullableNothing
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
object ImplicitNothingAsTypeParameterCallChecker : CallChecker {
@@ -61,10 +62,14 @@ object ImplicitNothingAsTypeParameterCallChecker : CallChecker {
resolvedCall.candidateDescriptor.valueParameters.filter { it.type.isFunctionOrSuspendFunctionType }
.map { it.returnType?.arguments?.last()?.type }.toSet()
val unsubstitutedReturnType = resultingDescriptor.original.returnType
val hasImplicitNothing = inferredReturnType?.isNothing() == true &&
val hasImplicitNothing = inferredReturnType?.isNothingOrNullableNothing() == true &&
unsubstitutedReturnType?.isTypeParameter() == true &&
(TypeUtils.noExpectedType(expectedType) || !expectedType.isNothing())
if (inferredReturnType?.isNullableNothing() == true && unsubstitutedReturnType?.isMarkedNullable == false) {
return false
}
if (hasImplicitNothing && unsubstitutedReturnType !in lambdasFromArgumentsReturnTypes) {
context.trace.reportDiagnosticOnceWrtDiagnosticFactoryList(
Errors.IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION.on(reportOn),

View File

@@ -1079,7 +1079,8 @@ class ExpressionCodegen(
nestedTryWithoutFinally: MutableList<TryInfo> = arrayListOf(),
stop: (LoopInfo) -> Boolean
): LoopInfo? {
return data.handleBlock {
@Suppress("RemoveExplicitTypeArguments")
return data.handleBlock<Nothing> {
when {
it is TryWithFinallyInfo -> {
genFinallyBlock(it, null, endLabel, data, nestedTryWithoutFinally)

View File

@@ -0,0 +1,12 @@
interface A {
fun a(): A
}
fun error(s: String): Nothing = null!!
class A1 : A {
override fun a() = test() ?: error("")
@Suppress("UNCHECKED_CAST")
private fun <V : A> test(): V? = this as? V
}

View File

@@ -0,0 +1,12 @@
interface A {
fun a(): A
}
fun error(s: String): Nothing = null!!
class A1 : A {
override fun a() = <!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>test<!>() ?: error("")
@Suppress("UNCHECKED_CAST")
private fun <V : A> test(): V? = this as? V
}

View File

@@ -0,0 +1,19 @@
package
public fun error(/*0*/ s: kotlin.String): kotlin.Nothing
public interface A {
public abstract fun a(): A
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class A1 : A {
public constructor A1()
public open override /*1*/ fun a(): kotlin.Nothing
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Suppress(names = {"UNCHECKED_CAST"}) private final fun </*0*/ V : A> test(): V?
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}

View File

@@ -10,7 +10,7 @@ fun test() {
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER{NI}, TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER{OI}!>make<!>()
)
select(make(), null)
select(<!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>make<!>(), null)
<!TYPE_INFERENCE_FAILED_ON_SPECIAL_CONSTRUCT{OI}!>if<!> (true) <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH{OI}!>make()<!> else TODO()
<!TYPE_INFERENCE_FAILED_ON_SPECIAL_CONSTRUCT{OI}!>if<!> (true) <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH{OI}!><!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>make<!>()<!> else TODO()
}

View File

@@ -13424,6 +13424,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/generateConstraintWithInnerNothingType.kt");
}
@Test
@TestMetadata("genericOverride.kt")
public void testGenericOverride() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/genericOverride.kt");
}
@Test
@TestMetadata("implicitInferenceTToFlexibleNothing.kt")
public void testImplicitInferenceTToFlexibleNothing() throws Exception {

View File

@@ -119,5 +119,5 @@ fun <T : <!FINAL_UPPER_BOUND!>String<!>> T?.case_11() = this
fun case_11() {
var x: Int? = 10
x = null
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int? & kotlin.Nothing?")!>x<!>.case_11()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int? & kotlin.Nothing?")!>x<!>.<!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>case_11<!>()
}