def resolve_call(self, fnty, pos_args, kw_args):
        """
        Resolve a call to a given function type.  A signature is returned.
        """
        if isinstance(fnty, types.FunctionType):
            return fnty.get_call_type(self, pos_args, kw_args)
        if isinstance(fnty, types.RecursiveCall) and not self._skip_recursion:
            # Recursive call
            disp = fnty.dispatcher_type.dispatcher
            pysig, args = disp.fold_argument_types(pos_args, kw_args)

            frame = self.context.callstack.match(disp.py_func, args)

            # If the signature is not being compiled
            if frame is None:
                sig = self.context.resolve_function_type(fnty.dispatcher_type,
                                                         pos_args, kw_args)
                fndesc = disp.overloads[args].fndesc
                qual = qualifying_prefix(fndesc.modname, fndesc.qualname)
                fnty.add_overloads(args, qual, fndesc.uid)
                return sig

            fnid = frame.func_id
            qual = qualifying_prefix(fnid.modname, fnid.func_qualname)
            fnty.add_overloads(args, qual, fnid.unique_id)
            # Resume propagation in parent frame
            return_type = frame.typeinfer.return_types_from_partial()
            # No known return type
            if return_type is None:
                raise TypingError("cannot type infer runaway recursion")

            sig = typing.signature(return_type, *args)
            sig = sig.replace(pysig=pysig)
            # Keep track of unique return_type
            frame.add_return_type(return_type)
            return sig
        else:
            # Normal non-recursive call
            return self.context.resolve_function_type(fnty, pos_args, kw_args)

        Resolve a call to a given function type.  A signature is returned.
        
numba/core/typeinfer.py