Skip to content

Commit

Permalink
+ ruby{33,34}.y: allow blocks inherit anonymous args. (#1010)
Browse files Browse the repository at this point in the history
This commit tracks upstream commit ruby/ruby@596db9c.
  • Loading branch information
iliabylich committed Apr 26, 2024
1 parent 570e065 commit 8af86b0
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 18 deletions.
6 changes: 3 additions & 3 deletions lib/parser/ruby33.y
Expand Up @@ -1101,7 +1101,7 @@ rule
end
if @context.in_dynamic_block? && context.in_def &&
@static_env.declared_anonymous_blockarg? && @static_env.parent_has_anonymous_blockarg?
@static_env.declared_anonymous_blockarg_in_current_scpe? && @static_env.parent_has_anonymous_blockarg?
diagnostic :error, :ambiguous_anonymous_blockarg, nil, val[0]
end
Expand Down Expand Up @@ -1142,7 +1142,7 @@ rule
end
if @context.in_dynamic_block? && context.in_def &&
@static_env.declared_anonymous_restarg? && @static_env.parent_has_anonymous_restarg?
@static_env.declared_anonymous_restarg_in_current_scope? && @static_env.parent_has_anonymous_restarg?
diagnostic :error, :ambiguous_anonymous_restarg, nil, val[0]
end
Expand Down Expand Up @@ -3059,7 +3059,7 @@ f_opt_paren_args: f_paren_args
end
if @context.in_dynamic_block? && context.in_def &&
@static_env.declared_anonymous_kwrestarg? && @static_env.parent_has_anonymous_kwrestarg?
@static_env.declared_anonymous_kwrestarg_in_current_scope? && @static_env.parent_has_anonymous_kwrestarg?
diagnostic :error, :ambiguous_anonymous_kwrestarg, nil, val[0]
end
Expand Down
6 changes: 3 additions & 3 deletions lib/parser/ruby34.y
Expand Up @@ -1101,7 +1101,7 @@ rule
end
if @context.in_dynamic_block? && context.in_def &&
@static_env.declared_anonymous_blockarg? && @static_env.parent_has_anonymous_blockarg?
@static_env.declared_anonymous_blockarg_in_current_scpe? && @static_env.parent_has_anonymous_blockarg?
diagnostic :error, :ambiguous_anonymous_blockarg, nil, val[0]
end
Expand Down Expand Up @@ -1142,7 +1142,7 @@ rule
end
if @context.in_dynamic_block? && context.in_def &&
@static_env.declared_anonymous_restarg? && @static_env.parent_has_anonymous_restarg?
@static_env.declared_anonymous_restarg_in_current_scope? && @static_env.parent_has_anonymous_restarg?
diagnostic :error, :ambiguous_anonymous_restarg, nil, val[0]
end
Expand Down Expand Up @@ -3059,7 +3059,7 @@ f_opt_paren_args: f_paren_args
end
if @context.in_dynamic_block? && context.in_def &&
@static_env.declared_anonymous_kwrestarg? && @static_env.parent_has_anonymous_kwrestarg?
@static_env.declared_anonymous_kwrestarg_in_current_scope? && @static_env.parent_has_anonymous_kwrestarg?
diagnostic :error, :ambiguous_anonymous_kwrestarg, nil, val[0]
end
Expand Down
59 changes: 47 additions & 12 deletions lib/parser/static_environment.rb
Expand Up @@ -4,9 +4,15 @@ module Parser

class StaticEnvironment
FORWARD_ARGS = :FORWARD_ARGS
ANONYMOUS_BLOCKARG = :ANONYMOUS_BLOCKARG
ANONYMOUS_RESTARG = :ANONYMOUS_RESTARG
ANONYMOUS_KWRESTARG = :ANONYMOUS_KWRESTARG

ANONYMOUS_RESTARG_IN_CURRENT_SCOPE = :ANONYMOUS_RESTARG_IN_CURRENT_SCOPE
ANONYMOUS_RESTARG_INHERITED = :ANONYMOUS_RESTARG_INHERITED

ANONYMOUS_KWRESTARG_IN_CURRENT_SCOPE = :ANONYMOUS_KWRESTARG_IN_CURRENT_SCOPE
ANONYMOUS_KWRESTARG_INHERITED = :ANONYMOUS_KWRESTARG_INHERITED

ANONYMOUS_BLOCKARG_IN_CURRENT_SCOPE = :ANONYMOUS_BLOCKARG_IN_CURRENT_SCOPE
ANONYMOUS_BLOCKARG_INHERITED = :ANONYMOUS_BLOCKARG_INHERITED

def initialize
reset
Expand All @@ -27,6 +33,15 @@ def extend_static
def extend_dynamic
@stack.push(@variables)
@variables = @variables.dup
if @variables.delete(ANONYMOUS_BLOCKARG_IN_CURRENT_SCOPE)
@variables.add(ANONYMOUS_BLOCKARG_INHERITED)
end
if @variables.delete(ANONYMOUS_RESTARG_IN_CURRENT_SCOPE)
@variables.add(ANONYMOUS_RESTARG_INHERITED)
end
if @variables.delete(ANONYMOUS_KWRESTARG_IN_CURRENT_SCOPE)
@variables.add(ANONYMOUS_KWRESTARG_INHERITED)
end

self
end
Expand All @@ -47,6 +62,8 @@ def declared?(name)
@variables.include?(name.to_sym)
end

# Forward args

def declare_forward_args
declare(FORWARD_ARGS)
end
Expand All @@ -55,40 +72,58 @@ def declared_forward_args?
declared?(FORWARD_ARGS)
end

# Anonymous blockarg

def declare_anonymous_blockarg
declare(ANONYMOUS_BLOCKARG)
declare(ANONYMOUS_BLOCKARG_IN_CURRENT_SCOPE)
end

def declared_anonymous_blockarg?
declared?(ANONYMOUS_BLOCKARG)
declared?(ANONYMOUS_BLOCKARG_IN_CURRENT_SCOPE) || declared?(ANONYMOUS_BLOCKARG_INHERITED)
end

def declared_anonymous_blockarg_in_current_scpe?
declared?(ANONYMOUS_BLOCKARG_IN_CURRENT_SCOPE)
end

def parent_has_anonymous_blockarg?
@stack.any? { |variables| variables.include?(ANONYMOUS_BLOCKARG) }
@stack.any? { |variables| variables.include?(ANONYMOUS_BLOCKARG_IN_CURRENT_SCOPE) }
end

# Anonymous restarg

def declare_anonymous_restarg
declare(ANONYMOUS_RESTARG)
declare(ANONYMOUS_RESTARG_IN_CURRENT_SCOPE)
end

def declared_anonymous_restarg?
declared?(ANONYMOUS_RESTARG)
declared?(ANONYMOUS_RESTARG_IN_CURRENT_SCOPE) || declared?(ANONYMOUS_RESTARG_INHERITED)
end

def declared_anonymous_restarg_in_current_scope?
declared?(ANONYMOUS_RESTARG_IN_CURRENT_SCOPE)
end

def parent_has_anonymous_restarg?
@stack.any? { |variables| variables.include?(ANONYMOUS_RESTARG) }
@stack.any? { |variables| variables.include?(ANONYMOUS_RESTARG_IN_CURRENT_SCOPE) }
end

# Anonymous kwresarg

def declare_anonymous_kwrestarg
declare(ANONYMOUS_KWRESTARG)
declare(ANONYMOUS_KWRESTARG_IN_CURRENT_SCOPE)
end

def declared_anonymous_kwrestarg?
declared?(ANONYMOUS_KWRESTARG)
declared?(ANONYMOUS_KWRESTARG_IN_CURRENT_SCOPE) || declared?(ANONYMOUS_KWRESTARG_INHERITED)
end

def declared_anonymous_kwrestarg_in_current_scope?
declared?(ANONYMOUS_KWRESTARG_IN_CURRENT_SCOPE)
end

def parent_has_anonymous_kwrestarg?
@stack.any? { |variables| variables.include?(ANONYMOUS_KWRESTARG) }
@stack.any? { |variables| variables.include?(ANONYMOUS_KWRESTARG_IN_CURRENT_SCOPE) }
end

def empty?
Expand Down
30 changes: 30 additions & 0 deletions test/test_parser.rb
Expand Up @@ -11497,4 +11497,34 @@ def test_parser_bug_989
%q{},
ALL_VERSIONS)
end

def test_parser_bug_19370
refute_diagnoses(
'def b(&) ->() {c(&)} end',
SINCE_3_3)

refute_diagnoses(
'def b(*) ->() {c(*)} end',
SINCE_3_3)

refute_diagnoses(
'def b(a, *) ->() {c(1, *)} end',
SINCE_3_3)

refute_diagnoses(
'def b(*) ->(a) {c(*)} end',
SINCE_3_3)

refute_diagnoses(
'def b(**) ->() {c(**)} end',
SINCE_3_3)

refute_diagnoses(
'def b(k:, **) ->() {c(k: 1, **)} end',
SINCE_3_3)

refute_diagnoses(
'def b(**) ->(k:) {c(**)} end',
SINCE_3_3)
end
end

0 comments on commit 8af86b0

Please sign in to comment.