Skip to content

Commit 5352d64

Browse files
authored
Merge pull request #12087 from rudkx/join
Switch TypeJoin over to being a CanTypeVisitor.
2 parents 952ca82 + c4fa057 commit 5352d64

File tree

2 files changed

+63
-67
lines changed

2 files changed

+63
-67
lines changed

include/swift/AST/Type.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -356,11 +356,11 @@ class Type {
356356
/// join of D and A (or D and B, or D and C) because there is no common
357357
/// superclass. One would have to jump to an existential (e.g., \c AnyObject)
358358
/// to find a common type.
359-
///
360-
/// \returns the join of the two types, if there is a concrete type that can
361-
/// express the join, or a null type if the only join would be a more-general
362-
/// existential type (e.g., \c Any).
363-
static Type join(Type type1, Type type2);
359+
///
360+
/// \returns the join of the two types, if there is a concrete type
361+
/// that can express the join, or Any if the only join would be a
362+
/// more-general existential type
363+
static Type join(Type first, Type second);
364364

365365
private:
366366
// Direct comparison is disabled for types, because they may not be canonical.

lib/AST/TypeJoinMeet.cpp

Lines changed: 58 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
//
1616
//===----------------------------------------------------------------------===//
1717
#include "swift/AST/ASTContext.h"
18+
#include "swift/AST/CanTypeVisitor.h"
1819
#include "swift/AST/Decl.h"
1920
#include "swift/AST/Type.h"
20-
#include "swift/AST/TypeVisitor.h"
2121
#include "swift/AST/Types.h"
2222
#include "llvm/ADT/SmallPtrSet.h"
2323
using namespace swift;
@@ -26,43 +26,33 @@ using namespace swift;
2626
// used for optimizing away extra exploratory work in the constraint
2727
// solver. It should eventually encompass all of the subtyping rules
2828
// of the language.
29-
struct TypeJoin : TypeVisitor<TypeJoin, Type> {
30-
Type First;
29+
struct TypeJoin : CanTypeVisitor<TypeJoin, CanType> {
30+
CanType First;
3131

32-
TypeJoin(Type First) : First(First) {
32+
TypeJoin(CanType First) : First(First) {
3333
assert(First && "Unexpected null type!");
3434
}
3535

36-
static Type getSuperclassJoin(Type first, Type second);
36+
static CanType getSuperclassJoin(CanType first, CanType second);
3737

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);
4545

46-
Type visitOptionalType(Type second);
46+
CanType visitOptionalType(CanType second);
4747

48-
Type visitType(Type second) {
48+
CanType visitType(CanType second) {
4949
// FIXME: Implement all the visitors.
5050
// llvm_unreachable("Unimplemented type visitor!");
5151
return First->getASTContext().TheAnyType;
5252
}
5353

5454
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) {
6656
assert(!first->hasTypeVariable() && !second->hasTypeVariable() &&
6757
"Cannot compute join of types involving type variables");
6858

@@ -72,7 +62,7 @@ struct TypeJoin : TypeVisitor<TypeJoin, Type> {
7262
"Expected simple type!");
7363

7464
// If the types are equivalent, the join is obvious.
75-
if (first->isEqual(second))
65+
if (first == second)
7666
return first;
7767

7868
// Until we handle all the combinations of joins, we need to make
@@ -85,118 +75,124 @@ struct TypeJoin : TypeVisitor<TypeJoin, Type> {
8575
}
8676
};
8777

88-
Type TypeJoin::getSuperclassJoin(Type first, Type second) {
89-
if (!first || !second)
90-
return TypeJoin::join(first, second);
91-
78+
CanType TypeJoin::getSuperclassJoin(CanType first, CanType second) {
9279
if (!first->mayHaveSuperclass() || !second->mayHaveSuperclass())
9380
return first->getASTContext().TheAnyType;
9481

9582
/// Walk the superclasses of `first` looking for `second`. Record them
9683
/// for our second step.
9784
llvm::SmallPtrSet<CanType, 8> superclassesOfFirst;
98-
CanType canSecond = second->getCanonicalType();
9985
for (Type super = first; super; super = super->getSuperclass()) {
100-
CanType canSuper = super->getCanonicalType();
86+
auto canSuper = super->getCanonicalType();
10187

10288
// If we have found the second type, we're done.
103-
if (canSuper == canSecond)
104-
return super;
89+
if (canSuper == second)
90+
return canSuper;
10591

10692
superclassesOfFirst.insert(canSuper);
10793
}
10894

10995
// Look through the superclasses of second to determine if any were also
11096
// superclasses of first.
11197
for (Type super = second; super; super = super->getSuperclass()) {
112-
CanType canSuper = super->getCanonicalType();
98+
auto canSuper = super->getCanonicalType();
11399

114100
// If we found the first type, we're done.
115101
if (superclassesOfFirst.count(canSuper))
116-
return super;
102+
return canSuper;
117103
}
118104

119105
// There is no common superclass; we're done.
120106
return first->getASTContext().TheAnyType;
121107
}
122108

123-
Type TypeJoin::visitClassType(Type second) {
109+
CanType TypeJoin::visitClassType(CanType second) {
124110
return getSuperclassJoin(First, second);
125111
}
126112

127-
Type TypeJoin::visitBoundGenericClassType(Type second) {
113+
CanType TypeJoin::visitBoundGenericClassType(CanType second) {
128114
return getSuperclassJoin(First, second);
129115
}
130116

131-
Type TypeJoin::visitArchetypeType(Type second) {
117+
CanType TypeJoin::visitArchetypeType(CanType second) {
132118
return getSuperclassJoin(First, second);
133119
}
134120

135-
Type TypeJoin::visitDynamicSelfType(Type second) {
121+
CanType TypeJoin::visitDynamicSelfType(CanType second) {
136122
return getSuperclassJoin(First, second);
137123
}
138124

139-
Type TypeJoin::visitMetatypeType(Type second) {
125+
CanType TypeJoin::visitMetatypeType(CanType second) {
140126
if (First->getKind() != second->getKind())
141127
return First->getASTContext().TheAnyType;
142128

143-
auto firstInstance = First->castTo<AnyMetatypeType>()->getInstanceType();
144-
auto secondInstance = second->castTo<AnyMetatypeType>()->getInstanceType();
129+
auto firstInstance =
130+
First->castTo<AnyMetatypeType>()->getInstanceType()->getCanonicalType();
131+
auto secondInstance =
132+
second->castTo<AnyMetatypeType>()->getInstanceType()->getCanonicalType();
145133

146134
auto joinInstance = join(firstInstance, secondInstance);
147135

148136
if (!joinInstance)
149137
return First->getASTContext().TheAnyType;
150138

151-
return MetatypeType::get(joinInstance);
139+
return MetatypeType::get(joinInstance)->getCanonicalType();
152140
}
153141

154-
Type TypeJoin::visitExistentialMetatypeType(Type second) {
142+
CanType TypeJoin::visitExistentialMetatypeType(CanType second) {
155143
if (First->getKind() != second->getKind())
156144
return First->getASTContext().TheAnyType;
157145

158-
auto firstInstance = First->castTo<AnyMetatypeType>()->getInstanceType();
159-
auto secondInstance = second->castTo<AnyMetatypeType>()->getInstanceType();
146+
auto firstInstance =
147+
First->castTo<AnyMetatypeType>()->getInstanceType()->getCanonicalType();
148+
auto secondInstance =
149+
second->castTo<AnyMetatypeType>()->getInstanceType()->getCanonicalType();
160150

161151
auto joinInstance = join(firstInstance, secondInstance);
162152

163153
if (!joinInstance)
164154
return First->getASTContext().TheAnyType;
165155

166-
return ExistentialMetatypeType::get(joinInstance);
156+
return ExistentialMetatypeType::get(joinInstance)->getCanonicalType();
167157
}
168158

169-
Type TypeJoin::visitBoundGenericEnumType(Type second) {
159+
CanType TypeJoin::visitBoundGenericEnumType(CanType second) {
170160
if (First->getKind() != second->getKind())
171161
return First->getASTContext().TheAnyType;
172162

173163
OptionalTypeKind otk1, otk2;
174-
Type objectType1 = First->getAnyOptionalObjectType(otk1);
175-
Type objectType2 = second->getAnyOptionalObjectType(otk2);
164+
auto firstObject = First->getAnyOptionalObjectType(otk1);
165+
auto secondObject = second->getAnyOptionalObjectType(otk2);
176166
if (otk1 == OTK_Optional || otk2 == OTK_Optional) {
167+
auto canFirst = firstObject->getCanonicalType();
168+
auto canSecond = secondObject->getCanonicalType();
169+
177170
// Compute the join of the unwrapped type. If there is none, we're done.
178-
Type unwrappedJoin = join(objectType1 ? objectType1 : First,
179-
objectType2 ? objectType2 : second);
171+
auto unwrappedJoin =
172+
join(canFirst ? canFirst : First, canSecond ? canSecond : second);
180173
// FIXME: More general joins of enums need to be handled.
181174
if (!unwrappedJoin)
182175
return First->getASTContext().TheAnyType;
183176

184-
return OptionalType::get(unwrappedJoin);
177+
return OptionalType::get(unwrappedJoin)->getCanonicalType();
185178
}
186179

187180
// FIXME: More general joins of enums need to be handled.
188181
return First->getASTContext().TheAnyType;
189182
}
190183

191-
Type TypeJoin::visitOptionalType(Type second) {
192-
auto canFirst = First->getCanonicalType();
193-
auto canSecond = second->getCanonicalType();
184+
Type Type::join(Type first, Type second) {
185+
assert(first && second && "Unexpected null type!");
194186

195-
return TypeJoin::join(canFirst, canSecond);
196-
}
187+
if (!first || !second) {
188+
if (first)
189+
return Type(ErrorType::get(first->getASTContext()));
197190

198-
Type Type::join(Type type1, Type type2) {
199-
assert(type1 && type2 && "Unexpected null type!");
191+
if (second)
192+
return Type(ErrorType::get(second->getASTContext()));
193+
194+
return Type();
195+
}
200196

201-
return TypeJoin::join(type1, type2);
197+
return TypeJoin::join(first->getCanonicalType(), second->getCanonicalType());
202198
}

0 commit comments

Comments
 (0)