// File: /workspace/github_c_makefile_star2_O0/oridb[P]mc/parse/infer.c
// Function: specializeimpl
static void
specializeimpl(Node *n)
{
	Node *dcl, *proto, *name, *sym;
	Tysubst *subst;
	Type *ty;
	Trait *tr;
	size_t i, j;
	int generic;
	char *traitns;

	tr = gettrait(curstab(), n->impl.traitname);
	if (!tr)
		fatal(n, "no trait %s\n", namestr(n->impl.traitname));
	n->impl.trait = tr;
	traitns = tr->name->name.ns;

	dcl = NULL;
	if (n->impl.naux != tr->naux)
		fatal(n, "%s incompatibly specialized with %zd types instead of %zd types",
			namestr(n->impl.traitname), n->impl.naux, tr->naux);
	n->impl.type = tf(n->impl.type);
	pushenv(n->impl.env);
	for (i = 0; i < n->impl.naux; i++)
		n->impl.aux[i] = tf(n->impl.aux[i]);
	for (i = 0; i < n->impl.ndecls; i++) {
		/* look up the prototype */
		proto = NULL;
		dcl = n->impl.decls[i];

		/*
		   since the decls in an impl are not installed in a namespace,
		   their names are not updated when we call updatens() on the
		   symbol table. Because we need to do namespace dependent
		   comparisons for specializing, we need to set the namespace
		   here.
		*/
		if (file.globls->name)
			setns(dcl->decl.name, traitns);
		for (j = 0; j < tr->nproto; j++) {
			if (nsnameeq(dcl->decl.name, tr->proto[j]->decl.name)) {
				proto = tr->proto[j];
				break;
			}
		}
		if (!proto)
			fatal(n, "declaration %s missing in %s, near %s", namestr(dcl->decl.name),
					namestr(tr->name), ctxstr(n));

		/* infer and unify types */
		pushenv(proto->decl.env);
		verifytraits(n, tr->param, n->impl.type);
		subst = mksubst();
		substput(subst, tr->param, n->impl.type);
		for (j = 0; j < tr->naux; j++)
			substput(subst, tr->aux[j], n->impl.aux[j]);
		ty = tyspecialize(type(proto), subst, delayed);
		substfree(subst);
		popenv(proto->decl.env);

		generic = hasparams(ty);
		if (generic)
			ingeneric++;

		inferdecl(dcl);
		unify(n, type(dcl), ty);

		/* and put the specialization into the global stab */
		name = genericname(proto, n->impl.type, ty);
		sym = getdcl(file.globls, name);
		if (sym)
			fatal(n, "trait %s already specialized with %s on %s:%d",
				namestr(tr->name), tystr(n->impl.type),
				fname(sym->loc), lnum(sym->loc));
		dcl->decl.name = name;
		putdcl(file.globls, dcl);
		htput(proto->decl.impls, n->impl.type, dcl);
		dcl->decl.isconst = 1;
		if (ty->type == Tygeneric || hasparams(ty)) {
			dcl->decl.isgeneric = 1;
			lappend(&proto->decl.gimpl, &proto->decl.ngimpl, dcl);
			lappend(&proto->decl.gtype, &proto->decl.ngtype, ty);
		}
		dcl->decl.vis = tr->vis;
		lappend(&impldecl, &nimpldecl, dcl);

		if (generic)
			ingeneric--;
	}
	popenv(n->impl.env);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
callq 0x32d60
movq %rax, %rdi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rsi
callq 0x33870
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x2c8a9
movq -0x8(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x30600
movq -0x68(%rbp), %rdi
movq %rax, %rdx
leaq 0x25e2a(%rip), %rsi     # 0x526cc
movb $0x0, %al
callq 0x1dfe0
movq -0x40(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x18(%rax), %rax
movq %rax, -0x60(%rbp)
movq $0x0, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x40(%rbp), %rcx
cmpq 0x28(%rcx), %rax
je 0x2c919
movq -0x8(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x30600
movq -0x70(%rbp), %rdi
movq %rax, %rdx
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rcx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %r8
leaq 0x25dc7(%rip), %rsi     # 0x526d9
movb $0x0, %al
callq 0x1dfe0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x277c0
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0x32f70
movq $0x0, -0x48(%rbp)
movq -0x48(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x40(%rcx), %rax
jae 0x2c98a
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x48(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x277c0
movq %rax, %rdx
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x48(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x2c946
movq $0x0, -0x48(%rbp)
movq -0x48(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x50(%rcx), %rax
jae 0x2cd6f
movq $0x0, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x48(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x10(%rbp)
leaq 0x503d1(%rip), %rax     # 0x7cd98
movq 0x90(%rax), %rax
cmpq $0x0, 0x8(%rax)
je 0x2c9e6
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x60(%rbp), %rsi
callq 0x2fb60
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq -0x40(%rbp), %rcx
cmpq 0x38(%rcx), %rax
jae 0x2ca48
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x40(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x50(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x20(%rax), %rsi
callq 0x32b30
cmpl $0x0, %eax
je 0x2ca38
movq -0x40(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x50(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x18(%rbp)
jmp 0x2ca48
jmp 0x2ca3a
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x2c9ee
cmpq $0x0, -0x18(%rbp)
jne 0x2caa5
movq -0x8(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x30600
movq %rax, -0x80(%rbp)
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x30600
movq %rax, -0x78(%rbp)
movq -0x8(%rbp), %rdi
callq 0x27be0
movq -0x88(%rbp), %rdi
movq -0x80(%rbp), %rdx
movq -0x78(%rbp), %rcx
movq %rax, %r8
leaq 0x25c7b(%rip), %rsi     # 0x52719
movb $0x0, %al
callq 0x1dfe0
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0x32f70
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rdx
callq 0x29be0
callq 0x30990
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
movq -0x40(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rdx
callq 0x308e0
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq -0x40(%rbp), %rcx
cmpq 0x28(%rcx), %rax
jae 0x2cb3a
movq -0x30(%rbp), %rdi
movq -0x40(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x50(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x50(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
callq 0x308e0
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x2caf5
movq -0x18(%rbp), %rdi
callq 0x2a8f0
movq %rax, %rdi
movq -0x30(%rbp), %rsi
movq 0x5076f(%rip), %rdx     # 0x7d2c0
callq 0x30a70
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rdi
callq 0x30a10
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0x32fe0
movq -0x38(%rbp), %rdi
callq 0x37ce0
movl %eax, -0x54(%rbp)
cmpl $0x0, -0x54(%rbp)
je 0x2cb91
movl 0x50888(%rip), %eax     # 0x7d410
addl $0x1, %eax
movl %eax, 0x5087f(%rip)     # 0x7d410
movq -0x10(%rbp), %rdi
callq 0x2b200
movq -0x8(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rdi
callq 0x2a8f0
movq -0x90(%rbp), %rdi
movq %rax, %rsi
movq -0x38(%rbp), %rdx
callq 0x28c00
movq -0x18(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rsi
movq -0x38(%rbp), %rdx
callq 0x319c0
movq %rax, -0x20(%rbp)
leaq 0x501b7(%rip), %rax     # 0x7cd98
movq 0x90(%rax), %rdi
movq -0x20(%rbp), %rsi
callq 0x334b0
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0x2cc7b
movq -0x8(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x30600
movq %rax, -0xa8(%rbp)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x38a10
movq %rax, -0xa0(%rbp)
movq -0x28(%rbp), %rax
movq (%rax), %rdi
callq 0x2f090
movq %rax, -0x98(%rbp)
movq -0x28(%rbp), %rax
movq (%rax), %rdi
callq 0x2f0b0
movq -0xb0(%rbp), %rdi
movq -0xa8(%rbp), %rdx
movq -0xa0(%rbp), %rcx
movq -0x98(%rbp), %r8
movl %eax, %r9d
leaq 0x25acb(%rip), %rsi     # 0x5273f
movb $0x0, %al
callq 0x1dfe0
movq -0x20(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
leaq 0x5010a(%rip), %rax     # 0x7cd98
movq 0x90(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x33970
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rdi
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rsi
movq -0x10(%rbp), %rdx
callq 0x49100
movq -0x10(%rbp), %rax
movb $0x1, 0x72(%rax)
movq -0x38(%rbp), %rax
cmpl $0x1d, (%rax)
je 0x2ccd6
movq -0x38(%rbp), %rdi
callq 0x37ce0
cmpl $0x0, %eax
je 0x2cd20
movq -0x10(%rbp), %rax
movb $0x1, 0x73(%rax)
movq -0x18(%rbp), %rdi
addq $0x18, %rdi
addq $0x38, %rdi
movq -0x18(%rbp), %rsi
addq $0x18, %rsi
addq $0x40, %rsi
movq -0x10(%rbp), %rdx
callq 0x48290
movq -0x18(%rbp), %rdi
addq $0x18, %rdi
addq $0x48, %rdi
movq -0x18(%rbp), %rsi
addq $0x18, %rsi
addq $0x50, %rsi
movq -0x38(%rbp), %rdx
callq 0x48290
movq -0x40(%rbp), %rax
movl 0xc(%rax), %eax
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, 0x70(%rax)
movq -0x10(%rbp), %rdx
leaq 0x5071d(%rip), %rdi     # 0x7d458
leaq 0x5071e(%rip), %rsi     # 0x7d460
callq 0x48290
cmpl $0x0, -0x54(%rbp)
je 0x2cd5c
movl 0x506bd(%rip), %eax     # 0x7d410
addl $-0x1, %eax
movl %eax, 0x506b4(%rip)     # 0x7d410
jmp 0x2cd5e
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x2c992
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0x32fe0
addq $0xb0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)