github.com/goplus/gogen@v1.16.0/inferfunc.go (about)

     1  //go:build !go1.21
     2  // +build !go1.21
     3  
     4  package gogen
     5  
     6  import (
     7  	"go/ast"
     8  	"go/types"
     9  
    10  	"github.com/goplus/gogen/internal"
    11  )
    12  
    13  func inferFunc(pkg *Package, fn *internal.Elem, sig *types.Signature, targs []types.Type, oargs []*Element, flags InstrFlags) ([]types.Type, types.Type, error) {
    14  	args, err := checkInferArgs(pkg, fn, sig, oargs, flags)
    15  	if err != nil {
    16  		return nil, nil, err
    17  	}
    18  	xlist := make([]*operand, len(args))
    19  	tp := sig.TypeParams()
    20  	n := tp.Len()
    21  	tparams := make([]*types.TypeParam, n)
    22  	for i := 0; i < n; i++ {
    23  		tparams[i] = tp.At(i)
    24  	}
    25  	for i, arg := range args {
    26  		xlist[i] = &operand{
    27  			mode: value,
    28  			expr: arg.Val,
    29  			typ:  arg.Type,
    30  			val:  arg.CVal,
    31  		}
    32  		tt := arg.Type
    33  	retry:
    34  		switch t := tt.(type) {
    35  		case *types.Slice:
    36  			tt = t.Elem()
    37  			goto retry
    38  		case *inferFuncType:
    39  			xlist[i].typ = types.Typ[types.UntypedNil]
    40  			xlist[i].expr = ast.NewIdent("nil")
    41  		case *types.Signature:
    42  			if tp := t.TypeParams(); tp != nil {
    43  				xlist[i].typ = types.Typ[types.UntypedNil]
    44  				xlist[i].expr = ast.NewIdent("nil")
    45  			}
    46  		}
    47  	}
    48  	targs, err = infer(pkg, fn.Val, tparams, targs, sig.Params(), xlist)
    49  	if err != nil {
    50  		return nil, nil, err
    51  	}
    52  	typ, err := types.Instantiate(pkg.cb.ctxt, sig, targs[:n], true)
    53  	return targs, typ, err
    54  }