@@ -285,61 +285,21 @@ private func typesOfValuesAreEqual(_ lhs: Value, _ rhs: Value, in function: Func
285285 let typesAreExact = lhsExistential. metatype is MetatypeInst &&
286286 rhsExistential. metatype is MetatypeInst
287287
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
300291 }
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 {
305295 return false
306296 }
307- default :
308- break
309297 }
310298
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
344303 }
304+ return nil
345305}
0 commit comments