Skip to content

Represent unresolved superclass as Ancestor::Partial#651

Open
Morriar wants to merge 3 commits intomainfrom
at-unresolved-superclass-partial-ancestor
Open

Represent unresolved superclass as Ancestor::Partial#651
Morriar wants to merge 3 commits intomainfrom
at-unresolved-superclass-partial-ancestor

Conversation

@Morriar
Copy link
Contributor

@Morriar Morriar commented Mar 6, 2026

Summary

  • When class Foo < Bar is indexed and Bar is never defined, Foo's ancestor chain was silently falling back to [Foo, Object, BasicObject] (partial) — Bar was completely absent. This is inconsistent with how unresolved mixins are handled, which push Ancestor::Partial(name_id) as a placeholder.
  • Fixed by applying the same approach for superclasses: when no resolved parent is found but an unresolved reference exists, linearize_parent_class now returns Ancestors::Partial([Ancestor::Partial(name_id)]) instead of falling back to Object's chain.
  • Updated assert_ancestors_eq to compare by name string, so it works uniformly for both Complete and Partial ancestor entries (previously panicked on Ancestors::Partial).
  • Added Class#superclass_name Ruby API that returns the unresolved superclass name as written in source, or nil when resolved or absent.

Test plan

  • New Rust test: unresolved_superclass_is_represented_as_partial_ancestor verifies class Foo < Bar yields ["Foo", "Bar"]
  • New Ruby tests: test_superclass_name_returns_nil_when_superclass_is_resolved and test_superclass_name_returns_name_when_superclass_is_unresolved
  • cargo test — all 380 tests pass
  • bundle exec ruby -Itest test/declaration_test.rb — all 23 tests pass
  • cargo clippy --all-targets -- -D warnings — clean

Morriar added 2 commits March 6, 2026 12:00
When a superclass reference is unresolved (e.g. `class Foo < Bar` where Bar
is never defined), the ancestor chain for Foo was silently falling back to
Object's chain with Ancestors::Partial state. Bar was completely absent from
the chain.

Mixins handle this consistently by pushing Ancestor::Partial(name_id) when
a mixin reference is unresolved. Apply the same approach for superclasses.

Also update assert_ancestors_eq to compare by name string so it works
uniformly for both Complete and Partial ancestor entries.
Adds rdx_class_superclass_name FFI function that walks the ancestor chain
looking for an Ancestor::Partial entry and reconstructs its fully-qualified
name string (handling ::Foo and Foo::Bar forms).

Exposed at the Ruby level as Class#superclass_name, returning nil when the
superclass is resolved or absent.
@Morriar Morriar requested a review from a team as a code owner March 6, 2026 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant