Skip to content

Commit fbe0f77

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 (Cherry picked from commit 8d649a2)
1 parent 3e816f5 commit fbe0f77

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
@@ -1009,6 +1009,7 @@ static Type substOpaqueTypesWithUnderlyingTypesRec(
10091009
/// opaque substitutions are or are not allowed.
10101010
static bool canSubstituteTypeInto(Type ty, const DeclContext *dc,
10111011
OpaqueSubstitutionKind kind,
1012+
ResilienceExpansion contextExpansion,
10121013
bool isContextWholeModule) {
10131014
TypeDecl *typeDecl = ty->getAnyNominal();
10141015
if (!typeDecl) {
@@ -1049,7 +1050,8 @@ static bool canSubstituteTypeInto(Type ty, const DeclContext *dc,
10491050

10501051
case OpaqueSubstitutionKind::SubstituteNonResilientModule:
10511052
// Can't access types that are not public from a different module.
1052-
if (dc->getParentModule() == typeDecl->getDeclContext()->getParentModule())
1053+
if (dc->getParentModule() == typeDecl->getDeclContext()->getParentModule() &&
1054+
contextExpansion != ResilienceExpansion::Minimal)
10531055
return typeDecl->getEffectiveAccess() > AccessLevel::FilePrivate;
10541056

10551057
return typeDecl->getEffectiveAccess() > AccessLevel::Internal;
@@ -1093,10 +1095,13 @@ operator()(SubstitutableType *maybeOpaqueType) const {
10931095
// context.
10941096
auto inContext = this->getContext();
10951097
auto isContextWholeModule = this->isWholeModule();
1098+
auto contextExpansion = this->contextExpansion;
10961099
if (inContext &&
10971100
partialSubstTy.findIf(
1098-
[inContext, substitutionKind, isContextWholeModule](Type t) -> bool {
1101+
[inContext, substitutionKind, isContextWholeModule,
1102+
contextExpansion](Type t) -> bool {
10991103
if (!canSubstituteTypeInto(t, inContext, substitutionKind,
1104+
contextExpansion,
11001105
isContextWholeModule))
11011106
return true;
11021107
return false;
@@ -1204,9 +1209,12 @@ operator()(CanType maybeOpaqueType, Type replacementType,
12041209
// context.
12051210
auto inContext = this->getContext();
12061211
auto isContextWholeModule = this->isWholeModule();
1212+
auto contextExpansion = this->contextExpansion;
12071213
if (partialSubstTy.findIf(
1208-
[inContext, substitutionKind, isContextWholeModule](Type t) -> bool {
1214+
[inContext, substitutionKind, isContextWholeModule,
1215+
contextExpansion](Type t) -> bool {
12091216
if (!canSubstituteTypeInto(t, inContext, substitutionKind,
1217+
contextExpansion,
12101218
isContextWholeModule))
12111219
return true;
12121220
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)