From d62a617938fbf56169af6fb8bd0900e3a9cb1526 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Fri, 31 May 2024 21:04:47 +0100 Subject: [PATCH] red-knot: Don't refer to `Module` instances as IDs (#11649) --- crates/red_knot/src/module.rs | 89 +++++++++++++++++------------- crates/red_knot/src/program/mod.rs | 2 +- 2 files changed, 51 insertions(+), 40 deletions(-) diff --git a/crates/red_knot/src/module.rs b/crates/red_knot/src/module.rs index 6f6ce355db404..bd02a1e819bc2 100644 --- a/crates/red_knot/src/module.rs +++ b/crates/red_knot/src/module.rs @@ -12,7 +12,10 @@ use crate::files::FileId; use crate::symbols::Dependency; use crate::FxDashMap; -/// ID uniquely identifying a module. +/// Representation of a Python module. +/// +/// The inner type wrapped by this struct is a unique identifier for the module +/// that is used by the struct's methods to lazily query information about the module. #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub struct Module(u32); @@ -100,7 +103,8 @@ impl Module { /// A module name, e.g. `foo.bar`. /// -/// Always normalized to the absolute form (never a relative module name). +/// Always normalized to the absolute form +/// (never a relative module name, i.e., never `.foo`). #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub struct ModuleName(smol_str::SmolStr); @@ -250,9 +254,11 @@ pub struct ModuleData { // Queries ////////////////////////////////////////////////////// -/// Resolves a module name to a module id -/// TODO: This would not work with Salsa because `ModuleName` isn't an ingredient and, therefore, cannot be used as part of a query. -/// For this to work with salsa, it would be necessary to intern all `ModuleName`s. +/// Resolves a module name to a module. +/// +/// TODO: This would not work with Salsa because `ModuleName` isn't an ingredient +/// and, therefore, cannot be used as part of a query. +/// For this to work with salsa, it would be necessary to intern all `ModuleName`s. #[tracing::instrument(level = "debug", skip(db))] pub fn resolve_module(db: &dyn SemanticDb, name: ModuleName) -> QueryResult> { let jar: &SemanticJar = db.jar()?; @@ -274,7 +280,7 @@ pub fn resolve_module(db: &dyn SemanticDb, name: ModuleName) -> QueryResult QueryResult QueryResult QueryResult> { let file = db.file_id(path); file_to_module(db, file) } -/// Resolves the module id for the file with the given id. +/// Resolves the module for the file with the given id. /// -/// Returns `None` if the file is not a module in `sys.path`. +/// Returns `None` if the file is not a module locatable via `sys.path`. #[tracing::instrument(level = "debug", skip(db))] pub fn file_to_module(db: &dyn SemanticDb, file: FileId) -> QueryResult> { let jar: &SemanticJar = db.jar()?; @@ -344,12 +350,12 @@ pub fn file_to_module(db: &dyn SemanticDb, file: FileId) -> QueryResult QueryResult Option<(Module, Vec>)> { // No locking is required because we're holding a mutable reference to `modules`. // TODO This needs tests - // Note: Intentionally by-pass caching here. Module should not be in the cache yet. + // Note: Intentionally bypass caching here. Module should not be in the cache yet. let module = path_to_module(db, path).ok()??; // The code below is to handle the addition of `__init__.py` files. @@ -424,15 +433,15 @@ pub fn add_module(db: &mut dyn SemanticDb, path: &Path) -> Option<(Module, Vec Option<(Module, Vec, - /// All known modules, indexed by the module id. + /// A map of all known modules to data about those modules modules: FxDashMap>, /// Lookup from absolute path to module. @@ -479,24 +488,26 @@ impl ModuleResolver { } /// Remove a module from the inner cache - pub(crate) fn remove_module(&mut self, file_id: FileId) { + pub(crate) fn remove_module_by_file(&mut self, file_id: FileId) { // No locking is required because we're holding a mutable reference to `self`. - let Some((_, id)) = self.by_file.remove(&file_id) else { + let Some((_, module)) = self.by_file.remove(&file_id) else { return; }; - self.remove_module_by_id(id); + self.remove_module(module); } - fn remove_module_by_id(&mut self, id: Module) -> Arc { - let (_, module) = self.modules.remove(&id).unwrap(); + fn remove_module(&mut self, module: Module) -> Arc { + let (_, module_data) = self.modules.remove(&module).unwrap(); - self.by_name.remove(&module.name).unwrap(); + self.by_name.remove(&module_data.name).unwrap(); - // It's possible that multiple paths map to the same id. Search all other paths referencing the same module id. - self.by_file.retain(|_, current_id| *current_id != id); + // It's possible that multiple paths map to the same module. + // Search all other paths referencing the same module. + self.by_file + .retain(|_, current_module| *current_module != module); - module + module_data } } diff --git a/crates/red_knot/src/program/mod.rs b/crates/red_knot/src/program/mod.rs index 4650b65967d06..473b14ac9d608 100644 --- a/crates/red_knot/src/program/mod.rs +++ b/crates/red_knot/src/program/mod.rs @@ -42,7 +42,7 @@ impl Program { let (source, semantic, lint) = self.jars_mut(); for change in aggregated_changes.iter() { - semantic.module_resolver.remove_module(change.id); + semantic.module_resolver.remove_module_by_file(change.id); semantic.symbol_tables.remove(&change.id); source.sources.remove(&change.id); source.parsed.remove(&change.id);