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:
Denis Zharkov
2017-03-02 13:10:10 +03:00
parent 2b21280ba9
commit be90f7d331
7 changed files with 48 additions and 48 deletions
@@ -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? {