Skip to content

Commit 57d8b7c

Browse files
authored
Merge pull request #21115 from slavapestov/on-demand-accessor-fix-5.0
Force SILGen emission of on-demand synthesized accessors [5.0]
2 parents 2c2cc70 + c5deb93 commit 57d8b7c

File tree

5 files changed

+61
-11
lines changed

5 files changed

+61
-11
lines changed

lib/SILGen/SILGenDecl.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,7 +1396,19 @@ void SILGenModule::emitExternalWitnessTable(ProtocolConformance *c) {
13961396
lastEmittedConformance = root;
13971397
}
13981398

1399+
static bool isDeclaredInPrimaryFile(SILModule &M, Decl *d) {
1400+
auto *dc = d->getDeclContext();
1401+
if (auto *sf = dyn_cast<SourceFile>(dc->getModuleScopeContext()))
1402+
if (M.isWholeModule() || M.getAssociatedContext() == sf)
1403+
return true;
1404+
1405+
return false;
1406+
}
1407+
13991408
void SILGenModule::emitExternalDefinition(Decl *d) {
1409+
if (isDeclaredInPrimaryFile(M, d))
1410+
return;
1411+
14001412
switch (d->getKind()) {
14011413
case DeclKind::Func:
14021414
case DeclKind::Accessor: {

lib/Sema/CodeSynthesis.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,11 @@ void TypeChecker::synthesizeWitnessAccessorsForStorage(
10831083
if (isOnDemandAccessor(storage, kind)) {
10841084
auto synthKind = getSynthKindForAccessorKind(kind);
10851085
triggerSynthesis(*this, storage->getAccessor(kind), synthKind);
1086+
1087+
// Make sure SILGen emits the accessor; on-demand accessors have shared
1088+
// linkage, and if its defined in a different translation unit from the
1089+
// conformance we cannot simply generate an external declaration.
1090+
Context.addExternalDecl(storage->getAccessor(kind));
10861091
}
10871092
});
10881093

lib/Sema/TypeChecker.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,17 @@ static void typeCheckFunctionsAndExternalDecls(SourceFile &SF, TypeChecker &TC)
453453
TC.typeCheckAbstractFunctionBody(AFD);
454454
}
455455

456+
// Synthesize any necessary function bodies.
457+
// FIXME: If we're not planning to run SILGen, this is wasted effort.
458+
while (!TC.FunctionsToSynthesize.empty()) {
459+
auto function = TC.FunctionsToSynthesize.back().second;
460+
TC.FunctionsToSynthesize.pop_back();
461+
if (function.getDecl()->isInvalid() || TC.Context.hadError())
462+
continue;
463+
464+
TC.synthesizeFunctionBody(function);
465+
}
466+
456467
// Type check external definitions.
457468
for (unsigned n = TC.Context.ExternalDefinitions.size();
458469
currentExternalDef != n;
@@ -483,17 +494,6 @@ static void typeCheckFunctionsAndExternalDecls(SourceFile &SF, TypeChecker &TC)
483494
TC.validateDecl(decl);
484495
}
485496

486-
// Synthesize any necessary function bodies.
487-
// FIXME: If we're not planning to run SILGen, this is wasted effort.
488-
while (!TC.FunctionsToSynthesize.empty()) {
489-
auto function = TC.FunctionsToSynthesize.back().second;
490-
TC.FunctionsToSynthesize.pop_back();
491-
if (function.getDecl()->isInvalid() || TC.Context.hadError())
492-
continue;
493-
494-
TC.synthesizeFunctionBody(function);
495-
}
496-
497497
// Validate any referenced declarations for SIL's purposes.
498498
// Note: if we ever start putting extension members in vtables, we'll need
499499
// to validate those members too.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import Foundation
2+
3+
public class Fish {
4+
@NSManaged public var name: String
5+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend -module-name main -emit-silgen -enable-sil-ownership -sdk %S/Inputs -primary-file %s %S/Inputs/nsmanaged-witness-multi-other.swift -I %S/Inputs -I %t -enable-source-import | %FileCheck %s
4+
5+
// RUN: %target-swift-frontend -module-name main -emit-silgen -enable-sil-ownership -sdk %S/Inputs -primary-file %s -primary-file %S/Inputs/nsmanaged-witness-multi-other.swift -I %S/Inputs -I %t -enable-source-import | %FileCheck %s
6+
7+
// RUN: %target-swift-frontend -module-name main -emit-silgen -enable-sil-ownership -sdk %S/Inputs %s %S/Inputs/nsmanaged-witness-multi-other.swift -I %S/Inputs -I %t -enable-source-import | %FileCheck %s
8+
9+
// REQUIRES: objc_interop
10+
import Foundation
11+
12+
public protocol FishProtocol {
13+
var name: String { get set }
14+
}
15+
16+
extension Fish : FishProtocol {}
17+
18+
// Make sure the modify accessor for Fish.name is emitted here even though it
19+
// its storage was declared in a different translation unit
20+
21+
// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] @$s4main4FishCAA0B8ProtocolA2aDP4nameSSvMTW : $@yield_once @convention(witness_method: FishProtocol) (@inout Fish) -> @yields @inout String
22+
// CHECK: function_ref @$s4main4FishC4nameSSvM
23+
// CHECK: return
24+
25+
// CHECK-LABEL: sil shared [serialized] @$s4main4FishC4nameSSvM : $@yield_once @convention(method) (@guaranteed Fish) -> @yields @inout String
26+
// CHECK: objc_method %0 : $Fish, #Fish.name!getter.1.foreign
27+
// CHECK: objc_method %0 : $Fish, #Fish.name!setter.1.foreign
28+
// CHECK: unwind

0 commit comments

Comments
 (0)