Skip to content

Commit 89b58d5

Browse files
authored
Merge pull request #38302 from hborla/warn-until-Swift-6
[Diagnostics] Add `InFlightDiagnostic::warnUntilSwiftVersion` to downgrade errors to warnings
2 parents fd31583 + b9040c7 commit 89b58d5

File tree

8 files changed

+37
-12
lines changed

8 files changed

+37
-12
lines changed

include/swift/AST/DiagnosticEngine.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/AST/DeclNameLoc.h"
2323
#include "swift/AST/DiagnosticConsumer.h"
2424
#include "swift/AST/TypeLoc.h"
25+
#include "swift/Basic/Version.h"
2526
#include "swift/Localization/LocalizationFormat.h"
2627
#include "llvm/ADT/BitVector.h"
2728
#include "llvm/ADT/StringRef.h"
@@ -528,6 +529,12 @@ namespace swift {
528529
/// emitted as a warning, but a note will still be emitted as a note.
529530
InFlightDiagnostic &limitBehavior(DiagnosticBehavior limit);
530531

532+
/// Limit the diagnostic behavior to warning until the specified version.
533+
///
534+
/// This helps stage in fixes for stricter diagnostics as warnings
535+
/// until the next major language version.
536+
InFlightDiagnostic &warnUntilSwiftVersion(unsigned majorVersion);
537+
531538
/// Wraps this diagnostic in another diagnostic. That is, \p wrapper will be
532539
/// emitted in place of the diagnostic that otherwise would have been
533540
/// emitted.
@@ -803,6 +810,10 @@ namespace swift {
803810
/// Path to diagnostic documentation directory.
804811
std::string diagnosticDocumentationPath = "";
805812

813+
/// The Swift language version. This is used to limit diagnostic behavior
814+
/// until a specific language version, e.g. Swift 6.
815+
version::Version languageVersion;
816+
806817
/// Whether we are actively pretty-printing a declaration as part of
807818
/// diagnostics.
808819
bool IsPrettyPrintingDecl = false;
@@ -865,6 +876,8 @@ namespace swift {
865876

866877
bool isPrettyPrintingDecl() const { return IsPrettyPrintingDecl; }
867878

879+
void setLanguageVersion(version::Version v) { languageVersion = v; }
880+
868881
void setLocalization(StringRef locale, StringRef path) {
869882
assert(!locale.empty());
870883
assert(!path.empty());

include/swift/AST/DiagnosticsCommon.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ NOTE(previous_decldef,none,
4444
NOTE(brace_stmt_suggest_do,none,
4545
"did you mean to use a 'do' statement?", ())
4646

47+
WARNING(error_in_future_swift_version,none,
48+
"%0; this is an error in Swift %1",
49+
(DiagnosticInfo *, unsigned))
50+
4751
// Generic disambiguation
4852
NOTE(while_parsing_as_left_angle_bracket,none,
4953
"while parsing this '<' as a type parameter bracket", ())

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4733,10 +4733,6 @@ ERROR(invalid_ownership_is_let,none,
47334733
ERROR(ownership_invalid_in_protocols,none,
47344734
"%0 cannot be applied to a property declaration in a protocol",
47354735
(ReferenceOwnership))
4736-
WARNING(ownership_invalid_in_protocols_compat_warning,none,
4737-
"%0 should not be applied to a property declaration "
4738-
"in a protocol and will be disallowed in future versions",
4739-
(ReferenceOwnership))
47404736

47414737
// required
47424738
ERROR(required_initializer_nonclass,none,

lib/AST/DiagnosticEngine.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
//===----------------------------------------------------------------------===//
1717

1818
#include "swift/AST/DiagnosticEngine.h"
19+
#include "swift/AST/DiagnosticsCommon.h"
1920
#include "swift/AST/ASTContext.h"
2021
#include "swift/AST/ASTPrinter.h"
2122
#include "swift/AST/Decl.h"
@@ -319,6 +320,16 @@ InFlightDiagnostic::limitBehavior(DiagnosticBehavior limit) {
319320
return *this;
320321
}
321322

323+
InFlightDiagnostic &
324+
InFlightDiagnostic::warnUntilSwiftVersion(unsigned majorVersion) {
325+
if (!Engine->languageVersion.isVersionAtLeast(majorVersion)) {
326+
limitBehavior(DiagnosticBehavior::Warning)
327+
.wrapIn(diag::error_in_future_swift_version, majorVersion);
328+
}
329+
330+
return *this;
331+
}
332+
322333
InFlightDiagnostic &
323334
InFlightDiagnostic::wrapIn(const Diagnostic &wrapper) {
324335
// Save current active diagnostic into WrappedDiagnostics, ignoring state

lib/Frontend/Frontend.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,8 @@ void CompilerInstance::setUpDiagnosticOptions() {
452452
}
453453
Diagnostics.setDiagnosticDocumentationPath(
454454
Invocation.getDiagnosticOptions().DiagnosticDocumentationPath);
455+
Diagnostics.setLanguageVersion(
456+
Invocation.getLangOptions().EffectiveLanguageVersion);
455457
if (!Invocation.getDiagnosticOptions().LocalizationCode.empty()) {
456458
Diagnostics.setLocalization(
457459
Invocation.getDiagnosticOptions().LocalizationCode,

lib/Sema/TypeCheckAttr.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3354,10 +3354,9 @@ Type TypeChecker::checkReferenceOwnershipAttr(VarDecl *var, Type type,
33543354
if (PDC && !PDC->isObjC()) {
33553355
// Ownership does not make sense in protocols, except for "weak" on
33563356
// properties of Objective-C protocols.
3357-
auto D = var->getASTContext().isSwiftVersionAtLeast(5)
3358-
? diag::ownership_invalid_in_protocols
3359-
: diag::ownership_invalid_in_protocols_compat_warning;
3357+
auto D = diag::ownership_invalid_in_protocols;
33603358
Diags.diagnose(attr->getLocation(), D, ownershipKind)
3359+
.warnUntilSwiftVersion(5)
33613360
.fixItRemove(attr->getRange());
33623361
attr->setInvalid();
33633362
}

test/Compatibility/ownership_protocol.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
class SomeClass {}
55

66
protocol P {
7-
// expected-warning@+1 {{'weak' should not be applied to a property declaration in a protocol and will be disallowed in future versions}}
7+
// expected-warning@+1 {{'weak' cannot be applied to a property declaration in a protocol; this is an error in Swift 5}}
88
weak var foo: SomeClass? { get set }
9-
// expected-warning@+1 {{'unowned' should not be applied to a property declaration in a protocol and will be disallowed in future versions}}
9+
// expected-warning@+1 {{'unowned' cannot be applied to a property declaration in a protocol; this is an error in Swift 5}}
1010
unowned var foo2: SomeClass { get set }
11-
// expected-warning@+2 {{'weak' should not be applied to a property declaration in a protocol and will be disallowed in future versions}}
11+
// expected-warning@+2 {{'weak' cannot be applied to a property declaration in a protocol; this is an error in Swift 5}}
1212
// expected-error@+1 {{'weak' may only be applied to class and class-bound protocol types, not 'Int'}}
1313
weak var foo3: Int? { get set }
14-
// expected-warning@+2 {{'unowned' should not be applied to a property declaration in a protocol and will be disallowed in future versions}}
14+
// expected-warning@+2 {{'unowned' cannot be applied to a property declaration in a protocol; this is an error in Swift 5}}
1515
// expected-error@+1 {{'unowned' may only be applied to class and class-bound protocol types, not 'Int'}}
1616
unowned var foo4: Int { get set }
1717
}

test/decl/protocol/protocols.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ protocol ShouldntCrash {
467467

468468
// rdar://problem/18168866
469469
protocol FirstProtocol {
470-
// expected-warning@+1 {{'weak' should not be applied to a property declaration in a protocol and will be disallowed in future versions}}
470+
// expected-warning@+1 {{'weak' cannot be applied to a property declaration in a protocol; this is an error in Swift 5}}
471471
weak var delegate : SecondProtocol? { get } // expected-error{{'weak' must not be applied to non-class-bound 'SecondProtocol'; consider adding a protocol conformance that has a class bound}}
472472
}
473473

0 commit comments

Comments
 (0)