[ty] Fix false-positive [invalid-return-type] diagnostics on generator functions (#17871)

This commit is contained in:
Alex Waygood 2025-05-05 22:44:59 +01:00 committed by GitHub
parent 47e3aa40b3
commit bb6c7cad07
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 253 additions and 22 deletions

View file

@ -109,6 +109,10 @@ pub(super) struct SemanticIndexBuilder<'db> {
definitions_by_node: FxHashMap<DefinitionNodeKey, Definitions<'db>>,
expressions_by_node: FxHashMap<ExpressionNodeKey, Expression<'db>>,
imported_modules: FxHashSet<ModuleName>,
/// Hashset of all [`FileScopeId`]s that correspond to [generator functions].
///
/// [generator functions]: https://docs.python.org/3/glossary.html#term-generator
generator_functions: FxHashSet<FileScopeId>,
eager_bindings: FxHashMap<EagerBindingsKey, ScopedEagerBindingsId>,
/// Errors collected by the `semantic_checker`.
semantic_syntax_errors: RefCell<Vec<SemanticSyntaxError>>,
@ -142,6 +146,7 @@ impl<'db> SemanticIndexBuilder<'db> {
expressions_by_node: FxHashMap::default(),
imported_modules: FxHashSet::default(),
generator_functions: FxHashSet::default(),
eager_bindings: FxHashMap::default(),
@ -1081,6 +1086,7 @@ impl<'db> SemanticIndexBuilder<'db> {
self.scope_ids_by_scope.shrink_to_fit();
self.scopes_by_node.shrink_to_fit();
self.eager_bindings.shrink_to_fit();
self.generator_functions.shrink_to_fit();
SemanticIndex {
symbol_tables,
@ -1097,6 +1103,7 @@ impl<'db> SemanticIndexBuilder<'db> {
has_future_annotations: self.has_future_annotations,
eager_bindings: self.eager_bindings,
semantic_syntax_errors: self.semantic_syntax_errors.into_inner(),
generator_functions: self.generator_functions,
}
}
@ -2305,6 +2312,13 @@ where
walk_expr(self, expr);
}
ast::Expr::Yield(_) => {
let scope = self.current_scope();
if self.scopes[scope].kind() == ScopeKind::Function {
self.generator_functions.insert(scope);
}
walk_expr(self, expr);
}
_ => {
walk_expr(self, expr);
}

View file

@ -13,7 +13,7 @@ use rustc_hash::FxHasher;
use crate::ast_node_ref::AstNodeRef;
use crate::node_key::NodeKey;
use crate::semantic_index::visibility_constraints::ScopedVisibilityConstraintId;
use crate::semantic_index::{semantic_index, SymbolMap};
use crate::semantic_index::{semantic_index, SemanticIndex, SymbolMap};
use crate::Db;
#[derive(Eq, PartialEq, Debug)]
@ -170,6 +170,10 @@ impl FileScopeId {
let index = semantic_index(db, file);
index.scope_ids_by_scope[self]
}
pub(crate) fn is_generator_function(self, index: &SemanticIndex) -> bool {
index.generator_functions.contains(&self)
}
}
#[derive(Debug, salsa::Update)]