Repository: numba/numba

Issue:
numba 0.54.1 casting IntEnum regression
numba 0.54.1
python 3.7.3
windows 10

This was first reported in [discourse](https://numba.discourse.group/t/casting-intenum-to-numba-int16/1005)

This code works in plain python and numba 0.53.1 but fails with numba 0.54.1

```python
from enum import IntEnum
import numba

class PmtType(IntEnum):
    LEVELA = 1
    LEVELB = 2

@numba.njit
def tester():
    return numba.int16(PmtType.LEVELA)

print(tester())
```
Error is

> File “int_enum.py”, line 16, in
> print(tester())
> File “C:\work\git\mims\venv\lib\site-packages\numba\core\dispatcher.py”, line 482, in _compile_for_args
> error_rewrite(e, ‘typing’)
> File “C:\work\git\mims\venv\lib\site-packages\numba\core\dispatcher.py”, line 423, in error_rewrite
> raise e.with_traceback(None)
> numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
> No implementation of function Function(int16) found for signature:
> 
> (IntEnum(PmtType))
> 
> There are 2 candidate implementations:
> 
> Of which 2 did not match due to:
> Overload in function ‘make_callable_template..generic’: File: numba\core\typing\templates.py: Line 174.
> With argument(s): ‘(IntEnum(PmtType))’:
> Rejected as the implementation raised a specific error:
> TypingError: Casting IntEnum(PmtType) to int16 directly is unsupported.
> raised from C:\work\git\mims\venv\lib\site-packages\numba\core\typing\builtins.py:818
> During: resolving callee type: class(int16)
> During: typing of call at C:/work/git/ims_core/playground/erik/discourse/int_enum.py (14)
> 
> File “int_enum.py”, line 14:
> def tester():
> return numba.int16(PmtType.LEVELA)
> ^
> Process finished with exit code 1
> 



Discussion:
I can reproduce this. This was introduced by f2311d20934a883dde3a2050ff947ff0f5d07977.
(cc @testhound)

Resolving patch:
diff --git a/numba/core/typing/builtins.py b/numba/core/typing/builtins.py
--- a/numba/core/typing/builtins.py
+++ b/numba/core/typing/builtins.py
@@ -807,7 +807,7 @@ def typer(val):
                 sig = fnty.get_call_type(self.context, (val, types.DType(ty)),
                                          {})
                 return sig.return_type
-            elif isinstance(val, (types.Number, types.Boolean)):
+            elif isinstance(val, (types.Number, types.Boolean, types.IntEnumMember)):
                  # Scalar constructor, e.g. np.int32(42)
                  return ty
             elif isinstance(val, (types.NPDatetime, types.NPTimedelta)):


Test patch:
diff --git a/numba/tests/test_enums.py b/numba/tests/test_enums.py
--- a/numba/tests/test_enums.py
+++ b/numba/tests/test_enums.py
@@ -5,7 +5,7 @@
 
 import numpy as np
 import unittest
-from numba import jit, vectorize
+from numba import jit, vectorize, int8, int16, int32
 
 from numba.tests.support import TestCase
 from .enum_usecases import Color, Shape, Shake, Planet, RequestError, \
@@ -50,6 +50,13 @@ def int_coerce_usecase(x):
     else:
         return x + Shape.circle
 
+def int_cast_usecase(x):
+    # Explicit coercion of intenums to ints
+    if x > int16(RequestError.internal_error):
+        return x - int32(RequestError.not_found)
+    else:
+        return x + int8(Shape.circle)
+
 
 def vectorize_usecase(x):
     if x != RequestError.not_found:
@@ -135,6 +142,13 @@ def test_int_coerce(self):
         for arg in [300, 450, 550]:
             self.assertPreciseEqual(pyfunc(arg), cfunc(arg))
 
+    def test_int_cast(self):
+        pyfunc = int_cast_usecase
+        cfunc = jit(nopython=True)(pyfunc)
+
+        for arg in [300, 450, 550]:
+            self.assertPreciseEqual(pyfunc(arg), cfunc(arg))
+
     def test_vectorize(self):
         cfunc = vectorize(nopython=True)(vectorize_usecase)
         arg = np.array([2, 404, 500, 404])