Skip to content

Commit 9f1cf08

Browse files
committed
Let generated availability attributes of initializers of subclasses inherit the message and renaming from the initializer of the superclass
1 parent 9e7f784 commit 9f1cf08

File tree

2 files changed

+44
-17
lines changed

2 files changed

+44
-17
lines changed

lib/AST/Availability.cpp

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17+
#include "swift/AST/Availability.h"
1718
#include "swift/AST/ASTContext.h"
1819
#include "swift/AST/Attr.h"
1920
#include "swift/AST/Decl.h"
20-
#include "swift/AST/Types.h"
21-
#include "swift/AST/Availability.h"
2221
#include "swift/AST/PlatformKind.h"
2322
#include "swift/AST/TypeWalker.h"
23+
#include "swift/AST/Types.h"
24+
#include "llvm/ADT/SmallSet.h"
2425
#include <map>
2526

2627
using namespace swift;
@@ -95,10 +96,11 @@ static void mergeWithInferredAvailability(const AvailableAttr *Attr,
9596

9697
/// Create an implicit availability attribute for the given platform
9798
/// and with the inferred availability.
98-
static AvailableAttr *
99-
createAvailableAttr(PlatformKind Platform,
100-
const InferredAvailability &Inferred,
101-
ASTContext &Context) {
99+
static AvailableAttr *createAvailableAttr(PlatformKind Platform,
100+
const InferredAvailability &Inferred,
101+
StringRef Message, StringRef Rename,
102+
ValueDecl *RenameDecl,
103+
ASTContext &Context) {
102104

103105
llvm::VersionTuple Introduced =
104106
Inferred.Introduced.getValueOr(llvm::VersionTuple());
@@ -107,21 +109,25 @@ createAvailableAttr(PlatformKind Platform,
107109
llvm::VersionTuple Obsoleted =
108110
Inferred.Obsoleted.getValueOr(llvm::VersionTuple());
109111

110-
return new (Context) AvailableAttr(
111-
SourceLoc(), SourceRange(), Platform,
112-
/*Message=*/StringRef(),
113-
/*Rename=*/StringRef(), /*RenameDecl=*/nullptr,
114-
Introduced, /*IntroducedRange=*/SourceRange(),
115-
Deprecated, /*DeprecatedRange=*/SourceRange(),
116-
Obsoleted, /*ObsoletedRange=*/SourceRange(),
117-
Inferred.PlatformAgnostic, /*Implicit=*/true,
118-
Inferred.IsSPI);
112+
return new (Context)
113+
AvailableAttr(SourceLoc(), SourceRange(), Platform,
114+
Message, Rename, RenameDecl,
115+
Introduced, /*IntroducedRange=*/SourceRange(),
116+
Deprecated, /*DeprecatedRange=*/SourceRange(),
117+
Obsoleted, /*ObsoletedRange=*/SourceRange(),
118+
Inferred.PlatformAgnostic, /*Implicit=*/true,
119+
Inferred.IsSPI);
119120
}
120121

121122
void AvailabilityInference::applyInferredAvailableAttrs(
122123
Decl *ToDecl, ArrayRef<const Decl *> InferredFromDecls,
123124
ASTContext &Context) {
124125

126+
// If all AvailableAttrs have the same message, let the new one
127+
// inherit that message. The same for rename.
128+
llvm::SmallSet<StringRef, 1> Messages;
129+
llvm::SmallSet<std::pair<StringRef, ValueDecl *>, 1> Renames;
130+
125131
// Iterate over the declarations and infer required availability on
126132
// a per-platform basis.
127133
std::map<PlatformKind, InferredAvailability> Inferred;
@@ -132,14 +138,30 @@ void AvailabilityInference::applyInferredAvailableAttrs(
132138
continue;
133139

134140
mergeWithInferredAvailability(AvAttr, Inferred[AvAttr->Platform]);
141+
142+
if (!AvAttr->Message.empty())
143+
Messages.insert(AvAttr->Message);
144+
145+
if (!AvAttr->Rename.empty())
146+
Renames.insert({AvAttr->Rename, AvAttr->RenameDecl});
135147
}
136148
}
137149

138150
// Create an availability attribute for each observed platform and add
139151
// to ToDecl.
140152
DeclAttributes &Attrs = ToDecl->getAttrs();
141153
for (auto &Pair : Inferred) {
142-
auto *Attr = createAvailableAttr(Pair.first, Pair.second, Context);
154+
const StringRef Message =
155+
Messages.size() == 1 ? *Messages.begin() : StringRef();
156+
157+
const auto Rename =
158+
Renames.size() == 1
159+
? *Renames.begin()
160+
: std::pair<StringRef, ValueDecl *>(StringRef(), nullptr);
161+
162+
auto *Attr = createAvailableAttr(Pair.first, Pair.second, Message,
163+
Rename.first, Rename.second, Context);
164+
143165
Attrs.add(Attr);
144166
}
145167
}

test/attr/attr_availability.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,12 @@ class DeprecatedInitSub1: DeprecatedInitBase {
611611

612612
class DeprecatedInitSub2: DeprecatedInitBase { }
613613

614-
_ = DeprecatedInitSub2(old: 0) // expected-warning {{'init(old:)' is deprecated}}
614+
_ = DeprecatedInitBase(old: 0) // expected-warning {{'init(old:)' is deprecated: replaced by 'init(new:)'}} expected-note {{use 'init(new:)' instead}} {{24-27=new}}
615+
_ = DeprecatedInitBase.init(old: 0) // expected-warning {{'init(old:)' is deprecated: replaced by 'init(new:)'}} expected-note {{use 'init(new:)' instead}} {{29-32=new}}
616+
let _: DeprecatedInitBase = .init(old: 0) // expected-warning {{'init(old:)' is deprecated: replaced by 'init(new:)'}} expected-note {{use 'init(new:)' instead}} {{35-38=new}}
617+
_ = DeprecatedInitSub2(old: 0) // expected-warning {{'init(old:)' is deprecated: replaced by 'init(new:)'}} expected-note {{use 'init(new:)' instead}} {{24-27=new}}
618+
_ = DeprecatedInitSub2.init(old: 0) // expected-warning {{'init(old:)' is deprecated: replaced by 'init(new:)'}} expected-note {{use 'init(new:)' instead}} {{29-32=new}}
619+
let _: DeprecatedInitSub2 = .init(old: 0) // expected-warning {{'init(old:)' is deprecated: replaced by 'init(new:)'}} expected-note {{use 'init(new:)' instead}} {{35-38=new}}
615620

616621
class Base {
617622
@available(*, unavailable)

0 commit comments

Comments
 (0)