Fix the implementation of TypeVariable.hashCode()
#260
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.
Previous implementation of this method was wrong in case the type variable has an implicit bound of
Object
. To conserve memory,TypeVariable
stores the information whether the first bound is implicitlyObject
as the most significant bit of thehash
field, which also serves as a hash code cache.Specifically, if the type variable has an implicit
Object
bound, the MSB is set to1
, otherwise it is set to0
. When it's1
, thehashCode()
method used to return one value when first called and a different value for subsequent calls.This is because the beginning of
hashCode()
looks like this:When the hash code has already been computed, the method returns the stored value, properly masked to always have a
0
at the MSB. When the hash code has not been computed yet, it is computed, cached and returned. The code for caching the computed value and returning it used to look like this:That is partly wrong. The hash code is cached correctly, but then the whole value of
this.hash
is returned, including the non-masked MSB, which is1
when the first bound is implicitlyObject
.This commit splits the two operations (storing into cache and returning) so that the
hashCode()
method always returns a properly masked value: