odin-lang / Odin

Odin Programming Language
https://odin-lang.org
BSD 3-Clause "New" or "Revised" License
6.59k stars 575 forks source link

Weird compile output when using `Maybe` type in union definition #3503

Open Guimica-gml opened 4 months ago

Guimica-gml commented 4 months ago

Context

I was writing an union to be a wrapper for a single type, because you can't have type aliases with generics, at least I think you can't (if someone knows how to, please tell me)

The code is:

Type :: struct($T: typeid) {
    index: int,
}

Wrapper :: union($T: typeid) {
    Maybe(Type(T)),
}

Which is really simple, there's literally nothing else to the code for some reason the compiler gives me this error:

odin run . -out:main
/home/{user}/.odin/base/runtime/core_builtin.odin(6:29) Invalid use of a non-specialized polymorphic type 'T'
    Maybe :: union($T: typeid) {T}
                                ^

I have no idea why it would give me an error on the core library of odin, is this normal and I'm doing something i'm not supposed to with types/unions? If I remove Maybe from the type it doesn't show nay errors. Even if this is normal behavior it really doesn't clarify what is the issue very well.

note: I have noticed after some time that I don't actually need the Maybe because since it is an union it can already be of value nil anyway, but I'm opening this issue anyway because I feel that the error message is at least strange.

Expected Behavior

Given how simple the types are, I would expect it to compile without any error messages, or at least give a better error message.

Current Behavior

Already explained in Context section.

Feoramund commented 4 months ago

You say you can't have type aliases with generics. Does the following program not do what you want?

package main

Type :: struct($T: typeid) {
    var: T,
}

Type_Int :: Type(int)

main :: proc () {
    a: Type_Int
    a.var = 42
}

Or did you mean something like Type_Int :: Type?

Maybes in Odin are already unions, as you've noted.

Guimica-gml commented 4 months ago

You say you can't have type aliases with generics. Does the following program not do what you want?

package main

Type :: struct($T: typeid) {
  var: T,
}

Type_Int :: Type(int)

main :: proc () {
  a: Type_Int
  a.var = 42
}

Or did you mean something like Type_Int :: Type?

Maybes in Odin are already unions, as you've noted.

Yes, this would work really well. There is a really small "issue" about it.

main :: proc () {
    a: Type_Int
    a.var = 42
}

In your example you still have to access the field var in order to assign the value, and I wanted something that looks more like:

Map :: alias($K: tyepid, $V: typeid) map[K]V // this is not possible in Odin (and also, I'm not saying it should)
a: Map(string, i32)

// your example is too simple, so I changed it to a map, but your example would look like:
Type :: alias($T: tyepid) T
a: Type(i32) = 69

It's a really small thing tho and your example is probably the best way to it. I just opened the issue because when I posted this on discord, people there said it could be a possible bug. (updated post for clarity)

Feoramund commented 4 months ago

If you want to preserve the Maybe functionality (allowing your example above with simple assignment), you can define an alias Type_Int :: Maybe(int). If you want to use a different name than Maybe, then Option :: Maybe works.

I'm not sure what else you might want to accomplish beyond those two though. I would need to know more about the end goal.

Guimica-gml commented 4 months ago

If you want to preserve the Maybe functionality (allowing your example above with simple assignment), you can define an alias Type_Int :: Maybe(int). If you want to use a different name than Maybe, then Option :: Maybe works.

I'm not sure what else you might want to accomplish beyond those two though. I would need to know more about the end goal.

The issue isn't really about having aliases tho, I did use what you are commenting and it did work. I opened the issue because of the error message that odin gives you is really strange and when someone on discord asked if it was intended behavior, gingerBill, the creator of the language, said it would probably be a bug, so I opened this issue. I probably should have changed the wording of the issue to make this clearer.