Existential Types Cannot Satisfy Superclass Bounds

It is not the case that `any P` satisfies a class bound
even if the existential is a composition with an exact
match to the class bound. The resulting existential box
must be opened as the exact class type before this conversion
can succeed.

This appears to be a regression from Swift 5.1, which was the last
Swift compiler that banned this typing rule.

rdar://92358570
This commit is contained in:
Robert Widmann
2022-05-02 15:59:10 -07:00
parent 8b2ccd9ed5
commit 6d28831617
2 changed files with 27 additions and 2 deletions

View File

@@ -3465,8 +3465,11 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
if (!req)
return getTypeMatchFailure(locator);
if (type1->isPlaceholder() ||
req->getRequirementKind() == RequirementKind::Superclass)
// Superclass constraints are never satisfied by existentials,
// even those that contain the superclass a la `any C & P`.
if (!type1->isExistentialType() &&
(type1->isPlaceholder() ||
req->getRequirementKind() == RequirementKind::Superclass))
return getTypeMatchSuccess();
auto *fix = fixRequirementFailure(*this, type1, type2, locator);

View File

@@ -753,3 +753,25 @@ func fSR14533(_ s: SR14533) {
// expected-error@-1{{value of type 'SR14533' has no member 'ys'}}
}
}
// rdar://92358570
class SomeClassBound {}
protocol ClassBoundProtocol: SomeClassBound {
}
struct RDAR92358570<Element> {}
extension RDAR92358570 where Element : SomeClassBound {
// expected-note@-1 2 {{where 'Element' = 'any ClassBoundProtocol', 'SomeClassBound' = 'AnyObject'}}
// expected-note@-2 2 {{where 'Element' = 'any SomeClassBound & ClassBoundProtocol', 'SomeClassBound' = 'AnyObject'}}
func doSomething() {}
static func doSomethingStatically() {}
}
func rdar92358570(_ x: RDAR92358570<ClassBoundProtocol>, _ y: RDAR92358570<SomeClassBound & ClassBoundProtocol>) {
x.doSomething() // expected-error {{referencing instance method 'doSomething()' on 'RDAR92358570' requires that 'any ClassBoundProtocol' inherit from 'AnyObject'}}
RDAR92358570<ClassBoundProtocol>.doSomethingStatically() // expected-error {{referencing static method 'doSomethingStatically()' on 'RDAR92358570' requires that 'any ClassBoundProtocol' inherit from 'AnyObject'}}
y.doSomething() // expected-error {{referencing instance method 'doSomething()' on 'RDAR92358570' requires that 'any SomeClassBound & ClassBoundProtocol' inherit from 'AnyObject'}}
RDAR92358570<SomeClassBound & ClassBoundProtocol>.doSomethingStatically() // expected-error {{referencing static method 'doSomethingStatically()' on 'RDAR92358570' requires that 'any SomeClassBound & ClassBoundProtocol' inherit from 'AnyObject'}}
}