Hi,
I'm trying to design a highly generic AST, which allows each expression/statement/etc. to have user-specified associated data, as well as user-specified IR statements and expressions. The general design I have is:
- A trait for functionality that is required from the associated data (how to Visit it with the visitor pattern) (
AssociatedData
). - A trait consisting of associated types, one for each of the several IR items and associated data types (
AstAssociations
). - Downstream crates create an empty struct that implements
AstAssociations
. - This crate provides a handy
EmptyNode
struct, indicating the absence of associated data or IR items. It - This crate also provides a special
AssocBase
, which has configurable associated data (defaulting to empty), and is restricted to empty IR items.
However, I'm running into a compiler error, stating that there is an overflow when evaluating a trait requirement. However, that requirement should obviously be satisfied. I just can't seem to understand where the overflow comes from.
Here is the code:
#![recursion_limit = "1024"]
use std::marker::PhantomData;
trait AssociatedData<A: AstAssociations + ?Sized> {
// Left empty in this Gist. However, it will have behaviour
// that is guided by the generic A, for instance, Visitor
// pattern helpers.
}
trait AstAssociations {
type ExprAssociatedData: AssociatedData<Self>;
}
struct AssocBase<ExprAssociatedData = EmptyNode>(PhantomData<ExprAssociatedData>);
impl<ExprAssociatedData> AstAssociations for AssocBase<ExprAssociatedData>
where
ExprAssociatedData: AssociatedData<Self>,
{
type ExprAssociatedData = ExprAssociatedData;
}
struct EmptyNode;
impl<Assoc: AstAssociations + ?Sized> AssociatedData<Assoc> for EmptyNode {}
struct Statement<Assoc: AstAssociations + ?Sized>(PhantomData<Assoc>);
impl<Assoc: AstAssociations + ?Sized> Statement<Assoc> {
fn zoop() { }
}
fn main() {
let s: Statement<AssocBase> = Statement(PhantomData);
s.zoop()
}
And the compiler output is here:
error[E0275]: overflow evaluating the requirement `EmptyNode: AssociatedData<AssocBase>`
--> src/main.rs:29:12
|
29 | let s: Statement<AssocBase> = Statement(PhantomData);
| ^^^^^^^^^^^^^^^^^^^^
|
note: required because of the requirements on the impl of `AstAssociations` for `AssocBase`
--> src/main.rs:12:26
|
12 | impl<ExprAssociatedData> AstAssociations for AssocBase<ExprAssociatedData>
| ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `Statement`
--> src/main.rs:22:25
|
22 | struct Statement<Assoc: AstAssociations + ?Sized>(PhantomData<Assoc>);
| ^^^^^^^^^^^^^^^ required by this bound in `Statement`
For more information about this error, try `rustc --explain E0275`.
error: could not compile `playground` due to previous error
For reference, here's my Rust playground: