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)
|
if (!req)
|
||||||
return getTypeMatchFailure(locator);
|
return getTypeMatchFailure(locator);
|
||||||
|
|
||||||
if (type1->isPlaceholder() ||
|
// Superclass constraints are never satisfied by existentials,
|
||||||
req->getRequirementKind() == RequirementKind::Superclass)
|
// even those that contain the superclass a la `any C & P`.
|
||||||
|
if (!type1->isExistentialType() &&
|
||||||
|
(type1->isPlaceholder() ||
|
||||||
|
req->getRequirementKind() == RequirementKind::Superclass))
|
||||||
return getTypeMatchSuccess();
|
return getTypeMatchSuccess();
|
||||||
|
|
||||||
auto *fix = fixRequirementFailure(*this, type1, type2, locator);
|
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'}}
|
// 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