@@ -304,14 +304,10 @@ impl<'db> SemanticModel<'db> {
304304 . scope ( self . db )
305305 . file_scope_id ( self . db ) ,
306306 ) ,
307- ast:: AnyNodeRef :: ExceptHandlerExceptHandler ( handler) => self
308- . except_handler_definition ( handler )
307+ ast:: AnyNodeRef :: ExceptHandlerExceptHandler ( handler) => handler
308+ . optional_definition ( self )
309309 . map ( |definition| definition. scope ( self . db ) . file_scope_id ( self . db ) )
310- . or_else ( || {
311- handler. type_ . as_deref ( ) . and_then ( |handled_exceptions| {
312- index. try_expression_scope_id ( handled_exceptions)
313- } )
314- } )
310+ . or_else ( || index. try_expression_scope_id ( handler. type_ . as_deref ( ) ?) )
315311 . or ( Some ( FileScopeId :: global ( ) ) ) ,
316312 ast:: AnyNodeRef :: TypeParamTypeVar ( var) => {
317313 Some ( var. definition ( self ) . scope ( self . db ) . file_scope_id ( self . db ) )
@@ -328,29 +324,6 @@ impl<'db> SemanticModel<'db> {
328324 }
329325 }
330326
331- /// Returns the definition for an exception-handler variable.
332- ///
333- /// Exception handlers only have a definition when they bind a name (`except E as name:`).
334- pub fn except_handler_definition (
335- & self ,
336- handler : & ast:: ExceptHandlerExceptHandler ,
337- ) -> Option < Definition < ' db > > {
338- handler. name . as_ref ( ) ?;
339- let index = semantic_index ( self . db , self . file ) ;
340- Some ( index. expect_single_definition ( handler) )
341- }
342-
343- /// Returns the inferred type of an exception-handler variable.
344- ///
345- /// Exception handlers only bind a variable when they have a name (`except E as name:`).
346- pub fn except_handler_type (
347- & self ,
348- handler : & ast:: ExceptHandlerExceptHandler ,
349- ) -> Option < Type < ' db > > {
350- let definition = self . except_handler_definition ( handler) ?;
351- Some ( binding_type ( self . db , definition) )
352- }
353-
354327 /// Get a "safe" [`ast::AnyNodeRef`] to use for referring to the given (sub-)AST node.
355328 ///
356329 /// If we're analyzing a string annotation, it will return the string literal's node.
@@ -543,6 +516,14 @@ pub trait HasDefinition {
543516 fn definition < ' db > ( & self , model : & SemanticModel < ' db > ) -> Definition < ' db > ;
544517}
545518
519+ pub trait HasOptionalDefinition {
520+ /// Returns the definition of `self`, if it has one.
521+ ///
522+ /// ## Panics
523+ /// May panic if `self` is from another file than `model`.
524+ fn optional_definition < ' db > ( & self , model : & SemanticModel < ' db > ) -> Option < Definition < ' db > > ;
525+ }
526+
546527impl HasType for ast:: ExprRef < ' _ > {
547528 fn inferred_type < ' db > ( & self , model : & SemanticModel < ' db > ) -> Option < Type < ' db > > {
548529 let index = semantic_index ( model. db , model. file ) ;
@@ -679,6 +660,21 @@ impl HasType for ast::Alias {
679660 }
680661}
681662
663+ impl HasOptionalDefinition for ast:: ExceptHandlerExceptHandler {
664+ fn optional_definition < ' db > ( & self , model : & SemanticModel < ' db > ) -> Option < Definition < ' db > > {
665+ self . name . as_ref ( ) ?;
666+ let index = semantic_index ( model. db , model. file ) ;
667+ Some ( index. expect_single_definition ( self ) )
668+ }
669+ }
670+
671+ impl HasType for ast:: ExceptHandlerExceptHandler {
672+ fn inferred_type < ' db > ( & self , model : & SemanticModel < ' db > ) -> Option < Type < ' db > > {
673+ let definition = self . optional_definition ( model) ?;
674+ Some ( binding_type ( model. db , definition) )
675+ }
676+ }
677+
682678/// Implemented by types for which the semantic index tracks their scope.
683679pub ( crate ) trait HasTrackedScope : HasNodeIndex { }
684680
0 commit comments