FIR Checker: check AMBIGUOUS_ANONYMOUS_TYPE_INFERRED

Also change
org.jetbrains.kotlin.fir.types.TypeUtilsKt#hideLocalTypeIfNeeded to skip
approximating anonymous objects if there are multiple super type refs so
that resolution behaves the same (for uncompilable code).

Note that this change does not implement check for
ApproximateAnonymousReturnTypesInPrivateInlineFunctions as the check is
already turned on in 1.5 and will likely not needed when FIR becomes
stable.
This commit is contained in:
Tianyu Geng
2021-09-01 13:30:02 -07:00
committed by teamcityserver
parent 6432388778
commit 76e192fc8a
14 changed files with 149 additions and 72 deletions
@@ -1960,6 +1960,15 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.AMBIGUOUS_ANONYMOUS_TYPE_INFERRED) { firDiagnostic ->
AmbiguousAnonymousTypeInferredImpl(
firDiagnostic.a.map { coneKotlinType ->
firSymbolBuilder.typeBuilder.buildKtType(coneKotlinType)
},
firDiagnostic as FirPsiDiagnostic,
token,
)
}
add(FirErrors.MANY_IMPL_MEMBER_NOT_IMPLEMENTED) { firDiagnostic ->
ManyImplMemberNotImplementedImpl(
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a.fir),
@@ -1397,6 +1397,11 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val invisibleDeclaration: KtCallableSymbol
}
abstract class AmbiguousAnonymousTypeInferred : KtFirDiagnostic<KtDeclaration>() {
override val diagnosticClass get() = AmbiguousAnonymousTypeInferred::class
abstract val superTypes: List<KtType>
}
abstract class ManyImplMemberNotImplemented : KtFirDiagnostic<KtClassOrObject>() {
override val diagnosticClass get() = ManyImplMemberNotImplemented::class
abstract val classOrObject: KtClassLikeSymbol
@@ -2232,6 +2232,14 @@ internal class InvisibleAbstractMemberFromSuperWarningImpl(
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}
internal class AmbiguousAnonymousTypeInferredImpl(
override val superTypes: List<KtType>,
firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.AmbiguousAnonymousTypeInferred(), KtAbstractFirDiagnostic<KtDeclaration> {
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}
internal class ManyImplMemberNotImplementedImpl(
override val classOrObject: KtClassLikeSymbol,
override val missingDeclaration: KtCallableSymbol,
@@ -714,6 +714,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<FirClassSymbol<*>>("classOrObject")
parameter<FirCallableSymbol<*>>("invisibleDeclaration")
}
val AMBIGUOUS_ANONYMOUS_TYPE_INFERRED by error<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE) {
parameter<Collection<ConeKotlinType>>("superTypes")
}
val MANY_IMPL_MEMBER_NOT_IMPLEMENTED by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirClassSymbol<*>>("classOrObject")
parameter<FirCallableSymbol<*>>("missingDeclaration")
@@ -404,6 +404,7 @@ object FirErrors {
val ABSTRACT_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER by deprecationError2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(ProhibitInvisibleAbstractMethodsInSuperclasses, SourceElementPositioningStrategies.DECLARATION_NAME)
val AMBIGUOUS_ANONYMOUS_TYPE_INFERRED by error1<KtDeclaration, Collection<ConeKotlinType>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val MANY_IMPL_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val OVERRIDING_FINAL_MEMBER_BY_DELEGATION by error2<KtClassOrObject, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
@@ -28,6 +28,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirCyclicTypeBoundsChecker,
FirExpectActualDeclarationChecker,
FirInvalidAndDangerousCharactersChecker,
FirAmbiguousAnonymousTypeChecker,
)
override val functionCheckers: Set<FirFunctionChecker>
@@ -0,0 +1,45 @@
/*
* 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.analysis.checkers.declaration
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isInline
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.shouldHideLocalType
import org.jetbrains.kotlin.fir.types.toSymbol
import org.jetbrains.kotlin.fir.types.visibilityForApproximation
object FirAmbiguousAnonymousTypeChecker : FirBasicDeclarationChecker() {
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirSimpleFunction && declaration !is FirProperty) return
require(declaration is FirCallableDeclaration)
if (context.containingDeclarations.any { it.isLocalMember || it is FirAnonymousObject }) return
if (!shouldHideLocalType(
declaration.visibilityForApproximation(context.containingDeclarations.lastOrNull()),
declaration.isInline
)
) return
val classSymbol = declaration.returnTypeRef.coneType.toSymbol(context.session) ?: return
if (classSymbol is FirAnonymousObjectSymbol) {
// Any anonymous object that has only one super type is already approximated to the super type by
// org.jetbrains.kotlin.fir.types.TypeUtilsKt#hideLocalTypeIfNeeded. Hence, any remaining anonymous object must have more than
// one super types and hence are ambiguous.
reporter.reportOn(
declaration.source,
FirErrors.AMBIGUOUS_ANONYMOUS_TYPE_INFERRED,
classSymbol.resolvedSuperTypeRefs.map { it.coneType },
context
)
}
}
}
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
@@ -18,7 +17,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.hasBackingField
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.argumentMapping
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.packageFqName
import org.jetbrains.kotlin.fir.resolve.fqName
@@ -51,6 +51,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_WITHOUT_EXPECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ACTUALS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ANONYMOUS_TYPE_INFERRED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_EXPECTS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_SUPER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_ARGUMENT_MUST_BE_CONST
@@ -1068,6 +1069,7 @@ class FirDefaultErrorMessages {
RENDER_CLASS_OR_OBJECT,
DECLARATION_NAME
)
map.put(AMBIGUOUS_ANONYMOUS_TYPE_INFERRED, "Right-hand side has anonymous type. Please specify type explicitly", NOT_RENDERED)
map.put(
MANY_IMPL_MEMBER_NOT_IMPLEMENTED,
"{0} must override {1} because it inherits many implementations of it",
@@ -51,14 +51,8 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
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
return visibilityForApproximation(container)
}
private inline fun <T> withFirArrayOfCallTransformer(block: () -> T): T {
@@ -8,9 +8,8 @@ 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.FirAnonymousObject
import org.jetbrains.kotlin.fir.declarations.FirTypedDeclaration
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.resolve.toSymbol
@@ -334,39 +333,51 @@ private fun FirTypeRef.hideLocalTypeIfNeeded(
containingCallableVisibility: Visibility?,
isInlineFunction: Boolean = false
): FirTypeRef {
if (containingCallableVisibility == null) {
if (!shouldHideLocalType(containingCallableVisibility, isInlineFunction)) return this
val firClass =
(((this as? FirResolvedTypeRef)
?.type as? ConeClassLikeType)
?.lookupTag as? ConeClassLookupTagWithFixedSymbol)
?.symbol?.fir
if (firClass !is FirAnonymousObject) {
// NB: local classes are acceptable here, but reported by EXPOSED_* checkers as errors
return this
}
// Approximate types for non-private (all but package private or private) members.
// Also private inline functions, as per KT-33917.
if (containingCallableVisibility == Visibilities.Public ||
containingCallableVisibility == Visibilities.Protected ||
containingCallableVisibility == Visibilities.Internal ||
(containingCallableVisibility == Visibilities.Private && isInlineFunction)
) {
val firClass =
(((this as? FirResolvedTypeRef)
?.type as? ConeClassLikeType)
?.lookupTag as? ConeClassLookupTagWithFixedSymbol)
?.symbol?.fir
if (firClass !is FirAnonymousObject) {
// NB: local classes are acceptable here, but reported by EXPOSED_* checkers as errors
return this
}
if (firClass.superTypeRefs.size > 1) {
return buildErrorTypeRef {
diagnostic = ConeSimpleDiagnostic("Cannot hide local type ${firClass.render()}")
}
}
val superType = firClass.superTypeRefs.single()
if (superType is FirResolvedTypeRef) {
val newKind = source?.kind
return if (newKind is FirFakeSourceElementKind) superType.copyWithNewSourceKind(newKind) else superType
}
if (firClass.superTypeRefs.size > 1) {
// NB: don't approximate so members can be resolved. The error is reported by FirAmbiguousAnonymousTypeChecker.
return this
}
val superType = firClass.superTypeRefs.single()
if (superType is FirResolvedTypeRef) {
val newKind = source?.kind
return if (newKind is FirFakeSourceElementKind) superType.copyWithNewSourceKind(newKind) else superType
}
return this
}
fun shouldHideLocalType(containingCallableVisibility: Visibility?, isInlineFunction: Boolean): Boolean {
if (containingCallableVisibility == null) {
return false
}
// Approximate types for non-private (all but package private or private) members.
// Also private inline functions, as per KT-33917.
return containingCallableVisibility == Visibilities.Public ||
containingCallableVisibility == Visibilities.Protected ||
containingCallableVisibility == Visibilities.Internal ||
(containingCallableVisibility == Visibilities.Private && isInlineFunction)
}
fun FirDeclaration.visibilityForApproximation(container: FirDeclaration?): Visibility {
if (this !is FirMemberDeclaration) return Visibilities.Local
val containerVisibility =
if (container == null || container is FirFile) 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
}
fun ConeTypeContext.captureFromArgumentsInternal(type: ConeKotlinType, status: CaptureStatus): ConeKotlinType? {
val capturedArguments = captureArguments(type, status) ?: return null
return if (type is ConeFlexibleType) {
@@ -16,15 +16,15 @@ class Foo {
privateProperty.f2()
}
protected val protectedProperty = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>protected val protectedProperty<!> = object : MyClass(), MyTrait {}
val internalProperty = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>val internalProperty<!> = object : MyClass(), MyTrait {}
internal val internal2Property = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal val internal2Property<!> = object : MyClass(), MyTrait {}
public val publicProperty = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public val publicProperty<!> = object : MyClass(), MyTrait {}
val propertyWithGetter
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>val propertyWithGetter<!>
get() = object: MyClass(), MyTrait {}
@@ -35,13 +35,13 @@ class Foo {
privateFunction().f2()
}
protected fun protectedFunction() = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>protected fun protectedFunction()<!> = object : MyClass(), MyTrait {}
fun internalFunction() = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>fun internalFunction()<!> = object : MyClass(), MyTrait {}
internal fun internal2Function() = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal fun internal2Function()<!> = object : MyClass(), MyTrait {}
public fun publicFunction() = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public fun publicFunction()<!> = object : MyClass(), MyTrait {}
@@ -53,13 +53,13 @@ class Foo {
privatePropertyInner.f2()
}
protected val protectedProperty = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>protected val protectedProperty<!> = object : MyClass(), MyTrait {}
val internalProperty = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>val internalProperty<!> = object : MyClass(), MyTrait {}
internal val internal2Property = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal val internal2Property<!> = object : MyClass(), MyTrait {}
public val publicProperty = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public val publicProperty<!> = object : MyClass(), MyTrait {}
private fun privateFunctionInner() = object : MyClass(), MyTrait {}
@@ -69,13 +69,13 @@ class Foo {
privateFunctionInner().f2()
}
protected fun protectedFunction() = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>protected fun protectedFunction()<!> = object : MyClass(), MyTrait {}
fun internalFunction() = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>fun internalFunction()<!> = object : MyClass(), MyTrait {}
internal fun internal2Function() = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal fun internal2Function()<!> = object : MyClass(), MyTrait {}
public fun publicFunction() = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public fun publicFunction()<!> = object : MyClass(), MyTrait {}
}
@@ -93,21 +93,21 @@ class Foo {
private val packagePrivateProperty = object : MyClass(), MyTrait {}
<!WRONG_MODIFIER_TARGET!>protected<!> val packageProtectedProperty = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!><!WRONG_MODIFIER_TARGET!>protected<!> val packageProtectedProperty<!> = object : MyClass(), MyTrait {}
val packageInternalProperty = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>val packageInternalProperty<!> = object : MyClass(), MyTrait {}
internal val packageInternal2Property = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal val packageInternal2Property<!> = object : MyClass(), MyTrait {}
public val packagePublicProperty = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public val packagePublicProperty<!> = object : MyClass(), MyTrait {}
<!WRONG_MODIFIER_TARGET!>protected<!> fun packageProtectedFunction() = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!><!WRONG_MODIFIER_TARGET!>protected<!> fun packageProtectedFunction()<!> = object : MyClass(), MyTrait {}
fun packageInternalFunction() = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>fun packageInternalFunction()<!> = object : MyClass(), MyTrait {}
internal fun packageInternal2Function() = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal fun packageInternal2Function()<!> = object : MyClass(), MyTrait {}
public fun packagePublicFunction() = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public fun packagePublicFunction()<!> = object : MyClass(), MyTrait {}
fun fooPackage() {
val packageLocalVar = object : MyClass(), MyTrait {}
@@ -11,7 +11,7 @@ private inline fun foo2(crossinline f: () -> Int) = object : I1 {
fun bar(): Int = f()
}
private inline fun foo3(crossinline f: () -> Int) = object : I1, I2 {
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>private inline fun foo3(crossinline f: () -> Int)<!> = object : I1, I2 {
fun bar(): Int = f()
}
@@ -36,11 +36,11 @@ fun test2(b: Boolean) {
}
fun test3(b: Boolean) {
var x = <!DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: Cannot hide local type object : R|I1|, R|I2| { private constructor(): R|<anonymous>| { super<R|kotlin/Any|>() } public final fun bar(): R|kotlin/Int| { ^bar R|<local>/f|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Int|>|() }}")!>foo3 { 1 }<!>
var x = <!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>")!>foo3 { 1 }<!>
if (b) {
x = <!DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: Cannot hide local type object : R|I1|, R|I2| { private constructor(): R|<anonymous>| { super<R|kotlin/Any|>() } public final fun bar(): R|kotlin/Int| { ^bar R|<local>/f|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Int|>|() }}")!>foo3 { 2 }<!>
x = <!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>")!>foo3 { 2 }<!>
}
x.<!UNRESOLVED_REFERENCE!>bar<!>()
x.bar()
}
fun test4(b: Boolean) {
@@ -11,7 +11,7 @@ private inline fun foo2(crossinline f: () -> Int) = object : I1 {
fun bar(): Int = f()
}
private inline fun foo3(crossinline f: () -> Int) = object : I1, I2 {
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>private inline fun foo3(crossinline f: () -> Int)<!> = object : I1, I2 {
fun bar(): Int = f()
}
@@ -36,11 +36,11 @@ fun test2(b: Boolean) {
}
fun test3(b: Boolean) {
var x = <!DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: Cannot hide local type object : R|I1|, R|I2| { private constructor(): R|<anonymous>| { super<R|kotlin/Any|>() } public final fun bar(): R|kotlin/Int| { ^bar R|<local>/f|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Int|>|() }}")!>foo3 { 1 }<!>
var x = <!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>")!>foo3 { 1 }<!>
if (b) {
x = <!DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: Cannot hide local type object : R|I1|, R|I2| { private constructor(): R|<anonymous>| { super<R|kotlin/Any|>() } public final fun bar(): R|kotlin/Int| { ^bar R|<local>/f|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Int|>|() }}")!>foo3 { 2 }<!>
x = <!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>")!>foo3 { 2 }<!>
}
x.<!UNRESOLVED_REFERENCE!>bar<!>()
x.bar()
}
fun test4(b: Boolean) {