mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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:
@@ -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);
|
||||
|
||||
@@ -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'}}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user