Skip to content

Commit 625436a

Browse files
authored
Merge pull request #73393 from slavapestov/pack-expansion-closures-part-3
SIL type lowering support for closures that capture pack element archetypes
2 parents a5fdf15 + af0f17e commit 625436a

File tree

7 files changed

+179
-69
lines changed

7 files changed

+179
-69
lines changed

include/swift/SIL/SILFunction.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1276,8 +1276,10 @@ class SILFunction
12761276
GenericEnvironment *getGenericEnvironment() const {
12771277
return GenericEnv;
12781278
}
1279-
void setGenericEnvironment(GenericEnvironment *env) {
1279+
void setGenericEnvironment(GenericEnvironment *env,
1280+
SubstitutionMap forwardingSubs=SubstitutionMap()) {
12801281
GenericEnv = env;
1282+
ForwardingSubMap = forwardingSubs;
12811283
}
12821284

12831285
/// Retrieve the generic signature from the generic environment of this

include/swift/SIL/TypeLowering.h

Lines changed: 32 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,12 +1069,20 @@ 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);
10551078

1079+
/// Get the generic environment for SILGen to use. The substitution map
1080+
/// sends the generic parameters of the function's interface type into
1081+
/// archetypes, which will either be primary archetypes from this
1082+
/// environment, or local archetypes captured by this function.
1083+
std::pair<GenericEnvironment *, SubstitutionMap>
1084+
getForwardingSubstitutionsForLowering(SILDeclRef constant);
1085+
10561086
/// Returns the SIL type of a constant reference.
10571087
SILType getConstantType(TypeExpansionContext context, SILDeclRef constant) {
10581088
return getConstantInfo(context, constant).getSILType();

lib/AST/RequirementMachine/GenericSignatureQueries.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,9 @@ Type RequirementMachine::getReducedType(
419419

420420
// Get a type (concrete or dependent) for U.
421421
auto prefixType = [&]() -> Type {
422+
if (prefix.empty())
423+
return Type();
424+
422425
verify(prefix);
423426

424427
auto *props = Map.lookUpProperties(prefix);
@@ -461,13 +464,25 @@ Type RequirementMachine::getReducedType(
461464

462465
// If U is not concrete, we have an invalid member type of a dependent
463466
// type, which is not valid in this generic signature. Give up.
464-
if (prefixType->isTypeParameter()) {
465-
llvm::errs() << "Invalid type parameter in getReducedType()\n";
466-
llvm::errs() << "Original type: " << type << "\n";
467-
llvm::errs() << "Simplified term: " << term << "\n";
468-
llvm::errs() << "Longest valid prefix: " << prefix << "\n";
469-
llvm::errs() << "Prefix type: " << prefixType << "\n";
467+
if (prefix.empty() || prefixType->isTypeParameter()) {
470468
llvm::errs() << "\n";
469+
llvm::errs() << "getReducedType() was called\n";
470+
llvm::errs() << " with " << Sig << ",\n";
471+
llvm::errs() << " and " << type << ".\n\n";
472+
llvm::errs() << "This type contains the type parameter " << t << ".\n\n";
473+
if (prefix.empty()) {
474+
llvm::errs() << "This type parameter contains the generic parameter "
475+
<< Type(t->getRootGenericParam()) << ".\n\n";
476+
llvm::errs() << "This generic parameter is not part of the given "
477+
<< "generic signature.\n\n";
478+
} else {
479+
llvm::errs() << "This type parameter's reduced term is " << term << ".\n\n";
480+
llvm::errs() << "This is not a valid term, because " << prefix << " does not "
481+
<< "have a member type named " << term[prefix.size()] << ".\n\n";
482+
}
483+
llvm::errs() << "This usually indicates the caller passed the wrong type or "
484+
<< "generic signature to getReducedType().\n\n";
485+
471486
dump(llvm::errs());
472487
abort();
473488
}

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1934,11 +1934,7 @@ void updateResultTypeForForeignInfo(
19341934
llvm_unreachable("unhandled kind");
19351935
}
19361936

1937-
/// Lower any/all capture context parameters.
1938-
///
1939-
/// *NOTE* Currently default arg generators can not capture anything.
1940-
/// If we ever add that ability, it will be a different capture list
1941-
/// from the function to which the argument is attached.
1937+
/// Captured values become SIL function parameters in this function.
19421938
static void
19431939
lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function,
19441940
CanGenericSignature genericSig,
@@ -1962,28 +1958,38 @@ lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function,
19621958
// signature from the AST for that.
19631959
auto origGenericSig = function.getAnyFunctionRef()->getGenericSignature();
19641960
auto loweredCaptures = TC.getLoweredLocalCaptures(function);
1961+
auto capturedEnvs = loweredCaptures.getGenericEnvironments();
19651962
auto *isolatedParam = loweredCaptures.getIsolatedParamCapture();
19661963

1964+
auto mapTypeOutOfContext = [&](Type t) -> CanType {
1965+
LLVM_DEBUG(llvm::dbgs() << "-- capture with contextual type " << t << "\n");
1966+
1967+
t = t.subst(MapLocalArchetypesOutOfContext(origGenericSig, capturedEnvs),
1968+
MakeAbstractConformanceForGenericType(),
1969+
SubstFlags::PreservePackExpansionLevel);
1970+
1971+
LLVM_DEBUG(llvm::dbgs() << "-- maps to " << t->getCanonicalType() << "\n");
1972+
return t->getCanonicalType();
1973+
};
1974+
19671975
for (auto capture : loweredCaptures.getCaptures()) {
19681976
if (capture.isDynamicSelfMetadata()) {
19691977
ParameterConvention convention = ParameterConvention::Direct_Unowned;
19701978
auto dynamicSelfInterfaceType =
1971-
loweredCaptures.getDynamicSelfType()->mapTypeOutOfContext();
1979+
mapTypeOutOfContext(loweredCaptures.getDynamicSelfType());
19721980

1973-
auto selfMetatype = MetatypeType::get(dynamicSelfInterfaceType,
1974-
MetatypeRepresentation::Thick);
1981+
auto selfMetatype = CanMetatypeType::get(dynamicSelfInterfaceType,
1982+
MetatypeRepresentation::Thick);
19751983

1976-
auto canSelfMetatype = selfMetatype->getReducedType(origGenericSig);
1977-
SILParameterInfo param(canSelfMetatype, convention);
1984+
SILParameterInfo param(selfMetatype, convention);
19781985
inputs.push_back(param);
19791986

19801987
continue;
19811988
}
19821989

19831990
if (capture.isOpaqueValue()) {
19841991
OpaqueValueExpr *opaqueValue = capture.getOpaqueValue();
1985-
auto canType = opaqueValue->getType()->mapTypeOutOfContext()
1986-
->getReducedType(origGenericSig);
1992+
auto canType = mapTypeOutOfContext(opaqueValue->getType());
19871993
auto &loweredTL =
19881994
TC.getTypeLowering(AbstractionPattern(genericSig, canType),
19891995
canType, expansion);
@@ -2001,9 +2007,16 @@ lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function,
20012007
continue;
20022008
}
20032009

2004-
auto *varDecl = capture.getDecl();
2005-
auto type = varDecl->getInterfaceType();
2006-
auto canType = type->getReducedType(origGenericSig);
2010+
auto *varDecl = cast<VarDecl>(capture.getDecl());
2011+
2012+
auto type = varDecl->getTypeInContext();
2013+
assert(!type->hasLocalArchetype() ||
2014+
(genericSig && origGenericSig &&
2015+
!genericSig->isEqual(origGenericSig)));
2016+
type = mapTypeOutOfContext(type);
2017+
2018+
auto canType = type->getReducedType(
2019+
genericSig ? genericSig : origGenericSig);
20072020

20082021
auto options = SILParameterInfo::Options();
20092022
if (isolatedParam == varDecl) {

0 commit comments

Comments
 (0)