Skip to content

Commit 26653a7

Browse files
authored
Merge pull request #68564 from kubamracek/embedded-closures
[embedded] Fix compiler asserts when building closures
2 parents 0abc2b7 + a5d5621 commit 26653a7

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,11 @@ deleteAndReenqueueForEmissionValuesDependentOnCanonicalPrespecializedMetadataRec
14071407
emitLazyTypeContextDescriptor(IGM, &decl, RequireMetadata);
14081408
}
14091409

1410+
static bool loweredFunctionHasGenericArguments(SILFunction *f) {
1411+
auto s = f->getLoweredFunctionType()->getInvocationGenericSignature();
1412+
return s && !s->areAllParamsConcrete();
1413+
}
1414+
14101415
/// Emit any lazy definitions (of globals or functions or whatever
14111416
/// else) that we require.
14121417
void IRGenerator::emitLazyDefinitions() {
@@ -1419,7 +1424,7 @@ void IRGenerator::emitLazyDefinitions() {
14191424
assert(LazyFieldDescriptors.empty());
14201425
// LazyFunctionDefinitions are allowed, but they must not be generic
14211426
for (SILFunction *f : LazyFunctionDefinitions) {
1422-
assert(!f->getLoweredFunctionType()->getSubstGenericSignature());
1427+
assert(!loweredFunctionHasGenericArguments(f));
14231428
}
14241429
assert(LazyWitnessTables.empty());
14251430
assert(LazyCanonicalSpecializedMetadataAccessors.empty());
@@ -1499,8 +1504,13 @@ void IRGenerator::emitLazyDefinitions() {
14991504
while (!LazyFunctionDefinitions.empty()) {
15001505
SILFunction *f = LazyFunctionDefinitions.pop_back_val();
15011506
CurrentIGMPtr IGM = getGenModule(f);
1502-
assert(!f->isPossiblyUsedExternally()
1503-
&& "function with externally-visible linkage emitted lazily?");
1507+
// In embedded Swift, we can gain public / externally-visible functions
1508+
// by deserializing them from imported modules, or by the CMO pass making
1509+
// local functions public. TODO: We should internalize as a separate pass.
1510+
if (!SIL.getASTContext().LangOpts.hasFeature(Feature::Embedded)) {
1511+
assert(!f->isPossiblyUsedExternally()
1512+
&& "function with externally-visible linkage emitted lazily?");
1513+
}
15041514
IGM->emitSILFunction(f);
15051515
}
15061516

@@ -1541,9 +1551,10 @@ void IRGenerator::addLazyFunction(SILFunction *f) {
15411551
// Add it to the queue if it hasn't already been put there.
15421552
if (!LazilyEmittedFunctions.insert(f).second)
15431553
return;
1544-
1554+
1555+
// Embedded Swift doesn't expect any generic functions to be referenced.
15451556
if (SIL.getASTContext().LangOpts.hasFeature(Feature::Embedded)) {
1546-
assert(!f->getLoweredFunctionType()->getSubstGenericSignature());
1557+
assert(!loweredFunctionHasGenericArguments(f));
15471558
}
15481559

15491560
assert(!FinishedEmittingLazyDefinitions);

test/embedded/closures.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %target-swift-emit-ir %s -parse-stdlib -enable-experimental-feature Embedded -wmo
2+
3+
// REQUIRES: swift_in_compiler
4+
5+
public func foo<Result>(_ body: () -> Result) -> Result {
6+
return body()
7+
}
8+
9+
public func main() {
10+
foo() { }
11+
}

0 commit comments

Comments
 (0)