Skip to content

Commit c4fa057

Browse files
committed
Switch TypeJoin over to being a CanTypeVisitor.
1 parent 16cae69 commit c4fa057

File tree

2 files changed

+63
-64
lines changed

2 files changed

+63
-64
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 & 59 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,115 +75,124 @@ struct TypeJoin : TypeVisitor<TypeJoin, Type> {
8575
}
8676
};
8777

88-
Type TypeJoin::getSuperclassJoin(Type first, Type second) {
78+
CanType TypeJoin::getSuperclassJoin(CanType first, CanType second) {
8979
if (!first->mayHaveSuperclass() || !second->mayHaveSuperclass())
9080
return first->getASTContext().TheAnyType;
9181

9282
/// Walk the superclasses of `first` looking for `second`. Record them
9383
/// for our second step.
9484
llvm::SmallPtrSet<CanType, 8> superclassesOfFirst;
95-
CanType canSecond = second->getCanonicalType();
9685
for (Type super = first; super; super = super->getSuperclass()) {
97-
CanType canSuper = super->getCanonicalType();
86+
auto canSuper = super->getCanonicalType();
9887

9988
// If we have found the second type, we're done.
100-
if (canSuper == canSecond)
101-
return super;
89+
if (canSuper == second)
90+
return canSuper;
10291

10392
superclassesOfFirst.insert(canSuper);
10493
}
10594

10695
// Look through the superclasses of second to determine if any were also
10796
// superclasses of first.
10897
for (Type super = second; super; super = super->getSuperclass()) {
109-
CanType canSuper = super->getCanonicalType();
98+
auto canSuper = super->getCanonicalType();
11099

111100
// If we found the first type, we're done.
112101
if (superclassesOfFirst.count(canSuper))
113-
return super;
102+
return canSuper;
114103
}
115104

116105
// There is no common superclass; we're done.
117106
return first->getASTContext().TheAnyType;
118107
}
119108

120-
Type TypeJoin::visitClassType(Type second) {
109+
CanType TypeJoin::visitClassType(CanType second) {
121110
return getSuperclassJoin(First, second);
122111
}
123112

124-
Type TypeJoin::visitBoundGenericClassType(Type second) {
113+
CanType TypeJoin::visitBoundGenericClassType(CanType second) {
125114
return getSuperclassJoin(First, second);
126115
}
127116

128-
Type TypeJoin::visitArchetypeType(Type second) {
117+
CanType TypeJoin::visitArchetypeType(CanType second) {
129118
return getSuperclassJoin(First, second);
130119
}
131120

132-
Type TypeJoin::visitDynamicSelfType(Type second) {
121+
CanType TypeJoin::visitDynamicSelfType(CanType second) {
133122
return getSuperclassJoin(First, second);
134123
}
135124

136-
Type TypeJoin::visitMetatypeType(Type second) {
125+
CanType TypeJoin::visitMetatypeType(CanType second) {
137126
if (First->getKind() != second->getKind())
138127
return First->getASTContext().TheAnyType;
139128

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();
142133

143134
auto joinInstance = join(firstInstance, secondInstance);
144135

145136
if (!joinInstance)
146137
return First->getASTContext().TheAnyType;
147138

148-
return MetatypeType::get(joinInstance);
139+
return MetatypeType::get(joinInstance)->getCanonicalType();
149140
}
150141

151-
Type TypeJoin::visitExistentialMetatypeType(Type second) {
142+
CanType TypeJoin::visitExistentialMetatypeType(CanType second) {
152143
if (First->getKind() != second->getKind())
153144
return First->getASTContext().TheAnyType;
154145

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();
157150

158151
auto joinInstance = join(firstInstance, secondInstance);
159152

160153
if (!joinInstance)
161154
return First->getASTContext().TheAnyType;
162155

163-
return ExistentialMetatypeType::get(joinInstance);
156+
return ExistentialMetatypeType::get(joinInstance)->getCanonicalType();
164157
}
165158

166-
Type TypeJoin::visitBoundGenericEnumType(Type second) {
159+
CanType TypeJoin::visitBoundGenericEnumType(CanType second) {
167160
if (First->getKind() != second->getKind())
168161
return First->getASTContext().TheAnyType;
169162

170163
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);
173166
if (otk1 == OTK_Optional || otk2 == OTK_Optional) {
167+
auto canFirst = firstObject->getCanonicalType();
168+
auto canSecond = secondObject->getCanonicalType();
169+
174170
// 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);
177173
// FIXME: More general joins of enums need to be handled.
178174
if (!unwrappedJoin)
179175
return First->getASTContext().TheAnyType;
180176

181-
return OptionalType::get(unwrappedJoin);
177+
return OptionalType::get(unwrappedJoin)->getCanonicalType();
182178
}
183179

184180
// FIXME: More general joins of enums need to be handled.
185181
return First->getASTContext().TheAnyType;
186182
}
187183

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!");
191186

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()));
194193

195-
Type Type::join(Type type1, Type type2) {
196-
assert(type1 && type2 && "Unexpected null type!");
194+
return Type();
195+
}
197196

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

0 commit comments

Comments
 (0)