Skip to content

Commit cf652e5

Browse files
committed
[sending] Look through the sending type repr when printing the type of a function result using the type repr fallback path.
When we print types in the AST printer if for some reason we cannot find the appropriate type to print or if the user explicitly asks, we fall back and use a type repr instead. This behavior causes a problem due to the implementation of sending results using a sending type repr to communicate that the relevant function has a sending result, but we actually do not use the sending type repr from that point on. So as a result, in this fallback case, we put in one too many sending on the result. rdar://135594964
1 parent 9546d69 commit cf652e5

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4127,8 +4127,34 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {
41274127
}
41284128

41294129
PrintWithOpaqueResultTypeKeywordRAII x(Options);
4130-
printTypeLocForImplicitlyUnwrappedOptional(
4131-
ResultTyLoc, decl->isImplicitlyUnwrappedOptional());
4130+
4131+
// Check if we would go down the type repr path... in such a case, see if
4132+
// we can find a type repr and if that type has a sending type repr. In
4133+
// such a case, look through the sending type repr since we handle it here
4134+
// ourselves.
4135+
bool usedTypeReprPrinting = false;
4136+
{
4137+
llvm::SaveAndRestore<PrintOptions> printOptions(Options);
4138+
Options.PrintOptionalAsImplicitlyUnwrapped = decl->isImplicitlyUnwrappedOptional();
4139+
if (willUseTypeReprPrinting(ResultTyLoc, CurrentType, Options)) {
4140+
if (auto repr = ResultTyLoc.getTypeRepr()) {
4141+
// If we are printing a sending result... and we found that we have to
4142+
// use type repr printing, look through sending type repr. Sending was
4143+
// already applied in our caller.
4144+
if (auto *sendingRepr = dyn_cast<SendingTypeRepr>(repr)) {
4145+
repr = sendingRepr->getBase();
4146+
}
4147+
repr->print(Printer, Options);
4148+
usedTypeReprPrinting = true;
4149+
}
4150+
}
4151+
}
4152+
4153+
// If we printed using type repr printing, do not print again.
4154+
if (!usedTypeReprPrinting) {
4155+
printTypeLocForImplicitlyUnwrappedOptional(
4156+
ResultTyLoc, decl->isImplicitlyUnwrappedOptional());
4157+
}
41324158
Printer.printStructurePost(PrintStructureKind::FunctionReturnType);
41334159
}
41344160
printDeclGenericRequirements(decl);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
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
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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 -DFILE_PREFIX=MyFile %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+
23+
public func test() -> sending NonSendableKlass { NonSendableKlass() }

0 commit comments

Comments
 (0)