@Override
  public Node typeCheck(ContextVisitor tc) throws SemanticException {
    RuleDef sym = null;

    MethodInstance mi = call.methodInstance();
    IbexClassType ct = (IbexClassType) mi.container();
    for (RuleInstance rule : ct.rules()) {
      if (rule.name() == mi.name()) sym = rule.def();
    }

    if (sym == null) throw new SemanticException("Cannot find rule for " + mi);

    RhsInvoke n = (RhsInvoke) symbol(sym.asNonterminal()).type(call.type());

    if (assocTag) {
      Context c = tc.context();
      CodeDef code = c.currentCode();
      if (code instanceof RuleDef) {
        RuleDef rd = (RuleDef) code;
        if (rd != sym)
          throw new SemanticException(
              "Associativity annotation must be self-recursive.", position());
      }
    }

    if (!call.type().isVoid()) {
      TypeSystem ts = tc.typeSystem();
      LocalDef li = ts.localDef(position(), Flags.FINAL, Types.ref(call.type()), call.name().id());
      // Formal parameters are never compile-time constants.
      li.setNotConstant();

      IbexNodeFactory nf = (IbexNodeFactory) tc.nodeFactory();
      LocalDecl ld =
          nf.LocalDecl(
              position(),
              nf.FlagsNode(position(), li.flags()),
              nf.CanonicalTypeNode(position(), li.type()),
              nf.Id(position(), li.name()));
      ld = ld.localDef(li);
      ld = ld.init(n);

      return nf.RhsSyntheticBind(position(), ld).type(n.type());
    }

    return n;
  }