Skip to content

Commit 44b2c4d

Browse files
authored
Merge pull request #72569 from meg-gupta/fixlifetime
Updates on lifetime dependence
2 parents 70d1d99 + 07beb21 commit 44b2c4d

File tree

5 files changed

+87
-48
lines changed

5 files changed

+87
-48
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7870,37 +7870,31 @@ ERROR(lifetime_dependence_only_on_function_method_init_result, none,
78707870
"functions, methods, initializers", ())
78717871
ERROR(lifetime_dependence_invalid_return_type, none,
78727872
"lifetime dependence can only be specified on ~Escapable results", ())
7873-
ERROR(lifetime_dependence_cannot_infer_ambiguous_candidate, none,
7874-
"cannot infer lifetime dependence, multiple ~Escapable or ~Copyable "
7875-
"parameters with ownership modifiers, specify explicit lifetime "
7876-
"dependence", ())
7877-
ERROR(lifetime_dependence_cannot_infer_no_candidates, none,
7878-
"cannot infer lifetime dependence, no parameters with ownership "
7879-
"modifiers present", ())
7880-
ERROR(lifetime_dependence_ctor_non_self_or_nil_return, none,
7881-
"expected nil or self as return values in an initializer with "
7882-
"lifetime dependent specifiers", ())
7883-
ERROR(lifetime_dependence_on_bitwise_copyable, none,
7884-
"invalid lifetime dependence on bitwise copyable type", ())
7885-
ERROR(lifetime_dependence_cannot_infer_implicit_init, none,
7886-
"cannot infer lifetime dependence on implicit initializer of ~Escapable"
7887-
" type, define an initializer with explicit lifetime dependence"
7888-
" specifiers", ())
7889-
ERROR(lifetime_dependence_cannot_be_applied_to_tuple_elt, none,
7890-
"lifetime dependence specifiers cannot be applied to tuple elements", ())
7891-
7892-
//===----------------------------------------------------------------------===//
7893-
// MARK: Transferring
7894-
//===----------------------------------------------------------------------===//
7895-
7896-
ERROR(transferring_unsupported_param_specifier, none,
7897-
"'%0' cannot be applied to a 'transferring' parameter", (StringRef))
7898-
7899-
ERROR(transferring_only_on_parameters_and_results, none,
7900-
"'transferring' may only be used on parameters and results", ())
7901-
ERROR(transferring_cannot_be_applied_to_tuple_elt, none,
7902-
"'transferring' cannot be applied to tuple elements", ())
7903-
7873+
ERROR(lifetime_dependence_cannot_infer_ambiguous_candidate, none,
7874+
"cannot infer lifetime dependence %0, multiple parameters qualifiy as a candidate", (StringRef))
7875+
ERROR(lifetime_dependence_cannot_infer_no_candidates, none,
7876+
"cannot infer lifetime dependence %0, no parameters found that are "
7877+
"~Escapable or Escapable with a borrowing ownership", (StringRef))
7878+
ERROR(lifetime_dependence_ctor_non_self_or_nil_return, none,
7879+
"expected nil or self as return values in an initializer with "
7880+
"lifetime dependent specifiers",
7881+
())
7882+
ERROR(lifetime_dependence_on_bitwise_copyable, none,
7883+
"invalid lifetime dependence on bitwise copyable type", ())
7884+
ERROR(lifetime_dependence_cannot_be_applied_to_tuple_elt, none,
7885+
"lifetime dependence specifiers cannot be applied to tuple elements", ())
7886+
7887+
//===----------------------------------------------------------------------===//
7888+
// MARK: Transferring
7889+
//===----------------------------------------------------------------------===//
7890+
7891+
ERROR(transferring_unsupported_param_specifier, none,
7892+
"'%0' cannot be applied to a 'transferring' parameter", (StringRef))
7893+
7894+
ERROR(transferring_only_on_parameters_and_results, none,
7895+
"'transferring' may only be used on parameters and results", ())
7896+
ERROR(transferring_cannot_be_applied_to_tuple_elt, none,
7897+
"'transferring' cannot be applied to tuple elements", ())
79047898

79057899
#define UNDEFINE_DIAGNOSTIC_MACROS
79067900
#include "DefineDiagnosticMacros.h"

lib/AST/Builtins.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2073,7 +2073,10 @@ static ValueDecl *getWithUnsafeContinuation(ASTContext &ctx,
20732073
auto *fnTy = FunctionType::get(params, voidTy, extInfo);
20742074

20752075
builder.addParameter(makeConcrete(fnTy));
2076-
builder.setResult(makeGenericParam());
2076+
2077+
auto resultTy = makeGenericParam();
2078+
builder.addConformanceRequirement(resultTy, KnownProtocolKind::Escapable);
2079+
builder.setResult(resultTy);
20772080

20782081
builder.setAsync();
20792082
if (throws)

lib/Sema/LifetimeDependence.cpp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -426,10 +426,6 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) {
426426
if (cd && cd->isImplicit()) {
427427
if (cd->getParameters()->size() == 0) {
428428
return std::nullopt;
429-
} else {
430-
diags.diagnose(cd->getLoc(),
431-
diag::lifetime_dependence_cannot_infer_implicit_init);
432-
return std::nullopt;
433429
}
434430
}
435431

@@ -471,9 +467,16 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) {
471467
continue;
472468
}
473469
if (candidateParam) {
474-
diags.diagnose(
475-
returnLoc,
476-
diag::lifetime_dependence_cannot_infer_ambiguous_candidate);
470+
if (afd->getKind() == DeclKind::Constructor && afd->isImplicit()) {
471+
diags.diagnose(
472+
returnLoc,
473+
diag::lifetime_dependence_cannot_infer_ambiguous_candidate,
474+
"on implicit initializer");
475+
return std::nullopt;
476+
}
477+
diags.diagnose(returnLoc,
478+
diag::lifetime_dependence_cannot_infer_ambiguous_candidate,
479+
"");
477480
return std::nullopt;
478481
}
479482
candidateParam = param;
@@ -482,17 +485,15 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) {
482485
}
483486

484487
if (!candidateParam && !hasParamError) {
485-
// Explicitly turn off error messages for builtins, since some of are
486-
// ~Escapable currently.
487-
// TODO: rdar://123555720: Remove this check after another round of
488-
// surveying builtins
489-
if (auto *fd = dyn_cast<FuncDecl>(afd)) {
490-
if (fd->isImplicit() && fd->getModuleContext()->isBuiltinModule()) {
491-
return std::nullopt;
492-
}
488+
if (afd->getKind() == DeclKind::Constructor && afd->isImplicit()) {
489+
diags.diagnose(returnLoc,
490+
diag::lifetime_dependence_cannot_infer_no_candidates,
491+
"on implicit initializer");
492+
return std::nullopt;
493493
}
494494
diags.diagnose(returnLoc,
495-
diag::lifetime_dependence_cannot_infer_no_candidates);
495+
diag::lifetime_dependence_cannot_infer_no_candidates,
496+
"");
496497
return std::nullopt;
497498
}
498499
return lifetimeDependenceInfo;

test/Sema/explicit_lifetime_dependence_specifiers1.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ struct BufferView : ~Escapable {
5656
consuming func consume() -> dependsOn(scoped self) BufferView { // expected-error{{invalid use of scoped lifetime dependence with consuming ownership}}
5757
return BufferView(self.ptr)
5858
}
59+
60+
func get() -> dependsOn(self) Self { // expected-note{{'get()' previously declared here}}
61+
return self
62+
}
63+
64+
func get() -> dependsOn(scoped self) Self { // expected-error{{invalid redeclaration of 'get()'}}
65+
return self
66+
}
5967
}
6068

6169
struct MutableBufferView : ~Escapable, ~Copyable {
@@ -202,3 +210,11 @@ public struct GenericBufferView<Element> : ~Escapable {
202210
self.count = count
203211
}
204212
}
213+
214+
func derive(_ x: BufferView) -> dependsOn(x) BufferView { // expected-note{{'derive' previously declared here}}
215+
return BufferView(x.ptr)
216+
}
217+
218+
func derive(_ x: BufferView) -> dependsOn(scoped x) BufferView { // expected-error{{invalid redeclaration of 'derive'}}
219+
return BufferView(x.ptr)
220+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-experimental-feature NonescapableTypes -enable-experimental-feature NoncopyableGenerics
2+
// REQUIRES: asserts
3+
4+
struct BufferView : ~Escapable, ~Copyable {
5+
let ptr: UnsafeRawBufferPointer
6+
let c: Int
7+
@_unsafeNonescapableResult
8+
init(_ ptr: UnsafeRawBufferPointer, _ c: Int) {
9+
self.ptr = ptr
10+
self.c = c
11+
}
12+
}
13+
14+
struct ImplicitInit1 : ~Escapable { // expected-error{{cannot infer lifetime dependence on implicit initializer, no parameters found that are ~Escapable or Escapable with a borrowing ownership}}
15+
let ptr: UnsafeRawBufferPointer
16+
}
17+
18+
struct ImplicitInit2 : ~Escapable, ~Copyable {
19+
let mbv: BufferView
20+
}
21+
22+
struct ImplicitInit3 : ~Escapable, ~Copyable { // expected-error{{cannot infer lifetime dependence on implicit initializer, multiple parameters qualifiy as a candidate}}
23+
let mbv1: BufferView
24+
let mbv2: BufferView
25+
}

0 commit comments

Comments
 (0)