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

Cannot for-loop with a distinct type in a generic proc #12086

Open
mratsim opened this issue Aug 29, 2019 · 1 comment
Open

Cannot for-loop with a distinct type in a generic proc #12086

mratsim opened this issue Aug 29, 2019 · 1 comment

Comments

@mratsim
Copy link
Collaborator

mratsim commented Aug 29, 2019

This is an advanced version of #12074 and probably a case of #8677 or #11225.

This makes distinct types very hard to use.

Take #12074 (whi was fixed)

# distinct_for_loop.nim

type
  Slot = distinct uint64

proc inc(x: var Slot, y = 1){.borrow.}
proc `..`(a, b: Slot): Slice[Slot]{.borrow.}
proc `<`(a, b: Slot): bool{.borrow.}

# This works, inc is visible
var x: Slot
inc x
echo "x: ", x.uint64

# This work after https://github.com/nim-lang/Nim/pull/12080
for y in Slot(0) ..< Slot(10):
  echo "y: ", y.uint64

Spread it on 3 files and hide it in a generic proc

# dforloop1.nim
type
  Slot* = distinct uint64

proc inc*(x: var Slot, y = 1){.borrow.}
proc `..`*(a, b: Slot): Slice[Slot]{.borrow.}
proc `<`*(a, b: Slot): bool{.borrow.}

var x: Slot
inc x
echo "x: ", x.uint64
# dforloop2.nim
import dforloop1

proc foo*[T](a: T) =
  mixin inc, `..`, `<`
  for y in Slot(0) ..< Slot(10):
    echo "y: ", y.uint64
# dforloop3.nim
import dforloop2

foo(10)

Compile dforloop3

Error: type mismatch: got <Slot, Slot>
but expected one of: 
proc `<`(x, y: pointer): bool
  first type mismatch at position: 1
  required type for x: pointer
  but expression 'i' is of type: Slot
proc `<`[Enum: enum](x, y: Enum): bool
  first type mismatch at position: 1
  required type for x: Enum: enum
  but expression 'i' is of type: Slot
...
...
...
@jangko
Copy link
Contributor

jangko commented Nov 20, 2019

iirc we can use export as a work around. in dforloop2.nim we can export those mixin symbols.
it has been known from long time ago that nim generic proc instantiation + it's instantiation cache can create confusion.
I have not look into the depth, but I suspect the generic instantiation cache mechanism 'remember' the wrong instantiation scope. similar with 'dynamicBindSym', it requires some tricks to keep the required scope alive and not washed away when involve multiple modules. and those tricks can be 'dirty'.

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

3 participants