Skip to content

Commit 3be5f7c

Browse files
authored
Merge pull request #42540 from beccadax/rdar91940820-5.7
[5.7] Soften new unavailable conformance diagnostics
2 parents ec0a32f + ba3fbb0 commit 3be5f7c

File tree

6 files changed

+73
-15
lines changed

6 files changed

+73
-15
lines changed

lib/AST/DeclContext.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "llvm/ADT/Statistic.h"
3131
#include "llvm/Support/raw_ostream.h"
3232
#include "llvm/Support/SaveAndRestore.h"
33+
#include "clang/AST/ASTContext.h"
3334
using namespace swift;
3435

3536
#define DEBUG_TYPE "Name lookup"
@@ -734,6 +735,14 @@ unsigned DeclContext::printContext(raw_ostream &OS, const unsigned indent,
734735
}
735736
}
736737

738+
if (auto decl = getAsDecl())
739+
if (decl->getClangNode().getLocation().isValid()) {
740+
auto &clangSM = getASTContext().getClangModuleLoader()
741+
->getClangASTContext().getSourceManager();
742+
OS << " clang_loc=";
743+
decl->getClangNode().getLocation().print(OS, clangSM);
744+
}
745+
737746
if (!onlyAPartialLine)
738747
OS << "\n";
739748
return Depth + 1;

lib/Sema/ResilienceDiagnostics.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ bool
158158
TypeChecker::diagnoseConformanceExportability(SourceLoc loc,
159159
const RootProtocolConformance *rootConf,
160160
const ExtensionDecl *ext,
161-
const ExportContext &where) {
161+
const ExportContext &where,
162+
bool useConformanceAvailabilityErrorsOption) {
162163
if (!where.mustOnlyReferenceExportedDecls())
163164
return false;
164165

@@ -178,6 +179,9 @@ TypeChecker::diagnoseConformanceExportability(SourceLoc loc,
178179
rootConf->getProtocol()->getName(),
179180
static_cast<unsigned>(*reason),
180181
M->getName(),
181-
static_cast<unsigned>(originKind));
182+
static_cast<unsigned>(originKind))
183+
.warnUntilSwiftVersionIf(useConformanceAvailabilityErrorsOption &&
184+
!ctx.LangOpts.EnableConformanceAvailabilityErrors,
185+
6);
182186
return true;
183187
}

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2584,7 +2584,8 @@ bool swift::diagnoseExplicitUnavailability(const ValueDecl *D, SourceRange R,
25842584
bool swift::diagnoseExplicitUnavailability(SourceLoc loc,
25852585
const RootProtocolConformance *rootConf,
25862586
const ExtensionDecl *ext,
2587-
const ExportContext &where) {
2587+
const ExportContext &where,
2588+
bool useConformanceAvailabilityErrorsOption) {
25882589
auto *attr = AvailableAttr::isUnavailable(ext);
25892590
if (!attr)
25902591
return false;
@@ -2641,7 +2642,10 @@ bool swift::diagnoseExplicitUnavailability(SourceLoc loc,
26412642
diags.diagnose(loc, diag::conformance_availability_unavailable,
26422643
type, proto,
26432644
platform.empty(), platform, EncodedMessage.Message)
2644-
.limitBehavior(behavior);
2645+
.limitBehavior(behavior)
2646+
.warnUntilSwiftVersionIf(useConformanceAvailabilityErrorsOption &&
2647+
!ctx.LangOpts.EnableConformanceAvailabilityErrors,
2648+
6);
26452649

26462650
switch (attr->getVersionAvailability(ctx)) {
26472651
case AvailableVersionComparison::Available:
@@ -2995,7 +2999,8 @@ class ExprAvailabilityWalker : public ASTWalker {
29952999

29963000
if (auto EE = dyn_cast<ErasureExpr>(E)) {
29973001
for (ProtocolConformanceRef C : EE->getConformances()) {
2998-
diagnoseConformanceAvailability(E->getLoc(), C, Where);
3002+
diagnoseConformanceAvailability(E->getLoc(), C, Where, Type(), Type(),
3003+
/*useConformanceAvailabilityErrorsOpt=*/true);
29993004
}
30003005
}
30013006

@@ -3791,7 +3796,8 @@ bool
37913796
swift::diagnoseConformanceAvailability(SourceLoc loc,
37923797
ProtocolConformanceRef conformance,
37933798
const ExportContext &where,
3794-
Type depTy, Type replacementTy) {
3799+
Type depTy, Type replacementTy,
3800+
bool useConformanceAvailabilityErrorsOption) {
37953801
assert(!where.isImplicit());
37963802

37973803
if (!conformance.isConcrete())
@@ -3825,12 +3831,14 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
38253831
};
38263832

38273833
if (auto *ext = dyn_cast<ExtensionDecl>(rootConf->getDeclContext())) {
3828-
if (TypeChecker::diagnoseConformanceExportability(loc, rootConf, ext, where)) {
3834+
if (TypeChecker::diagnoseConformanceExportability(loc, rootConf, ext, where,
3835+
useConformanceAvailabilityErrorsOption)) {
38293836
maybeEmitAssociatedTypeNote();
38303837
return true;
38313838
}
38323839

3833-
if (diagnoseExplicitUnavailability(loc, rootConf, ext, where)) {
3840+
if (diagnoseExplicitUnavailability(loc, rootConf, ext, where,
3841+
useConformanceAvailabilityErrorsOption)) {
38343842
maybeEmitAssociatedTypeNote();
38353843
return true;
38363844
}
@@ -3858,7 +3866,8 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
38583866
SubstitutionMap subConformanceSubs =
38593867
concreteConf->getSubstitutions(DC->getParentModule());
38603868
if (diagnoseSubstitutionMapAvailability(loc, subConformanceSubs, where,
3861-
depTy, replacementTy))
3869+
depTy, replacementTy,
3870+
useConformanceAvailabilityErrorsOption))
38623871
return true;
38633872

38643873
return false;
@@ -3868,11 +3877,13 @@ bool
38683877
swift::diagnoseSubstitutionMapAvailability(SourceLoc loc,
38693878
SubstitutionMap subs,
38703879
const ExportContext &where,
3871-
Type depTy, Type replacementTy) {
3880+
Type depTy, Type replacementTy,
3881+
bool useConformanceAvailabilityErrorsOption) {
38723882
bool hadAnyIssues = false;
38733883
for (ProtocolConformanceRef conformance : subs.getConformances()) {
38743884
if (diagnoseConformanceAvailability(loc, conformance, where,
3875-
depTy, replacementTy))
3885+
depTy, replacementTy,
3886+
useConformanceAvailabilityErrorsOption))
38763887
hadAnyIssues = true;
38773888
}
38783889
return hadAnyIssues;

lib/Sema/TypeCheckAvailability.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,14 +220,16 @@ diagnoseConformanceAvailability(SourceLoc loc,
220220
ProtocolConformanceRef conformance,
221221
const ExportContext &context,
222222
Type depTy=Type(),
223-
Type replacementTy=Type());
223+
Type replacementTy=Type(),
224+
bool useConformanceAvailabilityErrorsOption = false);
224225

225226
bool
226227
diagnoseSubstitutionMapAvailability(SourceLoc loc,
227228
SubstitutionMap subs,
228229
const ExportContext &context,
229230
Type depTy=Type(),
230-
Type replacementTy=Type());
231+
Type replacementTy=Type(),
232+
bool useConformanceAvailabilityErrorsOption = false);
231233

232234
/// Diagnose uses of unavailable declarations. Returns true if a diagnostic
233235
/// was emitted.
@@ -261,7 +263,8 @@ bool diagnoseExplicitUnavailability(
261263
SourceLoc loc,
262264
const RootProtocolConformance *rootConf,
263265
const ExtensionDecl *ext,
264-
const ExportContext &where);
266+
const ExportContext &where,
267+
bool useConformanceAvailabilityErrorsOption = false);
265268

266269
/// Check if \p decl has a introduction version required by -require-explicit-availability
267270
void checkExplicitAvailability(Decl *decl);

lib/Sema/TypeChecker.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,8 @@ bool diagnoseDeclRefExportability(SourceLoc loc,
10021002
bool diagnoseConformanceExportability(SourceLoc loc,
10031003
const RootProtocolConformance *rootConf,
10041004
const ExtensionDecl *ext,
1005-
const ExportContext &where);
1005+
const ExportContext &where,
1006+
bool useConformanceAvailabilityErrorsOpt = false);
10061007

10071008
/// \name Availability checking
10081009
///

test/Sema/conformance_availability_warn.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,33 @@ func passAvailableConformance1a(x: HasAvailableConformance1) {
5252
_ = x.isGalloping
5353
_ = UsesHorse<HasAvailableConformance1>.self
5454
}
55+
56+
// Explicit unavailability
57+
public struct HasAvailableConformance2 {}
58+
59+
@available(*, unavailable)
60+
extension HasAvailableConformance2 : Horse {} // expected-note 6 {{conformance of 'HasAvailableConformance2' to 'Horse' has been explicitly marked unavailable here}}
61+
62+
// Some availability diagnostics become warnings in Swift 5 mode without
63+
// -enable-conformance-availability-errors because they were incorrectly
64+
// accepted before and rejecting them would break source compatibility. Others
65+
// are unaffected because they have always been rejected.
66+
67+
func passAvailableConformance2(x: HasAvailableConformance2) {
68+
takesHorse(x) // expected-error {{conformance of 'HasAvailableConformance2' to 'Horse' is unavailable}}
69+
takesHorseExistential(x) // expected-warning {{conformance of 'HasAvailableConformance2' to 'Horse' is unavailable; this is an error in Swift 6}}
70+
x.giddyUp() // expected-error {{conformance of 'HasAvailableConformance2' to 'Horse' is unavailable}}
71+
_ = x.isGalloping // expected-error {{conformance of 'HasAvailableConformance2' to 'Horse' is unavailable}}
72+
_ = x[keyPath: \.isGalloping] // expected-error {{conformance of 'HasAvailableConformance2' to 'Horse' is unavailable}}
73+
_ = UsesHorse<HasAvailableConformance2>.self // expected-error {{conformance of 'HasAvailableConformance2' to 'Horse' is unavailable}}
74+
}
75+
76+
@available(*, unavailable)
77+
func passAvailableConformance2a(x: HasAvailableConformance2) {
78+
takesHorse(x)
79+
takesHorseExistential(x)
80+
x.giddyUp()
81+
_ = x.isGalloping
82+
_ = UsesHorse<HasAvailableConformance2>.self
83+
}
84+

0 commit comments

Comments
 (0)