Open
Description
I tried this code:
use std::collections::HashMap;
use std::hash::Hash;
pub struct Foo<T>
where
T: Hash + Eq + Clone + 'static,
{
rule: Box<dyn Fn(&T) -> Option<Vec<(T, u64)>>>
}
impl<T> Foo<T>
where
T: Hash + Eq + Clone + 'static
{
pub fn new(rules: HashMap<T, Vec<(T, u64)>>) -> Self {
let rule = Box::new(move |src| rules.get(src).map(|o| o.to_owned()));
Self { rule }
}
}
I expected to see this happen: this should compile, because this equivalent(?) code compiles:
use std::collections::HashMap;
use std::hash::Hash;
pub struct Foo<T>
where
T: Hash + Eq + Clone + 'static,
{
rule: Box<dyn Fn(&T) -> Option<Vec<(T, u64)>>>
}
impl<T> Foo<T>
where
T: Hash + Eq + Clone + 'static
{
pub fn new(rules: HashMap<T, Vec<(T, u64)>>) -> Self {
Self { rule: Box::new(move |src| rules.get(src).map(|o| o.to_owned())) }
}
}
the only difference here is the intermediate variable rule
, which appears to be inferring an incorrect type for some reason. the code also compiles successfully if rule
is given an explicit type annotation with the same type as defined in the struct.
Instead, this happened:
error: implementation of `FnOnce` is not general enough
--> src/lib.rs:17:16
|
17 | Self { rule }
| ^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'2 T) -> Option<Vec<(T, u64)>>` must implement `FnOnce<(&'1 T,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 T,)>`, for some specific lifetime `'2`
this seems maybe related to #87079 or #70263 but i can't tell if it's actually the same problem or not (this one isn't a problem with function arguments).
Meta
rustc --version --verbose
:
1.59.0-nightly
(2021-12-23 c09a9529c51cde41c110)