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

Assignment overloading: infinite recursion even with system.= #13024

Open
mratsim opened this issue Jan 3, 2020 · 6 comments
Open

Assignment overloading: infinite recursion even with system.= #13024

mratsim opened this issue Jan 3, 2020 · 6 comments
Labels
Destructors Documentation Content Related to documentation content (not generation).

Comments

@mratsim
Copy link
Collaborator

mratsim commented Jan 3, 2020

The following will lead to infinite Hello World being printed

type
  Foo = object
  Bar = object
    foo: Foo


proc `=`*(dest: var Foo, src: Foo) =
  echo "hello World!"
  system.`=`(dest, src)

proc initFoo(): Foo =
  discard

proc initBar(foo: Foo): Bar =
  result.foo = foo

let x = initFoo()

let y = initBar(x)

Having local variables instead works (cc @Clyybber)

type
  Foo = object
  Bar = object
    foo: Foo


proc `=`*(dest: var Foo, src: Foo) =
  echo "hello World!"
  system.`=`(dest, src)

proc initFoo(): Foo =
  discard

proc initBar(foo: sink Foo): Bar =
  echo "hi"
  result.foo = foo
  echo "ho"

proc main =
  let x = initFoo()
  echo "ha"
  let y = initBar(x)

main()
@mratsim
Copy link
Collaborator Author

mratsim commented Jan 3, 2020

And a slightly different case, adding a =sink recreates the problem even with a main proc

type
  Foo = object
  Bar = object
    foo: Foo

proc `=sink`*(dst: var Foo, src: Foo) {.inline.}

proc `=`*(dest: var Foo, src: Foo) =
  echo "hello World!"
  system.`=`(dest, src)

proc `=sink`*(dst: var Foo, src: Foo) {.inline.} =
  system.`=sink`(dst, src)

proc initFoo*(): Foo =
  discard

proc initBar*(foo: sink Foo): Bar =
  echo "hi"
  result.foo = foo
  echo "ho"

proc main =
  let x = initFoo()
  echo "ha"
  let y = initBar(x)

main()

The forward declaration is a workaround for #13025

@mratsim
Copy link
Collaborator Author

mratsim commented Jan 3, 2020

Ah it was not local variables but the sink annotation that solved the issue here, this recurses infinitely:

type
  Foo = object
  Bar = object
    foo: Foo

proc `=`*(dest: var Foo, src: Foo) =
  echo "hello World!"
  system.`=`(dest, src)

proc initFoo*(): Foo =
  discard

proc initBar*(foo: Foo): Bar =
  echo "hi"
  result.foo = foo
  echo "ho"

proc main =
  let x = initFoo()
  echo "ha"
  let y = initBar(x)

main()

@mratsim mratsim changed the title Assignment overloading for globals: infinite recursion even with system.= Assignment overloading: infinite recursion even with system.= Jan 3, 2020
mratsim added a commit to mratsim/weave that referenced this issue Jan 3, 2020
@cooldome
Copy link
Member

cooldome commented Jan 5, 2020

Hi @mratsim,
Could you please describe what you are trying to achieve?
The = in system is just a stub that will get resolved to a type specific assignment later on. It is not any different from a = b. It is possible to fix forced forward declaration for destructors, but infinite recursion is here to stay IMO.

Possibly you wanted:

`=`(ParentType(a), ParentType(b))

@mratsim
Copy link
Collaborator Author

mratsim commented Jan 6, 2020

It can be closed as won't fix then. However, I expect others will encounter this issue as in the past this was the recommended pattern to overload = (when it worked), so an example would be nice in the destructors documentation.

I was trying to do custom atomic ref counting. So after discussing with @Araq what I wanted to do is:

type
  Foo = object
    p: FooImpl
  FooImp = ptr object

proc `=`(dst: var Foo, src: Foo) =
  # refcounting goes here
  system.`=`(dst.p, src.p) # Notice that I don't copy the dst/src but the fields to avoid recursion

@mratsim mratsim added the Documentation Content Related to documentation content (not generation). label Jan 6, 2020
@shirleyquirk
Copy link
Contributor

only the =sink version recurs on devel (1.1.1)

@nim-lang nim-lang deleted a comment from shirleyquirk Apr 3, 2020
@mratsim
Copy link
Collaborator Author

mratsim commented Apr 3, 2020

(deleting duplicate comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Destructors Documentation Content Related to documentation content (not generation).
Projects
None yet
Development

No branches or pull requests

3 participants