Skip to content

Commit

Permalink
Add file name to file-private metaclass types during codegen (#15505)
Browse files Browse the repository at this point in the history
File-private types with the same name get collapsed into a single type during codegen, which messes up any dispatch over them: only one of their type IDs is considered, and the other is assumed to be unreachable.
Adding the file name as namespace keeps them apart.
  • Loading branch information
HertzDevil authored Feb 23, 2025
1 parent 0c18a2d commit 29e1b71
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
32 changes: 32 additions & 0 deletions spec/compiler/codegen/class_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,38 @@ describe "Code gen: class" do
)).to_string.should eq("Baz")
end

it "does not combine types with same name but different file scopes (#15503)" do
run(<<-CRYSTAL, Int32, filename: "foo.cr").should eq(11)
module Foo
def self.foo
1
end
end
alias Bar = Foo
{% Bar %} # forces immediate resolution of `Bar`
private module Foo
def self.foo
10
end
end
module Baz
def self.foo
100
end
end
def foo(x)
x.foo
end
foo(Foo || Baz) &+ foo(Bar || Baz)
CRYSTAL
end

it "builds generic class bug" do
codegen(%(
abstract class Base
Expand Down
6 changes: 6 additions & 0 deletions src/compiler/crystal/types.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2935,6 +2935,12 @@ module Crystal
end

def to_s_with_options(io : IO, skip_union_parens : Bool = false, generic_args : Bool = true, codegen : Bool = false) : Nil
if codegen
if (namespace = instance_type.namespace).is_a?(FileModule)
namespace.to_s_with_options(io, generic_args: false, codegen: codegen)
io << "::"
end
end
io << @name
end

Expand Down

0 comments on commit 29e1b71

Please sign in to comment.