[ruby-core:117754] [Ruby master Bug#20467] Prism creates a wrong ConstantReadNode for `Bar::Foo = 42`

Issue #20467 has been reported by mame (Yusuke Endoh). ---------------------------------------- Bug #20467: Prism creates a wrong ConstantReadNode for `Bar::Foo = 42` https://bugs.ruby-lang.org/issues/20467 * Author: mame (Yusuke Endoh) * Status: Open * Assignee: kddnewton (Kevin Newton) * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- Currently, Prism creates the following AST for `Bar::Foo = 42` ``` irb(main):001> Prism.parse(%q(Bar::Foo = 42)).value => @ ProgramNode (location: (1,0)-(1,13)) ├── locals: [] └── statements: @ StatementsNode (location: (1,0)-(1,13)) └── body: (length: 1) └── @ ConstantPathWriteNode (location: (1,0)-(1,13)) ├── target: │ @ ConstantPathNode (location: (1,0)-(1,8)) │ ├── parent: │ │ @ ConstantReadNode (location: (1,0)-(1,3)) │ │ └── name: :Bar │ ├── child: │ │ @ ConstantReadNode (location: (1,5)-(1,8)) │ │ └── name: :Foo │ └── delimiter_loc: (1,3)-(1,5) = "::" ├── operator_loc: (1,9)-(1,10) = "=" └── value: @ IntegerNode (location: (1,11)-(1,13)) ├── flags: decimal └── value: 42 ``` Note that it includes `ConstantReadNode(name: :Foo)`. I believe this is a bug because `Bar::Foo = 42` does not read a constant `Foo`. Also, `Foo` and `Bar::Foo` generates the followings. ``` irb(main):002> Prism.parse(%q(Foo)).value => @ ProgramNode (location: (1,0)-(1,3)) ├── locals: [] └── statements: @ StatementsNode (location: (1,0)-(1,3)) └── body: (length: 1) └── @ ConstantReadNode (location: (1,0)-(1,3)) └── name: :Foo irb(main):003> Prism.parse(%q(Bar::Foo)).value => @ ProgramNode (location: (1,0)-(1,8)) ├── locals: [] └── statements: @ StatementsNode (location: (1,0)-(1,8)) └── body: (length: 1) └── @ ConstantPathNode (location: (1,0)-(1,8)) ├── parent: │ @ ConstantReadNode (location: (1,0)-(1,3)) │ └── name: :Bar ├── child: │ @ ConstantReadNode (location: (1,5)-(1,8)) │ └── name: :Foo └── delimiter_loc: (1,3)-(1,5) = "::" ``` Note that both have the same subtree of `ConstantReadNode(name: :Foo)`. It is very confusing because `Foo` (non-scoped read of `Foo`) and `Bar::Foo` (scoped read of `Foo`) have very different meanings. I think the following design would be desirable. ``` # Foo::Bar=42 ConstantPathWriteNode( base: ConstantReadNode(name: ConstantNameNode(:Foo)), name: ConstantNameNode(:Bar), value: 42 ) # Foo ConstantReadNode(name: ConstantNameNode(:Foo)) # Foo::Bar ConstantPathReadNode( base: ConstantReadNode(name: ConstantNameNode(:Foo)), name: ConstantNameNode(:Bar), ) ``` -- https://bugs.ruby-lang.org/

Issue #20467 has been updated by kddnewton (Kevin Newton). I've changed it to be the following since https://github.com/ruby/ruby/pull/10716. ``` irb(main):001> Prism.parse(%q(Bar::Foo)).value => @ ProgramNode (location: (1,0)-(1,8)) ├── locals: [] └── statements: @ StatementsNode (location: (1,0)-(1,8)) └── body: (length: 1) └── @ ConstantPathNode (location: (1,0)-(1,8)) ├── parent: │ @ ConstantReadNode (location: (1,0)-(1,3)) │ └── name: :Bar ├── name: :Foo ├── delimiter_loc: (1,3)-(1,5) = "::" └── name_loc: (1,5)-(1,8) = "Foo" ``` ---------------------------------------- Bug #20467: Prism creates a wrong ConstantReadNode for `Bar::Foo = 42` https://bugs.ruby-lang.org/issues/20467#change-108167 * Author: mame (Yusuke Endoh) * Status: Open * Assignee: kddnewton (Kevin Newton) * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- Currently, Prism creates the following AST for `Bar::Foo = 42` ``` irb(main):001> Prism.parse(%q(Bar::Foo = 42)).value => @ ProgramNode (location: (1,0)-(1,13)) ├── locals: [] └── statements: @ StatementsNode (location: (1,0)-(1,13)) └── body: (length: 1) └── @ ConstantPathWriteNode (location: (1,0)-(1,13)) ├── target: │ @ ConstantPathNode (location: (1,0)-(1,8)) │ ├── parent: │ │ @ ConstantReadNode (location: (1,0)-(1,3)) │ │ └── name: :Bar │ ├── child: │ │ @ ConstantReadNode (location: (1,5)-(1,8)) │ │ └── name: :Foo │ └── delimiter_loc: (1,3)-(1,5) = "::" ├── operator_loc: (1,9)-(1,10) = "=" └── value: @ IntegerNode (location: (1,11)-(1,13)) ├── flags: decimal └── value: 42 ``` Note that it includes `ConstantReadNode(name: :Foo)`. I believe this is a bug because `Bar::Foo = 42` does not read a constant `Foo`. Also, `Foo` and `Bar::Foo` generates the followings. ``` irb(main):002> Prism.parse(%q(Foo)).value => @ ProgramNode (location: (1,0)-(1,3)) ├── locals: [] └── statements: @ StatementsNode (location: (1,0)-(1,3)) └── body: (length: 1) └── @ ConstantReadNode (location: (1,0)-(1,3)) └── name: :Foo irb(main):003> Prism.parse(%q(Bar::Foo)).value => @ ProgramNode (location: (1,0)-(1,8)) ├── locals: [] └── statements: @ StatementsNode (location: (1,0)-(1,8)) └── body: (length: 1) └── @ ConstantPathNode (location: (1,0)-(1,8)) ├── parent: │ @ ConstantReadNode (location: (1,0)-(1,3)) │ └── name: :Bar ├── child: │ @ ConstantReadNode (location: (1,5)-(1,8)) │ └── name: :Foo └── delimiter_loc: (1,3)-(1,5) = "::" ``` Note that both have the same subtree of `ConstantReadNode(name: :Foo)`. It is very confusing because `Foo` (non-scoped read of `Foo`) and `Bar::Foo` (scoped read of `Foo`) have very different meanings. I think the following design would be desirable. ``` # Foo::Bar=42 ConstantPathWriteNode( base: ConstantReadNode(name: ConstantNameNode(:Foo)), name: ConstantNameNode(:Bar), value: 42 ) # Foo ConstantReadNode(name: ConstantNameNode(:Foo)) # Foo::Bar ConstantPathReadNode( base: ConstantReadNode(name: ConstantNameNode(:Foo)), name: ConstantNameNode(:Bar), ) ``` -- https://bugs.ruby-lang.org/
participants (2)
-
kddnewton (Kevin Newton)
-
mame (Yusuke Endoh)