Skip to content

Commit 2eea17a

Browse files
authored
Merge pull request #76491 from gottesmm/rdar135594964
[sending] Look through the sending type repr when printing the type of a function result using the type repr fallback path.
2 parents 43e1935 + 15a34a5 commit 2eea17a

File tree

4 files changed

+105
-4
lines changed

4 files changed

+105
-4
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4144,8 +4144,35 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {
41444144
}
41454145

41464146
PrintWithOpaqueResultTypeKeywordRAII x(Options);
4147-
printTypeLocForImplicitlyUnwrappedOptional(
4148-
ResultTyLoc, decl->isImplicitlyUnwrappedOptional());
4147+
4148+
// Check if we would go down the type repr path... in such a case, see if
4149+
// we can find a type repr and if that type has a sending type repr. In
4150+
// such a case, look through the sending type repr since we handle it here
4151+
// ourselves.
4152+
bool usedTypeReprPrinting = false;
4153+
{
4154+
llvm::SaveAndRestore<PrintOptions> printOptions(Options);
4155+
Options.PrintOptionalAsImplicitlyUnwrapped =
4156+
decl->isImplicitlyUnwrappedOptional();
4157+
if (willUseTypeReprPrinting(ResultTyLoc, CurrentType, Options)) {
4158+
if (auto repr = ResultTyLoc.getTypeRepr()) {
4159+
// If we are printing a sending result... and we found that we have
4160+
// to use type repr printing, look through sending type repr.
4161+
// Sending was already applied in our caller.
4162+
if (auto *sendingRepr = dyn_cast<SendingTypeRepr>(repr)) {
4163+
repr = sendingRepr->getBase();
4164+
}
4165+
repr->print(Printer, Options);
4166+
usedTypeReprPrinting = true;
4167+
}
4168+
}
4169+
}
4170+
4171+
// If we printed using type repr printing, do not print again.
4172+
if (!usedTypeReprPrinting) {
4173+
printTypeLocForImplicitlyUnwrappedOptional(
4174+
ResultTyLoc, decl->isImplicitlyUnwrappedOptional());
4175+
}
41494176
Printer.printStructurePost(PrintStructureKind::FunctionReturnType);
41504177
}
41514178
printDeclGenericRequirements(decl);

lib/AST/TypeRepr.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,21 @@ void FunctionTypeRepr::printImpl(ASTPrinter &Printer,
435435
}
436436
Printer << " -> ";
437437
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
438-
printTypeRepr(RetTy, Printer, Opts);
438+
439+
// Check if we are supposed to suppress sending results. If so, look through
440+
// the ret ty if it is a Sending TypeRepr.
441+
//
442+
// DISCUSSION: The reason why we do this is that Sending TypeRepr is used for
443+
// arguments and results... and we need the arguments case when we suppress to
444+
// print __owned. So this lets us handle both cases.
445+
auto ActualRetTy = RetTy;
446+
if (Opts.SuppressSendingArgsAndResults) {
447+
if (auto *x = dyn_cast<SendingTypeRepr>(RetTy)) {
448+
ActualRetTy = x->getBase();
449+
}
450+
}
451+
printTypeRepr(ActualRetTy, Printer, Opts);
452+
439453
Printer.printStructurePost(PrintStructureKind::FunctionReturnType);
440454
Printer.printStructurePost(PrintStructureKind::FunctionType);
441455
}
@@ -853,7 +867,13 @@ void SpecifierTypeRepr::printImpl(ASTPrinter &Printer,
853867
Printer.printKeyword("isolated", Opts, " ");
854868
break;
855869
case TypeReprKind::Sending:
856-
Printer.printKeyword("sending", Opts, " ");
870+
// This handles the argument case. The result case is handled in
871+
// FunctionTypeRepr.
872+
if (!Opts.SuppressSendingArgsAndResults) {
873+
Printer.printKeyword("sending", Opts, " ");
874+
} else {
875+
Printer.printKeyword("__owned", Opts, " ");
876+
}
857877
break;
858878
case TypeReprKind::CompileTimeConst:
859879
Printer.printKeyword("_const", Opts, " ");
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
// CHECK: #if compiler(>=5.3) && $SendingArgsAndResults
3+
// CHECK-NEXT: public func test() -> sending NonSendableKlass
4+
// CHECK-NEXT: #else
5+
// CHECK-NEXT: public func test() -> NonSendableKlass
6+
// CHECK-NEXT: #endif
7+
8+
// CHECK: #if compiler(>=5.3) && $SendingArgsAndResults
9+
// CHECK-NEXT: public func test2(_ x: sending NonSendableKlass)
10+
// CHECK-NEXT: #else
11+
// CHECK-NEXT: public func test2(_ x: __owned NonSendableKlass)
12+
// CHECK-NEXT: #endif
13+
14+
// CHECK: #if compiler(>=5.3) && $SendingArgsAndResults
15+
// CHECK-NEXT: @_Concurrency.MainActor public var closure: () -> sending NonSendableKlass
16+
// CHECK-NEXT: #else
17+
// CHECK-NEXT: @_Concurrency.MainActor public var closure: () -> NonSendableKlass
18+
// CHECK-NEXT: #endif
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %s -typecheck -enable-library-evolution -parse-as-library -emit-module-interface-path - -module-name MyFile -swift-version 6 | %FileCheck %s
3+
// RUN: %target-swift-frontend %s -typecheck -enable-library-evolution -parse-as-library -emit-module-interface-path - -module-name MyFile -swift-version 6 -module-interface-preserve-types-as-written | %FileCheck %S/Inputs/sending_interfacefile_printing_repr_filecheck
4+
5+
// The force printing type reprs option is only available in asserts builds.
6+
// REQUIRES: asserts
7+
8+
// This test validates that when we produce interface files we produce the
9+
// correct interface file for sending when printing normally or with type reprs
10+
// enabled.
11+
12+
public class NonSendableKlass {}
13+
14+
// The two possible outputs are MyFile.NonSendableKlass and NonSendableKlass.
15+
//
16+
// So we just check for an optional M
17+
// CHECK: #if compiler(>=5.3) && $SendingArgsAndResults
18+
// CHECK-NEXT: public func test() -> sending MyFile.NonSendableKlass
19+
// CHECK-NEXT: #else
20+
// CHECK-NEXT: public func test() -> MyFile.NonSendableKlass
21+
// CHECK-NEXT: #endif
22+
public func test() -> sending NonSendableKlass { NonSendableKlass() }
23+
24+
// CHECK: #if compiler(>=5.3) && $SendingArgsAndResults
25+
// CHECK-NEXT: public func test2(_ x: sending MyFile.NonSendableKlass)
26+
// CHECK-NEXT: #else
27+
// CHECK-NEXT: public func test2(_ x: __owned MyFile.NonSendableKlass)
28+
// CHECK-NEXT: #endif
29+
public func test2(_ x: sending NonSendableKlass) {}
30+
31+
// CHECK: #if compiler(>=5.3) && $SendingArgsAndResults
32+
// CHECK-NEXT: @_Concurrency.MainActor public var closure: () -> sending MyFile.NonSendableKlass
33+
// CHECK-NEXT: #else
34+
// CHECK-NEXT: @_Concurrency.MainActor public var closure: () -> MyFile.NonSendableKlass
35+
// CHECK-NEXT: #endif
36+
@MainActor public var closure: () -> sending NonSendableKlass = { NonSendableKlass() }

0 commit comments

Comments
 (0)