Skip to content

Commit 3e936e3

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 8d52f71 commit 3e936e3

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
@@ -3950,6 +3950,10 @@ class ExistentialTypeVisitor
39503950
// Arbitrary protocol constraints are OK on opaque types.
39513951
if (isa<OpaqueReturnTypeRepr>(T))
39523952
return false;
3953+
3954+
// Arbitrary protocol constraints are okay for 'any' types.
3955+
if (isa<ExistentialTypeRepr>(T))
3956+
return false;
39533957

39543958
visit(T);
39553959
return true;
@@ -3973,7 +3977,36 @@ class ExistentialTypeVisitor
39733977
}
39743978

39753979
void visitIdentTypeRepr(IdentTypeRepr *T) {
3976-
return;
3980+
if (T->isInvalid() || !Ctx.LangOpts.EnableExplicitExistentialTypes)
3981+
return;
3982+
3983+
auto comp = T->getComponentRange().back();
3984+
if (auto *proto = dyn_cast_or_null<ProtocolDecl>(comp->getBoundDecl())) {
3985+
if (proto->existentialRequiresAny()) {
3986+
Ctx.Diags.diagnose(comp->getNameLoc(),
3987+
diag::existential_requires_any,
3988+
proto->getName());
3989+
}
3990+
} else if (auto *alias = dyn_cast_or_null<TypeAliasDecl>(comp->getBoundDecl())) {
3991+
auto type = Type(alias->getDeclaredInterfaceType()->getDesugaredType());
3992+
type.findIf([&](Type type) -> bool {
3993+
if (T->isInvalid())
3994+
return false;
3995+
if (type->isExistentialType()) {
3996+
auto layout = type->getExistentialLayout();
3997+
for (auto *proto : layout.getProtocols()) {
3998+
auto *protoDecl = proto->getDecl();
3999+
if (!protoDecl->existentialRequiresAny())
4000+
continue;
4001+
4002+
Ctx.Diags.diagnose(comp->getNameLoc(),
4003+
diag::existential_requires_any,
4004+
protoDecl->getName());
4005+
}
4006+
}
4007+
return false;
4008+
});
4009+
}
39774010
}
39784011

39794012
void visitRequirements(ArrayRef<RequirementRepr> reqts) {

0 commit comments

Comments
 (0)