Confusing lifetime outlives error when mixing generics and Fn traits
Open
Nobody has claimed this yet.
A-diagnostics
T-compiler
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Code
fn wrap(s: &str) -> Option<&str> {
Some(s)
}
fn apply<T, U>(f: impl Fn(&T) -> U) -> T
where
T: Default,
{
let x = T::default();
f(&x);
x
}
fn foo() {
let _ = apply::<String, _>(|s| wrap(s));
}
Current output
error: lifetime may not live long enough
--> src/lib.rs:15:36
|
15 | let _ = apply::<String, _>(|s| wrap(s));
| -- ^^^^^^^ returning this value requires that `'1` must outlive `'2`
| ||
| |return type of closure is Option<&'2 str>
| has type `&'1 String`
Desired output
Rationale and extra context
No response
Other cases
Removing the reliance on deref:
fn wrap(s: &String) -> Option<&String> {
Some(s)
}
fn apply<T, U>(f: impl Fn(&T) -> U) -> T
where
T: Default,
{
let x = T::default();
f(&x);
x
}
fn foo() {
let _ = apply::<String, _>(wrap);
}
error: implementation of `Fn` is not general enough
--> src/lib.rs:15:13
|
15 | let _ = apply::<String, _>(wrap);
| ^^^^^^^^^^^^^^^^^^ implementation of `Fn` is not general enough
|
= note: `for<'a> fn(&'a String) -> Option<&'a String> {wrap}` must implement `Fn<(&String,)>`
= note: ...but it actually implements `Fn<(&'0 String,)>`, for some specific lifetime `'0`
Using fn pointer:
fn wrap(s: &String) -> Option<&String> {
Some(s)
}
fn apply<T, U>(f: fn(&T) -> U) -> T
where
T: Default,
{
let x = T::default();
f(&x);
x
}
fn foo() {
let _ = apply::<String, _>(wrap);
}
error[E0308]: mismatched types
--> src/lib.rs:15:32
|
15 | let _ = apply::<String, _>(wrap);
| ------------------ ^^^^ one type is more general than the other
| |
| arguments to this function are incorrect
|
= note: expected fn pointer `for<'a> fn(&'a String) -> _`
found fn item `for<'a> fn(&'a String) -> Option<&'a String> {wrap}`
note: function defined here
--> src/lib.rs:5:4
|
5 | fn apply<T, U>(f: fn(&T) -> U) -> T
| ^^^^^ --------------
For more information about this error, try `rustc --explain E0308`.
Rust Version
stable 1.88.0
Anything else?
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the src/lib.rs reproducer and the three diagnostic cases in the issue, using Rust stable 1.88.0 as the baseline. Compare the reported lifetime, Fn-trait, and fn-pointer errors and determine what diagnostic behavior should replace the confusing output; done requires a clear, agreed diagnostic outcome for the reported examples.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100