Make type aliases constructors return correct original descriptors
The problem was that when resolving super-calls we used known substitutor when creating a type alias constructor, thus its original return itself, while it's expected that it should return the descriptor before substitution The main idea of the fix that `createIfAvailable` should always return unsubstituted constructor. Note that known substitutor for type alias constructor should be based on abbreviation. The test change seems to be correct as PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE is already reported. Beside this, resolution behavior isn't expected to be changed dramatically
This commit is contained in:
@@ -48,7 +48,6 @@ import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingVisitorDispatcher;
|
||||
@@ -452,17 +451,18 @@ public class CallResolver {
|
||||
}
|
||||
|
||||
// If any constructor has type parameter (currently it only can be true for ones from Java), try to infer arguments for them
|
||||
// Otherwise use NO_EXPECTED_TYPE and knownTypeParametersSubstitutor
|
||||
// Otherwise use NO_EXPECTED_TYPE and known type substitutor
|
||||
boolean anyConstructorHasDeclaredTypeParameters =
|
||||
anyConstructorHasDeclaredTypeParameters(superType.getConstructor().getDeclarationDescriptor());
|
||||
|
||||
TypeSubstitutor knownTypeParametersSubstitutor = anyConstructorHasDeclaredTypeParameters ? null : TypeSubstitutor.create(superType);
|
||||
if (anyConstructorHasDeclaredTypeParameters) {
|
||||
context = context.replaceExpectedType(superType);
|
||||
}
|
||||
|
||||
Collection<ResolutionCandidate<ConstructorDescriptor>> candidates =
|
||||
CallResolverUtilKt.createResolutionCandidatesForConstructors(context.scope, context.call, superType, knownTypeParametersSubstitutor);
|
||||
CallResolverUtilKt.createResolutionCandidatesForConstructors(
|
||||
context.scope, context.call, superType, !anyConstructorHasDeclaredTypeParameters
|
||||
);
|
||||
|
||||
return new Pair<Collection<ResolutionCandidate<ConstructorDescriptor>>, BasicCallResolutionContext>(candidates, context);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptorImpl
|
||||
import org.jetbrains.kotlin.lexer.KtToken
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -34,6 +33,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.getNestedTypeVariables
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.getTypeAliasConstructors
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
@@ -194,18 +194,25 @@ fun createResolutionCandidatesForConstructors(
|
||||
lexicalScope: LexicalScope,
|
||||
call: Call,
|
||||
typeWithConstructors: KotlinType,
|
||||
knownSubstitutor: TypeSubstitutor? = null
|
||||
useKnownTypeSubstitutor: Boolean
|
||||
): Collection<ResolutionCandidate<ConstructorDescriptor>> {
|
||||
val classWithConstructors = typeWithConstructors.constructor.declarationDescriptor as ClassDescriptor
|
||||
|
||||
val unwrappedType = typeWithConstructors.unwrap()
|
||||
val knownSubstitutor =
|
||||
if (useKnownTypeSubstitutor)
|
||||
TypeSubstitutor.create(
|
||||
(unwrappedType as? AbbreviatedType)?.abbreviation ?: unwrappedType
|
||||
)
|
||||
else null
|
||||
|
||||
val typeAliasDescriptor =
|
||||
if (unwrappedType is AbbreviatedType)
|
||||
unwrappedType.abbreviation.constructor.declarationDescriptor as? TypeAliasDescriptor
|
||||
else
|
||||
null
|
||||
|
||||
val constructors = classWithConstructors.constructors
|
||||
val constructors = typeAliasDescriptor?.getTypeAliasConstructors(withDispatchReceiver = true) ?: classWithConstructors.constructors
|
||||
|
||||
if (constructors.isEmpty()) return emptyList()
|
||||
|
||||
@@ -229,22 +236,10 @@ fun createResolutionCandidatesForConstructors(
|
||||
}
|
||||
|
||||
return constructors.map {
|
||||
val constructorDescriptor = it.getConstructorDescriptorForResolution(knownSubstitutor, typeAliasDescriptor)
|
||||
ResolutionCandidate.create(call, constructorDescriptor, dispatchReceiver, receiverKind, knownSubstitutor)
|
||||
ResolutionCandidate.create(call, it, dispatchReceiver, receiverKind, knownSubstitutor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClassConstructorDescriptor.getConstructorDescriptorForResolution(
|
||||
knownSubstitutor: TypeSubstitutor?,
|
||||
typeAliasDescriptor: TypeAliasDescriptor?
|
||||
): ConstructorDescriptor =
|
||||
if (typeAliasDescriptor != null)
|
||||
TypeAliasConstructorDescriptorImpl.createIfAvailable(typeAliasDescriptor, this, knownSubstitutor ?: TypeSubstitutor.EMPTY,
|
||||
withDispatchReceiver = true)
|
||||
?: throw AssertionError("Failed to create type alias constructor with substitutor: $knownSubstitutor")
|
||||
else
|
||||
this
|
||||
|
||||
fun KtLambdaExpression.getCorrespondingParameterForFunctionArgument(
|
||||
bindingContext: BindingContext
|
||||
): ValueParameterDescriptor? {
|
||||
|
||||
Reference in New Issue
Block a user