Repository: crytic/slither

Issue:
[Bug]: Typename shadowing causes mix-up
### Describe the issue:

When we have a nested struct and a top-level struct with the same name, the nested struct is incorrectly used as the type for parameters that are declared with the top-level struct.


### Code example to reproduce the issue:

Run `--print slithir` on the following code.

```
pragma solidity 0.8.13;

interface Interface {
    struct ZZZ {
        int x;
        int y;
    }
}

struct ZZZ {
    int x;
    int y;
    int z;
}

contract A {
    function test(ZZZ memory zzz) external {
        zzz.z = 3;

        Interface.ZZZ memory zzz2 = Interface.ZZZ(1,2);
    }
}
```

### Version:

0.9.6

### Relevant log output:

```
Contract A
        Function A.test(Interface.ZZZ) (*)
                Expression: zzz.z = 3
                IRs:
                        REF_0(uint256) -> zzz.z
                        REF_0(uint256) (->zzz) := 3(uint256)
                Expression: zzz2 = Interface.ZZZ(1,2)
                IRs:
                        TMP_0(Interface.ZZZ) = new ZZZ(1,2)
                        zzz2(Interface.ZZZ) := TMP_0(Interface.ZZZ)
```

Note that above we have `Function A.test(Interface.ZZZ)` instead of `Function A.test(ZZZ)`



Discussion:
I think this is related to https://github.com/crytic/slither/issues/1809

Resolving patch:
diff --git a/slither/solc_parsing/solidity_types/type_parsing.py b/slither/solc_parsing/solidity_types/type_parsing.py
--- a/slither/solc_parsing/solidity_types/type_parsing.py
+++ b/slither/solc_parsing/solidity_types/type_parsing.py
@@ -82,9 +82,9 @@ def _find_from_type_name(  # pylint: disable=too-many-locals,too-many-branches,t
         # all_enums = [c.enums for c in contracts]
         # all_enums = [item for sublist in all_enums for item in sublist]
         # all_enums += contract.slither.enums_top_level
-        var_type = next((e for e in all_enums if e.name == enum_name), None)
+        var_type = next((e for e in all_enums if e.canonical_name == enum_name), None)
         if not var_type:
-            var_type = next((e for e in all_enums if e.canonical_name == enum_name), None)
+            var_type = next((e for e in all_enums if e.name == enum_name), None)
     if not var_type:
         # any contract can refer to another contract's structure
         name_struct = name
@@ -94,9 +94,9 @@ def _find_from_type_name(  # pylint: disable=too-many-locals,too-many-branches,t
         # all_structures = [c.structures for c in contracts]
         # all_structures = [item for sublist in all_structures for item in sublist]
         # all_structures += contract.slither.structures_top_level
-        var_type = next((st for st in all_structures if st.name == name_struct), None)
+        var_type = next((st for st in all_structures if st.canonical_name == name_struct), None)
         if not var_type:
-            var_type = next((st for st in all_structures if st.canonical_name == name_struct), None)
+            var_type = next((st for st in all_structures if st.name == name_struct), None)
         # case where struct xxx.xx[] where not well formed in the AST
         if not var_type:
             depth = 0


Test patch: