@@ -196,7 +196,10 @@ impl<'db> SemanticModel<'db> {
196196
197197 /// Returns completions for symbols available in a `object.<CURSOR>` context.
198198 pub fn attribute_completions ( & self , node : & ast:: ExprAttribute ) -> Vec < Completion < ' db > > {
199- let ty = node. value . inferred_type ( self ) ;
199+ let Some ( ty) = node. value . inferred_type ( self ) else {
200+ return Vec :: new ( ) ;
201+ } ;
202+
200203 all_members ( self . db , ty)
201204 . into_iter ( )
202205 . map ( |member| Completion {
@@ -400,7 +403,7 @@ pub trait HasType {
400403 ///
401404 /// ## Panics
402405 /// May panic if `self` is from another file than `model`.
403- fn inferred_type < ' db > ( & self , model : & SemanticModel < ' db > ) -> Type < ' db > ;
406+ fn inferred_type < ' db > ( & self , model : & SemanticModel < ' db > ) -> Option < Type < ' db > > ;
404407}
405408
406409pub trait HasDefinition {
@@ -412,26 +415,24 @@ pub trait HasDefinition {
412415}
413416
414417impl HasType for ast:: ExprRef < ' _ > {
415- fn inferred_type < ' db > ( & self , model : & SemanticModel < ' db > ) -> Type < ' db > {
418+ fn inferred_type < ' db > ( & self , model : & SemanticModel < ' db > ) -> Option < Type < ' db > > {
416419 let index = semantic_index ( model. db , model. file ) ;
417420 // TODO(#1637): semantic tokens is making this crash even with
418421 // `try_expr_ref_in_ast` guarding this, for now just use `try_expression_scope_id`.
419422 // The problematic input is `x: "float` (with a dangling quote). I imagine the issue
420423 // is we're too eagerly setting `is_string_annotation` in inference.
421- let Some ( file_scope) = index. try_expression_scope_id ( & model. expr_ref_in_ast ( * self ) ) else {
422- return Type :: unknown ( ) ;
423- } ;
424+ let file_scope = index. try_expression_scope_id ( & model. expr_ref_in_ast ( * self ) ) ?;
424425 let scope = file_scope. to_scope_id ( model. db , model. file ) ;
425426
426- infer_scope_types ( model. db , scope) . expression_type ( * self )
427+ infer_scope_types ( model. db , scope) . try_expression_type ( * self )
427428 }
428429}
429430
430431macro_rules! impl_expression_has_type {
431432 ( $ty: ty) => {
432433 impl HasType for $ty {
433434 #[ inline]
434- fn inferred_type<' db>( & self , model: & SemanticModel <' db>) -> Type <' db> {
435+ fn inferred_type<' db>( & self , model: & SemanticModel <' db>) -> Option < Type <' db> > {
435436 let expression_ref = ExprRef :: from( self ) ;
436437 expression_ref. inferred_type( model)
437438 }
@@ -474,7 +475,7 @@ impl_expression_has_type!(ast::ExprSlice);
474475impl_expression_has_type ! ( ast:: ExprIpyEscapeCommand ) ;
475476
476477impl HasType for ast:: Expr {
477- fn inferred_type < ' db > ( & self , model : & SemanticModel < ' db > ) -> Type < ' db > {
478+ fn inferred_type < ' db > ( & self , model : & SemanticModel < ' db > ) -> Option < Type < ' db > > {
478479 match self {
479480 Expr :: BoolOp ( inner) => inner. inferred_type ( model) ,
480481 Expr :: Named ( inner) => inner. inferred_type ( model) ,
@@ -525,9 +526,9 @@ macro_rules! impl_binding_has_ty_def {
525526
526527 impl HasType for $ty {
527528 #[ inline]
528- fn inferred_type<' db>( & self , model: & SemanticModel <' db>) -> Type <' db> {
529+ fn inferred_type<' db>( & self , model: & SemanticModel <' db>) -> Option < Type <' db> > {
529530 let binding = HasDefinition :: definition( self , model) ;
530- binding_type( model. db, binding)
531+ Some ( binding_type( model. db, binding) )
531532 }
532533 }
533534 } ;
@@ -541,12 +542,12 @@ impl_binding_has_ty_def!(ast::ExceptHandlerExceptHandler);
541542impl_binding_has_ty_def ! ( ast:: TypeParamTypeVar ) ;
542543
543544impl HasType for ast:: Alias {
544- fn inferred_type < ' db > ( & self , model : & SemanticModel < ' db > ) -> Type < ' db > {
545+ fn inferred_type < ' db > ( & self , model : & SemanticModel < ' db > ) -> Option < Type < ' db > > {
545546 if & self . name == "*" {
546- return Type :: Never ;
547+ return Some ( Type :: Never ) ;
547548 }
548549 let index = semantic_index ( model. db , model. file ) ;
549- binding_type ( model. db , index. expect_single_definition ( self ) )
550+ Some ( binding_type ( model. db , index. expect_single_definition ( self ) ) )
550551 }
551552}
552553
@@ -584,7 +585,7 @@ mod tests {
584585
585586 let function = ast. suite ( ) [ 0 ] . as_function_def_stmt ( ) . unwrap ( ) ;
586587 let model = SemanticModel :: new ( & db, foo) ;
587- let ty = function. inferred_type ( & model) ;
588+ let ty = function. inferred_type ( & model) . unwrap ( ) ;
588589
589590 assert ! ( ty. is_function_literal( ) ) ;
590591
@@ -603,7 +604,7 @@ mod tests {
603604
604605 let class = ast. suite ( ) [ 0 ] . as_class_def_stmt ( ) . unwrap ( ) ;
605606 let model = SemanticModel :: new ( & db, foo) ;
606- let ty = class. inferred_type ( & model) ;
607+ let ty = class. inferred_type ( & model) . unwrap ( ) ;
607608
608609 assert ! ( ty. is_class_literal( ) ) ;
609610
@@ -624,7 +625,7 @@ mod tests {
624625 let import = ast. suite ( ) [ 0 ] . as_import_from_stmt ( ) . unwrap ( ) ;
625626 let alias = & import. names [ 0 ] ;
626627 let model = SemanticModel :: new ( & db, bar) ;
627- let ty = alias. inferred_type ( & model) ;
628+ let ty = alias. inferred_type ( & model) . unwrap ( ) ;
628629
629630 assert ! ( ty. is_class_literal( ) ) ;
630631
0 commit comments