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 use none as a ?&Type #21213

Closed
spiveeworks opened this issue Apr 7, 2024 · 0 comments · Fixed by #21231
Closed

cannot use none as a ?&Type #21213

spiveeworks opened this issue Apr 7, 2024 · 0 comments · Fixed by #21231
Assignees
Labels
Bug This tag is applied to issues which reports bugs. Option Type Bugs/feature requests, that are related to `?Type`. Unit: cgen Bugs/feature requests, that are related to the default C generating backend. Unit: Checker Bugs/feature requests, that are related to the type checker.

Comments

@spiveeworks
Copy link
Contributor

spiveeworks commented Apr 7, 2024

Describe the bug

When a function takes an optional pointer, ?&T, passing none to the function gives a type error.

Reproduction Steps

fn takes_optional_pointer(maybe_ptr ?&int) int {
    if ptr := maybe_ptr {
        return *ptr
    } else {
        return 0
    }
}

fn main() {
    val := takes_optional_pointer(none)
    println("${val}")
}

Expected Behavior

The program should compile and run fine.

Current Behavior

It gives a type error.

optional_ptr_bug.v:10:35: error: cannot use `none` as `?&int` in argument 1 to `takes_optional_pointer`
    8 |
    9 | fn main() {
   10 |     val := takes_optional_pointer(none)
      |                                   ~~~~
   11 |     println("${val}")
   12 | }

Possible Solution

The way that type checking only requires Type rather than &Type for function arguments might be tripping up the type inference, making it think that only ?Type is needed, and thus treating none as a ?Type.

In fact I think before #21081 was fixed, it used to actually accept none and complete type checking and cgen, but then the c compiler would complain about the resulting C code, its complaint was something along the lines of __t0 was an __option_MyTypeHere when it should be an __option_MyTypeHere_ptr.

Additional Information/Context

Given that nil is considered unsafe, one would expect ?&Type to be a natural and valid way of passing optional pointers around. In Rust ?&Type takes up just as much memory as &Type of course, but in V it should at least behave as expected, even if it takes more memory and requires manipulation of unaligned memory to work.

Optional pointers are especially useful when making C bindings for functions that take multiple optional pointers.

fn C.my_fun(arg1 &Type1, arg2 &Type2)

fn my_fun_wrapper(arg1 ?&Type1, arg2 ?&Type2) {
    arg1_ptr := arg1 or { unsafe { nil } }
    arg2_ptr := arg2 or { unsafe { nil } }
    C.my_fun(arg1_ptr, arg2_ptr)
}

fn main() {
    my_fun_wrapper(none, none) // This gives an error! How annoying!
    my_fun_wrapper(?&Type1(none), ?&Type2(none)) // This works, but is so much less convenient than option types should be for a language like V
}

Changing the V wrapper to take ?Type1 and ?Type2 instead of ?&Type1 and ?&Type2 would add unnecessary stack allocation and copying, and potentially complicated default-initialization and cleanup, in order to simply call a C function that takes nullable pointers - nullable pointers are very common in C APIs!

V version

V 0.4.5 ad17be5

Environment details (OS name and version, etc.)

V full version: V 0.4.5 386bd77.ad17be5
OS: windows, Microsoft Windows 10 Pro v19045 64-bit
Processor: 4 cpus, 64bit, little endian,

getwd: C:\Users\Owner\Code\v-experiments
vexe: C:\Program Files\v\v.exe
vexe mtime: 2024-04-07 05:22:56

vroot: contains spaces, value: C:\Program Files\v
VMODULES: OK, value: C:\Users\Owner.vmodules
VTMP: OK, value: C:\Users\Owner\AppData\Local\Temp\v_0

Git version: git version 2.37.2.windows.2
Git vroot status: weekly.2024.14-26-gad17be5d (5 commit(s) behind V master)
.git/config present: true

CC version: Error: 'cc' is not recognized as an internal or external command,
operable program or batch file.

thirdparty/tcc: N/A

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.

@spiveeworks spiveeworks added the Bug This tag is applied to issues which reports bugs. label Apr 7, 2024
@felipensp felipensp added Unit: Checker Bugs/feature requests, that are related to the type checker. Option Type Bugs/feature requests, that are related to `?Type`. labels Apr 7, 2024
@felipensp felipensp self-assigned this Apr 8, 2024
@felipensp felipensp added the Unit: cgen Bugs/feature requests, that are related to the default C generating backend. label Apr 8, 2024
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. Option Type Bugs/feature requests, that are related to `?Type`. Unit: cgen Bugs/feature requests, that are related to the default C generating backend. Unit: Checker Bugs/feature requests, that are related to the type checker.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants