如何解决HRTB错误?

时间:2018-07-20 06:01:16

标签: rust higher-rank-types

由于compiler bug,此代码段无法编译:

struct Theory<'a, T: 'a> {
    left: &'a T,
}

pub struct Contain<'a, T: 'a, U>
where
    &'a T: IntoIterator,
    for<'x> <(&'a T) as IntoIterator>::Item: PartialEq<&'x U>,
{
    theory: Theory<'a, T>,
    right: U,
}

impl<'a, T: 'a, U> Drop for Contain<'a, T, U>
where
    &'a T: IntoIterator,
    for<'x> <(&'a T) as IntoIterator>::Item: PartialEq<&'x U>,
{
    fn drop(&mut self) {
        //TODO
    }
}

fn main() {}

我需要这个,因为我必须将迭代器ItemU进行比较;但是Item是引用类型,因为我在借来的集合中调用into_iter()

然后我尝试了类似的方法来解决:

struct Theory<'a, T: 'a> {
    left: &'a T,
}

pub struct Contain<'a, 'b: 'a, T: 'a, U: 'b>
where
    &'a T: IntoIterator,
    <(&'a T) as IntoIterator>::Item: PartialEq<&'b U>,
{
    theory: Theory<'a, T>,
    right: U,
    _marker: ::std::marker::PhantomData<&'b ()>,
}

impl<'a, 'b, T: 'a, U> Drop for Contain<'a, 'b, T, U>
where
    &'a T: IntoIterator,
    <(&'a T) as IntoIterator>::Item: PartialEq<&'b U>,
{
    fn drop(&mut self) {
        for left in self.theory.left.into_iter() {
            if left == &self.right {
                return;
            }
        }
        //handle case where all lefts are different of right
    }
}

fn main() {}

但是我得到了:

cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
  --> src/main.rs:22:24
   |
22 |             if left == &self.right {
   |                        ^^^^^^^^^^^
   |

如何遍历left,然后将每个元素与right进行比较?

1 个答案:

答案 0 :(得分:3)

您只需将特征绑定到PartialEq<B>。特质中的方法eqne通过引用接受所有参数,因此没有理由要求PartialEq来引用类型。

这可行:

impl<'a, 'b, T: 'a, U> Drop for Contain<'a, 'b, T, U>
where
    &'a T: IntoIterator,
    <(&'a T) as IntoIterator>::Item: PartialEq<U>,  // <-- change 1 
{
    fn drop(&mut self) {
        for left in self.theory.left.into_iter() {
            if left == self.right {                 // <-- change 2
                return;
            }
        }
        //handle case where all lefts are different of right
    }
}