lotsoftools

Rust Error E0720 Explained: When Impl Trait Type Expands to a Recursive Type

Understanding Rust Error E0720

Rust Error E0720 occurs when an impl Trait type expands to a recursive type. Rust requires that every impl Trait type is expandable to a concrete type that contains no impl Trait types.

An example of erroneous code

#![allow(unused)]
fn main() {
    fn make_recursive_type() -> impl Sized {
        [make_recursive_type(), make_recursive_type()]
    }
}

In this example, an impl Trait type is defined as a function return type, and it is recursively called inside the function body, creating T that is equal to [T, T]. This code will trigger Rust Error E0720 as it violates the requirement for an impl Trait type to expand to a non-recursive concrete type.

Fixing the Error

One way to fix the error is by using a concrete type instead of an impl Trait type. In the case of our example, the function can return a Vec<Box<T>>:

#![allow(unused)]
fn main() {
    fn make_recursive_type() -> Vec<Box<[isize; 2]>> {
        vec![Box::new([0, 0]), Box::new([0, 0])]
    }
}

In this corrected example, we replace the impl Trait type with a Vec<Box<[isize; 2]>>, which is a concrete type, resolving Rust Error E0720.

Alternative Solution: Trait Objects

Another approach to fix Rust Error E0720 is by using trait objects. Trait objects represent instances of a trait without specifying their concrete type:

trait RecursiveType {}

impl RecursiveType for [Box<dyn RecursiveType>; 2] {}

fn main() {
    fn make_recursive_type() -> Box<dyn RecursiveType> {
        Box::new([Box::new([0, 0]), Box::new([0, 0])])
    }
}

In this solution, we define a trait 'RecursiveType' and implement it for a concrete type '[Box<dyn RecursiveType>;2]'. By returning a Box<dyn RecursiveType> in the 'make_recursive_type' function, we avoid the error.