Skip to content

Commit 535e938

Browse files
committed
Fix header compilation for function / class declarations nested inside inline functions.
^KT-78422
1 parent 5167de9 commit 535e938

File tree

8 files changed

+38
-9
lines changed

8 files changed

+38
-9
lines changed

compiler/fir/analysis-tests/testData/resolve/headerMode/classDeclaration.fir.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ FILE: classDeclaration.kt
2222
public final fun funD(): R|kotlin/Int|
2323

2424
public final inline fun funE(): R|kotlin/String| {
25-
local final fun funF(): R|kotlin/String|
25+
local final fun funF(): R|kotlin/String| {
26+
^funF String(funF body)
27+
}
2628

2729
^funE R|<local>/funF|()
2830
}

compiler/fir/analysis-tests/testData/resolve/headerMode/functionDeclaration.fir.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ FILE: functionDeclaration.kt
1212
private final fun funC(): R|kotlin/String|
1313
public final fun funD(): R|kotlin/Int|
1414
public final inline fun funE(): R|kotlin/String| {
15-
local final fun funF(): R|kotlin/String|
15+
local final fun funF(): R|kotlin/String| {
16+
^funF String(funF body)
17+
}
1618

1719
^funE R|<local>/funF|()
1820
}
@@ -22,7 +24,9 @@ FILE: functionDeclaration.kt
2224
super<R|kotlin/Any|>()
2325
}
2426

25-
public final fun funH(): R|kotlin/String|
27+
public final fun funH(): R|kotlin/String| {
28+
^funH String(funH body)
29+
}
2630

2731
}
2832

compiler/fir/analysis-tests/testData/resolve/headerMode/objectDeclaration.fir.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ FILE: objectDeclaration.kt
2222
public final fun funD(): R|kotlin/Int|
2323

2424
public final inline fun funE(): R|kotlin/String| {
25-
local final fun funF(): R|kotlin/String|
25+
local final fun funF(): R|kotlin/String| {
26+
^funF String(funF body)
27+
}
2628

2729
^funE R|<local>/funF|()
2830
}

compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirDeclarationBuilder.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.DanglingTypeConstraint
2828
import org.jetbrains.kotlin.fir.declarations.utils.addDeclarations
2929
import org.jetbrains.kotlin.fir.declarations.utils.addDefaultBoundIfNecessary
3030
import org.jetbrains.kotlin.fir.declarations.utils.danglingTypeConstraints
31+
import org.jetbrains.kotlin.fir.declarations.utils.isFromInlineFunction
3132
import org.jetbrains.kotlin.fir.declarations.utils.isScriptTopLevelDeclaration
3233
import org.jetbrains.kotlin.fir.diagnostics.*
3334
import org.jetbrains.kotlin.fir.expressions.*
@@ -687,6 +688,7 @@ class LightTreeRawFirDeclarationBuilder(
687688
}
688689
}
689690
}.also {
691+
it.isFromInlineFunction = context.containedWithinInlineFunction
690692
if (classNode.getParent()?.elementType == KtStubElementTypes.CLASS_BODY) {
691693
it.initContainingClassForLocalAttr()
692694
}
@@ -2058,7 +2060,8 @@ class LightTreeRawFirDeclarationBuilder(
20582060
}
20592061

20602062
val allowLegacyContractDescription = outerContractDescription == null
2061-
val bodyWithContractDescription = withForcedLocalContext {
2063+
val containedWithinInlineFunction = context.containedWithinInlineFunction || functionBuilder.status.isInline
2064+
val bodyWithContractDescription = withForcedLocalContext(containedWithinInlineFunction) {
20622065
convertFunctionBody(block, expression, allowLegacyContractDescription)
20632066
}
20642067
this.body = bodyWithContractDescription.first
@@ -2073,6 +2076,7 @@ class LightTreeRawFirDeclarationBuilder(
20732076
}
20742077
context.firFunctionTargets.removeLast()
20752078
}.build().also {
2079+
it.isFromInlineFunction = context.containedWithinInlineFunction
20762080
target.bind(it)
20772081
fillDanglingConstraintsTo(firTypeParameters, typeConstraints, it)
20782082
}

compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/AbstractRawFirBuilder.kt

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,21 +91,27 @@ abstract class AbstractRawFirBuilder<T : Any>(val baseSession: FirSession, val c
9191
name: Name,
9292
isExpect: Boolean,
9393
forceLocalContext: Boolean = false,
94+
containedWithinInlineFunction: Boolean? = null,
9495
l: () -> T,
9596
): T = when {
9697
forceLocalContext -> withForcedLocalContext {
97-
withChildClassNameRegardlessLocalContext(name, isExpect, l)
98+
withChildClassNameRegardlessLocalContext(name, isExpect, containedWithinInlineFunction, l)
9899
}
99100
else -> {
100-
withChildClassNameRegardlessLocalContext(name, isExpect, l)
101+
withChildClassNameRegardlessLocalContext(name, isExpect, containedWithinInlineFunction, l)
101102
}
102103
}
103104

104105
inline fun <T> withChildClassNameRegardlessLocalContext(
105106
name: Name,
106107
isExpect: Boolean,
108+
containedWithinInlineFunction: Boolean? = null,
107109
l: () -> T,
108110
): T {
111+
val oldContainedWithinInlineFunction = context.containedWithinInlineFunction
112+
if (containedWithinInlineFunction != null) {
113+
context.containedWithinInlineFunction = containedWithinInlineFunction
114+
}
109115
context.className = context.className.child(name)
110116
val previousIsExpect = context.containerIsExpect
111117
context.containerIsExpect = previousIsExpect || isExpect
@@ -123,10 +129,15 @@ abstract class AbstractRawFirBuilder<T : Any>(val baseSession: FirSession, val c
123129

124130
context.className = context.className.parent()
125131
context.containerIsExpect = previousIsExpect
132+
context.containedWithinInlineFunction = oldContainedWithinInlineFunction
126133
}
127134
}
128135

129-
inline fun <R> withForcedLocalContext(block: () -> R): R {
136+
inline fun <R> withForcedLocalContext(containedWithinInlineFunction: Boolean? = null, block: () -> R): R {
137+
val oldContainedWithinInlineFunction = context.containedWithinInlineFunction
138+
if (containedWithinInlineFunction != null) {
139+
context.containedWithinInlineFunction = containedWithinInlineFunction
140+
}
130141
val oldForcedLocalContext = context.inLocalContext
131142
context.inLocalContext = true
132143
val oldClassNameBeforeLocalContext = context.classNameBeforeLocalContext
@@ -141,6 +152,7 @@ abstract class AbstractRawFirBuilder<T : Any>(val baseSession: FirSession, val c
141152
context.classNameBeforeLocalContext = oldClassNameBeforeLocalContext
142153
context.inLocalContext = oldForcedLocalContext
143154
context.className = oldClassName
155+
context.containedWithinInlineFunction = oldContainedWithinInlineFunction
144156
}
145157
}
146158

compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Context.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ class Context<T> {
5959
val dispatchReceiverTypesStack: MutableList<ConeClassLikeType> = mutableListOf()
6060
var containerIsExpect: Boolean = false
6161

62+
var containedWithinInlineFunction: Boolean = false
63+
6264
var containingScriptSymbol: FirScriptSymbol? = null
6365
var containingReplSymbol: FirReplSnippetSymbol? = null
6466

compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyBackingField
2222
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
2323
import org.jetbrains.kotlin.fir.declarations.utils.hasExplicitBackingField
2424
import org.jetbrains.kotlin.fir.declarations.utils.isConst
25+
import org.jetbrains.kotlin.fir.declarations.utils.isFromInlineFunction
2526
import org.jetbrains.kotlin.fir.declarations.utils.isInline
2627
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
2728
import org.jetbrains.kotlin.fir.declarations.utils.isScriptTopLevelDeclaration
@@ -1039,7 +1040,7 @@ open class FirDeclarationsResolveTransformer(
10391040
}
10401041
result.transformReturnTypeRef(transformer, ResolutionMode.UpdateImplicitTypeRef(returnTypeRef))
10411042
}
1042-
if (session.languageVersionSettings.getFlag(AnalysisFlags.headerMode) && !function.isInline) {
1043+
if (session.languageVersionSettings.getFlag(AnalysisFlags.headerMode) && !function.isInline && function.isFromInlineFunction != true) {
10431044
// Header mode: once the return type for non-inline function is known, the body can be removed.
10441045
result.replaceBody(null)
10451046
}

compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/declarationAttributes.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.name.Name
2424
private object IsFromVarargKey : FirDeclarationDataKey()
2525
private object IsReferredViaField : FirDeclarationDataKey()
2626
private object IsFromPrimaryConstructor : FirDeclarationDataKey()
27+
private object IsFromInlineFunction: FirDeclarationDataKey()
2728
private object ComponentFunctionSymbolKey : FirDeclarationDataKey()
2829
private object SourceElementKey : FirDeclarationDataKey()
2930
private object ModuleNameKey : FirDeclarationDataKey()
@@ -43,6 +44,7 @@ private object FileNameForPluginGeneratedCallable : FirDeclarationDataKey()
4344
var FirProperty.isFromVararg: Boolean? by FirDeclarationDataRegistry.data(IsFromVarargKey)
4445
var FirProperty.isReferredViaField: Boolean? by FirDeclarationDataRegistry.data(IsReferredViaField)
4546
var FirProperty.fromPrimaryConstructor: Boolean? by FirDeclarationDataRegistry.data(IsFromPrimaryConstructor)
47+
var FirDeclaration.isFromInlineFunction: Boolean? by FirDeclarationDataRegistry.data(IsFromInlineFunction)
4648
var FirProperty.componentFunctionSymbol: FirNamedFunctionSymbol? by FirDeclarationDataRegistry.data(ComponentFunctionSymbolKey)
4749
var FirClassLikeDeclaration.sourceElement: SourceElement? by FirDeclarationDataRegistry.data(SourceElementKey)
4850
var FirRegularClass.moduleName: String? by FirDeclarationDataRegistry.data(ModuleNameKey)

0 commit comments

Comments
 (0)