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",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -617,7 +617,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim 0.10.0",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -628,7 +628,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
|
|||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -699,7 +699,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1092,7 +1092,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1260,7 +1260,7 @@ dependencies = [
|
|||
"Inflector",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1386,7 +1386,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "a2ae40017ac09cd2c6a53504cb3c871c7f2b41466eac5bc66ba63f39073b467b"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2010,7 +2010,7 @@ dependencies = [
|
|||
"ruff_python_stdlib",
|
||||
"ruff_text_size",
|
||||
"rustc-hash",
|
||||
"salsa-2022",
|
||||
"salsa",
|
||||
"smallvec",
|
||||
"smol_str",
|
||||
"tempfile",
|
||||
|
|
@ -2196,7 +2196,7 @@ dependencies = [
|
|||
"ruff_source_file",
|
||||
"ruff_text_size",
|
||||
"rustc-hash",
|
||||
"salsa-2022",
|
||||
"salsa",
|
||||
"tracing",
|
||||
"zip",
|
||||
]
|
||||
|
|
@ -2345,7 +2345,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"ruff_python_trivia",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2719,9 +2719,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||
|
||||
[[package]]
|
||||
name = "salsa-2022"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/salsa-rs/salsa.git?rev=05b4e3ebdcdc47730cdd359e7e97fb2470527279#05b4e3ebdcdc47730cdd359e7e97fb2470527279"
|
||||
name = "salsa"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/salsa-rs/salsa.git?rev=f706aa2d32d473ee633a77c1af01d180c85da308#f706aa2d32d473ee633a77c1af01d180c85da308"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"crossbeam",
|
||||
|
|
@ -2732,20 +2732,21 @@ dependencies = [
|
|||
"log",
|
||||
"parking_lot",
|
||||
"rustc-hash",
|
||||
"salsa-2022-macros",
|
||||
"salsa-macros",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "salsa-2022-macros"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/salsa-rs/salsa.git?rev=05b4e3ebdcdc47730cdd359e7e97fb2470527279#05b4e3ebdcdc47730cdd359e7e97fb2470527279"
|
||||
name = "salsa-macros"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/salsa-rs/salsa.git?rev=f706aa2d32d473ee633a77c1af01d180c85da308#f706aa2d32d473ee633a77c1af01d180c85da308"
|
||||
dependencies = [
|
||||
"eyre",
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2778,7 +2779,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_derive_internals",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2827,7 +2828,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2838,7 +2839,7 @@ checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2860,7 +2861,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2901,7 +2902,7 @@ dependencies = [
|
|||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3007,7 +3008,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3016,17 +3017,6 @@ version = "2.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "syn"
|
||||
version = "2.0.66"
|
||||
|
|
@ -3046,7 +3036,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3102,7 +3092,7 @@ dependencies = [
|
|||
"cfg-if",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3113,7 +3103,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
"test-case-core",
|
||||
]
|
||||
|
||||
|
|
@ -3134,7 +3124,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3256,7 +3246,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3492,7 +3482,7 @@ checksum = "9881bea7cbe687e36c9ab3b778c36cd0487402e270304e8b1296d5085303c1a2"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3577,7 +3567,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
|
@ -3611,7 +3601,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
|
@ -3644,7 +3634,7 @@ checksum = "b7f89739351a2e03cb94beb799d47fb2cac01759b40ec441f7de39b00cbf7ef0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3928,7 +3918,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -3949,7 +3939,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3969,7 +3959,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -3998,7 +3988,7 @@ checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ rand = { version = "0.8.5" }
|
|||
rayon = { version = "1.10.0" }
|
||||
regex = { version = "1.10.2" }
|
||||
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" }
|
||||
seahash = { version = "4.1.0" }
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ use crate::types::{infer_types, public_symbol_ty};
|
|||
|
||||
#[salsa::jar(db=Db)]
|
||||
pub struct Jar(
|
||||
ModuleNameIngredient,
|
||||
ModuleNameIngredient<'_>,
|
||||
ModuleResolverSearchPaths,
|
||||
ScopeId,
|
||||
PublicSymbolId,
|
||||
ScopeId<'_>,
|
||||
PublicSymbolId<'_>,
|
||||
symbol_table,
|
||||
resolve_module_query,
|
||||
file_to_module,
|
||||
|
|
@ -37,9 +37,10 @@ pub(crate) mod tests {
|
|||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
|
||||
use salsa::id::AsId;
|
||||
use salsa::ingredient::Ingredient;
|
||||
use salsa::storage::HasIngredientsFor;
|
||||
use salsa::{AsId, DebugWithDb};
|
||||
use salsa::DebugWithDb;
|
||||
|
||||
use ruff_db::file_system::{FileSystem, MemoryFileSystem, OsFileSystem};
|
||||
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.
|
||||
///
|
||||
/// 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) {
|
||||
self.file_system = TestFileSystem::Os(OsFileSystem);
|
||||
}
|
||||
|
|
@ -157,44 +157,43 @@ pub(crate) mod tests {
|
|||
|
||||
enum TestFileSystem {
|
||||
Memory(MemoryFileSystem),
|
||||
#[allow(unused)]
|
||||
Os(OsFileSystem),
|
||||
}
|
||||
|
||||
pub(crate) fn assert_will_run_function_query<C, Db, Jar>(
|
||||
db: &Db,
|
||||
pub(crate) fn assert_will_run_function_query<'db, C, Db, Jar>(
|
||||
db: &'db Db,
|
||||
to_function: impl FnOnce(&C) -> &salsa::function::FunctionIngredient<C>,
|
||||
key: C::Key,
|
||||
input: &C::Input<'db>,
|
||||
events: &[salsa::Event],
|
||||
) where
|
||||
C: salsa::function::Configuration<Jar = Jar>
|
||||
+ salsa::storage::IngredientsFor<Jar = Jar, Ingredients = C>,
|
||||
Jar: HasIngredientsFor<C>,
|
||||
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>(
|
||||
db: &Db,
|
||||
pub(crate) fn assert_will_not_run_function_query<'db, C, Db, Jar>(
|
||||
db: &'db Db,
|
||||
to_function: impl FnOnce(&C) -> &salsa::function::FunctionIngredient<C>,
|
||||
key: C::Key,
|
||||
input: &C::Input<'db>,
|
||||
events: &[salsa::Event],
|
||||
) where
|
||||
C: salsa::function::Configuration<Jar = Jar>
|
||||
+ salsa::storage::IngredientsFor<Jar = Jar, Ingredients = C>,
|
||||
Jar: HasIngredientsFor<C>,
|
||||
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>(
|
||||
db: &Db,
|
||||
fn will_run_function_query<'db, C, Db, Jar>(
|
||||
db: &'db Db,
|
||||
to_function: impl FnOnce(&C) -> &salsa::function::FunctionIngredient<C>,
|
||||
key: C::Key,
|
||||
input: &C::Input<'db>,
|
||||
events: &[salsa::Event],
|
||||
should_run: bool,
|
||||
) where
|
||||
|
|
@ -202,7 +201,7 @@ pub(crate) mod tests {
|
|||
+ salsa::storage::IngredientsFor<Jar = Jar, Ingredients = C>,
|
||||
Jar: HasIngredientsFor<C>,
|
||||
Db: salsa::DbWithJar<Jar>,
|
||||
C::Key: AsId,
|
||||
C::Input<'db>: AsId,
|
||||
{
|
||||
let (jar, _) =
|
||||
<_ 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| {
|
||||
if let salsa::EventKind::WillExecute { database_key } = event.kind {
|
||||
database_key.ingredient_index() == ingredient_index
|
||||
&& database_key.key_index() == key.as_id()
|
||||
&& database_key.key_index() == input.as_id()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
@ -229,7 +228,7 @@ pub(crate) mod tests {
|
|||
"Expected query {:?} to run but it didn't",
|
||||
DebugIdx {
|
||||
db: PhantomData::<Db>,
|
||||
value_id: key.as_id(),
|
||||
value_id: input.as_id(),
|
||||
ingredient: function_ingredient,
|
||||
}
|
||||
);
|
||||
|
|
@ -238,7 +237,7 @@ pub(crate) mod tests {
|
|||
"Expected query {:?} not to run but it did",
|
||||
DebugIdx {
|
||||
db: PhantomData::<Db>,
|
||||
value_id: key.as_id(),
|
||||
value_id: input.as_id(),
|
||||
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
|
||||
/// because Salsa requires the module name to be an ingredient.
|
||||
#[salsa::tracked]
|
||||
pub(crate) fn resolve_module_query(
|
||||
db: &dyn Db,
|
||||
module_name: internal::ModuleNameIngredient,
|
||||
pub(crate) fn resolve_module_query<'db>(
|
||||
db: &'db dyn Db,
|
||||
module_name: internal::ModuleNameIngredient<'db>,
|
||||
) -> Option<Module> {
|
||||
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.
|
||||
#[salsa::interned]
|
||||
pub(crate) struct ModuleNameIngredient {
|
||||
pub(crate) struct ModuleNameIngredient<'db> {
|
||||
#[return_ref]
|
||||
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
|
||||
/// is unchanged.
|
||||
#[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 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`.
|
||||
#[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();
|
||||
|
||||
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
|
||||
/// 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 symbol_table = symbol_table(db, root_scope);
|
||||
let local = symbol_table.symbol_id_by_name(name)?;
|
||||
|
|
@ -104,7 +108,6 @@ impl SemanticIndex {
|
|||
}
|
||||
|
||||
/// Returns the ID of the `expression`'s enclosing scope.
|
||||
#[allow(unused)]
|
||||
pub(crate) fn expression_scope_id(&self, expression: &ast::Expr) -> FileScopeId {
|
||||
self.expression_scopes[&NodeKey::from_node(expression)]
|
||||
}
|
||||
|
|
@ -116,7 +119,6 @@ impl SemanticIndex {
|
|||
}
|
||||
|
||||
/// Returns the [`Scope`] with the given id.
|
||||
#[allow(unused)]
|
||||
pub(crate) fn scope(&self, id: FileScopeId) -> &Scope {
|
||||
&self.scopes[id]
|
||||
}
|
||||
|
|
@ -140,13 +142,11 @@ impl SemanticIndex {
|
|||
}
|
||||
|
||||
/// Returns an iterator over the direct child scopes of `scope`.
|
||||
#[allow(unused)]
|
||||
pub(crate) fn child_scopes(&self, scope: FileScopeId) -> ChildrenIter {
|
||||
ChildrenIter::new(self, scope)
|
||||
}
|
||||
|
||||
/// Returns an iterator over all ancestors of `scope`, starting with `scope` itself.
|
||||
#[allow(unused)]
|
||||
pub(crate) fn ancestor_scopes(&self, scope: FileScopeId) -> AncestorsIter {
|
||||
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))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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::ops::Range;
|
||||
|
||||
|
|
@ -78,7 +74,7 @@ bitflags! {
|
|||
|
||||
/// ID that uniquely identifies a public symbol defined in a module's root scope.
|
||||
#[salsa::tracked]
|
||||
pub struct PublicSymbolId {
|
||||
pub struct PublicSymbolId<'db> {
|
||||
#[id]
|
||||
pub(crate) file: VfsFile,
|
||||
#[id]
|
||||
|
|
@ -132,7 +128,7 @@ impl ScopedSymbolId {
|
|||
|
||||
/// Returns a mapping from [`FileScopeId`] to globally unique [`ScopeId`].
|
||||
#[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 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
|
||||
/// (use of an [`IndexVec`] keyed by [`FileScopeId`] over an [`FxHashMap`] keyed by [`ScopeId`]).
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
pub(crate) struct ScopesMap {
|
||||
scopes: IndexVec<FileScopeId, ScopeId>,
|
||||
pub(crate) struct ScopesMap<'db> {
|
||||
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`.
|
||||
fn get(&self, scope: FileScopeId) -> ScopeId {
|
||||
fn get(&self, scope: FileScopeId) -> ScopeId<'db> {
|
||||
self.scopes[scope]
|
||||
}
|
||||
}
|
||||
|
||||
#[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 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).
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
pub(crate) struct PublicSymbolsMap {
|
||||
symbols: IndexVec<ScopedSymbolId, PublicSymbolId>,
|
||||
pub(crate) struct PublicSymbolsMap<'db> {
|
||||
symbols: IndexVec<ScopedSymbolId, PublicSymbolId<'db>>,
|
||||
}
|
||||
|
||||
impl PublicSymbolsMap {
|
||||
impl<'db> PublicSymbolsMap<'db> {
|
||||
/// 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]
|
||||
}
|
||||
}
|
||||
|
||||
/// A cross-module identifier of a scope that can be used as a salsa query parameter.
|
||||
#[salsa::tracked]
|
||||
pub struct ScopeId {
|
||||
pub struct ScopeId<'db> {
|
||||
#[allow(clippy::used_underscore_binding)]
|
||||
#[id]
|
||||
pub file: VfsFile,
|
||||
|
|
@ -213,7 +209,7 @@ impl FileScopeId {
|
|||
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)
|
||||
}
|
||||
}
|
||||
|
|
@ -284,7 +280,6 @@ impl SymbolTable {
|
|||
&self.symbols[symbol_id.into()]
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub(crate) fn symbol_ids(&self) -> impl Iterator<Item = ScopedSymbolId> {
|
||||
self.symbols.indices()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,11 @@ mod infer;
|
|||
///
|
||||
/// Prefer [`public_symbol_ty`] when resolving the type of symbol from another file.
|
||||
#[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 file_scope = index.expression_scope_id(expression);
|
||||
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.
|
||||
#[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 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`].
|
||||
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)?;
|
||||
Some(public_symbol_ty(db, symbol))
|
||||
}
|
||||
|
||||
/// Infers all types for `scope`.
|
||||
#[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 file = scope.file(db);
|
||||
|
|
@ -120,7 +128,7 @@ pub(crate) fn infer_types(db: &dyn Db, scope: ScopeId) -> TypeInference {
|
|||
|
||||
/// unique ID for a type
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum Type {
|
||||
pub enum Type<'db> {
|
||||
/// the dynamic type: a statically-unknown set of values
|
||||
Any,
|
||||
/// the empty set of values
|
||||
|
|
@ -133,20 +141,20 @@ pub enum Type {
|
|||
/// the None object (TODO remove this in favor of Instance(types.NoneType)
|
||||
None,
|
||||
/// a specific function object
|
||||
Function(TypeId<ScopedFunctionTypeId>),
|
||||
Function(TypeId<'db, ScopedFunctionTypeId>),
|
||||
/// a specific module object
|
||||
Module(TypeId<ScopedModuleTypeId>),
|
||||
Module(TypeId<'db, ScopedModuleTypeId>),
|
||||
/// 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
|
||||
Instance(TypeId<ScopedClassTypeId>),
|
||||
Union(TypeId<ScopedUnionTypeId>),
|
||||
Intersection(TypeId<ScopedIntersectionTypeId>),
|
||||
Instance(TypeId<'db, ScopedClassTypeId>),
|
||||
Union(TypeId<'db, ScopedUnionTypeId>),
|
||||
Intersection(TypeId<'db, ScopedIntersectionTypeId>),
|
||||
IntLiteral(i64),
|
||||
// TODO protocols, callable types, overloads, generics, type vars
|
||||
}
|
||||
|
||||
impl Type {
|
||||
impl<'db> Type<'db> {
|
||||
pub const fn is_unbound(&self) -> bool {
|
||||
matches!(self, Type::Unbound)
|
||||
}
|
||||
|
|
@ -155,7 +163,7 @@ impl Type {
|
|||
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 {
|
||||
Type::Any => Some(Type::Any),
|
||||
Type::Never => todo!("attribute lookup on Never type"),
|
||||
|
|
@ -191,18 +199,18 @@ impl Type {
|
|||
|
||||
/// ID that uniquely identifies a type in a program.
|
||||
#[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.
|
||||
scope: ScopeId,
|
||||
scope: ScopeId<'db>,
|
||||
/// The type's local ID in its scope.
|
||||
scoped: L,
|
||||
}
|
||||
|
||||
impl<Id> TypeId<Id>
|
||||
impl<'db, Id> TypeId<'db, Id>
|
||||
where
|
||||
Id: Copy,
|
||||
{
|
||||
pub fn scope(&self) -> ScopeId {
|
||||
pub fn scope(&self) -> ScopeId<'db> {
|
||||
self.scope
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +219,7 @@ where
|
|||
}
|
||||
|
||||
/// 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
|
||||
Id: ScopedTypeId,
|
||||
{
|
||||
|
|
@ -223,13 +231,13 @@ where
|
|||
/// ID that uniquely identifies a type in a scope.
|
||||
pub(crate) trait ScopedTypeId {
|
||||
/// The type that this ID points to.
|
||||
type Ty;
|
||||
type Ty<'db>;
|
||||
|
||||
/// Looks up the type in `index`.
|
||||
///
|
||||
/// ## Panics
|
||||
/// 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`.
|
||||
|
|
@ -237,28 +245,28 @@ pub(crate) trait ScopedTypeId {
|
|||
pub struct 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)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct FunctionType {
|
||||
pub struct FunctionType<'a> {
|
||||
/// name of the function at definition
|
||||
name: Name,
|
||||
/// types of all decorators on this function
|
||||
decorators: Vec<Type>,
|
||||
decorators: Vec<Type<'a>>,
|
||||
}
|
||||
|
||||
impl FunctionType {
|
||||
impl<'a> FunctionType<'a> {
|
||||
fn name(&self) -> &str {
|
||||
self.name.as_str()
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub(crate) fn decorators(&self) -> &[Type] {
|
||||
pub(crate) fn decorators(&self) -> &[Type<'a>] {
|
||||
self.decorators.as_slice()
|
||||
}
|
||||
}
|
||||
|
|
@ -267,18 +275,18 @@ impl FunctionType {
|
|||
pub struct 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)
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeId<ScopedClassTypeId> {
|
||||
impl<'db> TypeId<'db, ScopedClassTypeId> {
|
||||
/// Returns the class member of this class named `name`.
|
||||
///
|
||||
/// 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) {
|
||||
return Some(member);
|
||||
}
|
||||
|
|
@ -294,7 +302,7 @@ impl TypeId<ScopedClassTypeId> {
|
|||
}
|
||||
|
||||
/// 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 symbols = symbol_table(context.db, class.body_scope);
|
||||
|
|
@ -306,23 +314,23 @@ impl TypeId<ScopedClassTypeId> {
|
|||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct ClassType {
|
||||
pub struct ClassType<'db> {
|
||||
/// Name of the class at definition
|
||||
name: Name,
|
||||
|
||||
/// 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 {
|
||||
self.name.as_str()
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub(super) fn bases(&self) -> &[Type] {
|
||||
pub(super) fn bases(&self) -> &'db [Type] {
|
||||
self.bases.as_slice()
|
||||
}
|
||||
}
|
||||
|
|
@ -331,26 +339,26 @@ impl ClassType {
|
|||
pub struct 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)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct UnionType {
|
||||
pub struct UnionType<'db> {
|
||||
// the union type includes values in any of these types
|
||||
elements: FxIndexSet<Type>,
|
||||
elements: FxIndexSet<Type<'db>>,
|
||||
}
|
||||
|
||||
struct UnionTypeBuilder<'a> {
|
||||
elements: FxIndexSet<Type>,
|
||||
context: &'a TypingContext<'a>,
|
||||
struct UnionTypeBuilder<'db, 'a> {
|
||||
elements: FxIndexSet<Type<'db>>,
|
||||
context: &'a TypingContext<'db, 'a>,
|
||||
}
|
||||
|
||||
impl<'a> UnionTypeBuilder<'a> {
|
||||
fn new(context: &'a TypingContext<'a>) -> Self {
|
||||
impl<'db, 'a> UnionTypeBuilder<'db, 'a> {
|
||||
fn new(context: &'a TypingContext<'db, 'a>) -> Self {
|
||||
Self {
|
||||
context,
|
||||
elements: FxIndexSet::default(),
|
||||
|
|
@ -358,7 +366,7 @@ impl<'a> UnionTypeBuilder<'a> {
|
|||
}
|
||||
|
||||
/// Adds a type to this union.
|
||||
fn add(mut self, ty: Type) -> Self {
|
||||
fn add(mut self, ty: Type<'db>) -> Self {
|
||||
match ty {
|
||||
Type::Union(union_id) => {
|
||||
let union = union_id.lookup(self.context);
|
||||
|
|
@ -372,7 +380,7 @@ impl<'a> UnionTypeBuilder<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
fn build(self) -> UnionType {
|
||||
fn build(self) -> UnionType<'db> {
|
||||
UnionType {
|
||||
elements: self.elements,
|
||||
}
|
||||
|
|
@ -383,9 +391,9 @@ impl<'a> UnionTypeBuilder<'a> {
|
|||
pub struct 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)
|
||||
}
|
||||
}
|
||||
|
|
@ -397,26 +405,26 @@ impl ScopedTypeId for ScopedIntersectionTypeId {
|
|||
// have to represent it as a single-element intersection if it did) in exchange for better
|
||||
// efficiency in the within-intersection case.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct IntersectionType {
|
||||
pub struct IntersectionType<'db> {
|
||||
// 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
|
||||
negative: FxIndexSet<Type>,
|
||||
negative: FxIndexSet<Type<'db>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct 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()
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeId<ScopedModuleTypeId> {
|
||||
fn member(self, context: &TypingContext, name: &Name) -> Option<Type> {
|
||||
impl<'db> TypeId<'db, ScopedModuleTypeId> {
|
||||
fn member(self, context: &TypingContext<'db, '_>, name: &Name) -> Option<Type<'db>> {
|
||||
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
|
||||
/// 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.
|
||||
pub struct TypingContext<'a> {
|
||||
db: &'a dyn Db,
|
||||
pub struct TypingContext<'db, 'inference> {
|
||||
db: &'db dyn Db,
|
||||
|
||||
/// The Local type inference scope that is in the process of being built.
|
||||
///
|
||||
/// 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.
|
||||
#[allow(unused)]
|
||||
pub(super) fn global(db: &'a dyn Db) -> Self {
|
||||
pub(super) fn global(db: &'db dyn Db) -> Self {
|
||||
Self { db, local: None }
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
db,
|
||||
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`.
|
||||
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 scope == scope_id {
|
||||
return local_types;
|
||||
|
|
@ -466,7 +478,7 @@ impl<'a> TypingContext<'a> {
|
|||
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);
|
||||
|
||||
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`.
|
||||
/// 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)?;
|
||||
|
||||
if let Some((scope, local_types)) = self.local {
|
||||
|
|
@ -581,7 +593,7 @@ mod tests {
|
|||
assert_will_run_function_query::<infer_types, _, _>(
|
||||
&db,
|
||||
|ty| &ty.function,
|
||||
a_root_scope,
|
||||
&a_root_scope,
|
||||
&events,
|
||||
);
|
||||
|
||||
|
|
@ -629,7 +641,7 @@ mod tests {
|
|||
assert_will_not_run_function_query::<infer_types, _, _>(
|
||||
&db,
|
||||
|ty| &ty.function,
|
||||
a_root_scope,
|
||||
&a_root_scope,
|
||||
&events,
|
||||
);
|
||||
|
||||
|
|
@ -676,7 +688,7 @@ mod tests {
|
|||
assert_will_not_run_function_query::<infer_types, _, _>(
|
||||
&db,
|
||||
|ty| &ty.function,
|
||||
a_root_scope,
|
||||
&a_root_scope,
|
||||
&events,
|
||||
);
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use std::fmt::{Display, Formatter};
|
|||
|
||||
use crate::types::{IntersectionType, Type, TypingContext, UnionType};
|
||||
|
||||
impl Type {
|
||||
impl Type<'_> {
|
||||
pub fn display<'a>(&'a self, context: &'a TypingContext) -> DisplayType<'a> {
|
||||
DisplayType { ty: self, context }
|
||||
}
|
||||
|
|
@ -12,8 +12,8 @@ impl Type {
|
|||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct DisplayType<'a> {
|
||||
ty: &'a Type,
|
||||
context: &'a TypingContext<'a>,
|
||||
ty: &'a Type<'a>,
|
||||
context: &'a TypingContext<'a, 'a>,
|
||||
}
|
||||
|
||||
impl Display for DisplayType<'_> {
|
||||
|
|
@ -71,15 +71,15 @@ impl std::fmt::Debug for DisplayType<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
impl UnionType {
|
||||
fn display<'a>(&'a self, context: &'a TypingContext<'a>) -> DisplayUnionType<'a> {
|
||||
impl UnionType<'_> {
|
||||
fn display<'a>(&'a self, context: &'a TypingContext<'a, 'a>) -> DisplayUnionType<'a> {
|
||||
DisplayUnionType { context, ty: self }
|
||||
}
|
||||
}
|
||||
|
||||
struct DisplayUnionType<'a> {
|
||||
ty: &'a UnionType,
|
||||
context: &'a TypingContext<'a>,
|
||||
ty: &'a UnionType<'a>,
|
||||
context: &'a TypingContext<'a, 'a>,
|
||||
}
|
||||
|
||||
impl Display for DisplayUnionType<'_> {
|
||||
|
|
@ -134,15 +134,15 @@ impl std::fmt::Debug for DisplayUnionType<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntersectionType {
|
||||
fn display<'a>(&'a self, context: &'a TypingContext<'a>) -> DisplayIntersectionType<'a> {
|
||||
impl IntersectionType<'_> {
|
||||
fn display<'a>(&'a self, context: &'a TypingContext<'a, 'a>) -> DisplayIntersectionType<'a> {
|
||||
DisplayIntersectionType { ty: self, context }
|
||||
}
|
||||
}
|
||||
|
||||
struct DisplayIntersectionType<'a> {
|
||||
ty: &'a IntersectionType,
|
||||
context: &'a TypingContext<'a>,
|
||||
ty: &'a IntersectionType<'a>,
|
||||
context: &'a TypingContext<'a, 'a>,
|
||||
}
|
||||
|
||||
impl Display for DisplayIntersectionType<'_> {
|
||||
|
|
|
|||
|
|
@ -23,33 +23,33 @@ use crate::Db;
|
|||
|
||||
/// The inferred types for a single scope.
|
||||
#[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.
|
||||
module_type: Option<ModuleType>,
|
||||
|
||||
/// 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.
|
||||
function_types: IndexVec<ScopedFunctionTypeId, FunctionType>,
|
||||
function_types: IndexVec<ScopedFunctionTypeId, FunctionType<'db>>,
|
||||
|
||||
union_types: IndexVec<ScopedUnionTypeId, UnionType>,
|
||||
intersection_types: IndexVec<ScopedIntersectionTypeId, IntersectionType>,
|
||||
union_types: IndexVec<ScopedUnionTypeId, UnionType<'db>>,
|
||||
intersection_types: IndexVec<ScopedIntersectionTypeId, IntersectionType<'db>>,
|
||||
|
||||
/// 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.
|
||||
symbol_tys: IndexVec<ScopedSymbolId, Type>,
|
||||
symbol_tys: IndexVec<ScopedSymbolId, Type<'db>>,
|
||||
}
|
||||
|
||||
impl TypeInference {
|
||||
impl<'db> TypeInference<'db> {
|
||||
#[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]
|
||||
}
|
||||
|
||||
pub(super) fn symbol_ty(&self, symbol: ScopedSymbolId) -> Type {
|
||||
pub(super) fn symbol_ty(&self, symbol: ScopedSymbolId) -> Type<'db> {
|
||||
self.symbol_tys[symbol]
|
||||
}
|
||||
|
||||
|
|
@ -57,19 +57,19 @@ impl TypeInference {
|
|||
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]
|
||||
}
|
||||
|
||||
pub(super) fn function_ty(&self, id: ScopedFunctionTypeId) -> &FunctionType {
|
||||
pub(super) fn function_ty(&self, id: ScopedFunctionTypeId) -> &FunctionType<'db> {
|
||||
&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]
|
||||
}
|
||||
|
||||
pub(super) fn intersection_ty(&self, id: ScopedIntersectionTypeId) -> &IntersectionType {
|
||||
pub(super) fn intersection_ty(&self, id: ScopedIntersectionTypeId) -> &IntersectionType<'db> {
|
||||
&self.intersection_types[id]
|
||||
}
|
||||
|
||||
|
|
@ -90,20 +90,20 @@ pub(super) struct TypeInferenceBuilder<'a> {
|
|||
|
||||
// Cached lookups
|
||||
index: &'a SemanticIndex,
|
||||
scope: ScopeId,
|
||||
scope: ScopeId<'a>,
|
||||
file_scope_id: FileScopeId,
|
||||
file_id: VfsFile,
|
||||
symbol_table: Arc<SymbolTable>,
|
||||
|
||||
/// The type inference results
|
||||
types: TypeInference,
|
||||
definition_tys: FxHashMap<Definition, Type>,
|
||||
types: TypeInference<'a>,
|
||||
definition_tys: FxHashMap<Definition, Type<'a>>,
|
||||
children_scopes: ChildrenIter<'a>,
|
||||
}
|
||||
|
||||
impl<'a> TypeInferenceBuilder<'a> {
|
||||
impl<'db> TypeInferenceBuilder<'db> {
|
||||
/// 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.file(db);
|
||||
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 {
|
||||
range: _,
|
||||
expression,
|
||||
|
|
@ -419,7 +419,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
|||
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(
|
||||
arguments
|
||||
.args
|
||||
|
|
@ -440,7 +440,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
|||
types
|
||||
}
|
||||
|
||||
fn infer_expression(&mut self, expression: &ast::Expr) -> Type {
|
||||
fn infer_expression(&mut self, expression: &ast::Expr) -> Type<'db> {
|
||||
let ty = match expression {
|
||||
ast::Expr::NoneLiteral(ast::ExprNoneLiteral { range: _ }) => Type::None,
|
||||
ast::Expr::NumberLiteral(literal) => self.infer_number_literal_expression(literal),
|
||||
|
|
@ -459,7 +459,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
|||
}
|
||||
|
||||
#[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;
|
||||
|
||||
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 {
|
||||
range: _,
|
||||
target,
|
||||
|
|
@ -490,7 +490,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
|||
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 {
|
||||
range: _,
|
||||
test,
|
||||
|
|
@ -512,7 +512,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
|||
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;
|
||||
|
||||
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 {
|
||||
value,
|
||||
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 {
|
||||
left,
|
||||
op,
|
||||
|
|
@ -623,7 +623,7 @@ impl<'a> TypeInferenceBuilder<'a> {
|
|||
todo!("Infer type parameters")
|
||||
}
|
||||
|
||||
pub(super) fn finish(mut self) -> TypeInference {
|
||||
pub(super) fn finish(mut self) -> TypeInference<'db> {
|
||||
let symbol_tys: IndexVec<_, _> = self
|
||||
.index
|
||||
.symbol_table(self.file_scope_id)
|
||||
|
|
@ -636,32 +636,32 @@ impl<'a> TypeInferenceBuilder<'a> {
|
|||
self.types
|
||||
}
|
||||
|
||||
fn union_ty(&mut self, ty: UnionType) -> Type {
|
||||
fn union_ty(&mut self, ty: UnionType<'db>) -> Type<'db> {
|
||||
Type::Union(TypeId {
|
||||
scope: self.scope,
|
||||
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 {
|
||||
scope: self.scope,
|
||||
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 {
|
||||
scope: self.scope,
|
||||
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)
|
||||
}
|
||||
|
||||
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 mut definitions = symbol
|
||||
.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 shouldn't be a problem because the query will be re-executed as soon as the
|
||||
/// changes are applied to the database.
|
||||
#[allow(unused)]
|
||||
pub(crate) fn read(&self, db: &dyn Db) -> String {
|
||||
let path = self.path(db);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue