rustfmt icon indicating copy to clipboard operation
rustfmt copied to clipboard

Misformatting: excessive indentation due to `dyn` in type alias

Open inodentry opened this issue 2 years ago • 2 comments
trafficstars

I have some pretty complicated type aliases to hide away type complexity (boxed dyn Futures with generics).

Rustfmt formats them like this:

pub type AccountVerifyFuture<D, A> = Pin<
    Box<
        dyn Future<
                Output = Result<
                    VerifySuccess,
                    VerifyError<<D as AccountData>::Error, <A as AccountVerifier<D>>::Error>,
                >,
            > + Send,
    >,
>;
pub type GameExtrasProcessFuture<G> = Pin<
    Box<
        dyn Future<
                Output = Result<
                    (),
                    GameError<
                        <<G as GameExtrasHandler>::Data as GameExtras>::Error,
                        <G as GameExtrasHandler>::Error,
                    >,
                >,
            > + Send,
    >,
>;

Notice how the presence of the dyn keyword caused everything to be indented further in, by an additional 4 spaces (closing > aligns with Future).

I'd expect the above code to be formated like this:

pub type AccountVerifyFuture<D, A> = Pin<
    Box<
        dyn Future<
            Output = Result<
                VerifySuccess,
                VerifyError<<D as AccountData>::Error, <A as AccountVerifier<D>>::Error>,
            >,
        > + Send,
    >,
>;
pub type GameExtrasProcessFuture<G> = Pin<
    Box<
        dyn Future<
            Output = Result<
                (),
                GameError<
                    <<G as GameExtrasHandler>::Data as GameExtras>::Error,
                    <G as GameExtrasHandler>::Error,
                >,
            >,
        > + Send,
    >,
>;

Note how the closing > now aligns with the dyn, and there is no excessive indentation of everything inside the Future.

inodentry avatar May 23 '23 12:05 inodentry

@inodentry Thanks for reaching out. I agree the formatting with dyn looks a little odd.

@calebcartwright is this something we need to put on t-styles radar? From what I can tell the style guide doesn't provide any examples using dyn.

I'm also wondering if the current formatting contradicts the style guide's prescription for how to handle line breaks. Should + Send go on its own line? like this:

pub type GameExtrasProcessFuture<G> = Pin<
    Box<
        dyn Future<
            Output = Result<
                (),
                GameError<
                    <<G as GameExtrasHandler>::Data as GameExtras>::Error,
                    <G as GameExtrasHandler>::Error,
                >,
            >,
        >
        + Send,
    >,
>;

ytmimi avatar May 26 '23 16:05 ytmimi

This is definitely a shape-related bug where the presence of dyn results in the wrong indentation being used when there's also multiple bounds (note that the formatting is correct when + Send is removed, at least in quick testing on the playground).

As such I suspect this is probably another bug in the messy logic that handles bounds (linked below for reference), though I suppose it's possible we could get lucky and that the issue is with the shape derivation at a call site somewhere up the stack

https://github.com/rust-lang/rustfmt/blob/a44c7ea5923caa8f908ae0fdd6563033a7ad88da/src/types.rs#L929-L1082

I'm also wondering if the current formatting contradicts the style guide's prescription for how to handle line breaks. Should + Send go on its own line? like this:

No, not in my reading but I think that's a topic better discussed somewhere other than this issue

calebcartwright avatar May 26 '23 22:05 calebcartwright