Skip to content

Commit e1526a9

Browse files
authored
Merge pull request #34565 from slavapestov/conformance-availability-part1
Sema: (Mostly) check conformance availability
2 parents 5a87482 + ceb8675 commit e1526a9

11 files changed

+563
-57
lines changed

include/swift/AST/Availability.h

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -182,46 +182,19 @@ class VersionRange {
182182

183183
/// Records the reason a declaration is potentially unavailable.
184184
class UnavailabilityReason {
185-
public:
186-
enum class Kind {
187-
/// The declaration is potentially unavailable because it requires an OS
188-
/// version range that is not guaranteed by the minimum deployment
189-
/// target.
190-
RequiresOSVersionRange,
191-
192-
/// The declaration is potentially unavailable because it is explicitly
193-
/// weakly linked.
194-
ExplicitlyWeakLinked
195-
};
196-
197185
private:
198-
// A value of None indicates the declaration is potentially unavailable
199-
// because it is explicitly weak linked.
200-
Optional<VersionRange> RequiredDeploymentRange;
186+
VersionRange RequiredDeploymentRange;
201187

202-
UnavailabilityReason(const Optional<VersionRange> &RequiredDeploymentRange)
188+
explicit UnavailabilityReason(const VersionRange RequiredDeploymentRange)
203189
: RequiredDeploymentRange(RequiredDeploymentRange) {}
204190

205191
public:
206-
static UnavailabilityReason explicitlyWeaklyLinked() {
207-
return UnavailabilityReason(None);
208-
}
209-
210192
static UnavailabilityReason requiresVersionRange(const VersionRange Range) {
211193
return UnavailabilityReason(Range);
212194
}
213195

214-
Kind getReasonKind() const {
215-
if (RequiredDeploymentRange.hasValue()) {
216-
return Kind::RequiresOSVersionRange;
217-
} else {
218-
return Kind::ExplicitlyWeakLinked;
219-
}
220-
}
221-
222196
const VersionRange &getRequiredOSVersionRange() const {
223-
assert(getReasonKind() == Kind::RequiresOSVersionRange);
224-
return RequiredDeploymentRange.getValue();
197+
return RequiredDeploymentRange;
225198
}
226199
};
227200

include/swift/AST/DiagnosticsSema.def

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5040,6 +5040,39 @@ ERROR(availabilty_string_subscript_migration, none,
50405040
"subscripts returning String were obsoleted in Swift 4; explicitly "
50415041
"construct a String from subscripted result", ())
50425042

5043+
// Conformance availability checking diagnostics
5044+
5045+
ERROR(conformance_availability_unavailable, none,
5046+
"conformance of %0 to %1 is unavailable"
5047+
"%select{ in %3|}2%select{|: %4}4",
5048+
(Type, Type, bool, StringRef, StringRef))
5049+
5050+
NOTE(conformance_availability_marked_unavailable, none,
5051+
"conformance of %0 to %1 has been explicitly marked "
5052+
"unavailable here", (Type, Type))
5053+
5054+
NOTE(conformance_availability_introduced_in_version, none,
5055+
"conformance of %0 to %1 was introduced in %2 %3",
5056+
(Type, Type, StringRef, llvm::VersionTuple))
5057+
5058+
NOTE(conformance_availability_obsoleted, none,
5059+
"conformance of %0 to %1 was obsoleted in %2 %3",
5060+
(Type, Type, StringRef, llvm::VersionTuple))
5061+
5062+
WARNING(conformance_availability_deprecated, none,
5063+
"conformance of %0 to %1 %select{is|%select{is|was}4}2 "
5064+
"deprecated%select{| in %3%select{| %5}4}2%select{|: %6}6",
5065+
(Type, Type, bool, StringRef, bool, llvm::VersionTuple,
5066+
StringRef))
5067+
5068+
ERROR(conformance_availability_only_version_newer, none,
5069+
"conformance of %0 to %1 is only available in %2 %3 or newer",
5070+
(Type, Type, StringRef, llvm::VersionTuple))
5071+
5072+
WARNING(conformance_availability_only_version_newer_warn, none,
5073+
"conformance of %0 to %1 is only available in %2 %3 or newer",
5074+
(Type, Type, StringRef, llvm::VersionTuple))
5075+
50435076
//------------------------------------------------------------------------------
50445077
// MARK: @discardableResult
50455078
//------------------------------------------------------------------------------

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ namespace swift {
9595
/// Disable API availability checking.
9696
bool DisableAvailabilityChecking = false;
9797

98+
/// Should conformance availability violations be diagnosed as errors?
99+
bool EnableConformanceAvailabilityErrors = false;
100+
98101
/// Maximum number of typo corrections we are allowed to perform.
99102
/// This is disabled by default until we can get typo-correction working within acceptable performance bounds.
100103
unsigned TypoCorrectionLimit = 0;

include/swift/Option/FrontendOptions.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,14 @@ def disable_availability_checking : Flag<["-"],
405405
"disable-availability-checking">,
406406
HelpText<"Disable checking for potentially unavailable APIs">;
407407

408+
def enable_conformance_availability_errors : Flag<["-"],
409+
"enable-conformance-availability-errors">,
410+
HelpText<"Diagnose conformance availability violations as errors">;
411+
412+
def disable_conformance_availability_errors : Flag<["-"],
413+
"disable-conformance-availability-errors">,
414+
HelpText<"Diagnose conformance availability violations as warnings">;
415+
408416
def report_errors_to_debugger : Flag<["-"], "report-errors-to-debugger">,
409417
HelpText<"Deprecated, will be removed in future versions.">;
410418

lib/Frontend/CompilerInvocation.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,12 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
391391
Opts.DisableAvailabilityChecking |=
392392
Args.hasArg(OPT_disable_availability_checking);
393393

394+
if (auto A = Args.getLastArg(OPT_enable_conformance_availability_errors,
395+
OPT_disable_conformance_availability_errors)) {
396+
Opts.EnableConformanceAvailabilityErrors
397+
= A->getOption().matches(OPT_enable_conformance_availability_errors);
398+
}
399+
394400
if (auto A = Args.getLastArg(OPT_enable_access_control,
395401
OPT_disable_access_control)) {
396402
Opts.EnableAccessControl

lib/Sema/ResilienceDiagnostics.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,17 +160,16 @@ TypeChecker::diagnoseDeclRefExportability(SourceLoc loc,
160160
bool
161161
TypeChecker::diagnoseConformanceExportability(SourceLoc loc,
162162
const RootProtocolConformance *rootConf,
163+
const ExtensionDecl *ext,
163164
const ExportContext &where) {
164165
if (!where.mustOnlyReferenceExportedDecls())
165166
return false;
166167

167-
auto originKind = getDisallowedOriginKind(
168-
rootConf->getDeclContext()->getAsDecl(),
169-
where);
168+
auto originKind = getDisallowedOriginKind(ext, where);
170169
if (originKind == DisallowedOriginKind::None)
171170
return false;
172171

173-
ModuleDecl *M = rootConf->getDeclContext()->getParentModule();
172+
ModuleDecl *M = ext->getParentModule();
174173
ASTContext &ctx = M->getASTContext();
175174

176175
auto reason = where.getExportabilityReason();

0 commit comments

Comments
 (0)