code: func (st *state) findArgumentPack(a AST) *ArgumentPack {
  	var seen []AST
  	var ret *ArgumentPack
  	a.Traverse(func(a AST) bool {
  		if ret != nil {
  			return false
  		}
  		switch a := a.(type) {
  		case *TemplateParam:
  			if a.Template == nil || a.Index >= len(a.Template.Args) {
  				return true
  			}
  			if pack, ok := a.Template.Args[a.Index].(*ArgumentPack); ok {
  				ret = pack
  				return false
  			}
  		case *PackExpansion, *Closure, *Name:
  			return false
  		case *TaggedName, *Operator, *BuiltinType, *FunctionParam:
  			return false
  		case *UnnamedType, *FixedType, *DefaultArg:
  			return false
  		}
  		for _, v := range seen {
  			if v == a {
  				return false
  			}
  		}
  		seen = append(seen, a)
  		return true
  	})
  	return ret
  }
docs: // findArgumentPack walks the AST looking for the argument pack for a
  // pack expansion.  We find it via a template parameter.