Skip to content

Commit 5a92bc5

Browse files
Merge pull request #79897 from AnthonyLatsis/danaus-plexippus-3
Small adjustments to adoption mode modeling
2 parents 0afb206 + ae70d38 commit 5a92bc5

12 files changed

+87
-78
lines changed

include/swift/Basic/BasicBridging.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,7 @@ void BridgedData_free(BridgedData data);
214214
//===----------------------------------------------------------------------===//
215215

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

include/swift/Basic/Feature.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,13 @@ class LangOptions;
2222

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

3029
constexpr unsigned numFeatures() {
3130
enum Features {
32-
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
33-
FeatureName,
31+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) FeatureName,
3432
#include "swift/Basic/Features.def"
3533
NumFeatures
3634
};

include/swift/Basic/Features.def

+37-37
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,14 @@
1414
// features.
1515
//
1616
//
17-
// LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description)
17+
// LANGUAGE_FEATURE(FeatureName, 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-
//
3925
// SENumber: The number assigned to this feature in the Swift Evolution
4026
// process, or 0 if there isn't one.
4127
// Description: A string literal describing the feature.
@@ -106,13 +92,12 @@
10692

10793
#ifndef SUPPRESSIBLE_LANGUAGE_FEATURE
10894
#define SUPPRESSIBLE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
109-
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, SENumber, \
110-
Description)
95+
LANGUAGE_FEATURE(FeatureName, SENumber, Description)
11196
#endif
11297

11398
#ifndef OPTIONAL_LANGUAGE_FEATURE
11499
#define OPTIONAL_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
115-
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, SENumber, Description)
100+
LANGUAGE_FEATURE(FeatureName, SENumber, Description)
116101
#endif
117102

118103
// A feature that's both conditionally-suppressible and experimental.
@@ -133,33 +118,53 @@
133118
#ifndef CONDITIONALLY_SUPPRESSIBLE_LANGUAGE_FEATURE
134119
#define CONDITIONALLY_SUPPRESSIBLE_LANGUAGE_FEATURE(FeatureName, SENumber, \
135120
Description) \
136-
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, SENumber, \
137-
Description)
121+
LANGUAGE_FEATURE(FeatureName, SENumber, Description)
138122
#endif
139123

140124
// An upcoming feature that supports adoption mode.
125+
//
126+
// If the feature is source-breaking and provides for a
127+
// mechanical code migration, it should implement adoption mode.
128+
//
129+
// Adoption mode is a feature-oriented code migration mechanism: a mode
130+
// of operation that should produce compiler warnings with attached
131+
// fix-its that can be applied to preserve the behavior of the code once
132+
// the upcoming feature is enacted.
133+
// These warnings must belong to a diagnostic group named after the
134+
// feature. Adoption mode itself *and* the fix-its it produces must be
135+
// source and binary compatible with how the code is compiled when the
136+
// feature is disabled.
141137
#ifndef ADOPTABLE_UPCOMING_FEATURE
142138
#if defined(UPCOMING_FEATURE)
143139
#define ADOPTABLE_UPCOMING_FEATURE(FeatureName, SENumber, Version) \
144140
UPCOMING_FEATURE(FeatureName, SENumber, Version)
145141
#else
146142
#define ADOPTABLE_UPCOMING_FEATURE(FeatureName, SENumber, Version) \
147-
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/true, SENumber, \
148-
#FeatureName)
143+
LANGUAGE_FEATURE(FeatureName, SENumber, #FeatureName)
144+
#endif
145+
#endif
146+
147+
// See `ADOPTABLE_UPCOMING_FEATURE`.
148+
#ifndef ADOPTABLE_EXPERIMENTAL_FEATURE
149+
#if defined(EXPERIMENTAL_FEATURE)
150+
#define ADOPTABLE_EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
151+
EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd)
152+
#else
153+
#define ADOPTABLE_EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
154+
LANGUAGE_FEATURE(FeatureName, 0, #FeatureName)
149155
#endif
150156
#endif
151157

152158
#ifndef UPCOMING_FEATURE
153159
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) \
154-
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, SENumber, \
155-
#FeatureName)
160+
LANGUAGE_FEATURE(FeatureName, SENumber, #FeatureName)
156161
#endif
157162

158163
#ifndef EXPERIMENTAL_FEATURE
159164
// Warning: setting `AvailableInProd` to `true` on a feature means that the
160165
// flag cannot be dropped in the future.
161166
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
162-
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, 0, #FeatureName)
167+
LANGUAGE_FEATURE(FeatureName, 0, #FeatureName)
163168
#endif
164169

165170
#ifndef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
@@ -169,8 +174,7 @@
169174

170175
#ifndef BASELINE_LANGUAGE_FEATURE
171176
#define BASELINE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
172-
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, SENumber, \
173-
Description)
177+
LANGUAGE_FEATURE(FeatureName, SENumber, Description)
174178
#endif
175179

176180
BASELINE_LANGUAGE_FEATURE(AsyncAwait, 296, "async/await")
@@ -242,17 +246,12 @@ BASELINE_LANGUAGE_FEATURE(BodyMacros, 415, "Function body macros")
242246
SUPPRESSIBLE_LANGUAGE_FEATURE(SendingArgsAndResults, 430, "Sending arg and results")
243247
BASELINE_LANGUAGE_FEATURE(BorrowingSwitch, 432, "Noncopyable type pattern matching")
244248
CONDITIONALLY_SUPPRESSIBLE_LANGUAGE_FEATURE(IsolatedAny, 431, "@isolated(any) function types")
245-
LANGUAGE_FEATURE(IsolatedAny2, /*IsAdoptable=*/false, 431,
246-
"@isolated(any) function types")
247-
LANGUAGE_FEATURE(ObjCImplementation, /*IsAdoptable=*/false, 436,
248-
"@objc @implementation extensions")
249-
LANGUAGE_FEATURE(NonescapableTypes, /*IsAdoptable=*/false, 446,
250-
"Nonescapable types")
251-
LANGUAGE_FEATURE(BuiltinEmplaceTypedThrows, /*IsAdoptable=*/false, 0,
252-
"Builtin.emplace typed throws")
249+
LANGUAGE_FEATURE(IsolatedAny2, 431, "@isolated(any) function types")
250+
LANGUAGE_FEATURE(ObjCImplementation, 436, "@objc @implementation extensions")
251+
LANGUAGE_FEATURE(NonescapableTypes, 446, "Nonescapable types")
252+
LANGUAGE_FEATURE(BuiltinEmplaceTypedThrows, 0, "Builtin.emplace typed throws")
253253
SUPPRESSIBLE_LANGUAGE_FEATURE(MemorySafetyAttributes, 458, "@unsafe attribute")
254-
LANGUAGE_FEATURE(ValueGenerics, /*IsAdoptable=*/ false, 452,
255-
"Value generics feature (integer generics)")
254+
LANGUAGE_FEATURE(ValueGenerics, 452, "Value generics feature (integer generics)")
256255

257256
// Swift 6
258257
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)
@@ -521,6 +520,7 @@ EXPERIMENTAL_FEATURE(CompileTimeValues, true)
521520
#undef EXPERIMENTAL_FEATURE
522521
#undef UPCOMING_FEATURE
523522
#undef ADOPTABLE_UPCOMING_FEATURE
523+
#undef ADOPTABLE_EXPERIMENTAL_FEATURE
524524
#undef BASELINE_LANGUAGE_FEATURE
525525
#undef OPTIONAL_LANGUAGE_FEATURE
526526
#undef CONDITIONALLY_SUPPRESSIBLE_EXPERIMENTAL_FEATURE

include/swift/Basic/LangOptions.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ namespace swift {
814814

815815
/// A wrapper around the feature state enumeration.
816816
struct FeatureState {
817-
enum Kind : uint8_t { Off, EnabledForAdoption, Enabled };
817+
enum class Kind : uint8_t { Off, EnabledForAdoption, Enabled };
818818

819819
private:
820820
Feature feature;

lib/AST/ASTPrinter.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -3267,7 +3267,7 @@ suppressingFeatureExecutionAttribute(PrintOptions &options,
32673267
static void suppressingFeature(PrintOptions &options, Feature feature,
32683268
llvm::function_ref<void()> action) {
32693269
switch (feature) {
3270-
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
3270+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
32713271
case Feature::FeatureName: \
32723272
llvm_unreachable("not a suppressible feature");
32733273
#define SUPPRESSIBLE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \

lib/AST/FeatureSet.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static bool usesTypeMatching(const Decl *decl,
4646

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

5252
#define UNINTERESTING_FEATURE(FeatureName) \
@@ -559,7 +559,7 @@ void FeatureSet::collectFeaturesUsed(Decl *decl, InsertOrRemove operation) {
559559

560560
// Go through each of the features, checking whether the
561561
// declaration uses that feature.
562-
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
562+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
563563
if (CHECK(usesFeature##FeatureName)) \
564564
collectRequiredFeature(Feature::FeatureName, operation);
565565
#define SUPPRESSIBLE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \

lib/Basic/Feature.cpp

+18-9
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, IsAdoptable, SENumber, Description) \
21+
#define LANGUAGE_FEATURE(FeatureName, 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, IsAdoptable, SENumber, Description) \
34+
#define LANGUAGE_FEATURE(FeatureName, 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, IsAdoptable, SENumber, Description)
44+
#define LANGUAGE_FEATURE(FeatureName, 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, IsAdoptable, SENumber, Description)
53+
#define LANGUAGE_FEATURE(FeatureName, 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, IsAdoptable, SENumber, Description)
62+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description)
6363
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) \
6464
case Feature::FeatureName: \
6565
return Version;
@@ -71,16 +71,25 @@ std::optional<unsigned> swift::getFeatureLanguageVersion(Feature feature) {
7171

7272
bool swift::isFeatureAdoptable(Feature feature) {
7373
switch (feature) {
74-
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
75-
case Feature::FeatureName: \
76-
return IsAdoptable;
74+
#define ADOPTABLE_UPCOMING_FEATURE(FeatureName, SENumber, Version)
75+
#define ADOPTABLE_EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd)
76+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
77+
case Feature::FeatureName:
78+
#include "swift/Basic/Features.def"
79+
return false;
80+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description)
81+
#define ADOPTABLE_UPCOMING_FEATURE(FeatureName, SENumber, Version) \
82+
case Feature::FeatureName:
83+
#define ADOPTABLE_EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
84+
case Feature::FeatureName:
7785
#include "swift/Basic/Features.def"
86+
return true;
7887
}
7988
}
8089

8190
bool swift::includeInModuleInterface(Feature feature) {
8291
switch (feature) {
83-
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
92+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
8493
case Feature::FeatureName: \
8594
return true;
8695
#define EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE(FeatureName, \

lib/Basic/LangOptions.cpp

+10-9
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ using namespace swift;
3535

3636
LangOptions::LangOptions() {
3737
// Add all promoted language features
38-
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
38+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
3939
this->enableFeature(Feature::FeatureName);
4040
#define UPCOMING_FEATURE(FeatureName, SENumber, Version)
4141
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd)
@@ -295,18 +295,18 @@ bool LangOptions::isCustomConditionalCompilationFlagSet(StringRef Name) const {
295295
}
296296

297297
bool LangOptions::FeatureState::isEnabled() const {
298-
return this->state != FeatureState::Off;
298+
return this->state == FeatureState::Kind::Enabled;
299299
}
300300

301301
bool LangOptions::FeatureState::isEnabledForAdoption() const {
302302
ASSERT(isFeatureAdoptable(this->feature) &&
303303
"You forgot to make the feature adoptable!");
304304

305-
return this->state == FeatureState::EnabledForAdoption;
305+
return this->state == FeatureState::Kind::EnabledForAdoption;
306306
}
307307

308308
LangOptions::FeatureStateStorage::FeatureStateStorage()
309-
: states(numFeatures(), FeatureState::Off) {}
309+
: states(numFeatures(), FeatureState::Kind::Off) {}
310310

311311
void LangOptions::FeatureStateStorage::setState(Feature feature,
312312
FeatureState::Kind state) {
@@ -329,7 +329,7 @@ LangOptions::FeatureState LangOptions::getFeatureState(Feature feature) const {
329329

330330
if (auto version = getFeatureLanguageVersion(feature)) {
331331
if (this->isSwiftVersionAtLeast(*version)) {
332-
return FeatureState(feature, FeatureState::Enabled);
332+
return FeatureState(feature, FeatureState::Kind::Enabled);
333333
}
334334
}
335335

@@ -348,7 +348,7 @@ bool LangOptions::hasFeature(Feature feature) const {
348348

349349
bool LangOptions::hasFeature(llvm::StringRef featureName) const {
350350
auto feature = llvm::StringSwitch<std::optional<Feature>>(featureName)
351-
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
351+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
352352
.Case(#FeatureName, Feature::FeatureName)
353353
#include "swift/Basic/Features.def"
354354
.Default(std::nullopt);
@@ -361,14 +361,15 @@ bool LangOptions::hasFeature(llvm::StringRef featureName) const {
361361
void LangOptions::enableFeature(Feature feature, bool forAdoption) {
362362
if (forAdoption) {
363363
ASSERT(isFeatureAdoptable(feature));
364-
this->featureStates.setState(feature, FeatureState::EnabledForAdoption);
364+
this->featureStates.setState(feature,
365+
FeatureState::Kind::EnabledForAdoption);
365366
} else {
366-
this->featureStates.setState(feature, FeatureState::Enabled);
367+
this->featureStates.setState(feature, FeatureState::Kind::Enabled);
367368
}
368369
}
369370

370371
void LangOptions::disableFeature(Feature feature) {
371-
this->featureStates.setState(feature, FeatureState::Off);
372+
this->featureStates.setState(feature, FeatureState::Kind::Off);
372373
}
373374

374375
void LangOptions::setHasAtomicBitWidth(llvm::Triple triple) {

lib/Sema/TypeCheckType.cpp

+9-7
Original file line numberDiff line numberDiff line change
@@ -6411,8 +6411,10 @@ class ExistentialTypeSyntaxChecker : public ASTWalker {
64116411
return false;
64126412
}
64136413

6414-
// A missing `any` or `some` is always diagnosed if this feature is enabled.
6415-
if (ctx.LangOpts.hasFeature(Feature::ExistentialAny)) {
6414+
// A missing `any` or `some` is always diagnosed if this feature not
6415+
// disabled.
6416+
auto featureState = ctx.LangOpts.getFeatureState(Feature::ExistentialAny);
6417+
if (featureState.isEnabled() || featureState.isEnabledForAdoption()) {
64166418
return true;
64176419
}
64186420

@@ -6505,13 +6507,13 @@ class ExistentialTypeSyntaxChecker : public ASTWalker {
65056507
/*isAlias=*/isa<TypeAliasDecl>(decl)));
65066508
}
65076509

6508-
// If the feature is enabled in adoption mode, warn unconditionally.
6509-
// Otherwise, until Swift 7.
6510-
if (Ctx.LangOpts.getFeatureState(Feature::ExistentialAny)
6511-
.isEnabledForAdoption()) {
6510+
// If `ExistentialAny` is enabled in adoption mode, warn unconditionally.
6511+
// Otherwise, warn until the feature's coming-of-age language mode.
6512+
const auto feature = Feature::ExistentialAny;
6513+
if (Ctx.LangOpts.getFeatureState(feature).isEnabledForAdoption()) {
65126514
diag->limitBehavior(DiagnosticBehavior::Warning);
65136515
} else {
6514-
diag->warnUntilSwiftVersion(7);
6516+
diag->warnUntilSwiftVersion(getFeatureLanguageVersion(feature).value());
65156517
}
65166518

65176519
emitInsertAnyFixit(*diag, T);

test/lit.swift-features.cfg.inc

+1-1
Original file line numberDiff line numberDiff line change
@@ -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, IsAdoptable, SENumber, Description) \
33+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
3434
language_feature(#FeatureName, True)
3535

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

0 commit comments

Comments
 (0)