Skip to content

Commit 279d27a

Browse files
committed
[Sema] lay groundwork for noncopyable existentials
1 parent 88d2f93 commit 279d27a

File tree

4 files changed

+27
-9
lines changed

4 files changed

+27
-9
lines changed

include/swift/AST/ExistentialLayout.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct ExistentialLayout {
3131

3232
ExistentialLayout() {
3333
hasExplicitAnyObject = false;
34+
hasInverseCopyable = false;
3435
containsNonObjCProtocol = false;
3536
containsParameterized = false;
3637
}
@@ -46,6 +47,9 @@ struct ExistentialLayout {
4647
/// Whether the existential contains an explicit '& AnyObject' constraint.
4748
bool hasExplicitAnyObject : 1;
4849

50+
/// Whether the existential contains an explicit '& ~Copyable' constraint.
51+
bool hasInverseCopyable : 1;
52+
4953
/// Whether any protocol members are non-@objc.
5054
bool containsNonObjCProtocol : 1;
5155

lib/AST/Type.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,25 +341,40 @@ ExistentialLayout::ExistentialLayout(CanProtocolType type) {
341341
auto *protoDecl = type->getDecl();
342342

343343
hasExplicitAnyObject = false;
344+
hasInverseCopyable = false;
344345
containsNonObjCProtocol = !protoDecl->isObjC();
345346
containsParameterized = false;
346347

347348
protocols.push_back(protoDecl);
348349
}
349350

350351
ExistentialLayout::ExistentialLayout(CanInverseType type) {
351-
// TODO: implement this correctly!!!!!!!!!
352352
hasExplicitAnyObject = false;
353+
hasInverseCopyable = false;
353354
containsNonObjCProtocol = false;
354355
containsParameterized = false;
355-
llvm_unreachable("FIXME");
356+
357+
// Handle inverse.
358+
switch (type->getInverseKind()) {
359+
case InvertibleProtocolKind::Copyable:
360+
hasInverseCopyable = true;
361+
}
356362
}
357363

358364
ExistentialLayout::ExistentialLayout(CanProtocolCompositionType type) {
359365
hasExplicitAnyObject = type->hasExplicitAnyObject();
366+
hasInverseCopyable = false;
360367
containsNonObjCProtocol = false;
361368
containsParameterized = false;
362369

370+
// Handle inverses.
371+
for (auto ip : type->getInverses()) {
372+
switch (ip) {
373+
case InvertibleProtocolKind::Copyable:
374+
hasInverseCopyable = true;
375+
}
376+
}
377+
363378
auto members = type.getMembers();
364379
if (!members.empty() &&
365380
(members[0].getClassOrBoundGenericClass() ||

lib/Sema/TypeCheckDecl.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -961,13 +961,6 @@ bool HasNoncopyableAnnotationRequest::evaluate(Evaluator &evaluator, TypeDecl *d
961961
if (defaults.contains(kind)) {
962962
defaults.remove(kind);
963963
lastInverse.insert({kind, loc});
964-
965-
// Classes are always copyable.
966-
if (isa<ClassDecl>(decl) && kind == InvertibleProtocolKind::Copyable) {
967-
ctx.Diags.diagnose(loc, diag::noncopyable_class);
968-
return;
969-
}
970-
971964
return;
972965
}
973966

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,12 @@ static void checkInheritanceClause(
227227
continue;
228228
}
229229

230+
// Classes are always copyable.
231+
if (layout.hasInverseCopyable && isa<ClassDecl>(decl)) {
232+
decl->diagnose(diag::noncopyable_class);
233+
continue;
234+
}
235+
230236
// If the existential did not have a class constraint, we're done.
231237
if (!layout.explicitSuperclass)
232238
continue;

0 commit comments

Comments
 (0)