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