Skip to content

Commit 9c7afa7

Browse files
committed
SILGen: Fix issues with types nested inside fully-concrete extensions
Add a new version of TypeConverter::getEffectiveGenericSignature() which takes a DeclContext, which uses the same logic as the AnyFunctionRef version, and use it when computing lowered types for destructors, stored property initializers and ivar destroyers. Also, canonicalize the interface type of 'Self' as part of building these types, to fold away concrete generic parameters. Fixes <rdar://problem/32120987>.
1 parent 3722842 commit 9c7afa7

File tree

3 files changed

+96
-55
lines changed

3 files changed

+96
-55
lines changed

include/swift/SIL/TypeLowering.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,9 @@ class TypeConverter {
751751
CanGenericSignature getEffectiveGenericSignature(AnyFunctionRef fn,
752752
CaptureInfo captureInfo);
753753

754+
/// Retrieve the set of generic parameters closed over by the context.
755+
CanGenericSignature getEffectiveGenericSignature(DeclContext *dc);
756+
754757
/// Push a generic function context. See GenericContextScope for an RAII
755758
/// interface to this function.
756759
///

lib/SIL/TypeLowering.cpp

Lines changed: 58 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,8 +1728,7 @@ static CanAnyFunctionType getGlobalGetterType(CanType varType) {
17281728
static CanAnyFunctionType getDefaultArgGeneratorInterfaceType(
17291729
TypeConverter &TC,
17301730
AbstractFunctionDecl *AFD,
1731-
unsigned DefaultArgIndex,
1732-
ASTContext &context) {
1731+
unsigned DefaultArgIndex) {
17331732
auto resultTy = AFD->getDefaultArg(DefaultArgIndex).second;
17341733
assert(resultTy && "Didn't find default argument?");
17351734

@@ -1742,52 +1741,50 @@ static CanAnyFunctionType getDefaultArgGeneratorInterfaceType(
17421741
// Get the generic signature from the surrounding context.
17431742
auto funcInfo = TC.getConstantInfo(SILDeclRef(AFD));
17441743
CanGenericSignature sig;
1745-
if (auto genTy = funcInfo.FormalInterfaceType->getAs<GenericFunctionType>())
1746-
sig = genTy->getGenericSignature()->getCanonicalSignature();
1744+
if (auto genTy = dyn_cast<GenericFunctionType>(funcInfo.FormalInterfaceType))
1745+
sig = genTy.getGenericSignature();
17471746

17481747
if (sig) {
1749-
return cast<GenericFunctionType>(
1750-
GenericFunctionType::get(sig,
1751-
TupleType::getEmpty(context),
1752-
canResultTy,
1753-
AnyFunctionType::ExtInfo())
1754-
->getCanonicalType());
1748+
return CanGenericFunctionType::get(sig,
1749+
TupleType::getEmpty(TC.Context),
1750+
canResultTy,
1751+
AnyFunctionType::ExtInfo());
17551752
}
17561753

1757-
return CanFunctionType::get(TupleType::getEmpty(context), canResultTy);
1754+
return CanFunctionType::get(TupleType::getEmpty(TC.Context), canResultTy);
17581755
}
17591756

17601757
/// Get the type of a stored property initializer, () -> T.
17611758
static CanAnyFunctionType getStoredPropertyInitializerInterfaceType(
17621759
TypeConverter &TC,
1763-
VarDecl *VD,
1764-
ASTContext &context) {
1760+
VarDecl *VD) {
17651761
auto *DC = VD->getDeclContext();
17661762
CanType resultTy =
17671763
DC->mapTypeOutOfContext(VD->getParentPattern()->getType())
17681764
->getCanonicalType();
1769-
GenericSignature *sig = DC->getGenericSignatureOfContext();
1765+
auto sig = TC.getEffectiveGenericSignature(DC);
17701766

17711767
if (sig)
1772-
return CanGenericFunctionType::get(sig->getCanonicalSignature(),
1773-
TupleType::getEmpty(context),
1768+
return CanGenericFunctionType::get(sig,
1769+
TupleType::getEmpty(TC.Context),
17741770
resultTy,
17751771
GenericFunctionType::ExtInfo());
17761772

1777-
return CanFunctionType::get(TupleType::getEmpty(context), resultTy);
1773+
return CanFunctionType::get(TupleType::getEmpty(TC.Context), resultTy);
17781774
}
17791775

17801776
/// Get the type of a destructor function.
1781-
static CanAnyFunctionType getDestructorInterfaceType(DestructorDecl *dd,
1777+
static CanAnyFunctionType getDestructorInterfaceType(TypeConverter &TC,
1778+
DestructorDecl *dd,
17821779
bool isDeallocating,
1783-
ASTContext &C,
17841780
bool isForeign) {
17851781
auto classType = dd->getDeclContext()->getDeclaredInterfaceType()
1786-
->getCanonicalType();
1782+
->getCanonicalType(dd->getGenericSignatureOfContext(),
1783+
*TC.M.getSwiftModule());
17871784

17881785
assert((!isForeign || isDeallocating)
17891786
&& "There are no foreign destroying destructors");
1790-
AnyFunctionType::ExtInfo extInfo =
1787+
auto extInfo =
17911788
AnyFunctionType::ExtInfo(FunctionType::Representation::Thin,
17921789
/*throws*/ false);
17931790
if (isForeign)
@@ -1797,37 +1794,39 @@ static CanAnyFunctionType getDestructorInterfaceType(DestructorDecl *dd,
17971794
extInfo = extInfo
17981795
.withSILRepresentation(SILFunctionTypeRepresentation::Method);
17991796

1800-
CanType resultTy = isDeallocating? TupleType::getEmpty(C)->getCanonicalType()
1801-
: C.TheNativeObjectType;
1797+
auto &C = TC.Context;
1798+
CanType resultTy = (isDeallocating
1799+
? TupleType::getEmpty(C)
1800+
: C.TheNativeObjectType);
18021801

1803-
auto sig = dd->getDeclContext()->getGenericSignatureOfContext();
1802+
auto sig = TC.getEffectiveGenericSignature(dd);
18041803
if (sig)
1805-
return cast<GenericFunctionType>(
1806-
GenericFunctionType::get(sig, classType, resultTy, extInfo)
1807-
->getCanonicalType());
1804+
return CanGenericFunctionType::get(sig, classType, resultTy, extInfo);
18081805
return CanFunctionType::get(classType, resultTy, extInfo);
18091806
}
18101807

18111808
/// Retrieve the type of the ivar initializer or destroyer method for
18121809
/// a class.
1813-
static CanAnyFunctionType getIVarInitDestroyerInterfaceType(ClassDecl *cd,
1810+
static CanAnyFunctionType getIVarInitDestroyerInterfaceType(TypeConverter &TC,
1811+
ClassDecl *cd,
18141812
bool isObjC,
1815-
ASTContext &ctx,
18161813
bool isDestroyer) {
1817-
auto classType = cd->getDeclaredInterfaceType()->getCanonicalType();
1814+
auto classType = cd->getDeclaredInterfaceType()
1815+
->getCanonicalType(cd->getGenericSignatureOfContext(),
1816+
*TC.M.getSwiftModule());
18181817

1819-
auto emptyTupleTy = TupleType::getEmpty(ctx)->getCanonicalType();
1820-
CanType resultType = isDestroyer? emptyTupleTy : classType;
1818+
CanType emptyTupleTy = TupleType::getEmpty(TC.Context);
1819+
auto resultType = (isDestroyer ? emptyTupleTy : classType);
18211820
auto extInfo = AnyFunctionType::ExtInfo(FunctionType::Representation::Thin,
18221821
/*throws*/ false);
18231822
extInfo = extInfo
18241823
.withSILRepresentation(isObjC? SILFunctionTypeRepresentation::ObjCMethod
18251824
: SILFunctionTypeRepresentation::Method);
18261825

18271826
resultType = CanFunctionType::get(emptyTupleTy, resultType, extInfo);
1828-
auto sig = cd->getGenericSignatureOfContext();
1827+
auto sig = TC.getEffectiveGenericSignature(cd);
18291828
if (sig)
1830-
return CanGenericFunctionType::get(sig->getCanonicalSignature(),
1829+
return CanGenericFunctionType::get(sig,
18311830
classType, resultType,
18321831
extInfo);
18331832
return CanFunctionType::get(classType, resultType, extInfo);
@@ -1844,6 +1843,17 @@ TypeConverter::getEffectiveGenericEnvironment(AnyFunctionRef fn,
18441843
return nullptr;
18451844
}
18461845

1846+
CanGenericSignature
1847+
TypeConverter::getEffectiveGenericSignature(DeclContext *dc) {
1848+
if (auto sig = dc->getGenericSignatureOfContext()) {
1849+
if (sig->areAllParamsConcrete())
1850+
return nullptr;
1851+
return sig->getCanonicalSignature();
1852+
}
1853+
1854+
return nullptr;
1855+
}
1856+
18471857
CanGenericSignature
18481858
TypeConverter::getEffectiveGenericSignature(AnyFunctionRef fn,
18491859
CaptureInfo captureInfo) {
@@ -1853,13 +1863,7 @@ TypeConverter::getEffectiveGenericSignature(AnyFunctionRef fn,
18531863
!captureInfo.hasGenericParamCaptures())
18541864
return nullptr;
18551865

1856-
if (auto sig = dc->getGenericSignatureOfContext()) {
1857-
if (sig->areAllParamsConcrete())
1858-
return nullptr;
1859-
return sig->getCanonicalSignature();
1860-
}
1861-
1862-
return nullptr;
1866+
return getEffectiveGenericSignature(dc);
18631867
}
18641868

18651869
CanAnyFunctionType
@@ -1926,10 +1930,10 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) {
19261930

19271931
case SILDeclRef::Kind::Destroyer:
19281932
case SILDeclRef::Kind::Deallocator:
1929-
return getDestructorInterfaceType(cast<DestructorDecl>(vd),
1930-
c.kind == SILDeclRef::Kind::Deallocator,
1931-
Context,
1932-
c.isForeign);
1933+
return getDestructorInterfaceType(*this,
1934+
cast<DestructorDecl>(vd),
1935+
c.kind == SILDeclRef::Kind::Deallocator,
1936+
c.isForeign);
19331937

19341938
case SILDeclRef::Kind::GlobalAccessor: {
19351939
VarDecl *var = cast<VarDecl>(vd);
@@ -1946,17 +1950,18 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) {
19461950
case SILDeclRef::Kind::DefaultArgGenerator:
19471951
return getDefaultArgGeneratorInterfaceType(*this,
19481952
cast<AbstractFunctionDecl>(vd),
1949-
c.defaultArgIndex, Context);
1953+
c.defaultArgIndex);
19501954
case SILDeclRef::Kind::StoredPropertyInitializer:
19511955
return getStoredPropertyInitializerInterfaceType(*this,
1952-
cast<VarDecl>(vd),
1953-
Context);
1956+
cast<VarDecl>(vd));
19541957
case SILDeclRef::Kind::IVarInitializer:
1955-
return getIVarInitDestroyerInterfaceType(cast<ClassDecl>(vd),
1956-
c.isForeign, Context, false);
1958+
return getIVarInitDestroyerInterfaceType(*this,
1959+
cast<ClassDecl>(vd),
1960+
c.isForeign, false);
19571961
case SILDeclRef::Kind::IVarDestroyer:
1958-
return getIVarInitDestroyerInterfaceType(cast<ClassDecl>(vd),
1959-
c.isForeign, Context, true);
1962+
return getIVarInitDestroyerInterfaceType(*this,
1963+
cast<ClassDecl>(vd),
1964+
c.isForeign, true);
19601965
}
19611966

19621967
llvm_unreachable("Unhandled SILDeclRefKind in switch.");
@@ -2466,9 +2471,7 @@ TypeConverter::getInterfaceBoxTypeForCapture(ValueDecl *captured,
24662471
CanType loweredInterfaceType,
24672472
bool isMutable) {
24682473
auto &C = M.getASTContext();
2469-
CanGenericSignature signature;
2470-
if (auto sig = captured->getDeclContext()->getGenericSignatureOfContext())
2471-
signature = sig->getCanonicalSignature();
2474+
auto signature = getEffectiveGenericSignature(captured->getDeclContext());
24722475

24732476
// If the type is not dependent at all, we can form a concrete box layout.
24742477
// We don't need to capture the generic environment.

test/SILGen/constrained_extensions.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,38 @@ extension AnythingGoes where T : VeryConstrained {
188188
// CHECK: return
189189
init(fromExtension: ()) {}
190190
}
191+
192+
extension Array where Element == Int {
193+
struct Nested {
194+
// CHECK-LABEL: sil hidden [transparent] @_T0Sa22constrained_extensionsSiRszlE6NestedV1eSiSgvfi : $@convention(thin) () -> Optional<Int>
195+
var e: Element? = nil
196+
197+
// CHECK-LABEL: sil hidden @_T0Sa22constrained_extensionsSiRszlE6NestedV10hasDefaultySiSg1e_tFfA_ : $@convention(thin) () -> Optional<Int>
198+
// CHECK-LABEL: sil hidden @_T0Sa22constrained_extensionsSiRszlE6NestedV10hasDefaultySiSg1e_tF : $@convention(method) (Optional<Int>, @inout Array<Int>.Nested) -> ()
199+
mutating func hasDefault(e: Element? = nil) {
200+
self.e = e
201+
}
202+
}
203+
}
204+
205+
extension Array where Element == AnyObject {
206+
class NestedClass {
207+
// CHECK-LABEL: sil hidden @_T0Sa22constrained_extensionsyXlRszlE11NestedClassCfd : $@convention(method) (@guaranteed Array<AnyObject>.NestedClass) -> @owned Builtin.NativeObject
208+
// CHECK-LABEL: sil hidden @_T0Sa22constrained_extensionsyXlRszlE11NestedClassCfD : $@convention(method) (@owned Array<AnyObject>.NestedClass) -> ()
209+
deinit { }
210+
211+
// CHECK-LABEL: sil hidden @_T0Sa22constrained_extensionsyXlRszlE11NestedClassCACyyXl_GycfC : $@convention(method) (@thick Array<AnyObject>.NestedClass.Type) -> @owned Array<AnyObject>.NestedClass
212+
// CHECK-LABEL: sil hidden @_T0Sa22constrained_extensionsyXlRszlE11NestedClassCACyyXl_Gycfc : $@convention(method) (@owned Array<AnyObject>.NestedClass) -> @owned Array<AnyObject>.NestedClass
213+
}
214+
215+
class DerivedClass : NestedClass {
216+
// CHECK-LABEL: sil hidden [transparent] @_T0Sa22constrained_extensionsyXlRszlE12DerivedClassC1eyXlSgvfi : $@convention(thin) () -> @owned Optional<AnyObject>
217+
// CHECK-LABEL: sil hidden @_T0Sa22constrained_extensionsyXlRszlE12DerivedClassCfE : $@convention(method) (@guaranteed Array<AnyObject>.DerivedClass) -> ()
218+
var e: Element? = nil
219+
}
220+
}
221+
222+
func referenceNestedTypes() {
223+
_ = Array<AnyObject>.NestedClass()
224+
_ = Array<AnyObject>.DerivedClass()
225+
}

0 commit comments

Comments
 (0)