Skip to content

Commit 1f09be9

Browse files
authored
Merge pull request #72757 from DougGregor/noncopyable-failable-inits
2 parents 234f000 + bd696f9 commit 1f09be9

File tree

7 files changed

+56
-24
lines changed

7 files changed

+56
-24
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7743,8 +7743,6 @@ ERROR(noncopyable_enums_do_not_support_indirect,none,
77437743
"noncopyable enum %0 cannot be marked indirect or have indirect cases yet", (Identifier))
77447744
ERROR(noncopyable_cast,none,
77457745
"noncopyable types cannot be conditionally cast", ())
7746-
ERROR(noncopyable_failable_init,none,
7747-
"noncopyable types cannot have failable initializers yet", ())
77487746
ERROR(noncopyable_objc_enum, none,
77497747
"noncopyable enums cannot be marked '@objc'", ())
77507748
ERROR(moveOnly_not_allowed_here,none,

lib/IRGen/StructLayout.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,10 @@ StructLayout::StructLayout(IRGenModule &IGM, std::optional<CanType> type,
178178
SpareBits.clear();
179179
IsFixedLayout = true;
180180
IsLoadable = true;
181-
IsKnownTriviallyDestroyable = deinit;
182-
IsKnownBitwiseTakable = IsBitwiseTakable;
183-
IsKnownAlwaysFixedSize = IsFixedSize;
184-
IsKnownCopyable = copyable;
181+
IsKnownTriviallyDestroyable = deinit & builder.isTriviallyDestroyable();
182+
IsKnownBitwiseTakable = builder.isBitwiseTakable();
183+
IsKnownAlwaysFixedSize = builder.isAlwaysFixedSize();
184+
IsKnownCopyable = copyable & builder.isCopyable();
185185
Ty = (typeToFill ? typeToFill : IGM.OpaqueTy);
186186
} else {
187187
MinimumAlign = builder.getAlignment();

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4035,16 +4035,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
40354035
addDelayedFunction(CD);
40364036
}
40374037

4038-
// a move-only / noncopyable type cannot have a failable initializer, since
4039-
// that would require the ability to wrap one inside an optional
4040-
if (CD->isFailable()) {
4041-
if (auto *nom = CD->getDeclContext()->getSelfNominalTypeDecl()) {
4042-
if (!nom->canBeCopyable()) {
4043-
CD->diagnose(diag::noncopyable_failable_init);
4044-
}
4045-
}
4046-
}
4047-
40484038
checkDefaultArguments(CD->getParameters());
40494039
checkVariadicParameters(CD->getParameters(), CD);
40504040

test/Generics/inverse_generics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ struct NeverCopyableDeinit<T: ~Copyable>: ~Copyable {
109109
}
110110

111111
protocol Test: ~Copyable {
112-
init?() // expected-error {{noncopyable types cannot have failable initializers yet}}
112+
init?()
113113
}
114114

115115
struct NoncopyableAndSendable: ~Copyable, Sendable {}

test/IRGen/moveonly_deinits.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,18 @@ public func testKlassEnumPairWithDeinit() {
373373
consumeKlassEnumPairWithDeinit(f)
374374
}
375375
}
376+
377+
struct EmptyMoveOnlyWithDeinit: ~Copyable {
378+
deinit {}
379+
}
380+
381+
struct EnclosesEmptyMoveOnlyWithDeinit: ~Copyable {
382+
var stored: EmptyMoveOnlyWithDeinit
383+
}
384+
385+
// IR-LABEL: define {{.*}}swiftcc void @"$s16moveonly_deinits35testEnclosesEmptyMoveOnlyWithDeinityyF"()
386+
func testEnclosesEmptyMoveOnlyWithDeinit() {
387+
// CHECK-NOT: ret
388+
// CHECK: call swiftcc void @"$s16moveonly_deinits23EmptyMoveOnlyWithDeinitVfD"()
389+
_ = EnclosesEmptyMoveOnlyWithDeinit(stored: EmptyMoveOnlyWithDeinit())
390+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %target-swift-emit-sil -module-name test %s | %FileCheck %s --enable-var-scope
2+
3+
struct MoveWithDeinit: ~Copyable {
4+
deinit { }
5+
}
6+
7+
struct MyType: ~Copyable {
8+
var handle: MoveWithDeinit
9+
10+
// CHECK-LABEL: sil hidden @$s4test6MyTypeV6handleACSgAA14MoveWithDeinitVSg_tcfC : $@convention(method) (@owned Optional<MoveWithDeinit>, @thin MyType.Type) -> @owned Optional<MyType>
11+
// CHECK: bb0(%0 : $Optional<MoveWithDeinit>, %1 : $@thin MyType.Type):
12+
init?(handle: consuming MoveWithDeinit?) {
13+
// CHECK: switch_enum [[SUBJECT:%.*]] : $Optional<MoveWithDeinit>, case #Optional.some!enumelt: bb2, case #Optional.none!enumelt: bb1
14+
guard let handle = consume handle else {
15+
// CHECK: bb1:
16+
// CHECK: [[NONE:%.*]] = enum $Optional<MyType>, #Optional.none!enumelt
17+
// CHECK: br bb3([[NONE]] : $Optional<MyType>)
18+
return nil
19+
}
20+
21+
// CHECK: bb2([[WRAPPED:%.*]] : $MoveWithDeinit):
22+
// CHECK: br bb3
23+
self.handle = handle
24+
}
25+
}
26+
27+
func test() -> MyType? {
28+
return MyType(handle: MoveWithDeinit())
29+
}

test/Sema/moveonly_restrictions.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ class CopyableKlass {}
66

77
@_moveOnly
88
class MoveOnlyKlass { // expected-note 6{{class 'MoveOnlyKlass' has '~Copyable' constraint preventing 'Copyable' conformance}}
9-
init?() {} // expected-error {{noncopyable types cannot have failable initializers yet}}
9+
init?() {}
1010
}
1111

1212
@_moveOnly
1313
struct MoveOnlyStruct { // expected-note {{struct 'MoveOnlyStruct' has '~Copyable' constraint preventing 'Copyable' conformance}}
14-
init?(one: Bool) {} // expected-error {{noncopyable types cannot have failable initializers yet}}
15-
init!(two: Bool) {} // expected-error {{noncopyable types cannot have failable initializers yet}}
14+
init?(one: Bool) {}
15+
init!(two: Bool) {}
1616
}
1717

1818
class C {
@@ -78,19 +78,19 @@ enum EMoveOnly {
7878
case lhs(CopyableKlass)
7979
case rhs(MoveOnlyKlass)
8080

81-
init?() {} // expected-error {{noncopyable types cannot have failable initializers yet}}
81+
init?() {}
8282
}
8383

8484
extension EMoveOnly {
85-
init!(three: Bool) {} // expected-error {{noncopyable types cannot have failable initializers yet}}
85+
init!(three: Bool) {}
8686
}
8787

8888
extension MoveOnlyKlass {
89-
convenience init?(three: Bool) {} // expected-error {{noncopyable types cannot have failable initializers yet}}
89+
convenience init?(three: Bool) {}
9090
}
9191

9292
extension MoveOnlyStruct {
93-
init?(three: Bool) {} // expected-error {{noncopyable types cannot have failable initializers yet}}
93+
init?(three: Bool) {}
9494
}
9595

9696
func foo() {

0 commit comments

Comments
 (0)