mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[CSSimplify] Skip member access on existential checks if base is existential only due to marker protocols
If the base type is composed with marker protocol(s) i.e. `<<Type>> & Sendable`, let's skip this check because such compositions are always opened and simplified down to a superclass bound post-Sema. Resolves: rdar://148782046
This commit is contained in:
@@ -10431,22 +10431,33 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
|
||||
}
|
||||
|
||||
const auto isUnsupportedExistentialMemberAccess = [&] {
|
||||
// We may not be able to derive a well defined type for an existential
|
||||
// member access if the member's signature references 'Self'.
|
||||
if (instanceTy->isExistentialType()) {
|
||||
switch (isMemberAvailableOnExistential(instanceTy, decl)) {
|
||||
case ExistentialMemberAccessLimitation::Unsupported:
|
||||
// TODO: Write-only accesses are not supported yet.
|
||||
case ExistentialMemberAccessLimitation::WriteOnly:
|
||||
return true;
|
||||
if (!instanceTy->isExistentialType())
|
||||
return false;
|
||||
|
||||
case ExistentialMemberAccessLimitation::ReadOnly:
|
||||
case ExistentialMemberAccessLimitation::None:
|
||||
break;
|
||||
}
|
||||
// If the base type is composed with marker protocol(s) i.e.
|
||||
// `<<Type>> & Sendable`, let's skip this check because such
|
||||
// compositions are always opened and simplified down to a
|
||||
// superclass bound post-Sema.
|
||||
if (auto *existential = instanceTy->getAs<ExistentialType>()) {
|
||||
auto *compositionTy =
|
||||
existential->getConstraintType()->getAs<ProtocolCompositionType>();
|
||||
if (compositionTy &&
|
||||
!compositionTy->withoutMarkerProtocols()->isExistentialType())
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
// We may not be able to derive a well defined type for an existential
|
||||
// member access if the member's signature references 'Self'.
|
||||
switch (isMemberAvailableOnExistential(instanceTy, decl)) {
|
||||
case ExistentialMemberAccessLimitation::Unsupported:
|
||||
// TODO: Write-only accesses are not supported yet.
|
||||
case ExistentialMemberAccessLimitation::WriteOnly:
|
||||
return true;
|
||||
|
||||
case ExistentialMemberAccessLimitation::ReadOnly:
|
||||
case ExistentialMemberAccessLimitation::None:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// See if we have an instance method, instance member or static method,
|
||||
|
||||
@@ -58,3 +58,27 @@ do {
|
||||
generic(Int.self)
|
||||
// CHECK: D<Int>
|
||||
}
|
||||
|
||||
protocol Q {
|
||||
func update(_: [Self])
|
||||
}
|
||||
|
||||
extension Q {
|
||||
func update(_ arr: [Self]) { print(Self.self) }
|
||||
}
|
||||
|
||||
do {
|
||||
class Parent : Q {}
|
||||
class Subclass: Parent {}
|
||||
|
||||
func test(_ v: Parent & Sendable) {
|
||||
v.update([])
|
||||
}
|
||||
|
||||
test(Subclass())
|
||||
// CHECK: Subclass
|
||||
|
||||
let sendableV: any Subclass & Sendable = Subclass()
|
||||
test(sendableV)
|
||||
// CHECK: Subclass
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user