Skip to content

Commit cd61fd4

Browse files
committed
[NFC] Fix ImplementsAttr::clone()
Correct an issue with `ImplementsAttr` that would come up if you ever tried to clone an attribute that had been deserialized. No tests because there’s nothing in the compiler yet that might actually do so.
1 parent 97b249b commit cd61fd4

File tree

2 files changed

+22
-14
lines changed

2 files changed

+22
-14
lines changed

include/swift/AST/Attr.h

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,14 +1768,16 @@ class StorageRestrictionsAttr final
17681768
/// The @_implements attribute, which treats a decl as the implementation for
17691769
/// some named protocol requirement (but otherwise not-visible by that name).
17701770
class ImplementsAttr : public DeclAttribute {
1771-
TypeRepr *TyR;
1771+
/// If constructed by the \c create() variant with a TypeRepr, the TypeRepr;
1772+
/// if constructed by the \c create() variant with a DeclContext and
1773+
/// ProtocolDecl, the DeclContext.
1774+
llvm::PointerUnion<TypeRepr *, DeclContext *> TyROrDC;
17721775
DeclName MemberName;
17731776
DeclNameLoc MemberNameLoc;
17741777

17751778
ImplementsAttr(SourceLoc atLoc, SourceRange Range,
1776-
TypeRepr *TyR,
1777-
DeclName MemberName,
1778-
DeclNameLoc MemberNameLoc);
1779+
llvm::PointerUnion<TypeRepr *, DeclContext *> TyROrDC,
1780+
DeclName MemberName, DeclNameLoc MemberNameLoc);
17791781

17801782
public:
17811783
static ImplementsAttr *create(ASTContext &Ctx, SourceLoc atLoc,
@@ -1795,7 +1797,9 @@ class ImplementsAttr : public DeclAttribute {
17951797
/// otherwise `nullopt`. This should only be used for dumping.
17961798
std::optional<ProtocolDecl *> getCachedProtocol(DeclContext *dc) const;
17971799

1798-
TypeRepr *getProtocolTypeRepr() const { return TyR; }
1800+
TypeRepr *getProtocolTypeRepr() const {
1801+
return TyROrDC.dyn_cast<TypeRepr *>();
1802+
}
17991803

18001804
DeclName getMemberName() const { return MemberName; }
18011805
DeclNameLoc getMemberNameLoc() const { return MemberNameLoc; }
@@ -1806,8 +1810,12 @@ class ImplementsAttr : public DeclAttribute {
18061810

18071811
/// Create a copy of this attribute.
18081812
ImplementsAttr *clone(ASTContext &ctx) const {
1809-
return new (ctx) ImplementsAttr(
1810-
AtLoc, Range, TyR, getMemberName(), getMemberNameLoc());
1813+
if (auto tyR = getProtocolTypeRepr()) {
1814+
return create(ctx, AtLoc, Range, tyR, getMemberName(),
1815+
getMemberNameLoc());
1816+
}
1817+
auto dc = TyROrDC.dyn_cast<DeclContext *>();
1818+
return create(dc, getProtocol(dc), getMemberName());
18111819
}
18121820
};
18131821

lib/AST/Attr.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2712,11 +2712,12 @@ StorageRestrictionsAttr::create(
27122712
/*implicit=*/false);
27132713
}
27142714

2715-
ImplementsAttr::ImplementsAttr(SourceLoc atLoc, SourceRange range,
2716-
TypeRepr *TyR, DeclName MemberName,
2717-
DeclNameLoc MemberNameLoc)
2715+
ImplementsAttr::
2716+
ImplementsAttr(SourceLoc atLoc, SourceRange range,
2717+
llvm::PointerUnion<TypeRepr *, DeclContext *> TyROrDC,
2718+
DeclName MemberName, DeclNameLoc MemberNameLoc)
27182719
: DeclAttribute(DeclAttrKind::Implements, atLoc, range, /*Implicit=*/false),
2719-
TyR(TyR), MemberName(MemberName), MemberNameLoc(MemberNameLoc) {}
2720+
TyROrDC(TyROrDC), MemberName(MemberName), MemberNameLoc(MemberNameLoc) {}
27202721

27212722
ImplementsAttr *ImplementsAttr::create(ASTContext &Ctx, SourceLoc atLoc,
27222723
SourceRange range,
@@ -2733,9 +2734,8 @@ ImplementsAttr *ImplementsAttr::create(DeclContext *DC,
27332734
DeclName MemberName) {
27342735
auto &ctx = DC->getASTContext();
27352736
void *mem = ctx.Allocate(sizeof(ImplementsAttr), alignof(ImplementsAttr));
2736-
auto *attr = new (mem) ImplementsAttr(
2737-
SourceLoc(), SourceRange(), nullptr,
2738-
MemberName, DeclNameLoc());
2737+
auto *attr = new (mem) ImplementsAttr(SourceLoc(), SourceRange(), DC,
2738+
MemberName, DeclNameLoc());
27392739
ctx.evaluator.cacheOutput(ImplementsAttrProtocolRequest{attr, DC},
27402740
std::move(Proto));
27412741
return attr;

0 commit comments

Comments
 (0)