From 7a1b634f5803b1ad2141d3a36d8f34de0e1391bd Mon Sep 17 00:00:00 2001 From: Jeff Smits Date: Tue, 14 Apr 2026 15:07:58 +0200 Subject: [PATCH 1/2] Remove tracking of y in x.y expressions in LV analysis --- src/styx_compiler/live_variables.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/styx_compiler/live_variables.py b/src/styx_compiler/live_variables.py index a26717b..360d1c7 100644 --- a/src/styx_compiler/live_variables.py +++ b/src/styx_compiler/live_variables.py @@ -99,12 +99,6 @@ def visit_Name(self, node: cst.Name) -> bool | None: if result is not None: self._tfs[Node(index, 0)] = lambda lives, names=result: lives.union(names) - def visit_Attribute(self, node: cst.Attribute) -> bool | None: - index = self._provider.get_metadata(IndexProvider, node) - result = self.resolve_name(node) - if result is not None: - self._tfs[Node(index, 0)] = lambda lives, names=result: lives.union(names) - class LiveVariablesDataflowPropertyProvider(cst.BatchableMetadataProvider[DataflowProperty]): METADATA_DEPENDENCIES = (IndexProvider, QualifiedNameProvider) From 45c2711a18bfac9bbbc9030d0c0e093b41ea3d02 Mon Sep 17 00:00:00 2001 From: Jeff Smits Date: Wed, 29 Apr 2026 10:46:52 +0200 Subject: [PATCH 2/2] Fix missing SubscriptElement wrapper handling in CFG construction, don't count writes to subscripted things in LV as they are partial writes --- src/styx_compiler/control_flow.py | 20 ++++++++++++-------- src/styx_compiler/live_variables.py | 5 +++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/styx_compiler/control_flow.py b/src/styx_compiler/control_flow.py index fd4bf21..7597a36 100644 --- a/src/styx_compiler/control_flow.py +++ b/src/styx_compiler/control_flow.py @@ -630,18 +630,22 @@ def _visit_expression( expression: cst.Subscript = cst.ensure_type(expression, cst.Subscript) prev = self._visit_expression(expression.value, instance, prev, context) for element in expression.slice: - if m.matches(element, m.Index()): - element: cst.Index = cst.ensure_type(element, cst.Index) # noqa: PLW2901 + baseslice: cst.BaseSlice = cst.ensure_type(element, cst.SubscriptElement).slice + if m.matches(baseslice, m.Index()): + element: cst.Index = cst.ensure_type(baseslice, cst.Index) # noqa: PLW2901 prev = self._visit_expression(element.value, instance, prev) prev = self._make_cfg_node(element, instance, prev) # Index - elif m.matches(element, m.Slice()): - element: cst.Slice = cst.ensure_type(element, cst.Slice) # noqa: PLW2901 - prev = self._visit_expression(element.lower, instance, prev) - prev = self._visit_expression(element.upper, instance, prev) - prev = self._visit_expression(element.step, instance, prev) + elif m.matches(baseslice, m.Slice()): + element: cst.Slice = cst.ensure_type(baseslice, cst.Slice) # noqa: PLW2901 + if element.lower is not None: + prev = self._visit_expression(element.lower, instance, prev) + if element.upper is not None: + prev = self._visit_expression(element.upper, instance, prev) + if element.step is not None: + prev = self._visit_expression(element.step, instance, prev) prev = self._make_cfg_node(element, instance, prev) # Slice else: - msg = f"Unknown subscript element type {element}" + msg = f"Unknown BaseSlice type {baseslice}" raise RuntimeError(msg) prev = self._make_cfg_node(expression, instance, prev) # Subscript else: diff --git a/src/styx_compiler/live_variables.py b/src/styx_compiler/live_variables.py index 360d1c7..e225fd1 100644 --- a/src/styx_compiler/live_variables.py +++ b/src/styx_compiler/live_variables.py @@ -40,8 +40,9 @@ def _get_lhs_names(self, target: cst.BaseExpression) -> Sequence[QualifiedName]: if result is not None: return result if m.matches(target, m.Subscript()): - target: cst.Subscript = cst.ensure_type(target, cst.Subscript) - return self._get_lhs_names(target.value) + # target: cst.Subscript = cst.ensure_type(target, cst.Subscript) + # Don't return the name of the target.value, since only the subscripted part is written to + return [] if m.matches(target, m.StarredElement() | m.Element()): return self._get_lhs_names(target.value) if m.matches(target, m.Name()):