cmd/compile: create/use noder2 transform functions for more node types

Pull out the transformation part of the typechecking functions for:
 - assignment statements
 - return statements
 - send statements
 - select statements
 - type conversions
 - normal function/method calls
 - index operations

The transform functions are like the original typechecking functions,
but with all code removed related to:
  - Detecting compile-time errors (already done by types2)
  - Setting the actual type of existing nodes (already done based on
    info from types2)
  - Dealing with untyped constants

Moved all the transformation functions to a separate file, transform.go.

Continuing with the same pattern, we delay transforming a node if it has
any type params in its args, marking it with a typecheck flag of 3, and
do the actual transformation during stenciling.

Assignment statements are tricky, since their transformation must be
delayed if any of the left or right-hands-sides are delayed.

Still to do are:
 - selector expressions (OXDOT)
 - composite literal expressions (OCOMPLIT)
 - builtin function calls

Change-Id: Ie608cadbbc69b40db0067a5536cf707dd974aacc
Reviewed-on: https://go-review.googlesource.com/c/go/+/304049
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Dan Scales 2021-03-23 10:19:11 -07:00
parent 29ed12d4c7
commit e7e0995cba
7 changed files with 650 additions and 157 deletions

View file

@ -23,10 +23,14 @@ func (g *irgen) match(t1 *types.Type, t2 types2.Type, hasOK bool) bool {
}
if hasOK {
// For has-ok values, types2 represents the expression's type as
// a 2-element tuple, whereas ir just uses the first type and
// infers that the second type is boolean.
return tuple.Len() == 2 && types.Identical(t1, g.typ(tuple.At(0).Type()))
// For has-ok values, types2 represents the expression's type as a
// 2-element tuple, whereas ir just uses the first type and infers
// that the second type is boolean. Must match either, since we
// sometimes delay the transformation to the ir form.
if tuple.Len() == 2 && types.Identical(t1, g.typ(tuple.At(0).Type())) {
return true
}
return types.Identical(t1, g.typ(t2))
}
if t1 == nil || tuple == nil {