The Iterator trait isn't getting implemented?

I'm working on a project to make a datastore that is backed by SQLite. Before I work on it, though, I wanted to read prior projects that do something similar, and found Mozilla's abandoned mentat project. The last commit was back in september 2018, which does not seem like that long ago, so I thought I would try to pull it down and see if I could get it to build and run its tests, then begin to read how they structure their work.

Right away, the project doesn't build for a lot of reasons I can't immediately figure out. I suspect they must have been using a much older version of Rust, or something, and have decided to try to see if I can get it working with rustc 1.36.0.

The first culprit I'm working on is upgrading their very out-of-date SQLite dependency, the rusqlite crate. While I think I have managed to get the majority of compiler errors taken care of, this one completely stumps me.

I apologize for not knowing how to cut this down to a simple RustPlayground example, but if you'd like to follow along locally:

git clone git@github.com:cpdean/mentat.git
git checkout cd/upgrade_rusqulite_0.19 
# rustc --version
# rustc 1.36.0 (a53f9df32 2019-07-03)
cargo build

There should be two compiler errors, both regarding a type not implementing Iterator.

error[E0599]: no method named `next` found for type `rusqlite::MappedRows<'conn, F>` in the current scope
   --> db/src/cache.rs:223:14
    |
223 |             .next()
    |              ^^^^
    |
    = note: the method `next` exists but the following trait bounds were not satisfied:
            `rusqlite::MappedRows<'conn, F> : std::iter::Iterator`

error[E0599]: no method named `peekable` found for type `cache::AevRows<'_, [closure@db/src/cache.rs:1078:47: 1078:84 aev_factory:_]>` in the current scope
    --> db/src/cache.rs:1083:18
     |
210  | pub struct AevRows<'conn, F> {
     | ---------------------------- method `peekable` not found for this
...
1083 |             aevs.peekable(),
     |                  ^^^^^^^^
     |
     = note: the method `peekable` exists but the following trait bounds were not satisfied:
             `&mut cache::AevRows<'_, [closure@db/src/cache.rs:1078:47: 1078:84 aev_factory:_]> : std::iter::Iterator`
             `cache::AevRows<'_, [closure@db/src/cache.rs:1078:47: 1078:84 aev_factory:_]> : std::iter::Iterator`
     = help: items from traits can only be used if the trait is implemented and in scope
     = note: the following traits define an item `peekable`, perhaps you need to implement one of them:
             candidate #1: `std::iter::Iterator`
             candidate #2: `fallible_iterator::FallibleIterator`

error: aborting due to 2 previous errors

However, the type that AevRows uses internally to implement Iterator, rusqlite::MappedRows, actually DOES implement Iterator. On the crate version of rusqlite specified by the Cargo.toml's, it is implemented right here:

impl<T, F> Iterator for MappedRows<'_, F>
where
    F: FnMut(&Row<'_>) -> Result<T>,
{
    type Item = Result<T>;

    fn next(&mut self) -> Option<Result<T>> {
        let map = &mut self.map;
        self.rows
            .next()
            .transpose()
            .map(|row_result| row_result.and_then(|row| (map)(&row)))
    }
}

The second compiler error is similar to the first, in that there is an explicit implementation of Iterator but the compiler claims it's not being implemented, however I suspect since impl Iterator for AevRows is dependant on MappedRows's implementation, fixing the issue with MappedRows may fix it for both. Here is the Iterator impl for AevRows:

impl<'conn, F> Iterator for AevRows<'conn, F>
where
    F: FnMut(&rusqlite::Row) -> Result<Aev>,
{
    type Item = Aev;
    fn next(&mut self) -> Option<Aev> {
        self.rows
            .next()
            .map(|row_result| row_result.expect("All database contents should be representable"))
    }
}

How do I make sure these traits are implemented for these structs?

I think I've narrowed down the problem, or a possible solution to the problem, but I don't really understand how this works.

Linking here, with a PR of a specific example of my issue with its fix.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.