code: func (st *state) setTemplate(a AST, tmpl *Template) {
  	var seen []AST
  	a.Traverse(func(a AST) bool {
  		switch a := a.(type) {
  		case *TemplateParam:
  			if a.Template != nil {
  				if tmpl != nil {
  					st.fail("duplicate template parameters")
  				}
  				return false
  			}
  			if tmpl == nil {
  				st.fail("cast template parameter not in scope of template")
  			}
  			if a.Index >= len(tmpl.Args) {
  				st.fail(fmt.Sprintf("cast template index out of range (%d >= %d)", a.Index, len(tmpl.Args)))
  			}
  			a.Template = tmpl
  			return false
  		default:
  			for _, v := range seen {
  				if v == a {
  					return false
  				}
  			}
  			seen = append(seen, a)
  			return true
  		}
  	})
  }
docs: // setTemplate sets the Template field of any TemplateParam's in a.
  // This handles the forward referencing template parameters found in
  // cast operators.