[red-knot] Upgrade to Salsa 3.0 (#11952)

This commit is contained in:
Micha Reiser 2024-06-20 20:19:16 +01:00 committed by GitHub
parent c8ff89c73c
commit 927069c12f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 211 additions and 216 deletions

86
Cargo.lock generated
View File

@ -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]]

View File

@ -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"] }

View File

@ -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,
}
);

View File

@ -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,
}

View File

@ -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)
}

View File

@ -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))
}

View File

@ -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()
}

View File

@ -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(())

View File

@ -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<'_> {

View File

@ -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()

View File

@ -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);