Indexing 使用幻象作用域绕过边界检查

Indexing 使用幻象作用域绕过边界检查,indexing,rust,dependent-type,Indexing,Rust,Dependent Type,我想构造一个与某个值关联的索引类型,该值是usize的包装,这样从该值创建的任何向量都不需要检查索引。看起来幻影生命周期可以用来做一些少量的依赖类型的编程,比如这样。这能行吗?还是有些事情我没有考虑 换句话说,使用下面的模块是否不可能编写出内存不足的“安全”代码 还有,有没有办法在没有单元参考的情况下实现这一点 pub mod things { use std::iter; #[derive(Clone, Copy)] pub struct ThingIndex<

我想构造一个与某个值关联的索引类型,该值是
usize
的包装,这样从该值创建的任何向量都不需要检查索引。看起来幻影生命周期可以用来做一些少量的依赖类型的编程,比如这样。这能行吗?还是有些事情我没有考虑

换句话说,使用下面的模块是否不可能编写出内存不足的“安全”代码

还有,有没有办法在没有单元参考的情况下实现这一点

pub mod things {
    use std::iter;

    #[derive(Clone, Copy)]
    pub struct ThingIndex<'scope>(usize, &'scope ());
    pub struct Things {
        nthings: usize,
    }
    pub struct ThingMapping<'scope, V>(Vec<V>, &'scope ());

    impl Things {
        pub fn in_context<F: FnOnce(&Things) -> V, V>(nthings: usize, continuation: F) -> V {
            continuation(&Things { nthings })
        }
        pub fn make_index<'scope>(&'scope self, i: usize) -> ThingIndex<'scope> {
            if i >= self.nthings {
                panic!("Out-of-bounds index!")
            }
            ThingIndex(i, &())
        }
        pub fn make_mapping<'scope, V: Clone>(&'scope self, def: V) -> ThingMapping<'scope, V> {
            ThingMapping(iter::repeat(def).take(self.nthings).collect(), &())
        }
    }

    impl<'scope, V> ThingMapping<'scope, V> {
        pub fn get<'a>(&'a self, ind: ThingIndex<'scope>) -> &'a V {
            unsafe { &self.0.get_unchecked(ind.0) }
        }
        // ...
    }
}
注意:上下文中的
松散地基于Haskell的
runST
函数。在Haskell中,
runST
的类型签名需要
RankNTypes
。我想知道这是否是不可能的,因为Rust编译器没有与
RankNTypes
的行为相结合

#[cfg(test)]
mod tests {
    use crate::things::*;

    #[test]
    fn it_fails() {
        Things::in_context(1, |r1| {
            Things::in_context(5, |r2| {
                let m1 = r1.make_mapping(());
                let i2 = r2.make_index(3);
                assert_eq!(*m1.get(i2), ());
            });
        })
    }
}