Skip to content

Commit 843d003

Browse files
committed
Infer lifetime dependence for initializers of ~Escapable type
1 parent 968f69c commit 843d003

File tree

3 files changed

+54
-21
lines changed

3 files changed

+54
-21
lines changed

lib/Sema/LifetimeDependence.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,15 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) {
219219
return llvm::None;
220220
}
221221

222+
// Perform lifetime dependence inference under a flag only. Currently all
223+
// stdlib types can appear is ~Escapable and ~Copyable.
224+
if (!ctx.LangOpts.EnableExperimentalLifetimeDependenceInference) {
225+
return llvm::None;
226+
}
227+
222228
auto &diags = ctx.Diags;
223229
auto returnTypeRepr = afd->getResultTypeRepr();
224-
auto returnLoc = returnTypeRepr->getLoc();
230+
auto returnLoc = returnTypeRepr ? returnTypeRepr->getLoc() : afd->getLoc();
225231
Type returnTyInContext = afd->mapTypeIntoContext(resultType);
226232

227233
if (returnTyInContext->isEscapable()) {
@@ -231,7 +237,7 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) {
231237
return llvm::None;
232238
}
233239

234-
if (afd->hasImplicitSelfDecl()) {
240+
if (afd->getKind() == DeclKind::Func && afd->hasImplicitSelfDecl()) {
235241
auto ownership = afd->getImplicitSelfDecl()->getValueOwnership();
236242
if (ownership == ValueOwnership::Default) {
237243
diags.diagnose(
@@ -285,13 +291,14 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) {
285291
llvm::Optional<LifetimeDependenceInfo>
286292
LifetimeDependenceInfo::get(AbstractFunctionDecl *afd, Type resultType,
287293
bool allowIndex) {
288-
auto *returnTypeRepr = afd->getResultTypeRepr();
289-
if (!returnTypeRepr) {
294+
if (afd->getKind() != DeclKind::Func &&
295+
afd->getKind() != DeclKind::Constructor) {
290296
return llvm::None;
291297
}
292-
if (!isa<LifetimeDependentReturnTypeRepr>(returnTypeRepr)) {
293-
return LifetimeDependenceInfo::infer(afd, resultType);
298+
auto *returnTypeRepr = afd->getResultTypeRepr();
299+
if (isa_and_nonnull<LifetimeDependentReturnTypeRepr>(returnTypeRepr)) {
300+
return LifetimeDependenceInfo::fromTypeRepr(afd, resultType, allowIndex);
294301
}
295-
return LifetimeDependenceInfo::fromTypeRepr(afd, resultType, allowIndex);
302+
return LifetimeDependenceInfo::infer(afd, resultType);
296303
}
297304
} // namespace swift

test/SIL/explicit_lifetime_dependence_specifiers.swift

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,33 @@
1-
// RUN: %target-swift-frontend %s -emit-sil -enable-builtin-module \
2-
// RUN: -Xllvm -disable-lifetime-dependence-diagnostics \
3-
// RUN: -enable-experimental-feature NonescapableTypes \
4-
// RUN: -disable-experimental-parser-round-trip \
5-
// RUN: -enable-experimental-feature NoncopyableGenerics \
6-
// RUN: | %FileCheck %s
7-
1+
// RUN: %target-swift-frontend %s \
2+
// RUN: -emit-sil \
3+
// RUN: -enable-builtin-module \
4+
// RUN: -Xllvm -disable-lifetime-dependence-diagnostics \
5+
// RUN: -enable-experimental-feature NonescapableTypes \
6+
// RUN: -disable-experimental-parser-round-trip \
7+
// RUN: -enable-experimental-feature NoncopyableGenerics \
8+
// RUN: -enable-experimental-lifetime-dependence-inference | %FileCheck %s
89
// REQUIRES: asserts
910

1011
import Builtin
1112

1213
struct BufferView : ~Escapable {
1314
let ptr: UnsafeRawBufferPointer
15+
@_unsafeNonescapableResult
1416
init(_ ptr: UnsafeRawBufferPointer) {
1517
self.ptr = ptr
1618
}
1719
}
1820

1921
struct MutableBufferView : ~Escapable, ~Copyable {
2022
let ptr: UnsafeMutableRawBufferPointer
23+
@_unsafeNonescapableResult
2124
init(_ ptr: UnsafeMutableRawBufferPointer) {
2225
self.ptr = ptr
2326
}
2427
}
2528

29+
/*
30+
// rdar://121983770
2631
func testBasic() {
2732
let capacity = 4
2833
let a = Array(0..<capacity)
@@ -33,6 +38,7 @@ func testBasic() {
3338
use(newView)
3439
}
3540
}
41+
*/
3642

3743
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers6deriveyAA10BufferViewVADF : $@convention(thin) (@guaranteed BufferView) -> _borrow(1) @owned BufferView {
3844
func derive(_ x: borrowing BufferView) -> _borrow(x) BufferView {
@@ -64,6 +70,9 @@ func use(_ x: borrowing BufferView) {}
6470

6571
struct Wrapper : ~Escapable {
6672
let view: BufferView
73+
init(_ view: consuming BufferView) {
74+
self.view = view
75+
}
6776
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers7WrapperV8getView1AA10BufferViewVyF : $@convention(method) (@guaranteed Wrapper) -> _borrow(0) @owned BufferView {
6877
borrowing func getView1() -> _borrow(self) BufferView {
6978
return view

test/SIL/implicit_lifetime_dependence.swift

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,41 @@
1-
// RUN: %target-swift-frontend %s -emit-sil -enable-builtin-module \
2-
// RUN: -Xllvm -disable-lifetime-dependence-diagnostics \
3-
// RUN: -enable-experimental-feature NonescapableTypes \
4-
// RUN: -disable-experimental-parser-round-trip \
5-
// RUN: -enable-experimental-feature NoncopyableGenerics \
6-
// RUN: | %FileCheck %s
7-
1+
// RUN: %target-swift-frontend %s \
2+
// RUN: -emit-sil \
3+
// RUN: -enable-builtin-module \
4+
// RUN: -Xllvm -disable-lifetime-dependence-diagnostics \
5+
// RUN: -enable-experimental-feature NonescapableTypes \
6+
// RUN: -disable-experimental-parser-round-trip \
7+
// RUN: -enable-experimental-feature NoncopyableGenerics \
8+
// RUN: -enable-experimental-lifetime-dependence-inference | %FileCheck %s
89
// REQUIRES: asserts
910

1011
import Builtin
1112

1213
struct BufferView : ~Escapable {
1314
let ptr: UnsafeRawBufferPointer
15+
@_unsafeNonescapableResult
1416
init(_ ptr: UnsafeRawBufferPointer) {
1517
self.ptr = ptr
1618
}
19+
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence10BufferViewVyA2ChcfC : $@convention(method) (@guaranteed BufferView, @thin BufferView.Type) -> _borrow(1) @owned BufferView {
20+
init(_ otherBV: borrowing BufferView) {
21+
self.ptr = otherBV.ptr
22+
}
23+
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence10BufferViewVyA2CcfC : $@convention(method) (@owned BufferView, @thin BufferView.Type) -> _inherit(1) @owned BufferView {
24+
init(_ otherBV: consuming BufferView) {
25+
self.ptr = otherBV.ptr
26+
}
1727
}
1828

1929
struct MutableBufferView : ~Escapable, ~Copyable {
2030
let ptr: UnsafeMutableRawBufferPointer
31+
@_unsafeNonescapableResult
2132
init(_ ptr: UnsafeMutableRawBufferPointer) {
2233
self.ptr = ptr
2334
}
2435
}
2536

37+
/*
38+
// rdar://121983770
2639
func testBasic() {
2740
let capacity = 4
2841
let a = Array(0..<capacity)
@@ -33,6 +46,7 @@ func testBasic() {
3346
use(newView)
3447
}
3548
}
49+
*/
3650

3751
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence6deriveyAA10BufferViewVADF : $@convention(thin) (@guaranteed BufferView) -> _borrow(1) @owned BufferView {
3852
func derive(_ x: borrowing BufferView) -> BufferView {
@@ -48,6 +62,9 @@ func use(_ x: borrowing BufferView) {}
4862

4963
struct Wrapper : ~Escapable {
5064
let view: BufferView
65+
init(_ view: consuming BufferView) {
66+
self.view = view
67+
}
5168
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence7WrapperV8getView1AA10BufferViewVyF : $@convention(method) (@guaranteed Wrapper) -> _borrow(0) @owned BufferView {
5269
borrowing func getView1() -> BufferView {
5370
return view

0 commit comments

Comments
 (0)