Skip to content

Commit 5358eb6

Browse files
committed
AST: Fix bug in subclass composition minimization
Now that opened archetype signatures are generalized to encompass outer generic contexts, the number of requirements in the generic signature is not always indicative of whether the minimal type is also a composition.
1 parent 41d720e commit 5358eb6

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

lib/AST/Type.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4146,6 +4146,12 @@ CanType ProtocolCompositionType::getMinimalCanonicalType(
41464146
if (superclass)
41474147
MinimalMembers.insert(MinimalMembers.begin(), superclass->getCanonicalType());
41484148

4149+
// If we are left with a single member and no layout constraint, the member
4150+
// is the minimal type. Also, note that a protocol composition cannot be
4151+
// constructed with a single member unless there is a layout constraint.
4152+
if (MinimalMembers.size() == 1 && !MinimalHasExplicitAnyObject)
4153+
return CanType(MinimalMembers.front());
4154+
41494155
// The resulting composition is necessarily canonical.
41504156
return CanType(build(Ctx, MinimalMembers, MinimalHasExplicitAnyObject));
41514157
}

test/type/subclass_composition.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ typealias OtherAndP2 = Other & P2
4242

4343
protocol P3 : class {}
4444

45+
protocol P4 {}
46+
4547
struct Unrelated {}
4648

4749
//
@@ -70,6 +72,18 @@ func alreadyConforms(_: P3 & AnyObject) {} // expected-error {{invalid redeclara
7072
func alreadyConformsMeta(_: P3.Type) {} // expected-note {{'alreadyConformsMeta' previously declared here}}
7173
func alreadyConformsMeta(_: (P3 & AnyObject).Type) {} // expected-error {{invalid redeclaration of 'alreadyConformsMeta'}}
7274

75+
func notARedeclaration(_: P4) {}
76+
func notARedeclaration(_: P4 & AnyObject) {}
77+
78+
do {
79+
class C: P4 {}
80+
struct S<T: P4> {
81+
// Don't crash when computing minimal compositions inside a generic context.
82+
func redeclaration(_: C & P4) {} // expected-note {{'redeclaration' previously declared here}}
83+
func redeclaration(_: C & P4) {} // expected-error {{invalid redeclaration of 'redeclaration'}}
84+
}
85+
}
86+
7387
// SE-0156 stipulates that a composition can contain multiple classes, as long
7488
// as they are all the same.
7589
func basicDiagnostics(

0 commit comments

Comments
 (0)