Skip to content

Commit dd335e3

Browse files
fix
1 parent 7c7f25d commit dd335e3

2 files changed

Lines changed: 26 additions & 1 deletion

File tree

pyrefly/lib/binding/scope.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,6 +1816,31 @@ impl Scopes {
18161816
false
18171817
}
18181818

1819+
/// Record an additional write to an already-known `self.<attr>` in the current method.
1820+
///
1821+
/// Unlike `record_self_attr_assign`, this will not invent a new instance attribute for
1822+
/// augmented assignments like `self.x += 1`; those remain invalid unless a prior write
1823+
/// in the method established the attribute.
1824+
pub fn record_known_self_attr_write(
1825+
&mut self,
1826+
x: &ExprAttribute,
1827+
value: ExprOrBinding,
1828+
) -> bool {
1829+
for scope in self.iter_rev_mut() {
1830+
if let ScopeKind::Method(method_scope) = &mut scope.kind
1831+
&& let Some(self_name) = &method_scope.self_name
1832+
&& matches!(&*x.value, Expr::Name(name) if name.id == self_name.id)
1833+
{
1834+
if let Some(attr) = method_scope.instance_attributes.get_mut(&x.attr.id) {
1835+
attr.writes.push(value);
1836+
return true;
1837+
}
1838+
return false;
1839+
}
1840+
}
1841+
false
1842+
}
1843+
18191844
pub fn method_that_sets_attr(&self, x: &ExprAttribute) -> Option<MethodThatSetsAttr> {
18201845
let mut method_name: Option<Name> = None;
18211846
let mut receiver_kind = MethodSelfKind::Instance;

pyrefly/lib/binding/stmt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,7 @@ impl<'a> BindingsBuilder<'a> {
849849
*x_cloned.value = expr.clone();
850850
ExprOrBinding::Binding(Binding::AugAssign(ann, Box::new(x_cloned)))
851851
});
852-
self.scopes.record_self_attr_assign(attr, value, None);
852+
self.scopes.record_known_self_attr_write(attr, value);
853853
}
854854
Expr::Subscript(subscr) => {
855855
let mut x_cloned = x.clone();

0 commit comments

Comments
 (0)