Don't generate unique type IDs for virtual metaclasses #11188
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Type IDs for virtual metaclasses can be generated through at least four ways:
Those IDs are unnecessary; because virtual types are not directly exposed in Crystal code, the
typeof
should behave identically whether its argument has a virtual type or not:That is,
x
's binary representation should beA.crystal_type_id
in the first case, not(B | A).crystal_type_id
. The variablex
is still allowed to have typeA+.class
instead ofA.class
, since the method lookup process is slightly different between the two, but the binary representation of virtual metaclass variables should be identical to non-virtual ones: a single type ID referring to the non-virtual dynamic type of that variable. This is similar to how non-metaclass objects never use virtual type IDs.is_a?(T.class)
(more specifically the LLVM function~match<T+.class>
) unconditionally checks for this virtual metaclass's type ID, which explains why there is awhen Foo+.crystal_type_id
branch in #11134. With the above change we could assert that this branch is redundant; the default implementation will suffice, since callingeach_concrete_type
on a virtual metaclass will yield its non-virtual counterpart.A blank source file generates unique IDs for
Exception+.class
,File::Error+.class
, andIO::Error+.class
. This PR makes rescue-expressions for those exception types marginally faster.