Skip to content

Commit 1cad5f9

Browse files
committed
SIL: Plumb pack element captures through type lowering
1 parent 70fb18e commit 1cad5f9

File tree

2 files changed

+82
-31
lines changed

2 files changed

+82
-31
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: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include "swift/AST/DiagnosticsSIL.h"
2222
#include "swift/AST/Expr.h"
2323
#include "swift/AST/GenericEnvironment.h"
24-
#include "swift/AST/LazyResolver.h"
24+
#include "swift/AST/LocalArchetypeRequirementCollector.h"
2525
#include "swift/AST/Module.h"
2626
#include "swift/AST/NameLookup.h"
2727
#include "swift/AST/ParameterList.h"
@@ -3622,20 +3622,37 @@ const TypeLowering *TypeConverter::getTypeLoweringForExpansion(
36223622
return nullptr;
36233623
}
36243624

3625-
static GenericSignature
3626-
getEffectiveGenericSignature(DeclContext *dc,
3627-
CaptureInfo captureInfo) {
3625+
static GenericSignatureWithCapturedEnvironments
3626+
getGenericSignatureWithCapturedEnvironments(DeclContext *dc,
3627+
CaptureInfo captureInfo) {
3628+
auto capturedEnvs = captureInfo.getGenericEnvironments();
3629+
3630+
// A closure or local function does not need a generic signature if it
3631+
// doesn't capture the primary generic environment or any pack element
3632+
// environments from the outer scope.
36283633
if (dc->getParent()->isLocalContext() &&
3634+
capturedEnvs.empty() &&
36293635
!captureInfo.hasGenericParamCaptures())
3630-
return nullptr;
3636+
return GenericSignatureWithCapturedEnvironments();
3637+
3638+
auto genericSig = dc->getGenericSignatureOfContext();
3639+
if (capturedEnvs.empty())
3640+
return GenericSignatureWithCapturedEnvironments(genericSig);
3641+
3642+
// Build a new generic signature where all captured element archetypes
3643+
// are represented by new generic parameters.
3644+
auto newSig = buildGenericSignatureWithCapturedEnvironments(
3645+
dc->getASTContext(), genericSig, capturedEnvs);
36313646

3632-
return dc->getGenericSignatureOfContext();
3647+
LLVM_DEBUG(llvm::dbgs() << "-- effective generic signature: " << newSig << "\n");
3648+
return GenericSignatureWithCapturedEnvironments(genericSig, newSig, capturedEnvs);
36333649
}
36343650

3635-
static GenericSignature
3636-
getEffectiveGenericSignature(AnyFunctionRef fn,
3637-
CaptureInfo captureInfo) {
3638-
return getEffectiveGenericSignature(fn.getAsDeclContext(), captureInfo);
3651+
static GenericSignatureWithCapturedEnvironments
3652+
getGenericSignatureWithCapturedEnvironments(AnyFunctionRef fn,
3653+
CaptureInfo captureInfo) {
3654+
return getGenericSignatureWithCapturedEnvironments(
3655+
fn.getAsDeclContext(), captureInfo);
36393656
}
36403657

36413658
static CanGenericSignature
@@ -3692,7 +3709,7 @@ static CanAnyFunctionType getDefaultArgGeneratorInterfaceType(
36923709
canResultTy = removeNoEscape(canResultTy);
36933710

36943711
// Get the generic signature from the surrounding context.
3695-
auto sig = TC.getConstantGenericSignature(c);
3712+
auto sig = TC.getGenericSignatureWithCapturedEnvironments(c).genericSig;
36963713

36973714
// FIXME: Verify ExtInfo state is correct, not working by accident.
36983715
CanAnyFunctionType::ExtInfo info;
@@ -3745,7 +3762,8 @@ static CanAnyFunctionType getPropertyWrapperBackingInitializerInterfaceType(
37453762
inputType = interfaceType->getCanonicalType();
37463763
}
37473764

3748-
GenericSignature sig = TC.getConstantGenericSignature(c);
3765+
GenericSignature sig = TC.getGenericSignatureWithCapturedEnvironments(c)
3766+
.genericSig;
37493767

37503768
AnyFunctionType::Param param(
37513769
inputType, Identifier(),
@@ -3831,7 +3849,16 @@ getAnyFunctionRefInterfaceType(TypeConverter &TC,
38313849

38323850
// Capture generic parameters from the enclosing context if necessary.
38333851
auto closure = *constant.getAnyFunctionRef();
3834-
auto genericSig = getEffectiveGenericSignature(closure, captureInfo);
3852+
auto sig = getGenericSignatureWithCapturedEnvironments(closure, captureInfo);
3853+
3854+
if (funcType->hasArchetype()) {
3855+
assert(isa<FunctionType>(funcType));
3856+
auto substType = Type(funcType).subst(
3857+
MapLocalArchetypesOutOfContext(sig.baseGenericSig, sig.capturedEnvs),
3858+
MakeAbstractConformanceForGenericType(),
3859+
SubstFlags::PreservePackExpansionLevel);
3860+
funcType = cast<FunctionType>(substType->getCanonicalType());
3861+
}
38353862

38363863
auto innerExtInfo =
38373864
AnyFunctionType::ExtInfoBuilder(FunctionType::Representation::Thin,
@@ -3845,7 +3872,7 @@ getAnyFunctionRefInterfaceType(TypeConverter &TC,
38453872
.build();
38463873

38473874
return CanAnyFunctionType::get(
3848-
getCanonicalSignatureOrNull(genericSig),
3875+
getCanonicalSignatureOrNull(sig.genericSig),
38493876
funcType.getParams(), funcType.getResult(),
38503877
innerExtInfo);
38513878
}
@@ -3931,12 +3958,9 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) {
39313958
case SILDeclRef::Kind::Func: {
39323959
CanAnyFunctionType funcTy;
39333960
if (auto *ACE = c.loc.dyn_cast<AbstractClosureExpr *>()) {
3934-
// FIXME: Closures could have an interface type computed by Sema.
3935-
funcTy = cast<AnyFunctionType>(
3936-
ACE->getType()->mapTypeOutOfContext()->getCanonicalType());
3961+
funcTy = cast<AnyFunctionType>(ACE->getType()->getCanonicalType());
39373962
} else {
3938-
funcTy = cast<AnyFunctionType>(
3939-
vd->getInterfaceType()->getCanonicalType());
3963+
funcTy = cast<AnyFunctionType>(vd->getInterfaceType()->getCanonicalType());
39403964
}
39413965
return getAnyFunctionRefInterfaceType(*this, funcTy, c);
39423966
}
@@ -3999,10 +4023,10 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) {
39994023
llvm_unreachable("Unhandled SILDeclRefKind in switch.");
40004024
}
40014025

4002-
GenericSignature
4003-
TypeConverter::getConstantGenericSignature(SILDeclRef c) {
4026+
GenericSignatureWithCapturedEnvironments
4027+
TypeConverter::getGenericSignatureWithCapturedEnvironments(SILDeclRef c) {
40044028
auto *vd = c.loc.dyn_cast<ValueDecl *>();
4005-
4029+
40064030
/// Get the function generic params, including outer params.
40074031
switch (c.kind) {
40084032
case SILDeclRef::Kind::Func:
@@ -4011,16 +4035,17 @@ TypeConverter::getConstantGenericSignature(SILDeclRef c) {
40114035
case SILDeclRef::Kind::Destroyer:
40124036
case SILDeclRef::Kind::Deallocator: {
40134037
auto captureInfo = getLoweredLocalCaptures(c);
4014-
return getEffectiveGenericSignature(
4038+
return ::getGenericSignatureWithCapturedEnvironments(
40154039
*c.getAnyFunctionRef(), captureInfo);
40164040
}
40174041
case SILDeclRef::Kind::IVarInitializer:
40184042
case SILDeclRef::Kind::IVarDestroyer:
4019-
return cast<ClassDecl>(vd)->getGenericSignature();
4043+
return GenericSignatureWithCapturedEnvironments(
4044+
cast<ClassDecl>(vd)->getGenericSignature());
40204045
case SILDeclRef::Kind::DefaultArgGenerator: {
40214046
// Use the generic environment of the original function.
40224047
auto captureInfo = getLoweredLocalCaptures(c);
4023-
return getEffectiveGenericSignature(
4048+
return ::getGenericSignatureWithCapturedEnvironments(
40244049
vd->getInnermostDeclContext(), captureInfo);
40254050
}
40264051
case SILDeclRef::Kind::PropertyWrapperBackingInitializer:
@@ -4037,14 +4062,16 @@ TypeConverter::getConstantGenericSignature(SILDeclRef c) {
40374062
} else {
40384063
enclosingDecl = SILDeclRef(cast<AbstractFunctionDecl>(dc));
40394064
}
4040-
return getConstantGenericSignature(enclosingDecl);
4065+
return getGenericSignatureWithCapturedEnvironments(enclosingDecl);
40414066
}
4042-
return dc->getGenericSignatureOfContext();
4067+
return GenericSignatureWithCapturedEnvironments(
4068+
dc->getGenericSignatureOfContext());
40434069
}
40444070
case SILDeclRef::Kind::EnumElement:
40454071
case SILDeclRef::Kind::GlobalAccessor:
40464072
case SILDeclRef::Kind::StoredPropertyInitializer:
4047-
return vd->getDeclContext()->getGenericSignatureOfContext();
4073+
return GenericSignatureWithCapturedEnvironments(
4074+
vd->getDeclContext()->getGenericSignatureOfContext());
40484075
case SILDeclRef::Kind::EntryPoint:
40494076
case SILDeclRef::Kind::AsyncEntryPoint:
40504077
llvm_unreachable("Doesn't have generic signature");
@@ -4055,7 +4082,8 @@ TypeConverter::getConstantGenericSignature(SILDeclRef c) {
40554082

40564083
GenericEnvironment *
40574084
TypeConverter::getConstantGenericEnvironment(SILDeclRef c) {
4058-
return getConstantGenericSignature(c).getGenericEnvironment();
4085+
return getGenericSignatureWithCapturedEnvironments(c)
4086+
.genericSig.getGenericEnvironment();
40594087
}
40604088

40614089
SILType TypeConverter::getSubstitutedStorageType(TypeExpansionContext context,

0 commit comments

Comments
 (0)