diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt index 6790fd4748f..8855c11fecf 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt @@ -40,6 +40,10 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, return StandardClassIds.Nothing(symbolProvider).constructType(emptyArray(), false) } + override fun anyType(): SimpleTypeMarker { + return StandardClassIds.Any(symbolProvider).constructType(emptyArray(), false) + } + override fun createFlexibleType(lowerBound: SimpleTypeMarker, upperBound: SimpleTypeMarker): KotlinTypeMarker { require(lowerBound is ConeKotlinType) require(upperBound is ConeKotlinType) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt index a630395347a..2d6a3880fce 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt @@ -135,7 +135,7 @@ class DiagnosticReporterByTrackingStrategy( require(diagnostic is ArgumentTypeMismatchDiagnostic) reportIfNonNull(callArgument.safeAs()?.valueArgument?.getArgumentExpression()) { if (it.isNull()) { - trace.report(NULL_FOR_NONNULL_TYPE.on(it, diagnostic.expectedType)) + trace.reportDiagnosticOnce(NULL_FOR_NONNULL_TYPE.on(it, diagnostic.expectedType)) } else { trace.report(TYPE_MISMATCH.on(it, diagnostic.expectedType, diagnostic.actualType)) } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt index 6b7f00d384a..b2801012180 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPosi import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintPosition import org.jetbrains.kotlin.resolve.calls.inference.model.ReceiverConstraintPosition import org.jetbrains.kotlin.resolve.calls.model.* +import org.jetbrains.kotlin.types.NotNullTypeVariable import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.checker.captureFromExpression import org.jetbrains.kotlin.types.checker.hasSupertypeWithGivenTypeConstructor @@ -81,6 +82,20 @@ private fun checkExpressionArgument( val expectedNullableType = expectedType.makeNullableAsSpecified(true) val position = if (isReceiver) ReceiverConstraintPosition(expressionArgument) else ArgumentConstraintPosition(expressionArgument) + + // Used only for arguments with @NotNull annotation + if (expectedType is NotNullTypeVariable) { + var expectedTypeIsNull: Boolean = false + csBuilder.runTransaction { + addNotNullUpperConstraint(argumentType, position) + expectedTypeIsNull = hasContradiction + false + } + if (expectedTypeIsNull) { + diagnosticsHolder.addDiagnostic(ArgumentTypeMismatchDiagnostic(expectedType, argumentType, expressionArgument)) + } + } + if (expressionArgument.isSafeCall) { if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) { diagnosticsHolder.addDiagnosticIfNotNull( diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt index 71cf58dd8d5..6657838e332 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt @@ -40,6 +40,8 @@ interface ConstraintSystemOperation { fun isPostponedTypeVariable(typeVariable: TypeVariableMarker): Boolean fun getProperSuperTypeConstructors(type: KotlinTypeMarker): List + + fun addNotNullUpperConstraint(type: KotlinTypeMarker, position: ConstraintPosition) } interface ConstraintSystemBuilder : ConstraintSystemOperation { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt index 379b4084f64..f0063d8e613 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt @@ -302,4 +302,8 @@ class NewConstraintSystemImpl( return constraints.any { (it.kind == ConstraintKind.UPPER || it.kind == ConstraintKind.EQUALITY) && it.type.isUnit() } } + + override fun addNotNullUpperConstraint(type: KotlinTypeMarker, position: ConstraintPosition) { + addSubtypeConstraint(type, anyType(), position) + } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/generics/projectionsScope/starNullabilityRecursive.kt b/compiler/testData/diagnostics/tests/generics/projectionsScope/starNullabilityRecursive.kt index 7cc339fe377..7a5f0dc7fdd 100644 --- a/compiler/testData/diagnostics/tests/generics/projectionsScope/starNullabilityRecursive.kt +++ b/compiler/testData/diagnostics/tests/generics/projectionsScope/starNullabilityRecursive.kt @@ -5,6 +5,5 @@ interface A?> { fun foo(): T? } fun testA(a: A<*>) { - // in new inference here we have A>> - a.foo() checkType { _?>() } + a.foo() checkType { _?>() } } diff --git a/compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt b/compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt index 940d1900a42..b08bed6f734 100644 --- a/compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt +++ b/compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt @@ -18,11 +18,11 @@ public interface J2 extends J { fun main() { J { s: String -> s} // should be prohibited, because SAM value parameter has nullable type J { "" + it.length } - J { null } + J { null } J { it?.length?.toString() } J2 { s: String -> s} J2 { "" + it.length } - J2 { null } + J2 { null } J2 { it?.length?.toString() } } diff --git a/compiler/testData/diagnostics/tests/platformTypes/notNullTypeParameter/methodTypeParameter.kt b/compiler/testData/diagnostics/tests/platformTypes/notNullTypeParameter/methodTypeParameter.kt index e1baf17bc99..b3cfaecde22 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/notNullTypeParameter/methodTypeParameter.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/notNullTypeParameter/methodTypeParameter.kt @@ -11,13 +11,15 @@ public class A { // FILE: k.kt fun test() { - A.bar(null, "") + A.bar(null, "") A.bar(null, "") - A.bar(null, "") - A.bar(null, A.platformString()) + A.bar(null, "") + A.bar("", "") + + A.bar(null, A.platformString()) val x: String? = null - A.bar(x, "") - A.bar(null, "") + A.bar(x, "") + A.bar(null, "") } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt index 197f2461af3..f73f8c9de52 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt @@ -215,7 +215,7 @@ private object EnhancedTypeAnnotationDescriptor : AnnotationDescriptor { override fun toString() = "[EnhancedType]" } -internal class NotNullTypeParameter(override val delegate: SimpleType) : CustomTypeVariable, DelegatingSimpleType() { +internal class NotNullTypeParameter(override val delegate: SimpleType) : NotNullTypeVariable, DelegatingSimpleType() { override val isTypeVariable: Boolean get() = true diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeCapabilities.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeCapabilities.kt index 33924046ca8..428df8a0d3f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeCapabilities.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeCapabilities.kt @@ -27,6 +27,10 @@ interface CustomTypeVariable { fun substitutionResult(replacement: KotlinType): KotlinType } +// That interface is needed to provide information about definitely not null +// type parameters (e.g. from @NotNull annotation) to type system +interface NotNullTypeVariable : CustomTypeVariable + fun KotlinType.isCustomTypeVariable(): Boolean = (unwrap() as? CustomTypeVariable)?.isTypeVariable ?: false fun KotlinType.getCustomTypeVariable(): CustomTypeVariable? = (unwrap() as? CustomTypeVariable)?.let { diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt index 570f1215948..c1f1411db37 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -333,6 +333,10 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext { return builtIns.nothingType } + override fun anyType(): SimpleTypeMarker { + return builtIns.anyType + } + val builtIns: KotlinBuiltIns get() = throw UnsupportedOperationException("Not supported") override fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker { diff --git a/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt b/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt index 062d58c8a36..39ff35c9caf 100644 --- a/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt +++ b/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt @@ -49,6 +49,7 @@ interface TypeSystemBuiltInsContext { fun nullableNothingType(): SimpleTypeMarker fun nullableAnyType(): SimpleTypeMarker fun nothingType(): SimpleTypeMarker + fun anyType(): SimpleTypeMarker } interface TypeSystemTypeFactoryContext {