I am trying to use the following "extracted architecture" in a larger project. I'm using GATs, and I see no easy way to work around them. This snippet works, but I slip on ICE constantly when taking this architecture to the larger project. Any pointers for avoiding generic_associated_types, and preferably also type_alias_impl_trait?
#![allow(incomplete_features)]
#![feature(type_alias_impl_trait)]
#![feature(generic_associated_types)]
use core::marker::PhantomData;
////////////////////////////////////////////////////////////////////////////////
trait SparseColumnGenerator {
type NT;
type MySparseColumn<'a>: SparseColumn<'a, Self::NT>;
fn generate_column<'a>(&'a self) -> Self::MySparseColumn<'a>;
}
trait SparseColumn<'a, NT: 'a>
where
for<'r> &'r Self: IntoIterator<Item = &'a (usize, NT)>,
{
}
////////////////////////////////////////////////////////////////////////////////
struct IGenerateSparseColumns<NT>(Vec<(usize, NT)>);
impl<NT: 'static> SparseColumnGenerator for IGenerateSparseColumns<NT> {
type NT = NT;
type MySparseColumn<'a> = IAmAColumn<'a, NT, impl Iterator<Item = &'a (usize, NT)> + Clone>;
fn generate_column<'a>(&'a self) -> Self::MySparseColumn<'a> {
IAmAColumn(self.0.iter().filter(|&(i, _)| i % 2 == 0))
}
}
struct IAmAColumn<'a, NT: 'a, I: Iterator<Item = &'a (usize, NT)>>(I);
impl<'a, NT: 'a, I: 'a + Iterator<Item = &'a (usize, NT)> + Clone> SparseColumn<'a, NT> for IAmAColumn<'a, NT, I> {
}
impl<'a, NT, I: Iterator<Item = &'a (usize, NT)> + Clone> IntoIterator for &IAmAColumn<'a, NT, I> {
type Item = &'a (usize, NT);
type IntoIter = impl Iterator<Item = Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.0.clone().filter(|&(i, _)| i % 4 == 0).clone()
}
}
////////////////////////////////////////////////////////////////////////////////
trait InverseMaintenance<'data> {
type InnerNT;
fn compute<NT: 'data, C>(&self, column: C) -> Self::InnerNT
where
&'data NT: Into<Self::InnerNT>,
C: SparseColumn<'data, NT>,
for<'r> &'r C: IntoIterator<Item = &'data (usize, NT)>,
;
}
struct IMaintainInverse<NT>(PhantomData<NT>);
impl<'data, InnerNT> InverseMaintenance<'data> for IMaintainInverse<InnerNT> {
type InnerNT = InnerNT;
fn compute<NT: 'data, C>(&self, column: C) -> InnerNT
where
&'data NT: Into<InnerNT>,
C: SparseColumn<'data, NT>,
for<'r> &'r C: IntoIterator<Item = &'data (usize, NT)>,
{
let x = &column;
for (_, y) in x {
return y.into();
}
panic!();
}
}
////////////////////////////////////////////////////////////////////////////////
fn main() {
let data = IGenerateSparseColumns(vec![(3, 0), (8, 1), (10, 2), (99, 3)]);
let x = data.generate_column();
for z in &x {
let (_, y) = z;
println!("{}", y);
}
for y in &x {
println!("{:?}", y);
}
let a = IMaintainInverse(Default::default());
let result: &i32 = a.compute(x);
println!("{}", result);
}