Skip to content

Panic in RCA when using tuple variables as arguments to a lambda #2696

@swernli

Description

@swernli

The following should work but panics in RCA:

@EntryPoint(Base)
operation Main() : Unit {
    // Works fine...
    let x = (1, 2, 3);
    Foo(x);

    // Panics RCA!
    let f : (Int, Int, Int) -> Unit = (a, b, c) -> {};
    f(x)
}

function Foo(a : Int, b : Int, c : Int) : Unit {}

The issue is in source/compiler/qsc_rca/src/core.rs inside of analyze_expr_call_with_spec_callee where it has special handling of lambdas with captures:

// Derive the compute kind based on the value kind of the arguments.
let arg_value_kinds = if let Some(fixed_args) = fixed_args {
// In items that come from lifted lambdas, fixed arguments that capture local variables, if any, come before
// other arguments, so we use the `fixed_args` as the base of the chain of values and concatenate the rest of
// the arguments when building the full list of arguments for a callable application.
fixed_args
.into_iter()
.map(|local_var_id| {
self.get_current_application_instance()
.locals_map
.find_local_compute_kind(local_var_id)
.expect("local should have been processed before this")
.compute_kind
.value_kind_or_default(ValueKind::Element(RuntimeKind::Static))
})
.chain(self.derive_arg_value_kinds(&arg_exprs))
.collect()
} else {
self.derive_arg_value_kinds(&arg_exprs)
};

Because the lambda takes more than one argument, the results of self.derive_arg_value_kinds is a vector representing the argument tuple, but the call to .chain with the preceeding iterator effectively unwraps it. We expect the parameter to be of type ((Int, Int, Int),) which is a tuple of single arity, but it gets passed as (Int, Int, Int) causing the panic.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions