aiken-lang / aiken

A modern smart contract platform for Cardano
https://aiken-lang.org
Apache License 2.0
396 stars 82 forks source link

Compiler crashes if structs contain functions #939

Closed t4ccer closed 2 months ago

t4ccer commented 2 months ago

What Git revision are you using?

Compiled from source at 075668b52ea748cb1cd3bc6723b1add752976f0f

$ aiken --version
aiken v1.0.26-alpha+unknown

What operating system are you using, and which version?

Describe what the problem is?

type Rec<t> {
     get_t: t,
}

fn use_dict(dict: Rec<fn(Bool) -> Bool>, b: Bool) -> Bool {
   let f = dict.get_t
   f(b)
}

fn not(x: Bool) -> Bool {
   when x is {
     False -> True
     True -> False
   }
}

fn foo() -> Bool {
   let dict = Rec {get_t: not}
   use_dict(dict, False)
}

When foo() is used anywhere in validator code, compiler crashes

   aiken::fatal::error
   Whoops! You found a bug in the Aiken compiler.

   Please report this error at https://github.com/aiken-lang/aiken/issues/new.
   In your bug report please provide the information below and if possible the code
   that produced it.

   Operating System: linux
   Architecture:     x86_64
   Version:          v1.0.26-alpha+unknown

   crates/aiken-lang/src/gen_uplc.rs:4193:77

       called `Result::unwrap()` on an `Err` value: NotAConstant(<a lot of uplc>)

What should be the expected behavior?

The code above is valid, it should compile.

KtorZ commented 2 months ago

The code above is valid, it should compile.

No it is not. Not in Aiken at least. Records aren't allowed to hold functions unfortunately due to how values are encoded on the VM (and specifically, to how Aiken chooses to encode them).

That is however a but with the type-checker here which should catch that.