Skip to content

Commit adfb983

Browse files
committed
[SE-0290] Cleanup BuilderTransform for #unavailable
1 parent 1fe3857 commit adfb983

File tree

3 files changed

+52
-52
lines changed

3 files changed

+52
-52
lines changed

lib/Sema/BuilderTransform.cpp

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -505,16 +505,16 @@ class BuilderClosureVisitor
505505
Expr *thenVarRefExpr = buildVarRef(
506506
thenVar, ifStmt->getThenStmt()->getEndLoc());
507507

508-
/// If there is a #available in the condition, wrap the 'then' in a call to
509-
/// buildLimitedAvailability(_:).
508+
// If there is a #available in the condition, wrap the 'then' in a call to
509+
// buildLimitedAvailability(_:).
510510
auto availabilityCond = findAvailabilityCondition(ifStmt->getCond());
511-
bool supportsAvailable = availabilityCond &&
512-
builderSupports(ctx.Id_buildLimitedAvailability);
513-
auto apiAvailability = availabilityCond->getAvailability();
514-
if (supportsAvailable && !apiAvailability->isUnavailability()) {
515-
thenVarRefExpr = buildCallIfWanted(
516-
ifStmt->getThenStmt()->getEndLoc(), ctx.Id_buildLimitedAvailability,
517-
{ thenVarRefExpr }, { Identifier() });
511+
bool supportsAvailability =
512+
availabilityCond && builderSupports(ctx.Id_buildLimitedAvailability);
513+
if (supportsAvailability &&
514+
!availabilityCond->getAvailability()->isUnavailability()) {
515+
thenVarRefExpr = buildCallIfWanted(ifStmt->getThenStmt()->getEndLoc(),
516+
ctx.Id_buildLimitedAvailability,
517+
{thenVarRefExpr}, {Identifier()});
518518
}
519519

520520
// Prepare the `then` operand by wrapping it to produce a chain result.
@@ -530,25 +530,29 @@ class BuilderClosureVisitor
530530
assert(isOptional);
531531
elseLoc = ifStmt->getEndLoc();
532532
elseExpr = buildNoneExpr(elseLoc);
533-
} else {
533+
534+
// - If there's an `else if`, the chain expression from that
535+
// should already be producing a chain result.
536+
} else if (isElseIf) {
537+
elseExpr = buildVarRef(*elseChainVar, ifStmt->getEndLoc());
534538
elseLoc = ifStmt->getElseLoc();
535-
Expr *elseVarRefExpr = buildVarRef(*elseChainVar, ifStmt->getEndLoc());
536-
/// If there is a #unavailable in the condition, wrap the 'else' in a call
537-
/// to buildLimitedAvailability(_:).
538-
if (supportsAvailable && apiAvailability->isUnavailability()) {
539-
elseVarRefExpr = buildCallIfWanted(
540-
ifStmt->getEndLoc(), ctx.Id_buildLimitedAvailability,
541-
{ elseVarRefExpr }, { Identifier() });
542-
}
543-
// - If there's an `else if`, the chain expression from that
544-
// should already be producing a chain result.
545-
if (isElseIf) {
546-
elseExpr = elseVarRefExpr;
539+
547540
// - Otherwise, wrap it to produce a chain result.
548-
} else {
549-
elseExpr = buildWrappedChainPayload(
550-
elseVarRefExpr, payloadIndex + 1, numPayloads, isOptional);
541+
} else {
542+
Expr *elseVarRefExpr = buildVarRef(*elseChainVar, ifStmt->getEndLoc());
543+
544+
// If there is a #unavailable in the condition, wrap the 'else' in a call
545+
// to buildLimitedAvailability(_:).
546+
if (supportsAvailability &&
547+
availabilityCond->getAvailability()->isUnavailability()) {
548+
elseVarRefExpr = buildCallIfWanted(ifStmt->getEndLoc(),
549+
ctx.Id_buildLimitedAvailability,
550+
{elseVarRefExpr}, {Identifier()});
551551
}
552+
553+
elseExpr = buildWrappedChainPayload(elseVarRefExpr, payloadIndex + 1,
554+
numPayloads, isOptional);
555+
elseLoc = ifStmt->getElseLoc();
552556
}
553557

554558
// The operand should have optional type if we had optional results,

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -795,14 +795,15 @@ class TypeRefinementContextBuilder : private ASTWalker {
795795
FalseRefinement = FalseFlow;
796796
}
797797

798-
auto makeResult = ^(Optional<AvailabilityContext> TrueRefinement,
799-
Optional<AvailabilityContext> FalseRefinement) {
800-
if (isUnavailability.hasValue() && isUnavailability.getValue()) {
801-
// If this is an unavailability check, invert the result.
802-
return std::make_pair(FalseRefinement, TrueRefinement);
803-
}
804-
return std::make_pair(TrueRefinement, FalseRefinement);
805-
};
798+
auto makeResult =
799+
[isUnavailability](Optional<AvailabilityContext> TrueRefinement,
800+
Optional<AvailabilityContext> FalseRefinement) {
801+
if (isUnavailability.hasValue() && isUnavailability.getValue()) {
802+
// If this is an unavailability check, invert the result.
803+
return std::make_pair(FalseRefinement, TrueRefinement);
804+
}
805+
return std::make_pair(TrueRefinement, FalseRefinement);
806+
};
806807

807808
if (NestedCount == 0)
808809
return makeResult(None, FalseRefinement);
@@ -823,9 +824,7 @@ class TypeRefinementContextBuilder : private ASTWalker {
823824
OtherPlatformAvailabilitySpec *FoundOtherSpec = nullptr;
824825
PlatformVersionConstraintAvailabilitySpec *BestSpec = nullptr;
825826

826-
auto Queries = available->getQueries();
827-
828-
for (auto *Spec : Queries) {
827+
for (auto *Spec : available->getQueries()) {
829828
if (auto *OtherSpec = dyn_cast<OtherPlatformAvailabilitySpec>(Spec)) {
830829
FoundOtherSpec = OtherSpec;
831830
continue;

test/Constraints/result_builder_availability.swift

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -73,26 +73,32 @@ struct Only10_52 { }
7373
func globalFuncAvailableOn10_52() -> Only10_52 { .init() }
7474

7575
tuplify(true) { cond in
76-
var bool = true
7776
globalFuncAvailableOn10_9()
7877
if #available(OSX 10.51, *) {
7978
globalFuncAvailableOn10_51()
8079
tuplify(false) { cond2 in
81-
if cond, #available(OSX 10.52, *) { // expected-warning{{result builder 'TupleBuilder' does not implement 'buildLimitedAvailability'; this code may crash on earlier versions of the OS}}
80+
if cond, #available(OSX 10.52, *) {
81+
// expected-warning@-1{{result builder 'TupleBuilder' does not implement 'buildLimitedAvailability'; this code may crash on earlier versions of the OS}}
8282
cond2
8383
globalFuncAvailableOn10_52()
84-
} else if bool {
84+
} else if true {
85+
globalFuncAvailableOn10_52() // expected-error{{'globalFuncAvailableOn10_52()' is only available in macOS 10.52 or newer}}
86+
// expected-note@-1{{add 'if #available' version check}}
87+
} else if false {
8588
globalFuncAvailableOn10_52() // expected-error{{'globalFuncAvailableOn10_52()' is only available in macOS 10.52 or newer}}
8689
// expected-note@-1{{add 'if #available' version check}}
8790
} else {
8891
globalFuncAvailableOn10_52() // expected-error{{'globalFuncAvailableOn10_52()' is only available in macOS 10.52 or newer}}
8992
// expected-note@-1{{add 'if #available' version check}}
9093
}
91-
if cond, #unavailable(OSX 10.52) { // expected-warning{{result builder 'TupleBuilder' does not implement 'buildLimitedAvailability'; this code may crash on earlier versions of the OS}}
94+
if cond, #unavailable(OSX 10.52) {
95+
// expected-warning@-1{{result builder 'TupleBuilder' does not implement 'buildLimitedAvailability'; this code may crash on earlier versions of the OS}}
9296
cond2
9397
globalFuncAvailableOn10_52() // expected-error{{'globalFuncAvailableOn10_52()' is only available in macOS 10.52 or newer}}
9498
// expected-note@-1{{add 'if #available' version check}}
95-
} else if bool {
99+
} else if true {
100+
globalFuncAvailableOn10_52()
101+
} else if false {
96102
globalFuncAvailableOn10_52()
97103
} else {
98104
globalFuncAvailableOn10_52()
@@ -148,21 +154,12 @@ func tuplifyWithAvailabilityErasure<T>(_ cond: Bool, @TupleBuilderAvailability b
148154
}
149155

150156
tuplifyWithAvailabilityErasure(true) { cond in
151-
var bool = true
152157
if cond, #available(OSX 10.52, *) {
153158
globalFuncAvailableOn10_52()
154-
} else if bool {
155-
globalFuncAvailableOn10_52() // expected-error{{'globalFuncAvailableOn10_52()' is only available in macOS 10.52 or newer}}
156-
// expected-note@-1{{add 'if #available' version check}}
157-
} else {
158-
globalFuncAvailableOn10_52() // expected-error{{'globalFuncAvailableOn10_52()' is only available in macOS 10.52 or newer}}
159-
// expected-note@-1{{add 'if #available' version check}}
160159
}
160+
161161
if cond, #unavailable(OSX 10.52) {
162-
globalFuncAvailableOn10_52() // expected-error{{'globalFuncAvailableOn10_52()' is only available in macOS 10.52 or newer}}
163-
// expected-note@-1{{add 'if #available' version check}}
164-
} else if bool {
165-
globalFuncAvailableOn10_52()
162+
cond
166163
} else {
167164
globalFuncAvailableOn10_52()
168165
}

0 commit comments

Comments
 (0)