(typ super.Type, drop path)
| 595 | } |
| 596 | |
| 597 | func (c *checker) dropPath(typ super.Type, drop path) super.Type { |
| 598 | if len(drop.elems) == 0 { |
| 599 | return nil |
| 600 | } |
| 601 | // Drop is a little tricky since it passes through non-record values so |
| 602 | // we need to preserve any union type presented to its input. pickRec returns |
| 603 | // a copy of the types slice so we can modify it. |
| 604 | types, pick := pickRec(typ) |
| 605 | if types == nil { |
| 606 | // drop passes through non-records |
| 607 | return typ |
| 608 | } |
| 609 | rec := super.TypeUnder(types[pick]).(*super.TypeRecord) |
| 610 | off, ok := rec.IndexOfField(drop.elems[0]) |
| 611 | if !ok { |
| 612 | if !hasUnknown(typ) { |
| 613 | c.error(drop.loc, errors.New("expression not present in drop input")) |
| 614 | } |
| 615 | return c.unknown |
| 616 | } |
| 617 | fields := slices.Clone(rec.Fields) |
| 618 | childType := c.dropPath(fields[off].Type, path{drop.loc, drop.elems[1:]}) |
| 619 | if childType == nil { |
| 620 | fields = slices.Delete(fields, off, off+1) |
| 621 | } else { |
| 622 | fields[off].Type = childType |
| 623 | } |
| 624 | types[pick] = c.t.sctx.MustLookupTypeRecord(fields) |
| 625 | if len(types) > 1 { |
| 626 | return c.t.sctx.LookupTypeUnion(types) |
| 627 | } |
| 628 | return types[0] |
| 629 | } |
| 630 | |
| 631 | func pickRec(typ super.Type) ([]super.Type, int) { |
| 632 | switch typ := super.TypeUnder(typ).(type) { |
no test coverage detected