foundry-rs/foundry

Forge fmt incorrectly handles multi-line function pointer types in `returns` definitions

emo-eth opened this issue · 1 comments

Component

Forge

Have you ensured that all of these are up to date?

  • Foundry
  • Foundryup

What version of Foundry are you on?

forge 0.2.0 (9256265 2023-01-12T00:04:39.480435Z)

What command(s) is the bug in?

fmt

Operating System

macOS (Apple Silicon)

Describe the bug

When running forge fmt on the following code, Forge will introduce two new tab-widths of spacing on the line(s) taken up by the function attributes (internal, pure, returns, etc) every time the command is run, even when it means the resulting line(s) will exceed the max line length specified by settings. This is true regardless of default or custom [fmt] settings.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract ReturnFnFormat {
    function returnsFunction()
        internal
        pure
        returns (
            function() 
                    internal pure returns (uint256)
        )
    {}
}

It also will not correctly put a space between returns and the parentheses containing the type(s) returned by the returned function pointer, but will correctly add one to the function definition's returns attribute.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract ReturnFnFormat {
    function returnsFunction()
        internal
        pure
        returns(
            function() 
            internal pure returns(uint256)
        )
    {}
}

becomes

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract ReturnFnFormat {
    function returnsFunction()
        internal
        pure
        returns (
            function() 
                    internal pure returns(uint256)
        )
    {}
}

We're still facing this issue, but I wanted to share two workarounds for people who come through here:

  1. Wrap the return in // forgefmt: disable-start and // forgefmt: disable-end
  2. Pack everything onto one line and then run forge fmt

The second option typically results in minimal or no changes, and ameliorates the problem of forge fmt adding a new tab width each time the command is run.

It'd be great to get a proper fix, though :)