Skip to content

Missing register state panic when returning inside a call expression #1012

Description

@yorickpeterse

Please describe the bug

The following code:

type A {
  let @b: B

  fn mut example(a: A) {}
}

type B {

}

fn example -> A {
  let a = A(B())

  a.example(return a)
  A(B())
}

type async Main {
  fn async main {
    example
  }
}

Triggers a compiler panic like so:

thread 'main' (118831) panicked at compiler/src/mir/passes.rs:4877:9:
missing state for register r3 in block b4 (method "example" in "/home/yorickpeterse/Downloads/test.inko")
stack backtrace:
   0: __rustc::rust_begin_unwind
             at /rustc/4a4ef493e3a1488c6e321570238084b38948f6db/library/std/src/panicking.rs:689:5
   1: core::panicking::panic_fmt
             at /rustc/4a4ef493e3a1488c6e321570238084b38948f6db/library/core/src/panicking.rs:80:14
   2: compiler::mir::passes::LowerMethod::register_state
             at /home/yorickpeterse/Projects/inko/inko/compiler/src/mir/passes.rs:4877:9
   3: compiler::mir::passes::LowerMethod::register_is_moved
             at /home/yorickpeterse/Projects/inko/inko/compiler/src/mir/passes.rs:4780:14
   4: compiler::mir::passes::LowerMethod::call_method
             at /home/yorickpeterse/Projects/inko/inko/compiler/src/mir/passes.rs:2203:41
   5: compiler::mir::passes::LowerMethod::call
             at /home/yorickpeterse/Projects/inko/inko/compiler/src/mir/passes.rs:1985:22
   6: compiler::mir::passes::LowerMethod::expression
             at /home/yorickpeterse/Projects/inko/inko/compiler/src/mir/passes.rs:1683:46
   7: compiler::mir::passes::LowerMethod::lower_method_body
             at /home/yorickpeterse/Projects/inko/inko/compiler/src/mir/passes.rs:1539:22
   8: compiler::mir::passes::LowerMethod::run
             at /home/yorickpeterse/Projects/inko/inko/compiler/src/mir/passes.rs:1500:14
   9: compiler::mir::passes::LowerToMir::define_module_method
             at /home/yorickpeterse/Projects/inko/inko/compiler/src/mir/passes.rs:1280:15
  10: compiler::mir::passes::LowerToMir::lower_rest
             at /home/yorickpeterse/Projects/inko/inko/compiler/src/mir/passes.rs:1124:43
  11: compiler::mir::passes::LowerToMir::run_all
             at /home/yorickpeterse/Projects/inko/inko/compiler/src/mir/passes.rs:1084:47
  12: compiler::compiler::Compiler::compile_mir
             at /home/yorickpeterse/Projects/inko/inko/compiler/src/compiler.rs:536:13
  13: compiler::compiler::Compiler::build
             at /home/yorickpeterse/Projects/inko/inko/compiler/src/compiler.rs:325:28
  14: inko::command::build::run
             at /home/yorickpeterse/Projects/inko/inko/inko/src/command/build.rs:282:31
  15: inko::command::main::run
             at /home/yorickpeterse/Projects/inko/inko/inko/src/command/main.rs:62:26
  16: inko::main
             at /home/yorickpeterse/Projects/inko/inko/inko/src/main.rs:13:11
  17: core::ops::function::FnOnce::call_once
             at /home/yorickpeterse/.rustup/toolchains/1.94-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

The issue here is that in LowerMethod::call_method at the end we check if the receiver register is moved but don't account for the current basic block being disconnected.

I'm currently in the process of refactoring how we mark registers as temporarily unavailable during call expressions (e.g. so that a.b.move_the_argument(a) is invalid) to better handle call chains, which will likely fix this automatically as part of that work as the current check won't be necessary any more.

Operating system

Fedora

Inko version

main

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

compilerChanges related to the compiler

Type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions