Skip to content

Commit 938dbf4

Browse files
author
ematejska
authored
Merge pull request #7236 from jckarter/capture-canonicalization-context-3.1
[3.1] SIL: Canonicalize capture types with the AST function's generic signature.
2 parents 0502fb8 + 6f4e65a commit 938dbf4

File tree

5 files changed

+51
-6
lines changed

5 files changed

+51
-6
lines changed

include/swift/AST/AnyFunctionRef.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,16 @@ class AnyFunctionRef {
176176
}
177177
llvm_unreachable("unexpected AnyFunctionRef representation");
178178
}
179+
180+
GenericSignature *getGenericSignature() const {
181+
if (auto afd = TheFunction.dyn_cast<AbstractFunctionDecl *>()) {
182+
return afd->getGenericSignature();
183+
}
184+
if (auto ce = TheFunction.dyn_cast<AbstractClosureExpr *>()) {
185+
return ce->getGenericSignatureOfContext();
186+
}
187+
llvm_unreachable("unexpected AnyFunctionRef representation");
188+
}
179189
};
180190
#if SWIFT_COMPILER_IS_MSVC
181191
#pragma warning(pop)

lib/SIL/SILFunctionType.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/AST/Decl.h"
2424
#include "swift/AST/DiagnosticsSIL.h"
2525
#include "swift/AST/ForeignErrorConvention.h"
26+
#include "swift/AST/GenericEnvironment.h"
2627
#include "swift/Basic/Fallthrough.h"
2728
#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
2829
#include "clang/AST/Attr.h"
@@ -742,9 +743,17 @@ static CanSILFunctionType getSILFunctionType(SILModule &M,
742743
// from the function to which the argument is attached.
743744
if (constant && !constant->isDefaultArgGenerator())
744745
if (auto function = constant->getAnyFunctionRef()) {
745-
auto getCanonicalType = [&](Type t) -> CanType {
746-
if (genericSig)
747-
return genericSig->getCanonicalTypeInContext(t, *M.getSwiftModule());
746+
// NB: The generic signature may be elided from the lowered function type
747+
// if the function is in a fully-specialized context, but we still need to
748+
// canonicalize references to the generic parameters that may appear in
749+
// non-canonical types in that context. We need the original generic
750+
// signature from the AST for that.
751+
auto origGenericSig
752+
= function->getGenericSignature();
753+
auto getCanonicalType = [origGenericSig, &M](Type t) -> CanType {
754+
if (origGenericSig)
755+
return origGenericSig->getCanonicalTypeInContext(t,
756+
*M.getSwiftModule());
748757
return t->getCanonicalType();
749758
};
750759

lib/SIL/SILInstructions.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,11 @@ ApplyInst *ApplyInst::create(SILDebugLocation Loc, SILValue Callee,
408408
ArrayRef<SILValue> Args, bool isNonThrowing,
409409
SILFunction &F,
410410
SILOpenedArchetypesState &OpenedArchetypes) {
411+
if (!F.getModule().Types.getCurGenericContext())
412+
assert(Callee->getType().castTo<SILFunctionType>()
413+
->substGenericArgs(F.getModule(), Subs)
414+
== SubstCalleeTy.getSwiftRValueType());
415+
411416
SmallVector<SILValue, 32> TypeDependentOperands;
412417
collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, F,
413418
SubstCalleeTy.getSwiftRValueType(), Subs);

lib/SILGen/SILGenProlog.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,9 @@ void SILGenFunction::bindParametersForForwarding(const ParameterList *params,
344344
}
345345
}
346346

347-
static void emitCaptureArguments(SILGenFunction &gen, CapturedValue capture,
347+
static void emitCaptureArguments(SILGenFunction &gen,
348+
AnyFunctionRef closure,
349+
CapturedValue capture,
348350
unsigned ArgNo) {
349351

350352
auto *VD = capture.getDecl();
@@ -357,7 +359,12 @@ static void emitCaptureArguments(SILGenFunction &gen, CapturedValue capture,
357359
auto interfaceType = cast<VarDecl>(VD)->getInterfaceType();
358360
if (!interfaceType->hasTypeParameter()) return interfaceType;
359361

360-
auto genericEnv = gen.F.getGenericEnvironment();
362+
// NB: The generic signature may be elided from the lowered function type
363+
// if the function is in a fully-specialized context, but we still need to
364+
// canonicalize references to the generic parameters that may appear in
365+
// non-canonical types in that context. We need the original generic
366+
// environment from the AST for that.
367+
auto genericEnv = closure.getGenericEnvironment();
361368
return genericEnv->mapTypeIntoContext(gen.F.getModule().getSwiftModule(),
362369
interfaceType);
363370
};
@@ -446,7 +453,7 @@ void SILGenFunction::emitProlog(AnyFunctionRef TheClosure,
446453
return;
447454
}
448455

449-
emitCaptureArguments(*this, capture, ++ArgNo);
456+
emitCaptureArguments(*this, TheClosure, capture, ++ArgNo);
450457
}
451458
}
452459

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
2+
3+
struct Foo<T> {}
4+
struct Bar {}
5+
6+
extension Foo where T == Bar {
7+
func foo(x: T) -> Bar {
8+
// CHECK-LABEL: sil shared @{{.*}}3foo{{.*}}4foo2{{.*}} : $@convention(thin) (Bar) -> Bar
9+
func foo2() -> Bar {
10+
return x
11+
}
12+
return foo2()
13+
}
14+
}

0 commit comments

Comments
 (0)