Skip to content

Commit 11d5179

Browse files
committed
Allow lifetime dependence inference on implicit initializers
1 parent 3aa5f94 commit 11d5179

File tree

3 files changed

+66
-36
lines changed

3 files changed

+66
-36
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7870,36 +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 parameters qualifiy as a candidate", ())
7873+
ERROR(lifetime_dependence_cannot_infer_ambiguous_candidate, none,
7874+
"cannot infer lifetime dependence %0, multiple parameters qualifiy as a candidate", (StringRef))
78757875
ERROR(lifetime_dependence_cannot_infer_no_candidates, none,
7876-
"cannot infer lifetime dependence, no parameters found that are "
7877-
"~Escapable or Escapable with a borrowing ownership",
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",
78787881
())
7879-
ERROR(lifetime_dependence_ctor_non_self_or_nil_return, none,
7880-
"expected nil or self as return values in an initializer with "
7881-
"lifetime dependent specifiers", ())
7882-
ERROR(lifetime_dependence_on_bitwise_copyable, none,
7883-
"invalid lifetime dependence on bitwise copyable type", ())
7884-
ERROR(lifetime_dependence_cannot_infer_implicit_init, none,
7885-
"cannot infer lifetime dependence on implicit initializer of ~Escapable"
7886-
" type, define an initializer with explicit lifetime dependence"
7887-
" specifiers", ())
7888-
ERROR(lifetime_dependence_cannot_be_applied_to_tuple_elt, none,
7889-
"lifetime dependence specifiers cannot be applied to tuple elements", ())
7890-
7891-
//===----------------------------------------------------------------------===//
7892-
// MARK: Transferring
7893-
//===----------------------------------------------------------------------===//
7894-
7895-
ERROR(transferring_unsupported_param_specifier, none,
7896-
"'%0' cannot be applied to a 'transferring' parameter", (StringRef))
7897-
7898-
ERROR(transferring_only_on_parameters_and_results, none,
7899-
"'transferring' may only be used on parameters and results", ())
7900-
ERROR(transferring_cannot_be_applied_to_tuple_elt, none,
7901-
"'transferring' cannot be applied to tuple elements", ())
7902-
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", ())
79037898

79047899
#define UNDEFINE_DIAGNOSTIC_MACROS
79057900
#include "DefineDiagnosticMacros.h"

lib/Sema/LifetimeDependence.cpp

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

@@ -470,9 +466,16 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) {
470466
continue;
471467
}
472468
if (candidateParam) {
473-
diags.diagnose(
474-
returnLoc,
475-
diag::lifetime_dependence_cannot_infer_ambiguous_candidate);
469+
if (afd->getKind() == DeclKind::Constructor && afd->isImplicit()) {
470+
diags.diagnose(
471+
returnLoc,
472+
diag::lifetime_dependence_cannot_infer_ambiguous_candidate,
473+
"on implicit initializer");
474+
return std::nullopt;
475+
}
476+
diags.diagnose(returnLoc,
477+
diag::lifetime_dependence_cannot_infer_ambiguous_candidate,
478+
"");
476479
return std::nullopt;
477480
}
478481
candidateParam = param;
@@ -481,8 +484,15 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) {
481484
}
482485

483486
if (!candidateParam && !hasParamError) {
487+
if (afd->getKind() == DeclKind::Constructor && afd->isImplicit()) {
488+
diags.diagnose(returnLoc,
489+
diag::lifetime_dependence_cannot_infer_no_candidates,
490+
"on implicit initializer");
491+
return std::nullopt;
492+
}
484493
diags.diagnose(returnLoc,
485-
diag::lifetime_dependence_cannot_infer_no_candidates);
494+
diag::lifetime_dependence_cannot_infer_no_candidates,
495+
"");
486496
return std::nullopt;
487497
}
488498
return lifetimeDependenceInfo;
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)