Skip to content

Commit 6662a48

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

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
@@ -3848,7 +3848,14 @@ static void printParameterFlags(ASTPrinter &printer,
38483848
const PrintOptions &options,
38493849
const ParamDecl *param,
38503850
ParameterTypeFlags flags,
3851-
bool escaping) {
3851+
bool escaping,
3852+
bool isIsolatedToCaller = false) {
3853+
// Always print `nonisolated(nonsending)` specifier on a parameter
3854+
// first, to avoid any issues with ordering.
3855+
if (isIsolatedToCaller) {
3856+
printer.printKeyword("nonisolated(nonsending)", options, " ");
3857+
}
3858+
38523859
if (!options.excludeAttrKind(TypeAttrKind::Autoclosure) &&
38533860
flags.isAutoClosure())
38543861
printer.printAttrName("@autoclosure ");
@@ -4024,11 +4031,24 @@ void PrintAST::printOneParameter(const ParamDecl *param,
40244031

40254032
printArgName();
40264033

4034+
auto interfaceTy = param->getInterfaceType();
4035+
4036+
// If type of this parameter is isolated to a caller, let's
4037+
// strip the isolation from the type to avoid printing it as
4038+
// part of the function type because that would break ordering
4039+
// between specifiers and attributes.
4040+
if (param->isCallerIsolated()) {
4041+
if (auto *funcTy = dyn_cast<AnyFunctionType>(interfaceTy.getPointer())) {
4042+
interfaceTy =
4043+
funcTy->withIsolation(FunctionTypeIsolation::forNonIsolated());
4044+
}
4045+
}
4046+
40274047
TypeLoc TheTypeLoc;
40284048
if (auto *repr = param->getTypeRepr()) {
4029-
TheTypeLoc = TypeLoc(repr, param->getInterfaceType());
4049+
TheTypeLoc = TypeLoc(repr, interfaceTy);
40304050
} else {
4031-
TheTypeLoc = TypeLoc::withoutLoc(param->getInterfaceType());
4051+
TheTypeLoc = TypeLoc::withoutLoc(interfaceTy);
40324052
}
40334053

40344054
{
@@ -4040,7 +4060,8 @@ void PrintAST::printOneParameter(const ParamDecl *param,
40404060
!willUseTypeReprPrinting(TheTypeLoc, CurrentType, Options)) {
40414061
auto type = TheTypeLoc.getType();
40424062
printParameterFlags(Printer, Options, param, paramFlags,
4043-
isEscaping(type));
4063+
isEscaping(type),
4064+
param->isCallerIsolated());
40444065
}
40454066

40464067
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)