Skip to content

Commit c1d4589

Browse files
committed
SIL: Fix type lowering of 'unowned T' where 'T' is a type parameter
The abstraction pattern's generic signature does not describe the substituted type, and it may not be present at all. Fixes #79244.
1 parent 7f6a8c6 commit c1d4589

File tree

2 files changed

+35
-13
lines changed

2 files changed

+35
-13
lines changed

lib/SIL/IR/TypeLowering.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -655,19 +655,29 @@ namespace {
655655
return visitAbstractTypeParamType(type, origType, isSensitive);
656656
}
657657

658-
Type getConcreteReferenceStorageReferent(Type type,
658+
Type getConcreteReferenceStorageReferent(Type substType,
659659
AbstractionPattern origType) {
660-
if (type->isTypeParameter()) {
661-
auto genericSig = origType.getGenericSignature();
662-
if (auto concreteType = genericSig->getConcreteType(type))
663-
return concreteType;
664-
if (auto superclassType = genericSig->getSuperclassBound(type))
665-
return superclassType;
666-
assert(genericSig->requiresClass(type));
660+
substType = substType->getReferenceStorageReferent();
661+
origType = origType.getReferenceStorageReferentType();
662+
663+
if (auto objectType = substType->getOptionalObjectType()) {
664+
substType = objectType;
665+
origType = origType.getOptionalObjectType();
666+
}
667+
668+
if (substType->isTypeParameter()) {
669+
if (auto genericSig = origType.getGenericSignature()) {
670+
auto type = origType.getType();
671+
if (auto concreteType = genericSig->getConcreteType(type))
672+
return concreteType;
673+
if (auto superclassType = genericSig->getSuperclassBound(type))
674+
return superclassType;
675+
assert(genericSig->requiresClass(type));
676+
}
667677
return TC.Context.getAnyObjectType();
668678
}
669679

670-
return type;
680+
return substType;
671681
}
672682

673683
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
@@ -710,9 +720,7 @@ namespace {
710720
RetTy visit##Name##StorageType(Can##Name##StorageType type, \
711721
AbstractionPattern origType, \
712722
IsTypeExpansionSensitive_t isSensitive) { \
713-
auto referentType = \
714-
type->getReferentType()->lookThroughSingleOptionalType(); \
715-
auto concreteType = getConcreteReferenceStorageReferent(referentType, origType); \
723+
auto concreteType = getConcreteReferenceStorageReferent(type, origType); \
716724
if (Name##StorageType::get(concreteType, TC.Context) \
717725
->isLoadable(Expansion.getResilienceExpansion())) { \
718726
return asImpl().visitLoadable##Name##StorageType(type, origType, \

test/SILGen/unowned-class-bound-generic-parameter.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,18 @@ func makeGenericClosureWithNativeClass2<T>(t: T) where T : ClassProtocol, T : Ba
2020
_ = { [unowned t] in _ = t }
2121
}
2222

23-
// CHECK-LABEL: sil private [ossa] @$s4main34makeGenericClosureWithNativeClass21tyx_tAA9BaseClassCRbzAA0I8ProtocolRzlFyycfU_ : $@convention(thin) <T where T : BaseClass, T : ClassProtocol> (@guaranteed @sil_unowned T) -> () {
23+
// CHECK-LABEL: sil private [ossa] @$s4main34makeGenericClosureWithNativeClass21tyx_tAA9BaseClassCRbzAA0I8ProtocolRzlFyycfU_ : $@convention(thin) <T where T : BaseClass, T : ClassProtocol> (@guaranteed @sil_unowned T) -> () {
24+
25+
// https://github.com/swiftlang/swift/issues/79244
26+
27+
struct Wrapper<T: AnyObject> {
28+
unowned var t: T
29+
}
30+
31+
func f1<T: AnyObject>(t: T) {
32+
_ = { Wrapper(t: t) }
33+
}
34+
35+
func f2<T: AnyObject, U: AnyObject>(u: U, tt: Array<Wrapper<T>>) {
36+
_ = tt.map { _ in Wrapper(t: u) }
37+
}

0 commit comments

Comments
 (0)