Async closure does not have the same type as itself

⚓ Rust    📅 2025-08-26    👤 surdeus    👁️ 4      

surdeus

I'm using the TryStreams trait from the futures library to read files, and I'm hitting a type error that I don't understand.

        let layers = ReadDirStream::new(fs::read_dir(&path).await?)
            .map_err(MyError::from)
            .try_filter(async |dir_entry| dir_entry.path().is_dir());
            .try_filter_map(async |dir_entry| Layer::read(dir_entry.path()).await.map(Some))
            .collect::<Vec<_>>()
            .await;

This is the error I get. My reading is that the async closure on line 86 is not the same type as... the async closure on line 86?

error[E0308]: mismatched types
   --> core/src/layer.rs:84:22
    |
84  |           let layers = ReadDirStream::new(fs::read_dir(&parent).await?)
    |  ______________________^
85  | |             .map_err(MyError::from)
86  | |             .try_filter(async |res| res.path().is_dir())
87  | |             .try_filter_map(async |res| Layer::read(res.path()).await.map(Some))
    | |________________________________________________________________________________^ one type is more general than the other
    |
    = note: expected `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
               found `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
    = note: no two async blocks, even if identical, have the same type
    = help: consider pinning your async block and casting it to a trait object
note: the lifetime requirement is introduced here
   --> /home/chief/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-util-0.3.31/src/stream/try_stream/mod.rs:739:32
    |
739 |         F: FnMut(&Self::Ok) -> Fut,
    |                                ^^^

error[E0308]: mismatched types
   --> core/src/layer.rs:84:22
    |
84  |           let layers = ReadDirStream::new(fs::read_dir(&parent).await?)
    |  ______________________^
85  | |             .map_err(MyError::from)
86  | |             .try_filter(async |res| res.path().is_dir())
87  | |             .try_filter_map(async |res| Layer::read(res.path()).await.map(Some))
    | |________________________________________________________________________________^ one type is more general than the other
    |
    = note: expected `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
               found `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
    = note: no two async blocks, even if identical, have the same type
    = help: consider pinning your async block and casting it to a trait object
note: the lifetime requirement is introduced here
   --> /home/chief/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-util-0.3.31/src/stream/try_stream/mod.rs:180:25
    |
180 | pub trait TryStreamExt: TryStream {
    |                         ^^^^^^^^^

error[E0308]: mismatched types
  --> core/src/layer.rs:84:22
   |
84 |           let layers = ReadDirStream::new(fs::read_dir(&parent).await?)
   |  ______________________^
85 | |             .map_err(MyError::from)
86 | |             .try_filter(async |res| res.path().is_dir())
87 | |             .try_filter_map(async |res| Layer::read(res.path()).await.map(Some))
   | |________________________________________________________________________________^ one type is more general than the other
   |
   = note: expected `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
              found `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
   = note: no two async blocks, even if identical, have the same type
   = help: consider pinning your async block and casting it to a trait object

error[E0308]: mismatched types
   --> core/src/layer.rs:84:22
    |
84  |           let layers = ReadDirStream::new(fs::read_dir(&parent).await?)
    |  ______________________^
85  | |             .map_err(MyError::from)
86  | |             .try_filter(async |res| res.path().is_dir())
87  | |             .try_filter_map(async |res| Layer::read(res.path()).await.map(Some))
    | |________________________________________________________________________________^ one type is more general than the other
    |
    = note: expected `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
               found `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
    = note: no two async blocks, even if identical, have the same type
    = help: consider pinning your async block and casting it to a trait object
note: the lifetime requirement is introduced here
   --> /home/chief/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-util-0.3.31/src/stream/try_stream/mod.rs:779:40
    |
779 |         Fut: TryFuture<Ok = Option<T>, Error = Self::Error>,
    |                                        ^^^^^^^^^^^^^^^^^^^

error[E0308]: mismatched types
   --> core/src/layer.rs:84:22
    |
84  |           let layers = ReadDirStream::new(fs::read_dir(&parent).await?)
    |  ______________________^
85  | |             .map_err(MyError::from)
86  | |             .try_filter(async |res| res.path().is_dir())
87  | |             .try_filter_map(async |res| Layer::read(res.path()).await.map(Some))
    | |________________________________________________________________________________^ one type is more general than the other
    |
    = note: expected `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
               found `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
    = note: no two async blocks, even if identical, have the same type
    = help: consider pinning your async block and casting it to a trait object
note: the lifetime requirement is introduced here
   --> /home/chief/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-util-0.3.31/src/stream/try_stream/mod.rs:780:12
    |
780 |         F: FnMut(Self::Ok) -> Fut,
    |            ^^^^^^^^^^^^^^^^^^^^^^

error[E0308]: mismatched types
  --> core/src/layer.rs:84:22
   |
84 |           let layers = ReadDirStream::new(fs::read_dir(&parent).await?)
   |  ______________________^
85 | |             .map_err(MyError::from)
86 | |             .try_filter(async |res| res.path().is_dir())
87 | |             .try_filter_map(async |res| Layer::read(res.path()).await.map(Some))
88 | |             .collect::<Vec<_>>()
   | |________________________________^ one type is more general than the other
   |
   = note: expected `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
              found `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
   = note: no two async blocks, even if identical, have the same type
   = help: consider pinning your async block and casting it to a trait object

error[E0308]: mismatched types
   --> core/src/layer.rs:84:22
    |
84  |           let layers = ReadDirStream::new(fs::read_dir(&parent).await?)
    |  ______________________^
85  | |             .map_err(MyError::from)
86  | |             .try_filter(async |res| res.path().is_dir())
87  | |             .try_filter_map(async |res| Layer::read(res.path()).await.map(Some))
88  | |             .collect::<Vec<_>>()
    | |________________________________^ one type is more general than the other
    |
    = note: expected `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
               found `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
    = note: no two async blocks, even if identical, have the same type
    = help: consider pinning your async block and casting it to a trait object
note: the lifetime requirement is introduced here
   --> /home/chief/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-util-0.3.31/src/stream/try_stream/mod.rs:780:31
    |
780 |         F: FnMut(Self::Ok) -> Fut,
    |                               ^^^

error[E0308]: mismatched types
  --> core/src/layer.rs:89:14
   |
86 |             .try_filter(async |res| res.path().is_dir())
   |                                     -------------------
   |                                     |
   |                                     the expected `async` closure body
   |                                     the found `async` closure body
...
89 |             .await;
   |              ^^^^^ one type is more general than the other
   |
   = note: expected `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
              found `async` closure body `{async closure body@core/src/layer.rs:86:37: 86:56}`
   = note: no two async blocks, even if identical, have the same type
   = help: consider pinning your async block and casting it to a trait object

4 posts - 3 participants

Read full topic

🏷️ Rust_feed