-
Notifications
You must be signed in to change notification settings - Fork 0
minijinja: type annotations needed #195
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Labels
from-crater
A regression found via a crater run, not part of our test suite
Comments
Instance of #168 enum Value {
String(String),
U32(u32),
}
trait Arg<'a> {
type Output;
fn from_value(value: &'a Value) -> Option<Self::Output>;
}
impl<'a, 'b> Arg<'a> for &'b str {
type Output = &'a str;
fn from_value(value: &'a Value) -> Option<Self::Output> {
match value {
Value::String(s) => Some(s),
Value::U32(_) => None,
}
}
}
impl<'a> Arg<'a> for u32 {
type Output = u32;
fn from_value(value: &'a Value) -> Option<Self::Output> {
match value {
Value::String(_) => None,
Value::U32(x) => Some(*x),
}
}
}
fn get_values() -> Vec<Value> {
vec![Value::String("string".into()), Value::U32(128)]
}
trait Filter<A> {
fn filter(&mut self, arg: A);
}
impl<A, F: FnMut(A)> Filter<A> for F {
fn filter(&mut self, arg: A) {
self(arg)
}
}
fn inspect_values<F, A>(mut f: F)
where
A: for<'a> Arg<'a>,
F: for<'a> Filter<<A as Arg<'a>>::Output> + Filter<A>,
{
let values = get_values();
for arg in values.iter().filter_map(A::from_value) {
f.filter(arg);
}
}
fn generic_caller<F, A>(f: F)
where
A: for<'a> Arg<'a>,
F: for<'a> Filter<<A as Arg<'a>>::Output> + Filter<A>,
{
inspect_values(f)
}
fn main() {
generic_caller(|x: u32| println!("{x}"));
generic_caller(|x: &str| println!("'{}' has len {}", x, x.len()));
} |
Tragic :< |
a rewrite which should fix this? enum Value {
String(String),
U32(u32),
}
trait Arg<'a> {
type Output;
fn from_value(value: &'a Value) -> Option<Self::Output>;
}
impl<'a, 'b> Arg<'a> for &'b str {
type Output = &'a str;
fn from_value(value: &'a Value) -> Option<Self::Output> {
match value {
Value::String(s) => Some(s),
Value::U32(_) => None,
}
}
}
impl<'a> Arg<'a> for u32 {
type Output = u32;
fn from_value(value: &'a Value) -> Option<Self::Output> {
match value {
Value::String(_) => None,
Value::U32(x) => Some(*x),
}
}
}
fn get_values() -> Vec<Value> {
vec![Value::String("string".into()), Value::U32(128)]
}
trait Filter<A: for<'a> Arg<'a>> {
fn filter<'a>(&mut self, arg: <A as Arg<'a>>::Output);
}
// Move both `FnMut` bounds to the impl of `Filter` instead of having
// two generic bounds. This means we're now always choosing a unique
// where-bound in `generic_caller` and no longer rely on incomplete
// alias-relate.
impl<A: for<'a> Arg<'a>, F: for<'a> FnMut(<A as Arg<'a>>::Output) + FnMut(A)> Filter<A> for F {
fn filter<'a>(&mut self, arg: <A as Arg<'a>>::Output) {
self(arg)
}
}
fn inspect_values<F, A>(mut f: F)
where
A: for<'a> Arg<'a>,
F: Filter<A>,
{
let values = get_values();
for arg in values.iter().filter_map(A::from_value) {
f.filter(arg);
}
}
fn generic_caller<F, A>(f: F)
where
A: for<'a> Arg<'a>,
F: Filter<A>,
{
inspect_values(f)
}
fn foo(x: &str) {
println!("this is '{x}'")
}
fn main() {
generic_caller(|x: u32| println!("{x}"));
generic_caller(|x: &str| println!("'{}' has len {}", x, x.len()));
generic_caller(foo);
} |
fixed by mitsuhiko/minijinja#787 |
# for free
to join this conversation on GitHub.
Already have an account?
# to comment
The text was updated successfully, but these errors were encountered: