mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Sema: Better support for nested generic functions
There was a weird corner case with nested generic functions that would fail in the SIL verifier with some nonsense about archetypes out of context. Fix this the "right" way, by re-working Sema function declaration validation to assign generic signatures in a more principled way. Previously, nested functions did not get an interface type unless they themselves had generic parameters. This was inconsistent with methods nested inside generic types, which did get an interface type even if they themselves did not have a generic parameter list. There's some spill-over in SILGen from this change. Mostly it makes things more consistent and fixes some corner cases.
This commit is contained in:
@@ -337,6 +337,7 @@ SILGenFunction::emitClosureValue(SILLocation loc, SILDeclRef constant,
|
||||
ArrayRef<Substitution> subs) {
|
||||
auto closure = *constant.getAnyFunctionRef();
|
||||
auto captureInfo = closure.getCaptureInfo();
|
||||
auto loweredCaptureInfo = SGM.Types.getLoweredLocalCaptures(closure);
|
||||
|
||||
assert(((constant.uncurryLevel == 1 &&
|
||||
captureInfo.hasLocalCaptures()) ||
|
||||
@@ -351,17 +352,21 @@ SILGenFunction::emitClosureValue(SILLocation loc, SILDeclRef constant,
|
||||
// Apply substitutions.
|
||||
auto pft = constantInfo.SILFnType;
|
||||
|
||||
auto *dc = closure.getAsDeclContext()->getParent();
|
||||
if (dc->isLocalContext() && !loweredCaptureInfo.hasGenericParamCaptures()) {
|
||||
// If the lowered function type is not polymorphic but we were given
|
||||
// substitutions, we have a closure in a generic context which does not
|
||||
// capture generic parameters. Just drop the substitutions.
|
||||
subs = { };
|
||||
} else if (closure.getAbstractClosureExpr()) {
|
||||
// If we have a closure expression in generic context, Sema won't give
|
||||
// us substitutions, so we just use the forwarding substitutions from
|
||||
// context.
|
||||
subs = getForwardingSubstitutions();
|
||||
}
|
||||
|
||||
bool wasSpecialized = false;
|
||||
if (pft->isPolymorphic()) {
|
||||
// If the lowered function type is generic but Sema did not hand us any
|
||||
// substitutions, the function is a local function that appears in a
|
||||
// generic context but does not have a generic parameter list of its own;
|
||||
// just use our forwarding substitutions.
|
||||
if (subs.empty()) {
|
||||
assert(closure.getAsDeclContext()->isLocalContext() &&
|
||||
"cannot reference generic global function without substitutions");
|
||||
subs = getForwardingSubstitutions();
|
||||
}
|
||||
if (!subs.empty()) {
|
||||
auto specialized = pft->substGenericArgs(F.getModule(),
|
||||
F.getModule().getSwiftModule(),
|
||||
subs);
|
||||
|
||||
Reference in New Issue
Block a user