1818#define SWIFT_AST_REQUIREMENT_H
1919
2020#include " swift/AST/LayoutConstraint.h"
21- #include " swift/AST/RequirementBase .h"
21+ #include " swift/AST/RequirementKind .h"
2222#include " swift/AST/Type.h"
2323#include " swift/Basic/Debug.h"
2424#include " llvm/ADT/Hashing.h"
@@ -29,18 +29,97 @@ namespace swift {
2929
3030// / A single requirement placed on the type parameters (or associated
3131// / types thereof) of a
32- class Requirement
33- : public RequirementBase<Type,
34- llvm::PointerIntPair<Type, 3 , RequirementKind>,
35- LayoutConstraint> {
32+ class Requirement {
33+ llvm::PointerIntPair<Type, 3 , RequirementKind> FirstTypeAndKind;
34+ // / The second element of the requirement. Its content is dependent
35+ // / on the requirement kind.
36+ // / The payload of the following enum should always match the kind!
37+ // / Any access to the fields of this enum should first check if the
38+ // / requested access matches the kind of the requirement.
39+ union {
40+ Type SecondType;
41+ LayoutConstraint SecondLayout;
42+ };
43+
3644public:
3745 // / Create a conformance or same-type requirement.
3846 Requirement (RequirementKind kind, Type first, Type second)
39- : RequirementBase(kind, first, second) {}
47+ : FirstTypeAndKind(first, kind), SecondType(second) {
48+ assert (first);
49+ assert (second);
50+ assert (kind != RequirementKind::Layout);
51+ }
4052
4153 // / Create a layout constraint requirement.
4254 Requirement (RequirementKind kind, Type first, LayoutConstraint second)
43- : RequirementBase(kind, first, second) {}
55+ : FirstTypeAndKind(first, kind), SecondLayout(second) {
56+ assert (first);
57+ assert (second);
58+ assert (kind == RequirementKind::Layout);
59+ }
60+
61+
62+ // / Determine the kind of requirement.
63+ RequirementKind getKind () const { return FirstTypeAndKind.getInt (); }
64+
65+ // / Retrieve the first type.
66+ Type getFirstType () const {
67+ return FirstTypeAndKind.getPointer ();
68+ }
69+
70+ // / Retrieve the second type.
71+ Type getSecondType () const {
72+ assert (getKind () != RequirementKind::Layout);
73+ return SecondType;
74+ }
75+
76+ // / Retrieve the layout constraint.
77+ LayoutConstraint getLayoutConstraint () const {
78+ assert (getKind () == RequirementKind::Layout);
79+ return SecondLayout;
80+ }
81+
82+ friend llvm::hash_code hash_value (const Requirement &requirement) {
83+ using llvm::hash_value;
84+
85+ llvm::hash_code first =
86+ hash_value (requirement.FirstTypeAndKind .getOpaqueValue ());
87+ llvm::hash_code second;
88+ switch (requirement.getKind ()) {
89+ case RequirementKind::SameShape:
90+ case RequirementKind::Conformance:
91+ case RequirementKind::Superclass:
92+ case RequirementKind::SameType:
93+ second = hash_value (requirement.getSecondType ());
94+ break ;
95+
96+ case RequirementKind::Layout:
97+ second = hash_value (requirement.getLayoutConstraint ());
98+ break ;
99+ }
100+
101+ return llvm::hash_combine (first, second);
102+ }
103+
104+ friend bool operator ==(const Requirement &lhs,
105+ const Requirement &rhs) {
106+ if (lhs.FirstTypeAndKind .getOpaqueValue ()
107+ != rhs.FirstTypeAndKind .getOpaqueValue ())
108+ return false ;
109+
110+ switch (lhs.getKind ()) {
111+ case RequirementKind::SameShape:
112+ case RequirementKind::Conformance:
113+ case RequirementKind::Superclass:
114+ case RequirementKind::SameType:
115+ return lhs.getSecondType ().getPointer () ==
116+ rhs.getSecondType ().getPointer ();
117+
118+ case RequirementKind::Layout:
119+ return lhs.getLayoutConstraint () == rhs.getLayoutConstraint ();
120+ }
121+ llvm_unreachable (" Unhandled RequirementKind in switch" );
122+ }
44123
45124 // / Whether this requirement's types contain ErrorTypes.
46125 bool hasError () const ;
0 commit comments