Skip to content

Commit a7f6e3d

Browse files
committed
OpaqueArchetypeSpecializer: inlinable functions are now in this module
...not the one they came from. This is important when specializing an inlinable function that takes an opaque type as a generic argument: that opaque type should still be considered opaque even if it came from the same module as the inlinable function. rdar://problem/56410009
1 parent b08014a commit a7f6e3d

File tree

5 files changed

+81
-22
lines changed

5 files changed

+81
-22
lines changed

lib/AST/Type.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2653,8 +2653,14 @@ substOpaqueTypesWithUnderlyingTypes(Type ty, DeclContext *inContext,
26532653
return ty.subst(replacer, replacer, SubstFlags::SubstituteOpaqueArchetypes);
26542654
}
26552655

2656-
bool canSubstituteTypeInto(Type ty, DeclContext *dc,
2657-
OpaqueSubstitutionKind kind) {
2656+
/// Checks that \p dc has access to \p ty for the purposes of an opaque
2657+
/// substitution described by \p kind.
2658+
///
2659+
/// This is purely an implementation detail check about whether type metadata
2660+
/// will be accessible. It's not intended to enforce any rules about what
2661+
/// opaque substitutions are or are not allowed.
2662+
static bool canSubstituteTypeInto(Type ty, DeclContext *dc,
2663+
OpaqueSubstitutionKind kind) {
26582664
auto nominal = ty->getAnyNominal();
26592665
if (!nominal)
26602666
return true;

lib/SIL/SILFunctionType.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2805,8 +2805,9 @@ static bool areABICompatibleParamsOrReturns(SILType a, SILType b,
28052805
if (inFunction) {
28062806
auto opaqueTypesSubsituted = aa;
28072807
auto *dc = inFunction->getDeclContext();
2808-
if (!dc)
2809-
dc = inFunction->getModule().getSwiftModule();
2808+
auto *currentModule = inFunction->getModule().getSwiftModule();
2809+
if (!dc || !dc->isChildContextOf(currentModule))
2810+
dc = currentModule;
28102811
ReplaceOpaqueTypesWithUnderlyingTypes replacer(
28112812
dc, inFunction->getResilienceExpansion());
28122813
if (aa.getASTType()->hasOpaqueArchetype())

lib/SILOptimizer/Transforms/SpecializeOpaqueArchetypes.cpp

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,26 @@ llvm::cl::opt<bool>
3131

3232
using namespace swift;
3333

34+
static DeclContext *
35+
getDeclContextIfInCurrentModule(const SILFunction &fn) {
36+
auto *dc = fn.getDeclContext();
37+
auto *currentModule = fn.getModule().getSwiftModule();
38+
if (dc && dc->isChildContextOf(currentModule))
39+
return dc;
40+
return currentModule;
41+
}
42+
3443
static Type substOpaqueTypesWithUnderlyingTypes(
3544
Type ty, SILFunction *context) {
36-
auto *dc = context->getDeclContext();
37-
if (!dc)
38-
dc = context->getModule().getSwiftModule();
39-
45+
auto *dc = getDeclContextIfInCurrentModule(*context);
4046
ReplaceOpaqueTypesWithUnderlyingTypes replacer(
4147
dc, context->getResilienceExpansion());
4248
return ty.subst(replacer, replacer, SubstFlags::SubstituteOpaqueArchetypes);
4349
}
4450

4551
static SubstitutionMap
4652
substOpaqueTypesWithUnderlyingTypes(SubstitutionMap map, SILFunction *context) {
47-
auto *dc = context->getDeclContext();
48-
if (!dc)
49-
dc = context->getModule().getSwiftModule();
53+
auto *dc = getDeclContextIfInCurrentModule(*context);
5054
ReplaceOpaqueTypesWithUnderlyingTypes replacer(
5155
dc, context->getResilienceExpansion());
5256
return map.subst(replacer, replacer, SubstFlags::SubstituteOpaqueArchetypes);
@@ -331,9 +335,7 @@ class OpaqueSpecializerCloner
331335
SILType &Sty = TypeCache[Ty];
332336
if (Sty)
333337
return Sty;
334-
auto *dc = Original.getDeclContext();
335-
if (!dc)
336-
dc = Original.getModule().getSwiftModule();
338+
auto *dc = getDeclContextIfInCurrentModule(Original);
337339

338340
// Apply the opaque types substitution.
339341
ReplaceOpaqueTypesWithUnderlyingTypes replacer(
@@ -351,9 +353,7 @@ class OpaqueSpecializerCloner
351353

352354
ProtocolConformanceRef remapConformance(Type type,
353355
ProtocolConformanceRef conf) {
354-
auto *dc = Original.getDeclContext();
355-
if (!dc)
356-
dc = Original.getModule().getSwiftModule();
356+
auto *dc = getDeclContextIfInCurrentModule(Original);
357357
// Apply the opaque types substitution.
358358
ReplaceOpaqueTypesWithUnderlyingTypes replacer(
359359
dc, Original.getResilienceExpansion());
@@ -504,9 +504,6 @@ class OpaqueArchetypeSpecializer : public SILFunctionTransform {
504504

505505
return ty.findIf([=](Type type) -> bool {
506506
if (auto opaqueTy = type->getAs<OpaqueTypeArchetypeType>()) {
507-
auto *dc = context->getDeclContext();
508-
if (!dc)
509-
dc = context->getModule().getSwiftModule();
510507
auto opaque = opaqueTy->getDecl();
511508
OpaqueSubstitutionKind subKind =
512509
ReplaceOpaqueTypesWithUnderlyingTypes::

test/SILOptimizer/Inputs/specialize_opaque_type_archetypes_3.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,19 @@ public struct ResilientContainer {
4747
print(x)
4848
}
4949
}
50+
51+
public struct WrapperP2<Wrapped: ExternalP2>: ExternalP2 {
52+
public init(_ wrapped: Wrapped) {}
53+
public func myValue3() -> Int64 { 0 }
54+
}
55+
56+
public func externalResilientWrapper<Wrapped: ExternalP2>(_ wrapped: Wrapped) -> some ExternalP2 {
57+
return WrapperP2(wrapped)
58+
}
59+
60+
@inlinable
61+
@inline(never)
62+
public func inlinableExternalResilientWrapper<Wrapped: ExternalP2>(_ wrapped: Wrapped) -> some ExternalP2 {
63+
return WrapperP2(wrapped)
64+
}
65+

test/SILOptimizer/specialize_opaque_type_archetypes.swift

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
// RUN: %target-swift-frontend -disable-availability-checking %S/Inputs/specialize_opaque_type_archetypes_4.swift -I %t -enable-library-evolution -module-name External3 -emit-module -emit-module-path %t/External3.swiftmodule
55
// RUN: %target-swift-frontend -disable-availability-checking %S/Inputs/specialize_opaque_type_archetypes_3.swift -I %t -enable-library-evolution -module-name External2 -Osize -emit-module -o - | %target-sil-opt -module-name External2 | %FileCheck --check-prefix=RESILIENT %s
66
// RUN: %target-swift-frontend -disable-availability-checking -I %t -module-name A -enforce-exclusivity=checked -Osize -emit-sil -sil-verify-all %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
7-
// RUN: %target-swift-frontend -disable-availability-checking -I %t -module-name A -enforce-exclusivity=checked -Osize -emit-sil -sil-verify-all %s | %FileCheck %s
8-
// RUN: %target-swift-frontend -disable-availability-checking -I %t -module-name A -enforce-exclusivity=checked -enable-library-evolution -Osize -emit-sil -sil-verify-all %s | %FileCheck %s
7+
// RUN: %target-swift-frontend -disable-availability-checking -I %t -module-name A -enforce-exclusivity=checked -enable-library-evolution -Osize -emit-sil -sil-verify-all %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
98

109
import External
1110
import External2
@@ -546,3 +545,43 @@ func useAbstractFunction<T: P>(_ fn: (Int64) -> T) {}
546545
public func testThinToThick() {
547546
useAbstractFunction(bar)
548547
}
548+
549+
// CHECK-LABEL: sil @$s1A19rdar56410009_normalyyF
550+
public func rdar56410009_normal() {
551+
// CHECK: [[EXTERNAL_RESILIENT_WRAPPER:%.+]] = function_ref @$s9External224externalResilientWrapperyQrxAA10ExternalP2RzlF
552+
// CHECK: = apply [[EXTERNAL_RESILIENT_WRAPPER]]<@_opaqueReturnTypeOf("$s9External217externalResilientQryF", 0) 🦸>({{%.+}}, {{%.+}}) : $@convention(thin) <τ_0_0 where τ_0_0 : ExternalP2> (@in_guaranteed τ_0_0) -> @out @_opaqueReturnTypeOf("$s9External224externalResilientWrapperyQrxAA10ExternalP2RzlF", 0) 🦸<τ_0_0>
553+
_ = externalResilientWrapper(externalResilient())
554+
} // CHECK: end sil function '$s1A19rdar56410009_normalyyF'
555+
556+
// CHECK-LABEL: sil @$s1A25rdar56410009_inlinedInneryyF
557+
public func rdar56410009_inlinedInner() {
558+
// CHECK: [[EXTERNAL_RESILIENT_WRAPPER:%.+]] = function_ref @$s9External224externalResilientWrapperyQrxAA10ExternalP2RzlF
559+
// CHECK: = apply [[EXTERNAL_RESILIENT_WRAPPER]]<Int64>({{%.+}}, {{%.+}}) : $@convention(thin) <τ_0_0 where τ_0_0 : ExternalP2> (@in_guaranteed τ_0_0) -> @out @_opaqueReturnTypeOf("$s9External224externalResilientWrapperyQrxAA10ExternalP2RzlF", 0) 🦸<τ_0_0>
560+
_ = externalResilientWrapper(inlinableExternalResilient())
561+
} // CHECK: end sil function '$s1A25rdar56410009_inlinedInneryyF'
562+
563+
// CHECK-LABEL: sil @$s1A25rdar56410009_inlinedOuteryyF
564+
public func rdar56410009_inlinedOuter() {
565+
// CHECK: [[INLINABLE_EXTERNAL_RESILIENT_WRAPPER:%.+]] = function_ref @$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlFAA08externalD0QryFQOyQo__Tg5
566+
// CHECK: = apply [[INLINABLE_EXTERNAL_RESILIENT_WRAPPER]]({{%.+}}, {{%.+}}) : $@convention(thin) (@in_guaranteed @_opaqueReturnTypeOf("$s9External217externalResilientQryF", 0) 🦸) -> @out @_opaqueReturnTypeOf("$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlF", 0) 🦸<@_opaqueReturnTypeOf("$s9External217externalResilientQryF", 0) 🦸>
567+
_ = inlinableExternalResilientWrapper(externalResilient())
568+
} // CHECK: end sil function '$s1A25rdar56410009_inlinedOuteryyF'
569+
570+
// Specialized from above
571+
// CHECK-LABEL: sil shared [noinline] @$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlFAA08externalD0QryFQOyQo__Tg5
572+
// CHECK: [[WRAPPER_INIT:%.+]] = function_ref @$s9External29WrapperP2VyACyxGxcfC
573+
// CHECK: = apply [[WRAPPER_INIT]]<@_opaqueReturnTypeOf("$s9External217externalResilientQryF", 0) 🦸>({{%.+}}, {{%.+}}, {{%.+}}) : $@convention(method) <τ_0_0 where τ_0_0 : ExternalP2> (@in τ_0_0, @thin WrapperP2<τ_0_0>.Type) -> @out WrapperP2<τ_0_0>
574+
// CHECK: end sil function '$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlFAA08externalD0QryFQOyQo__Tg5'
575+
576+
// Specialized from below
577+
// CHECK-LABEL: sil shared [noinline] @$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlFs5Int64V_Tg5
578+
// CHECK: [[WRAPPER_INIT:%.+]] = function_ref @$s9External29WrapperP2VyACyxGxcfC
579+
// CHECK: = apply [[WRAPPER_INIT]]<Int64>({{%.+}}, {{%.+}}, {{%.+}}) : $@convention(method) <τ_0_0 where τ_0_0 : ExternalP2> (@in τ_0_0, @thin WrapperP2<τ_0_0>.Type) -> @out WrapperP2<τ_0_0>
580+
// CHECK: end sil function '$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlFs5Int64V_Tg5'
581+
582+
// CHECK-LABEL: sil @$s1A24rdar56410009_inlinedBothyyF
583+
public func rdar56410009_inlinedBoth() {
584+
// CHECK: [[INLINABLE_EXTERNAL_RESILIENT_WRAPPER:%.+]] = function_ref @$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlFs5Int64V_Tg5
585+
// CHECK: = apply [[INLINABLE_EXTERNAL_RESILIENT_WRAPPER]]({{%.+}}, {{%.+}}) : $@convention(thin) (Int64) -> @out @_opaqueReturnTypeOf("$s9External233inlinableExternalResilientWrapperyQrxAA0C2P2RzlF", 0) 🦸<Int64>
586+
_ = inlinableExternalResilientWrapper(inlinableExternalResilient())
587+
} // CHECK: end sil function '$s1A24rdar56410009_inlinedBothyyF'

0 commit comments

Comments
 (0)