Skip to content

Commit 30d1568

Browse files
authored
Merge pull request #19522 from jrose-apple/lined-pockets
Remove unwanted exceptions from @inlinable checking
2 parents 35c03ac + df1ef05 commit 30d1568

12 files changed

+163
-40
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4031,9 +4031,6 @@ WARNING(inlinable_implies_usable_from_inline,none,
40314031
ERROR(usable_from_inline_attr_in_protocol,none,
40324032
"'@usableFromInline' attribute cannot be used in protocols", ())
40334033

4034-
ERROR(usable_from_inline_dynamic_not_supported,none,
4035-
"'@usableFromInline' attribute cannot be applied to 'dynamic' declarations", ())
4036-
40374034
#define FRAGILE_FUNC_KIND \
40384035
"%select{a '@_transparent' function|" \
40394036
"an '@inline(__always)' function|" \

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

lib/Sema/TypeCheckAttr.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,16 +1844,6 @@ void AttributeChecker::visitUsableFromInlineAttr(UsableFromInlineAttr *attr) {
18441844
return;
18451845
}
18461846

1847-
// Symbols of dynamically-dispatched declarations are never referenced
1848-
// directly, so marking them as @usableFromInline does not make sense.
1849-
if (VD->isDynamic()) {
1850-
if (attr->isImplicit())
1851-
attr->setInvalid();
1852-
else
1853-
diagnoseAndRemoveAttr(attr, diag::usable_from_inline_dynamic_not_supported);
1854-
return;
1855-
}
1856-
18571847
// On internal declarations, @inlinable implies @usableFromInline.
18581848
if (VD->getAttrs().hasAttribute<InlinableAttr>()) {
18591849
if (TC.Context.isSwiftVersionAtLeast(4,2))
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/Compatibility/attr_usableFromInline_swift4.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-typecheck-verify-swift -swift-version 4
2-
// RUN: %target-typecheck-verify-swift -enable-testing -swift-version 4
1+
// RUN: %target-typecheck-verify-swift -swift-version 4 -disable-objc-attr-requires-foundation-module -enable-objc-interop
2+
// RUN: %target-typecheck-verify-swift -enable-testing -swift-version 4 -disable-objc-attr-requires-foundation-module -enable-objc-interop
33

44
@usableFromInline private func privateVersioned() {}
55
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'privateVersioned()' is private}}
@@ -121,3 +121,9 @@ enum BadEnum {
121121

122122
@usableFromInline
123123
class BadClass : InternalClass {}
124+
125+
public class DynamicMembers {
126+
@usableFromInline @objc dynamic init() {}
127+
@usableFromInline @objc dynamic func foo() {}
128+
@usableFromInline @objc dynamic var bar: Int = 0
129+
}

test/Compatibility/attr_usableFromInline_swift42.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-typecheck-verify-swift -swift-version 4.2
2-
// RUN: %target-typecheck-verify-swift -enable-testing -swift-version 4.2
1+
// RUN: %target-typecheck-verify-swift -swift-version 4.2 -disable-objc-attr-requires-foundation-module -enable-objc-interop
2+
// RUN: %target-typecheck-verify-swift -enable-testing -swift-version 4.2 -disable-objc-attr-requires-foundation-module -enable-objc-interop
33

44
@usableFromInline private func privateVersioned() {}
55
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'privateVersioned()' is private}}
@@ -141,3 +141,9 @@ enum BadEnum {
141141
@usableFromInline
142142
class BadClass : InternalClass {}
143143
// expected-warning@-1 {{type referenced from the superclass of a '@usableFromInline' class should be '@usableFromInline' or public}}
144+
145+
public class DynamicMembers {
146+
@usableFromInline @objc dynamic init() {}
147+
@usableFromInline @objc dynamic func foo() {}
148+
@usableFromInline @objc dynamic var bar: Int = 0
149+
}

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+
}

test/attr/attr_objc.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2291,13 +2291,10 @@ class User: NSObject {
22912291
}
22922292
}
22932293

2294-
// 'dynamic' methods cannot be @inlinable or @usableFromInline
2294+
// 'dynamic' methods cannot be @inlinable.
22952295
class BadClass {
22962296
@inlinable @objc dynamic func badMethod1() {}
22972297
// expected-error@-1 {{'@inlinable' attribute cannot be applied to 'dynamic' declarations}}
2298-
2299-
@usableFromInline @objc dynamic func badMethod2() {}
2300-
// expected-error@-1 {{'@usableFromInline' attribute cannot be applied to 'dynamic' declarations}}
23012298
}
23022299

23032300
@objc

test/attr/attr_usableFromInline.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-typecheck-verify-swift -swift-version 5
2-
// RUN: %target-typecheck-verify-swift -enable-testing -swift-version 5
1+
// RUN: %target-typecheck-verify-swift -swift-version 5 -disable-objc-attr-requires-foundation-module -enable-objc-interop
2+
// RUN: %target-typecheck-verify-swift -swift-version 5 -disable-objc-attr-requires-foundation-module -enable-objc-interop -enable-testing
33

44
@usableFromInline private func privateVersioned() {}
55
// expected-error@-1 {{'@usableFromInline' attribute can only be applied to internal declarations, but 'privateVersioned()' is private}}
@@ -68,6 +68,12 @@ public func usesEqEnum() -> Bool {
6868
_ = RawEnum(rawValue: 0)
6969
}
7070

71+
public class DynamicMembers {
72+
@usableFromInline @objc dynamic init() {}
73+
@usableFromInline @objc dynamic func foo() {}
74+
@usableFromInline @objc dynamic var bar: Int = 0
75+
}
76+
7177
internal struct InternalStruct {}
7278
// expected-note@-1 9{{type declared here}}
7379

0 commit comments

Comments
 (0)