diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/innerClassInAnonymousObject.fir.txt b/compiler/fir/analysis-tests/testData/resolve/cfg/innerClassInAnonymousObject.fir.txt index 34e9c667163..f1c88d5bd1b 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/innerClassInAnonymousObject.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/innerClassInAnonymousObject.fir.txt @@ -1,5 +1,5 @@ FILE: innerClassInAnonymousObject.kt - public final val x: R|| = object : R|kotlin/Any| { + public final val x: R|kotlin/Any| = object : R|kotlin/Any| { private constructor(): R|| { super() } @@ -16,4 +16,4 @@ FILE: innerClassInAnonymousObject.kt } - public get(): R|| + public get(): R|kotlin/Any| diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/annotationArgumentKClassLiteralTypeError.fir.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/annotationArgumentKClassLiteralTypeError.fir.txt index fa58d460db5..5d037b7f706 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/annotationArgumentKClassLiteralTypeError.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/annotationArgumentKClassLiteralTypeError.fir.txt @@ -8,7 +8,7 @@ FILE: annotationArgumentKClassLiteralTypeError.kt public get(): R|kotlin/Array>| } - public final val R|T|.test: R|| + public final val R|T|.test: R|kotlin/Any| public get(): R|| { ^ @R|Ann|(((R|T|), (Q|kotlin/Array|))) object : R|kotlin/Any| { private constructor(): R|| { diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingOverloads.fir.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingOverloads.fir.txt index b732440a451..67b922bdde5 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingOverloads.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingOverloads.fir.txt @@ -90,14 +90,14 @@ FILE: conflictingOverloads.kt } - public final val Companion: R|| = object : R|kotlin/Any| { + public final val Companion: R|kotlin/Any| = object : R|kotlin/Any| { private constructor(): R|| { super() } } - public get(): R|| + public get(): R|kotlin/Any| } public final fun R|B|.foo(): R|kotlin/Unit| { diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/localEntitytNotAllowed.fir.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/localEntitytNotAllowed.fir.txt index ff83835dd72..f6a6c1b4556 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/localEntitytNotAllowed.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/localEntitytNotAllowed.fir.txt @@ -21,7 +21,7 @@ FILE: localEntitytNotAllowed.kt public abstract interface X : R|kotlin/Any| { } - public final val a: R|| = object : R|kotlin/Any| { + public final val a: R|kotlin/Any| = object : R|kotlin/Any| { private constructor(): R|| { super() } @@ -48,7 +48,7 @@ FILE: localEntitytNotAllowed.kt } - public get(): R|| + public get(): R|kotlin/Any| public final fun b(): R|kotlin/Unit| { local final object E : R|kotlin/Any| { diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/privateObjectLiteral.fir.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/privateObjectLiteral.fir.txt index f7622cce04e..cefdbc55d45 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/privateObjectLiteral.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/privateObjectLiteral.fir.txt @@ -20,7 +20,7 @@ FILE: privateObjectLiteral.kt public final val y: R|kotlin/Int| = this@R|/C|.R|/C.x|.R|/.foo|() public get(): R|kotlin/Int| - internal final val z: R|| = object : R|kotlin/Any| { + internal final val z: R|kotlin/Any| = object : R|kotlin/Any| { private constructor(): R|| { super() } @@ -31,9 +31,9 @@ FILE: privateObjectLiteral.kt } - internal get(): R|| + internal get(): R|kotlin/Any| - public final val w: R|kotlin/Int| = this@R|/C|.R|/C.z|.R|/.foo|() - public get(): R|kotlin/Int| + public final val w: R|ERROR CLASS: Unresolved name: foo| = this@R|/C|.R|/C.z|.#() + public get(): R|ERROR CLASS: Unresolved name: foo| } diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/privateObjectLiteral.kt b/compiler/fir/analysis-tests/testData/resolve/expresssions/privateObjectLiteral.kt index 67188d0d0fe..45f71375792 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/privateObjectLiteral.kt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/privateObjectLiteral.kt @@ -9,5 +9,5 @@ class C { fun foo() = 13 } - val w = z.foo() // ERROR! + val w = z.foo() // ERROR! } diff --git a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantVisibilityModifierChecker.fir.txt b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantVisibilityModifierChecker.fir.txt index d2c4e79b455..2fd1132eb4c 100644 --- a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantVisibilityModifierChecker.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantVisibilityModifierChecker.fir.txt @@ -22,7 +22,7 @@ FILE: RedundantVisibilityModifierChecker.kt super() } - internal final val z: R|| = object : R|kotlin/Any| { + internal final val z: R|kotlin/Any| = object : R|kotlin/Any| { private constructor(): R|| { super() } @@ -33,7 +33,7 @@ FILE: RedundantVisibilityModifierChecker.kt } - internal get(): R|| + internal get(): R|kotlin/Any| } public final class Foo2 : R|kotlin/Any| { diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems.fir.txt index d6832dbdd69..71f780c9ba1 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems.fir.txt @@ -1,7 +1,7 @@ FILE: problems.kt public final val sb: R|java/lang/StringBuilder| = R|java/lang/StringBuilder.StringBuilder|() public get(): R|java/lang/StringBuilder| - public final val o: R|| = object : R|kotlin/Any| { + public final val o: R|kotlin/Any| = object : R|kotlin/Any| { private constructor(): R|| { super() } @@ -15,7 +15,7 @@ FILE: problems.kt } - public get(): R|| + public get(): R|kotlin/Any| public final fun test(): R|kotlin/Unit| { local final class Local : R|kotlin/Any| { public constructor(): R|Local| { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 6c735933fd5..bc5c67c3e9f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -6,6 +6,8 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter @@ -45,6 +47,17 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor private var containingClass: FirRegularClass? = null private val statusResolver: FirStatusResolver = FirStatusResolver(session, scopeSession) + private fun FirDeclaration.visibilityForApproximation(): Visibility { + if (this !is FirMemberDeclaration) return Visibilities.Local + val container = context.containers.getOrNull(context.containers.size - 2) + val containerVisibility = + if (container == null) Visibilities.Public + else (container as? FirRegularClass)?.visibility ?: Visibilities.Local + if (containerVisibility == Visibilities.Local || visibility == Visibilities.Local) return Visibilities.Local + if (containerVisibility == Visibilities.Private) return Visibilities.Private + return visibility + } + private inline fun withFirArrayOfCallTransformer(block: () -> T): T { transformer.expressionsTransformer.enableArrayOfCallTransformation = true return try { @@ -560,7 +573,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor transformer, withExpectedType( returnExpression.resultType.approximatedIfNeededOrSelf( - inferenceComponents.approximator, simpleFunction?.visibility, simpleFunction?.isInline == true + inferenceComponents.approximator, + simpleFunction?.visibilityForApproximation(), + simpleFunction?.isInline == true ) ) ) @@ -990,67 +1005,50 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor private fun storeVariableReturnType(variable: FirVariable<*>) { val initializer = variable.initializer if (variable.returnTypeRef is FirImplicitTypeRef) { - when { + val resultType = when { initializer != null -> { val unwrappedInitializer = (initializer as? FirExpressionWithSmartcast)?.originalExpression ?: initializer - val expectedType = when (val resultType = unwrappedInitializer.resultType) { - is FirImplicitTypeRef -> buildErrorTypeRef { - diagnostic = ConeSimpleDiagnostic("No result type for initializer", DiagnosticKind.InferenceError) - } - else -> { - buildResolvedTypeRef { - type = resultType.coneType - annotations.addAll(resultType.annotations) - resultType.source?.fakeElement(FirFakeSourceElementKind.PropertyFromParameter)?.let { - source = it - } + unwrappedInitializer.resultType + } + variable.getter != null && variable.getter !is FirDefaultPropertyAccessor -> variable.getter?.returnTypeRef + else -> null + } + if (resultType != null) { + val expectedType = when (resultType) { + is FirImplicitTypeRef -> buildErrorTypeRef { + diagnostic = ConeSimpleDiagnostic("No result type for initializer", DiagnosticKind.InferenceError) + } + else -> { + buildResolvedTypeRef { + type = resultType.coneType + annotations.addAll(resultType.annotations) + resultType.source?.fakeElement(FirFakeSourceElementKind.PropertyFromParameter)?.let { + source = it } } } - variable.transformReturnTypeRef( - transformer, - withExpectedType( - expectedType.approximatedIfNeededOrSelf(inferenceComponents.approximator, (variable as? FirProperty)?.visibility) + } + variable.transformReturnTypeRef( + transformer, + withExpectedType( + expectedType.approximatedIfNeededOrSelf( + inferenceComponents.approximator, + variable.visibilityForApproximation() ) ) - } - variable.getter != null && variable.getter !is FirDefaultPropertyAccessor -> { - val expectedType = when (val resultType = variable.getter?.returnTypeRef) { - is FirImplicitTypeRef -> buildErrorTypeRef { - diagnostic = ConeSimpleDiagnostic("No result type for getter", DiagnosticKind.InferenceError) - } - else -> { - resultType?.let { - buildResolvedTypeRef { - type = resultType.coneType - annotations.addAll(resultType.annotations) - resultType.source?.fakeElement(FirFakeSourceElementKind.PropertyFromParameter)?.let { - source = it - } - } - } - } - } - variable.transformReturnTypeRef( - transformer, - withExpectedType( - expectedType?.approximatedIfNeededOrSelf(inferenceComponents.approximator, (variable as? FirProperty)?.visibility) - ) + ) + } else { + variable.transformReturnTypeRef( + transformer, + withExpectedType( + buildErrorTypeRef { + diagnostic = ConeSimpleDiagnostic( + "Cannot infer variable type without initializer / getter / delegate", + DiagnosticKind.InferenceError, + ) + }, ) - } - else -> { - variable.transformReturnTypeRef( - transformer, - withExpectedType( - buildErrorTypeRef { - diagnostic = ConeSimpleDiagnostic( - "Cannot infer variable type without initializer / getter / delegate", - DiagnosticKind.InferenceError, - ) - }, - ) - ) - } + ) } if (variable.getter?.returnTypeRef is FirImplicitTypeRef) { variable.getter?.transformReturnTypeRef(transformer, withExpectedType(variable.returnTypeRef)) 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 3a18b53a1f4..95450c2de1b 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 @@ -8,7 +8,7 @@ package org.jetbrains.kotlin.fir.types import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.* -import org.jetbrains.kotlin.fir.declarations.classId +import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap @@ -309,7 +309,8 @@ private fun FirTypeRef.hideLocalTypeIfNeeded( ?.type as? ConeClassLikeType) ?.lookupTag as? ConeClassLookupTagWithFixedSymbol) ?.symbol?.fir - if (firClass?.classId?.isLocal != true) { + if (firClass !is FirAnonymousObject) { + // NB: local classes are acceptable here, but reported by EXPOSED_* checkers as errors return this } if (firClass.superTypeRefs.size > 1) { @@ -318,7 +319,7 @@ private fun FirTypeRef.hideLocalTypeIfNeeded( } } val superType = firClass.superTypeRefs.single() - if (superType is FirResolvedTypeRef && !superType.isAny) { + if (superType is FirResolvedTypeRef) { return superType } } diff --git a/compiler/testData/codegen/box/ir/anonymousClassLeak.kt b/compiler/testData/codegen/box/ir/anonymousClassLeak.kt index 085288c8634..f5edc88422f 100644 --- a/compiler/testData/codegen/box/ir/anonymousClassLeak.kt +++ b/compiler/testData/codegen/box/ir/anonymousClassLeak.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // DONT_TARGET_EXACT_BACKEND: WASM // WASM_MUTE_REASON: PROPERTY_REFERENCES // WITH_RUNTIME diff --git a/compiler/testData/diagnostics/tests/inline/approximateReturnedAnonymousObjects.fir.kt b/compiler/testData/diagnostics/tests/inline/approximateReturnedAnonymousObjects.fir.kt index e5a992792f2..298cb10d9be 100644 --- a/compiler/testData/diagnostics/tests/inline/approximateReturnedAnonymousObjects.fir.kt +++ b/compiler/testData/diagnostics/tests/inline/approximateReturnedAnonymousObjects.fir.kt @@ -20,11 +20,11 @@ private fun foo4(f: () -> Int) = object { } fun test1(b: Boolean) { - var x = ")!>foo1 { 1 } + var x = foo1 { 1 } if (b) { - x = ")!>foo1 { 2 } + x = foo1 { 2 } } - x.bar() + x.bar() } fun test2(b: Boolean) { diff --git a/compiler/testData/diagnostics/tests/inline/returnedAnonymousObjects.fir.kt b/compiler/testData/diagnostics/tests/inline/returnedAnonymousObjects.fir.kt index 7e3dfc4bb9a..45af611f7d9 100644 --- a/compiler/testData/diagnostics/tests/inline/returnedAnonymousObjects.fir.kt +++ b/compiler/testData/diagnostics/tests/inline/returnedAnonymousObjects.fir.kt @@ -20,11 +20,11 @@ private fun foo4(f: () -> Int) = object { } fun test1(b: Boolean) { - var x = ")!>foo1 { 1 } + var x = foo1 { 1 } if (b) { - x = ")!>foo1 { 2 } + x = foo1 { 2 } } - x.bar() + x.bar() } fun test2(b: Boolean) { diff --git a/compiler/testData/ir/irText/classes/objectLiteralExpressions.fir.kt.txt b/compiler/testData/ir/irText/classes/objectLiteralExpressions.fir.kt.txt index b9886d37fce..693175fa5f8 100644 --- a/compiler/testData/ir/irText/classes/objectLiteralExpressions.fir.kt.txt +++ b/compiler/testData/ir/irText/classes/objectLiteralExpressions.fir.kt.txt @@ -3,7 +3,7 @@ interface IFoo { } -val test1: +val test1: Any field = { // BLOCK local class { private constructor() /* primary */ { diff --git a/compiler/testData/ir/irText/classes/objectLiteralExpressions.fir.txt b/compiler/testData/ir/irText/classes/objectLiteralExpressions.fir.txt index efbf62e8ce8..d37fe51b879 100644 --- a/compiler/testData/ir/irText/classes/objectLiteralExpressions.fir.txt +++ b/compiler/testData/ir/irText/classes/objectLiteralExpressions.fir.txt @@ -17,7 +17,7 @@ FILE fqName: fileName:/objectLiteralExpressions.kt public open fun toString (): kotlin.String declared in kotlin.Any $this: VALUE_PARAMETER name: type:kotlin.Any PROPERTY name:test1 visibility:public modality:FINAL [val] - FIELD PROPERTY_BACKING_FIELD name:test1 type:.test1. visibility:private [final,static] + FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.Any visibility:private [final,static] EXPRESSION_BODY BLOCK type=.test1. origin=OBJECT_LITERAL CLASS CLASS name: modality:FINAL visibility:local superTypes:[kotlin.Any] @@ -40,11 +40,11 @@ FILE fqName: fileName:/objectLiteralExpressions.kt public open fun toString (): kotlin.String declared in kotlin.Any $this: VALUE_PARAMETER name: type:kotlin.Any CONSTRUCTOR_CALL 'private constructor () [primary] declared in .test1.' type=.test1. origin=OBJECT_LITERAL - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:.test1. + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Any correspondingProperty: PROPERTY name:test1 visibility:public modality:FINAL [val] BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): .test1. declared in ' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test1 type:.test1. visibility:private [final,static]' type=.test1. origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Any declared in ' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.Any visibility:private [final,static]' type=kotlin.Any origin=null PROPERTY name:test2 visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:test2 type:.IFoo visibility:private [final,static] EXPRESSION_BODY diff --git a/compiler/testData/ir/irText/expressions/objectReference.fir.kt.txt b/compiler/testData/ir/irText/expressions/objectReference.fir.kt.txt index a079149616d..518effa0539 100644 --- a/compiler/testData/ir/irText/expressions/objectReference.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/objectReference.fir.kt.txt @@ -53,7 +53,7 @@ object Z { get - val anObject: + val anObject: Any field = { // BLOCK local class { private constructor() /* primary */ { diff --git a/compiler/testData/ir/irText/expressions/objectReference.fir.txt b/compiler/testData/ir/irText/expressions/objectReference.fir.txt index 9133a67547d..5cd4d0318f4 100644 --- a/compiler/testData/ir/irText/expressions/objectReference.fir.txt +++ b/compiler/testData/ir/irText/expressions/objectReference.fir.txt @@ -108,7 +108,7 @@ FILE fqName: fileName:/objectReference.kt GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:aLambda type:kotlin.Function0 visibility:private [final]' type=kotlin.Function0 origin=null receiver: GET_VAR ': .Z declared in .Z.' type=.Z origin=null PROPERTY name:anObject visibility:public modality:FINAL [val] - FIELD PROPERTY_BACKING_FIELD name:anObject type:.Z.anObject. visibility:private [final] + FIELD PROPERTY_BACKING_FIELD name:anObject type:kotlin.Any visibility:private [final] EXPRESSION_BODY BLOCK type=.Z.anObject. origin=OBJECT_LITERAL CLASS CLASS name: modality:FINAL visibility:local superTypes:[kotlin.Any] @@ -156,12 +156,12 @@ FILE fqName: fileName:/objectReference.kt public open fun toString (): kotlin.String declared in kotlin.Any $this: VALUE_PARAMETER name: type:kotlin.Any CONSTRUCTOR_CALL 'private constructor () [primary] declared in .Z.anObject.' type=.Z.anObject. origin=OBJECT_LITERAL - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Z) returnType:.Z.anObject. + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Z) returnType:kotlin.Any correspondingProperty: PROPERTY name:anObject visibility:public modality:FINAL [val] $this: VALUE_PARAMETER name: type:.Z BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): .Z.anObject. declared in .Z' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:anObject type:.Z.anObject. visibility:private [final]' type=.Z.anObject. origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Any declared in .Z' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:anObject type:kotlin.Any visibility:private [final]' type=kotlin.Any origin=null receiver: GET_VAR ': .Z declared in .Z.' type=.Z origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/4.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/4.fir.kt index 8f587d178ee..4465240a87b 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/4.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/4.fir.kt @@ -63,8 +63,8 @@ fun case_6(x: EmptyClass) { // TESTCASE NUMBER: 7 fun case_7() { - if (anonymousTypeProperty == null || & ")!>anonymousTypeProperty == null) { - ")!>anonymousTypeProperty + if (anonymousTypeProperty == null || anonymousTypeProperty == null) { + anonymousTypeProperty } }