@@ -3848,13 +3848,13 @@ static void printParameterFlags(ASTPrinter &printer,
38483848 const PrintOptions &options,
38493849 const ParamDecl *param,
38503850 ParameterTypeFlags flags,
3851- bool escaping) {
3852- if (!options. excludeAttrKind (TypeAttrKind::Autoclosure) &&
3853- flags. isAutoClosure ())
3854- printer. printAttrName ( " @autoclosure " );
3855- if (!options. excludeAttrKind (TypeAttrKind::NoDerivative) &&
3856- flags. isNoDerivative ())
3857- printer. printAttrName ( " @noDerivative " );
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+ }
38583858
38593859 switch (flags.getOwnershipSpecifier ()) {
38603860 case ParamSpecifier::Default:
@@ -3883,7 +3883,7 @@ static void printParameterFlags(ASTPrinter &printer,
38833883
38843884 if (flags.isSending ()) {
38853885 if (!options.SuppressSendingArgsAndResults ) {
3886- printer.printAttrName (" sending " );
3886+ printer.printKeyword (" sending" , options, " " );
38873887 } else if (flags.getOwnershipSpecifier () ==
38883888 ParamSpecifier::ImplicitlyCopyableConsuming) {
38893889 // Ok. We are suppressing sending. If our ownership specifier was
@@ -3901,14 +3901,24 @@ static void printParameterFlags(ASTPrinter &printer,
39013901 printer.printKeyword (" isolated" , options, " " );
39023902 }
39033903
3904- if (!options.excludeAttrKind (TypeAttrKind::Escaping) && escaping)
3905- printer.printKeyword (" @escaping" , options, " " );
3906-
39073904 if (flags.isCompileTimeLiteral ())
39083905 printer.printKeyword (" _const" , options, " " );
3909-
3906+
3907+ if (!options.excludeAttrKind (TypeAttrKind::Autoclosure) &&
3908+ flags.isAutoClosure ())
3909+ printer.printAttrName (" @autoclosure " );
3910+ if (!options.excludeAttrKind (TypeAttrKind::NoDerivative) &&
3911+ flags.isNoDerivative ())
3912+ printer.printAttrName (" @noDerivative " );
3913+
3914+ // `inout` implies `@escaping`
3915+ if (flags.getOwnershipSpecifier () != ParamSpecifier::InOut) {
3916+ if (!options.excludeAttrKind (TypeAttrKind::Escaping) && escaping)
3917+ printer.printAttrName (" @escaping " );
3918+ }
3919+
39103920 if (flags.isConstValue ())
3911- printer.printKeyword (" @const" , options, " " );
3921+ printer.printAttrName (" @const " );
39123922}
39133923
39143924void PrintAST::visitVarDecl (VarDecl *decl) {
@@ -4024,11 +4034,24 @@ void PrintAST::printOneParameter(const ParamDecl *param,
40244034
40254035 printArgName ();
40264036
4037+ auto interfaceTy = param->getInterfaceType ();
4038+
4039+ // If type of this parameter is isolated to a caller, let's
4040+ // strip the isolation from the type to avoid printing it as
4041+ // part of the function type because that would break ordering
4042+ // between specifiers and attributes.
4043+ if (param->isCallerIsolated ()) {
4044+ if (auto *funcTy = dyn_cast<AnyFunctionType>(interfaceTy.getPointer ())) {
4045+ interfaceTy =
4046+ funcTy->withIsolation (FunctionTypeIsolation::forNonIsolated ());
4047+ }
4048+ }
4049+
40274050 TypeLoc TheTypeLoc;
40284051 if (auto *repr = param->getTypeRepr ()) {
4029- TheTypeLoc = TypeLoc (repr, param-> getInterfaceType () );
4052+ TheTypeLoc = TypeLoc (repr, interfaceTy );
40304053 } else {
4031- TheTypeLoc = TypeLoc::withoutLoc (param-> getInterfaceType () );
4054+ TheTypeLoc = TypeLoc::withoutLoc (interfaceTy );
40324055 }
40334056
40344057 {
@@ -4040,7 +4063,8 @@ void PrintAST::printOneParameter(const ParamDecl *param,
40404063 !willUseTypeReprPrinting (TheTypeLoc, CurrentType, Options)) {
40414064 auto type = TheTypeLoc.getType ();
40424065 printParameterFlags (Printer, Options, param, paramFlags,
4043- isEscaping (type));
4066+ isEscaping (type),
4067+ param->isCallerIsolated ());
40444068 }
40454069
40464070 printTypeLocForImplicitlyUnwrappedOptional (
0 commit comments