Open HertzDevil opened 3 years ago
I think you are right but ai can't understand what is a proposal and what is currently working the way you say. Could you clarify what are the proposed changes, and how, if you want to generically call new on a bunch of types that inherit from an abstract type, make that work?
Follow-up to https://github.com/crystal-lang/crystal/issues/5956#issuecomment-731856760.
There is no such thing as an abstract base metaclass in Crystal; as long as you can name a type, that type is already an instance of its metaclass, even if the user never explicitly instantiates the type object. Besides, code like this is perfectly legal:
Thus it is erroneous to declare
Foo.class
itself as an abstract type.The differences become apparent when virtual types involving metaclasses are resolved into concrete types. Suppose we have
When
Base.class
is abstract,typeof(Base, Derived)
is the virtual typeBase.class+
.Base.class+
include onlyDerived.class
, because they cannot containBase.class
, which is abstract.Derived.class#foo
is defined, thereforeBase.class+#foo
is fully defined. Thus the code compiles even thoughBase.foo
leads to undefined behaviour.When
Base.class
is not abstract,typeof(Base, Derived)
is the virtual typeBase+.class
.Base+.class
areBase.class
andDerived.class
.Base.class#foo
is not defined, therefore callingBase+.class#foo
is a compile-time error.Now also consider the example from #3835:
Suppose
Foo.class#new
is not defined (the compiler detects theFoo.new
errors through a different mechanism). The code would still compile, sinceFoo.class
is abstract and the concrete types ofFoo.class+
must all define#new
. But ifa[0]
is typed to beFoo+.class
, then due to our supposition the code would fail to compile, because the last line requires a definition ofFoo.class#new
.This will be a breaking change but I can't think of a scenario where the current behaviour is desirable.