Skip to content

Commit 8a281ef

Browse files
committed
[AST] Implement IgnoreSendability flag while matching types
This supports `any Sendable` -> `Any` matching in generic types and directly.
1 parent 17deda6 commit 8a281ef

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

lib/AST/Type.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3310,6 +3310,37 @@ static bool matches(CanType t1, CanType t2, TypeMatchOptions matchMode,
33103310
opaque1->getInterfaceType()->getCanonicalType()->matches(
33113311
opaque2->getInterfaceType()->getCanonicalType(), matchMode);
33123312

3313+
if (matchMode.contains(TypeMatchFlags::IgnoreSendability)) {
3314+
// Support `any Sendable` -> `Any` matching inside generic types
3315+
// e.g. collections and optionals (i.e. `[String: (any Sendable)?]`).
3316+
if (auto *generic1 = t1->getAs<BoundGenericType>()) {
3317+
if (auto *generic2 = t2->getAs<BoundGenericType>()) {
3318+
if (generic1->getDecl() == generic2->getDecl()) {
3319+
auto genericArgs1 = generic1->getGenericArgs();
3320+
auto genericArgs2 = generic2->getGenericArgs();
3321+
3322+
if (genericArgs1.size() == genericArgs2.size() &&
3323+
llvm::all_of(llvm::zip_equal(genericArgs1, genericArgs2),
3324+
[&](const auto &elt) -> bool {
3325+
return matches(
3326+
std::get<0>(elt)->getCanonicalType(),
3327+
std::get<1>(elt)->getCanonicalType(),
3328+
matchMode, ParameterPosition::NotParameter,
3329+
OptionalUnwrapping::None);
3330+
}))
3331+
return true;
3332+
}
3333+
}
3334+
}
3335+
3336+
// Attempting to match `any Sendable` by `Any` is allowed in this mode.
3337+
if (t1->isAny()) {
3338+
auto *PD = dyn_cast_or_null<ProtocolDecl>(t2->getAnyNominal());
3339+
if (PD && PD->isSpecificProtocol(KnownProtocolKind::Sendable))
3340+
return true;
3341+
}
3342+
}
3343+
33133344
return false;
33143345
}
33153346

0 commit comments

Comments
 (0)