Check scans the Path for any recursive transformers and panics when any recursive transformers are detected. Note that the presence of a recursive Transformer does not necessarily imply an infinite cycle. As such, this check only activates after some minimal number of path steps.
(p Path)
| 603 | // recursive Transformer does not necessarily imply an infinite cycle. |
| 604 | // As such, this check only activates after some minimal number of path steps. |
| 605 | func (rc *recChecker) Check(p Path) { |
| 606 | const minLen = 1 << 16 |
| 607 | if rc.next == 0 { |
| 608 | rc.next = minLen |
| 609 | } |
| 610 | if len(p) < rc.next { |
| 611 | return |
| 612 | } |
| 613 | rc.next <<= 1 |
| 614 | |
| 615 | // Check whether the same transformer has appeared at least twice. |
| 616 | var ss []string |
| 617 | m := map[Option]int{} |
| 618 | for _, ps := range p { |
| 619 | if t, ok := ps.(Transform); ok { |
| 620 | t := t.Option() |
| 621 | if m[t] == 1 { // Transformer was used exactly once before |
| 622 | tf := t.(*transformer).fnc.Type() |
| 623 | ss = append(ss, fmt.Sprintf("%v: %v => %v", t, tf.In(0), tf.Out(0))) |
| 624 | } |
| 625 | m[t]++ |
| 626 | } |
| 627 | } |
| 628 | if len(ss) > 0 { |
| 629 | const warning = "recursive set of Transformers detected" |
| 630 | const help = "consider using cmpopts.AcyclicTransformer" |
| 631 | set := strings.Join(ss, "\n\t") |
| 632 | panic(fmt.Sprintf("%s:\n\t%s\n%s", warning, set, help)) |
| 633 | } |
| 634 | } |
| 635 | |
| 636 | // dynChecker tracks the state needed to periodically perform checks that |
| 637 | // user provided functions are symmetric and deterministic. |
no test coverage detected