Skip to content

Commit 7d74229

Browse files
committed
Basic: Adjust feature macros for adoption mode
1 parent 88fd413 commit 7d74229

File tree

9 files changed

+95
-40
lines changed

9 files changed

+95
-40
lines changed

include/swift/Basic/BasicBridging.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2022 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2022 - 2025 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -214,7 +214,8 @@ void BridgedData_free(BridgedData data);
214214
//===----------------------------------------------------------------------===//
215215

216216
enum ENUM_EXTENSIBILITY_ATTR(open) BridgedFeature {
217-
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) FeatureName,
217+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
218+
FeatureName,
218219
#include "swift/Basic/Features.def"
219220
};
220221

include/swift/Basic/Feature.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -22,13 +22,15 @@ class LangOptions;
2222

2323
/// Enumeration describing all of the named features.
2424
enum class Feature {
25-
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) FeatureName,
25+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
26+
FeatureName,
2627
#include "swift/Basic/Features.def"
2728
};
2829

2930
constexpr unsigned numFeatures() {
3031
enum Features {
31-
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) FeatureName,
32+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
33+
FeatureName,
3234
#include "swift/Basic/Features.def"
3335
NumFeatures
3436
};
@@ -61,6 +63,9 @@ std::optional<Feature> getExperimentalFeature(llvm::StringRef name);
6163
/// \c None if it does not have such a version.
6264
std::optional<unsigned> getFeatureLanguageVersion(Feature feature);
6365

66+
/// Determine whether the given feature supports adoption mode.
67+
bool isFeatureAdoptable(Feature feature);
68+
6469
/// Determine whether this feature should be included in the
6570
/// module interface
6671
bool includeInModuleInterface(Feature feature);

include/swift/Basic/Features.def

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,28 @@
1414
// features.
1515
//
1616
//
17-
// LANGUAGE_FEATURE(FeatureName, SENumber, Description)
17+
// LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description)
1818
//
1919
// The LANGUAGE_FEATURE macro describes each named feature that is
2020
// introduced in Swift. It allows Swift code to check for a particular
2121
// feature with "#if $FeatureName" in source code.
2222
//
2323
// FeatureName: The name given to this feature to be used in source code,
2424
// e.g., AsyncAwait.
25+
// IsAdoptable: Whether the feature implements adoption mode.
26+
//
27+
// If the feature is upcoming (source-breaking) and provides for a
28+
// mechanical code migration, it should implement adoption mode.
29+
//
30+
// Adoption mode is a feature-oriented code migration mechanism: a mode
31+
// of operation that should produce compiler warnings with attached
32+
// fix-its that can be applied to preserve the behavior of the code once
33+
// the upcoming feature is enacted.
34+
// These warnings must belong to a diagnostic group named after the
35+
// feature. Adoption mode itself *and* the fix-its it produces must be
36+
// source and binary compatible with how the code is compiled when the
37+
// feature is disabled.
38+
//
2539
// SENumber: The number assigned to this feature in the Swift Evolution
2640
// process, or 0 if there isn't one.
2741
// Description: A string literal describing the feature.
@@ -91,13 +105,14 @@
91105
#endif
92106

93107
#ifndef SUPPRESSIBLE_LANGUAGE_FEATURE
94-
# define SUPPRESSIBLE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
95-
LANGUAGE_FEATURE(FeatureName, SENumber, Description)
108+
#define SUPPRESSIBLE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
109+
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, SENumber, \
110+
Description)
96111
#endif
97112

98113
#ifndef OPTIONAL_LANGUAGE_FEATURE
99-
# define OPTIONAL_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
100-
LANGUAGE_FEATURE(FeatureName, SENumber, Description)
114+
#define OPTIONAL_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
115+
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, SENumber, Description)
101116
#endif
102117

103118
// A feature that's both conditionally-suppressible and experimental.
@@ -116,20 +131,35 @@
116131
#endif
117132

118133
#ifndef CONDITIONALLY_SUPPRESSIBLE_LANGUAGE_FEATURE
119-
# define CONDITIONALLY_SUPPRESSIBLE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
120-
LANGUAGE_FEATURE(FeatureName, SENumber, Description)
134+
#define CONDITIONALLY_SUPPRESSIBLE_LANGUAGE_FEATURE(FeatureName, SENumber, \
135+
Description) \
136+
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, SENumber, \
137+
Description)
138+
#endif
139+
140+
// An upcoming feature that supports adoption mode.
141+
#ifndef ADOPTABLE_UPCOMING_FEATURE
142+
#if defined(UPCOMING_FEATURE)
143+
#define ADOPTABLE_UPCOMING_FEATURE(FeatureName, SENumber, Version) \
144+
UPCOMING_FEATURE(FeatureName, SENumber, Version)
145+
#else
146+
#define ADOPTABLE_UPCOMING_FEATURE(FeatureName, SENumber, Version) \
147+
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/true, SENumber, \
148+
#FeatureName)
149+
#endif
121150
#endif
122151

123152
#ifndef UPCOMING_FEATURE
124-
# define UPCOMING_FEATURE(FeatureName, SENumber, Version) \
125-
LANGUAGE_FEATURE(FeatureName, SENumber, #FeatureName)
153+
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) \
154+
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, SENumber, \
155+
#FeatureName)
126156
#endif
127157

128158
#ifndef EXPERIMENTAL_FEATURE
129-
// Warning: setting `AvailableInProd` to `true` on a feature means that the flag
130-
// cannot be dropped in the future.
131-
# define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
132-
LANGUAGE_FEATURE(FeatureName, 0, #FeatureName)
159+
// Warning: setting `AvailableInProd` to `true` on a feature means that the
160+
// flag cannot be dropped in the future.
161+
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
162+
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, 0, #FeatureName)
133163
#endif
134164

135165
#ifndef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
@@ -138,8 +168,9 @@
138168
#endif
139169

140170
#ifndef BASELINE_LANGUAGE_FEATURE
141-
# define BASELINE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
142-
LANGUAGE_FEATURE(FeatureName, SENumber, Description)
171+
#define BASELINE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
172+
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, SENumber, \
173+
Description)
143174
#endif
144175

145176
BASELINE_LANGUAGE_FEATURE(AsyncAwait, 296, "async/await")
@@ -210,10 +241,14 @@ BASELINE_LANGUAGE_FEATURE(BodyMacros, 415, "Function body macros")
210241
SUPPRESSIBLE_LANGUAGE_FEATURE(SendingArgsAndResults, 430, "Sending arg and results")
211242
BASELINE_LANGUAGE_FEATURE(BorrowingSwitch, 432, "Noncopyable type pattern matching")
212243
CONDITIONALLY_SUPPRESSIBLE_LANGUAGE_FEATURE(IsolatedAny, 431, "@isolated(any) function types")
213-
LANGUAGE_FEATURE(IsolatedAny2, 431, "@isolated(any) function types")
214-
LANGUAGE_FEATURE(ObjCImplementation, 436, "@objc @implementation extensions")
215-
LANGUAGE_FEATURE(NonescapableTypes, 446, "Nonescapable types")
216-
LANGUAGE_FEATURE(BuiltinEmplaceTypedThrows, 0, "Builtin.emplace typed throws")
244+
LANGUAGE_FEATURE(IsolatedAny2, /*IsAdoptable=*/false, 431,
245+
"@isolated(any) function types")
246+
LANGUAGE_FEATURE(ObjCImplementation, /*IsAdoptable=*/false, 436,
247+
"@objc @implementation extensions")
248+
LANGUAGE_FEATURE(NonescapableTypes, /*IsAdoptable=*/false, 446,
249+
"Nonescapable types")
250+
LANGUAGE_FEATURE(BuiltinEmplaceTypedThrows, /*IsAdoptable=*/false, 0,
251+
"Builtin.emplace typed throws")
217252
SUPPRESSIBLE_LANGUAGE_FEATURE(MemorySafetyAttributes, 458, "@unsafe attribute")
218253

219254
// Swift 6
@@ -476,6 +511,7 @@ EXPERIMENTAL_FEATURE(IsolatedConformances, true)
476511
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
477512
#undef EXPERIMENTAL_FEATURE
478513
#undef UPCOMING_FEATURE
514+
#undef ADOPTABLE_UPCOMING_FEATURE
479515
#undef BASELINE_LANGUAGE_FEATURE
480516
#undef OPTIONAL_LANGUAGE_FEATURE
481517
#undef CONDITIONALLY_SUPPRESSIBLE_EXPERIMENTAL_FEATURE

lib/AST/ASTPrinter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// This source file is part of the Swift.org open source project
33
//
4-
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
4+
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
55
// Licensed under Apache License v2.0 with Runtime Library Exception
66
//
77
// See https://swift.org/LICENSE.txt for license information
@@ -3268,7 +3268,7 @@ suppressingFeatureExecutionAttribute(PrintOptions &options,
32683268
static void suppressingFeature(PrintOptions &options, Feature feature,
32693269
llvm::function_ref<void()> action) {
32703270
switch (feature) {
3271-
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
3271+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
32723272
case Feature::FeatureName: \
32733273
llvm_unreachable("not a suppressible feature");
32743274
#define SUPPRESSIBLE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \

lib/AST/FeatureSet.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2024 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2024 - 2025 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -45,7 +45,7 @@ static bool usesTypeMatching(Decl *decl, llvm::function_ref<bool(Type)> fn) {
4545

4646
#define BASELINE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
4747
static bool usesFeature##FeatureName(Decl *decl) { return false; }
48-
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description)
48+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description)
4949
#include "swift/Basic/Features.def"
5050

5151
#define UNINTERESTING_FEATURE(FeatureName) \
@@ -542,7 +542,7 @@ void FeatureSet::collectFeaturesUsed(Decl *decl, InsertOrRemove operation) {
542542

543543
// Go through each of the features, checking whether the
544544
// declaration uses that feature.
545-
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
545+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
546546
if (CHECK(usesFeature##FeatureName)) \
547547
collectRequiredFeature(Feature::FeatureName, operation);
548548
#define SUPPRESSIBLE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \

lib/Basic/Feature.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ using namespace swift;
1818

1919
bool swift::isFeatureAvailableInProduction(Feature feature) {
2020
switch (feature) {
21-
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
21+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
2222
case Feature::FeatureName: \
2323
return true;
2424
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
@@ -31,7 +31,7 @@ bool swift::isFeatureAvailableInProduction(Feature feature) {
3131

3232
llvm::StringRef swift::getFeatureName(Feature feature) {
3333
switch (feature) {
34-
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
34+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
3535
case Feature::FeatureName: \
3636
return #FeatureName;
3737
#include "swift/Basic/Features.def"
@@ -41,7 +41,7 @@ llvm::StringRef swift::getFeatureName(Feature feature) {
4141

4242
std::optional<Feature> swift::getUpcomingFeature(llvm::StringRef name) {
4343
return llvm::StringSwitch<std::optional<Feature>>(name)
44-
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description)
44+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description)
4545
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) \
4646
.Case(#FeatureName, Feature::FeatureName)
4747
#include "swift/Basic/Features.def"
@@ -50,7 +50,7 @@ std::optional<Feature> swift::getUpcomingFeature(llvm::StringRef name) {
5050

5151
std::optional<Feature> swift::getExperimentalFeature(llvm::StringRef name) {
5252
return llvm::StringSwitch<std::optional<Feature>>(name)
53-
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description)
53+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description)
5454
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
5555
.Case(#FeatureName, Feature::FeatureName)
5656
#include "swift/Basic/Features.def"
@@ -59,7 +59,7 @@ std::optional<Feature> swift::getExperimentalFeature(llvm::StringRef name) {
5959

6060
std::optional<unsigned> swift::getFeatureLanguageVersion(Feature feature) {
6161
switch (feature) {
62-
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description)
62+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description)
6363
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) \
6464
case Feature::FeatureName: \
6565
return Version;
@@ -69,9 +69,18 @@ std::optional<unsigned> swift::getFeatureLanguageVersion(Feature feature) {
6969
}
7070
}
7171

72+
bool swift::isFeatureAdoptable(Feature feature) {
73+
switch (feature) {
74+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
75+
case Feature::FeatureName: \
76+
return IsAdoptable;
77+
#include "swift/Basic/Features.def"
78+
}
79+
}
80+
7281
bool swift::includeInModuleInterface(Feature feature) {
7382
switch (feature) {
74-
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
83+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
7584
case Feature::FeatureName: \
7685
return true;
7786
#define EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE(FeatureName, \

lib/Basic/LangOptions.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ using namespace swift;
3434

3535
LangOptions::LangOptions() {
3636
// Add all promoted language features
37-
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
37+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
3838
Features.insert(Feature::FeatureName);
3939
#define UPCOMING_FEATURE(FeatureName, SENumber, Version)
4040
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd)
@@ -303,7 +303,7 @@ bool LangOptions::hasFeature(Feature feature) const {
303303

304304
bool LangOptions::hasFeature(llvm::StringRef featureName) const {
305305
auto feature = llvm::StringSwitch<std::optional<Feature>>(featureName)
306-
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
306+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
307307
.Case(#FeatureName, Feature::FeatureName)
308308
#include "swift/Basic/Features.def"
309309
.Default(std::nullopt);

test/lit.swift-features.cfg.inc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/*
44
* This source file is part of the Swift.org open source project
55
*
6-
* Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
6+
* Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
77
* Licensed under Apache License v2.0 with Runtime Library Exception
88
*
99
* See https://swift.org/LICENSE.txt for license information
@@ -30,7 +30,7 @@ def language_feature(feature_name, enabled):
3030

3131
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) language_feature(#FeatureName, True)
3232
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) language_feature(#FeatureName, #AvailableInProd == "true")
33-
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) language_feature(#FeatureName, True)
34-
#define OPTIONAL_LANGUAGE_FEATURE(FeatureName, SENumber, Description) language_feature(#FeatureName, True)
33+
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
34+
language_feature(#FeatureName, True)
3535

3636
#include <swift/Basic/Features.def>

unittests/Frontend/IsFeatureEnabledTests.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,27 @@ TEST_F(IsFeatureEnabledTest, VerifyTestedFeatures) {
3434
{
3535
ASSERT_FALSE(getUpcomingFeature(feature.name));
3636
ASSERT_FALSE(getExperimentalFeature(feature.name));
37+
ASSERT_FALSE(isFeatureAdoptable(feature));
3738
}
3839

3940
feature = upcomingF;
4041
{
4142
ASSERT_TRUE(getUpcomingFeature(feature.name));
43+
ASSERT_FALSE(isFeatureAdoptable(feature));
4244
ASSERT_LT(defaultLangMode, feature.langMode);
4345
}
4446

4547
feature = strictConcurrencyF;
4648
{
4749
ASSERT_TRUE(getUpcomingFeature(feature.name));
50+
ASSERT_FALSE(isFeatureAdoptable(feature));
4851
ASSERT_LT(defaultLangMode, feature.langMode);
4952
}
5053

5154
feature = experimentalF;
5255
{
5356
ASSERT_TRUE(getExperimentalFeature(feature.name));
57+
ASSERT_FALSE(isFeatureAdoptable(feature));
5458
}
5559
}
5660

0 commit comments

Comments
 (0)