@@ -4008,6 +4008,30 @@ NeverNullType TypeResolver::resolveMetatypeType(MetatypeTypeRepr *repr,
4008
4008
NeverNullType
4009
4009
TypeResolver::buildMetatypeType (MetatypeTypeRepr *repr, Type instanceType,
4010
4010
Optional<MetatypeRepresentation> storedRepr) {
4011
+ // If the instance type is an existential metatype, figure out if
4012
+ // the syntax is of the form '(any <protocol metatype>).Type'. In
4013
+ // this case, type resolution should produce the static metatype
4014
+ // of that existential metatype, versus another existential metatype
4015
+ // via the old '<protocol metatype>.Type' syntax.
4016
+ if (instanceType->is <ExistentialMetatypeType>()) {
4017
+ // First, look for the paren type.
4018
+ auto *tuple = dyn_cast<TupleTypeRepr>(repr->getBase ());
4019
+ if (tuple && tuple->isParenType ()) {
4020
+ // Then, look through parens for the 'any' keyword.
4021
+ auto *element = tuple->getWithoutParens ();
4022
+ if (auto *existential = dyn_cast<ExistentialTypeRepr>(element)) {
4023
+ // Finally, look for a constraint ending with '.Type'. Assume the
4024
+ // base is a protocol, otherwise resolveExistentialType would
4025
+ // have emitted an error message and returned the concrete type
4026
+ // instead of an existential metatype.
4027
+ auto *constraint = existential->getConstraint ()->getWithoutParens ();
4028
+ if (isa<MetatypeTypeRepr>(constraint)) {
4029
+ return MetatypeType::get (instanceType, storedRepr);
4030
+ }
4031
+ }
4032
+ }
4033
+ }
4034
+
4011
4035
if (instanceType->isAnyExistentialType () &&
4012
4036
!instanceType->is <ExistentialType>()) {
4013
4037
// TODO: diagnose invalid representations?
0 commit comments