Skip to content

Conversation

darkestpigeon
Copy link

Right now an object with an RwLock field can't be properly initialized (myobj.rwLock = createRwLock() fails due to a deleted move constructor). This PR addresses this by introducing an in-place initializer (init(myobj.rwLock)).

@Araq
Copy link
Member

Araq commented Oct 17, 2024

No, instead myobj.rwLock = createRwLock() should compile and treated as a move. The RwLock type needs to be marked with byref for this to work.

@darkestpigeon
Copy link
Author

@Araq checked out byref in the manual, but am still puzzled how this will work in this case.
I have some structure that is shared by multiple threads, and is effectively passed around via a pointer. The structure shouldn't be moved around for the pointer to remain valid. The lock is part of this structure, and must be created in-place or moved in. It can't be moved in since the move constructor is deleted. How does byref help?

@planetis-m
Copy link
Contributor

Related: #75

@darkestpigeon
Copy link
Author

darkestpigeon commented Oct 17, 2024

Checked out the discussion in #75. Still don't understand how byref is relevant. I need RwLock to occupy a specific chunk of memory. How will byref help with this?

@darkestpigeon
Copy link
Author

darkestpigeon commented Oct 17, 2024

By the way, perhaps the compiler could be patched so that in constructions like

var x: T
x = fn()

or

obj.x = fn()

the special result variable would reuse the already allocated var x or obj.x instead of making a new allocation on the stack. This would remove the need for an in-place constructor for types with deleted copy and sink.
This could be problematic for stuff like x = fn(x), but for types with copy and sink deleted this doesn't make much sense anyway.

@Araq
Copy link
Member

Araq commented Oct 17, 2024

the special result variable would reuse the already allocated var x or obj.x instead of making a new allocation on the stack.

That is what I mean with .byref, yes.

@darkestpigeon
Copy link
Author

No, instead myobj.rwLock = createRwLock() should compile and treated as a move. The RwLock type needs to be marked with byref for this to work.

I have a following toy example

type MyObj {.byref.} = object
  value: int

proc `=copy`(a: var MyObj, b: MyObj) {.error.}
proc `=sink`(a: var MyObj, b: MyObj) {.error.}

proc createMyObj(value: int): MyObj =
  result.value = value

var x: MyObj
x = createMyObj(3)

This doesn't compile ('=sink' is not available for type <MyObj>).

Nim Compiler Version 2.2.0 [Linux: amd64]
Compiled at 2024-10-02
Copyright (c) 2006-2024 by Andreas Rumpf

git hash: 78983f1876726a49c69d65629ab433ea1310ece1
active boot switches: -d:release

@Araq what am I doing wrong here?

@Araq
Copy link
Member

Araq commented Oct 18, 2024

@Araq what am I doing wrong here?

We need to teach the compiler new tricks first. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants