From 891ebbae3816ebb82d74138cf700f882cea1d439 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Fri, 19 Sep 2025 15:44:42 +0200 Subject: [PATCH 1/5] fix: resolve imports at the end --- crates/compilers/src/compilers/mod.rs | 4 ++++ crates/compilers/src/compilers/multi.rs | 6 ++++++ crates/compilers/src/compilers/solc/mod.rs | 11 +++++++++++ crates/compilers/src/resolver/mod.rs | 2 ++ 4 files changed, 23 insertions(+) diff --git a/crates/compilers/src/compilers/mod.rs b/crates/compilers/src/compilers/mod.rs index 29e1ca75d..e00f97995 100644 --- a/crates/compilers/src/compilers/mod.rs +++ b/crates/compilers/src/compilers/mod.rs @@ -166,6 +166,10 @@ pub trait SourceParser: Clone + Debug + Send + Sync { }) .collect::>() } + + fn finalize_imports(&mut self, _include_paths: &BTreeSet) -> Result<()> { + Ok(()) + } } /// Parser of the source files which is used to identify imports and version requirements of the diff --git a/crates/compilers/src/compilers/multi.rs b/crates/compilers/src/compilers/multi.rs index 0953349c5..d93874708 100644 --- a/crates/compilers/src/compilers/multi.rs +++ b/crates/compilers/src/compilers/multi.rs @@ -412,6 +412,12 @@ impl SourceParser for MultiCompilerParser { ) .collect()) } + + fn finalize_imports(&mut self, include_paths: &BTreeSet) -> Result<()> { + self.solc.finalize_imports(include_paths)?; + self.vyper.finalize_imports(include_paths)?; + Ok(()) + } } impl ParsedSource for MultiCompilerParsedSource { diff --git a/crates/compilers/src/compilers/solc/mod.rs b/crates/compilers/src/compilers/solc/mod.rs index bf7792e5e..3ca74d031 100644 --- a/crates/compilers/src/compilers/solc/mod.rs +++ b/crates/compilers/src/compilers/solc/mod.rs @@ -401,6 +401,7 @@ impl SourceParser for SolParser { ) -> Result)>> { self.compiler_mut().enter_mut(|compiler| { let mut pcx = compiler.parse(); + pcx.set_resolve_imports(false); let files = sources .par_iter() .map(|(path, source)| { @@ -447,6 +448,16 @@ impl SourceParser for SolParser { Ok(parsed) }) } + + fn finalize_imports(&mut self, include_paths: &BTreeSet) -> Result<()> { + self.compiler_mut().sess_mut().opts.include_paths.extend(include_paths.iter().cloned()); + self.compiler_mut().enter_mut(|compiler| { + let mut pcx = compiler.parse(); + pcx.set_resolve_imports(true); + pcx.force_resolve_all_imports(); + }); + Ok(()) + } } impl ParsedSource for SolData { diff --git a/crates/compilers/src/resolver/mod.rs b/crates/compilers/src/resolver/mod.rs index 4a9cc85fc..e81b6f218 100644 --- a/crates/compilers/src/resolver/mod.rs +++ b/crates/compilers/src/resolver/mod.rs @@ -484,6 +484,8 @@ impl Graph

{ ); } + parser.finalize_imports(&resolved_solc_include_paths)?; + let edges = GraphEdges { edges, rev_edges, From 2a657f05edc77f6fd19e57c2e7bd34f77d118ab1 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Fri, 19 Sep 2025 18:43:50 +0200 Subject: [PATCH 2/5] fix: assign errors once --- crates/compilers/src/compilers/mod.rs | 6 ++- crates/compilers/src/compilers/multi.rs | 37 +++++++++++++-- crates/compilers/src/compilers/solc/mod.rs | 53 ++++++++++++---------- crates/compilers/src/resolver/mod.rs | 2 +- 4 files changed, 69 insertions(+), 29 deletions(-) diff --git a/crates/compilers/src/compilers/mod.rs b/crates/compilers/src/compilers/mod.rs index e00f97995..ea9db512a 100644 --- a/crates/compilers/src/compilers/mod.rs +++ b/crates/compilers/src/compilers/mod.rs @@ -167,7 +167,11 @@ pub trait SourceParser: Clone + Debug + Send + Sync { .collect::>() } - fn finalize_imports(&mut self, _include_paths: &BTreeSet) -> Result<()> { + fn finalize_imports( + &mut self, + _nodes: &mut Vec>, + _include_paths: &BTreeSet, + ) -> Result<()> { Ok(()) } } diff --git a/crates/compilers/src/compilers/multi.rs b/crates/compilers/src/compilers/multi.rs index d93874708..6543a3ac0 100644 --- a/crates/compilers/src/compilers/multi.rs +++ b/crates/compilers/src/compilers/multi.rs @@ -413,9 +413,40 @@ impl SourceParser for MultiCompilerParser { .collect()) } - fn finalize_imports(&mut self, include_paths: &BTreeSet) -> Result<()> { - self.solc.finalize_imports(include_paths)?; - self.vyper.finalize_imports(include_paths)?; + fn finalize_imports( + &mut self, + all_nodes: &mut Vec>, + include_paths: &BTreeSet, + ) -> Result<()> { + let mut solc_nodes = Vec::new(); + let mut vyper_nodes = Vec::new(); + for node in std::mem::take(all_nodes) { + match node.data { + MultiCompilerParsedSource::Solc(_) => { + solc_nodes.push(node.map_data(|data| match data { + MultiCompilerParsedSource::Solc(data) => data, + _ => unreachable!(), + })) + } + MultiCompilerParsedSource::Vyper(_) => { + vyper_nodes.push(node.map_data(|data| match data { + MultiCompilerParsedSource::Vyper(data) => data, + _ => unreachable!(), + })) + } + } + } + + self.solc.finalize_imports(&mut solc_nodes, include_paths)?; + self.vyper.finalize_imports(&mut vyper_nodes, include_paths)?; + + all_nodes.extend( + solc_nodes.into_iter().map(|node| node.map_data(MultiCompilerParsedSource::Solc)), + ); + all_nodes.extend( + vyper_nodes.into_iter().map(|node| node.map_data(MultiCompilerParsedSource::Vyper)), + ); + Ok(()) } } diff --git a/crates/compilers/src/compilers/solc/mod.rs b/crates/compilers/src/compilers/solc/mod.rs index 3ca74d031..0f044d314 100644 --- a/crates/compilers/src/compilers/solc/mod.rs +++ b/crates/compilers/src/compilers/solc/mod.rs @@ -399,7 +399,7 @@ impl SourceParser for SolParser { &mut self, sources: &mut Sources, ) -> Result)>> { - self.compiler_mut().enter_mut(|compiler| { + self.compiler.enter_mut(|compiler| { let mut pcx = compiler.parse(); pcx.set_resolve_imports(false); let files = sources @@ -424,38 +424,43 @@ impl SourceParser for SolParser { ); (path.clone(), node) }); - let mut parsed = parsed.collect::>(); - - // Set error on the first successful source, if any. This doesn't really have to be - // exact, as long as at least one source has an error set it should be enough. - if let Some(Err(diag)) = compiler.gcx().sess.emitted_errors() { - if let Some(idx) = parsed - .iter() - .position(|(_, node)| node.data.parse_result.is_ok()) - .or_else(|| parsed.first().map(|_| 0)) - { - let (_, node) = &mut parsed[idx]; - node.data.parse_result = Err(diag.to_string()); - } - } - - for (path, node) in &parsed { - if let Err(e) = &node.data.parse_result { - debug!("failed parsing {}: {e}", path.display()); - } - } + let parsed = parsed.collect::>(); Ok(parsed) }) } - fn finalize_imports(&mut self, include_paths: &BTreeSet) -> Result<()> { - self.compiler_mut().sess_mut().opts.include_paths.extend(include_paths.iter().cloned()); - self.compiler_mut().enter_mut(|compiler| { + fn finalize_imports( + &mut self, + nodes: &mut Vec>, + include_paths: &BTreeSet, + ) -> Result<()> { + let compiler = &mut self.compiler; + compiler.sess_mut().opts.include_paths.extend(include_paths.iter().cloned()); + compiler.enter_mut(|compiler| { let mut pcx = compiler.parse(); pcx.set_resolve_imports(true); pcx.force_resolve_all_imports(); }); + + // Set error on the first successful source, if any. This doesn't really have to be + // exact, as long as at least one source has an error set it should be enough. + if let Some(Err(diag)) = compiler.sess().emitted_errors() { + if let Some(idx) = nodes + .iter() + .position(|node| node.data.parse_result.is_ok()) + .or_else(|| nodes.first().map(|_| 0)) + { + nodes[idx].data.parse_result = Err(diag.to_string()); + } + } + + for node in nodes.iter() { + if let Err(e) = &node.data.parse_result { + debug!("failed parsing:\n{e}"); + } + } + Ok(()) } } diff --git a/crates/compilers/src/resolver/mod.rs b/crates/compilers/src/resolver/mod.rs index e81b6f218..0f16b9870 100644 --- a/crates/compilers/src/resolver/mod.rs +++ b/crates/compilers/src/resolver/mod.rs @@ -484,7 +484,7 @@ impl Graph

{ ); } - parser.finalize_imports(&resolved_solc_include_paths)?; + parser.finalize_imports(&mut nodes, &resolved_solc_include_paths)?; let edges = GraphEdges { edges, From c5bc537ae89701fa2a9bd390e944f95bbe09b9b3 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Wed, 1 Oct 2025 19:42:18 +0200 Subject: [PATCH 3/5] test: patch --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index af4caf253..f67dbe18e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,4 +70,4 @@ tokio = { version = "1.47", features = ["rt-multi-thread"] } snapbox = "0.6.21" [patch.crates-io] -# solar = { package = "solar-compiler", git = "https://github.com/paradigmxyz/solar", branch = "main" } +solar = { package = "solar-compiler", git = "https://github.com/paradigmxyz/solar", branch = "main" } From ef9b022a3b71427433e329666b69fb150fda8a42 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Wed, 1 Oct 2025 19:57:45 +0200 Subject: [PATCH 4/5] Revert "test: patch" This reverts commit c5bc537ae89701fa2a9bd390e944f95bbe09b9b3. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f67dbe18e..af4caf253 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,4 +70,4 @@ tokio = { version = "1.47", features = ["rt-multi-thread"] } snapbox = "0.6.21" [patch.crates-io] -solar = { package = "solar-compiler", git = "https://github.com/paradigmxyz/solar", branch = "main" } +# solar = { package = "solar-compiler", git = "https://github.com/paradigmxyz/solar", branch = "main" } From e06bf6ba18bf9a0b38a4ede4efc0fe18a25ad3ac Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Wed, 1 Oct 2025 20:06:04 +0200 Subject: [PATCH 5/5] dep --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index af4caf253..3426b8c12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,7 @@ semver = { version = "1.0", features = ["serde"] } serde = { version = "1", features = ["derive", "rc"] } serde_json = "1.0" similar-asserts = "1" -solar = { package = "solar-compiler", version = "=0.1.7", default-features = false } +solar = { package = "solar-compiler", version = "=0.1.8", default-features = false } svm = { package = "svm-rs", version = "0.5", default-features = false } tempfile = "3.20" thiserror = "2"