Immutable iteration over slice by reference


#1

I have

#![feature(unicode, decode_utf8)]

extern crate std_unicode;

fn main() {
    let src = b"abc";
    for c in std_unicode::char::decode_utf8(src) {
        println!("{:?}", c);
    }
}

(Playground link)

This fails with

   Compiling playground v0.0.1 (file:///playground)
error[E0271]: type mismatch resolving `<&[u8; 3] as std::iter::IntoIterator>::Item == u8`
 --> src/main.rs:7:14
  |
7 |     for c in std_unicode::char::decode_utf8(src) {
  |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found u8
  |
  = note: expected type `&u8`
             found type `u8`
  = note: required by `std_unicode::char::decode_utf8`

error[E0271]: type mismatch resolving `<std::slice::Iter<'_, u8> as std::iter::Iterator>::Item == u8`
 --> src/main.rs:7:14
  |
7 |     for c in std_unicode::char::decode_utf8(src) {
  |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found u8
  |
  = note: expected type `&u8`
             found type `u8`
  = note: required by `std_unicode::char::DecodeUtf8`

error[E0271]: type mismatch resolving `<std::slice::Iter<'_, u8> as std::iter::Iterator>::Item == u8`
 --> src/main.rs:7:5
  |
7 | /     for c in std_unicode::char::decode_utf8(src) {
8 | |         println!("{:?}", c);
9 | |     }
  | |_____^ expected reference, found u8
  |
  = note: expected type `&u8`
             found type `u8`
  = note: required because of the requirements on the impl of `std::iter::Iterator` for `std_unicode::char::DecodeUtf8<std::slice::Iter<'_, u8>>`

Why and what can I do about it? (Changing the argument from src to src.iter() or src.into_iter() doesn’t help.)


#2

https://play.rust-lang.org/?gist=1e780988d16a3944b1bd44bc73a5b395&version=nightly

Basically you can tack on a cloned() call to src.iter() so you get u8 back from the iterator, and not &u8 (that’s what decode_utf8 wants).


#3

Thank you.

The error message in my original post appears to say exactly the opposite of what the problem was. It says it expected &u8 but found u8. Yet, it seems it expected u8 and found &u8!


#4

Turns out there’s already a bug on file about the error message being backwards.


#5

To be honest, I didn’t even pay too much attention to the error message. Instead, I looked at the docs for decode_utf8 and saw it wants IntoIterator<Item=u8> (although that bit is in the error message).