You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It happens because the overloads of Foo2#foo need to be ordered, and in doing so the compiler looks up Foo1::Bar's definition as soon as the String overload is defined. At this point, Foo3 is indeed defined, and it inherits constants from Foo1, so Foo3::Bar is exactly Foo1::Bar, which explains why Foo1::Bar refers to itself. Similarly, an "undefined constant" error can be triggered this way by not forward declaring any types:
classFoo1aliasBar=Foo2::Bar|Foo3::Bar# Error: undefined constant Foo3::BarendclassFoo2 < Foo1classBar; enddeffoo(other : Foo1::Bar); end# okay, `Foo1` is defined up to this pointdeffoo(other : String); endendclassFoo3 < Foo1classBar; endend
I discovered this while trying to do this seemingly harmless refactor:
# src/float.crstructFloat64# `Foo1::Bar` corresponds to `Number::Primitive`# note that primitive number types are forward declared by the compiler itselfNumber.expand_div [Int::Primitive], Float64Number.expand_div [Float32], Float64end
A workaround is to also forward declare Bar1 before any methods are defined. On the other hand, making these examples work means that the compiler has to defer overload ordering to a later stage (contrast with #4897); resolving the aliases "beforehand" is not enough, because both aliases and defs are declared as they are read during the top-level phase.
The text was updated successfully, but these errors were encountered:
Here is another variant also triggered by the inheritance of namespaced constants:
classFoo1classBar; endendclassFoo2 < Foo1; enddeffoo(x : Foo1::Bar); enddeffoo(x : Foo2::Bar); end# at this point `Foo2::Bar` is identical to `Foo1::Bar`, so this is a# redefinition and the first overload disappearsclassFoo2::Bar; end
foo(Foo1::Bar.new) # Error: no overload matches 'foo' with type Foo1::Bar
The following code reports an improper recursive alias even though there are none:
It happens because the overloads of
Foo2#foo
need to be ordered, and in doing so the compiler looks upFoo1::Bar
's definition as soon as theString
overload is defined. At this point,Foo3
is indeed defined, and it inherits constants fromFoo1
, soFoo3::Bar
is exactlyFoo1::Bar
, which explains whyFoo1::Bar
refers to itself. Similarly, an "undefined constant" error can be triggered this way by not forward declaring any types:I discovered this while trying to do this seemingly harmless refactor:
A workaround is to also forward declare
Bar1
before any methods are defined. On the other hand, making these examples work means that the compiler has to defer overload ordering to a later stage (contrast with #4897); resolving the aliases "beforehand" is not enough, because both aliases and defs are declared as they are read during the top-level phase.The text was updated successfully, but these errors were encountered: