Skip to content

Commit c853e01

Browse files
authored
Merge pull request #1079 from sbillig/def-conflict
conflict analysis rework
2 parents 7262289 + 33217b5 commit c853e01

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+2035
-2011
lines changed

Cargo.lock

+12-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ glob = "0.3.2"
2323
rustc-hash = "2.1.0"
2424
num-bigint = "0.4"
2525
paste = "1.0.15"
26-
salsa = { git = "https://github.com/salsa-rs/salsa", rev = "296a8c78da1b54c76ff5795eb4c1e3fe2467e9fc" }
26+
salsa = "0.20"
2727
smallvec = { version = "2.0.0-alpha.10" }
28+
smallvec1 = { version = "1", package = "smallvec" }
2829
semver = "1.0.24"
30+
thin-vec = "0.2.14"
2931
tracing = "0.1.41"
3032
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
3133
tracing-tree = "0.4.0"

crates/common/src/lib.rs

+1-15
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pub mod ingot;
55
pub mod input;
66
pub use input::{InputFile, InputIngot};
77

8-
#[derive(Embed)]
8+
#[derive(rust_embed::Embed)]
99
#[folder = "../../library/core"]
1010
pub(crate) struct Core;
1111

@@ -14,17 +14,3 @@ pub trait InputDb: salsa::Database {}
1414

1515
#[salsa::db]
1616
impl<T> InputDb for T where T: salsa::Database {}
17-
18-
#[doc(hidden)]
19-
pub use paste::paste;
20-
use rust_embed::Embed;
21-
22-
#[macro_export]
23-
macro_rules! impl_db_traits {
24-
($db_type:ty, $($trait_name:ident),+ $(,)?) => {
25-
#[salsa::db]
26-
impl salsa::Database for $db_type {
27-
fn salsa_event(&self, _event: &dyn Fn() -> salsa::Event) {}
28-
}
29-
};
30-
}

crates/driver/src/db.rs

+31-40
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ use hir::{
1111
use hir_analysis::{
1212
analysis_pass::{AnalysisPassManager, ParsingPass},
1313
diagnostics::DiagnosticVoucher,
14-
name_resolution::{DefConflictAnalysisPass, ImportAnalysisPass, PathAnalysisPass},
14+
name_resolution::ImportAnalysisPass,
1515
ty::{
16-
AdtDefAnalysisPass, BodyAnalysisPass, FuncAnalysisPass, ImplAnalysisPass,
17-
ImplTraitAnalysisPass, TraitAnalysisPass, TypeAliasAnalysisPass,
16+
AdtDefAnalysisPass, BodyAnalysisPass, DefConflictAnalysisPass, FuncAnalysisPass,
17+
ImplAnalysisPass, ImplTraitAnalysisPass, TraitAnalysisPass, TypeAliasAnalysisPass,
1818
},
1919
};
2020

@@ -33,50 +33,42 @@ impl salsa::Database for DriverDataBase {
3333
impl DriverDataBase {
3434
// TODO: An temporary implementation for ui testing.
3535
pub fn run_on_top_mod<'db>(&'db self, top_mod: TopLevelMod<'db>) -> DiagnosticsCollection<'db> {
36-
self.run_on_file_with_pass_manager(top_mod, initialize_analysis_pass)
36+
self.run_on_file_with_pass_manager(top_mod, initialize_analysis_pass())
3737
}
3838

39-
pub fn run_on_file_with_pass_manager<'db, F>(
39+
pub fn run_on_file_with_pass_manager<'db>(
4040
&'db self,
4141
top_mod: TopLevelMod<'db>,
42-
pm_builder: F,
43-
) -> DiagnosticsCollection<'db>
44-
where
45-
F: FnOnce(&'db DriverDataBase) -> AnalysisPassManager<'db>,
46-
{
47-
let mut pass_manager = pm_builder(self);
48-
DiagnosticsCollection(pass_manager.run_on_module(top_mod))
42+
mut pass_manager: AnalysisPassManager,
43+
) -> DiagnosticsCollection<'db> {
44+
DiagnosticsCollection(pass_manager.run_on_module(self, top_mod))
4945
}
5046

5147
pub fn run_on_ingot(&self, ingot: InputIngot) -> DiagnosticsCollection {
52-
self.run_on_ingot_with_pass_manager(ingot, initialize_analysis_pass)
48+
self.run_on_ingot_with_pass_manager(ingot, initialize_analysis_pass())
5349
}
5450

55-
pub fn run_on_ingot_with_pass_manager<'db, F>(
56-
&'db self,
51+
pub fn run_on_ingot_with_pass_manager(
52+
&self,
5753
ingot: InputIngot,
58-
pm_builder: F,
59-
) -> DiagnosticsCollection<'db>
60-
where
61-
F: FnOnce(&'db DriverDataBase) -> AnalysisPassManager<'db>,
62-
{
54+
mut pass_manager: AnalysisPassManager,
55+
) -> DiagnosticsCollection {
6356
let tree = module_tree(self, ingot);
64-
let mut pass_manager = pm_builder(self);
65-
DiagnosticsCollection(pass_manager.run_on_module_tree(tree))
57+
DiagnosticsCollection(pass_manager.run_on_module_tree(self, tree))
6658
}
6759

6860
pub fn top_mod(&self, ingot: InputIngot, input: InputFile) -> TopLevelMod {
6961
map_file_to_mod(self, ingot, input)
7062
}
7163
}
7264

73-
pub struct DiagnosticsCollection<'db>(Vec<Box<dyn DiagnosticVoucher<'db> + 'db>>);
74-
impl<'db> DiagnosticsCollection<'db> {
65+
pub struct DiagnosticsCollection<'db>(Vec<Box<dyn DiagnosticVoucher + 'db>>);
66+
impl DiagnosticsCollection<'_> {
7567
pub fn is_empty(&self) -> bool {
7668
self.0.is_empty()
7769
}
7870

79-
pub fn emit(&self, db: &'db DriverDataBase) {
71+
pub fn emit(&self, db: &DriverDataBase) {
8072
let writer = BufferWriter::stderr(ColorChoice::Auto);
8173
let mut buffer = writer.buffer();
8274
let config = term::Config::default();
@@ -89,7 +81,7 @@ impl<'db> DiagnosticsCollection<'db> {
8981
}
9082

9183
/// Format the accumulated diagnostics to a string.
92-
pub fn format_diags(&self, db: &'db DriverDataBase) -> String {
84+
pub fn format_diags(&self, db: &DriverDataBase) -> String {
9385
let writer = BufferWriter::stderr(ColorChoice::Never);
9486
let mut buffer = writer.buffer();
9587
let config = term::Config::default();
@@ -101,8 +93,8 @@ impl<'db> DiagnosticsCollection<'db> {
10193
std::str::from_utf8(buffer.as_slice()).unwrap().to_string()
10294
}
10395

104-
fn finalize(&self, db: &'db DriverDataBase) -> Vec<CompleteDiagnostic> {
105-
let mut diags: Vec<_> = self.0.iter().map(|d| d.to_complete(db)).collect();
96+
fn finalize(&self, db: &DriverDataBase) -> Vec<CompleteDiagnostic> {
97+
let mut diags: Vec<_> = self.0.iter().map(|d| d.as_ref().to_complete(db)).collect();
10698
diags.sort_by(|lhs, rhs| match lhs.error_code.cmp(&rhs.error_code) {
10799
std::cmp::Ordering::Equal => lhs.primary_span().cmp(&rhs.primary_span()),
108100
ord => ord,
@@ -111,18 +103,17 @@ impl<'db> DiagnosticsCollection<'db> {
111103
}
112104
}
113105

114-
fn initialize_analysis_pass(db: &DriverDataBase) -> AnalysisPassManager<'_> {
106+
fn initialize_analysis_pass() -> AnalysisPassManager {
115107
let mut pass_manager = AnalysisPassManager::new();
116-
pass_manager.add_module_pass(Box::new(ParsingPass::new(db)));
117-
pass_manager.add_module_pass(Box::new(DefConflictAnalysisPass::new(db)));
118-
pass_manager.add_module_pass(Box::new(ImportAnalysisPass::new(db)));
119-
pass_manager.add_module_pass(Box::new(PathAnalysisPass::new(db)));
120-
pass_manager.add_module_pass(Box::new(AdtDefAnalysisPass::new(db)));
121-
pass_manager.add_module_pass(Box::new(TypeAliasAnalysisPass::new(db)));
122-
pass_manager.add_module_pass(Box::new(TraitAnalysisPass::new(db)));
123-
pass_manager.add_module_pass(Box::new(ImplAnalysisPass::new(db)));
124-
pass_manager.add_module_pass(Box::new(ImplTraitAnalysisPass::new(db)));
125-
pass_manager.add_module_pass(Box::new(FuncAnalysisPass::new(db)));
126-
pass_manager.add_module_pass(Box::new(BodyAnalysisPass::new(db)));
108+
pass_manager.add_module_pass(Box::new(ParsingPass {}));
109+
pass_manager.add_module_pass(Box::new(DefConflictAnalysisPass {}));
110+
pass_manager.add_module_pass(Box::new(ImportAnalysisPass {}));
111+
pass_manager.add_module_pass(Box::new(AdtDefAnalysisPass {}));
112+
pass_manager.add_module_pass(Box::new(TypeAliasAnalysisPass {}));
113+
pass_manager.add_module_pass(Box::new(TraitAnalysisPass {}));
114+
pass_manager.add_module_pass(Box::new(ImplAnalysisPass {}));
115+
pass_manager.add_module_pass(Box::new(ImplTraitAnalysisPass {}));
116+
pass_manager.add_module_pass(Box::new(FuncAnalysisPass {}));
117+
pass_manager.add_module_pass(Box::new(BodyAnalysisPass {}));
127118
pass_manager
128119
}

crates/driver/src/diagnostics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ impl<T> SpannedInputDb for T where T: SpannedHirAnalysisDb + InputDb {}
1818

1919
impl<T> ToCsDiag for T
2020
where
21-
T: for<'db> DiagnosticVoucher<'db>,
21+
T: DiagnosticVoucher,
2222
{
2323
fn to_cs(&self, db: &dyn SpannedInputDb) -> cs_diag::Diagnostic<InputFile> {
2424
let complete = self.to_complete(db);

crates/hir-analysis/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ num-bigint.workspace = true
1818
rustc-hash.workspace = true
1919
salsa.workspace = true
2020
smallvec.workspace = true
21+
smallvec1.workspace = true
22+
thin-vec.workspace = true
2123

2224
common.workspace = true
2325
test-utils.workspace = true
+25-29
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,73 @@
1-
use crate::diagnostics::DiagnosticVoucher;
1+
use crate::{diagnostics::DiagnosticVoucher, HirAnalysisDb};
22
use hir::{
33
hir_def::{ModuleTree, TopLevelMod},
44
lower::parse_file_impl,
5-
HirDb, ParseErrorAccumulator,
5+
ParserError,
66
};
77

88
/// All analysis passes that run analysis on the HIR top level module
99
/// granularity should implement this trait.
10-
pub trait ModuleAnalysisPass<'db> {
11-
fn run_on_module(
10+
pub trait ModuleAnalysisPass {
11+
fn run_on_module<'db>(
1212
&mut self,
13+
db: &'db dyn HirAnalysisDb,
1314
top_mod: TopLevelMod<'db>,
14-
) -> Vec<Box<dyn DiagnosticVoucher<'db> + 'db>>;
15+
) -> Vec<Box<dyn DiagnosticVoucher + 'db>>;
1516
}
1617

1718
#[derive(Default)]
18-
pub struct AnalysisPassManager<'db> {
19-
module_passes: Vec<Box<dyn ModuleAnalysisPass<'db> + 'db>>,
19+
pub struct AnalysisPassManager {
20+
module_passes: Vec<Box<dyn ModuleAnalysisPass>>,
2021
}
2122

22-
impl<'db> AnalysisPassManager<'db> {
23+
impl AnalysisPassManager {
2324
pub fn new() -> Self {
2425
Self::default()
2526
}
2627

27-
pub fn add_module_pass(&mut self, pass: Box<dyn ModuleAnalysisPass<'db> + 'db>) {
28+
pub fn add_module_pass(&mut self, pass: Box<dyn ModuleAnalysisPass>) {
2829
self.module_passes.push(pass);
2930
}
3031

31-
pub fn run_on_module(
32+
pub fn run_on_module<'db>(
3233
&mut self,
34+
db: &'db dyn HirAnalysisDb,
3335
top_mod: TopLevelMod<'db>,
34-
) -> Vec<Box<dyn DiagnosticVoucher<'db> + 'db>> {
36+
) -> Vec<Box<dyn DiagnosticVoucher + 'db>> {
3537
let mut diags = vec![];
3638
for pass in self.module_passes.iter_mut() {
37-
diags.extend(pass.run_on_module(top_mod));
39+
diags.extend(pass.run_on_module(db, top_mod));
3840
}
3941
diags
4042
}
4143

42-
pub fn run_on_module_tree(
44+
pub fn run_on_module_tree<'db>(
4345
&mut self,
46+
db: &'db dyn HirAnalysisDb,
4447
tree: &'db ModuleTree<'db>,
45-
) -> Vec<Box<dyn DiagnosticVoucher<'db> + 'db>> {
48+
) -> Vec<Box<dyn DiagnosticVoucher + 'db>> {
4649
let mut diags = vec![];
4750
for module in tree.all_modules() {
4851
for pass in self.module_passes.iter_mut() {
49-
diags.extend(pass.run_on_module(module));
52+
diags.extend(pass.run_on_module(db, module));
5053
}
5154
}
5255
diags
5356
}
5457
}
5558

5659
#[derive(Clone, Copy)]
57-
pub struct ParsingPass<'db> {
58-
db: &'db dyn HirDb,
59-
}
60-
61-
impl<'db> ParsingPass<'db> {
62-
pub fn new(db: &'db dyn HirDb) -> Self {
63-
Self { db }
64-
}
65-
}
60+
pub struct ParsingPass {}
6661

67-
impl<'db> ModuleAnalysisPass<'db> for ParsingPass<'db> {
68-
fn run_on_module(
62+
impl ModuleAnalysisPass for ParsingPass {
63+
fn run_on_module<'db>(
6964
&mut self,
65+
db: &'db dyn HirAnalysisDb,
7066
top_mod: TopLevelMod<'db>,
71-
) -> Vec<Box<dyn DiagnosticVoucher<'db> + 'db>> {
72-
parse_file_impl::accumulated::<ParseErrorAccumulator>(self.db, top_mod)
67+
) -> Vec<Box<dyn DiagnosticVoucher>> {
68+
parse_file_impl::accumulated::<ParserError>(db, top_mod)
7369
.into_iter()
74-
.map(|d| Box::new(d.0.clone()) as _)
70+
.map(|d| Box::new(d.clone()) as _)
7571
.collect::<Vec<_>>()
7672
}
7773
}

0 commit comments

Comments
 (0)