Skip to content

Commit bd03d47

Browse files
committed
AST: Fix a regression in constraining an AvailabilityContext for a decl.
When building up AvailabilityContexts, we assume that all of the enclosing decls have already been accounted for in the AvailabilityContext that we are constraining. Therefore, it doesn't make sense to merge availability constraints from the enclosing extension of the target decl.
1 parent 91b3b16 commit bd03d47

File tree

4 files changed

+24
-6
lines changed

4 files changed

+24
-6
lines changed

include/swift/AST/AvailabilityConstraint.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/AST/AvailabilityRange.h"
2323
#include "swift/AST/PlatformKind.h"
2424
#include "swift/Basic/LLVM.h"
25+
#include "swift/Basic/OptionSet.h"
2526

2627
namespace swift {
2728

@@ -165,12 +166,22 @@ class DeclAvailabilityConstraints {
165166
const_iterator end() const { return constraints.end(); }
166167
};
167168

169+
enum class AvailabilityConstraintFlag : uint8_t {
170+
/// By default, the availability constraints for the members of extensions
171+
/// include the constraints for `@available` attributes that were written on
172+
/// the enclosing extension, since these members can be referred to without
173+
/// referencing the extension. When this flag is specified, though, only the
174+
/// attributes directly attached to the declaration are considered.
175+
SkipEnclosingExtension = 1 << 0,
176+
};
177+
using AvailabilityConstraintFlags = OptionSet<AvailabilityConstraintFlag>;
178+
168179
/// Returns the set of availability constraints that restrict use of \p decl
169180
/// when it is referenced from the given context. In other words, it is the
170181
/// collection of of `@available` attributes with unsatisfied conditions.
171-
DeclAvailabilityConstraints
172-
getAvailabilityConstraintsForDecl(const Decl *decl,
173-
const AvailabilityContext &context);
182+
DeclAvailabilityConstraints getAvailabilityConstraintsForDecl(
183+
const Decl *decl, const AvailabilityContext &context,
184+
AvailabilityConstraintFlags flags = std::nullopt);
174185
} // end namespace swift
175186

176187
#endif

lib/AST/AvailabilityConstraint.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ static void getAvailabilityConstraintsForDecl(
224224

225225
DeclAvailabilityConstraints
226226
swift::getAvailabilityConstraintsForDecl(const Decl *decl,
227-
const AvailabilityContext &context) {
227+
const AvailabilityContext &context,
228+
AvailabilityConstraintFlags flags) {
228229
llvm::SmallVector<AvailabilityConstraint, 4> constraints;
229230

230231
// Generic parameters are always available.
@@ -235,6 +236,9 @@ swift::getAvailabilityConstraintsForDecl(const Decl *decl,
235236

236237
getAvailabilityConstraintsForDecl(constraints, decl, context);
237238

239+
if (flags.contains(AvailabilityConstraintFlag::SkipEnclosingExtension))
240+
return constraints;
241+
238242
// If decl is an extension member, query the attributes of the extension, too.
239243
//
240244
// Skip decls imported from Clang, though, as they could be associated to the

lib/AST/AvailabilityContext.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,10 @@ void AvailabilityContext::constrainWithDeclAndPlatformRange(
202202
bool isConstrained = false;
203203

204204
Info info{storage->info};
205-
auto constraints = swift::getAvailabilityConstraintsForDecl(decl, *this);
205+
AvailabilityConstraintFlags flags =
206+
AvailabilityConstraintFlag::SkipEnclosingExtension;
207+
auto constraints =
208+
swift::getAvailabilityConstraintsForDecl(decl, *this, flags);
206209
isConstrained |= info.constrainWith(constraints, decl->getASTContext());
207210
isConstrained |= CONSTRAIN_BOOL(info.IsDeprecated, decl->isDeprecated());
208211
isConstrained |= constrainRange(info.Range, platformRange);

test/Sema/availability_scopes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ extension SomeEnum {
358358
// CHECK-NEXT: {{^}} (decl_implicit version=50 decl=extension.SomeEnum
359359
// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=extension.SomeEnum
360360
// CHECK-NEXT: {{^}} (decl_implicit version=50 unavailable=macOS decl=availableMacOS_52
361-
// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=availableMacOS_52
361+
// CHECK-NEXT: {{^}} (decl version=52 unavailable=macOS decl=availableMacOS_52
362362
// CHECK-NEXT: {{^}} (decl version=50 unavailable=* decl=neverAvailable()
363363

364364
@available(macOS, unavailable)

0 commit comments

Comments
 (0)