From c3a1c7fddd9fd9b9cdfc93a250f555d9c04b3cb1 Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Mon, 14 Sep 2020 12:53:28 -0700 Subject: [PATCH] SILGen: Relax assertion that incorrectly tripped on lowered opaque capture types. When lowering the SILConstantInfo for a closure implementation type with captures, we are more conservative about substituting opaque types in the capture, since the underlying types may only be available in the local context. This means the SILConstantInfo type may not in fact be exactly what you get from `SILFunction::getFunctionTypeInContext` referencing the implementation function from its originating context, since those opaque types will be substituted in the local context. Fixes SR-13480 | rdar://problem/68159831. --- lib/SILGen/SILGenThunk.cpp | 10 ++++++++-- .../serialized-capture-opaque-type-subst.swift | 12 ++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 test/SILGen/serialized-capture-opaque-type-subst.swift diff --git a/lib/SILGen/SILGenThunk.cpp b/lib/SILGen/SILGenThunk.cpp index c8fce513fa347..5fa0804c08f7c 100644 --- a/lib/SILGen/SILGenThunk.cpp +++ b/lib/SILGen/SILGenThunk.cpp @@ -144,8 +144,14 @@ SILGenFunction::emitGlobalFunctionRef(SILLocation loc, SILDeclRef constant, } auto f = SGM.getFunction(constant, NotForDefinition); - assert(f->getLoweredFunctionTypeInContext(B.getTypeExpansionContext()) == - constantInfo.SILFnType); +#ifndef NDEBUG + auto constantFnTypeInContext = + SGM.Types.getLoweredType(constantInfo.SILFnType, + B.getTypeExpansionContext()) + .castTo(); + assert(f->getLoweredFunctionTypeInContext(B.getTypeExpansionContext()) + == constantFnTypeInContext); +#endif if (callPreviousDynamicReplaceableImpl) return B.createPreviousDynamicFunctionRef(loc, f); else diff --git a/test/SILGen/serialized-capture-opaque-type-subst.swift b/test/SILGen/serialized-capture-opaque-type-subst.swift new file mode 100644 index 0000000000000..e355155ff46fb --- /dev/null +++ b/test/SILGen/serialized-capture-opaque-type-subst.swift @@ -0,0 +1,12 @@ +// RUN: %target-swift-frontend -disable-availability-checking -emit-silgen -verify %s + +public func foo() -> some Any { return 1 } + +public struct XY { public init(x: X, y: Y) { fatalError() } } + +@inlinable +public func bar() -> () -> Any { + let xy = XY(x: 1, y: foo()) + + return { xy } +}