Save a noob: error[E0308]: mismatched types

Hello Rust friends, this is my first contact with a programming languages community. :smiling_face_with_three_hearts:

Can someone help me? I'm working with this code:

fn main() {
    let args: Vec<String> = env::args().collect();
    
    let config = Config::new(&args).unwrap_or_else(|err| {
        println!("Problem parsing arguments: {}", err);
        process::exit(1);
    });

for building a simple CLI, but I'm receiving this error:

mismatched types
expected struct `Args`
found reference `&Vec<String>`

diagnostic message:

error[E0308]: mismatched types
  --> src/main.rs:9:30
   |
9  |     let config = Config::new(&args).unwrap_or_else(|err| {
   |                  ----------- ^^^^^ expected `Args`, found `&Vec<String>`
   |                  |
   |                  arguments to this function are incorrect
   |
   = note: expected struct `Args`
           found reference `&Vec<String>`
note: associated function defined here
  --> /home/ubuntu/.cargo/registry/src/index.crates.io-6f17d22bba15001f/minigrep-0.1.0/src/lib.rs:31:12
   |
31 |     pub fn new(mut args: env::Args) -> Result<Config, &'static str> {
   |            ^^^

The Config::new() function wants to be given the std::env::args() iterator without you .collect()ing it first. That's rather restrictive (accepting any IntoIterator type would be conventional for a library) but that's what it wants.

6 Likes

Welcome! Thanks for formatting the code you posted using triple back-quotes. If you do the same for the full error, the columns will line up and it will also be easier to read.

1 Like

It's also weird to have a struct that in itself is not an iterator wrapper of some sort, take an iterator in new(). It's also not the best practice to let new() return a Result. try_new() may be a better name. But then, I'd rather implement TryFrom for the struct. Where does Config come from, by the way?

1 Like

I apologize but I ended up forgetting to put the code for the lib.rs file that complements it, here it is:

use std::error::Error;
use std::fs;

pub fn run(config: Config) -> Result<(), Box<dyn Error>>{    
    let contents = fs::read_to_string(&config.filename)?;
    println!("Com o texto:\n{}", contents);
    Ok(())
}


pub struct Config {
    pub query: String,
    pub filename: String,
}


impl Config {
   pub  fn new(args: &[String]) -> Result<Config, &'static str> {
        if args.len() < 3 {
            return Err("Argumentos insuficientes!");
        }

        let query = args[1].clone();
        let filename = args[2].clone();

        Ok(Config { query, filename })
    }
}

When I copy the code from your first and last posts into a playground, there are no compilation errors.

Can you reproduce the problem in the playground, click the SHARE button, click the doc icon button next to "Permalink to the playground" to copy the link, and then paste the link here?

You have a use minigrep::Config; [1] somewhere that is conflicting with your intended Config type.


  1. Of much worse, use minigrep::*; I really hate wildcard imports because they make name ambiguities such a pain. ↩︎

1 Like