@@ -285,61 +285,21 @@ private func typesOfValuesAreEqual(_ lhs: Value, _ rhs: Value, in function: Func
285
285
let typesAreExact = lhsExistential. metatype is MetatypeInst &&
286
286
rhsExistential. metatype is MetatypeInst
287
287
288
- switch ( lhsTy. typeKind, rhsTy. typeKind) {
289
- case ( _, . unknown) , ( . unknown, _) :
290
- return nil
291
- case ( let leftKind, let rightKind) where leftKind != rightKind:
292
- // E.g. a function type is always different than a struct, regardless of what archetypes
293
- // the two types may contain.
294
- return false
295
- case ( . struct, . struct) , ( . enum, . enum) :
296
- // Two different structs/enums are always not equal, regardless of what archetypes
297
- // the two types may contain.
298
- if lhsTy. nominal != rhsTy. nominal {
299
- return false
288
+ if typesAreExact {
289
+ if lhsTy == rhsTy {
290
+ return true
300
291
}
301
- case ( . class, . class) :
302
- // In case of classes this only holds if we know the exact types.
303
- // Otherwise one class could be a sub-class of the other class.
304
- if typesAreExact && lhsTy. nominal != rhsTy. nominal {
292
+ // Comparing types of different classes which are in a sub-class relation is not handled by the
293
+ // cast optimizer (below).
294
+ if lhsTy. isClass && rhsTy. isClass && lhsTy. nominal != rhsTy. nominal {
305
295
return false
306
296
}
307
- default :
308
- break
309
297
}
310
298
311
- if !typesAreExact {
312
- // Types which e.g. come from type parameters may differ at runtime while the declared AST types are the same.
313
- return nil
314
- }
315
-
316
- if lhsTy. hasArchetype || rhsTy. hasArchetype {
317
- // We don't know anything about archetypes. They may be identical at runtime or not.
318
- // We could do something more sophisticated here, e.g. look at conformances. But for simplicity,
319
- // we are just conservative.
320
- return nil
321
- }
322
-
323
- // Generic ObjectiveC class, which are specialized for different NSObject types have different AST types
324
- // but the same runtime metatype.
325
- if lhsTy. isOrContainsObjectiveCClass || rhsTy. isOrContainsObjectiveCClass {
326
- return nil
327
- }
328
-
329
- return lhsTy == rhsTy
330
- }
331
-
332
- private extension Type {
333
- enum TypeKind {
334
- case `struct`, `class`, `enum`, tuple, function, unknown
335
- }
336
-
337
- var typeKind : TypeKind {
338
- if isStruct { return . struct }
339
- if isClass { return . class }
340
- if isEnum { return . enum }
341
- if isTuple { return . tuple }
342
- if isFunction { return . function }
343
- return . unknown
299
+ // If casting in either direction doesn't work, the types cannot be equal.
300
+ if !( canDynamicallyCast ( from: lhsTy, to: rhsTy, in: function, sourceTypeIsExact: typesAreExact) ?? true ) ||
301
+ !( canDynamicallyCast ( from: rhsTy, to: lhsTy, in: function, sourceTypeIsExact: typesAreExact) ?? true ) {
302
+ return false
344
303
}
304
+ return nil
345
305
}
0 commit comments