mirror of https://github.com/astral-sh/ruff
[red-knot] Upgrade to Salsa 3.0 (#11952)
This commit is contained in:
parent
c8ff89c73c
commit
927069c12f
|
|
@ -376,7 +376,7 @@ dependencies = [
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -617,7 +617,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"strsim 0.10.0",
|
"strsim 0.10.0",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -628,7 +628,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -699,7 +699,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1092,7 +1092,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1260,7 +1260,7 @@ dependencies = [
|
||||||
"Inflector",
|
"Inflector",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1386,7 +1386,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2ae40017ac09cd2c6a53504cb3c871c7f2b41466eac5bc66ba63f39073b467b"
|
checksum = "a2ae40017ac09cd2c6a53504cb3c871c7f2b41466eac5bc66ba63f39073b467b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2010,7 +2010,7 @@ dependencies = [
|
||||||
"ruff_python_stdlib",
|
"ruff_python_stdlib",
|
||||||
"ruff_text_size",
|
"ruff_text_size",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"salsa-2022",
|
"salsa",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"smol_str",
|
"smol_str",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
|
|
@ -2196,7 +2196,7 @@ dependencies = [
|
||||||
"ruff_source_file",
|
"ruff_source_file",
|
||||||
"ruff_text_size",
|
"ruff_text_size",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"salsa-2022",
|
"salsa",
|
||||||
"tracing",
|
"tracing",
|
||||||
"zip",
|
"zip",
|
||||||
]
|
]
|
||||||
|
|
@ -2345,7 +2345,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"ruff_python_trivia",
|
"ruff_python_trivia",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2719,9 +2719,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "salsa-2022"
|
name = "salsa"
|
||||||
version = "0.1.0"
|
version = "0.18.0"
|
||||||
source = "git+https://github.com/salsa-rs/salsa.git?rev=05b4e3ebdcdc47730cdd359e7e97fb2470527279#05b4e3ebdcdc47730cdd359e7e97fb2470527279"
|
source = "git+https://github.com/salsa-rs/salsa.git?rev=f706aa2d32d473ee633a77c1af01d180c85da308#f706aa2d32d473ee633a77c1af01d180c85da308"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"crossbeam",
|
"crossbeam",
|
||||||
|
|
@ -2732,20 +2732,21 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"salsa-2022-macros",
|
"salsa-macros",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "salsa-2022-macros"
|
name = "salsa-macros"
|
||||||
version = "0.1.0"
|
version = "0.18.0"
|
||||||
source = "git+https://github.com/salsa-rs/salsa.git?rev=05b4e3ebdcdc47730cdd359e7e97fb2470527279#05b4e3ebdcdc47730cdd359e7e97fb2470527279"
|
source = "git+https://github.com/salsa-rs/salsa.git?rev=f706aa2d32d473ee633a77c1af01d180c85da308#f706aa2d32d473ee633a77c1af01d180c85da308"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"eyre",
|
"eyre",
|
||||||
"heck 0.4.1",
|
"heck 0.4.1",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 1.0.109",
|
"syn",
|
||||||
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2778,7 +2779,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"serde_derive_internals",
|
"serde_derive_internals",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2827,7 +2828,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2838,7 +2839,7 @@ checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2860,7 +2861,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2901,7 +2902,7 @@ dependencies = [
|
||||||
"darling",
|
"darling",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3007,7 +3008,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3016,17 +3017,6 @@ version = "2.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "1.0.109"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.66"
|
version = "2.0.66"
|
||||||
|
|
@ -3046,7 +3036,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3102,7 +3092,7 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3113,7 +3103,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
"test-case-core",
|
"test-case-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -3134,7 +3124,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3256,7 +3246,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3492,7 +3482,7 @@ checksum = "9881bea7cbe687e36c9ab3b778c36cd0487402e270304e8b1296d5085303c1a2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3577,7 +3567,7 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -3611,7 +3601,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
@ -3644,7 +3634,7 @@ checksum = "b7f89739351a2e03cb94beb799d47fb2cac01759b40ec441f7de39b00cbf7ef0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3928,7 +3918,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -3949,7 +3939,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3969,7 +3959,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -3998,7 +3988,7 @@ checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.66",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ rand = { version = "0.8.5" }
|
||||||
rayon = { version = "1.10.0" }
|
rayon = { version = "1.10.0" }
|
||||||
regex = { version = "1.10.2" }
|
regex = { version = "1.10.2" }
|
||||||
rustc-hash = { version = "1.1.0" }
|
rustc-hash = { version = "1.1.0" }
|
||||||
salsa = { git = "https://github.com/salsa-rs/salsa.git", package = "salsa-2022", rev = "05b4e3ebdcdc47730cdd359e7e97fb2470527279" }
|
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "f706aa2d32d473ee633a77c1af01d180c85da308" }
|
||||||
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"] }
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ use crate::types::{infer_types, public_symbol_ty};
|
||||||
|
|
||||||
#[salsa::jar(db=Db)]
|
#[salsa::jar(db=Db)]
|
||||||
pub struct Jar(
|
pub struct Jar(
|
||||||
ModuleNameIngredient,
|
ModuleNameIngredient<'_>,
|
||||||
ModuleResolverSearchPaths,
|
ModuleResolverSearchPaths,
|
||||||
ScopeId,
|
ScopeId<'_>,
|
||||||
PublicSymbolId,
|
PublicSymbolId<'_>,
|
||||||
symbol_table,
|
symbol_table,
|
||||||
resolve_module_query,
|
resolve_module_query,
|
||||||
file_to_module,
|
file_to_module,
|
||||||
|
|
@ -37,9 +37,10 @@ pub(crate) mod tests {
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use salsa::id::AsId;
|
||||||
use salsa::ingredient::Ingredient;
|
use salsa::ingredient::Ingredient;
|
||||||
use salsa::storage::HasIngredientsFor;
|
use salsa::storage::HasIngredientsFor;
|
||||||
use salsa::{AsId, DebugWithDb};
|
use salsa::DebugWithDb;
|
||||||
|
|
||||||
use ruff_db::file_system::{FileSystem, MemoryFileSystem, OsFileSystem};
|
use ruff_db::file_system::{FileSystem, MemoryFileSystem, OsFileSystem};
|
||||||
use ruff_db::vfs::Vfs;
|
use ruff_db::vfs::Vfs;
|
||||||
|
|
@ -82,7 +83,6 @@ pub(crate) mod tests {
|
||||||
/// This useful for testing advanced file system features like permissions, symlinks, etc.
|
/// This useful for testing advanced file system features like permissions, symlinks, etc.
|
||||||
///
|
///
|
||||||
/// Note that any files written to the memory file system won't be copied over.
|
/// Note that any files written to the memory file system won't be copied over.
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) fn with_os_file_system(&mut self) {
|
pub(crate) fn with_os_file_system(&mut self) {
|
||||||
self.file_system = TestFileSystem::Os(OsFileSystem);
|
self.file_system = TestFileSystem::Os(OsFileSystem);
|
||||||
}
|
}
|
||||||
|
|
@ -157,44 +157,43 @@ pub(crate) mod tests {
|
||||||
|
|
||||||
enum TestFileSystem {
|
enum TestFileSystem {
|
||||||
Memory(MemoryFileSystem),
|
Memory(MemoryFileSystem),
|
||||||
#[allow(unused)]
|
|
||||||
Os(OsFileSystem),
|
Os(OsFileSystem),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn assert_will_run_function_query<C, Db, Jar>(
|
pub(crate) fn assert_will_run_function_query<'db, C, Db, Jar>(
|
||||||
db: &Db,
|
db: &'db Db,
|
||||||
to_function: impl FnOnce(&C) -> &salsa::function::FunctionIngredient<C>,
|
to_function: impl FnOnce(&C) -> &salsa::function::FunctionIngredient<C>,
|
||||||
key: C::Key,
|
input: &C::Input<'db>,
|
||||||
events: &[salsa::Event],
|
events: &[salsa::Event],
|
||||||
) where
|
) where
|
||||||
C: salsa::function::Configuration<Jar = Jar>
|
C: salsa::function::Configuration<Jar = Jar>
|
||||||
+ salsa::storage::IngredientsFor<Jar = Jar, Ingredients = C>,
|
+ salsa::storage::IngredientsFor<Jar = Jar, Ingredients = C>,
|
||||||
Jar: HasIngredientsFor<C>,
|
Jar: HasIngredientsFor<C>,
|
||||||
Db: salsa::DbWithJar<Jar>,
|
Db: salsa::DbWithJar<Jar>,
|
||||||
C::Key: AsId,
|
C::Input<'db>: AsId,
|
||||||
{
|
{
|
||||||
will_run_function_query(db, to_function, key, events, true);
|
will_run_function_query(db, to_function, input, events, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn assert_will_not_run_function_query<C, Db, Jar>(
|
pub(crate) fn assert_will_not_run_function_query<'db, C, Db, Jar>(
|
||||||
db: &Db,
|
db: &'db Db,
|
||||||
to_function: impl FnOnce(&C) -> &salsa::function::FunctionIngredient<C>,
|
to_function: impl FnOnce(&C) -> &salsa::function::FunctionIngredient<C>,
|
||||||
key: C::Key,
|
input: &C::Input<'db>,
|
||||||
events: &[salsa::Event],
|
events: &[salsa::Event],
|
||||||
) where
|
) where
|
||||||
C: salsa::function::Configuration<Jar = Jar>
|
C: salsa::function::Configuration<Jar = Jar>
|
||||||
+ salsa::storage::IngredientsFor<Jar = Jar, Ingredients = C>,
|
+ salsa::storage::IngredientsFor<Jar = Jar, Ingredients = C>,
|
||||||
Jar: HasIngredientsFor<C>,
|
Jar: HasIngredientsFor<C>,
|
||||||
Db: salsa::DbWithJar<Jar>,
|
Db: salsa::DbWithJar<Jar>,
|
||||||
C::Key: AsId,
|
C::Input<'db>: AsId,
|
||||||
{
|
{
|
||||||
will_run_function_query(db, to_function, key, events, false);
|
will_run_function_query(db, to_function, input, events, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn will_run_function_query<C, Db, Jar>(
|
fn will_run_function_query<'db, C, Db, Jar>(
|
||||||
db: &Db,
|
db: &'db Db,
|
||||||
to_function: impl FnOnce(&C) -> &salsa::function::FunctionIngredient<C>,
|
to_function: impl FnOnce(&C) -> &salsa::function::FunctionIngredient<C>,
|
||||||
key: C::Key,
|
input: &C::Input<'db>,
|
||||||
events: &[salsa::Event],
|
events: &[salsa::Event],
|
||||||
should_run: bool,
|
should_run: bool,
|
||||||
) where
|
) where
|
||||||
|
|
@ -202,7 +201,7 @@ pub(crate) mod tests {
|
||||||
+ salsa::storage::IngredientsFor<Jar = Jar, Ingredients = C>,
|
+ salsa::storage::IngredientsFor<Jar = Jar, Ingredients = C>,
|
||||||
Jar: HasIngredientsFor<C>,
|
Jar: HasIngredientsFor<C>,
|
||||||
Db: salsa::DbWithJar<Jar>,
|
Db: salsa::DbWithJar<Jar>,
|
||||||
C::Key: AsId,
|
C::Input<'db>: AsId,
|
||||||
{
|
{
|
||||||
let (jar, _) =
|
let (jar, _) =
|
||||||
<_ as salsa::storage::HasJar<<C as salsa::storage::IngredientsFor>::Jar>>::jar(db);
|
<_ as salsa::storage::HasJar<<C as salsa::storage::IngredientsFor>::Jar>>::jar(db);
|
||||||
|
|
@ -218,7 +217,7 @@ pub(crate) mod tests {
|
||||||
let did_run = events.iter().any(|event| {
|
let did_run = events.iter().any(|event| {
|
||||||
if let salsa::EventKind::WillExecute { database_key } = event.kind {
|
if let salsa::EventKind::WillExecute { database_key } = event.kind {
|
||||||
database_key.ingredient_index() == ingredient_index
|
database_key.ingredient_index() == ingredient_index
|
||||||
&& database_key.key_index() == key.as_id()
|
&& database_key.key_index() == input.as_id()
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
@ -229,7 +228,7 @@ pub(crate) mod tests {
|
||||||
"Expected query {:?} to run but it didn't",
|
"Expected query {:?} to run but it didn't",
|
||||||
DebugIdx {
|
DebugIdx {
|
||||||
db: PhantomData::<Db>,
|
db: PhantomData::<Db>,
|
||||||
value_id: key.as_id(),
|
value_id: input.as_id(),
|
||||||
ingredient: function_ingredient,
|
ingredient: function_ingredient,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -238,7 +237,7 @@ pub(crate) mod tests {
|
||||||
"Expected query {:?} not to run but it did",
|
"Expected query {:?} not to run but it did",
|
||||||
DebugIdx {
|
DebugIdx {
|
||||||
db: PhantomData::<Db>,
|
db: PhantomData::<Db>,
|
||||||
value_id: key.as_id(),
|
value_id: input.as_id(),
|
||||||
ingredient: function_ingredient,
|
ingredient: function_ingredient,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,9 @@ pub fn resolve_module(db: &dyn Db, module_name: ModuleName) -> Option<Module> {
|
||||||
/// This query should not be called directly. Instead, use [`resolve_module`]. It only exists
|
/// This query should not be called directly. Instead, use [`resolve_module`]. It only exists
|
||||||
/// because Salsa requires the module name to be an ingredient.
|
/// because Salsa requires the module name to be an ingredient.
|
||||||
#[salsa::tracked]
|
#[salsa::tracked]
|
||||||
pub(crate) fn resolve_module_query(
|
pub(crate) fn resolve_module_query<'db>(
|
||||||
db: &dyn Db,
|
db: &'db dyn Db,
|
||||||
module_name: internal::ModuleNameIngredient,
|
module_name: internal::ModuleNameIngredient<'db>,
|
||||||
) -> Option<Module> {
|
) -> Option<Module> {
|
||||||
let _ = tracing::trace_span!("resolve_module", module_name = ?module_name.debug(db)).enter();
|
let _ = tracing::trace_span!("resolve_module", module_name = ?module_name.debug(db)).enter();
|
||||||
|
|
||||||
|
|
@ -221,7 +221,7 @@ pub(crate) mod internal {
|
||||||
///
|
///
|
||||||
/// This is needed because Salsa requires that all query arguments are salsa ingredients.
|
/// This is needed because Salsa requires that all query arguments are salsa ingredients.
|
||||||
#[salsa::interned]
|
#[salsa::interned]
|
||||||
pub(crate) struct ModuleNameIngredient {
|
pub(crate) struct ModuleNameIngredient<'db> {
|
||||||
#[return_ref]
|
#[return_ref]
|
||||||
pub(super) name: ModuleName,
|
pub(super) name: ModuleName,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ pub(crate) fn semantic_index(db: &dyn Db, file: VfsFile) -> SemanticIndex {
|
||||||
/// Salsa can avoid invalidating dependent queries if this scope's symbol table
|
/// Salsa can avoid invalidating dependent queries if this scope's symbol table
|
||||||
/// is unchanged.
|
/// is unchanged.
|
||||||
#[salsa::tracked]
|
#[salsa::tracked]
|
||||||
pub(crate) fn symbol_table(db: &dyn Db, scope: ScopeId) -> Arc<SymbolTable> {
|
pub(crate) fn symbol_table<'db>(db: &'db dyn Db, scope: ScopeId<'db>) -> Arc<SymbolTable> {
|
||||||
let _ = tracing::trace_span!("symbol_table", scope = ?scope.debug(db)).enter();
|
let _ = tracing::trace_span!("symbol_table", scope = ?scope.debug(db)).enter();
|
||||||
let index = semantic_index(db, scope.file(db));
|
let index = semantic_index(db, scope.file(db));
|
||||||
|
|
||||||
|
|
@ -51,7 +51,7 @@ pub(crate) fn symbol_table(db: &dyn Db, scope: ScopeId) -> Arc<SymbolTable> {
|
||||||
|
|
||||||
/// Returns the root scope of `file`.
|
/// Returns the root scope of `file`.
|
||||||
#[salsa::tracked]
|
#[salsa::tracked]
|
||||||
pub(crate) fn root_scope(db: &dyn Db, file: VfsFile) -> ScopeId {
|
pub(crate) fn root_scope(db: &dyn Db, file: VfsFile) -> ScopeId<'_> {
|
||||||
let _ = tracing::trace_span!("root_scope", file = ?file.debug(db.upcast())).enter();
|
let _ = tracing::trace_span!("root_scope", file = ?file.debug(db.upcast())).enter();
|
||||||
|
|
||||||
FileScopeId::root().to_scope_id(db, file)
|
FileScopeId::root().to_scope_id(db, file)
|
||||||
|
|
@ -59,7 +59,11 @@ pub(crate) fn root_scope(db: &dyn Db, file: VfsFile) -> ScopeId {
|
||||||
|
|
||||||
/// Returns the symbol with the given name in `file`'s public scope or `None` if
|
/// Returns the symbol with the given name in `file`'s public scope or `None` if
|
||||||
/// no symbol with the given name exists.
|
/// no symbol with the given name exists.
|
||||||
pub fn public_symbol(db: &dyn Db, file: VfsFile, name: &str) -> Option<PublicSymbolId> {
|
pub fn public_symbol<'db>(
|
||||||
|
db: &'db dyn Db,
|
||||||
|
file: VfsFile,
|
||||||
|
name: &str,
|
||||||
|
) -> Option<PublicSymbolId<'db>> {
|
||||||
let root_scope = root_scope(db, file);
|
let root_scope = root_scope(db, file);
|
||||||
let symbol_table = symbol_table(db, root_scope);
|
let symbol_table = symbol_table(db, root_scope);
|
||||||
let local = symbol_table.symbol_id_by_name(name)?;
|
let local = symbol_table.symbol_id_by_name(name)?;
|
||||||
|
|
@ -104,7 +108,6 @@ impl SemanticIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the ID of the `expression`'s enclosing scope.
|
/// Returns the ID of the `expression`'s enclosing scope.
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) fn expression_scope_id(&self, expression: &ast::Expr) -> FileScopeId {
|
pub(crate) fn expression_scope_id(&self, expression: &ast::Expr) -> FileScopeId {
|
||||||
self.expression_scopes[&NodeKey::from_node(expression)]
|
self.expression_scopes[&NodeKey::from_node(expression)]
|
||||||
}
|
}
|
||||||
|
|
@ -116,7 +119,6 @@ impl SemanticIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`Scope`] with the given id.
|
/// Returns the [`Scope`] with the given id.
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) fn scope(&self, id: FileScopeId) -> &Scope {
|
pub(crate) fn scope(&self, id: FileScopeId) -> &Scope {
|
||||||
&self.scopes[id]
|
&self.scopes[id]
|
||||||
}
|
}
|
||||||
|
|
@ -140,13 +142,11 @@ impl SemanticIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over the direct child scopes of `scope`.
|
/// Returns an iterator over the direct child scopes of `scope`.
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) fn child_scopes(&self, scope: FileScopeId) -> ChildrenIter {
|
pub(crate) fn child_scopes(&self, scope: FileScopeId) -> ChildrenIter {
|
||||||
ChildrenIter::new(self, scope)
|
ChildrenIter::new(self, scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all ancestors of `scope`, starting with `scope` itself.
|
/// Returns an iterator over all ancestors of `scope`, starting with `scope` itself.
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) fn ancestor_scopes(&self, scope: FileScopeId) -> AncestorsIter {
|
pub(crate) fn ancestor_scopes(&self, scope: FileScopeId) -> AncestorsIter {
|
||||||
AncestorsIter::new(self, scope)
|
AncestorsIter::new(self, scope)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ impl std::fmt::Debug for AstIds {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ast_ids(db: &dyn Db, scope: ScopeId) -> &AstIds {
|
fn ast_ids<'db>(db: &'db dyn Db, scope: ScopeId) -> &'db AstIds {
|
||||||
semantic_index(db, scope.file(db)).ast_ids(scope.file_scope_id(db))
|
semantic_index(db, scope.file(db)).ast_ids(scope.file_scope_id(db))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,3 @@
|
||||||
// Allow unused underscore violations generated by the salsa macro
|
|
||||||
// TODO(micha): Contribute fix upstream
|
|
||||||
#![allow(clippy::used_underscore_binding)]
|
|
||||||
|
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
|
|
@ -78,7 +74,7 @@ bitflags! {
|
||||||
|
|
||||||
/// ID that uniquely identifies a public symbol defined in a module's root scope.
|
/// ID that uniquely identifies a public symbol defined in a module's root scope.
|
||||||
#[salsa::tracked]
|
#[salsa::tracked]
|
||||||
pub struct PublicSymbolId {
|
pub struct PublicSymbolId<'db> {
|
||||||
#[id]
|
#[id]
|
||||||
pub(crate) file: VfsFile,
|
pub(crate) file: VfsFile,
|
||||||
#[id]
|
#[id]
|
||||||
|
|
@ -132,7 +128,7 @@ impl ScopedSymbolId {
|
||||||
|
|
||||||
/// Returns a mapping from [`FileScopeId`] to globally unique [`ScopeId`].
|
/// Returns a mapping from [`FileScopeId`] to globally unique [`ScopeId`].
|
||||||
#[salsa::tracked(return_ref)]
|
#[salsa::tracked(return_ref)]
|
||||||
pub(crate) fn scopes_map(db: &dyn Db, file: VfsFile) -> ScopesMap {
|
pub(crate) fn scopes_map(db: &dyn Db, file: VfsFile) -> ScopesMap<'_> {
|
||||||
let _ = tracing::trace_span!("scopes_map", file = ?file.debug(db.upcast())).enter();
|
let _ = tracing::trace_span!("scopes_map", file = ?file.debug(db.upcast())).enter();
|
||||||
|
|
||||||
let index = semantic_index(db, file);
|
let index = semantic_index(db, file);
|
||||||
|
|
@ -152,19 +148,19 @@ pub(crate) fn scopes_map(db: &dyn Db, file: VfsFile) -> ScopesMap {
|
||||||
/// because they allow for more efficient storage of associated data
|
/// because they allow for more efficient storage of associated data
|
||||||
/// (use of an [`IndexVec`] keyed by [`FileScopeId`] over an [`FxHashMap`] keyed by [`ScopeId`]).
|
/// (use of an [`IndexVec`] keyed by [`FileScopeId`] over an [`FxHashMap`] keyed by [`ScopeId`]).
|
||||||
#[derive(Eq, PartialEq, Debug)]
|
#[derive(Eq, PartialEq, Debug)]
|
||||||
pub(crate) struct ScopesMap {
|
pub(crate) struct ScopesMap<'db> {
|
||||||
scopes: IndexVec<FileScopeId, ScopeId>,
|
scopes: IndexVec<FileScopeId, ScopeId<'db>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScopesMap {
|
impl<'db> ScopesMap<'db> {
|
||||||
/// Gets the program-wide unique scope id for the given file specific `scope_id`.
|
/// Gets the program-wide unique scope id for the given file specific `scope_id`.
|
||||||
fn get(&self, scope: FileScopeId) -> ScopeId {
|
fn get(&self, scope: FileScopeId) -> ScopeId<'db> {
|
||||||
self.scopes[scope]
|
self.scopes[scope]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[salsa::tracked(return_ref)]
|
#[salsa::tracked(return_ref)]
|
||||||
pub(crate) fn public_symbols_map(db: &dyn Db, file: VfsFile) -> PublicSymbolsMap {
|
pub(crate) fn public_symbols_map(db: &dyn Db, file: VfsFile) -> PublicSymbolsMap<'_> {
|
||||||
let _ = tracing::trace_span!("public_symbols_map", file = ?file.debug(db.upcast())).enter();
|
let _ = tracing::trace_span!("public_symbols_map", file = ?file.debug(db.upcast())).enter();
|
||||||
|
|
||||||
let module_scope = root_scope(db, file);
|
let module_scope = root_scope(db, file);
|
||||||
|
|
@ -182,20 +178,20 @@ pub(crate) fn public_symbols_map(db: &dyn Db, file: VfsFile) -> PublicSymbolsMap
|
||||||
|
|
||||||
/// Maps [`LocalSymbolId`] of a file's root scope to the corresponding [`PublicSymbolId`] (Salsa ingredients).
|
/// Maps [`LocalSymbolId`] of a file's root scope to the corresponding [`PublicSymbolId`] (Salsa ingredients).
|
||||||
#[derive(Eq, PartialEq, Debug)]
|
#[derive(Eq, PartialEq, Debug)]
|
||||||
pub(crate) struct PublicSymbolsMap {
|
pub(crate) struct PublicSymbolsMap<'db> {
|
||||||
symbols: IndexVec<ScopedSymbolId, PublicSymbolId>,
|
symbols: IndexVec<ScopedSymbolId, PublicSymbolId<'db>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PublicSymbolsMap {
|
impl<'db> PublicSymbolsMap<'db> {
|
||||||
/// Resolve the [`PublicSymbolId`] for the module-level `symbol_id`.
|
/// Resolve the [`PublicSymbolId`] for the module-level `symbol_id`.
|
||||||
fn public(&self, symbol_id: ScopedSymbolId) -> PublicSymbolId {
|
fn public(&self, symbol_id: ScopedSymbolId) -> PublicSymbolId<'db> {
|
||||||
self.symbols[symbol_id]
|
self.symbols[symbol_id]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A cross-module identifier of a scope that can be used as a salsa query parameter.
|
/// A cross-module identifier of a scope that can be used as a salsa query parameter.
|
||||||
#[salsa::tracked]
|
#[salsa::tracked]
|
||||||
pub struct ScopeId {
|
pub struct ScopeId<'db> {
|
||||||
#[allow(clippy::used_underscore_binding)]
|
#[allow(clippy::used_underscore_binding)]
|
||||||
#[id]
|
#[id]
|
||||||
pub file: VfsFile,
|
pub file: VfsFile,
|
||||||
|
|
@ -213,7 +209,7 @@ impl FileScopeId {
|
||||||
FileScopeId::from_u32(0)
|
FileScopeId::from_u32(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_scope_id(self, db: &dyn Db, file: VfsFile) -> ScopeId {
|
pub fn to_scope_id(self, db: &dyn Db, file: VfsFile) -> ScopeId<'_> {
|
||||||
scopes_map(db, file).get(self)
|
scopes_map(db, file).get(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -284,7 +280,6 @@ impl SymbolTable {
|
||||||
&self.symbols[symbol_id.into()]
|
&self.symbols[symbol_id.into()]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) fn symbol_ids(&self) -> impl Iterator<Item = ScopedSymbolId> {
|
pub(crate) fn symbol_ids(&self) -> impl Iterator<Item = ScopedSymbolId> {
|
||||||
self.symbols.indices()
|
self.symbols.indices()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,11 @@ mod infer;
|
||||||
///
|
///
|
||||||
/// Prefer [`public_symbol_ty`] when resolving the type of symbol from another file.
|
/// Prefer [`public_symbol_ty`] when resolving the type of symbol from another file.
|
||||||
#[tracing::instrument(level = "debug", skip(db))]
|
#[tracing::instrument(level = "debug", skip(db))]
|
||||||
pub(crate) fn expression_ty(db: &dyn Db, file: VfsFile, expression: &ast::Expr) -> Type {
|
pub(crate) fn expression_ty<'db>(
|
||||||
|
db: &'db dyn Db,
|
||||||
|
file: VfsFile,
|
||||||
|
expression: &ast::Expr,
|
||||||
|
) -> Type<'db> {
|
||||||
let index = semantic_index(db, file);
|
let index = semantic_index(db, file);
|
||||||
let file_scope = index.expression_scope_id(expression);
|
let file_scope = index.expression_scope_id(expression);
|
||||||
let expression_id = expression.scope_ast_id(db, file, file_scope);
|
let expression_id = expression.scope_ast_id(db, file, file_scope);
|
||||||
|
|
@ -61,7 +65,7 @@ pub(crate) fn expression_ty(db: &dyn Db, file: VfsFile, expression: &ast::Expr)
|
||||||
///
|
///
|
||||||
/// This being a query ensures that the invalidation short-circuits if the type of this symbol didn't change.
|
/// This being a query ensures that the invalidation short-circuits if the type of this symbol didn't change.
|
||||||
#[salsa::tracked]
|
#[salsa::tracked]
|
||||||
pub(crate) fn public_symbol_ty(db: &dyn Db, symbol: PublicSymbolId) -> Type {
|
pub(crate) fn public_symbol_ty<'db>(db: &'db dyn Db, symbol: PublicSymbolId<'db>) -> Type<'db> {
|
||||||
let _ = tracing::trace_span!("public_symbol_ty", symbol = ?symbol.debug(db)).enter();
|
let _ = tracing::trace_span!("public_symbol_ty", symbol = ?symbol.debug(db)).enter();
|
||||||
|
|
||||||
let file = symbol.file(db);
|
let file = symbol.file(db);
|
||||||
|
|
@ -72,14 +76,18 @@ pub(crate) fn public_symbol_ty(db: &dyn Db, symbol: PublicSymbolId) -> Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shorthand for `public_symbol_ty` that takes a symbol name instead of a [`PublicSymbolId`].
|
/// Shorthand for `public_symbol_ty` that takes a symbol name instead of a [`PublicSymbolId`].
|
||||||
pub fn public_symbol_ty_by_name(db: &dyn Db, file: VfsFile, name: &str) -> Option<Type> {
|
pub fn public_symbol_ty_by_name<'db>(
|
||||||
|
db: &'db dyn Db,
|
||||||
|
file: VfsFile,
|
||||||
|
name: &str,
|
||||||
|
) -> Option<Type<'db>> {
|
||||||
let symbol = public_symbol(db, file, name)?;
|
let symbol = public_symbol(db, file, name)?;
|
||||||
Some(public_symbol_ty(db, symbol))
|
Some(public_symbol_ty(db, symbol))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Infers all types for `scope`.
|
/// Infers all types for `scope`.
|
||||||
#[salsa::tracked(return_ref)]
|
#[salsa::tracked(return_ref)]
|
||||||
pub(crate) fn infer_types(db: &dyn Db, scope: ScopeId) -> TypeInference {
|
pub(crate) fn infer_types<'db>(db: &'db dyn Db, scope: ScopeId<'db>) -> TypeInference<'db> {
|
||||||
let _ = tracing::trace_span!("infer_types", scope = ?scope.debug(db)).enter();
|
let _ = tracing::trace_span!("infer_types", scope = ?scope.debug(db)).enter();
|
||||||
|
|
||||||
let file = scope.file(db);
|
let file = scope.file(db);
|
||||||
|
|
@ -120,7 +128,7 @@ pub(crate) fn infer_types(db: &dyn Db, scope: ScopeId) -> TypeInference {
|
||||||
|
|
||||||
/// unique ID for a type
|
/// unique ID for a type
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum Type {
|
pub enum Type<'db> {
|
||||||
/// the dynamic type: a statically-unknown set of values
|
/// the dynamic type: a statically-unknown set of values
|
||||||
Any,
|
Any,
|
||||||
/// the empty set of values
|
/// the empty set of values
|
||||||
|
|
@ -133,20 +141,20 @@ pub enum Type {
|
||||||
/// the None object (TODO remove this in favor of Instance(types.NoneType)
|
/// the None object (TODO remove this in favor of Instance(types.NoneType)
|
||||||
None,
|
None,
|
||||||
/// a specific function object
|
/// a specific function object
|
||||||
Function(TypeId<ScopedFunctionTypeId>),
|
Function(TypeId<'db, ScopedFunctionTypeId>),
|
||||||
/// a specific module object
|
/// a specific module object
|
||||||
Module(TypeId<ScopedModuleTypeId>),
|
Module(TypeId<'db, ScopedModuleTypeId>),
|
||||||
/// a specific class object
|
/// a specific class object
|
||||||
Class(TypeId<ScopedClassTypeId>),
|
Class(TypeId<'db, ScopedClassTypeId>),
|
||||||
/// the set of Python objects with the given class in their __class__'s method resolution order
|
/// the set of Python objects with the given class in their __class__'s method resolution order
|
||||||
Instance(TypeId<ScopedClassTypeId>),
|
Instance(TypeId<'db, ScopedClassTypeId>),
|
||||||
Union(TypeId<ScopedUnionTypeId>),
|
Union(TypeId<'db, ScopedUnionTypeId>),
|
||||||
Intersection(TypeId<ScopedIntersectionTypeId>),
|
Intersection(TypeId<'db, ScopedIntersectionTypeId>),
|
||||||
IntLiteral(i64),
|
IntLiteral(i64),
|
||||||
// TODO protocols, callable types, overloads, generics, type vars
|
// TODO protocols, callable types, overloads, generics, type vars
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Type {
|
impl<'db> Type<'db> {
|
||||||
pub const fn is_unbound(&self) -> bool {
|
pub const fn is_unbound(&self) -> bool {
|
||||||
matches!(self, Type::Unbound)
|
matches!(self, Type::Unbound)
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +163,7 @@ impl Type {
|
||||||
matches!(self, Type::Unknown)
|
matches!(self, Type::Unknown)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn member(&self, context: &TypingContext, name: &Name) -> Option<Type> {
|
pub fn member(&self, context: &TypingContext<'db, '_>, name: &Name) -> Option<Type<'db>> {
|
||||||
match self {
|
match self {
|
||||||
Type::Any => Some(Type::Any),
|
Type::Any => Some(Type::Any),
|
||||||
Type::Never => todo!("attribute lookup on Never type"),
|
Type::Never => todo!("attribute lookup on Never type"),
|
||||||
|
|
@ -191,18 +199,18 @@ impl Type {
|
||||||
|
|
||||||
/// ID that uniquely identifies a type in a program.
|
/// ID that uniquely identifies a type in a program.
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
pub struct TypeId<L> {
|
pub struct TypeId<'db, L> {
|
||||||
/// The scope in which this type is defined or was created.
|
/// The scope in which this type is defined or was created.
|
||||||
scope: ScopeId,
|
scope: ScopeId<'db>,
|
||||||
/// The type's local ID in its scope.
|
/// The type's local ID in its scope.
|
||||||
scoped: L,
|
scoped: L,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Id> TypeId<Id>
|
impl<'db, Id> TypeId<'db, Id>
|
||||||
where
|
where
|
||||||
Id: Copy,
|
Id: Copy,
|
||||||
{
|
{
|
||||||
pub fn scope(&self) -> ScopeId {
|
pub fn scope(&self) -> ScopeId<'db> {
|
||||||
self.scope
|
self.scope
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,7 +219,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolves the type ID to the actual type.
|
/// Resolves the type ID to the actual type.
|
||||||
pub(crate) fn lookup<'a>(self, context: &'a TypingContext) -> &'a Id::Ty
|
pub(crate) fn lookup<'a>(self, context: &'a TypingContext<'db, 'a>) -> &'a Id::Ty<'db>
|
||||||
where
|
where
|
||||||
Id: ScopedTypeId,
|
Id: ScopedTypeId,
|
||||||
{
|
{
|
||||||
|
|
@ -223,13 +231,13 @@ where
|
||||||
/// ID that uniquely identifies a type in a scope.
|
/// ID that uniquely identifies a type in a scope.
|
||||||
pub(crate) trait ScopedTypeId {
|
pub(crate) trait ScopedTypeId {
|
||||||
/// The type that this ID points to.
|
/// The type that this ID points to.
|
||||||
type Ty;
|
type Ty<'db>;
|
||||||
|
|
||||||
/// Looks up the type in `index`.
|
/// Looks up the type in `index`.
|
||||||
///
|
///
|
||||||
/// ## Panics
|
/// ## Panics
|
||||||
/// May panic if this type is from another scope than `index`, or might just return an invalid type.
|
/// May panic if this type is from another scope than `index`, or might just return an invalid type.
|
||||||
fn lookup_scoped(self, index: &TypeInference) -> &Self::Ty;
|
fn lookup_scoped<'a, 'db>(self, index: &'a TypeInference<'db>) -> &'a Self::Ty<'db>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ID uniquely identifying a function type in a `scope`.
|
/// ID uniquely identifying a function type in a `scope`.
|
||||||
|
|
@ -237,28 +245,28 @@ pub(crate) trait ScopedTypeId {
|
||||||
pub struct ScopedFunctionTypeId;
|
pub struct ScopedFunctionTypeId;
|
||||||
|
|
||||||
impl ScopedTypeId for ScopedFunctionTypeId {
|
impl ScopedTypeId for ScopedFunctionTypeId {
|
||||||
type Ty = FunctionType;
|
type Ty<'db> = FunctionType<'db>;
|
||||||
|
|
||||||
fn lookup_scoped(self, types: &TypeInference) -> &Self::Ty {
|
fn lookup_scoped<'a, 'db>(self, types: &'a TypeInference<'db>) -> &'a Self::Ty<'db> {
|
||||||
types.function_ty(self)
|
types.function_ty(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
pub struct FunctionType {
|
pub struct FunctionType<'a> {
|
||||||
/// name of the function at definition
|
/// name of the function at definition
|
||||||
name: Name,
|
name: Name,
|
||||||
/// types of all decorators on this function
|
/// types of all decorators on this function
|
||||||
decorators: Vec<Type>,
|
decorators: Vec<Type<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionType {
|
impl<'a> FunctionType<'a> {
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
self.name.as_str()
|
self.name.as_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub(crate) fn decorators(&self) -> &[Type] {
|
pub(crate) fn decorators(&self) -> &[Type<'a>] {
|
||||||
self.decorators.as_slice()
|
self.decorators.as_slice()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -267,18 +275,18 @@ impl FunctionType {
|
||||||
pub struct ScopedClassTypeId;
|
pub struct ScopedClassTypeId;
|
||||||
|
|
||||||
impl ScopedTypeId for ScopedClassTypeId {
|
impl ScopedTypeId for ScopedClassTypeId {
|
||||||
type Ty = ClassType;
|
type Ty<'db> = ClassType<'db>;
|
||||||
|
|
||||||
fn lookup_scoped(self, types: &TypeInference) -> &Self::Ty {
|
fn lookup_scoped<'a, 'db>(self, types: &'a TypeInference<'db>) -> &'a Self::Ty<'db> {
|
||||||
types.class_ty(self)
|
types.class_ty(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeId<ScopedClassTypeId> {
|
impl<'db> TypeId<'db, ScopedClassTypeId> {
|
||||||
/// Returns the class member of this class named `name`.
|
/// Returns the class member of this class named `name`.
|
||||||
///
|
///
|
||||||
/// The member resolves to a member of the class itself or any of its bases.
|
/// The member resolves to a member of the class itself or any of its bases.
|
||||||
fn class_member(self, context: &TypingContext, name: &Name) -> Option<Type> {
|
fn class_member(self, context: &TypingContext<'db, '_>, name: &Name) -> Option<Type<'db>> {
|
||||||
if let Some(member) = self.own_class_member(context, name) {
|
if let Some(member) = self.own_class_member(context, name) {
|
||||||
return Some(member);
|
return Some(member);
|
||||||
}
|
}
|
||||||
|
|
@ -294,7 +302,7 @@ impl TypeId<ScopedClassTypeId> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the inferred type of the class member named `name`.
|
/// Returns the inferred type of the class member named `name`.
|
||||||
fn own_class_member(self, context: &TypingContext, name: &Name) -> Option<Type> {
|
fn own_class_member(self, context: &TypingContext<'db, '_>, name: &Name) -> Option<Type<'db>> {
|
||||||
let class = self.lookup(context);
|
let class = self.lookup(context);
|
||||||
|
|
||||||
let symbols = symbol_table(context.db, class.body_scope);
|
let symbols = symbol_table(context.db, class.body_scope);
|
||||||
|
|
@ -306,23 +314,23 @@ impl TypeId<ScopedClassTypeId> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
pub struct ClassType {
|
pub struct ClassType<'db> {
|
||||||
/// Name of the class at definition
|
/// Name of the class at definition
|
||||||
name: Name,
|
name: Name,
|
||||||
|
|
||||||
/// Types of all class bases
|
/// Types of all class bases
|
||||||
bases: Vec<Type>,
|
bases: Vec<Type<'db>>,
|
||||||
|
|
||||||
body_scope: ScopeId,
|
body_scope: ScopeId<'db>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClassType {
|
impl<'db> ClassType<'db> {
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
self.name.as_str()
|
self.name.as_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub(super) fn bases(&self) -> &[Type] {
|
pub(super) fn bases(&self) -> &'db [Type] {
|
||||||
self.bases.as_slice()
|
self.bases.as_slice()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -331,26 +339,26 @@ impl ClassType {
|
||||||
pub struct ScopedUnionTypeId;
|
pub struct ScopedUnionTypeId;
|
||||||
|
|
||||||
impl ScopedTypeId for ScopedUnionTypeId {
|
impl ScopedTypeId for ScopedUnionTypeId {
|
||||||
type Ty = UnionType;
|
type Ty<'db> = UnionType<'db>;
|
||||||
|
|
||||||
fn lookup_scoped(self, types: &TypeInference) -> &Self::Ty {
|
fn lookup_scoped<'a, 'db>(self, types: &'a TypeInference<'db>) -> &'a Self::Ty<'db> {
|
||||||
types.union_ty(self)
|
types.union_ty(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
pub struct UnionType {
|
pub struct UnionType<'db> {
|
||||||
// the union type includes values in any of these types
|
// the union type includes values in any of these types
|
||||||
elements: FxIndexSet<Type>,
|
elements: FxIndexSet<Type<'db>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UnionTypeBuilder<'a> {
|
struct UnionTypeBuilder<'db, 'a> {
|
||||||
elements: FxIndexSet<Type>,
|
elements: FxIndexSet<Type<'db>>,
|
||||||
context: &'a TypingContext<'a>,
|
context: &'a TypingContext<'db, 'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> UnionTypeBuilder<'a> {
|
impl<'db, 'a> UnionTypeBuilder<'db, 'a> {
|
||||||
fn new(context: &'a TypingContext<'a>) -> Self {
|
fn new(context: &'a TypingContext<'db, 'a>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
context,
|
context,
|
||||||
elements: FxIndexSet::default(),
|
elements: FxIndexSet::default(),
|
||||||
|
|
@ -358,7 +366,7 @@ impl<'a> UnionTypeBuilder<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a type to this union.
|
/// Adds a type to this union.
|
||||||
fn add(mut self, ty: Type) -> Self {
|
fn add(mut self, ty: Type<'db>) -> Self {
|
||||||
match ty {
|
match ty {
|
||||||
Type::Union(union_id) => {
|
Type::Union(union_id) => {
|
||||||
let union = union_id.lookup(self.context);
|
let union = union_id.lookup(self.context);
|
||||||
|
|
@ -372,7 +380,7 @@ impl<'a> UnionTypeBuilder<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build(self) -> UnionType {
|
fn build(self) -> UnionType<'db> {
|
||||||
UnionType {
|
UnionType {
|
||||||
elements: self.elements,
|
elements: self.elements,
|
||||||
}
|
}
|
||||||
|
|
@ -383,9 +391,9 @@ impl<'a> UnionTypeBuilder<'a> {
|
||||||
pub struct ScopedIntersectionTypeId;
|
pub struct ScopedIntersectionTypeId;
|
||||||
|
|
||||||
impl ScopedTypeId for ScopedIntersectionTypeId {
|
impl ScopedTypeId for ScopedIntersectionTypeId {
|
||||||
type Ty = IntersectionType;
|
type Ty<'db> = IntersectionType<'db>;
|
||||||
|
|
||||||
fn lookup_scoped(self, types: &TypeInference) -> &Self::Ty {
|
fn lookup_scoped<'a, 'db>(self, types: &'a TypeInference<'db>) -> &'a Self::Ty<'db> {
|
||||||
types.intersection_ty(self)
|
types.intersection_ty(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -397,26 +405,26 @@ impl ScopedTypeId for ScopedIntersectionTypeId {
|
||||||
// have to represent it as a single-element intersection if it did) in exchange for better
|
// have to represent it as a single-element intersection if it did) in exchange for better
|
||||||
// efficiency in the within-intersection case.
|
// efficiency in the within-intersection case.
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub struct IntersectionType {
|
pub struct IntersectionType<'db> {
|
||||||
// the intersection type includes only values in all of these types
|
// the intersection type includes only values in all of these types
|
||||||
positive: FxIndexSet<Type>,
|
positive: FxIndexSet<Type<'db>>,
|
||||||
// the intersection type does not include any value in any of these types
|
// the intersection type does not include any value in any of these types
|
||||||
negative: FxIndexSet<Type>,
|
negative: FxIndexSet<Type<'db>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
pub struct ScopedModuleTypeId;
|
pub struct ScopedModuleTypeId;
|
||||||
|
|
||||||
impl ScopedTypeId for ScopedModuleTypeId {
|
impl ScopedTypeId for ScopedModuleTypeId {
|
||||||
type Ty = ModuleType;
|
type Ty<'db> = ModuleType;
|
||||||
|
|
||||||
fn lookup_scoped(self, types: &TypeInference) -> &Self::Ty {
|
fn lookup_scoped<'a, 'db>(self, types: &'a TypeInference<'db>) -> &'a Self::Ty<'db> {
|
||||||
types.module_ty()
|
types.module_ty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeId<ScopedModuleTypeId> {
|
impl<'db> TypeId<'db, ScopedModuleTypeId> {
|
||||||
fn member(self, context: &TypingContext, name: &Name) -> Option<Type> {
|
fn member(self, context: &TypingContext<'db, '_>, name: &Name) -> Option<Type<'db>> {
|
||||||
context.public_symbol_ty(self.scope.file(context.db), name)
|
context.public_symbol_ty(self.scope.file(context.db), name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -431,24 +439,28 @@ pub struct ModuleType {
|
||||||
/// This abstraction is necessary to support a uniform API that can be used
|
/// This abstraction is necessary to support a uniform API that can be used
|
||||||
/// while in the process of building the type inference structure for a scope
|
/// while in the process of building the type inference structure for a scope
|
||||||
/// but also when all types should be resolved by querying the db.
|
/// but also when all types should be resolved by querying the db.
|
||||||
pub struct TypingContext<'a> {
|
pub struct TypingContext<'db, 'inference> {
|
||||||
db: &'a dyn Db,
|
db: &'db dyn Db,
|
||||||
|
|
||||||
/// The Local type inference scope that is in the process of being built.
|
/// The Local type inference scope that is in the process of being built.
|
||||||
///
|
///
|
||||||
/// Bypass the `db` when resolving the types for this scope.
|
/// Bypass the `db` when resolving the types for this scope.
|
||||||
local: Option<(ScopeId, &'a TypeInference)>,
|
local: Option<(ScopeId<'db>, &'inference TypeInference<'db>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypingContext<'a> {
|
impl<'db, 'inference> TypingContext<'db, 'inference> {
|
||||||
/// Creates a context that resolves all types by querying the db.
|
/// Creates a context that resolves all types by querying the db.
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub(super) fn global(db: &'a dyn Db) -> Self {
|
pub(super) fn global(db: &'db dyn Db) -> Self {
|
||||||
Self { db, local: None }
|
Self { db, local: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a context that by-passes the `db` when resolving types from `scope_id` and instead uses `types`.
|
/// Creates a context that by-passes the `db` when resolving types from `scope_id` and instead uses `types`.
|
||||||
fn scoped(db: &'a dyn Db, scope_id: ScopeId, types: &'a TypeInference) -> Self {
|
fn scoped(
|
||||||
|
db: &'db dyn Db,
|
||||||
|
scope_id: ScopeId<'db>,
|
||||||
|
types: &'inference TypeInference<'db>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
db,
|
db,
|
||||||
local: Some((scope_id, types)),
|
local: Some((scope_id, types)),
|
||||||
|
|
@ -456,7 +468,7 @@ impl<'a> TypingContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`TypeInference`] results (not guaranteed to be complete) for `scope_id`.
|
/// Returns the [`TypeInference`] results (not guaranteed to be complete) for `scope_id`.
|
||||||
fn types(&self, scope_id: ScopeId) -> &'a TypeInference {
|
fn types(&self, scope_id: ScopeId<'db>) -> &'inference TypeInference<'db> {
|
||||||
if let Some((scope, local_types)) = self.local {
|
if let Some((scope, local_types)) = self.local {
|
||||||
if scope == scope_id {
|
if scope == scope_id {
|
||||||
return local_types;
|
return local_types;
|
||||||
|
|
@ -466,7 +478,7 @@ impl<'a> TypingContext<'a> {
|
||||||
infer_types(self.db, scope_id)
|
infer_types(self.db, scope_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn module_ty(&self, file: VfsFile) -> Type {
|
fn module_ty(&self, file: VfsFile) -> Type<'db> {
|
||||||
let scope = root_scope(self.db, file);
|
let scope = root_scope(self.db, file);
|
||||||
|
|
||||||
Type::Module(TypeId {
|
Type::Module(TypeId {
|
||||||
|
|
@ -479,7 +491,7 @@ impl<'a> TypingContext<'a> {
|
||||||
///
|
///
|
||||||
/// This function calls [`public_symbol_ty`] if the local scope isn't the module scope of `file`.
|
/// This function calls [`public_symbol_ty`] if the local scope isn't the module scope of `file`.
|
||||||
/// It otherwise tries to resolve the symbol type locally.
|
/// It otherwise tries to resolve the symbol type locally.
|
||||||
fn public_symbol_ty(&self, file: VfsFile, name: &Name) -> Option<Type> {
|
fn public_symbol_ty(&self, file: VfsFile, name: &Name) -> Option<Type<'db>> {
|
||||||
let symbol = public_symbol(self.db, file, name)?;
|
let symbol = public_symbol(self.db, file, name)?;
|
||||||
|
|
||||||
if let Some((scope, local_types)) = self.local {
|
if let Some((scope, local_types)) = self.local {
|
||||||
|
|
@ -581,7 +593,7 @@ mod tests {
|
||||||
assert_will_run_function_query::<infer_types, _, _>(
|
assert_will_run_function_query::<infer_types, _, _>(
|
||||||
&db,
|
&db,
|
||||||
|ty| &ty.function,
|
|ty| &ty.function,
|
||||||
a_root_scope,
|
&a_root_scope,
|
||||||
&events,
|
&events,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -629,7 +641,7 @@ mod tests {
|
||||||
assert_will_not_run_function_query::<infer_types, _, _>(
|
assert_will_not_run_function_query::<infer_types, _, _>(
|
||||||
&db,
|
&db,
|
||||||
|ty| &ty.function,
|
|ty| &ty.function,
|
||||||
a_root_scope,
|
&a_root_scope,
|
||||||
&events,
|
&events,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -676,7 +688,7 @@ mod tests {
|
||||||
assert_will_not_run_function_query::<infer_types, _, _>(
|
assert_will_not_run_function_query::<infer_types, _, _>(
|
||||||
&db,
|
&db,
|
||||||
|ty| &ty.function,
|
|ty| &ty.function,
|
||||||
a_root_scope,
|
&a_root_scope,
|
||||||
&events,
|
&events,
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
use crate::types::{IntersectionType, Type, TypingContext, UnionType};
|
use crate::types::{IntersectionType, Type, TypingContext, UnionType};
|
||||||
|
|
||||||
impl Type {
|
impl Type<'_> {
|
||||||
pub fn display<'a>(&'a self, context: &'a TypingContext) -> DisplayType<'a> {
|
pub fn display<'a>(&'a self, context: &'a TypingContext) -> DisplayType<'a> {
|
||||||
DisplayType { ty: self, context }
|
DisplayType { ty: self, context }
|
||||||
}
|
}
|
||||||
|
|
@ -12,8 +12,8 @@ impl Type {
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct DisplayType<'a> {
|
pub struct DisplayType<'a> {
|
||||||
ty: &'a Type,
|
ty: &'a Type<'a>,
|
||||||
context: &'a TypingContext<'a>,
|
context: &'a TypingContext<'a, 'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayType<'_> {
|
impl Display for DisplayType<'_> {
|
||||||
|
|
@ -71,15 +71,15 @@ impl std::fmt::Debug for DisplayType<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnionType {
|
impl UnionType<'_> {
|
||||||
fn display<'a>(&'a self, context: &'a TypingContext<'a>) -> DisplayUnionType<'a> {
|
fn display<'a>(&'a self, context: &'a TypingContext<'a, 'a>) -> DisplayUnionType<'a> {
|
||||||
DisplayUnionType { context, ty: self }
|
DisplayUnionType { context, ty: self }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DisplayUnionType<'a> {
|
struct DisplayUnionType<'a> {
|
||||||
ty: &'a UnionType,
|
ty: &'a UnionType<'a>,
|
||||||
context: &'a TypingContext<'a>,
|
context: &'a TypingContext<'a, 'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayUnionType<'_> {
|
impl Display for DisplayUnionType<'_> {
|
||||||
|
|
@ -134,15 +134,15 @@ impl std::fmt::Debug for DisplayUnionType<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntersectionType {
|
impl IntersectionType<'_> {
|
||||||
fn display<'a>(&'a self, context: &'a TypingContext<'a>) -> DisplayIntersectionType<'a> {
|
fn display<'a>(&'a self, context: &'a TypingContext<'a, 'a>) -> DisplayIntersectionType<'a> {
|
||||||
DisplayIntersectionType { ty: self, context }
|
DisplayIntersectionType { ty: self, context }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DisplayIntersectionType<'a> {
|
struct DisplayIntersectionType<'a> {
|
||||||
ty: &'a IntersectionType,
|
ty: &'a IntersectionType<'a>,
|
||||||
context: &'a TypingContext<'a>,
|
context: &'a TypingContext<'a, 'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DisplayIntersectionType<'_> {
|
impl Display for DisplayIntersectionType<'_> {
|
||||||
|
|
|
||||||
|
|
@ -23,33 +23,33 @@ use crate::Db;
|
||||||
|
|
||||||
/// The inferred types for a single scope.
|
/// The inferred types for a single scope.
|
||||||
#[derive(Debug, Eq, PartialEq, Default, Clone)]
|
#[derive(Debug, Eq, PartialEq, Default, Clone)]
|
||||||
pub(crate) struct TypeInference {
|
pub(crate) struct TypeInference<'db> {
|
||||||
/// The type of the module if the scope is a module scope.
|
/// The type of the module if the scope is a module scope.
|
||||||
module_type: Option<ModuleType>,
|
module_type: Option<ModuleType>,
|
||||||
|
|
||||||
/// The types of the defined classes in this scope.
|
/// The types of the defined classes in this scope.
|
||||||
class_types: IndexVec<ScopedClassTypeId, ClassType>,
|
class_types: IndexVec<ScopedClassTypeId, ClassType<'db>>,
|
||||||
|
|
||||||
/// The types of the defined functions in this scope.
|
/// The types of the defined functions in this scope.
|
||||||
function_types: IndexVec<ScopedFunctionTypeId, FunctionType>,
|
function_types: IndexVec<ScopedFunctionTypeId, FunctionType<'db>>,
|
||||||
|
|
||||||
union_types: IndexVec<ScopedUnionTypeId, UnionType>,
|
union_types: IndexVec<ScopedUnionTypeId, UnionType<'db>>,
|
||||||
intersection_types: IndexVec<ScopedIntersectionTypeId, IntersectionType>,
|
intersection_types: IndexVec<ScopedIntersectionTypeId, IntersectionType<'db>>,
|
||||||
|
|
||||||
/// The types of every expression in this scope.
|
/// The types of every expression in this scope.
|
||||||
expression_tys: IndexVec<ScopeExpressionId, Type>,
|
expression_tys: IndexVec<ScopeExpressionId, Type<'db>>,
|
||||||
|
|
||||||
/// The public types of every symbol in this scope.
|
/// The public types of every symbol in this scope.
|
||||||
symbol_tys: IndexVec<ScopedSymbolId, Type>,
|
symbol_tys: IndexVec<ScopedSymbolId, Type<'db>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeInference {
|
impl<'db> TypeInference<'db> {
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub(super) fn expression_ty(&self, expression: ScopeExpressionId) -> Type {
|
pub(super) fn expression_ty(&self, expression: ScopeExpressionId) -> Type<'db> {
|
||||||
self.expression_tys[expression]
|
self.expression_tys[expression]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn symbol_ty(&self, symbol: ScopedSymbolId) -> Type {
|
pub(super) fn symbol_ty(&self, symbol: ScopedSymbolId) -> Type<'db> {
|
||||||
self.symbol_tys[symbol]
|
self.symbol_tys[symbol]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,19 +57,19 @@ impl TypeInference {
|
||||||
self.module_type.as_ref().unwrap()
|
self.module_type.as_ref().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn class_ty(&self, id: ScopedClassTypeId) -> &ClassType {
|
pub(super) fn class_ty(&self, id: ScopedClassTypeId) -> &ClassType<'db> {
|
||||||
&self.class_types[id]
|
&self.class_types[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn function_ty(&self, id: ScopedFunctionTypeId) -> &FunctionType {
|
pub(super) fn function_ty(&self, id: ScopedFunctionTypeId) -> &FunctionType<'db> {
|
||||||
&self.function_types[id]
|
&self.function_types[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn union_ty(&self, id: ScopedUnionTypeId) -> &UnionType {
|
pub(super) fn union_ty(&self, id: ScopedUnionTypeId) -> &UnionType<'db> {
|
||||||
&self.union_types[id]
|
&self.union_types[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn intersection_ty(&self, id: ScopedIntersectionTypeId) -> &IntersectionType {
|
pub(super) fn intersection_ty(&self, id: ScopedIntersectionTypeId) -> &IntersectionType<'db> {
|
||||||
&self.intersection_types[id]
|
&self.intersection_types[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,20 +90,20 @@ pub(super) struct TypeInferenceBuilder<'a> {
|
||||||
|
|
||||||
// Cached lookups
|
// Cached lookups
|
||||||
index: &'a SemanticIndex,
|
index: &'a SemanticIndex,
|
||||||
scope: ScopeId,
|
scope: ScopeId<'a>,
|
||||||
file_scope_id: FileScopeId,
|
file_scope_id: FileScopeId,
|
||||||
file_id: VfsFile,
|
file_id: VfsFile,
|
||||||
symbol_table: Arc<SymbolTable>,
|
symbol_table: Arc<SymbolTable>,
|
||||||
|
|
||||||
/// The type inference results
|
/// The type inference results
|
||||||
types: TypeInference,
|
types: TypeInference<'a>,
|
||||||
definition_tys: FxHashMap<Definition, Type>,
|
definition_tys: FxHashMap<Definition, Type<'a>>,
|
||||||
children_scopes: ChildrenIter<'a>,
|
children_scopes: ChildrenIter<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypeInferenceBuilder<'a> {
|
impl<'db> TypeInferenceBuilder<'db> {
|
||||||
/// Creates a new builder for inferring the types of `scope`.
|
/// Creates a new builder for inferring the types of `scope`.
|
||||||
pub(super) fn new(db: &'a dyn Db, scope: ScopeId, index: &'a SemanticIndex) -> Self {
|
pub(super) fn new(db: &'db dyn Db, scope: ScopeId<'db>, index: &'db SemanticIndex) -> Self {
|
||||||
let file_scope_id = scope.file_scope_id(db);
|
let file_scope_id = scope.file_scope_id(db);
|
||||||
let file = scope.file(db);
|
let file = scope.file(db);
|
||||||
let children_scopes = index.child_scopes(file_scope_id);
|
let children_scopes = index.child_scopes(file_scope_id);
|
||||||
|
|
@ -410,7 +410,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_decorator(&mut self, decorator: &ast::Decorator) -> Type {
|
fn infer_decorator(&mut self, decorator: &ast::Decorator) -> Type<'db> {
|
||||||
let ast::Decorator {
|
let ast::Decorator {
|
||||||
range: _,
|
range: _,
|
||||||
expression,
|
expression,
|
||||||
|
|
@ -419,7 +419,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
||||||
self.infer_expression(expression)
|
self.infer_expression(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_arguments(&mut self, arguments: &ast::Arguments) -> Vec<Type> {
|
fn infer_arguments(&mut self, arguments: &ast::Arguments) -> Vec<Type<'db>> {
|
||||||
let mut types = Vec::with_capacity(
|
let mut types = Vec::with_capacity(
|
||||||
arguments
|
arguments
|
||||||
.args
|
.args
|
||||||
|
|
@ -440,7 +440,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
||||||
types
|
types
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_expression(&mut self, expression: &ast::Expr) -> Type {
|
fn infer_expression(&mut self, expression: &ast::Expr) -> Type<'db> {
|
||||||
let ty = match expression {
|
let ty = match expression {
|
||||||
ast::Expr::NoneLiteral(ast::ExprNoneLiteral { range: _ }) => Type::None,
|
ast::Expr::NoneLiteral(ast::ExprNoneLiteral { range: _ }) => Type::None,
|
||||||
ast::Expr::NumberLiteral(literal) => self.infer_number_literal_expression(literal),
|
ast::Expr::NumberLiteral(literal) => self.infer_number_literal_expression(literal),
|
||||||
|
|
@ -459,7 +459,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::unused_self)]
|
#[allow(clippy::unused_self)]
|
||||||
fn infer_number_literal_expression(&mut self, literal: &ast::ExprNumberLiteral) -> Type {
|
fn infer_number_literal_expression(&mut self, literal: &ast::ExprNumberLiteral) -> Type<'db> {
|
||||||
let ast::ExprNumberLiteral { range: _, value } = literal;
|
let ast::ExprNumberLiteral { range: _, value } = literal;
|
||||||
|
|
||||||
match value {
|
match value {
|
||||||
|
|
@ -472,7 +472,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_named_expression(&mut self, named: &ast::ExprNamed) -> Type {
|
fn infer_named_expression(&mut self, named: &ast::ExprNamed) -> Type<'db> {
|
||||||
let ast::ExprNamed {
|
let ast::ExprNamed {
|
||||||
range: _,
|
range: _,
|
||||||
target,
|
target,
|
||||||
|
|
@ -490,7 +490,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
||||||
value_ty
|
value_ty
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_if_expression(&mut self, if_expression: &ast::ExprIf) -> Type {
|
fn infer_if_expression(&mut self, if_expression: &ast::ExprIf) -> Type<'db> {
|
||||||
let ast::ExprIf {
|
let ast::ExprIf {
|
||||||
range: _,
|
range: _,
|
||||||
test,
|
test,
|
||||||
|
|
@ -512,7 +512,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
||||||
self.union_ty(union)
|
self.union_ty(union)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_name_expression(&mut self, name: &ast::ExprName) -> Type {
|
fn infer_name_expression(&mut self, name: &ast::ExprName) -> Type<'db> {
|
||||||
let ast::ExprName { range: _, id, ctx } = name;
|
let ast::ExprName { range: _, id, ctx } = name;
|
||||||
|
|
||||||
match ctx {
|
match ctx {
|
||||||
|
|
@ -546,7 +546,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_attribute_expression(&mut self, attribute: &ast::ExprAttribute) -> Type {
|
fn infer_attribute_expression(&mut self, attribute: &ast::ExprAttribute) -> Type<'db> {
|
||||||
let ast::ExprAttribute {
|
let ast::ExprAttribute {
|
||||||
value,
|
value,
|
||||||
attr,
|
attr,
|
||||||
|
|
@ -566,7 +566,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_binary_expression(&mut self, binary: &ast::ExprBinOp) -> Type {
|
fn infer_binary_expression(&mut self, binary: &ast::ExprBinOp) -> Type<'db> {
|
||||||
let ast::ExprBinOp {
|
let ast::ExprBinOp {
|
||||||
left,
|
left,
|
||||||
op,
|
op,
|
||||||
|
|
@ -623,7 +623,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
||||||
todo!("Infer type parameters")
|
todo!("Infer type parameters")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn finish(mut self) -> TypeInference {
|
pub(super) fn finish(mut self) -> TypeInference<'db> {
|
||||||
let symbol_tys: IndexVec<_, _> = self
|
let symbol_tys: IndexVec<_, _> = self
|
||||||
.index
|
.index
|
||||||
.symbol_table(self.file_scope_id)
|
.symbol_table(self.file_scope_id)
|
||||||
|
|
@ -636,32 +636,32 @@ impl<'a> TypeInferenceBuilder<'a> {
|
||||||
self.types
|
self.types
|
||||||
}
|
}
|
||||||
|
|
||||||
fn union_ty(&mut self, ty: UnionType) -> Type {
|
fn union_ty(&mut self, ty: UnionType<'db>) -> Type<'db> {
|
||||||
Type::Union(TypeId {
|
Type::Union(TypeId {
|
||||||
scope: self.scope,
|
scope: self.scope,
|
||||||
scoped: self.types.union_types.push(ty),
|
scoped: self.types.union_types.push(ty),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn function_ty(&mut self, ty: FunctionType) -> Type {
|
fn function_ty(&mut self, ty: FunctionType<'db>) -> Type<'db> {
|
||||||
Type::Function(TypeId {
|
Type::Function(TypeId {
|
||||||
scope: self.scope,
|
scope: self.scope,
|
||||||
scoped: self.types.function_types.push(ty),
|
scoped: self.types.function_types.push(ty),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn class_ty(&mut self, ty: ClassType) -> Type {
|
fn class_ty(&mut self, ty: ClassType<'db>) -> Type<'db> {
|
||||||
Type::Class(TypeId {
|
Type::Class(TypeId {
|
||||||
scope: self.scope,
|
scope: self.scope,
|
||||||
scoped: self.types.class_types.push(ty),
|
scoped: self.types.class_types.push(ty),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn typing_context(&self) -> TypingContext {
|
fn typing_context(&self) -> TypingContext<'db, '_> {
|
||||||
TypingContext::scoped(self.db, self.scope, &self.types)
|
TypingContext::scoped(self.db, self.scope, &self.types)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_definition_ty(&mut self, symbol: ScopedSymbolId) -> Type {
|
fn local_definition_ty(&mut self, symbol: ScopedSymbolId) -> Type<'db> {
|
||||||
let symbol = self.symbol_table.symbol(symbol);
|
let symbol = self.symbol_table.symbol(symbol);
|
||||||
let mut definitions = symbol
|
let mut definitions = symbol
|
||||||
.definitions()
|
.definitions()
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,6 @@ impl VfsFile {
|
||||||
/// an empty string, which is the closest to the content that the file contains now. Returning
|
/// an empty string, which is the closest to the content that the file contains now. Returning
|
||||||
/// an empty string shouldn't be a problem because the query will be re-executed as soon as the
|
/// an empty string shouldn't be a problem because the query will be re-executed as soon as the
|
||||||
/// changes are applied to the database.
|
/// changes are applied to the database.
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) fn read(&self, db: &dyn Db) -> String {
|
pub(crate) fn read(&self, db: &dyn Db) -> String {
|
||||||
let path = self.path(db);
|
let path = self.path(db);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue