Skip to content

Commit f46585d

Browse files
authored
Merge pull request #9860 from slavapestov/more-fun-with-constrained-extensions
SILGen: Fix issues with types nested inside fully-concrete extensions
2 parents 6e4c8ba + 9c7afa7 commit f46585d

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)