[ty] Test "list modules" versus "resolve module" in every mdtest

This ensures there is some level of consistency between the APIs.

This did require exposing a couple more things on `Module` for good
error messages. This also motivated a switch to an interned struct
instead of a tracked struct. This ensures that `list_modules` and
`resolve_modules` reuse the same `Module` values when the inputs are the
same.

Ref https://github.com/astral-sh/ruff/pull/19883#discussion_r2272520194
This commit is contained in:
Andrew Gallant 2025-08-13 09:44:05 -04:00 committed by Andrew Gallant
parent 2e9c241d7e
commit 468eb37d75
3 changed files with 128 additions and 25 deletions

View file

@ -3,7 +3,7 @@ use std::iter::FusedIterator;
pub use list::list_modules;
pub(crate) use module::KnownModule;
pub use module::Module;
pub use path::SearchPathValidationError;
pub use path::{SearchPath, SearchPathValidationError};
pub use resolver::SearchPaths;
pub(crate) use resolver::file_to_module;
pub use resolver::{resolve_module, resolve_real_module};

View file

@ -59,7 +59,7 @@ impl<'db> Module<'db> {
}
/// Is this a module that we special-case somehow? If so, which one?
pub(crate) fn known(self, db: &'db dyn Database) -> Option<KnownModule> {
pub fn known(self, db: &'db dyn Database) -> Option<KnownModule> {
match self {
Module::File(module) => module.known(db),
Module::Namespace(_) => None,
@ -75,7 +75,7 @@ impl<'db> Module<'db> {
///
/// It is guaranteed that if `None` is returned, then this is a namespace
/// package. Otherwise, this is a regular package or file module.
pub(crate) fn search_path(self, db: &'db dyn Database) -> Option<&'db SearchPath> {
pub fn search_path(self, db: &'db dyn Database) -> Option<&'db SearchPath> {
match self {
Module::File(module) => Some(module.search_path(db)),
Module::Namespace(_) => None,
@ -214,7 +214,7 @@ fn all_submodule_names_for_package(db: &dyn Db, file: File) -> Option<Vec<Name>>
}
/// A module that resolves to a file (`lib.py` or `package/__init__.py`)
#[salsa::tracked(debug, heap_size=ruff_memory_usage::heap_size)]
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
pub struct FileModule<'db> {
#[returns(ref)]
pub(super) name: ModuleName,
@ -229,7 +229,7 @@ pub struct FileModule<'db> {
///
/// Namespace packages are special because there are
/// multiple possible paths and they have no corresponding code file.
#[salsa::tracked(debug, heap_size=ruff_memory_usage::heap_size)]
#[salsa::interned(debug, heap_size=ruff_memory_usage::heap_size)]
pub struct NamespacePackage<'db> {
#[returns(ref)]
pub(super) name: ModuleName,