-1

I have this Rusqlite code:

use rusqlite::types::ToSql;

// ... normal Rusqlite initialisation code ...

let mut statement = tx.prepare("INSERT INTO table VALUES (?1, ?2)")?;
let params: &[&dyn ToSql] = &[
    &0u32,
    &"hello",
];
statement.execute(params)?;

The ?1 parameter is an INTEGER and the ?2 parameter is TEXT. This compiles, however if I move the params into the function call it does not compile:

statement.execute(&[
    &0u32,
    &"hello",
])?;

This gives the following error for &hello.

mismatched types
  expected type `&u32`
found reference `&&'static str`

It seems like it infers the type for the array literal based on the type of the first element. What is the syntax for explicitly setting the type of the array?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Timmmm
  • 88,195
  • 71
  • 364
  • 509
  • try with as `&[&0u32 as &dyn ToSql, &"hello" as &dyn ToSql]` ? – Ömer Erden Jul 01 '20 at 12:37
  • 1
    I think you only need to coerce the first array element to `&dyn ToSql`. – Aloso Jul 01 '20 at 12:43
  • It's hard to answer your question because it doesn't include a [MRE]. We can't tell what crates (and their versions), types, traits, fields, etc. are present in the code. It would make it easier for us to help you if you try to reproduce your error on the [Rust Playground](https://play.rust-lang.org) if possible, otherwise in a brand new Cargo project, then [edit] your question to include the additional info. There are [Rust-specific MRE tips](//stackoverflow.com/tags/rust/info) you can use to reduce your original code for posting here. Thanks! – Shepmaster Jul 01 '20 at 12:52
  • Please [edit] your question and paste the exact and entire error that you're getting — that will help us to understand what the problem is so we can help best. Sometimes trying to interpret an error message is tricky and it's actually a different part of the error message that's important. Please use the message from running the compiler directly, not the message produced by an IDE, which might be trying to interpret the error for you. – Shepmaster Jul 01 '20 at 12:52
  • See also [Why does Rusqlite reject the Option type when executing a query?](https://stackoverflow.com/q/59900003/155423); [Cannot call rusqlite's query because it expects the type &[&rusqlite::types::ToSql\]](https://stackoverflow.com/q/46624591/155423). – Shepmaster Jul 01 '20 at 12:53

1 Answers1

2

You annotate the type of an array literal the same way as any other type, by writing the type after the variable name, separated by a colon:

let array: [u8; 5] = [1, 2, 3, 4, 5];

That's not your problem. Your problem is that you are creating a heterogeneous array, one where the types of each element differ. The first element is a reference to an integer, the second a string, etc. You need to perform the case to the trait object more eagerly:

let x = [&42 as &dyn Display, &true];

For rusqlite specifically, use the params! macro to do this for you:

use rusqlite::params; // 0.23.1

fn main() {
    let x = params![&42, &true];
}

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366