(define impc:ti:expand-generic-type
(lambda (t)
(let* ((t2 (symbol->string t))
(p (regex:type-split t2 ":"))
(name (car p)))
(if (or (null? (cdr p))
(not (char=? #\$ (string-ref (cadr p) 0))))
t
(let* ((func? (char=? #\[ (string-ref (cadr p) 1)))
(xtype (substring (cadr p) 1 (string-length (cadr p))))
(ptrdepth (impc:ir:get-ptr-depth xtype))
(base (impc:ir:get-base-type xtype))
(xvars (if func?
(impc:ir:get-pretty-closure-arg-strings base)
(impc:ir:get-pretty-tuple-arg-strings base)))
(gtt (if func?
(impc:ti:expand-generic-type-func-gpoly-arity (string->symbol name) (length xvars))
(assoc-strcmp (string->symbol name) *impc:ti:generictype-cache*)))
(gtype (if gtt
(symbol->string (if func? (car gtt) (cdr gtt)))
(impc:compiler:print-cannot-expand-non-generic-error name)))
(_gvars (regex:match-all gtype "(![A-Za-z0-9_]*)"))
(gvars (cl:remove-duplicates _gvars)))
(if (<> (length gvars) (length xvars))
(impc:compiler:print-expansion-arity-error (cdr t) (string->symbol (string-append (car p) ":" gtype))))
(for-each (lambda (x y)
(set! gtype (regex:replace-all gtype x y)))
gvars xvars)
(if func?
(string->symbol (impc:ir:pointer++ (string-append (car p) "_poly_" (cname-encode gtype)) (- ptrdepth 1)))
(string->symbol (impc:ir:pointer++ (string-append (car p) ":" gtype) ptrdepth))))))))