|
19 | 19 | ErrMissingExportedParamName = errors.New("exported method is not allowed to have unnamed parameter")
|
20 | 20 | // ErrInvalidExportedRetCount is returned when exported contract method has invalid return values count.
|
21 | 21 | ErrInvalidExportedRetCount = errors.New("exported method is not allowed to have more than one return value")
|
| 22 | + // ErrGenericsUnsuppored is returned when generics-related tokens are encountered. |
| 23 | + ErrGenericsUnsuppored = errors.New("generics are currently unsupported, please, see the https://github.com/nspcc-dev/neo-go/issues/2376") |
22 | 24 | )
|
23 | 25 |
|
24 | 26 | var (
|
@@ -361,6 +363,13 @@ func (c *codegen) analyzeFuncAndGlobalVarUsage() funcUsage {
|
361 | 363 | case *ast.FuncDecl:
|
362 | 364 | name := c.getFuncNameFromDecl(pkgPath, n)
|
363 | 365 |
|
| 366 | + // filter out generic functions |
| 367 | + err := c.checkGenericsFuncDecl(n, name) |
| 368 | + if err != nil { |
| 369 | + c.prog.Err = err |
| 370 | + return false // Program is invalid. |
| 371 | + } |
| 372 | + |
364 | 373 | // exported functions and methods are always assumed to be used
|
365 | 374 | if isMain && n.Name.IsExported() || isInitFunc(n) || isDeployFunc(n) {
|
366 | 375 | diff[name] = true
|
@@ -535,6 +544,32 @@ func (c *codegen) analyzeFuncAndGlobalVarUsage() funcUsage {
|
535 | 544 | return usage
|
536 | 545 | }
|
537 | 546 |
|
| 547 | +// checkGenericFuncDecl checks whether provided ast.FuncDecl has generic code. |
| 548 | +func (c *codegen) checkGenericsFuncDecl(n *ast.FuncDecl, funcName string) error { |
| 549 | + var errGenerics error |
| 550 | + |
| 551 | + // Generic function receiver. |
| 552 | + if n.Recv != nil { |
| 553 | + switch t := n.Recv.List[0].Type.(type) { |
| 554 | + case *ast.StarExpr: |
| 555 | + switch t.X.(type) { |
| 556 | + case *ast.IndexExpr: |
| 557 | + // func (x *Pointer[T]) Load() *T |
| 558 | + errGenerics = errors.New("generic pointer function receiver") |
| 559 | + } |
| 560 | + case *ast.IndexExpr: |
| 561 | + // func (x Structure[T]) Load() *T |
| 562 | + errGenerics = errors.New("generic function receiver") |
| 563 | + } |
| 564 | + } |
| 565 | + |
| 566 | + if errGenerics != nil { |
| 567 | + return fmt.Errorf("%w: %s has %s", ErrGenericsUnsuppored, funcName, errGenerics.Error()) |
| 568 | + } |
| 569 | + |
| 570 | + return nil |
| 571 | +} |
| 572 | + |
538 | 573 | // nodeContext contains ast node with the corresponding import map, type info and package information
|
539 | 574 | // required to retrieve fully qualified node name (if so).
|
540 | 575 | type nodeContext struct {
|
|
0 commit comments