diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt index 0112aefd01a..1dfad011c54 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeCheckerContext +import org.jetbrains.kotlin.types.checker.NewCapturedType import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.utils.addToStdlib.cast @@ -267,6 +268,16 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo return this.constructor.typeParameterMarker } + override fun CapturedTypeMarker.withNotNullProjection(): KotlinTypeMarker { + require(this is ConeCapturedType) + return this // TODO + } + + override fun CapturedTypeMarker.isProjectionNotNull(): Boolean { + require(this is ConeCapturedType) + return false // TODO + } + override fun DefinitelyNotNullTypeMarker.original(): SimpleTypeMarker { require(this is ConeDefinitelyNotNullType) return this.original as SimpleTypeMarker diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index d98ea1d8816..621c370e8e0 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -10725,6 +10725,16 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/inference/constraints/constraintOnFunctionLiteral.kt"); } + @TestMetadata("definitelyNotNullTypeInArguments.kt") + public void testDefinitelyNotNullTypeInArguments() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInArguments.kt"); + } + + @TestMetadata("definitelyNotNullTypeInReturnPosition.kt") + public void testDefinitelyNotNullTypeInReturnPosition() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInReturnPosition.kt"); + } + @TestMetadata("definitelyNotNullTypeInvariantPosition.kt") public void testDefinitelyNotNullTypeInvariantPosition() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInvariantPosition.kt"); diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt index 50dd7960e30..391ac104dc4 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt @@ -75,6 +75,9 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun CapturedTypeMarker.typeConstructor(): CapturedTypeConstructorMarker = error("Captured types should be used for IrTypes") + override fun CapturedTypeMarker.isProjectionNotNull(): Boolean = + error("Captured types should be used for IrTypes") + override fun CapturedTypeMarker.captureStatus(): CaptureStatus = error("Captured types should be used for IrTypes") diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt index 483fb571795..dc3a83a08aa 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt @@ -12,8 +12,10 @@ import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor import org.jetbrains.kotlin.incremental.record +import org.jetbrains.kotlin.resolve.calls.components.CollectionTypeVariableUsagesInfo.getTypeParameterByVariable import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation +import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor import org.jetbrains.kotlin.resolve.calls.inference.model.* import org.jetbrains.kotlin.resolve.calls.inference.substitute @@ -26,6 +28,9 @@ import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError import org.jetbrains.kotlin.resolve.sam.SAM_LOOKUP_NAME import org.jetbrains.kotlin.resolve.sam.getFunctionTypeForPossibleSamType import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.types.model.KotlinTypeMarker +import org.jetbrains.kotlin.types.model.TypeConstructorMarker +import org.jetbrains.kotlin.types.model.typeConstructor import org.jetbrains.kotlin.types.typeUtil.contains import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.types.typeUtil.makeNullable @@ -285,6 +290,144 @@ internal object CheckExplicitReceiverKindConsistency : ResolutionPart() { } } +internal object CollectionTypeVariableUsagesInfo : ResolutionPart() { + private val KotlinType.isComputed get() = this !is WrappedType || isComputed() + + private fun NewConstraintSystem.isContainedInInvariantOrContravariantPositions( + variableTypeConstructor: TypeConstructorMarker, + baseType: KotlinTypeMarker, + wasOutVariance: Boolean = true + ): Boolean { + if (baseType !is KotlinType) return false + + val dependentTypeParameter = getTypeParameterByVariable(variableTypeConstructor) ?: return false + val declaredTypeParameters = baseType.constructor.parameters + + if (declaredTypeParameters.size < baseType.arguments.size) return false + + for ((argumentsIndex, argument) in baseType.arguments.withIndex()) { + if (argument.isStarProjection || argument.type.isMarkedNullable) continue + + val currentEffectiveVariance = + declaredTypeParameters[argumentsIndex].variance == Variance.OUT_VARIANCE || argument.projectionKind == Variance.OUT_VARIANCE + val effectiveVarianceFromTopLevel = wasOutVariance && currentEffectiveVariance + + if ((argument.type.constructor == dependentTypeParameter || argument.type.constructor == variableTypeConstructor) && !effectiveVarianceFromTopLevel) + return true + + if (isContainedInInvariantOrContravariantPositions(variableTypeConstructor, argument.type, effectiveVarianceFromTopLevel)) + return true + } + + return false + } + + private fun isContainedInInvariantOrContravariantPositionsAmongTypeParameters( + checkingType: TypeVariableFromCallableDescriptor, + typeParameters: List + ) = typeParameters.any { + it.variance != Variance.OUT_VARIANCE && it.typeConstructor == checkingType.originalTypeParameter.typeConstructor + } + + private fun NewConstraintSystem.getDependentTypeParameters( + variable: TypeConstructorMarker, + dependentTypeParametersSeen: List> = listOf() + ): List> { + val context = asConstraintSystemCompleterContext() + val dependentTypeParameters = getBuilder().currentStorage().notFixedTypeVariables.mapNotNull { (typeConstructor, constraints) -> + val upperBounds = constraints.constraints.filter { + it.position.from is DeclaredUpperBoundConstraintPosition && it.kind == ConstraintKind.UPPER + } + + upperBounds.mapNotNull { constraint -> + if (constraint.type.typeConstructor(context) != variable) { + val suitableUpperBound = upperBounds.find { upperBound -> + with(context) { upperBound.type.contains { it.typeConstructor() == variable } } + }?.type + + if (suitableUpperBound != null) typeConstructor to suitableUpperBound else null + } else typeConstructor to null + } + }.flatten().filter { it !in dependentTypeParametersSeen && it.first != variable } + + return dependentTypeParameters + dependentTypeParameters.mapNotNull { (typeConstructor, _) -> + if (typeConstructor != variable) { + getDependentTypeParameters(typeConstructor, dependentTypeParameters + dependentTypeParametersSeen) + } else null + }.flatten() + } + + private fun NewConstraintSystem.isContainedInInvariantOrContravariantPositionsAmongUpperBound( + checkingType: TypeConstructorMarker, + dependentTypeParameters: List> + ): Boolean { + var currentTypeParameterConstructor = checkingType + + return dependentTypeParameters.any { (typeConstructor, upperBound) -> + val isContainedOrNoUpperBound = + upperBound == null || isContainedInInvariantOrContravariantPositions(currentTypeParameterConstructor, upperBound) + currentTypeParameterConstructor = typeConstructor + isContainedOrNoUpperBound + } + } + + private fun NewConstraintSystem.getTypeParameterByVariable(typeConstructor: TypeConstructorMarker) = + (getBuilder().currentStorage().allTypeVariables[typeConstructor] as? TypeVariableFromCallableDescriptor)?.originalTypeParameter?.typeConstructor + + private fun NewConstraintSystem.getDependingOnTypeParameter(variable: TypeConstructor) = + getBuilder().currentStorage().notFixedTypeVariables[variable]?.constraints?.mapNotNull { + if (it.position.from is DeclaredUpperBoundConstraintPosition && it.kind == ConstraintKind.UPPER) { + it.type.typeConstructor(asConstraintSystemCompleterContext()) + } else null + } ?: emptyList() + + private fun NewConstraintSystem.isContainedInInvariantOrContravariantPositionsWithDependencies( + variable: TypeVariableFromCallableDescriptor, + declarationDescriptor: DeclarationDescriptor? + ): Boolean { + if (declarationDescriptor !is CallableDescriptor) return false + + val returnType = declarationDescriptor.returnType ?: return false + + if (!returnType.isComputed) return false + + val typeVariableConstructor = variable.freshTypeConstructor + val dependentTypeParameters = getDependentTypeParameters(typeVariableConstructor) + val dependingOnTypeParameter = getDependingOnTypeParameter(typeVariableConstructor) + + val isContainedInUpperBounds = + isContainedInInvariantOrContravariantPositionsAmongUpperBound(typeVariableConstructor, dependentTypeParameters) + val isContainedAnyDependentTypeInReturnType = dependentTypeParameters.any { (typeParameter, _) -> + returnType.contains { + it.typeConstructor(asConstraintSystemCompleterContext()) == getTypeParameterByVariable(typeParameter) && !it.isMarkedNullable + } + } + + return isContainedInInvariantOrContravariantPositions(typeVariableConstructor, returnType) + || dependingOnTypeParameter.any { isContainedInInvariantOrContravariantPositions(it, returnType) } + || dependentTypeParameters.any { isContainedInInvariantOrContravariantPositions(it.first, returnType) } + || (isContainedAnyDependentTypeInReturnType && isContainedInUpperBounds) + } + + private fun TypeVariableFromCallableDescriptor.recordInfoAboutTypeVariableUsagesAsInvariantOrContravariantParameter() { + freshTypeConstructor.isContainedInInvariantOrContravariantPositions = true + } + + override fun KotlinResolutionCandidate.process(workIndex: Int) { + for (variable in resolvedCall.freshVariablesSubstitutor.freshVariables) { + if (resolvedCall.candidateDescriptor is ClassConstructorDescriptor) { + val typeParameters = resolvedCall.candidateDescriptor.containingDeclaration.declaredTypeParameters + + if (isContainedInInvariantOrContravariantPositionsAmongTypeParameters(variable, typeParameters)) { + variable.recordInfoAboutTypeVariableUsagesAsInvariantOrContravariantParameter() + } + } else if (getSystem().isContainedInInvariantOrContravariantPositionsWithDependencies(variable, candidateDescriptor)) { + variable.recordInfoAboutTypeVariableUsagesAsInvariantOrContravariantParameter() + } + } + } +} + private fun KotlinResolutionCandidate.resolveKotlinArgument( argument: KotlinCallArgument, candidateParameter: ParameterDescriptor?, diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt index 4419b1bcef7..e681c5a14c6 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt @@ -5,9 +5,11 @@ package org.jetbrains.kotlin.resolve.calls.inference.components +import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableTypeConstructor import org.jetbrains.kotlin.types.AbstractNullabilityChecker import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeCheckerContext +import org.jetbrains.kotlin.types.checker.NewCapturedType import org.jetbrains.kotlin.types.model.* abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheckerContext(), TypeSystemInferenceExtensionContext { @@ -179,9 +181,31 @@ abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheck private fun simplifyLowerConstraint(typeVariable: KotlinTypeMarker, subType: KotlinTypeMarker): Boolean { val lowerConstraint = when (typeVariable) { is SimpleTypeMarker -> - // Foo <: T or - // Foo <: T? -- Foo!! <: T - if (typeVariable.isMarkedNullable()) subType.makeDefinitelyNotNullOrNotNull() else subType + /* + * Foo <: T -- Foo <: T + * Foo <: T? (T is contained in invariant or contravariant positions of a return type) -- Foo <: T + * Example: + * fun foo(x: T?): Inv {} + * fun main(z: K) { val x = foo(z) } + * Foo <: T? (T isn't contained there) -- Foo!! <: T + * Example: + * fun foo(x: T?) {} + * fun main(z: K) { foo(z) } + */ + if (typeVariable.isMarkedNullable()) { + val typeVariableTypeConstructor = typeVariable.typeConstructor() + val subTypeConstructor = subType.typeConstructor() + + if (subTypeConstructor !is TypeVariableTypeConstructor && typeVariableTypeConstructor is TypeVariableTypeConstructor && typeVariableTypeConstructor.isContainedInInvariantOrContravariantPositions) { + if (subType is NewCapturedType) { + subType.withNotNullProjection() + } else { + subType.withNullability(false) + } + } else { + subType.makeDefinitelyNotNullOrNotNull() + } + } else subType is FlexibleTypeMarker -> { assertFlexibleTypeVariable(typeVariable) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/TypeVariable.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/TypeVariable.kt index eb37f855740..ef22b96113e 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/TypeVariable.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/TypeVariable.kt @@ -49,10 +49,12 @@ class TypeVariableTypeConstructor(private val builtIns: KotlinBuiltIns, val debu override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): TypeConstructor = this override fun toString() = "TypeVariable($debugName)" + + var isContainedInInvariantOrContravariantPositions: Boolean = false } sealed class NewTypeVariable(builtIns: KotlinBuiltIns, name: String) : TypeVariableMarker { - val freshTypeConstructor: TypeConstructor = TypeVariableTypeConstructor(builtIns, name) + val freshTypeConstructor = TypeVariableTypeConstructor(builtIns, name) // member scope is used if we have receiver with type TypeVariable(T) // todo add to member scope methods from supertypes for type variable diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt index bf10b34f3d8..bf1ca960c1c 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt @@ -206,6 +206,7 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) { NoTypeArguments, NoArguments, CreateFreshVariablesSubstitutor, + CollectionTypeVariableUsagesInfo, CheckExplicitReceiverKindConsistency, CheckReceivers, PostponedVariablesInitializerResolutionPart @@ -220,6 +221,7 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) { MapArguments, ArgumentsToCandidateParameterDescriptor, CreateFreshVariablesSubstitutor, + CollectionTypeVariableUsagesInfo, CheckExplicitReceiverKindConsistency, CheckReceivers, CheckArgumentsInParenthesis, diff --git a/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt b/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt index dc1be049f1e..1c52648e60d 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt @@ -41,7 +41,6 @@ open class TypeApproximatorConfiguration { open val errorType get() = false open val integerLiteralType: Boolean = false // IntegerLiteralTypeConstructor open val definitelyNotNullType get() = true - open val definitelyNotNullTypeInInvariantPosition get() = true open val intersection: IntersectionStrategy = TO_COMMON_SUPERTYPE open val typeVariable: (TypeVariableTypeConstructorMarker) -> Boolean = { false } @@ -83,10 +82,7 @@ open class TypeApproximatorConfiguration { override val typeVariable: (TypeVariableTypeConstructorMarker) -> Boolean get() = { true } } - object IncorporationConfiguration : TypeApproximatorConfiguration.AbstractCapturedTypesApproximation(FOR_INCORPORATION) { - override val definitelyNotNullTypeInInvariantPosition: Boolean get() = false - } - + object IncorporationConfiguration : TypeApproximatorConfiguration.AbstractCapturedTypesApproximation(FOR_INCORPORATION) object SubtypeCapturedTypesApproximation : TypeApproximatorConfiguration.AbstractCapturedTypesApproximation(FOR_SUBTYPING) object CapturedAndIntegerLiteralsTypesApproximation : TypeApproximatorConfiguration.AbstractCapturedTypesApproximation(FROM_EXPRESSION) { override val integerLiteralType: Boolean get() = true @@ -95,7 +91,6 @@ open class TypeApproximatorConfiguration { object FinalApproximationAfterResolutionAndInference : TypeApproximatorConfiguration.AbstractCapturedTypesApproximation(FROM_EXPRESSION) { override val integerLiteralType: Boolean get() = true - override val definitelyNotNullTypeInInvariantPosition: Boolean get() = false } object IntegerLiteralsTypesApproximation : TypeApproximatorConfiguration.AllFlexibleSameValue() { @@ -377,7 +372,11 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon // C = in Int, Int <: C => Int? <: C? // C = out Number, C <: Number => C? <: Number? - return if (type.isMarkedNullable()) baseResult.withNullability(true) else baseResult + return when { + type.isMarkedNullable() -> baseResult.withNullability(true) + type.isProjectionNotNull() -> baseResult.withNullability(false) + else -> baseResult + } } private fun approximateSimpleToSuperType(type: SimpleTypeMarker, conf: TypeApproximatorConfiguration, depth: Int) = @@ -480,12 +479,6 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon if (argument.isStarProjection()) continue val effectiveVariance = AbstractTypeChecker.effectiveVariance(parameter.getVariance(), argument.getVariance()) - if (effectiveVariance == TypeVariance.INV) { - val argumentType = argument.getType() - if (argumentType is DefinitelyNotNullTypeMarker && !conf.definitelyNotNullTypeInInvariantPosition) { - newArguments[index] = argumentType.original().withNullability(false).asTypeArgument() - } - } val argumentType = newArguments[index]?.getType() ?: argument.getType() diff --git a/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInArguments.fir.kt b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInArguments.fir.kt new file mode 100644 index 00000000000..b11d5abb53d --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInArguments.fir.kt @@ -0,0 +1,131 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION -UNUSED_VARIABLE + +class Foo(x: T) +class Bar +class OutBar +class InBar + +fun foo0(x: K?, y: Bar) {} +fun foo1(x: K?, y: Foo>) {} +fun foo2(x: K?, y: Foo>) {} +fun foo3(x: K?, y: Foo>) {} +fun foo4(x: K?, y: Foo>) {} +fun foo5(x: K?, y: Bar) {} +fun foo6(x: K?, y: OutBar) {} +fun foo7(x: K?, y: InBar) {} +fun foo8(x: T?, y: Foo>) {} +fun foo9(x: M?, y: Foo>) {} +fun foo10(x: L?, y: Foo>, z: Bar) {} +fun foo11(x: M?, y: Foo>, z: Bar) {} +fun foo12(x: K?, y: Bar) {} + +class Foo13(x: T) { + fun foo1(x: T?, y: Bar) {} + fun foo2(x: K?, y: Bar) {} +} + +fun foo14(x: K?, y: Bar) where K: Comparable, K: CharSequence {} +fun foo15(x: T, y: Bar) {} +fun foo16(x: K, y: Bar) {} +fun Bar.foo18(x: T) {} + +fun foo21(x: K?, y: Foo>>) {} +fun foo22(x: K?, y: Foo>>) {} +fun foo23(x: K?, y: Foo>>) {} +fun foo24(x: K?, y: Foo>>) {} + +fun main(x: L?, y: L) { + foo0(x, Bar()) + foo0(y, Bar()) + + foo1(x, Foo(Bar())) + foo1(y, Foo(Bar())) + + if (x != null && y != null) { + foo1(x, Foo(Bar())) + foo1(y, Foo(Bar())) + } + + foo2(x, Foo(Bar())) + foo2(y, Foo(Bar())) + + foo3(x, Foo(Bar())) + foo3(y, Foo(Bar())) + + foo4(x, Foo(Bar())) + foo4(y, Foo(Bar())) + + foo5(x, Bar()) + foo5(y, Bar()) + + foo6(x, OutBar()) + foo6(y, OutBar()) + + foo7(x, InBar()) + foo7(y, InBar()) + + foo8(x, Foo(Bar())) + foo8(y, Foo(Bar())) + + foo9(x, Foo(Bar())) + foo9(y, Foo(Bar())) + + foo10(x, Foo(Bar()), Bar()) + foo10(y, Foo(Bar()), Bar()) + + foo11(x, Foo(Bar()), Bar()) + foo11(y, Foo(Bar()), Bar()) + + if (x != null && y != null) { + foo12(x, Bar()) + foo12(y, Bar()) + } + + foo12(x, Bar()) + foo12(y, Bar()) + + Foo13(x).foo1(x, Bar()) + Foo13(x).foo2(y, Bar()) + Foo13(y).foo1(x, Bar()) + Foo13(y).foo2(y, Bar()) + if (x != null) { + Foo13(x).foo2(y, Bar()) + Foo13(y).foo2(x, Bar()) + } + if (y != null) { + Foo13(x).foo2(y, Bar()) + Foo13(y).foo2(x, Bar()) + } + + foo14("y", Bar()) + foo14("x", Bar()) + + foo15(x, Bar()) + foo15(y, Bar()) + if (x != null && y != null) { + foo15(x, Bar()) + foo15(y, Bar()) + } + + foo16(x, Bar()) + foo16(y, Bar()) + if (x != null && y != null) { + foo16(x, Bar()) + foo16(y, Bar()) + } + + Bar().foo18(x) + Bar().foo18(y) + + foo21(x, Foo(Foo(OutBar()))) + foo21(y, Foo(Foo(OutBar()))) + + foo22(x, Foo(Foo(InBar()))) + foo22(y, Foo(Foo(InBar()))) + + foo23(x, Foo(Foo(Bar()))) + foo23(y, Foo(Foo(Bar()))) + + foo24(x, Foo(Foo(Bar()))) + foo24(y, Foo(Foo(Bar()))) +} diff --git a/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInArguments.kt b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInArguments.kt new file mode 100644 index 00000000000..bde686d5303 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInArguments.kt @@ -0,0 +1,131 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION -UNUSED_VARIABLE + +class Foo(x: T) +class Bar +class OutBar +class InBar + +fun foo0(x: K?, y: Bar) {} +fun foo1(x: K?, y: Foo>) {} +fun foo2(x: K?, y: Foo>) {} +fun foo3(x: K?, y: Foo>) {} +fun foo4(x: K?, y: Foo>) {} +fun foo5(x: K?, y: Bar) {} +fun foo6(x: K?, y: OutBar) {} +fun foo7(x: K?, y: InBar) {} +fun foo8(x: T?, y: Foo>) {} +fun foo9(x: M?, y: Foo>) {} +fun foo10(x: L?, y: Foo>, z: Bar) {} +fun foo11(x: M?, y: Foo>, z: Bar) {} +fun foo12(x: K?, y: Bar) {} + +class Foo13(x: T) { + fun foo1(x: T?, y: Bar) {} + fun foo2(x: K?, y: Bar) {} +} + +fun foo14(x: K?, y: Bar) where K: Comparable, K: CharSequence {} +fun foo15(x: T, y: Bar) {} +fun foo16(x: K, y: Bar) {} +fun Bar.foo18(x: T) {} + +fun foo21(x: K?, y: Foo>>) {} +fun foo22(x: K?, y: Foo>>) {} +fun foo23(x: K?, y: Foo>>) {} +fun foo24(x: K?, y: Foo>>) {} + +fun main(x: L?, y: L) { + foo0(x, ")!>Bar()) + foo0(y, ")!>Bar()) + + foo1(x, >")!>Foo(Bar())) + foo1(y, >")!>Foo(Bar())) + + if (x != null && y != null) { + foo1(x, >")!>Foo(Bar())) + foo1(y, >")!>Foo(Bar())) + } + + foo2(x, >")!>Foo(Bar())) + foo2(y, >")!>Foo(Bar())) + + foo3(x, >")!>Foo(Bar())) + foo3(y, >")!>Foo(Bar())) + + foo4(x, >")!>Foo(Bar())) + foo4(y, >")!>Foo(Bar())) + + foo5(x, ")!>Bar()) + foo5(y, ")!>Bar()) + + foo6(x, ")!>OutBar()) + foo6(y, ")!>OutBar()) + + foo7(x, ")!>InBar()) + foo7(y, ")!>InBar()) + + foo8(x, >")!>Foo(Bar())) + foo8(y, >")!>Foo(Bar())) + + foo9(x, >")!>Foo(Bar())) + foo9(y, >")!>Foo(Bar())) + + foo10(x, >")!>Foo(Bar()), ")!>Bar()) + foo10(y, >")!>Foo(Bar()), ")!>Bar()) + + foo11(x, >")!>Foo(Bar()), ")!>Bar()) + foo11(y, >")!>Foo(Bar()), ")!>Bar()) + + if (x != null && y != null) { + foo12(x, ")!>Bar()) + foo12(y, ")!>Bar()) + } + + foo12(x, ")!>Bar()) + foo12(y, ")!>Bar()) + + Foo13(x).foo1(x, ")!>Bar()) + Foo13(x).foo2(y, ")!>Bar()) + Foo13(y).foo1(x, ")!>Bar()) + Foo13(y).foo2(y, ")!>Bar()) + if (x != null) { + Foo13(x).foo2(y, ")!>Bar()) + Foo13(y).foo2(x, ")!>Bar()) + } + if (y != null) { + Foo13(x).foo2(y, ")!>Bar()) + Foo13(y).foo2(x, ")!>Bar()) + } + + foo14("y", ")!>Bar()) + foo14("x", ")!>Bar()) + + foo15(x, ")!>Bar()) + foo15(y, ")!>Bar()) + if (x != null && y != null) { + foo15(x, ")!>Bar()) + foo15(y, ")!>Bar()) + } + + foo16(x, ")!>Bar()) + foo16(y, ")!>Bar()) + if (x != null && y != null) { + foo16(x, ")!>Bar()) + foo16(y, ")!>Bar()) + } + + Bar().foo18(x) + Bar().foo18(y) + + foo21(x, >>")!>Foo(Foo(OutBar()))) + foo21(y, >>")!>Foo(Foo(OutBar()))) + + foo22(x, >>")!>Foo(Foo(InBar()))) + foo22(y, >>")!>Foo(Foo(InBar()))) + + foo23(x, >>")!>Foo(Foo(Bar()))) + foo23(y, >>")!>Foo(Foo(Bar()))) + + foo24(x, >>")!>Foo(Foo(Bar()))) + foo24(y, >>")!>Foo(Foo(Bar()))) +} diff --git a/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInArguments.txt b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInArguments.txt new file mode 100644 index 00000000000..7b9cdfda2f2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInArguments.txt @@ -0,0 +1,61 @@ +package + +public fun foo0(/*0*/ x: K?, /*1*/ y: Bar): kotlin.Unit +public fun foo1(/*0*/ x: K?, /*1*/ y: Foo>): kotlin.Unit +public fun foo10(/*0*/ x: L?, /*1*/ y: Foo>, /*2*/ z: Bar): kotlin.Unit +public fun foo11(/*0*/ x: M?, /*1*/ y: Foo>, /*2*/ z: Bar): kotlin.Unit +public fun foo12(/*0*/ x: K?, /*1*/ y: Bar): kotlin.Unit +public fun > foo14(/*0*/ x: K?, /*1*/ y: Bar): kotlin.Unit where K : kotlin.CharSequence +public fun foo15(/*0*/ x: T, /*1*/ y: Bar): kotlin.Unit +public fun foo16(/*0*/ x: K, /*1*/ y: Bar): kotlin.Unit +public fun foo2(/*0*/ x: K?, /*1*/ y: Foo>): kotlin.Unit +public fun foo21(/*0*/ x: K?, /*1*/ y: Foo>>): kotlin.Unit +public fun foo22(/*0*/ x: K?, /*1*/ y: Foo>>): kotlin.Unit +public fun foo23(/*0*/ x: K?, /*1*/ y: Foo>>): kotlin.Unit +public fun foo24(/*0*/ x: K?, /*1*/ y: Foo>>): kotlin.Unit +public fun foo3(/*0*/ x: K?, /*1*/ y: Foo>): kotlin.Unit +public fun foo4(/*0*/ x: K?, /*1*/ y: Foo>): kotlin.Unit +public fun foo5(/*0*/ x: K?, /*1*/ y: Bar): kotlin.Unit +public fun foo6(/*0*/ x: K?, /*1*/ y: OutBar): kotlin.Unit +public fun foo7(/*0*/ x: K?, /*1*/ y: InBar): kotlin.Unit +public fun foo8(/*0*/ x: T?, /*1*/ y: Foo>): kotlin.Unit +public fun foo9(/*0*/ x: M?, /*1*/ y: Foo>): kotlin.Unit +public fun main(/*0*/ x: L?, /*1*/ y: L): kotlin.Unit +public fun Bar.foo18(/*0*/ x: T): kotlin.Unit + +public final class Bar { + public constructor Bar() + 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 Foo { + public constructor Foo(/*0*/ x: T) + 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 Foo13 { + public constructor Foo13(/*0*/ x: T) + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo1(/*0*/ x: T?, /*1*/ y: Bar): kotlin.Unit + public final fun foo2(/*0*/ x: K?, /*1*/ y: Bar): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class InBar { + public constructor InBar() + 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 OutBar { + public constructor OutBar() + 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 +} diff --git a/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInReturnPosition.fir.kt b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInReturnPosition.fir.kt new file mode 100644 index 00000000000..f8905b49a0b --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInReturnPosition.fir.kt @@ -0,0 +1,278 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION -CAST_NEVER_SUCCEEDS -UNUSED_VARIABLE -UNCHECKED_CAST + +class Foo(x: T) +class Bar +class OutBar +class InBar + +interface IBar +interface IFoo + +typealias OutBarAliasUseSite = Bar +typealias OutBarAliasDecSite = OutBar + +fun materialize(): T = null as T + +fun foo0(x: K?): Bar = materialize() +fun foo1(x: K?): Foo> = materialize() +fun foo2(x: K?): Foo> = materialize() +fun foo3(x: K?): Foo> = materialize() +fun foo4(x: K?): Foo> = materialize() +fun foo5(x: K?): Bar = materialize() +fun foo6(x: K?): OutBar = materialize() +fun foo7(x: K?): InBar = materialize() +fun foo8(x: T?): Foo> = materialize() +fun foo9(x: M?): Foo> = materialize() +fun foo10(x: L?, y: Foo>): Bar = materialize() +fun foo11(x: M?, y: Foo>): Bar = materialize() +fun foo12(x: K?): Bar = materialize() + +class Foo13(x: T) { + fun foo1(x: K?): Bar = materialize() +} + +fun foo14(x: K?): Bar where K: Comparable, K: CharSequence = materialize() +fun foo15(x: T): Bar = materialize() +fun foo16(x: K): Bar = materialize() +fun foo17(x: K): Bar = null as Bar +fun foo19(x: Bar): K = null as K +fun Bar.foo20(): K = null as K + +fun foo21(x: K?): Foo>> = materialize() +fun foo22(x: K?): Foo>> = materialize() +fun foo23(x: K?): Foo>> = materialize() +fun foo24(x: K?): Foo>> = materialize() + +fun foo25(x: K?): Bar = materialize() +fun foo26(x: K?): Foo>> = materialize() +fun foo27(x: K?): Foo>> = materialize() +fun foo28(x: K?): OutBar>> = materialize() +fun foo29(x: K?): OutBar>> = materialize() +fun foo30(x: K?): OutBar>> = materialize() +fun foo31(x: K?): OutBarAliasUseSite = materialize() +fun foo32(x: K?): OutBarAliasDecSite = materialize() +fun foo33(x: K?): OutBar>> = materialize() +fun foo34(x: K?): OutBar>> = materialize() +fun foo35(x: K?): InBar = materialize() +fun foo36(x: K?): Bar = materialize() +fun > foo37(x: K?): T = materialize() +fun , S: Bar> foo38(x: K?): T = materialize() +fun , S: Bar> foo39(x: K?): Bar = materialize() +fun > foo40(x: K?): Bar = materialize() +fun > foo41(x: K?): T = materialize() +fun foo42(x: K?): T where T: IFoo = materialize() +fun foo43(x: K?): T where T: IBar, T: IFoo = materialize() +fun foo44(x: K?): T where S: IFoo, S: IBar = materialize() +fun , S: Bar> foo45(x: K?): OutBar = materialize() +fun , S: OutBar> foo46(x: K?): Bar = materialize() +fun , S: OutBar> foo47(x: K?): OutBar = materialize() +fun foo48(fn: Function0): Bar = materialize() + +val K?.vfoo0: Foo> get() = materialize() +val K?.vfoo1: OutBar>> get() = materialize() +val K?.vfoo2: OutBar>> get() = materialize() + +class Main(x: L?, y: L) { + init { + if (x != null && y != null) { + val x12 = foo1(x) + val x13 = foo1(y) + } + if (x != null && y != null) { + val x120 = foo12(x) + val x121 = foo12(y) + } + if (x != null) { + val x137 = Foo13(y).foo1(x) + } + if (y != null) { + val x138 = Foo13(x).foo1(y) + } + if (x != null && y != null) { + val x153 = foo15(x) + val x154 = foo15(y) + } + if (x != null && y != null) { + val x163 = foo16(x) + val x164 = foo16(y) + } + } + + val x00 = foo0(x) + val x01 = foo0(y) + + val x10 = foo1(x) + val x11 = foo1(y) + + val x12 = foo1(x!!) + val x13 = foo1(y!!) + + val x20 = foo2(x) + val x21 = foo2(y) + + val x30 = foo3(x) + val x31 = foo3(y) + + val x40 = foo4(x) + val x41 = foo4(y) + + val x50 = foo5(x) + val x51 = foo5(y) + + val x60 = foo6(x) + val x61 = foo6(y) + + val x70 = foo7(x) + val x71 = foo7(y) + + val x80 = foo8(x) + val x81 = foo8(y) + + val x90 = foo9(x) + val x91 = foo9(y) + + val x100 = foo10(x, Foo(Bar())) + val x101 = foo10(y, Foo(Bar())) + + val x110 = foo11(x, Foo(Bar())) + val x111 = foo11(y, Foo(Bar())) + + val x120 = foo12(x!!) + val x121 = foo12(y!!) + + val x122 = foo12(x) + val x123 = foo12(y) + + val x133 = Foo13(x).foo1(y) + val x135 = Foo13(y).foo1(y) + val x137 = Foo13(y).foo1(x!!) + val x138 = Foo13(x).foo1(y!!) + + val x140 = foo14("y") + val x141 = foo14("x") + + val x151 = foo15(x) + val x152 = foo15(y) + val x153 = foo15(x!!) + val x154 = foo15(y!!) + + val x161 = foo16(x) + val x162 = foo16(y) + val x163 = foo16(x!!) + val x164 = foo16(y!!) + + val x170 = foo17(x) + val x171 = foo17(y) + + val x180 = Bar().foo18(x) + val x181 = Bar().foo18(y) + + val x200: L = Bar().foo19() + val x201: L = Bar().foo19() + + val x210 = foo21(x) + val x211 = foo21(y) + + val x220 = foo22(x) + val x221 = foo22(y) + + val x230 = foo23(x) + val x231 = foo23(y) + + val x240 = foo24(x) + val x241 = foo24(y) + + val x250 = foo25(x) + val x251 = foo25(y) + + val x260 = foo26(x) + val x261 = foo26(y) + + val x270 = foo27(x) + val x271 = foo27(y) + + val x280 = foo28(x) + val x281 = foo28(y) + + val x290 = foo29(x) + val x291 = foo29(y) + + val x300 = foo30(x) + val x301 = foo30(y) + + val x310 = foo31(x) + val x311 = foo31(y) + + val x320 = foo32(x) + val x321 = foo32(y) + + val x330 = foo33(x) + val x331 = foo33(y) + + val x340 = foo34(x) + val x341 = foo34(y) + + val x350 = foo35(x) + val x351 = foo35(y) + + val x360 = foo36(x) + val x361 = foo36(y) + + val vx01 = x.vfoo0 + val vx02 = y.vfoo0 + + val vx11 = x.vfoo1 + val vx12 = y.vfoo1 + + val vx21 = x.vfoo2 + val vx22 = y.vfoo2 + + val x370 = foo37(x) + val x371 = foo37(y) + + val x380 = foo38(x) + val x381 = foo38(y) + + val x390 = foo39(x) + val x391 = foo39(y) + + val x400 = foo40(x) + val x401 = foo40(y) + + val x410 = foo41(x) + val x411 = foo41(y) + + val x420 = foo42(x) + val x421 = foo42(y) + + val x430 = foo43(x) + val x431 = foo43(y) + + val x440 = foo44(x) + val x441 = foo44(y) + + val x450 = foo45(x) + val x451 = foo45(y) + + val x460 = foo46(x) + val x461 = foo46(y) + + val x470 = foo47(x) + val x471 = foo47(y) + + fun takeLambda(block: () -> R): R = materialize() + val x480 = takeLambda { foo48 { x } } + val x481 = takeLambda { foo48 { y } } + val x482 = takeLambda { foo48 { null } } +} + +fun > nullsLast() = null as Foo +fun take(x: Foo, comparator: Foo): Foo {} +fun test() { + take(null as Foo, nullsLast()) +} + +class Inv1 +class Inv2 +fun > Inv1.assertStableSorted() {} +fun > Inv2.assertStableSorted() = Inv1().assertStableSorted() diff --git a/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInReturnPosition.kt b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInReturnPosition.kt new file mode 100644 index 00000000000..332417051ff --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInReturnPosition.kt @@ -0,0 +1,278 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION -CAST_NEVER_SUCCEEDS -UNUSED_VARIABLE -UNCHECKED_CAST + +class Foo(x: T) +class Bar +class OutBar +class InBar + +interface IBar +interface IFoo + +typealias OutBarAliasUseSite = Bar +typealias OutBarAliasDecSite = OutBar + +fun materialize(): T = null as T + +fun foo0(x: K?): Bar = materialize() +fun foo1(x: K?): Foo> = materialize() +fun foo2(x: K?): Foo> = materialize() +fun foo3(x: K?): Foo> = materialize() +fun foo4(x: K?): Foo> = materialize() +fun foo5(x: K?): Bar = materialize() +fun foo6(x: K?): OutBar = materialize() +fun foo7(x: K?): InBar = materialize() +fun foo8(x: T?): Foo> = materialize() +fun foo9(x: M?): Foo> = materialize() +fun foo10(x: L?, y: Foo>): Bar = materialize() +fun foo11(x: M?, y: Foo>): Bar = materialize() +fun foo12(x: K?): Bar = materialize() + +class Foo13(x: T) { + fun foo1(x: K?): Bar = materialize() +} + +fun foo14(x: K?): Bar where K: Comparable, K: CharSequence = materialize() +fun foo15(x: T): Bar = materialize() +fun foo16(x: K): Bar = materialize() +fun foo17(x: K): Bar = null as Bar +fun foo19(x: Bar): K = null as K +fun Bar.foo20(): K = null as K + +fun foo21(x: K?): Foo>> = materialize() +fun foo22(x: K?): Foo>> = materialize() +fun foo23(x: K?): Foo>> = materialize() +fun foo24(x: K?): Foo>> = materialize() + +fun foo25(x: K?): Bar = materialize() +fun foo26(x: K?): Foo>> = materialize() +fun foo27(x: K?): Foo>> = materialize() +fun foo28(x: K?): OutBar>> = materialize() +fun foo29(x: K?): OutBar>> = materialize() +fun foo30(x: K?): OutBar>> = materialize() +fun foo31(x: K?): OutBarAliasUseSite = materialize() +fun foo32(x: K?): OutBarAliasDecSite = materialize() +fun foo33(x: K?): OutBar>> = materialize() +fun foo34(x: K?): OutBar>> = materialize() +fun foo35(x: K?): InBar = materialize() +fun foo36(x: K?): Bar = materialize() +fun > foo37(x: K?): T = materialize() +fun , S: Bar> foo38(x: K?): T = materialize() +fun , S: Bar> foo39(x: K?): Bar = materialize() +fun > foo40(x: K?): Bar = materialize() +fun > foo41(x: K?): T = materialize() +fun foo42(x: K?): T where T: IFoo = materialize() +fun foo43(x: K?): T where T: IBar, T: IFoo = materialize() +fun foo44(x: K?): T where S: IFoo, S: IBar = materialize() +fun , S: Bar> foo45(x: K?): OutBar = materialize() +fun , S: OutBar> foo46(x: K?): Bar = materialize() +fun , S: OutBar> foo47(x: K?): OutBar = materialize() +fun foo48(fn: Function0): Bar = materialize() + +val K?.vfoo0: Foo> get() = materialize() +val K?.vfoo1: OutBar>> get() = materialize() +val K?.vfoo2: OutBar>> get() = materialize() + +class Main(x: L?, y: L) { + init { + if (x != null && y != null) { + val x12 = >")!>foo1(x) + val x13 = >")!>foo1(y) + } + if (x != null && y != null) { + val x120 = ")!>foo12(x) + val x121 = ")!>foo12(y) + } + if (x != null) { + val x137 = ")!>Foo13(y).foo1(x) + } + if (y != null) { + val x138 = ")!>Foo13(x).foo1(y) + } + if (x != null && y != null) { + val x153 = ")!>foo15(x) + val x154 = ")!>foo15(y) + } + if (x != null && y != null) { + val x163 = ")!>foo16(x) + val x164 = ")!>foo16(y) + } + } + + val x00 = ")!>foo0(x) + val x01 = ")!>foo0(y) + + val x10 = >")!>foo1(x) + val x11 = >")!>foo1(y) + + val x12 = >")!>foo1(x!!) + val x13 = >")!>foo1(y!!) + + val x20 = >")!>foo2(x) + val x21 = >")!>foo2(y) + + val x30 = >")!>foo3(x) + val x31 = >")!>foo3(y) + + val x40 = >")!>foo4(x) + val x41 = >")!>foo4(y) + + val x50 = ")!>foo5(x) + val x51 = ")!>foo5(y) + + val x60 = ")!>foo6(x) + val x61 = ")!>foo6(y) + + val x70 = ")!>foo7(x) + val x71 = ")!>foo7(y) + + val x80 = >")!>foo8(x) + val x81 = >")!>foo8(y) + + val x90 = >")!>foo9(x) + val x91 = >")!>foo9(y) + + val x100 = ")!>foo10(x, >")!>Foo(Bar())) + val x101 = ")!>foo10(y, >")!>Foo(Bar())) + + val x110 = ")!>foo11(x, >")!>Foo(Bar())) + val x111 = ")!>foo11(y, >")!>Foo(Bar())) + + val x120 = ")!>foo12(x!!) + val x121 = ")!>foo12(y!!) + + val x122 = ")!>foo12(x) + val x123 = ")!>foo12(y) + + val x133 = ")!>Foo13(x).foo1(y) + val x135 = ")!>Foo13(y).foo1(y) + val x137 = ")!>Foo13(y).foo1(x!!) + val x138 = ")!>Foo13(x).foo1(y!!) + + val x140 = ")!>foo14("y") + val x141 = ")!>foo14("x") + + val x151 = ")!>foo15(x) + val x152 = ")!>foo15(y) + val x153 = ")!>foo15(x!!) + val x154 = ")!>foo15(y!!) + + val x161 = ")!>foo16(x) + val x162 = ")!>foo16(y) + val x163 = ")!>foo16(x!!) + val x164 = ")!>foo16(y!!) + + val x170 = ")!>foo17(x) + val x171 = ")!>foo17(y) + + val x180 = Bar().foo18(x) + val x181 = Bar().foo18(y) + + val x200: L = Bar().foo19() + val x201: L = Bar().foo19() + + val x210 = >>")!>foo21(x) + val x211 = >>")!>foo21(y) + + val x220 = >>")!>foo22(x) + val x221 = >>")!>foo22(y) + + val x230 = >>")!>foo23(x) + val x231 = >>")!>foo23(y) + + val x240 = >>")!>foo24(x) + val x241 = >>")!>foo24(y) + + val x250 = ")!>foo25(x) + val x251 = ")!>foo25(y) + + val x260 = >>")!>foo26(x) + val x261 = >>")!>foo26(y) + + val x270 = >>")!>foo27(x) + val x271 = >>")!>foo27(y) + + val x280 = >>")!>foo28(x) + val x281 = >>")!>foo28(y) + + val x290 = >>")!>foo29(x) + val x291 = >>")!>foo29(y) + + val x300 = >>")!>foo30(x) + val x301 = >>")!>foo30(y) + + val x310 = /* = Bar */")!>foo31(x) + val x311 = /* = Bar */")!>foo31(y) + + val x320 = /* = OutBar */")!>foo32(x) + val x321 = /* = OutBar */")!>foo32(y) + + val x330 = >>")!>foo33(x) + val x331 = >>")!>foo33(y) + + val x340 = >>")!>foo34(x) + val x341 = >>")!>foo34(y) + + val x350 = ")!>foo35(x) + val x351 = ")!>foo35(y) + + val x360 = ")!>foo36(x) + val x361 = ")!>foo36(y) + + val vx01 = >")!>x.vfoo0 + val vx02 = >")!>y.vfoo0 + + val vx11 = >>")!>x.vfoo1 + val vx12 = >>")!>y.vfoo1 + + val vx21 = >>")!>x.vfoo2 + val vx22 = >>")!>y.vfoo2 + + val x370 = ")!>foo37(x) + val x371 = ")!>foo37(y) + + val x380 = >")!>foo38(x) + val x381 = >")!>foo38(y) + + val x390 = >>")!>foo39(x) + val x391 = >>")!>foo39(y) + + val x400 = >")!>foo40(x) + val x401 = >")!>foo40(y) + + val x410 = ")!>foo41(x) + val x411 = ")!>foo41(y) + + val x420 = ")!>foo42(x) + val x421 = ")!>foo42(y) + + val x430 = & IFoo}")!>foo43(x) + val x431 = & IFoo}")!>foo43(y) + + val x440 = & IBar & IFoo}")!>foo44(x) + val x441 = & IBar & IFoo}")!>foo44(y) + + val x450 = >>")!>foo45(x) + val x451 = >>")!>foo45(y) + + val x460 = >>")!>foo46(x) + val x461 = >>")!>foo46(y) + + val x470 = >>")!>foo47(x) + val x471 = >>")!>foo47(y) + + fun takeLambda(block: () -> R): R = materialize() + val x480 = ")!>takeLambda { foo48 { x } } + val x481 = ")!>takeLambda { foo48 { y } } + val x482 = ")!>takeLambda { foo48 { null } } +} + +fun > nullsLast() = null as Foo +fun take(x: Foo, comparator: Foo): Foo {} +fun test() { + ")!>take(null as Foo, ")!>nullsLast()) +} + +class Inv1 +class Inv2 +fun > Inv1.assertStableSorted() {} +fun > Inv2.assertStableSorted() = Inv1().assertStableSorted() diff --git a/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInReturnPosition.txt b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInReturnPosition.txt new file mode 100644 index 00000000000..35f47211e72 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInReturnPosition.txt @@ -0,0 +1,243 @@ +package + +public val K?.vfoo0: Foo> +public val K?.vfoo1: OutBar>> +public val K?.vfoo2: OutBar>> +public fun foo0(/*0*/ x: K?): Bar +public fun foo1(/*0*/ x: K?): Foo> +public fun foo10(/*0*/ x: L?, /*1*/ y: Foo>): Bar +public fun foo11(/*0*/ x: M?, /*1*/ y: Foo>): Bar +public fun foo12(/*0*/ x: K?): Bar +public fun > foo14(/*0*/ x: K?): Bar where K : kotlin.CharSequence +public fun foo15(/*0*/ x: T): Bar +public fun foo16(/*0*/ x: K): Bar +public fun foo17(/*0*/ x: K): Bar +public fun foo19(/*0*/ x: Bar): K +public fun foo2(/*0*/ x: K?): Foo> +public fun foo21(/*0*/ x: K?): Foo>> +public fun foo22(/*0*/ x: K?): Foo>> +public fun foo23(/*0*/ x: K?): Foo>> +public fun foo24(/*0*/ x: K?): Foo>> +public fun foo25(/*0*/ x: K?): Bar +public fun foo26(/*0*/ x: K?): Foo>> +public fun foo27(/*0*/ x: K?): Foo>> +public fun foo28(/*0*/ x: K?): OutBar>> +public fun foo29(/*0*/ x: K?): OutBar>> +public fun foo3(/*0*/ x: K?): Foo> +public fun foo30(/*0*/ x: K?): OutBar>> +public fun foo31(/*0*/ x: K?): OutBarAliasUseSite /* = Bar */ +public fun foo32(/*0*/ x: K?): OutBarAliasDecSite /* = OutBar */ +public fun foo33(/*0*/ x: K?): OutBar>> +public fun foo34(/*0*/ x: K?): OutBar>> +public fun foo35(/*0*/ x: K?): InBar +public fun foo36(/*0*/ x: K?): Bar +public fun > foo37(/*0*/ x: K?): T +public fun , /*2*/ S : Bar> foo38(/*0*/ x: K?): T +public fun , /*2*/ S : Bar> foo39(/*0*/ x: K?): Bar +public fun foo4(/*0*/ x: K?): Foo> +public fun > foo40(/*0*/ x: K?): Bar +public fun > foo41(/*0*/ x: K?): T +public fun > foo42(/*0*/ x: K?): T +public fun > foo43(/*0*/ x: K?): T where T : IFoo +public fun , /*2*/ T : S> foo44(/*0*/ x: K?): T where S : IBar +public fun , /*2*/ S : Bar> foo45(/*0*/ x: K?): OutBar +public fun , /*2*/ S : OutBar> foo46(/*0*/ x: K?): Bar +public fun , /*2*/ S : OutBar> foo47(/*0*/ x: K?): OutBar +public fun foo48(/*0*/ fn: () -> U?): Bar +public fun foo5(/*0*/ x: K?): Bar +public fun foo6(/*0*/ x: K?): OutBar +public fun foo7(/*0*/ x: K?): InBar +public fun foo8(/*0*/ x: T?): Foo> +public fun foo9(/*0*/ x: M?): Foo> +public fun materialize(): T +public fun > nullsLast(): Foo +public fun take(/*0*/ x: Foo, /*1*/ comparator: Foo): Foo +public fun test(): kotlin.Unit +public fun > Inv1.assertStableSorted(): kotlin.Unit +public fun > Inv2.assertStableSorted(): kotlin.Unit +public fun Bar.foo20(): K + +public final class Bar { + public constructor Bar() + 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 Foo { + public constructor Foo(/*0*/ x: T) + 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 Foo13 { + public constructor Foo13(/*0*/ x: T) + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo1(/*0*/ x: K?): Bar + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface IBar { + 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 interface IFoo { + 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 InBar { + public constructor InBar() + 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 Inv1 { + public constructor Inv1() + 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 Inv2 { + public constructor Inv2() + 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 Main { + public constructor Main(/*0*/ x: L?, /*1*/ y: L) + public final val vx01: Foo> + public final val vx02: Foo> + public final val vx11: OutBar>> + public final val vx12: OutBar>> + public final val vx21: OutBar>> + public final val vx22: OutBar>> + public final val x00: Bar + public final val x01: Bar + public final val x10: Foo> + public final val x100: Bar + public final val x101: Bar + public final val x11: Foo> + public final val x110: Bar + public final val x111: Bar + public final val x12: Foo> + public final val x120: Bar + public final val x121: Bar + public final val x122: Bar + public final val x123: Bar + public final val x13: Foo> + public final val x133: Bar + public final val x135: Bar + public final val x137: Bar + public final val x138: Bar + public final val x140: Bar + public final val x141: Bar + public final val x151: Bar + public final val x152: Bar + public final val x153: Bar + public final val x154: Bar + public final val x161: Bar + public final val x162: Bar + public final val x163: Bar + public final val x164: Bar + public final val x170: Bar + public final val x171: Bar + public final val x180: [ERROR : ] + public final val x181: [ERROR : ] + public final val x20: Foo> + public final val x200: L + public final val x201: L + public final val x21: Foo> + public final val x210: Foo>> + public final val x211: Foo>> + public final val x220: Foo>> + public final val x221: Foo>> + public final val x230: Foo>> + public final val x231: Foo>> + public final val x240: Foo>> + public final val x241: Foo>> + public final val x250: Bar + public final val x251: Bar + public final val x260: Foo>> + public final val x261: Foo>> + public final val x270: Foo>> + public final val x271: Foo>> + public final val x280: OutBar>> + public final val x281: OutBar>> + public final val x290: OutBar>> + public final val x291: OutBar>> + public final val x30: Foo> + public final val x300: OutBar>> + public final val x301: OutBar>> + public final val x31: Foo> + public final val x310: Bar + public final val x311: Bar + public final val x320: OutBar + public final val x321: OutBar + public final val x330: OutBar>> + public final val x331: OutBar>> + public final val x340: OutBar>> + public final val x341: OutBar>> + public final val x350: InBar + public final val x351: InBar + public final val x360: Bar + public final val x361: Bar + public final val x370: Bar + public final val x371: Bar + public final val x380: Bar> + public final val x381: Bar> + public final val x390: Bar>> + public final val x391: Bar>> + public final val x40: Foo> + public final val x400: Bar> + public final val x401: Bar> + public final val x41: Foo> + public final val x410: Bar + public final val x411: Bar + public final val x420: IFoo + public final val x421: IFoo + public final val x430: kotlin.Any + public final val x431: kotlin.Any + public final val x440: kotlin.Any + public final val x441: kotlin.Any + public final val x450: OutBar>> + public final val x451: OutBar>> + public final val x460: Bar>> + public final val x461: Bar>> + public final val x470: OutBar>> + public final val x471: OutBar>> + public final val x480: Bar + public final val x481: Bar + public final val x482: Bar + public final val x50: Bar + public final val x51: Bar + public final val x60: OutBar + public final val x61: OutBar + public final val x70: InBar + public final val x71: InBar + public final val x80: Foo> + public final val x81: Foo> + public final val x90: Foo> + public final val x91: Foo> + 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 final fun takeLambda(/*0*/ block: () -> R): R + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class OutBar { + public constructor OutBar() + 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 typealias OutBarAliasDecSite = OutBar +public typealias OutBarAliasUseSite = Bar diff --git a/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInvariantPosition.fir.kt b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInvariantPosition.fir.kt index 8b1bbe80eb4..59f44e66b4e 100644 --- a/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInvariantPosition.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInvariantPosition.fir.kt @@ -1,4 +1,4 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION -UNUSED_VARIABLE class Inv(val x: T?) @@ -21,4 +21,4 @@ fun test(i: Int, s: S) { c takeInvInt(create(i)) -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInvariantPosition.kt b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInvariantPosition.kt index 79e74d4eed3..f9d98d333d4 100644 --- a/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInvariantPosition.kt +++ b/compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInvariantPosition.kt @@ -1,8 +1,8 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION -UNUSED_VARIABLE class Inv(val x: T?) -fun create(y: K) = Inv(y) +fun create(y: K) = ")!>Inv(y) fun createPrivate(y: K) = Inv(y) fun takeInvInt(i: Inv) {} @@ -21,4 +21,4 @@ fun test(i: Int, s: S) { ")!>c takeInvInt(create(i)) -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.fir.kt b/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.fir.kt index 017be489027..b0fba7f2052 100644 --- a/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.fir.kt @@ -1,4 +1,12 @@ -fun foo(x: Array, y: Array) { +fun foo1(x: Array, y: Array) { + val xo = outANullable(x) + val yo = inANullable(y) + + var f: Array = xo + f = yo +} + +fun foo2(x: Array, y: Array) { val xo = outA(x) val yo = inA(y) @@ -6,6 +14,18 @@ fun foo(x: Array, y: Array) { f = yo } +class A1(x: Array, y: Array) { + val xo = outANullable(x) + val yo = inANullable(y) +} -fun outA(x: Array): Array = TODO() -fun inA(x: Array): Array = TODO() \ No newline at end of file +class A2(x: Array, y: Array) { + val xo = outA(x) + val yo = inA(y) +} + +fun outANullable(x: Array): Array = TODO() +fun inANullable(x: Array): Array = TODO() + +fun outA(x: Array): Array = TODO() +fun inA(x: Array): Array = TODO() diff --git a/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.kt b/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.kt index 67da957de5c..c37436aff76 100644 --- a/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.kt +++ b/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.kt @@ -1,11 +1,31 @@ -fun foo(x: Array, y: Array) { - val xo = outA(x) - val yo = inA(y) +fun foo1(x: Array, y: Array) { + val xo = ")!>outANullable(x) + val yo = ")!>inANullable(y) var f: Array = xo f = yo } +fun foo2(x: Array, y: Array) { + val xo = ")!>outA(x) + val yo = ")!>inA(y) -fun outA(x: Array): Array = TODO() -fun inA(x: Array): Array = TODO() \ No newline at end of file + var f: Array = xo + f = yo +} + +class A1(x: Array, y: Array) { + val xo = ")!>outANullable(x) + val yo = ")!>inANullable(y) +} + +class A2(x: Array, y: Array) { + val xo = ")!>outA(x) + val yo = ")!>inA(y) +} + +fun outANullable(x: Array): Array = TODO() +fun inANullable(x: Array): Array = TODO() + +fun outA(x: Array): Array = TODO() +fun inA(x: Array): Array = TODO() diff --git a/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.txt b/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.txt index ef7cfe651be..ddfae19dd56 100644 --- a/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.txt +++ b/compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.txt @@ -1,5 +1,26 @@ package -public fun foo(/*0*/ x: kotlin.Array, /*1*/ y: kotlin.Array): kotlin.Unit -public fun inA(/*0*/ x: kotlin.Array): kotlin.Array -public fun outA(/*0*/ x: kotlin.Array): kotlin.Array +public fun foo1(/*0*/ x: kotlin.Array, /*1*/ y: kotlin.Array): kotlin.Unit +public fun foo2(/*0*/ x: kotlin.Array, /*1*/ y: kotlin.Array): kotlin.Unit +public fun inA(/*0*/ x: kotlin.Array): kotlin.Array +public fun inANullable(/*0*/ x: kotlin.Array): kotlin.Array +public fun outA(/*0*/ x: kotlin.Array): kotlin.Array +public fun outANullable(/*0*/ x: kotlin.Array): kotlin.Array + +public final class A1 { + public constructor A1(/*0*/ x: kotlin.Array, /*1*/ y: kotlin.Array) + public final val xo: kotlin.Array + public final val yo: kotlin.Array + 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 A2 { + public constructor A2(/*0*/ x: kotlin.Array, /*1*/ y: kotlin.Array) + public final val xo: kotlin.Array + public final val yo: kotlin.Array + 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 +} diff --git a/compiler/testData/diagnostics/tests/inference/upperBounds/flexibilityInCommonSuperTypeCalculation.ni.kt b/compiler/testData/diagnostics/tests/inference/upperBounds/flexibilityInCommonSuperTypeCalculation.ni.kt index 9d3943e6ef5..2ea53605e6f 100644 --- a/compiler/testData/diagnostics/tests/inference/upperBounds/flexibilityInCommonSuperTypeCalculation.ni.kt +++ b/compiler/testData/diagnostics/tests/inference/upperBounds/flexibilityInCommonSuperTypeCalculation.ni.kt @@ -169,8 +169,8 @@ fun case_11(y: T) { x3 y - ")!>result_1 - ")!>result_2 + ")!>result_1 + ")!>result_2 ")!>result_3 ")!>result_4 ")!>result_5 diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index da181d9f8d6..85c935af8b9 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -10732,6 +10732,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali runTest("compiler/testData/diagnostics/tests/inference/constraints/constraintOnFunctionLiteral.kt"); } + @TestMetadata("definitelyNotNullTypeInArguments.kt") + public void testDefinitelyNotNullTypeInArguments() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInArguments.kt"); + } + + @TestMetadata("definitelyNotNullTypeInReturnPosition.kt") + public void testDefinitelyNotNullTypeInReturnPosition() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInReturnPosition.kt"); + } + @TestMetadata("definitelyNotNullTypeInvariantPosition.kt") public void testDefinitelyNotNullTypeInvariantPosition() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInvariantPosition.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 2588099bd4c..58ef683da6e 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -10727,6 +10727,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/inference/constraints/constraintOnFunctionLiteral.kt"); } + @TestMetadata("definitelyNotNullTypeInArguments.kt") + public void testDefinitelyNotNullTypeInArguments() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInArguments.kt"); + } + + @TestMetadata("definitelyNotNullTypeInReturnPosition.kt") + public void testDefinitelyNotNullTypeInReturnPosition() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInReturnPosition.kt"); + } + @TestMetadata("definitelyNotNullTypeInvariantPosition.kt") public void testDefinitelyNotNullTypeInvariantPosition() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/constraints/definitelyNotNullTypeInvariantPosition.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/SpecialTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/types/SpecialTypes.kt index 4882e66ef8e..2b6281fe12a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/SpecialTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/SpecialTypes.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner +import org.jetbrains.kotlin.types.checker.NewCapturedType import org.jetbrains.kotlin.types.checker.NewTypeVariableConstructor import org.jetbrains.kotlin.types.checker.NullabilityChecker import org.jetbrains.kotlin.types.model.DefinitelyNotNullTypeMarker @@ -150,6 +151,9 @@ fun SimpleType.makeSimpleTypeDefinitelyNotNullOrNotNull(): SimpleType = ?: makeIntersectionTypeDefinitelyNotNullOrNotNull() ?: makeNullableAsSpecified(false) +fun NewCapturedType.withNotNullProjection() = + NewCapturedType(captureStatus, constructor, lowerType, annotations, isMarkedNullable, isProjectionNotNull = true) + fun UnwrappedType.makeDefinitelyNotNullOrNotNull(): UnwrappedType = DefinitelyNotNullType.makeDefinitelyNotNull(this) ?: makeIntersectionTypeDefinitelyNotNullOrNotNull() 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 406396a66cf..538c9663ba6 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -405,6 +405,17 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy return this.constructor.projection } + override fun CapturedTypeMarker.withNotNullProjection(): KotlinTypeMarker { + require(this is NewCapturedType, this::errorMessage) + + return NewCapturedType(captureStatus, constructor, lowerType, annotations, isMarkedNullable, isProjectionNotNull = true) + } + + override fun CapturedTypeMarker.isProjectionNotNull(): Boolean { + require(this is NewCapturedType, this::errorMessage) + return this.isProjectionNotNull + } + override fun CapturedTypeMarker.typeParameter(): TypeParameterMarker? { require(this is NewCapturedType, this::errorMessage) return this.constructor.typeParameter diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/IntersectionType.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/IntersectionType.kt index 9a0b9cf5e31..6f289331677 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/IntersectionType.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/IntersectionType.kt @@ -94,7 +94,9 @@ object TypeIntersector { * and other types is captured types or type parameters without not-null upper bound. Example: `String? & T` such types we should leave as is. */ val correctNullability = inputTypes.mapTo(LinkedHashSet()) { - if (resultNullability == ResultNullability.NOT_NULL) it.makeSimpleTypeDefinitelyNotNullOrNotNull() else it + if (resultNullability == ResultNullability.NOT_NULL) { + (if (it is NewCapturedType) it.withNotNullProjection() else it).makeSimpleTypeDefinitelyNotNullOrNotNull() + } else it } return intersectTypesWithoutIntersectionType(correctNullability) diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewCapturedType.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewCapturedType.kt index 06a26934326..67ae00f59f0 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewCapturedType.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewCapturedType.kt @@ -110,7 +110,8 @@ class NewCapturedType( override val constructor: NewCapturedTypeConstructor, val lowerType: UnwrappedType?, // todo check lower type for nullable captured types override val annotations: Annotations = Annotations.EMPTY, - override val isMarkedNullable: Boolean = false + override val isMarkedNullable: Boolean = false, + val isProjectionNotNull: Boolean = false ) : SimpleType(), CapturedTypeMarker { internal constructor( captureStatus: CaptureStatus, lowerType: UnwrappedType?, projection: TypeProjection, typeParameter: TypeParameterDescriptor diff --git a/core/type-system/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt b/core/type-system/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt index e8d71f762b7..aa6143151ee 100644 --- a/core/type-system/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt +++ b/core/type-system/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt @@ -508,6 +508,9 @@ object AbstractNullabilityChecker { // i.e. subType is definitely not null if (subType.isDefinitelyNotNullType()) return true + // i.e. subType is captured type, projection of which is marked not-null + if (subType is CapturedTypeMarker && subType.isProjectionNotNull()) return true + // i.e. subType is not-nullable if (hasNotNullSupertype(subType, SupertypesPolicy.LowerIfFlexible)) return true 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 c39abedd766..94df620d87f 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 @@ -154,6 +154,7 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui fun CapturedTypeMarker.typeConstructorProjection(): TypeArgumentMarker fun CapturedTypeMarker.typeParameter(): TypeParameterMarker? + fun CapturedTypeMarker.withNotNullProjection(): KotlinTypeMarker fun DefinitelyNotNullTypeMarker.original(): SimpleTypeMarker @@ -200,6 +201,7 @@ interface TypeSystemContext : TypeSystemOptimizationContext { fun CapturedTypeMarker.typeConstructor(): CapturedTypeConstructorMarker fun CapturedTypeMarker.captureStatus(): CaptureStatus + fun CapturedTypeMarker.isProjectionNotNull(): Boolean fun CapturedTypeConstructorMarker.projection(): TypeArgumentMarker fun KotlinTypeMarker.argumentsCount(): Int