Skip to content

Commit 4d0e837

Browse files
committed
[6.0] Fix lifetime dependence demangling and add a new Sema diagnostic
Fixes rdar://125564108
1 parent bbaa90d commit 4d0e837

File tree

7 files changed

+51
-14
lines changed

7 files changed

+51
-14
lines changed

docs/ABI/Mangling.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ Types
727727
C-TYPE is mangled according to the Itanium ABI, and prefixed with the length.
728728
Non-ASCII identifiers are preserved as-is; we do not use Punycode.
729729

730-
function-signature ::= params-type params-type async? sendable? throws? differentiable? function-isolation? // results and parameters
730+
function-signature ::= params-type params-type async? sendable? throws? differentiable? function-isolation? self-lifetime-dependence? // results and parameters
731731

732732
params-type ::= type 'z'? 'h'? // tuple in case of multiple parameters or a single parameter with a single tuple type
733733
// with optional inout convention, shared convention. parameters don't have labels,

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7886,6 +7886,10 @@ ERROR(lifetime_dependence_cannot_infer_ambiguous_candidate, none,
78867886
"invalid lifetime dependence on bitwise copyable type", ())
78877887
ERROR(lifetime_dependence_cannot_be_applied_to_tuple_elt, none,
78887888
"lifetime dependence specifiers cannot be applied to tuple elements", ())
7889+
ERROR(lifetime_dependence_method_escapable_bitwisecopyable_self, none,
7890+
"cannot infer lifetime dependence on a self which is BitwiseCopyable & "
7891+
"Escapable",
7892+
())
78897893

78907894
//===----------------------------------------------------------------------===//
78917895
// MARK: Transferring

lib/Demangling/Demangler.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,6 +1579,7 @@ NodePointer Demangler::popFunctionType(Node::Kind kind, bool hasClangType) {
15791579
ClangType = demangleClangType();
15801580
}
15811581
addChild(FuncType, ClangType);
1582+
addChild(FuncType, popNode(Node::Kind::SelfLifetimeDependence));
15821583
addChild(FuncType, popNode(Node::Kind::GlobalActorFunctionType));
15831584
addChild(FuncType, popNode(Node::Kind::IsolatedAnyFunctionType));
15841585
addChild(FuncType, popNode(Node::Kind::TransferringResultFunctionType));
@@ -1589,7 +1590,6 @@ NodePointer Demangler::popFunctionType(Node::Kind kind, bool hasClangType) {
15891590
}));
15901591
addChild(FuncType, popNode(Node::Kind::ConcurrentFunctionType));
15911592
addChild(FuncType, popNode(Node::Kind::AsyncAnnotation));
1592-
addChild(FuncType, popNode(Node::Kind::SelfLifetimeDependence));
15931593

15941594
FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ArgumentTuple));
15951595
FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ReturnType));
@@ -1622,6 +1622,9 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
16221622
return nullptr;
16231623

16241624
unsigned FirstChildIdx = 0;
1625+
if (FuncType->getChild(FirstChildIdx)->getKind() ==
1626+
Node::Kind::SelfLifetimeDependence)
1627+
++FirstChildIdx;
16251628
if (FuncType->getChild(FirstChildIdx)->getKind()
16261629
== Node::Kind::GlobalActorFunctionType)
16271630
++FirstChildIdx;
@@ -1648,9 +1651,6 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
16481651
if (FuncType->getChild(FirstChildIdx)->getKind() ==
16491652
Node::Kind::ParamLifetimeDependence)
16501653
++FirstChildIdx;
1651-
if (FuncType->getChild(FirstChildIdx)->getKind() ==
1652-
Node::Kind::SelfLifetimeDependence)
1653-
++FirstChildIdx;
16541654
auto ParameterType = FuncType->getChild(FirstChildIdx);
16551655

16561656
assert(ParameterType->getKind() == Node::Kind::ArgumentTuple);

lib/Sema/LifetimeDependence.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ std::optional<LifetimeDependenceInfo>
399399
LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) {
400400
auto *dc = afd->getDeclContext();
401401
auto &ctx = dc->getASTContext();
402+
auto *mod = afd->getModuleContext();
402403

403404
if (!ctx.LangOpts.hasFeature(Feature::NonescapableTypes)) {
404405
return std::nullopt;
@@ -430,6 +431,19 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) {
430431

431432
if (afd->getKind() != DeclKind::Constructor && afd->hasImplicitSelfDecl()) {
432433
Type selfTypeInContext = dc->getSelfTypeInContext();
434+
if (selfTypeInContext->isEscapable()) {
435+
if (ctx.LangOpts.hasFeature(Feature::BitwiseCopyable)) {
436+
auto *bitwiseCopyableProtocol =
437+
ctx.getProtocol(KnownProtocolKind::BitwiseCopyable);
438+
if (bitwiseCopyableProtocol &&
439+
mod->checkConformance(selfTypeInContext, bitwiseCopyableProtocol)) {
440+
diags.diagnose(
441+
returnLoc,
442+
diag::lifetime_dependence_method_escapable_bitwisecopyable_self);
443+
return std::nullopt;
444+
}
445+
}
446+
}
433447
auto kind = getLifetimeDependenceKindFromType(selfTypeInContext);
434448
auto selfOwnership = afd->getImplicitSelfDecl()->getValueOwnership();
435449
if (!isLifetimeDependenceCompatibleWithOwnership(kind, selfOwnership,

test/SIL/implicit_lifetime_dependence.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %target-swift-frontend %s \
2-
// RUN: -emit-sil \
2+
// RUN: -emit-sil -disable-availability-checking \
33
// RUN: -enable-experimental-feature NonescapableTypes \
44
// RUN: -enable-experimental-feature NoncopyableGenerics | %FileCheck %s
55
// REQUIRES: asserts
@@ -82,13 +82,13 @@ struct Wrapper : ~Escapable {
8282
self._view = view
8383
}
8484
// TODO: Investigate why it was mangled as Yli and not YLi before
85-
// CHECK: sil hidden @$s28implicit_lifetime_dependence7WrapperV8getView1AA10BufferViewVyYLiF : $@convention(method) (@guaranteed Wrapper) -> _inherit(0) @owned BufferView {
86-
borrowing func getView1() -> BufferView {
85+
// CHECK: sil hidden @$s28implicit_lifetime_dependence7WrapperV8getView1AA10BufferViewVyKYLiF : $@convention(method) (@guaranteed Wrapper) -> _inherit(0) (@owned BufferView, @error any Error) {
86+
borrowing func getView1() throws -> BufferView {
8787
return _view
8888
}
8989

90-
// CHECK:sil hidden @$s28implicit_lifetime_dependence7WrapperV8getView2AA10BufferViewVyYLiF : $@convention(method) (@owned Wrapper) -> _inherit(0) @owned BufferView {
91-
consuming func getView2() -> BufferView {
90+
// CHECK: sil hidden @$s28implicit_lifetime_dependence7WrapperV8getView2AA10BufferViewVyYaKYLiF : $@convention(method) @async (@owned Wrapper) -> _inherit(0) (@owned BufferView, @error any Error) {
91+
consuming func getView2() async throws -> BufferView {
9292
return _view
9393
}
9494
}

test/Sema/explicit_lifetime_dependence_specifiers1.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-experimental-feature NonescapableTypes -enable-experimental-feature NoncopyableGenerics
1+
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-experimental-feature NonescapableTypes -enable-experimental-feature NoncopyableGenerics -enable-experimental-feature BitwiseCopyable
22
// REQUIRES: asserts
33

44
struct Container {
@@ -218,3 +218,17 @@ func derive(_ x: BufferView) -> dependsOn(x) BufferView { // expected-note{{'der
218218
func derive(_ x: BufferView) -> dependsOn(scoped x) BufferView { // expected-error{{invalid redeclaration of 'derive'}}
219219
return BufferView(x.ptr)
220220
}
221+
222+
struct RawBufferView {
223+
let ptr: UnsafeRawBufferPointer
224+
@_unsafeNonescapableResult
225+
init(_ ptr: UnsafeRawBufferPointer) {
226+
self.ptr = ptr
227+
}
228+
}
229+
230+
extension RawBufferView {
231+
mutating func zeroBufferView() throws -> BufferView { // expected-error{{cannot infer lifetime dependence on a self which is BitwiseCopyable & Escapable}}
232+
return BufferView(ptr)
233+
}
234+
}

test/Sema/implicit_lifetime_dependence.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-experimental-feature NonescapableTypes -enable-experimental-feature NoncopyableGenerics
1+
// RUN: %target-typecheck-verify-swift -enable-experimental-feature NonescapableTypes -enable-experimental-feature NoncopyableGenerics
22
// REQUIRES: asserts
33

44
struct BufferView : ~Escapable, ~Copyable {
5-
let ptr: UnsafeRawBufferPointer
5+
let ptr: UnsafeRawBufferPointer?
66
let c: Int
77
@_unsafeNonescapableResult
8-
init(_ ptr: UnsafeRawBufferPointer, _ c: Int) {
8+
init(_ ptr: UnsafeRawBufferPointer?, _ c: Int) {
99
self.ptr = ptr
1010
self.c = c
1111
}
@@ -23,3 +23,8 @@ struct ImplicitInit3 : ~Escapable, ~Copyable { // expected-error{{cannot infer l
2323
let mbv1: BufferView
2424
let mbv2: BufferView
2525
}
26+
27+
func foo() -> BufferView { // expected-error{{cannot infer lifetime dependence , no parameters found that are ~Escapable or Escapable with a borrowing ownership}}
28+
return BufferView(nil, 0)
29+
}
30+

0 commit comments

Comments
 (0)