Describe the bug
// main.v
fn main() {
// ...
db := client.create_db('my_db') or {
match err {
types.AdministratorRequired {
panic("admin is required")
}
types.InvalidDBName {
panic("Database name not allowed")
}
types.DatabaseAlreadyExists {
types.DB { // Should be returned (Line 56)
name: "my_db"
}
}
else {
panic(err)
}
}
}
}
Results in compiler error:
main.v:56:11: error: return type mismatch, it should be `void`
54 | }
55 | types.DatabaseAlreadyExists {
56 | types.DB {
| ~~~~
57 | name: "my_db"
58 | }
Well, this should be fine, lets just create some boilerplate after the match statement that returns a type.DB{} struct, to let the compiler infer the return type of or.
// main.v
fn main() {
// ...
db := client.create_db('my_db') or {
match err {
types.AdministratorRequired {
panic("admin is required")
}
types.InvalidDBName {
panic("Database name not allowed")
}
types.DatabaseAlreadyExists {
types.DB { // Should be returned (Line 56)
name: "my_db"
}
}
else {
panic(err)
}
}
types.DB { // This shouldn't be seen and is to only let V infer the return type. This is returned and causes everything else to be ignored.
name: "Should never see this"
}
}
}
Unfortunately, it seems like everything in the block is ignored if something is returned at all in or
Console Output:
types.DB{
name: 'Should never see this'
}
- For the purposes of this report the implementation of
create_db function is not important, but is provided below for completeness.
// client.v
// create_db Performs a request to create a database on CouchDB
//
// Possible errors are: `types.InvalidDBName` `types.AdministratorRequired` `types.DatabaseAlreadyExists` `IError`
pub fn (client &Client) create_db(name string) !types.DB {
response := http.fetch(client.gen_fetch_config("${client.host.str()}/$name", http.Method.put, ''))!
return match response.status_code {
201 {
types.DB{name}
}
202 {
types.DB{name}
}
400 {
types.InvalidDBName{}
}
401 {
types.AdministratorRequired{}
}
412 {
types.DatabaseAlreadyExists{}
}
else {
error(response.body)
}
}
}
// types/db.v
// ...
pub struct InvalidDBName {
Error
}
pub fn (_ &InvalidDBName) msg() string {
return 'An invalid name was provided'
}
// This error can be safely recovered from, and easily ignored
pub struct DatabaseAlreadyExists {
Error
}
pub fn (_ &DatabaseAlreadyExists) msg() string {
return 'A database with this name already exists'
}
Expected Behavior
Everything in the or block should be ran, or have the or block act infer its return type based on the expected result type of the function.
Currently the expected type of return for an or block is void.
main.v:56:11: error: return type mismatch, it should be `void`
54 | }
55 | types.DatabaseAlreadyExists {
56 | types.DB {
| ~~~~
57 | name: "my_db"
58 | }
Unless a return is given at the root level of or.
Current Behavior
Please see "Describe the bug"
Reproduction Steps
// main.v
module main
struct MySpecialError {
Error
}
struct MyStruct {
pub:
name string
}
fn (_ &MySpecialError) msg() string {
return 'My special error'
}
fn do_a_thing(arg1 string, arg2 bool) !MyStruct {
// ..
if arg2 {
return MySpecialError{}
}
return MyStruct{
name: arg1
}
}
fn main() {
data := do_a_thing('my_db', true) or {
match err {
MySpecialError {
MyStruct{
name: 'my_db'
}
}
else {
panic(err)
}
}
MyStruct{
name: "shouldn't get this"
}
}
println(data)
}
Possible Solution
// main.v
fn main() {
// ...
// We know the return type of client.create_db is !types.DB, this should automatically be inferred by the `or` block
db := client.create_db('my_db') or { // Expect return type of types.DB, or [noreturn] function
match err {
types.AdministratorRequired {
panic("admin is required")
}
types.InvalidDBName {
panic("Database name not allowed")
}
types.DatabaseAlreadyExists {
types.DB { // This is returned
name: "my_db"
}
}
else {
panic(err)
}
}
}
}
Additional Information/Context
No response
V version
V 0.3.3 c7237b1
Environment details (OS name and version, etc.)
OS Name Microsoft Windows 11 Pro
Version 10.0.22621 Build 22621
Describe the bug
Results in compiler error:
Well, this should be fine, lets just create some boilerplate after the match statement that returns a type.DB{} struct, to let the compiler infer the return type of
or.Unfortunately, it seems like everything in the block is ignored if something is returned at all in
orConsole Output:
types.DB{ name: 'Should never see this' }create_dbfunction is not important, but is provided below for completeness.Expected Behavior
Everything in the
orblock should be ran, or have theorblock act infer its return type based on the expected result type of the function.Currently the expected type of return for an
orblock is void.Unless a return is given at the root level of
or.Current Behavior
Please see "Describe the bug"
Reproduction Steps
Possible Solution
Additional Information/Context
No response
V version
V 0.3.3 c7237b1
Environment details (OS name and version, etc.)
OS Name Microsoft Windows 11 Pro
Version 10.0.22621 Build 22621