-
Notifications
You must be signed in to change notification settings - Fork 219
Add support for lower bounds in type parameters #2490
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
rbs_parser_advance(parser); | ||
} | ||
|
||
if (parser->next_token.type == pRBRACKET) { | ||
} else if (parser->next_token.type == pRBRACKET) { | ||
break; | ||
} else { | ||
rbs_parser_set_error(parser, parser->next_token, true, "expected ',' or ']' after type parameter, got %s", rbs_token_type_str(parser->next_token.type)); | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change ensures the parser correctly validates syntax after type parameter bounds. Previously, expressions like [T < String Integer]
would be silently accepted despite being invalid.
upper_bound_range.end = parser->current_token.range.end; | ||
rbs_range_t lower_bound_range = NULL_RANGE; | ||
|
||
for (int bound_parse_attempt = 0; bound_parse_attempt < 2; bound_parse_attempt++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This loop is to parse both upper bound (<) and lower bound (>) constraints for type parameters. The loop runs at most twice to allow both bound types in either order: [T < UpperBound > LowerBound]
or [T > LowerBound < UpperBound]
. It detects and prevents duplicate bounds of the same type and exits early if no bounds are present.
487f79c
to
c63e115
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Side Note: In RBS, the generic type specify covariance and contravariance with in
/out
keywords:
class Covariant[out O] …
class Contravariant[in I] …
def example(src, dst) #: [T] (Covariant[T], Contravariant[T]) -> void
dst.set src.get
end
Java generics are invariant; instead, each application specifies co- and contravariance through wildcard lower and upper bounds case-by-case:
class Covariant<O> …
class Contravariant<I> …
<T> void example(Covariant<? extends T> src, Contravariant<? super T> dst) {
dst.set(src.get());
}
In RBS, that is equivalent to:
class Covariant[O] …
class Contravariant[I] …
def example: [T, O < T = T, I > T = T] (Covariant[O], Contravariant[I]) -> void
This change implements lower bound constraints for generic type parameters in RBS, allowing declarations like `[T > SomeType]`. The implementation includes: - Parser and lexer modifications to handle ">" token in type params - Relevant changes to the Ruby API, like Locator and Validator - Schema updates to typeParam.json - Documentation updates
c63e115
to
ac8348a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! 🎉
This change implements lower bound constraints for generic type parameters in RBS, allowing declarations like
[T > SomeType]
.The implementation includes: