📑

[Bug #22064] 特定のケースで Set の同一性が壊れるバグ報告

に公開

[Bug #22064] GC compaction breaks compare-by-identity sets

  • Set#compare_by_identity したオブジェクトで GC.verify_compaction_references(expand_heap: true, toward: :empty) を実行すると Set のオブジェクトの同一性が壊れるというバグ報告
set = Set.new.compare_by_identity

o = Object.new
set.add(o)

puts set.include?(o)
# => true

# これの実行後だと set の同一性が壊れる
GC.verify_compaction_references(expand_heap: true, toward: :empty)

puts set.include?(o)
# 期待する挙動 => true
# 実際の挙動   => false
  • Set#compare_by_identity では hash 値にアドレスを使用するので GC.verify_compaction_references でアドレスが変わってしまうと壊れる、みたいな感じみたい?
  • この不具合は開発版の Ruby 4.1-dev で修正済み
set = Set.new.compare_by_identity

o = Object.new
set.add(o)

puts set.include?(o)
# => true

# これの実行後だと set の同一性が壊れる
GC.verify_compaction_references(expand_heap: true, toward: :empty)

puts set.include?(o)
# Ruby 4.0 => false
# Ruby 4.1 => true
GitHubで編集を提案

Discussion