@@ -3847,13 +3847,13 @@ static void printParameterFlags(ASTPrinter &printer,
38473847 const PrintOptions &options,
38483848 const ParamDecl *param,
38493849 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+ }
38573857
38583858 switch (flags.getOwnershipSpecifier ()) {
38593859 case ParamSpecifier::Default:
@@ -3882,7 +3882,7 @@ static void printParameterFlags(ASTPrinter &printer,
38823882
38833883 if (flags.isSending ()) {
38843884 if (!options.SuppressSendingArgsAndResults ) {
3885- printer.printAttrName (" sending " );
3885+ printer.printKeyword (" sending" , options, " " );
38863886 } else if (flags.getOwnershipSpecifier () ==
38873887 ParamSpecifier::ImplicitlyCopyableConsuming) {
38883888 // Ok. We are suppressing sending. If our ownership specifier was
@@ -3900,14 +3900,24 @@ static void printParameterFlags(ASTPrinter &printer,
39003900 printer.printKeyword (" isolated" , options, " " );
39013901 }
39023902
3903- if (!options.excludeAttrKind (TypeAttrKind::Escaping) && escaping)
3904- printer.printKeyword (" @escaping" , options, " " );
3905-
39063903 if (flags.isCompileTimeLiteral ())
39073904 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+
39093919 if (flags.isConstValue ())
3910- printer.printKeyword (" @const" , options, " " );
3920+ printer.printAttrName (" @const " );
39113921}
39123922
39133923void PrintAST::visitVarDecl (VarDecl *decl) {
@@ -4016,11 +4026,24 @@ void PrintAST::printOneParameter(const ParamDecl *param,
40164026
40174027 printArgName ();
40184028
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+
40194042 TypeLoc TheTypeLoc;
40204043 if (auto *repr = param->getTypeRepr ()) {
4021- TheTypeLoc = TypeLoc (repr, param-> getInterfaceType () );
4044+ TheTypeLoc = TypeLoc (repr, interfaceTy );
40224045 } else {
4023- TheTypeLoc = TypeLoc::withoutLoc (param-> getInterfaceType () );
4046+ TheTypeLoc = TypeLoc::withoutLoc (interfaceTy );
40244047 }
40254048
40264049 {
@@ -4032,7 +4055,8 @@ void PrintAST::printOneParameter(const ParamDecl *param,
40324055 !willUseTypeReprPrinting (TheTypeLoc, CurrentType, Options)) {
40334056 auto type = TheTypeLoc.getType ();
40344057 printParameterFlags (Printer, Options, param, paramFlags,
4035- isEscaping (type));
4058+ isEscaping (type),
4059+ param->isCallerIsolated ());
40364060 }
40374061
40384062 printTypeLocForImplicitlyUnwrappedOptional (
0 commit comments