diff --git a/compiler/fir/analysis-tests/testData/resolve/bareTypes2.fir.txt b/compiler/fir/analysis-tests/testData/resolve/bareTypes2.fir.txt index bbec9d8c0e3..6fd8444cbe8 100644 --- a/compiler/fir/analysis-tests/testData/resolve/bareTypes2.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/bareTypes2.fir.txt @@ -21,7 +21,7 @@ FILE: bareTypes2.kt when ((R|/x| as? R|C|)?.{ $subj$.R|/A.field| }) { ($subj$ is R|kotlin/String|) -> { when () { - ==((R|/x| as? R|B|)?.{ $subj$.R|/A.cond| }, Boolean(true)) -> { + ==((R|/x| as? R|B<*>|)?.{ $subj$.R|/A.cond| }, Boolean(true)) -> { R|/x|.R|/C.foo|() } } diff --git a/compiler/fir/analysis-tests/testData/resolve/bareTypesWithFlexibleArguments.fir.txt b/compiler/fir/analysis-tests/testData/resolve/bareTypesWithFlexibleArguments.fir.txt index e941ae5c122..ecdcf5eb80c 100644 --- a/compiler/fir/analysis-tests/testData/resolve/bareTypesWithFlexibleArguments.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/bareTypesWithFlexibleArguments.fir.txt @@ -1,7 +1,7 @@ FILE: bareTypesWithFlexibleArguments.kt public final fun R|kotlin/collections/Collection?|.concat(collection: R|kotlin/collections/Collection|): R|kotlin/collections/Collection?| { when () { - (this@R|/concat| is R|kotlin/collections/LinkedHashSet|) -> { + (this@R|/concat| is R|java/util/LinkedHashSet|) -> { this@R|/concat|.R|SubstitutionOverride|(R|/collection|) ^concat this@R|/concat| } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.fir.txt index 2212c2dee4a..1106495c5f3 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.fir.txt @@ -17,7 +17,7 @@ FILE: capturedTypeInEquality.kt } public final fun foo(target: R|FirTarget>|, property: R|FirProperty|): R|kotlin/Unit| { lval functionTarget: R|FirFunction<*>| = R|/target|.R|SubstitutionOverride|>| - lval x: R|kotlin/Int?| = (R|/functionTarget| as? R|FirFunction|)?.{ $subj$.R|kotlin/let||, R|kotlin/Int|>( = let@fun (it: R|FirFunction<*>|): R|kotlin/Int| { + lval x: R|kotlin/Int?| = (R|/functionTarget| as? R|FirFunction<*>|)?.{ $subj$.R|kotlin/let||, R|kotlin/Int|>( = let@fun (it: R|FirFunction<*>|): R|kotlin/Int| { when () { ===(R|/property|.R|/FirProperty.getter|, R|/functionTarget|) -> { ^@let Int(1) diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.kt index 90fd2436ed8..a66bc975f82 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.kt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.kt @@ -15,7 +15,7 @@ interface FirTarget { fun foo(target: FirTarget>, property: FirProperty) { val functionTarget = target.labeledElement val x = (functionTarget as? FirFunction)?.let { - if (property.getter === functionTarget) { + if (property.getter === functionTarget) { return@let 1 } 0 diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 2956711f562..ee631291a64 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -4350,6 +4350,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/cast/bare/RedundantNullable.kt"); } + @Test + @TestMetadata("SupertypeChain.kt") + public void testSupertypeChain() throws Exception { + runTest("compiler/testData/diagnostics/tests/cast/bare/SupertypeChain.kt"); + } + @Test @TestMetadata("ToErrorType.kt") public void testToErrorType() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 725d4140ad2..8f9a7495e46 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -4350,6 +4350,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/cast/bare/RedundantNullable.kt"); } + @Test + @TestMetadata("SupertypeChain.kt") + public void testSupertypeChain() throws Exception { + runTest("compiler/testData/diagnostics/tests/cast/bare/SupertypeChain.kt"); + } + @Test @TestMetadata("ToErrorType.kt") public void testToErrorType() throws Exception { 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 76f6f7821b9..41fdc3a68b9 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 @@ -32,6 +32,20 @@ object ConeStarProjection : ConeTypeProjection() { sealed class ConeKotlinTypeProjection : ConeTypeProjection() { abstract val type: ConeKotlinType + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is ConeKotlinTypeProjection) return false + + if (kind != other.kind) return false + if (type != other.type) return false + + return true + } + + override fun hashCode(): Int { + return type.hashCode() * 31 + kind.hashCode() + } } data class ConeKotlinTypeProjectionIn(override val type: ConeKotlinType) : ConeKotlinTypeProjection() { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 1ddb28bd0fc..6e1f17a1cb2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.calls.* +import org.jetbrains.kotlin.fir.resolve.dfa.unwrapSmartcastExpression import org.jetbrains.kotlin.fir.resolve.diagnostics.* import org.jetbrains.kotlin.fir.resolve.inference.FirStubInferenceSession import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents @@ -589,40 +590,6 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform override fun shouldRunCompletion(call: T): Boolean where T : FirStatement, T : FirResolvable = false } - private fun ConeClassLikeType.inheritTypeArguments( - base: FirClassLikeDeclaration, - arguments: Array - ): Array? { - val firClass = lookupTag.toSymbol(session)?.fir ?: return null - if (firClass !is FirTypeParameterRefsOwner || firClass.typeParameters.isEmpty()) return arrayOf() - return when (firClass) { - base -> arguments - is FirTypeAlias -> firClass.inheritTypeArguments(firClass.expandedTypeRef, base, arguments) - // TODO: if many supertypes, check consistency - is FirClass -> firClass.superTypeRefs.mapNotNull { firClass.inheritTypeArguments(it, base, arguments) }.firstOrNull() - else -> null - } - } - - private fun FirTypeParameterRefsOwner.inheritTypeArguments( - typeRef: FirTypeRef, - base: FirClassLikeDeclaration, - arguments: Array - ): Array? { - val type = typeRef.coneTypeSafe() ?: return null - val indexMapping = typeParameters.map { parameter -> - // TODO: if many, check consistency of the result - type.typeArguments.indexOfFirst { - val argument = (it as? ConeKotlinType)?.lowerBoundIfFlexible() - argument is ConeTypeParameterType && argument.lookupTag.typeParameterSymbol == parameter.symbol - } - } - if (indexMapping.any { it == -1 }) return null - - val typeArguments = type.inheritTypeArguments(base, arguments) ?: return null - return Array(typeParameters.size) { typeArguments[indexMapping[it]] } - } - private fun FirTypeRef.withTypeArgumentsForBareType(argument: FirExpression): FirTypeRef { val type = coneTypeSafe() ?: return this if (type.typeArguments.isNotEmpty()) return this @@ -630,43 +597,14 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform val firClass = type.lookupTag.toSymbol(session)?.fir ?: return this if (firClass !is FirTypeParameterRefsOwner || firClass.typeParameters.isEmpty()) return this - val originalType = argument.typeRef.coneTypeSafe() ?: return this - val newType = computeRepresentativeTypeForBareType(type, originalType) ?: return buildErrorTypeRef { + val originalType = argument.unwrapSmartcastExpression().typeRef.coneTypeSafe() ?: return this + val newType = components.computeRepresentativeTypeForBareType(type, originalType) ?: return buildErrorTypeRef { source = this@withTypeArgumentsForBareType.source diagnostic = ConeNoTypeArgumentsOnRhsError(firClass.typeParameters.size, firClass.symbol) } return if (newType.typeArguments.isEmpty()) this else withReplacedConeType(newType) } - private fun computeRepresentativeTypeForBareType(type: ConeClassLikeType, originalType: ConeKotlinType): ConeKotlinType? { - @Suppress("NAME_SHADOWING") - val originalType = originalType.lowerBoundIfFlexible().fullyExpandedType(session) - if (originalType is ConeIntersectionType) { - val candidatesFromIntersectedTypes = originalType.intersectedTypes.mapNotNull { computeRepresentativeTypeForBareType(type, it) } - candidatesFromIntersectedTypes.firstOrNull { it.typeArguments.isNotEmpty() }?.let { return it } - return candidatesFromIntersectedTypes.firstOrNull() - } - if (originalType !is ConeClassLikeType) return type - val baseFirClass = originalType.lookupTag.toSymbol(session)?.fir ?: return type - val isSubtype = AbstractTypeChecker.isSubtypeOfClass( - session.typeContext.newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true), - originalType.lookupTag, - type.lookupTag - ) - val newArguments = if (isSubtype) { - // If actual type of declaration is more specific than bare type then we should just find - // corresponding supertype with proper arguments - with(session.typeContext) { - val superType = originalType.fastCorrespondingSupertypes(type.lookupTag)?.firstOrNull() as? ConeKotlinType? - superType?.typeArguments - } - } else { - type.inheritTypeArguments(baseFirClass, originalType.typeArguments) - } ?: return null - if (newArguments.isEmpty()) return type - return type.withArguments(newArguments) - } - override fun transformTypeOperatorCall( typeOperatorCall: FirTypeOperatorCall, data: ResolutionMode, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/bareTypes.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/bareTypes.kt new file mode 100644 index 00000000000..83059c5e196 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/bareTypes.kt @@ -0,0 +1,179 @@ +/* + * Copyright 2010-2021 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.resolve.transformers.body.resolve + +import org.jetbrains.kotlin.fir.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.declarations.FirTypeAlias +import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef +import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType +import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents +import org.jetbrains.kotlin.fir.resolve.defaultType +import org.jetbrains.kotlin.fir.resolve.fullyExpandedType +import org.jetbrains.kotlin.fir.resolve.toSymbol +import org.jetbrains.kotlin.fir.typeContext +import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.types.AbstractTypeChecker + +fun BodyResolveComponents.computeRepresentativeTypeForBareType(type: ConeClassLikeType, originalType: ConeKotlinType): ConeKotlinType? { + originalType.lowerBoundIfFlexible().fullyExpandedType(session).let { + if (it !== originalType) return computeRepresentativeTypeForBareType(type, it) + } + + if (originalType is ConeIntersectionType) { + val candidatesFromIntersectedTypes = originalType.intersectedTypes.mapNotNull { computeRepresentativeTypeForBareType(type, it) } + candidatesFromIntersectedTypes.firstOrNull { it.typeArguments.isNotEmpty() }?.let { return it } + return candidatesFromIntersectedTypes.firstOrNull() + } + + val originalClassLookupTag = (originalType as? ConeClassLikeType)?.fullyExpandedType(session)?.lookupTag ?: return null + + val castTypeAlias = type.lookupTag.toSymbol(session)?.fir as? FirTypeAlias + if (castTypeAlias != null && !canBeUsedAsBareType(castTypeAlias)) return null + + val expandedCastType = type.fullyExpandedType(session) + val castClass = expandedCastType.lookupTag.toSymbol(session)?.fir as? FirRegularClass ?: return null + + val superTypeWithParameters = with(session.typeContext) { + val correspondingSupertype = AbstractTypeChecker.findCorrespondingSupertypes( + newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false), + castClass.defaultType(), originalClassLookupTag, + ).firstOrNull() as? ConeClassLikeType ?: return null + + if (originalType.nullability.isNullable) + correspondingSupertype.withNullability(nullable = true) as ConeClassLikeType + else + correspondingSupertype + } + + val substitution = mutableMapOf() + val typeParameters = castClass.typeParameters.mapTo(mutableSetOf()) { it.symbol.fir } + if (!doUnify(originalType, superTypeWithParameters, typeParameters, substitution)) return null + + val newArguments = castClass.typeParameters.map { substitution[it.symbol.fir] ?: return@computeRepresentativeTypeForBareType null } + return expandedCastType.withArguments(newArguments.toTypedArray()) +} + +private fun canBeUsedAsBareType(firTypeAlias: FirTypeAlias): Boolean { + val typeAliasParameters = firTypeAlias.typeParameters.toSet() + val usedTypeParameters = mutableSetOf() + + val expandedType = firTypeAlias.expandedConeType ?: return false + for (argument in expandedType.typeArguments) { + if (argument.kind == ProjectionKind.STAR) continue + if (argument.kind != ProjectionKind.INVARIANT) return false + + val type = argument.type!! + val typeParameter = (type as? ConeTypeParameterType)?.lookupTag?.typeParameterSymbol?.fir ?: return false + if (typeParameter !in typeAliasParameters || typeParameter in usedTypeParameters) return false + + usedTypeParameters.add(typeParameter) + } + + return true +} + +/** + * @return false does only mean that there were conflicted values for some type parameter. In all other cases, it returns true. + * "fail" result in the comments below means that we can't infer anything meaningful in that branch of unification. + * See more at org.jetbrains.kotlin.types.TypeUnifier.doUnify. + * NB: "Failed@ result of UnificationResultImpl is effectively unused in production. + */ +private fun BodyResolveComponents.doUnify( + originalTypeProjection: ConeTypeProjection, + typeWithParametersProjection: ConeTypeProjection, + targetTypeParameters: Set, + result: MutableMap, +): Boolean { + val originalType = originalTypeProjection.type + val typeWithParameters = typeWithParametersProjection.type + + // in Foo ~ in X => Foo ~ X + if (originalTypeProjection.kind == typeWithParametersProjection.kind && + originalTypeProjection.kind != ProjectionKind.INVARIANT && originalTypeProjection.kind != ProjectionKind.STAR) { + return doUnify(originalType!!, typeWithParameters!!, targetTypeParameters, result) + } + + // Foo? ~ X? => Foo ~ X + if (originalType?.nullability?.isNullable == true && typeWithParameters?.nullability?.isNullable == true) { + return doUnify( + originalTypeProjection.removeQuestionMark(session.typeContext), + typeWithParametersProjection.removeQuestionMark(session.typeContext), + targetTypeParameters, result, + ) + } + + // in Foo ~ out X => fail + // in Foo ~ X => may be OK + if (originalTypeProjection.kind != typeWithParametersProjection.kind && typeWithParametersProjection.kind != ProjectionKind.INVARIANT) { + return true + } + + if (typeWithParameters is ConeFlexibleType) { + return doUnify( + if (originalType?.nullability?.isNullable == true) + originalTypeProjection.removeQuestionMark(session.typeContext) + else + originalTypeProjection, + typeWithParametersProjection.replaceType(typeWithParameters.lowerBound), + targetTypeParameters, result, + ) + } + + // Foo ~ X? => fail + if (originalType?.nullability?.isNullable != true && typeWithParameters?.nullability?.isNullable == true) { + return true + } + + // Foo ~ X => x |-> Foo + // * ~ X => x |-> * + val typeParameter = (typeWithParameters as? ConeTypeParameterType)?.lookupTag?.typeParameterSymbol?.fir + if (typeParameter != null && typeParameter in targetTypeParameters) { + if (typeParameter in result && result[typeParameter] != originalTypeProjection) return false + result[typeParameter] = originalTypeProjection + return true + } + + // Foo? ~ Foo || in Foo ~ Foo || Foo ~ Bar + if (originalType?.nullability?.isNullable != typeWithParameters?.nullability?.isNullable) return true + if (originalTypeProjection.kind != typeWithParametersProjection.kind) return true + if ((originalType as? ConeLookupTagBasedType)?.lookupTag != (typeWithParameters as? ConeLookupTagBasedType)?.lookupTag) return true + if (originalType == null || typeWithParameters == null) return true + + // Foo ~ Foo + if (originalType.typeArguments.size != typeWithParameters.typeArguments.size) { + return true + } + + // Foo ~ Foo + if (originalType.typeArguments.isEmpty()) { + return true + } + + // Foo<...> ~ Foo<...> + for ((originalTypeArgument, typeWithParametersArgument) in originalType.typeArguments.zip(typeWithParameters.typeArguments)) { + if (!doUnify(originalTypeArgument, typeWithParametersArgument, targetTypeParameters, result)) return false + } + + return true +} + +private fun ConeTypeProjection.removeQuestionMark(typeContext: ConeTypeContext): ConeTypeProjection { + val type = type + require(type != null && type.nullability.isNullable) { + "Expected nullable type, got $type" + } + + return replaceType(type.withNullability(ConeNullability.NOT_NULL, typeContext)) +} + +private fun ConeTypeProjection.replaceType(newType: ConeKotlinType): ConeTypeProjection = + when (kind) { + ProjectionKind.INVARIANT -> newType + ProjectionKind.IN -> ConeKotlinTypeProjectionIn(newType) + ProjectionKind.OUT -> ConeKotlinTypeProjectionOut(newType) + ProjectionKind.STAR -> error("Should not be a star projection") + } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt index 5ee94cc3c8b..f317556ccad 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt @@ -524,3 +524,8 @@ private class CapturedArguments(val capturedArguments: Array } } +fun ConeKotlinType.isSubtypeOf(superType: ConeKotlinType, session: FirSession): Boolean = + AbstractTypeChecker.isSubtypeOf( + session.typeContext.newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false), + this, superType, + ) diff --git a/compiler/testData/diagnostics/tests/cast/bare/FromErrorType.fir.kt b/compiler/testData/diagnostics/tests/cast/bare/FromErrorType.fir.kt index 7dc989eb0a6..17b8ea12bdf 100644 --- a/compiler/testData/diagnostics/tests/cast/bare/FromErrorType.fir.kt +++ b/compiler/testData/diagnostics/tests/cast/bare/FromErrorType.fir.kt @@ -3,6 +3,6 @@ class G fun foo(p: P) { - val v = p as G? - checkSubtype>(v!!) + val v = p as G? + checkSubtype>(v!!) } diff --git a/compiler/testData/diagnostics/tests/cast/bare/SupertypeChain.kt b/compiler/testData/diagnostics/tests/cast/bare/SupertypeChain.kt new file mode 100644 index 00000000000..6a380a522d3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/cast/bare/SupertypeChain.kt @@ -0,0 +1,17 @@ +// FIR_IDENTICAL +// SKIP_TXT +abstract class Parent +abstract class DefaultParent : Parent() +abstract class TableDerived : DefaultParent() { + fun bar(): K = TODO() +} + +interface A {} +interface B : A { fun b() } + +fun foo(): Parent = TODO() + +fun main() { + val w = foo() as? TableDerived ?: return + w.bar().b() +} diff --git a/compiler/testData/diagnostics/tests/generics/innerClasses/bareTypesComplex.fir.kt b/compiler/testData/diagnostics/tests/generics/innerClasses/bareTypesComplex.fir.kt deleted file mode 100644 index 6659a53794c..00000000000 --- a/compiler/testData/diagnostics/tests/generics/innerClasses/bareTypesComplex.fir.kt +++ /dev/null @@ -1,14 +0,0 @@ -open class SuperOuter { - inner open class SuperInner -} - -class DerivedOuter : SuperOuter() { - inner class DerivedInner : SuperOuter.SuperInner() -} - -fun bare(x: SuperOuter<*>.SuperInner<*>, y: Any?) { - if (x is SuperOuter.SuperInner) return - if (y is SuperOuter.SuperInner) { - return - } -} diff --git a/compiler/testData/diagnostics/tests/generics/innerClasses/bareTypesComplex.kt b/compiler/testData/diagnostics/tests/generics/innerClasses/bareTypesComplex.kt index 748e1b72a9b..f68edcd0420 100644 --- a/compiler/testData/diagnostics/tests/generics/innerClasses/bareTypesComplex.kt +++ b/compiler/testData/diagnostics/tests/generics/innerClasses/bareTypesComplex.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL open class SuperOuter { inner open class SuperInner } diff --git a/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParams.kt b/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParams.kt index c565d9f9ef3..b835d033472 100644 --- a/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParams.kt +++ b/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParams.kt @@ -1,4 +1,3 @@ -// FIR_IDE_IGNORE // FIR_IDENTICAL // !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL diff --git a/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParamsBoundMismatch.kt b/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParamsBoundMismatch.kt index 995168d6f99..f6b4f38f101 100644 --- a/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParamsBoundMismatch.kt +++ b/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParamsBoundMismatch.kt @@ -1,4 +1,3 @@ -// FIR_IDE_IGNORE // FIR_IDENTICAL // !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL diff --git a/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParamsNameMismatch.kt b/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParamsNameMismatch.kt index 80ef7b71c1c..ec29bbe746a 100644 --- a/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParamsNameMismatch.kt +++ b/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParamsNameMismatch.kt @@ -1,4 +1,3 @@ -// FIR_IDE_IGNORE // FIR_IDENTICAL // !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL diff --git a/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInReturnType.kt b/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInReturnType.kt index 0099061a731..dc6aeb13967 100644 --- a/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInReturnType.kt +++ b/compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInReturnType.kt @@ -1,4 +1,3 @@ -// FIR_IDE_IGNORE // FIR_IDENTICAL // !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasAsBareType.fir.kt b/compiler/testData/diagnostics/tests/typealias/typeAliasAsBareType.fir.kt index 5f4f58be304..4c57c4a7261 100644 --- a/compiler/testData/diagnostics/tests/typealias/typeAliasAsBareType.fir.kt +++ b/compiler/testData/diagnostics/tests/typealias/typeAliasAsBareType.fir.kt @@ -14,16 +14,16 @@ fun testNL1(x: Collection?): Boolean = x is NL fun testNL2(x: Collection?): List? = x as NL fun testNL3(x: Collection?): List? = x as NL? -fun testLStar(x: Collection): List = x as LStar -fun testMyList(x: Collection): List = x as MyList +fun testLStar(x: Collection): List = x as LStar +fun testMyList(x: Collection): List = x as MyList typealias MMTT = MutableMap typealias Dictionary = MutableMap typealias WriteableMap = MutableMap typealias ReadableList = MutableList -fun testWrong1(x: Map) = x is MMTT -fun testWrong2(x: Map) = x is Dictionary +fun testWrong1(x: Map) = x is MMTT +fun testWrong2(x: Map) = x is Dictionary fun testWrong3(x: Map) = x is WriteableMap fun testWrong4(x: List) = x is ReadableList 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 e494e1b1dea..890c668cfec 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 @@ -4356,6 +4356,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/cast/bare/RedundantNullable.kt"); } + @Test + @TestMetadata("SupertypeChain.kt") + public void testSupertypeChain() throws Exception { + runTest("compiler/testData/diagnostics/tests/cast/bare/SupertypeChain.kt"); + } + @Test @TestMetadata("ToErrorType.kt") public void testToErrorType() throws Exception { diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index c04ec4f7463..27decb636bd 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -4350,6 +4350,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/cast/bare/RedundantNullable.kt"); } + @Test + @TestMetadata("SupertypeChain.kt") + public void testSupertypeChain() throws Exception { + runTest("compiler/testData/diagnostics/tests/cast/bare/SupertypeChain.kt"); + } + @Test @TestMetadata("ToErrorType.kt") public void testToErrorType() throws Exception {