Skip to content

Commit 8d77d95

Browse files
authored
Merge pull request #17784 from slavapestov/unowned-source-compat-regression
SIL: Fix regression with unowned capture of generic parameter
2 parents 9f055be + a2035b1 commit 8d77d95

File tree

2 files changed

+19
-9
lines changed

2 files changed

+19
-9
lines changed

lib/SIL/TypeLowering.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -272,13 +272,13 @@ namespace {
272272
return visitAbstractTypeParamType(type);
273273
}
274274

275-
bool hasNativeReferenceCounting(CanType type) {
275+
Type getConcreteReferenceStorageReferent(Type type) {
276276
if (type->isTypeParameter()) {
277277
auto signature = getGenericSignature();
278278
assert(signature && "dependent type without generic signature?!");
279279

280280
if (auto concreteType = signature->getConcreteType(type))
281-
return hasNativeReferenceCounting(concreteType->getCanonicalType());
281+
return concreteType->getCanonicalType();
282282

283283
assert(signature->requiresClass(type));
284284

@@ -288,17 +288,14 @@ namespace {
288288
// at some point the type-checker should prove acyclic-ness.
289289
auto bound = signature->getSuperclassBound(type);
290290
if (bound) {
291-
return hasNativeReferenceCounting(bound->getCanonicalType());
291+
return getConcreteReferenceStorageReferent(bound->getCanonicalType());
292292
}
293293

294-
// Ask whether Builtin.UnknownObject uses native reference counting.
295294
auto &ctx = M.getASTContext();
296-
return ctx.TheUnknownObjectType->
297-
usesNativeReferenceCounting(ResilienceExpansion::Maximal);
295+
return ctx.TheUnknownObjectType;
298296
}
299297

300-
// FIXME: resilience
301-
return type->usesNativeReferenceCounting(ResilienceExpansion::Maximal);
298+
return type;
302299
}
303300

304301
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
@@ -321,7 +318,11 @@ namespace {
321318
IsAddressOnly}); \
322319
} \
323320
RetTy visit##Name##StorageType(Can##Name##StorageType type) { \
324-
if (type->isLoadable(ResilienceExpansion::Maximal)) { \
321+
auto referentType = type->getReferentType(); \
322+
auto concreteType = getConcreteReferenceStorageReferent(referentType); \
323+
auto &ctx = M.getASTContext(); \
324+
if (Name##StorageType::get(concreteType, ctx) \
325+
->isLoadable(ResilienceExpansion::Maximal)) { \
325326
return asImpl().visitLoadable##Name##StorageType(type); \
326327
} else { \
327328
return asImpl().visitAddressOnly##Name##StorageType(type); \

test/SILGen/unowned.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,12 @@ struct Unowned<T: AnyObject> {
159159
}
160160
func takesUnownedStruct(_ z: Unowned<C>) {}
161161
// CHECK-LABEL: sil hidden @$S7unowned18takesUnownedStructyyAA0C0VyAA1CCGF : $@convention(thin) (@guaranteed Unowned<C>) -> ()
162+
163+
// Make sure we don't crash here
164+
struct UnownedGenericCapture<T : AnyObject> {
165+
var object: T
166+
167+
func f() -> () -> () {
168+
return { [unowned object] in _ = object }
169+
}
170+
}

0 commit comments

Comments
 (0)