lcompilers / lpython

Python compiler
https://lpython.org/
Other
1.37k stars 156 forks source link

Detect unhashable object types at the ASR level #2664

Closed kmr-srbh closed 2 months ago

kmr-srbh commented 2 months ago

Fixes #2663

Working for dict is shown below. It is the same for set.

List

from lpython import i32

my_dict: dict[list[i32], str] = {[1, 2]: "first", [3, 4]: "second"}
(base) saurabh-kumar@Awadh:~/Projects/System/lpython$ ./src/bin/lpython ./examples/example.py
semantic error: Unhashable type: 'list'
 --> ./examples/example.py:3:15
  |
3 | my_dict: dict[list[i32], str] = {[1, 2]: "first", [3, 4]: "second"}
  |               ^^^^^^^^^ Mutable type 'list' cannot become a key in dict. Hint: Use an immutable type for key.

Note: Please report unclear or confusing messages as bugs at
https://github.com/lcompilers/lpython/issues.

Dictionary

from lpython import i32

my_dict: dict[dict[i32, str], str] = {{1: "a", 2: "b"}: "first", {3: "c", 4: "d"}: "second"}
(base) saurabh-kumar@Awadh:~/Projects/System/lpython$ ./src/bin/lpython ./examples/example.py
semantic error: Unhashable type: 'dict'
 --> ./examples/example.py:3:15
  |
3 | my_dict: dict[dict[i32, str], str] = {{1: "a", 2: "b"}: "first", {3: "c", 4: "d"}: "second"}
  |               ^^^^^^^^^^^^^^ Mutable type 'dict' cannot become a key in dict. Hint: Use an immutable type for key.

Note: Please report unclear or confusing messages as bugs at
https://github.com/lcompilers/lpython/issues.

Set

from lpython import i32

my_dict: dict[set[str], str] = {{1, 2}: "first", {3, 4}: "second"}
(base) saurabh-kumar@Awadh:~/Projects/System/lpython$ ./src/bin/lpython ./examples/example.py
semantic error: Unhashable type: 'set'
 --> ./examples/example.py:3:15
  |
3 | my_dict: dict[set[str], str] = {{1, 2}: "first", {3, 4}: "second"}
  |               ^^^^^^^^ Mutable type 'set' cannot become a key in dict. Hint: Use an immutable type for key.

Note: Please report unclear or confusing messages as bugs at
https://github.com/lcompilers/lpython/issues.
kmr-srbh commented 2 months ago

We should also check for mutable/unhashable types in the type declaration for a dict.

Let's handle this in this PR only.