Repository navigation
Conversation
Allow `module Foo : singleton(Bar)` (optionally with type arguments, `singleton(Bar)[T]`) in addition to class instance and interface self types. The new syntax is represented by a new AST node, `RBS::AST::Declarations::Module::SingletonSelf`, so that existing consumers of `Module::Self` keep working unchanged. - parser: accept `singleton` `(` class_name `)` type_args? in `parse_module_self_types` - AST: add `Module::SingletonSelf` (C node generated from config.yml) and `#update` to `Module::Self`/`SingletonSelf` - environment: resolve type names and align type parameters of singleton self types through `#update` - docs: describe the syntax in docs/syntax.md Part of ruby#1334 (proposal 1). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`module Foo : singleton(Bar)` now contributes the singleton methods (and class instance variables) of `Bar` to the instance definition of `Foo`, the same way class instance self types contribute instance methods. - ancestor_builder: push `Definition::Ancestor::Singleton` (with the new `source` attribute) for singleton self types, and check for recursive ancestors through `singleton_ancestors`, consistent with the existing check for class instance self types - definition_builder: merge `build_singleton(Bar)` into the module definition; methods defined in the module take precedence - errors: `NoSelfTypeFoundError.check!` rejects `singleton(_Interface)` Method types are taken as written: `instance`/`class`/`self` in the singleton methods are not rewritten, consistent with class instance self types. Resolving them is left to the type checker. Part of ruby#1334 (proposal 1). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
This PR implements proposal 1 of #1334:
singleton(C)is allowed as a module self type constraint, so that a moduleextended to a class (e.g. Rails'ClassMethodspattern) can declare the class methods it depends on without copying them into an interface.Changes
module Foo : singleton(Bar)andsingleton(Bar)[T](type arguments are optional, as in the class singleton type). Documented indocs/syntax.md.RBS::AST::Declarations::Module::SingletonSelf(name,args,location).Module::Selfis unchanged, so existing consumers keep working.Module#self_typesis nowArray[Module::Self | Module::SingletonSelf]. Both classes get#update.Definition::Ancestor::Singleton(with a new optionalsourceattribute) inOneAncestors#self_types. The recursive ancestor check goes throughsingleton_ancestors, consistent with the existing check for class instance self types (module M : Foo+class Foo; include Mis an error today, and so ismodule M : singleton(C)+class C; extend M).build_instance(Foo)mergesbuild_singleton(Bar)(methods and class instance variables). Methods defined inFootake precedence. Method types are taken as written:instance/class/selfare not rewritten, consistent with class instance self types, and resolving them is left to the type checker.singleton(_Interface)is rejected by the parser and byNoSelfTypeFoundError.check!.Not included
Proposal 2 of #1334 (
singleton(M) < singleton(C)whenmodule M : singleton(C)) is intentionally not included. Theselfinside the body ofMis aModuleobject at runtime and does not respond to the class methods ofC, so treatingsingleton(M)as a subtype ofsingleton(C)would be unsound.Also out of scope: the inline
# @rbs module-self:annotation, and the Steep side (type_construction.rbconvertsmodule_entry.self_typesto types byname.interface?/name.class?, so it needs a branch forSingletonSelf→Types::ClassSingleton).🤖 Generated with Claude Code