Skip to content

Commit dbf7fe6

Browse files
authored
Merge pull request #82426 from DougGregor/selector-objc-async
Allow #selector to reference async method in non-async code
2 parents 644f364 + c34f81e commit dbf7fe6

File tree

3 files changed

+64
-46
lines changed

3 files changed

+64
-46
lines changed

docs/ABI/Mangling.rst

Lines changed: 46 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ part of a symbolic reference.
6666

6767
symbolic-reference ::= [\x01-\x17] .{4} // Relative symbolic reference
6868
#if sizeof(void*) == 8
69-
symbolic-reference ::= [\x18-\x1F] .{8} // Absolute symbolic reference
69+
symbolic-reference ::= [\x18-\x1F] .{8} // Absolute symbolic reference for 64-bit pointers
7070
#elif sizeof(void*) == 4
71-
symbolic-reference ::= [\x18-\x1F] .{4} // Absolute symbolic reference
71+
symbolic-reference ::= [\x18-\x1F] .{4} // Absolute symbolic reference for 32-bit pointers
7272
#endif
7373

7474
Symbolic references are only valid in compiler-emitted metadata structures
@@ -110,7 +110,7 @@ The following symbolic reference kinds are currently implemented:
110110
#endif
111111

112112
#if SWIFT_RUNTIME_VERSION >= 5.TBD
113-
objective-c-protocol-relative-reference ::= `\x0C` .{4} // Reference points directly to a objective-c protcol reference
113+
objective-c-protocol-relative-reference ::= '\x0C' .{4} // Reference points directly to a objective-c protcol reference
114114
#endif
115115

116116
A mangled name may also include ``\xFF`` bytes, which are only used for
@@ -151,7 +151,7 @@ Globals
151151
global ::= protocol 'Hr' // protocol descriptor runtime record
152152
global ::= nominal-type 'Hn' // nominal type descriptor runtime record
153153
#if SWIFT_RUNTIME_VERSION >= 5.1
154-
global ::= opaque-type 'Ho' // opaque type descriptor runtime record
154+
global ::= opaque-type-decl-name 'Ho' // opaque type descriptor runtime record
155155
#endif
156156
global ::= protocol-conformance 'Hc' // protocol conformance runtime record
157157
global ::= global 'HF' // accessible function runtime record
@@ -250,14 +250,11 @@ types where the metadata itself has unknown layout.)
250250
global ::= global specialization // function specialization
251251
global ::= global 'Tm' // merged function
252252
global ::= entity // some identifiable thing
253-
global ::= from-type to-type generic-signature? 'TR' // reabstraction thunk
254-
global ::= impl-function-type type 'Tz' index? // objc-to-swift-async completion handler block implementation
255-
global ::= impl-function-type type 'TZ' index? // objc-to-swift-async completion handler block implementation (predefined by runtime)
256-
global ::= from-type to-type generic-signature? 'TR' // reabstraction thunk
257-
global ::= impl-function-type type generic-signature? 'Tz' // objc-to-swift-async completion handler block implementation
258-
global ::= impl-function-type type generic-signature? 'TZ' // objc-to-swift-async completion handler block implementation (predefined by runtime)
259-
global ::= from-type to-type self-type generic-signature? 'Ty' // reabstraction thunk with dynamic 'Self' capture
260-
global ::= from-type to-type generic-signature? 'Tr' // obsolete mangling for reabstraction thunk
253+
global ::= type type generic-signature? 'TR' // reabstraction thunk
254+
global ::= impl-function-type type generic-signature? 'Tz' index? // objc-to-swift-async completion handler block implementation
255+
global ::= impl-function-type type generic-signature? 'TZ' index? // objc-to-swift-async completion handler block implementation predefined by runtime
256+
global ::= type type type generic-signature? 'Ty' // reabstraction thunk with dynamic 'Self' capture
257+
global ::= type type generic-signature? 'Tr' // obsolete mangling for reabstraction thunk
261258
global ::= entity generic-signature? type type* 'TK' // key path getter
262259
global ::= entity generic-signature? type type* 'Tk' // key path setter
263260
global ::= entity generic-signature? type type* 'Tkmu' // key path unapplied method
@@ -266,9 +263,9 @@ types where the metadata itself has unknown layout.)
266263
global ::= type generic-signature 'Th' // key path hasher
267264
global ::= global generic-signature? 'TJ' AUTODIFF-FUNCTION-KIND INDEX-SUBSET 'p' INDEX-SUBSET 'r' // autodiff function
268265
global ::= global generic-signature? 'TJV' AUTODIFF-FUNCTION-KIND INDEX-SUBSET 'p' INDEX-SUBSET 'r' // autodiff derivative vtable thunk
269-
global ::= from-type to-type 'TJO' AUTODIFF-FUNCTION-KIND // autodiff self-reordering reabstraction thunk
270-
global ::= from-type 'TJS' AUTODIFF-FUNCTION-KIND INDEX-SUBSET 'p' INDEX-SUBSET 'r' INDEX-SUBSET 'P' // autodiff linear map subset parameters thunk
271-
global ::= global to-type 'TJS' AUTODIFF-FUNCTION-KIND INDEX-SUBSET 'p' INDEX-SUBSET 'r' INDEX-SUBSET 'P' // autodiff derivative function subset parameters thunk
266+
global ::= type type 'TJO' AUTODIFF-FUNCTION-KIND // autodiff self-reordering reabstraction thunk
267+
global ::= type 'TJS' AUTODIFF-FUNCTION-KIND INDEX-SUBSET 'p' INDEX-SUBSET 'r' INDEX-SUBSET 'P' // autodiff linear map subset parameters thunk
268+
global ::= global type 'TJS' AUTODIFF-FUNCTION-KIND INDEX-SUBSET 'p' INDEX-SUBSET 'r' INDEX-SUBSET 'P' // autodiff derivative function subset parameters thunk
272269

273270
global ::= protocol 'TL' // protocol requirements base descriptor
274271
global ::= assoc-type-name 'Tl' // associated type descriptor
@@ -280,9 +277,9 @@ types where the metadata itself has unknown layout.)
280277
REABSTRACT-THUNK-TYPE ::= 'R' // reabstraction thunk
281278
REABSTRACT-THUNK-TYPE ::= 'r' // reabstraction thunk (obsolete)
282279

283-
global ::= reabstraction-thunk type 'TU' // reabstraction thunk with global actor constraint
280+
global ::= global type 'TU' // reabstraction thunk with global actor constraint
284281

285-
The `from-type` and `to-type` in a reabstraction thunk helper function
282+
All reabstraction thunks have the "from" and "to" types in that order, and
286283
are always non-polymorphic ``<impl-function-type>`` types.
287284

288285
::
@@ -341,9 +338,9 @@ with a differentiable function used for differentiable programming.
341338
global ::= generic-signature? type 'WOF' // Outlined assignWithCopy, not using value witness
342339
global ::= generic-signature? type 'WOh' // Outlined destroy
343340
global ::= generic-signature? type 'WOH' // Outlined destroy, not using value witness
344-
global ::= generic-signature? type 'WOi` // Outlined store enum tag
345-
global ::= generic-signature? type 'WOj` // Outlined enum destructive project
346-
global ::= generic-signature? type 'WOg` // Outlined enum get tag
341+
global ::= generic-signature? type 'WOi' // Outlined store enum tag
342+
global ::= generic-signature? type 'WOj' // Outlined enum destructive project
343+
global ::= generic-signature? type 'WOg' // Outlined enum get tag
347344

348345
Entities
349346
~~~~~~~~
@@ -357,8 +354,10 @@ Entities
357354
curry-thunk ::= 'Tc'
358355

359356
label-list ::= empty-list // represents complete absence of parameter labels
360-
label-list ::= ('_' | identifier)* // '_' is inserted as placeholder for empty label,
357+
label-list ::= label* // '_' is inserted as placeholder for empty label,
361358
// since the number of labels should match the number of parameters
359+
label ::= '_' // empty label
360+
label ::= identifier // label
362361

363362
// The leading type is the function type
364363
entity-spec ::= label-list type file-discriminator? 'fC' // allocating constructor
@@ -602,6 +601,8 @@ Types
602601

603602
any-generic-type ::= standard-substitutions
604603

604+
nominal-type ::= any-generic-type // nominal type
605+
605606
standard-substitutions ::= 'S' KNOWN-TYPE-KIND // known nominal type substitution
606607
standard-substitutions ::= 'S' NATURAL KNOWN-TYPE-KIND // repeated known type substitutions of the same kind
607608

@@ -724,8 +725,9 @@ Types
724725
type ::= '$' 'n'? INDEX // integer type
725726
#endif
726727

727-
bound-generic-type ::= type 'y' (type* '_')* type* retroactive-conformance* 'G' // one type-list per nesting level of type
728+
bound-generic-type ::= type bound-generic-args 'G' // one type-list per nesting level of type
728729
bound-generic-type ::= substitution
730+
bound-generic-args ::= 'y' (type* '_')* type* retroactive-conformance* // generic arguments
729731

730732
FUNCTION-KIND ::= 'f' // @thin function type
731733
FUNCTION-KIND ::= 'U' // uncurried function type (currently not used)
@@ -738,7 +740,7 @@ Types
738740
FUNCTION-KIND ::= 'A' // @auto_closure function type (escaping)
739741
FUNCTION-KIND ::= 'E' // function type (noescape)
740742

741-
C-TYPE ::= NATURAL CHAR* // raw Itanium mangling
743+
C-TYPE ::= NATURAL IDENTIFIER-STRING // raw Itanium mangling
742744

743745
function-signature ::= result-type params-type async? sendable? throws? differentiable? function-isolation? sending-result? // results and parameters
744746

@@ -785,7 +787,7 @@ The 6.0 Swift runtime supports demangling ``sending-result``, but has a bug when
785787
METATYPE-REPR ::= 'o' // ObjC metatype representation
786788

787789
existential-layout ::= protocol-list 'p' // existential layout
788-
existential-layout ::= protocol-list superclass 'Xc' // existential layout with superclass
790+
existential-layout ::= protocol-list type 'Xc' // existential layout with superclass
789791
existential-layout ::= protocol-list 'Xl' // existential layout with AnyObject
790792

791793
type ::= associated-type
@@ -801,11 +803,10 @@ The 6.0 Swift runtime supports demangling ``sending-result``, but has a bug when
801803
type ::= assoc-type-name 'Qz' // shortcut for 'Qyz'
802804
type ::= assoc-type-list 'QY' GENERIC-PARAM-INDEX // associated type at depth
803805
type ::= assoc-type-list 'QZ' // shortcut for 'QYz'
804-
type ::= opaque-type-decl-name bound-generic-args 'Qo' INDEX // opaque type
805-
806-
type ::= pack-type 'Qe' INDEX // pack element type
806+
807+
type ::= type 'Qe' INDEX // pack element type
807808
808-
type ::= pattern-type count-type 'Qp' // pack expansion type
809+
type ::= type type 'Qp' // pack expansion type (pattern, count)
809810
type ::= pack-element-list 'QP' // pack type
810811
type ::= pack-element-list 'QS' DIRECTNESS // SIL pack type
811812

@@ -814,7 +815,7 @@ The 6.0 Swift runtime supports demangling ``sending-result``, but has a bug when
814815
815816
#if SWIFT_RUNTIME_VERSION >= 5.2
816817
type ::= type assoc-type-name 'Qx' // associated type relative to base `type`
817-
type ::= type assoc-type-list 'QX' // associated type relative to base `type`
818+
type ::= type assoc-type-list 'QX' // associated type relative to base `type` list
818819
#endif
819820

820821
#if SWIFT_RUNTIME_VERSION >= 5.7
@@ -830,7 +831,7 @@ The 6.0 Swift runtime supports demangling ``sending-result``, but has a bug when
830831
associated-type ::= type identifier 'Qa' // associated type
831832

832833
assoc-type-name ::= identifier // associated type name without protocol
833-
assoc-type-name ::= identifier protocol 'P' //
834+
assoc-type-name ::= identifier protocol 'P' // associated type name with protocol
834835

835836
empty-list ::= 'y'
836837

@@ -845,7 +846,7 @@ mangled in to disambiguate.
845846
impl-function-type ::= type* 'I' FUNC-ATTRIBUTES '_'
846847
impl-function-type ::= type* generic-signature 'I' FUNC-ATTRIBUTES '_'
847848

848-
FUNC-ATTRIBUTES ::= PATTERN-SUBS? INVOCATION-SUBS? PSEUDO-GENERIC? CALLEE-ESCAPE? ISOLATION? DIFFERENTIABILITY-KIND? CALLEE-CONVENTION FUNC-REPRESENTATION? COROUTINE-KIND? SENDABLE? ASYNC? SENDING-RESULT? (PARAM-CONVENTION PARAM-DIFFERENTIABILITY?)* RESULT-CONVENTION* ('Y' PARAM-CONVENTION)* ('z' RESULT-CONVENTION RESULT-DIFFERENTIABILITY?)?
849+
FUNC-ATTRIBUTES ::= PATTERN-SUBS? INVOCATION-SUB? PSEUDO-GENERIC? CALLEE-ESCAPE? ISOLATION? DIFFERENTIABILITY-KIND? CALLEE-CONVENTION FUNC-REPRESENTATION? COROUTINE-KIND? SENDABLE? ASYNC? SENDING-RESULT? (PARAM-CONVENTION PARAM-DIFFERENTIABILITY?)* RESULT-CONVENTION* ('Y' PARAM-CONVENTION)* ('z' RESULT-CONVENTION RESULT-DIFFERENTIABILITY?)?
849850

850851
PATTERN-SUBS ::= 's' // has pattern substitutions
851852
INVOCATION-SUB ::= 'I' // has invocation substitutions
@@ -953,10 +954,10 @@ productions:
953954
::
954955

955956
any-generic-type ::= context decl-name 'a' // typealias type
956-
type ::= base-type "XSq" // sugared Optional type
957-
type ::= base-type "XSa" // sugared Array type
958-
type ::= key-type value-type "XSD" // sugared Dictionary type
959-
type ::= count-type element-type "XSA" // sugared InlineArray type
957+
type ::= type 'XSq' // sugared Optional type
958+
type ::= type 'XSa' // sugared Array type
959+
type ::= type type 'XSD' // sugared Dictionary type (key, value)
960+
type ::= type type 'XSA' // sugared InlineArray type (count, element)
960961

961962
Generics
962963
~~~~~~~~
@@ -1005,7 +1006,7 @@ Property behaviors are implemented using private protocol conformances.
10051006
dependent-associated-conformance 'HA' DEPENDENT-CONFORMANCE-INDEX
10061007

10071008
dependent-associated-conformance ::= type protocol
1008-
dependent-protocol-conformance ::= dependent-protocol-conformance opaque-type 'HO'
1009+
dependent-protocol-conformance ::= dependent-protocol-conformance type 'HO'
10091010

10101011
pack-protocol-conformance ::= any-protocol-conformance-list 'HX'
10111012

@@ -1041,7 +1042,7 @@ now codified into the ABI; the index 0 is therefore reserved.
10411042
generic-param-marker ::= generic-param-pack-marker
10421043
generic-param-marker ::= generic-param-value-marker
10431044

1044-
generic-param-pack-marker ::= 'Rv' GENERIC_PARAM-INDEX // generic parameter pack marker
1045+
generic-param-pack-marker ::= 'Rv' GENERIC-PARAM-INDEX // generic parameter pack marker
10451046

10461047
#if SWIFT_RUNTIME_VERSION >= 6.TBD
10471048
generic-param-value-marker ::= type 'RV' GENERIC-PARAM-INDEX // generic parameter value marker
@@ -1085,9 +1086,9 @@ now codified into the ABI; the index 0 is therefore reserved.
10851086
LAYOUT-CONSTRAINT ::= 'T' // Trivial
10861087
LAYOUT-CONSTRAINT ::= 'C' // Class
10871088
LAYOUT-CONSTRAINT ::= 'D' // NativeClass
1088-
LAYOUT-CONSTRAINT ::= 'E' LAYOUT-SIZE-AND-ALIGNMENT // Trivial of exact size
1089+
LAYOUT-CONSTRAINT ::= 'E' LAYOUT-SIZE-AND-ALIGNMENT // Trivial of exact size and alignment
10891090
LAYOUT-CONSTRAINT ::= 'e' LAYOUT-SIZE // Trivial of exact size
1090-
LAYOUT-CONSTRAINT ::= 'M' LAYOUT-SIZE-AND-ALIGNMENT // Trivial of size at most N bits
1091+
LAYOUT-CONSTRAINT ::= 'M' LAYOUT-SIZE-AND-ALIGNMENT // Trivial of size and alignment at most N bits
10911092
LAYOUT-CONSTRAINT ::= 'm' LAYOUT-SIZE // Trivial of size at most N bits
10921093
LAYOUT-CONSTRAINT ::= 'U' // Unknown layout
10931094
LAYOUT-CONSTRAINT ::= 'B' // BridgeObject
@@ -1231,7 +1232,7 @@ Substitutions
12311232
::
12321233

12331234
substitution ::= 'A' INDEX // substitution of N+26
1234-
substitution ::= 'A' SUBST_IDX* LAST-SUBST-IDX // One or more consecutive substitutions of N < 26
1235+
substitution ::= 'A' SUBST-IDX* LAST-SUBST-IDX // One or more consecutive substitutions of N < 26
12351236
SUBST-IDX ::= [a-z]
12361237
SUBST-IDX ::= NATURAL [a-z]
12371238
LAST-SUBST-IDX ::= [A-Z]
@@ -1282,14 +1283,14 @@ Numbers and Indexes
12821283
INDEX ::= '_' // 0
12831284
INDEX ::= NATURAL '_' // N+1
12841285
NATURAL ::= [1-9] [0-9]*
1285-
NATURAL_ZERO ::= [0-9]+
1286+
NATURAL-ZERO ::= [0-9]+
12861287

12871288
``<INDEX>`` is a production for encoding numbers in contexts that can't
12881289
end in a digit; it's optimized for encoding smaller numbers.
12891290

12901291
::
12911292

1292-
INDEX-SUBSET ::= ('S' | 'U')+
1293+
INDEX-SUBSET ::= [SU]+
12931294

12941295
``<INDEX-SUBSET>`` is encoded like a bit vector and is optimized for encoding
12951296
indices with a small upper bound.
@@ -1359,14 +1360,14 @@ Some kinds need arguments, which precede ``Tf``.
13591360

13601361
CONST-PROP ::= 'f' // Consumes one identifier argument which is a function symbol name
13611362
CONST-PROP ::= 'g' // Consumes one identifier argument which is a global symbol name
1362-
CONST-PROP ::= 'i' NATURAL_ZERO // 64-bit-integer
1363-
CONST-PROP ::= 'd' NATURAL_ZERO // float-as-64-bit-integer
1363+
CONST-PROP ::= 'i' NATURAL-ZERO // 64-bit-integer
1364+
CONST-PROP ::= 'd' NATURAL-ZERO // float-as-64-bit-integer
13641365
CONST-PROP ::= 's' ENCODING // string literal. Consumes one identifier argument.
13651366
CONST-PROP ::= 'k' // keypath. Consumes one identifier - the SHA1 of the keypath and two types (root and value).
13661367

13671368
ENCODING ::= 'b' // utf8
13681369
ENCODING ::= 'w' // utf16
1369-
ENCODING ::= 'c' // utf16
1370+
ENCODING ::= 'c' // objc
13701371

13711372
If the first character of the string literal is a digit ``[0-9]`` or an
13721373
underscore ``_``, the identifier for the string literal is prefixed with an

lib/Sema/TypeCheckEffects.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3061,6 +3061,13 @@ class Context {
30613061
return copy;
30623062
}
30633063

3064+
/// Form a subcontext that handles all async calls.
3065+
Context withHandlesAsync() const {
3066+
Context copy = *this;
3067+
copy.HandlesAsync = true;
3068+
return copy;
3069+
}
3070+
30643071
Kind getKind() const { return TheKind; }
30653072

30663073
DeclContext *getDeclContext() const { return DC; }
@@ -4068,7 +4075,7 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
40684075

40694076
ShouldRecurse_t checkObjCSelector(ObjCSelectorExpr *E) {
40704077
// Walk the operand.
4071-
ContextScope scope(*this, std::nullopt);
4078+
ContextScope scope(*this, CurContext.withHandlesAsync());
40724079
scope.enterNonExecuting();
40734080

40744081
E->getSubExpr()->walk(*this);

test/expr/primary/selector/selector.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,13 @@ func test() -> Selector {
180180
func testWithThrowing(obj: AnyObject) {
181181
_ = #selector(HasThrows.doSomething(to:))
182182
}
183+
184+
@available(SwiftStdlib 5.1, *)
185+
@objc protocol HasAsync {
186+
@objc optional func doSomething(to object: AnyObject) async -> Void
187+
}
188+
189+
@available(SwiftStdlib 5.1, *)
190+
func testWithAsync(obj: AnyObject) {
191+
_ = #selector(HasAsync.doSomething(to:))
192+
}

0 commit comments

Comments
 (0)