K2: report MISSING_DEPENDENCY_CLASS for lambda parameters if needed
#KT-62525 Fixed
This commit is contained in:
committed by
Space Team
parent
c03830556f
commit
06ce57ea56
+6
@@ -22742,6 +22742,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/javac/Annotations.kt");
|
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
|
@Nested
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution")
|
@TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+6
@@ -22742,6 +22742,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
|||||||
runTest("compiler/testData/diagnostics/tests/javac/Annotations.kt");
|
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
|
@Nested
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution")
|
@TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+6
@@ -22736,6 +22736,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
|||||||
runTest("compiler/testData/diagnostics/tests/javac/Annotations.kt");
|
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
|
@Nested
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution")
|
@TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+6
@@ -22742,6 +22742,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/javac/Annotations.kt");
|
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
|
@Nested
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution")
|
@TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+1
@@ -199,6 +199,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
|||||||
override val valueParameterCheckers: Set<FirValueParameterChecker>
|
override val valueParameterCheckers: Set<FirValueParameterChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirValueParameterDefaultValueTypeMismatchChecker,
|
FirValueParameterDefaultValueTypeMismatchChecker,
|
||||||
|
FirMissingDependencyClassForParameterChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val enumEntryCheckers: Set<FirEnumEntryChecker>
|
override val enumEntryCheckers: Set<FirEnumEntryChecker>
|
||||||
|
|||||||
+25
@@ -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<ConeKotlinType>()
|
||||||
|
considerType(declaration.returnTypeRef.coneType, missingTypes, context)
|
||||||
|
reportMissingTypes(declaration.source, missingTypes, context, reporter)
|
||||||
|
}
|
||||||
|
}
|
||||||
+46
-23
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
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
|
* @see org.jetbrains.kotlin.resolve.checkers.MissingDependencyClassChecker
|
||||||
*/
|
*/
|
||||||
object FirMissingDependencyClassChecker : FirQualifiedAccessExpressionChecker() {
|
object FirMissingDependencyClassChecker : FirQualifiedAccessExpressionChecker(), FirMissingDependencyClassProxy {
|
||||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val calleeReference = expression.calleeReference
|
val calleeReference = expression.calleeReference
|
||||||
|
|
||||||
@@ -29,33 +30,21 @@ object FirMissingDependencyClassChecker : FirQualifiedAccessExpressionChecker()
|
|||||||
if (calleeReference.isError() && calleeReference.diagnostic !is ConeDiagnosticWithSingleCandidate) return
|
if (calleeReference.isError() && calleeReference.diagnostic !is ConeDiagnosticWithSingleCandidate) return
|
||||||
|
|
||||||
val missingTypes = mutableSetOf<ConeKotlinType>()
|
val missingTypes = mutableSetOf<ConeKotlinType>()
|
||||||
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
|
val symbol = calleeReference.toResolvedCallableSymbol() ?: return
|
||||||
consider(symbol.resolvedReturnTypeRef.coneType)
|
considerType(symbol.resolvedReturnTypeRef.coneType, missingTypes, context)
|
||||||
symbol.resolvedReceiverTypeRef?.coneType?.let(::consider)
|
symbol.resolvedReceiverTypeRef?.coneType?.let {
|
||||||
(symbol as? FirFunctionSymbol<*>)?.valueParameterSymbols?.forEach { consider(it.resolvedReturnTypeRef.coneType) }
|
considerType(it, missingTypes, context)
|
||||||
|
|
||||||
for (missingType in missingTypes) {
|
|
||||||
reporter.reportOn(expression.source, FirErrors.MISSING_DEPENDENCY_CLASS, missingType, 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) {
|
when (this) {
|
||||||
is ConeFlexibleType -> {
|
is ConeFlexibleType -> {
|
||||||
lowerBound.forEachClassLikeType(action)
|
lowerBound.forEachClassLikeType(action)
|
||||||
@@ -68,4 +57,38 @@ object FirMissingDependencyClassChecker : FirQualifiedAccessExpressionChecker()
|
|||||||
else -> {} // Ignore all type parameters.
|
else -> {} // Ignore all type parameters.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun considerType(type: ConeKotlinType, missingTypes: MutableSet<ConeKotlinType>, 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<ConeKotlinType>,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter,
|
||||||
|
) {
|
||||||
|
for (missingType in missingTypes) {
|
||||||
|
reporter.reportOn(source, FirErrors.MISSING_DEPENDENCY_CLASS, missingType, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class ConeClassLikeErrorLookupTag(override val classId: ClassId) : ConeClassLike
|
|||||||
class ConeErrorType(
|
class ConeErrorType(
|
||||||
val diagnostic: ConeDiagnostic,
|
val diagnostic: ConeDiagnostic,
|
||||||
val isUninferredParameter: Boolean = false,
|
val isUninferredParameter: Boolean = false,
|
||||||
|
val delegatedType: ConeKotlinType? = null,
|
||||||
override val typeArguments: Array<out ConeTypeProjection> = EMPTY_ARRAY,
|
override val typeArguments: Array<out ConeTypeProjection> = EMPTY_ARRAY,
|
||||||
override val attributes: ConeAttributes = ConeAttributes.Empty
|
override val attributes: ConeAttributes = ConeAttributes.Empty
|
||||||
) : ConeClassLikeType() {
|
) : ConeClassLikeType() {
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
|||||||
class TypeApproximatorForMetadataSerializer(session: FirSession) :
|
class TypeApproximatorForMetadataSerializer(session: FirSession) :
|
||||||
AbstractTypeApproximator(session.typeContext, session.languageVersionSettings) {
|
AbstractTypeApproximator(session.typeContext, session.languageVersionSettings) {
|
||||||
|
|
||||||
override fun createErrorType(debugName: String): SimpleTypeMarker {
|
override fun createErrorType(debugName: String, delegatedType: SimpleTypeMarker?): SimpleTypeMarker {
|
||||||
return ConeErrorType(ConeIntermediateDiagnostic(debugName))
|
return ConeErrorType(ConeIntermediateDiagnostic(debugName))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -187,8 +187,8 @@ abstract class AbstractConeSubstitutor(protected val typeContext: ConeTypeContex
|
|||||||
is ConeErrorType -> ConeErrorType(
|
is ConeErrorType -> ConeErrorType(
|
||||||
diagnostic,
|
diagnostic,
|
||||||
isUninferredParameter,
|
isUninferredParameter,
|
||||||
newArguments as Array<ConeTypeProjection>,
|
typeArguments = newArguments as Array<ConeTypeProjection>,
|
||||||
attributes
|
attributes = attributes
|
||||||
)
|
)
|
||||||
else -> errorWithAttachment("Unknown class-like type to substitute, ${this::class}") {
|
else -> errorWithAttachment("Unknown class-like type to substitute, ${this::class}") {
|
||||||
withConeTypeEntry("type", this@substituteArguments)
|
withConeTypeEntry("type", this@substituteArguments)
|
||||||
|
|||||||
@@ -384,8 +384,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
return isContainedInInvariantOrContravariantPositions
|
return isContainedInInvariantOrContravariantPositions
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createErrorType(debugName: String): ConeErrorType {
|
override fun createErrorType(debugName: String, delegatedType: SimpleTypeMarker?): ConeErrorType {
|
||||||
return ConeErrorType(ConeIntermediateDiagnostic(debugName))
|
return ConeErrorType(ConeIntermediateDiagnostic(debugName), delegatedType = delegatedType as ConeKotlinType?)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createUninferredType(constructor: TypeConstructorMarker): KotlinTypeMarker {
|
override fun createUninferredType(constructor: TypeConstructorMarker): KotlinTypeMarker {
|
||||||
@@ -434,9 +434,9 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker {
|
override fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker {
|
||||||
if (this is ErrorTypeConstructor) return createErrorType(reason)
|
if (this is ErrorTypeConstructor) return createErrorType(reason, delegatedType = null)
|
||||||
if (this is ConeClassLikeLookupTag) return createErrorType("Not found classifier: $classId")
|
if (this is ConeClassLikeLookupTag) return createErrorType("Not found classifier: $classId", delegatedType = null)
|
||||||
return createErrorType("Unknown reason")
|
return createErrorType("Unknown reason", delegatedType = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findCommonIntegerLiteralTypesSuperType(explicitSupertypes: List<SimpleTypeMarker>): SimpleTypeMarker? {
|
override fun findCommonIntegerLiteralTypesSuperType(explicitSupertypes: List<SimpleTypeMarker>): SimpleTypeMarker? {
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ fun <T : ConeKotlinType> T.withArguments(arguments: Array<out ConeTypeProjection
|
|||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeErrorType -> 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 ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, arguments, nullability.isNullable, attributes) as T
|
||||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType(original.withArguments(arguments)) as T
|
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType(original.withArguments(arguments)) as T
|
||||||
else -> errorWithAttachment("Not supported: ${this::class}") {
|
else -> errorWithAttachment("Not supported: ${this::class}") {
|
||||||
|
|||||||
@@ -423,7 +423,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
|||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createErrorType(debugName: String): SimpleTypeMarker {
|
override fun createErrorType(debugName: String, delegatedType: SimpleTypeMarker?): SimpleTypeMarker {
|
||||||
TODO("IrTypeSystemContext doesn't support constraint system resolution")
|
TODO("IrTypeSystemContext doesn't support constraint system resolution")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -82,7 +82,7 @@ object NewCommonSuperTypeCalculator {
|
|||||||
stateStubTypesNotEqual: TypeCheckerState
|
stateStubTypesNotEqual: TypeCheckerState
|
||||||
): SimpleTypeMarker {
|
): SimpleTypeMarker {
|
||||||
if (types.any { it.isError() }) {
|
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
|
// i.e. result type also should be marked nullable
|
||||||
|
|||||||
+6
-2
@@ -456,7 +456,10 @@ abstract class AbstractTypeApproximator(
|
|||||||
val typeConstructor = type.typeConstructor()
|
val typeConstructor = type.typeConstructor()
|
||||||
if (typeConstructor.parametersCount() != type.argumentsCount()) {
|
if (typeConstructor.parametersCount() != type.argumentsCount()) {
|
||||||
return if (conf.errorType) {
|
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)
|
} else type.defaultResult(toSuper)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,7 +493,8 @@ abstract class AbstractTypeApproximator(
|
|||||||
return if (conf.errorType) {
|
return if (conf.errorType) {
|
||||||
createErrorType(
|
createErrorType(
|
||||||
"Inconsistent type: $type ($index parameter has declared variance: ${parameter.getVariance()}, " +
|
"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)
|
} else type.defaultResult(toSuper)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// -- Module: <m1> --
|
||||||
|
|
||||||
|
// -- Module: <m2> --
|
||||||
|
|
||||||
|
// -- Module: <m3> --
|
||||||
|
|
||||||
|
// -- Module: <m4> --
|
||||||
|
/Call.kt:90:19: error: unresolved reference: result
|
||||||
|
fun simple(b: com.result.B<*>) {}
|
||||||
|
^
|
||||||
@@ -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'.
|
||||||
@@ -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<out Success, out Error> {
|
||||||
|
class Success<out Success>(val value: Success) : Result<Success, Nothing>()
|
||||||
|
|
||||||
|
class Error<out Error>(val error: Error) : Result<Nothing, Error>()
|
||||||
|
|
||||||
|
inline fun <Mapped> mapError(transform: (Error) -> Mapped): Result<Success, Mapped> =
|
||||||
|
when (this) {
|
||||||
|
is Result.Success -> this
|
||||||
|
is Result.Error -> Error(transform(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T, U> request(success: T, error: U): Result<T, U> {
|
||||||
|
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<T> {
|
||||||
|
|
||||||
|
class HttpError<T>(val response: T) : B<T>() {}
|
||||||
|
|
||||||
|
class Exception<T>(val exception: Throwable) : B<T>() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {}
|
||||||
|
|
||||||
|
class Owner<T> {
|
||||||
|
inner class Nested<S> {
|
||||||
|
inner class VeryNested<R, P>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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<A, B<C>> {
|
||||||
|
return request<A, B<C>>(A(), B.Exception(RuntimeException("Error")))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun request_withNested(): Result<Owner<C>.Nested<A>, Owner<A>.Nested<C>.VeryNested<C, A>> {
|
||||||
|
return request<Owner<C>.Nested<A>, Owner<A>.Nested<C>.VeryNested<C, A>>(Owner<C>().Nested<A>(), Owner<A>().Nested<C>().VeryNested<C, A>())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 <!MISSING_DEPENDENCY_CLASS!>{ 1 + 1 }<!>
|
||||||
|
request_a().mapError { <!MISSING_DEPENDENCY_CLASS!>it<!> -> 1 + 1 }
|
||||||
|
request_withNested().mapError <!MISSING_DEPENDENCY_CLASS!>{ 1 + 1 }<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun simple(b: com.<!UNRESOLVED_REFERENCE!>result<!>.B<*>) {}
|
||||||
@@ -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<out Success, out Error> {
|
||||||
|
class Success<out Success>(val value: Success) : Result<Success, Nothing>()
|
||||||
|
|
||||||
|
class Error<out Error>(val error: Error) : Result<Nothing, Error>()
|
||||||
|
|
||||||
|
inline fun <Mapped> mapError(transform: (Error) -> Mapped): Result<Success, Mapped> =
|
||||||
|
when (this) {
|
||||||
|
is Result.Success -> <!DEBUG_INFO_SMARTCAST!>this<!>
|
||||||
|
is Result.Error -> Error(transform(<!DEBUG_INFO_IMPLICIT_RECEIVER_SMARTCAST!>error<!>))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T, U> request(success: T, error: U): Result<T, U> {
|
||||||
|
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<T> {
|
||||||
|
|
||||||
|
class HttpError<T>(val response: T) : B<T>() {}
|
||||||
|
|
||||||
|
class Exception<T>(val exception: Throwable) : B<T>() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {}
|
||||||
|
|
||||||
|
class Owner<T> {
|
||||||
|
inner class Nested<S> {
|
||||||
|
inner class VeryNested<R, P>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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<A, B<C>> {
|
||||||
|
return request<A, B<C>>(A(), B.Exception(RuntimeException("Error")))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun request_withNested(): Result<Owner<C>.Nested<A>, Owner<A>.Nested<C>.VeryNested<C, A>> {
|
||||||
|
return request<Owner<C>.Nested<A>, Owner<A>.Nested<C>.VeryNested<C, A>>(Owner<C>().Nested<A>(), Owner<A>().Nested<C>().VeryNested<C, A>())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.<!UNRESOLVED_REFERENCE!>result<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>B<!><*>) {}
|
||||||
Generated
+6
@@ -22742,6 +22742,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/javac/Annotations.kt");
|
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
|
@Nested
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution")
|
@TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+6
@@ -30,6 +30,12 @@ public class DiagnosticUsingJavacTestGenerated extends AbstractDiagnosticUsingJa
|
|||||||
runTest("compiler/testData/diagnostics/tests/javac/Annotations.kt");
|
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
|
@Nested
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution")
|
@TestMetadata("compiler/testData/diagnostics/tests/javac/fieldsResolution")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ interface TypeSystemTypeFactoryContext: TypeSystemBuiltInsContext {
|
|||||||
fun createTypeArgument(type: KotlinTypeMarker, variance: TypeVariance): TypeArgumentMarker
|
fun createTypeArgument(type: KotlinTypeMarker, variance: TypeVariance): TypeArgumentMarker
|
||||||
fun createStarProjection(typeParameter: TypeParameterMarker): TypeArgumentMarker
|
fun createStarProjection(typeParameter: TypeParameterMarker): TypeArgumentMarker
|
||||||
|
|
||||||
fun createErrorType(debugName: String): SimpleTypeMarker
|
fun createErrorType(debugName: String, delegatedType: SimpleTypeMarker?): SimpleTypeMarker
|
||||||
fun createUninferredType(constructor: TypeConstructorMarker): KotlinTypeMarker
|
fun createUninferredType(constructor: TypeConstructorMarker): KotlinTypeMarker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -597,7 +597,6 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
|||||||
|
|
||||||
override fun SimpleTypeMarker.replaceArguments(replacement: (TypeArgumentMarker) -> TypeArgumentMarker): SimpleTypeMarker {
|
override fun SimpleTypeMarker.replaceArguments(replacement: (TypeArgumentMarker) -> TypeArgumentMarker): SimpleTypeMarker {
|
||||||
require(this is SimpleType, this::errorMessage)
|
require(this is SimpleType, this::errorMessage)
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
return this.replaceArgumentsByExistingArgumentsWith(replacement)
|
return this.replaceArgumentsByExistingArgumentsWith(replacement)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -714,7 +713,7 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
|||||||
return captureFromExpressionInternal(type as UnwrappedType)
|
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)
|
return ErrorUtils.createErrorType(ErrorTypeKind.RESOLUTION_ERROR_TYPE, debugName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -922,8 +921,6 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
|||||||
|
|
||||||
override val isK2: Boolean
|
override val isK2: Boolean
|
||||||
get() = false
|
get() = false
|
||||||
|
|
||||||
class WA // Workaround for KT-52313
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TypeVariance.convertVariance(): Variance {
|
fun TypeVariance.convertVariance(): Variance {
|
||||||
|
|||||||
Reference in New Issue
Block a user