rhaiscript / rhai

Rhai - An embedded scripting language for Rust.
https://crates.io/crates/rhai
Apache License 2.0
3.8k stars 177 forks source link

Anonymous function are not exported by modules. #526

Closed ltabis closed 2 years ago

ltabis commented 2 years ago

Hello,

I discovered that anonymous function seems to, even though they are de-sugared as functions, not exported by modules. Here is an example:

// --- main.rs

use std::str::FromStr;

fn main() {
    let mut engine = rhai::Engine::new();

    engine.set_module_resolver(rhai::module_resolvers::FileModuleResolver::new_with_path(
        "./scripts",
    ));

    let ast = engine
        .compile_file(std::path::PathBuf::from_str("./scripts/main.rhai").unwrap())
        .expect("failed to compile");

    engine.eval_ast::<()>(&ast).unwrap();
}

// --- scripts/external.rhai

export const anonymous_func = |param| print(param);

fn normal_func(param) {
    print(param)
}

// --- scripts/main.rhai

import "external" as external;

external::normal_func(42);
external::anonymous_func.call(42);

calling the following script returns:

42
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ErrorFunctionNotFound("anon$3135e461af3cc922 (i64)", 4:26)', src/main.rs:14:33

anon$3135e461af3cc922 "should" have been exported by the module, since it de-sugars into a function.

Could it be that anon$3135e461af3cc922 is under the "external" namespace, and to be able to call it the function pointer should be something like this:

Fn("external::anon$3135e461af3cc922")

I guess anonymous functions not being exported could be normal behavior, but I couldn't find anything specified in the documentation. Did I missed something ?

schungx commented 2 years ago

Yes, this is probably a case that doesn't work well. I never anticipated an exported constant can be a closure...

There is no way to refer to the function under external without attaching the namespace name, which is not supported for function pointers.

I'll need some time to think of a solution to this...

ltabis commented 2 years ago

Thank you for your quick response ! I know it is a weird use case, I'll find another way to achieve what I want in the meantime. Have a good day.

schungx commented 2 years ago

It probably won't be easy to support this... maybe I should just fail with an error for the time being...

ltabis commented 2 years ago

It probably won't be easy to support this... maybe I should just fail with an error for the time being...

Yes, as long as it's documented I think it's all good. I think exporting anonymous functions could cause unpredictable behavior concerning currying so I guess it's a good idea to just fail !

schungx commented 2 years ago

OK, it'll throw a runtime error then.

schungx commented 2 years ago

This will be in effect for the next release. Thanks for catching this.

Closing for now.