距离我们上次更新已经过去了近半年。我们正在重新实现 rustc 的特征求解器,目标是完全替换现有的系统。这应该可以让我们修复一些长期存在的错误,实现未来的类型系统改进,并减少编译时间。有关更详细的介绍,请参阅之前的更新。我们在新的求解器上继续取得了重大进展,主要集中在使求解器准备好用于一致性检查。我们更改了不稳定的编译器标志以启用新的求解器:您现在可以使用 -Znext-solver=globally
在所有地方启用它,并使用 -Znext-solver=coherence
仅在一致性检查中启用新的求解器。
特征求解器的重新实现现在已准备好用于一致性检查,该检查负责防止特征实现的重叠。旧求解器的所有已知行为更改都是预期的,并且错误消息的质量应与现有实现相匹配。然而,在过去的几个月中,对非致命溢出的处理已成为最重要和最复杂的问题之一。
非致命溢出
与现有的特征求解器不同,新的求解器在达到递归限制时不会立即中止编译
struct Wrapper<T>(T);
trait Overflow {}
impl<T> Overflow for Wrapper<Wrapper<T>> where Wrapper<T>: Overflow {}
impl Overflow for Wrapper<u32> {}
// Checking whether these two implementations overlap
// tries to prove that either `Wrapper<_>: Overflow` or
// `Wrapper<_>: Copy` do not hold.
//
// The existing solver first checks `Wrapper<_>: Overflow`,
// resulting in overflow and aborting compilation.
//
// The new solver does not abort compilation on overflow and
// considers the implementations to be disjoint, given that
// `Wrapper<_>: Copy` does not hold.
trait MayOverlap {}
impl<T: Overflow + Copy> MayOverlap for T {}
impl<T> MayOverlap for Wrapper<T> {}
这种更改是必要的,因为流行的 crate,例如 typenum,现在使用新的求解器会达到递归限制,如果溢出仍然是致命的,则会中断。这是由于旧求解器中存在的启发式的移除造成的。这也是可取的,因为编译结果否则将依赖于顺序。这种顺序依赖性会使未来对类型系统的更改变得复杂,例如 尝试在旧求解器中切换到延迟投影相等也最终导致 typenum 中出现溢出错误,阻止其被合并。用户也可以观察到这一点,例如,在上面的示例中将 where 子句的顺序切换为 T: Copy + Overflow
会使该代码片段使用旧的求解器编译。
新的求解器现在在达到递归限制时返回溢出。但是,这种更改本身会导致求解器由于指数级爆炸而非常容易挂起。因此,在遇到溢出后,我们会大大限制后续目标的可用递归深度,并丢弃一些导致溢出的目标的推断约束。
重要的是要平衡特征求解器的性能和特征系统的表达能力。虽然我们对目前采用的方法相当满意,但要做到这一点更多的是艺术而非科学。我们相信我们目前的方法在大多数情况下是高性能的,并且可以在未来实现进一步的显著性能优化。我们还希望它能够提供必要的表达能力,以向后兼容旧的求解器,并按照用户的预期行事。
展望未来并呼吁测试
由于我们认为现在可以使用新的求解器进行一致性检查,并且它处于稳定就绪状态,请通过启用不稳定的 -Znext-solver=coherence
编译器标志来试用新的实现。如果您遇到任何行为或性能回归、诊断问题,甚至是不健全性1,请在 GitHub 上打开一个 issue。
在一致性检查期间使用新的求解器将改善某些边缘情况下的行为,至少修复一个几乎无法利用的不健全性。它还将允许我们删除对现有求解器中“crate 间模式”的支持。但是,使用新的求解器的大部分积极影响2 只有在它在更多领域中使用时才会适用。
因此,我们打算稍微延迟其在一致性检查中的稳定化,以确保我们的设计选择不会在未来造成复杂情况。展望未来,我们将把工作重点重新放在在所有地方启用新的求解器上。通过修复更多剩余的 -Znext-solver=globally
问题,我们应该对我们的溢出处理方法更有信心。我们预计实际上将在 2024 年 3 月稳定新求解器在一致性检查中的使用,并打算在此之前提供额外的学习材料和文档。
如果您对新的求解器有任何疑问或想法,请在 zulip 上联系我们。