“Overflow evaluating the requirement” but that kind of recursion should not happen at all

后端 未结 1 1795
逝去的感伤
逝去的感伤 2020-12-06 19:35

Here is a kind of lengthy example because I was not able to reduce it further. Rust Playground

use std::marker::PhantomData;
use std::ops::{Add, Sub, Mul, Di         


        
相关标签:
1条回答
  • 2020-12-06 20:11

    ScalarVal(1) + a resolves basically to <ScalarVal(1) as Add>.add(a), which looks for an Add implementation on ScalarVal.

    For whatever reason, this one is checked first:

    impl<PixelP> Add<Image<PixelP>> for ScalarVal<<PixelP as Pixel>::ScalarType>
        where PixelP: Pixel,
              ScalarVal<<PixelP as Pixel>::ScalarType>: Add<PixelP, Output = PixelP>
    

    PixelP is uninstantiated at this point, so PixelP: Pixel can't be checked. Thus we get to

    ScalarVal<<PixelP as Pixel>::ScalarType>: Add<PixelP, Output = PixelP>
    

    Let's simplify this. Since PixelP is unknown right now, <PixelP as Pixel>::ScalarType is unknown. The actual information known by the compiler looks more like

    impl<T> Add<Image<T>> for ScalarVal<_>
        where ScalarVal<_>: Add<T, Output = T>
    

    So ScalarVal<_> looks for an Add<T, Output = T>. This means we should look for an appropriate T. Obviously this means looking in ScalarVal's Add impls. Looking at the same one, we get

    impl<T2> Add<Image<T2>> for ScalarVal<_>
        where ScalarVal<_>: Add<T2, Output = T2>
    

    which means that if this one matches, T == Image<T2>.

    Obviously then T2 == Image<T3>, T3 == Image<T4>, etc. This results in an overflow and general sadness. Rust never finds a disproof, so can't ever guarantee it's going down the wrong path.

    0 讨论(0)
提交回复
热议问题