Skip to content

Commit c0847e3

Browse files
committed
Remove diagnostic error when 'return self' is missing in an initializer with explicit lifetime dependence
Also, handle it similar to other initializers in SILGen and ASTVerifier
1 parent c0c24c1 commit c0847e3

6 files changed

+34
-36
lines changed

include/swift/AST/AnyFunctionRef.h

-5
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,6 @@ class AnyFunctionRef {
115115
if (auto *AFD = TheFunction.dyn_cast<AbstractFunctionDecl *>()) {
116116
if (auto *FD = dyn_cast<FuncDecl>(AFD))
117117
return FD->mapTypeIntoContext(FD->getResultInterfaceType());
118-
if (auto *CD = dyn_cast<ConstructorDecl>(AFD)) {
119-
if (CD->hasLifetimeDependentReturn()) {
120-
return CD->mapTypeIntoContext(CD->getResultInterfaceType());
121-
}
122-
}
123118
return TupleType::getEmpty(AFD->getASTContext());
124119
}
125120
return TheFunction.get<AbstractClosureExpr *>()->getResultType();

lib/AST/ASTVerifier.cpp

+1-6
Original file line numberDiff line numberDiff line change
@@ -1076,12 +1076,7 @@ class Verifier : public ASTWalker {
10761076
} else if (auto closure = dyn_cast<AbstractClosureExpr>(func)) {
10771077
resultType = closure->getResultType();
10781078
} else if (auto *CD = dyn_cast<ConstructorDecl>(func)) {
1079-
if (CD->hasLifetimeDependentReturn()) {
1080-
resultType = CD->getResultInterfaceType();
1081-
resultType = CD->mapTypeIntoContext(resultType);
1082-
} else {
1083-
resultType = TupleType::getEmpty(Ctx);
1084-
}
1079+
resultType = TupleType::getEmpty(Ctx);
10851080
} else {
10861081
resultType = TupleType::getEmpty(Ctx);
10871082
}

lib/SILGen/SILGenConstructor.cpp

+2-12
Original file line numberDiff line numberDiff line change
@@ -683,13 +683,8 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
683683
// Create a basic block to jump to for the implicit 'self' return.
684684
// We won't emit this until after we've emitted the body.
685685
// The epilog takes a void return because the return of 'self' is implicit.
686-
// When lifetime dependence specifiers are present, epilog will take the
687-
// explicit 'self' return.
688-
prepareEpilog(ctor,
689-
ctor->hasLifetimeDependentReturn()
690-
? std::optional<Type>(ctor->getResultInterfaceType())
691-
: std::nullopt,
692-
ctor->getEffectiveThrownErrorType(), CleanupLocation(ctor));
686+
prepareEpilog(ctor, std::nullopt, ctor->getEffectiveThrownErrorType(),
687+
CleanupLocation(ctor));
693688

694689
// If the constructor can fail, set up an alternative epilog for constructor
695690
// failure.
@@ -773,11 +768,6 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
773768
// Emit the constructor body.
774769
emitStmt(ctor->getTypecheckedBody());
775770

776-
if (ctor->hasLifetimeDependentReturn()) {
777-
emitEpilog(ctor, /*UsesCustomEpilog*/ false);
778-
return;
779-
}
780-
781771
// Build a custom epilog block, since the AST representation of the
782772
// constructor decl (which has no self in the return type) doesn't match the
783773
// SIL representation.

lib/Sema/TypeCheckStmt.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -1723,6 +1723,10 @@ Stmt *PreCheckReturnStmtRequest::evaluate(Evaluator &evaluator, ReturnStmt *RS,
17231723
bool isSelf = false;
17241724
if (auto *UDRE = dyn_cast<UnresolvedDeclRefExpr>(E)) {
17251725
isSelf = UDRE->getName().isSimpleName(ctx.Id_self);
1726+
// Result the result expression so that rest of the compilation
1727+
// pipeline handles initializers with lifetime dependence specifiers
1728+
// in the same way as other initializers.
1729+
RS->setResult(nullptr);
17261730
}
17271731
if (!isSelf) {
17281732
ctx.Diags.diagnose(

test/Sema/explicit_lifetime_dependence_specifiers.swift test/Sema/explicit_lifetime_dependence_specifiers1.swift

+6-13
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,10 @@
1-
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-experimental-feature NonescapableTypes -disable-experimental-parser-round-trip -enable-experimental-feature NoncopyableGenerics -enable-experimental-feature BitwiseCopyable
1+
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-experimental-feature NonescapableTypes -disable-experimental-parser-round-trip -enable-experimental-feature NoncopyableGenerics
22
// REQUIRES: asserts
3-
// REQUIRES: noncopyable_generics
4-
// REQUIRES: nonescapable_types
53

64
struct Container {
75
let ptr: UnsafeRawBufferPointer
86
}
97

10-
struct AnotherBufferView : ~Escapable, _BitwiseCopyable {
11-
let ptr: UnsafeRawBufferPointer
12-
@_unsafeNonescapableResult
13-
init(_ ptr: UnsafeRawBufferPointer) {
14-
self.ptr = ptr
15-
}
16-
}
17-
188
struct BufferView : ~Escapable {
199
let ptr: UnsafeRawBufferPointer
2010
@_unsafeNonescapableResult
@@ -25,10 +15,13 @@ struct BufferView : ~Escapable {
2515
self.ptr = c.ptr
2616
return self
2717
}
28-
init(_ bv: borrowing AnotherBufferView) -> _borrow(bv) Self {
29-
self.ptr = bv.ptr
18+
init(_ ptr: UnsafeRawBufferPointer, _ arr: borrowing Array<Int>) -> _borrow(arr) Self {
19+
self.ptr = ptr
3020
return self
3121
}
22+
init(_ ptr: UnsafeRawBufferPointer, _ arr: borrowing Array<Double>) -> _borrow(arr) Self {
23+
self.ptr = ptr
24+
}
3225
}
3326

3427
struct MutableBufferView : ~Escapable, ~Copyable {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-experimental-feature NonescapableTypes -disable-experimental-parser-round-trip -enable-experimental-feature NoncopyableGenerics -enable-experimental-feature BitwiseCopyable
2+
// REQUIRES: asserts
3+
// REQUIRES: noncopyable_generics
4+
// REQUIRES: nonescapable_types
5+
6+
struct AnotherBufferView : ~Escapable, _BitwiseCopyable {
7+
let ptr: UnsafeRawBufferPointer
8+
@_unsafeNonescapableResult
9+
init(_ ptr: UnsafeRawBufferPointer) {
10+
self.ptr = ptr
11+
}
12+
}
13+
14+
struct BufferView : ~Escapable {
15+
let ptr: UnsafeRawBufferPointer
16+
init(_ bv: borrowing AnotherBufferView) -> _borrow(bv) Self {
17+
self.ptr = bv.ptr
18+
return self
19+
}
20+
}
21+

0 commit comments

Comments
 (0)