[NI] Preserve annotations during type substitution
#KT-31346 Fixed
This commit is contained in:
+3
-3
@@ -53,14 +53,14 @@ class DelegatedPropertyInferenceSession(
|
||||
?: builtIns.nullableNothingType
|
||||
|
||||
val valueParameterForThis = descriptor.valueParameters.getOrNull(0) ?: return
|
||||
val substitutedType = substitutor.substituteKeepAnnotations(valueParameterForThis.type.unwrap())
|
||||
val substitutedType = substitutor.safeSubstitute(valueParameterForThis.type.unwrap())
|
||||
commonSystem.addSubtypeConstraint(typeOfThis.unwrap(), substitutedType, DelegatedPropertyConstraintPosition(atom))
|
||||
}
|
||||
|
||||
private fun ResolvedCallAtom.addConstraintsForGetValueMethod(commonSystem: ConstraintSystemBuilder) {
|
||||
if (expectedType != null) {
|
||||
val unsubstitutedReturnType = candidateDescriptor.returnType?.unwrap() ?: return
|
||||
val substitutedReturnType = substitutor.substituteKeepAnnotations(unsubstitutedReturnType)
|
||||
val substitutedReturnType = substitutor.safeSubstitute(unsubstitutedReturnType)
|
||||
|
||||
commonSystem.addSubtypeConstraint(substitutedReturnType, expectedType, DelegatedPropertyConstraintPosition(atom))
|
||||
}
|
||||
@@ -71,7 +71,7 @@ class DelegatedPropertyInferenceSession(
|
||||
private fun ResolvedCallAtom.addConstraintsForSetValueMethod(commonSystem: ConstraintSystemBuilder) {
|
||||
if (expectedType != null) {
|
||||
val unsubstitutedParameterType = candidateDescriptor.valueParameters.getOrNull(2)?.type?.unwrap() ?: return
|
||||
val substitutedParameterType = substitutor.substituteKeepAnnotations(unsubstitutedParameterType)
|
||||
val substitutedParameterType = substitutor.safeSubstitute(unsubstitutedParameterType)
|
||||
|
||||
commonSystem.addSubtypeConstraint(expectedType, substitutedParameterType, DelegatedPropertyConstraintPosition(atom))
|
||||
}
|
||||
|
||||
+2
-1
@@ -91,6 +91,7 @@ class KotlinResolutionCallbacksImpl(
|
||||
receiverType: UnwrappedType?,
|
||||
parameters: List<UnwrappedType>,
|
||||
expectedReturnType: UnwrappedType?,
|
||||
annotations: Annotations,
|
||||
stubsForPostponedVariables: Map<NewTypeVariable, StubType>
|
||||
): Pair<List<KotlinCallArgument>, InferenceSession?> {
|
||||
val psiCallArgument = lambdaArgument.psiCallArgument as PSIFunctionKotlinCallArgument
|
||||
@@ -130,7 +131,7 @@ class KotlinResolutionCallbacksImpl(
|
||||
|
||||
val builtIns = outerCallContext.scope.ownerDescriptor.builtIns
|
||||
val expectedType = createFunctionType(
|
||||
builtIns, Annotations.EMPTY, receiverType, parameters, null,
|
||||
builtIns, annotations, receiverType, parameters, null,
|
||||
lambdaInfo.expectedType, isSuspend
|
||||
)
|
||||
|
||||
|
||||
+3
-3
@@ -191,8 +191,8 @@ class ResolvedAtomCompleter(
|
||||
val substitutedFunctionalType = createFunctionType(
|
||||
builtIns,
|
||||
existingLambdaType.annotations,
|
||||
lambda.receiver?.let { resultSubstitutor.substituteKeepAnnotations(it) },
|
||||
lambda.parameters.map { resultSubstitutor.substituteKeepAnnotations(it) },
|
||||
lambda.receiver?.let { resultSubstitutor.safeSubstitute(it) },
|
||||
lambda.parameters.map { resultSubstitutor.safeSubstitute(it) },
|
||||
null, // parameter names transforms to special annotations, so they are already taken from parameter types
|
||||
returnType,
|
||||
lambda.isSuspend
|
||||
@@ -208,7 +208,7 @@ class ResolvedAtomCompleter(
|
||||
}
|
||||
|
||||
val valueType = receiver.value.type.unwrap()
|
||||
val newValueType = resultSubstitutor.substituteKeepAnnotations(valueType)
|
||||
val newValueType = resultSubstitutor.safeSubstitute(valueType)
|
||||
|
||||
if (valueType !== newValueType) {
|
||||
val newReceiverValue = receiver.value.replaceType(newValueType)
|
||||
|
||||
+2
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
|
||||
@@ -41,6 +42,7 @@ interface KotlinResolutionCallbacks {
|
||||
receiverType: UnwrappedType?,
|
||||
parameters: List<UnwrappedType>,
|
||||
expectedReturnType: UnwrappedType?, // null means, that return type is not proper i.e. it depends on some type variables
|
||||
annotations: Annotations,
|
||||
stubsForPostponedVariables: Map<NewTypeVariable, StubType>
|
||||
): Pair<List<KotlinCallArgument>, InferenceSession?>
|
||||
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ class KotlinCallCompleter(
|
||||
private fun KotlinResolutionCandidate.returnTypeWithSmartCastInfo(resolutionCallbacks: KotlinResolutionCallbacks): UnwrappedType? {
|
||||
val returnType = resolvedCall.candidateDescriptor.returnType?.unwrap() ?: return null
|
||||
val returnTypeWithSmartCastInfo = computeReturnTypeWithSmartCastInfo(returnType, resolutionCallbacks)
|
||||
return resolvedCall.substitutor.substituteKeepAnnotations(returnTypeWithSmartCastInfo)
|
||||
return resolvedCall.substitutor.safeSubstitute(returnTypeWithSmartCastInfo)
|
||||
}
|
||||
|
||||
private fun KotlinResolutionCandidate.addExpectedTypeConstraint(
|
||||
|
||||
+2
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve.calls.components
|
||||
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
|
||||
import org.jetbrains.kotlin.builtins.getValueParameterTypesFromFunctionType
|
||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.addSubsystemFromArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||
@@ -105,6 +106,7 @@ class PostponedArgumentsAnalyzer(
|
||||
receiver,
|
||||
parameters,
|
||||
expectedTypeForReturnArguments,
|
||||
lambda.expectedType?.annotations ?: Annotations.EMPTY,
|
||||
stubsForPostponedVariables.cast()
|
||||
)
|
||||
|
||||
|
||||
+1
-1
@@ -290,7 +290,7 @@ private fun KotlinResolutionCandidate.prepareExpectedType(
|
||||
callComponents.languageVersionSettings
|
||||
)
|
||||
val resultType = knownTypeParametersResultingSubstitutor?.substitute(argumentType) ?: argumentType
|
||||
return resolvedCall.substitutor.substituteKeepAnnotations(resultType)
|
||||
return resolvedCall.substitutor.safeSubstitute(resultType)
|
||||
}
|
||||
|
||||
private fun KotlinResolutionCandidate.getExpectedTypeWithSAMConversion(
|
||||
|
||||
+3
-4
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.resolve.calls.inference.components
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor
|
||||
import org.jetbrains.kotlin.types.*
|
||||
@@ -17,9 +18,7 @@ import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||
interface NewTypeSubstitutor: TypeSubstitutorMarker {
|
||||
fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType?
|
||||
|
||||
fun safeSubstitute(type: UnwrappedType): UnwrappedType = substitute(type, runCapturedChecks = true, keepAnnotation = false) ?: type
|
||||
|
||||
fun substituteKeepAnnotations(type: UnwrappedType): UnwrappedType =
|
||||
fun safeSubstitute(type: UnwrappedType): UnwrappedType =
|
||||
substitute(type, runCapturedChecks = true, keepAnnotation = true) ?: type
|
||||
|
||||
private fun substitute(type: UnwrappedType, keepAnnotation: Boolean, runCapturedChecks: Boolean): UnwrappedType? =
|
||||
@@ -114,7 +113,7 @@ interface NewTypeSubstitutor: TypeSubstitutorMarker {
|
||||
// simple classifier type
|
||||
var replacement = substituteNotNullTypeWithConstructor(typeConstructor) ?: return null
|
||||
if (keepAnnotation) {
|
||||
replacement = replacement.replaceAnnotations(type.annotations)
|
||||
replacement = replacement.replaceAnnotations(CompositeAnnotations(replacement.annotations, type.annotations))
|
||||
}
|
||||
if (type.isMarkedNullable) {
|
||||
replacement = replacement.makeNullableAsSpecified(true)
|
||||
|
||||
+2
-2
@@ -9,8 +9,8 @@ fun test() {
|
||||
|
||||
// KT-KT-9070
|
||||
<!TYPE_MISMATCH!>{ }<!> <!USELESS_ELVIS!>?: 1<!>
|
||||
use(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>{ 2 }<!> <!USELESS_ELVIS!>?: 1<!>);
|
||||
use({ 2 } <!USELESS_ELVIS!>?: 1<!>);
|
||||
|
||||
1 <!USELESS_ELVIS!>?: <!TYPE_MISMATCH, UNUSED_LAMBDA_EXPRESSION!>{ }<!><!>
|
||||
use(1 <!USELESS_ELVIS!>?: <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>{ }<!><!>)
|
||||
use(1 <!USELESS_ELVIS!>?: { }<!>)
|
||||
}
|
||||
+4
-4
@@ -21,7 +21,7 @@ fun baz4(x: @MyDsl B.() -> Unit) {}
|
||||
fun @MyDsl A.baz5() {
|
||||
baz4 {
|
||||
bar()
|
||||
<!OI;DSL_SCOPE_VIOLATION_WARNING!>foo<!>()
|
||||
<!DSL_SCOPE_VIOLATION_WARNING!>foo<!>()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,21 +36,21 @@ fun main() {
|
||||
baz3 {
|
||||
baz2 {
|
||||
bar()
|
||||
<!OI;DSL_SCOPE_VIOLATION_WARNING!>foo<!>()
|
||||
<!DSL_SCOPE_VIOLATION_WARNING!>foo<!>()
|
||||
}
|
||||
}
|
||||
|
||||
baz1 {
|
||||
baz4 {
|
||||
bar()
|
||||
<!OI;DSL_SCOPE_VIOLATION_WARNING!>foo<!>()
|
||||
<!DSL_SCOPE_VIOLATION_WARNING!>foo<!>()
|
||||
}
|
||||
}
|
||||
|
||||
baz3 {
|
||||
baz4 {
|
||||
bar()
|
||||
<!OI;DSL_SCOPE_VIOLATION_WARNING!>foo<!>()
|
||||
<!DSL_SCOPE_VIOLATION_WARNING!>foo<!>()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -22,7 +22,7 @@ fun baz4(x: @MyDsl B.() -> Unit) {}
|
||||
fun @MyDsl A.baz5() {
|
||||
baz4 {
|
||||
bar()
|
||||
<!OI;DSL_SCOPE_VIOLATION!>foo<!>()
|
||||
<!DSL_SCOPE_VIOLATION!>foo<!>()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,21 +37,21 @@ fun main() {
|
||||
baz3 {
|
||||
baz2 {
|
||||
bar()
|
||||
<!OI;DSL_SCOPE_VIOLATION!>foo<!>()
|
||||
<!DSL_SCOPE_VIOLATION!>foo<!>()
|
||||
}
|
||||
}
|
||||
|
||||
baz1 {
|
||||
baz4 {
|
||||
bar()
|
||||
<!OI;DSL_SCOPE_VIOLATION!>foo<!>()
|
||||
<!DSL_SCOPE_VIOLATION!>foo<!>()
|
||||
}
|
||||
}
|
||||
|
||||
baz3 {
|
||||
baz4 {
|
||||
bar()
|
||||
<!OI;DSL_SCOPE_VIOLATION!>foo<!>()
|
||||
<!DSL_SCOPE_VIOLATION!>foo<!>()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -60,7 +60,7 @@ fun test() {
|
||||
bar1t(this) {
|
||||
a()
|
||||
bar1 {
|
||||
<!OI;DSL_SCOPE_VIOLATION!>a<!>()
|
||||
<!DSL_SCOPE_VIOLATION!>a<!>()
|
||||
b()
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ fun test() {
|
||||
foo2 {
|
||||
bar1t(this) {
|
||||
a()
|
||||
<!OI;DSL_SCOPE_VIOLATION!>b<!>()
|
||||
<!DSL_SCOPE_VIOLATION!>b<!>()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ fun test() {
|
||||
foo<A> {
|
||||
a()
|
||||
bar<B> {
|
||||
<!OI;DSL_SCOPE_VIOLATION!>a<!>()
|
||||
<!DSL_SCOPE_VIOLATION!>a<!>()
|
||||
this@foo.a()
|
||||
b()
|
||||
}
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ fun test() {
|
||||
<!OI;CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!>
|
||||
}<!>)
|
||||
|
||||
bar(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!><!OI;CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!> ?: <!OI;CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!><!>)
|
||||
bar(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!><!CONSTANT_EXPECTED_TYPE_MISMATCH, NI;CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!> ?: <!CONSTANT_EXPECTED_TYPE_MISMATCH, NI;CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!><!>)
|
||||
}
|
||||
|
||||
fun bar(s: String) = s
|
||||
Reference in New Issue
Block a user