@@ -214,19 +214,10 @@ fn has_local_dunder_class_var_ref(semantic: &SemanticModel, func_stmt: &Stmt) ->
214214 return false ;
215215 }
216216
217- let mut finder = AnyExpressionFinder :: new ( vec ! [
218- |expr: & Expr | {
219- expr. as_name_expr( )
220- . is_some_and( |name| name. id. as_str( ) == "super" && name. ctx. is_load( ) )
221- } ,
222- |expr: & Expr | {
223- expr. as_name_expr( )
224- . is_some_and( |name| name. id. as_str( ) == "__class__" && name. ctx. is_load( ) )
225- } ,
226- ] ) ;
217+ let mut finder = ClassCellExpressionFinder :: new ( ) ;
227218 finder. visit_stmt ( func_stmt) ;
228219
229- finder. has_expression ( )
220+ finder. found ( )
230221}
231222
232223/// Returns `true` if the call is to the built-in `builtins.super` function.
@@ -236,44 +227,42 @@ fn is_builtins_super(semantic: &SemanticModel, call: &ast::ExprCall) -> bool {
236227 . is_some_and ( |qualified_name| matches ! ( qualified_name. segments( ) , [ "builtins" , "super" ] ) )
237228}
238229
239- /// A [`Visitor`] that searches for [`Expr`] matching any of the provided conditions
240- /// , excluding nested class definitions.
230+ /// A [`Visitor`] that searches for implicit reference to `__class__` cell,
231+ /// excluding nested class definitions.
241232#[ derive( Debug ) ]
242- struct AnyExpressionFinder < ' a > {
243- result_expression : Vec < & ' a Expr > ,
244- conditions : Vec < fn ( & Expr ) -> bool > ,
233+ struct ClassCellExpressionFinder {
234+ has_class_cell : bool ,
245235}
246236
247- impl AnyExpressionFinder < ' _ > {
248- pub ( crate ) fn new ( conditions : Vec < fn ( & Expr ) -> bool > ) -> Self {
249- AnyExpressionFinder {
250- result_expression : Vec :: with_capacity ( 1 ) ,
251- conditions,
237+ impl ClassCellExpressionFinder {
238+ pub ( crate ) fn new ( ) -> Self {
239+ ClassCellExpressionFinder {
240+ has_class_cell : false ,
252241 }
253242 }
254- pub ( crate ) fn has_expression ( & self ) -> bool {
255- ! self . result_expression . is_empty ( )
243+ pub ( crate ) fn found ( & self ) -> bool {
244+ self . has_class_cell
256245 }
257246}
258247
259- impl < ' a > Visitor < ' a > for AnyExpressionFinder < ' a > {
248+ impl < ' a > Visitor < ' a > for ClassCellExpressionFinder {
260249 fn visit_stmt ( & mut self , stmt : & ' a Stmt ) {
261250 match stmt {
262251 Stmt :: ClassDef ( _) => { }
263252 _ => {
264- if self . result_expression . is_empty ( ) {
253+ if ! self . has_class_cell {
265254 walk_stmt ( self , stmt) ;
266255 }
267256 }
268257 }
269258 }
270259
271260 fn visit_expr ( & mut self , expr : & ' a Expr ) {
272- for condition in & self . conditions {
273- if condition ( expr ) {
274- self . result_expression . insert ( 0 , expr ) ;
275- return ;
276- }
261+ if expr . as_name_expr ( ) . is_some_and ( |name| {
262+ matches ! ( name . id . as_str ( ) , "super" | "__class__" ) && name . ctx . is_load ( )
263+ } ) {
264+ self . has_class_cell = true ;
265+ return ;
277266 }
278267 walk_expr ( self , expr) ;
279268 }
0 commit comments