Skip to content

Commit 6bb0e49

Browse files
committed
Move precedence group cycle checking into requests
Use the request evaluator to get the easier in-module precedence group cycles. Unfortunately, cross-module precedence group cycles are still a possibility, and do not actually cause cyclic request evaluation, so we cannot completely erase the old diagnostics machinery. Move the machinery itself into the type checker and shift the request into that zone as well to appease the linker.
1 parent f7b3e4b commit 6bb0e49

File tree

11 files changed

+167
-184
lines changed

11 files changed

+167
-184
lines changed

include/swift/AST/Decl.h

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -282,13 +282,6 @@ bool conflicting(ASTContext &ctx,
282282

283283
/// Decl - Base class for all declarations in Swift.
284284
class alignas(1 << DeclAlignInBits) Decl {
285-
public:
286-
enum class ValidationState {
287-
Unchecked,
288-
Checking,
289-
Checked,
290-
};
291-
292285
protected:
293286
union { uint64_t OpaqueBits;
294287

@@ -307,9 +300,6 @@ class alignas(1 << DeclAlignInBits) Decl {
307300
/// Use getClangNode() to retrieve the corresponding Clang AST.
308301
FromClang : 1,
309302

310-
/// The validation state of this declaration.
311-
ValidationState : 2,
312-
313303
/// Whether this declaration was added to the surrounding
314304
/// DeclContext of an active #if config clause.
315305
EscapedFromIfConfig : 1
@@ -689,7 +679,6 @@ class alignas(1 << DeclAlignInBits) Decl {
689679
Bits.Decl.Invalid = false;
690680
Bits.Decl.Implicit = false;
691681
Bits.Decl.FromClang = false;
692-
Bits.Decl.ValidationState = unsigned(ValidationState::Unchecked);
693682
Bits.Decl.EscapedFromIfConfig = false;
694683
}
695684

@@ -830,37 +819,7 @@ class alignas(1 << DeclAlignInBits) Decl {
830819
/// Mark this declaration as implicit.
831820
void setImplicit(bool implicit = true) { Bits.Decl.Implicit = implicit; }
832821

833-
/// Get the validation state.
834-
ValidationState getValidationState() const {
835-
return ValidationState(Bits.Decl.ValidationState);
836-
}
837-
838-
private:
839-
friend class DeclValidationRAII;
840-
841-
/// Set the validation state.
842-
void setValidationState(ValidationState VS) {
843-
assert(VS > getValidationState() && "Validation is unidirectional");
844-
Bits.Decl.ValidationState = unsigned(VS);
845-
}
846-
847822
public:
848-
/// Whether the declaration is in the middle of validation or not.
849-
bool isBeingValidated() const {
850-
switch (getValidationState()) {
851-
case ValidationState::Unchecked:
852-
case ValidationState::Checked:
853-
return false;
854-
case ValidationState::Checking:
855-
return true;
856-
}
857-
llvm_unreachable("Unknown ValidationState");
858-
}
859-
860-
bool hasValidationStarted() const {
861-
return getValidationState() > ValidationState::Unchecked;
862-
}
863-
864823
bool escapedFromIfConfig() const {
865824
return Bits.Decl.EscapedFromIfConfig;
866825
}
@@ -982,25 +941,6 @@ class alignas(1 << DeclAlignInBits) Decl {
982941
}
983942
};
984943

985-
/// Use RAII to track Decl validation progress and non-reentrancy.
986-
class DeclValidationRAII {
987-
Decl *D;
988-
989-
public:
990-
DeclValidationRAII(const DeclValidationRAII &) = delete;
991-
DeclValidationRAII(DeclValidationRAII &&) = delete;
992-
void operator =(const DeclValidationRAII &) = delete;
993-
void operator =(DeclValidationRAII &&) = delete;
994-
995-
DeclValidationRAII(Decl *decl) : D(decl) {
996-
D->setValidationState(Decl::ValidationState::Checking);
997-
}
998-
999-
~DeclValidationRAII() {
1000-
D->setValidationState(Decl::ValidationState::Checked);
1001-
}
1002-
};
1003-
1004944
/// Allocates memory for a Decl with the given \p baseSize. If necessary,
1005945
/// it includes additional space immediately preceding the Decl for a ClangNode.
1006946
/// \note \p baseSize does not need to include space for a ClangNode if

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,8 @@ NOTE(found_this_precedence_group,none,
883883
ERROR(unknown_precedence_group,none,
884884
"unknown precedence group %0", (Identifier))
885885
ERROR(precedence_group_cycle,none,
886+
"cycle in '%select{lowerThan|higherThan}0' relation", (bool))
887+
ERROR(higher_than_precedence_group_cycle,none,
886888
"cycle in higherThan relation: %0", (StringRef))
887889
ERROR(precedence_group_lower_within_module,none,
888890
"precedence group cannot be given lower precedence than group in same"

include/swift/AST/NameLookupRequests.h

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -278,56 +278,6 @@ class GenericParamListRequest :
278278
void cacheResult(GenericParamList *value) const;
279279
};
280280

281-
struct PrecedenceGroupDescriptor {
282-
DeclContext *dc;
283-
Identifier ident;
284-
SourceLoc nameLoc;
285-
286-
SourceLoc getLoc() const;
287-
288-
friend llvm::hash_code hash_value(const PrecedenceGroupDescriptor &owner) {
289-
return hash_combine(llvm::hash_value(owner.dc),
290-
llvm::hash_value(owner.ident.getAsOpaquePointer()),
291-
llvm::hash_value(owner.nameLoc.getOpaquePointerValue()));
292-
}
293-
294-
friend bool operator==(const PrecedenceGroupDescriptor &lhs,
295-
const PrecedenceGroupDescriptor &rhs) {
296-
return lhs.dc == rhs.dc &&
297-
lhs.ident == rhs.ident &&
298-
lhs.nameLoc == rhs.nameLoc;
299-
}
300-
301-
friend bool operator!=(const PrecedenceGroupDescriptor &lhs,
302-
const PrecedenceGroupDescriptor &rhs) {
303-
return !(lhs == rhs);
304-
}
305-
};
306-
307-
void simple_display(llvm::raw_ostream &out, const PrecedenceGroupDescriptor &d);
308-
309-
class LookupPrecedenceGroupRequest
310-
: public SimpleRequest<LookupPrecedenceGroupRequest,
311-
PrecedenceGroupDecl *(PrecedenceGroupDescriptor),
312-
CacheKind::Cached> {
313-
public:
314-
using SimpleRequest::SimpleRequest;
315-
316-
private:
317-
friend SimpleRequest;
318-
319-
// Evaluation.
320-
llvm::Expected<PrecedenceGroupDecl *>
321-
evaluate(Evaluator &evaluator, PrecedenceGroupDescriptor descriptor) const;
322-
323-
public:
324-
// Source location
325-
SourceLoc getNearestLoc() const;
326-
327-
// Separate caching.
328-
bool isCached() const { return true; }
329-
};
330-
331281
/// Expand the given ASTScope. Requestified to detect recursion.
332282
class ExpandASTScopeRequest
333283
: public SimpleRequest<ExpandASTScopeRequest,

include/swift/AST/NameLookupTypeIDZone.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ SWIFT_REQUEST(NameLookup, InheritedDeclsReferencedRequest,
3434
DirectlyReferencedTypeDecls(
3535
llvm::PointerUnion<TypeDecl *, ExtensionDecl *>, unsigned),
3636
Uncached, HasNearestLocation)
37-
SWIFT_REQUEST(NameLookup, LookupPrecedenceGroupRequest,
38-
PrecedenceGroupDecl *(DeclContext *, Identifier, SourceLoc),
39-
Cached, NoLocationInfo)
4037
SWIFT_REQUEST(NameLookup, SelfBoundsFromWhereClauseRequest,
4138
SelfBounds(llvm::PointerUnion<TypeDecl *, ExtensionDecl *>),
4239
Uncached, NoLocationInfo)

include/swift/AST/TypeCheckRequests.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,6 +1448,62 @@ class InterfaceTypeRequest :
14481448
void cacheResult(Type value) const;
14491449
};
14501450

1451+
struct PrecedenceGroupDescriptor {
1452+
DeclContext *dc;
1453+
Identifier ident;
1454+
SourceLoc nameLoc;
1455+
// Exists for diagnostics. Does not contribute to the descriptor otherwise.
1456+
Optional<bool> pathDirection;
1457+
1458+
SourceLoc getLoc() const;
1459+
1460+
friend llvm::hash_code hash_value(const PrecedenceGroupDescriptor &owner) {
1461+
return llvm::hash_combine(owner.dc,
1462+
owner.ident.getAsOpaquePointer(),
1463+
owner.nameLoc.getOpaquePointerValue());
1464+
}
1465+
1466+
friend bool operator==(const PrecedenceGroupDescriptor &lhs,
1467+
const PrecedenceGroupDescriptor &rhs) {
1468+
return lhs.dc == rhs.dc &&
1469+
lhs.ident == rhs.ident &&
1470+
lhs.nameLoc == rhs.nameLoc;
1471+
}
1472+
1473+
friend bool operator!=(const PrecedenceGroupDescriptor &lhs,
1474+
const PrecedenceGroupDescriptor &rhs) {
1475+
return !(lhs == rhs);
1476+
}
1477+
};
1478+
1479+
void simple_display(llvm::raw_ostream &out, const PrecedenceGroupDescriptor &d);
1480+
1481+
class LookupPrecedenceGroupRequest
1482+
: public SimpleRequest<LookupPrecedenceGroupRequest,
1483+
PrecedenceGroupDecl *(PrecedenceGroupDescriptor),
1484+
CacheKind::Cached> {
1485+
public:
1486+
using SimpleRequest::SimpleRequest;
1487+
1488+
private:
1489+
friend SimpleRequest;
1490+
1491+
// Evaluation.
1492+
llvm::Expected<PrecedenceGroupDecl *>
1493+
evaluate(Evaluator &evaluator, PrecedenceGroupDescriptor descriptor) const;
1494+
1495+
public:
1496+
// Cycle handling.
1497+
void diagnoseCycle(DiagnosticEngine &diags) const;
1498+
void noteCycleStep(DiagnosticEngine &diags) const;
1499+
1500+
// Source location
1501+
SourceLoc getNearestLoc() const;
1502+
1503+
// Separate caching.
1504+
bool isCached() const { return true; }
1505+
};
1506+
14511507
// Allow AnyValue to compare two Type values, even though Type doesn't
14521508
// support ==.
14531509
template<>

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ SWIFT_REQUEST(TypeChecker, IsSetterMutatingRequest, bool(AbstractStorageDecl *),
8585
SeparatelyCached, NoLocationInfo)
8686
SWIFT_REQUEST(TypeChecker, LazyStoragePropertyRequest, VarDecl *(VarDecl *),
8787
Cached, NoLocationInfo)
88+
SWIFT_REQUEST(TypeChecker, LookupPrecedenceGroupRequest,
89+
PrecedenceGroupDecl *(DeclContext *, Identifier, SourceLoc),
90+
Cached, NoLocationInfo)
8891
SWIFT_REQUEST(TypeChecker, MangleLocalTypeDeclRequest,
8992
std::string(const TypeDecl *), Cached, NoLocationInfo)
9093
SWIFT_REQUEST(TypeChecker, NamingPatternRequest,

lib/AST/Decl.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7404,21 +7404,6 @@ PrecedenceGroupDecl::PrecedenceGroupDecl(DeclContext *dc,
74047404
lowerThan.size() * sizeof(Relation));
74057405
}
74067406

7407-
llvm::Expected<PrecedenceGroupDecl *> LookupPrecedenceGroupRequest::evaluate(
7408-
Evaluator &eval, PrecedenceGroupDescriptor descriptor) const {
7409-
auto *dc = descriptor.dc;
7410-
PrecedenceGroupDecl *group = nullptr;
7411-
if (auto sf = dc->getParentSourceFile()) {
7412-
bool cascading = dc->isCascadingContextForLookup(false);
7413-
group = sf->lookupPrecedenceGroup(descriptor.ident, cascading,
7414-
descriptor.nameLoc);
7415-
} else {
7416-
group = dc->getParentModule()->lookupPrecedenceGroup(descriptor.ident,
7417-
descriptor.nameLoc);
7418-
}
7419-
return group;
7420-
}
7421-
74227407
PrecedenceGroupDecl *InfixOperatorDecl::getPrecedenceGroup() const {
74237408
return evaluateOrDefault(
74247409
getASTContext().evaluator,

lib/AST/NameLookupRequests.cpp

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -128,26 +128,6 @@ void GenericParamListRequest::cacheResult(GenericParamList *params) const {
128128
context->GenericParamsAndBit.setPointerAndInt(params, true);
129129
}
130130

131-
132-
//----------------------------------------------------------------------------//
133-
// LookupPrecedenceGroupRequest computation.
134-
//----------------------------------------------------------------------------//
135-
136-
SourceLoc LookupPrecedenceGroupRequest::getNearestLoc() const {
137-
auto &desc = std::get<0>(getStorage());
138-
return desc.getLoc();
139-
}
140-
141-
SourceLoc PrecedenceGroupDescriptor::getLoc() const {
142-
return nameLoc;
143-
}
144-
145-
void swift::simple_display(llvm::raw_ostream &out,
146-
const PrecedenceGroupDescriptor &desc) {
147-
out << "precedence group " << desc.ident << " at ";
148-
desc.nameLoc.print(out, desc.dc->getASTContext().SourceMgr);
149-
}
150-
151131
// Define request evaluation functions for each of the name lookup requests.
152132
static AbstractRequestFunction *nameLookupRequestFunctions[] = {
153133
#define SWIFT_REQUEST(Zone, Name, Sig, Caching, LocOptions) \

lib/AST/TypeCheckRequests.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,3 +1026,36 @@ void InterfaceTypeRequest::cacheResult(Type type) const {
10261026
}
10271027
decl->TypeAndAccess.setPointer(type);
10281028
}
1029+
1030+
//----------------------------------------------------------------------------//
1031+
// LookupPrecedenceGroupRequest computation.
1032+
//----------------------------------------------------------------------------//
1033+
1034+
SourceLoc LookupPrecedenceGroupRequest::getNearestLoc() const {
1035+
auto &desc = std::get<0>(getStorage());
1036+
return desc.getLoc();
1037+
}
1038+
1039+
void LookupPrecedenceGroupRequest::diagnoseCycle(DiagnosticEngine &diags) const {
1040+
auto &desc = std::get<0>(getStorage());
1041+
if (auto pathDir = desc.pathDirection) {
1042+
diags.diagnose(desc.nameLoc, diag::precedence_group_cycle, *pathDir);
1043+
} else {
1044+
diags.diagnose(desc.nameLoc, diag::circular_reference);
1045+
}
1046+
}
1047+
1048+
void LookupPrecedenceGroupRequest::noteCycleStep(DiagnosticEngine &diags) const {
1049+
auto &desc = std::get<0>(getStorage());
1050+
diags.diagnose(desc.nameLoc, diag::circular_reference_through);
1051+
}
1052+
1053+
SourceLoc PrecedenceGroupDescriptor::getLoc() const {
1054+
return nameLoc;
1055+
}
1056+
1057+
void swift::simple_display(llvm::raw_ostream &out,
1058+
const PrecedenceGroupDescriptor &desc) {
1059+
out << "precedence group " << desc.ident << " at ";
1060+
desc.nameLoc.print(out, desc.dc->getASTContext().SourceMgr);
1061+
}

0 commit comments

Comments
 (0)