Skip to content

Commit 668297e

Browse files
committed
Don't print conformance attributes redundantly in -preserve-types-as-written.
Since we no longer remove these attributes from the AttributedTypeRepr, if we print based on the TypeRepr, we'll print them twice. The best solution is to only print the attributes based on the inheritance clause if we're not printing the type based on the TypeRepr. Fixes rdar://122965951.
1 parent 2ded8ba commit 668297e

File tree

2 files changed

+33
-12
lines changed

2 files changed

+33
-12
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -887,8 +887,10 @@ class PrintAST : public ASTVisitor<PrintAST> {
887887
printTransformedTypeWithOptions(T, Options);
888888
}
889889

890-
void printTypeLocWithOptions(const TypeLoc &TL, const PrintOptions &options) {
890+
void printTypeLocWithOptions(const TypeLoc &TL, const PrintOptions &options,
891+
std::optional<llvm::function_ref<void()>> printBeforeType = std::nullopt) {
891892
if (CurrentType && TL.getType()) {
893+
if (printBeforeType) (*printBeforeType)();
892894
printTransformedTypeWithOptions(TL.getType(), options);
893895
return;
894896
}
@@ -901,11 +903,21 @@ class PrintAST : public ASTVisitor<PrintAST> {
901903
return;
902904
}
903905

906+
if (printBeforeType) (*printBeforeType)();
904907
TL.getType().print(Printer, options);
905908
}
906909

907910
void printTypeLoc(const TypeLoc &TL) { printTypeLocWithOptions(TL, Options); }
908911

912+
/// Print a TypeLoc. If we decide to print based on the type, rather than
913+
/// based on the TypeRepr, call the given function before printing the type;
914+
/// this is useful if there are attributes in the TypeRepr which don't end
915+
/// up being part of the type, such as `@unchecked` in inheritance clauses.
916+
void printTypeLoc(const TypeLoc &TL,
917+
llvm::function_ref<void()> printBeforeType) {
918+
printTypeLocWithOptions(TL, Options, printBeforeType);
919+
}
920+
909921
void printTypeLocForImplicitlyUnwrappedOptional(TypeLoc TL, bool IUO) {
910922
PrintOptions options = Options;
911923
options.PrintOptionalAsImplicitlyUnwrapped = IUO;
@@ -2710,15 +2722,15 @@ void PrintAST::printInherited(const Decl *decl) {
27102722
Printer << ": ";
27112723

27122724
interleave(TypesToPrint, [&](InheritedEntry inherited) {
2713-
if (inherited.isUnchecked())
2714-
Printer << "@unchecked ";
2715-
if (inherited.isRetroactive() &&
2716-
!llvm::is_contained(Options.ExcludeAttrList, TypeAttrKind::Retroactive))
2717-
Printer << "@retroactive ";
2718-
if (inherited.isPreconcurrency())
2719-
Printer << "@preconcurrency ";
2720-
2721-
printTypeLoc(inherited);
2725+
printTypeLoc(inherited, [&] {
2726+
if (inherited.isUnchecked())
2727+
Printer << "@unchecked ";
2728+
if (inherited.isRetroactive() &&
2729+
!llvm::is_contained(Options.ExcludeAttrList, TypeAttrKind::Retroactive))
2730+
Printer << "@retroactive ";
2731+
if (inherited.isPreconcurrency())
2732+
Printer << "@preconcurrency ";
2733+
});
27222734
}, [&]() {
27232735
Printer << ", ";
27242736
});

test/ModuleInterface/concurrency.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ public struct InferredPreconcurrencyMainActor: PreconcurrencyMainProtocol {
4343
public func requirement() {}
4444
}
4545

46+
// rdar://122965951
47+
public struct UncheckedSendable: @unchecked Sendable {}
48+
extension UnsafePointer : @retroactive @unchecked Sendable {}
49+
4650
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency -I %t
4751

4852
#else
@@ -54,7 +58,7 @@ func callFn() async {
5458
}
5559
#endif
5660

57-
// RUN: %FileCheck %s < %t/Library.swiftinterface
61+
// RUN: %FileCheck --check-prefix=CHECK --check-prefix=CHECK-TYPECHECKED %s < %t/Library.swiftinterface
5862
// CHECK: // swift-module-flags:{{.*}} -enable-experimental-concurrency
5963
// CHECK: public func fn() async
6064
// CHECK: public func reasyncFn(_: () async -> ()) reasync
@@ -77,7 +81,12 @@ func callFn() async {
7781
// CHECK-NEXT: @_Concurrency.MainActor @preconcurrency public func requirement()
7882
// CHECK-NEXT: }
7983

84+
// CHECK-TYPECHECKED: public struct UncheckedSendable : @unchecked Swift.Sendable
85+
// CHECK-ASWRITTEN: public struct UncheckedSendable : @unchecked Sendable
86+
87+
// CHECK-TYPECHECKED: extension Swift.UnsafePointer : @unchecked @retroactive Swift.Sendable
88+
// CHECK-ASWRITTEN: extension UnsafePointer : @retroactive @unchecked Sendable
8089

8190
// RUN: %target-swift-emit-module-interface(%t/LibraryPreserveTypesAsWritten.swiftinterface) %s -enable-experimental-concurrency -DLIBRARY -module-name LibraryPreserveTypesAsWritten -module-interface-preserve-types-as-written
8291
// RUN: %target-swift-typecheck-module-from-interface(%t/LibraryPreserveTypesAsWritten.swiftinterface) -enable-experimental-concurrency
83-
// RUN: %FileCheck %s < %t/LibraryPreserveTypesAsWritten.swiftinterface
92+
// RUN: %FileCheck --check-prefix=CHECK --check-prefix=CHECK-ASWRITTEN %s < %t/LibraryPreserveTypesAsWritten.swiftinterface

0 commit comments

Comments
 (0)