[FIR] Don't transform call arguments during TYPES phase

Instead, it should happen during BODY_RESOLVE phase.

This fixes KT-66150. The problem was, that `super<B>.f()` expression
in delegated constructor call was transformed during TYPES phase,
and type transformer has no special logic for allowing bare types in
super qualifiers, like the one in expressions transformer (see
`org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer.transformSuperReceiver`).
As a result, `B` without type argument leads to
WrongNumberOfTypeArgumentsError.
It looks incorrect that expressions in constructor call resolved
during TYPES phase, so skipping transformation of
argument list seems like the best solution here.

^KT-66150 Fixed
This commit is contained in:
Roman Efremov
2024-03-12 11:38:41 +01:00
committed by Space Team
parent c4f89ab32e
commit 284d5437e5
5 changed files with 14 additions and 37 deletions
@@ -309,7 +309,9 @@ FILE: [ResolvedTo(IMPORTS)] superQualifierTypeArgsInDelegatedConstructorLocalCla
BODY_RESOLVE:
FILE: [ResolvedTo(IMPORTS)] superQualifierTypeArgsInDelegatedConstructorLocalClass.kt
public abstract [ResolvedTo(STATUS)] interface B<[ResolvedTo(STATUS)] T> : R|kotlin/Any| {
public open [ResolvedTo(STATUS)] fun f(): <implicit> { LAZY_BLOCK }
public open [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] fun f(): R|kotlin/Boolean| {
^f Boolean(true)
}
}
public open [ResolvedTo(STATUS)] class A<[ResolvedTo(STATUS)] T> : R|kotlin/Any| {
@@ -328,7 +330,7 @@ FILE: [ResolvedTo(IMPORTS)] superQualifierTypeArgsInDelegatedConstructorLocalCla
public final [ResolvedTo(BODY_RESOLVE)] fun test(): R|kotlin/Unit| {
local final [ResolvedTo(BODY_RESOLVE)] class LocalClass : R|one/A<one/D>| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=LocalClass] constructor(): R|<local>/LocalClass| {
super<R|one/A<one/D>|>(this@R|one/C|.super<<ERROR TYPE REF: Wrong number of type arguments>>.<Unresolved name: f>#())
super<R|one/A<one/D>|>(this@R|one/C|.super<R|one/B<kotlin/Int>|>.R|SubstitutionOverride<one/B.f: R|kotlin/Boolean|>|())
}
}
@@ -361,7 +363,7 @@ FILE: [ResolvedTo(BODY_RESOLVE)] superQualifierTypeArgsInDelegatedConstructorLoc
public final [ResolvedTo(BODY_RESOLVE)] fun test(): R|kotlin/Unit| {
local final [ResolvedTo(BODY_RESOLVE)] class LocalClass : R|one/A<one/D>| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=LocalClass] constructor(): R|<local>/LocalClass| {
super<R|one/A<one/D>|>(this@R|one/C|.super<<ERROR TYPE REF: Wrong number of type arguments>>.<Unresolved name: f>#())
super<R|one/A<one/D>|>(this@R|one/C|.super<R|one/B<kotlin/Int>|>.R|SubstitutionOverride<one/B.f: R|kotlin/Boolean|>|())
}
}
@@ -12,7 +12,9 @@ import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.copyWithNewSourceKind
import org.jetbrains.kotlin.fir.correspondingProperty
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isFromVararg
import org.jetbrains.kotlin.fir.declarations.utils.isInner
@@ -31,6 +33,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.wrapNestedClassifierScopeWithSubstit
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.fir.whileAnalysing
import org.jetbrains.kotlin.util.PrivateForInline
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
@@ -348,6 +351,10 @@ open class FirTypeResolveTransformer(
return block
}
override fun transformArgumentList(argumentList: FirArgumentList, data: Any?): FirArgumentList {
return argumentList
}
override fun transformAnnotation(annotation: FirAnnotation, data: Any?): FirStatement {
shouldNotBeCalled()
}
@@ -1,15 +0,0 @@
interface B<T> {
fun f() = true
}
open class A(b: Boolean)
class C : B<Int> {
inner class Inner : A(super<<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>B<!>>.<!UNRESOLVED_REFERENCE!>f<!>())
inner class Inner2 : A(super<B<!TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER!><Int><!>>.f())
fun test() {
class LocalClass : A(super<<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>B<!>>.<!UNRESOLVED_REFERENCE!>f<!>())
class LocalClass2 : A(super<B<!TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER!><Int><!>>.f())
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
interface B<T> {
fun f() = true
}
@@ -1,18 +0,0 @@
// LL_FIR_DIVERGENCE
// WRONG_NUMBER_OF_TYPE_ARGUMENTS not reported in Inner class because of BodyBuildingMode.LAZY_BODIES
// LL_FIR_DIVERGENCE
interface B<T> {
fun f() = true
}
open class A(b: Boolean)
class C : B<Int> {
inner class Inner : A(super<B>.f())
inner class Inner2 : A(super<B<!TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER!><Int><!>>.f())
fun test() {
class LocalClass : A(super<<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>B<!>>.<!UNRESOLVED_REFERENCE!>f<!>())
class LocalClass2 : A(super<B<!TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER!><Int><!>>.f())
}
}