@@ -3712,6 +3712,16 @@ bool ProtocolCompositionType::requiresClass() {
3712
3712
Type ProtocolCompositionType::get (const ASTContext &C,
3713
3713
ArrayRef<Type> Members,
3714
3714
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
+
3715
3725
for (Type t : Members) {
3716
3726
if (!t->isCanonical ())
3717
3727
return build (C, Members, HasExplicitAnyObject);
@@ -3730,11 +3740,6 @@ Type ProtocolCompositionType::get(const ASTContext &C,
3730
3740
if (Superclass)
3731
3741
HasExplicitAnyObject = false ;
3732
3742
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
-
3738
3743
// Form the set of canonical protocol types from the protocol
3739
3744
// declarations, and use that to build the canonical composition type.
3740
3745
SmallVector<Type, 4 > CanTypes;
@@ -3744,6 +3749,10 @@ Type ProtocolCompositionType::get(const ASTContext &C,
3744
3749
Protocols, std::back_inserter (CanTypes),
3745
3750
[](ProtocolDecl *Proto) { return Proto->getDeclaredInterfaceType (); });
3746
3751
3752
+ // If one member remains and no layout constraint, return that type.
3753
+ if (CanTypes.size () == 1 && !HasExplicitAnyObject)
3754
+ return CanTypes.front ();
3755
+
3747
3756
// TODO: Canonicalize away HasExplicitAnyObject if it is implied
3748
3757
// by one of our member protocols.
3749
3758
return build (C, CanTypes, HasExplicitAnyObject);
0 commit comments