Empty array as argument to generic fn fails

Hi, I've made a function with this signature to run internal scripts:

pub async fn run_asset_script(
    script: impl AsRef<str>,
    env: impl IntoIterator<Item = (impl AsRef<str>, impl AsRef<str>)>,
) -> Result<()>

It works nicely when I have one or more env vars:

run_asset_script("script1.sh", [("NAME", "a name")]).await?;

But it doesn't work when trying to pass an empty array, for a script that doesn't require any env vars:

error[E0698]: type inside `async fn` body must be known in this context
   --> src/cjdns.rs:102:13
102 |             utils::run_asset_script("cjdns_launch.sh", [])
    |             ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `impl AsRef<str>` declared on the function `run_asset_script`
note: the type is part of the `async fn` body because of this `await`
   --> src/cjdns.rs:103:17
103 |                 .await
    |                 ^^^^^^

Why it doesn't work? How could I make it compile, please?

impl Trait in argument position is equivalent to a generic parameter. If the array has no elements, then how is the compiler supposed to infer the concrete item type of the array? You'll have to specify the type explicitly somehow. (That can be cumbersome with impl Trait – use an explicit generic type parameter instead.)

Yes, I can see that, thanks.
But since it is an empty IntoIterator, I wouldn't use anything in that param anyway, there isn't any data to use... So, I'd want it to infer simply anything, it doesn't matter, &str for instance.
Is there any way I can do this?

You can explicitly declare a variable of the appropriate type, eg.:

let empty: [&str; 0] = [];

and then pass that concretely-typed variable to the function.

Nice, it does work like that, thanks!

            let empty: [(&str, &str); 0] = [];
            run_asset_script("script.sh", empty).await?;

Out of curiosity, is there any way I could make this a one-liner? Like using a turbofish or something.

If you declare your function with a real generic type parameter rather than impl AsRef<str>, then you can use the turbofish.

Perfect, that makes total sense...
I don't really like to declare types on variables, I always use turbofish when needed.
I'm really thankful @H2CO3 :+1:

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.