diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp index 430d336628f06..032510e40259a 100644 --- a/lib/Sema/MiscDiagnostics.cpp +++ b/lib/Sema/MiscDiagnostics.cpp @@ -2848,7 +2848,9 @@ class OpaqueUnderlyingTypeChecker : public ASTWalker { // If this is `if #available` statement with no other dynamic // conditions, let's check if it returns opaque type directly. if (llvm::all_of(If->getCond(), [&](const auto &condition) { - return condition.getKind() == StmtConditionElement::CK_Availability; + return condition.getKind() == + StmtConditionElement::CK_Availability && + !condition.getAvailability()->isUnavailability(); })) { // Check return statement directly with availability context set. if (auto *Then = dyn_cast(If->getThenStmt())) { diff --git a/test/type/opaque_with_conditional_availability.swift b/test/type/opaque_with_conditional_availability.swift index e0317c47d24b9..640b6f913a38b 100644 --- a/test/type/opaque_with_conditional_availability.swift +++ b/test/type/opaque_with_conditional_availability.swift @@ -106,3 +106,15 @@ func test_fail_without_universally_available_type() -> some P { return Y() } } + +// Treat `if #unavailable` like regular conditions. +func test_fail_with_unavailability_condition() -> some P { + // expected-error@-1 {{function declares an opaque return type 'some P', but the return statements in its body do not have matching underlying types}} + // expected-note@-2 {{add @available attribute to enclosing global function}} + if #unavailable(macOS 12) { + return X() // expected-error {{'X' is only available in macOS 11.0 or newer}} expected-note {{return statement has underlying type 'X'}} + // expected-note@-1 {{add 'if #available' version check}} + } + + return Y() // expected-note {{return statement has underlying type 'Y'}} +}