@@ -3847,13 +3847,13 @@ static void printParameterFlags(ASTPrinter &printer,
3847
3847
const PrintOptions &options,
3848
3848
const ParamDecl *param,
3849
3849
ParameterTypeFlags flags,
3850
- bool escaping) {
3851
- if (!options. excludeAttrKind (TypeAttrKind::Autoclosure) &&
3852
- flags. isAutoClosure ())
3853
- printer. printAttrName ( " @autoclosure " );
3854
- if (!options. excludeAttrKind (TypeAttrKind::NoDerivative) &&
3855
- flags. isNoDerivative ())
3856
- printer. printAttrName ( " @noDerivative " );
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
3857
3858
3858
switch (flags.getOwnershipSpecifier ()) {
3859
3859
case ParamSpecifier::Default:
@@ -3882,7 +3882,7 @@ static void printParameterFlags(ASTPrinter &printer,
3882
3882
3883
3883
if (flags.isSending ()) {
3884
3884
if (!options.SuppressSendingArgsAndResults ) {
3885
- printer.printAttrName (" sending " );
3885
+ printer.printKeyword (" sending" , options, " " );
3886
3886
} else if (flags.getOwnershipSpecifier () ==
3887
3887
ParamSpecifier::ImplicitlyCopyableConsuming) {
3888
3888
// Ok. We are suppressing sending. If our ownership specifier was
@@ -3900,14 +3900,24 @@ static void printParameterFlags(ASTPrinter &printer,
3900
3900
printer.printKeyword (" isolated" , options, " " );
3901
3901
}
3902
3902
3903
- if (!options.excludeAttrKind (TypeAttrKind::Escaping) && escaping)
3904
- printer.printKeyword (" @escaping" , options, " " );
3905
-
3906
3903
if (flags.isCompileTimeLiteral ())
3907
3904
printer.printKeyword (" _const" , options, " " );
3908
-
3905
+
3906
+ if (!options.excludeAttrKind (TypeAttrKind::Autoclosure) &&
3907
+ flags.isAutoClosure ())
3908
+ printer.printAttrName (" @autoclosure " );
3909
+ if (!options.excludeAttrKind (TypeAttrKind::NoDerivative) &&
3910
+ flags.isNoDerivative ())
3911
+ printer.printAttrName (" @noDerivative " );
3912
+
3913
+ // `inout` implies `@escaping`
3914
+ if (flags.getOwnershipSpecifier () != ParamSpecifier::InOut) {
3915
+ if (!options.excludeAttrKind (TypeAttrKind::Escaping) && escaping)
3916
+ printer.printAttrName (" @escaping " );
3917
+ }
3918
+
3909
3919
if (flags.isConstValue ())
3910
- printer.printKeyword (" @const" , options, " " );
3920
+ printer.printAttrName (" @const " );
3911
3921
}
3912
3922
3913
3923
void PrintAST::visitVarDecl (VarDecl *decl) {
@@ -4016,11 +4026,24 @@ void PrintAST::printOneParameter(const ParamDecl *param,
4016
4026
4017
4027
printArgName ();
4018
4028
4029
+ auto interfaceTy = param->getInterfaceType ();
4030
+
4031
+ // If type of this parameter is isolated to a caller, let's
4032
+ // strip the isolation from the type to avoid printing it as
4033
+ // part of the function type because that would break ordering
4034
+ // between specifiers and attributes.
4035
+ if (param->isCallerIsolated ()) {
4036
+ if (auto *funcTy = dyn_cast<AnyFunctionType>(interfaceTy.getPointer ())) {
4037
+ interfaceTy =
4038
+ funcTy->withIsolation (FunctionTypeIsolation::forNonIsolated ());
4039
+ }
4040
+ }
4041
+
4019
4042
TypeLoc TheTypeLoc;
4020
4043
if (auto *repr = param->getTypeRepr ()) {
4021
- TheTypeLoc = TypeLoc (repr, param-> getInterfaceType () );
4044
+ TheTypeLoc = TypeLoc (repr, interfaceTy );
4022
4045
} else {
4023
- TheTypeLoc = TypeLoc::withoutLoc (param-> getInterfaceType () );
4046
+ TheTypeLoc = TypeLoc::withoutLoc (interfaceTy );
4024
4047
}
4025
4048
4026
4049
{
@@ -4032,7 +4055,8 @@ void PrintAST::printOneParameter(const ParamDecl *param,
4032
4055
!willUseTypeReprPrinting (TheTypeLoc, CurrentType, Options)) {
4033
4056
auto type = TheTypeLoc.getType ();
4034
4057
printParameterFlags (Printer, Options, param, paramFlags,
4035
- isEscaping (type));
4058
+ isEscaping (type),
4059
+ param->isCallerIsolated ());
4036
4060
}
4037
4061
4038
4062
printTypeLocForImplicitlyUnwrappedOptional (
0 commit comments