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