5

I received this error:

error: mismatched types [E0308]
                         process(s);
                                 ^
help: run `rustc --explain E0308` to see a detailed explanation
note: expected type `&(u32, u32, image::Luma<u8>)`
note:    found type `&mut (u32, u32, &mut _)`

but I do not understand what the _ means.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Kamil Szot
  • 17,436
  • 6
  • 62
  • 65
  • 1
    @Shepmaster Sorry. I'll trim down the question. And create new one for "bonus content" with self-response since I already got it. – Kamil Szot Jun 20 '16 at 15:32
  • You really do not need the leading `&mut` here, I assure you. You are complicating the signature way too much :x Just dereference at the call site, your tuple is `Copy` anyway. – Matthieu M. Jun 20 '16 at 15:33

2 Answers2

6

In Rust, the _ identifier is used when the name does not matter. This occurs in a few situations:

  • let _ = ...; is used to ignore the result of an expression (only necessary when said result is marked with the #[must_use] attribute)
  • In types, _ is used to elide types (either because you prefer to let the compiler infer it or because the compiler judges it does not matter)

Thus, in your case, the compiler has elided the type because it does not matter, so that you can focus on the specific reason of the error. It may be confusing, at first, but once used to it it's actually helpful, especially when types are hairy (very large).


The error is simple: you are mistaking references and values.

Your original signature expects: &(u32, u32, Type) but you pass &mut (u32, u32, &mut Type).

The difference in mutability does not matter (in this direction), however a &mut Type and a Type have very different memory structure and are not interchangeable.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • Can you try to answer bonus question? How to avoid `*tup.2` and put it all in function signature? – Kamil Szot Jun 20 '16 at 14:59
  • @KamilSzot: `process(&mut (x, y, pixel): &mut (u32,u32,&mut image::Luma))` I would expect. It's a pattern matching game. – Matthieu M. Jun 20 '16 at 15:02
  • Tried that but "cannot move out of borrowed content". – Kamil Szot Jun 20 '16 at 15:05
  • @KamilSzot: Ah... why do you have that `&mut` in front by the way? It's unused here. Shouldn't the signature be `process((x, y, pixel): (u32, u32, &mut image::Luma))` ? – Matthieu M. Jun 20 '16 at 15:07
  • I need it. Without it, rust complains about mismatch between (_, _, _) and &mut (u32, u32, &mut image::Luma) – Kamil Szot Jun 20 '16 at 15:20
  • Basically what I need is pattern that can destructure reference to borrowed value from a borrow. I could do `process(&mut (x,y, ref mut pixel): &mut (u32,u32,&mut image::Luma))` but then I had to do `**pixel = image::Luma([i as u8]);` instead of `*pixel = image::Luma([i as u8]);` – Kamil Szot Jun 20 '16 at 15:21
  • I tried to cram `*` somewhere into the signature but rust doesn't seem to like it. – Kamil Szot Jun 20 '16 at 15:23
  • @KamilSzot: Can you not dereference at the call site? => `process(*my_tuple)` instead of `process(my_tuple)` and then all worries go away! – Matthieu M. Jun 20 '16 at 15:30
  • Hah! Got it! `fn process(&mut (x,y, &mut ref mut pixel): &mut (u32,u32,&mut image::Luma)) {` – Kamil Szot Jun 20 '16 at 15:30
  • Seems good but when trying to dereference at the call site I'm getting "cannot move out of borrowed content" there. – Kamil Szot Jun 20 '16 at 15:47
  • I moved my "bonus question" there: http://stackoverflow.com/questions/37926546/how-to-destructure-to-reference-to-value-instead-of-reference-to-borrow – Kamil Szot Jun 20 '16 at 15:48
4

The _ is just a placeholder that could mean anything, and helps to clarify the error message.

In this case, it's saying it was expecting an image::Luma<u8>, but it actually found a mutable reference (&mut) to something. It doesn't matter what that something is; it &mut <something> can never be matched with image::Luma<i>.

If instead it said ...found type &mut (u32, u32, &mut T: SomeTrait) or similar, I think it would be harder to zoom in to the immediate problem.

You can't pass a reference to a function that expects an copied (or moved) full object instead.

Chris Emerson
  • 13,041
  • 3
  • 44
  • 66