I tried to refactor some code using GATs, but ran into an error.
The following code is a reduced version of the code that produces the same error:
#![feature(generic_associated_types)]
trait Hittable {
type HitRecordType<'a>
where
Self: 'a,
Self::HitRecordType<'a>: HitRecord;
fn hit<'a>(&'a self) -> Self::HitRecordType<'a>;
}
trait HitRecord {
fn t(&self) -> f64;
}
struct CompleteHitRecord<'a> {
i: &'a f64,
}
impl<'a> HitRecord for CompleteHitRecord<'a> {
fn t(&self) -> f64 {
0.0
}
}
struct PartialHitRecord {}
impl HitRecord for PartialHitRecord {
fn t(&self) -> f64 {
0.0
}
}
struct AddMaterial<H> {
i: H,
j: f64,
}
impl<H> Hittable for AddMaterial<H>
where
H: for<'a> Hittable<HitRecordType<'a> = PartialHitRecord>,
{
type HitRecordType<'b> = CompleteHitRecord<'b>;
fn hit(&self) -> Self::HitRecordType<'_> {
CompleteHitRecord { i: &self.j }
}
}
fn main() {
println!("Hello, world!");
}
Playground link:
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=60c3ba61959021676bf87ec8ec9ecdbf
The compiler output is:
Compiling playground v0.0.1 (/playground)
error[E0275]: overflow evaluating the requirement `for<'a> <H as Hittable>::HitRecordType<'a> == _`
--> src/main.rs:40:9
|
40 | impl<H> Hittable for AddMaterial<H>
| ^^^^^^^^
|
note: required because of the requirements on the impl of `Hittable` for `AddMaterial<H>`
--> src/main.rs:40:9
|
40 | impl<H> Hittable for AddMaterial<H>
| ^^^^^^^^ ^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0275`.
error: could not compile `playground` due to previous error
I don't really know what causes the recursion and the error message isn't verbose enough for me to understand the root cause of this error.
It is totally possible that this code is architecturally wrong, I am using GATs for the first time.
A browser interface to the Rust compiler to experiment with the language