diff --git a/spec/compiler/interpreter/structs_spec.cr b/spec/compiler/interpreter/structs_spec.cr index 150065193b7b..a573866d1e84 100644 --- a/spec/compiler/interpreter/structs_spec.cr +++ b/spec/compiler/interpreter/structs_spec.cr @@ -338,5 +338,30 @@ describe Crystal::Repl::Interpreter do f.x + f.y + f.z CODE end + + it "inlines struct method that returns self (#12253)" do + interpret(<<-CODE).should eq(42) + struct Foo + def initialize(@x : Int32) + end + + def x + @x + end + + def foo + me + end + + def me + self + end + end + + a = Foo.new(42) + b = a.foo + b.x + CODE + end end end diff --git a/src/compiler/crystal/interpreter/compiler.cr b/src/compiler/crystal/interpreter/compiler.cr index df265a94a148..66842c52d3a4 100644 --- a/src/compiler/crystal/interpreter/compiler.cr +++ b/src/compiler/crystal/interpreter/compiler.cr @@ -1773,7 +1773,12 @@ class Crystal::Repl::Compiler < Crystal::Visitor if obj request_value(obj) else - put_self(node: node) + if scope.struct? && scope.passed_by_value? + # Load the entire self from the pointer that's self + get_self_ivar 0, aligned_sizeof_type(scope), node: node + else + put_self(node: node) + end end end