[E0308] one type is more general than the other: expected and found are reported as same #114849
Closed as not planned
Closed as 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