Skip to content

Commit 05736d1

Browse files
committed
Handle multiple @available attributes correctly
The previous commit broke a promise made by the implementation it replaced: if there were two or more @available(introduced:) attributes for the same platform, the greatest version wins. This commit restores that property while still completely overriding the parent platform’s availability with a child platform’s.
1 parent 96e6e50 commit 05736d1

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

lib/AST/Availability.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,26 @@ void AvailabilityInference::applyInferredAvailableAttrs(
132132
}
133133
}
134134

135+
/// Returns true if the introduced version in \p newAttr should be used instead
136+
/// of the introduced version in \p prevAttr when both are attached to the same
137+
/// declaration and refer to the active platform.
138+
static bool isBetterThan(const AvailableAttr *newAttr,
139+
const AvailableAttr *prevAttr) {
140+
assert(newAttr);
141+
142+
// If there is no prevAttr, newAttr of course wins.
143+
if (!prevAttr)
144+
return true;
145+
146+
// If they belong to the same platform, the one that introduces later wins.
147+
if (prevAttr->Platform == newAttr->Platform)
148+
return prevAttr->Introduced.getValue() < newAttr->Introduced.getValue();
149+
150+
// If the new attribute's platform inherits from the old one, it wins.
151+
return inheritsAvailabilityFromPlatform(newAttr->Platform,
152+
prevAttr->Platform);
153+
}
154+
135155
Optional<AvailabilityContext>
136156
AvailabilityInference::annotatedAvailableRange(const Decl *D, ASTContext &Ctx) {
137157
const AvailableAttr *bestAvailAttr = nullptr;
@@ -145,12 +165,8 @@ AvailabilityInference::annotatedAvailableRange(const Decl *D, ASTContext &Ctx) {
145165
continue;
146166
}
147167

148-
// Okay, we have a candidate, but is it better than one we already found?
149-
if (!bestAvailAttr ||
150-
inheritsAvailabilityFromPlatform(AvailAttr->Platform,
151-
bestAvailAttr->Platform)) {
168+
if (isBetterThan(AvailAttr, bestAvailAttr))
152169
bestAvailAttr = AvailAttr;
153-
}
154170
}
155171

156172
if (!bestAvailAttr)

0 commit comments

Comments
 (0)