Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
internal/refactor/inline: fallible constant analysis
This change adds an analysis of "fallible constant" (falcon) expressions, and uses it to reject substitution of parameters by constant arguments in the (rare) cases where it is not safe. When substituting a parameter by its argument expression, it is (perhaps surprisingly) not always safe to replace a variable by a constant expression, even of exactly the same type, as it may turn a dynamic error into a compile-time one, as in this example: func f(s string) { if len(s) > 0 { println(s[0]) } } f("") // inline The call is replaced by: if len("") > 0 { println(""[0]) // error: constant index out of range } In general, operations on constants (in particular -x, x+y, x[i], x[i:j], and f(x)) are subject to additional static checks that don't make sense for non-constant operands. This analysis scans the callee function body for all expressions that are not constant but would become constant if the parameter vars were redeclared as constants, and emits a constraint (a Go expression) for each one that has the property that it will not type-check (using types.CheckExpr) if the particular argument values are unsuitable. The substitution logic checks the constraints and falls back to a binding decl if they are not all satisfied. (More optimal solutions could be found, but this situation is very uncommon.) (It would be easy to detect these problems if we simply type-checked the transformed source, but, by design, we simply don't have the necessary type information for indirect dependencies when running in an environment like unitchecker.) Fixes golang/go#62664 Change-Id: I27d40adb681c469e9c711bf1ee6f7319b5725a2a Reviewed-on: https://go-review.googlesource.com/c/tools/+/531695 Reviewed-by: Robert Findley <[email protected]> Auto-Submit: Alan Donovan <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
- Loading branch information