diff --git a/lib/typeprof/core/ast/meta.rb b/lib/typeprof/core/ast/meta.rb index f3c2ff69..2a6be0f6 100644 --- a/lib/typeprof/core/ast/meta.rb +++ b/lib/typeprof/core/ast/meta.rb @@ -326,7 +326,12 @@ def define0(genv) end if @kind == :struct # Struct.[] calls the receiver's initialize, like Class#new - genv.resolve_method(struct_base_cpath, true, :[]).builtin = Builtin.new(genv).method(:class_new) + me = genv.resolve_method(struct_base_cpath, true, :[]) + unless me.builtin + me.builtin = Builtin.new(genv).method(:class_new) + # Unlike a method definition, a builtin does not notify the calls itself + me.add_run_all_method_call_boxes(genv) + end end @block_body.define(genv) if @block_body cdef @@ -358,7 +363,9 @@ def undefine0(genv) end # On an update, the new node has already set the builtin if base.module_defs.to_a.none? { _1.kind == :struct } - genv.resolve_method(struct_base_cpath, true, :[]).builtin = nil + me = genv.resolve_method(struct_base_cpath, true, :[]) + me.builtin = nil + me.add_run_all_method_call_boxes(genv) end @block_body.undefine(genv) if @block_body end diff --git a/scenario/incremental/struct-aref-to-data.rb b/scenario/incremental/struct-aref-to-data.rb new file mode 100644 index 00000000..6d45c040 --- /dev/null +++ b/scenario/incremental/struct-aref-to-data.rb @@ -0,0 +1,35 @@ +## update +Pt = Struct.new(:x, :y) +def f = Pt[1, 2] + +## diagnostics + +## assert +class Pt + def x: -> Integer + def x=: (untyped) -> untyped + def y: -> Integer + def y=: (untyped) -> untyped + def initialize: (?Integer, ?Integer) -> void + def self.[]: (?Integer, ?Integer) -> Pt +end +class Object + def f: -> Pt +end + +## update +Pt = Data.define(:x, :y) +def f = Pt[1, 2] + +## diagnostics +(2,10)-(2,16): undefined method: singleton(Pt)#[] + +## assert +class Pt + def x: -> untyped + def y: -> untyped + def initialize: (x: untyped, y: untyped) -> void +end +class Object + def f: -> untyped +end