Odin icon indicating copy to clipboard operation
Odin copied to clipboard

Procedure declaration in defer block crashes compiler

Open Despacito696969 opened this issue 2 years ago • 5 comments

Compile following with odin build .

package main

main :: proc()
{
   defer
   {
      foo :: proc(x: int) {return x}
   }
}

You should get:

D:\a\Odin\Odin\src\llvm_backend_stmt.cpp(42): Assertion Failure: `e != nullptr`

Context

Odin: dev-2022-08-nightly:4c3281b3
OS:   Windows 10 Professional (version: 21H2), build 19044.1826
CPU:  Intel(R) Core(TM) i5-8600K CPU @ 3.60GHz
RAM:  16330 MiB

Despacito696969 avatar Aug 10 '22 16:08 Despacito696969

Also interesting that this gives you undeclared name: foo:

package main

main :: proc()
{
   defer
   {
      foo :: proc(x: int) {return x}
      foo(1)
   }
}

Kelimion avatar Aug 10 '22 16:08 Kelimion

This begs the question, is this something we should allow in the first place?

defer really is an edge in many ways (e.g. it disallows return within it for loads of sanity reasons (not technical))

gingerBill avatar Aug 10 '22 17:08 gingerBill

This begs the question, is this something we should allow in the first place?

I'm inclined to say no. There's no good reason foo couldn't be a child proc of main or even its own top-level proc.

If extrapolated to a larger codebase, it would also be more maintainable to enforce defer hosting only simple expressions and statements, not procedure definitions.

defer blocks by design are meant to be a compact "clean up what we did just above" kind of block. If that cleanup is complicated, put it in its own procedure and call that, e.g. defer destroy_thing(thing).

Kelimion avatar Aug 10 '22 17:08 Kelimion

This begs the question, is this something we should allow in the first place?

I think many users, myself included, would have expected constant declarations :: inside a defer block to work. Variable declarations are also allowed inside a defer block. So the user thinks that they are allowed to write normal code within defer as if it were just a simple copy of contents to the end of the containing scope. A more restrictive defer means that the language rules become more complex and less intuitive.

But @Kelimion's arguments also make a lot of sense to me.

awwdev avatar Aug 11 '22 08:08 awwdev

The issue isn't :: but rather procedure declarations with defer (I know what the bug is and how to fix it).

I'm wondering what the best approach to this is. Understand that this is not a technical problem but a design problem. You could easily have as many constant value and type declarations as you want within a defer.

gingerBill avatar Aug 11 '22 09:08 gingerBill