From 06ce57ea5627f080176285e3a4593edd4e3122eb Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 1 Dec 2023 15:20:28 +0100 Subject: [PATCH] K2: report MISSING_DEPENDENCY_CLASS for lambda parameters if needed #KT-62525 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 6 ++ ...sticCompilerFE10TestDataTestGenerated.java | 6 ++ ...eeOldFrontendDiagnosticsTestGenerated.java | 6 ++ ...siOldFrontendDiagnosticsTestGenerated.java | 6 ++ .../checkers/CommonDeclarationCheckers.kt | 1 + ...ssingDependencyClassForParameterChecker.kt | 25 ++++++ .../FirMissingDependencyClassChecker.kt | 69 +++++++++----- .../jetbrains/kotlin/fir/types/ConeTypes.kt | 1 + .../fir/serialization/serializationUtil.kt | 2 +- .../fir/resolve/substitution/Substitutors.kt | 4 +- .../kotlin/fir/types/ConeInferenceContext.kt | 10 +-- .../jetbrains/kotlin/fir/types/TypeUtils.kt | 2 +- .../kotlin/ir/types/IrTypeSystemContext.kt | 2 +- .../calls/NewCommonSuperTypeCalculator.kt | 2 +- .../kotlin/types/AbstractTypeApproximator.kt | 8 +- .../diagnostics/tests/javac/Lambda.diag.txt | 10 +++ .../tests/javac/Lambda.fir.diag.txt | 7 ++ .../diagnostics/tests/javac/Lambda.fir.kt | 90 +++++++++++++++++++ .../diagnostics/tests/javac/Lambda.kt | 90 +++++++++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 6 ++ .../DiagnosticUsingJavacTestGenerated.java | 6 ++ .../kotlin/types/model/TypeSystemContext.kt | 2 +- .../types/checker/ClassicTypeSystemContext.kt | 5 +- 23 files changed, 325 insertions(+), 41 deletions(-) create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMissingDependencyClassForParameterChecker.kt create mode 100644 compiler/testData/diagnostics/tests/javac/Lambda.diag.txt create mode 100644 compiler/testData/diagnostics/tests/javac/Lambda.fir.diag.txt create mode 100644 compiler/testData/diagnostics/tests/javac/Lambda.fir.kt create mode 100644 compiler/testData/diagnostics/tests/javac/Lambda.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index f2a02476cbb..fd94d20a6e7 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -22742,6 +22742,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/javac/Annotations.kt"); } + @Test + @TestMetadata("Lambda.kt") + public void testLambda() throws Exception { + runTest("compiler/testData/diagnostics/tests/javac/Lambda.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution") @TestDataPath("$PROJECT_ROOT") diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index c90156fe34c..f912831885a 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -22742,6 +22742,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/javac/Annotations.kt"); } + @Test + @TestMetadata("Lambda.kt") + public void testLambda() throws Exception { + runTest("compiler/testData/diagnostics/tests/javac/Lambda.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index b41816b92c0..b6eb1ed5fe1 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -22736,6 +22736,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/javac/Annotations.kt"); } + @Test + @TestMetadata("Lambda.kt") + public void testLambda() throws Exception { + runTest("compiler/testData/diagnostics/tests/javac/Lambda.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index a1b258b561f..970601e6df3 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -22742,6 +22742,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/javac/Annotations.kt"); } + @Test + @TestMetadata("Lambda.kt") + public void testLambda() throws Exception { + runTest("compiler/testData/diagnostics/tests/javac/Lambda.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index d201eff39d0..7e760871bbb 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -199,6 +199,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { override val valueParameterCheckers: Set get() = setOf( FirValueParameterDefaultValueTypeMismatchChecker, + FirMissingDependencyClassForParameterChecker, ) override val enumEntryCheckers: Set diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMissingDependencyClassForParameterChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMissingDependencyClassForParameterChecker.kt new file mode 100644 index 00000000000..444da195804 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMissingDependencyClassForParameterChecker.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.fir.analysis.checkers.declaration + +import org.jetbrains.kotlin.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirMissingDependencyClassProxy +import org.jetbrains.kotlin.fir.declarations.FirValueParameter +import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.coneType + +object FirMissingDependencyClassForParameterChecker : FirValueParameterChecker(), FirMissingDependencyClassProxy { + override fun check( + declaration: FirValueParameter, + context: CheckerContext, + reporter: DiagnosticReporter, + ) { + val missingTypes = mutableSetOf() + considerType(declaration.returnTypeRef.coneType, missingTypes, context) + reportMissingTypes(declaration.source, missingTypes, context, reporter) + } +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirMissingDependencyClassChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirMissingDependencyClassChecker.kt index d55948af66b..3f7f6746c26 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirMissingDependencyClassChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirMissingDependencyClassChecker.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression +import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext @@ -20,7 +21,7 @@ import org.jetbrains.kotlin.fir.types.* /** * @see org.jetbrains.kotlin.resolve.checkers.MissingDependencyClassChecker */ -object FirMissingDependencyClassChecker : FirQualifiedAccessExpressionChecker() { +object FirMissingDependencyClassChecker : FirQualifiedAccessExpressionChecker(), FirMissingDependencyClassProxy { override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) { val calleeReference = expression.calleeReference @@ -29,33 +30,21 @@ object FirMissingDependencyClassChecker : FirQualifiedAccessExpressionChecker() if (calleeReference.isError() && calleeReference.diagnostic !is ConeDiagnosticWithSingleCandidate) return val missingTypes = mutableSetOf() - fun consider(type: ConeKotlinType) { - var hasError = false - var hasMissingClass = false - type.forEachClassLikeType { - when (it) { - is ConeErrorType -> hasError = true - else -> hasMissingClass = hasMissingClass || it.lookupTag.toSymbol(context.session) == null - } - } - - if (hasMissingClass && !hasError) { - val reportedType = type.withNullability(ConeNullability.NOT_NULL, context.session.typeContext).withArguments(emptyArray()) - missingTypes.add(reportedType) - } - } val symbol = calleeReference.toResolvedCallableSymbol() ?: return - consider(symbol.resolvedReturnTypeRef.coneType) - symbol.resolvedReceiverTypeRef?.coneType?.let(::consider) - (symbol as? FirFunctionSymbol<*>)?.valueParameterSymbols?.forEach { consider(it.resolvedReturnTypeRef.coneType) } - - for (missingType in missingTypes) { - reporter.reportOn(expression.source, FirErrors.MISSING_DEPENDENCY_CLASS, missingType, context) + considerType(symbol.resolvedReturnTypeRef.coneType, missingTypes, context) + symbol.resolvedReceiverTypeRef?.coneType?.let { + considerType(it, missingTypes, context) } + (symbol as? FirFunctionSymbol<*>)?.valueParameterSymbols?.forEach { + considerType(it.resolvedReturnTypeRef.coneType, missingTypes, context) + } + reportMissingTypes(expression.source, missingTypes, context, reporter) } +} - private fun ConeKotlinType.forEachClassLikeType(action: (ConeClassLikeType) -> Unit) { +internal interface FirMissingDependencyClassProxy { + fun ConeKotlinType.forEachClassLikeType(action: (ConeClassLikeType) -> Unit) { when (this) { is ConeFlexibleType -> { lowerBound.forEachClassLikeType(action) @@ -68,4 +57,38 @@ object FirMissingDependencyClassChecker : FirQualifiedAccessExpressionChecker() else -> {} // Ignore all type parameters. } } + + fun considerType(type: ConeKotlinType, missingTypes: MutableSet, context: CheckerContext) { + var hasError = false + var hasMissingClass = false + type.forEachClassLikeType { + when (it) { + is ConeErrorType -> { + val delegatedType = it.delegatedType + if (delegatedType == null) { + hasError = true + } else { + considerType(delegatedType, missingTypes, context) + } + } + else -> hasMissingClass = hasMissingClass || it.lookupTag.toSymbol(context.session) == null + } + } + + if (hasMissingClass && !hasError) { + val reportedType = type.withNullability(ConeNullability.NOT_NULL, context.session.typeContext).withArguments(emptyArray()) + missingTypes.add(reportedType) + } + } + + fun reportMissingTypes( + source: KtSourceElement?, + missingTypes: MutableSet, + context: CheckerContext, + reporter: DiagnosticReporter, + ) { + for (missingType in missingTypes) { + reporter.reportOn(source, FirErrors.MISSING_DEPENDENCY_CLASS, missingType, context) + } + } } diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt index ceedef6878f..41a433d5405 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt @@ -44,6 +44,7 @@ class ConeClassLikeErrorLookupTag(override val classId: ClassId) : ConeClassLike class ConeErrorType( val diagnostic: ConeDiagnostic, val isUninferredParameter: Boolean = false, + val delegatedType: ConeKotlinType? = null, override val typeArguments: Array = EMPTY_ARRAY, override val attributes: ConeAttributes = ConeAttributes.Empty ) : ConeClassLikeType() { diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/serializationUtil.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/serializationUtil.kt index f3333f82995..9e3f7ea0875 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/serializationUtil.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/serializationUtil.kt @@ -25,7 +25,7 @@ import org.jetbrains.kotlin.types.model.SimpleTypeMarker class TypeApproximatorForMetadataSerializer(session: FirSession) : AbstractTypeApproximator(session.typeContext, session.languageVersionSettings) { - override fun createErrorType(debugName: String): SimpleTypeMarker { + override fun createErrorType(debugName: String, delegatedType: SimpleTypeMarker?): SimpleTypeMarker { return ConeErrorType(ConeIntermediateDiagnostic(debugName)) } } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt index 5aeb125c6f4..4be45cbabc7 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt @@ -187,8 +187,8 @@ abstract class AbstractConeSubstitutor(protected val typeContext: ConeTypeContex is ConeErrorType -> ConeErrorType( diagnostic, isUninferredParameter, - newArguments as Array, - attributes + typeArguments = newArguments as Array, + attributes = attributes ) else -> errorWithAttachment("Unknown class-like type to substitute, ${this::class}") { withConeTypeEntry("type", this@substituteArguments) diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt index 00b8744f6c3..19cec665ac6 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt @@ -384,8 +384,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo return isContainedInInvariantOrContravariantPositions } - override fun createErrorType(debugName: String): ConeErrorType { - return ConeErrorType(ConeIntermediateDiagnostic(debugName)) + override fun createErrorType(debugName: String, delegatedType: SimpleTypeMarker?): ConeErrorType { + return ConeErrorType(ConeIntermediateDiagnostic(debugName), delegatedType = delegatedType as ConeKotlinType?) } override fun createUninferredType(constructor: TypeConstructorMarker): KotlinTypeMarker { @@ -434,9 +434,9 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo } override fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker { - if (this is ErrorTypeConstructor) return createErrorType(reason) - if (this is ConeClassLikeLookupTag) return createErrorType("Not found classifier: $classId") - return createErrorType("Unknown reason") + if (this is ErrorTypeConstructor) return createErrorType(reason, delegatedType = null) + if (this is ConeClassLikeLookupTag) return createErrorType("Not found classifier: $classId", delegatedType = null) + return createErrorType("Unknown reason", delegatedType = null) } override fun findCommonIntegerLiteralTypesSuperType(explicitSupertypes: List): SimpleTypeMarker? { diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt index 8dd21ac939d..fa4bba4ca3b 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt @@ -209,7 +209,7 @@ fun T.withArguments(arguments: Array ConeErrorType(diagnostic, isUninferredParameter, arguments, attributes) as T + is ConeErrorType -> ConeErrorType(diagnostic, isUninferredParameter, typeArguments = arguments, attributes = attributes) as T is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, arguments, nullability.isNullable, attributes) as T is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType(original.withArguments(arguments)) as T else -> errorWithAttachment("Not supported: ${this::class}") { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt index bcd38662850..a0182e0d04d 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt @@ -423,7 +423,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon return emptyList() } - override fun createErrorType(debugName: String): SimpleTypeMarker { + override fun createErrorType(debugName: String, delegatedType: SimpleTypeMarker?): SimpleTypeMarker { TODO("IrTypeSystemContext doesn't support constraint system resolution") } diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt index 38eebdbeadd..7a01ed6af9d 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt @@ -82,7 +82,7 @@ object NewCommonSuperTypeCalculator { stateStubTypesNotEqual: TypeCheckerState ): SimpleTypeMarker { if (types.any { it.isError() }) { - return createErrorType("CST(${types.joinToString()}") + return createErrorType("CST(${types.joinToString()}", delegatedType = null) } // i.e. result type also should be marked nullable diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/types/AbstractTypeApproximator.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/types/AbstractTypeApproximator.kt index c2c275d6bd3..cc627270350 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/types/AbstractTypeApproximator.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/types/AbstractTypeApproximator.kt @@ -456,7 +456,10 @@ abstract class AbstractTypeApproximator( val typeConstructor = type.typeConstructor() if (typeConstructor.parametersCount() != type.argumentsCount()) { return if (conf.errorType) { - createErrorType("Inconsistent type: $type (parameters.size = ${typeConstructor.parametersCount()}, arguments.size = ${type.argumentsCount()})") + createErrorType( + "Inconsistent type: $type (parameters.size = ${typeConstructor.parametersCount()}, arguments.size = ${type.argumentsCount()})", + type + ) } else type.defaultResult(toSuper) } @@ -490,7 +493,8 @@ abstract class AbstractTypeApproximator( return if (conf.errorType) { createErrorType( "Inconsistent type: $type ($index parameter has declared variance: ${parameter.getVariance()}, " + - "but argument variance is ${argument.getVariance()})" + "but argument variance is ${argument.getVariance()})", + type ) } else type.defaultResult(toSuper) } diff --git a/compiler/testData/diagnostics/tests/javac/Lambda.diag.txt b/compiler/testData/diagnostics/tests/javac/Lambda.diag.txt new file mode 100644 index 00000000000..60807823caf --- /dev/null +++ b/compiler/testData/diagnostics/tests/javac/Lambda.diag.txt @@ -0,0 +1,10 @@ +// -- Module: -- + +// -- Module: -- + +// -- Module: -- + +// -- Module: -- +/Call.kt:90:19: error: unresolved reference: result +fun simple(b: com.result.B<*>) {} + ^ diff --git a/compiler/testData/diagnostics/tests/javac/Lambda.fir.diag.txt b/compiler/testData/diagnostics/tests/javac/Lambda.fir.diag.txt new file mode 100644 index 00000000000..ffdf456334e --- /dev/null +++ b/compiler/testData/diagnostics/tests/javac/Lambda.fir.diag.txt @@ -0,0 +1,7 @@ +/Call.kt:(253,262): error: Cannot access class 'com.result.B'. Check your module classpath for missing or conflicting dependencies. + +/Call.kt:(294,296): error: Cannot access class 'com.result.B'. Check your module classpath for missing or conflicting dependencies. + +/Call.kt:(346,355): error: Cannot access class 'com.result.Owner.Nested.VeryNested'. Check your module classpath for missing or conflicting dependencies. + +/Call.kt:(383,389): error: Unresolved reference 'result'. diff --git a/compiler/testData/diagnostics/tests/javac/Lambda.fir.kt b/compiler/testData/diagnostics/tests/javac/Lambda.fir.kt new file mode 100644 index 00000000000..82e82ec4ef5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/javac/Lambda.fir.kt @@ -0,0 +1,90 @@ +// TARGET_BACKEND: JVM_IR +// WITH_STDLIB +// RENDER_DIAGNOSTICS_FULL_TEXT +// ISSUE: KT-62525 + +// MODULE: m1 +// FILE: Request.kt + +package com.request + +sealed class Result { + class Success(val value: Success) : Result() + + class Error(val error: Error) : Result() + + inline fun mapError(transform: (Error) -> Mapped): Result = + when (this) { + is Result.Success -> this + is Result.Error -> Error(transform(error)) + } +} + +fun request(success: T, error: U): Result { + if (1 + 1 + 2 == 4) { + return Result.Success(success) + } else { + return Result.Error(error) + } +} + +// MODULE: m2 +// FILE: Result.kt + +package com.result + +class A {} + +sealed class B { + + class HttpError(val response: T) : B() {} + + class Exception(val exception: Throwable) : B() {} +} + +class C {} + +class Owner { + inner class Nested { + inner class VeryNested + } +} + +// MODULE: m3(m1, m2) +// FILE: Repo.kt + +package com.repo + +import com.request.Result +import com.request.request +import com.result.A +import com.result.B +import com.result.C +import com.result.Owner +import java.lang.RuntimeException + +fun request_a(): Result> { + return request>(A(), B.Exception(RuntimeException("Error"))) +} + +fun request_withNested(): Result.Nested, Owner.Nested.VeryNested> { + return request.Nested, Owner.Nested.VeryNested>(Owner().Nested(), Owner().Nested().VeryNested()) +} + +// MODULE: m4(m3, m1) +// FILE: Call.kt + +package com.call + +import com.repo.request_a +import com.repo.request_withNested + +class Model { + fun call() { + request_a().mapError { 1 + 1 } + request_a().mapError { it -> 1 + 1 } + request_withNested().mapError { 1 + 1 } + } +} + +fun simple(b: com.result.B<*>) {} diff --git a/compiler/testData/diagnostics/tests/javac/Lambda.kt b/compiler/testData/diagnostics/tests/javac/Lambda.kt new file mode 100644 index 00000000000..d1b2201dedf --- /dev/null +++ b/compiler/testData/diagnostics/tests/javac/Lambda.kt @@ -0,0 +1,90 @@ +// TARGET_BACKEND: JVM_IR +// WITH_STDLIB +// RENDER_DIAGNOSTICS_FULL_TEXT +// ISSUE: KT-62525 + +// MODULE: m1 +// FILE: Request.kt + +package com.request + +sealed class Result { + class Success(val value: Success) : Result() + + class Error(val error: Error) : Result() + + inline fun mapError(transform: (Error) -> Mapped): Result = + when (this) { + is Result.Success -> this + is Result.Error -> Error(transform(error)) + } +} + +fun request(success: T, error: U): Result { + if (1 + 1 + 2 == 4) { + return Result.Success(success) + } else { + return Result.Error(error) + } +} + +// MODULE: m2 +// FILE: Result.kt + +package com.result + +class A {} + +sealed class B { + + class HttpError(val response: T) : B() {} + + class Exception(val exception: Throwable) : B() {} +} + +class C {} + +class Owner { + inner class Nested { + inner class VeryNested + } +} + +// MODULE: m3(m1, m2) +// FILE: Repo.kt + +package com.repo + +import com.request.Result +import com.request.request +import com.result.A +import com.result.B +import com.result.C +import com.result.Owner +import java.lang.RuntimeException + +fun request_a(): Result> { + return request>(A(), B.Exception(RuntimeException("Error"))) +} + +fun request_withNested(): Result.Nested, Owner.Nested.VeryNested> { + return request.Nested, Owner.Nested.VeryNested>(Owner().Nested(), Owner().Nested().VeryNested()) +} + +// MODULE: m4(m3, m1) +// FILE: Call.kt + +package com.call + +import com.repo.request_a +import com.repo.request_withNested + +class Model { + fun call() { + request_a().mapError { 1 + 1 } + request_a().mapError { it -> 1 + 1 } + request_withNested().mapError { 1 + 1 } + } +} + +fun simple(b: com.result.B<*>) {} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 8edc759403b..c1cb6465684 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -22742,6 +22742,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/javac/Annotations.kt"); } + @Test + @TestMetadata("Lambda.kt") + public void testLambda() throws Exception { + runTest("compiler/testData/diagnostics/tests/javac/Lambda.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticUsingJavacTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticUsingJavacTestGenerated.java index 4cafbb1be4f..bcf61b85487 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticUsingJavacTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticUsingJavacTestGenerated.java @@ -30,6 +30,12 @@ public class DiagnosticUsingJavacTestGenerated extends AbstractDiagnosticUsingJa runTest("compiler/testData/diagnostics/tests/javac/Annotations.kt"); } + @Test + @TestMetadata("Lambda.kt") + public void testLambda() throws Exception { + runTest("compiler/testData/diagnostics/tests/javac/Lambda.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution") @TestDataPath("$PROJECT_ROOT") diff --git a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt index ded923ce2a9..7d69e04c9a9 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt @@ -87,7 +87,7 @@ interface TypeSystemTypeFactoryContext: TypeSystemBuiltInsContext { fun createTypeArgument(type: KotlinTypeMarker, variance: TypeVariance): TypeArgumentMarker fun createStarProjection(typeParameter: TypeParameterMarker): TypeArgumentMarker - fun createErrorType(debugName: String): SimpleTypeMarker + fun createErrorType(debugName: String, delegatedType: SimpleTypeMarker?): SimpleTypeMarker fun createUninferredType(constructor: TypeConstructorMarker): KotlinTypeMarker } 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 b79951b8b67..569c1a9f4df 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -597,7 +597,6 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy override fun SimpleTypeMarker.replaceArguments(replacement: (TypeArgumentMarker) -> TypeArgumentMarker): SimpleTypeMarker { require(this is SimpleType, this::errorMessage) - @Suppress("UNCHECKED_CAST") return this.replaceArgumentsByExistingArgumentsWith(replacement) } @@ -714,7 +713,7 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy return captureFromExpressionInternal(type as UnwrappedType) } - override fun createErrorType(debugName: String): SimpleTypeMarker { + override fun createErrorType(debugName: String, delegatedType: SimpleTypeMarker?): SimpleTypeMarker { return ErrorUtils.createErrorType(ErrorTypeKind.RESOLUTION_ERROR_TYPE, debugName) } @@ -922,8 +921,6 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy override val isK2: Boolean get() = false - - class WA // Workaround for KT-52313 } fun TypeVariance.convertVariance(): Variance {