Skip to content

Commit d34dec8

Browse files
committed
SimplifyBuiltin: use dynamic cast utilities in folding metatype comparisons
1 parent 308b5f9 commit d34dec8

File tree

1 file changed

+11
-51
lines changed

1 file changed

+11
-51
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBuiltin.swift

Lines changed: 11 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)