vlang / v

Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io
MIT License
35.79k stars 2.16k forks source link

semicolon in or clause causes error: last statement in the `or {}` block must ... #21354

Closed hholst80 closed 6 months ago

hholst80 commented 6 months ago

Describe the bug

If I use a semicolon after a panic("..."); the v compiler will state that

error: last statement in the `or {}` block should be an expression of type `int` or exit parent scope

Obviously, the type depends on the specific expected return type.

Reproduction Steps

fn foo() !int {
  error("failure")
  return 0
}
fn main() {
  mut x := 1
  x = foo() or { panic("failed"); }
  println("x=${x}")
}

Expected Behavior

The program should compile, or maybe it should complain about unreachable code in foo(), but I did not expect to see an error regarding the if block.

Current Behavior

repro.v:7:33: error: last statement in the `or {}` block should be an expression of type `int` or exit parent scope
    5 | fn main() {
    6 |   mut x := 1
    7 |   x = foo() or { panic("failed"); }
      |                                 ^
    8 |   println("x=${x}")
    9 | }

Possible Solution

No response

Additional Information/Context

No response

V version

V 0.4.5 1aee2b5

Environment details (OS name and version, etc.)

V full version: V 0.4.5 bfd53a9.1aee2b5
OS: linux, "Artix Linux"
Processor: 4 cpus, 64bit, little endian, Intel(R) Core(TM) i7-6600U CPU @ 2.60GHz

getwd: /home/root/omnicoder/docker/events-sidecar
vexe: /home/root/Apps/v/v
vexe mtime: 2024-04-24 20:07:06

vroot: OK, value: /home/root/Apps/v
VMODULES: OK, value: /home/root/.vmodules
VTMP: OK, value: /tmp/v_0

Git version: git version 2.44.0
Git vroot status: weekly.2024.17-13-g1aee2b56 (12 commit(s) behind V master)
.git/config present: true

CC version: cc (GCC) 13.2.1 20230801
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.

JalonSolov commented 6 months ago

Since ; is now valid in V, this looks like an unreachable code thing since V will exit because of the panic.

hholst80 commented 6 months ago

It seems there is also a related issue with nesting?

        event := json2.decode[Event](req.data) or {
            eprintln(err)
            conf := http.ResponseConfig{
                status: .internal_server_error
            header: http.new_header(http.HeaderConfig{ key: .content_type, value: 'text/plain' })
            body: "${err}"
            }
            con.close() or { panic(err) }
        }
src/main.v:40:8: error: `or` block must provide a default value of type `Event`, or return/continue/break or call a [noreturn] function like panic(err) or exit(1)
   38 |               body: "${err}"
   39 |             }
   40 |             con.close() or { panic(err) }
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~
   41 |         }
   42 |         // req := http.parse_request(mut buf_reader)!

EDIT:

I misunderstood the error. The error is resolved by adding a panic after the close statement. The error originated from the first if block.

        event := json2.decode[Event](req.data) or {
            eprintln(err)
            conf := http.ResponseConfig{
                status: .internal_server_error
            header: http.new_header(http.HeaderConfig{ key: .content_type, value: 'text/plain' })
            body: "${err}"
            }
            con.close() or { panic(err) }
            panic(err)
        }
JalonSolov commented 6 months ago

Yes, which is a separate error. With the ;, it looks like unreachable code. Without the ;, it is wrong in that a default value isn't required since it would exit before that extra code was reached.

Both could be handled by the seeing that it will exit, but it would be more clear to have 2 separate errors.

JalonSolov commented 6 months ago

Oh, and although the ; is accepted, v fmt will remove it, as it is not needed for anything (other than some cases with -e on the command line).