Upgrade salsa (#13757)

This commit is contained in:
Micha Reiser 2024-10-15 13:06:32 +02:00 committed by GitHub
parent 72ac6cd5a5
commit 5f65e842e8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 143 additions and 120 deletions

6
Cargo.lock generated
View file

@ -3009,7 +3009,7 @@ checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
[[package]] [[package]]
name = "salsa" name = "salsa"
version = "0.18.0" version = "0.18.0"
source = "git+https://github.com/salsa-rs/salsa.git?rev=4a7c955255e707e64e43f3ce5eabb771ae067768#4a7c955255e707e64e43f3ce5eabb771ae067768" source = "git+https://github.com/salsa-rs/salsa.git?rev=b14be5c0392f4c55eca60b92e457a35549372382#b14be5c0392f4c55eca60b92e457a35549372382"
dependencies = [ dependencies = [
"append-only-vec", "append-only-vec",
"arc-swap", "arc-swap",
@ -3029,12 +3029,12 @@ dependencies = [
[[package]] [[package]]
name = "salsa-macro-rules" name = "salsa-macro-rules"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/salsa-rs/salsa.git?rev=4a7c955255e707e64e43f3ce5eabb771ae067768#4a7c955255e707e64e43f3ce5eabb771ae067768" source = "git+https://github.com/salsa-rs/salsa.git?rev=b14be5c0392f4c55eca60b92e457a35549372382#b14be5c0392f4c55eca60b92e457a35549372382"
[[package]] [[package]]
name = "salsa-macros" name = "salsa-macros"
version = "0.18.0" version = "0.18.0"
source = "git+https://github.com/salsa-rs/salsa.git?rev=4a7c955255e707e64e43f3ce5eabb771ae067768#4a7c955255e707e64e43f3ce5eabb771ae067768" source = "git+https://github.com/salsa-rs/salsa.git?rev=b14be5c0392f4c55eca60b92e457a35549372382#b14be5c0392f4c55eca60b92e457a35549372382"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",

View file

@ -117,7 +117,7 @@ rayon = { version = "1.10.0" }
regex = { version = "1.10.2" } regex = { version = "1.10.2" }
rstest = { version = "0.22.0", default-features = false } rstest = { version = "0.22.0", default-features = false }
rustc-hash = { version = "2.0.0" } rustc-hash = { version = "2.0.0" }
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "4a7c955255e707e64e43f3ce5eabb771ae067768" } salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "b14be5c0392f4c55eca60b92e457a35549372382" }
schemars = { version = "0.8.16" } schemars = { version = "0.8.16" }
seahash = { version = "4.1.0" } seahash = { version = "4.1.0" }
serde = { version = "1.0.197", features = ["derive"] } serde = { version = "1.0.197", features = ["derive"] }

View file

@ -501,7 +501,10 @@ fn directory_moved_to_workspace() -> anyhow::Result<()> {
.with_context(|| "Failed to create __init__.py")?; .with_context(|| "Failed to create __init__.py")?;
std::fs::write(a_original_path.as_std_path(), "").with_context(|| "Failed to create a.py")?; std::fs::write(a_original_path.as_std_path(), "").with_context(|| "Failed to create a.py")?;
let sub_a_module = resolve_module(case.db().upcast(), ModuleName::new_static("sub.a").unwrap()); let sub_a_module = resolve_module(
case.db().upcast(),
&ModuleName::new_static("sub.a").unwrap(),
);
assert_eq!(sub_a_module, None); assert_eq!(sub_a_module, None);
assert_eq!( assert_eq!(
@ -525,7 +528,11 @@ fn directory_moved_to_workspace() -> anyhow::Result<()> {
.expect("a.py to exist"); .expect("a.py to exist");
// `import sub.a` should now resolve // `import sub.a` should now resolve
assert!(resolve_module(case.db().upcast(), ModuleName::new_static("sub.a").unwrap()).is_some()); assert!(resolve_module(
case.db().upcast(),
&ModuleName::new_static("sub.a").unwrap()
)
.is_some());
assert_eq!( assert_eq!(
case.collect_package_files(&case.workspace_path("bar.py")), case.collect_package_files(&case.workspace_path("bar.py")),
@ -544,7 +551,11 @@ fn directory_moved_to_trash() -> anyhow::Result<()> {
])?; ])?;
let bar = case.system_file(case.workspace_path("bar.py")).unwrap(); let bar = case.system_file(case.workspace_path("bar.py")).unwrap();
assert!(resolve_module(case.db().upcast(), ModuleName::new_static("sub.a").unwrap()).is_some()); assert!(resolve_module(
case.db().upcast(),
&ModuleName::new_static("sub.a").unwrap()
)
.is_some());
let sub_path = case.workspace_path("sub"); let sub_path = case.workspace_path("sub");
let init_file = case let init_file = case
@ -569,7 +580,11 @@ fn directory_moved_to_trash() -> anyhow::Result<()> {
case.apply_changes(changes); case.apply_changes(changes);
// `import sub.a` should no longer resolve // `import sub.a` should no longer resolve
assert!(resolve_module(case.db().upcast(), ModuleName::new_static("sub.a").unwrap()).is_none()); assert!(resolve_module(
case.db().upcast(),
&ModuleName::new_static("sub.a").unwrap()
)
.is_none());
assert!(!init_file.exists(case.db())); assert!(!init_file.exists(case.db()));
assert!(!a_file.exists(case.db())); assert!(!a_file.exists(case.db()));
@ -592,10 +607,14 @@ fn directory_renamed() -> anyhow::Result<()> {
let bar = case.system_file(case.workspace_path("bar.py")).unwrap(); let bar = case.system_file(case.workspace_path("bar.py")).unwrap();
assert!(resolve_module(case.db().upcast(), ModuleName::new_static("sub.a").unwrap()).is_some());
assert!(resolve_module( assert!(resolve_module(
case.db().upcast(), case.db().upcast(),
ModuleName::new_static("foo.baz").unwrap() &ModuleName::new_static("sub.a").unwrap()
)
.is_some());
assert!(resolve_module(
case.db().upcast(),
&ModuleName::new_static("foo.baz").unwrap()
) )
.is_none()); .is_none());
@ -623,11 +642,15 @@ fn directory_renamed() -> anyhow::Result<()> {
case.apply_changes(changes); case.apply_changes(changes);
// `import sub.a` should no longer resolve // `import sub.a` should no longer resolve
assert!(resolve_module(case.db().upcast(), ModuleName::new_static("sub.a").unwrap()).is_none()); assert!(resolve_module(
case.db().upcast(),
&ModuleName::new_static("sub.a").unwrap()
)
.is_none());
// `import foo.baz` should now resolve // `import foo.baz` should now resolve
assert!(resolve_module( assert!(resolve_module(
case.db().upcast(), case.db().upcast(),
ModuleName::new_static("foo.baz").unwrap() &ModuleName::new_static("foo.baz").unwrap()
) )
.is_some()); .is_some());
@ -665,7 +688,11 @@ fn directory_deleted() -> anyhow::Result<()> {
let bar = case.system_file(case.workspace_path("bar.py")).unwrap(); let bar = case.system_file(case.workspace_path("bar.py")).unwrap();
assert!(resolve_module(case.db().upcast(), ModuleName::new_static("sub.a").unwrap()).is_some()); assert!(resolve_module(
case.db().upcast(),
&ModuleName::new_static("sub.a").unwrap()
)
.is_some());
let sub_path = case.workspace_path("sub"); let sub_path = case.workspace_path("sub");
@ -688,7 +715,11 @@ fn directory_deleted() -> anyhow::Result<()> {
case.apply_changes(changes); case.apply_changes(changes);
// `import sub.a` should no longer resolve // `import sub.a` should no longer resolve
assert!(resolve_module(case.db().upcast(), ModuleName::new_static("sub.a").unwrap()).is_none()); assert!(resolve_module(
case.db().upcast(),
&ModuleName::new_static("sub.a").unwrap()
)
.is_none());
assert!(!init_file.exists(case.db())); assert!(!init_file.exists(case.db()));
assert!(!a_file.exists(case.db())); assert!(!a_file.exists(case.db()));
@ -710,7 +741,7 @@ fn search_path() -> anyhow::Result<()> {
let site_packages = case.root_path().join("site_packages"); let site_packages = case.root_path().join("site_packages");
assert_eq!( assert_eq!(
resolve_module(case.db(), ModuleName::new("a").unwrap()), resolve_module(case.db(), &ModuleName::new("a").unwrap()),
None None
); );
@ -720,7 +751,7 @@ fn search_path() -> anyhow::Result<()> {
case.apply_changes(changes); case.apply_changes(changes);
assert!(resolve_module(case.db().upcast(), ModuleName::new_static("a").unwrap()).is_some()); assert!(resolve_module(case.db().upcast(), &ModuleName::new_static("a").unwrap()).is_some());
assert_eq!( assert_eq!(
case.collect_package_files(&case.workspace_path("bar.py")), case.collect_package_files(&case.workspace_path("bar.py")),
&[case.system_file(case.workspace_path("bar.py")).unwrap()] &[case.system_file(case.workspace_path("bar.py")).unwrap()]
@ -736,7 +767,7 @@ fn add_search_path() -> anyhow::Result<()> {
let site_packages = case.workspace_path("site_packages"); let site_packages = case.workspace_path("site_packages");
std::fs::create_dir_all(site_packages.as_std_path())?; std::fs::create_dir_all(site_packages.as_std_path())?;
assert!(resolve_module(case.db().upcast(), ModuleName::new_static("a").unwrap()).is_none()); assert!(resolve_module(case.db().upcast(), &ModuleName::new_static("a").unwrap()).is_none());
// Register site-packages as a search path. // Register site-packages as a search path.
case.update_search_path_settings(SearchPathConfiguration { case.update_search_path_settings(SearchPathConfiguration {
@ -751,7 +782,7 @@ fn add_search_path() -> anyhow::Result<()> {
case.apply_changes(changes); case.apply_changes(changes);
assert!(resolve_module(case.db().upcast(), ModuleName::new_static("a").unwrap()).is_some()); assert!(resolve_module(case.db().upcast(), &ModuleName::new_static("a").unwrap()).is_some());
Ok(()) Ok(())
} }
@ -805,7 +836,7 @@ fn changed_versions_file() -> anyhow::Result<()> {
// Unset the custom typeshed directory. // Unset the custom typeshed directory.
assert_eq!( assert_eq!(
resolve_module(case.db(), ModuleName::new("os").unwrap()), resolve_module(case.db(), &ModuleName::new("os").unwrap()),
None None
); );
@ -820,7 +851,7 @@ fn changed_versions_file() -> anyhow::Result<()> {
case.apply_changes(changes); case.apply_changes(changes);
assert!(resolve_module(case.db(), ModuleName::new("os").unwrap()).is_some()); assert!(resolve_module(case.db(), &ModuleName::new("os").unwrap()).is_some());
Ok(()) Ok(())
} }
@ -1044,7 +1075,7 @@ mod unix {
let baz = resolve_module( let baz = resolve_module(
case.db().upcast(), case.db().upcast(),
ModuleName::new_static("bar.baz").unwrap(), &ModuleName::new_static("bar.baz").unwrap(),
) )
.expect("Expected bar.baz to exist in site-packages."); .expect("Expected bar.baz to exist in site-packages.");
let baz_workspace = case.workspace_path("bar/baz.py"); let baz_workspace = case.workspace_path("bar/baz.py");
@ -1125,7 +1156,7 @@ mod unix {
let baz = resolve_module( let baz = resolve_module(
case.db().upcast(), case.db().upcast(),
ModuleName::new_static("bar.baz").unwrap(), &ModuleName::new_static("bar.baz").unwrap(),
) )
.expect("Expected bar.baz to exist in site-packages."); .expect("Expected bar.baz to exist in site-packages.");
let bar_baz = case.workspace_path("bar/baz.py"); let bar_baz = case.workspace_path("bar/baz.py");
@ -1229,7 +1260,7 @@ mod unix {
let baz = resolve_module( let baz = resolve_module(
case.db().upcast(), case.db().upcast(),
ModuleName::new_static("bar.baz").unwrap(), &ModuleName::new_static("bar.baz").unwrap(),
) )
.expect("Expected bar.baz to exist in site-packages."); .expect("Expected bar.baz to exist in site-packages.");
let baz_site_packages_path = let baz_site_packages_path =

View file

@ -17,7 +17,7 @@ use super::module::{Module, ModuleKind};
use super::path::{ModulePath, SearchPath, SearchPathValidationError}; use super::path::{ModulePath, SearchPath, SearchPathValidationError};
/// Resolves a module name to a module. /// Resolves a module name to a module.
pub fn resolve_module(db: &dyn Db, module_name: ModuleName) -> Option<Module> { pub fn resolve_module(db: &dyn Db, module_name: &ModuleName) -> Option<Module> {
let interned_name = ModuleNameIngredient::new(db, module_name); let interned_name = ModuleNameIngredient::new(db, module_name);
resolve_module_query(db, interned_name) resolve_module_query(db, interned_name)
@ -103,7 +103,7 @@ pub(crate) fn file_to_module(db: &dyn Db, file: File) -> Option<Module> {
// If it doesn't, then that means that multiple modules have the same name in different // If it doesn't, then that means that multiple modules have the same name in different
// root paths, but that the module corresponding to `path` is in a lower priority search path, // root paths, but that the module corresponding to `path` is in a lower priority search path,
// in which case we ignore it. // in which case we ignore it.
let module = resolve_module(db, module_name)?; let module = resolve_module(db, &module_name)?;
if file == module.file() { if file == module.file() {
Some(module) Some(module)
@ -728,11 +728,11 @@ mod tests {
.build(); .build();
let foo_module_name = ModuleName::new_static("foo").unwrap(); let foo_module_name = ModuleName::new_static("foo").unwrap();
let foo_module = resolve_module(&db, foo_module_name.clone()).unwrap(); let foo_module = resolve_module(&db, &foo_module_name).unwrap();
assert_eq!( assert_eq!(
Some(&foo_module), Some(&foo_module),
resolve_module(&db, foo_module_name.clone()).as_ref() resolve_module(&db, &foo_module_name).as_ref()
); );
assert_eq!("foo", foo_module.name()); assert_eq!("foo", foo_module.name());
@ -755,7 +755,7 @@ mod tests {
.build(); .build();
let builtins_module_name = ModuleName::new_static("builtins").unwrap(); let builtins_module_name = ModuleName::new_static("builtins").unwrap();
let builtins = resolve_module(&db, builtins_module_name).expect("builtins to resolve"); let builtins = resolve_module(&db, &builtins_module_name).expect("builtins to resolve");
assert_eq!(builtins.file().path(&db), &stdlib.join("builtins.pyi")); assert_eq!(builtins.file().path(&db), &stdlib.join("builtins.pyi"));
} }
@ -776,7 +776,7 @@ mod tests {
.build(); .build();
let builtins_module_name = ModuleName::new_static("builtins").unwrap(); let builtins_module_name = ModuleName::new_static("builtins").unwrap();
let builtins = resolve_module(&db, builtins_module_name).expect("builtins to resolve"); let builtins = resolve_module(&db, &builtins_module_name).expect("builtins to resolve");
assert_eq!(builtins.file().path(&db), &stdlib.join("builtins.pyi")); assert_eq!(builtins.file().path(&db), &stdlib.join("builtins.pyi"));
} }
@ -794,11 +794,11 @@ mod tests {
.build(); .build();
let functools_module_name = ModuleName::new_static("functools").unwrap(); let functools_module_name = ModuleName::new_static("functools").unwrap();
let functools_module = resolve_module(&db, functools_module_name.clone()).unwrap(); let functools_module = resolve_module(&db, &functools_module_name).unwrap();
assert_eq!( assert_eq!(
Some(&functools_module), Some(&functools_module),
resolve_module(&db, functools_module_name).as_ref() resolve_module(&db, &functools_module_name).as_ref()
); );
assert_eq!(&stdlib, functools_module.search_path()); assert_eq!(&stdlib, functools_module.search_path());
@ -848,7 +848,7 @@ mod tests {
let existing_modules = create_module_names(&["asyncio", "functools", "xml.etree"]); let existing_modules = create_module_names(&["asyncio", "functools", "xml.etree"]);
for module_name in existing_modules { for module_name in existing_modules {
let resolved_module = resolve_module(&db, module_name.clone()).unwrap_or_else(|| { let resolved_module = resolve_module(&db, &module_name).unwrap_or_else(|| {
panic!("Expected module {module_name} to exist in the mock stdlib") panic!("Expected module {module_name} to exist in the mock stdlib")
}); });
let search_path = resolved_module.search_path(); let search_path = resolved_module.search_path();
@ -901,7 +901,7 @@ mod tests {
for module_name in nonexisting_modules { for module_name in nonexisting_modules {
assert!( assert!(
resolve_module(&db, module_name.clone()).is_none(), resolve_module(&db, &module_name).is_none(),
"Unexpectedly resolved a module for {module_name}" "Unexpectedly resolved a module for {module_name}"
); );
} }
@ -944,7 +944,7 @@ mod tests {
]); ]);
for module_name in existing_modules { for module_name in existing_modules {
let resolved_module = resolve_module(&db, module_name.clone()).unwrap_or_else(|| { let resolved_module = resolve_module(&db, &module_name).unwrap_or_else(|| {
panic!("Expected module {module_name} to exist in the mock stdlib") panic!("Expected module {module_name} to exist in the mock stdlib")
}); });
let search_path = resolved_module.search_path(); let search_path = resolved_module.search_path();
@ -980,7 +980,7 @@ mod tests {
let nonexisting_modules = create_module_names(&["importlib", "xml", "xml.etree"]); let nonexisting_modules = create_module_names(&["importlib", "xml", "xml.etree"]);
for module_name in nonexisting_modules { for module_name in nonexisting_modules {
assert!( assert!(
resolve_module(&db, module_name.clone()).is_none(), resolve_module(&db, &module_name).is_none(),
"Unexpectedly resolved a module for {module_name}" "Unexpectedly resolved a module for {module_name}"
); );
} }
@ -1002,11 +1002,11 @@ mod tests {
.build(); .build();
let functools_module_name = ModuleName::new_static("functools").unwrap(); let functools_module_name = ModuleName::new_static("functools").unwrap();
let functools_module = resolve_module(&db, functools_module_name.clone()).unwrap(); let functools_module = resolve_module(&db, &functools_module_name).unwrap();
assert_eq!( assert_eq!(
Some(&functools_module), Some(&functools_module),
resolve_module(&db, functools_module_name).as_ref() resolve_module(&db, &functools_module_name).as_ref()
); );
assert_eq!(&src, functools_module.search_path()); assert_eq!(&src, functools_module.search_path());
assert_eq!(ModuleKind::Module, functools_module.kind()); assert_eq!(ModuleKind::Module, functools_module.kind());
@ -1026,7 +1026,7 @@ mod tests {
.build(); .build();
let pydoc_data_topics_name = ModuleName::new_static("pydoc_data.topics").unwrap(); let pydoc_data_topics_name = ModuleName::new_static("pydoc_data.topics").unwrap();
let pydoc_data_topics = resolve_module(&db, pydoc_data_topics_name).unwrap(); let pydoc_data_topics = resolve_module(&db, &pydoc_data_topics_name).unwrap();
assert_eq!("pydoc_data.topics", pydoc_data_topics.name()); assert_eq!("pydoc_data.topics", pydoc_data_topics.name());
assert_eq!(pydoc_data_topics.search_path(), &stdlib); assert_eq!(pydoc_data_topics.search_path(), &stdlib);
@ -1043,7 +1043,7 @@ mod tests {
.build(); .build();
let foo_path = src.join("foo/__init__.py"); let foo_path = src.join("foo/__init__.py");
let foo_module = resolve_module(&db, ModuleName::new_static("foo").unwrap()).unwrap(); let foo_module = resolve_module(&db, &ModuleName::new_static("foo").unwrap()).unwrap();
assert_eq!("foo", foo_module.name()); assert_eq!("foo", foo_module.name());
assert_eq!(&src, foo_module.search_path()); assert_eq!(&src, foo_module.search_path());
@ -1070,7 +1070,7 @@ mod tests {
let TestCase { db, src, .. } = TestCaseBuilder::new().with_src_files(SRC).build(); let TestCase { db, src, .. } = TestCaseBuilder::new().with_src_files(SRC).build();
let foo_module = resolve_module(&db, ModuleName::new_static("foo").unwrap()).unwrap(); let foo_module = resolve_module(&db, &ModuleName::new_static("foo").unwrap()).unwrap();
let foo_init_path = src.join("foo/__init__.py"); let foo_init_path = src.join("foo/__init__.py");
assert_eq!(&src, foo_module.search_path()); assert_eq!(&src, foo_module.search_path());
@ -1098,11 +1098,11 @@ mod tests {
let foo_bar_module_name = ModuleName::new_static("foo.bar").unwrap(); let foo_bar_module_name = ModuleName::new_static("foo.bar").unwrap();
// `foo.py` takes priority over the `foo` namespace package // `foo.py` takes priority over the `foo` namespace package
let foo_module = resolve_module(&db, foo_module_name.clone()).unwrap(); let foo_module = resolve_module(&db, &foo_module_name).unwrap();
assert_eq!(foo_module.file().path(&db), &src.join("foo.py")); assert_eq!(foo_module.file().path(&db), &src.join("foo.py"));
// `foo.bar` isn't recognised as a module // `foo.bar` isn't recognised as a module
let foo_bar_module = resolve_module(&db, foo_bar_module_name.clone()); let foo_bar_module = resolve_module(&db, &foo_bar_module_name);
assert_eq!(foo_bar_module, None); assert_eq!(foo_bar_module, None);
} }
@ -1112,7 +1112,7 @@ mod tests {
let TestCase { db, src, .. } = TestCaseBuilder::new().with_src_files(SRC).build(); let TestCase { db, src, .. } = TestCaseBuilder::new().with_src_files(SRC).build();
let foo = resolve_module(&db, ModuleName::new_static("foo").unwrap()).unwrap(); let foo = resolve_module(&db, &ModuleName::new_static("foo").unwrap()).unwrap();
let foo_stub = src.join("foo.pyi"); let foo_stub = src.join("foo.pyi");
assert_eq!(&src, foo.search_path()); assert_eq!(&src, foo.search_path());
@ -1136,7 +1136,7 @@ mod tests {
let TestCase { db, src, .. } = TestCaseBuilder::new().with_src_files(SRC).build(); let TestCase { db, src, .. } = TestCaseBuilder::new().with_src_files(SRC).build();
let baz_module = let baz_module =
resolve_module(&db, ModuleName::new_static("foo.bar.baz").unwrap()).unwrap(); resolve_module(&db, &ModuleName::new_static("foo.bar.baz").unwrap()).unwrap();
let baz_path = src.join("foo/bar/baz.py"); let baz_path = src.join("foo/bar/baz.py");
assert_eq!(&src, baz_module.search_path()); assert_eq!(&src, baz_module.search_path());
@ -1175,14 +1175,14 @@ mod tests {
let one_module_name = ModuleName::new_static("parent.child.one").unwrap(); let one_module_name = ModuleName::new_static("parent.child.one").unwrap();
let one_module_path = FilePath::System(src.join("parent/child/one.py")); let one_module_path = FilePath::System(src.join("parent/child/one.py"));
assert_eq!( assert_eq!(
resolve_module(&db, one_module_name), resolve_module(&db, &one_module_name),
path_to_module(&db, &one_module_path) path_to_module(&db, &one_module_path)
); );
let two_module_name = ModuleName::new_static("parent.child.two").unwrap(); let two_module_name = ModuleName::new_static("parent.child.two").unwrap();
let two_module_path = FilePath::System(site_packages.join("parent/child/two.py")); let two_module_path = FilePath::System(site_packages.join("parent/child/two.py"));
assert_eq!( assert_eq!(
resolve_module(&db, two_module_name), resolve_module(&db, &two_module_name),
path_to_module(&db, &two_module_path) path_to_module(&db, &two_module_path)
); );
} }
@ -1215,12 +1215,12 @@ mod tests {
let one_module_path = FilePath::System(src.join("parent/child/one.py")); let one_module_path = FilePath::System(src.join("parent/child/one.py"));
let one_module_name = let one_module_name =
resolve_module(&db, ModuleName::new_static("parent.child.one").unwrap()); resolve_module(&db, &ModuleName::new_static("parent.child.one").unwrap());
assert_eq!(one_module_name, path_to_module(&db, &one_module_path)); assert_eq!(one_module_name, path_to_module(&db, &one_module_path));
assert_eq!( assert_eq!(
None, None,
resolve_module(&db, ModuleName::new_static("parent.child.two").unwrap()) resolve_module(&db, &ModuleName::new_static("parent.child.two").unwrap())
); );
} }
@ -1236,7 +1236,7 @@ mod tests {
.with_site_packages_files(&[("foo.py", "")]) .with_site_packages_files(&[("foo.py", "")])
.build(); .build();
let foo_module = resolve_module(&db, ModuleName::new_static("foo").unwrap()).unwrap(); let foo_module = resolve_module(&db, &ModuleName::new_static("foo").unwrap()).unwrap();
let foo_src_path = src.join("foo.py"); let foo_src_path = src.join("foo.py");
assert_eq!(&src, foo_module.search_path()); assert_eq!(&src, foo_module.search_path());
@ -1301,8 +1301,8 @@ mod tests {
) )
.context("Invalid program settings")?; .context("Invalid program settings")?;
let foo_module = resolve_module(&db, ModuleName::new_static("foo").unwrap()).unwrap(); let foo_module = resolve_module(&db, &ModuleName::new_static("foo").unwrap()).unwrap();
let bar_module = resolve_module(&db, ModuleName::new_static("bar").unwrap()).unwrap(); let bar_module = resolve_module(&db, &ModuleName::new_static("bar").unwrap()).unwrap();
assert_ne!(foo_module, bar_module); assert_ne!(foo_module, bar_module);
@ -1337,7 +1337,7 @@ mod tests {
.build(); .build();
let foo_module_name = ModuleName::new_static("foo").unwrap(); let foo_module_name = ModuleName::new_static("foo").unwrap();
let foo_module = resolve_module(&db, foo_module_name.clone()).unwrap(); let foo_module = resolve_module(&db, &foo_module_name).unwrap();
let bar_path = src.join("bar.py"); let bar_path = src.join("bar.py");
let bar = system_path_to_file(&db, &bar_path).expect("bar.py to exist"); let bar = system_path_to_file(&db, &bar_path).expect("bar.py to exist");
@ -1351,7 +1351,7 @@ mod tests {
// Re-query the foo module. The foo module should still be cached because `bar.py` isn't relevant // Re-query the foo module. The foo module should still be cached because `bar.py` isn't relevant
// for resolving `foo`. // for resolving `foo`.
let foo_module2 = resolve_module(&db, foo_module_name); let foo_module2 = resolve_module(&db, &foo_module_name);
assert!(!db assert!(!db
.take_salsa_events() .take_salsa_events()
@ -1368,14 +1368,14 @@ mod tests {
let foo_path = src.join("foo.py"); let foo_path = src.join("foo.py");
let foo_module_name = ModuleName::new_static("foo").unwrap(); let foo_module_name = ModuleName::new_static("foo").unwrap();
assert_eq!(resolve_module(&db, foo_module_name.clone()), None); assert_eq!(resolve_module(&db, &foo_module_name), None);
// Now write the foo file // Now write the foo file
db.write_file(&foo_path, "x = 1")?; db.write_file(&foo_path, "x = 1")?;
let foo_file = system_path_to_file(&db, &foo_path).expect("foo.py to exist"); let foo_file = system_path_to_file(&db, &foo_path).expect("foo.py to exist");
let foo_module = resolve_module(&db, foo_module_name).expect("Foo module to resolve"); let foo_module = resolve_module(&db, &foo_module_name).expect("Foo module to resolve");
assert_eq!(foo_file, foo_module.file()); assert_eq!(foo_file, foo_module.file());
Ok(()) Ok(())
@ -1389,7 +1389,7 @@ mod tests {
let TestCase { mut db, src, .. } = TestCaseBuilder::new().with_src_files(SRC).build(); let TestCase { mut db, src, .. } = TestCaseBuilder::new().with_src_files(SRC).build();
let foo_module_name = ModuleName::new_static("foo").unwrap(); let foo_module_name = ModuleName::new_static("foo").unwrap();
let foo_module = resolve_module(&db, foo_module_name.clone()).expect("foo module to exist"); let foo_module = resolve_module(&db, &foo_module_name).expect("foo module to exist");
let foo_init_path = src.join("foo/__init__.py"); let foo_init_path = src.join("foo/__init__.py");
assert_eq!(&foo_init_path, foo_module.file().path(&db)); assert_eq!(&foo_init_path, foo_module.file().path(&db));
@ -1401,7 +1401,7 @@ mod tests {
File::sync_path(&mut db, &foo_init_path); File::sync_path(&mut db, &foo_init_path);
File::sync_path(&mut db, foo_init_path.parent().unwrap()); File::sync_path(&mut db, foo_init_path.parent().unwrap());
let foo_module = resolve_module(&db, foo_module_name).expect("Foo module to resolve"); let foo_module = resolve_module(&db, &foo_module_name).expect("Foo module to resolve");
assert_eq!(&src.join("foo.py"), foo_module.file().path(&db)); assert_eq!(&src.join("foo.py"), foo_module.file().path(&db));
Ok(()) Ok(())
@ -1427,7 +1427,7 @@ mod tests {
let functools_module_name = ModuleName::new_static("functools").unwrap(); let functools_module_name = ModuleName::new_static("functools").unwrap();
let stdlib_functools_path = stdlib.join("functools.pyi"); let stdlib_functools_path = stdlib.join("functools.pyi");
let functools_module = resolve_module(&db, functools_module_name.clone()).unwrap(); let functools_module = resolve_module(&db, &functools_module_name).unwrap();
assert_eq!(functools_module.search_path(), &stdlib); assert_eq!(functools_module.search_path(), &stdlib);
assert_eq!( assert_eq!(
Ok(functools_module.file()), Ok(functools_module.file()),
@ -1440,7 +1440,7 @@ mod tests {
let site_packages_functools_path = site_packages.join("functools.py"); let site_packages_functools_path = site_packages.join("functools.py");
db.write_file(&site_packages_functools_path, "f: int") db.write_file(&site_packages_functools_path, "f: int")
.unwrap(); .unwrap();
let functools_module = resolve_module(&db, functools_module_name.clone()).unwrap(); let functools_module = resolve_module(&db, &functools_module_name).unwrap();
let events = db.take_salsa_events(); let events = db.take_salsa_events();
assert_function_query_was_not_run( assert_function_query_was_not_run(
&db, &db,
@ -1473,7 +1473,7 @@ mod tests {
.build(); .build();
let functools_module_name = ModuleName::new_static("functools").unwrap(); let functools_module_name = ModuleName::new_static("functools").unwrap();
let functools_module = resolve_module(&db, functools_module_name.clone()).unwrap(); let functools_module = resolve_module(&db, &functools_module_name).unwrap();
assert_eq!(functools_module.search_path(), &stdlib); assert_eq!(functools_module.search_path(), &stdlib);
assert_eq!( assert_eq!(
Ok(functools_module.file()), Ok(functools_module.file()),
@ -1484,7 +1484,7 @@ mod tests {
// since first-party files take higher priority in module resolution: // since first-party files take higher priority in module resolution:
let src_functools_path = src.join("functools.py"); let src_functools_path = src.join("functools.py");
db.write_file(&src_functools_path, "FOO: int").unwrap(); db.write_file(&src_functools_path, "FOO: int").unwrap();
let functools_module = resolve_module(&db, functools_module_name.clone()).unwrap(); let functools_module = resolve_module(&db, &functools_module_name).unwrap();
assert_eq!(functools_module.search_path(), &src); assert_eq!(functools_module.search_path(), &src);
assert_eq!( assert_eq!(
Ok(functools_module.file()), Ok(functools_module.file()),
@ -1515,7 +1515,7 @@ mod tests {
let functools_module_name = ModuleName::new_static("functools").unwrap(); let functools_module_name = ModuleName::new_static("functools").unwrap();
let src_functools_path = src.join("functools.py"); let src_functools_path = src.join("functools.py");
let functools_module = resolve_module(&db, functools_module_name.clone()).unwrap(); let functools_module = resolve_module(&db, &functools_module_name).unwrap();
assert_eq!(functools_module.search_path(), &src); assert_eq!(functools_module.search_path(), &src);
assert_eq!( assert_eq!(
Ok(functools_module.file()), Ok(functools_module.file()),
@ -1528,7 +1528,7 @@ mod tests {
.remove_file(&src_functools_path) .remove_file(&src_functools_path)
.unwrap(); .unwrap();
File::sync_path(&mut db, &src_functools_path); File::sync_path(&mut db, &src_functools_path);
let functools_module = resolve_module(&db, functools_module_name.clone()).unwrap(); let functools_module = resolve_module(&db, &functools_module_name).unwrap();
assert_eq!(functools_module.search_path(), &stdlib); assert_eq!(functools_module.search_path(), &stdlib);
assert_eq!( assert_eq!(
Ok(functools_module.file()), Ok(functools_module.file()),
@ -1550,8 +1550,8 @@ mod tests {
let foo_module_name = ModuleName::new_static("foo").unwrap(); let foo_module_name = ModuleName::new_static("foo").unwrap();
let foo_bar_module_name = ModuleName::new_static("foo.bar").unwrap(); let foo_bar_module_name = ModuleName::new_static("foo.bar").unwrap();
let foo_module = resolve_module(&db, foo_module_name.clone()).unwrap(); let foo_module = resolve_module(&db, &foo_module_name).unwrap();
let foo_bar_module = resolve_module(&db, foo_bar_module_name.clone()).unwrap(); let foo_bar_module = resolve_module(&db, &foo_bar_module_name).unwrap();
assert_eq!( assert_eq!(
foo_module.file().path(&db), foo_module.file().path(&db),
@ -1579,11 +1579,11 @@ mod tests {
// Lines with leading whitespace in `.pth` files do not parse: // Lines with leading whitespace in `.pth` files do not parse:
let foo_module_name = ModuleName::new_static("foo").unwrap(); let foo_module_name = ModuleName::new_static("foo").unwrap();
assert_eq!(resolve_module(&db, foo_module_name), None); assert_eq!(resolve_module(&db, &foo_module_name), None);
// Lines with trailing whitespace in `.pth` files do: // Lines with trailing whitespace in `.pth` files do:
let bar_module_name = ModuleName::new_static("bar").unwrap(); let bar_module_name = ModuleName::new_static("bar").unwrap();
let bar_module = resolve_module(&db, bar_module_name.clone()).unwrap(); let bar_module = resolve_module(&db, &bar_module_name).unwrap();
assert_eq!( assert_eq!(
bar_module.file().path(&db), bar_module.file().path(&db),
&FilePath::system("/y/src/bar.py") &FilePath::system("/y/src/bar.py")
@ -1602,7 +1602,7 @@ mod tests {
.build(); .build();
let foo_module_name = ModuleName::new_static("foo").unwrap(); let foo_module_name = ModuleName::new_static("foo").unwrap();
let foo_module = resolve_module(&db, foo_module_name.clone()).unwrap(); let foo_module = resolve_module(&db, &foo_module_name).unwrap();
assert_eq!( assert_eq!(
foo_module.file().path(&db), foo_module.file().path(&db),
@ -1650,10 +1650,10 @@ not_a_directory
let b_module_name = ModuleName::new_static("b").unwrap(); let b_module_name = ModuleName::new_static("b").unwrap();
let spam_module_name = ModuleName::new_static("spam").unwrap(); let spam_module_name = ModuleName::new_static("spam").unwrap();
let foo_module = resolve_module(&db, foo_module_name.clone()).unwrap(); let foo_module = resolve_module(&db, &foo_module_name).unwrap();
let a_module = resolve_module(&db, a_module_name.clone()).unwrap(); let a_module = resolve_module(&db, &a_module_name).unwrap();
let b_module = resolve_module(&db, b_module_name.clone()).unwrap(); let b_module = resolve_module(&db, &b_module_name).unwrap();
let spam_module = resolve_module(&db, spam_module_name.clone()).unwrap(); let spam_module = resolve_module(&db, &spam_module_name).unwrap();
assert_eq!( assert_eq!(
foo_module.file().path(&db), foo_module.file().path(&db),
@ -1681,14 +1681,14 @@ not_a_directory
let foo_module_name = ModuleName::new_static("foo").unwrap(); let foo_module_name = ModuleName::new_static("foo").unwrap();
let bar_module_name = ModuleName::new_static("bar").unwrap(); let bar_module_name = ModuleName::new_static("bar").unwrap();
let foo_module = resolve_module(&db, foo_module_name).unwrap(); let foo_module = resolve_module(&db, &foo_module_name).unwrap();
assert_eq!( assert_eq!(
foo_module.file().path(&db), foo_module.file().path(&db),
&FilePath::system("/x/src/foo.py") &FilePath::system("/x/src/foo.py")
); );
db.clear_salsa_events(); db.clear_salsa_events();
let bar_module = resolve_module(&db, bar_module_name).unwrap(); let bar_module = resolve_module(&db, &bar_module_name).unwrap();
assert_eq!( assert_eq!(
bar_module.file().path(&db), bar_module.file().path(&db),
&FilePath::system("/y/src/bar.py") &FilePath::system("/y/src/bar.py")
@ -1713,7 +1713,7 @@ not_a_directory
db.write_files(x_directory).unwrap(); db.write_files(x_directory).unwrap();
let foo_module_name = ModuleName::new_static("foo").unwrap(); let foo_module_name = ModuleName::new_static("foo").unwrap();
let foo_module = resolve_module(&db, foo_module_name.clone()).unwrap(); let foo_module = resolve_module(&db, &foo_module_name).unwrap();
assert_eq!( assert_eq!(
foo_module.file().path(&db), foo_module.file().path(&db),
&FilePath::system("/x/src/foo.py") &FilePath::system("/x/src/foo.py")
@ -1725,7 +1725,7 @@ not_a_directory
File::sync_path(&mut db, &site_packages.join("_foo.pth")); File::sync_path(&mut db, &site_packages.join("_foo.pth"));
assert_eq!(resolve_module(&db, foo_module_name.clone()), None); assert_eq!(resolve_module(&db, &foo_module_name), None);
} }
#[test] #[test]
@ -1740,7 +1740,7 @@ not_a_directory
db.write_files(x_directory).unwrap(); db.write_files(x_directory).unwrap();
let foo_module_name = ModuleName::new_static("foo").unwrap(); let foo_module_name = ModuleName::new_static("foo").unwrap();
let foo_module = resolve_module(&db, foo_module_name.clone()).unwrap(); let foo_module = resolve_module(&db, &foo_module_name).unwrap();
let src_path = SystemPathBuf::from("/x/src"); let src_path = SystemPathBuf::from("/x/src");
assert_eq!( assert_eq!(
foo_module.file().path(&db), foo_module.file().path(&db),
@ -1753,7 +1753,7 @@ not_a_directory
db.memory_file_system().remove_directory(&src_path).unwrap(); db.memory_file_system().remove_directory(&src_path).unwrap();
File::sync_path(&mut db, &src_path.join("foo.py")); File::sync_path(&mut db, &src_path.join("foo.py"));
File::sync_path(&mut db, &src_path); File::sync_path(&mut db, &src_path);
assert_eq!(resolve_module(&db, foo_module_name.clone()), None); assert_eq!(resolve_module(&db, &foo_module_name), None);
} }
#[test] #[test]
@ -1812,7 +1812,7 @@ not_a_directory
// The editable installs discovered from the `.pth` file in the first `site-packages` directory // The editable installs discovered from the `.pth` file in the first `site-packages` directory
// take precedence over the second `site-packages` directory... // take precedence over the second `site-packages` directory...
let a_module_name = ModuleName::new_static("a").unwrap(); let a_module_name = ModuleName::new_static("a").unwrap();
let a_module = resolve_module(&db, a_module_name.clone()).unwrap(); let a_module = resolve_module(&db, &a_module_name).unwrap();
assert_eq!(a_module.file().path(&db), &editable_install_location); assert_eq!(a_module.file().path(&db), &editable_install_location);
db.memory_file_system() db.memory_file_system()
@ -1823,7 +1823,7 @@ not_a_directory
// ...But now that the `.pth` file in the first `site-packages` directory has been deleted, // ...But now that the `.pth` file in the first `site-packages` directory has been deleted,
// the editable install no longer exists, so the module now resolves to the file in the // the editable install no longer exists, so the module now resolves to the file in the
// second `site-packages` directory // second `site-packages` directory
let a_module = resolve_module(&db, a_module_name).unwrap(); let a_module = resolve_module(&db, &a_module_name).unwrap();
assert_eq!(a_module.file().path(&db), &system_site_packages_location); assert_eq!(a_module.file().path(&db), &system_site_packages_location);
} }
} }

View file

@ -35,7 +35,7 @@ impl<'db> SemanticModel<'db> {
line_index(self.db.upcast(), self.file) line_index(self.db.upcast(), self.file)
} }
pub fn resolve_module(&self, module_name: ModuleName) -> Option<Module> { pub fn resolve_module(&self, module_name: &ModuleName) -> Option<Module> {
resolve_module(self.db, module_name) resolve_module(self.db, module_name)
} }

View file

@ -35,7 +35,7 @@ fn core_module_symbol_ty<'db>(
core_module: CoreStdlibModule, core_module: CoreStdlibModule,
symbol: &str, symbol: &str,
) -> Type<'db> { ) -> Type<'db> {
resolve_module(db, core_module.name()) resolve_module(db, &core_module.name())
.map(|module| global_symbol_ty(db, module.file(), symbol)) .map(|module| global_symbol_ty(db, module.file(), symbol))
.unwrap_or(Type::Unbound) .unwrap_or(Type::Unbound)
} }
@ -76,7 +76,7 @@ pub(crate) fn typing_extensions_symbol_ty<'db>(db: &'db dyn Db, symbol: &str) ->
/// ///
/// Can return `None` if a custom typeshed is used that is missing the core module in question. /// Can return `None` if a custom typeshed is used that is missing the core module in question.
fn core_module_scope(db: &dyn Db, core_module: CoreStdlibModule) -> Option<ScopeId<'_>> { fn core_module_scope(db: &dyn Db, core_module: CoreStdlibModule) -> Option<ScopeId<'_>> {
resolve_module(db, core_module.name()).map(|module| global_scope(db, module.file())) resolve_module(db, &core_module.name()).map(|module| global_scope(db, module.file()))
} }
/// Get the `builtins` module scope. /// Get the `builtins` module scope.

View file

@ -791,14 +791,10 @@ impl<'db> Type<'db> {
Type::IntLiteral(number) => Type::StringLiteral(StringLiteralType::new(db, { Type::IntLiteral(number) => Type::StringLiteral(StringLiteralType::new(db, {
number.to_string().into_boxed_str() number.to_string().into_boxed_str()
})), })),
Type::BooleanLiteral(true) => { Type::BooleanLiteral(true) => Type::StringLiteral(StringLiteralType::new(db, "True")),
Type::StringLiteral(StringLiteralType::new(db, "True".into())) Type::BooleanLiteral(false) => Type::StringLiteral(StringLiteralType::new(db, "False")),
}
Type::BooleanLiteral(false) => {
Type::StringLiteral(StringLiteralType::new(db, "False".into()))
}
Type::StringLiteral(literal) => Type::StringLiteral(StringLiteralType::new(db, { Type::StringLiteral(literal) => Type::StringLiteral(StringLiteralType::new(db, {
format!("'{}'", literal.value(db).escape_default()).into() format!("'{}'", literal.value(db).escape_default()).into_boxed_str()
})), })),
Type::LiteralString => Type::LiteralString, Type::LiteralString => Type::LiteralString,
// TODO: handle more complex types // TODO: handle more complex types
@ -1532,20 +1528,16 @@ mod tests {
Ty::Unknown => Type::Unknown, Ty::Unknown => Type::Unknown,
Ty::Any => Type::Any, Ty::Any => Type::Any,
Ty::IntLiteral(n) => Type::IntLiteral(n), Ty::IntLiteral(n) => Type::IntLiteral(n),
Ty::StringLiteral(s) => { Ty::StringLiteral(s) => Type::StringLiteral(StringLiteralType::new(db, s)),
Type::StringLiteral(StringLiteralType::new(db, (*s).into()))
}
Ty::BoolLiteral(b) => Type::BooleanLiteral(b), Ty::BoolLiteral(b) => Type::BooleanLiteral(b),
Ty::LiteralString => Type::LiteralString, Ty::LiteralString => Type::LiteralString,
Ty::BytesLiteral(s) => { Ty::BytesLiteral(s) => Type::BytesLiteral(BytesLiteralType::new(db, s.as_bytes())),
Type::BytesLiteral(BytesLiteralType::new(db, s.as_bytes().into()))
}
Ty::BuiltinInstance(s) => builtins_symbol_ty(db, s).to_instance(db), Ty::BuiltinInstance(s) => builtins_symbol_ty(db, s).to_instance(db),
Ty::Union(tys) => { Ty::Union(tys) => {
UnionType::from_elements(db, tys.into_iter().map(|ty| ty.into_type(db))) UnionType::from_elements(db, tys.into_iter().map(|ty| ty.into_type(db)))
} }
Ty::Tuple(tys) => { Ty::Tuple(tys) => {
let elements = tys.into_iter().map(|ty| ty.into_type(db)).collect(); let elements: Box<_> = tys.into_iter().map(|ty| ty.into_type(db)).collect();
Type::Tuple(TupleType::new(db, elements)) Type::Tuple(TupleType::new(db, elements))
} }
} }

View file

@ -111,7 +111,7 @@ impl<'db> UnionBuilder<'db> {
match self.elements.len() { match self.elements.len() {
0 => Type::Never, 0 => Type::Never,
1 => self.elements[0], 1 => self.elements[0],
_ => Type::Union(UnionType::new(self.db, self.elements.into())), _ => Type::Union(UnionType::new(self.db, self.elements.into_boxed_slice())),
} }
} }
} }

View file

@ -341,12 +341,12 @@ mod tests {
Type::Unknown, Type::Unknown,
Type::IntLiteral(-1), Type::IntLiteral(-1),
global_symbol_ty(&db, mod_file, "A"), global_symbol_ty(&db, mod_file, "A"),
Type::StringLiteral(StringLiteralType::new(&db, Box::from("A"))), Type::StringLiteral(StringLiteralType::new(&db, "A")),
Type::BytesLiteral(BytesLiteralType::new(&db, Box::from([0]))), Type::BytesLiteral(BytesLiteralType::new(&db, [0u8].as_slice())),
Type::BytesLiteral(BytesLiteralType::new(&db, Box::from([7]))), Type::BytesLiteral(BytesLiteralType::new(&db, [7u8].as_slice())),
Type::IntLiteral(0), Type::IntLiteral(0),
Type::IntLiteral(1), Type::IntLiteral(1),
Type::StringLiteral(StringLiteralType::new(&db, Box::from("B"))), Type::StringLiteral(StringLiteralType::new(&db, "B")),
global_symbol_ty(&db, mod_file, "foo"), global_symbol_ty(&db, mod_file, "foo"),
global_symbol_ty(&db, mod_file, "bar"), global_symbol_ty(&db, mod_file, "bar"),
global_symbol_ty(&db, mod_file, "B"), global_symbol_ty(&db, mod_file, "B"),

View file

@ -725,7 +725,7 @@ impl<'db> TypeInferenceBuilder<'db> {
decorator_list, decorator_list,
} = function; } = function;
let decorator_tys = decorator_list let decorator_tys: Box<[Type]> = decorator_list
.iter() .iter()
.map(|decorator| self.infer_decorator(decorator)) .map(|decorator| self.infer_decorator(decorator))
.collect(); .collect();
@ -1415,7 +1415,7 @@ impl<'db> TypeInferenceBuilder<'db> {
} = alias; } = alias;
let module_ty = if let Some(module_name) = ModuleName::new(name) { let module_ty = if let Some(module_name) = ModuleName::new(name) {
if let Some(module) = self.module_ty_from_name(module_name) { if let Some(module) = self.module_ty_from_name(&module_name) {
module module
} else { } else {
self.unresolved_module_diagnostic(alias, 0, Some(name)); self.unresolved_module_diagnostic(alias, 0, Some(name));
@ -1501,7 +1501,7 @@ impl<'db> TypeInferenceBuilder<'db> {
if module.kind().is_package() { if module.kind().is_package() {
level -= 1; level -= 1;
} }
let mut module_name = module.name().to_owned(); let mut module_name = module.name().clone();
for _ in 0..level { for _ in 0..level {
module_name = module_name module_name = module_name
.parent() .parent()
@ -1553,7 +1553,7 @@ impl<'db> TypeInferenceBuilder<'db> {
let module_ty = match module_name { let module_ty = match module_name {
Ok(name) => { Ok(name) => {
if let Some(ty) = self.module_ty_from_name(name) { if let Some(ty) = self.module_ty_from_name(&name) {
ty ty
} else { } else {
self.unresolved_module_diagnostic(import_from, *level, module); self.unresolved_module_diagnostic(import_from, *level, module);
@ -1626,7 +1626,7 @@ impl<'db> TypeInferenceBuilder<'db> {
} }
} }
fn module_ty_from_name(&self, module_name: ModuleName) -> Option<Type<'db>> { fn module_ty_from_name(&self, module_name: &ModuleName) -> Option<Type<'db>> {
resolve_module(self.db, module_name).map(|module| Type::Module(module.file())) resolve_module(self.db, module_name).map(|module| Type::Module(module.file()))
} }
@ -1740,10 +1740,7 @@ impl<'db> TypeInferenceBuilder<'db> {
fn infer_string_literal_expression(&mut self, literal: &ast::ExprStringLiteral) -> Type<'db> { fn infer_string_literal_expression(&mut self, literal: &ast::ExprStringLiteral) -> Type<'db> {
if literal.value.len() <= Self::MAX_STRING_LITERAL_SIZE { if literal.value.len() <= Self::MAX_STRING_LITERAL_SIZE {
Type::StringLiteral(StringLiteralType::new( Type::StringLiteral(StringLiteralType::new(self.db, literal.value.to_str()))
self.db,
literal.value.to_str().into(),
))
} else { } else {
Type::LiteralString Type::LiteralString
} }
@ -1753,7 +1750,7 @@ impl<'db> TypeInferenceBuilder<'db> {
// TODO: ignoring r/R prefixes for now, should normalize bytes values // TODO: ignoring r/R prefixes for now, should normalize bytes values
Type::BytesLiteral(BytesLiteralType::new( Type::BytesLiteral(BytesLiteralType::new(
self.db, self.db,
literal.value.bytes().collect(), literal.value.bytes().collect::<Box<[u8]>>(),
)) ))
} }
@ -2402,7 +2399,7 @@ impl<'db> TypeInferenceBuilder<'db> {
let rhs_value = rhs.value(self.db).as_ref(); let rhs_value = rhs.value(self.db).as_ref();
if lhs_value.len() + rhs_value.len() <= Self::MAX_STRING_LITERAL_SIZE { if lhs_value.len() + rhs_value.len() <= Self::MAX_STRING_LITERAL_SIZE {
Type::StringLiteral(StringLiteralType::new(self.db, { Type::StringLiteral(StringLiteralType::new(self.db, {
(lhs_value + rhs_value).into() (lhs_value + rhs_value).into_boxed_str()
})) }))
} else { } else {
Type::LiteralString Type::LiteralString
@ -2418,13 +2415,16 @@ impl<'db> TypeInferenceBuilder<'db> {
(Type::StringLiteral(s), Type::IntLiteral(n), ast::Operator::Mult) (Type::StringLiteral(s), Type::IntLiteral(n), ast::Operator::Mult)
| (Type::IntLiteral(n), Type::StringLiteral(s), ast::Operator::Mult) => { | (Type::IntLiteral(n), Type::StringLiteral(s), ast::Operator::Mult) => {
if n < 1 { if n < 1 {
Type::StringLiteral(StringLiteralType::new(self.db, Box::default())) Type::StringLiteral(StringLiteralType::new(self.db, ""))
} else if let Ok(n) = usize::try_from(n) { } else if let Ok(n) = usize::try_from(n) {
if n.checked_mul(s.value(self.db).len()) if n.checked_mul(s.value(self.db).len())
.is_some_and(|new_length| new_length <= Self::MAX_STRING_LITERAL_SIZE) .is_some_and(|new_length| new_length <= Self::MAX_STRING_LITERAL_SIZE)
{ {
let new_literal = s.value(self.db).repeat(n); let new_literal = s.value(self.db).repeat(n);
Type::StringLiteral(StringLiteralType::new(self.db, new_literal.into())) Type::StringLiteral(StringLiteralType::new(
self.db,
new_literal.into_boxed_str(),
))
} else { } else {
Type::LiteralString Type::LiteralString
} }
@ -2436,7 +2436,7 @@ impl<'db> TypeInferenceBuilder<'db> {
(Type::LiteralString, Type::IntLiteral(n), ast::Operator::Mult) (Type::LiteralString, Type::IntLiteral(n), ast::Operator::Mult)
| (Type::IntLiteral(n), Type::LiteralString, ast::Operator::Mult) => { | (Type::IntLiteral(n), Type::LiteralString, ast::Operator::Mult) => {
if n < 1 { if n < 1 {
Type::StringLiteral(StringLiteralType::new(self.db, Box::default())) Type::StringLiteral(StringLiteralType::new(self.db, ""))
} else { } else {
Type::LiteralString Type::LiteralString
} }

View file

@ -136,7 +136,7 @@ fn lint_bad_override(context: &SemanticLintContext, class: &ast::StmtClassDef) {
// TODO we should have a special marker on the real typing module (from typeshed) so if you // TODO we should have a special marker on the real typing module (from typeshed) so if you
// have your own "typing" module in your project, we don't consider it THE typing module (and // have your own "typing" module in your project, we don't consider it THE typing module (and
// same for other stdlib modules that our lint rules care about) // same for other stdlib modules that our lint rules care about)
let Some(typing) = semantic.resolve_module(ModuleName::new("typing").unwrap()) else { let Some(typing) = semantic.resolve_module(&ModuleName::new("typing").unwrap()) else {
return; return;
}; };

View file

@ -19,18 +19,18 @@ impl<'a> Resolver<'a> {
pub(crate) fn resolve(&self, import: CollectedImport) -> Option<&'a FilePath> { pub(crate) fn resolve(&self, import: CollectedImport) -> Option<&'a FilePath> {
match import { match import {
CollectedImport::Import(import) => { CollectedImport::Import(import) => {
resolve_module(self.db, import).map(|module| module.file().path(self.db)) resolve_module(self.db, &import).map(|module| module.file().path(self.db))
} }
CollectedImport::ImportFrom(import) => { CollectedImport::ImportFrom(import) => {
// Attempt to resolve the member (e.g., given `from foo import bar`, look for `foo.bar`). // Attempt to resolve the member (e.g., given `from foo import bar`, look for `foo.bar`).
let parent = import.parent(); let parent = import.parent();
resolve_module(self.db, import) resolve_module(self.db, &import)
.map(|module| module.file().path(self.db)) .map(|module| module.file().path(self.db))
.or_else(|| { .or_else(|| {
// Attempt to resolve the module (e.g., given `from foo import bar`, look for `foo`). // Attempt to resolve the module (e.g., given `from foo import bar`, look for `foo`).
resolve_module(self.db, parent?).map(|module| module.file().path(self.db)) resolve_module(self.db, &parent?).map(|module| module.file().path(self.db))
}) })
} }
} }