From f20ec3e0a6bf865dfc3415431e7b31ad99a8e7b6 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 16 May 2019 14:51:17 +0300 Subject: [PATCH] [NI] Disable capturing/approximation type in TypeSubstitutor with enabled NI There is added a new service named `SubstitutingScopeProvider`, that provides factory that creates captured types and approximator for them. In OI they are the same as before commit, for NI they are empty, because that approximation interferes with NI algorithm That service is injected into function descriptors and property descriptors and used for creating `SubstitutingScope` with correct services Also there is changed time when we approximate captured types in NI (after all call checkers) #KT-25290 Fixed --- .../fir/FirDiagnosticsSmokeTestGenerated.java | 20 +++++ .../kotlin/frontend/java/di/injection.kt | 2 + .../analyzer/common/CommonAnalyzerFacade.kt | 2 + .../impl/LocalVariableDescriptor.java | 3 +- .../kotlin/diagnostics/diagnosticUtils.kt | 5 +- .../jetbrains/kotlin/frontend/di/injection.kt | 5 ++ .../kotlin/resolve/DescriptorResolver.java | 3 +- .../tower/KotlinToResolvedCallTransformer.kt | 89 ++++++++++++++----- .../resolve/calls/tower/PSICallResolver.kt | 1 + .../calls/tower/ResolvedAtomCompleter.kt | 5 +- .../kotlin/resolve/lazy/LazyClassContext.kt | 2 + .../kotlin/resolve/lazy/ResolveSession.java | 13 +++ .../lazy/descriptors/LazyClassDescriptor.java | 2 +- .../types/SubstitutingScopeProviderImpl.kt | 49 ++++++++++ .../BasicExpressionTypingVisitor.java | 10 ++- .../expressions/LocalClassifierAnalyzer.kt | 11 ++- .../resolve/calls/inference/InferenceUtils.kt | 35 ++++++-- .../kotlin/types/TypeApproximator.kt | 17 ++-- .../tests/callableReference/sam.kt | 4 +- .../tests/callableReference/sam.ni.txt | 28 ++++++ .../collectionLiteralsWithVarargs.kt | 2 +- .../controlFlowAnalysis/elvisNotProcessed.kt | 2 +- .../kt770.kt351.kt735_StatementType.kt | 2 +- .../ExpectedParametersTypesMismatch.kt | 4 +- .../LocalReturnsWithExplicitReturnType.kt | 4 +- .../generics/capturedTypeInInputPosition.kt | 20 +++++ .../generics/capturedTypeInInputPosition.txt | 39 ++++++++ .../innerClasses/innerUncheckedCast.kt | 2 +- .../projectionsScope/projectedOutSmartCast.kt | 4 +- .../starNullabilityRecursive.kt | 3 +- .../projectionsScope/typeMismatchInLambda.kt | 10 +-- .../projectionsScope/typeParameterBounds.kt | 12 +-- .../tests/generics/starProjections/invalid.kt | 4 +- .../setterNotProjectedOutAssign.kt | 2 +- .../varProjection/setterProjectedOutAssign.kt | 7 +- .../setterProjectedOutAssignFromJava.kt | 16 ++++ .../setterProjectedOutAssignFromJava.txt | 12 +++ .../setterProjectedOutNoPlusAssign.kt | 2 +- .../capturedTypes/captureForNullableTypes.kt | 12 +-- ...romNullableChildAndNonParameterizedType.kt | 2 +- .../tests/inference/regressions/kt2283.kt | 2 +- .../tests/j+k/sam/enhancedSamConstructor.kt | 8 +- .../samByProjectedType/genericInReturnType.kt | 2 +- .../testData/diagnostics/tests/kt13401.kt | 2 +- .../testData/diagnostics/tests/kt13401.ni.txt | 4 +- ...rningForModFromBuiltinsWhenApi1_0_after.kt | 8 +- ...ningForModFromBuiltinsWhenApi1_0_before.kt | 8 +- .../methodTypeParameter.kt | 10 ++- ...rrectResultSubstitutorForErrorCandidate.kt | 2 +- .../tests/resolve/implicitAndExplicitThis.kt | 29 ++++++ .../tests/resolve/implicitAndExplicitThis.txt | 38 ++++++++ .../specialConstructions/constantsInIf.kt | 2 +- .../tests/samConversions/kt25290.kt | 29 ++++++ .../tests/samConversions/kt25290.txt | 21 +++++ .../tests/substitutions/starProjections.kt | 6 +- .../noAssigningArraysToVarargsFeature.kt | 8 +- .../jetbrains/kotlin/tests/di/injection.kt | 2 + .../diagnostics/notLinked/dfa/pos/38.kt | 2 +- .../diagnostics/notLinked/dfa/pos/50.kt | 24 ++--- .../checkers/DiagnosticsTestGenerated.java | 20 +++++ .../DiagnosticsUsingJavacTestGenerated.java | 20 +++++ .../kotlin/load/java/lazy/context.kt | 6 +- .../descriptors/LazyJavaClassDescriptor.kt | 3 +- .../internal/components/RuntimeModuleData.kt | 3 +- .../impl/AbstractClassDescriptor.java | 15 ++-- .../descriptors/impl/ClassDescriptorBase.java | 14 ++- .../impl/FunctionDescriptorImpl.java | 23 ++++- .../impl/LazySubstitutingClassDescriptor.java | 12 +-- .../impl/PropertyDescriptorImpl.java | 69 +++++++++++++- .../impl/ValueParameterDescriptorImpl.kt | 4 +- .../inference/CapturedTypeConstructor.kt | 25 ++++-- .../resolve/scopes/SubstitutingScope.kt | 51 +++++++++-- .../kotlin/types/CapturedTypeApproximation.kt | 6 ++ .../kotlin/types/DescriptorSubstitutor.java | 7 +- .../kotlin/types/SubstitutingScopeProvider.kt | 47 ++++++++++ .../kotlin/types/TypeSubstitutor.java | 18 +++- .../org/jetbrains/kotlin/types/TypeUtils.java | 5 ++ .../types/checker/ClassicTypeSystemContext.kt | 4 + .../lightClasses/IDELightClassContexts.kt | 7 +- .../kotlin/frontend/js/di/injection.kt | 2 + 80 files changed, 864 insertions(+), 171 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/kotlin/types/SubstitutingScopeProviderImpl.kt create mode 100644 compiler/testData/diagnostics/tests/callableReference/sam.ni.txt create mode 100644 compiler/testData/diagnostics/tests/generics/capturedTypeInInputPosition.kt create mode 100644 compiler/testData/diagnostics/tests/generics/capturedTypeInInputPosition.txt create mode 100644 compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssignFromJava.kt create mode 100644 compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssignFromJava.txt create mode 100644 compiler/testData/diagnostics/tests/resolve/implicitAndExplicitThis.kt create mode 100644 compiler/testData/diagnostics/tests/resolve/implicitAndExplicitThis.txt create mode 100644 compiler/testData/diagnostics/tests/samConversions/kt25290.kt create mode 100644 compiler/testData/diagnostics/tests/samConversions/kt25290.txt create mode 100644 core/descriptors/src/org/jetbrains/kotlin/types/SubstitutingScopeProvider.kt diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java index 00f8899cdf3..4e1648e8872 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java @@ -8086,6 +8086,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok runTest("compiler/testData/diagnostics/tests/generics/argumentsForT.kt"); } + @TestMetadata("capturedTypeInInputPosition.kt") + public void testCapturedTypeInInputPosition() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/capturedTypeInInputPosition.kt"); + } + @TestMetadata("commonSupertypeContravariant.kt") public void testCommonSupertypeContravariant() throws Exception { runTest("compiler/testData/diagnostics/tests/generics/commonSupertypeContravariant.kt"); @@ -8925,6 +8930,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok runTest("compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.kt"); } + @TestMetadata("setterProjectedOutAssignFromJava.kt") + public void testSetterProjectedOutAssignFromJava() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssignFromJava.kt"); + } + @TestMetadata("setterProjectedOutNoPlusAssign.kt") public void testSetterProjectedOutNoPlusAssign() throws Exception { runTest("compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.kt"); @@ -17363,6 +17373,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok runTest("compiler/testData/diagnostics/tests/resolve/HiddenDeclarations.kt"); } + @TestMetadata("implicitAndExplicitThis.kt") + public void testImplicitAndExplicitThis() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/implicitAndExplicitThis.kt"); + } + @TestMetadata("implicitReceiverProperty.kt") public void testImplicitReceiverProperty() throws Exception { runTest("compiler/testData/diagnostics/tests/resolve/implicitReceiverProperty.kt"); @@ -18080,6 +18095,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok runTest("compiler/testData/diagnostics/tests/samConversions/GenericSubstitutionKT.kt"); } + @TestMetadata("kt25290.kt") + public void testKt25290() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/kt25290.kt"); + } + @TestMetadata("OverloadPriority.kt") public void testOverloadPriority() throws Exception { runTest("compiler/testData/diagnostics/tests/samConversions/OverloadPriority.kt"); diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt index 6c50ac836e8..d194723e4c8 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt @@ -47,6 +47,7 @@ import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer import org.jetbrains.kotlin.resolve.lazy.ResolveSession import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory +import org.jetbrains.kotlin.types.SubstitutingScopeProviderImpl private fun StorageComponentContainer.configureJavaTopDownAnalysis( moduleContentScope: GlobalSearchScope, @@ -126,6 +127,7 @@ fun createContainerForLazyResolveWithJava( useImpl() useImpl() + useImpl() }.apply { get().initialize(bindingTrace, get()) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonAnalyzerFacade.kt b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonAnalyzerFacade.kt index 4f69612cb87..652c50c77f2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonAnalyzerFacade.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonAnalyzerFacade.kt @@ -45,6 +45,7 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService import org.jetbrains.kotlin.serialization.deserialization.MetadataPackageFragmentProvider import org.jetbrains.kotlin.serialization.deserialization.MetadataPartProvider +import org.jetbrains.kotlin.types.SubstitutingScopeProviderImpl class CommonAnalysisParameters( val metadataPartProviderFactory: (ModuleContent<*>) -> MetadataPartProvider @@ -166,6 +167,7 @@ object CommonAnalyzerFacade : ResolverForModuleFactory() { useInstance(declarationProviderFactory) useImpl() useImpl() + useImpl() val metadataFinderFactory = ServiceManager.getService(moduleContext.project, MetadataFinderFactory::class.java) ?: error("No MetadataFinderFactory in project") diff --git a/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/LocalVariableDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/LocalVariableDescriptor.java index ad254f40667..748c9861aa8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/LocalVariableDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/LocalVariableDescriptor.java @@ -81,8 +81,7 @@ public class LocalVariableDescriptor extends VariableDescriptorWithInitializerIm @NotNull @Override public LocalVariableDescriptor substitute(@NotNull TypeSubstitutor substitutor) { - if (substitutor.isEmpty()) return this; - throw new UnsupportedOperationException(); // TODO + return this; } @Override diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/diagnosticUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/diagnosticUtils.kt index c6a4957c83f..b3236140ef1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/diagnosticUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/diagnosticUtils.kt @@ -38,6 +38,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.wrapWithCapturingSubstitutio import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.SubstitutingScopeProvider import org.jetbrains.kotlin.types.TypeConstructorSubstitution import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny @@ -77,7 +78,9 @@ fun ResolutionContext<*>.reportTypeMismatchDueToTypeProjection( TypeConstructorSubstitution .create(receiverType) .wrapWithCapturingSubstitution(needApproximation = false) - .buildSubstitutor().let { callableDescriptor.substitute(it) } ?: return false + .buildSubstitutor().apply { + setSubstitutingScopeProvider(SubstitutingScopeProvider.DEFAULT) + }.let { callableDescriptor.substitute(it) } ?: return false val nonApproximatedExpectedType = correspondingNotApproximatedTypeByDescriptor(substitutedDescriptor) ?: return false if (!TypeUtils.contains(nonApproximatedExpectedType) { it.isCaptured() }) return false diff --git a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt index f47a8644e73..edc8478dbdd 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt @@ -37,6 +37,7 @@ import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker import org.jetbrains.kotlin.resolve.lazy.* import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory +import org.jetbrains.kotlin.types.SubstitutingScopeProviderImpl import org.jetbrains.kotlin.types.expressions.DeclarationScopeProviderForLocalClassifierAnalyzer import org.jetbrains.kotlin.types.expressions.LocalClassDescriptorHolder import org.jetbrains.kotlin.types.expressions.LocalLazyDeclarationResolver @@ -103,6 +104,7 @@ fun createContainerForBodyResolve( useImpl() useImpl() + useImpl() } fun createContainerForLazyBodyResolve( @@ -123,6 +125,7 @@ fun createContainerForLazyBodyResolve( useImpl() useImpl() useImpl() + useImpl() } fun createContainerForLazyLocalClassifierAnalyzer( @@ -154,6 +157,7 @@ fun createContainerForLazyLocalClassifierAnalyzer( useImpl() useInstance(languageVersionSettings) + useImpl() useInstance(statementFilter) } @@ -177,6 +181,7 @@ fun createContainerForLazyResolve( useImpl() useImpl() + useImpl() } fun createLazyResolveSession(moduleContext: ModuleContext, files: Collection): ResolveSession = diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index 1ceb21ad25c..7bf482f9d3d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -911,7 +911,8 @@ public class DescriptorResolver { container instanceof ClassDescriptor && ((ClassDescriptor) container).isExpect(), modifierList != null && PsiUtilsKt.hasActualModifier(modifierList), modifierList != null && modifierList.hasModifier(KtTokens.EXTERNAL_KEYWORD), - propertyInfo.getHasDelegate() + propertyInfo.getHasDelegate(), + new SubstitutingScopeProviderImpl(languageVersionSettings) ); List typeParameterDescriptors; diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt index 75d02c765a5..bfa491d0828 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt @@ -8,6 +8,8 @@ package org.jetbrains.kotlin.resolve.calls.tower import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl +import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.psi.* @@ -23,12 +25,13 @@ import org.jetbrains.kotlin.resolve.calls.components.AdditionalDiagnosticReporte import org.jetbrains.kotlin.resolve.calls.components.isVararg import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext import org.jetbrains.kotlin.resolve.calls.context.CallPosition +import org.jetbrains.kotlin.resolve.calls.inference.approximateCapturedTypes import org.jetbrains.kotlin.resolve.calls.inference.buildResultingSubstitutor import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor import org.jetbrains.kotlin.resolve.calls.inference.model.* import org.jetbrains.kotlin.resolve.calls.inference.substitute -import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateCapturedTypes +import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateIntegerLiteralTypes import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.makeNullableTypeIfSafeReceiver import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus @@ -38,14 +41,13 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor -import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver +import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.types.* -import org.jetbrains.kotlin.types.checker.NewCapturedType import org.jetbrains.kotlin.types.expressions.DataFlowAnalyzer import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices @@ -293,15 +295,14 @@ class KotlinToResolvedCallTransformer( // todo external argument val argumentExpression = valueArgument.getArgumentExpression() ?: continue - updateRecordedType(argumentExpression, parameter, newContext, resolvedCall.isReallySuccess()) + updateRecordedType(argumentExpression, parameter, newContext) } } fun updateRecordedType( expression: KtExpression, parameter: ValueParameterDescriptor?, - context: BasicCallResolutionContext, - reportErrorForTypeMismatch: Boolean + context: BasicCallResolutionContext ): KotlinType? { val deparenthesized = expression.let { KtPsiUtil.getLastElementDeparenthesized(it, context.statementFilter) @@ -318,9 +319,6 @@ class KotlinToResolvedCallTransformer( updatedType = argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, deparenthesized) ?: updatedType } - - var reportErrorDuringTypeCheck = reportErrorForTypeMismatch - if (parameter != null && ImplicitIntegerCoercion.isEnabledForParameter(parameter)) { val argumentCompileTimeValue = context.trace[BindingContext.COMPILE_TIME_VALUE, deparenthesized] if (argumentCompileTimeValue != null && argumentCompileTimeValue.parameters.isConvertableConstVal) { @@ -329,7 +327,6 @@ class KotlinToResolvedCallTransformer( updatedType = argumentTypeResolver.updateResultArgumentTypeIfNotDenotable( context.trace, context.statementFilter, context.expectedType, generalNumberType, expression ) - reportErrorDuringTypeCheck = true } } @@ -337,7 +334,7 @@ class KotlinToResolvedCallTransformer( updatedType = updateRecordedTypeForArgument(updatedType, recordedType, expression, context) - dataFlowAnalyzer.checkType(updatedType, deparenthesized, context, reportErrorDuringTypeCheck) + dataFlowAnalyzer.checkType(updatedType, deparenthesized, context, false) return updatedType } @@ -690,32 +687,44 @@ class NewResolvedCallImpl( @Suppress("UNCHECKED_CAST") resultingDescriptor = run { val candidateDescriptor = resolvedCallAtom.candidateDescriptor - val containsCapturedTypes = resolvedCallAtom.candidateDescriptor.returnType?.contains { it is NewCapturedType } ?: false - val containsIntegerLiteralTypes = resolvedCallAtom.candidateDescriptor.returnType?.contains { it.constructor is IntegerLiteralTypeConstructor } ?: false + val containsIntegerLiteralTypes = resolvedCallAtom.candidateDescriptor.returnType?.contains { + it.constructor is IntegerLiteralTypeConstructor + } ?: false when { candidateDescriptor is FunctionDescriptor || - (candidateDescriptor is PropertyDescriptor && (candidateDescriptor.typeParameters.isNotEmpty() || containsCapturedTypes || containsIntegerLiteralTypes)) -> + (candidateDescriptor is PropertyDescriptor && candidateDescriptor.typeParameters.isNotEmpty() || containsIntegerLiteralTypes) -> // this code is very suspicious. Now it is very useful for BE, because they cannot do nothing with captured types, // but it seems like temporary solution. - candidateDescriptor.substitute(resolvedCallAtom.substitutor).substituteAndApproximateCapturedTypes( - substitutor ?: FreshVariableNewTypeSubstitutor.Empty - ) + candidateDescriptor.substituteAndApproximateIntegerLiteralTypes(resolvedCallAtom.substitutor).let { + if (substitutor != null) { + it.substitute(substitutor) + } else { + it + } + } + else -> candidateDescriptor } } as D typeArguments = resolvedCallAtom.substitutor.freshVariables.map { - val substituted = (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType) - TypeApproximator(substituted.constructor.builtIns) - .approximateToSuperType(substituted, TypeApproximatorConfiguration.IntegerLiteralsTypesApproximation) - ?: substituted + (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType) } calculateExpectedTypeForSamConvertedArgumentMap(substitutor) } + fun approximateCapturedTypesAndHackSetters() { + val approximator = TypeApproximator(resultingDescriptor.builtIns) + resultingDescriptor = resultingDescriptor.hackSettersAccordingToCapturedOutTypes() + resultingDescriptor = resultingDescriptor.approximateCapturedTypes() + typeArguments = typeArguments.map { + approximator.approximateToSuperType(it, TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation) ?: it + } + } + fun getExpectedTypeForSamConvertedArgument(valueArgument: ValueArgument): UnwrappedType? = expedtedTypeForSamConvertedArgumentMap?.get(valueArgument) @@ -808,3 +817,41 @@ fun NewResolvedCallImpl<*>.hasInferredReturnType(): Boolean { val returnType = this.resultingDescriptor.returnType ?: return false return !returnType.contains { ErrorUtils.isUninferredParameter(it) } } + +fun ResolvedCall<*>.approximateCapturedTypesAndHackSetters() { + when (this) { + is NewResolvedCallImpl<*> -> approximateCapturedTypesAndHackSetters() + is NewVariableAsFunctionResolvedCallImpl -> { + functionCall.approximateCapturedTypesAndHackSetters() + variableCall.approximateCapturedTypesAndHackSetters() + } + else -> throw UnsupportedOperationException("Illegal resolved call: $this") + } +} + +fun D.hackSettersAccordingToCapturedOutTypes(): D { + return when (this) { + is PropertyDescriptorImpl -> hackSettersAccordingToCapturedOutTypes() as D + else -> this + } +} + +private fun PropertyDescriptorImpl.hackSettersAccordingToCapturedOutTypes(): PropertyDescriptor { + val setter = setter ?: return this + val valueParameter = setter.valueParameters.first() + val inputType = valueParameter.type + val approximatedType = TypeApproximator(builtIns).approximateToSubType( + inputType.unwrap(), + TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation + ) ?: return this + + val newProperty = newCopyBuilder().build() as PropertyDescriptorImpl + + val newSetter = with(setter) { + PropertySetterDescriptorImpl(newProperty, annotations, modality, visibility, isDefault, isExternal, isInline, kind, original, source) + } + newSetter.initialize(PropertySetterDescriptorImpl.createSetterParameter(newSetter, approximatedType, setter.annotations)) + newProperty.initialize(getter, newSetter, backingField, delegateField) + newProperty.isSetterProjectedOut = true + return newProperty +} \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt index 0aee6b6e18b..ea676f0a304 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt @@ -382,6 +382,7 @@ class PSICallResolver( return cache.getOrPut(implicitReceiver) { context.transformToReceiverWithSmartCastInfo(implicitReceiver.value) + .prepareReceiverRegardingCaptureTypes() } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt index 2750f5d521c..ecb6ab5e145 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt @@ -110,6 +110,7 @@ class ResolvedAtomCompleter( kotlinToResolvedCallTransformer.reportDiagnostics(topLevelCallContext, topLevelTrace, resolvedCall, diagnostics) + resolvedCall.approximateCapturedTypesAndHackSetters() return resolvedCall } @@ -155,9 +156,7 @@ class ResolvedAtomCompleter( .replaceBindingTrace(topLevelTrace) val argumentExpression = resultValueArgument.valueArgument.getArgumentExpression() ?: continue - kotlinToResolvedCallTransformer.updateRecordedType( - argumentExpression, parameter = null, context = newContext, reportErrorForTypeMismatch = true - ) + kotlinToResolvedCallTransformer.updateRecordedType(argumentExpression, parameter = null, context = newContext) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyClassContext.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyClassContext.kt index fb37ff382a0..0fdb6790ce1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyClassContext.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyClassContext.kt @@ -24,10 +24,12 @@ import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.types.SubstitutingScopeProvider import org.jetbrains.kotlin.types.WrappedTypeFactory interface LazyClassContext { val declarationScopeProvider: DeclarationScopeProvider + val substitutingScopeProvider: SubstitutingScopeProvider val storageManager: StorageManager val trace: BindingTrace diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ResolveSession.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ResolveSession.java index 613a11b9815..6213f45e639 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ResolveSession.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ResolveSession.java @@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor; import org.jetbrains.kotlin.resolve.scopes.LexicalScope; import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.storage.*; +import org.jetbrains.kotlin.types.SubstitutingScopeProvider; import org.jetbrains.kotlin.types.WrappedTypeFactory; import org.jetbrains.kotlin.utils.SmartList; @@ -81,6 +82,7 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext { private DelegationFilter delegationFilter; private WrappedTypeFactory wrappedTypeFactory; private PlatformDiagnosticSuppressor platformDiagnosticSuppressor; + private SubstitutingScopeProvider substitutingScopeProvider; private final SyntheticResolveExtension syntheticResolveExtension; @@ -146,6 +148,17 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext { this.platformDiagnosticSuppressor = platformDiagnosticSuppressor; } + @NotNull + @Override + public SubstitutingScopeProvider getSubstitutingScopeProvider() { + return substitutingScopeProvider; + } + + @Inject + public void setSubstitutingScopeProvider(SubstitutingScopeProvider substitutingScopeProvider) { + this.substitutingScopeProvider = substitutingScopeProvider; + } + // Only calls from injectors expected @Deprecated public ResolveSession( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java index 06513e7087f..755b5862b52 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -113,7 +113,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes ) { super(c.getStorageManager(), containingDeclaration, name, KotlinSourceElementKt.toSourceElement(classLikeInfo.getCorrespondingClassOrObject()), - isExternal + isExternal, c.getSubstitutingScopeProvider() ); this.c = c; diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/SubstitutingScopeProviderImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/SubstitutingScopeProviderImpl.kt new file mode 100644 index 00000000000..c1214cd242c --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/SubstitutingScopeProviderImpl.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.types + +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.resolve.calls.inference.OldCapturedTypeCreator +import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.resolve.scopes.SubstitutingScope +import org.jetbrains.kotlin.types.typesApproximation.OldCaptureTypeApproximator + +class SubstitutingScopeProviderImpl(private val languageVersionSettings: LanguageVersionSettings) : SubstitutingScopeProvider { + override val isNewInferenceEnabled: Boolean get() = languageVersionSettings.supportsFeature(LanguageFeature.NewInference) + + override fun createSubstitutingScope(workerScope: MemberScope, givenSubstitutor: TypeSubstitutor): SubstitutingScope { + return SubstitutingScope(workerScope, givenSubstitutor, this) + } + + override fun provideApproximator(): CapturedTypeApproximator { + return if (isNewInferenceEnabled) { + NoCapturedTypeApproximator + } else { + OldCaptureTypeApproximator() + } + } + + override fun provideCapturedTypeCreator(): CapturedTypeCreator { + return if (isNewInferenceEnabled) { + NoCapturedTypeCreator + } else { + OldCapturedTypeCreator + } + } +} + +object NoCapturedTypeCreator : CapturedTypeCreator { + override fun createCapturedType(typeProjection: TypeProjection): TypeProjection { + return typeProjection + } +} + +object NoCapturedTypeApproximator : CapturedTypeApproximator { + override fun approximateCapturedTypes(typeProjection: TypeProjection?, approximateContravariant: Boolean): TypeProjection? { + return typeProjection + } +} \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index 02c9db8543b..934d670b53d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -958,6 +958,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { boolean result = true; KtExpression reportOn = expression != null ? expression : expressionWithParenthesis; + KtExpression originalReportOn = reportOn; if (reportOn instanceof KtQualifiedExpression) { KtExpression selector = ((KtQualifiedExpression) reportOn).getSelectorExpression(); if (selector != null) @@ -968,14 +969,19 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variable; PropertySetterDescriptor setter = propertyDescriptor.getSetter(); if (propertyDescriptor.isSetterProjectedOut()) { - trace.report(SETTER_PROJECTED_OUT.on(reportOn, propertyDescriptor)); + trace.report(SETTER_PROJECTED_OUT.on(originalReportOn, propertyDescriptor)); result = false; } else if (setter != null) { ResolvedCall resolvedCall = CallUtilKt.getResolvedCall(expressionWithParenthesis, context.trace.getBindingContext()); assert resolvedCall != null : "Call is not resolved for property setter: " + PsiUtilsKt.getElementTextWithContext(expressionWithParenthesis); - checkPropertySetterCall(context.replaceBindingTrace(trace), setter, resolvedCall, reportOn); + if (((PropertyDescriptor)resolvedCall.getResultingDescriptor()).isSetterProjectedOut()) { + trace.report(SETTER_PROJECTED_OUT.on(originalReportOn, propertyDescriptor)); + result = false; + } else { + checkPropertySetterCall(context.replaceBindingTrace(trace), setter, resolvedCall, reportOn); + } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/LocalClassifierAnalyzer.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/LocalClassifierAnalyzer.kt index 51eb2d4628d..e9a2efcb7f2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/LocalClassifierAnalyzer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/LocalClassifierAnalyzer.kt @@ -50,6 +50,7 @@ import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.types.SubstitutingScopeProvider import org.jetbrains.kotlin.types.WrappedTypeFactory class LocalClassifierAnalyzer( @@ -65,7 +66,8 @@ class LocalClassifierAnalyzer( private val targetPlatformVersion: TargetPlatformVersion, private val languageVersionSettings: LanguageVersionSettings, private val delegationFilter: DelegationFilter, - private val wrappedTypeFactory: WrappedTypeFactory + private val wrappedTypeFactory: WrappedTypeFactory, + private val substitutingScopeProvider: SubstitutingScopeProvider ) { fun processClassOrObject( scope: LexicalWritableScope?, @@ -99,7 +101,8 @@ class LocalClassifierAnalyzer( languageVersionSettings, SyntheticResolveExtension.getInstance(project), delegationFilter, - wrappedTypeFactory + wrappedTypeFactory, + substitutingScopeProvider ) ) @@ -126,7 +129,8 @@ class LocalClassDescriptorHolder( val languageVersionSettings: LanguageVersionSettings, val syntheticResolveExtension: SyntheticResolveExtension, val delegationFilter: DelegationFilter, - val wrappedTypeFactory: WrappedTypeFactory + val wrappedTypeFactory: WrappedTypeFactory, + val substitutingScopeProvider: SubstitutingScopeProvider ) { // We do not need to synchronize here, because this code is used strictly from one thread private var classDescriptor: ClassDescriptor? = null @@ -166,6 +170,7 @@ class LocalClassDescriptorHolder( override val syntheticResolveExtension = this@LocalClassDescriptorHolder.syntheticResolveExtension override val delegationFilter: DelegationFilter = this@LocalClassDescriptorHolder.delegationFilter override val wrappedTypeFactory: WrappedTypeFactory = this@LocalClassDescriptorHolder.wrappedTypeFactory + override val substitutingScopeProvider: SubstitutingScopeProvider = this@LocalClassDescriptorHolder.substitutingScopeProvider }, containingDeclaration, classOrObject.nameAsSafeName, diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt index e7528ab7bb1..6cac42b40e6 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt @@ -60,6 +60,20 @@ val CallableDescriptor.returnTypeOrNothing: UnwrappedType fun TypeSubstitutor.substitute(type: UnwrappedType): UnwrappedType = safeSubstitute(type, Variance.INVARIANT).unwrap() +fun CallableDescriptor.substituteAndApproximateIntegerLiteralTypes(substitutor: NewTypeSubstitutor): CallableDescriptor { + val wrappedSubstitution = object : TypeSubstitution() { + override fun get(key: KotlinType): TypeProjection? = null + + override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = + substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType -> + TypeApproximator(builtIns).approximateToSuperType(substitutedType, TypeApproximatorConfiguration.IntegerLiteralsTypesApproximation) + ?: substitutedType + } + } + + return substitute(TypeSubstitutor.create(wrappedSubstitution)) +} + fun CallableDescriptor.substitute(substitutor: NewTypeSubstitutor): CallableDescriptor { val wrappedSubstitution = object : TypeSubstitution() { override fun get(key: KotlinType): TypeProjection? = null @@ -68,18 +82,25 @@ fun CallableDescriptor.substitute(substitutor: NewTypeSubstitutor): CallableDesc return substitute(TypeSubstitutor.create(wrappedSubstitution)) } -fun CallableDescriptor.substituteAndApproximateCapturedTypes(substitutor: NewTypeSubstitutor): CallableDescriptor { +fun D.approximateCapturedTypes(): D { + val approximator = TypeApproximator(builtIns) + var anyChanges = false val wrappedSubstitution = object : TypeSubstitution() { override fun get(key: KotlinType): TypeProjection? = null - override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = - substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType -> - TypeApproximator(builtIns).approximateToSuperType(substitutedType, TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation) - ?: substitutedType + override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance): KotlinType { + val type = topLevelType.unwrap() + val approximatedType = + approximator.approximateToSuperType(type, TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation) + if (approximatedType != null) { + anyChanges = true } + return approximatedType as? KotlinType ?: type + } } - return substitute(TypeSubstitutor.create(wrappedSubstitution)) + val substitutedDescriptor = substitute(TypeSubstitutor.create(wrappedSubstitution)) as D + return if (anyChanges) substitutedDescriptor else this } -internal fun MutableList.trimToSize(newSize: Int) = subList(newSize, size).clear() +internal fun MutableList.trimToSize(newSize: Int) = subList(newSize, size).clear() \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt b/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt index d2f5c621b22..0b6d062e716 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt @@ -21,14 +21,10 @@ import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator import org.jetbrains.kotlin.resolve.calls.components.ClassicTypeSystemContextForCS -import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableTypeConstructor -import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor import org.jetbrains.kotlin.types.TypeApproximatorConfiguration.IntersectionStrategy.* -import org.jetbrains.kotlin.types.checker.NewCapturedType import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.model.CaptureStatus.* -import org.jetbrains.kotlin.types.typeUtil.builtIns open class TypeApproximatorConfiguration { @@ -424,6 +420,8 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon if (argument.isStarProjection()) continue val argumentType = argument.getType()//.unwrap() + val argumentTypeIsNullable = argumentType.asSimpleType()?.isMarkedNullable() ?: false + val effectiveVariance = AbstractTypeChecker.effectiveVariance(parameter.getVariance(), argument.getVariance()) when (effectiveVariance) { null -> { @@ -487,7 +485,7 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon */ if (argumentType.typeConstructor() is NewCapturedTypeConstructor) { val subType = approximateToSubType(argumentType, conf, depth) ?: continue@loop - if (!subType.isTrivialSub()) { + if (!subType.isTrivialSub(argumentTypeIsNullable)) { newArguments[index] = createTypeArgument(subType, TypeVariance.IN) continue@loop } @@ -498,7 +496,7 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon if (approximatedSuperType.isTrivialSuper()) { val approximatedSubType = approximateToSubType(argumentType, conf, depth) ?: continue@loop // seems like this is never null - if (!approximatedSubType.isTrivialSub()) { + if (!approximatedSubType.isTrivialSub(argumentTypeIsNullable)) { newArguments[index] = createTypeArgument(approximatedSubType, TypeVariance.IN) continue@loop } @@ -527,7 +525,12 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon private fun KotlinTypeMarker.isTrivialSuper() = upperBoundIfFlexible().isNullableAny() // Nothing or Nothing! - private fun KotlinTypeMarker.isTrivialSub() = lowerBoundIfFlexible().isNothing() + private fun KotlinTypeMarker.isTrivialSub(originalIsNullable: Boolean) = lowerBoundIfFlexible().let { + if (originalIsNullable) + it.isNothing() || it.isNullableNothing() + else + it.isNothing() + } } // //internal fun KotlinTypeMarker.typeDepth() = diff --git a/compiler/testData/diagnostics/tests/callableReference/sam.kt b/compiler/testData/diagnostics/tests/callableReference/sam.kt index e733d9060f1..20febc37ae6 100644 --- a/compiler/testData/diagnostics/tests/callableReference/sam.kt +++ b/compiler/testData/diagnostics/tests/callableReference/sam.kt @@ -1,4 +1,6 @@ // FILE: test/GenericSam.java +// !WITH_NEW_INFERENCE +// NI_EXPECTED_FILE package test; @@ -16,7 +18,7 @@ fun f3() = java.lang.Runnable::class fun f4() = java.lang.Runnable::run fun f5() = GenericSam::class -fun f6() = GenericSam<*>::invoke +fun f6() = GenericSam<*>::invoke fun f7() = test.GenericSam::class fun f8() = test.GenericSam::invoke diff --git a/compiler/testData/diagnostics/tests/callableReference/sam.ni.txt b/compiler/testData/diagnostics/tests/callableReference/sam.ni.txt new file mode 100644 index 00000000000..51df5db7bd1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/sam.ni.txt @@ -0,0 +1,28 @@ +package + +public fun f1(): kotlin.reflect.KClass +public fun f2(): kotlin.reflect.KFunction1 +public fun f3(): kotlin.reflect.KClass +public fun f4(): kotlin.reflect.KFunction1 +public fun f5(): kotlin.reflect.KClass> +public fun f6(): kotlin.reflect.KFunction0<[ERROR : ]> +public fun f7(): kotlin.reflect.KClass> +public fun f8(): kotlin.reflect.KFunction2, @kotlin.ParameterName(name = "t") kotlin.String!, kotlin.Unit> +public fun g1(): kotlin.reflect.KClass +public fun g2(): kotlin.reflect.KFunction0 +public fun g3(): kotlin.reflect.KClass +public fun g4(): kotlin.reflect.KFunction0 +public fun g5(): kotlin.reflect.KClass> +public fun g6(): kotlin.reflect.KFunction1<@kotlin.ParameterName(name = "t") kotlin.String!, kotlin.Unit> +public fun g7(): kotlin.reflect.KClass> +public fun g8(): kotlin.reflect.KFunction1<@kotlin.ParameterName(name = "t") kotlin.String!, kotlin.Unit> + +package test { + + public interface GenericSam { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public abstract operator fun invoke(/*0*/ t: T!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsWithVarargs.kt b/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsWithVarargs.kt index 2da19fbbd30..8459ffc2188 100644 --- a/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsWithVarargs.kt +++ b/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsWithVarargs.kt @@ -37,5 +37,5 @@ annotation class AnnArray(val a: Array) @AnnArray(*["/"]) fun testArray() {} -@Ann1([""]) +@Ann1([""]) fun testVararg() {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/elvisNotProcessed.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/elvisNotProcessed.kt index e17ee5b0c38..03e5d977eca 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/elvisNotProcessed.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/elvisNotProcessed.kt @@ -34,6 +34,6 @@ val bbb = null ?: ( l() ?: null) val bbbb = ( l() ?: null) ?: ( l() ?: null) fun f(x : Long?): Long { - var a = x ?: (fun() {} ?: fun() {}) + var a = x ?: (fun() {} ?: fun() {}) return a } diff --git a/compiler/testData/diagnostics/tests/controlStructures/kt770.kt351.kt735_StatementType.kt b/compiler/testData/diagnostics/tests/controlStructures/kt770.kt351.kt735_StatementType.kt index 599e85e9e40..801f663679e 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/kt770.kt351.kt735_StatementType.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/kt770.kt351.kt735_StatementType.kt @@ -108,7 +108,7 @@ fun testImplicitCoercion() { val h = if (false) 4 else {} bar(if (true) { - 4 + 4 } else { z = 342 diff --git a/compiler/testData/diagnostics/tests/functionLiterals/ExpectedParametersTypesMismatch.kt b/compiler/testData/diagnostics/tests/functionLiterals/ExpectedParametersTypesMismatch.kt index cc3dc836f84..601b19e0e55 100644 --- a/compiler/testData/diagnostics/tests/functionLiterals/ExpectedParametersTypesMismatch.kt +++ b/compiler/testData/diagnostics/tests/functionLiterals/ExpectedParametersTypesMismatch.kt @@ -26,7 +26,7 @@ fun test1() { x, y -> "" } foo1 { - -> 42 + -> 42 } @@ -40,6 +40,6 @@ fun test1() { x -> "" } foo2 { - -> 42 + -> 42 } } diff --git a/compiler/testData/diagnostics/tests/functionLiterals/return/LocalReturnsWithExplicitReturnType.kt b/compiler/testData/diagnostics/tests/functionLiterals/return/LocalReturnsWithExplicitReturnType.kt index ea7ca3be1ac..955b61ef6f6 100644 --- a/compiler/testData/diagnostics/tests/functionLiterals/return/LocalReturnsWithExplicitReturnType.kt +++ b/compiler/testData/diagnostics/tests/functionLiterals/return/LocalReturnsWithExplicitReturnType.kt @@ -1,10 +1,10 @@ // !WITH_NEW_INFERENCE fun test(a: Int) { runf@{ - if (a > 0) return@f "" + if (a > 0) return@f "" return@f 1 } - run{ "" } + run{ "" } run{ 1 } } diff --git a/compiler/testData/diagnostics/tests/generics/capturedTypeInInputPosition.kt b/compiler/testData/diagnostics/tests/generics/capturedTypeInInputPosition.kt new file mode 100644 index 00000000000..408d89fd5b5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/capturedTypeInInputPosition.kt @@ -0,0 +1,20 @@ +// !WITH_NEW_INFERENCE +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION + +interface Inv +class InvImpl : Inv +open class OpenInv + +class A { + fun > foo(x: F) = 1 + +} +class B { + fun > foo(x: F) = 1 + +} + +fun test(a: A, b: B) { + a.foo(OpenInv()) + b.foo(InvImpl()) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/generics/capturedTypeInInputPosition.txt b/compiler/testData/diagnostics/tests/generics/capturedTypeInInputPosition.txt new file mode 100644 index 00000000000..d79bf9b7038 --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/capturedTypeInInputPosition.txt @@ -0,0 +1,39 @@ +package + +public fun test(/*0*/ a: A, /*1*/ b: B): kotlin.Unit + +public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun > foo(/*0*/ x: F): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class B { + public constructor B() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun > foo(/*0*/ x: F): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Inv { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class InvImpl : Inv { + public constructor InvImpl() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class OpenInv { + public constructor OpenInv() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/generics/innerClasses/innerUncheckedCast.kt b/compiler/testData/diagnostics/tests/generics/innerClasses/innerUncheckedCast.kt index d766cbcf95a..7e12d47c989 100644 --- a/compiler/testData/diagnostics/tests/generics/innerClasses/innerUncheckedCast.kt +++ b/compiler/testData/diagnostics/tests/generics/innerClasses/innerUncheckedCast.kt @@ -20,7 +20,7 @@ class Outer { } if (y is Outer<*>.Inner<*>) { - y.prop.checkType { _() } + y.prop.checkType { _() } } } diff --git a/compiler/testData/diagnostics/tests/generics/projectionsScope/projectedOutSmartCast.kt b/compiler/testData/diagnostics/tests/generics/projectionsScope/projectedOutSmartCast.kt index 32877a619a6..8bbceb6bf69 100644 --- a/compiler/testData/diagnostics/tests/generics/projectionsScope/projectedOutSmartCast.kt +++ b/compiler/testData/diagnostics/tests/generics/projectionsScope/projectedOutSmartCast.kt @@ -9,7 +9,7 @@ fun foo(x: Any?, y: C<*>) { y.bindTo("") if (x is C<*>) { - x.bindTo("") + x.bindTo("") with(x) { bindTo("") } @@ -17,7 +17,7 @@ fun foo(x: Any?, y: C<*>) { with(x) { if (this is C<*>) { - bindTo("") + bindTo("") } } } diff --git a/compiler/testData/diagnostics/tests/generics/projectionsScope/starNullabilityRecursive.kt b/compiler/testData/diagnostics/tests/generics/projectionsScope/starNullabilityRecursive.kt index 7a5f0dc7fdd..7cc339fe377 100644 --- a/compiler/testData/diagnostics/tests/generics/projectionsScope/starNullabilityRecursive.kt +++ b/compiler/testData/diagnostics/tests/generics/projectionsScope/starNullabilityRecursive.kt @@ -5,5 +5,6 @@ interface A?> { fun foo(): T? } fun testA(a: A<*>) { - a.foo() checkType { _?>() } + // in new inference here we have A>> + a.foo() checkType { _?>() } } diff --git a/compiler/testData/diagnostics/tests/generics/projectionsScope/typeMismatchInLambda.kt b/compiler/testData/diagnostics/tests/generics/projectionsScope/typeMismatchInLambda.kt index be388ac63a8..8c48d77c1f9 100644 --- a/compiler/testData/diagnostics/tests/generics/projectionsScope/typeMismatchInLambda.kt +++ b/compiler/testData/diagnostics/tests/generics/projectionsScope/typeMismatchInLambda.kt @@ -14,14 +14,14 @@ class A { fun test(a: A, z: Out) { a.foo { val x: String = 1 // Should be no TYPE_MISMATCH_DUE_TO_TYPE_PROJECTIONS - "" + "" } - a.bar { Out() } + a.bar { Out() } a.bar { Out() } - a.bar { z.id() } + a.bar { z.id() } a.foo { - z.foobar(if (1 > 2) return@foo "" else "") - "" + z.foobar(if (1 > 2) return@foo "" else "") + "" } } diff --git a/compiler/testData/diagnostics/tests/generics/projectionsScope/typeParameterBounds.kt b/compiler/testData/diagnostics/tests/generics/projectionsScope/typeParameterBounds.kt index e5d8d0dc248..9f5b7458d9c 100644 --- a/compiler/testData/diagnostics/tests/generics/projectionsScope/typeParameterBounds.kt +++ b/compiler/testData/diagnostics/tests/generics/projectionsScope/typeParameterBounds.kt @@ -14,14 +14,14 @@ class A { fun foo2(a: A, b: A) { a.foo1(Out()) - a.foo1<Out>(Out()) + a.foo1<Out>(Out()) a.foo1(Out()) a.foo1(Out()) - a.foo2(Inv()) + a.foo2(Inv()) a.foo2(Inv()) - a.foo2<Inv>(Inv()) + a.foo2<Inv>(Inv()) a.foo3(In()) a.foo3(In()) @@ -31,13 +31,13 @@ fun foo2(a: A, b: A) { b.foo1(Out()) b.foo1>(Out()) - b.foo2(Inv()) + b.foo2(Inv()) b.foo2(Inv()) - b.foo2<Inv>(Inv()) + b.foo2<Inv>(Inv()) b.foo3(In()) - b.foo3<In>(In()) + b.foo3<In>(In()) b.foo3(In()) b.foo3(In()) diff --git a/compiler/testData/diagnostics/tests/generics/starProjections/invalid.kt b/compiler/testData/diagnostics/tests/generics/starProjections/invalid.kt index 6c61d165fb9..8ea991b53aa 100644 --- a/compiler/testData/diagnostics/tests/generics/starProjections/invalid.kt +++ b/compiler/testData/diagnostics/tests/generics/starProjections/invalid.kt @@ -13,8 +13,8 @@ class Inv2<T : Inv2>(val x: T) fun main(a: A<*>, j: JavaClass<*>, i2: Inv2<*>) { // Probably it's too restrictive to suppose star projection type here as Any?, // but looks like we can refine it later - a.foo() checkType { _() } - j.foo() checkType { _() } + a.foo() checkType { _() } + j.foo() checkType { _() } i2.x checkType { _() } j.bar(1, 2, Any()) diff --git a/compiler/testData/diagnostics/tests/generics/varProjection/setterNotProjectedOutAssign.kt b/compiler/testData/diagnostics/tests/generics/varProjection/setterNotProjectedOutAssign.kt index 3a985d9f749..b72c5e14314 100644 --- a/compiler/testData/diagnostics/tests/generics/varProjection/setterNotProjectedOutAssign.kt +++ b/compiler/testData/diagnostics/tests/generics/varProjection/setterNotProjectedOutAssign.kt @@ -5,6 +5,6 @@ interface Tr { } fun test(t: Tr<*>) { - t.v = t + t.v = t t.v checkType { _>() } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.kt b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.kt index d2d740e37ec..96de789cab7 100644 --- a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.kt +++ b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.kt @@ -7,8 +7,9 @@ interface Tr { } fun test(t: Tr<*>) { - t.v = null!! - t.v = "" - t.v = null + t.v = null!! + t.v = "" + t.v = null + t.v checkType { _() } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssignFromJava.kt b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssignFromJava.kt new file mode 100644 index 00000000000..e6460450cae --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssignFromJava.kt @@ -0,0 +1,16 @@ +// !WITH_NEW_INFERENCE +// Issue: KT-31594 + +// FILE: Tr.java + +public class Tr { + public T getV() { return null; } + public void setV(T value) {} +} + +// FILE: main.kt + +fun test(t: Tr<*>) { + t.v = null + t.v = "" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssignFromJava.txt b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssignFromJava.txt new file mode 100644 index 00000000000..c8bda9b4c28 --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssignFromJava.txt @@ -0,0 +1,12 @@ +package + +public fun test(/*0*/ t: Tr<*>): kotlin.Unit + +public open class Tr { + public constructor Tr() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun getV(): T! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open fun setV(/*0*/ value: T!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.kt b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.kt index b2046304041..c59994c6b28 100644 --- a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.kt +++ b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.kt @@ -7,5 +7,5 @@ interface Tr { fun test(t: Tr) { // resolved as t.v = t.v + null!!, where type of right operand is String, // so TYPE_MISMATCH: String is not <: of Captured(out String) - t.v += null!! + t.v += null!! } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/capturedTypes/captureForNullableTypes.kt b/compiler/testData/diagnostics/tests/inference/capturedTypes/captureForNullableTypes.kt index 87da35a3390..1f1c83f0fbf 100644 --- a/compiler/testData/diagnostics/tests/inference/capturedTypes/captureForNullableTypes.kt +++ b/compiler/testData/diagnostics/tests/inference/capturedTypes/captureForNullableTypes.kt @@ -5,15 +5,15 @@ fun bar(a: Array): Array = null!! fun test1(a: Array) { - val r: Array = bar(a) - val t = bar(a) - t checkType { _>() } + val r: Array = bar(a) + val t = bar(a) + t checkType { _>() } } fun foo(l: Array): Array> = null!! fun test2(a: Array) { - val r: Array> = foo(a) - val t = foo(a) - t checkType { _>>() } + val r: Array> = foo(a) + val t = foo(a) + t checkType { _>>() } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/commonSystem/cstFromNullableChildAndNonParameterizedType.kt b/compiler/testData/diagnostics/tests/inference/commonSystem/cstFromNullableChildAndNonParameterizedType.kt index efa24dd7bea..1eb687629b7 100644 --- a/compiler/testData/diagnostics/tests/inference/commonSystem/cstFromNullableChildAndNonParameterizedType.kt +++ b/compiler/testData/diagnostics/tests/inference/commonSystem/cstFromNullableChildAndNonParameterizedType.kt @@ -16,5 +16,5 @@ fun test1(a: ParameterizedChild?, b: Child): Base = myRun { } fun test2(a: S?, b: S): S = myRun { - select(a, b) + select(a, b) } diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt2283.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt2283.kt index 7ead3c4ae8b..4dabb621a93 100644 --- a/compiler/testData/diagnostics/tests/inference/regressions/kt2283.kt +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt2283.kt @@ -10,5 +10,5 @@ fun Foo.map(f: (A) -> B): Foo = object : Foo fun foo() { val l: Foo = object : Foo {} - val m: Foo = l.map { ppp -> 1 } + val m: Foo = l.map { ppp -> 1 } } diff --git a/compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt b/compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt index 9f59e7247b8..940d1900a42 100644 --- a/compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt +++ b/compiler/testData/diagnostics/tests/j+k/sam/enhancedSamConstructor.kt @@ -18,11 +18,11 @@ public interface J2 extends J { fun main() { J { s: String -> s} // should be prohibited, because SAM value parameter has nullable type J { "" + it.length } - J { null } - J { it?.length?.toString() } + J { null } + J { it?.length?.toString() } J2 { s: String -> s} J2 { "" + it.length } - J2 { null } - J2 { it?.length?.toString() } + J2 { null } + J2 { it?.length?.toString() } } diff --git a/compiler/testData/diagnostics/tests/j+k/samByProjectedType/genericInReturnType.kt b/compiler/testData/diagnostics/tests/j+k/samByProjectedType/genericInReturnType.kt index d5cbb3e3f9b..7574984c51e 100644 --- a/compiler/testData/diagnostics/tests/j+k/samByProjectedType/genericInReturnType.kt +++ b/compiler/testData/diagnostics/tests/j+k/samByProjectedType/genericInReturnType.kt @@ -34,7 +34,7 @@ fun main() { } A.baz { - x -> x.hashCode() + x -> x.hashCode() } val block: (String) -> Any? = { diff --git a/compiler/testData/diagnostics/tests/kt13401.kt b/compiler/testData/diagnostics/tests/kt13401.kt index e9ccffb6966..3989d8d1d37 100644 --- a/compiler/testData/diagnostics/tests/kt13401.kt +++ b/compiler/testData/diagnostics/tests/kt13401.kt @@ -14,5 +14,5 @@ class Owner { fun getT() = u } - fun foo(arg: Inner<*>) = arg.getT() + fun foo(arg: Inner<*>) = arg.getT() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/kt13401.ni.txt b/compiler/testData/diagnostics/tests/kt13401.ni.txt index 879c71b95a9..fc8d60240d2 100644 --- a/compiler/testData/diagnostics/tests/kt13401.ni.txt +++ b/compiler/testData/diagnostics/tests/kt13401.ni.txt @@ -3,7 +3,7 @@ package public final class Owner { public constructor Owner() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public final fun foo(/*0*/ arg: Owner.Inner<*>): kotlin.Any? + public final fun foo(/*0*/ arg: Owner.Inner<*>): T public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String @@ -26,7 +26,7 @@ public interface Rec> { public interface Super { public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public open fun foo(/*0*/ p: Rec<*>): Rec<*> + public open fun foo(/*0*/ p: Rec<*>): Rec>>>>> public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } diff --git a/compiler/testData/diagnostics/tests/operatorRem/noWarningForModFromBuiltinsWhenApi1_0_after.kt b/compiler/testData/diagnostics/tests/operatorRem/noWarningForModFromBuiltinsWhenApi1_0_after.kt index 74e040d2fff..66b5b196c6f 100644 --- a/compiler/testData/diagnostics/tests/operatorRem/noWarningForModFromBuiltinsWhenApi1_0_after.kt +++ b/compiler/testData/diagnostics/tests/operatorRem/noWarningForModFromBuiltinsWhenApi1_0_after.kt @@ -29,9 +29,9 @@ class WithMod { operator fun mod(other: WithMod) = this fun test() { - val a = this % this + val a = this % this var b = this.mod(this) - b %= this + b %= this } } @@ -43,6 +43,6 @@ fun builtIns(b: Byte, s: Short) { var a = 1 % 2 a %= 3 1.mod(2) - b % s - 1.0 % 2.0 + b % s + 1.0 % 2.0 } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/operatorRem/noWarningForModFromBuiltinsWhenApi1_0_before.kt b/compiler/testData/diagnostics/tests/operatorRem/noWarningForModFromBuiltinsWhenApi1_0_before.kt index 26591343801..ba596d33333 100644 --- a/compiler/testData/diagnostics/tests/operatorRem/noWarningForModFromBuiltinsWhenApi1_0_before.kt +++ b/compiler/testData/diagnostics/tests/operatorRem/noWarningForModFromBuiltinsWhenApi1_0_before.kt @@ -29,9 +29,9 @@ class WithMod { operator fun mod(other: WithMod) = this fun test() { - val a = this % this + val a = this % this var b = this.mod(this) - b %= this + b %= this } } @@ -43,6 +43,6 @@ fun builtIns(b: Byte, s: Short) { var a = 1 % 2 a %= 3 1.mod(2) - b % s - 1.0 % 2.0 + b % s + 1.0 % 2.0 } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/platformTypes/notNullTypeParameter/methodTypeParameter.kt b/compiler/testData/diagnostics/tests/platformTypes/notNullTypeParameter/methodTypeParameter.kt index 7629ccbec8c..e1baf17bc99 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/notNullTypeParameter/methodTypeParameter.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/notNullTypeParameter/methodTypeParameter.kt @@ -11,9 +11,13 @@ public class A { // FILE: k.kt fun test() { - A.bar(null, "") + A.bar(null, "") A.bar(null, "") - A.bar(null, "") - A.bar(null, A.platformString()) + A.bar(null, "") + A.bar(null, A.platformString()) + + val x: String? = null + A.bar(x, "") + A.bar(null, "") } diff --git a/compiler/testData/diagnostics/tests/regressions/correctResultSubstitutorForErrorCandidate.kt b/compiler/testData/diagnostics/tests/regressions/correctResultSubstitutorForErrorCandidate.kt index 8fa76806ef3..6b103f7e083 100644 --- a/compiler/testData/diagnostics/tests/regressions/correctResultSubstitutorForErrorCandidate.kt +++ b/compiler/testData/diagnostics/tests/regressions/correctResultSubstitutorForErrorCandidate.kt @@ -2,7 +2,7 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER fun test(a: Int, b: Boolean) { - bar(a.foo(b)) + bar(a.foo(b)) } fun T.foo(l: (T) -> R): R = TODO() diff --git a/compiler/testData/diagnostics/tests/resolve/implicitAndExplicitThis.kt b/compiler/testData/diagnostics/tests/resolve/implicitAndExplicitThis.kt new file mode 100644 index 00000000000..dd78dcf4a14 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/implicitAndExplicitThis.kt @@ -0,0 +1,29 @@ +// !LANGUAGE: -NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION +// !WITH_NEW_INFERENCE + +abstract class A> { + val x: X = TODO() + + fun getGetX(): X = TODO() +} + +class B : A>() + +class C : A() + +interface X { + fun foo() +} + +fun B<*>.checkValueArguments() { + this.x.foo() + x.foo() + + this.getGetX().foo() + getGetX().foo() +} + +fun C.test() { + x.foo() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/implicitAndExplicitThis.txt b/compiler/testData/diagnostics/tests/resolve/implicitAndExplicitThis.txt new file mode 100644 index 00000000000..2e32585f593 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/implicitAndExplicitThis.txt @@ -0,0 +1,38 @@ +package + +public fun B<*>.checkValueArguments(): kotlin.Unit +public fun C.test(): kotlin.Unit + +public abstract class A> { + public constructor A>() + public final val x: X + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun getGetX(): X + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class B : A> { + public constructor B() + public final override /*1*/ /*fake_override*/ val x: X + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun getGetX(): X + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class C : A { + public constructor C() + public final override /*1*/ /*fake_override*/ val x: X + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun getGetX(): X + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface X { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/resolve/specialConstructions/constantsInIf.kt b/compiler/testData/diagnostics/tests/resolve/specialConstructions/constantsInIf.kt index 2cabddea8fd..a25eabd0684 100644 --- a/compiler/testData/diagnostics/tests/resolve/specialConstructions/constantsInIf.kt +++ b/compiler/testData/diagnostics/tests/resolve/specialConstructions/constantsInIf.kt @@ -8,7 +8,7 @@ fun test() { 2 }) - bar(1 ?: 2) + bar(1 ?: 2) } fun bar(s: String) = s \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/samConversions/kt25290.kt b/compiler/testData/diagnostics/tests/samConversions/kt25290.kt new file mode 100644 index 00000000000..854776fbe1d --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/kt25290.kt @@ -0,0 +1,29 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER +// !WITH_NEW_INFERENCE + +// FILE: JavaFace.java +public interface JavaFace { + void singleMethod(); +} + +// FILE: JavaFaceUser.java +public class JavaFaceUser { + public void use1(JavaFace face) {} + public void use2(JavaFace face) {} +} + +// FILE: KotlinSamUser.kt +fun JavaFaceUser.useOut() { + use1 {} + use2 {} +} + +fun JavaFaceUser.useIn() { + use1 {} + use2 {} +} + +fun JavaFaceUser.useInv() { + use1 {} + use2 {} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/samConversions/kt25290.txt b/compiler/testData/diagnostics/tests/samConversions/kt25290.txt new file mode 100644 index 00000000000..246e191fad0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/kt25290.txt @@ -0,0 +1,21 @@ +package + +public fun JavaFaceUser.useIn(): kotlin.Unit +public fun JavaFaceUser.useInv(): kotlin.Unit +public fun JavaFaceUser.useOut(): kotlin.Unit + +public interface JavaFace { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public abstract fun singleMethod(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class JavaFaceUser { + public constructor JavaFaceUser() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public open fun use1(/*0*/ face: JavaFace!): kotlin.Unit + public open fun use2(/*0*/ face: JavaFace!): kotlin.Unit +} diff --git a/compiler/testData/diagnostics/tests/substitutions/starProjections.kt b/compiler/testData/diagnostics/tests/substitutions/starProjections.kt index d09276c0c03..932d99dc1d3 100644 --- a/compiler/testData/diagnostics/tests/substitutions/starProjections.kt +++ b/compiler/testData/diagnostics/tests/substitutions/starProjections.kt @@ -17,9 +17,9 @@ interface B, T>> { } fun testB(b: B<*, *>) { - b.r().checkType { _() } - b.t().checkType { _, *>>() } + b.r().checkType { _() } + b.t().checkType { _, *>>() } - b.t().r().size + b.t().r().size } diff --git a/compiler/testData/diagnostics/tests/varargs/noAssigningArraysToVarargsFeature.kt b/compiler/testData/diagnostics/tests/varargs/noAssigningArraysToVarargsFeature.kt index fdf985cc372..3d538e89007 100644 --- a/compiler/testData/diagnostics/tests/varargs/noAssigningArraysToVarargsFeature.kt +++ b/compiler/testData/diagnostics/tests/varargs/noAssigningArraysToVarargsFeature.kt @@ -21,21 +21,21 @@ fun test2() {} @Ann(s = arrayOf(1)) fun test3() {} -@Ann(s = ["value"]) +@Ann(s = ["value"]) fun test5() {} @JavaAnn(value = arrayOf("value")) fun jTest1() {} -@JavaAnn(value = ["value"]) +@JavaAnn(value = ["value"]) fun jTest2() {} -@JavaAnn(value = ["value"], path = ["path"]) +@JavaAnn(value = ["value"], path = ["path"]) fun jTest3() {} annotation class IntAnn(vararg val i: Int) -@IntAnn(i = [1, 2]) +@IntAnn(i = [1, 2]) fun foo1() {} @IntAnn(i = intArrayOf(0)) diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/tests/di/injection.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/tests/di/injection.kt index 073dac31aa6..ec0c9028e31 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/tests/di/injection.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/tests/di/injection.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.frontend.di.configureModule import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform +import org.jetbrains.kotlin.types.SubstitutingScopeProviderImpl import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices import org.jetbrains.kotlin.types.expressions.FakeCallResolver @@ -36,6 +37,7 @@ fun createContainerForTests(project: Project, module: ModuleDescriptor): Contain return ContainerForTests(createContainer("Tests", JvmPlatform) { configureModule(ModuleContext(module, project), JvmPlatform, JvmTarget.DEFAULT) useInstance(LanguageVersionSettingsImpl.DEFAULT) + useImpl() useImpl() useImpl() }) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/38.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/38.kt index 9e049683f51..9ef6265551f 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/38.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/38.kt @@ -83,7 +83,7 @@ fun case_5(x: Any?) { & kotlin.Any?"), DEBUG_INFO_SMARTCAST!>x.x x.y x.z - & kotlin.Any?"), DEBUG_INFO_SMARTCAST!>x.ip2test() + & InterfaceWithTwoTypeParameters<*, *> & kotlin.Any & kotlin.Any?")!>x.ip2test() & InterfaceWithTwoTypeParameters<*, *> & kotlin.Any & kotlin.Any?")!>x & kotlin.Any?"), DEBUG_INFO_SMARTCAST!>x.x } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/50.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/50.kt index f0ee96c8535..4b51a667e80 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/50.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/50.kt @@ -14,18 +14,18 @@ // TESTCASE NUMBER: 1 fun Any.case_1() { if (this is Inv<*>) { - "), DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any"), DEBUG_INFO_SMARTCAST!>this.test() - "), DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any"), DEBUG_INFO_SMARTCAST!>this.prop_4 - "), DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any"), DEBUG_INFO_SMARTCAST!>this.prop_4.inv() - prop_4 - prop_4.inv() + & kotlin.Any"), DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>this.test() + & kotlin.Any"), DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>this.prop_4 + & kotlin.Any"), DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>this.prop_4.inv() + prop_4 + prop_4.inv() } } // TESTCASE NUMBER: 2 fun Any.case_2() { if (this is ClassWithSixTypeParameters<*, *, *, *, *, *>) { - "), DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any"), DEBUG_INFO_SMARTCAST!>this.test() + & kotlin.Any"), DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>this.test() "), DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any"), DEBUG_INFO_SMARTCAST!>this.x "), DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any"), DEBUG_INFO_SMARTCAST!>this.y x @@ -36,18 +36,18 @@ fun Any.case_2() { // TESTCASE NUMBER: 3 fun T.case_3() { if (this is Inv<*>) { - "), DEBUG_INFO_EXPRESSION_TYPE("T"), DEBUG_INFO_SMARTCAST!>this.test() - "), DEBUG_INFO_EXPRESSION_TYPE("T"), DEBUG_INFO_SMARTCAST!>this.prop_4 - "), DEBUG_INFO_EXPRESSION_TYPE("T"), DEBUG_INFO_SMARTCAST!>this.prop_4.inv() - prop_4 - prop_4.inv() + & T & T!!"), DEBUG_INFO_EXPRESSION_TYPE("T")!>this.test() + & T & T!!"), DEBUG_INFO_EXPRESSION_TYPE("T")!>this.prop_4 + & T & T!!"), DEBUG_INFO_EXPRESSION_TYPE("T")!>this.prop_4.inv() + prop_4 + prop_4.inv() } } // TESTCASE NUMBER: 4 fun T?.case_4() { if (this is ClassWithSixTypeParameters<*, *, *, *, *, *>) { - "), DEBUG_INFO_EXPRESSION_TYPE("T?"), DEBUG_INFO_SMARTCAST!>this.test() + & T!! & T?"), DEBUG_INFO_EXPRESSION_TYPE("T?")!>this.test() "), DEBUG_INFO_EXPRESSION_TYPE("T?"), DEBUG_INFO_SMARTCAST!>this.x "), DEBUG_INFO_EXPRESSION_TYPE("T?"), DEBUG_INFO_SMARTCAST!>this.y x diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index e57c8a3f796..c30007c8787 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -8093,6 +8093,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/generics/argumentsForT.kt"); } + @TestMetadata("capturedTypeInInputPosition.kt") + public void testCapturedTypeInInputPosition() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/capturedTypeInInputPosition.kt"); + } + @TestMetadata("commonSupertypeContravariant.kt") public void testCommonSupertypeContravariant() throws Exception { runTest("compiler/testData/diagnostics/tests/generics/commonSupertypeContravariant.kt"); @@ -8932,6 +8937,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.kt"); } + @TestMetadata("setterProjectedOutAssignFromJava.kt") + public void testSetterProjectedOutAssignFromJava() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssignFromJava.kt"); + } + @TestMetadata("setterProjectedOutNoPlusAssign.kt") public void testSetterProjectedOutNoPlusAssign() throws Exception { runTest("compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.kt"); @@ -17375,6 +17385,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/resolve/HiddenDeclarations.kt"); } + @TestMetadata("implicitAndExplicitThis.kt") + public void testImplicitAndExplicitThis() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/implicitAndExplicitThis.kt"); + } + @TestMetadata("implicitReceiverProperty.kt") public void testImplicitReceiverProperty() throws Exception { runTest("compiler/testData/diagnostics/tests/resolve/implicitReceiverProperty.kt"); @@ -18092,6 +18107,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/samConversions/GenericSubstitutionKT.kt"); } + @TestMetadata("kt25290.kt") + public void testKt25290() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/kt25290.kt"); + } + @TestMetadata("OverloadPriority.kt") public void testOverloadPriority() throws Exception { runTest("compiler/testData/diagnostics/tests/samConversions/OverloadPriority.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 4716bafbf3d..6cc1567e079 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -8088,6 +8088,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/generics/argumentsForT.kt"); } + @TestMetadata("capturedTypeInInputPosition.kt") + public void testCapturedTypeInInputPosition() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/capturedTypeInInputPosition.kt"); + } + @TestMetadata("commonSupertypeContravariant.kt") public void testCommonSupertypeContravariant() throws Exception { runTest("compiler/testData/diagnostics/tests/generics/commonSupertypeContravariant.kt"); @@ -8927,6 +8932,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.kt"); } + @TestMetadata("setterProjectedOutAssignFromJava.kt") + public void testSetterProjectedOutAssignFromJava() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssignFromJava.kt"); + } + @TestMetadata("setterProjectedOutNoPlusAssign.kt") public void testSetterProjectedOutNoPlusAssign() throws Exception { runTest("compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.kt"); @@ -17365,6 +17375,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/resolve/HiddenDeclarations.kt"); } + @TestMetadata("implicitAndExplicitThis.kt") + public void testImplicitAndExplicitThis() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/implicitAndExplicitThis.kt"); + } + @TestMetadata("implicitReceiverProperty.kt") public void testImplicitReceiverProperty() throws Exception { runTest("compiler/testData/diagnostics/tests/resolve/implicitReceiverProperty.kt"); @@ -18082,6 +18097,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/samConversions/GenericSubstitutionKT.kt"); } + @TestMetadata("kt25290.kt") + public void testKt25290() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/kt25290.kt"); + } + @TestMetadata("OverloadPriority.kt") public void testOverloadPriority() throws Exception { runTest("compiler/testData/diagnostics/tests/samConversions/OverloadPriority.kt"); diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/context.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/context.kt index c1b5e3a7b41..0aa53821404 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/context.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/context.kt @@ -42,6 +42,7 @@ import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder import org.jetbrains.kotlin.load.kotlin.PackagePartProvider import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.types.SubstitutingScopeProvider import java.util.* class JavaResolverComponents( @@ -64,7 +65,8 @@ class JavaResolverComponents( val annotationTypeQualifierResolver: AnnotationTypeQualifierResolver, val signatureEnhancement: SignatureEnhancement, val javaClassesTracker: JavaClassesTracker, - val settings: JavaResolverSettings + val settings: JavaResolverSettings, + val substitutingScopeProvider: SubstitutingScopeProvider ) { fun replace( javaResolverCache: JavaResolverCache = this.javaResolverCache @@ -73,7 +75,7 @@ class JavaResolverComponents( signaturePropagator, errorReporter, javaResolverCache, javaPropertyInitializerEvaluator, samConversionResolver, sourceElementFactory, moduleClassResolver, packagePartProvider, supertypeLoopChecker, lookupTracker, module, reflectionTypes, - annotationTypeQualifierResolver, signatureEnhancement, javaClassesTracker, settings + annotationTypeQualifierResolver, signatureEnhancement, javaClassesTracker, settings, substitutingScopeProvider ) } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt index ac4bbf67334..8c7cc5cfd74 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt @@ -46,7 +46,8 @@ class LazyJavaClassDescriptor( ) : ClassDescriptorBase( outerContext.storageManager, containingDeclaration, jClass.name, outerContext.components.sourceElementFactory.source(jClass), - /* isExternal = */ false + /* isExternal = */ false, + outerContext.components.substitutingScopeProvider ), JavaClassDescriptor { companion object { diff --git a/core/descriptors.runtime/src/kotlin/reflect/jvm/internal/components/RuntimeModuleData.kt b/core/descriptors.runtime/src/kotlin/reflect/jvm/internal/components/RuntimeModuleData.kt index 45bcf3391f5..6bb98066a41 100644 --- a/core/descriptors.runtime/src/kotlin/reflect/jvm/internal/components/RuntimeModuleData.kt +++ b/core/descriptors.runtime/src/kotlin/reflect/jvm/internal/components/RuntimeModuleData.kt @@ -43,6 +43,7 @@ import org.jetbrains.kotlin.serialization.deserialization.ContractDeserializer import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration import org.jetbrains.kotlin.storage.LockBasedStorageManager +import org.jetbrains.kotlin.types.SubstitutingScopeProvider import org.jetbrains.kotlin.utils.Jsr305State class RuntimeModuleData private constructor( @@ -70,7 +71,7 @@ class RuntimeModuleData private constructor( singleModuleClassResolver, PackagePartProvider.Empty, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING, module, ReflectionTypes(module, notFoundClasses), annotationTypeQualifierResolver, SignatureEnhancement(annotationTypeQualifierResolver, Jsr305State.DISABLED), - JavaClassesTracker.Default, JavaResolverSettings.Default + JavaClassesTracker.Default, JavaResolverSettings.Default, SubstitutingScopeProvider.DEFAULT ) val lazyJavaPackageFragmentProvider = LazyJavaPackageFragmentProvider(javaResolverComponents) diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java index 59d62742da0..ddeef6efd43 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java @@ -24,7 +24,6 @@ import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.resolve.scopes.InnerClassesScopeWrapper; import org.jetbrains.kotlin.resolve.scopes.MemberScope; -import org.jetbrains.kotlin.resolve.scopes.SubstitutingScope; import org.jetbrains.kotlin.storage.NotNullLazyValue; import org.jetbrains.kotlin.storage.StorageManager; import org.jetbrains.kotlin.types.*; @@ -34,10 +33,11 @@ import java.util.List; public abstract class AbstractClassDescriptor implements ClassDescriptor { private final Name name; protected final NotNullLazyValue defaultType; + protected final SubstitutingScopeProvider substitutingScopeProvider; private final NotNullLazyValue unsubstitutedInnerClassesScope; private final NotNullLazyValue thisAsReceiverParameter; - public AbstractClassDescriptor(@NotNull StorageManager storageManager, @NotNull Name name) { + public AbstractClassDescriptor(@NotNull StorageManager storageManager, @NotNull Name name, @NotNull SubstitutingScopeProvider substitutingScopeProvider) { this.name = name; this.defaultType = storageManager.createLazyValue(new Function0() { @Override @@ -57,6 +57,11 @@ public abstract class AbstractClassDescriptor implements ClassDescriptor { return new LazyClassReceiverParameterDescriptor(AbstractClassDescriptor.this); } }); + this.substitutingScopeProvider = substitutingScopeProvider; + } + + public AbstractClassDescriptor(@NotNull StorageManager storageManager, @NotNull Name name) { + this(storageManager, name, SubstitutingScopeProvider.Companion.getDEFAULT()); } @NotNull @@ -92,7 +97,7 @@ public abstract class AbstractClassDescriptor implements ClassDescriptor { if (typeArguments.isEmpty()) return getUnsubstitutedMemberScope(); TypeSubstitutor substitutor = TypeConstructorSubstitution.create(getTypeConstructor(), typeArguments).buildSubstitutor(); - return new SubstitutingScope(getUnsubstitutedMemberScope(), substitutor); + return substitutingScopeProvider.createSubstitutingScope(getUnsubstitutedMemberScope(), substitutor); } @NotNull @@ -101,7 +106,7 @@ public abstract class AbstractClassDescriptor implements ClassDescriptor { if (typeSubstitution.isEmpty()) return getUnsubstitutedMemberScope(); TypeSubstitutor substitutor = TypeSubstitutor.create(typeSubstitution); - return new SubstitutingScope(getUnsubstitutedMemberScope(), substitutor); + return substitutingScopeProvider.createSubstitutingScope(getUnsubstitutedMemberScope(), substitutor); } @NotNull @@ -110,7 +115,7 @@ public abstract class AbstractClassDescriptor implements ClassDescriptor { if (substitutor.isEmpty()) { return this; } - return new LazySubstitutingClassDescriptor(this, substitutor); + return new LazySubstitutingClassDescriptor(this, substitutor, substitutingScopeProvider); } @NotNull diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorBase.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorBase.java index f4b4c75f8b2..5d8f9220c96 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorBase.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorBase.java @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.SourceElement; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.storage.StorageManager; +import org.jetbrains.kotlin.types.SubstitutingScopeProvider; public abstract class ClassDescriptorBase extends AbstractClassDescriptor { @@ -35,7 +36,18 @@ public abstract class ClassDescriptorBase extends AbstractClassDescriptor { @NotNull SourceElement source, boolean isExternal ) { - super(storageManager, name); + this(storageManager, containingDeclaration, name, source, isExternal, SubstitutingScopeProvider.Companion.getDEFAULT()); + } + + protected ClassDescriptorBase( + @NotNull StorageManager storageManager, + @NotNull DeclarationDescriptor containingDeclaration, + @NotNull Name name, + @NotNull SourceElement source, + boolean isExternal, + @NotNull SubstitutingScopeProvider substitutingScopeProvider + ) { + super(storageManager, name, substitutingScopeProvider); this.containingDeclaration = containingDeclaration; this.source = source; this.isExternal = isExternal; diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java index 2842c4f1fcd..1010090c4b0 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java @@ -324,11 +324,21 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo } @Override + @Nullable public FunctionDescriptor substitute(@NotNull TypeSubstitutor originalSubstitutor) { + return substitute(originalSubstitutor, SubstitutingScopeProvider.Companion.getDEFAULT()); + } + + @Nullable + public FunctionDescriptor substitute(@NotNull TypeSubstitutor originalSubstitutor, SubstitutingScopeProvider substitutingScopeProvider) { if (originalSubstitutor.isEmpty()) { return this; } - return newCopyBuilder(originalSubstitutor).setOriginal(getOriginal()).setJustForTypeSubstitution(true).build(); + return newCopyBuilder(originalSubstitutor) + .setOriginal(getOriginal()) + .setJustForTypeSubstitution(true) + .setSubstitutingScopeProvider(substitutingScopeProvider) + .build(); } @Nullable @@ -365,6 +375,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo private Map, Object> userDataMap = new LinkedHashMap, Object>(); private Boolean newHasSynthesizedParameterNames = null; protected boolean justForTypeSubstitution = false; + protected @NotNull SubstitutingScopeProvider substitutingScopeProvider; public CopyConfiguration( @NotNull TypeSubstitution substitution, @@ -386,6 +397,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo this.newExtensionReceiverParameter = newExtensionReceiverParameter; this.newReturnType = newReturnType; this.name = name; + substitutingScopeProvider = SubstitutingScopeProvider.Companion.getDEFAULT(); } @Override @@ -554,6 +566,12 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo justForTypeSubstitution = value; return this; } + + @NotNull + public CopyConfiguration setSubstitutingScopeProvider(@NotNull SubstitutingScopeProvider substitutingScopeProvider) { + this.substitutingScopeProvider = substitutingScopeProvider; + return this; + } } @Override @@ -591,7 +609,8 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo List substitutedTypeParameters = new ArrayList(unsubstitutedTypeParameters.size()); final TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters( - unsubstitutedTypeParameters, configuration.substitution, substitutedDescriptor, substitutedTypeParameters, wereChanges + unsubstitutedTypeParameters, configuration.substitution, substitutedDescriptor, substitutedTypeParameters, + wereChanges, configuration.substitutingScopeProvider ); if (substitutor == null) return null; diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java index aa45dbbaa04..88d613d6ca8 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java @@ -28,10 +28,12 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor { private List typeConstructorParameters; private List declaredTypeParameters; private TypeConstructor typeConstructor; + private final SubstitutingScopeProvider substitutingScopeProvider; - public LazySubstitutingClassDescriptor(ClassDescriptor descriptor, TypeSubstitutor substitutor) { + public LazySubstitutingClassDescriptor(ClassDescriptor descriptor, TypeSubstitutor substitutor, SubstitutingScopeProvider substitutingScopeProvider) { this.original = descriptor; this.originalSubstitutor = substitutor; + this.substitutingScopeProvider = substitutingScopeProvider; } private TypeSubstitutor getSubstitutor() { @@ -87,7 +89,7 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor { if (originalSubstitutor.isEmpty()) { return memberScope; } - return new SubstitutingScope(memberScope, getSubstitutor()); + return substitutingScopeProvider.createSubstitutingScope(memberScope, getSubstitutor()); } @NotNull @@ -97,7 +99,7 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor { if (originalSubstitutor.isEmpty()) { return memberScope; } - return new SubstitutingScope(memberScope, getSubstitutor()); + return substitutingScopeProvider.createSubstitutingScope(memberScope, getSubstitutor()); } @NotNull @@ -107,7 +109,7 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor { if (originalSubstitutor.isEmpty()) { return memberScope; } - return new SubstitutingScope(memberScope, getSubstitutor()); + return substitutingScopeProvider.createSubstitutingScope(memberScope, getSubstitutor()); } @NotNull @@ -175,7 +177,7 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor { @Override public ClassDescriptor substitute(@NotNull TypeSubstitutor substitutor) { if (substitutor.isEmpty()) return this; - return new LazySubstitutingClassDescriptor(this, TypeSubstitutor.createChainedSubstitutor(substitutor.getSubstitution(), getSubstitutor().getSubstitution())); + return new LazySubstitutingClassDescriptor(this, TypeSubstitutor.createChainedSubstitutor(substitutor.getSubstitution(), getSubstitutor().getSubstitution()), substitutingScopeProvider); } @Override diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java index 0a3154a4f70..8b688fd53ce 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java @@ -47,6 +47,8 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp private final boolean isExternal; private final boolean isDelegated; + private final SubstitutingScopeProvider substitutingScopeProvider; + private ReceiverParameterDescriptor dispatchReceiverParameter; private ReceiverParameterDescriptor extensionReceiverParameter; private List typeParameters; @@ -72,6 +74,28 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp boolean isActual, boolean isExternal, boolean isDelegated + ) { + this(containingDeclaration, original, annotations, modality, visibility, isVar, name, kind, source, + lateInit, isConst, isExpect, isActual, isExternal, isDelegated, SubstitutingScopeProvider.Companion.getDEFAULT()); + } + + protected PropertyDescriptorImpl( + @NotNull DeclarationDescriptor containingDeclaration, + @Nullable PropertyDescriptor original, + @NotNull Annotations annotations, + @NotNull Modality modality, + @NotNull Visibility visibility, + boolean isVar, + @NotNull Name name, + @NotNull Kind kind, + @NotNull SourceElement source, + boolean lateInit, + boolean isConst, + boolean isExpect, + boolean isActual, + boolean isExternal, + boolean isDelegated, + @NotNull SubstitutingScopeProvider substitutingScopeProvider ) { super(containingDeclaration, annotations, name, null, isVar, source); this.modality = modality; @@ -84,6 +108,7 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp this.isActual = isActual; this.isExternal = isExternal; this.isDelegated = isDelegated; + this.substitutingScopeProvider = substitutingScopeProvider; } @NotNull @@ -102,10 +127,39 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp boolean isActual, boolean isExternal, boolean isDelegated + ) { + return create(containingDeclaration, annotations, modality, visibility, isVar, name, kind, source, + lateInit, isConst, isExpect, isActual, isExternal, isDelegated, SubstitutingScopeProvider.Companion.getDEFAULT()); + } + + @NotNull + public static PropertyDescriptorImpl create( + @NotNull DeclarationDescriptor containingDeclaration, + @NotNull Annotations annotations, + @NotNull Modality modality, + @NotNull Visibility visibility, + boolean isVar, + @NotNull Name name, + @NotNull Kind kind, + @NotNull SourceElement source, + boolean lateInit, + boolean isConst, + boolean isExpect, + boolean isActual, + boolean isExternal, + boolean isDelegated, + @NotNull SubstitutingScopeProvider substitutingScopeProvider ) { return new PropertyDescriptorImpl(containingDeclaration, null, annotations, modality, visibility, isVar, name, kind, source, lateInit, isConst, - isExpect, isActual, isExternal, isDelegated); + isExpect, isActual, isExternal, isDelegated, substitutingScopeProvider); + } + + @NotNull + public PropertyDescriptorImpl getCopy() { + return new PropertyDescriptorImpl(getContainingDeclaration(), original, getAnnotations(), + modality, visibility, isVar(), getName(), kind, getSource(), lateInit, isConst, + isExpect, isActual, isExternal, isDelegated, substitutingScopeProvider); } public void setType( @@ -258,6 +312,7 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp private ReceiverParameterDescriptor dispatchReceiverParameter = PropertyDescriptorImpl.this.dispatchReceiverParameter; private List newTypeParameters = null; private Name name = getName(); + private boolean setterProjectedOut = PropertyDescriptorImpl.this.setterProjectedOut; @NotNull @Override @@ -364,6 +419,7 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters( originalTypeParameters, copyConfiguration.substitution, substitutedDescriptor, substitutedTypeParameters ); + substitutor.setSubstitutingScopeProvider(substitutingScopeProvider); KotlinType originalOutType = getType(); KotlinType outType = substitutor.substitute(originalOutType, Variance.OUT_VARIANCE); @@ -460,6 +516,8 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp substitutedDescriptor.setCompileTimeInitializer(compileTimeInitializer); } + substitutedDescriptor.setterProjectedOut = copyConfiguration.setterProjectedOut; + return substitutedDescriptor; } @@ -470,7 +528,7 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp return prev; } - private static FunctionDescriptor getSubstitutedInitialSignatureDescriptor( + public static FunctionDescriptor getSubstitutedInitialSignatureDescriptor( @NotNull TypeSubstitutor substitutor, @NotNull PropertyAccessorDescriptor accessorDescriptor ) { @@ -490,7 +548,7 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp ) { return new PropertyDescriptorImpl( newOwner, original, getAnnotations(), newModality, newVisibility, isVar(), newName, kind, SourceElement.NO_SOURCE, - isLateInit(), isConst(), isExpect(), isActual(), isExternal(), isDelegated() + isLateInit(), isConst(), isExpect(), isActual(), isExternal(), isDelegated(), substitutingScopeProvider ); } @@ -564,4 +622,9 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp public V getUserData(UserDataKey key) { return null; } + + @NotNull + public SubstitutingScopeProvider getSubstitutingScopeProvider() { + return substitutingScopeProvider; + } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ValueParameterDescriptorImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ValueParameterDescriptorImpl.kt index 05f39458aae..74e017b181e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ValueParameterDescriptorImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ValueParameterDescriptorImpl.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeSubstitutor +import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.utils.join open class ValueParameterDescriptorImpl( @@ -102,8 +103,7 @@ open class ValueParameterDescriptorImpl( override fun getOriginal() = if (original === this) this else original.original override fun substitute(substitutor: TypeSubstitutor): ValueParameterDescriptor { - if (substitutor.isEmpty) return this - throw UnsupportedOperationException() // TODO + return this } override fun accept(visitor: DeclarationDescriptorVisitor, data: D): R { diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt index d06a1e53ed5..cc71ca00dea 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt @@ -100,16 +100,25 @@ class CapturedType( CapturedType(typeProjection, constructor, isMarkedNullable, newAnnotations) } +object OldCapturedTypeCreator : CapturedTypeCreator { + override fun createCapturedType(typeProjection: TypeProjection): TypeProjection { + return TypeProjectionImpl(CapturedType(typeProjection)) + } +} + fun createCapturedType(typeProjection: TypeProjection): KotlinType = CapturedType(typeProjection) fun KotlinType.isCaptured(): Boolean = constructor is CapturedTypeConstructor -fun TypeSubstitution.wrapWithCapturingSubstitution(needApproximation: Boolean = true): TypeSubstitution = +fun TypeSubstitution.wrapWithCapturingSubstitution( + capturedTypeCreator: CapturedTypeCreator = OldCapturedTypeCreator, + needApproximation: Boolean = true +): TypeSubstitution = if (this is IndexedParametersSubstitution) IndexedParametersSubstitution( this.parameters, this.arguments.zip(this.parameters).map { - it.first.createCapturedIfNeeded(it.second) + it.first.createCapturedIfNeeded(it.second, capturedTypeCreator) }.toTypedArray(), approximateCapturedTypes = needApproximation ) @@ -117,10 +126,16 @@ fun TypeSubstitution.wrapWithCapturingSubstitution(needApproximation: Boolean = object : DelegatedTypeSubstitution(this@wrapWithCapturingSubstitution) { override fun approximateContravariantCapturedTypes() = needApproximation override fun get(key: KotlinType) = - super.get(key)?.createCapturedIfNeeded(key.constructor.declarationDescriptor as? TypeParameterDescriptor) + super.get(key)?.createCapturedIfNeeded( + key.constructor.declarationDescriptor as? TypeParameterDescriptor, + capturedTypeCreator + ) } -private fun TypeProjection.createCapturedIfNeeded(typeParameterDescriptor: TypeParameterDescriptor?): TypeProjection { +private fun TypeProjection.createCapturedIfNeeded( + typeParameterDescriptor: TypeParameterDescriptor?, + capturedTypeCreator: CapturedTypeCreator +): TypeProjection { if (typeParameterDescriptor == null || projectionKind == Variance.INVARIANT) return this // Treat consistent projections as invariant @@ -134,5 +149,5 @@ private fun TypeProjection.createCapturedIfNeeded(typeParameterDescriptor: TypeP TypeProjectionImpl(this@createCapturedIfNeeded.type) } - return TypeProjectionImpl(createCapturedType(this)) + return capturedTypeCreator.createCapturedType(this) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SubstitutingScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SubstitutingScope.kt index 7da12970861..de67e867a9e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SubstitutingScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SubstitutingScope.kt @@ -18,18 +18,24 @@ package org.jetbrains.kotlin.resolve.scopes import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.Substitutable +import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl import org.jetbrains.kotlin.incremental.components.LookupLocation +import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.inference.wrapWithCapturingSubstitution +import org.jetbrains.kotlin.types.ErrorUtils +import org.jetbrains.kotlin.types.SubstitutingScopeProvider import org.jetbrains.kotlin.types.TypeSubstitutor import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.newLinkedHashSetWithExpectedSize import org.jetbrains.kotlin.utils.sure import java.util.* -class SubstitutingScope(private val workerScope: MemberScope, givenSubstitutor: TypeSubstitutor) : MemberScope { +class SubstitutingScope(private val workerScope: MemberScope, givenSubstitutor: TypeSubstitutor, private val substitutingScopeProvider: SubstitutingScopeProvider) : MemberScope { - private val substitutor = givenSubstitutor.substitution.wrapWithCapturingSubstitution().buildSubstitutor() + private val substitutor: TypeSubstitutor = givenSubstitutor.substitution + .wrapWithCapturingSubstitution(capturedTypeCreator = substitutingScopeProvider.provideCapturedTypeCreator()) + .buildSubstitutor().also { it.setSubstitutingScopeProvider(substitutingScopeProvider) } private var substitutedDescriptors: MutableMap? = null @@ -43,11 +49,44 @@ class SubstitutingScope(private val workerScope: MemberScope, givenSubstitutor: } val substituted = substitutedDescriptors!!.getOrPut(descriptor) { + val assertionMessage = { + "We expect that no conflict should happen while substitution is guaranteed to generate invariant projection, " + + "but $descriptor substitution fails" + } when (descriptor) { - is Substitutable<*> -> descriptor.substitute(substitutor).sure { - "We expect that no conflict should happen while substitution is guaranteed to generate invariant projection, " + - "but $descriptor substitution fails" + /* + * Here we can take null if NI enabled, because inside this place we have OI and NI collide. See following example: + * + * class Out + * + * class A { + * fun T.foo() {} + * fun Out.bar() {} + * } + * + * fun test(x: A, y: Out) { + * with(x) { + * "".foo() <-- problem is here + * } + * } + * + * Because of we don't capture type projections, in call "".foo() we have `out CharSequence` as substituted type `T` + * (instead of `CapturedType(out CharSequence)`, and `in String` as type from receiver, so we have type variance error + * and can not substitute descriptor. + * + * So, fix of it is hack + */ + is FunctionDescriptorImpl -> { + val substitutedDescriptor = descriptor.substitute(substitutor, substitutingScopeProvider) + if (substitutingScopeProvider.isNewInferenceEnabled) { + substitutedDescriptor ?: ErrorUtils.createErrorScope("Cannot substitute functional descriptor") + .getContributedFunctions(descriptor.name, NoLookupLocation.WHEN_RESOLVE_DECLARATION).first() + } else { + substitutedDescriptor.sure(assertionMessage) + } } + + is Substitutable<*> -> descriptor.substitute(substitutor).sure(assertionMessage) else -> error("Unknown descriptor in scope: $descriptor") } } @@ -72,7 +111,7 @@ class SubstitutingScope(private val workerScope: MemberScope, givenSubstitutor: override fun getContributedVariables(name: Name, location: LookupLocation) = substitute(workerScope.getContributedVariables(name, location)) override fun getContributedClassifier(name: Name, location: LookupLocation) = - workerScope.getContributedClassifier(name, location)?.let { substitute(it) } + workerScope.getContributedClassifier(name, location)?.let { substitute(it) } override fun getContributedFunctions(name: Name, location: LookupLocation) = substitute(workerScope.getContributedFunctions(name, location)) diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/CapturedTypeApproximation.kt b/core/descriptors/src/org/jetbrains/kotlin/types/CapturedTypeApproximation.kt index 8498af270b8..0e7cdd3600f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/CapturedTypeApproximation.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/CapturedTypeApproximation.kt @@ -28,6 +28,12 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.typeUtil.builtIns import java.util.* +class OldCaptureTypeApproximator : CapturedTypeApproximator { + override fun approximateCapturedTypes(typeProjection: TypeProjection?, approximateContravariant: Boolean): TypeProjection? { + return approximateCapturedTypesIfNecessary(typeProjection, approximateContravariant) + } +} + data class ApproximationBounds( val lower: T, val upper: T diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/DescriptorSubstitutor.java b/core/descriptors/src/org/jetbrains/kotlin/types/DescriptorSubstitutor.java index 0bb756907ec..aa99355b6bd 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/DescriptorSubstitutor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/DescriptorSubstitutor.java @@ -40,7 +40,7 @@ public class DescriptorSubstitutor { @NotNull DeclarationDescriptor newContainingDeclaration, @NotNull @Mutable List result ) { - TypeSubstitutor substitutor = substituteTypeParameters(typeParameters, originalSubstitution, newContainingDeclaration, result, null); + TypeSubstitutor substitutor = substituteTypeParameters(typeParameters, originalSubstitution, newContainingDeclaration, result, null, SubstitutingScopeProvider.Companion.getDEFAULT()); if (substitutor == null) throw new AssertionError("Substitution failed"); return substitutor; } @@ -51,7 +51,8 @@ public class DescriptorSubstitutor { @NotNull TypeSubstitution originalSubstitution, @NotNull DeclarationDescriptor newContainingDeclaration, @NotNull @Mutable List result, - @Nullable boolean[] wereChanges + @Nullable boolean[] wereChanges, + @NotNull SubstitutingScopeProvider substitutingScopeProvider ) { Map mutableSubstitution = new HashMap(); @@ -76,7 +77,7 @@ public class DescriptorSubstitutor { TypeSubstitutor substitutor = TypeSubstitutor.createChainedSubstitutor( originalSubstitution, TypeConstructorSubstitution.createByConstructorsMap(mutableSubstitution) - ); + ).setSubstitutingScopeProvider(substitutingScopeProvider); for (TypeParameterDescriptor descriptor : typeParameters) { TypeParameterDescriptorImpl substituted = substitutedMap.get(descriptor); diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/SubstitutingScopeProvider.kt b/core/descriptors/src/org/jetbrains/kotlin/types/SubstitutingScopeProvider.kt new file mode 100644 index 00000000000..2a17c1aa89a --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/types/SubstitutingScopeProvider.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.types + +import org.jetbrains.kotlin.resolve.calls.inference.OldCapturedTypeCreator +import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.resolve.scopes.SubstitutingScope +import org.jetbrains.kotlin.types.typesApproximation.OldCaptureTypeApproximator + +interface SubstitutingScopeProvider { + fun createSubstitutingScope(workerScope: MemberScope, givenSubstitutor: TypeSubstitutor): SubstitutingScope + + fun provideCapturedTypeCreator(): CapturedTypeCreator + + fun provideApproximator(): CapturedTypeApproximator + + val isNewInferenceEnabled: Boolean + + companion object { + val DEFAULT: SubstitutingScopeProvider = object : SubstitutingScopeProvider { + override fun createSubstitutingScope(workerScope: MemberScope, givenSubstitutor: TypeSubstitutor): SubstitutingScope { + return SubstitutingScope(workerScope, givenSubstitutor, this) + } + + override fun provideCapturedTypeCreator(): CapturedTypeCreator { + return OldCapturedTypeCreator + } + + override fun provideApproximator(): CapturedTypeApproximator { + return OldCaptureTypeApproximator() + } + + override val isNewInferenceEnabled: Boolean get() = false + } + } +} + +interface CapturedTypeCreator { + fun createCapturedType(typeProjection: TypeProjection): TypeProjection +} + +interface CapturedTypeApproximator { + fun approximateCapturedTypes(typeProjection: TypeProjection?, approximateContravariant: Boolean): TypeProjection? +} \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java index af389bed94e..c0b5fe59141 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java @@ -28,7 +28,6 @@ import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.resolve.calls.inference.CapturedTypeConstructorKt; import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker; import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt; -import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt; import org.jetbrains.kotlin.utils.ExceptionUtilsKt; import java.util.ArrayList; @@ -47,6 +46,14 @@ public class TypeSubstitutor implements TypeSubstitutorMarker { } } + private @NotNull SubstitutingScopeProvider substitutingScopeProvider; + + @NotNull + public TypeSubstitutor setSubstitutingScopeProvider(@NotNull SubstitutingScopeProvider substitutingScopeProvider) { + this.substitutingScopeProvider = substitutingScopeProvider; + return this; + } + @NotNull public static TypeSubstitutor create(@NotNull TypeSubstitution substitution) { return new TypeSubstitutor(substitution); @@ -73,6 +80,7 @@ public class TypeSubstitutor implements TypeSubstitutorMarker { protected TypeSubstitutor(@NotNull TypeSubstitution substitution) { this.substitution = substitution; + this.substitutingScopeProvider = SubstitutingScopeProvider.Companion.getDEFAULT(); } public boolean isEmpty() { @@ -110,8 +118,12 @@ public class TypeSubstitutor implements TypeSubstitutorMarker { if (!substitution.approximateCapturedTypes() && !substitution.approximateContravariantCapturedTypes()) { return substitutedTypeProjection; } - return CapturedTypeApproximationKt.approximateCapturedTypesIfNecessary( - substitutedTypeProjection, substitution.approximateContravariantCapturedTypes()); + + CapturedTypeApproximator approximator = substitutingScopeProvider.provideApproximator(); + return approximator.approximateCapturedTypes( + substitutedTypeProjection, + substitution.approximateContravariantCapturedTypes() + ); } @Nullable diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java index 66e37d9a706..24e5440540e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java @@ -55,6 +55,11 @@ public class TypeUtils { throw new IllegalStateException(name); } + @Override + public boolean isMarkedNullable() { + return false; + } + @NotNull @Override public String toString() { diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt index c7755993f0d..570f1215948 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -521,6 +521,10 @@ internal fun UnwrappedType.typeDepthInternal() = internal fun SimpleType.typeDepthInternal(): Int { if (this is TypeUtils.SpecialType) return 0 + if (this is NewCapturedType) { + return constructor.projection.type.unwrap().typeDepthInternal() + } + val maxInArguments = arguments.asSequence().map { if (it.isStarProjection) 1 else it.type.unwrap().typeDepthInternal() }.max() ?: 0 diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/IDELightClassContexts.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/IDELightClassContexts.kt index 00ff6905f7e..e27adb32b3e 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/IDELightClassContexts.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/IDELightClassContexts.kt @@ -71,10 +71,7 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProvid import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.StorageManager -import org.jetbrains.kotlin.types.ErrorUtils -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.TypeUtils -import org.jetbrains.kotlin.types.WrappedTypeFactory +import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.utils.sure @@ -333,7 +330,7 @@ internal object IDELightClassContexts { }) IdeaEnvironment.configure(this) - + useImpl() useImpl() } diff --git a/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt b/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt index ed001f98d0d..0d6507db3c2 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt @@ -36,6 +36,7 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil import org.jetbrains.kotlin.serialization.js.PackagesWithHeaderMetadata +import org.jetbrains.kotlin.types.SubstitutingScopeProviderImpl fun createTopDownAnalyzerForJs( moduleContext: ModuleContext, @@ -59,6 +60,7 @@ fun createTopDownAnalyzerForJs( useInstance(languageVersionSettings) useImpl() useImpl() + useImpl() }.apply { val packagePartProviders = mutableListOf(get().packageFragmentProvider) val moduleDescriptor = get()