Skip to content

Commit b577a13

Browse files
authored
Merge pull request #79614 from DougGregor/conformance-attributes
Factor conformance attributes into their own separate structure.
2 parents 5f558fd + d681f92 commit b577a13

File tree

5 files changed

+83
-80
lines changed

5 files changed

+83
-80
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===--- ConformanceLookup.h - Global conformance lookup --------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_AST_CONFORMANCEATTRIBUTES_H
14+
#define SWIFT_AST_CONFORMANCEATTRIBUTES_H
15+
16+
#include "swift/Basic/SourceLoc.h"
17+
18+
namespace swift {
19+
20+
/// Describes all of the attributes that can occur on a conformance.
21+
struct ConformanceAttributes {
22+
/// The location of the "unchecked" attribute, if present.
23+
SourceLoc uncheckedLoc;
24+
25+
/// The location of the "preconcurrency" attribute if present.
26+
SourceLoc preconcurrencyLoc;
27+
28+
/// The location of the "unsafe" attribute if present.
29+
SourceLoc unsafeLoc;
30+
31+
/// Merge other conformance attributes into this set.
32+
ConformanceAttributes &
33+
operator |=(const ConformanceAttributes &other) {
34+
if (other.uncheckedLoc.isValid())
35+
uncheckedLoc = other.uncheckedLoc;
36+
if (other.preconcurrencyLoc.isValid())
37+
preconcurrencyLoc = other.preconcurrencyLoc;
38+
if (other.unsafeLoc.isValid())
39+
unsafeLoc = other.unsafeLoc;
40+
return *this;
41+
}
42+
};
43+
44+
}
45+
46+
#endif

include/swift/AST/NameLookup.h

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "swift/AST/ASTVisitor.h"
2121
#include "swift/AST/CatchNode.h"
22+
#include "swift/AST/ConformanceAttributes.h"
2223
#include "swift/AST/GenericSignature.h"
2324
#include "swift/AST/Identifier.h"
2425
#include "swift/AST/Module.h"
@@ -603,25 +604,17 @@ void forEachPotentialAttachedMacro(
603604

604605
/// Describes an inherited nominal entry.
605606
struct InheritedNominalEntry : Located<NominalTypeDecl *> {
606-
/// The location of the "unchecked" attribute, if present.
607-
SourceLoc uncheckedLoc;
608-
609-
/// The location of the "preconcurrency" attribute if present.
610-
SourceLoc preconcurrencyLoc;
611-
612-
/// The location of the "unsafe" attribute if present.
613-
SourceLoc unsafeLoc;
607+
ConformanceAttributes attributes;
614608

615609
/// Whether this inherited entry was suppressed via "~".
616610
bool isSuppressed;
617611

618612
InheritedNominalEntry() { }
619613

620614
InheritedNominalEntry(NominalTypeDecl *item, SourceLoc loc,
621-
SourceLoc uncheckedLoc, SourceLoc preconcurrencyLoc,
622-
SourceLoc unsafeLoc, bool isSuppressed)
623-
: Located(item, loc), uncheckedLoc(uncheckedLoc),
624-
preconcurrencyLoc(preconcurrencyLoc), unsafeLoc(unsafeLoc),
615+
ConformanceAttributes attributes,
616+
bool isSuppressed)
617+
: Located(item, loc), attributes(attributes),
625618
isSuppressed(isSuppressed) {}
626619
};
627620

lib/AST/ConformanceLookupTable.cpp

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "ConformanceLookupTable.h"
1818
#include "swift/AST/ASTContext.h"
19+
#include "swift/AST/ConformanceAttributes.h"
1920
#include "swift/AST/ConformanceLookup.h"
2021
#include "swift/AST/Decl.h"
2122
#include "swift/AST/ExistentialLayout.h"
@@ -148,23 +149,13 @@ void ConformanceLookupTable::destroy() {
148149

149150
namespace {
150151
struct ConformanceConstructionInfo : public Located<ProtocolDecl *> {
151-
/// The location of the "unchecked" attribute, if present.
152-
const SourceLoc uncheckedLoc;
153-
154-
/// The location of the "preconcurrency" attribute if present.
155-
const SourceLoc preconcurrencyLoc;
156-
157-
/// The location of the "unsafe" attribute if present.
158-
const SourceLoc unsafeLoc;
152+
ConformanceAttributes attributes;
159153

160154
ConformanceConstructionInfo() { }
161155

162156
ConformanceConstructionInfo(ProtocolDecl *item, SourceLoc loc,
163-
SourceLoc uncheckedLoc,
164-
SourceLoc preconcurrencyLoc,
165-
SourceLoc unsafeLoc)
166-
: Located(item, loc), uncheckedLoc(uncheckedLoc),
167-
preconcurrencyLoc(preconcurrencyLoc), unsafeLoc(unsafeLoc) {}
157+
ConformanceAttributes attributes)
158+
: Located(item, loc), attributes(attributes) {}
168159
};
169160
}
170161

@@ -220,7 +211,7 @@ void ConformanceLookupTable::forEachInStage(ConformanceStage stage,
220211
registerProtocolConformances(next, conformances);
221212
for (auto conf : conformances) {
222213
protocols.push_back(
223-
{conf->getProtocol(), SourceLoc(), SourceLoc(), SourceLoc(), SourceLoc()});
214+
{conf->getProtocol(), SourceLoc(), ConformanceAttributes()});
224215
}
225216
} else if (next->getParentSourceFile() ||
226217
next->getParentModule()->isBuiltinModule()) {
@@ -229,9 +220,7 @@ void ConformanceLookupTable::forEachInStage(ConformanceStage stage,
229220
for (const auto &found :
230221
getDirectlyInheritedNominalTypeDecls(next, inverses, anyObject)) {
231222
if (auto proto = dyn_cast<ProtocolDecl>(found.Item))
232-
protocols.push_back(
233-
{proto, found.Loc, found.uncheckedLoc,
234-
found.preconcurrencyLoc, found.unsafeLoc});
223+
protocols.push_back({proto, found.Loc, found.attributes});
235224
}
236225
}
237226

@@ -318,10 +307,8 @@ void ConformanceLookupTable::updateLookupTable(NominalTypeDecl *nominal,
318307
kp.has_value() &&
319308
"suppressed conformance for non-known protocol!?");
320309
if (!found.isSuppressed) {
321-
addProtocol(proto, found.Loc,
322-
source.withUncheckedLoc(found.uncheckedLoc)
323-
.withPreconcurrencyLoc(found.preconcurrencyLoc)
324-
.withUnsafeLoc(found.unsafeLoc));
310+
addProtocol(
311+
proto, found.Loc, source.withAttributes(found.attributes));
325312
}
326313
}
327314

@@ -335,9 +322,7 @@ void ConformanceLookupTable::updateLookupTable(NominalTypeDecl *nominal,
335322
for (auto locAndProto : protos)
336323
addProtocol(
337324
locAndProto.Item, locAndProto.Loc,
338-
source.withUncheckedLoc(locAndProto.uncheckedLoc)
339-
.withPreconcurrencyLoc(locAndProto.preconcurrencyLoc)
340-
.withUnsafeLoc(locAndProto.unsafeLoc));
325+
source.withAttributes(locAndProto.attributes));
341326
});
342327
break;
343328

lib/AST/ConformanceLookupTable.h

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define SWIFT_AST_CONFORMANCE_LOOKUP_TABLE_H
2222

2323
#include "swift/AST/DeclContext.h"
24+
#include "swift/AST/ConformanceAttributes.h"
2425
#include "swift/AST/ProtocolConformanceOptions.h"
2526
#include "swift/Basic/Debug.h"
2627
#include "swift/Basic/LLVM.h"
@@ -89,14 +90,7 @@ class ConformanceLookupTable : public ASTAllocated<ConformanceLookupTable> {
8990

9091
ConformanceEntryKind Kind;
9192

92-
/// The location of the "unchecked" attribute, if there is one.
93-
SourceLoc uncheckedLoc;
94-
95-
/// The location of the "preconcurrency" attribute, if there is one.
96-
SourceLoc preconcurrencyLoc;
97-
98-
/// The location of the "unsafe" attribute, if there is one.
99-
SourceLoc unsafeLoc;
93+
ConformanceAttributes attributes;
10094

10195
ConformanceSource(void *ptr, ConformanceEntryKind kind)
10296
: Storage(ptr), Kind(kind) { }
@@ -140,29 +134,16 @@ class ConformanceLookupTable : public ASTAllocated<ConformanceLookupTable> {
140134
return ConformanceSource(dc, ConformanceEntryKind::PreMacroExpansion);
141135
}
142136

143-
/// Return a new conformance source with the given location of "@unchecked".
144-
ConformanceSource withUncheckedLoc(SourceLoc uncheckedLoc) {
145-
ConformanceSource result(*this);
146-
if (uncheckedLoc.isValid())
147-
result.uncheckedLoc = uncheckedLoc;
148-
return result;
149-
}
150-
151-
/// Return a new conformance source with the given location of
152-
/// "@preconcurrency".
153-
ConformanceSource withPreconcurrencyLoc(SourceLoc preconcurrencyLoc) {
137+
/// Return a new conformance source with the given conformance
138+
/// attributes.
139+
ConformanceSource withAttributes(ConformanceAttributes attributes) {
154140
ConformanceSource result(*this);
155-
if (preconcurrencyLoc.isValid())
156-
result.preconcurrencyLoc = preconcurrencyLoc;
141+
result.attributes |= attributes;
157142
return result;
158143
}
159144

160-
/// Return a new conformance source with the given location of "@unsafe".
161-
ConformanceSource withUnsafeLoc(SourceLoc unsafeLoc) {
162-
ConformanceSource result(*this);
163-
if (unsafeLoc.isValid())
164-
result.unsafeLoc = unsafeLoc;
165-
return result;
145+
ConformanceAttributes getAttributes() const {
146+
return attributes;
166147
}
167148

168149
ProtocolConformanceOptions getOptions() const {
@@ -216,16 +197,16 @@ class ConformanceLookupTable : public ASTAllocated<ConformanceLookupTable> {
216197

217198
/// The location of the @unchecked attribute, if any.
218199
SourceLoc getUncheckedLoc() const {
219-
return uncheckedLoc;
200+
return attributes.uncheckedLoc;
220201
}
221202

222203
SourceLoc getPreconcurrencyLoc() const {
223-
return preconcurrencyLoc;
204+
return attributes.preconcurrencyLoc;
224205
}
225206

226207
/// The location of the @unsafe attribute, if any.
227208
SourceLoc getUnsafeLoc() const {
228-
return unsafeLoc;
209+
return attributes.unsafeLoc;
229210
}
230211

231212
/// For an inherited conformance, retrieve the class declaration

lib/AST/NameLookup.cpp

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/AST/ASTVisitor.h"
2020
#include "swift/AST/ASTWalker.h"
2121
#include "swift/AST/ClangModuleLoader.h"
22+
#include "swift/AST/ConformanceAttributes.h"
2223
#include "swift/AST/DebuggerClient.h"
2324
#include "swift/AST/ExistentialLayout.h"
2425
#include "swift/AST/GenericParamList.h"
@@ -3962,23 +3963,19 @@ void swift::getDirectlyInheritedNominalTypeDecls(
39623963
// FIXME: This is a hack. We need cooperation from
39633964
// InheritedDeclsReferencedRequest to make this work.
39643965
SourceLoc loc;
3965-
SourceLoc uncheckedLoc;
3966-
SourceLoc preconcurrencyLoc;
3967-
SourceLoc unsafeLoc;
3966+
ConformanceAttributes attributes;
39683967
auto inheritedTypes = InheritedTypes(decl);
39693968
bool isSuppressed = inheritedTypes.getEntry(i).isSuppressed();
39703969
if (TypeRepr *typeRepr = inheritedTypes.getTypeRepr(i)) {
39713970
loc = typeRepr->getLoc();
3972-
uncheckedLoc = typeRepr->findAttrLoc(TypeAttrKind::Unchecked);
3973-
preconcurrencyLoc = typeRepr->findAttrLoc(TypeAttrKind::Preconcurrency);
3974-
unsafeLoc = typeRepr->findAttrLoc(TypeAttrKind::Unsafe);
3971+
attributes.uncheckedLoc = typeRepr->findAttrLoc(TypeAttrKind::Unchecked);
3972+
attributes.preconcurrencyLoc = typeRepr->findAttrLoc(TypeAttrKind::Preconcurrency);
3973+
attributes.unsafeLoc = typeRepr->findAttrLoc(TypeAttrKind::Unsafe);
39753974
}
39763975

39773976
// Form the result.
39783977
for (auto nominal : nominalTypes) {
3979-
result.push_back(
3980-
{nominal, loc, uncheckedLoc, preconcurrencyLoc, unsafeLoc,
3981-
isSuppressed});
3978+
result.push_back({nominal, loc, attributes, isSuppressed});
39823979
}
39833980
}
39843981

@@ -4008,10 +4005,11 @@ swift::getDirectlyInheritedNominalTypeDecls(
40084005
for (auto attr :
40094006
protoDecl->getAttrs().getAttributes<SynthesizedProtocolAttr>()) {
40104007
auto loc = attr->getLocation();
4008+
ConformanceAttributes attributes;
4009+
if (attr->isUnchecked())
4010+
attributes.uncheckedLoc = loc;
40114011
result.push_back(
4012-
{attr->getProtocol(), loc, attr->isUnchecked() ? loc : SourceLoc(),
4013-
/*preconcurrencyLoc=*/SourceLoc(), SourceLoc(),
4014-
/*isSuppressed=*/false});
4012+
{attr->getProtocol(), loc, attributes, /*isSuppressed=*/false});
40154013
}
40164014

40174015
// Else we have access to this information on the where clause.
@@ -4022,8 +4020,8 @@ swift::getDirectlyInheritedNominalTypeDecls(
40224020
// FIXME: Refactor SelfBoundsFromWhereClauseRequest to dig out
40234021
// the source location.
40244022
for (auto inheritedNominal : selfBounds.decls)
4025-
result.emplace_back(inheritedNominal, SourceLoc(), SourceLoc(),
4026-
SourceLoc(), SourceLoc(), /*isSuppressed=*/false);
4023+
result.emplace_back(inheritedNominal, SourceLoc(), ConformanceAttributes(),
4024+
/*isSuppressed=*/false);
40274025

40284026
return result;
40294027
}

0 commit comments

Comments
 (0)