Mismatch in Number/Types of Arguments

1.7k views Asked by At

This

extern crate postgres;

use postgres::{Connection, SslMode};

struct User {
    reference: String,
    email: String,
    firstname: String,
    lastname: String
}

static DB_URI: &'static str = "postgres://postgres:postgres@localhost/test";

fn main() {

    let conn = Connection::connect(DB_URI, &SslMode::None).unwrap();
    let trans = conn.transaction().unwrap();

    //...

}

fn insert_user<'a>(trans: &'a postgres::Transaction, user: &User) -> &'a postgres::Result {
    //...
}

is throwing an error

error: wrong number of type arguments: expected 1, found 0 [E0243]
fn insert_user<'a>(trans: &'a postgres::Transaction, user: &User) -> &'a postgres::Result {
                                                                         ^~~~~~~~~~~~~~~~

What is missing here? I just want to return a result of an executed query.

UPDATE So I modified the function line like this:

fn insert_user(trans: &postgres::Transaction, user: &User) -> &postgres::Result<()> {

to trick the compiler into revealing the correct return type and it gave me this:

mismatched types:
 expected `core::result::Result<(), postgres::error::Error>`,
    found `core::result::Result<postgres::Rows<'_>, postgres::error::Error>`

however when I tried to match the return type like this:

fn insert_user(trans: &postgres::Transaction, user: &User) -> &postgres::Result<postgres::Rows<'_>, postgres::error::Error> {

it's now throwing a new error:

error: use of undeclared lifetime name `'_` [E0261]
fn insert_user(trans: &postgres::Transaction, user: &User) -> postgres::Result<postgres::Rows<'_>, postgres::error::Error> {
                                                                                              ^~
2

There are 2 answers

4
mdup On BEST ANSWER

Looking at the documentation for the crate postgres, we can see that the type postgres::Result is generic over one type argument:

type Result<T> = Result<T, Error>;

Normally you would have two options:

  1. Specify the type yourself if you know what it is: postgres::Result<MyType>
  2. Let the compiler infer it for you (if it has enough information elsewhere): postgres::Result<_>

However in a return type (what comes after the ->) type inference is not triggered, so only option 1. is available.

(Hint: you still have one trick up your sleeve to find out the desired type. You can try specifying the unit type: ... -> postgres::Result<()> and check if the compiler complains with an error such as "expected MyType, found ()". This means you want to specify ... -> postgres::Result<MyType>.)

0
llogiq On

Result is defined as postgres::Result<T> (we say it is generic over T). Depending on the innards of the insert_user function, it could be Result<bool>, Result<u64>, Result<()> or something else entierly.

For example, the execute method on Transaction returns a Result<u64>, so that is a likely variant.