Skip to content

Commit bf66c7e

Browse files
authored
Merge pull request #17313 from slavapestov/inlinable-warning-tweak-4.2
Small @inlinable tweaks for [4.2]
2 parents 76e5166 + 574327b commit bf66c7e

10 files changed

+85
-39
lines changed

include/swift/AST/DiagnosticsSema.def

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

3838+
WARNING(resilience_decl_unavailable_warn,
3839+
none, "%0 %1 is %select{private|fileprivate|internal|%error|%error}2 and "
3840+
"should not be referenced from " FRAGILE_FUNC_KIND "3",
3841+
(DescriptiveDeclKind, DeclName, AccessLevel, unsigned))
3842+
38383843
#undef FRAGILE_FUNC_KIND
38393844

38403845
NOTE(resilience_decl_declared_here_public,

lib/Sema/DerivedConformanceRawRepresentable.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,22 @@ static void deriveBodyRawRepresentable_raw(AbstractFunctionDecl *toRawDecl) {
121121
toRawDecl->setBody(body);
122122
}
123123

124+
static void maybeMarkAsInlinable(DerivedConformance &derived,
125+
AbstractFunctionDecl *afd) {
126+
ASTContext &C = derived.TC.Context;
127+
auto parentDC = derived.getConformanceContext();
128+
if (parentDC->getParentModule()->getResilienceStrategy() !=
129+
ResilienceStrategy::Resilient) {
130+
AccessScope access =
131+
afd->getFormalAccessScope(nullptr,
132+
/*treatUsableFromInlineAsPublic*/true);
133+
if (auto *attr = afd->getAttrs().getAttribute<UsableFromInlineAttr>())
134+
attr->setInvalid();
135+
if (access.isPublic())
136+
afd->getAttrs().add(new (C) InlinableAttr(/*implicit*/false));
137+
}
138+
}
139+
124140
static VarDecl *deriveRawRepresentable_raw(DerivedConformance &derived) {
125141
ASTContext &C = derived.TC.Context;
126142

@@ -143,14 +159,7 @@ static VarDecl *deriveRawRepresentable_raw(DerivedConformance &derived) {
143159

144160
// If the containing module is not resilient, make sure clients can get at
145161
// the raw value without function call overhead.
146-
if (parentDC->getParentModule()->getResilienceStrategy() !=
147-
ResilienceStrategy::Resilient) {
148-
AccessScope access =
149-
enumDecl->getFormalAccessScope(nullptr,
150-
/*treatUsableFromInlineAsPublic*/true);
151-
if (access.isPublic())
152-
getterDecl->getAttrs().add(new (C) InlinableAttr(/*implicit*/false));
153-
}
162+
maybeMarkAsInlinable(derived, getterDecl);
154163

155164
derived.addMembersToConformanceContext({getterDecl, propDecl, pbDecl});
156165

@@ -350,14 +359,7 @@ deriveRawRepresentable_init(DerivedConformance &derived) {
350359

351360
// If the containing module is not resilient, make sure clients can construct
352361
// an instance without function call overhead.
353-
if (parentDC->getParentModule()->getResilienceStrategy() !=
354-
ResilienceStrategy::Resilient) {
355-
AccessScope access =
356-
enumDecl->getFormalAccessScope(nullptr,
357-
/*treatUsableFromInlineAsPublic*/true);
358-
if (access.isPublic())
359-
initDecl->getAttrs().add(new (C) InlinableAttr(/*implicit*/false));
360-
}
362+
maybeMarkAsInlinable(derived, initDecl);
361363

362364
C.addSynthesizedDecl(initDecl);
363365

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

lib/Sema/TypeCheckAttr.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,9 +1979,7 @@ void AttributeChecker::visitUsableFromInlineAttr(UsableFromInlineAttr *attr) {
19791979

19801980
// On internal declarations, @inlinable implies @usableFromInline.
19811981
if (VD->getAttrs().hasAttribute<InlinableAttr>()) {
1982-
if (attr->isImplicit())
1983-
attr->setInvalid();
1984-
else
1982+
if (TC.Context.isSwiftVersionAtLeast(4,2))
19851983
diagnoseAndRemoveAttr(attr, diag::inlinable_implies_usable_from_inline);
19861984
return;
19871985
}

test/Compatibility/attr_inlinable_old_spelling_4.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@
55

66
@_inlineable public func oldInlinableFunction() {}
77
@_versioned func oldVersionedFunction() {}
8+
9+
// No warning here
10+
@_inlineable @_versioned func redundantAttribute() {}

test/Compatibility/attr_inlinable_old_spelling_42.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@
77

88
@_versioned func oldVersionedFunction() {}
99
// expected-warning@-1 {{'@_versioned' has been renamed to '@usableFromInline'}}{{2-12=usableFromInline}}
10+
11+
@inlinable @usableFromInline func redundantAttribute() {}
12+
// expected-warning@-1 {{'@inlinable' declaration is already '@usableFromInline'}}
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.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
// RUN: %target-typecheck-verify-swift -swift-version 4
2-
// RUN: %target-typecheck-verify-swift -swift-version 4 -enable-testing
3-
// RUN: %target-typecheck-verify-swift -swift-version 4 -enable-resilience
4-
// RUN: %target-typecheck-verify-swift -swift-version 4 -enable-resilience -enable-testing
1+
// RUN: %target-typecheck-verify-swift -swift-version 4.2
2+
// RUN: %target-typecheck-verify-swift -swift-version 4.2 -enable-testing
3+
// RUN: %target-typecheck-verify-swift -swift-version 4.2 -enable-resilience
4+
// RUN: %target-typecheck-verify-swift -swift-version 4.2 -enable-resilience -enable-testing
55
@inlinable struct TestInlinableStruct {}
66
// expected-error@-1 {{'@inlinable' attribute cannot be applied to this declaration}}
77

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)