Skip to content

Commit ee1bc88

Browse files
committed
[BitwiseCopyable] Loosen validation assertion.
Now that it's possible to be `BitwiseCopyable` and `~Escapable`, because the latter implies non-trivial, verification must permit a type to be non-trivial but conform to `BitwiseCopyable` when it contains a `~Escapable` field. rdar://124552608
1 parent cf619e2 commit ee1bc88

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

lib/SIL/IR/TypeLowering.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3202,9 +3202,10 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
32023202
}
32033203

32043204
if (!lowering.isTrivial() && conformance) {
3205-
// A non-trivial type can have a conformance in one case:
3205+
// A non-trivial type can have a conformance in a few cases:
32063206
// (1) contains a conforming archetype
32073207
// (2) is resilient with minimal expansion
3208+
// (3) containing or being ~Escapable
32083209
bool hasNoConformingArchetypeNode = visitAggregateLeaves(
32093210
origType, substType, forExpansion,
32103211
/*isLeaf=*/
@@ -3217,6 +3218,12 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
32173218
ResilienceExpansion::Minimal) {
32183219
return true;
32193220
}
3221+
// A type that may not be escapable is non-trivial but can conform
3222+
// (case (3)).
3223+
if (nominal &&
3224+
nominal->canBeEscapable() != TypeDecl::CanBeInvertible::Always) {
3225+
return true;
3226+
}
32203227
// Walk into every aggregate.
32213228
return false;
32223229
},
@@ -3236,6 +3243,13 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
32363243
return false;
32373244
}
32383245

3246+
// A type that may not be escapable is non-trivial but can conform
3247+
// (case (3)).
3248+
if (nominal &&
3249+
nominal->canBeEscapable() != TypeDecl::CanBeInvertible::Always) {
3250+
return false;
3251+
}
3252+
32393253
// An archetype may conform but be non-trivial (case (1)).
32403254
if (origTy.isTypeParameter())
32413255
return false;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// R N: %target-swift-frontend -enable-experimental-feature NonescapableTypes -enable-experimental-feature BuiltinModule -enable-experimental-feature NoncopyableGenerics -parse-stdlib -module-name Swift -DEMPTY -emit-sil -verify %s
2+
3+
// RUN: %target-swift-frontend \
4+
// RUN: -emit-sil \
5+
// RUN: %s \
6+
// RUN: -parse-stdlib \
7+
// RUN: -module-name Swift \
8+
// RUN: -disable-availability-checking \
9+
// RUN: -enable-experimental-feature BuiltinModule \
10+
// RUN: -enable-experimental-feature BitwiseCopyable \
11+
// RUN: -enable-experimental-feature NoncopyableGenerics \
12+
// RUN: -enable-experimental-feature NonescapableTypes \
13+
// RUN: -enable-builtin-module
14+
15+
// REQUIRES: asserts
16+
17+
// Force verification of TypeLowering's isTrivial.
18+
19+
import Builtin
20+
21+
@_marker public protocol Copyable: ~Escapable {}
22+
@_marker public protocol Escapable: ~Copyable {}
23+
@_marker public protocol _BitwiseCopyable : ~Escapable {}
24+
25+
struct Storage : ~Escapable, _BitwiseCopyable {}
26+
27+
28+
func take<T : _BitwiseCopyable & ~Escapable>(_ t: T) {}
29+
30+
func passStorage(_ s: Storage) { take(s) }

0 commit comments

Comments
 (0)