diff --git a/crates/red_knot/src/lint.rs b/crates/red_knot/src/lint.rs index e6b2c7f62d..e70db18d5f 100644 --- a/crates/red_knot/src/lint.rs +++ b/crates/red_knot/src/lint.rs @@ -130,7 +130,7 @@ fn lint_bad_override(context: &SemanticLintContext, class: &ast::StmtClassDef) { return; }; - let override_ty = semantic.module_global_symbol_ty(&typing, "override"); + let override_ty = semantic.global_symbol_ty(&typing, "override"); let Type::Class(class_ty) = class.ty(semantic) else { return; diff --git a/crates/red_knot_python_semantic/src/db.rs b/crates/red_knot_python_semantic/src/db.rs index c2b0456aa9..7fabc88725 100644 --- a/crates/red_knot_python_semantic/src/db.rs +++ b/crates/red_knot_python_semantic/src/db.rs @@ -6,7 +6,7 @@ use ruff_db::{Db as SourceDb, Upcast}; use crate::semantic_index::definition::Definition; use crate::semantic_index::expression::Expression; use crate::semantic_index::symbol::ScopeId; -use crate::semantic_index::{module_global_scope, semantic_index, symbol_table, use_def_map}; +use crate::semantic_index::{global_scope, semantic_index, symbol_table, use_def_map}; use crate::types::{ infer_definition_types, infer_expression_types, infer_scope_types, ClassType, FunctionType, IntersectionType, UnionType, @@ -23,7 +23,7 @@ pub struct Jar( IntersectionType<'_>, symbol_table, use_def_map, - module_global_scope, + global_scope, semantic_index, infer_definition_types, infer_expression_types, diff --git a/crates/red_knot_python_semantic/src/semantic_index.rs b/crates/red_knot_python_semantic/src/semantic_index.rs index 32a4648bb1..ef8f6f0aa1 100644 --- a/crates/red_knot_python_semantic/src/semantic_index.rs +++ b/crates/red_knot_python_semantic/src/semantic_index.rs @@ -68,10 +68,10 @@ pub(crate) fn use_def_map<'db>(db: &'db dyn Db, scope: ScopeId<'db>) -> Arc ScopeId<'_> { - let _span = tracing::trace_span!("module_global_scope", ?file).entered(); +pub(crate) fn global_scope(db: &dyn Db, file: File) -> ScopeId<'_> { + let _span = tracing::trace_span!("global_scope", ?file).entered(); - FileScopeId::module_global().to_scope_id(db, file) + FileScopeId::global().to_scope_id(db, file) } /// The symbol tables and use-def maps for all scopes in a file. @@ -309,7 +309,7 @@ mod tests { use crate::semantic_index::ast_ids::HasScopedUseId; use crate::semantic_index::definition::DefinitionKind; use crate::semantic_index::symbol::{FileScopeId, Scope, ScopeKind, SymbolTable}; - use crate::semantic_index::{module_global_scope, semantic_index, symbol_table, use_def_map}; + use crate::semantic_index::{global_scope, semantic_index, symbol_table, use_def_map}; use crate::Db; struct TestCase { @@ -336,38 +336,38 @@ mod tests { #[test] fn empty() { let TestCase { db, file } = test_case(""); - let module_global_table = symbol_table(&db, module_global_scope(&db, file)); + let global_table = symbol_table(&db, global_scope(&db, file)); - let module_global_names = names(&module_global_table); + let global_names = names(&global_table); - assert_eq!(module_global_names, Vec::<&str>::new()); + assert_eq!(global_names, Vec::<&str>::new()); } #[test] fn simple() { let TestCase { db, file } = test_case("x"); - let module_global_table = symbol_table(&db, module_global_scope(&db, file)); + let global_table = symbol_table(&db, global_scope(&db, file)); - assert_eq!(names(&module_global_table), vec!["x"]); + assert_eq!(names(&global_table), vec!["x"]); } #[test] fn annotation_only() { let TestCase { db, file } = test_case("x: int"); - let module_global_table = symbol_table(&db, module_global_scope(&db, file)); + let global_table = symbol_table(&db, global_scope(&db, file)); - assert_eq!(names(&module_global_table), vec!["int", "x"]); + assert_eq!(names(&global_table), vec!["int", "x"]); // TODO record definition } #[test] fn import() { let TestCase { db, file } = test_case("import foo"); - let scope = module_global_scope(&db, file); - let module_global_table = symbol_table(&db, scope); + let scope = global_scope(&db, file); + let global_table = symbol_table(&db, scope); - assert_eq!(names(&module_global_table), vec!["foo"]); - let foo = module_global_table.symbol_id_by_name("foo").unwrap(); + assert_eq!(names(&global_table), vec!["foo"]); + let foo = global_table.symbol_id_by_name("foo").unwrap(); let use_def = use_def_map(&db, scope); let [definition] = use_def.public_definitions(foo) else { @@ -379,28 +379,28 @@ mod tests { #[test] fn import_sub() { let TestCase { db, file } = test_case("import foo.bar"); - let module_global_table = symbol_table(&db, module_global_scope(&db, file)); + let global_table = symbol_table(&db, global_scope(&db, file)); - assert_eq!(names(&module_global_table), vec!["foo"]); + assert_eq!(names(&global_table), vec!["foo"]); } #[test] fn import_as() { let TestCase { db, file } = test_case("import foo.bar as baz"); - let module_global_table = symbol_table(&db, module_global_scope(&db, file)); + let global_table = symbol_table(&db, global_scope(&db, file)); - assert_eq!(names(&module_global_table), vec!["baz"]); + assert_eq!(names(&global_table), vec!["baz"]); } #[test] fn import_from() { let TestCase { db, file } = test_case("from bar import foo"); - let scope = module_global_scope(&db, file); - let module_global_table = symbol_table(&db, scope); + let scope = global_scope(&db, file); + let global_table = symbol_table(&db, scope); - assert_eq!(names(&module_global_table), vec!["foo"]); + assert_eq!(names(&global_table), vec!["foo"]); assert!( - module_global_table + global_table .symbol_by_name("foo") .is_some_and(|symbol| { symbol.is_defined() && !symbol.is_used() }), "symbols that are defined get the defined flag" @@ -408,7 +408,7 @@ mod tests { let use_def = use_def_map(&db, scope); let [definition] = use_def.public_definitions( - module_global_table + global_table .symbol_id_by_name("foo") .expect("symbol to exist"), ) else { @@ -423,22 +423,20 @@ mod tests { #[test] fn assign() { let TestCase { db, file } = test_case("x = foo"); - let scope = module_global_scope(&db, file); - let module_global_table = symbol_table(&db, scope); + let scope = global_scope(&db, file); + let global_table = symbol_table(&db, scope); - assert_eq!(names(&module_global_table), vec!["foo", "x"]); + assert_eq!(names(&global_table), vec!["foo", "x"]); assert!( - module_global_table + global_table .symbol_by_name("foo") .is_some_and(|symbol| { !symbol.is_defined() && symbol.is_used() }), "a symbol used but not defined in a scope should have only the used flag" ); let use_def = use_def_map(&db, scope); - let [definition] = use_def.public_definitions( - module_global_table - .symbol_id_by_name("x") - .expect("symbol exists"), - ) else { + let [definition] = + use_def.public_definitions(global_table.symbol_id_by_name("x").expect("symbol exists")) + else { panic!("expected one definition"); }; assert!(matches!( @@ -456,14 +454,14 @@ class C: y = 2 ", ); - let module_global_table = symbol_table(&db, module_global_scope(&db, file)); + let global_table = symbol_table(&db, global_scope(&db, file)); - assert_eq!(names(&module_global_table), vec!["C", "y"]); + assert_eq!(names(&global_table), vec!["C", "y"]); let index = semantic_index(&db, file); let [(class_scope_id, class_scope)] = index - .child_scopes(FileScopeId::module_global()) + .child_scopes(FileScopeId::global()) .collect::>()[..] else { panic!("expected one child scope") @@ -496,12 +494,12 @@ y = 2 ", ); let index = semantic_index(&db, file); - let module_global_table = index.symbol_table(FileScopeId::module_global()); + let global_table = index.symbol_table(FileScopeId::global()); - assert_eq!(names(&module_global_table), vec!["func", "y"]); + assert_eq!(names(&global_table), vec!["func", "y"]); let [(function_scope_id, function_scope)] = index - .child_scopes(FileScopeId::module_global()) + .child_scopes(FileScopeId::global()) .collect::>()[..] else { panic!("expected one child scope") @@ -537,11 +535,11 @@ def func(): ", ); let index = semantic_index(&db, file); - let module_global_table = index.symbol_table(FileScopeId::module_global()); + let global_table = index.symbol_table(FileScopeId::global()); - assert_eq!(names(&module_global_table), vec!["func"]); + assert_eq!(names(&global_table), vec!["func"]); let [(func_scope1_id, func_scope_1), (func_scope2_id, func_scope_2)] = index - .child_scopes(FileScopeId::module_global()) + .child_scopes(FileScopeId::global()) .collect::>()[..] else { panic!("expected two child scopes"); @@ -558,9 +556,9 @@ def func(): assert_eq!(names(&func1_table), vec!["x"]); assert_eq!(names(&func2_table), vec!["y"]); - let use_def = index.use_def_map(FileScopeId::module_global()); + let use_def = index.use_def_map(FileScopeId::global()); let [definition] = use_def.public_definitions( - module_global_table + global_table .symbol_id_by_name("func") .expect("symbol exists"), ) else { @@ -579,12 +577,12 @@ def func[T](): ); let index = semantic_index(&db, file); - let module_global_table = index.symbol_table(FileScopeId::module_global()); + let global_table = index.symbol_table(FileScopeId::global()); - assert_eq!(names(&module_global_table), vec!["func"]); + assert_eq!(names(&global_table), vec!["func"]); let [(ann_scope_id, ann_scope)] = index - .child_scopes(FileScopeId::module_global()) + .child_scopes(FileScopeId::global()) .collect::>()[..] else { panic!("expected one child scope"); @@ -616,12 +614,12 @@ class C[T]: ); let index = semantic_index(&db, file); - let module_global_table = index.symbol_table(FileScopeId::module_global()); + let global_table = index.symbol_table(FileScopeId::global()); - assert_eq!(names(&module_global_table), vec!["C"]); + assert_eq!(names(&global_table), vec!["C"]); let [(ann_scope_id, ann_scope)] = index - .child_scopes(FileScopeId::module_global()) + .child_scopes(FileScopeId::global()) .collect::>()[..] else { panic!("expected one child scope"); @@ -653,7 +651,7 @@ class C[T]: fn reachability_trivial() { let TestCase { db, file } = test_case("x = 1; x"); let parsed = parsed_module(&db, file); - let scope = module_global_scope(&db, file); + let scope = global_scope(&db, file); let ast = parsed.syntax(); let ast::Stmt::Expr(ast::StmtExpr { value: x_use_expr, .. @@ -694,7 +692,7 @@ class C[T]: let x = &x_stmt.targets[0]; assert_eq!(index.expression_scope(x).kind(), ScopeKind::Module); - assert_eq!(index.expression_scope_id(x), FileScopeId::module_global()); + assert_eq!(index.expression_scope_id(x), FileScopeId::global()); let def = ast.body[1].as_function_def_stmt().unwrap(); let y_stmt = def.body[0].as_assign_stmt().unwrap(); @@ -731,20 +729,16 @@ def x(): let index = semantic_index(&db, file); - let descendents = index.descendent_scopes(FileScopeId::module_global()); + let descendents = index.descendent_scopes(FileScopeId::global()); assert_eq!( scope_names(descendents, &db, file), vec!["Test", "foo", "bar", "baz", "x"] ); - let children = index.child_scopes(FileScopeId::module_global()); + let children = index.child_scopes(FileScopeId::global()); assert_eq!(scope_names(children, &db, file), vec!["Test", "x"]); - let test_class = index - .child_scopes(FileScopeId::module_global()) - .next() - .unwrap() - .0; + let test_class = index.child_scopes(FileScopeId::global()).next().unwrap().0; let test_child_scopes = index.child_scopes(test_class); assert_eq!( scope_names(test_child_scopes, &db, file), @@ -752,7 +746,7 @@ def x(): ); let bar_scope = index - .descendent_scopes(FileScopeId::module_global()) + .descendent_scopes(FileScopeId::global()) .nth(2) .unwrap() .0; diff --git a/crates/red_knot_python_semantic/src/semantic_index/symbol.rs b/crates/red_knot_python_semantic/src/semantic_index/symbol.rs index a31963fa50..a04331199c 100644 --- a/crates/red_knot_python_semantic/src/semantic_index/symbol.rs +++ b/crates/red_knot_python_semantic/src/semantic_index/symbol.rs @@ -133,7 +133,7 @@ pub struct FileScopeId; impl FileScopeId { /// Returns the scope id of the module-global scope. - pub fn module_global() -> Self { + pub fn global() -> Self { FileScopeId::from_u32(0) } diff --git a/crates/red_knot_python_semantic/src/semantic_model.rs b/crates/red_knot_python_semantic/src/semantic_model.rs index 2ecb9ece3e..aa5702170c 100644 --- a/crates/red_knot_python_semantic/src/semantic_model.rs +++ b/crates/red_knot_python_semantic/src/semantic_model.rs @@ -5,7 +5,7 @@ use ruff_python_ast::{Expr, ExpressionRef, StmtClassDef}; use crate::semantic_index::ast_ids::HasScopedAstId; use crate::semantic_index::semantic_index; -use crate::types::{definition_ty, infer_scope_types, module_global_symbol_ty_by_name, Type}; +use crate::types::{definition_ty, global_symbol_ty_by_name, infer_scope_types, Type}; use crate::Db; pub struct SemanticModel<'db> { @@ -28,8 +28,8 @@ impl<'db> SemanticModel<'db> { resolve_module(self.db.upcast(), module_name) } - pub fn module_global_symbol_ty(&self, module: &Module, symbol_name: &str) -> Type<'db> { - module_global_symbol_ty_by_name(self.db, module.file(), symbol_name) + pub fn global_symbol_ty(&self, module: &Module, symbol_name: &str) -> Type<'db> { + global_symbol_ty_by_name(self.db, module.file(), symbol_name) } } diff --git a/crates/red_knot_python_semantic/src/types.rs b/crates/red_knot_python_semantic/src/types.rs index 3c17c05c90..f0b30348e6 100644 --- a/crates/red_knot_python_semantic/src/types.rs +++ b/crates/red_knot_python_semantic/src/types.rs @@ -3,7 +3,7 @@ use ruff_python_ast::name::Name; use crate::semantic_index::definition::Definition; use crate::semantic_index::symbol::{ScopeId, ScopedSymbolId}; -use crate::semantic_index::{module_global_scope, symbol_table, use_def_map}; +use crate::semantic_index::{global_scope, symbol_table, use_def_map}; use crate::{Db, FxOrderSet}; mod display; @@ -43,12 +43,8 @@ pub(crate) fn symbol_ty_by_name<'db>( } /// Shorthand for `symbol_ty` that looks up a module-global symbol in a file. -pub(crate) fn module_global_symbol_ty_by_name<'db>( - db: &'db dyn Db, - file: File, - name: &str, -) -> Type<'db> { - symbol_ty_by_name(db, module_global_scope(db, file), name) +pub(crate) fn global_symbol_ty_by_name<'db>(db: &'db dyn Db, file: File, name: &str) -> Type<'db> { + symbol_ty_by_name(db, global_scope(db, file), name) } /// Infer the type of a [`Definition`]. @@ -145,7 +141,7 @@ impl<'db> Type<'db> { Type::Unbound => Type::Unbound, Type::None => todo!("attribute lookup on None type"), Type::Function(_) => todo!("attribute lookup on Function type"), - Type::Module(file) => module_global_symbol_ty_by_name(db, *file, name), + Type::Module(file) => global_symbol_ty_by_name(db, *file, name), Type::Class(class) => class.class_member(db, name), Type::Instance(_) => { // TODO MRO? get_own_instance_member, get_instance_member diff --git a/crates/red_knot_python_semantic/src/types/infer.rs b/crates/red_knot_python_semantic/src/types/infer.rs index faca379b28..73178be1b0 100644 --- a/crates/red_knot_python_semantic/src/types/infer.rs +++ b/crates/red_knot_python_semantic/src/types/infer.rs @@ -37,8 +37,7 @@ use crate::semantic_index::symbol::NodeWithScopeKind; use crate::semantic_index::symbol::{NodeWithScopeRef, ScopeId}; use crate::semantic_index::SemanticIndex; use crate::types::{ - definitions_ty, module_global_symbol_ty_by_name, ClassType, FunctionType, Name, Type, - UnionTypeBuilder, + definitions_ty, global_symbol_ty_by_name, ClassType, FunctionType, Name, Type, UnionTypeBuilder, }; use crate::Db; @@ -685,7 +684,7 @@ impl<'db> TypeInferenceBuilder<'db> { let symbol = symbols.symbol_by_name(id).unwrap(); if !symbol.is_defined() || !self.scope.is_function_like(self.db) { // implicit global - Some(module_global_symbol_ty_by_name(self.db, self.file, id)) + Some(global_symbol_ty_by_name(self.db, self.file, id)) } else { Some(Type::Unbound) } @@ -796,7 +795,7 @@ mod tests { use crate::semantic_index::semantic_index; use crate::semantic_index::symbol::FileScopeId; use crate::types::{ - infer_definition_types, module_global_scope, module_global_symbol_ty_by_name, symbol_table, + global_scope, global_symbol_ty_by_name, infer_definition_types, symbol_table, symbol_ty_by_name, use_def_map, Type, }; use crate::{HasTy, SemanticModel}; @@ -821,7 +820,7 @@ mod tests { fn assert_public_ty(db: &TestDb, file_name: &str, symbol_name: &str, expected: &str) { let file = system_path_to_file(db, file_name).expect("Expected file to exist."); - let ty = module_global_symbol_ty_by_name(db, file, symbol_name); + let ty = global_symbol_ty_by_name(db, file, symbol_name); assert_eq!(ty.display(db).to_string(), expected); } @@ -855,7 +854,7 @@ mod tests { )?; let mod_file = system_path_to_file(&db, "src/mod.py").expect("Expected file to exist."); - let ty = module_global_symbol_ty_by_name(&db, mod_file, "Sub"); + let ty = global_symbol_ty_by_name(&db, mod_file, "Sub"); let Type::Class(class) = ty else { panic!("Sub is not a Class") @@ -885,7 +884,7 @@ mod tests { )?; let mod_file = system_path_to_file(&db, "src/mod.py").unwrap(); - let ty = module_global_symbol_ty_by_name(&db, mod_file, "C"); + let ty = global_symbol_ty_by_name(&db, mod_file, "C"); let Type::Class(class_id) = ty else { panic!("C is not a Class"); @@ -1234,7 +1233,7 @@ mod tests { )?; let a = system_path_to_file(&db, "src/a.py").expect("Expected file to exist."); - let c_ty = module_global_symbol_ty_by_name(&db, a, "C"); + let c_ty = global_symbol_ty_by_name(&db, a, "C"); let Type::Class(c_class) = c_ty else { panic!("C is not a Class") }; @@ -1272,7 +1271,7 @@ mod tests { let file = system_path_to_file(&db, "src/a.py").expect("Expected file to exist."); let index = semantic_index(&db, file); let function_scope = index - .child_scopes(FileScopeId::module_global()) + .child_scopes(FileScopeId::global()) .next() .unwrap() .0 @@ -1303,7 +1302,7 @@ mod tests { let file = system_path_to_file(&db, "src/a.py").expect("Expected file to exist."); let index = semantic_index(&db, file); let function_scope = index - .child_scopes(FileScopeId::module_global()) + .child_scopes(FileScopeId::global()) .next() .unwrap() .0 @@ -1336,7 +1335,7 @@ mod tests { let file = system_path_to_file(&db, "src/a.py").expect("Expected file to exist."); let index = semantic_index(&db, file); let class_scope = index - .child_scopes(FileScopeId::module_global()) + .child_scopes(FileScopeId::global()) .next() .unwrap() .0 @@ -1370,7 +1369,7 @@ mod tests { } fn first_public_def<'db>(db: &'db TestDb, file: File, name: &str) -> Definition<'db> { - let scope = module_global_scope(db, file); + let scope = global_scope(db, file); *use_def_map(db, scope) .public_definitions(symbol_table(db, scope).symbol_id_by_name(name).unwrap()) .first() @@ -1387,7 +1386,7 @@ mod tests { ])?; let a = system_path_to_file(&db, "/src/a.py").unwrap(); - let x_ty = module_global_symbol_ty_by_name(&db, a, "x"); + let x_ty = global_symbol_ty_by_name(&db, a, "x"); assert_eq!(x_ty.display(&db).to_string(), "Literal[10]"); @@ -1396,7 +1395,7 @@ mod tests { let a = system_path_to_file(&db, "/src/a.py").unwrap(); - let x_ty_2 = module_global_symbol_ty_by_name(&db, a, "x"); + let x_ty_2 = global_symbol_ty_by_name(&db, a, "x"); assert_eq!(x_ty_2.display(&db).to_string(), "Literal[20]"); @@ -1413,7 +1412,7 @@ mod tests { ])?; let a = system_path_to_file(&db, "/src/a.py").unwrap(); - let x_ty = module_global_symbol_ty_by_name(&db, a, "x"); + let x_ty = global_symbol_ty_by_name(&db, a, "x"); assert_eq!(x_ty.display(&db).to_string(), "Literal[10]"); @@ -1423,7 +1422,7 @@ mod tests { db.clear_salsa_events(); - let x_ty_2 = module_global_symbol_ty_by_name(&db, a, "x"); + let x_ty_2 = global_symbol_ty_by_name(&db, a, "x"); assert_eq!(x_ty_2.display(&db).to_string(), "Literal[10]"); @@ -1449,7 +1448,7 @@ mod tests { ])?; let a = system_path_to_file(&db, "/src/a.py").unwrap(); - let x_ty = module_global_symbol_ty_by_name(&db, a, "x"); + let x_ty = global_symbol_ty_by_name(&db, a, "x"); assert_eq!(x_ty.display(&db).to_string(), "Literal[10]"); @@ -1459,7 +1458,7 @@ mod tests { db.clear_salsa_events(); - let x_ty_2 = module_global_symbol_ty_by_name(&db, a, "x"); + let x_ty_2 = global_symbol_ty_by_name(&db, a, "x"); assert_eq!(x_ty_2.display(&db).to_string(), "Literal[10]");