Not planned
Description
Code
use std::{
fmt::Debug,
};
#[derive(Clone,Debug)]
struct Data {
name: String,
}
impl Data {
fn new(name: &'static str) -> Self {
Self {
name: name.to_owned(),
}
}
fn name(&self) -> &String {
&self.name
}
}
fn assert_all<FN, A, E>(
producer: Vec<Data>,
f: FN,
expecteds: Vec<E>,
)
where
FN: FnMut(&Data) -> A,
A: Debug + std::cmp::PartialEq<E>,
E: Debug,
{
let data = producer.clone();
let actuals: Vec<_> = data.iter().map(f).collect();
assert_eq!(actuals, expecteds);
}
fn main() {
let producer = vec![
Data::new("first"),
Data::new("second"),
];
assert_all(producer, Data::name, vec!["first", "second"]);
}
Current output
error[E0308]: mismatched types
--> src/main.rs:42:5
|
42 | assert_all(producer, Data::name, vec!["first", "second"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected reference `&String`
found reference `&String`
note: the lifetime requirement is introduced here
--> src/main.rs:28:25
|
28 | FN: FnMut(&Data) -> A,
| ^
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` (bin "playground") due to previous error
Desired output
- Underline (
^^^^
) code doesn't point to faulty types. - Lifetime is "noted", but not represented in output.
- Don't know as I can't really understand issue with current output. I suspect issue comes from lifetime not "just types" (I suppose lifetime are part of type signature).
Rationale and extra context
No response
Other cases
I tried to add explicit lifetime 'inner
to method generic signature, and bound to both f
arg and A
(https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b1ae4d1f31e235183b0bc164d8c777bf):
fn assert_all<'inner, FN, A, E>(...) where
FN: FnMut(&'inner Data) -> A,
A: 'inner + Debug + std::cmp::PartialEq<E>,
{ ... }
But got another issue about data
needed to outlive assert_all
function. Sounds like it's interpreted as a requirement that data
must outlive f
:
error[E0597]: `data` does not live long enough
--> src/main.rs:33:27
|
22 | fn assert_all<'inner, FN, A, E>(
| ------ lifetime `'inner` defined here
...
32 | let data = producer.clone();
| ---- binding `data` declared here
33 | let actuals: Vec<_> = data.iter().map(f).collect();
| ^^^^^^^^^^^-------
| |
| borrowed value does not live long enough
| argument requires that `data` is borrowed for `'inner`
34 | assert_eq!(actuals, expecteds);
35 | }
| - `data` dropped here while still borrowed
For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground` (bin "playground") due to previous error
Anything else?
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
asquared31415 commentedon Aug 15, 2023
minimized:
playground
trevyn commentedon Feb 2, 2024
cc #112985
loganmzz commentedon Feb 2, 2024
@trevyn @hartwork Should I close this in favor of #112985 (or designated "root") ?
My main complain is about compiler error message that makes non-sense. Which doesn't help me to define if I'm doing wrong or if it's a compiler issue.
hartwork commentedon Feb 2, 2024
@loganmzz from a quick look it seems to be the same indeed. I have added #114849 (here) to the list at #112985 now. We still need a fix, but since the issue number is bigger here, closing as a duplicate probably makes sense even unfixed.