error[E0275]: overflow evaluating the requirement `Xxx<Xxx<Xxx<Xxx<Xxx<Xxx<Xxx<...>>>>>>>: Food`

トレイトの確認作業が無限再帰になってしまった。

パターン

パターン A

基本形

トレイト実装の確認において、その境界条件から同じトレイト実装の確認がまた必要となり、これが無限再帰する。

サンプル

以下では、TMyTrait になるには、Wrap<T>MyTrait であればよい。
そして、Wrap<T>MyTrait になるには、Wrap<Wrap<T>>MyTrait であればよい。
さらに、……と続いて永遠に確認が終らない。


fn main() {
    with_t(0);
}

fn with_t<T: MyTrait>(_: T) {}

trait MyTrait {}
impl<T> MyTrait for T where Wrap<T>: MyTrait {}

struct Wrap<T>(T);

error[E0275]: overflow evaluating the requirement `Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<...>>>>>>>: MyTrait`
 --> src/main.rs:5:14
  |
5 | fn with_t<T: MyTrait>(_: T) {}
  |              ^^^^^^^
  |
  = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`rust_test`)
note: required for `Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<...>>>>>>>>>>>>>>>>>>>>>` to implement `MyTrait`
 --> src/main.rs:8:9
  |
8 | impl<T> MyTrait for T where Wrap<T>: MyTrait {}
  |         ^^^^^^^     ^                ------- unsatisfied trait bound introduced here
  = note: 126 redundant requirements hidden
  = note: required for `T` to implement `MyTrait`
  = note: the full name for the type has been written to 'D:\dev\rust_test\target\debug\deps\rust_test-6b3b9ca234395a90.long-type-387083807051803833.txt'    
  = note: consider using `--verbose` to print the full type name to the console

error[E0275]: overflow evaluating the requirement `Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<...>>>>>>>: MyTrait`
 --> src/main.rs:8:38
  |
8 | impl<T> MyTrait for T where Wrap<T>: MyTrait {}
  |                                      ^^^^^^^
  |
  = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`rust_test`)
note: required for `Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<...>>>>>>>>>>>>>>>>>>>>>` to implement `MyTrait`
 --> src/main.rs:8:9
  |
8 | impl<T> MyTrait for T where Wrap<T>: MyTrait {}
  |         ^^^^^^^     ^                ------- unsatisfied trait bound introduced here
  = note: 126 redundant requirements hidden
  = note: required for `Wrap<T>` to implement `MyTrait`
  = note: the full name for the type has been written to 'D:\dev\rust_test\target\debug\deps\rust_test-6b3b9ca234395a90.long-type-3390070394551464438.txt'   
  = note: consider using `--verbose` to print the full type name to the console

For more information about this error, try `rustc --explain E0275`.
error: could not compile `rust_test` (bin "rust_test") due to 2 previous errors

パターン B

バグ

まだ修正されていないコンパイラのバグが原因。

このパターンでは無限再帰しないはずだが、誤動作しているらしい。

条件は基本形と似ている。まず、基本形と同様、実装対象の型と境界の型は、型パラメタ部分以外の型の構造とトレイトが同じになる。ただし、基本形では実装対象の型のパラメタ部分を他の型で包含したのが境界の型になるが、このパターンではそれが逆になる。

サンプル

以下では、MyTrait の実装対象の型 &'a Wrap<T> に境界の型 &'a T がある。ここで、両者はどちらも MyTrait を実装し、前者は後者の TWrap で包含しており、バグの条件を満たしている。なお、MyTrait の実装型には &'a i32 もあるが、トレイト実装どうしが衝突するのを予防するため、エラーとなる側も確認されてしまう。


fn main() {
    with_t(0i32);
}

fn with_t<T>(_: T) where for<'a> &'a T: MyTrait {}

trait MyTrait {}
impl<'a> MyTrait for &'a i32 {}
impl<'a, T> MyTrait for &'a Wrap<T> where &'a T: MyTrait {}

#[allow(dead_code)]
struct Wrap<T>(T);

error[E0275]: overflow evaluating the requirement `&Wrap<_>: MyTrait`
 --> src/main.rs:2:5
  |
2 |     with_t(0i32);
  |     ^^^^^^^^^^^^
  |
  = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`rust_test`)
note: required for `&Wrap<Wrap<_>>` to implement `MyTrait`
 --> src/main.rs:9:13
  |
9 | impl<'a, T> MyTrait for &'a Wrap<T> where &'a T: MyTrait {}
  |             ^^^^^^^     ^^^^^^^^^^^              ------- unsatisfied trait bound introduced here
  = note: 126 redundant requirements hidden
  = note: required for `&Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<...>>>>>>>>>>>>>>>>>>>>>` to implement `for<'a> MyTrait`
note: required by a bound in `with_t`
 --> src/main.rs:5:48
  |
5 | fn with_t<T>(_: T) where for<'a> &'a T: MyTrait {}
  |                                         ^^^^^^^ required by this bound in `with_t`
  = note: the full name for the type has been written to 'D:\dev\rust_test\target\debug\deps\rust_test-6b3b9ca234395a90.long-type-12800731075102081934.txt'  
  = note: consider using `--verbose` to print the full type name to the console

For more information about this error, try `rustc --explain E0275`.
error: could not compile `rust_test` (bin "rust_test") due to 1 previous error

新しいトレイトソルバー

開発中のトレイトソルバーではこの問題が発生しない。

試用手順は以下の通り。

  • ナイトリー版を有効化
    (具体的な方法は『バージョンの切替』を参照)

  • ビルド時のコマンドライン引数で新しいトレイトソルバーを有効化。
    (以下は .cargo/config.toml ファイルからの引数の指定方法)

    
    [build]
    rustflags = ["-Znext-solver"]