Skip to content

x/tools/internal/refactor/inline: simplify control statements when the operand is known #65572

Open
@adonovan

Description

@adonovan

When inlining a call f(true) to a function such as this one:

func f(x bool) {
    if x {
        fmt.Println("hello")
    } else {
        fmt.Println("goodbye")
    }
}

the inliner should apply logical simplifications to the body when the argument value (here "true") is known. The result would then be simply fmt.Println("hello").

Logical simplification is conceptually orthogonal to inlining: all it requires is a piece of code and some extra knowledge about the values or variables (e.g. x = true). But unfortunately the inliner doesn't get to see the typed syntax after the inlining, so the analysis would need to be integrated into the callee portion of the inliner analysis.

A good starting point would be to tabulate the set of statements of the form for range x {...} or if x {...} else {...} where the operand x depends only on constants and parameters. The expression can then be retained and reevaluated (similar to the approach in the falcon analysis), and if it is degenerate (true, false, zero, empty, a singleton, etc) then the statement can be reduced according to a set of rules:

  • if true S1 else S2 => S1
  • if false S1 else S2 => S2
  • for x := range []T{} S => nothing
  • for x := range []T{v} S => { x := v; S } (assuming no break/continue)
  • for i := 0; i < 0; i++ S => nothing
  • etc

@stapelberg

Metadata

Metadata

Assignees

No one assigned

    Labels

    RefactoringIssues related to refactoring toolsToolsThis label describes issues relating to any tools in the x/tools repository.goplsIssues related to the Go language server, gopls.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions