Open tzekid opened 7 years ago
To reproduce:
def main(options, arguments : Array(String))
end
main("foo", ["bar", "baz"])
Looks like your def main
collides with fun main
which is probably the only fun outside a lib - and ofc also defined in the empty prelude.
A minimal sample to reproduce doesn't even to call main
itself:
def main(options, arguments : Array(String))
end
At the very least we should have a nicer error message for this.
Yes, the parser could prevent to define a method named main
as a special case. Or, better find a way around this. From inside a Crystal program you'll never need to call the main
function so this could perhaps be fixed with proper scoping or - as a naive approach - transparently renaming main
method and calls.
Error in line 1: while requiring "prelude"
in /usr/lib/crystal/prelude.cr:39: while requiring "crystal/main": BUG: called Pointer(Pointer(UInt8)).restriction_of?(Array(String))
require "crystal/main"
^
I think we need to use a different name for main
, maybe __main
, or even __crystal_main
. Then the compiler could look up that name to define the C main
function, but allowing users to define main
methods without conflict.
fun main
is already defined in the prelude, we should just disallow a def
with the same name.
The compiler shouldn't assume the main
method name, it already pregenerates __crystal_main
. Having fun main
be defined in crystal makes a bunch of usecases possible, such as using SDL.
Yes. What I'm saying is, there's no need to use main for the C function. It's more common to define a main top level method. Or, put another way, no other language prevents you from using main (or any other non keyword name) as a name.
If you want to change the symbol mangling so that fun
and top-level-def
with the same name don't collide I'm fine with that. Changing around how fun main
works right now I'm not so sure...
I actually see no problem with not being able to define fun main
to redefine main
, that's what we have redefine_main
for, no?
I was thinking that maybe top-level fun
could be implicitly added to LibC
, and only called by doing LibC.whatever
. That way fun main
(or any other fun, for that matter) would never conflict with a main
method.
I like the idea of another namespace for toplevel funs, but not with adding them to LibC, since the manually defined functions are usually not related to libc.
Maybe something more like ExternalFunctions
.
Note: A "long" module name is not a problem I think, because those functions are usually not called by crystal code (or very occasionally).
I actually see no problem with not being able to define
fun main
to redefinemain
, that's what we haveredefine_main
for, no?
We removed redefine_main
in favour of this commit: https://github.com/crystal-lang/crystal/commit/5f0fe1c09a93a8b5f53f3cb8db99af2f03644096
I like that as-is.
I like that as-is.
@RX14 As-is generates the error linked above in https://github.com/crystal-lang/crystal/issues/4761#issuecomment-429661099
Yes. The error should be improved. But I don't think the ability to define a top-level def main
(this has been complained about once in the 2.5 years since that commit) is worth changing it around.
I think the easiest solution is to disallow overriding fun
with def
and vice versa.
We can consider some options to disambiguate with mangling as a next step. But I don't really see too many good reasons for that.
I tried out an old project and got a rather strange error.
The project is bindgencr. Unfortunately I don't really know what the root cause of the bug / error is, but (at least on my system) it can be easily reproduced by downloading the rep. and running the sample code.
Here's an example:
I've tried running it with the
--prelude=empty
flag, but that gives out the same output as before.My setup info: