Skip to content

Commit 4541337

Browse files
authored
[red-knot] Remove <Db: SemanticDb> contraints in favor of dynamic dispatch (#11339)
1 parent 8e9ddee commit 4541337

File tree

11 files changed

+222
-332
lines changed

11 files changed

+222
-332
lines changed

crates/red_knot/src/db.rs

+34-83
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::path::Path;
21
use std::sync::Arc;
32

43
pub use jars::{HasJar, HasJars};
@@ -7,12 +6,12 @@ pub use runtime::DbRuntime;
76
pub use storage::JarsStorage;
87

98
use crate::files::FileId;
10-
use crate::lint::{Diagnostics, LintSemanticStorage, LintSyntaxStorage};
11-
use crate::module::{Module, ModuleData, ModuleName, ModuleResolver, ModuleSearchPath};
12-
use crate::parse::{Parsed, ParsedStorage};
13-
use crate::source::{Source, SourceStorage};
14-
use crate::symbols::{SymbolId, SymbolTable, SymbolTablesStorage};
15-
use crate::types::{Type, TypeStore};
9+
use crate::lint::{LintSemanticStorage, LintSyntaxStorage};
10+
use crate::module::ModuleResolver;
11+
use crate::parse::ParsedStorage;
12+
use crate::source::SourceStorage;
13+
use crate::symbols::SymbolTablesStorage;
14+
use crate::types::TypeStore;
1615

1716
mod jars;
1817
mod query;
@@ -61,6 +60,8 @@ pub trait ParallelDatabase: Database + Send {
6160
fn snapshot(&self) -> Snapshot<Self>;
6261
}
6362

63+
pub trait DbWithJar<Jar>: Database + HasJar<Jar> {}
64+
6465
/// Readonly snapshot of a database.
6566
///
6667
/// ## Dead locks
@@ -96,45 +97,24 @@ where
9697
}
9798
}
9899

100+
pub trait Upcast<T: ?Sized> {
101+
fn upcast(&self) -> &T;
102+
}
103+
99104
// Red knot specific databases code.
100105

101-
pub trait SourceDb: Database {
106+
pub trait SourceDb: DbWithJar<SourceJar> {
102107
// queries
103108
fn file_id(&self, path: &std::path::Path) -> FileId;
104109

105110
fn file_path(&self, file_id: FileId) -> Arc<std::path::Path>;
106-
107-
fn source(&self, file_id: FileId) -> QueryResult<Source>;
108-
109-
fn parse(&self, file_id: FileId) -> QueryResult<Parsed>;
110-
}
111-
112-
pub trait SemanticDb: SourceDb {
113-
// queries
114-
fn resolve_module(&self, name: ModuleName) -> QueryResult<Option<Module>>;
115-
116-
fn file_to_module(&self, file_id: FileId) -> QueryResult<Option<Module>>;
117-
118-
fn path_to_module(&self, path: &Path) -> QueryResult<Option<Module>>;
119-
120-
fn symbol_table(&self, file_id: FileId) -> QueryResult<Arc<SymbolTable>>;
121-
122-
fn infer_symbol_type(&self, file_id: FileId, symbol_id: SymbolId) -> QueryResult<Type>;
123-
124-
// mutations
125-
126-
fn add_module(&mut self, path: &Path) -> Option<(Module, Vec<Arc<ModuleData>>)>;
127-
128-
fn set_module_search_paths(&mut self, paths: Vec<ModuleSearchPath>);
129111
}
130112

131-
pub trait LintDb: SemanticDb {
132-
fn lint_syntax(&self, file_id: FileId) -> QueryResult<Diagnostics>;
113+
pub trait SemanticDb: SourceDb + DbWithJar<SemanticJar> + Upcast<dyn SourceDb> {}
133114

134-
fn lint_semantic(&self, file_id: FileId) -> QueryResult<Diagnostics>;
135-
}
115+
pub trait LintDb: SemanticDb + DbWithJar<LintJar> + Upcast<dyn SemanticDb> {}
136116

137-
pub trait Db: LintDb {}
117+
pub trait Db: LintDb + Upcast<dyn LintDb> {}
138118

139119
#[derive(Debug, Default)]
140120
pub struct SourceJar {
@@ -161,19 +141,10 @@ pub(crate) mod tests {
161141
use std::sync::Arc;
162142

163143
use crate::db::{
164-
Database, DbRuntime, HasJar, HasJars, JarsStorage, LintDb, LintJar, QueryResult, SourceDb,
165-
SourceJar,
144+
Database, DbRuntime, DbWithJar, HasJar, HasJars, JarsStorage, LintDb, LintJar, QueryResult,
145+
SourceDb, SourceJar, Upcast,
166146
};
167147
use crate::files::{FileId, Files};
168-
use crate::lint::{lint_semantic, lint_syntax, Diagnostics};
169-
use crate::module::{
170-
add_module, file_to_module, path_to_module, resolve_module, set_module_search_paths,
171-
Module, ModuleData, ModuleName, ModuleSearchPath,
172-
};
173-
use crate::parse::{parse, Parsed};
174-
use crate::source::{source_text, Source};
175-
use crate::symbols::{symbol_table, SymbolId, SymbolTable};
176-
use crate::types::{infer_symbol_type, Type};
177148

178149
use super::{SemanticDb, SemanticJar};
179150

@@ -223,56 +194,36 @@ pub(crate) mod tests {
223194
fn file_path(&self, file_id: FileId) -> Arc<Path> {
224195
self.files.path(file_id)
225196
}
226-
227-
fn source(&self, file_id: FileId) -> QueryResult<Source> {
228-
source_text(self, file_id)
229-
}
230-
231-
fn parse(&self, file_id: FileId) -> QueryResult<Parsed> {
232-
parse(self, file_id)
233-
}
234197
}
235198

236-
impl SemanticDb for TestDb {
237-
fn resolve_module(&self, name: ModuleName) -> QueryResult<Option<Module>> {
238-
resolve_module(self, name)
239-
}
240-
241-
fn file_to_module(&self, file_id: FileId) -> QueryResult<Option<Module>> {
242-
file_to_module(self, file_id)
243-
}
199+
impl DbWithJar<SourceJar> for TestDb {}
244200

245-
fn path_to_module(&self, path: &Path) -> QueryResult<Option<Module>> {
246-
path_to_module(self, path)
201+
impl Upcast<dyn SourceDb> for TestDb {
202+
fn upcast(&self) -> &(dyn SourceDb + 'static) {
203+
self
247204
}
205+
}
248206

249-
fn symbol_table(&self, file_id: FileId) -> QueryResult<Arc<SymbolTable>> {
250-
symbol_table(self, file_id)
251-
}
207+
impl SemanticDb for TestDb {}
252208

253-
fn infer_symbol_type(&self, file_id: FileId, symbol_id: SymbolId) -> QueryResult<Type> {
254-
infer_symbol_type(self, file_id, symbol_id)
255-
}
209+
impl DbWithJar<SemanticJar> for TestDb {}
256210

257-
fn add_module(&mut self, path: &Path) -> Option<(Module, Vec<Arc<ModuleData>>)> {
258-
add_module(self, path)
259-
}
260-
261-
fn set_module_search_paths(&mut self, paths: Vec<ModuleSearchPath>) {
262-
set_module_search_paths(self, paths);
211+
impl Upcast<dyn SemanticDb> for TestDb {
212+
fn upcast(&self) -> &(dyn SemanticDb + 'static) {
213+
self
263214
}
264215
}
265216

266-
impl LintDb for TestDb {
267-
fn lint_syntax(&self, file_id: FileId) -> QueryResult<Diagnostics> {
268-
lint_syntax(self, file_id)
269-
}
217+
impl LintDb for TestDb {}
270218

271-
fn lint_semantic(&self, file_id: FileId) -> QueryResult<Diagnostics> {
272-
lint_semantic(self, file_id)
219+
impl Upcast<dyn LintDb> for TestDb {
220+
fn upcast(&self) -> &(dyn LintDb + 'static) {
221+
self
273222
}
274223
}
275224

225+
impl DbWithJar<LintJar> for TestDb {}
226+
276227
impl HasJars for TestDb {
277228
type Jars = (SourceJar, SemanticJar, LintJar);
278229

crates/red_knot/src/lint.rs

+18-22
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,17 @@ use ruff_python_ast::visitor::Visitor;
77
use ruff_python_ast::{ModModule, StringLiteral};
88

99
use crate::cache::KeyValueCache;
10-
use crate::db::{HasJar, LintDb, LintJar, QueryResult, SemanticDb};
10+
use crate::db::{LintDb, LintJar, QueryResult};
1111
use crate::files::FileId;
12-
use crate::parse::Parsed;
13-
use crate::source::Source;
14-
use crate::symbols::{Definition, SymbolId, SymbolTable};
15-
use crate::types::Type;
12+
use crate::parse::{parse, Parsed};
13+
use crate::source::{source_text, Source};
14+
use crate::symbols::{symbol_table, Definition, SymbolId, SymbolTable};
15+
use crate::types::{infer_symbol_type, Type};
1616

1717
#[tracing::instrument(level = "debug", skip(db))]
18-
pub(crate) fn lint_syntax<Db>(db: &Db, file_id: FileId) -> QueryResult<Diagnostics>
19-
where
20-
Db: LintDb + HasJar<LintJar>,
21-
{
22-
let storage = &db.jar()?.lint_syntax;
18+
pub(crate) fn lint_syntax(db: &dyn LintDb, file_id: FileId) -> QueryResult<Diagnostics> {
19+
let lint_jar: &LintJar = db.jar()?;
20+
let storage = &lint_jar.lint_syntax;
2321

2422
#[allow(clippy::print_stdout)]
2523
if std::env::var("RED_KNOT_SLOW_LINT").is_ok() {
@@ -33,10 +31,10 @@ where
3331
storage.get(&file_id, |file_id| {
3432
let mut diagnostics = Vec::new();
3533

36-
let source = db.source(*file_id)?;
34+
let source = source_text(db.upcast(), *file_id)?;
3735
lint_lines(source.text(), &mut diagnostics);
3836

39-
let parsed = db.parse(*file_id)?;
37+
let parsed = parse(db.upcast(), *file_id)?;
4038

4139
if parsed.errors().is_empty() {
4240
let ast = parsed.ast();
@@ -73,16 +71,14 @@ fn lint_lines(source: &str, diagnostics: &mut Vec<String>) {
7371
}
7472

7573
#[tracing::instrument(level = "debug", skip(db))]
76-
pub(crate) fn lint_semantic<Db>(db: &Db, file_id: FileId) -> QueryResult<Diagnostics>
77-
where
78-
Db: LintDb + HasJar<LintJar>,
79-
{
80-
let storage = &db.jar()?.lint_semantic;
74+
pub(crate) fn lint_semantic(db: &dyn LintDb, file_id: FileId) -> QueryResult<Diagnostics> {
75+
let lint_jar: &LintJar = db.jar()?;
76+
let storage = &lint_jar.lint_semantic;
8177

8278
storage.get(&file_id, |file_id| {
83-
let source = db.source(*file_id)?;
84-
let parsed = db.parse(*file_id)?;
85-
let symbols = db.symbol_table(*file_id)?;
79+
let source = source_text(db.upcast(), *file_id)?;
80+
let parsed = parse(db.upcast(), *file_id)?;
81+
let symbols = symbol_table(db.upcast(), *file_id)?;
8682

8783
let context = SemanticLintContext {
8884
file_id: *file_id,
@@ -145,7 +141,7 @@ pub struct SemanticLintContext<'a> {
145141
source: Source,
146142
parsed: Parsed,
147143
symbols: Arc<SymbolTable>,
148-
db: &'a dyn SemanticDb,
144+
db: &'a dyn LintDb,
149145
diagnostics: RefCell<Vec<String>>,
150146
}
151147

@@ -167,7 +163,7 @@ impl<'a> SemanticLintContext<'a> {
167163
}
168164

169165
pub fn infer_symbol_type(&self, symbol_id: SymbolId) -> QueryResult<Type> {
170-
self.db.infer_symbol_type(self.file_id, symbol_id)
166+
infer_symbol_type(self.db.upcast(), self.file_id, symbol_id)
171167
}
172168

173169
pub fn push_diagnostic(&self, diagnostic: String) {

crates/red_knot/src/main.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use tracing_subscriber::layer::{Context, Filter, SubscriberExt};
1111
use tracing_subscriber::{Layer, Registry};
1212
use tracing_tree::time::Uptime;
1313

14-
use red_knot::db::{HasJar, ParallelDatabase, QueryError, SemanticDb, SourceDb, SourceJar};
15-
use red_knot::module::{ModuleSearchPath, ModuleSearchPathKind};
14+
use red_knot::db::{HasJar, ParallelDatabase, QueryError, SourceDb, SourceJar};
15+
use red_knot::module::{set_module_search_paths, ModuleSearchPath, ModuleSearchPathKind};
1616
use red_knot::program::check::ExecutionMode;
1717
use red_knot::program::{FileWatcherChange, Program};
1818
use red_knot::watch::FileWatcher;
@@ -49,7 +49,7 @@ fn main() -> anyhow::Result<()> {
4949
ModuleSearchPathKind::FirstParty,
5050
);
5151
let mut program = Program::new(workspace);
52-
program.set_module_search_paths(vec![workspace_search_path]);
52+
set_module_search_paths(&mut program, vec![workspace_search_path]);
5353

5454
let entry_id = program.file_id(entry_point);
5555
program.workspace_mut().open_file(entry_id);

0 commit comments

Comments
 (0)