Filter internal annotations for resolve in type substitutor
to avoid having List<@NoInfer Int> as a result type of function invocation (the function returns List<@NoInfer T>)
This commit is contained in:
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInvokeCallOnExpress
|
|||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isExplicitSafeCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.isExplicitSafeCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker
|
import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.*
|
import org.jetbrains.kotlin.resolve.calls.context.*
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.SubstitutionFilteringInternalResolveAnnotations
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatchStatus
|
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatchStatus
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
@@ -43,7 +44,6 @@ import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.*
|
|||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionTask
|
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionTask
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.isSynthesizedInvoke
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
@@ -127,7 +127,7 @@ public class CandidateResolver(
|
|||||||
"Explicit type argument expected for " + candidateDescriptor.getTypeParameters().get(index).getName()))
|
"Explicit type argument expected for " + candidateDescriptor.getTypeParameters().get(index).getName()))
|
||||||
}
|
}
|
||||||
val substitution = FunctionDescriptorUtil.createSubstitution(candidateDescriptor as FunctionDescriptor, typeArguments)
|
val substitution = FunctionDescriptorUtil.createSubstitution(candidateDescriptor as FunctionDescriptor, typeArguments)
|
||||||
val substitutor = TypeSubstitutor.create(substitution)
|
val substitutor = TypeSubstitutor.create(SubstitutionFilteringInternalResolveAnnotations(substitution))
|
||||||
|
|
||||||
if (expectedTypeArgumentCount != jetTypeArguments.size()) {
|
if (expectedTypeArgumentCount != jetTypeArguments.size()) {
|
||||||
candidateCall.addStatus(OTHER_ERROR)
|
candidateCall.addStatus(OTHER_ERROR)
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||||
|
fun <R> Iterable<*>.filterIsInstance1(): List<@kotlin.internal.NoInfer R> = throw Exception()
|
||||||
|
|
||||||
|
fun test(list: List<Int>) {
|
||||||
|
list.filterIsInstance1<Int>().map { it * 2}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||||
|
fun <R> foo(t: R): List<@kotlin.internal.NoInfer R> = throw Exception("$t")
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(1).map { it * 2}
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
@kotlin.Suppress(names = {"INVISIBLE_MEMBER", "INVISIBLE_REFERENCE"}) public fun </*0*/ R> foo(/*0*/ t: R): kotlin.List<R>
|
||||||
|
public fun test(): kotlin.Unit
|
||||||
|
public fun test(/*0*/ list: kotlin.List<kotlin.Int>): kotlin.Unit
|
||||||
|
@kotlin.Suppress(names = {"INVISIBLE_MEMBER", "INVISIBLE_REFERENCE"}) public fun </*0*/ R> kotlin.Iterable<*>.filterIsInstance1(): kotlin.List<R>
|
||||||
+6
@@ -696,6 +696,12 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("internalAnnotationsOnTypes.kt")
|
||||||
|
public void testInternalAnnotationsOnTypes() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/internalAnnotationsOnTypes.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("noInferAnnotation.kt")
|
@TestMetadata("noInferAnnotation.kt")
|
||||||
public void testNoInferAnnotation() throws Exception {
|
public void testNoInferAnnotation() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAnnotation.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAnnotation.kt");
|
||||||
|
|||||||
@@ -18,17 +18,22 @@ package org.jetbrains.kotlin.resolve.descriptorUtil
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.types.KtType
|
import org.jetbrains.kotlin.types.KtType
|
||||||
|
|
||||||
private val NO_INFER_ANNOTATION_FQ_NAME = FqName("kotlin.internal.NoInfer")
|
private val NO_INFER_ANNOTATION_FQ_NAME = FqName("kotlin.internal.NoInfer")
|
||||||
|
private val EXACT_ANNOTATION_FQ_NAME = FqName("kotlin.internal.Exact")
|
||||||
|
|
||||||
public fun KtType.hasNoInferAnnotation(): Boolean = annotations.hasAnnotation(NO_INFER_ANNOTATION_FQ_NAME)
|
public fun KtType.hasNoInferAnnotation(): Boolean = annotations.hasAnnotation(NO_INFER_ANNOTATION_FQ_NAME)
|
||||||
|
|
||||||
private val EXACT_ANNOTATION_FQ_NAME = FqName("kotlin.internal.Exact")
|
|
||||||
|
|
||||||
public fun KtType.hasExactAnnotation(): Boolean = annotations.hasAnnotation(EXACT_ANNOTATION_FQ_NAME)
|
public fun KtType.hasExactAnnotation(): Boolean = annotations.hasAnnotation(EXACT_ANNOTATION_FQ_NAME)
|
||||||
|
|
||||||
|
public fun Annotations.hasInternalAnnotationForResolve(): Boolean =
|
||||||
|
hasAnnotation(NO_INFER_ANNOTATION_FQ_NAME) || hasAnnotation(EXACT_ANNOTATION_FQ_NAME)
|
||||||
|
|
||||||
|
public fun FqName.isInternalAnnotationForResolve() = this == NO_INFER_ANNOTATION_FQ_NAME || this == EXACT_ANNOTATION_FQ_NAME
|
||||||
|
|
||||||
private val LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME = FqName("kotlin.internal.LowPriorityInOverloadResolution")
|
private val LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME = FqName("kotlin.internal.LowPriorityInOverloadResolution")
|
||||||
|
|
||||||
public fun CallableDescriptor.hasLowPriorityInOverloadResolution(): Boolean = annotations.hasAnnotation(LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME)
|
public fun CallableDescriptor.hasLowPriorityInOverloadResolution(): Boolean = annotations.hasAnnotation(LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME)
|
||||||
|
|||||||
+12
-7
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.inference
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.FilteredAnnotations
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl.ConstraintKind.EQUAL
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl.ConstraintKind.EQUAL
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl.ConstraintKind.SUB_TYPE
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl.ConstraintKind.SUB_TYPE
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound
|
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound
|
||||||
@@ -29,9 +30,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.Constrain
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
|
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.TYPE_BOUND_POSITION
|
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.TYPE_BOUND_POSITION
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.derivedFrom
|
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.derivedFrom
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasNoInferAnnotation
|
import org.jetbrains.kotlin.resolve.descriptorUtil.*
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasExactAnnotation
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasOnlyInputTypesAnnotation
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.KtScope
|
import org.jetbrains.kotlin.resolve.scopes.KtScope
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
|
import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
|
||||||
@@ -137,7 +136,8 @@ public class ConstraintSystemImpl : ConstraintSystem {
|
|||||||
substituteOriginal: Boolean
|
substituteOriginal: Boolean
|
||||||
): TypeSubstitutor {
|
): TypeSubstitutor {
|
||||||
val parameterToInferredValueMap = getParameterToInferredValueMap(allTypeParameterBounds, getDefaultValue, substituteOriginal)
|
val parameterToInferredValueMap = getParameterToInferredValueMap(allTypeParameterBounds, getDefaultValue, substituteOriginal)
|
||||||
return TypeConstructorSubstitution.createByParametersMap(parameterToInferredValueMap).buildSubstitutor()
|
val substitution = TypeConstructorSubstitution.createByParametersMap(parameterToInferredValueMap)
|
||||||
|
return SubstitutionFilteringInternalResolveAnnotations(substitution).buildSubstitutor()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getStatus(): ConstraintSystemStatus = constraintSystemStatus
|
override fun getStatus(): ConstraintSystemStatus = constraintSystemStatus
|
||||||
@@ -546,12 +546,17 @@ private fun TypeSubstitutor.setApproximateCapturedTypes(): TypeSubstitutor {
|
|||||||
return TypeSubstitutor.create(SubstitutionWithCapturedTypeApproximation(getSubstitution()))
|
return TypeSubstitutor.create(SubstitutionWithCapturedTypeApproximation(getSubstitution()))
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SubstitutionWithCapturedTypeApproximation(val substitution: TypeSubstitution) : TypeSubstitution() {
|
private class SubstitutionWithCapturedTypeApproximation(substitution: TypeSubstitution) : DelegatedTypeSubstitution(substitution) {
|
||||||
override fun get(key: KtType) = substitution[key]
|
|
||||||
override fun isEmpty() = substitution.isEmpty()
|
|
||||||
override fun approximateCapturedTypes() = true
|
override fun approximateCapturedTypes() = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SubstitutionFilteringInternalResolveAnnotations(substitution: TypeSubstitution) : DelegatedTypeSubstitution(substitution) {
|
||||||
|
override fun filterAnnotations(annotations: Annotations): Annotations {
|
||||||
|
if (!annotations.hasInternalAnnotationForResolve()) return annotations
|
||||||
|
return FilteredAnnotations(annotations) { !it.isInternalAnnotationForResolve() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public fun ConstraintSystemImpl.registerTypeVariables(typeVariables: Map<TypeParameterDescriptor, Variance>) {
|
public fun ConstraintSystemImpl.registerTypeVariables(typeVariables: Map<TypeParameterDescriptor, Variance>) {
|
||||||
registerTypeVariables(typeVariables.keySet(), { typeVariables[it]!! }, { it })
|
registerTypeVariables(typeVariables.keySet(), { typeVariables[it]!! }, { it })
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.types;
|
package org.jetbrains.kotlin.types;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
|
||||||
public class DisjointKeysUnionTypeSubstitution private constructor(
|
public class DisjointKeysUnionTypeSubstitution private constructor(
|
||||||
private val first: TypeSubstitution,
|
private val first: TypeSubstitution,
|
||||||
@@ -37,4 +37,6 @@ public class DisjointKeysUnionTypeSubstitution private constructor(
|
|||||||
override fun isEmpty() = false
|
override fun isEmpty() = false
|
||||||
|
|
||||||
override fun approximateCapturedTypes() = first.approximateCapturedTypes() || second.approximateCapturedTypes()
|
override fun approximateCapturedTypes() = first.approximateCapturedTypes() || second.approximateCapturedTypes()
|
||||||
|
|
||||||
|
override fun filterAnnotations(annotations: Annotations) = second.filterAnnotations(first.filterAnnotations(annotations))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.types
|
package org.jetbrains.kotlin.types
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
|
||||||
public abstract class TypeSubstitution {
|
public abstract class TypeSubstitution {
|
||||||
companion object {
|
companion object {
|
||||||
@@ -34,6 +35,8 @@ public abstract class TypeSubstitution {
|
|||||||
|
|
||||||
public open fun approximateCapturedTypes(): Boolean = false
|
public open fun approximateCapturedTypes(): Boolean = false
|
||||||
|
|
||||||
|
public open fun filterAnnotations(annotations: Annotations) = annotations
|
||||||
|
|
||||||
public fun buildSubstitutor(): TypeSubstitutor = TypeSubstitutor.create(this)
|
public fun buildSubstitutor(): TypeSubstitutor = TypeSubstitutor.create(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,4 +126,16 @@ private class CompositeTypeSubstitution(
|
|||||||
override fun isEmpty() = first.isEmpty() && second.isEmpty()
|
override fun isEmpty() = first.isEmpty() && second.isEmpty()
|
||||||
//
|
//
|
||||||
override fun approximateCapturedTypes() = first.approximateCapturedTypes() || second.approximateCapturedTypes()
|
override fun approximateCapturedTypes() = first.approximateCapturedTypes() || second.approximateCapturedTypes()
|
||||||
|
|
||||||
|
override fun filterAnnotations(annotations: Annotations): Annotations = second.filterAnnotations(first.filterAnnotations(annotations))
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class DelegatedTypeSubstitution(val substitution: TypeSubstitution): TypeSubstitution() {
|
||||||
|
override fun get(key: KtType) = substitution.get(key)
|
||||||
|
|
||||||
|
override fun isEmpty() = substitution.isEmpty()
|
||||||
|
|
||||||
|
override fun approximateCapturedTypes() = substitution.approximateCapturedTypes()
|
||||||
|
|
||||||
|
override fun filterAnnotations(annotations: Annotations) = substitution.filterAnnotations(annotations)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,10 @@ import org.jetbrains.kotlin.resolve.scopes.SubstitutingScope;
|
|||||||
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
|
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
|
||||||
import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt;
|
import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class TypeSubstitutor {
|
public class TypeSubstitutor {
|
||||||
|
|
||||||
@@ -183,7 +186,7 @@ public class TypeSubstitutor {
|
|||||||
|
|
||||||
// substitutionType.annotations = replacement.annotations ++ type.annotations
|
// substitutionType.annotations = replacement.annotations ++ type.annotations
|
||||||
if (!type.getAnnotations().isEmpty()) {
|
if (!type.getAnnotations().isEmpty()) {
|
||||||
Annotations typeAnnotations = filterOutUnsafeVariance(type.getAnnotations());
|
Annotations typeAnnotations = filterOutUnsafeVariance(substitution.filterAnnotations(type.getAnnotations()));
|
||||||
substitutedType = TypeUtilsKt.replaceAnnotations(
|
substitutedType = TypeUtilsKt.replaceAnnotations(
|
||||||
substitutedType,
|
substitutedType,
|
||||||
new CompositeAnnotations(substitutedType.getAnnotations(), typeAnnotations)
|
new CompositeAnnotations(substitutedType.getAnnotations(), typeAnnotations)
|
||||||
@@ -227,7 +230,7 @@ public class TypeSubstitutor {
|
|||||||
|
|
||||||
// Only type parameters of the corresponding class (or captured type parameters of outer declaration) are substituted
|
// Only type parameters of the corresponding class (or captured type parameters of outer declaration) are substituted
|
||||||
// e.g. for return type Foo of 'add(..)' in 'class Foo { fun <R> add(bar: Bar<R>): Foo }' R shouldn't be substituted in the scope
|
// e.g. for return type Foo of 'add(..)' in 'class Foo { fun <R> add(bar: Bar<R>): Foo }' R shouldn't be substituted in the scope
|
||||||
TypeSubstitution substitutionFilteringTypeParameters = new TypeSubstitution() {
|
TypeSubstitution substitutionFilteringTypeParameters = new DelegatedTypeSubstitution(substitution) {
|
||||||
private final Collection<TypeConstructor> containedOrCapturedTypeParameters =
|
private final Collection<TypeConstructor> containedOrCapturedTypeParameters =
|
||||||
TypeUtilsKt.getContainedAndCapturedTypeParameterConstructors(type);
|
TypeUtilsKt.getContainedAndCapturedTypeParameterConstructors(type);
|
||||||
|
|
||||||
@@ -236,11 +239,6 @@ public class TypeSubstitutor {
|
|||||||
public TypeProjection get(@NotNull KtType key) {
|
public TypeProjection get(@NotNull KtType key) {
|
||||||
return containedOrCapturedTypeParameters.contains(key.getConstructor()) ? substitution.get(key) : null;
|
return containedOrCapturedTypeParameters.contains(key.getConstructor()) ? substitution.get(key) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return substitution.isEmpty();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
KtType substitutedType = KtTypeImpl.create(type.getAnnotations(), // Old annotations. This is questionable
|
KtType substitutedType = KtTypeImpl.create(type.getAnnotations(), // Old annotations. This is questionable
|
||||||
type.getConstructor(), // The same constructor
|
type.getConstructor(), // The same constructor
|
||||||
|
|||||||
Reference in New Issue
Block a user