Skip to content

Commit 5356dc9

Browse files
committed
Add Sema diagnostic when we cant infer lifetime dependence on a method because self is BitwiseCopyable & Escapable
1 parent bc0b884 commit 5356dc9

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7889,6 +7889,10 @@ ERROR(lifetime_dependence_cannot_infer_ambiguous_candidate, none,
78897889
"invalid lifetime dependence on bitwise copyable type", ())
78907890
ERROR(lifetime_dependence_cannot_be_applied_to_tuple_elt, none,
78917891
"lifetime dependence specifiers cannot be applied to tuple elements", ())
7892+
ERROR(lifetime_dependence_method_escapable_bitwisecopyable_self, none,
7893+
"cannot infer lifetime dependence on a self which is BitwiseCopyable & "
7894+
"Escapable",
7895+
())
78927896

78937897
//===----------------------------------------------------------------------===//
78947898
// MARK: Transferring

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;
@@ -431,6 +432,19 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd, Type resultType) {
431432

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

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+
}

0 commit comments

Comments
 (0)