Skip to content

Commit 4af8ff6

Browse files
committed
Sema: TypeChecker::getFragileFunctionKind() returns if @usableFromInline references are allowed
For now, always true, soon, default arguments of public functions will return false here.
1 parent b280f61 commit 4af8ff6

File tree

4 files changed

+35
-16
lines changed

4 files changed

+35
-16
lines changed

lib/Sema/ResilienceDiagnostics.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,17 @@
2323
using namespace swift;
2424
using FragileFunctionKind = TypeChecker::FragileFunctionKind;
2525

26-
FragileFunctionKind TypeChecker::getFragileFunctionKind(const DeclContext *DC) {
26+
std::pair<FragileFunctionKind, bool>
27+
TypeChecker::getFragileFunctionKind(const DeclContext *DC) {
2728
for (; DC->isLocalContext(); DC = DC->getParent()) {
28-
if (isa<DefaultArgumentInitializer>(DC))
29-
return FragileFunctionKind::DefaultArgument;
29+
if (isa<DefaultArgumentInitializer>(DC)) {
30+
return std::make_pair(FragileFunctionKind::DefaultArgument,
31+
/*treatUsableFromInlineAsPublic=*/true);
32+
}
3033

3134
if (isa<PatternBindingInitializer>(DC))
32-
return FragileFunctionKind::PropertyInitializer;
35+
return std::make_pair(FragileFunctionKind::PropertyInitializer,
36+
/*treatUsableFromInlineAsPublic=*/true);
3337

3438
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(DC)) {
3539
// If the function is a nested function, we will serialize its body if
@@ -40,20 +44,24 @@ FragileFunctionKind TypeChecker::getFragileFunctionKind(const DeclContext *DC) {
4044
// Bodies of public transparent and always-inline functions are
4145
// serialized, so use conservative access patterns.
4246
if (AFD->isTransparent())
43-
return FragileFunctionKind::Transparent;
47+
return std::make_pair(FragileFunctionKind::Transparent,
48+
/*treatUsableFromInlineAsPublic=*/true);
4449

4550
if (AFD->getAttrs().hasAttribute<InlinableAttr>())
46-
return FragileFunctionKind::Inlinable;
51+
return std::make_pair(FragileFunctionKind::Inlinable,
52+
/*treatUsableFromInlineAsPublic=*/true);
4753

4854
if (auto attr = AFD->getAttrs().getAttribute<InlineAttr>())
4955
if (attr->getKind() == InlineKind::Always)
50-
return FragileFunctionKind::InlineAlways;
56+
return std::make_pair(FragileFunctionKind::InlineAlways,
57+
/*treatUsableFromInlineAsPublic=*/true);
5158

5259
// If a property or subscript is @inlinable, the accessors are
5360
// @inlinable also.
5461
if (auto accessor = dyn_cast<AccessorDecl>(AFD))
5562
if (accessor->getStorage()->getAttrs().getAttribute<InlinableAttr>())
56-
return FragileFunctionKind::Inlinable;
63+
return std::make_pair(FragileFunctionKind::Inlinable,
64+
/*treatUsableFromInlineAsPublic=*/true);
5765
}
5866
}
5967

@@ -64,16 +72,18 @@ void TypeChecker::diagnoseInlinableLocalType(const NominalTypeDecl *NTD) {
6472
auto *DC = NTD->getDeclContext();
6573
auto expansion = DC->getResilienceExpansion();
6674
if (expansion == ResilienceExpansion::Minimal) {
75+
auto kind = getFragileFunctionKind(DC);
6776
diagnose(NTD, diag::local_type_in_inlinable_function,
6877
NTD->getFullName(),
69-
static_cast<unsigned>(getFragileFunctionKind(DC)));
78+
static_cast<unsigned>(kind.first));
7079
}
7180
}
7281

7382
bool TypeChecker::diagnoseInlinableDeclRef(SourceLoc loc,
7483
const ValueDecl *D,
7584
const DeclContext *DC,
76-
FragileFunctionKind Kind) {
85+
FragileFunctionKind Kind,
86+
bool TreatUsableFromInlineAsPublic) {
7787
// Local declarations are OK.
7888
if (D->getDeclContext()->isLocalContext())
7989
return false;
@@ -84,7 +94,7 @@ bool TypeChecker::diagnoseInlinableDeclRef(SourceLoc loc,
8494

8595
// Public declarations are OK.
8696
if (D->getFormalAccessScope(/*useDC=*/nullptr,
87-
/*treatUsableFromInlineAsPublic*/true).isPublic())
97+
TreatUsableFromInlineAsPublic).isPublic())
8898
return false;
8999

90100
// Enum cases are handled as part of their containing enum.

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2235,13 +2235,15 @@ class AvailabilityWalker : public ASTWalker {
22352235
SmallVector<const Expr *, 16> ExprStack;
22362236
ResilienceExpansion Expansion;
22372237
Optional<TypeChecker::FragileFunctionKind> FragileKind;
2238+
bool TreatUsableFromInlineAsPublic = false;
22382239

22392240
public:
22402241
AvailabilityWalker(
22412242
TypeChecker &TC, DeclContext *DC) : TC(TC), DC(DC) {
22422243
Expansion = DC->getResilienceExpansion();
22432244
if (Expansion == ResilienceExpansion::Minimal)
2244-
FragileKind = TC.getFragileFunctionKind(DC);
2245+
std::tie(FragileKind, TreatUsableFromInlineAsPublic)
2246+
= TC.getFragileFunctionKind(DC);
22452247
}
22462248

22472249
std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
@@ -2465,7 +2467,8 @@ bool AvailabilityWalker::diagAvailability(const ValueDecl *D, SourceRange R,
24652467

24662468
if (FragileKind)
24672469
if (R.isValid())
2468-
if (TC.diagnoseInlinableDeclRef(R.Start, D, DC, *FragileKind))
2470+
if (TC.diagnoseInlinableDeclRef(R.Start, D, DC, *FragileKind,
2471+
TreatUsableFromInlineAsPublic))
24692472
return true;
24702473

24712474
if (TC.diagnoseExplicitUnavailability(D, R, DC, call))

lib/Sema/TypeCheckStmt.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1669,9 +1669,10 @@ bool TypeChecker::typeCheckConstructorBodyUntil(ConstructorDecl *ctor,
16691669
// declarations.
16701670
if (!isDelegating && ClassD->isResilient() &&
16711671
ctor->getResilienceExpansion() == ResilienceExpansion::Minimal) {
1672+
auto kind = getFragileFunctionKind(ctor);
16721673
diagnose(ctor, diag::class_designated_init_inlinable_resilient,
16731674
ClassD->getDeclaredInterfaceType(),
1674-
static_cast<unsigned>(getFragileFunctionKind(ctor)));
1675+
static_cast<unsigned>(kind.first));
16751676
}
16761677
}
16771678

lib/Sema/TypeChecker.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2309,13 +2309,18 @@ class TypeChecker final : public LazyResolver {
23092309

23102310
bool diagnoseInlinableDeclRef(SourceLoc loc, const ValueDecl *D,
23112311
const DeclContext *DC,
2312-
FragileFunctionKind Kind);
2312+
FragileFunctionKind Kind,
2313+
bool TreatUsableFromInlineAsPublic);
23132314

23142315
/// Given that \p DC is within a fragile context for some reason, describe
23152316
/// why.
23162317
///
2318+
/// The second element of the pair is true if references to @usableFromInline
2319+
/// declarations are permitted.
2320+
///
23172321
/// \see FragileFunctionKind
2318-
FragileFunctionKind getFragileFunctionKind(const DeclContext *DC);
2322+
std::pair<FragileFunctionKind, bool>
2323+
getFragileFunctionKind(const DeclContext *DC);
23192324

23202325
/// \name Availability checking
23212326
///

0 commit comments

Comments
 (0)