Skip to content

Commit 37cb6a8

Browse files
committed
Make Type::join return Any by default.
For the moment, update the sole caller to not infer Any in cases where neither argument was Any. This is in part because not all the cases are handled here and the result of inferring Any will be to miss appropriate bindings in certain cases. It is also in part because by inferring Any we may end up deferring diagnostics until later in a function, which may result in very hard to understand diagnostics for users. This will be revisted once all the cases are properly handled here.
1 parent 6fcb830 commit 37cb6a8

File tree

3 files changed

+25
-33
lines changed

3 files changed

+25
-33
lines changed

lib/AST/TypeJoinMeet.cpp

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ struct TypeJoin : TypeVisitor<TypeJoin, Type> {
4848
Type visitType(Type second) {
4949
// FIXME: Implement all the visitors.
5050
// llvm_unreachable("Unimplemented type visitor!");
51-
// return First->getASTContext().TheAnyType;
52-
return nullptr;
51+
return First->getASTContext().TheAnyType;
5352
}
5453

5554
public:
@@ -90,9 +89,8 @@ Type TypeJoin::getSuperclassJoin(Type first, Type second) {
9089
if (!first || !second)
9190
return TypeJoin::join(first, second);
9291

93-
// FIXME: Return Any
9492
if (!first->mayHaveSuperclass() || !second->mayHaveSuperclass())
95-
return nullptr;
93+
return first->getASTContext().TheAnyType;
9694

9795
/// Walk the superclasses of `first` looking for `second`. Record them
9896
/// for our second step.
@@ -102,7 +100,8 @@ Type TypeJoin::getSuperclassJoin(Type first, Type second) {
102100
CanType canSuper = super->getCanonicalType();
103101

104102
// If we have found the second type, we're done.
105-
if (canSuper == canSecond) return super;
103+
if (canSuper == canSecond)
104+
return super;
106105

107106
superclassesOfFirst.insert(canSuper);
108107
}
@@ -113,12 +112,12 @@ Type TypeJoin::getSuperclassJoin(Type first, Type second) {
113112
CanType canSuper = super->getCanonicalType();
114113

115114
// If we found the first type, we're done.
116-
if (superclassesOfFirst.count(canSuper)) return super;
115+
if (superclassesOfFirst.count(canSuper))
116+
return super;
117117
}
118118

119-
// FIXME: Return Any
120119
// There is no common superclass; we're done.
121-
return nullptr;
120+
return first->getASTContext().TheAnyType;
122121
}
123122

124123
Type TypeJoin::visitClassType(Type second) {
@@ -138,47 +137,38 @@ Type TypeJoin::visitDynamicSelfType(Type second) {
138137
}
139138

140139
Type TypeJoin::visitMetatypeType(Type second) {
141-
assert(!First->mayHaveSuperclass() && !second->mayHaveSuperclass());
142-
143-
// FIXME: Return Any
144140
if (First->getKind() != second->getKind())
145-
return nullptr;
141+
return First->getASTContext().TheAnyType;
146142

147143
auto firstInstance = First->castTo<AnyMetatypeType>()->getInstanceType();
148144
auto secondInstance = second->castTo<AnyMetatypeType>()->getInstanceType();
149145

150146
auto joinInstance = join(firstInstance, secondInstance);
151147

152-
// FIXME: Return Any
153148
if (!joinInstance)
154-
return nullptr;
149+
return First->getASTContext().TheAnyType;
155150

156151
return MetatypeType::get(joinInstance);
157152
}
158153

159154
Type TypeJoin::visitExistentialMetatypeType(Type second) {
160-
assert(!First->mayHaveSuperclass() && !second->mayHaveSuperclass());
161-
162-
// FIXME: Return Any
163155
if (First->getKind() != second->getKind())
164-
return nullptr;
156+
return First->getASTContext().TheAnyType;
165157

166158
auto firstInstance = First->castTo<AnyMetatypeType>()->getInstanceType();
167159
auto secondInstance = second->castTo<AnyMetatypeType>()->getInstanceType();
168160

169161
auto joinInstance = join(firstInstance, secondInstance);
170162

171-
// FIXME: Return Any
172163
if (!joinInstance)
173-
return nullptr;
164+
return First->getASTContext().TheAnyType;
174165

175166
return ExistentialMetatypeType::get(joinInstance);
176167
}
177168

178169
Type TypeJoin::visitBoundGenericEnumType(Type second) {
179-
// FIXME: Return Any
180170
if (First->getKind() != second->getKind())
181-
return nullptr;
171+
return First->getASTContext().TheAnyType;
182172

183173
OptionalTypeKind otk1, otk2;
184174
Type objectType1 = First->getAnyOptionalObjectType(otk1);
@@ -188,15 +178,14 @@ Type TypeJoin::visitBoundGenericEnumType(Type second) {
188178
Type unwrappedJoin = join(objectType1 ? objectType1 : First,
189179
objectType2 ? objectType2 : second);
190180
// FIXME: More general joins of enums need to be handled.
191-
if (!unwrappedJoin) return nullptr;
181+
if (!unwrappedJoin)
182+
return First->getASTContext().TheAnyType;
192183

193184
return OptionalType::get(unwrappedJoin);
194185
}
195186

196-
// FIXME: More general joins of enums need to be handled, and
197-
// then Any should be returned when there is no better
198-
// choice.
199-
return nullptr;
187+
// FIXME: More general joins of enums need to be handled.
188+
return First->getASTContext().TheAnyType;
200189
}
201190

202191
Type TypeJoin::visitOptionalType(Type second) {

lib/Sema/ConstraintSystem.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2644,10 +2644,15 @@ class ConstraintSystem {
26442644
auto &lastBinding = Bindings[*lastSupertypeIndex];
26452645
auto lastType = lastBinding.BindingType->getWithoutSpecifierType();
26462646
auto bindingType = binding.BindingType->getWithoutSpecifierType();
2647-
if (auto join = Type::join(lastType, bindingType)) {
2648-
// Replace the last supertype binding with the join. We're done.
2649-
lastBinding.BindingType = join;
2650-
return;
2647+
auto join = Type::join(lastType, bindingType);
2648+
if (join) {
2649+
auto anyType = join->getASTContext().TheAnyType;
2650+
if (!join->isEqual(anyType) || lastType->isEqual(anyType) ||
2651+
bindingType->isEqual(anyType)) {
2652+
// Replace the last supertype binding with the join. We're done.
2653+
lastBinding.BindingType = join;
2654+
return;
2655+
}
26512656
}
26522657
}
26532658

test/Constraints/array_literal.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,6 @@ struct Beef : Pear {}
304304

305305
let routerFruit = Company(
306306
routes: [
307-
// FIXME: implement join() for existentials
308-
// expected-error@+1 {{cannot convert value of type '() -> Tomato.Type' to expected element type '() -> _'}}
309307
{ () -> Tomato.Type in
310308
_ = ()
311309
return Chicken.self

0 commit comments

Comments
 (0)