2757 Commits
Author SHA1 Message Date
Nobuyoshi Nakada 6b15825df0 Use digit scanner in the universal parser
Parser configuration no longer needs base-specific scanner callbacks.
2026-10-27 01:32:35 +09:00
Nobuyoshi Nakada 47feb4e7ff Set dummy ID when broken numeric
Reported-by: 外崎青波
2026-10-24 18:34:05 +09:00
ydah f7789b7af6 Preserve multibyte characters in regexp Unicode escapes
Consume the leading byte before calling tokadd_mbchar in the regexp Unicode escape fast path. The helper reads the character length from pcur - 1; passing an unconsumed byte corrupted multibyte characters and skipped following bytes.

Add regression coverage for two-, three-, and four-byte UTF-8 characters in invalid Unicode escapes inside extended regexp comments.
2026-10-24 09:43:28 +09:00
Nobuyoshi Nakada 31a3aa4e46 [Bug #22450] Preserve do-block binding in control-flow arguments
Inherited `CMDARG` state made `do` blocks in control-flow arguments
bind to the wrong call.
2026-10-18 00:33:30 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 9d123b1e2c Saturate parser columns at INT_MAX
Token columns are int, so a token past column INT_MAX got a negative column, and the excerpt shown for a syntax error there was read from before the line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 18:29:43 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 e5e36b4e3c Range-check parser columns with rb_len2int
rb_long2int is a plain cast where int and long have the same width, so on 64-bit mswin a column past INT_MAX wrapped instead of raising RangeError as it does on LP64.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 18:29:43 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 c68782a239 Hold heredoc offsets in rb_len_t
Where rb_len_t is wider than long, a heredoc opener past column LONG_MAX made the long offset negative, and the identifier and the restored lexer position were read from before the line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 18:29:43 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 4f42bb946c Hold parser string lengths in rb_len_t
rb_parser_string_t kept its length in a long, so rb_str_to_parser_string had to reject a String longer than LONG_MAX where rb_len_t is wider than long. Now the parser string holds the whole length and the check is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 18:29:43 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 66b3c8f32e Reject a string too long for rb_parser_string_t
rb_parser_string_t holds its length as a long, which is narrower than a String length on mswin once rb_len_t widens, so a line or literal of 2GiB or more would be truncated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:00:15 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 adf30005ea Use rb_len_t for the lengths left in long
These hold String and Array lengths or offsets into them, so they would truncate on mswin once rb_len_t widens. A build with rb_len_t set to long long reported them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:00:15 +09:00
Benoit DalozeandClaude Fable 5.1 b2ec82d4ea Cover the whole Const op= value expression in the constant read node in parse.y
For `Const += value`, parse.y builds a NODE_CDECL whose value is an
OPCALL on a NODE_CONST read node, and that read node only spanned the
constant name. The NameError for an undefined constant is raised by that
read, so Thread::Backtrace::Location#source_range reported only the
constant name. Prism has no separate read node and reports the whole
ConstantOperatorWriteNode, and the same holds for ConstantAndWriteNode.

Give the NODE_CONST read node the location of the whole operator
assignment (`+=`, `&&=` and `||=`) so both parsers report the same range.
Other variable reads keep their own location as error_highlight locates
the operator from the end of the receiver node.

See [Bug #22235] for more details.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 14:17:27 +02:00
Benoit DalozeandClaude Opus 4.8 8040d06599 [Bug #22302] Emit a line event for a method's implicit nil return in parse.y
reduce_nodes eliminated a bare `nil` in a method's tail (value) position
down to an empty method body, so parse.y emitted no :line event and
recorded no line coverage for that line, even though it is executed:

    def m
      nil    # <- no :line event, no coverage under parse.y
    end

The Prism compiler keeps the explicit nil and correctly emits the event.
Keep the nil in reduce_nodes when it carries a newline flag (i.e. it is
on its own line) so it still produces a line event, while the implicit
nil of an empty body (no newline flag) is still dropped. This makes
parse.y match Prism for TracePoint :line events and line coverage.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-10 23:42:44 +02:00
Hiroya Fujinami c9764e85f7 Avoid quadratic parse time on and/or chains (#18638)
Avoid quadratic parse time on long and/or chains

logop() builds a left-associative and/or chain into a right-leaning
tree, and found the insertion point by walking the whole right spine
from the top on every operator. For a chain such as
`a && a && ... && a` that walk is O(n) per operator, so parsing the
chain is O(n^2): 32k operators took seconds.

Cache the tail of the chain most recently built by logop(), so an
operator that extends the same chain reaches the insertion point in
constant time, making the parse linear. The cached tail is validated
before use (it must still be a node of the chain's type whose nd_2nd
is not another such node), so a stale entry from an earlier parse
falls back to the scan. The resulting tree is unchanged: AST and
compiled bytecode are byte-identical to before across left-associative,
parenthesized, and mixed and/or chains.
2026-09-08 15:40:20 +09:00
TSUYUSATO Kitsune a946c1bd8e Report a void value in an and/or chain only once
value_expr_check descended into the left operand of an and/or node,
so a chain such as `x = (return) && (return) && a` reported the same
void value once per operator instead of once. The left operand is
already checked for a value when logop() builds the node, so stop at
the node rather than descending.

This matches the existing test_void_value_in_rhs expectation that the
same warning is emitted just once, and mirrors the same change in
ruby/prism#4221.
2026-09-05 21:59:07 +09:00
ydah d311b34116 parse.y: clear errno before parsing float literals 2026-09-02 11:47:00 +09:00
ydah a3f47303bb parse.y: fix high nibble in invalid byte escapes 2026-08-28 16:04:08 +09:00
Nobuyoshi Nakada e5132b1627 [Bug #22264] Warn for duplicate keys after leading keyword splat
Leading keyword splats must not suppress duplicate literal key
warnings.
2026-08-26 14:42:13 +09:00
Nobuyoshi Nakada b51ae934f7 [Feature #22215] Remove vm_core dependency from gc header
Keep `internal/gc.h` usable without VM-private definitions so bundled
extensions do not inherit `vm_core.h` dependencies.
2026-08-07 09:59:15 +09:00
Yusuke EndohandClaude Fable 5 93638d07e1 Compute a source hash of the program in parse.y
Introduce a streaming source hash API (rb_source_hash_init/update/
finalize) in ruby_parser.c, and use it in the lexer of parse.y to
accumulate a hash of the source as each line is read. The hash is
stored in the AST, and will be used to check whether a file still
contains the same source code when it is re-parsed later.
[Feature #21795]

The hash algorithm (currently FNV-1a) is hidden behind the API as an
implementation detail of the interpreter, so it can be changed freely
between releases.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 13:20:23 +02:00
Shugo MaedaandClaude Opus 4.8 da37301f08 Keep room in the token buffer for the terminator
tokspace stops doubling as soon as the buffer reaches the token's length,
so a copy that lands exactly on the end leaves tokfix writing its
terminator one byte past it.  No caller passes a large enough n to reach
that today, but the invariant tokfix relies on is worth holding.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 22:49:27 +09:00
Nobuyoshi Nakada db7fba3217 Make __VA_ARGS__ check mandatory
Since we already require C99 compilers, and autoconf 2.67 or later.
`__VA_ARGS__` is always available.
2026-07-13 20:03:55 +09:00
Nobuyoshi Nakada 3f7d4bc859 [Bug #22183] Preserve lpar_beg across interpolation
Fix unexpected `keyword_do_LAMBDA` inside string interpolation within
default argument of lambda.
2026-07-07 21:07:12 +09:00
Earlopain 7ea07dd74d [Bug #21994] Drop warning for ambiguous regexp use
https://bugs.ruby-lang.org/issues/21994
2026-07-06 09:38:14 -04:00
Nobuyoshi Nakada d8444812f4 [Bug #22124] Add block to the proper node 2026-06-23 20:44:57 +09:00
Earlopain 11de89ca1a Reject END { next } as well
Followup for https://bugs.ruby-lang.org/issues/20409
2026-05-15 19:58:27 +09:00
Nobuyoshi Nakada 2f9432d211 [Bug #20409] Make break and redo in END syntax error 2026-05-12 20:04:00 +09:00
Nobuyoshi Nakada 803b3169e0 Show "END in method" warning immediately 2026-05-12 20:04:00 +09:00
Nobuyoshi Nakada 4644e4f2fa [Bug #21986] Fix location of numeric literal
When checking for suffixes, do not flush the numeric literal token
even if no suffix is found.
2026-04-09 13:32:31 +09:00
Nobuyoshi Nakada 24a2ba09af [Bug #21985] Include the - in the negative numbers location 2026-04-08 14:50:30 +09:00
Jean Boussier 53099633e2 Make ruby_xfree_sized and ruby_xrealloc_sized public
[Feature #21861]
2026-04-01 08:10:07 +01:00
Nobuyoshi Nakada ae9b60f189 [Feature #19107] parse.y: Allow trailing comma in method signature 2026-03-30 22:14:09 +09:00
Nobuyoshi Nakada 55694ad7ef [Bug #21945] Correctly handle and? and similar 2026-03-07 10:39:46 +09:00
Nobuyoshi Nakada d5d144c149 parse.y: Split forwarding argument in method and lambda
Eliminate the lambda argument conditions from the action.
2026-03-06 18:25:08 +09:00
Nobuyoshi Nakada 7a3940e8b6 Unify rb_node_list_new and rb_node_list_new2
The former is the specialized case of the latter.
2026-03-03 23:05:00 +09:00
Nobuyoshi Nakada 45dce19e22 parse.y: Parameterize argument list rules
Parametrize `block_param` and `f_args` into `arg-list` and
`tail-only-args`.  Since the pattern for `pre_args` alone differs
between `opt_comma` and `excessed_comma`, retain it within each rule.
2026-03-01 19:44:59 +09:00
Nobuyoshi Nakada 0980de4c1a parse.y: Extract new_empty_args_tail macro 2026-03-01 12:10:06 +09:00
Nobuyoshi Nakada 504cf455fb parse.y: Extract f_empty_arg 2026-03-01 12:04:38 +09:00
Nobuyoshi Nakada 851a10bcb5 Revert "parse.y: narrow excessed_comma to block_param_def"
This reverts commit 2239d54348.
At first glance, it seemed like a good idea, but it wasn't all that
great.
2026-03-01 09:20:18 +09:00
Nobuyoshi Nakada 68080febee parse.y: Unify to use only tagged references
Unify references in rules that mix positional references and tagged
references.  Leave the positional reference-only rules unchanged.
2026-02-28 01:01:46 +09:00
Nobuyoshi Nakada 486f7fcc27 parse.y: prefer @$ over @0 in empty-rule actions 2026-02-27 23:47:11 +09:00
Nobuyoshi Nakada 2239d54348 parse.y: narrow excessed_comma to block_param_def 2026-02-27 13:10:04 +09:00
Nobuyoshi Nakada 116d402067 [Feature #19979] Method definition with &nil
Allow methods to declare that they don't accept a block via `&nil`.
2026-02-15 14:12:15 -05:00
Nobuyoshi Nakada cb303ff4b8 [Bug #21669] Fix void value expression check for pattern-matching
If the all `in` and `else` branches are void, the `case` is also void.
2026-02-04 13:28:34 +09:00
Nobuyoshi Nakada baaf0ccb9c [Bug #21669] Fix void value expression check for block
A block containing a void statement that is not contained in a branch
is also void.
2026-02-04 13:28:34 +09:00
Nobuyoshi Nakada 932ce048fe [Bug #21669] Implement void value expression check for case/when
If the all `when` and `else` branches are void, the `case` is also
void.
2026-02-04 13:28:33 +09:00
Nobuyoshi Nakada 4f36010738 [Bug #21669] Fix void value expression check for rescue-else
If `rescue`-else node is void, the `rescue`-body is also void.
2026-02-04 13:28:33 +09:00
Nobuyoshi Nakada c8b2a453d0 [Bug #21669] Fix void value expression check for rescue
If any `rescue` node is non-void, the enclosing block is also
non-void.
2026-02-04 13:28:33 +09:00
Jean Boussier 9be01bc70d gc.c: also verify sized_xrealloc old size 2026-01-30 15:24:48 +01:00
Benoit Daloze c970d2941d [Bug #21784] Fix the Proc#source_location start_column for stabby lambdas
* Consistent with plain `blocks` and `for` blocks and methods
  where the source_location covers their entire definition.
* Matches the documentation which mentions
  "where the definition starts/ends".
* Partially reverts d357d50f0a
  which was a workaround to be compatible with parse.y.
2025-12-30 16:02:39 +01:00
yui-knk f81c62be3d Terminate args_tail_basic rule with a semicolon
Semicolon is optional however it clarifies the end of the rule.
2025-12-19 13:39:12 +08:00