Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

regression: {.pure.} pragma fails to hide enum #16462

Open
geekrelief opened this issue Dec 24, 2020 · 14 comments
Open

regression: {.pure.} pragma fails to hide enum #16462

geekrelief opened this issue Dec 24, 2020 · 14 comments

Comments

@geekrelief
Copy link
Contributor

Compiling with 979148e breaks compilation of https://github.com/pragmagic/godot-nim

Current Output

C:\godot\gdnim\deps\godot\core\poolarrays.nim(128, 16) template/generic instantiation of definePoolArray from here
C:\godot\gdnim\deps\godot\core\poolarrays.nim(49, 26) Error: type expected, but got symbol 'Array' of kind 'enumField'

Expected Output

This compiled without error before.

Additional Information

979148e breaks.
Two modules are involved. https://github.com/pragmagic/godot-nim/blob/master/godot/core/poolarrays.nim and https://github.com/pragmagic/godot-nim/blob/master/godot/core/arrays.nim

poolarrays has a template that fails because Array is not found.

template definePoolArray(T, GodotT, DataT, fieldName, newProcName, initProcName;
                         noData = false) =

  proc newProcName*(arr: Array): T {.inline.} =
    #new(result, poolArrayFinalizer)
    new(result)
    initProcName(result.fieldName, arr.godotArray[])

poolarrays imports arrays online 125.

import arrays

definePoolArray(PoolByteArray, GodotPoolByteArray, uint8,
                godotPoolByteArray, newPoolByteArray,
                initGodotPoolByteArray)
@timotheecour
Copy link
Member

timotheecour commented Dec 27, 2020

@geekrelief can you reduce this to an example with just 2 (say mod1, mod2) modules and no imports besides mod1 importing mod2 or vice versa?
this would be needed anyways for regression tests

@geekrelief
Copy link
Contributor Author

Yes, I'll make this my next priority. Thanks!

@geekrelief
Copy link
Contributor Author

It's actually an issue with the {.pure.} pragma

#v.nim
type
  V* {.pure.} = enum
    A
#test.nim
import v

template defA() =
  proc onA(a:A) =
    echo A.val

type 
  A* = object
    val: int

defA()

nim c test produces

Error: type expected, but got symbol 'A' of kind 'enumField'

V.A should be hidden with the pure pragma per the manual. https://nim-lang.org/docs/manual.html#pragmas-pure-pragma

@geekrelief geekrelief changed the title commit 979148e86 breaks compilation {.pure.} pragma fails to hide enum Dec 29, 2020
@metagn
Copy link
Collaborator

metagn commented Jan 1, 2021

V.A should be hidden with the pure pragma per the manual.

There was discussion about this in #8066. For now {.pure.} not providing a full restriction is intended. Your code example should be fixed by changing template defA() = to template defA(): untyped =, or adding mixin A below. If you still think the issue is "{.pure.} doesn't work" then #12893 exists and this would be a duplicate, but I don't think that's the issue here and this is a more specific result (perhaps even intended).

@geekrelief
Copy link
Contributor Author

Those issues you referenced are quite old. This was working until pretty recently.

I tried both of your suggestions. Adding untyped produces the same error. Adding mixin A produces this:

Error: type expected, but got: <<0th child missing for nkOpenSymChoice >>

@metagn
Copy link
Collaborator

metagn commented Jan 1, 2021

Ok, my point is that something did change, but you shouldn't change the issue title to "{.pure.} doesn't work", because that's an old issue and not the problem here. The incremental compilation commit broke something with symbols as the mixin error shows.

@geekrelief
Copy link
Contributor Author

I was trying to be more helpful with the title. Would you prefer I change it to something else?

@timotheecour timotheecour changed the title {.pure.} pragma fails to hide enum regression: {.pure.} pragma fails to hide enum Jan 2, 2021
@ghost
Copy link

ghost commented Mar 6, 2021

#15935 also breaks https://github.com/ftsf/nico - ftsf/nico#49 (not sure if this is the same bug):

# a.nim
import sdl except Scancode
import other

let a = SCANCODE_LEFT
# other.nim
type
  Scancode* = enum
    SCANCODE_LEFT = 80
# sdl.nim
type
  Scancode* = enum
    SCANCODE_LEFT = 80

The error is:

Error: ambiguous identifier: 'SCANCODE_LEFT' -- use one of the following:
 Scancode.SCANCODE_LEFT: Scancode
 Scancode.SCANCODE_LEFT: Scancode

@jyapayne
Copy link
Contributor

jyapayne commented May 3, 2021

@geekrelief this can also be worked around by declaring the template underneath the type declaration like so:

#v.nim
type
  V* {.pure.} = enum
    A

#test.nim
import v

type 
  A* = object
    val: int

template defA() =
  proc onA(a:A) =
    echo A.val

defA()

jyapayne added a commit to jyapayne/godot-nim that referenced this issue May 3, 2021
Fixes pragmagic#81 

Alternate workaround for nim-lang/Nim#16462 without changing VariantType.
endragor pushed a commit to pragmagic/godot-nim that referenced this issue May 3, 2021
Fixes #81 

Alternate workaround for nim-lang/Nim#16462 without changing VariantType.
@geekrelief
Copy link
Contributor Author

geekrelief commented May 3, 2021

@jyapayne Thanks for the suggestion. I saw the commit for godot-nim, and it helps for that case. But this issue popped up again in another place when I implemented signal declarations and got a name clash with VariantType.Object and type Object defined in godotapi/godottypes.nim. For now, I've renamed the enum identifiers following https://nim-lang.org/docs/nep1.html naming conventions.

@jyapayne
Copy link
Contributor

jyapayne commented May 6, 2021

Ah, I see. You're right that there's another clash down the line.

@Araq do you have any advice on where this could be fixed? I'm interested in attempting to fix the issue

@jyapayne
Copy link
Contributor

jyapayne commented May 6, 2021

Or @timotheecour :)

@Araq
Copy link
Member

Araq commented May 7, 2021

We should do this nim-lang/RFCs#373 (comment)

In general, the compiler must produce sym choices that are then collapsed taking into account more context. For example in param: Type we know Type is an skType. And then we should ignore the "pure" enum annotation altogether, there should only be enums in Nim, not "pure enums". But I suspect this to be highly controversial...

ringabout added a commit to ringabout/Nim that referenced this issue Apr 6, 2022
@ringabout
Copy link
Member

Hello @Yardanico, the pure enum version of your example works in devel

# a.nim
import sdl except Scancode
import other

let a = SCANCODE_LEFT
# other.nim
type
  Scancode* {.pure.} = enum
    SCANCODE_LEFT = 80
# sdl.nim
type
  Scancode* {.pure.} = enum
    SCANCODE_LEFT = 80

see also: #19692

Araq pushed a commit that referenced this issue Apr 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants