[About HRTB] How to make this compile?

⚓ Rust    📅 2026-03-21    👤 surdeus    👁️ 1      

surdeus

use futures::{Sink, never::Never, sink};

trait Foo {
    fn foo(&self) -> Box<dyn for<'a> Sink<&'a str, Error = Never>>;
}

struct A;

impl Foo for A {
    fn foo(&self) -> Box<dyn for<'a> Sink<&'a str, Error = Never>> {
        Box::new(sink::unfold(String::new(), async |mut s, i| {
            s += i;
            Ok(s)
        }))
    }
}

trait Bar {
    fn foo(&self) -> Box<dyn for<'a> Fn(&'a str)>;
}

struct B;

impl Bar for B {
    fn foo(&self) -> Box<dyn for<'a> Fn(&'a str)> {
        Box::new(|_: &str| {})
    }
}
cargo check
    Checking test_ v0.1.0 (/tmp/test_)
error: implementation of `FnOnce` is not general enough
  --> src/lib.rs:11:9
   |
11 | /         Box::new(sink::unfold(String::new(), async |mut s, i| {
12 | |             s += i;
13 | |             Ok(s)
14 | |         }))
   | |___________^ implementation of `FnOnce` is not general enough
   |
   = note: `{async closure@src/lib.rs:11:46: 11:62}` must implement `FnOnce<(String, &'1 str)>`, for any lifetime `'1`...
   = note: ...but it actually implements `FnOnce<(String, &'2 str)>`, for some specific lifetime `'2`

I was told to let target type drive HRTB, so impl Bar for B can be compiled. But why it fails on impl Foo for A?

4 posts - 2 participants

Read full topic

🏷️ Rust_feed