Skip to content

Commit b137b08

Browse files
committed
Sema: Type aliases referenced from @inlinable functions must be public or @usableFromInline
This is a source breaking change, so emit a warning in Swift 4 mode, and an error in Swift 5 mode.
1 parent 161901f commit b137b08

File tree

5 files changed

+56
-16
lines changed

5 files changed

+56
-16
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3849,6 +3849,11 @@ ERROR(resilience_decl_unavailable,
38493849
"cannot be referenced from " FRAGILE_FUNC_KIND "3",
38503850
(DescriptiveDeclKind, DeclName, AccessLevel, unsigned))
38513851

3852+
WARNING(resilience_decl_unavailable_warn,
3853+
none, "%0 %1 is %select{private|fileprivate|internal|%error|%error}2 and "
3854+
"should not be referenced from " FRAGILE_FUNC_KIND "3",
3855+
(DescriptiveDeclKind, DeclName, AccessLevel, unsigned))
3856+
38523857
#undef FRAGILE_FUNC_KIND
38533858

38543859
NOTE(resilience_decl_declared_here_public,

lib/Sema/ResilienceDiagnostics.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ void TypeChecker::diagnoseInlinableLocalType(const NominalTypeDecl *NTD) {
8686
}
8787
}
8888

89+
/// A uniquely-typed boolean to reduce the chances of accidentally inverting
90+
/// a check.
91+
enum class DowngradeToWarning: bool {
92+
No,
93+
Yes
94+
};
95+
8996
bool TypeChecker::diagnoseInlinableDeclRef(SourceLoc loc,
9097
const ValueDecl *D,
9198
const DeclContext *DC,
@@ -119,11 +126,18 @@ bool TypeChecker::diagnoseInlinableDeclRef(SourceLoc loc,
119126
if (D->isDynamic())
120127
return false;
121128

122-
// FIXME: Figure out what to do with typealiases
123-
if (isa<TypeAliasDecl>(D))
124-
return false;
129+
DowngradeToWarning downgradeToWarning = DowngradeToWarning::No;
130+
131+
// Swift 4.2 did not perform any checks for type aliases.
132+
if (!Context.isSwiftVersionAtLeast(5) &&
133+
isa<TypeAliasDecl>(D))
134+
downgradeToWarning = DowngradeToWarning::Yes;
135+
136+
auto diagID = diag::resilience_decl_unavailable;
137+
if (downgradeToWarning == DowngradeToWarning::Yes)
138+
diagID = diag::resilience_decl_unavailable_warn;
125139

126-
diagnose(loc, diag::resilience_decl_unavailable,
140+
diagnose(loc, diagID,
127141
D->getDescriptiveKind(), D->getFullName(),
128142
D->getFormalAccessScope().accessLevelForDiagnostics(),
129143
static_cast<unsigned>(Kind));
@@ -136,6 +150,6 @@ bool TypeChecker::diagnoseInlinableDeclRef(SourceLoc loc,
136150
D->getDescriptiveKind(), D->getFullName());
137151
}
138152

139-
return true;
153+
return (downgradeToWarning == DowngradeToWarning::No);
140154
}
141155

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 4
2+
3+
private typealias PrivateAlias = Int
4+
// expected-note@-1 {{type alias 'PrivateAlias' is not '@usableFromInline' or public}}
5+
6+
internal typealias InternalAlias = Int
7+
// expected-note@-1 {{type alias 'InternalAlias' is not '@usableFromInline' or public}}
8+
9+
@usableFromInline typealias UsableFromInlineAlias = Int
10+
11+
public typealias PublicAlias = Int
12+
13+
@inlinable public func f() {
14+
_ = PrivateAlias.self
15+
// expected-warning@-1 {{type alias 'PrivateAlias' is private and should not be referenced from an '@inlinable' function}}
16+
17+
_ = InternalAlias.self
18+
// expected-warning@-1 {{type alias 'InternalAlias' is internal and should not be referenced from an '@inlinable' function}}
19+
20+
_ = UsableFromInlineAlias.self
21+
22+
_ = PublicAlias.self
23+
}

test/SIL/Serialization/Inputs/def_generic.swift

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
@_fixed_layout
22
public class A<T> {
3-
typealias Element = T
4-
@usableFromInline
5-
@inlinable
6-
func convertFromArrayLiteral(_ elements: Element...) -> A {
3+
@usableFromInline typealias Element = T
4+
5+
@inlinable func convertFromArrayLiteral(_ elements: Element...) -> A {
76
return A()
87
}
98

10-
@usableFromInline
11-
@inlinable
12-
init() {}
9+
@inlinable init() {}
1310

1411
@inlinable public subscript<U>(value: T) -> U? {
1512
return nil

test/attr/attr_inlinable_typealias.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
// RUN: %target-typecheck-verify-swift
2-
3-
// None of this is enforced for now, but make sure we don't crash or
4-
// do anything stupid when a typealias is annotated with @usableFromInline.
1+
// RUN: %target-typecheck-verify-swift -swift-version 5
52

63
private typealias PrivateAlias = Int
4+
// expected-note@-1 {{type alias 'PrivateAlias' is not '@usableFromInline' or public}}
75

86
internal typealias InternalAlias = Int
7+
// expected-note@-1 {{type alias 'InternalAlias' is not '@usableFromInline' or public}}
98

109
@usableFromInline typealias UsableFromInlineAlias = Int
1110

1211
public typealias PublicAlias = Int
1312

1413
@inlinable public func f() {
1514
_ = PrivateAlias.self
15+
// expected-error@-1 {{type alias 'PrivateAlias' is private and cannot be referenced from an '@inlinable' function}}
1616

1717
_ = InternalAlias.self
18+
// expected-error@-1 {{type alias 'InternalAlias' is internal and cannot be referenced from an '@inlinable' function}}
1819

1920
_ = UsableFromInlineAlias.self
2021

0 commit comments

Comments
 (0)