Skip to content

Commit 4fafee7

Browse files
committed
[Sema] Require existential types with Self or associated type
requirements to be spelled with 'any' when explicit existential types are enabled.
1 parent ac5dc85 commit 4fafee7

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4623,6 +4623,9 @@ WARNING(unnecessary_any,none,
46234623
ERROR(any_not_existential,none,
46244624
"'any' has no effect on %select{concrete type|type parameter}0 %1",
46254625
(bool, Type))
4626+
ERROR(existential_requires_any,none,
4627+
"protocol %0 as a type must be explicitly marked as 'any'",
4628+
(Identifier))
46264629
ERROR(explicit_existential_not_supported,none,
46274630
"explicit 'any' not supported; use frontend flag "
46284631
"-enable-explicit-existential-types to enable this feature",

lib/Sema/TypeCheckType.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3968,6 +3968,10 @@ class ExistentialTypeVisitor
39683968
// Arbitrary protocol constraints are OK on opaque types.
39693969
if (isa<OpaqueReturnTypeRepr>(T))
39703970
return false;
3971+
3972+
// Arbitrary protocol constraints are okay for 'any' types.
3973+
if (isa<ExistentialTypeRepr>(T))
3974+
return false;
39713975

39723976
visit(T);
39733977
return true;
@@ -3991,7 +3995,36 @@ class ExistentialTypeVisitor
39913995
}
39923996

39933997
void visitIdentTypeRepr(IdentTypeRepr *T) {
3994-
return;
3998+
if (T->isInvalid() || !Ctx.LangOpts.EnableExplicitExistentialTypes)
3999+
return;
4000+
4001+
auto comp = T->getComponentRange().back();
4002+
if (auto *proto = dyn_cast_or_null<ProtocolDecl>(comp->getBoundDecl())) {
4003+
if (proto->existentialRequiresAny()) {
4004+
Ctx.Diags.diagnose(comp->getNameLoc(),
4005+
diag::existential_requires_any,
4006+
proto->getName());
4007+
}
4008+
} else if (auto *alias = dyn_cast_or_null<TypeAliasDecl>(comp->getBoundDecl())) {
4009+
auto type = Type(alias->getDeclaredInterfaceType()->getDesugaredType());
4010+
type.findIf([&](Type type) -> bool {
4011+
if (T->isInvalid())
4012+
return false;
4013+
if (type->isExistentialType()) {
4014+
auto layout = type->getExistentialLayout();
4015+
for (auto *proto : layout.getProtocols()) {
4016+
auto *protoDecl = proto->getDecl();
4017+
if (!protoDecl->existentialRequiresAny())
4018+
continue;
4019+
4020+
Ctx.Diags.diagnose(comp->getNameLoc(),
4021+
diag::existential_requires_any,
4022+
protoDecl->getName());
4023+
}
4024+
}
4025+
return false;
4026+
});
4027+
}
39954028
}
39964029

39974030
void visitRequirements(ArrayRef<RequirementRepr> reqts) {

0 commit comments

Comments
 (0)