diff --git a/crates/ty_python_semantic/src/semantic_index/scope.rs b/crates/ty_python_semantic/src/semantic_index/scope.rs index dc24988207..62c7ff2a97 100644 --- a/crates/ty_python_semantic/src/semantic_index/scope.rs +++ b/crates/ty_python_semantic/src/semantic_index/scope.rs @@ -26,10 +26,6 @@ pub struct ScopeId<'db> { impl get_size2::GetSize for ScopeId<'_> {} impl<'db> ScopeId<'db> { - pub(crate) fn is_function_like(self, db: &'db dyn Db) -> bool { - self.node(db).scope_kind().is_function_like() - } - pub(crate) fn is_annotation(self, db: &'db dyn Db) -> bool { self.node(db).scope_kind().is_annotation() } diff --git a/crates/ty_python_semantic/src/types/class.rs b/crates/ty_python_semantic/src/types/class.rs index f31a86b3e3..48766457d7 100644 --- a/crates/ty_python_semantic/src/types/class.rs +++ b/crates/ty_python_semantic/src/types/class.rs @@ -9,7 +9,7 @@ use super::{ use crate::FxOrderMap; use crate::module_resolver::KnownModule; use crate::semantic_index::definition::{Definition, DefinitionState}; -use crate::semantic_index::scope::NodeWithScopeKind; +use crate::semantic_index::scope::{NodeWithScopeKind, Scope}; use crate::semantic_index::symbol::Symbol; use crate::semantic_index::{ DeclarationWithConstraint, SemanticIndex, attribute_declarations, attribute_scopes, @@ -2935,8 +2935,8 @@ impl<'db> ClassLiteral<'db> { let class_map = use_def_map(db, class_body_scope); let class_table = place_table(db, class_body_scope); - let is_valid_scope = |method_scope: ScopeId<'db>| { - if let Some(method_def) = method_scope.node(db).as_function() { + let is_valid_scope = |method_scope: &Scope| { + if let Some(method_def) = method_scope.node().as_function() { let method_name = method_def.node(&module).name.as_str(); if let Place::Type(Type::FunctionLiteral(method_type), _) = class_symbol(db, class_body_scope, method_name).place @@ -2954,7 +2954,7 @@ impl<'db> ClassLiteral<'db> { for (attribute_declarations, method_scope_id) in attribute_declarations(db, class_body_scope, &name) { - let method_scope = method_scope_id.to_scope_id(db, file); + let method_scope = index.scope(method_scope_id); if !is_valid_scope(method_scope) { continue; } @@ -3010,14 +3010,13 @@ impl<'db> ClassLiteral<'db> { for (attribute_assignments, method_scope_id) in attribute_assignments(db, class_body_scope, &name) { - let method_scope = method_scope_id.to_scope_id(db, file); + let method_scope = index.scope(method_scope_id); if !is_valid_scope(method_scope) { continue; } // The attribute assignment inherits the reachability of the method which contains it - let is_method_reachable = if let Some(method_def) = method_scope.node(db).as_function() - { + let is_method_reachable = if let Some(method_def) = method_scope.node().as_function() { let method = index.expect_single_definition(method_def); let method_place = class_table .symbol_id(&method_def.node(&module).name) diff --git a/crates/ty_python_semantic/src/types/display.rs b/crates/ty_python_semantic/src/types/display.rs index 92b86c406b..fdc093d439 100644 --- a/crates/ty_python_semantic/src/types/display.rs +++ b/crates/ty_python_semantic/src/types/display.rs @@ -191,10 +191,8 @@ impl ClassDisplay<'_> { let mut name_parts = vec![]; // Skips itself - for (ancestor_file_scope_id, ancestor_scope) in index.ancestor_scopes(file_scope_id).skip(1) - { - let ancestor_scope_id = ancestor_file_scope_id.to_scope_id(self.db, file); - let node = ancestor_scope_id.node(self.db); + for (_, ancestor_scope) in index.ancestor_scopes(file_scope_id).skip(1) { + let node = ancestor_scope.node(); match ancestor_scope.kind() { ScopeKind::Class => { diff --git a/crates/ty_python_semantic/src/types/infer/builder.rs b/crates/ty_python_semantic/src/types/infer/builder.rs index 9d39d3c08f..db04778cf8 100644 --- a/crates/ty_python_semantic/src/types/infer/builder.rs +++ b/crates/ty_python_semantic/src/types/infer/builder.rs @@ -4858,7 +4858,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> { let db = self.db(); let scope = self.scope(); let file_scope_id = scope.file_scope_id(db); - let current_file = self.file(); + 'names: for name in names { // Walk up parent scopes looking for a possible enclosing scope that may have a // definition of this name visible to us. Note that we skip the scope containing the @@ -4866,8 +4866,8 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> { for (enclosing_scope_file_id, _) in self.index.ancestor_scopes(file_scope_id).skip(1) { // Class scopes are not visible to nested scopes, and `nonlocal` cannot refer to // globals, so check only function-like scopes. - let enclosing_scope_id = enclosing_scope_file_id.to_scope_id(db, current_file); - if !enclosing_scope_id.is_function_like(db) { + let enclosing_scope = self.index.scope(enclosing_scope_file_id); + if !enclosing_scope.kind().is_function_like() { continue; } let enclosing_place_table = self.index.place_table(enclosing_scope_file_id); @@ -6348,7 +6348,6 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> { } let place = PlaceAndQualifiers::from(local_scope_place).or_fall_back_to(db, || { - let current_file = self.file(); let mut symbol_resolves_locally = false; if let Some(symbol) = place_expr.as_symbol() { if let Some(symbol_id) = place_table.symbol_id(symbol.name()) { @@ -6414,7 +6413,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> { // check only function-like scopes. // There is one exception to this rule: annotation scopes can see // names defined in an immediately-enclosing class scope. - let enclosing_scope_id = enclosing_scope_file_id.to_scope_id(db, current_file); + let enclosing_scope = self.index.scope(enclosing_scope_file_id); let is_immediately_enclosing_scope = scope.is_annotation(db) && scope @@ -6481,7 +6480,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> { } } - if !enclosing_scope_id.is_function_like(db) && !is_immediately_enclosing_scope { + if !enclosing_scope.kind().is_function_like() && !is_immediately_enclosing_scope { continue; } @@ -6502,6 +6501,8 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> { break; } + let enclosing_scope_id = enclosing_scope_file_id.to_scope_id(db, self.file()); + // If the name is declared or bound in this scope, figure out its type. This might // resolve the name and end the walk. But if the name is declared `nonlocal` in // this scope, we'll keep walking enclosing scopes and union this type with the