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

mut and & confusion #21832

Closed
pd-giz-dave opened this issue Jul 9, 2024 · 4 comments
Closed

mut and & confusion #21832

pd-giz-dave opened this issue Jul 9, 2024 · 4 comments
Labels
Bug This tag is applied to issues which reports bugs.

Comments

@pd-giz-dave
Copy link

pd-giz-dave commented Jul 9, 2024

Describe the bug

Attempt to compile this:

module main
@[heap]
struct Logger {}
struct Thing {
mut:
	logger &Logger
}
fn new_logger() &Logger {
	return &Logger{}
}
fn step(mut logr &Logger) Thing {
	return Thing{logger: logr}
}
fn main()  {
	mut logr := new_logger()
	thing := step(mut logr)
}

It generates a compiler error of:

compiler_bugs/main.v:12:15: error: cannot assign to field `logger`: expected `&Logger`, not `&&Logger`
   10 | }
   11 | fn step(mut logr &Logger) Thing {
   12 |     return Thing{logger: logr}
      |                  ~~~~~~~~~~~~
   13 | }
   14 | fn main()  {

Reproduction Steps

Attempt to compile the source of above

Expected Behavior

I expect it to compile

Current Behavior

Compiler error of: error: cannot assign to field logger: expected &Logger, not `&&Logger'

Possible Solution

No response

Additional Information/Context

No response

V version

V 0.4.6 66ea826

Environment details (OS name and version, etc.)

dave@dave-mini-pc~/.../fellsafe/v >>> v doctor
V full version: V 0.4.6 294f7e4.66ea826
OS: linux, "EndeavourOS Linux"
Processor: 16 cpus, 64bit, little endian, AMD Ryzen 7 5800H with Radeon Graphics

getwd: /home/dave/precious/fellsafe/v
vexe: /home/dave/v/v
vexe mtime: 2024-07-08 15:23:28

vroot: OK, value: /home/dave/v
VMODULES: OK, value: /home/dave/.vmodules
VTMP: OK, value: /tmp/v_1000

Git version: git version 2.45.2
Git vroot status: weekly.2024.27-32-g66ea8260
.git/config present: true

CC version: cc (GCC) 14.1.1 20240522
thirdparty/tcc status: thirdparty-linux-amd64 40e5cbb5

Note

You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote.
Other reactions and those to comments will not be taken into account.

@pd-giz-dave pd-giz-dave added the Bug This tag is applied to issues which reports bugs. label Jul 9, 2024
@JalonSolov
Copy link
Contributor

mut adds an implicit &, since you have to pass by reference to access the original in order to modify it. So mut log &Logger == log &&Logger... in other words, a pointer to a pointer to a Logger instance,

@pd-giz-dave
Copy link
Author

Yes, but the compiler insists on the 'mut' in the step call.
Coming from a 'C' like environment I get very confused in V about the use of mut and &
So is the 'fix' to remove the '&' everywhere and just rely on 'mut' to ensure aobjects are passed by reference and not copied?
In my struct I want a reference to an object, not a copy.

@JalonSolov
Copy link
Contributor

Yes, it is confusing... until you realize a mut parameter has to be a reference.

mut implies a reference, since you can't modify the original without a reference. Without a reference, you get a copy on the stack.

So yes, using mut logr Logger is correct to get a reference to a Logger instance named logr.

@pd-giz-dave
Copy link
Author

Thanks. I've unconfused myself.
In my mind a 'mut' was merely allowing the compiler to tolerate an assign; reference, or not, was up to me.
That is clearly incorrect.
It may be helpful if the documentation explicitly stated that mut implies a reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug This tag is applied to issues which reports bugs.
Projects
None yet
Development

No branches or pull requests

2 participants