Skip to content

Commit 66c4ace

Browse files
authored
Merge pull request #37675 from slavapestov/gsb-v2
RequirementMachine: A term rewriting system for reasoning about generic signatures
2 parents 16ae354 + a7486b4 commit 66c4ace

16 files changed

+1993
-17
lines changed

include/swift/AST/ASTContext.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ namespace swift {
111111
class TupleTypeElt;
112112
class EnumElementDecl;
113113
class ProtocolDecl;
114+
class RequirementMachine;
114115
class SubstitutableType;
115116
class SourceManager;
116117
class ValueDecl;
@@ -1132,6 +1133,11 @@ class ASTContext final {
11321133
GenericSignatureBuilder *getOrCreateGenericSignatureBuilder(
11331134
CanGenericSignature sig);
11341135

1136+
/// Retrieve or create a term rewriting system for answering queries on
1137+
/// type parameters written against the given generic signature.
1138+
RequirementMachine *getOrCreateRequirementMachine(
1139+
CanGenericSignature sig);
1140+
11351141
/// Retrieve a generic signature with a single unconstrained type parameter,
11361142
/// like `<T>`.
11371143
CanGenericSignature getSingleGenericParameterSignature() const;

include/swift/AST/LayoutConstraint.h

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,10 @@ class LayoutConstraint {
284284
bool operator!=(LayoutConstraint rhs) const {
285285
return !(*this == rhs);
286286
}
287+
288+
/// Defines a somewhat arbitrary linear order on layout constraints.
289+
/// -1 if this < rhs, 0 if this == rhs, 1 if this > rhs.
290+
int compare(LayoutConstraint rhs) const;
287291
};
288292

289293
// Permit direct uses of isa/cast/dyn_cast on LayoutConstraint.
@@ -313,12 +317,6 @@ struct LayoutConstraintLoc {
313317

314318
bool isError() const;
315319

316-
// FIXME: We generally shouldn't need to build LayoutConstraintLoc without
317-
// a location.
318-
static LayoutConstraintLoc withoutLoc(LayoutConstraint Layout) {
319-
return LayoutConstraintLoc(Layout, SourceLoc());
320-
}
321-
322320
/// Get the representative location of this type, for diagnostic
323321
/// purposes.
324322
SourceLoc getLoc() const { return Loc; }
@@ -328,13 +326,7 @@ struct LayoutConstraintLoc {
328326
bool hasLocation() const { return Loc.isValid(); }
329327
LayoutConstraint getLayoutConstraint() const { return Layout; }
330328

331-
void setLayoutConstraint(LayoutConstraint value) {
332-
Layout = value;
333-
}
334-
335329
bool isNull() const { return Layout.isNull(); }
336-
337-
LayoutConstraintLoc clone(ASTContext &ctx) const { return *this; }
338330
};
339331

340332
/// Checks if ID is a name of a layout constraint and returns this

include/swift/AST/LayoutConstraintKind.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17+
#include "llvm/Support/DataTypes.h"
18+
1719
#ifndef SWIFT_LAYOUT_CONSTRAINTKIND_H
1820
#define SWIFT_LAYOUT_CONSTRAINTKIND_H
1921

include/swift/AST/ProtocolGraph.h

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//===--- ProtocolGraph.h - Collects information about protocols -*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2021 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_PROTOCOLGRAPH_H
14+
#define SWIFT_PROTOCOLGRAPH_H
15+
16+
#include "swift/AST/Requirement.h"
17+
#include "llvm/ADT/ArrayRef.h"
18+
#include "llvm/ADT/DenseMap.h"
19+
#include "llvm/ADT/TinyPtrVector.h"
20+
21+
namespace swift {
22+
23+
class ProtocolDecl;
24+
class AssociatedTypeDecl;
25+
26+
namespace rewriting {
27+
28+
/// Stores cached information about a protocol.
29+
struct ProtocolInfo {
30+
/// All immediately-inherited protocols.
31+
ArrayRef<ProtocolDecl *> Inherited;
32+
33+
/// Transitive closure of inherited protocols; does not include the protocol
34+
/// itself. Computed by ProtocolGraph::computeInheritedProtocols().
35+
llvm::TinyPtrVector<const ProtocolDecl *> AllInherited;
36+
37+
/// Transitive closure of inherited associated types together with all
38+
/// associated types from the protocol itself. Computed by
39+
/// ProtocolGraph::computeInheritedAssociatedTypes().
40+
llvm::TinyPtrVector<AssociatedTypeDecl *> AssociatedTypes;
41+
42+
/// The protocol's requirement signature.
43+
ArrayRef<Requirement> Requirements;
44+
45+
/// Used by ProtocolGraph::computeProtocolDepth() to detect circularity.
46+
unsigned Mark : 1;
47+
48+
/// Longest chain of protocol refinements, including this one. Greater than
49+
/// zero on valid code, might be zero if there's a cycle. Computed by
50+
/// ProtocolGraph::computeLinearOrder().
51+
unsigned Depth : 31;
52+
53+
/// Index of the protocol in the linear order. Computed by
54+
/// ProtocolGraph::computeLinearOrder().
55+
unsigned Index : 32;
56+
57+
ProtocolInfo() {
58+
Mark = 0;
59+
Depth = 0;
60+
Index = 0;
61+
}
62+
63+
ProtocolInfo(ArrayRef<ProtocolDecl *> inherited,
64+
llvm::TinyPtrVector<AssociatedTypeDecl *> &&types,
65+
ArrayRef<Requirement> reqs)
66+
: Inherited(inherited),
67+
AssociatedTypes(types),
68+
Requirements(reqs) {
69+
Mark = 0;
70+
Depth = 0;
71+
Index = 0;
72+
}
73+
};
74+
75+
/// Stores cached information about all protocols transtively
76+
/// referenced from a set of generic requirements.
77+
///
78+
/// Out-of-line methods are documented in ProtocolGraph.cpp.
79+
struct ProtocolGraph {
80+
llvm::DenseMap<const ProtocolDecl *, ProtocolInfo> Info;
81+
std::vector<const ProtocolDecl *> Protocols;
82+
bool Debug = false;
83+
84+
void visitRequirements(ArrayRef<Requirement> reqs);
85+
86+
const ProtocolInfo &getProtocolInfo(
87+
const ProtocolDecl *proto) const;
88+
89+
void addProtocol(const ProtocolDecl *proto);
90+
91+
void computeTransitiveClosure();
92+
93+
void computeLinearOrder();
94+
95+
void computeInheritedAssociatedTypes();
96+
97+
void computeInheritedProtocols();
98+
99+
int compareProtocols(const ProtocolDecl *lhs,
100+
const ProtocolDecl *rhs) const;
101+
102+
bool inheritsFrom(const ProtocolDecl *thisProto,
103+
const ProtocolDecl *otherProto) const;
104+
105+
private:
106+
unsigned computeProtocolDepth(const ProtocolDecl *proto);
107+
};
108+
109+
} // end namespace rewriting
110+
111+
} // end namespace swift
112+
113+
#endif
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//===--- RequirementMachine.h - Generics with term rewriting ----*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2021 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_REQUIREMENTMACHINE_H
14+
#define SWIFT_REQUIREMENTMACHINE_H
15+
16+
namespace swift {
17+
18+
class ASTContext;
19+
class AssociatedTypeDecl;
20+
class CanGenericSignature;
21+
class CanType;
22+
class GenericSignature;
23+
class ProtocolDecl;
24+
class Requirement;
25+
26+
namespace rewriting {
27+
28+
class Term;
29+
30+
Term getTermForType(CanType paramType, const ProtocolDecl *proto);
31+
32+
} // end namespace rewriting
33+
34+
/// Wraps a rewrite system with higher-level operations in terms of
35+
/// generic signatures and interface types.
36+
class RequirementMachine final {
37+
friend class ASTContext;
38+
39+
struct Implementation;
40+
41+
ASTContext &Context;
42+
Implementation *Impl;
43+
44+
explicit RequirementMachine(ASTContext &ctx);
45+
46+
RequirementMachine(const RequirementMachine &) = delete;
47+
RequirementMachine(RequirementMachine &&) = delete;
48+
RequirementMachine &operator=(const RequirementMachine &) = delete;
49+
RequirementMachine &operator=(RequirementMachine &&) = delete;
50+
51+
void addGenericSignature(CanGenericSignature sig);
52+
53+
bool isComplete() const;
54+
void markComplete();
55+
56+
public:
57+
~RequirementMachine();
58+
};
59+
60+
} // end namespace swift
61+
62+
#endif

0 commit comments

Comments
 (0)