Skip to content

Commit 0835d00

Browse files
committed
Add serialization/deserialization support to lifetime depedence on initializers
1 parent c8ece10 commit 0835d00

File tree

8 files changed

+70
-1
lines changed

8 files changed

+70
-1
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8334,6 +8334,8 @@ class ConstructorDecl : public AbstractFunctionDecl {
83348334

83358335
TypeRepr *getResultTypeRepr() const { return InitRetType.getTypeRepr(); }
83368336

8337+
void setDeserializedResultTypeLoc(TypeLoc ResultTyR);
8338+
83378339
/// Get the typechecked call to super.init expression, which needs to be
83388340
/// inserted at the end of the initializer by SILGen.
83398341
Expr *getSuperInitCall() { return CallToSuperInit; }

lib/AST/Decl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10423,6 +10423,10 @@ ConstructorDecl *ConstructorDecl::createImported(
1042310423
return ctor;
1042410424
}
1042510425

10426+
void ConstructorDecl::setDeserializedResultTypeLoc(TypeLoc ResultTyR) {
10427+
InitRetType = ResultTyR;
10428+
}
10429+
1042610430
bool ConstructorDecl::isObjCZeroParameterWithLongSelector() const {
1042710431
// The initializer must have a single, non-empty argument name.
1042810432
if (getName().getArgumentNames().size() != 1 ||

lib/Serialization/Deserialization.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3532,7 +3532,6 @@ class DeclDeserializer {
35323532
return thrownTypeOrError.takeError();
35333533
const auto thrownType = thrownTypeOrError.get();
35343534

3535-
// Handle LifetimeDependence here
35363535
auto ctor = MF.createDecl<ConstructorDecl>(name, SourceLoc(), isFailable,
35373536
/*FailabilityLoc=*/SourceLoc(),
35383537
/*Async=*/async,
@@ -3556,6 +3555,15 @@ class DeclDeserializer {
35563555
assert(bodyParams && "missing parameters for constructor");
35573556
ctor->setParameters(bodyParams);
35583557

3558+
SmallVector<LifetimeDependenceSpecifier> specifierList;
3559+
if (MF.maybeReadLifetimeDependence(specifierList, bodyParams->size())) {
3560+
auto SelfType = ctor->getDeclaredInterfaceType();
3561+
auto typeRepr = new (ctx) FixedTypeRepr(SelfType, SourceLoc());
3562+
auto lifetimeTypeRepr =
3563+
LifetimeDependentReturnTypeRepr::create(ctx, typeRepr, specifierList);
3564+
ctor->setDeserializedResultTypeLoc(TypeLoc(lifetimeTypeRepr, SelfType));
3565+
}
3566+
35593567
if (auto errorConvention = MF.maybeReadForeignErrorConvention())
35603568
ctor->setForeignErrorConvention(*errorConvention);
35613569
if (auto asyncConvention = MF.maybeReadForeignAsyncConvention())

lib/Serialization/Serialization.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4783,6 +4783,12 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
47834783
writeGenericParams(ctor->getGenericParams());
47844784
writeParameterList(ctor->getParameters());
47854785

4786+
auto fnType = ty->getAs<FunctionType>();
4787+
if (fnType && fnType->hasLifetimeDependenceInfo()) {
4788+
assert(!fnType->getLifetimeDependenceInfo().empty());
4789+
writeLifetimeDependenceInfo(fnType->getLifetimeDependenceInfo());
4790+
}
4791+
47864792
if (auto errorConvention = ctor->getForeignErrorConvention())
47874793
writeForeignErrorConvention(*errorConvention);
47884794
if (auto asyncConvention = ctor->getForeignAsyncConvention())

test/Serialization/Inputs/def_explicit_lifetime_dependence.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@ public struct BufferView : ~Escapable {
44
public init(_ ptr: UnsafeRawBufferPointer) {
55
self.ptr = ptr
66
}
7+
public init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array<Int>) -> _borrow(a) Self {
8+
self.ptr = ptr
9+
return self
10+
}
11+
public init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Array<Double>) -> _consume(a) Self {
12+
self.ptr = ptr
13+
return self
14+
}
15+
public init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Array<Int>, _ b: borrowing Array<Int>) -> _consume(a) _borrow(b) Self {
16+
self.ptr = ptr
17+
return self
18+
}
719
}
820

921
public struct MutableBufferView : ~Escapable, ~Copyable {

test/Serialization/Inputs/def_implicit_lifetime_dependence.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ public struct BufferView : ~Escapable {
44
public init(_ ptr: UnsafeRawBufferPointer) {
55
self.ptr = ptr
66
}
7+
public init(_ otherBV: borrowing BufferView) {
8+
self.ptr = otherBV.ptr
9+
}
710
}
811

912
public struct MutableBufferView : ~Escapable, ~Copyable {

test/Serialization/explicit_lifetime_dependence.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,22 @@ func testBasic() {
2828
}
2929
}
3030

31+
func testInitializers() {
32+
let capacity = 4
33+
let a = Array(0..<capacity)
34+
let b = Array(0..<capacity)
35+
a.withUnsafeBytes {
36+
let view1 = BufferView($0, a)
37+
let view2 = BufferView($0, a, b)
38+
let mysteryView = deriveThisOrThat(view1, view2)
39+
use(mysteryView)
40+
}
41+
}
3142
// CHECK: sil @$s32def_explicit_lifetime_dependence6deriveyAA10BufferViewVADF : $@convention(thin) (@guaranteed BufferView) -> _borrow(1) @owned BufferView
3243
// CHECK: sil @$s32def_explicit_lifetime_dependence16consumeAndCreateyAA10BufferViewVADnF : $@convention(thin) (@owned BufferView) -> _inherit(1) @owned BufferView
3344
// CHECK: sil @$s32def_explicit_lifetime_dependence15borrowAndCreateyAA10BufferViewVADF : $@convention(thin) (@guaranteed BufferView) -> _borrow(1) @owned BufferView
3445
// CHECK: sil @$s32def_explicit_lifetime_dependence16deriveThisOrThatyAA10BufferViewVAD_ADtF : $@convention(thin) (@guaranteed BufferView, @guaranteed BufferView) -> _borrow(1, 2) @owned BufferView
46+
47+
// CHECK: sil @$s32def_explicit_lifetime_dependence10BufferViewVyACSW_SaySiGhtcfC : $@convention(method) (UnsafeRawBufferPointer, @guaranteed Array<Int>, @thin BufferView.Type) -> _borrow(2) @owned BufferView
48+
49+
// CHECK: sil @$s32def_explicit_lifetime_dependence10BufferViewVyACSW_SaySiGADhtcfC : $@convention(method) (UnsafeRawBufferPointer, @owned Array<Int>, @guaranteed Array<Int>, @thin BufferView.Type) -> _inherit(2)_borrow(3) @owned BufferView

test/Serialization/implicit_lifetime_dependence.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,26 @@ func testBasic() {
2828
}
2929
}
3030

31+
func testInitializers() {
32+
let capacity = 4
33+
let a = Array(0..<capacity)
34+
a.withUnsafeBytes {
35+
let view1 = BufferView($0)
36+
let view2 = BufferView(view1)
37+
let view3 = BufferView(view2)
38+
use(view3)
39+
}
40+
}
41+
42+
func unsafetest(_ ptr: UnsafeRawBufferPointer) {
43+
let view1 = BufferView(ptr)
44+
let view2 = BufferView(view1)
45+
let view3 = BufferView(view2)
46+
use(view3)
47+
}
48+
3149
// CHECK: sil @$s32def_implicit_lifetime_dependence6deriveyAA10BufferViewVADF : $@convention(thin) (@guaranteed BufferView) -> _borrow(1) @owned BufferView
3250
// CHECK: sil @$s32def_implicit_lifetime_dependence16consumeAndCreateyAA10BufferViewVADnF : $@convention(thin) (@owned BufferView) -> _inherit(1) @owned BufferView
3351
// CHECK: sil @$s32def_implicit_lifetime_dependence15borrowAndCreateyAA10BufferViewVADF : $@convention(thin) (@guaranteed BufferView) -> _borrow(1) @owned BufferView
52+
// CHECK: sil @$s32def_implicit_lifetime_dependence10BufferViewVyA2ChcfC : $@convention(method) (@guaranteed BufferView, @thin BufferView.Type) -> _borrow(1) @owned BufferView
3453

0 commit comments

Comments
 (0)