@@ -9,7 +9,7 @@ use ruff_db::{
99} ;
1010use ruff_text_size:: { Ranged , TextRange } ;
1111
12- use super :: { Type , TypeCheckDiagnostics , binding_type } ;
12+ use super :: { Type , TypeCheckDiagnostics , infer_definition_types } ;
1313
1414use crate :: diagnostic:: DiagnosticGuard ;
1515use crate :: lint:: LintSource ;
@@ -190,17 +190,22 @@ impl<'db, 'ast> InferContext<'db, 'ast> {
190190
191191 let scope_id = self . scope . file_scope_id ( self . db ) ;
192192
193- // Inspect all ancestor function scopes by walking bottom up and infer the function's type.
194- let mut function_scope_tys = index
193+ // Inspect all ancestor function scopes by walking bottom up and check
194+ // if any is decorated with `@no_type_check`. We use the undecorated type
195+ // rather than the binding type because other decorators (e.g. unknown ones)
196+ // may transform the function type into a non-`FunctionLiteral`.
197+ // `undecorated_type()` can be `None` during cycle recovery.
198+ index
195199 . ancestor_scopes ( scope_id)
196200 . filter_map ( |( _, scope) | scope. node ( ) . as_function ( ) )
197- . map ( |node| binding_type ( self . db , index. expect_single_definition ( node) ) )
198- . filter_map ( Type :: as_function_literal) ;
199-
200- // Iterate over all functions and test if any is decorated with `@no_type_check`.
201- function_scope_tys. any ( |function_ty| {
202- function_ty. has_known_decorator ( self . db , FunctionDecorators :: NO_TYPE_CHECK )
203- } )
201+ . filter_map ( |node| {
202+ infer_definition_types ( self . db , index. expect_single_definition ( node) )
203+ . undecorated_type ( )
204+ . and_then ( Type :: as_function_literal)
205+ } )
206+ . any ( |function_ty| {
207+ function_ty. has_known_decorator ( self . db , FunctionDecorators :: NO_TYPE_CHECK )
208+ } )
204209 }
205210 InNoTypeCheck :: Yes => true ,
206211 }
0 commit comments