Skip to content

Commit 33a059f

Browse files
authored
Merge pull request #84136 from hnrklssn/print-lifetime-arg-backticks
[ASTPrinter] Escape @_lifetime arguments when needed Printing a LifetimeDescriptor would never wrap it in backticks (even if originally wrapped in backticks). This would result in the output not being able to be parsed rdar://159992995
2 parents ca35ad7 + 5ea8452 commit 33a059f

File tree

4 files changed

+82
-15
lines changed

4 files changed

+82
-15
lines changed

include/swift/AST/LifetimeDependence.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -141,17 +141,7 @@ struct LifetimeDescriptor {
141141
return getName().str() == "immortal";
142142
}
143143

144-
std::string getString() const {
145-
switch (kind) {
146-
case DescriptorKind::Named:
147-
return getName().str().str();
148-
case DescriptorKind::Ordered:
149-
return std::to_string(getIndex());
150-
case DescriptorKind::Self:
151-
return "self";
152-
}
153-
llvm_unreachable("Invalid DescriptorKind");
154-
}
144+
std::string getString() const;
155145
};
156146

157147
class LifetimeEntry final

lib/AST/LifetimeDependence.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "swift/AST/LifetimeDependence.h"
1414
#include "swift/AST/ASTContext.h"
15+
#include "swift/AST/ASTPrinter.h"
1516
#include "swift/AST/Builtins.h"
1617
#include "swift/AST/ConformanceLookup.h"
1718
#include "swift/AST/Decl.h"
@@ -29,6 +30,24 @@
2930

3031
namespace swift {
3132

33+
std::string LifetimeDescriptor::getString() const {
34+
switch (kind) {
35+
case DescriptorKind::Named: {
36+
bool shouldEscape =
37+
escapeIdentifierInContext(getName(), PrintNameContext::Normal);
38+
if (shouldEscape) {
39+
return ("`" + getName().str() + "`").str();
40+
}
41+
return getName().str().str();
42+
}
43+
case DescriptorKind::Ordered:
44+
return std::to_string(getIndex());
45+
case DescriptorKind::Self:
46+
return "self";
47+
}
48+
llvm_unreachable("Invalid DescriptorKind");
49+
}
50+
3251
LifetimeEntry *
3352
LifetimeEntry::create(const ASTContext &ctx, SourceLoc startLoc,
3453
SourceLoc endLoc, ArrayRef<LifetimeDescriptor> sources,

test/IDE/print_lifetime_attr.swift

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// REQUIRES: swift_feature_Lifetimes
2+
// REQUIRES: swift_feature_LifetimeDependence
3+
4+
// RUN: %empty-directory(%t)
5+
// RUN: split-file %s %t
6+
7+
// RUN: %target-swift-ide-test -enable-experimental-feature Lifetimes -enable-experimental-feature LifetimeDependence -print-swift-file-interface -source-filename %t/test.swift > %t/interface.txt
8+
// RUN: diff %t/interface.txt %t/interface.txt.expected
9+
10+
//--- test.swift
11+
public struct S : ~Escapable {
12+
@_lifetime(immortal)
13+
init() {}
14+
}
15+
16+
@_lifetime(foo: copy foo)
17+
public func fooFunc(_ foo: inout S) {}
18+
19+
@_lifetime(&bar)
20+
public func barFunc(_ bar: inout S) -> S {
21+
return bar
22+
}
23+
24+
@_lifetime(`func`: copy `func`)
25+
public func funcFunc(func: inout S) {}
26+
27+
public struct T : ~Escapable {
28+
let s: S
29+
@_lifetime(borrow self)
30+
func selfFunc() -> S { return s }
31+
@_lifetime(borrow `self`)
32+
func selfFunc2(`self`: S) -> S { return `self` }
33+
}
34+
35+
//--- interface.txt.expected
36+
37+
public struct S : ~Escapable {
38+
39+
@_lifetime(immortal)
40+
internal init()
41+
}
42+
@_lifetime(foo: copy foo)
43+
public func fooFunc(_ foo: inout S)
44+
@_lifetime(&bar)
45+
public func barFunc(_ bar: inout S) -> S
46+
@_lifetime(`func`: copy `func`)
47+
public func funcFunc(func: inout S)
48+
49+
public struct T : ~Escapable {
50+
51+
internal let s: S
52+
53+
@_lifetime(borrow self)
54+
internal func selfFunc() -> S
55+
56+
@_lifetime(borrow `self`)
57+
internal func selfFunc2(self: S) -> S
58+
}

test/Interop/C/swiftify-import/counted-by-noescape.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import CountedByNoEscapeClang
1818

1919
// CHECK-NEXT: /// This is an auto-generated wrapper for safer interop
2020
// CHECK-NEXT: @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *)
21-
// CHECK-NEXT: @_lifetime(func: copy func)
21+
// CHECK-NEXT: @_lifetime(`func`: copy `func`)
2222
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func clash(func: inout MutableSpan<Int32>?, clash where: Int32)
2323

2424
// CHECK-NEXT: /// This is an auto-generated wrapper for safer interop
@@ -38,7 +38,7 @@ import CountedByNoEscapeClang
3838

3939
// CHECK-NEXT: /// This is an auto-generated wrapper for safer interop
4040
// CHECK-NEXT: @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *)
41-
// CHECK-NEXT: @_lifetime(func: copy func)
41+
// CHECK-NEXT: @_lifetime(`func`: copy `func`)
4242
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func funcRenamed(func: inout MutableSpan<Int32>?, extension: Int32, init: Int32, open: Int32, var: Int32, is: Int32, as: Int32, in: Int32, guard: Int32, where: Int32) -> UnsafeMutableRawPointer!
4343

4444
// CHECK-NEXT: /// This is an auto-generated wrapper for safer interop
@@ -53,7 +53,7 @@ import CountedByNoEscapeClang
5353

5454
// CHECK-NEXT: /// This is an auto-generated wrapper for safer interop
5555
// CHECK-NEXT: @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *)
56-
// CHECK-NEXT: @_lifetime(func: copy func)
56+
// CHECK-NEXT: @_lifetime(`func`: copy `func`)
5757
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func keyword(_ func: inout MutableSpan<Int32>?, _ extension: Int32, _ init: Int32, _ open: Int32, _ var: Int32, _ is: Int32, _ as: Int32, _ in: Int32, _ guard: Int32, _ where: Int32)
5858

5959
// CHECK-NEXT: /// This is an auto-generated wrapper for safer interop
@@ -83,7 +83,7 @@ import CountedByNoEscapeClang
8383

8484
// CHECK-NEXT: /// This is an auto-generated wrapper for safer interop
8585
// CHECK-NEXT: @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *)
86-
// CHECK-NEXT: @_lifetime(func: copy func)
86+
// CHECK-NEXT: @_lifetime(`func`: copy `func`)
8787
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func open(func: inout MutableSpan<Int32>?, open where: Int32)
8888

8989
// CHECK-NEXT: /// This is an auto-generated wrapper for safer interop

0 commit comments

Comments
 (0)