Skip to content

Commit df1ef05

Browse files
committed
Remove unwanted exceptions from @inlinable checking
- Treat protocol requirements just like associated types in how they inherit usable-from-inline-ness, rather than special-casing them in the check for inlinable code. - Enum elements are already treated this way, so we can remove a redundant check for that. - Finally, start enforcing that 'dynamic' declarations need to be '@usableFromInline' to be used in inlinable functions...in Swift 5 mode or resilient code. I didn't even add a warning in Swift 4/4.2 because it was illegal to use '@usableFromInline' on a 'dynamic' declaration in Swift 4.2. (Oops.)
1 parent 3114ed1 commit df1ef05

File tree

6 files changed

+138
-17
lines changed

6 files changed

+138
-17
lines changed

lib/AST/Decl.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2358,9 +2358,11 @@ bool ValueDecl::isUsableFromInline() const {
23582358
if (EED->getParentEnum()->getAttrs().hasAttribute<UsableFromInlineAttr>())
23592359
return true;
23602360

2361-
if (auto *ATD = dyn_cast<AssociatedTypeDecl>(this))
2362-
if (ATD->getProtocol()->getAttrs().hasAttribute<UsableFromInlineAttr>())
2361+
if (auto *containingProto = dyn_cast<ProtocolDecl>(getDeclContext())) {
2362+
if (isProtocolRequirement() &&
2363+
containingProto->getAttrs().hasAttribute<UsableFromInlineAttr>())
23632364
return true;
2365+
}
23642366

23652367
if (auto *DD = dyn_cast<DestructorDecl>(this))
23662368
if (auto *CD = dyn_cast<ClassDecl>(DD->getDeclContext()))

lib/Sema/ResilienceDiagnostics.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -111,20 +111,14 @@ bool TypeChecker::diagnoseInlinableDeclRef(SourceLoc loc,
111111
TreatUsableFromInlineAsPublic).isPublic())
112112
return false;
113113

114-
// Enum cases are handled as part of their containing enum.
115-
if (isa<EnumElementDecl>(D))
116-
return false;
117-
118-
// Protocol requirements are not versioned because there's no
119-
// global entry point.
120-
if (isa<ProtocolDecl>(D->getDeclContext()) &&
121-
D->isProtocolRequirement())
122-
return false;
123-
124-
// Dynamic declarations are not versioned because there's no
125-
// global entry point.
126-
if (D->isDynamic())
114+
// Dynamic declarations were mistakenly not checked in Swift 4.2.
115+
// Do enforce the restriction even in pre-Swift-5 modes if the module we're
116+
// building is resilient, though.
117+
if (D->isDynamic() && !Context.isSwiftVersionAtLeast(5) &&
118+
DC->getParentModule()->getResilienceStrategy() !=
119+
ResilienceStrategy::Resilient) {
127120
return false;
121+
}
128122

129123
DowngradeToWarning downgradeToWarning = DowngradeToWarning::No;
130124

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %target-swift-frontend -typecheck %s -swift-version 4 -enable-objc-interop -disable-objc-attr-requires-foundation-module
2+
// RUN: %target-swift-frontend -typecheck %s -swift-version 4 -enable-objc-interop -disable-objc-attr-requires-foundation-module -enable-testing
3+
// RUN: %target-swift-frontend -typecheck %s -swift-version 4.2 -enable-objc-interop -disable-objc-attr-requires-foundation-module
4+
// RUN: %target-swift-frontend -typecheck %s -swift-version 4.2 -enable-objc-interop -disable-objc-attr-requires-foundation-module -enable-testing
5+
6+
// RUN: %target-swift-frontend -typecheck %s -swift-version 4 -enable-objc-interop -disable-objc-attr-requires-foundation-module -enable-resilience -verify
7+
// RUN: %target-swift-frontend -typecheck %s -swift-version 4 -enable-objc-interop -disable-objc-attr-requires-foundation-module -enable-testing -enable-resilience -verify
8+
// RUN: %target-swift-frontend -typecheck %s -swift-version 4.2 -enable-objc-interop -disable-objc-attr-requires-foundation-module -enable-resilience -verify
9+
// RUN: %target-swift-frontend -typecheck %s -swift-version 4.2 -enable-objc-interop -disable-objc-attr-requires-foundation-module -enable-testing -enable-resilience -verify
10+
11+
@objc internal enum InternalEnum: UInt8 {
12+
case dummy
13+
}
14+
15+
public class Foo {
16+
@objc dynamic func dynamicFunc() -> InternalEnum {} // expected-note {{instance method 'dynamicFunc()' is not '@usableFromInline' or public}}
17+
@inlinable func inlineMe() {
18+
_ = dynamicFunc() // expected-error {{instance method 'dynamicFunc()' is internal and cannot be referenced from an '@inlinable' function}}
19+
}
20+
}

test/ParseableInterface/access-filter.swift

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ internal struct UFIStruct {
4747

4848
// CHECK: public protocol PublicProto {{[{]$}}
4949
public protocol PublicProto {
50-
} // CHECK: {{^[}]$}}
50+
// CHECK-NEXT: associatedtype Assoc = Swift.Int
51+
associatedtype Assoc = Int
52+
// CHECK-NEXT: func requirement()
53+
func requirement()
54+
} // CHECK-NEXT: {{^[}]$}}
5155

5256
// CHECK: extension PublicProto {{[{]$}}
5357
extension PublicProto {
@@ -72,6 +76,8 @@ public extension PublicProto {
7276
}
7377

7478
internal protocol InternalProto_BAD {
79+
associatedtype AssocBAD = Int
80+
func requirementBAD()
7581
}
7682

7783
extension InternalProto_BAD {
@@ -84,7 +90,11 @@ extension InternalProto_BAD {
8490
// CHECK-NEXT: internal protocol UFIProto {{[{]$}}
8591
@usableFromInline
8692
internal protocol UFIProto {
87-
} // CHECK: {{^[}]$}}
93+
// CHECK-NEXT: associatedtype Assoc = Swift.Int
94+
associatedtype Assoc = Int
95+
// CHECK-NEXT: func requirement()
96+
func requirement()
97+
} // CHECK-NEXT: {{^[}]$}}
8898

8999
// CHECK: extension UFIProto {{[{]$}}
90100
extension UFIProto {
@@ -104,10 +114,38 @@ extension PublicStruct {
104114
} // CHECK: {{^[}]$}}
105115

106116
extension InternalStruct_BAD: PublicProto {
117+
func requirement() {}
107118
internal static var dummy: Int { return 0 }
108119
}
109120

110121
// CHECK: extension UFIStruct : PublicProto {{[{]$}}
111122
extension UFIStruct: PublicProto {
123+
// CHECK-NEXT: @usableFromInline
124+
// CHECK-NEXT: internal typealias Assoc = Swift.Int
125+
126+
// FIXME: Is it okay for this non-@usableFromInline implementation to satisfy
127+
// the protocol?
128+
func requirement() {}
112129
internal static var dummy: Int { return 0 }
113130
} // CHECK-NEXT: {{^[}]$}}
131+
132+
// CHECK: public enum PublicEnum {{[{]$}}
133+
public enum PublicEnum {
134+
// CHECK-NEXT: case x
135+
case x
136+
// CHECK-NEXT: case y(Int)
137+
case y(Int)
138+
} // CHECK-NEXT: {{^[}]$}}
139+
140+
enum InternalEnum_BAD {
141+
case xBAD
142+
}
143+
144+
// CHECK: @usableFromInline
145+
// CHECK-NEXT: internal enum UFIEnum {{[{]$}}
146+
@usableFromInline enum UFIEnum {
147+
// CHECK-NEXT: case x
148+
case x
149+
// CHECK-NEXT: case y(Int)
150+
case y(Int)
151+
} // CHECK-NEXT: {{^[}]$}}

test/api-digester/Outputs/stability-stdlib-abi.swift.expected

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,54 @@
1414
/* Decl Attribute changes */
1515

1616
/* Protocol Requirement Changes */
17+
18+
// These are requirements of @usableFromInline protocols, which previously
19+
// were not being tracked.
20+
Func _AnyHashableBox._downCastConditional(into:) has been added as a protocol requirement
21+
Func _AnyHashableBox._hash(into:) has been added as a protocol requirement
22+
Func _AnyHashableBox._isEqual(to:) has been added as a protocol requirement
23+
Func _AnyHashableBox._rawHashValue(_seed:) has been added as a protocol requirement
24+
Func _AnyHashableBox._unbox() has been added as a protocol requirement
25+
Func _AnyIndexBox._isEqual(to:) has been added as a protocol requirement
26+
Func _AnyIndexBox._isLess(than:) has been added as a protocol requirement
27+
Func _AnyIndexBox._unbox() has been added as a protocol requirement
28+
Func _ArrayBufferProtocol._copyContents(subRange:initializing:) has been added as a protocol requirement
29+
Func _ArrayBufferProtocol.isMutableAndUniquelyReferenced() has been added as a protocol requirement
30+
Func _ArrayBufferProtocol.replaceSubrange(_:with:elementsOf:) has been added as a protocol requirement
31+
Func _ArrayBufferProtocol.requestNativeBuffer() has been added as a protocol requirement
32+
Func _ArrayBufferProtocol.requestUniqueMutableBackingBuffer(minimumCapacity:) has been added as a protocol requirement
33+
Func _ArrayBufferProtocol.withUnsafeBufferPointer(_:) has been added as a protocol requirement
34+
Func _ArrayBufferProtocol.withUnsafeMutableBufferPointer(_:) has been added as a protocol requirement
35+
Func _HasContiguousBytes.withUnsafeBytes(_:) has been added as a protocol requirement
36+
Func _HashTableDelegate.hashValue(at:) has been added as a protocol requirement
37+
Func _HashTableDelegate.moveEntry(from:to:) has been added as a protocol requirement
38+
Func _HasherCore.compress(_:) has been added as a protocol requirement
39+
Func _HasherCore.finalize(tailAndByteCount:) has been added as a protocol requirement
40+
Func _StringVariant._copy(into:) has been added as a protocol requirement
41+
Func _StringVariant._measureFirstExtendedGraphemeClusterSlow() has been added as a protocol requirement
42+
Func _StringVariant._measureLastExtendedGraphemeClusterSlow() has been added as a protocol requirement
43+
Func _StringVariant.makeUnicodeScalarIterator() has been added as a protocol requirement
44+
Func _StringVariant.measureFirstExtendedGraphemeCluster() has been added as a protocol requirement
45+
Func _StringVariant.measureLastExtendedGraphemeCluster() has been added as a protocol requirement
46+
Subscript _ArrayBufferProtocol.subscript(_:) has been added as a protocol requirement
47+
Subscript _StringVariant.subscript(_:) has been added as a protocol requirement
48+
Var _AnyHashableBox._base has been added as a protocol requirement
49+
Var _AnyHashableBox._canonicalBox has been added as a protocol requirement
50+
Var _AnyHashableBox._hashValue has been added as a protocol requirement
51+
Var _AnyIndexBox._typeID has been added as a protocol requirement
52+
Var _ArrayBufferProtocol.capacity has been added as a protocol requirement
53+
Var _ArrayBufferProtocol.firstElementAddress has been added as a protocol requirement
54+
Var _ArrayBufferProtocol.firstElementAddressIfContiguous has been added as a protocol requirement
55+
Var _ArrayBufferProtocol.identity has been added as a protocol requirement
56+
Var _ArrayBufferProtocol.owner has been added as a protocol requirement
57+
Var _ArrayBufferProtocol.subscriptBaseAddress has been added as a protocol requirement
58+
Var _ArrayProtocol._baseAddressIfContiguous has been added as a protocol requirement
59+
Var _ArrayProtocol._buffer has been added as a protocol requirement
60+
Var _ArrayProtocol._owner has been added as a protocol requirement
61+
Var _ArrayProtocol.capacity has been added as a protocol requirement
62+
Var _HeapBufferHeader_.value has been added as a protocol requirement
63+
Var _StringVariant.isASCII has been added as a protocol requirement
64+
Var _SwiftStringView._encodedOffsetRange has been added as a protocol requirement
65+
Var _SwiftStringView._ephemeralContent has been added as a protocol requirement
66+
Var _SwiftStringView._persistentContent has been added as a protocol requirement
67+
Var _SwiftStringView._wholeString has been added as a protocol requirement
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-swift-frontend -typecheck %s -swift-version 5 -enable-objc-interop -disable-objc-attr-requires-foundation-module -verify
2+
// RUN: %target-swift-frontend -typecheck %s -swift-version 5 -enable-objc-interop -disable-objc-attr-requires-foundation-module -enable-testing -verify
3+
4+
// RUN: %target-swift-frontend -typecheck %s -swift-version 5 -enable-objc-interop -disable-objc-attr-requires-foundation-module -enable-resilience -verify
5+
// RUN: %target-swift-frontend -typecheck %s -swift-version 5 -enable-objc-interop -disable-objc-attr-requires-foundation-module -enable-testing -enable-resilience -verify
6+
7+
@objc internal enum InternalEnum: UInt8 {
8+
case dummy
9+
}
10+
11+
public class Foo {
12+
@objc dynamic func dynamicFunc() -> InternalEnum {} // expected-note {{instance method 'dynamicFunc()' is not '@usableFromInline' or public}}
13+
@inlinable func inlineMe() {
14+
_ = dynamicFunc() // expected-error {{instance method 'dynamicFunc()' is internal and cannot be referenced from an '@inlinable' function}}
15+
}
16+
}

0 commit comments

Comments
 (0)