Hi,
I don't see the bug. Look at this example:
| a b ha hb |
a := Object new.
b := Object new.
ha := a identityHash.
hb := b identityHash.
a becomeForward: b copyHash: true.
{ ha = hb. a == b. a identityHash == ha }. #(false true true)
So here a has indeed become b; all references to a are now references to b. But b's identityHash is now that of what a's was before the become. That's as specified.
Let's extend the example:
| a b ha hb is |
a := Object new.
b := Object new.
is := IdentitySet new.
is add: b.
ha := a identityHash.
hb := b identityHash.
a becomeForward: b copyHash: true.
{ ha = hb. a == b. a identityHash == ha. is includes: a }. #(false true true false)
This is correct; a (and b) is (are) now in the set at the old hash of b, which is no longer its hash. So...
| a b ha hb is |
a := Object new.
b := Object new.
is := IdentitySet new.
is add: b.
ha := a identityHash.
hb := b identityHash.
a becomeForward: b copyHash: true.
is rehash.
{ ha = hb. a == b. a identityHash == ha. is includes: a }. #(false true true true)
Good.
So instead what you might have meant to say was
| a b ha hb is |
a := Object new.
b := Object new.
is := IdentitySet new.
is add: a.
ha := a identityHash.
hb := b identityHash.
a becomeForward: b copyHash: true.
{ ha = hb. a == b. a identityHash == ha. is includes: a }. #(false true true true)
That looks good.