Skip to content

Commit dfa95c4

Browse files
committed
Support lifetime dependence inference on getters
1 parent d330cb6 commit dfa95c4

4 files changed

+52
-6
lines changed

lib/Sema/LifetimeDependence.cpp

+12-6
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,18 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) {
282282
return llvm::None;
283283
}
284284

285-
if (afd->getKind() == DeclKind::Func && afd->hasImplicitSelfDecl()) {
286-
auto ownership = afd->getImplicitSelfDecl()->getValueOwnership();
285+
if (afd->getKind() != DeclKind::Constructor && afd->hasImplicitSelfDecl()) {
286+
ValueOwnership ownership = ValueOwnership::Default;
287+
if (auto *AD = dyn_cast<AccessorDecl>(afd)) {
288+
if (AD->getAccessorKind() == AccessorKind::Get) {
289+
// We don't support "borrowing/consuming" ownership modifiers on
290+
// getters, by default they are guaranteed for now.
291+
ownership = ValueOwnership::Shared;
292+
}
293+
} else {
294+
ownership = afd->getImplicitSelfDecl()->getValueOwnership();
295+
}
296+
287297
if (ownership == ValueOwnership::Default) {
288298
diags.diagnose(
289299
returnLoc,
@@ -338,10 +348,6 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) {
338348
llvm::Optional<LifetimeDependenceInfo>
339349
LifetimeDependenceInfo::get(AbstractFunctionDecl *afd, Type resultType,
340350
bool allowIndex) {
341-
if (afd->getKind() != DeclKind::Func &&
342-
afd->getKind() != DeclKind::Constructor) {
343-
return llvm::None;
344-
}
345351
auto *returnTypeRepr = afd->getResultTypeRepr();
346352
if (isa_and_nonnull<LifetimeDependentReturnTypeRepr>(returnTypeRepr)) {
347353
return LifetimeDependenceInfo::fromTypeRepr(afd, resultType, allowIndex);

test/SIL/implicit_lifetime_dependence.swift

+13
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,16 @@ struct Wrapper : ~Escapable {
7777
return view
7878
}
7979
}
80+
81+
struct Container : ~Copyable {
82+
var ptr: UnsafeRawBufferPointer
83+
// CHECK: sil hidden @$s28implicit_lifetime_dependence9ContainerV4viewAA10BufferViewVvg : $@convention(method) (@guaranteed Container) -> _scope(0) @owned BufferView {
84+
var view: BufferView {
85+
get {
86+
return BufferView(ptr)
87+
}
88+
set(newView) {
89+
ptr = newView.ptr
90+
}
91+
}
92+
}

test/Serialization/Inputs/def_implicit_lifetime_dependence.swift

+16
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,19 @@ public func consumeAndCreate(_ view: consuming BufferView) -> BufferView {
3131
return BufferView(view.ptr)
3232
}
3333

34+
public struct Container : ~Copyable {
35+
var ptr: UnsafeRawBufferPointer
36+
37+
public init(_ ptr: UnsafeRawBufferPointer) {
38+
self.ptr = ptr
39+
}
40+
41+
public var view: BufferView {
42+
get {
43+
return BufferView(ptr)
44+
}
45+
set(newView) {
46+
ptr = newView.ptr
47+
}
48+
}
49+
}

test/Serialization/implicit_lifetime_dependence.swift

+11
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ func unsafetest(_ ptr: UnsafeRawBufferPointer) {
4646
use(view3)
4747
}
4848

49+
func testGetter() {
50+
let capacity = 4
51+
let a = Array(0..<capacity)
52+
a.withUnsafeBytes {
53+
let c = Container($0)
54+
let view = c.view
55+
use(view)
56+
}
57+
}
58+
4959
// CHECK: sil @$s32def_implicit_lifetime_dependence6deriveyAA10BufferViewVADYlsF : $@convention(thin) (@guaranteed BufferView) -> _scope(1) @owned BufferView
5060

5161
// CHECK: sil @$s32def_implicit_lifetime_dependence16consumeAndCreateyAA10BufferViewVADnYliF : $@convention(thin) (@owned BufferView) -> _inherit(1) @owned BufferView
@@ -54,3 +64,4 @@ func unsafetest(_ ptr: UnsafeRawBufferPointer) {
5464

5565
// CHECK: sil @$s32def_implicit_lifetime_dependence10BufferViewVyA2ChYlscfC : $@convention(method) (@guaranteed BufferView, @thin BufferView.Type) -> _scope(1) @owned BufferView
5666

67+
// CHECK: sil @$s32def_implicit_lifetime_dependence9ContainerV4viewAA10BufferViewVvg : $@convention(method) (@guaranteed Container) -> _scope(0) @owned BufferView

0 commit comments

Comments
 (0)