crystal-lang / crystal

The Crystal Programming Language
https://crystal-lang.org
Apache License 2.0
19.35k stars 1.62k forks source link

Disallow `Void` type in type restrictions except for C bindings #10657

Open straight-shoota opened 3 years ago

straight-shoota commented 3 years ago

The main purpose of the Void type is for C bindings where it represents no value. In Crystal's type system it maps to Nil. The philosophical difference is that a Nil value is still a value and not nothing. Practically, it doesn't have any effect.

There should be no reason to use the Void type in Crystal code for anything else but C interfaces.

And you can't really get a Void value in Crystal. It's just Nil. Void is already disallowed as a field type for lib structs. So why should it be valid in a Crystal struct?

I propose to disallow a plain Void type from any type restriction in Crystal except for lib functions. The only relevant use case is a void pointer indicating untyped memory. So Pointer(Void) should be allowed. Subsequently Void should probably be valid as a generic type argument for any generic type.

But any type restriction x : Void just doesn't make sense, nor does uninitialized Void which can even break the compiler (#5364).

Previous discussion: #10146

HertzDevil commented 3 years ago

IMO we should go one step further and represent void pointers as some other concrete type, say RawPointer, and make it so that Pointer(T) < RawPointer, keeping pointer arithmetic operations in the generic type. This RawPointer, like Int and Float, is never a union root (to prevent unions of different pointers from coalescing into void pointers).

Void* would still be allowed within libs (maybe outside libs too), but it would be the parser that transforms them into ::RawPointers, and any invalid use of Void results in a parsing error; thus Void will be gone during semantic analysis.

The main disadvantage is Pointer(T) forall T will no longer match void pointers, but I don't think this impacts the standard library, since types like Slice(Void) are ill-formed anyway.