Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expotential compile time with recursive trait bounds #75542

Open
weiznich opened this issue Aug 14, 2020 · 1 comment
Open

Expotential compile time with recursive trait bounds #75542

weiznich opened this issue Aug 14, 2020 · 1 comment
Labels
A-traits Area: Trait system C-bug Category: This is a bug. I-compiletime Issue: Problems and improvements with respect to compile times. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@weiznich
Copy link
Contributor

While developing diesel we've hit a surprising increase in compile time caused by our trait impls for tuples. See diesel-rs/diesel#2480 for details. I've extracted a somewhat minimal example here. There is an option to control the tuple size up to which traits should be implemented in line 861. For a size of 16 the compilation of the example succeeds in less then 2 seconds using the rust-playground + the current stable compiler. For a tuple size > 20 the playground is terminated. (Diesel takes ~30s to build while implementing traits for tuples up to 16 elements, and 17 minutes while implementing traits for tuples up to 32 elements for my local setup).

I suspect that this is caused by the combination of a having a recursive trait bound here + enforcing that bound for each tuple size here. Diesel itself has not only one trait that requires Self: SqlType, but probably the problem is increased by that.

@weiznich weiznich added the C-bug Category: This is a bug. label Aug 14, 2020
@jonas-schievink jonas-schievink added I-compiletime Issue: Problems and improvements with respect to compile times. A-traits Area: Trait system labels Aug 15, 2020
@JohnTitor JohnTitor added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Aug 16, 2020
@weiznich
Copy link
Contributor Author

Replacing the impl_sql_type with

macro_rules! impl_sql_type {
    (
        @build
        start_ts = [$($ST: ident,)*],
        ts = [$T1: ident,],
        bounds = [$($bounds: tt)*],
        is_null = [$($is_null: tt)*],
    )=> {
        impl<$($ST,)*> SqlType for ($($ST,)*)
        where
            $($ST: SqlType,)*
            $($bounds)*https://github.com/diesel-rs/diesel/pull/2485
            $T1::IsNull: OneIsNullable<$($is_null)*>,
        {
            type IsNull = <$T1::IsNull as OneIsNullable<$($is_null)*>>::Out;
        }

    };
    (
        @build
        start_ts = [$($ST: ident,)*],
        ts = [$T1: ident, $($T: ident,)+],
        bounds = [$($bounds: tt)*],
        is_null = [$($is_null: tt)*],
    )=> {
        impl_sql_type!{
            @build
            start_ts = [$($ST,)*],
            ts = [$($T,)*],
            bounds = [$($bounds)* $T1::IsNull: OneIsNullable<$($is_null)*>,],
            is_null = [<$T1::IsNull as OneIsNullable<$($is_null)*>>::Out],
        }
    };
    ($T1: ident, $($T: ident,)+) => {
        impl_sql_type!{
            @build
            start_ts = [$T1, $($T,)*],
            ts = [$($T,)*],
            bounds = [],
            is_null = [$T1::IsNull],
        }
    };
    ($T1: ident,) => {
        impl<$T1> SqlType for ($T1,)
        where $T1: SqlType,
        {
            type IsNull = $T1::IsNull;
        }
    }
}

speeds up the compile time for large tuples drastically. This is only replacing the recursive "calculation" of the associated type with an explicit version for each tuple size, so instead of having type IsNull = <FirstTupleElement as OneIsNullable<<(All, Other Tuple, Elements, …) as SqlType>::IsNull>::Out; we write now type IsNull = <FirstTupleElement as OneIsNullable<<SecondTupleElement as OneIsNullable<…>>::Out>>::Out;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-traits Area: Trait system C-bug Category: This is a bug. I-compiletime Issue: Problems and improvements with respect to compile times. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants