diff --git a/tools/witx/src/io.rs b/tools/witx/src/io.rs index f46ab1766..a38a22d82 100644 --- a/tools/witx/src/io.rs +++ b/tools/witx/src/io.rs @@ -52,7 +52,7 @@ impl WitxIo for Filesystem { } pub struct MockFs { - map: HashMap, + map: HashMap, } impl MockFs { @@ -60,7 +60,7 @@ impl MockFs { MockFs { map: strings .iter() - .map(|(k, v)| (k.to_string(), v.to_string())) + .map(|(k, v)| (PathBuf::from(k), v.to_string())) .collect(), } } @@ -68,7 +68,7 @@ impl MockFs { impl WitxIo for MockFs { fn fgets(&self, path: &Path) -> Result { - if let Some(entry) = self.map.get(path.to_str().unwrap()) { + if let Some(entry) = self.map.get(path) { Ok(entry.to_string()) } else { Err(WitxError::Io( @@ -78,7 +78,7 @@ impl WitxIo for MockFs { } } fn fget_line(&self, path: &Path, line: usize) -> Result { - if let Some(entry) = self.map.get(path.to_str().unwrap()) { + if let Some(entry) = self.map.get(path) { entry .lines() .skip(line - 1) diff --git a/tools/witx/src/toplevel.rs b/tools/witx/src/toplevel.rs index 257e6edd8..94dbd1323 100644 --- a/tools/witx/src/toplevel.rs +++ b/tools/witx/src/toplevel.rs @@ -66,6 +66,7 @@ fn parse_file( .map_err(WitxError::Validation)?; } TopLevelSyntax::Use(u) => { + let root = path.parent().unwrap_or(root); parse_file(u.as_ref(), io, root, validator, definitions, parsed)?; } } @@ -138,6 +139,37 @@ mod test { ); } + #[test] + fn multi_use_with_layered_dirs() { + let doc = parse_witx_with( + &[Path::new("/root.witx")], + &MockFs::new(&[ + ("/root.witx", "(use \"subdir/child.witx\")"), + ( + "/subdir/child.witx", + "(use \"sibling.witx\")\n(typename $b_float f64)", + ), + ("/subdir/sibling.witx", "(typename $c_int u32)"), + // This definition looks just like subdir/sibling.witx but + // defines c_int differently - this test shows it does Not get + // included by subdir/child.witx's use. + ("/sibling.witx", "(typename $c_int u64)"), + ]), + ) + .expect("parse"); + + let b_float = doc.typename(&Id::new("b_float")).unwrap(); + assert_eq!(**b_float.type_(), Type::Builtin(BuiltinType::F64)); + + let c_int = doc.typename(&Id::new("c_int")).unwrap(); + assert_eq!( + **c_int.type_(), + Type::Builtin(BuiltinType::U32 { + lang_ptr_size: false + }) + ); + } + #[test] fn use_not_found() { match parse_witx_with(&[Path::new("/a")], &MockFs::new(&[("/a", "(use \"b\")")]))