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

Option smartcast after non-option assignment #23611

Open
quaesitor-scientiam opened this issue Jan 29, 2025 · 5 comments
Open

Option smartcast after non-option assignment #23611

quaesitor-scientiam opened this issue Jan 29, 2025 · 5 comments
Labels
Feature/Enhancement Request This issue is made to request a feature or an enhancement to an existing one.

Comments

@quaesitor-scientiam
Copy link

quaesitor-scientiam commented Jan 29, 2025

V version: V 0.4.9 a6a8e4c, press to see full `v doctor` output
V full version V 0.4.9 45fd7eb.a6a8e4c
OS windows, Microsoft Windows 11 Pro 26100 64-bit
Processor 24 cpus, 64bit, little endian, AMD Ryzen 9 5900X 12-Core Processor
Memory 76.58GB/127.92GB
V executable S:\repo\vlang\v.exe
V last modified time 2025-01-29 18:20:27
V home dir OK, value: S:\repo\vlang
VMODULES OK, value: C:\Users\john3.vmodules
VTMP OK, value: C:\Users\john3\AppData\Local\Temp\v_0
Current working dir OK, value: S:\vProjects\testit
Git version git version 2.45.1.windows.1
V git status weekly.2025.04-67-ga6a8e4c9
.git/config present true
cc version N/A
gcc version gcc (MinGW-W64 x86_64-ucrt-posix-seh, built by Brecht Sanders, r2) 14.2.0
clang version (built by Brecht Sanders, r2) clang version 19.1.1
msvc version N/A
tcc version tcc version 0.9.27 (x86_64 Windows)
tcc git status thirdparty-windows-amd64 b425ac82
emcc version N/A
glibc version N/A

What did you do?
./v -g -o vdbg cmd/v && ./vdbg -cg testit.v && S:\vProjects\testit\testit.exe

module main

pub struct Foo {
	mut:
	test bool
}
pub fn Foo.init() Foo {
	return Foo{test: false}
}


fn what(mut foo ?Foo) {
	if foo == none {
		foo = Foo.init()
		foo.test = true
	}
}

fn main() {
	what(none)
}

What did you see?

testit.v:20:7: warning: automatic referencing/dereferencing is deprecated and will be removed soon (got: 0 references, expected: 1 references)
   18 | 
   19 | fn main() {
   20 |     what(none)
      |          ~~~~
   21 | }
testit.v:15:7: error: cannot access fields of an Option, handle the error with `or {...}` or propagate it with `?`
   13 |     if foo == none {
   14 |         foo = Foo.init()
   15 |         foo.test = true
      |             ~~~~
   16 |     }
   17 | }
testit.v:20:7: error: function `what` parameter `foo` is `mut`, so use `mut none` instead
   18 | 
   19 | fn main() {
   20 |     what(none)
      |          ~~~~
   21 | }

What did you expect to see?

clean build

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.

Copy link

Connected to Huly®: V_0.6-22036

@spytheman
Copy link
Member

spytheman commented Jan 29, 2025

The what(none) errors are irrelevant to the problem.
Only this block is:

if foo == none {
		foo = Foo.init()
		foo.test = true
}

since after foo = Foo.init(), foo is guaranteed to be a Foo value, and in the lines that follow, its fields should be accessible.

@jorgeluismireles
Copy link

I only can get rid of warnings and errors until Foo was a member of another struct Bar:

pub struct Foo {
mut:
	test bool
}

struct Bar {
mut:
	foo ?Foo
}

fn (mut b Bar) what() {
	if b.foo != none { 
		b.foo.test = true
	}
}

fn main() {
	mut b1 := Bar{ } // foo remains none
	b1.what()
	println('${b1.foo}') // Option(none)
	mut b2 := Bar{ foo:Foo{} }
	b2.what()
	println('${b2.foo}') // Option(Foo{test:true})
}

@quaesitor-scientiam
Copy link
Author

That doesn't solve the issue unfortunately

@JalonSolov
Copy link
Contributor

No, it doesn't. That will have to be done with a bug fix.

The workaround, as @spytheman said yesterday in discord, would be to create a new variable, and assign that to foo at the end of the if statement:

if foo == none {
	mut newfoo := Foo.init()
	newfoo.test = true
	foo = newfoo
}

@felipensp felipensp added the Feature/Enhancement Request This issue is made to request a feature or an enhancement to an existing one. label Jan 31, 2025
@felipensp felipensp changed the title Bug build with mutable optional Option smartcast after non-option assignment Jan 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature/Enhancement Request This issue is made to request a feature or an enhancement to an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants