diff --git a/Cargo.lock b/Cargo.lock index 9b0a4ca..467bc9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,9 +37,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95" [[package]] name = "autocfg" @@ -145,9 +145,9 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "els" -version = "0.1.58" +version = "0.1.59-nightly.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab76dea4883a3e75fab38a6cd6c761346fec5909850c557fcbd683f7bd30b54e" +checksum = "a2f90c210a0919808e48b96ecffd370ac788386ab061203132872e9bf1ad9f7f" dependencies = [ "erg_common", "erg_compiler", @@ -161,9 +161,9 @@ dependencies = [ [[package]] name = "erg_common" -version = "0.6.46" +version = "0.6.47-nightly.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cef7281a06474cd12e7eb653d164777023440b13a28c8834124770c4b8f65fa" +checksum = "d41f171eb77bf2763b119893966358ad9da72a3edd43cf278a78cf1c16daa2cf" dependencies = [ "backtrace-on-stack-overflow", "erg_proc_macros", @@ -174,9 +174,9 @@ dependencies = [ [[package]] name = "erg_compiler" -version = "0.6.46" +version = "0.6.47-nightly.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf1c1e83a364fafbcec194a27affd02bf4538740c34c1617c45d960d4a3e33c" +checksum = "93d0486bc668c120faf7af954dd4046224185c28821fb945a97eedcadf3e7d58" dependencies = [ "erg_common", "erg_parser", @@ -184,9 +184,9 @@ dependencies = [ [[package]] name = "erg_parser" -version = "0.6.46" +version = "0.6.47-nightly.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c65037a0c9b890d8f810f7a827b897fba6ae950b34258b1450c9ab1e310813c" +checksum = "98c37f58f3aef2e765610e7281ada15dbba707beaa0262a71e7f6958ee058ed0" dependencies = [ "erg_common", "erg_proc_macros", @@ -195,9 +195,9 @@ dependencies = [ [[package]] name = "erg_proc_macros" -version = "0.6.46" +version = "0.6.47-nightly.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29d7235082b39bf55cdec52da8c010c2d2d9ff7d41dde051158b7815f560f321" +checksum = "97fa545f626fd04abea193a07c364c4fca3903c228bbe9cca4895500944b5aaf" dependencies = [ "quote", "syn 1.0.109", @@ -292,9 +292,9 @@ checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" [[package]] name = "libc" -version = "0.2.159" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libm" @@ -554,9 +554,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] @@ -764,9 +764,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.131" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "67d42a0bd4ac281beff598909bb56a86acaf979b84483e1c79c10dcaf98f8cf3" dependencies = [ "itoa", "memchr", diff --git a/Cargo.toml b/Cargo.toml index 8b47acc..c4e2add 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,9 +24,9 @@ edition = "2021" repository = "https://github.com/mtshiba/pylyzer" [workspace.dependencies] -erg_common = { version = "0.6.46", features = ["py_compat", "els"] } -erg_compiler = { version = "0.6.46", features = ["py_compat", "els"] } -els = { version = "0.1.58", features = ["py_compat"] } +erg_common = { version = "0.6.47-nightly.2", features = ["py_compat", "els"] } +erg_compiler = { version = "0.6.47-nightly.2", features = ["py_compat", "els"] } +els = { version = "0.1.59-nightly.2", features = ["py_compat"] } # rustpython-parser = { version = "0.3.0", features = ["all-nodes-with-ranges", "location"] } # rustpython-ast = { version = "0.3.0", features = ["all-nodes-with-ranges", "location"] } rustpython-parser = { git = "https://github.com/RustPython/Parser", version = "0.4.0", features = ["all-nodes-with-ranges", "location"] } diff --git a/crates/py2erg/convert.rs b/crates/py2erg/convert.rs index 06470cb..82a4952 100644 --- a/crates/py2erg/convert.rs +++ b/crates/py2erg/convert.rs @@ -114,6 +114,9 @@ impl BlockKind { pub const fn is_function(&self) -> bool { matches!(self, Self::Function | Self::AsyncFunction) } + pub const fn makes_scope(&self) -> bool { + matches!(self, Self::Function | Self::AsyncFunction | Self::Class) + } } /// Variables are automatically rewritten with `py_compat`, @@ -554,6 +557,7 @@ pub struct ASTConverter { comments: CommentStorage, pyi_types: PyiTypeStorage, block_id_counter: usize, + /// block != scope (if block doesn't make a scope, for example) block_ids: Vec, contexts: Vec, warns: CompileErrors, @@ -628,6 +632,10 @@ impl ASTConverter { self.contexts.pop(); } + fn cur_block_kind(&self) -> BlockKind { + self.contexts.last().unwrap().kind + } + fn cur_block_id(&self) -> usize { *self.block_ids.last().unwrap() } @@ -657,6 +665,7 @@ impl ASTConverter { fn register_name_info(&mut self, name: &str, kind: NameKind) -> CanShadow { let cur_namespace = self.cur_namespace(); let cur_block_id = self.cur_block_id(); + let cur_block_kind = self.cur_block_kind(); if let Some(name_info) = self.get_mut_name(name) { if name_info.defined_in == cur_namespace && name_info.defined_block_id == cur_block_id { name_info.defined_times += 1; @@ -665,7 +674,10 @@ impl ASTConverter { name_info.defined_in = DefinedPlace::Known(cur_namespace); name_info.defined_times += 1; // 0 -> 1 } - if name_info.defined_block_id == cur_block_id || name_info.defined_times == 0 { + if cur_block_kind.makes_scope() + || name_info.defined_block_id == cur_block_id + || name_info.defined_times == 0 + { CanShadow::Yes } else { CanShadow::No diff --git a/tests/dict.py b/tests/dict.py new file mode 100644 index 0000000..8ee4c46 --- /dev/null +++ b/tests/dict.py @@ -0,0 +1,18 @@ +dic = {"a": 1, "b": 2} + +def f(): + dic = {"a": 1} + _ = dic["b"] # ERR + + +class TaskManager: + def __init__(self): + self.tasks: list[dict[str, int]] = [] + + def add_task(self, title: str, id: int): + task = {title: id} + self.tasks.append(task) + + def add_task2(self, title: str, id: int): + task = {id: title} + self.tasks.append(task) # ERR diff --git a/tests/test.rs b/tests/test.rs index 773b8bd..91b5bc8 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -77,6 +77,11 @@ fn exec_import() -> Result<(), String> { expect("tests/import.py", 1, 2) } +#[test] +fn exec_dict() -> Result<(), String> { + expect("tests/dict.py", 0, 2) +} + #[test] fn exec_export() -> Result<(), String> { expect("tests/export.py", 0, 0)