[FE 1.0] Introduce deprecation of inferred type variable into a declared upper bound within a builder inference call

This commit is contained in:
Victor Petukhov
2022-05-31 13:42:35 +02:00
committed by teamcity
parent 848075192c
commit b472ccd358
31 changed files with 300 additions and 35 deletions
@@ -890,6 +890,7 @@ public interface Errors {
DiagnosticFactory1<PsiElement, InferenceErrorData> TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, String> NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, String> INFERRED_INTO_DECLARED_UPPER_BOUNDS = DiagnosticFactory1.create(WARNING);
DiagnosticFactory1<PsiElement, String> COULD_BE_INFERRED_ONLY_WITH_UNRESTRICTED_BUILDER_INFERENCE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, InferenceErrorData> TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS = DiagnosticFactory1.create(ERROR);
@@ -959,6 +959,8 @@ public class DefaultErrorMessages {
MAP.put(TYPE_INFERENCE_CANNOT_CAPTURE_TYPES, "Type inference failed: {0}", TYPE_INFERENCE_CANNOT_CAPTURE_TYPES_RENDERER);
MAP.put(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER, "Type inference failed: {0}", TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER_RENDERER);
MAP.put(NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, "Not enough information to infer type variable {0}", STRING);
MAP.put(INFERRED_INTO_DECLARED_UPPER_BOUNDS, "Type parameter for a type argument {0} can''t be inferred into declared upper bounds. " +
"Please provide any use-site type information. It will become an error in future releases.", STRING);
MAP.put(COULD_BE_INFERRED_ONLY_WITH_UNRESTRICTED_BUILDER_INFERENCE, "Builder inference lambda contains inapplicable calls so {0} can''t be inferred. It could be resolved only with unrestricted builder inference. Please use -Xunrestricted-builder-inference compiler flag to enable it.", STRING);
MAP.put(TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR, "Type inference failed: {0}", TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR_RENDERER);
@@ -541,6 +541,22 @@ class DiagnosticReporterByTrackingStrategy(
}
}
InferredIntoDeclaredUpperBounds::class.java -> {
error as InferredIntoDeclaredUpperBounds
val psiCall = psiKotlinCall.psiCall
val expression = if (psiCall is CallTransformer.CallForImplicitInvoke) {
psiCall.outerCall.calleeExpression
} else {
psiCall.calleeExpression
} ?: return
val typeVariable = error.typeVariable as? TypeVariableFromCallableDescriptor ?: return
trace.reportDiagnosticOnce(
INFERRED_INTO_DECLARED_UPPER_BOUNDS.on(expression, typeVariable.originalTypeParameter.name.asString())
)
}
NotEnoughInformationForTypeParameterImpl::class.java -> {
error as NotEnoughInformationForTypeParameterImpl
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.resolve.calls.inference
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
@@ -34,7 +35,6 @@ import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.NewCapturedType
import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
import org.jetbrains.kotlin.types.model.freshTypeConstructor
import org.jetbrains.kotlin.types.model.safeSubstitute
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
import org.jetbrains.kotlin.types.typeUtil.contains
@@ -589,10 +589,15 @@ class BuilderInferenceSession(
if (lowerSubstituted == a && upperSubstituted == b) return this
val resultingPosition = if (upperSubstituted == b && position is DeclaredUpperBoundConstraintPosition<*>) {
val isInferringIntoUpperBoundsForbidden = expressionTypingServices.languageVersionSettings.supportsFeature(
LanguageFeature.ForbidInferringPostponedTypeVariableIntoDeclaredUpperBound
)
val isFromNotSubstitutedDeclaredUpperBound = upperSubstituted == b && position is DeclaredUpperBoundConstraintPosition<*>
val resultingPosition = if (isFromNotSubstitutedDeclaredUpperBound && isInferringIntoUpperBoundsForbidden) {
position
} else {
BuilderInferenceSubstitutionConstraintPositionImpl(lambdaArgument, this)
BuilderInferenceSubstitutionConstraintPositionImpl(lambdaArgument, this, isFromNotSubstitutedDeclaredUpperBound)
}
return InitialConstraint(