Skip to content

Commit 8d649a2

Browse files
committed
AST: Fix ReplaceOpaqueTypesWithUnderlyingTypes to consider the current resilience expansion in non resilient mode
When we decide which access level we can allow for types we need to consider the resilience expansion context. 'internal' visibility cannot be allowed to be looked through in inlineable code as an external module does not have visiblity to such a symbol. rdar://119725428
1 parent 7787da1 commit 8d649a2

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

lib/AST/TypeSubstitution.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,7 @@ static Type substOpaqueTypesWithUnderlyingTypesRec(
10161016
/// opaque substitutions are or are not allowed.
10171017
static bool canSubstituteTypeInto(Type ty, const DeclContext *dc,
10181018
OpaqueSubstitutionKind kind,
1019+
ResilienceExpansion contextExpansion,
10191020
bool isContextWholeModule) {
10201021
TypeDecl *typeDecl = ty->getAnyNominal();
10211022
if (!typeDecl) {
@@ -1056,7 +1057,8 @@ static bool canSubstituteTypeInto(Type ty, const DeclContext *dc,
10561057

10571058
case OpaqueSubstitutionKind::SubstituteNonResilientModule:
10581059
// Can't access types that are not public from a different module.
1059-
if (dc->getParentModule() == typeDecl->getDeclContext()->getParentModule())
1060+
if (dc->getParentModule() == typeDecl->getDeclContext()->getParentModule() &&
1061+
contextExpansion != ResilienceExpansion::Minimal)
10601062
return typeDecl->getEffectiveAccess() > AccessLevel::FilePrivate;
10611063

10621064
return typeDecl->getEffectiveAccess() > AccessLevel::Internal;
@@ -1100,10 +1102,13 @@ operator()(SubstitutableType *maybeOpaqueType) const {
11001102
// context.
11011103
auto inContext = this->getContext();
11021104
auto isContextWholeModule = this->isWholeModule();
1105+
auto contextExpansion = this->contextExpansion;
11031106
if (inContext &&
11041107
partialSubstTy.findIf(
1105-
[inContext, substitutionKind, isContextWholeModule](Type t) -> bool {
1108+
[inContext, substitutionKind, isContextWholeModule,
1109+
contextExpansion](Type t) -> bool {
11061110
if (!canSubstituteTypeInto(t, inContext, substitutionKind,
1111+
contextExpansion,
11071112
isContextWholeModule))
11081113
return true;
11091114
return false;
@@ -1211,9 +1216,12 @@ operator()(CanType maybeOpaqueType, Type replacementType,
12111216
// context.
12121217
auto inContext = this->getContext();
12131218
auto isContextWholeModule = this->isWholeModule();
1219+
auto contextExpansion = this->contextExpansion;
12141220
if (partialSubstTy.findIf(
1215-
[inContext, substitutionKind, isContextWholeModule](Type t) -> bool {
1221+
[inContext, substitutionKind, isContextWholeModule,
1222+
contextExpansion](Type t) -> bool {
12161223
if (!canSubstituteTypeInto(t, inContext, substitutionKind,
1224+
contextExpansion,
12171225
isContextWholeModule))
12181226
return true;
12191227
return false;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
public protocol P {}
2+
3+
public struct G<T, V> : P {
4+
5+
var t: T
6+
var v: V
7+
8+
public init(_ t: T, _ v: V) {
9+
self.t = t
10+
self.v = v
11+
}
12+
}
13+
14+
struct I {
15+
public init() {
16+
}
17+
}
18+
19+
public struct E : P {
20+
public init() {}
21+
22+
@inlinable
23+
public static var a : some P {
24+
return G(E(), C().b())
25+
}
26+
}
27+
28+
public struct C {
29+
public init() {}
30+
31+
@usableFromInline
32+
internal func b() -> some P {
33+
return G(self, I())
34+
}
35+
}
36+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -O -disable-availability-checking -emit-module -emit-module-path=%t/R.swiftmodule -module-name=R %S/Inputs/opaque_result_type_internal_inlinable.swift
3+
// RUN: %target-swift-frontend -O -I %t -disable-availability-checking -c -primary-file %s
4+
5+
import R
6+
7+
// This used to crash because when we were importing E.a the serialized sil
8+
// contained underlying types that this module does not have access to (internal type `I`).
9+
10+
public func testIt() {
11+
var e = E.a
12+
print(e)
13+
}

0 commit comments

Comments
 (0)