diff --git a/spec/compiler/crystal/tools/hierarchy_spec.cr b/spec/compiler/crystal/tools/hierarchy_spec.cr index ae1bcd2dbadb..8b971947b299 100644 --- a/spec/compiler/crystal/tools/hierarchy_spec.cr +++ b/spec/compiler/crystal/tools/hierarchy_spec.cr @@ -41,6 +41,36 @@ describe Crystal::TextHierarchyPrinter do @x : Bool (1 bytes)\n EOS end + + it "shows correct size for Proc inside extern struct" do + program = semantic(<<-CRYSTAL).program + @[Extern] + struct Foo + @x = uninitialized -> + end + + lib Bar + struct Foo + x : Int32 -> Int32 + end + end + CRYSTAL + + output = String.build { |io| Crystal.print_hierarchy(program, io, "Foo", "text") } + output.should eq(<<-EOS) + - class Object (4 bytes) + | + +- struct Value (0 bytes) + | + +- struct Struct (0 bytes) + | + +- struct Bar::Foo (8 bytes) + | @x : Proc(Int32, Int32) (8 bytes) + | + +- struct Foo (8 bytes) + @x : Proc(Nil) (8 bytes)\n + EOS + end end describe Crystal::JSONHierarchyPrinter do diff --git a/src/compiler/crystal/tools/print_hierarchy.cr b/src/compiler/crystal/tools/print_hierarchy.cr index b6fcb7a76fdc..0e6b3427020c 100644 --- a/src/compiler/crystal/tools/print_hierarchy.cr +++ b/src/compiler/crystal/tools/print_hierarchy.cr @@ -106,8 +106,9 @@ module Crystal @llvm_typer.size_of(@llvm_typer.llvm_struct_type(type)) end - def ivar_size(ivar) - @llvm_typer.size_of(@llvm_typer.llvm_embedded_type(ivar.type)) + def ivar_size(ivar, extern) + llvm_type = extern ? @llvm_typer.llvm_embedded_c_type(ivar.type) : @llvm_typer.llvm_embedded_type(ivar.type) + @llvm_typer.size_of(llvm_type) end end @@ -201,7 +202,7 @@ module Crystal max_name_size = instance_vars.max_of &.name.size max_type_size = typed_instance_vars.max_of?(&.type.to_s.size) || 0 - max_bytes_size = typed_instance_vars.max_of? { |var| ivar_size(var).to_s.size } || 0 + max_bytes_size = typed_instance_vars.max_of? { |var| ivar_size(var, type.extern?).to_s.size } || 0 instance_vars.each do |ivar| print_indent @@ -214,7 +215,7 @@ module Crystal ivar_type.to_s.ljust(@io, max_type_size) with_color.light_gray.surround(@io) do @io << " (" - ivar_size(ivar).to_s.rjust(@io, max_bytes_size) + ivar_size(ivar, type.extern?).to_s.rjust(@io, max_bytes_size) @io << " bytes)" end else @@ -330,7 +331,7 @@ module Crystal @json.object do @json.field "name", instance_var.name.to_s @json.field "type", ivar_type.to_s - @json.field "size_in_bytes", ivar_size(instance_var) + @json.field "size_in_bytes", ivar_size(instance_var, type.extern?) end end end