Skip to content

Commit 2bf497d

Browse files
committed
[sending] Do not mangle sending into function/methods but keep mangling into vars/storage.
We want to ensure that functions/methods themselves do not have sending mangled into their names, but we do want sending mangled in non-top level positions. For example: we do not want to mangle sending into a function like the following: ```swift // We don't want to mangle this. func test(_ x: sending NonSendableKlass) -> () ``` But when it comes to actually storing functions into memory, we do want to distinguish in between function values that use sending vs those that do not since we do not want to allow for them to alias. Thus we want to mangle sending into things like the following: ```swift // We want to distinguish in between Array<(sending T) -> ()> and // Array((T) -> ()> let a = Array<(sending T) -> ()> // We want to distinguish in between a global contianing (sending T) -> () and a // global containing (T) -> (). var global: (sending T) -> () ``` This commit achieves that by making changes to the ASTMangler in getDeclType which causes getDeclType to set a flag that says that we have not yet recursed through the system and thus should suppress the printing of sendable. Once we get further into the system and recurse, that flag is by default set to true, so we get the old sending parameter without having to update large amounts of code. rdar://127383107
1 parent b8305cc commit 2bf497d

File tree

6 files changed

+210
-98
lines changed

6 files changed

+210
-98
lines changed

include/swift/AST/ASTMangler.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,8 @@ class ASTMangler : public Mangler {
445445
void appendRetroactiveConformances(SubstitutionMap subMap,
446446
GenericSignature sig);
447447
void appendImplFunctionType(SILFunctionType *fn, GenericSignature sig,
448-
const ValueDecl *forDecl = nullptr);
448+
const ValueDecl *forDecl = nullptr,
449+
bool isInRecursion = true);
449450
void appendOpaqueTypeArchetype(ArchetypeType *archetype,
450451
OpaqueTypeDecl *opaqueDecl,
451452
SubstitutionMap subs,
@@ -521,25 +522,29 @@ class ASTMangler : public Mangler {
521522
FunctionMangling,
522523
};
523524

524-
void appendFunction(AnyFunctionType *fn, GenericSignature sig,
525-
FunctionManglingKind functionMangling = NoFunctionMangling,
526-
const ValueDecl *forDecl = nullptr);
525+
void
526+
appendFunction(AnyFunctionType *fn, GenericSignature sig,
527+
FunctionManglingKind functionMangling = NoFunctionMangling,
528+
const ValueDecl *forDecl = nullptr,
529+
bool isRecursedInto = true);
527530
void appendFunctionType(AnyFunctionType *fn, GenericSignature sig,
528531
bool isAutoClosure = false,
529-
const ValueDecl *forDecl = nullptr);
532+
const ValueDecl *forDecl = nullptr,
533+
bool isRecursedInto = true);
530534
void appendClangType(AnyFunctionType *fn);
531535
template <typename FnType>
532536
void appendClangType(FnType *fn, llvm::raw_svector_ostream &os);
533537

534-
void appendFunctionSignature(AnyFunctionType *fn,
535-
GenericSignature sig,
538+
void appendFunctionSignature(AnyFunctionType *fn, GenericSignature sig,
536539
const ValueDecl *forDecl,
537-
FunctionManglingKind functionMangling);
540+
FunctionManglingKind functionMangling,
541+
bool isRecursedInto = true);
538542

539543
void appendFunctionInputType(ArrayRef<AnyFunctionType::Param> params,
540544
LifetimeDependenceInfo lifetimeDependenceInfo,
541545
GenericSignature sig,
542-
const ValueDecl *forDecl = nullptr);
546+
const ValueDecl *forDecl = nullptr,
547+
bool isRecursedInto = true);
543548
void appendFunctionResultType(Type resultType,
544549
GenericSignature sig,
545550
const ValueDecl *forDecl = nullptr);

lib/AST/ASTMangler.cpp

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,7 +2039,8 @@ getResultDifferentiability(SILResultInfo::Options options) {
20392039

20402040
void ASTMangler::appendImplFunctionType(SILFunctionType *fn,
20412041
GenericSignature outerGenericSig,
2042-
const ValueDecl *forDecl) {
2042+
const ValueDecl *forDecl,
2043+
bool isInRecursion) {
20432044

20442045
llvm::SmallVector<char, 32> OpArgs;
20452046

@@ -2164,7 +2165,7 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn,
21642165
}
21652166

21662167
// Mangle if we have a transferring result.
2167-
if (fn->hasSendingResult())
2168+
if (isInRecursion && fn->hasSendingResult())
21682169
OpArgs.push_back('T');
21692170

21702171
// Mangle the results.
@@ -2947,7 +2948,7 @@ void ASTMangler::appendAnyGenericType(const GenericTypeDecl *decl,
29472948

29482949
void ASTMangler::appendFunction(AnyFunctionType *fn, GenericSignature sig,
29492950
FunctionManglingKind functionMangling,
2950-
const ValueDecl *forDecl) {
2951+
const ValueDecl *forDecl, bool isRecursedInto) {
29512952
// Append parameter labels right before the signature/type.
29522953
auto parameters = fn->getParams();
29532954
auto firstLabel = std::find_if(
@@ -2967,15 +2968,16 @@ void ASTMangler::appendFunction(AnyFunctionType *fn, GenericSignature sig,
29672968
}
29682969

29692970
if (functionMangling != NoFunctionMangling) {
2970-
appendFunctionSignature(fn, sig, forDecl, functionMangling);
2971+
appendFunctionSignature(fn, sig, forDecl, functionMangling, isRecursedInto);
29712972
} else {
2972-
appendFunctionType(fn, sig, /*autoclosure*/ false, forDecl);
2973+
appendFunctionType(fn, sig, /*autoclosure*/ false, forDecl, isRecursedInto);
29732974
}
29742975
}
29752976

29762977
void ASTMangler::appendFunctionType(AnyFunctionType *fn, GenericSignature sig,
29772978
bool isAutoClosure,
2978-
const ValueDecl *forDecl) {
2979+
const ValueDecl *forDecl,
2980+
bool isRecursedInto) {
29792981
assert((DWARFMangling || fn->isCanonical()) &&
29802982
"expecting canonical types when not mangling for the debugger");
29812983

@@ -3047,10 +3049,11 @@ void ASTMangler::appendClangType(AnyFunctionType *fn) {
30473049
void ASTMangler::appendFunctionSignature(AnyFunctionType *fn,
30483050
GenericSignature sig,
30493051
const ValueDecl *forDecl,
3050-
FunctionManglingKind functionMangling) {
3052+
FunctionManglingKind functionMangling,
3053+
bool isRecursedInto) {
30513054
appendFunctionResultType(fn->getResult(), sig, forDecl);
30523055
appendFunctionInputType(fn->getParams(), fn->getLifetimeDependenceInfo(), sig,
3053-
forDecl);
3056+
forDecl, isRecursedInto);
30543057
if (fn->isAsync())
30553058
appendOperator("Ya");
30563059
if (fn->isSendable())
@@ -3096,7 +3099,7 @@ void ASTMangler::appendFunctionSignature(AnyFunctionType *fn,
30963099
break;
30973100
}
30983101

3099-
if (fn->hasSendingResult()) {
3102+
if (isRecursedInto && fn->hasSendingResult()) {
31003103
appendOperator("YT");
31013104
}
31023105

@@ -3142,7 +3145,13 @@ getDefaultOwnership(const ValueDecl *forDecl) {
31423145

31433146
static ParameterTypeFlags
31443147
getParameterFlagsForMangling(ParameterTypeFlags flags,
3145-
ParamSpecifier defaultSpecifier) {
3148+
ParamSpecifier defaultSpecifier,
3149+
bool isInRecursion = true) {
3150+
// If we have been recursed into, then remove sending from our flags.
3151+
if (!isInRecursion) {
3152+
flags = flags.withSending(false);
3153+
}
3154+
31463155
switch (auto specifier = flags.getOwnershipSpecifier()) {
31473156
// If no parameter specifier was provided, mangle as-is, because we are by
31483157
// definition using the default convention.
@@ -3169,7 +3178,7 @@ getParameterFlagsForMangling(ParameterTypeFlags flags,
31693178
void ASTMangler::appendFunctionInputType(
31703179
ArrayRef<AnyFunctionType::Param> params,
31713180
LifetimeDependenceInfo lifetimeDependenceInfo, GenericSignature sig,
3172-
const ValueDecl *forDecl) {
3181+
const ValueDecl *forDecl, bool isRecursedInto) {
31733182
auto defaultSpecifier = getDefaultOwnership(forDecl);
31743183

31753184
switch (params.size()) {
@@ -3192,7 +3201,7 @@ void ASTMangler::appendFunctionInputType(
31923201
appendParameterTypeListElement(
31933202
Identifier(), type,
31943203
getParameterFlagsForMangling(param.getParameterFlags(),
3195-
defaultSpecifier),
3204+
defaultSpecifier, isRecursedInto),
31963205
lifetimeDependenceInfo.getLifetimeDependenceOnParam(/*paramIndex*/ 0),
31973206
sig, nullptr);
31983207
break;
@@ -3214,7 +3223,7 @@ void ASTMangler::appendFunctionInputType(
32143223
appendParameterTypeListElement(
32153224
Identifier(), param.getPlainType(),
32163225
getParameterFlagsForMangling(param.getParameterFlags(),
3217-
defaultSpecifier),
3226+
defaultSpecifier, isRecursedInto),
32183227
lifetimeDependenceInfo.getLifetimeDependenceOnParam(paramIndex), sig,
32193228
nullptr);
32203229
appendListSeparator(isFirstParam);
@@ -3878,7 +3887,8 @@ void ASTMangler::appendDeclType(const ValueDecl *decl,
38783887
: decl->getDeclContext()->getGenericSignatureOfContext());
38793888

38803889
if (AnyFunctionType *FuncTy = type->getAs<AnyFunctionType>()) {
3881-
appendFunction(FuncTy, sig, functionMangling, decl);
3890+
appendFunction(FuncTy, sig, functionMangling, decl,
3891+
false /*is recursed into*/);
38823892
} else {
38833893
appendType(type, sig, decl);
38843894
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// RUN: %target-swift-frontend %s -emit-silgen -swift-version 6 | swift-demangle | %FileCheck -check-prefix=CHECK %s
2+
3+
// REQUIRES: concurrency
4+
// REQUIRES: asserts
5+
6+
class NonSendableKlass {}
7+
8+
struct S<T> {
9+
var count: Int { 0 }
10+
}
11+
12+
// CHECK: sil hidden [ossa] @sending_mangling.testRemoveFunctionArg(__owned sending_mangling.NonSendableKlass) -> () : $@convention(thin) (@sil_sending @owned NonSendableKlass) -> () {
13+
func testRemoveFunctionArg(_ x: sending NonSendableKlass) {}
14+
15+
// CHECK: sil hidden [ossa] @sending_mangling.testNoRemoveFunctionArgSubTypeArg(__owned sending_mangling.S<(sending __owned sending_mangling.NonSendableKlass) -> ()>) -> () : $@convention(thin) (@sil_sending S<(sending NonSendableKlass) -> ()>) -> () {
16+
func testNoRemoveFunctionArgSubTypeArg(_ x: sending S<(sending NonSendableKlass) -> ()>) {}
17+
18+
// CHECK: sil hidden [ossa] @sending_mangling.testNoRemoveFunctionArgSubTypeReturn(__owned sending_mangling.S<() -> sending sending_mangling.NonSendableKlass>) -> () : $@convention(thin) (@sil_sending S<() -> sending NonSendableKlass>) -> () {
19+
func testNoRemoveFunctionArgSubTypeReturn(_ x: sending S<() -> sending NonSendableKlass>) {}
20+
21+
// CHECK: sil hidden [ossa] @sending_mangling.testRemoveFunctionResult() -> sending_mangling.NonSendableKlass : $@convention(thin) () -> @sil_sending @owned NonSendableKlass {
22+
func testRemoveFunctionResult() -> sending NonSendableKlass {
23+
}
24+
25+
// CHECK: sil hidden [ossa] @sending_mangling.testNoRemoveFunctionResultSubTypeArg() -> sending_mangling.S<(sending __owned sending_mangling.NonSendableKlass) -> ()> : $@convention(thin) () -> @sil_sending S<(sending NonSendableKlass) -> ()> {
26+
func testNoRemoveFunctionResultSubTypeArg() -> sending S<(sending NonSendableKlass) -> ()> { fatalError() }
27+
28+
// CHECK: sil hidden [ossa] @sending_mangling.testNoRemoveFunctionResultSubTypeResult() -> sending_mangling.S<() -> sending sending_mangling.NonSendableKlass> : $@convention(thin) () -> @sil_sending S<() -> sending NonSendableKlass> {
29+
func testNoRemoveFunctionResultSubTypeResult() -> sending S<() -> sending NonSendableKlass> { fatalError() }
30+
31+
// We do not remove this since the sending is in the subtype of the result.
32+
// CHECK: sil hidden [ossa] @sending_mangling.testNoRemoveFunctionResultImmediateTypedFunctionWithArg() -> (sending __owned sending_mangling.NonSendableKlass) -> () : $@convention(thin) () -> @owned @callee_guaranteed (@sil_sending @owned NonSendableKlass) -> () {
33+
func testNoRemoveFunctionResultImmediateTypedFunctionWithArg() -> ((sending NonSendableKlass) -> ()) { fatalError() }
34+
35+
// CHECK: sil hidden [ossa] @sending_mangling.testNoRemoveFunctionResultImmedateTypedFunctionWithResult() -> () -> sending sending_mangling.NonSendableKlass : $@convention(thin) () -> @owned @callee_guaranteed () -> @sil_sending @owned NonSendableKlass {
36+
func testNoRemoveFunctionResultImmedateTypedFunctionWithResult() -> (() -> sending NonSendableKlass) { fatalError() }
37+
38+
struct MethodTest {
39+
// CHECK: sil hidden [ossa] @sending_mangling.MethodTest.testMethodRemoveFunctionArg(__owned sending_mangling.NonSendableKlass) -> () : $@convention(method) (@sil_sending @owned NonSendableKlass, MethodTest) -> () {
40+
func testMethodRemoveFunctionArg(_ x: sending NonSendableKlass) {}
41+
42+
// CHECK: sil hidden [ossa] @sending_mangling.MethodTest.testNoRemoveFunctionArgSubTypeArg(__owned sending_mangling.S<(sending __owned sending_mangling.NonSendableKlass) -> ()>) -> () : $@convention(method) (@sil_sending S<(sending NonSendableKlass) -> ()>, MethodTest) -> () {
43+
func testNoRemoveFunctionArgSubTypeArg(_ x: sending S<(sending NonSendableKlass) -> ()>) {}
44+
45+
// DEMANGLE sil hidden [ossa] @sending_mangling.MethodTest.testNoRemoveFunctionArgSubTypeReturn(__owned sending_mangling.S<() -> sending sending_mangling.NonSendableKlass>) -> () : $@convention(method) (@sil_sending S<() -> sending NonSendableKlass>, MethodTest) -> () {
46+
func testNoRemoveFunctionArgSubTypeReturn(_ x: sending S<() -> sending NonSendableKlass>) {}
47+
48+
// CHECK: sil hidden [ossa] @sending_mangling.MethodTest.testMethodRemoveFunctionResult() -> sending_mangling.NonSendableKlass : $@convention(method) (MethodTest) -> @sil_sending @owned NonSendableKlass {
49+
func testMethodRemoveFunctionResult() -> sending NonSendableKlass {
50+
}
51+
52+
// CHECK: sil hidden [ossa] @sending_mangling.MethodTest.testNoRemoveFunctionResultSubTypeArg() -> sending_mangling.S<(sending __owned sending_mangling.NonSendableKlass) -> ()> : $@convention(method) (MethodTest) -> @sil_sending S<(sending NonSendableKlass) -> ()> {
53+
func testNoRemoveFunctionResultSubTypeArg() -> sending S<(sending NonSendableKlass) -> ()> { fatalError() }
54+
55+
// CHECK: sil hidden [ossa] @sending_mangling.MethodTest.testNoRemoveFunctionResultSubTypeResult() -> sending_mangling.S<() -> sending sending_mangling.NonSendableKlass> : $@convention(method) (MethodTest) -> @sil_sending S<() -> sending NonSendableKlass> {
56+
func testNoRemoveFunctionResultSubTypeResult() -> sending S<() -> sending NonSendableKlass> { fatalError() }
57+
58+
// CHECK: sil hidden [ossa] @sending_mangling.MethodTest.testNoRemoveFunctionResultImmediateTypedFunctionWithArg() -> (sending __owned sending_mangling.NonSendableKlass) -> () : $@convention(method) (MethodTest) -> @owned @callee_guaranteed (@sil_sending @owned NonSendableKlass) -> () {
59+
func testNoRemoveFunctionResultImmediateTypedFunctionWithArg() -> ((sending NonSendableKlass) -> ()) { fatalError() }
60+
61+
// CHECK: sil hidden [ossa] @sending_mangling.MethodTest.testNoRemoveFunctionResultImmedateTypedFunctionWithResult() -> () -> sending sending_mangling.NonSendableKlass : $@convention(method) (MethodTest) -> @owned @callee_guaranteed () -> @sil_sending @owned NonSendableKlass {
62+
func testNoRemoveFunctionResultImmedateTypedFunctionWithResult() -> (() -> sending NonSendableKlass) { fatalError() }
63+
}
64+
65+
protocol SendingProtocol {
66+
func sendingArg(_ x: sending NonSendableKlass)
67+
func sendingResult() -> sending NonSendableKlass
68+
func sendingArgWithFunctionSendingArg(_ x: sending (sending NonSendableKlass) -> ())
69+
func sendingArgWithFunctionSendingResult() -> sending (sending NonSendableKlass) -> ()
70+
}
71+
72+
extension SendingProtocol {
73+
// CHECK: sil hidden [ossa] @(extension in sending_mangling):sending_mangling.SendingProtocol.sendingArg(__owned sending_mangling.NonSendableKlass) -> () : $@convention(method) <Self where Self : SendingProtocol> (@sil_sending @owned NonSendableKlass, @in_guaranteed Self) -> () {
74+
func sendingArg(_ x: sending NonSendableKlass) {}
75+
76+
// CHECK: sil hidden [ossa] @(extension in sending_mangling):sending_mangling.SendingProtocol.sendingResult() -> sending_mangling.NonSendableKlass : $@convention(method) <Self where Self : SendingProtocol> (@in_guaranteed Self) -> @sil_sending @owned NonSendableKlass {
77+
func sendingResult() -> sending NonSendableKlass { fatalError() }
78+
79+
// CHECK: sil hidden [ossa] @(extension in sending_mangling):sending_mangling.SendingProtocol.sendingArgWithFunctionSendingArg(__owned (sending __owned sending_mangling.NonSendableKlass) -> ()) -> () : $@convention(method) <Self where Self : SendingProtocol> (@sil_sending @owned @noescape @callee_guaranteed (@sil_sending @owned NonSendableKlass) -> (), @in_guaranteed Self) -> () {
80+
func sendingArgWithFunctionSendingArg(_ x: sending (sending NonSendableKlass) -> ()) {}
81+
82+
// CHECK: sil hidden [ossa] @(extension in sending_mangling):sending_mangling.SendingProtocol.sendingArgWithFunctionSendingResult() -> (sending __owned sending_mangling.NonSendableKlass) -> () : $@convention(method) <Self where Self : SendingProtocol> (@in_guaranteed Self) -> @sil_sending @owned @callee_guaranteed (@sil_sending @owned NonSendableKlass) -> () {
83+
func sendingArgWithFunctionSendingResult() -> sending (sending NonSendableKlass) -> () { fatalError() }
84+
}

0 commit comments

Comments
 (0)