-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implied lifetimes lead to mismatched type error with seemingly identical types in the msg - async closure edition #108114
Comments
Please try: use core::future::{Future};
use anyhow::Error;
struct Session {}
impl Session {
pub async fn dispatch_request<'a, T, F, Fut>(&self, interpreter: F) -> Result<T, Error>
where
F: FnMut(&'a mut String) -> Fut, // <-- note the lifetime annotation
Fut: Future<Output = Result<T, Error>>,
{
let mut interpreter = interpreter;
let mut stream = "hello".to_string();
interpreter(&mut stream).await
}
}
async fn test_interpreter(input_stream: &mut String) -> Result<String, Error> {
Ok(input_stream.clone())
}
#[tokio::main]
async fn main() {
let session = Session{};
session.dispatch_request(test_interpreter).await.unwrap();
} |
With the explicit lifetime annotation, the error is sensible. I filed this issue to see if there was a way to make that the default error message with elided lifetimes as well. Thank you. |
Incidentally, as someone who understands that making the lifetime a function parameter means it's too long to borrow a local for, and thus understands that I need a HRTB, the alternative version is something I'm very unlikely to try. Additionally, while the error when you do so is a reasonable message for what it talks about, it's an error about wrongfully making the lifetime a function parameter; that function can't compile at all. What is desired here is an error explaining why the function bounds aren't general enough for closures which produce futures that capture input lifetimes. The function in the OP compiles just fine, the problem comes when you attempt to call it with closures too general for the bound. Probably the function writer intended the more general bound (but there's no good way to write it). Making the HRTB more explicit doesn't produce a better error. use core::future::{Future};
use anyhow::Error;
struct Session {}
impl Session {
pub async fn dispatch_request<T, F, Fut>(&self, interpreter: F) -> Result<T, Error>
where
F: for<'a> FnMut(&'a mut String) -> Fut,
Fut: Future<Output = Result<T, Error>>,
{
let mut interpreter = interpreter;
let mut stream = "hello".to_string();
interpreter(&mut stream).await
}
}
async fn test_interpreter(input_stream: &mut String) -> Result<String, Error> {
Ok(input_stream.clone())
}
#[tokio::main]
async fn main() {
let session = Session{};
session.dispatch_request(test_interpreter).await.unwrap();
}
Making the HRTB more explicit with a name other than use core::future::{Future};
use anyhow::Error;
struct Session {}
impl Session {
pub async fn dispatch_request<T, F, Fut>(&self, interpreter: F) -> Result<T, Error>
where
F: for<'b> FnMut(&'b mut String) -> Fut,
Fut: Future<Output = Result<T, Error>>,
{
let mut interpreter = interpreter;
let mut stream = "hello".to_string();
interpreter(&mut stream).await
}
}
async fn test_interpreter(input_stream: &mut String) -> Result<String, Error> {
Ok(input_stream.clone())
}
#[tokio::main]
async fn main() {
let session = Session{};
session.dispatch_request(test_interpreter).await.unwrap();
} error[[E0308]](https://doc.rust-lang.org/stable/error_codes/E0308.html): mismatched types
--> src/main.rs:27:5
|
27 | session.dispatch_request(test_interpreter).await.unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected trait `for<'b> FnOnce<(&'b mut String,)>`
found trait `for<'a> FnOnce<(&'a mut String,)>`
note: the lifetime requirement is introduced here
--> src/main.rs:9:45
|
9 | F: for<'b> FnMut(&'b mut String) -> Fut,
| ^^^ |
Code
Current output
Desired output
Rationale and extra context
This thread has some additional context as well as two proposed solutions. https://users.rust-lang.org/t/lifetime-bounds-to-use-for-future-that-isnt-supposed-to-outlive-calling-scope/89277
I understand this situation is one among a set of situations under which the same confusing error might manifest. However this might be a candidate for a special case check.
Thank you.
Other cases
No response
Anything else?
No response
The text was updated successfully, but these errors were encountered: