prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  [Bug]: High level call does not always have function
  ### Describe the issue:
  
  I have two somehow similar examples, in the first one I have the function on the high level call in function safeAdd. In the next example I edited the array size to be constant instead of a literal, and I got None instead of a function object
  
  ### Code example to reproduce the issue:
  
  ```solidity
  library SafeMath {
      uint256 private constant twelve = 12; 
      struct A {uint256 a;}
      function add(A[twelve] storage z) internal { }
  }
  
  contract MathContract {
      uint256 private constant twelve = 12; 
      using SafeMath for SafeMath.A[12];
      SafeMath.A[12] public z;
      function safeAdd() public {
          z.add();
      }
  }
  ```
  ```solidity
  library SafeMath {
      uint256 private constant twelve = 12; 
      struct A {uint256 a;}
      function add(A[twelve] storage z) internal { }
  }
  
  contract MathContract {
      uint256 private constant twelve = 12; 
      using SafeMath for SafeMath.A[twelve];
      SafeMath.A[twelve] public z;
      function safeAdd() public {
          z.add();
      }
  }
  ```
  
  ### Version:
  
  0.10.0
  
  ### Relevant log output:
  
  ```shell
  >>> from slither import Slither
  >>> math = Slither('a.sol').contracts[1]
  >>> math.name
  'MathContract'
  >>> f = math.functions[0]
  >>> f.name
  'safeAdd'
  >>> f.nodes
  [<slither.core.cfg.node.Node object at 0x7f5460aa1e50>, <slither.core.cfg.node.No
  de object at 0x7f5460aa2090>]
  >>> f.nodes[1]
  <slither.core.cfg.node.Node object at 0x7f5460aa2090>
  >>> f.nodes[1].irs
  [<slither.slithir.operations.library_call.LibraryCall object at 0x7f5460a748d0>]
  >>> f.nodes[1].irs[0].function
  <slither.core.declarations.function_contract.FunctionContract object at 0x7f5460a
  9e090>
  >>> f.nodes[1].irs[0].function.name
  'add'
  ----------------------------------------------------------------------------------
  >>> from slither import Slither
  >>> math = Slither('a.sol').contracts[1]
  >>> math.name
  'MathContract'
  >>> f = math.functions[0]
  >>> f.name
  'safeAdd'
  >>> f.nodes
  [<slither.core.cfg.node.Node object at 0x7f9d6379db10>, <slither.core.cfg.node.No
  de object at 0x7f9d63a47850>]
  >>> f.nodes[1]
  <slither.core.cfg.node.Node object at 0x7f9d63a47850>
  >>> f.nodes[1].irs
  [<slither.slithir.operations.high_level_call.HighLevelCall object at 0x7f9d63a376
  90>]
  >>> f.nodes[1].irs[0].function
  >>> print(f.nodes[1].irs[0].function)
  None
  ```
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `slither/core/solidity_types/array_type.py`
  Content:
  ```
  1 from typing import Union, Optional, Tuple, Any, TYPE_CHECKING
  2 
  3 from slither.core.expressions.expression import Expression
  4 from slither.core.expressions.literal import Literal
  5 from slither.core.solidity_types.elementary_type import ElementaryType
  6 from slither.core.solidity_types.type import Type
  7 from slither.visitors.expression.constants_folding import ConstantFolding
  8 
  9 if TYPE_CHECKING:
  10     from slither.core.expressions.binary_operation import BinaryOperation
  11     from slither.core.expressions.identifier import Identifier
  12 
  13 
  14 class ArrayType(Type):
  15     def __init__(
  16         self,
  17         t: Type,
  18         length: Optional[Union["Identifier", Literal, "BinaryOperation", int]],
  19     ) -> None:
  20         assert isinstance(t, Type)
  21         if length:
  22             if isinstance(length, int):
  23                 length = Literal(length, ElementaryType("uint256"))
  24 
  25         super().__init__()
  26         self._type: Type = t
  27         assert length is None or isinstance(length, Expression)
  28         self._length: Optional[Expression] = length
  29 
  30         if length:
  31             if not isinstance(length, Literal):
  32                 cf = ConstantFolding(length, "uint256")
  33                 length = cf.result()
  34             self._length_value: Optional[Literal] = length
  35         else:
  36             self._length_value = None
  37 
  38     @property
  39     def type(self) -> Type:
  40         return self._type
  41 
  42     @property
  43     def is_dynamic(self) -> bool:
  44         return self.length is None
  45 
  46     @property
  47     def length(self) -> Optional[Expression]:
  48         return self._length
  49 
  50     @property
  51     def length_value(self) -> Optional[Literal]:
  52         return self._length_value
  53 
  54     @property
  55     def is_fixed_array(self) -> bool:
  56         return bool(self.length)
  57 
  58     @property
  59     def is_dynamic_array(self) -> bool:
  60         return not self.is_fixed_array
  61 
  62     @property
  63     def storage_size(self) -> Tuple[int, bool]:
  64         if self._length_value:
  65             elem_size, _ = self._type.storage_size
  66             return elem_size * int(str(self._length_value)), True
  67         return 32, True
  68 
  69     def __str__(self) -> str:
  70         if self._length:
  71             return str(self._type) + f"[{str(self._length_value)}]"
  72         return str(self._type) + "[]"
  73 
  74     def __eq__(self, other: Any) -> bool:
  75         if not isinstance(other, ArrayType):
  76             return False
  77         return self._type == other.type and self.length == other.length
  78 
  79     def __hash__(self) -> int:
  80         return hash(str(self))
  81
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/slither/core/solidity_types/array_type.py b/slither/core/solidity_types/array_type.py
  --- a/slither/core/solidity_types/array_type.py
  +++ b/slither/core/solidity_types/array_type.py
  @@ -74,7 +74,7 @@
       def __eq__(self, other: Any) -> bool:
           if not isinstance(other, ArrayType):
               return False
  -        return self._type == other.type and self.length == other.length
  +        return self._type == other.type and self._length_value == other.length_value
   
       def __hash__(self) -> int:
           return hash(str(self))
  
verification_info: {"golden_diff": "diff --git a/slither/core/solidity_types/array_type.py b/slither/core/solidity_types/array_type.py\n--- a/slither/core/solidity_types/array_type.py\n+++ b/slither/core/solidity_types/array_type.py\n@@ -74,7 +74,7 @@\n     def __eq__(self, other: Any) -> bool:\n         if not isinstance(other, ArrayType):\n             return False\n-        return self._type == other.type and self.length == other.length\n+        return self._type == other.type and self._length_value == other.length_value\n \n     def __hash__(self) -> int:\n         return hash(str(self))\n", "issue": "[Bug]: High level call does not always have function\n### Describe the issue:\r\n\r\nI have two somehow similar examples, in the first one I have the function on the high level call in function safeAdd. In the next example I edited the array size to be constant instead of a literal, and I got None instead of a function object\r\n\r\n### Code example to reproduce the issue:\r\n\r\n```solidity\r\nlibrary SafeMath {\r\n    uint256 private constant twelve = 12; \r\n    struct A {uint256 a;}\r\n    function add(A[twelve] storage z) internal { }\r\n}\r\n\r\ncontract MathContract {\r\n    uint256 private constant twelve = 12; \r\n    using SafeMath for SafeMath.A[12];\r\n    SafeMath.A[12] public z;\r\n    function safeAdd() public {\r\n        z.add();\r\n    }\r\n}\r\n```\r\n```solidity\r\nlibrary SafeMath {\r\n    uint256 private constant twelve = 12; \r\n    struct A {uint256 a;}\r\n    function add(A[twelve] storage z) internal { }\r\n}\r\n\r\ncontract MathContract {\r\n    uint256 private constant twelve = 12; \r\n    using SafeMath for SafeMath.A[twelve];\r\n    SafeMath.A[twelve] public z;\r\n    function safeAdd() public {\r\n        z.add();\r\n    }\r\n}\r\n```\r\n\r\n### Version:\r\n\r\n0.10.0\r\n\r\n### Relevant log output:\r\n\r\n```shell\r\n>>> from slither import Slither\r\n>>> math = Slither('a.sol').contracts[1]\r\n>>> math.name\r\n'MathContract'\r\n>>> f = math.functions[0]\r\n>>> f.name\r\n'safeAdd'\r\n>>> f.nodes\r\n[<slither.core.cfg.node.Node object at 0x7f5460aa1e50>, <slither.core.cfg.node.No\r\nde object at 0x7f5460aa2090>]\r\n>>> f.nodes[1]\r\n<slither.core.cfg.node.Node object at 0x7f5460aa2090>\r\n>>> f.nodes[1].irs\r\n[<slither.slithir.operations.library_call.LibraryCall object at 0x7f5460a748d0>]\r\n>>> f.nodes[1].irs[0].function\r\n<slither.core.declarations.function_contract.FunctionContract object at 0x7f5460a\r\n9e090>\r\n>>> f.nodes[1].irs[0].function.name\r\n'add'\r\n----------------------------------------------------------------------------------\r\n>>> from slither import Slither\r\n>>> math = Slither('a.sol').contracts[1]\r\n>>> math.name\r\n'MathContract'\r\n>>> f = math.functions[0]\r\n>>> f.name\r\n'safeAdd'\r\n>>> f.nodes\r\n[<slither.core.cfg.node.Node object at 0x7f9d6379db10>, <slither.core.cfg.node.No\r\nde object at 0x7f9d63a47850>]\r\n>>> f.nodes[1]\r\n<slither.core.cfg.node.Node object at 0x7f9d63a47850>\r\n>>> f.nodes[1].irs\r\n[<slither.slithir.operations.high_level_call.HighLevelCall object at 0x7f9d63a376\r\n90>]\r\n>>> f.nodes[1].irs[0].function\r\n>>> print(f.nodes[1].irs[0].function)\r\nNone\r\n```\r\n\n", "before_files": [{"content": "from typing import Union, Optional, Tuple, Any, TYPE_CHECKING\n\nfrom slither.core.expressions.expression import Expression\nfrom slither.core.expressions.literal import Literal\nfrom slither.core.solidity_types.elementary_type import ElementaryType\nfrom slither.core.solidity_types.type import Type\nfrom slither.visitors.expression.constants_folding import ConstantFolding\n\nif TYPE_CHECKING:\n    from slither.core.expressions.binary_operation import BinaryOperation\n    from slither.core.expressions.identifier import Identifier\n\n\nclass ArrayType(Type):\n    def __init__(\n        self,\n        t: Type,\n        length: Optional[Union[\"Identifier\", Literal, \"BinaryOperation\", int]],\n    ) -> None:\n        assert isinstance(t, Type)\n        if length:\n            if isinstance(length, int):\n                length = Literal(length, ElementaryType(\"uint256\"))\n\n        super().__init__()\n        self._type: Type = t\n        assert length is None or isinstance(length, Expression)\n        self._length: Optional[Expression] = length\n\n        if length:\n            if not isinstance(length, Literal):\n                cf = ConstantFolding(length, \"uint256\")\n                length = cf.result()\n            self._length_value: Optional[Literal] = length\n        else:\n            self._length_value = None\n\n    @property\n    def type(self) -> Type:\n        return self._type\n\n    @property\n    def is_dynamic(self) -> bool:\n        return self.length is None\n\n    @property\n    def length(self) -> Optional[Expression]:\n        return self._length\n\n    @property\n    def length_value(self) -> Optional[Literal]:\n        return self._length_value\n\n    @property\n    def is_fixed_array(self) -> bool:\n        return bool(self.length)\n\n    @property\n    def is_dynamic_array(self) -> bool:\n        return not self.is_fixed_array\n\n    @property\n    def storage_size(self) -> Tuple[int, bool]:\n        if self._length_value:\n            elem_size, _ = self._type.storage_size\n            return elem_size * int(str(self._length_value)), True\n        return 32, True\n\n    def __str__(self) -> str:\n        if self._length:\n            return str(self._type) + f\"[{str(self._length_value)}]\"\n        return str(self._type) + \"[]\"\n\n    def __eq__(self, other: Any) -> bool:\n        if not isinstance(other, ArrayType):\n            return False\n        return self._type == other.type and self.length == other.length\n\n    def __hash__(self) -> int:\n        return hash(str(self))\n", "path": "slither/core/solidity_types/array_type.py"}], "after_files": [{"content": "from typing import Union, Optional, Tuple, Any, TYPE_CHECKING\n\nfrom slither.core.expressions.expression import Expression\nfrom slither.core.expressions.literal import Literal\nfrom slither.core.solidity_types.elementary_type import ElementaryType\nfrom slither.core.solidity_types.type import Type\nfrom slither.visitors.expression.constants_folding import ConstantFolding\n\nif TYPE_CHECKING:\n    from slither.core.expressions.binary_operation import BinaryOperation\n    from slither.core.expressions.identifier import Identifier\n\n\nclass ArrayType(Type):\n    def __init__(\n        self,\n        t: Type,\n        length: Optional[Union[\"Identifier\", Literal, \"BinaryOperation\", int]],\n    ) -> None:\n        assert isinstance(t, Type)\n        if length:\n            if isinstance(length, int):\n                length = Literal(length, ElementaryType(\"uint256\"))\n\n        super().__init__()\n        self._type: Type = t\n        assert length is None or isinstance(length, Expression)\n        self._length: Optional[Expression] = length\n\n        if length:\n            if not isinstance(length, Literal):\n                cf = ConstantFolding(length, \"uint256\")\n                length = cf.result()\n            self._length_value: Optional[Literal] = length\n        else:\n            self._length_value = None\n\n    @property\n    def type(self) -> Type:\n        return self._type\n\n    @property\n    def is_dynamic(self) -> bool:\n        return self.length is None\n\n    @property\n    def length(self) -> Optional[Expression]:\n        return self._length\n\n    @property\n    def length_value(self) -> Optional[Literal]:\n        return self._length_value\n\n    @property\n    def is_fixed_array(self) -> bool:\n        return bool(self.length)\n\n    @property\n    def is_dynamic_array(self) -> bool:\n        return not self.is_fixed_array\n\n    @property\n    def storage_size(self) -> Tuple[int, bool]:\n        if self._length_value:\n            elem_size, _ = self._type.storage_size\n            return elem_size * int(str(self._length_value)), True\n        return 32, True\n\n    def __str__(self) -> str:\n        if self._length:\n            return str(self._type) + f\"[{str(self._length_value)}]\"\n        return str(self._type) + \"[]\"\n\n    def __eq__(self, other: Any) -> bool:\n        if not isinstance(other, ArrayType):\n            return False\n        return self._type == other.type and self._length_value == other.length_value\n\n    def __hash__(self) -> int:\n        return hash(str(self))\n", "path": "slither/core/solidity_types/array_type.py"}]}