@@ -3712,6 +3712,16 @@ bool ProtocolCompositionType::requiresClass() {
37123712Type ProtocolCompositionType::get (const ASTContext &C,
37133713 ArrayRef<Type> Members,
37143714 bool HasExplicitAnyObject) {
3715+ // Fast path for 'AnyObject' and 'Any'.
3716+ if (Members.empty ()) {
3717+ return build (C, Members, HasExplicitAnyObject);
3718+ }
3719+
3720+ // If there's a single member and no layout constraint, return that type.
3721+ if (Members.size () == 1 && !HasExplicitAnyObject) {
3722+ return Members.front ();
3723+ }
3724+
37153725 for (Type t : Members) {
37163726 if (!t->isCanonical ())
37173727 return build (C, Members, HasExplicitAnyObject);
@@ -3730,11 +3740,6 @@ Type ProtocolCompositionType::get(const ASTContext &C,
37303740 if (Superclass)
37313741 HasExplicitAnyObject = false ;
37323742
3733- // If one protocol remains with no further constraints, its nominal
3734- // type is the canonical type.
3735- if (Protocols.size () == 1 && !Superclass && !HasExplicitAnyObject)
3736- return Protocols.front ()->getDeclaredInterfaceType ();
3737-
37383743 // Form the set of canonical protocol types from the protocol
37393744 // declarations, and use that to build the canonical composition type.
37403745 SmallVector<Type, 4 > CanTypes;
@@ -3744,6 +3749,10 @@ Type ProtocolCompositionType::get(const ASTContext &C,
37443749 Protocols, std::back_inserter (CanTypes),
37453750 [](ProtocolDecl *Proto) { return Proto->getDeclaredInterfaceType (); });
37463751
3752+ // If one member remains and no layout constraint, return that type.
3753+ if (CanTypes.size () == 1 && !HasExplicitAnyObject)
3754+ return CanTypes.front ();
3755+
37473756 // TODO: Canonicalize away HasExplicitAnyObject if it is implied
37483757 // by one of our member protocols.
37493758 return build (C, CanTypes, HasExplicitAnyObject);
0 commit comments