@@ -4008,6 +4008,30 @@ NeverNullType TypeResolver::resolveMetatypeType(MetatypeTypeRepr *repr,
40084008NeverNullType
40094009TypeResolver::buildMetatypeType (MetatypeTypeRepr *repr, Type instanceType,
40104010 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+
40114035 if (instanceType->isAnyExistentialType () &&
40124036 !instanceType->is <ExistentialType>()) {
40134037 // TODO: diagnose invalid representations?
0 commit comments