Skip to content

Commit 9cf984a

Browse files
committed
[AST] ASTPrinter: Always print nonisolated(nonsending) parameter specifier first
This avoids any possible positioning issues between specifiers and attributes. (cherry picked from commit 6662a48)
1 parent 0af7032 commit 9cf984a

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3847,7 +3847,14 @@ static void printParameterFlags(ASTPrinter &printer,
38473847
const PrintOptions &options,
38483848
const ParamDecl *param,
38493849
ParameterTypeFlags flags,
3850-
bool escaping) {
3850+
bool escaping,
3851+
bool isIsolatedToCaller = false) {
3852+
// Always print `nonisolated(nonsending)` specifier on a parameter
3853+
// first, to avoid any issues with ordering.
3854+
if (isIsolatedToCaller) {
3855+
printer.printKeyword("nonisolated(nonsending)", options, " ");
3856+
}
3857+
38513858
if (!options.excludeAttrKind(TypeAttrKind::Autoclosure) &&
38523859
flags.isAutoClosure())
38533860
printer.printAttrName("@autoclosure ");
@@ -4016,11 +4023,24 @@ void PrintAST::printOneParameter(const ParamDecl *param,
40164023

40174024
printArgName();
40184025

4026+
auto interfaceTy = param->getInterfaceType();
4027+
4028+
// If type of this parameter is isolated to a caller, let's
4029+
// strip the isolation from the type to avoid printing it as
4030+
// part of the function type because that would break ordering
4031+
// between specifiers and attributes.
4032+
if (param->isCallerIsolated()) {
4033+
if (auto *funcTy = dyn_cast<AnyFunctionType>(interfaceTy.getPointer())) {
4034+
interfaceTy =
4035+
funcTy->withIsolation(FunctionTypeIsolation::forNonIsolated());
4036+
}
4037+
}
4038+
40194039
TypeLoc TheTypeLoc;
40204040
if (auto *repr = param->getTypeRepr()) {
4021-
TheTypeLoc = TypeLoc(repr, param->getInterfaceType());
4041+
TheTypeLoc = TypeLoc(repr, interfaceTy);
40224042
} else {
4023-
TheTypeLoc = TypeLoc::withoutLoc(param->getInterfaceType());
4043+
TheTypeLoc = TypeLoc::withoutLoc(interfaceTy);
40244044
}
40254045

40264046
{
@@ -4032,7 +4052,8 @@ void PrintAST::printOneParameter(const ParamDecl *param,
40324052
!willUseTypeReprPrinting(TheTypeLoc, CurrentType, Options)) {
40334053
auto type = TheTypeLoc.getType();
40344054
printParameterFlags(Printer, Options, param, paramFlags,
4035-
isEscaping(type));
4055+
isEscaping(type),
4056+
param->isCallerIsolated());
40364057
}
40374058

40384059
printTypeLocForImplicitlyUnwrappedOptional(

test/ModuleInterface/execution_behavior_attrs.swift

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

66
// REQUIRES: concurrency
77

8+
public struct TestWithAttrs {
9+
// CHECK: #if compiler(>=5.3) && $AsyncExecutionBehaviorAttributes
10+
// CHECK-NEXT: public func test(_: nonisolated(nonsending) @escaping () async -> Swift.Void)
11+
// CHECK-NEXT: #endif
12+
public func test(_: nonisolated(nonsending) @escaping () async -> Void) {}
13+
}
14+
815
public struct Test {
916
// CHECK: #if compiler(>=5.3) && $AsyncExecutionBehaviorAttributes
1017
// CHECK-NEXT: nonisolated(nonsending) public init() async

0 commit comments

Comments
 (0)