15
15
//
16
16
// ===----------------------------------------------------------------------===//
17
17
#include " swift/AST/ASTContext.h"
18
+ #include " swift/AST/CanTypeVisitor.h"
18
19
#include " swift/AST/Decl.h"
19
20
#include " swift/AST/Type.h"
20
- #include " swift/AST/TypeVisitor.h"
21
21
#include " swift/AST/Types.h"
22
22
#include " llvm/ADT/SmallPtrSet.h"
23
23
using namespace swift ;
@@ -26,43 +26,33 @@ using namespace swift;
26
26
// used for optimizing away extra exploratory work in the constraint
27
27
// solver. It should eventually encompass all of the subtyping rules
28
28
// of the language.
29
- struct TypeJoin : TypeVisitor <TypeJoin, Type > {
30
- Type First;
29
+ struct TypeJoin : CanTypeVisitor <TypeJoin, CanType > {
30
+ CanType First;
31
31
32
- TypeJoin (Type First) : First(First) {
32
+ TypeJoin (CanType First) : First(First) {
33
33
assert (First && " Unexpected null type!" );
34
34
}
35
35
36
- static Type getSuperclassJoin (Type first, Type second);
36
+ static CanType getSuperclassJoin (CanType first, CanType second);
37
37
38
- Type visitClassType (Type second);
39
- Type visitBoundGenericClassType (Type second);
40
- Type visitArchetypeType (Type second);
41
- Type visitDynamicSelfType (Type second);
42
- Type visitMetatypeType (Type second);
43
- Type visitExistentialMetatypeType (Type second);
44
- Type visitBoundGenericEnumType (Type second);
38
+ CanType visitClassType (CanType second);
39
+ CanType visitBoundGenericClassType (CanType second);
40
+ CanType visitArchetypeType (CanType second);
41
+ CanType visitDynamicSelfType (CanType second);
42
+ CanType visitMetatypeType (CanType second);
43
+ CanType visitExistentialMetatypeType (CanType second);
44
+ CanType visitBoundGenericEnumType (CanType second);
45
45
46
- Type visitOptionalType (Type second);
46
+ CanType visitOptionalType (CanType second);
47
47
48
- Type visitType (Type second) {
48
+ CanType visitType (CanType second) {
49
49
// FIXME: Implement all the visitors.
50
50
// llvm_unreachable("Unimplemented type visitor!");
51
51
return First->getASTContext ().TheAnyType ;
52
52
}
53
53
54
54
public:
55
- static Type join (Type first, Type second) {
56
- if (!first || !second) {
57
- if (first)
58
- return ErrorType::get (first->getASTContext ());
59
-
60
- if (second)
61
- return ErrorType::get (second->getASTContext ());
62
-
63
- return Type ();
64
- }
65
-
55
+ static CanType join (CanType first, CanType second) {
66
56
assert (!first->hasTypeVariable () && !second->hasTypeVariable () &&
67
57
" Cannot compute join of types involving type variables" );
68
58
@@ -72,7 +62,7 @@ struct TypeJoin : TypeVisitor<TypeJoin, Type> {
72
62
" Expected simple type!" );
73
63
74
64
// If the types are equivalent, the join is obvious.
75
- if (first-> isEqual ( second) )
65
+ if (first == second)
76
66
return first;
77
67
78
68
// Until we handle all the combinations of joins, we need to make
@@ -85,115 +75,124 @@ struct TypeJoin : TypeVisitor<TypeJoin, Type> {
85
75
}
86
76
};
87
77
88
- Type TypeJoin::getSuperclassJoin (Type first, Type second) {
78
+ CanType TypeJoin::getSuperclassJoin (CanType first, CanType second) {
89
79
if (!first->mayHaveSuperclass () || !second->mayHaveSuperclass ())
90
80
return first->getASTContext ().TheAnyType ;
91
81
92
82
// / Walk the superclasses of `first` looking for `second`. Record them
93
83
// / for our second step.
94
84
llvm::SmallPtrSet<CanType, 8 > superclassesOfFirst;
95
- CanType canSecond = second->getCanonicalType ();
96
85
for (Type super = first; super; super = super->getSuperclass ()) {
97
- CanType canSuper = super->getCanonicalType ();
86
+ auto canSuper = super->getCanonicalType ();
98
87
99
88
// If we have found the second type, we're done.
100
- if (canSuper == canSecond )
101
- return super ;
89
+ if (canSuper == second )
90
+ return canSuper ;
102
91
103
92
superclassesOfFirst.insert (canSuper);
104
93
}
105
94
106
95
// Look through the superclasses of second to determine if any were also
107
96
// superclasses of first.
108
97
for (Type super = second; super; super = super->getSuperclass ()) {
109
- CanType canSuper = super->getCanonicalType ();
98
+ auto canSuper = super->getCanonicalType ();
110
99
111
100
// If we found the first type, we're done.
112
101
if (superclassesOfFirst.count (canSuper))
113
- return super ;
102
+ return canSuper ;
114
103
}
115
104
116
105
// There is no common superclass; we're done.
117
106
return first->getASTContext ().TheAnyType ;
118
107
}
119
108
120
- Type TypeJoin::visitClassType (Type second) {
109
+ CanType TypeJoin::visitClassType (CanType second) {
121
110
return getSuperclassJoin (First, second);
122
111
}
123
112
124
- Type TypeJoin::visitBoundGenericClassType (Type second) {
113
+ CanType TypeJoin::visitBoundGenericClassType (CanType second) {
125
114
return getSuperclassJoin (First, second);
126
115
}
127
116
128
- Type TypeJoin::visitArchetypeType (Type second) {
117
+ CanType TypeJoin::visitArchetypeType (CanType second) {
129
118
return getSuperclassJoin (First, second);
130
119
}
131
120
132
- Type TypeJoin::visitDynamicSelfType (Type second) {
121
+ CanType TypeJoin::visitDynamicSelfType (CanType second) {
133
122
return getSuperclassJoin (First, second);
134
123
}
135
124
136
- Type TypeJoin::visitMetatypeType (Type second) {
125
+ CanType TypeJoin::visitMetatypeType (CanType second) {
137
126
if (First->getKind () != second->getKind ())
138
127
return First->getASTContext ().TheAnyType ;
139
128
140
- auto firstInstance = First->castTo <AnyMetatypeType>()->getInstanceType ();
141
- auto secondInstance = second->castTo <AnyMetatypeType>()->getInstanceType ();
129
+ auto firstInstance =
130
+ First->castTo <AnyMetatypeType>()->getInstanceType ()->getCanonicalType ();
131
+ auto secondInstance =
132
+ second->castTo <AnyMetatypeType>()->getInstanceType ()->getCanonicalType ();
142
133
143
134
auto joinInstance = join (firstInstance, secondInstance);
144
135
145
136
if (!joinInstance)
146
137
return First->getASTContext ().TheAnyType ;
147
138
148
- return MetatypeType::get (joinInstance);
139
+ return MetatypeType::get (joinInstance)-> getCanonicalType () ;
149
140
}
150
141
151
- Type TypeJoin::visitExistentialMetatypeType (Type second) {
142
+ CanType TypeJoin::visitExistentialMetatypeType (CanType second) {
152
143
if (First->getKind () != second->getKind ())
153
144
return First->getASTContext ().TheAnyType ;
154
145
155
- auto firstInstance = First->castTo <AnyMetatypeType>()->getInstanceType ();
156
- auto secondInstance = second->castTo <AnyMetatypeType>()->getInstanceType ();
146
+ auto firstInstance =
147
+ First->castTo <AnyMetatypeType>()->getInstanceType ()->getCanonicalType ();
148
+ auto secondInstance =
149
+ second->castTo <AnyMetatypeType>()->getInstanceType ()->getCanonicalType ();
157
150
158
151
auto joinInstance = join (firstInstance, secondInstance);
159
152
160
153
if (!joinInstance)
161
154
return First->getASTContext ().TheAnyType ;
162
155
163
- return ExistentialMetatypeType::get (joinInstance);
156
+ return ExistentialMetatypeType::get (joinInstance)-> getCanonicalType () ;
164
157
}
165
158
166
- Type TypeJoin::visitBoundGenericEnumType (Type second) {
159
+ CanType TypeJoin::visitBoundGenericEnumType (CanType second) {
167
160
if (First->getKind () != second->getKind ())
168
161
return First->getASTContext ().TheAnyType ;
169
162
170
163
OptionalTypeKind otk1, otk2;
171
- Type objectType1 = First->getAnyOptionalObjectType (otk1);
172
- Type objectType2 = second->getAnyOptionalObjectType (otk2);
164
+ auto firstObject = First->getAnyOptionalObjectType (otk1);
165
+ auto secondObject = second->getAnyOptionalObjectType (otk2);
173
166
if (otk1 == OTK_Optional || otk2 == OTK_Optional) {
167
+ auto canFirst = firstObject->getCanonicalType ();
168
+ auto canSecond = secondObject->getCanonicalType ();
169
+
174
170
// Compute the join of the unwrapped type. If there is none, we're done.
175
- Type unwrappedJoin = join (objectType1 ? objectType1 : First,
176
- objectType2 ? objectType2 : second);
171
+ auto unwrappedJoin =
172
+ join (canFirst ? canFirst : First, canSecond ? canSecond : second);
177
173
// FIXME: More general joins of enums need to be handled.
178
174
if (!unwrappedJoin)
179
175
return First->getASTContext ().TheAnyType ;
180
176
181
- return OptionalType::get (unwrappedJoin);
177
+ return OptionalType::get (unwrappedJoin)-> getCanonicalType () ;
182
178
}
183
179
184
180
// FIXME: More general joins of enums need to be handled.
185
181
return First->getASTContext ().TheAnyType ;
186
182
}
187
183
188
- Type TypeJoin::visitOptionalType (Type second) {
189
- auto canFirst = First->getCanonicalType ();
190
- auto canSecond = second->getCanonicalType ();
184
+ Type Type::join (Type first, Type second) {
185
+ assert (first && second && " Unexpected null type!" );
191
186
192
- return join (canFirst, canSecond);
193
- }
187
+ if (!first || !second) {
188
+ if (first)
189
+ return Type (ErrorType::get (first->getASTContext ()));
190
+
191
+ if (second)
192
+ return Type (ErrorType::get (second->getASTContext ()));
194
193
195
- Type Type::join (Type type1, Type type2) {
196
- assert (type1 && type2 && " Unexpected null type! " );
194
+ return Type ();
195
+ }
197
196
198
- return TypeJoin::join (type1, type2 );
197
+ return TypeJoin::join (first-> getCanonicalType (), second-> getCanonicalType () );
199
198
}
0 commit comments