mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Make circular argument reference a SyntaxError instead of a warning
Fixes [Bug #10314]
This commit is contained in:
parent
fdfb5100b9
commit
0162e7e647
Notes:
git
2019-10-18 01:32:31 +09:00
5 changed files with 99 additions and 54 deletions
6
parse.y
6
parse.y
|
@ -9890,7 +9890,8 @@ gettable(struct parser_params *p, ID id, const YYLTYPE *loc)
|
|||
if (dyna_in_block(p) && dvar_defined_ref(p, id, &vidp)) {
|
||||
if (NUMPARAM_ID_P(id) && numparam_nested_p(p)) return 0;
|
||||
if (id == p->cur_arg) {
|
||||
rb_warn1("circular argument reference - %"PRIsWARN, rb_id2str(id));
|
||||
compile_error(p, "circular argument reference - %"PRIsWARN, rb_id2str(id));
|
||||
return 0;
|
||||
}
|
||||
if (vidp) *vidp |= LVAR_USED;
|
||||
node = NEW_DVAR(id, loc);
|
||||
|
@ -9898,7 +9899,8 @@ gettable(struct parser_params *p, ID id, const YYLTYPE *loc)
|
|||
}
|
||||
if (local_id_ref(p, id, &vidp)) {
|
||||
if (id == p->cur_arg) {
|
||||
rb_warn1("circular argument reference - %"PRIsWARN, rb_id2str(id));
|
||||
compile_error(p, "circular argument reference - %"PRIsWARN, rb_id2str(id));
|
||||
return 0;
|
||||
}
|
||||
if (vidp) *vidp |= LVAR_USED;
|
||||
node = NEW_LVAR(id, loc);
|
||||
|
|
|
@ -876,20 +876,38 @@ describe "Post-args" do
|
|||
end
|
||||
|
||||
describe "with a circular argument reference" do
|
||||
it "shadows an existing local with the same name as the argument" do
|
||||
a = 1
|
||||
-> {
|
||||
@proc = eval "proc { |a=a| a }"
|
||||
}.should complain(/circular argument reference/)
|
||||
@proc.call.should == nil
|
||||
ruby_version_is ''...'2.7' do
|
||||
it "warns and uses a nil value when there is an existing local variable with same name" do
|
||||
a = 1
|
||||
-> {
|
||||
@proc = eval "proc { |a=a| a }"
|
||||
}.should complain(/circular argument reference/)
|
||||
@proc.call.should == nil
|
||||
end
|
||||
|
||||
it "warns and uses a nil value when there is an existing method with same name" do
|
||||
def a; 1; end
|
||||
-> {
|
||||
@proc = eval "proc { |a=a| a }"
|
||||
}.should complain(/circular argument reference/)
|
||||
@proc.call.should == nil
|
||||
end
|
||||
end
|
||||
|
||||
it "shadows an existing method with the same name as the argument" do
|
||||
def a; 1; end
|
||||
-> {
|
||||
@proc = eval "proc { |a=a| a }"
|
||||
}.should complain(/circular argument reference/)
|
||||
@proc.call.should == nil
|
||||
ruby_version_is '2.7' do
|
||||
it "raises a SyntaxError if using an existing local with the same name as the argument" do
|
||||
a = 1
|
||||
-> {
|
||||
@proc = eval "proc { |a=a| a }"
|
||||
}.should raise_error(SyntaxError)
|
||||
end
|
||||
|
||||
it "raises a SyntaxError if there is an existing method with the same name as the argument" do
|
||||
def a; 1; end
|
||||
-> {
|
||||
@proc = eval "proc { |a=a| a }"
|
||||
}.should raise_error(SyntaxError)
|
||||
end
|
||||
end
|
||||
|
||||
it "calls an existing method with the same name as the argument if explicitly using ()" do
|
||||
|
|
|
@ -177,17 +177,32 @@ describe "An instance method with a default argument" do
|
|||
foo(2,3,3).should == [2,3,[3]]
|
||||
end
|
||||
|
||||
it "shadows an existing method with the same name as the local" do
|
||||
def bar
|
||||
1
|
||||
ruby_version_is ''...'2.7' do
|
||||
it "warns and uses a nil value when there is an existing local method with same name" do
|
||||
def bar
|
||||
1
|
||||
end
|
||||
-> {
|
||||
eval "def foo(bar = bar)
|
||||
bar
|
||||
end"
|
||||
}.should complain(/circular argument reference/)
|
||||
foo.should == nil
|
||||
foo(2).should == 2
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '2.7' do
|
||||
it "raises a syntaxError an existing method with the same name as the local variable" do
|
||||
def bar
|
||||
1
|
||||
end
|
||||
-> {
|
||||
eval "def foo(bar = bar)
|
||||
bar
|
||||
end"
|
||||
}.should raise_error(SyntaxError)
|
||||
end
|
||||
-> {
|
||||
eval "def foo(bar = bar)
|
||||
bar
|
||||
end"
|
||||
}.should complain(/circular argument reference/)
|
||||
foo.should == nil
|
||||
foo(2).should == 2
|
||||
end
|
||||
|
||||
it "calls a method with the same name as the local when explicitly using ()" do
|
||||
|
|
|
@ -267,20 +267,38 @@ describe "A lambda literal -> () { }" do
|
|||
end
|
||||
|
||||
describe "with circular optional argument reference" do
|
||||
it "shadows an existing local with the same name as the argument" do
|
||||
a = 1
|
||||
-> {
|
||||
@proc = eval "-> (a=a) { a }"
|
||||
}.should complain(/circular argument reference/)
|
||||
@proc.call.should == nil
|
||||
ruby_version_is ''...'2.7' do
|
||||
it "warns and uses a nil value when there is an existing local variable with same name" do
|
||||
a = 1
|
||||
-> {
|
||||
@proc = eval "-> (a=a) { a }"
|
||||
}.should complain(/circular argument reference/)
|
||||
@proc.call.should == nil
|
||||
end
|
||||
|
||||
it "warns and uses a nil value when there is an existing method with same name" do
|
||||
def a; 1; end
|
||||
-> {
|
||||
@proc = eval "-> (a=a) { a }"
|
||||
}.should complain(/circular argument reference/)
|
||||
@proc.call.should == nil
|
||||
end
|
||||
end
|
||||
|
||||
it "shadows an existing method with the same name as the argument" do
|
||||
def a; 1; end
|
||||
-> {
|
||||
@proc = eval "-> (a=a) { a }"
|
||||
}.should complain(/circular argument reference/)
|
||||
@proc.call.should == nil
|
||||
ruby_version_is '2.7' do
|
||||
it "raises a SyntaxError if using an existing local with the same name as the argument" do
|
||||
a = 1
|
||||
-> {
|
||||
@proc = eval "-> (a=a) { a }"
|
||||
}.should raise_error(SyntaxError)
|
||||
end
|
||||
|
||||
it "raises a SyntaxError if there is an existing method with the same name as the argument" do
|
||||
def a; 1; end
|
||||
-> {
|
||||
@proc = eval "-> (a=a) { a }"
|
||||
}.should raise_error(SyntaxError)
|
||||
end
|
||||
end
|
||||
|
||||
it "calls an existing method with the same name as the argument if explicitly using ()" do
|
||||
|
|
|
@ -230,27 +230,23 @@ class TestSyntax < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_keyword_self_reference
|
||||
bug9593 = '[ruby-core:61299] [Bug #9593]'
|
||||
o = Object.new
|
||||
assert_warn(/circular argument reference - var/) do
|
||||
assert_raise(SyntaxError) do
|
||||
o.instance_eval("def foo(var: defined?(var)) var end")
|
||||
end
|
||||
assert_equal(42, o.foo(var: 42))
|
||||
assert_equal("local-variable", o.foo, bug9593)
|
||||
|
||||
o = Object.new
|
||||
assert_warn(/circular argument reference - var/) do
|
||||
assert_raise(SyntaxError) do
|
||||
o.instance_eval("def foo(var: var) var end")
|
||||
end
|
||||
assert_nil(o.foo, bug9593)
|
||||
|
||||
o = Object.new
|
||||
assert_warn(/circular argument reference - var/) do
|
||||
assert_raise(SyntaxError) do
|
||||
o.instance_eval("def foo(var: bar(var)) var end")
|
||||
end
|
||||
|
||||
o = Object.new
|
||||
assert_warn(/circular argument reference - var/) do
|
||||
assert_raise(SyntaxError) do
|
||||
o.instance_eval("def foo(var: bar {var}) var end")
|
||||
end
|
||||
|
||||
|
@ -302,37 +298,33 @@ class TestSyntax < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_optional_self_reference
|
||||
bug9593 = '[ruby-core:61299] [Bug #9593]'
|
||||
o = Object.new
|
||||
assert_warn(/circular argument reference - var/) do
|
||||
assert_raise(SyntaxError) do
|
||||
o.instance_eval("def foo(var = defined?(var)) var end")
|
||||
end
|
||||
assert_equal(42, o.foo(42))
|
||||
assert_equal("local-variable", o.foo, bug9593)
|
||||
|
||||
o = Object.new
|
||||
assert_warn(/circular argument reference - var/) do
|
||||
assert_raise(SyntaxError) do
|
||||
o.instance_eval("def foo(var = var) var end")
|
||||
end
|
||||
assert_nil(o.foo, bug9593)
|
||||
|
||||
o = Object.new
|
||||
assert_warn(/circular argument reference - var/) do
|
||||
assert_raise(SyntaxError) do
|
||||
o.instance_eval("def foo(var = bar(var)) var end")
|
||||
end
|
||||
|
||||
o = Object.new
|
||||
assert_warn(/circular argument reference - var/) do
|
||||
assert_raise(SyntaxError) do
|
||||
o.instance_eval("def foo(var = bar {var}) var end")
|
||||
end
|
||||
|
||||
o = Object.new
|
||||
assert_warn(/circular argument reference - var/) do
|
||||
assert_raise(SyntaxError) do
|
||||
o.instance_eval("def foo(var = (def bar;end; var)) var end")
|
||||
end
|
||||
|
||||
o = Object.new
|
||||
assert_warn(/circular argument reference - var/) do
|
||||
assert_raise(SyntaxError) do
|
||||
o.instance_eval("def foo(var = (def self.bar;end; var)) var end")
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue