Fix of external SDK crate override bug#312
Conversation
|
In 3390c42: I'm confused by this solution. We now how have two methods, In parallel to this, this commit adds We then change |
|
@Sdoba16 could you update the description to reflect recent updates? |
|
Can you squash these commits? |
4414d2d to
438d6ff
Compare
| @@ -0,0 +1,106 @@ | |||
| use std::path::Path; | |||
There was a problem hiding this comment.
Once this file is added, let's move the CanonSourceFile struct and its implementation from driver/mod.rs into this new one
| K: Into<String>, | ||
| { | ||
| let mut dependency_map = DependencyMap::new(); | ||
| let mut builder = crate::resolution::DependencyMapBuilder::new(); |
There was a problem hiding this comment.
Use DependencyMapBuilder instead of crate::resolution::DependencyMapBuilder
| let canon_root = crate::source::CanonPath::canonicalize(&root).unwrap(); | ||
| let dependency_map = crate::resolution::DependencyMapBuilder::new() |
There was a problem hiding this comment.
Same here: use the name directly and remove the crate:: prefix
| dependency_map.insert(context, drp.into(), target).unwrap(); | ||
|
|
||
| dependency_map | ||
| crate::resolution::DependencyMapBuilder::new() |
There was a problem hiding this comment.
Found crate again. Let’s nix these everywhere else too
| /// A router for resolving dependencies across multi-file workspaces. | ||
| /// | ||
| /// Mappings are strictly sorted by the longest `context_prefix` match. | ||
| /// This mathematical guarantee ensures that if multiple nested directories | ||
| /// define the same dependency root path, the most specific (deepest) context wins. | ||
| #[derive(Debug, Clone, Default)] | ||
| pub struct DependencyMap { | ||
| /// External dependency remappings (e.g., `use math::...`) | ||
| remappings: Vec<Remapping>, | ||
| /// Package roots for resolving `crate::...` (sorted by longest path match) | ||
| package_roots: Vec<CanonPath>, | ||
| } |
There was a problem hiding this comment.
Add a bit more explanation of the architecture here. Why do we need Vec<CanonPath> here?
| pub fn with_entry_root(mut self, root: CanonPath) -> Self { | ||
| self.entry_root = Some(root); | ||
| self |
There was a problem hiding this comment.
Let’s pull this into new() and get rid of the Option for entry_root
| let resolved = Self::build_and_verify_path(&remapping.target, &parts[1..]) | ||
| .map_err(|failed_path| { | ||
| let err = if drp_name == CRATE_STR { | ||
| Error::FileNotFound(failed_path) | ||
| } else { | ||
| Error::ExternalFileNotFound(drp_name.to_string(), failed_path) | ||
| }; | ||
| RichError::new(err, *use_decl.span()) | ||
| RichError::new( | ||
| Error::ExternalFileNotFound(drp_name.to_string(), failed_path), | ||
| *use_decl.span(), | ||
| ) | ||
| })?; | ||
|
|
||
| self.check_local_file_imported_as_external( | ||
| drp_name, | ||
| current_file, | ||
| &resolved, | ||
| use_decl, | ||
| )?; | ||
| if !resolved.starts_with(&remapping.target) { | ||
| return Err(RichError::new( | ||
| Error::ExternalFileNotFound( | ||
| drp_name.to_string(), | ||
| resolved.as_path().to_path_buf(), | ||
| ), | ||
| *use_decl.span(), | ||
| )); | ||
| } | ||
|
|
||
| self.check_local_file_imported_as_external(current_file, &resolved, use_decl)?; |
There was a problem hiding this comment.
Extract this into a separate function
6ed86cb to
1836312
Compare
| self.as_path().starts_with(path.as_path()) | ||
| } | ||
| // Sort package roots by length descending to ensure longest prefix match | ||
| crate_roots.sort_by(|a, b| { |
There was a problem hiding this comment.
Should this not have a then_by sort for paths with the same length? It could probably then be used instead of the above sort at line 138
| } | ||
|
|
||
| impl DependencyMap { | ||
| pub fn new() -> Self { |
There was a problem hiding this comment.
Should this method maybe be private and add documentation to only use the builder. It seems like it is quite complicated to create this struct
| /// This mathematically guarantees that the first match we find is the most specific. | ||
| fn sort_mappings(&mut self) { | ||
| self.inner.sort_by(|a, b| { | ||
| self.remappings.sort_by(|a, b| { |
There was a problem hiding this comment.
Also feels like there should be a second sorting clause for paths with the same length
1836312 to
5be4511
Compare
5be4511 to
7ff8fd2
Compare
|
ACK 7ff8fd2; tested locally |
Closes #310
Previously, users could interact directly with the DependencyMap API in SimplicityHL, they could manually set the crate keyword to any path they want. This happened because the insert method allowed adding the crate alias without throwing any validation errors.
Fix
Was introduced
DependencyMapBuilderwhich collects dependencies and then could with build command it can be built.While building are made following validations:
Remapping was made pub(crate) to hide from external API.
resolution.rswas separated into 2 filessource.rsandresolution.rsfor readability.