Sema: Diagnose opaque types that depend on availability of a custom domain.

Serialization and IRGen don't yet support opaque return types that would depend
on querying availability of a custom domain so we need to reject this code to
avoid mis-compiling it.
This commit is contained in:
Allan Shortlidge
2025-06-25 15:22:54 -07:00
parent 4a76c04cf5
commit 59d74fa1c7
3 changed files with 45 additions and 1 deletions

View File

@@ -5300,7 +5300,9 @@ GROUPED_ERROR(opaque_type_var_no_init,OpaqueTypeInference,none,
GROUPED_ERROR(opaque_type_var_no_underlying_type,OpaqueTypeInference,none,
"property declares an opaque return type, but cannot infer the "
"underlying type from its initializer expression", ())
GROUPED_ERROR(opaque_type_unsupported_availability,OpaqueTypeInference,none,
"opaque return type cannot depend on %0 availability",
(AvailabilityDomain))
//------------------------------------------------------------------------------
// MARK: Discard Statement

View File

@@ -3530,6 +3530,32 @@ public:
return;
}
// Diagnose unsupported availability domains.
// FIXME: [availability] Support custom domains.
bool anyUnsupportedDomain = false;
for (const auto &entry : Candidates) {
IfStmt *stmt = entry.first;
if (!stmt) continue;
for (const auto &elt : stmt->getCond()) {
if (elt.getKind() != StmtConditionElement::CK_Availability)
continue;
auto poundAvailable = elt.getAvailability();
if (auto query = poundAvailable->getAvailabilityQuery()) {
if (query->getDomain().isCustom()) {
Ctx.Diags.diagnose(poundAvailable->getStartLoc(),
diag::opaque_type_unsupported_availability,
query->getDomain());
anyUnsupportedDomain = true;
}
}
}
}
if (anyUnsupportedDomain)
return;
SmallVector<Candidate, 4> universallyUniqueCandidates;
for (const auto &entry : Candidates) {

View File

@@ -193,3 +193,19 @@ struct EnabledDomainAvailable {
unavailableInDisabledDomain() // expected-error {{'unavailableInDisabledDomain()' is unavailable}}
}
}
protocol P { }
@available(EnabledDomain)
struct AvailableInEnabledDomain: P { }
@available(EnabledDomain, unavailable)
struct UnavailableInEnabledDomain: P { }
func testOpaqueReturnType() -> some P {
if #available(EnabledDomain) { // expected-error {{opaque return type cannot depend on EnabledDomain availability}}
return AvailableInEnabledDomain()
} else {
return UnavailableInEnabledDomain()
}
}