1
+ // ===--- PropertyRelations.cpp - Relations between property rules ---------===//
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
+ #include " swift/AST/Type.h"
14
+ #include " llvm/Support/raw_ostream.h"
15
+ #include < algorithm>
16
+ #include " RewriteSystem.h"
17
+
18
+ using namespace swift ;
19
+ using namespace rewriting ;
20
+
21
+ RewriteSystem::Relation
22
+ RewriteSystem::getRelation (unsigned index) const {
23
+ return Relations[index];
24
+ }
25
+
26
+ // / Record a relation that transforms the left hand side when it appears
27
+ // / at the end of a term to the right hand side. Returns the relation ID,
28
+ // / which can be passed to RewriteStep::forRelation().
29
+ unsigned RewriteSystem::recordRelation (Term lhs, Term rhs) {
30
+ auto key = std::make_pair (lhs, rhs);
31
+ auto found = RelationMap.find (key);
32
+ if (found != RelationMap.end ())
33
+ return found->second ;
34
+
35
+ unsigned index = Relations.size ();
36
+ Relations.push_back (key);
37
+ auto inserted = RelationMap.insert (std::make_pair (key, index));
38
+ assert (inserted.second );
39
+ (void ) inserted;
40
+
41
+ return index;
42
+ }
43
+
44
+ // / Given a left-hand side symbol [p1] and a right-hand side symbol
45
+ // / [p2], record a relation ([p1].[p2] => [p1]), which denotes that
46
+ // / the property p1 implies the property p2.
47
+ // /
48
+ // / An example is a superclass requirement that implies a layout
49
+ // / requirement.
50
+ unsigned RewriteSystem::recordRelation (Symbol lhsProperty,
51
+ Symbol rhsProperty) {
52
+ assert (lhsProperty.isProperty ());
53
+ assert (rhsProperty.isProperty ());
54
+
55
+ MutableTerm lhsTerm;
56
+ lhsTerm.add (lhsProperty);
57
+ lhsTerm.add (rhsProperty);
58
+
59
+ MutableTerm rhsTerm;
60
+ rhsTerm.add (lhsProperty);
61
+
62
+ // Record a relation ([p1].[p2] => [p1]).
63
+ return recordRelation (
64
+ Term::get (lhsTerm, Context),
65
+ Term::get (rhsTerm, Context));
66
+ }
67
+
68
+ // / Record a relation ([concrete: C].[P] => [concrete: C : P])
69
+ // / or ([superclass: C].[P] => [concrete: C : P]) which combines a
70
+ // / concrete type symbol (or a superclass symbol) with a protocol
71
+ // / symbol to form a single a concrete conformance symbol.
72
+ unsigned RewriteSystem::recordConcreteConformanceRelation (
73
+ Symbol concreteSymbol, Symbol protocolSymbol,
74
+ Symbol concreteConformanceSymbol) {
75
+ assert (protocolSymbol.getKind () == Symbol::Kind::Protocol);
76
+ assert (protocolSymbol.getProtocol () ==
77
+ concreteConformanceSymbol.getProtocol ());
78
+ assert (concreteSymbol.getKind () == Symbol::Kind::Superclass ||
79
+ concreteSymbol.getKind () == Symbol::Kind::ConcreteType);
80
+
81
+ MutableTerm lhsTerm;
82
+ lhsTerm.add (concreteSymbol);
83
+ lhsTerm.add (protocolSymbol);
84
+
85
+ MutableTerm rhsTerm;
86
+ rhsTerm.add (concreteConformanceSymbol);
87
+
88
+ return recordRelation (
89
+ Term::get (lhsTerm, Context),
90
+ Term::get (rhsTerm, Context));
91
+ }
92
+
93
+ // / Record a relation ([concrete: C : P].[P:X].[concrete: C.X] =>
94
+ // / [concrete: C : P].[P:X]) which "concretizes" a nested type C.X of a
95
+ // / type parameter conforming to P known to equal the concrete type C.
96
+ unsigned RewriteSystem::recordConcreteTypeWitnessRelation (
97
+ Symbol concreteConformanceSymbol,
98
+ Symbol associatedTypeSymbol,
99
+ Symbol typeWitnessSymbol) {
100
+ assert (concreteConformanceSymbol.getKind () ==
101
+ Symbol::Kind::ConcreteConformance);
102
+ assert (associatedTypeSymbol.getKind () ==
103
+ Symbol::Kind::AssociatedType);
104
+ assert (associatedTypeSymbol.getProtocols ().size () == 1 );
105
+ assert (concreteConformanceSymbol.getProtocol () ==
106
+ associatedTypeSymbol.getProtocols ()[0 ]);
107
+ assert (typeWitnessSymbol.getKind () == Symbol::Kind::ConcreteType);
108
+
109
+ MutableTerm rhsTerm;
110
+ rhsTerm.add (concreteConformanceSymbol);
111
+ rhsTerm.add (associatedTypeSymbol);
112
+
113
+ MutableTerm lhsTerm (rhsTerm);
114
+ lhsTerm.add (typeWitnessSymbol);
115
+
116
+ return recordRelation (
117
+ Term::get (lhsTerm, Context),
118
+ Term::get (rhsTerm, Context));
119
+ }
120
+
121
+ // / Record a relation ([concrete: C : P].[P:X].[concrete: C] =>
122
+ // / [concrete: C : P].[P:X]) which "ties off" a nested type C.X that is
123
+ // / equivalent to C.
124
+ unsigned RewriteSystem::recordSameTypeWitnessRelation (
125
+ Symbol concreteConformanceSymbol,
126
+ Symbol associatedTypeSymbol) {
127
+ assert (concreteConformanceSymbol.getKind () ==
128
+ Symbol::Kind::ConcreteConformance);
129
+ assert (associatedTypeSymbol.getKind () ==
130
+ Symbol::Kind::AssociatedType);
131
+
132
+ MutableTerm rhsTerm;
133
+ rhsTerm.add (concreteConformanceSymbol);
134
+
135
+ auto concreteSymbol = Symbol::forConcreteType (
136
+ concreteConformanceSymbol.getConcreteType (),
137
+ concreteConformanceSymbol.getSubstitutions (),
138
+ Context);
139
+ MutableTerm lhsTerm (rhsTerm);
140
+ lhsTerm.add (associatedTypeSymbol);
141
+ lhsTerm.add (concreteSymbol);
142
+
143
+ return recordRelation (
144
+ Term::get (lhsTerm, Context),
145
+ Term::get (rhsTerm, Context));
146
+ }
0 commit comments