Skip to content

Commit 413d94b

Browse files
committed
SIL: Plumb pack element captures through type lowering
1 parent 5db9e4d commit 413d94b

File tree

2 files changed

+83
-32
lines changed

2 files changed

+83
-32
lines changed

include/swift/SIL/TypeLowering.h

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,28 @@ struct FunctionTypeInfo {
704704
CanSILFunctionType ExpectedLoweredType;
705705
};
706706

707+
/// Return type of getGenericSignatureWithCapturedEnvironments().
708+
struct GenericSignatureWithCapturedEnvironments {
709+
GenericSignature baseGenericSig;
710+
GenericSignature genericSig;
711+
ArrayRef<GenericEnvironment *> capturedEnvs;
712+
713+
explicit GenericSignatureWithCapturedEnvironments() {}
714+
715+
explicit GenericSignatureWithCapturedEnvironments(
716+
GenericSignature baseGenericSig)
717+
: baseGenericSig(baseGenericSig),
718+
genericSig(baseGenericSig) {}
719+
720+
GenericSignatureWithCapturedEnvironments(
721+
GenericSignature baseGenericSig,
722+
GenericSignature genericSig,
723+
ArrayRef<GenericEnvironment *> capturedEnvs)
724+
: baseGenericSig(baseGenericSig),
725+
genericSig(genericSig),
726+
capturedEnvs(capturedEnvs) {}
727+
};
728+
707729
/// TypeConverter - helper class for creating and managing TypeLowerings.
708730
class TypeConverter {
709731
friend class TypeLowering;
@@ -1047,8 +1069,9 @@ class TypeConverter {
10471069
const SILConstantInfo &getConstantInfo(TypeExpansionContext context,
10481070
SILDeclRef constant);
10491071

1050-
/// Get the generic environment for a constant.
1051-
GenericSignature getConstantGenericSignature(SILDeclRef constant);
1072+
/// Get the generic signature for a constant.
1073+
GenericSignatureWithCapturedEnvironments
1074+
getGenericSignatureWithCapturedEnvironments(SILDeclRef constant);
10521075

10531076
/// Get the generic environment for a constant.
10541077
GenericEnvironment *getConstantGenericEnvironment(SILDeclRef constant);

lib/SIL/IR/TypeLowering.cpp

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include "swift/AST/Expr.h"
2323
#include "swift/AST/FileUnit.h"
2424
#include "swift/AST/GenericEnvironment.h"
25-
#include "swift/AST/LazyResolver.h"
25+
#include "swift/AST/LocalArchetypeRequirementCollector.h"
2626
#include "swift/AST/Module.h"
2727
#include "swift/AST/NameLookup.h"
2828
#include "swift/AST/ParameterList.h"
@@ -3634,20 +3634,37 @@ const TypeLowering *TypeConverter::getTypeLoweringForExpansion(
36343634
return nullptr;
36353635
}
36363636

3637-
static GenericSignature
3638-
getEffectiveGenericSignature(DeclContext *dc,
3639-
CaptureInfo captureInfo) {
3637+
static GenericSignatureWithCapturedEnvironments
3638+
getGenericSignatureWithCapturedEnvironments(DeclContext *dc,
3639+
CaptureInfo captureInfo) {
3640+
auto capturedEnvs = captureInfo.getGenericEnvironments();
3641+
3642+
// A closure or local function does not need a generic signature if it
3643+
// doesn't capture the primary generic environment or any pack element
3644+
// environments from the outer scope.
36403645
if (dc->getParent()->isLocalContext() &&
3646+
capturedEnvs.empty() &&
36413647
!captureInfo.hasGenericParamCaptures())
3642-
return nullptr;
3648+
return GenericSignatureWithCapturedEnvironments();
3649+
3650+
auto genericSig = dc->getGenericSignatureOfContext();
3651+
if (capturedEnvs.empty())
3652+
return GenericSignatureWithCapturedEnvironments(genericSig);
3653+
3654+
// Build a new generic signature where all captured element archetypes
3655+
// are represented by new generic parameters.
3656+
auto newSig = buildGenericSignatureWithCapturedEnvironments(
3657+
dc->getASTContext(), genericSig, capturedEnvs);
36433658

3644-
return dc->getGenericSignatureOfContext();
3659+
LLVM_DEBUG(llvm::dbgs() << "-- effective generic signature: " << newSig << "\n");
3660+
return GenericSignatureWithCapturedEnvironments(genericSig, newSig, capturedEnvs);
36453661
}
36463662

3647-
static GenericSignature
3648-
getEffectiveGenericSignature(AnyFunctionRef fn,
3649-
CaptureInfo captureInfo) {
3650-
return getEffectiveGenericSignature(fn.getAsDeclContext(), captureInfo);
3663+
static GenericSignatureWithCapturedEnvironments
3664+
getGenericSignatureWithCapturedEnvironments(AnyFunctionRef fn,
3665+
CaptureInfo captureInfo) {
3666+
return getGenericSignatureWithCapturedEnvironments(
3667+
fn.getAsDeclContext(), captureInfo);
36513668
}
36523669

36533670
static CanGenericSignature
@@ -3704,7 +3721,7 @@ static CanAnyFunctionType getDefaultArgGeneratorInterfaceType(
37043721
canResultTy = removeNoEscape(canResultTy);
37053722

37063723
// Get the generic signature from the surrounding context.
3707-
auto sig = TC.getConstantGenericSignature(c);
3724+
auto sig = TC.getGenericSignatureWithCapturedEnvironments(c).genericSig;
37083725

37093726
// FIXME: Verify ExtInfo state is correct, not working by accident.
37103727
CanAnyFunctionType::ExtInfo info;
@@ -3757,7 +3774,8 @@ static CanAnyFunctionType getPropertyWrapperBackingInitializerInterfaceType(
37573774
inputType = interfaceType->getCanonicalType();
37583775
}
37593776

3760-
GenericSignature sig = TC.getConstantGenericSignature(c);
3777+
GenericSignature sig = TC.getGenericSignatureWithCapturedEnvironments(c)
3778+
.genericSig;
37613779

37623780
AnyFunctionType::Param param(
37633781
inputType, Identifier(),
@@ -3839,7 +3857,16 @@ getFunctionInterfaceTypeWithCaptures(TypeConverter &TC,
38393857

38403858
// Capture generic parameters from the enclosing context if necessary.
38413859
auto closure = *constant.getAnyFunctionRef();
3842-
auto genericSig = getEffectiveGenericSignature(closure, captureInfo);
3860+
auto sig = getGenericSignatureWithCapturedEnvironments(closure, captureInfo);
3861+
3862+
if (funcType->hasArchetype()) {
3863+
assert(isa<FunctionType>(funcType));
3864+
auto substType = Type(funcType).subst(
3865+
MapLocalArchetypesOutOfContext(sig.baseGenericSig, sig.capturedEnvs),
3866+
MakeAbstractConformanceForGenericType(),
3867+
SubstFlags::PreservePackExpansionLevel);
3868+
funcType = cast<FunctionType>(substType->getCanonicalType());
3869+
}
38433870

38443871
auto innerExtInfo =
38453872
AnyFunctionType::ExtInfoBuilder(FunctionType::Representation::Thin,
@@ -3853,7 +3880,7 @@ getFunctionInterfaceTypeWithCaptures(TypeConverter &TC,
38533880
.build();
38543881

38553882
return CanAnyFunctionType::get(
3856-
getCanonicalSignatureOrNull(genericSig),
3883+
getCanonicalSignatureOrNull(sig.genericSig),
38573884
funcType.getParams(), funcType.getResult(),
38583885
innerExtInfo);
38593886
}
@@ -3939,12 +3966,9 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) {
39393966
case SILDeclRef::Kind::Func: {
39403967
CanAnyFunctionType funcTy;
39413968
if (auto *ACE = c.loc.dyn_cast<AbstractClosureExpr *>()) {
3942-
// FIXME: Closures could have an interface type computed by Sema.
3943-
funcTy = cast<AnyFunctionType>(
3944-
ACE->getType()->mapTypeOutOfContext()->getCanonicalType());
3969+
funcTy = cast<AnyFunctionType>(ACE->getType()->getCanonicalType());
39453970
} else {
3946-
funcTy = cast<AnyFunctionType>(
3947-
vd->getInterfaceType()->getCanonicalType());
3971+
funcTy = cast<AnyFunctionType>(vd->getInterfaceType()->getCanonicalType());
39483972
}
39493973
return getFunctionInterfaceTypeWithCaptures(*this, funcTy, c);
39503974
}
@@ -4007,10 +4031,10 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) {
40074031
llvm_unreachable("Unhandled SILDeclRefKind in switch.");
40084032
}
40094033

4010-
GenericSignature
4011-
TypeConverter::getConstantGenericSignature(SILDeclRef c) {
4034+
GenericSignatureWithCapturedEnvironments
4035+
TypeConverter::getGenericSignatureWithCapturedEnvironments(SILDeclRef c) {
40124036
auto *vd = c.loc.dyn_cast<ValueDecl *>();
4013-
4037+
40144038
/// Get the function generic params, including outer params.
40154039
switch (c.kind) {
40164040
case SILDeclRef::Kind::Func:
@@ -4019,16 +4043,17 @@ TypeConverter::getConstantGenericSignature(SILDeclRef c) {
40194043
case SILDeclRef::Kind::Destroyer:
40204044
case SILDeclRef::Kind::Deallocator: {
40214045
auto captureInfo = getLoweredLocalCaptures(c);
4022-
return getEffectiveGenericSignature(
4046+
return ::getGenericSignatureWithCapturedEnvironments(
40234047
*c.getAnyFunctionRef(), captureInfo);
40244048
}
40254049
case SILDeclRef::Kind::IVarInitializer:
40264050
case SILDeclRef::Kind::IVarDestroyer:
4027-
return cast<ClassDecl>(vd)->getGenericSignature();
4051+
return GenericSignatureWithCapturedEnvironments(
4052+
cast<ClassDecl>(vd)->getGenericSignature());
40284053
case SILDeclRef::Kind::DefaultArgGenerator: {
40294054
// Use the generic environment of the original function.
40304055
auto captureInfo = getLoweredLocalCaptures(c);
4031-
return getEffectiveGenericSignature(
4056+
return ::getGenericSignatureWithCapturedEnvironments(
40324057
vd->getInnermostDeclContext(), captureInfo);
40334058
}
40344059
case SILDeclRef::Kind::PropertyWrapperBackingInitializer:
@@ -4045,25 +4070,28 @@ TypeConverter::getConstantGenericSignature(SILDeclRef c) {
40454070
} else {
40464071
enclosingDecl = SILDeclRef(cast<AbstractFunctionDecl>(dc));
40474072
}
4048-
return getConstantGenericSignature(enclosingDecl);
4073+
return getGenericSignatureWithCapturedEnvironments(enclosingDecl);
40494074
}
4050-
return dc->getGenericSignatureOfContext();
4075+
return GenericSignatureWithCapturedEnvironments(
4076+
dc->getGenericSignatureOfContext());
40514077
}
40524078
case SILDeclRef::Kind::EnumElement:
40534079
case SILDeclRef::Kind::GlobalAccessor:
40544080
case SILDeclRef::Kind::StoredPropertyInitializer:
4055-
return vd->getDeclContext()->getGenericSignatureOfContext();
4081+
return GenericSignatureWithCapturedEnvironments(
4082+
vd->getDeclContext()->getGenericSignatureOfContext());
40564083
case SILDeclRef::Kind::EntryPoint:
40574084
case SILDeclRef::Kind::AsyncEntryPoint:
4058-
llvm_unreachable("Doesn't have generic signature");
4085+
return GenericSignatureWithCapturedEnvironments();
40594086
}
40604087

40614088
llvm_unreachable("Unhandled SILDeclRefKind in switch.");
40624089
}
40634090

40644091
GenericEnvironment *
40654092
TypeConverter::getConstantGenericEnvironment(SILDeclRef c) {
4066-
return getConstantGenericSignature(c).getGenericEnvironment();
4093+
return getGenericSignatureWithCapturedEnvironments(c)
4094+
.genericSig.getGenericEnvironment();
40674095
}
40684096

40694097
SILType TypeConverter::getSubstitutedStorageType(TypeExpansionContext context,

0 commit comments

Comments
 (0)