Skip to content

Commit 2af7d8a

Browse files
authored
Merge pull request #30847 from slavapestov/opaque-type-lowering-access-level-fix
AST: Fix accessibility checking in opaque type archetype substitution logic
2 parents b1ea908 + dbaa619 commit 2af7d8a

File tree

5 files changed

+109
-30
lines changed

5 files changed

+109
-30
lines changed

lib/AST/Type.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2932,13 +2932,13 @@ substOpaqueTypesWithUnderlyingTypes(Type ty, const DeclContext *inContext,
29322932
static bool canSubstituteTypeInto(Type ty, const DeclContext *dc,
29332933
OpaqueSubstitutionKind kind,
29342934
bool isContextWholeModule) {
2935-
ValueDecl *nominal = ty->getAnyNominal();
2936-
if (!nominal) {
2935+
TypeDecl *typeDecl = ty->getAnyNominal();
2936+
if (!typeDecl) {
29372937
// We also need to check that the opaque type descriptor is accessible.
29382938
if (auto opaqueTy = ty->getAs<OpaqueTypeArchetypeType>())
2939-
nominal = opaqueTy->getDecl();
2939+
typeDecl = opaqueTy->getDecl();
29402940
}
2941-
if (!nominal) {
2941+
if (!typeDecl) {
29422942
return true;
29432943
}
29442944

@@ -2956,14 +2956,18 @@ static bool canSubstituteTypeInto(Type ty, const DeclContext *dc,
29562956

29572957
// In the same file any visibility is okay.
29582958
if (!dc->isModuleContext() &&
2959-
nominal->getDeclContext()->getParentSourceFile() ==
2959+
typeDecl->getDeclContext()->getParentSourceFile() ==
29602960
dc->getParentSourceFile())
29612961
return true;
2962-
return nominal->getEffectiveAccess() > AccessLevel::FilePrivate;
2962+
2963+
return typeDecl->getEffectiveAccess() > AccessLevel::FilePrivate;
29632964

29642965
case OpaqueSubstitutionKind::SubstituteNonResilientModule:
29652966
// Can't access types that are not public from a different module.
2966-
return nominal->getEffectiveAccess() > AccessLevel::Internal;
2967+
if (dc->getParentModule() == typeDecl->getDeclContext()->getParentModule())
2968+
return true;
2969+
2970+
return typeDecl->getEffectiveAccess() > AccessLevel::Internal;
29672971
}
29682972
}
29692973

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
public protocol View {}
2+
3+
struct InternalView : View {}
4+
struct InternalGenericView<T> : View {}
5+
6+
public struct PublicView : View {}
7+
public struct PublicGenericView<T> : View {}
8+
9+
extension View {
10+
public func passThrough() -> some View {
11+
return self
12+
}
13+
14+
public func wrapWithInternalView() -> some View {
15+
return InternalView()
16+
}
17+
18+
public func wrapWithInternalGenericView() -> some View {
19+
return InternalGenericView<Self>()
20+
}
21+
22+
public func wrapWithPublicView() -> some View {
23+
return PublicView()
24+
}
25+
26+
public func wrapWithPublicGenericView() -> some View {
27+
return PublicGenericView<Self>()
28+
}
29+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -disable-availability-checking -emit-module %S/Inputs/opaque_result_type_fragile_other.swift -emit-module-path %t/opaque_result_type_fragile_other.swiftmodule
3+
// RUN: %target-swift-frontend -disable-availability-checking -emit-silgen -I%t %s | %FileCheck %s
4+
5+
import opaque_result_type_fragile_other
6+
7+
struct InternalView: View {}
8+
public struct PublicView: View {}
9+
10+
public func testInternalView() {
11+
let v = InternalView()
12+
13+
// CHECK: function_ref @$s32opaque_result_type_fragile_other4ViewPAAE11passThroughQryF : $@convention(method) <τ_0_0 where τ_0_0 : View> (@in_guaranteed τ_0_0) -> @out τ_0_0
14+
_ = v.passThrough()
15+
16+
// CHECK: function_ref @$s32opaque_result_type_fragile_other4ViewPAAE016wrapWithInternalF0QryF : $@convention(method) <τ_0_0 where τ_0_0 : View> (@in_guaranteed τ_0_0) -> @out @_opaqueReturnTypeOf("$s32opaque_result_type_fragile_other4ViewPAAE016wrapWithInternalF0QryF", 0) 🦸<τ_0_0>
17+
_ = v.wrapWithInternalView()
18+
19+
// CHECK: function_ref @$s32opaque_result_type_fragile_other4ViewPAAE023wrapWithInternalGenericF0QryF : $@convention(method) <τ_0_0 where τ_0_0 : View> (@in_guaranteed τ_0_0) -> @out @_opaqueReturnTypeOf("$s32opaque_result_type_fragile_other4ViewPAAE023wrapWithInternalGenericF0QryF", 0) 🦸<τ_0_0>
20+
_ = v.wrapWithInternalGenericView()
21+
22+
// CHECK: function_ref @$s32opaque_result_type_fragile_other4ViewPAAE014wrapWithPublicF0QryF : $@convention(method) <τ_0_0 where τ_0_0 : View> (@in_guaranteed τ_0_0) -> @out PublicView
23+
_ = v.wrapWithPublicView()
24+
25+
//CHECK: function_ref @$s32opaque_result_type_fragile_other4ViewPAAE021wrapWithPublicGenericF0QryF : $@convention(method) <τ_0_0 where τ_0_0 : View> (@in_guaranteed τ_0_0) -> @out PublicGenericView<τ_0_0>
26+
_ = v.wrapWithPublicGenericView()
27+
}
28+
29+
public func testPublicView() {
30+
let v = PublicView()
31+
32+
// CHECK: function_ref @$s32opaque_result_type_fragile_other4ViewPAAE11passThroughQryF : $@convention(method) <τ_0_0 where τ_0_0 : View> (@in_guaranteed τ_0_0) -> @out τ_0_0
33+
_ = v.passThrough()
34+
35+
// CHECK: function_ref @$s32opaque_result_type_fragile_other4ViewPAAE016wrapWithInternalF0QryF : $@convention(method) <τ_0_0 where τ_0_0 : View> (@in_guaranteed τ_0_0) -> @out @_opaqueReturnTypeOf("$s32opaque_result_type_fragile_other4ViewPAAE016wrapWithInternalF0QryF", 0) 🦸<τ_0_0>
36+
_ = v.wrapWithInternalView()
37+
38+
// CHECK: function_ref @$s32opaque_result_type_fragile_other4ViewPAAE023wrapWithInternalGenericF0QryF : $@convention(method) <τ_0_0 where τ_0_0 : View> (@in_guaranteed τ_0_0) -> @out @_opaqueReturnTypeOf("$s32opaque_result_type_fragile_other4ViewPAAE023wrapWithInternalGenericF0QryF", 0) 🦸<τ_0_0>
39+
_ = v.wrapWithInternalGenericView()
40+
41+
// CHECK: function_ref @$s32opaque_result_type_fragile_other4ViewPAAE014wrapWithPublicF0QryF : $@convention(method) <τ_0_0 where τ_0_0 : View> (@in_guaranteed τ_0_0) -> @out PublicView
42+
_ = v.wrapWithPublicView()
43+
44+
//CHECK: function_ref @$s32opaque_result_type_fragile_other4ViewPAAE021wrapWithPublicGenericF0QryF : $@convention(method) <τ_0_0 where τ_0_0 : View> (@in_guaranteed τ_0_0) -> @out PublicGenericView<τ_0_0>
45+
_ = v.wrapWithPublicGenericView()
46+
}

test/SILOptimizer/cast_folding.swift

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
// RUN: %target-swift-frontend -disable-availability-checking -O -emit-sil %s | %FileCheck %s
2-
// RUN: %target-swift-frontend -disable-availability-checking -Onone -emit-sil %s | %FileCheck %s --check-prefix=MANDATORY
3-
// RUN: %target-swift-frontend -Xllvm -sil-disable-pass=FunctionSignatureOpts -Xllvm -sil-disable-pass=PerfInliner -enable-ownership-stripping-after-serialization -disable-availability-checking -O -emit-sil %s | %FileCheck %s
4-
// RUN: %target-swift-frontend -enable-ownership-stripping-after-serialization -disable-availability-checking -Onone -emit-sil %s | %FileCheck %s --check-prefix=MANDATORY
1+
// RUN: %target-swift-frontend -O -emit-sil %s | %FileCheck %s
2+
// RUN: %target-swift-frontend -Xllvm -sil-disable-pass=FunctionSignatureOpts -Xllvm -sil-disable-pass=PerfInliner -enable-ownership-stripping-after-serialization -O -emit-sil %s | %FileCheck %s
53

64
// We want to check two things here:
75
// - Correctness
@@ -1069,25 +1067,6 @@ public func testCastToPForOptionalFailure() -> Bool {
10691067
return testCastToPForOptional(t)
10701068
}
10711069

1072-
struct Underlying : P {
1073-
}
1074-
1075-
public func returnOpaque() -> some P {
1076-
return Underlying()
1077-
}
1078-
1079-
// MANDATORY-LABEL: sil{{.*}} @$s12cast_folding23testCastOpaqueArchetypeyyF
1080-
// MANDATORY: [[O:%.*]] = alloc_stack $@_opaqueReturnTypeOf("$s12cast_folding12returnOpaqueQryF", 0)
1081-
// MANDATORY: [[F:%.*]] = function_ref @$s12cast_folding12returnOpaqueQryF
1082-
// MANDATORY: apply [[F]]([[O]])
1083-
// MANDATORY: [[U:%.*]] = alloc_stack $Underlying
1084-
// MANDATORY: unconditional_checked_cast_addr @_opaqueReturnTypeOf{{.*}}in [[O]] : $*@_opaqueReturnTypeOf{{.*}}to Underlying in [[U]] : $*Underlying
1085-
// MANDATORY: load [[U]] : $*Underlying
1086-
@inlinable
1087-
public func testCastOpaqueArchetype() {
1088-
let o = returnOpaque() as! Underlying
1089-
}
1090-
10911070
print("test0=\(test0())")
10921071

10931072
print("test1=\(test1())")
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %target-swift-frontend -enable-library-evolution -disable-availability-checking -O -emit-sil %s
2+
// RUN: %target-swift-frontend -enable-library-evolution -disable-availability-checking -Onone -emit-sil %s | %FileCheck %s
3+
4+
public protocol P {}
5+
6+
public struct Underlying : P {
7+
}
8+
9+
public func returnOpaque() -> some P {
10+
return Underlying()
11+
}
12+
13+
// CHECK-LABEL: sil [serialized] @$s19cast_folding_opaque23testCastOpaqueArchetypeAA10UnderlyingVyF
14+
// CHECK: [[O:%.*]] = alloc_stack $@_opaqueReturnTypeOf("$s19cast_folding_opaque12returnOpaqueQryF", 0)
15+
// CHECK: [[F:%.*]] = function_ref @$s19cast_folding_opaque12returnOpaqueQryF
16+
// CHECK: apply [[F]]([[O]])
17+
// CHECK: unconditional_checked_cast_addr @_opaqueReturnTypeOf{{.*}}in [[O]] : $*@_opaqueReturnTypeOf{{.*}}to Underlying in %0 : $*Underlying
18+
@inlinable
19+
public func testCastOpaqueArchetype() -> Underlying {
20+
return returnOpaque() as! Underlying
21+
}

0 commit comments

Comments
 (0)