1use std::cmp::Ordering;
2use std::collections::hash_map;
3use std::collections::{BTreeMap, HashMap, HashSet};
4use std::fmt;
5use std::mem;
6use std::path::{Path, PathBuf};
7
8use anyhow::{Context, Result, anyhow, bail};
9use id_arena::{Arena, Id};
10use indexmap::{IndexMap, IndexSet};
11use semver::Version;
12#[cfg(feature = "serde")]
13use serde_derive::Serialize;
14
15use crate::ast::lex::Span;
16use crate::ast::{ParsedUsePath, parse_use_path};
17#[cfg(feature = "serde")]
18use crate::serde_::{serialize_arena, serialize_id_map};
19use crate::{
20 AstItem, Docs, Error, Function, FunctionKind, Handle, IncludeName, Interface, InterfaceId,
21 InterfaceSpan, LiftLowerAbi, ManglingAndAbi, PackageName, PackageNotFoundError, SourceMap,
22 Stability, Type, TypeDef, TypeDefKind, TypeId, TypeIdVisitor, TypeOwner, UnresolvedPackage,
23 UnresolvedPackageGroup, World, WorldId, WorldItem, WorldKey, WorldSpan,
24};
25
26mod clone;
27
28#[derive(Default, Clone, Debug)]
42#[cfg_attr(feature = "serde", derive(Serialize))]
43pub struct Resolve {
44 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
49 pub worlds: Arena<World>,
50
51 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
56 pub interfaces: Arena<Interface>,
57
58 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
64 pub types: Arena<TypeDef>,
65
66 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
71 pub packages: Arena<Package>,
72
73 #[cfg_attr(feature = "serde", serde(skip))]
75 pub package_names: IndexMap<PackageName, PackageId>,
76
77 #[cfg_attr(feature = "serde", serde(skip))]
84 pub features: IndexSet<String>,
85
86 #[cfg_attr(feature = "serde", serde(skip))]
88 pub all_features: bool,
89}
90
91#[derive(Clone, Debug)]
97#[cfg_attr(feature = "serde", derive(Serialize))]
98pub struct Package {
99 pub name: PackageName,
101
102 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Docs::is_empty"))]
104 pub docs: Docs,
105
106 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_id_map"))]
109 pub interfaces: IndexMap<String, InterfaceId>,
110
111 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_id_map"))]
113 pub worlds: IndexMap<String, WorldId>,
114}
115
116pub type PackageId = Id<Package>;
117
118#[derive(Clone, Debug)]
120pub struct PackageSourceMap {
121 sources: Vec<Vec<PathBuf>>,
122 package_id_to_source_map_idx: BTreeMap<PackageId, usize>,
123}
124
125impl PackageSourceMap {
126 fn from_single_source(package_id: PackageId, source: &Path) -> Self {
127 Self {
128 sources: vec![vec![source.to_path_buf()]],
129 package_id_to_source_map_idx: BTreeMap::from([(package_id, 0)]),
130 }
131 }
132
133 fn from_source_maps(
134 source_maps: Vec<SourceMap>,
135 package_id_to_source_map_idx: BTreeMap<PackageId, usize>,
136 ) -> PackageSourceMap {
137 for (package_id, idx) in &package_id_to_source_map_idx {
138 if *idx >= source_maps.len() {
139 panic!(
140 "Invalid source map index: {}, package id: {:?}, source maps size: {}",
141 idx,
142 package_id,
143 source_maps.len()
144 )
145 }
146 }
147
148 Self {
149 sources: source_maps
150 .into_iter()
151 .map(|source_map| {
152 source_map
153 .source_files()
154 .map(|path| path.to_path_buf())
155 .collect()
156 })
157 .collect(),
158 package_id_to_source_map_idx,
159 }
160 }
161
162 pub fn paths(&self) -> impl Iterator<Item = &Path> {
164 self.sources
168 .iter()
169 .flatten()
170 .map(|path_buf| path_buf.as_ref())
171 .collect::<HashSet<&Path>>()
172 .into_iter()
173 }
174
175 pub fn package_paths(&self, id: PackageId) -> Option<impl Iterator<Item = &Path>> {
177 self.package_id_to_source_map_idx
178 .get(&id)
179 .map(|&idx| self.sources[idx].iter().map(|path_buf| path_buf.as_ref()))
180 }
181}
182
183enum ParsedFile {
184 #[cfg(feature = "decoding")]
185 Package(PackageId),
186 Unresolved(UnresolvedPackageGroup),
187}
188
189fn visit<'a>(
191 pkg: &'a UnresolvedPackage,
192 pkg_details_map: &'a BTreeMap<PackageName, (UnresolvedPackage, usize)>,
193 order: &mut IndexSet<PackageName>,
194 visiting: &mut HashSet<&'a PackageName>,
195 source_maps: &[SourceMap],
196) -> Result<()> {
197 if order.contains(&pkg.name) {
198 return Ok(());
199 }
200
201 match pkg_details_map.get(&pkg.name) {
202 Some(pkg_details) => {
203 let (_, source_maps_index) = pkg_details;
204 source_maps[*source_maps_index].rewrite_error(|| {
205 for (i, (dep, _)) in pkg.foreign_deps.iter().enumerate() {
206 let span = pkg.foreign_dep_spans[i];
207 if !visiting.insert(dep) {
208 bail!(Error::new(span, "package depends on itself"));
209 }
210 if let Some(dep) = pkg_details_map.get(dep) {
211 let (dep_pkg, _) = dep;
212 visit(dep_pkg, pkg_details_map, order, visiting, source_maps)?;
213 }
214 assert!(visiting.remove(dep));
215 }
216 assert!(order.insert(pkg.name.clone()));
217 Ok(())
218 })
219 }
220 None => panic!("No pkg_details found for package when doing topological sort"),
221 }
222}
223
224impl Resolve {
225 pub fn new() -> Resolve {
227 Resolve::default()
228 }
229
230 pub fn push_path(&mut self, path: impl AsRef<Path>) -> Result<(PackageId, PackageSourceMap)> {
258 self._push_path(path.as_ref())
259 }
260
261 fn _push_path(&mut self, path: &Path) -> Result<(PackageId, PackageSourceMap)> {
262 if path.is_dir() {
263 self.push_dir(path).with_context(|| {
264 format!(
265 "failed to resolve directory while parsing WIT for path [{}]",
266 path.display()
267 )
268 })
269 } else {
270 let id = self.push_file(path)?;
271 Ok((id, PackageSourceMap::from_single_source(id, path)))
272 }
273 }
274
275 fn sort_unresolved_packages(
276 &mut self,
277 main: UnresolvedPackageGroup,
278 deps: Vec<UnresolvedPackageGroup>,
279 ) -> Result<(PackageId, PackageSourceMap)> {
280 let mut pkg_details_map = BTreeMap::new();
281 let mut source_maps = Vec::new();
282
283 let mut insert = |group: UnresolvedPackageGroup| {
284 let UnresolvedPackageGroup {
285 main,
286 nested,
287 source_map,
288 } = group;
289 let i = source_maps.len();
290 source_maps.push(source_map);
291
292 for pkg in nested.into_iter().chain([main]) {
293 let name = pkg.name.clone();
294 let my_span = pkg.package_name_span;
295 let (prev_pkg, prev_i) = match pkg_details_map.insert(name.clone(), (pkg, i)) {
296 Some(pair) => pair,
297 None => continue,
298 };
299 let loc1 = source_maps[i].render_location(my_span);
300 let loc2 = source_maps[prev_i].render_location(prev_pkg.package_name_span);
301 bail!(
302 "\
303package {name} is defined in two different locations:\n\
304 * {loc1}\n\
305 * {loc2}\n\
306 "
307 )
308 }
309 Ok(())
310 };
311
312 let main_name = main.main.name.clone();
313 insert(main)?;
314 for dep in deps {
315 insert(dep)?;
316 }
317
318 let mut order = IndexSet::new();
322 let mut visiting = HashSet::new();
323 for pkg_details in pkg_details_map.values() {
324 let (pkg, _) = pkg_details;
325 visit(
326 pkg,
327 &pkg_details_map,
328 &mut order,
329 &mut visiting,
330 &source_maps,
331 )?;
332 }
333
334 let mut package_id_to_source_map_idx = BTreeMap::new();
338 let mut main_pkg_id = None;
339 for name in order {
340 let (pkg, source_map_index) = pkg_details_map.remove(&name).unwrap();
341 let source_map = &source_maps[source_map_index];
342 let is_main = pkg.name == main_name;
343 let id = self.push(pkg, source_map)?;
344 if is_main {
345 assert!(main_pkg_id.is_none());
346 main_pkg_id = Some(id);
347 }
348 package_id_to_source_map_idx.insert(id, source_map_index);
349 }
350
351 Ok((
352 main_pkg_id.unwrap(),
353 PackageSourceMap::from_source_maps(source_maps, package_id_to_source_map_idx),
354 ))
355 }
356
357 pub fn push_dir(&mut self, path: impl AsRef<Path>) -> Result<(PackageId, PackageSourceMap)> {
391 self._push_dir(path.as_ref())
392 }
393
394 fn _push_dir(&mut self, path: &Path) -> Result<(PackageId, PackageSourceMap)> {
395 let top_pkg = UnresolvedPackageGroup::parse_dir(path)
396 .with_context(|| format!("failed to parse package: {}", path.display()))?;
397 let deps = path.join("deps");
398 let deps = self
399 .parse_deps_dir(&deps)
400 .with_context(|| format!("failed to parse dependency directory: {}", deps.display()))?;
401
402 self.sort_unresolved_packages(top_pkg, deps)
403 }
404
405 fn parse_deps_dir(&mut self, path: &Path) -> Result<Vec<UnresolvedPackageGroup>> {
406 let mut ret = Vec::new();
407 if !path.exists() {
408 return Ok(ret);
409 }
410 let mut entries = path
411 .read_dir()
412 .and_then(|i| i.collect::<std::io::Result<Vec<_>>>())
413 .context("failed to read directory")?;
414 entries.sort_by_key(|e| e.file_name());
415 for dep in entries {
416 let path = dep.path();
417 let pkg = if dep.file_type()?.is_dir() || path.metadata()?.is_dir() {
418 UnresolvedPackageGroup::parse_dir(&path)
423 .with_context(|| format!("failed to parse package: {}", path.display()))?
424 } else {
425 let filename = dep.file_name();
429 match Path::new(&filename).extension().and_then(|s| s.to_str()) {
430 Some("wit") | Some("wat") | Some("wasm") => match self._push_file(&path)? {
431 #[cfg(feature = "decoding")]
432 ParsedFile::Package(_) => continue,
433 ParsedFile::Unresolved(pkg) => pkg,
434 },
435
436 _ => continue,
440 }
441 };
442 ret.push(pkg);
443 }
444 Ok(ret)
445 }
446
447 pub fn push_file(&mut self, path: impl AsRef<Path>) -> Result<PackageId> {
462 match self._push_file(path.as_ref())? {
463 #[cfg(feature = "decoding")]
464 ParsedFile::Package(id) => Ok(id),
465 ParsedFile::Unresolved(pkg) => self.push_group(pkg),
466 }
467 }
468
469 fn _push_file(&mut self, path: &Path) -> Result<ParsedFile> {
470 let contents = std::fs::read(path)
471 .with_context(|| format!("failed to read path for WIT [{}]", path.display()))?;
472
473 #[cfg(feature = "decoding")]
476 {
477 use crate::decoding::{DecodedWasm, decode};
478
479 #[cfg(feature = "wat")]
480 let is_wasm = wat::Detect::from_bytes(&contents).is_wasm();
481 #[cfg(not(feature = "wat"))]
482 let is_wasm = wasmparser::Parser::is_component(&contents);
483
484 if is_wasm {
485 #[cfg(feature = "wat")]
486 let contents = wat::parse_bytes(&contents).map_err(|mut e| {
487 e.set_path(path);
488 e
489 })?;
490
491 match decode(&contents)? {
492 DecodedWasm::Component(..) => {
493 bail!("found an actual component instead of an encoded WIT package in wasm")
494 }
495 DecodedWasm::WitPackage(resolve, pkg) => {
496 let remap = self.merge(resolve)?;
497 return Ok(ParsedFile::Package(remap.packages[pkg.index()]));
498 }
499 }
500 }
501 }
502
503 let text = match std::str::from_utf8(&contents) {
505 Ok(s) => s,
506 Err(_) => bail!("input file is not valid utf-8 [{}]", path.display()),
507 };
508 let pkgs = UnresolvedPackageGroup::parse(path, text)?;
509 Ok(ParsedFile::Unresolved(pkgs))
510 }
511
512 pub fn push(
523 &mut self,
524 unresolved: UnresolvedPackage,
525 source_map: &SourceMap,
526 ) -> Result<PackageId> {
527 let ret = source_map.rewrite_error(|| Remap::default().append(self, unresolved));
528 if ret.is_ok() {
529 #[cfg(debug_assertions)]
530 self.assert_valid();
531 }
532 ret
533 }
534
535 pub fn push_group(&mut self, unresolved_group: UnresolvedPackageGroup) -> Result<PackageId> {
544 let (pkg_id, _) = self.sort_unresolved_packages(unresolved_group, Vec::new())?;
545 Ok(pkg_id)
546 }
547
548 pub fn push_str(&mut self, path: impl AsRef<Path>, contents: &str) -> Result<PackageId> {
555 self.push_group(UnresolvedPackageGroup::parse(path.as_ref(), contents)?)
556 }
557
558 pub fn all_bits_valid(&self, ty: &Type) -> bool {
559 match ty {
560 Type::U8
561 | Type::S8
562 | Type::U16
563 | Type::S16
564 | Type::U32
565 | Type::S32
566 | Type::U64
567 | Type::S64
568 | Type::F32
569 | Type::F64 => true,
570
571 Type::Bool | Type::Char | Type::String | Type::ErrorContext => false,
572
573 Type::Id(id) => match &self.types[*id].kind {
574 TypeDefKind::List(_)
575 | TypeDefKind::Variant(_)
576 | TypeDefKind::Enum(_)
577 | TypeDefKind::Option(_)
578 | TypeDefKind::Result(_)
579 | TypeDefKind::Future(_)
580 | TypeDefKind::Stream(_) => false,
581 TypeDefKind::Type(t) | TypeDefKind::FixedSizeList(t, ..) => self.all_bits_valid(t),
582
583 TypeDefKind::Handle(h) => match h {
584 crate::Handle::Own(_) => true,
585 crate::Handle::Borrow(_) => true,
586 },
587
588 TypeDefKind::Resource => false,
589 TypeDefKind::Record(r) => r.fields.iter().all(|f| self.all_bits_valid(&f.ty)),
590 TypeDefKind::Tuple(t) => t.types.iter().all(|t| self.all_bits_valid(t)),
591
592 TypeDefKind::Flags(_) => false,
596
597 TypeDefKind::Unknown => unreachable!(),
598 },
599 }
600 }
601
602 pub fn merge(&mut self, resolve: Resolve) -> Result<Remap> {
614 log::trace!(
615 "merging {} packages into {} packages",
616 resolve.packages.len(),
617 self.packages.len()
618 );
619
620 let mut map = MergeMap::new(&resolve, &self);
621 map.build()?;
622 let MergeMap {
623 package_map,
624 interface_map,
625 type_map,
626 world_map,
627 interfaces_to_add,
628 worlds_to_add,
629 ..
630 } = map;
631
632 let mut remap = Remap::default();
651 let Resolve {
652 types,
653 worlds,
654 interfaces,
655 packages,
656 package_names,
657 features: _,
658 ..
659 } = resolve;
660
661 let mut moved_types = Vec::new();
662 for (id, mut ty) in types {
663 let new_id = match type_map.get(&id).copied() {
664 Some(id) => {
665 update_stability(&ty.stability, &mut self.types[id].stability)?;
666 id
667 }
668 None => {
669 log::debug!("moving type {:?}", ty.name);
670 moved_types.push(id);
671 remap.update_typedef(self, &mut ty, None)?;
672 self.types.alloc(ty)
673 }
674 };
675 assert_eq!(remap.types.len(), id.index());
676 remap.types.push(Some(new_id));
677 }
678
679 let mut moved_interfaces = Vec::new();
680 for (id, mut iface) in interfaces {
681 let new_id = match interface_map.get(&id).copied() {
682 Some(id) => {
683 update_stability(&iface.stability, &mut self.interfaces[id].stability)?;
684 id
685 }
686 None => {
687 log::debug!("moving interface {:?}", iface.name);
688 moved_interfaces.push(id);
689 remap.update_interface(self, &mut iface, None)?;
690 self.interfaces.alloc(iface)
691 }
692 };
693 assert_eq!(remap.interfaces.len(), id.index());
694 remap.interfaces.push(Some(new_id));
695 }
696
697 let mut moved_worlds = Vec::new();
698 for (id, mut world) in worlds {
699 let new_id = match world_map.get(&id).copied() {
700 Some(world_id) => {
701 update_stability(&world.stability, &mut self.worlds[world_id].stability)?;
702 for from_import in world.imports.iter() {
703 Resolve::update_world_imports_stability(
704 from_import,
705 &mut self.worlds[world_id].imports,
706 &interface_map,
707 )?;
708 }
709 for from_export in world.exports.iter() {
710 Resolve::update_world_imports_stability(
711 from_export,
712 &mut self.worlds[world_id].exports,
713 &interface_map,
714 )?;
715 }
716 world_id
717 }
718 None => {
719 log::debug!("moving world {}", world.name);
720 moved_worlds.push(id);
721 let mut update = |map: &mut IndexMap<WorldKey, WorldItem>| -> Result<_> {
722 for (mut name, mut item) in mem::take(map) {
723 remap.update_world_key(&mut name, None)?;
724 match &mut item {
725 WorldItem::Function(f) => remap.update_function(self, f, None)?,
726 WorldItem::Interface { id, .. } => {
727 *id = remap.map_interface(*id, None)?
728 }
729 WorldItem::Type(i) => *i = remap.map_type(*i, None)?,
730 }
731 map.insert(name, item);
732 }
733 Ok(())
734 };
735 update(&mut world.imports)?;
736 update(&mut world.exports)?;
737 self.worlds.alloc(world)
738 }
739 };
740 assert_eq!(remap.worlds.len(), id.index());
741 remap.worlds.push(Some(new_id));
742 }
743
744 for (id, mut pkg) in packages {
745 let new_id = match package_map.get(&id).copied() {
746 Some(id) => id,
747 None => {
748 for (_, id) in pkg.interfaces.iter_mut() {
749 *id = remap.map_interface(*id, None)?;
750 }
751 for (_, id) in pkg.worlds.iter_mut() {
752 *id = remap.map_world(*id, None)?;
753 }
754 self.packages.alloc(pkg)
755 }
756 };
757 assert_eq!(remap.packages.len(), id.index());
758 remap.packages.push(new_id);
759 }
760
761 for (name, id) in package_names {
762 let id = remap.packages[id.index()];
763 if let Some(prev) = self.package_names.insert(name, id) {
764 assert_eq!(prev, id);
765 }
766 }
767
768 for id in moved_worlds {
776 let id = remap.map_world(id, None)?;
777 if let Some(pkg) = self.worlds[id].package.as_mut() {
778 *pkg = remap.packages[pkg.index()];
779 }
780 }
781 for id in moved_interfaces {
782 let id = remap.map_interface(id, None)?;
783 if let Some(pkg) = self.interfaces[id].package.as_mut() {
784 *pkg = remap.packages[pkg.index()];
785 }
786 }
787 for id in moved_types {
788 let id = remap.map_type(id, None)?;
789 match &mut self.types[id].owner {
790 TypeOwner::Interface(id) => *id = remap.map_interface(*id, None)?,
791 TypeOwner::World(id) => *id = remap.map_world(*id, None)?,
792 TypeOwner::None => {}
793 }
794 }
795
796 for (name, pkg, iface) in interfaces_to_add {
801 let prev = self.packages[pkg]
802 .interfaces
803 .insert(name, remap.map_interface(iface, None)?);
804 assert!(prev.is_none());
805 }
806 for (name, pkg, world) in worlds_to_add {
807 let prev = self.packages[pkg]
808 .worlds
809 .insert(name, remap.map_world(world, None)?);
810 assert!(prev.is_none());
811 }
812
813 log::trace!("now have {} packages", self.packages.len());
814
815 #[cfg(debug_assertions)]
816 self.assert_valid();
817 Ok(remap)
818 }
819
820 fn update_world_imports_stability(
821 from_item: (&WorldKey, &WorldItem),
822 into_items: &mut IndexMap<WorldKey, WorldItem>,
823 interface_map: &HashMap<Id<Interface>, Id<Interface>>,
824 ) -> Result<()> {
825 match from_item.0 {
826 WorldKey::Name(_) => {
827 Ok(())
829 }
830 key @ WorldKey::Interface(_) => {
831 let new_key = MergeMap::map_name(key, interface_map);
832 if let Some(into) = into_items.get_mut(&new_key) {
833 match (from_item.1, into) {
834 (
835 WorldItem::Interface {
836 id: aid,
837 stability: astability,
838 },
839 WorldItem::Interface {
840 id: bid,
841 stability: bstability,
842 },
843 ) => {
844 let aid = interface_map.get(aid).copied().unwrap_or(*aid);
845 assert_eq!(aid, *bid);
846 update_stability(astability, bstability)?;
847 Ok(())
848 }
849 _ => unreachable!(),
850 }
851 } else {
852 unreachable!()
855 }
856 }
857 }
858 }
859
860 pub fn merge_worlds(&mut self, from: WorldId, into: WorldId) -> Result<()> {
871 let mut new_imports = Vec::new();
872 let mut new_exports = Vec::new();
873
874 let from_world = &self.worlds[from];
875 let into_world = &self.worlds[into];
876
877 log::trace!("merging {} into {}", from_world.name, into_world.name);
878
879 for (name, from_import) in from_world.imports.iter() {
887 let name_str = self.name_world_key(name);
888 match into_world.imports.get(name) {
889 Some(into_import) => {
890 log::trace!("info/from shared import on `{name_str}`");
891 self.merge_world_item(from_import, into_import)
892 .with_context(|| format!("failed to merge world import {name_str}"))?;
893 }
894 None => {
895 log::trace!("new import: `{name_str}`");
896 new_imports.push((name.clone(), from_import.clone()));
897 }
898 }
899 }
900
901 let mut must_be_imported = HashMap::new();
908 for (key, export) in into_world.exports.iter() {
909 for dep in self.world_item_direct_deps(export) {
910 if into_world.exports.contains_key(&WorldKey::Interface(dep)) {
911 continue;
912 }
913 self.foreach_interface_dep(dep, &mut |id| {
914 must_be_imported.insert(id, key.clone());
915 });
916 }
917 }
918
919 for (name, from_export) in from_world.exports.iter() {
922 let name_str = self.name_world_key(name);
923 match into_world.exports.get(name) {
924 Some(into_export) => {
925 log::trace!("info/from shared export on `{name_str}`");
926 self.merge_world_item(from_export, into_export)
927 .with_context(|| format!("failed to merge world export {name_str}"))?;
928 }
929 None => {
930 log::trace!("new export `{name_str}`");
931 self.ensure_can_add_world_export(
934 into_world,
935 name,
936 from_export,
937 &must_be_imported,
938 )
939 .with_context(|| {
940 format!("failed to add export `{}`", self.name_world_key(name))
941 })?;
942 new_exports.push((name.clone(), from_export.clone()));
943 }
944 }
945 }
946
947 let mut cloner = clone::Cloner::new(self, TypeOwner::World(from), TypeOwner::World(into));
961 cloner.register_world_type_overlap(from, into);
962 for (name, item) in new_imports.iter_mut().chain(&mut new_exports) {
963 cloner.world_item(name, item);
964 }
965
966 let into_world = &mut self.worlds[into];
968 for (name, import) in new_imports {
969 let prev = into_world.imports.insert(name, import);
970 assert!(prev.is_none());
971 }
972 for (name, export) in new_exports {
973 let prev = into_world.exports.insert(name, export);
974 assert!(prev.is_none());
975 }
976
977 #[cfg(debug_assertions)]
978 self.assert_valid();
979 Ok(())
980 }
981
982 fn merge_world_item(&self, from: &WorldItem, into: &WorldItem) -> Result<()> {
983 let mut map = MergeMap::new(self, self);
984 match (from, into) {
985 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
986 if from == into {
991 return Ok(());
992 }
993
994 map.build_interface(*from, *into)
1004 .context("failed to merge interfaces")?;
1005 }
1006
1007 (WorldItem::Function(from), WorldItem::Function(into)) => {
1010 map.build_function(from, into)
1011 .context("failed to merge functions")?;
1012 }
1013 (WorldItem::Type(from), WorldItem::Type(into)) => {
1014 map.build_type_id(*from, *into)
1015 .context("failed to merge types")?;
1016 }
1017
1018 (WorldItem::Interface { .. }, _)
1020 | (WorldItem::Function { .. }, _)
1021 | (WorldItem::Type { .. }, _) => {
1022 bail!("different kinds of items");
1023 }
1024 }
1025 assert!(map.interfaces_to_add.is_empty());
1026 assert!(map.worlds_to_add.is_empty());
1027 Ok(())
1028 }
1029
1030 fn ensure_can_add_world_export(
1042 &self,
1043 into: &World,
1044 name: &WorldKey,
1045 item: &WorldItem,
1046 must_be_imported: &HashMap<InterfaceId, WorldKey>,
1047 ) -> Result<()> {
1048 assert!(!into.exports.contains_key(name));
1049 let name = self.name_world_key(name);
1050
1051 for dep in self.world_item_direct_deps(item) {
1055 if into.exports.contains_key(&WorldKey::Interface(dep)) {
1056 continue;
1057 }
1058 self.ensure_not_exported(into, dep)
1059 .with_context(|| format!("failed validating export of `{name}`"))?;
1060 }
1061
1062 if let WorldItem::Interface { id, .. } = item {
1066 if let Some(export) = must_be_imported.get(&id) {
1067 let export_name = self.name_world_key(export);
1068 bail!(
1069 "export `{export_name}` depends on `{name}` \
1070 previously as an import which will change meaning \
1071 if `{name}` is added as an export"
1072 );
1073 }
1074 }
1075
1076 Ok(())
1077 }
1078
1079 fn ensure_not_exported(&self, world: &World, id: InterfaceId) -> Result<()> {
1080 let key = WorldKey::Interface(id);
1081 let name = self.name_world_key(&key);
1082 if world.exports.contains_key(&key) {
1083 bail!(
1084 "world exports `{name}` but it's also transitively used by an \
1085 import \
1086 which means that this is not valid"
1087 )
1088 }
1089 for dep in self.interface_direct_deps(id) {
1090 self.ensure_not_exported(world, dep)
1091 .with_context(|| format!("failed validating transitive import dep `{name}`"))?;
1092 }
1093 Ok(())
1094 }
1095
1096 fn world_item_direct_deps(&self, item: &WorldItem) -> impl Iterator<Item = InterfaceId> + '_ {
1102 let mut interface = None;
1103 let mut ty = None;
1104 match item {
1105 WorldItem::Function(_) => {}
1106 WorldItem::Type(id) => ty = Some(*id),
1107 WorldItem::Interface { id, .. } => interface = Some(*id),
1108 }
1109
1110 interface
1111 .into_iter()
1112 .flat_map(move |id| self.interface_direct_deps(id))
1113 .chain(ty.and_then(|t| self.type_interface_dep(t)))
1114 }
1115
1116 fn foreach_interface_dep(&self, id: InterfaceId, f: &mut dyn FnMut(InterfaceId)) {
1120 self._foreach_interface_dep(id, f, &mut HashSet::new())
1121 }
1122
1123 fn _foreach_interface_dep(
1127 &self,
1128 id: InterfaceId,
1129 f: &mut dyn FnMut(InterfaceId),
1130 visited: &mut HashSet<InterfaceId>,
1131 ) {
1132 if !visited.insert(id) {
1133 return;
1134 }
1135 f(id);
1136 for dep in self.interface_direct_deps(id) {
1137 self._foreach_interface_dep(dep, f, visited);
1138 }
1139 }
1140
1141 pub fn id_of(&self, interface: InterfaceId) -> Option<String> {
1145 let interface = &self.interfaces[interface];
1146 Some(self.id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1147 }
1148
1149 pub fn canonicalized_id_of(&self, interface: InterfaceId) -> Option<String> {
1154 let interface = &self.interfaces[interface];
1155 Some(self.canonicalized_id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1156 }
1157
1158 pub fn importize(&mut self, world_id: WorldId, out_world_name: Option<String>) -> Result<()> {
1174 let world = &mut self.worlds[world_id];
1179 let pkg = &mut self.packages[world.package.unwrap()];
1180 pkg.worlds.shift_remove(&world.name);
1181 if let Some(name) = out_world_name {
1182 world.name = name.clone();
1183 pkg.worlds.insert(name, world_id);
1184 } else {
1185 world.name.push_str("-importized");
1186 pkg.worlds.insert(world.name.clone(), world_id);
1187 }
1188
1189 world.imports.retain(|_, item| match item {
1192 WorldItem::Type(_) => true,
1193 _ => false,
1194 });
1195
1196 for (name, export) in mem::take(&mut world.exports) {
1197 match (name.clone(), world.imports.insert(name, export)) {
1198 (_, None) => {}
1200
1201 (WorldKey::Name(name), Some(_)) => {
1203 bail!("world export `{name}` conflicts with import of same name");
1204 }
1205
1206 (WorldKey::Interface(_), _) => unreachable!(),
1209 }
1210 }
1211
1212 self.elaborate_world(world_id)?;
1215
1216 #[cfg(debug_assertions)]
1217 self.assert_valid();
1218 Ok(())
1219 }
1220
1221 pub fn id_of_name(&self, pkg: PackageId, name: &str) -> String {
1223 let package = &self.packages[pkg];
1224 let mut base = String::new();
1225 base.push_str(&package.name.namespace);
1226 base.push_str(":");
1227 base.push_str(&package.name.name);
1228 base.push_str("/");
1229 base.push_str(name);
1230 if let Some(version) = &package.name.version {
1231 base.push_str(&format!("@{version}"));
1232 }
1233 base
1234 }
1235
1236 pub fn canonicalized_id_of_name(&self, pkg: PackageId, name: &str) -> String {
1242 let package = &self.packages[pkg];
1243 let mut base = String::new();
1244 base.push_str(&package.name.namespace);
1245 base.push_str(":");
1246 base.push_str(&package.name.name);
1247 base.push_str("/");
1248 base.push_str(name);
1249 if let Some(version) = &package.name.version {
1250 base.push_str("@");
1251 let string = PackageName::version_compat_track_string(version);
1252 base.push_str(&string);
1253 }
1254 base
1255 }
1256
1257 pub fn select_world(
1372 &self,
1373 main_packages: &[PackageId],
1374 world: Option<&str>,
1375 ) -> Result<WorldId> {
1376 let world_path = match world {
1378 Some(world) => Some(
1379 parse_use_path(world)
1380 .with_context(|| format!("failed to parse world specifier `{world}`"))?,
1381 ),
1382 None => None,
1383 };
1384
1385 match world_path {
1386 Some(world_path) => {
1388 let (pkg, world_name) = match (main_packages, world_path) {
1389 ([], _) => bail!("No main packages defined"),
1391
1392 ([main_package], ParsedUsePath::Name(name)) => (*main_package, name),
1394
1395 (_, ParsedUsePath::Name(_name)) => {
1397 bail!(
1398 "There are multiple main packages; a world must be explicitly chosen:{}",
1399 self.worlds
1400 .iter()
1401 .map(|world| format!(
1402 "\n {}",
1403 self.id_of_name(world.1.package.unwrap(), &world.1.name)
1404 ))
1405 .collect::<String>()
1406 )
1407 }
1408
1409 (_, ParsedUsePath::Package(pkg, world_name)) => {
1411 let pkg = match self.package_names.get(&pkg) {
1412 Some(pkg) => *pkg,
1413 None => {
1414 let mut candidates =
1415 self.package_names.iter().filter(|(name, _)| {
1416 pkg.version.is_none()
1417 && pkg.name == name.name
1418 && pkg.namespace == name.namespace
1419 && name.version.is_some()
1420 });
1421 let candidate = candidates.next();
1422 if let Some((c2, _)) = candidates.next() {
1423 let (c1, _) = candidate.unwrap();
1424 bail!(
1425 "package name `{pkg}` is available at both \
1426 versions {} and {} but which is not specified",
1427 c1.version.as_ref().unwrap(),
1428 c2.version.as_ref().unwrap(),
1429 );
1430 }
1431 match candidate {
1432 Some((_, id)) => *id,
1433 None => bail!("unknown package `{pkg}`"),
1434 }
1435 }
1436 };
1437 (pkg, world_name.to_string())
1438 }
1439 };
1440
1441 let pkg = &self.packages[pkg];
1443 pkg.worlds.get(&world_name).copied().ok_or_else(|| {
1444 anyhow!("World `{world_name}` not found in package `{}`", pkg.name)
1445 })
1446 }
1447
1448 None => match main_packages {
1450 [] => bail!("No main packages defined"),
1451
1452 [main_package] => {
1454 let pkg = &self.packages[*main_package];
1455 match pkg.worlds.len() {
1456 0 => bail!("The main package `{}` contains no worlds", pkg.name),
1457 1 => Ok(pkg.worlds[0]),
1458 _ => bail!(
1459 "There are multiple worlds in `{}`; one must be explicitly chosen:{}",
1460 pkg.name,
1461 pkg.worlds
1462 .values()
1463 .map(|world| format!(
1464 "\n {}",
1465 self.id_of_name(*main_package, &self.worlds[*world].name)
1466 ))
1467 .collect::<String>()
1468 ),
1469 }
1470 }
1471
1472 _ => {
1474 bail!(
1475 "There are multiple main packages; a world must be explicitly chosen:{}",
1476 self.worlds
1477 .iter()
1478 .map(|world| format!(
1479 "\n {}",
1480 self.id_of_name(world.1.package.unwrap(), &world.1.name)
1481 ))
1482 .collect::<String>()
1483 )
1484 }
1485 },
1486 }
1487 }
1488
1489 pub fn name_world_key(&self, key: &WorldKey) -> String {
1491 match key {
1492 WorldKey::Name(s) => s.to_string(),
1493 WorldKey::Interface(i) => self.id_of(*i).expect("unexpected anonymous interface"),
1494 }
1495 }
1496
1497 pub fn name_canonicalized_world_key(&self, key: &WorldKey) -> String {
1500 match key {
1501 WorldKey::Name(s) => s.to_string(),
1502 WorldKey::Interface(i) => self
1503 .canonicalized_id_of(*i)
1504 .expect("unexpected anonymous interface"),
1505 }
1506 }
1507
1508 pub fn type_interface_dep(&self, id: TypeId) -> Option<InterfaceId> {
1514 let ty = &self.types[id];
1515 let dep = match ty.kind {
1516 TypeDefKind::Type(Type::Id(id)) => id,
1517 _ => return None,
1518 };
1519 let other = &self.types[dep];
1520 if ty.owner == other.owner {
1521 None
1522 } else {
1523 match other.owner {
1524 TypeOwner::Interface(id) => Some(id),
1525 _ => unreachable!(),
1526 }
1527 }
1528 }
1529
1530 pub fn interface_direct_deps(&self, id: InterfaceId) -> impl Iterator<Item = InterfaceId> + '_ {
1540 self.interfaces[id]
1541 .types
1542 .iter()
1543 .filter_map(move |(_name, ty)| self.type_interface_dep(*ty))
1544 }
1545
1546 pub fn package_direct_deps(&self, id: PackageId) -> impl Iterator<Item = PackageId> + '_ {
1556 let pkg = &self.packages[id];
1557
1558 pkg.interfaces
1559 .iter()
1560 .flat_map(move |(_name, id)| self.interface_direct_deps(*id))
1561 .chain(pkg.worlds.iter().flat_map(move |(_name, id)| {
1562 let world = &self.worlds[*id];
1563 world
1564 .imports
1565 .iter()
1566 .chain(world.exports.iter())
1567 .filter_map(move |(_name, item)| match item {
1568 WorldItem::Interface { id, .. } => Some(*id),
1569 WorldItem::Function(_) => None,
1570 WorldItem::Type(t) => self.type_interface_dep(*t),
1571 })
1572 }))
1573 .filter_map(move |iface_id| {
1574 let pkg = self.interfaces[iface_id].package?;
1575 if pkg == id { None } else { Some(pkg) }
1576 })
1577 }
1578
1579 pub fn topological_packages(&self) -> Vec<PackageId> {
1585 let mut pushed = vec![false; self.packages.len()];
1586 let mut order = Vec::new();
1587 for (id, _) in self.packages.iter() {
1588 self.build_topological_package_ordering(id, &mut pushed, &mut order);
1589 }
1590 order
1591 }
1592
1593 fn build_topological_package_ordering(
1594 &self,
1595 id: PackageId,
1596 pushed: &mut Vec<bool>,
1597 order: &mut Vec<PackageId>,
1598 ) {
1599 if pushed[id.index()] {
1600 return;
1601 }
1602 for dep in self.package_direct_deps(id) {
1603 self.build_topological_package_ordering(dep, pushed, order);
1604 }
1605 order.push(id);
1606 pushed[id.index()] = true;
1607 }
1608
1609 #[doc(hidden)]
1610 pub fn assert_valid(&self) {
1611 let mut package_interfaces = Vec::new();
1612 let mut package_worlds = Vec::new();
1613 for (id, pkg) in self.packages.iter() {
1614 let mut interfaces = HashSet::new();
1615 for (name, iface) in pkg.interfaces.iter() {
1616 assert!(interfaces.insert(*iface));
1617 let iface = &self.interfaces[*iface];
1618 assert_eq!(name, iface.name.as_ref().unwrap());
1619 assert_eq!(iface.package.unwrap(), id);
1620 }
1621 package_interfaces.push(pkg.interfaces.values().copied().collect::<HashSet<_>>());
1622 let mut worlds = HashSet::new();
1623 for (name, world) in pkg.worlds.iter() {
1624 assert!(worlds.insert(*world));
1625 assert_eq!(
1626 pkg.worlds.get_key_value(name),
1627 Some((name, world)),
1628 "`MutableKeys` impl may have been used to change a key's hash or equality"
1629 );
1630 let world = &self.worlds[*world];
1631 assert_eq!(*name, world.name);
1632 assert_eq!(world.package.unwrap(), id);
1633 }
1634 package_worlds.push(pkg.worlds.values().copied().collect::<HashSet<_>>());
1635 }
1636
1637 let mut interface_types = Vec::new();
1638 for (id, iface) in self.interfaces.iter() {
1639 assert!(self.packages.get(iface.package.unwrap()).is_some());
1640 if iface.name.is_some() {
1641 assert!(package_interfaces[iface.package.unwrap().index()].contains(&id));
1642 }
1643
1644 for (name, ty) in iface.types.iter() {
1645 let ty = &self.types[*ty];
1646 assert_eq!(ty.name.as_ref(), Some(name));
1647 assert_eq!(ty.owner, TypeOwner::Interface(id));
1648 }
1649 interface_types.push(iface.types.values().copied().collect::<HashSet<_>>());
1650 for (name, f) in iface.functions.iter() {
1651 assert_eq!(*name, f.name);
1652 }
1653 }
1654
1655 let mut world_types = Vec::new();
1656 for (id, world) in self.worlds.iter() {
1657 log::debug!("validating world {}", &world.name);
1658 if let Some(package) = world.package {
1659 assert!(self.packages.get(package).is_some());
1660 assert!(package_worlds[package.index()].contains(&id));
1661 }
1662 assert!(world.includes.is_empty());
1663
1664 let mut types = HashSet::new();
1665 for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1666 log::debug!("validating world item: {}", self.name_world_key(name));
1667 match item {
1668 WorldItem::Interface { id, .. } => {
1669 if matches!(name, WorldKey::Name(_)) {
1672 assert_eq!(self.interfaces[*id].package, world.package);
1673 }
1674 }
1675 WorldItem::Function(f) => {
1676 assert!(!matches!(name, WorldKey::Interface(_)));
1677 assert_eq!(f.name, name.clone().unwrap_name());
1678 }
1679 WorldItem::Type(ty) => {
1680 assert!(!matches!(name, WorldKey::Interface(_)));
1681 assert!(types.insert(*ty));
1682 let ty = &self.types[*ty];
1683 assert_eq!(ty.name, Some(name.clone().unwrap_name()));
1684 assert_eq!(ty.owner, TypeOwner::World(id));
1685 }
1686 }
1687 }
1688 self.assert_world_elaborated(world);
1689 world_types.push(types);
1690 }
1691
1692 for (ty_id, ty) in self.types.iter() {
1693 match ty.owner {
1694 TypeOwner::Interface(id) => {
1695 assert!(self.interfaces.get(id).is_some());
1696 assert!(interface_types[id.index()].contains(&ty_id));
1697 }
1698 TypeOwner::World(id) => {
1699 assert!(self.worlds.get(id).is_some());
1700 assert!(world_types[id.index()].contains(&ty_id));
1701 }
1702 TypeOwner::None => {}
1703 }
1704 }
1705
1706 self.assert_topologically_sorted();
1707 }
1708
1709 fn assert_topologically_sorted(&self) {
1710 let mut positions = IndexMap::new();
1711 for id in self.topological_packages() {
1712 let pkg = &self.packages[id];
1713 log::debug!("pkg {}", pkg.name);
1714 let prev = positions.insert(Some(id), IndexSet::new());
1715 assert!(prev.is_none());
1716 }
1717 positions.insert(None, IndexSet::new());
1718
1719 for (id, iface) in self.interfaces.iter() {
1720 log::debug!("iface {:?}", iface.name);
1721 let ok = positions.get_mut(&iface.package).unwrap().insert(id);
1722 assert!(ok);
1723 }
1724
1725 for (_, world) in self.worlds.iter() {
1726 log::debug!("world {:?}", world.name);
1727
1728 let my_package = world.package;
1729 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1730
1731 for (_, item) in world.imports.iter().chain(&world.exports) {
1732 let id = match item {
1733 WorldItem::Interface { id, .. } => *id,
1734 _ => continue,
1735 };
1736 let other_package = self.interfaces[id].package;
1737 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1738
1739 assert!(other_package_pos <= my_package_pos);
1740 }
1741 }
1742
1743 for (_id, ty) in self.types.iter() {
1744 log::debug!("type {:?} {:?}", ty.name, ty.owner);
1745 let other_id = match ty.kind {
1746 TypeDefKind::Type(Type::Id(ty)) => ty,
1747 _ => continue,
1748 };
1749 let other = &self.types[other_id];
1750 if ty.kind == other.kind {
1751 continue;
1752 }
1753 let my_interface = match ty.owner {
1754 TypeOwner::Interface(id) => id,
1755 _ => continue,
1756 };
1757 let other_interface = match other.owner {
1758 TypeOwner::Interface(id) => id,
1759 _ => continue,
1760 };
1761
1762 let my_package = self.interfaces[my_interface].package;
1763 let other_package = self.interfaces[other_interface].package;
1764 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1765 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1766
1767 if my_package_pos == other_package_pos {
1768 let interfaces = &positions[&my_package];
1769 let my_interface_pos = interfaces.get_index_of(&my_interface).unwrap();
1770 let other_interface_pos = interfaces.get_index_of(&other_interface).unwrap();
1771 assert!(other_interface_pos <= my_interface_pos);
1772 } else {
1773 assert!(other_package_pos < my_package_pos);
1774 }
1775 }
1776 }
1777
1778 fn assert_world_elaborated(&self, world: &World) {
1779 for (key, item) in world.imports.iter() {
1780 log::debug!(
1781 "asserting elaborated world import {}",
1782 self.name_world_key(key)
1783 );
1784 match item {
1785 WorldItem::Type(t) => self.assert_world_imports_type_deps(world, key, *t),
1786
1787 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1789
1790 WorldItem::Interface { id, .. } => {
1792 for dep in self.interface_direct_deps(*id) {
1793 assert!(
1794 world.imports.contains_key(&WorldKey::Interface(dep)),
1795 "world import of {} is missing transitive dep of {}",
1796 self.name_world_key(key),
1797 self.id_of(dep).unwrap(),
1798 );
1799 }
1800 }
1801 }
1802 }
1803 for (key, item) in world.exports.iter() {
1804 log::debug!(
1805 "asserting elaborated world export {}",
1806 self.name_world_key(key)
1807 );
1808 match item {
1809 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1811
1812 WorldItem::Interface { id, .. } => {
1816 for dep in self.interface_direct_deps(*id) {
1817 let dep_key = WorldKey::Interface(dep);
1818 if world.exports.contains_key(&dep_key) {
1819 continue;
1820 }
1821 self.foreach_interface_dep(dep, &mut |dep| {
1822 let dep_key = WorldKey::Interface(dep);
1823 assert!(
1824 world.imports.contains_key(&dep_key),
1825 "world should import {} (required by {})",
1826 self.name_world_key(&dep_key),
1827 self.name_world_key(key),
1828 );
1829 assert!(
1830 !world.exports.contains_key(&dep_key),
1831 "world should not export {} (required by {})",
1832 self.name_world_key(&dep_key),
1833 self.name_world_key(key),
1834 );
1835 });
1836 }
1837 }
1838
1839 WorldItem::Type(_) => unreachable!(),
1841 }
1842 }
1843 }
1844
1845 fn assert_world_imports_type_deps(&self, world: &World, key: &WorldKey, ty: TypeId) {
1846 let ty = &self.types[ty];
1849 if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
1850 if let TypeOwner::Interface(id) = self.types[other].owner {
1851 let key = WorldKey::Interface(id);
1852 assert!(world.imports.contains_key(&key));
1853 return;
1854 }
1855 }
1856
1857 let mut visitor = MyVisit(self, Vec::new());
1861 visitor.visit_type_def(self, ty);
1862 for ty in visitor.1 {
1863 let ty = &self.types[ty];
1864 let Some(name) = ty.name.clone() else {
1865 continue;
1866 };
1867 let dep_key = WorldKey::Name(name);
1868 assert!(
1869 world.imports.contains_key(&dep_key),
1870 "world import `{}` should also force an import of `{}`",
1871 self.name_world_key(key),
1872 self.name_world_key(&dep_key),
1873 );
1874 }
1875
1876 struct MyVisit<'a>(&'a Resolve, Vec<TypeId>);
1877
1878 impl TypeIdVisitor for MyVisit<'_> {
1879 fn before_visit_type_id(&mut self, id: TypeId) -> bool {
1880 self.1.push(id);
1881 self.0.types[id].name.is_none()
1883 }
1884 }
1885 }
1886
1887 fn assert_world_function_imports_types(&self, world: &World, key: &WorldKey, func: &Function) {
1891 for ty in func
1892 .parameter_and_result_types()
1893 .chain(func.kind.resource().map(Type::Id))
1894 {
1895 let Type::Id(id) = ty else {
1896 continue;
1897 };
1898 self.assert_world_imports_type_deps(world, key, id);
1899 }
1900 }
1901
1902 fn include_stability(
1918 &self,
1919 stability: &Stability,
1920 pkg_id: &PackageId,
1921 span: Option<Span>,
1922 ) -> Result<bool> {
1923 let err = |msg: String| match span {
1924 Some(span) => Error::new(span, msg).into(),
1925 None => anyhow::Error::msg(msg),
1926 };
1927 Ok(match stability {
1928 Stability::Unknown => true,
1929 Stability::Stable { since, .. } => {
1932 let Some(p) = self.packages.get(*pkg_id) else {
1933 return Ok(true);
1941 };
1942
1943 let package_version = p.name.version.as_ref().ok_or_else(|| {
1946 err(format!(
1947 "package [{}] contains a feature gate with a version \
1948 specifier, so it must have a version",
1949 p.name
1950 ))
1951 })?;
1952
1953 if since > package_version {
1957 return Err(err(format!(
1958 "feature gate cannot reference unreleased version \
1959 {since} of package [{}] (current version {package_version})",
1960 p.name
1961 )));
1962 }
1963
1964 true
1965 }
1966 Stability::Unstable { feature, .. } => {
1967 self.features.contains(feature) || self.all_features
1968 }
1969 })
1970 }
1971
1972 fn include_type(&self, ty: &TypeDef, pkgid: PackageId, span: Span) -> Result<bool> {
1975 self.include_stability(&ty.stability, &pkgid, Some(span))
1976 .with_context(|| {
1977 format!(
1978 "failed to process feature gate for type [{}] in package [{}]",
1979 ty.name.as_ref().map(String::as_str).unwrap_or("<unknown>"),
1980 self.packages[pkgid].name,
1981 )
1982 })
1983 }
1984
1985 fn elaborate_world(&mut self, world_id: WorldId) -> Result<()> {
1997 let mut new_imports = IndexMap::new();
2001 let world = &self.worlds[world_id];
2002
2003 let sort_key = |resolve: &Resolve, item: &WorldItem| match item {
2026 WorldItem::Interface { .. } => 0,
2027 WorldItem::Type(ty) => {
2028 let ty = &resolve.types[*ty];
2029 match ty.kind {
2030 TypeDefKind::Type(Type::Id(t)) if resolve.types[t].owner != ty.owner => 1,
2031 _ => 2,
2032 }
2033 }
2034 WorldItem::Function(f) => {
2035 if f.kind.resource().is_none() {
2036 3
2037 } else {
2038 4
2039 }
2040 }
2041 };
2042
2043 let mut world_imports = world.imports.iter().collect::<Vec<_>>();
2046 world_imports.sort_by_key(|(_name, import)| sort_key(self, import));
2047 for (name, item) in world_imports {
2048 match item {
2049 WorldItem::Interface { id, stability } => {
2052 self.elaborate_world_import(&mut new_imports, name.clone(), *id, &stability);
2053 }
2054
2055 WorldItem::Function(_) => {
2058 let prev = new_imports.insert(name.clone(), item.clone());
2059 assert!(prev.is_none());
2060 }
2061
2062 WorldItem::Type(id) => {
2066 if let Some(dep) = self.type_interface_dep(*id) {
2067 self.elaborate_world_import(
2068 &mut new_imports,
2069 WorldKey::Interface(dep),
2070 dep,
2071 &self.types[*id].stability,
2072 );
2073 }
2074 let prev = new_imports.insert(name.clone(), item.clone());
2075 assert!(prev.is_none());
2076 }
2077 }
2078 }
2079
2080 let mut new_exports = IndexMap::new();
2086 let mut export_interfaces = IndexMap::new();
2087 for (name, item) in world.exports.iter() {
2088 match item {
2089 WorldItem::Interface { id, stability } => {
2090 let prev = export_interfaces.insert(*id, (name.clone(), stability));
2091 assert!(prev.is_none());
2092 }
2093 WorldItem::Function(_) => {
2094 let prev = new_exports.insert(name.clone(), item.clone());
2095 assert!(prev.is_none());
2096 }
2097 WorldItem::Type(_) => unreachable!(),
2098 }
2099 }
2100
2101 self.elaborate_world_exports(&export_interfaces, &mut new_imports, &mut new_exports)?;
2102
2103 new_imports.sort_by_cached_key(|_name, import| sort_key(self, import));
2107
2108 log::trace!("imports = {new_imports:?}");
2111 log::trace!("exports = {new_exports:?}");
2112 let world = &mut self.worlds[world_id];
2113 world.imports = new_imports;
2114 world.exports = new_exports;
2115
2116 Ok(())
2117 }
2118
2119 fn elaborate_world_import(
2120 &self,
2121 imports: &mut IndexMap<WorldKey, WorldItem>,
2122 key: WorldKey,
2123 id: InterfaceId,
2124 stability: &Stability,
2125 ) {
2126 if imports.contains_key(&key) {
2127 return;
2128 }
2129 for dep in self.interface_direct_deps(id) {
2130 self.elaborate_world_import(imports, WorldKey::Interface(dep), dep, stability);
2131 }
2132 let prev = imports.insert(
2133 key,
2134 WorldItem::Interface {
2135 id,
2136 stability: stability.clone(),
2137 },
2138 );
2139 assert!(prev.is_none());
2140 }
2141
2142 fn elaborate_world_exports(
2189 &self,
2190 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2191 imports: &mut IndexMap<WorldKey, WorldItem>,
2192 exports: &mut IndexMap<WorldKey, WorldItem>,
2193 ) -> Result<()> {
2194 let mut required_imports = HashSet::new();
2195 for (id, (key, stability)) in export_interfaces.iter() {
2196 let name = self.name_world_key(&key);
2197 let ok = add_world_export(
2198 self,
2199 imports,
2200 exports,
2201 export_interfaces,
2202 &mut required_imports,
2203 *id,
2204 key,
2205 true,
2206 stability,
2207 );
2208 if !ok {
2209 bail!(
2210 InvalidTransitiveDependency(name),
2228 );
2229 }
2230 }
2231 return Ok(());
2232
2233 fn add_world_export(
2234 resolve: &Resolve,
2235 imports: &mut IndexMap<WorldKey, WorldItem>,
2236 exports: &mut IndexMap<WorldKey, WorldItem>,
2237 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2238 required_imports: &mut HashSet<InterfaceId>,
2239 id: InterfaceId,
2240 key: &WorldKey,
2241 add_export: bool,
2242 stability: &Stability,
2243 ) -> bool {
2244 if exports.contains_key(key) {
2245 if add_export {
2246 return true;
2247 } else {
2248 return false;
2249 }
2250 }
2251 if !add_export && required_imports.contains(&id) {
2254 return true;
2255 }
2256 let ok = resolve.interface_direct_deps(id).all(|dep| {
2257 let key = WorldKey::Interface(dep);
2258 let add_export = add_export && export_interfaces.contains_key(&dep);
2259 add_world_export(
2260 resolve,
2261 imports,
2262 exports,
2263 export_interfaces,
2264 required_imports,
2265 dep,
2266 &key,
2267 add_export,
2268 stability,
2269 )
2270 });
2271 if !ok {
2272 return false;
2273 }
2274 let item = WorldItem::Interface {
2275 id,
2276 stability: stability.clone(),
2277 };
2278 if add_export {
2279 if required_imports.contains(&id) {
2280 return false;
2281 }
2282 exports.insert(key.clone(), item);
2283 } else {
2284 required_imports.insert(id);
2285 imports.insert(key.clone(), item);
2286 }
2287 true
2288 }
2289 }
2290
2291 pub fn merge_world_imports_based_on_semver(&mut self, world_id: WorldId) -> Result<()> {
2303 let world = &self.worlds[world_id];
2304
2305 let mut semver_tracks = HashMap::new();
2314 let mut to_remove = HashSet::new();
2315 for (key, _) in world.imports.iter() {
2316 let iface_id = match key {
2317 WorldKey::Interface(id) => *id,
2318 WorldKey::Name(_) => continue,
2319 };
2320 let (track, version) = match self.semver_track(iface_id) {
2321 Some(track) => track,
2322 None => continue,
2323 };
2324 log::debug!(
2325 "{} is on track {}/{}",
2326 self.id_of(iface_id).unwrap(),
2327 track.0,
2328 track.1,
2329 );
2330 match semver_tracks.entry(track.clone()) {
2331 hash_map::Entry::Vacant(e) => {
2332 e.insert((version, iface_id));
2333 }
2334 hash_map::Entry::Occupied(mut e) => match version.cmp(&e.get().0) {
2335 Ordering::Greater => {
2336 to_remove.insert(e.get().1);
2337 e.insert((version, iface_id));
2338 }
2339 Ordering::Equal => {}
2340 Ordering::Less => {
2341 to_remove.insert(iface_id);
2342 }
2343 },
2344 }
2345 }
2346
2347 let mut replacements = HashMap::new();
2350 for id in to_remove {
2351 let (track, _) = self.semver_track(id).unwrap();
2352 let (_, latest) = semver_tracks[&track];
2353 let prev = replacements.insert(id, latest);
2354 assert!(prev.is_none());
2355 }
2356
2357 for (to_replace, replace_with) in replacements.iter() {
2362 self.merge_world_item(
2363 &WorldItem::Interface {
2364 id: *to_replace,
2365 stability: Default::default(),
2366 },
2367 &WorldItem::Interface {
2368 id: *replace_with,
2369 stability: Default::default(),
2370 },
2371 )
2372 .with_context(|| {
2373 let old_name = self.id_of(*to_replace).unwrap();
2374 let new_name = self.id_of(*replace_with).unwrap();
2375 format!(
2376 "failed to upgrade `{old_name}` to `{new_name}`, was \
2377 this semver-compatible update not semver compatible?"
2378 )
2379 })?;
2380 }
2381
2382 for (to_replace, replace_with) in replacements.iter() {
2383 log::debug!(
2384 "REPLACE {} => {}",
2385 self.id_of(*to_replace).unwrap(),
2386 self.id_of(*replace_with).unwrap(),
2387 );
2388 }
2389
2390 for (key, item) in mem::take(&mut self.worlds[world_id].imports) {
2399 if let WorldItem::Interface { id, .. } = item {
2400 if replacements.contains_key(&id) {
2401 continue;
2402 }
2403 }
2404
2405 self.update_interface_deps_of_world_item(&item, &replacements);
2406
2407 let prev = self.worlds[world_id].imports.insert(key, item);
2408 assert!(prev.is_none());
2409 }
2410 for (key, item) in mem::take(&mut self.worlds[world_id].exports) {
2411 self.update_interface_deps_of_world_item(&item, &replacements);
2412 let prev = self.worlds[world_id].exports.insert(key, item);
2413 assert!(prev.is_none());
2414 }
2415
2416 let ids = self.worlds.iter().map(|(id, _)| id).collect::<Vec<_>>();
2422 for world_id in ids {
2423 self.elaborate_world(world_id).with_context(|| {
2424 let name = &self.worlds[world_id].name;
2425 format!(
2426 "failed to elaborate world `{name}` after deduplicating imports \
2427 based on semver"
2428 )
2429 })?;
2430 }
2431
2432 #[cfg(debug_assertions)]
2433 self.assert_valid();
2434
2435 Ok(())
2436 }
2437
2438 fn update_interface_deps_of_world_item(
2439 &mut self,
2440 item: &WorldItem,
2441 replacements: &HashMap<InterfaceId, InterfaceId>,
2442 ) {
2443 match *item {
2444 WorldItem::Type(t) => self.update_interface_dep_of_type(t, &replacements),
2445 WorldItem::Interface { id, .. } => {
2446 let types = self.interfaces[id]
2447 .types
2448 .values()
2449 .copied()
2450 .collect::<Vec<_>>();
2451 for ty in types {
2452 self.update_interface_dep_of_type(ty, &replacements);
2453 }
2454 }
2455 WorldItem::Function(_) => {}
2456 }
2457 }
2458
2459 fn semver_track(&self, id: InterfaceId) -> Option<((PackageName, String), &Version)> {
2470 let iface = &self.interfaces[id];
2471 let pkg = &self.packages[iface.package?];
2472 let version = pkg.name.version.as_ref()?;
2473 let mut name = pkg.name.clone();
2474 name.version = Some(PackageName::version_compat_track(version));
2475 Some(((name, iface.name.clone()?), version))
2476 }
2477
2478 fn update_interface_dep_of_type(
2482 &mut self,
2483 ty: TypeId,
2484 replacements: &HashMap<InterfaceId, InterfaceId>,
2485 ) {
2486 let to_replace = match self.type_interface_dep(ty) {
2487 Some(id) => id,
2488 None => return,
2489 };
2490 let replace_with = match replacements.get(&to_replace) {
2491 Some(id) => id,
2492 None => return,
2493 };
2494 let dep = match self.types[ty].kind {
2495 TypeDefKind::Type(Type::Id(id)) => id,
2496 _ => return,
2497 };
2498 let name = self.types[dep].name.as_ref().unwrap();
2499 let replacement_id = self.interfaces[*replace_with].types[name];
2502 self.types[ty].kind = TypeDefKind::Type(Type::Id(replacement_id));
2503 }
2504
2505 pub fn wasm_import_name(
2512 &self,
2513 mangling: ManglingAndAbi,
2514 import: WasmImport<'_>,
2515 ) -> (String, String) {
2516 match mangling {
2517 ManglingAndAbi::Standard32 => match import {
2518 WasmImport::Func { interface, func } => {
2519 let module = match interface {
2520 Some(key) => format!("cm32p2|{}", self.name_canonicalized_world_key(key)),
2521 None => format!("cm32p2"),
2522 };
2523 (module, func.name.clone())
2524 }
2525 WasmImport::ResourceIntrinsic {
2526 interface,
2527 resource,
2528 intrinsic,
2529 } => {
2530 let name = self.types[resource].name.as_ref().unwrap();
2531 let (prefix, name) = match intrinsic {
2532 ResourceIntrinsic::ImportedDrop => ("", format!("{name}_drop")),
2533 ResourceIntrinsic::ExportedDrop => ("_ex_", format!("{name}_drop")),
2534 ResourceIntrinsic::ExportedNew => ("_ex_", format!("{name}_new")),
2535 ResourceIntrinsic::ExportedRep => ("_ex_", format!("{name}_rep")),
2536 };
2537 let module = match interface {
2538 Some(key) => {
2539 format!("cm32p2|{prefix}{}", self.name_canonicalized_world_key(key))
2540 }
2541 None => {
2542 assert_eq!(prefix, "");
2543 format!("cm32p2")
2544 }
2545 };
2546 (module, name)
2547 }
2548 },
2549 ManglingAndAbi::Legacy(abi) => match import {
2550 WasmImport::Func { interface, func } => {
2551 let module = match interface {
2552 Some(key) => self.name_world_key(key),
2553 None => format!("$root"),
2554 };
2555 (module, format!("{}{}", abi.import_prefix(), func.name))
2556 }
2557 WasmImport::ResourceIntrinsic {
2558 interface,
2559 resource,
2560 intrinsic,
2561 } => {
2562 let name = self.types[resource].name.as_ref().unwrap();
2563 let (prefix, name) = match intrinsic {
2564 ResourceIntrinsic::ImportedDrop => ("", format!("[resource-drop]{name}")),
2565 ResourceIntrinsic::ExportedDrop => {
2566 ("[export]", format!("[resource-drop]{name}"))
2567 }
2568 ResourceIntrinsic::ExportedNew => {
2569 ("[export]", format!("[resource-new]{name}"))
2570 }
2571 ResourceIntrinsic::ExportedRep => {
2572 ("[export]", format!("[resource-rep]{name}"))
2573 }
2574 };
2575 let module = match interface {
2576 Some(key) => format!("{prefix}{}", self.name_world_key(key)),
2577 None => {
2578 assert_eq!(prefix, "");
2579 format!("$root")
2580 }
2581 };
2582 (module, format!("{}{name}", abi.import_prefix()))
2583 }
2584 },
2585 }
2586 }
2587
2588 pub fn wasm_export_name(&self, mangling: ManglingAndAbi, export: WasmExport<'_>) -> String {
2592 match mangling {
2593 ManglingAndAbi::Standard32 => match export {
2594 WasmExport::Func {
2595 interface,
2596 func,
2597 kind,
2598 } => {
2599 let mut name = String::from("cm32p2|");
2600 if let Some(interface) = interface {
2601 let s = self.name_canonicalized_world_key(interface);
2602 name.push_str(&s);
2603 }
2604 name.push_str("|");
2605 name.push_str(&func.name);
2606 match kind {
2607 WasmExportKind::Normal => {}
2608 WasmExportKind::PostReturn => name.push_str("_post"),
2609 WasmExportKind::Callback => todo!(
2610 "not yet supported: \
2611 async callback functions using standard name mangling"
2612 ),
2613 }
2614 name
2615 }
2616 WasmExport::ResourceDtor {
2617 interface,
2618 resource,
2619 } => {
2620 let name = self.types[resource].name.as_ref().unwrap();
2621 let interface = self.name_canonicalized_world_key(interface);
2622 format!("cm32p2|{interface}|{name}_dtor")
2623 }
2624 WasmExport::Memory => "cm32p2_memory".to_string(),
2625 WasmExport::Initialize => "cm32p2_initialize".to_string(),
2626 WasmExport::Realloc => "cm32p2_realloc".to_string(),
2627 },
2628 ManglingAndAbi::Legacy(abi) => match export {
2629 WasmExport::Func {
2630 interface,
2631 func,
2632 kind,
2633 } => {
2634 let mut name = abi.export_prefix().to_string();
2635 match kind {
2636 WasmExportKind::Normal => {}
2637 WasmExportKind::PostReturn => name.push_str("cabi_post_"),
2638 WasmExportKind::Callback => {
2639 assert!(matches!(abi, LiftLowerAbi::AsyncCallback));
2640 name = format!("[callback]{name}")
2641 }
2642 }
2643 if let Some(interface) = interface {
2644 let s = self.name_world_key(interface);
2645 name.push_str(&s);
2646 name.push_str("#");
2647 }
2648 name.push_str(&func.name);
2649 name
2650 }
2651 WasmExport::ResourceDtor {
2652 interface,
2653 resource,
2654 } => {
2655 let name = self.types[resource].name.as_ref().unwrap();
2656 let interface = self.name_world_key(interface);
2657 format!("{}{interface}#[dtor]{name}", abi.export_prefix())
2658 }
2659 WasmExport::Memory => "memory".to_string(),
2660 WasmExport::Initialize => "_initialize".to_string(),
2661 WasmExport::Realloc => "cabi_realloc".to_string(),
2662 },
2663 }
2664 }
2665}
2666
2667#[derive(Debug)]
2669pub enum WasmImport<'a> {
2670 Func {
2672 interface: Option<&'a WorldKey>,
2677
2678 func: &'a Function,
2680 },
2681
2682 ResourceIntrinsic {
2684 interface: Option<&'a WorldKey>,
2686
2687 resource: TypeId,
2689
2690 intrinsic: ResourceIntrinsic,
2692 },
2693}
2694
2695#[derive(Debug)]
2698pub enum ResourceIntrinsic {
2699 ImportedDrop,
2700 ExportedDrop,
2701 ExportedNew,
2702 ExportedRep,
2703}
2704
2705#[derive(Debug)]
2708pub enum WasmExportKind {
2709 Normal,
2711
2712 PostReturn,
2714
2715 Callback,
2717}
2718
2719#[derive(Debug)]
2722pub enum WasmExport<'a> {
2723 Func {
2725 interface: Option<&'a WorldKey>,
2728
2729 func: &'a Function,
2731
2732 kind: WasmExportKind,
2734 },
2735
2736 ResourceDtor {
2738 interface: &'a WorldKey,
2740 resource: TypeId,
2742 },
2743
2744 Memory,
2746
2747 Initialize,
2749
2750 Realloc,
2752}
2753
2754#[derive(Default)]
2757pub struct Remap {
2758 pub types: Vec<Option<TypeId>>,
2759 pub interfaces: Vec<Option<InterfaceId>>,
2760 pub worlds: Vec<Option<WorldId>>,
2761 pub packages: Vec<PackageId>,
2762
2763 own_handles: HashMap<TypeId, TypeId>,
2773
2774 type_has_borrow: Vec<Option<bool>>,
2775}
2776
2777fn apply_map<T>(map: &[Option<Id<T>>], id: Id<T>, desc: &str, span: Option<Span>) -> Result<Id<T>> {
2778 match map.get(id.index()) {
2779 Some(Some(id)) => Ok(*id),
2780 Some(None) => {
2781 let msg = format!(
2782 "found a reference to a {desc} which is excluded \
2783 due to its feature not being activated"
2784 );
2785 match span {
2786 Some(span) => Err(Error::new(span, msg).into()),
2787 None => bail!("{msg}"),
2788 }
2789 }
2790 None => panic!("request to remap a {desc} that has not yet been registered"),
2791 }
2792}
2793
2794fn rename(original_name: &str, include_name: &IncludeName) -> Option<String> {
2795 if original_name == include_name.name {
2796 return Some(include_name.as_.to_string());
2797 }
2798 let (kind, rest) = original_name.split_once(']')?;
2799 match rest.split_once('.') {
2800 Some((name, rest)) if name == include_name.name => {
2801 Some(format!("{kind}]{}.{rest}", include_name.as_))
2802 }
2803 _ if rest == include_name.name => Some(format!("{kind}]{}", include_name.as_)),
2804 _ => None,
2805 }
2806}
2807
2808impl Remap {
2809 pub fn map_type(&self, id: TypeId, span: Option<Span>) -> Result<TypeId> {
2810 apply_map(&self.types, id, "type", span)
2811 }
2812
2813 pub fn map_interface(&self, id: InterfaceId, span: Option<Span>) -> Result<InterfaceId> {
2814 apply_map(&self.interfaces, id, "interface", span)
2815 }
2816
2817 pub fn map_world(&self, id: WorldId, span: Option<Span>) -> Result<WorldId> {
2818 apply_map(&self.worlds, id, "world", span)
2819 }
2820
2821 fn append(
2822 &mut self,
2823 resolve: &mut Resolve,
2824 unresolved: UnresolvedPackage,
2825 ) -> Result<PackageId> {
2826 let pkgid = resolve.packages.alloc(Package {
2827 name: unresolved.name.clone(),
2828 docs: unresolved.docs.clone(),
2829 interfaces: Default::default(),
2830 worlds: Default::default(),
2831 });
2832 let prev = resolve.package_names.insert(unresolved.name.clone(), pkgid);
2833 if let Some(prev) = prev {
2834 resolve.package_names.insert(unresolved.name.clone(), prev);
2835 bail!(
2836 "attempting to re-add package `{}` when it's already present in this `Resolve`",
2837 unresolved.name,
2838 );
2839 }
2840
2841 self.process_foreign_deps(resolve, pkgid, &unresolved)?;
2842
2843 let foreign_types = self.types.len();
2844 let foreign_interfaces = self.interfaces.len();
2845 let foreign_worlds = self.worlds.len();
2846
2847 assert_eq!(unresolved.types.len(), unresolved.type_spans.len());
2853 for ((id, mut ty), span) in unresolved
2854 .types
2855 .into_iter()
2856 .zip(&unresolved.type_spans)
2857 .skip(foreign_types)
2858 {
2859 if !resolve.include_type(&ty, pkgid, *span)? {
2860 self.types.push(None);
2861 continue;
2862 }
2863
2864 self.update_typedef(resolve, &mut ty, Some(*span))?;
2865 let new_id = resolve.types.alloc(ty);
2866 assert_eq!(self.types.len(), id.index());
2867
2868 let new_id = match resolve.types[new_id] {
2869 TypeDef {
2874 name: None,
2875 owner: TypeOwner::None,
2876 kind: TypeDefKind::Handle(Handle::Own(id)),
2877 docs: _,
2878 stability: _,
2879 } => *self.own_handles.entry(id).or_insert(new_id),
2880
2881 _ => new_id,
2884 };
2885 self.types.push(Some(new_id));
2886 }
2887
2888 assert_eq!(
2891 unresolved.interfaces.len(),
2892 unresolved.interface_spans.len()
2893 );
2894 for ((id, mut iface), span) in unresolved
2895 .interfaces
2896 .into_iter()
2897 .zip(&unresolved.interface_spans)
2898 .skip(foreign_interfaces)
2899 {
2900 if !resolve
2901 .include_stability(&iface.stability, &pkgid, Some(span.span))
2902 .with_context(|| {
2903 format!(
2904 "failed to process feature gate for interface [{}] in package [{}]",
2905 iface
2906 .name
2907 .as_ref()
2908 .map(String::as_str)
2909 .unwrap_or("<unknown>"),
2910 resolve.packages[pkgid].name,
2911 )
2912 })?
2913 {
2914 self.interfaces.push(None);
2915 continue;
2916 }
2917 assert!(iface.package.is_none());
2918 iface.package = Some(pkgid);
2919 self.update_interface(resolve, &mut iface, Some(span))?;
2920 let new_id = resolve.interfaces.alloc(iface);
2921 assert_eq!(self.interfaces.len(), id.index());
2922 self.interfaces.push(Some(new_id));
2923 }
2924
2925 for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2928 let id = match id {
2929 Some(id) => *id,
2930 None => continue,
2931 };
2932 match &mut resolve.types[id].owner {
2933 TypeOwner::Interface(id) => {
2934 let span = unresolved.type_spans[i];
2935 *id = self.map_interface(*id, Some(span))
2936 .with_context(|| {
2937 "this type is not gated by a feature but its interface is gated by a feature"
2938 })?;
2939 }
2940 TypeOwner::World(_) | TypeOwner::None => {}
2941 }
2942 }
2943
2944 assert_eq!(unresolved.worlds.len(), unresolved.world_spans.len());
2952 for ((id, mut world), span) in unresolved
2953 .worlds
2954 .into_iter()
2955 .zip(&unresolved.world_spans)
2956 .skip(foreign_worlds)
2957 {
2958 if !resolve
2959 .include_stability(&world.stability, &pkgid, Some(span.span))
2960 .with_context(|| {
2961 format!(
2962 "failed to process feature gate for world [{}] in package [{}]",
2963 world.name, resolve.packages[pkgid].name,
2964 )
2965 })?
2966 {
2967 self.worlds.push(None);
2968 continue;
2969 }
2970 self.update_world(&mut world, resolve, &pkgid, &span)?;
2971
2972 let new_id = resolve.worlds.alloc(world);
2973 assert_eq!(self.worlds.len(), id.index());
2974 self.worlds.push(Some(new_id));
2975 }
2976
2977 for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2979 let id = match id {
2980 Some(id) => *id,
2981 None => continue,
2982 };
2983 match &mut resolve.types[id].owner {
2984 TypeOwner::World(id) => {
2985 let span = unresolved.type_spans[i];
2986 *id = self.map_world(*id, Some(span))
2987 .with_context(|| {
2988 "this type is not gated by a feature but its interface is gated by a feature"
2989 })?;
2990 }
2991 TypeOwner::Interface(_) | TypeOwner::None => {}
2992 }
2993 }
2994
2995 assert_eq!(self.worlds.len(), unresolved.world_spans.len());
3012 for (id, span) in self
3013 .worlds
3014 .iter()
3015 .zip(unresolved.world_spans.iter())
3016 .skip(foreign_worlds)
3017 {
3018 let Some(id) = *id else {
3019 continue;
3020 };
3021 self.process_world_includes(id, resolve, &pkgid, &span)?;
3022
3023 resolve.elaborate_world(id).with_context(|| {
3024 Error::new(
3025 span.span,
3026 format!(
3027 "failed to elaborate world imports/exports of `{}`",
3028 resolve.worlds[id].name
3029 ),
3030 )
3031 })?;
3032 }
3033
3034 for id in self.interfaces.iter().skip(foreign_interfaces) {
3036 let id = match id {
3037 Some(id) => *id,
3038 None => continue,
3039 };
3040 let iface = &mut resolve.interfaces[id];
3041 iface.package = Some(pkgid);
3042 if let Some(name) = &iface.name {
3043 let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), id);
3044 assert!(prev.is_none());
3045 }
3046 }
3047 for id in self.worlds.iter().skip(foreign_worlds) {
3048 let id = match id {
3049 Some(id) => *id,
3050 None => continue,
3051 };
3052 let world = &mut resolve.worlds[id];
3053 world.package = Some(pkgid);
3054 let prev = resolve.packages[pkgid]
3055 .worlds
3056 .insert(world.name.clone(), id);
3057 assert!(prev.is_none());
3058 }
3059 Ok(pkgid)
3060 }
3061
3062 fn process_foreign_deps(
3063 &mut self,
3064 resolve: &mut Resolve,
3065 pkgid: PackageId,
3066 unresolved: &UnresolvedPackage,
3067 ) -> Result<()> {
3068 let mut world_to_package = HashMap::new();
3071 let mut interface_to_package = HashMap::new();
3072 for (i, (pkg_name, worlds_or_ifaces)) in unresolved.foreign_deps.iter().enumerate() {
3073 for (name, item) in worlds_or_ifaces {
3074 match item {
3075 AstItem::Interface(unresolved_interface_id) => {
3076 let prev = interface_to_package.insert(
3077 *unresolved_interface_id,
3078 (pkg_name, name, unresolved.foreign_dep_spans[i]),
3079 );
3080 assert!(prev.is_none());
3081 }
3082 AstItem::World(unresolved_world_id) => {
3083 let prev = world_to_package.insert(
3084 *unresolved_world_id,
3085 (pkg_name, name, unresolved.foreign_dep_spans[i]),
3086 );
3087 assert!(prev.is_none());
3088 }
3089 }
3090 }
3091 }
3092
3093 self.process_foreign_interfaces(unresolved, &interface_to_package, resolve)?;
3097
3098 self.process_foreign_worlds(unresolved, &world_to_package, resolve)?;
3102
3103 self.process_foreign_types(unresolved, pkgid, resolve)?;
3106
3107 for (id, span) in unresolved.required_resource_types.iter() {
3108 let Ok(mut id) = self.map_type(*id, Some(*span)) else {
3113 continue;
3114 };
3115 loop {
3116 match resolve.types[id].kind {
3117 TypeDefKind::Type(Type::Id(i)) => id = i,
3118 TypeDefKind::Resource => break,
3119 _ => bail!(Error::new(
3120 *span,
3121 format!("type used in a handle must be a resource"),
3122 )),
3123 }
3124 }
3125 }
3126
3127 #[cfg(debug_assertions)]
3128 resolve.assert_valid();
3129
3130 Ok(())
3131 }
3132
3133 fn process_foreign_interfaces(
3134 &mut self,
3135 unresolved: &UnresolvedPackage,
3136 interface_to_package: &HashMap<InterfaceId, (&PackageName, &String, Span)>,
3137 resolve: &mut Resolve,
3138 ) -> Result<(), anyhow::Error> {
3139 for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() {
3140 let (pkg_name, interface, span) = match interface_to_package.get(&unresolved_iface_id) {
3141 Some(items) => *items,
3142 None => break,
3146 };
3147 let pkgid = resolve
3148 .package_names
3149 .get(pkg_name)
3150 .copied()
3151 .ok_or_else(|| {
3152 PackageNotFoundError::new(
3153 span,
3154 pkg_name.clone(),
3155 resolve.package_names.keys().cloned().collect(),
3156 )
3157 })?;
3158
3159 assert!(unresolved_iface.functions.is_empty());
3161
3162 let pkg = &resolve.packages[pkgid];
3163 let span = &unresolved.interface_spans[unresolved_iface_id.index()];
3164 let iface_id = pkg
3165 .interfaces
3166 .get(interface)
3167 .copied()
3168 .ok_or_else(|| Error::new(span.span, "interface not found in package"))?;
3169 assert_eq!(self.interfaces.len(), unresolved_iface_id.index());
3170 self.interfaces.push(Some(iface_id));
3171 }
3172 for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) {
3173 assert!(
3174 interface_to_package.get(&id).is_none(),
3175 "found foreign interface after local interface"
3176 );
3177 }
3178 Ok(())
3179 }
3180
3181 fn process_foreign_worlds(
3182 &mut self,
3183 unresolved: &UnresolvedPackage,
3184 world_to_package: &HashMap<WorldId, (&PackageName, &String, Span)>,
3185 resolve: &mut Resolve,
3186 ) -> Result<(), anyhow::Error> {
3187 for (unresolved_world_id, _) in unresolved.worlds.iter() {
3188 let (pkg_name, world, span) = match world_to_package.get(&unresolved_world_id) {
3189 Some(items) => *items,
3190 None => break,
3193 };
3194
3195 let pkgid = resolve
3196 .package_names
3197 .get(pkg_name)
3198 .copied()
3199 .ok_or_else(|| Error::new(span, "package not found"))?;
3200 let pkg = &resolve.packages[pkgid];
3201 let span = &unresolved.world_spans[unresolved_world_id.index()];
3202 let world_id = pkg
3203 .worlds
3204 .get(world)
3205 .copied()
3206 .ok_or_else(|| Error::new(span.span, "world not found in package"))?;
3207 assert_eq!(self.worlds.len(), unresolved_world_id.index());
3208 self.worlds.push(Some(world_id));
3209 }
3210 for (id, _) in unresolved.worlds.iter().skip(self.worlds.len()) {
3211 assert!(
3212 world_to_package.get(&id).is_none(),
3213 "found foreign world after local world"
3214 );
3215 }
3216 Ok(())
3217 }
3218
3219 fn process_foreign_types(
3220 &mut self,
3221 unresolved: &UnresolvedPackage,
3222 pkgid: PackageId,
3223 resolve: &mut Resolve,
3224 ) -> Result<(), anyhow::Error> {
3225 for ((unresolved_type_id, unresolved_ty), span) in
3226 unresolved.types.iter().zip(&unresolved.type_spans)
3227 {
3228 match unresolved_ty.kind {
3232 TypeDefKind::Unknown => {}
3233 _ => break,
3234 }
3235
3236 if !resolve.include_type(unresolved_ty, pkgid, *span)? {
3237 self.types.push(None);
3238 continue;
3239 }
3240
3241 let unresolved_iface_id = match unresolved_ty.owner {
3242 TypeOwner::Interface(id) => id,
3243 _ => unreachable!(),
3244 };
3245 let iface_id = self.map_interface(unresolved_iface_id, None)?;
3246 let name = unresolved_ty.name.as_ref().unwrap();
3247 let span = unresolved.unknown_type_spans[unresolved_type_id.index()];
3248 let type_id = *resolve.interfaces[iface_id]
3249 .types
3250 .get(name)
3251 .ok_or_else(|| {
3252 Error::new(span, format!("type `{name}` not defined in interface"))
3253 })?;
3254 assert_eq!(self.types.len(), unresolved_type_id.index());
3255 self.types.push(Some(type_id));
3256 }
3257 for (_, ty) in unresolved.types.iter().skip(self.types.len()) {
3258 if let TypeDefKind::Unknown = ty.kind {
3259 panic!("unknown type after defined type");
3260 }
3261 }
3262 Ok(())
3263 }
3264
3265 fn update_typedef(
3266 &mut self,
3267 resolve: &mut Resolve,
3268 ty: &mut TypeDef,
3269 span: Option<Span>,
3270 ) -> Result<()> {
3271 use crate::TypeDefKind::*;
3274 match &mut ty.kind {
3275 Handle(handle) => match handle {
3276 crate::Handle::Own(ty) | crate::Handle::Borrow(ty) => {
3277 self.update_type_id(ty, span)?
3278 }
3279 },
3280 Resource => {}
3281 Record(r) => {
3282 for field in r.fields.iter_mut() {
3283 self.update_ty(resolve, &mut field.ty, span)
3284 .with_context(|| format!("failed to update field `{}`", field.name))?;
3285 }
3286 }
3287 Tuple(t) => {
3288 for ty in t.types.iter_mut() {
3289 self.update_ty(resolve, ty, span)?;
3290 }
3291 }
3292 Variant(v) => {
3293 for case in v.cases.iter_mut() {
3294 if let Some(t) = &mut case.ty {
3295 self.update_ty(resolve, t, span)?;
3296 }
3297 }
3298 }
3299 Option(t) | List(t, ..) | FixedSizeList(t, ..) | Future(Some(t)) | Stream(Some(t)) => {
3300 self.update_ty(resolve, t, span)?
3301 }
3302 Result(r) => {
3303 if let Some(ty) = &mut r.ok {
3304 self.update_ty(resolve, ty, span)?;
3305 }
3306 if let Some(ty) = &mut r.err {
3307 self.update_ty(resolve, ty, span)?;
3308 }
3309 }
3310
3311 Type(crate::Type::Id(id)) => self.update_type_id(id, span)?,
3316 Type(_) => {}
3317
3318 Flags(_) | Enum(_) | Future(None) | Stream(None) => {}
3320
3321 Unknown => unreachable!(),
3322 }
3323
3324 Ok(())
3325 }
3326
3327 fn update_ty(
3328 &mut self,
3329 resolve: &mut Resolve,
3330 ty: &mut Type,
3331 span: Option<Span>,
3332 ) -> Result<()> {
3333 let id = match ty {
3334 Type::Id(id) => id,
3335 _ => return Ok(()),
3336 };
3337 self.update_type_id(id, span)?;
3338
3339 let mut cur = *id;
3344 let points_to_resource = loop {
3345 match resolve.types[cur].kind {
3346 TypeDefKind::Type(Type::Id(id)) => cur = id,
3347 TypeDefKind::Resource => break true,
3348 _ => break false,
3349 }
3350 };
3351
3352 if points_to_resource {
3353 *id = *self.own_handles.entry(*id).or_insert_with(|| {
3354 resolve.types.alloc(TypeDef {
3355 name: None,
3356 owner: TypeOwner::None,
3357 kind: TypeDefKind::Handle(Handle::Own(*id)),
3358 docs: Default::default(),
3359 stability: Default::default(),
3360 })
3361 });
3362 }
3363 Ok(())
3364 }
3365
3366 fn update_type_id(&self, id: &mut TypeId, span: Option<Span>) -> Result<()> {
3367 *id = self.map_type(*id, span)?;
3368 Ok(())
3369 }
3370
3371 fn update_interface(
3372 &mut self,
3373 resolve: &mut Resolve,
3374 iface: &mut Interface,
3375 spans: Option<&InterfaceSpan>,
3376 ) -> Result<()> {
3377 iface.types.retain(|_, ty| self.types[ty.index()].is_some());
3378 let iface_pkg_id = iface.package.as_ref().unwrap_or_else(|| {
3379 panic!(
3380 "unexpectedly missing package on interface [{}]",
3381 iface
3382 .name
3383 .as_ref()
3384 .map(String::as_str)
3385 .unwrap_or("<unknown>"),
3386 )
3387 });
3388
3389 for (_name, ty) in iface.types.iter_mut() {
3392 self.update_type_id(ty, spans.map(|s| s.span))?;
3393 }
3394 if let Some(spans) = spans {
3395 assert_eq!(iface.functions.len(), spans.funcs.len());
3396 }
3397 for (i, (func_name, func)) in iface.functions.iter_mut().enumerate() {
3398 let span = spans.map(|s| s.funcs[i]);
3399 if !resolve
3400 .include_stability(&func.stability, iface_pkg_id, span)
3401 .with_context(|| {
3402 format!(
3403 "failed to process feature gate for function [{func_name}] in package [{}]",
3404 resolve.packages[*iface_pkg_id].name,
3405 )
3406 })?
3407 {
3408 continue;
3409 }
3410 self.update_function(resolve, func, span)
3411 .with_context(|| format!("failed to update function `{}`", func.name))?;
3412 }
3413
3414 for (name, func) in mem::take(&mut iface.functions) {
3417 if resolve.include_stability(&func.stability, iface_pkg_id, None)? {
3418 iface.functions.insert(name, func);
3419 }
3420 }
3421
3422 Ok(())
3423 }
3424
3425 fn update_function(
3426 &mut self,
3427 resolve: &mut Resolve,
3428 func: &mut Function,
3429 span: Option<Span>,
3430 ) -> Result<()> {
3431 if let Some(id) = func.kind.resource_mut() {
3432 self.update_type_id(id, span)?;
3433 }
3434 for (_, ty) in func.params.iter_mut() {
3435 self.update_ty(resolve, ty, span)?;
3436 }
3437 if let Some(ty) = &mut func.result {
3438 self.update_ty(resolve, ty, span)?;
3439 }
3440
3441 if let Some(ty) = &func.result {
3442 if self.type_has_borrow(resolve, ty) {
3443 match span {
3444 Some(span) => {
3445 bail!(Error::new(
3446 span,
3447 format!(
3448 "function returns a type which contains \
3449 a `borrow<T>` which is not supported"
3450 )
3451 ))
3452 }
3453 None => unreachable!(),
3454 }
3455 }
3456 }
3457
3458 Ok(())
3459 }
3460
3461 fn update_world(
3462 &mut self,
3463 world: &mut World,
3464 resolve: &mut Resolve,
3465 pkg_id: &PackageId,
3466 spans: &WorldSpan,
3467 ) -> Result<()> {
3468 assert_eq!(world.imports.len(), spans.imports.len());
3469 assert_eq!(world.exports.len(), spans.exports.len());
3470
3471 let imports = mem::take(&mut world.imports).into_iter();
3475 let imports = imports.zip(&spans.imports).map(|p| (p, true));
3476 let exports = mem::take(&mut world.exports).into_iter();
3477 let exports = exports.zip(&spans.exports).map(|p| (p, false));
3478 for (((mut name, mut item), span), import) in imports.chain(exports) {
3479 if let WorldItem::Type(id) = &mut item {
3482 *id = self.map_type(*id, Some(*span))?;
3483 }
3484 let stability = item.stability(resolve);
3485 if !resolve
3486 .include_stability(stability, pkg_id, Some(*span))
3487 .with_context(|| format!("failed to process world item in `{}`", world.name))?
3488 {
3489 continue;
3490 }
3491 self.update_world_key(&mut name, Some(*span))?;
3492 match &mut item {
3493 WorldItem::Interface { id, .. } => {
3494 *id = self.map_interface(*id, Some(*span))?;
3495 }
3496 WorldItem::Function(f) => {
3497 self.update_function(resolve, f, Some(*span))?;
3498 }
3499 WorldItem::Type(_) => {
3500 }
3502 }
3503
3504 let dst = if import {
3505 &mut world.imports
3506 } else {
3507 &mut world.exports
3508 };
3509 let prev = dst.insert(name, item);
3510 assert!(prev.is_none());
3511 }
3512
3513 Ok(())
3514 }
3515
3516 fn process_world_includes(
3517 &self,
3518 id: WorldId,
3519 resolve: &mut Resolve,
3520 pkg_id: &PackageId,
3521 spans: &WorldSpan,
3522 ) -> Result<()> {
3523 let world = &mut resolve.worlds[id];
3524 assert_eq!(world.includes.len(), spans.includes.len());
3527 let includes = mem::take(&mut world.includes);
3528 let include_names = mem::take(&mut world.include_names);
3529 for (((stability, include_world), span), names) in includes
3530 .into_iter()
3531 .zip(&spans.includes)
3532 .zip(&include_names)
3533 {
3534 if !resolve
3535 .include_stability(&stability, pkg_id, Some(*span))
3536 .with_context(|| {
3537 format!(
3538 "failed to process feature gate for included world [{}] in package [{}]",
3539 resolve.worlds[include_world].name.as_str(),
3540 resolve.packages[*pkg_id].name
3541 )
3542 })?
3543 {
3544 continue;
3545 }
3546 self.resolve_include(id, include_world, names, *span, pkg_id, resolve)?;
3547 }
3548
3549 Ok(())
3550 }
3551
3552 fn update_world_key(&self, key: &mut WorldKey, span: Option<Span>) -> Result<()> {
3553 match key {
3554 WorldKey::Name(_) => {}
3555 WorldKey::Interface(id) => {
3556 *id = self.map_interface(*id, span)?;
3557 }
3558 }
3559 Ok(())
3560 }
3561
3562 fn resolve_include(
3563 &self,
3564 id: WorldId,
3565 include_world_id_orig: WorldId,
3566 names: &[IncludeName],
3567 span: Span,
3568 pkg_id: &PackageId,
3569 resolve: &mut Resolve,
3570 ) -> Result<()> {
3571 let world = &resolve.worlds[id];
3572 let include_world_id = self.map_world(include_world_id_orig, Some(span))?;
3573 let include_world = resolve.worlds[include_world_id].clone();
3574 let mut names_ = names.to_owned();
3575 let is_external_include = world.package != include_world.package;
3576
3577 for import in include_world.imports.iter() {
3579 self.remove_matching_name(import, &mut names_);
3580 }
3581 for export in include_world.exports.iter() {
3582 self.remove_matching_name(export, &mut names_);
3583 }
3584 if !names_.is_empty() {
3585 bail!(Error::new(
3586 span,
3587 format!(
3588 "no import or export kebab-name `{}`. Note that an ID does not support renaming",
3589 names_[0].name
3590 ),
3591 ));
3592 }
3593
3594 let mut cloner = clone::Cloner::new(
3595 resolve,
3596 TypeOwner::World(if is_external_include {
3597 include_world_id
3598 } else {
3599 include_world_id
3600 }),
3602 TypeOwner::World(id),
3603 );
3604 cloner.new_package = Some(*pkg_id);
3605
3606 for import in include_world.imports.iter() {
3608 self.resolve_include_item(
3609 &mut cloner,
3610 names,
3611 |resolve| &mut resolve.worlds[id].imports,
3612 import,
3613 span,
3614 "import",
3615 is_external_include,
3616 )?;
3617 }
3618
3619 for export in include_world.exports.iter() {
3620 self.resolve_include_item(
3621 &mut cloner,
3622 names,
3623 |resolve| &mut resolve.worlds[id].exports,
3624 export,
3625 span,
3626 "export",
3627 is_external_include,
3628 )?;
3629 }
3630 Ok(())
3631 }
3632
3633 fn resolve_include_item(
3634 &self,
3635 cloner: &mut clone::Cloner<'_>,
3636 names: &[IncludeName],
3637 get_items: impl Fn(&mut Resolve) -> &mut IndexMap<WorldKey, WorldItem>,
3638 item: (&WorldKey, &WorldItem),
3639 span: Span,
3640 item_type: &str,
3641 is_external_include: bool,
3642 ) -> Result<()> {
3643 match item.0 {
3644 WorldKey::Name(n) => {
3645 let n = names
3646 .into_iter()
3647 .find_map(|include_name| rename(n, include_name))
3648 .unwrap_or(n.clone());
3649
3650 let mut new_item = item.1.clone();
3656 let key = WorldKey::Name(n.clone());
3657 cloner.world_item(&key, &mut new_item);
3658 match &mut new_item {
3659 WorldItem::Function(f) => f.name = n.clone(),
3660 WorldItem::Type(id) => cloner.resolve.types[*id].name = Some(n.clone()),
3661 WorldItem::Interface { .. } => {}
3662 }
3663
3664 let prev = get_items(cloner.resolve).insert(key, new_item);
3665 if prev.is_some() {
3666 bail!(Error::new(
3667 span,
3668 format!("{item_type} of `{n}` shadows previously {item_type}ed items"),
3669 ))
3670 }
3671 }
3672 key @ WorldKey::Interface(_) => {
3673 let prev = get_items(cloner.resolve)
3674 .entry(key.clone())
3675 .or_insert(item.1.clone());
3676 match (&item.1, prev) {
3677 (
3678 WorldItem::Interface {
3679 id: aid,
3680 stability: astability,
3681 },
3682 WorldItem::Interface {
3683 id: bid,
3684 stability: bstability,
3685 },
3686 ) => {
3687 assert_eq!(*aid, *bid);
3688 merge_include_stability(astability, bstability, is_external_include)?;
3689 }
3690 (WorldItem::Interface { .. }, _) => unreachable!(),
3691 (WorldItem::Function(_), _) => unreachable!(),
3692 (WorldItem::Type(_), _) => unreachable!(),
3693 }
3694 }
3695 };
3696
3697 Ok(())
3698 }
3699
3700 fn remove_matching_name(&self, item: (&WorldKey, &WorldItem), names: &mut Vec<IncludeName>) {
3701 match item.0 {
3702 WorldKey::Name(n) => {
3703 names.retain(|name| rename(n, name).is_none());
3704 }
3705 _ => {}
3706 }
3707 }
3708
3709 fn type_has_borrow(&mut self, resolve: &Resolve, ty: &Type) -> bool {
3710 let id = match ty {
3711 Type::Id(id) => *id,
3712 _ => return false,
3713 };
3714
3715 if let Some(Some(has_borrow)) = self.type_has_borrow.get(id.index()) {
3716 return *has_borrow;
3717 }
3718
3719 let result = self.typedef_has_borrow(resolve, &resolve.types[id]);
3720 if self.type_has_borrow.len() <= id.index() {
3721 self.type_has_borrow.resize(id.index() + 1, None);
3722 }
3723 self.type_has_borrow[id.index()] = Some(result);
3724 result
3725 }
3726
3727 fn typedef_has_borrow(&mut self, resolve: &Resolve, ty: &TypeDef) -> bool {
3728 match &ty.kind {
3729 TypeDefKind::Type(t) => self.type_has_borrow(resolve, t),
3730 TypeDefKind::Variant(v) => v
3731 .cases
3732 .iter()
3733 .filter_map(|case| case.ty.as_ref())
3734 .any(|ty| self.type_has_borrow(resolve, ty)),
3735 TypeDefKind::Handle(Handle::Borrow(_)) => true,
3736 TypeDefKind::Handle(Handle::Own(_)) => false,
3737 TypeDefKind::Resource => false,
3738 TypeDefKind::Record(r) => r
3739 .fields
3740 .iter()
3741 .any(|case| self.type_has_borrow(resolve, &case.ty)),
3742 TypeDefKind::Flags(_) => false,
3743 TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.type_has_borrow(resolve, t)),
3744 TypeDefKind::Enum(_) => false,
3745 TypeDefKind::List(ty)
3746 | TypeDefKind::FixedSizeList(ty, ..)
3747 | TypeDefKind::Future(Some(ty))
3748 | TypeDefKind::Stream(Some(ty))
3749 | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty),
3750 TypeDefKind::Result(r) => [&r.ok, &r.err]
3751 .iter()
3752 .filter_map(|t| t.as_ref())
3753 .any(|t| self.type_has_borrow(resolve, t)),
3754 TypeDefKind::Future(None) | TypeDefKind::Stream(None) => false,
3755 TypeDefKind::Unknown => unreachable!(),
3756 }
3757 }
3758}
3759
3760struct MergeMap<'a> {
3761 package_map: HashMap<PackageId, PackageId>,
3764
3765 interface_map: HashMap<InterfaceId, InterfaceId>,
3768
3769 type_map: HashMap<TypeId, TypeId>,
3772
3773 world_map: HashMap<WorldId, WorldId>,
3776
3777 interfaces_to_add: Vec<(String, PackageId, InterfaceId)>,
3785 worlds_to_add: Vec<(String, PackageId, WorldId)>,
3786
3787 from: &'a Resolve,
3789
3790 into: &'a Resolve,
3792}
3793
3794impl<'a> MergeMap<'a> {
3795 fn new(from: &'a Resolve, into: &'a Resolve) -> MergeMap<'a> {
3796 MergeMap {
3797 package_map: Default::default(),
3798 interface_map: Default::default(),
3799 type_map: Default::default(),
3800 world_map: Default::default(),
3801 interfaces_to_add: Default::default(),
3802 worlds_to_add: Default::default(),
3803 from,
3804 into,
3805 }
3806 }
3807
3808 fn build(&mut self) -> Result<()> {
3809 for from_id in self.from.topological_packages() {
3810 let from = &self.from.packages[from_id];
3811 let into_id = match self.into.package_names.get(&from.name) {
3812 Some(id) => *id,
3813
3814 None => {
3817 log::trace!("adding unique package {}", from.name);
3818 continue;
3819 }
3820 };
3821 log::trace!("merging duplicate package {}", from.name);
3822
3823 self.build_package(from_id, into_id).with_context(|| {
3824 format!("failed to merge package `{}` into existing copy", from.name)
3825 })?;
3826 }
3827
3828 Ok(())
3829 }
3830
3831 fn build_package(&mut self, from_id: PackageId, into_id: PackageId) -> Result<()> {
3832 let prev = self.package_map.insert(from_id, into_id);
3833 assert!(prev.is_none());
3834
3835 let from = &self.from.packages[from_id];
3836 let into = &self.into.packages[into_id];
3837
3838 for (name, from_interface_id) in from.interfaces.iter() {
3842 let into_interface_id = match into.interfaces.get(name) {
3843 Some(id) => *id,
3844 None => {
3845 log::trace!("adding unique interface {name}");
3846 self.interfaces_to_add
3847 .push((name.clone(), into_id, *from_interface_id));
3848 continue;
3849 }
3850 };
3851
3852 log::trace!("merging duplicate interfaces {name}");
3853 self.build_interface(*from_interface_id, into_interface_id)
3854 .with_context(|| format!("failed to merge interface `{name}`"))?;
3855 }
3856
3857 for (name, from_world_id) in from.worlds.iter() {
3858 let into_world_id = match into.worlds.get(name) {
3859 Some(id) => *id,
3860 None => {
3861 log::trace!("adding unique world {name}");
3862 self.worlds_to_add
3863 .push((name.clone(), into_id, *from_world_id));
3864 continue;
3865 }
3866 };
3867
3868 log::trace!("merging duplicate worlds {name}");
3869 self.build_world(*from_world_id, into_world_id)
3870 .with_context(|| format!("failed to merge world `{name}`"))?;
3871 }
3872
3873 Ok(())
3874 }
3875
3876 fn build_interface(&mut self, from_id: InterfaceId, into_id: InterfaceId) -> Result<()> {
3877 let prev = self.interface_map.insert(from_id, into_id);
3878 assert!(prev.is_none());
3879
3880 let from_interface = &self.from.interfaces[from_id];
3881 let into_interface = &self.into.interfaces[into_id];
3882
3883 for (name, from_type_id) in from_interface.types.iter() {
3897 let into_type_id = *into_interface
3898 .types
3899 .get(name)
3900 .ok_or_else(|| anyhow!("expected type `{name}` to be present"))?;
3901 let prev = self.type_map.insert(*from_type_id, into_type_id);
3902 assert!(prev.is_none());
3903
3904 self.build_type_id(*from_type_id, into_type_id)
3905 .with_context(|| format!("mismatch in type `{name}`"))?;
3906 }
3907
3908 for (name, from_func) in from_interface.functions.iter() {
3909 let into_func = match into_interface.functions.get(name) {
3910 Some(func) => func,
3911 None => bail!("expected function `{name}` to be present"),
3912 };
3913 self.build_function(from_func, into_func)
3914 .with_context(|| format!("mismatch in function `{name}`"))?;
3915 }
3916
3917 Ok(())
3918 }
3919
3920 fn build_type_id(&mut self, from_id: TypeId, into_id: TypeId) -> Result<()> {
3921 let _ = from_id;
3925 let _ = into_id;
3926 Ok(())
3927 }
3928
3929 fn build_type(&mut self, from_ty: &Type, into_ty: &Type) -> Result<()> {
3930 match (from_ty, into_ty) {
3931 (Type::Id(from), Type::Id(into)) => {
3932 self.build_type_id(*from, *into)?;
3933 }
3934 (from, into) if from != into => bail!("different kinds of types"),
3935 _ => {}
3936 }
3937 Ok(())
3938 }
3939
3940 fn build_function(&mut self, from_func: &Function, into_func: &Function) -> Result<()> {
3941 if from_func.name != into_func.name {
3942 bail!(
3943 "different function names `{}` and `{}`",
3944 from_func.name,
3945 into_func.name
3946 );
3947 }
3948 match (&from_func.kind, &into_func.kind) {
3949 (FunctionKind::Freestanding, FunctionKind::Freestanding) => {}
3950 (FunctionKind::AsyncFreestanding, FunctionKind::AsyncFreestanding) => {}
3951
3952 (FunctionKind::Method(from), FunctionKind::Method(into))
3953 | (FunctionKind::Static(from), FunctionKind::Static(into))
3954 | (FunctionKind::AsyncMethod(from), FunctionKind::AsyncMethod(into))
3955 | (FunctionKind::AsyncStatic(from), FunctionKind::AsyncStatic(into))
3956 | (FunctionKind::Constructor(from), FunctionKind::Constructor(into)) => {
3957 self.build_type_id(*from, *into)
3958 .context("different function kind types")?;
3959 }
3960
3961 (FunctionKind::Method(_), _)
3962 | (FunctionKind::Constructor(_), _)
3963 | (FunctionKind::Static(_), _)
3964 | (FunctionKind::Freestanding, _)
3965 | (FunctionKind::AsyncFreestanding, _)
3966 | (FunctionKind::AsyncMethod(_), _)
3967 | (FunctionKind::AsyncStatic(_), _) => {
3968 bail!("different function kind types")
3969 }
3970 }
3971
3972 if from_func.params.len() != into_func.params.len() {
3973 bail!("different number of function parameters");
3974 }
3975 for ((from_name, from_ty), (into_name, into_ty)) in
3976 from_func.params.iter().zip(&into_func.params)
3977 {
3978 if from_name != into_name {
3979 bail!("different function parameter names: {from_name} != {into_name}");
3980 }
3981 self.build_type(from_ty, into_ty)
3982 .with_context(|| format!("different function parameter types for `{from_name}`"))?;
3983 }
3984 match (&from_func.result, &into_func.result) {
3985 (Some(from_ty), Some(into_ty)) => {
3986 self.build_type(from_ty, into_ty)
3987 .context("different function result types")?;
3988 }
3989 (None, None) => {}
3990 (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
3991 }
3992 Ok(())
3993 }
3994
3995 fn build_world(&mut self, from_id: WorldId, into_id: WorldId) -> Result<()> {
3996 let prev = self.world_map.insert(from_id, into_id);
3997 assert!(prev.is_none());
3998
3999 let from_world = &self.from.worlds[from_id];
4000 let into_world = &self.into.worlds[into_id];
4001
4002 if from_world.imports.len() != into_world.imports.len() {
4011 bail!("world contains different number of imports than expected");
4012 }
4013 if from_world.exports.len() != into_world.exports.len() {
4014 bail!("world contains different number of exports than expected");
4015 }
4016
4017 for (from_name, from) in from_world.imports.iter() {
4018 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4019 let name_str = self.from.name_world_key(from_name);
4020 let into = into_world
4021 .imports
4022 .get(&into_name)
4023 .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?;
4024 self.match_world_item(from, into)
4025 .with_context(|| format!("import `{name_str}` didn't match target world"))?;
4026 }
4027
4028 for (from_name, from) in from_world.exports.iter() {
4029 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4030 let name_str = self.from.name_world_key(from_name);
4031 let into = into_world
4032 .exports
4033 .get(&into_name)
4034 .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?;
4035 self.match_world_item(from, into)
4036 .with_context(|| format!("export `{name_str}` didn't match target world"))?;
4037 }
4038
4039 Ok(())
4040 }
4041
4042 fn map_name(
4043 from_name: &WorldKey,
4044 interface_map: &HashMap<InterfaceId, InterfaceId>,
4045 ) -> WorldKey {
4046 match from_name {
4047 WorldKey::Name(s) => WorldKey::Name(s.clone()),
4048 WorldKey::Interface(id) => {
4049 WorldKey::Interface(interface_map.get(id).copied().unwrap_or(*id))
4050 }
4051 }
4052 }
4053
4054 fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> Result<()> {
4055 match (from, into) {
4056 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
4057 match (
4058 &self.from.interfaces[*from].name,
4059 &self.into.interfaces[*into].name,
4060 ) {
4061 (None, None) => self.build_interface(*from, *into)?,
4065
4066 _ => {
4071 if self.interface_map.get(&from) != Some(&into) {
4072 bail!("interfaces are not the same");
4073 }
4074 }
4075 }
4076 }
4077 (WorldItem::Function(from), WorldItem::Function(into)) => {
4078 let _ = (from, into);
4079 }
4082 (WorldItem::Type(from), WorldItem::Type(into)) => {
4083 let prev = self.type_map.insert(*from, *into);
4086 assert!(prev.is_none());
4087 }
4088
4089 (WorldItem::Interface { .. }, _)
4090 | (WorldItem::Function(_), _)
4091 | (WorldItem::Type(_), _) => {
4092 bail!("world items do not have the same type")
4093 }
4094 }
4095 Ok(())
4096 }
4097}
4098
4099fn update_stability(from: &Stability, into: &mut Stability) -> Result<()> {
4105 if from == into || from.is_unknown() {
4108 return Ok(());
4109 }
4110 if into.is_unknown() {
4113 *into = from.clone();
4114 return Ok(());
4115 }
4116
4117 bail!("mismatch in stability from '{:?}' to '{:?}'", from, into)
4120}
4121
4122fn merge_include_stability(
4123 from: &Stability,
4124 into: &mut Stability,
4125 is_external_include: bool,
4126) -> Result<()> {
4127 if is_external_include && from.is_stable() {
4128 log::trace!("dropped stability from external package");
4129 *into = Stability::Unknown;
4130 return Ok(());
4131 }
4132
4133 return update_stability(from, into);
4134}
4135
4136#[derive(Debug, Clone)]
4149pub struct InvalidTransitiveDependency(String);
4150
4151impl fmt::Display for InvalidTransitiveDependency {
4152 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4153 write!(
4154 f,
4155 "interface `{}` transitively depends on an interface in \
4156 incompatible ways",
4157 self.0
4158 )
4159 }
4160}
4161
4162impl std::error::Error for InvalidTransitiveDependency {}
4163
4164#[cfg(test)]
4165mod tests {
4166 use crate::Resolve;
4167 use anyhow::Result;
4168
4169 #[test]
4170 fn select_world() -> Result<()> {
4171 let mut resolve = Resolve::default();
4172 resolve.push_str(
4173 "test.wit",
4174 r#"
4175 package foo:bar@0.1.0;
4176
4177 world foo {}
4178 "#,
4179 )?;
4180 resolve.push_str(
4181 "test.wit",
4182 r#"
4183 package foo:baz@0.1.0;
4184
4185 world foo {}
4186 "#,
4187 )?;
4188 resolve.push_str(
4189 "test.wit",
4190 r#"
4191 package foo:baz@0.2.0;
4192
4193 world foo {}
4194 "#,
4195 )?;
4196
4197 let dummy = resolve.push_str(
4198 "test.wit",
4199 r#"
4200 package foo:dummy;
4201
4202 world foo {}
4203 "#,
4204 )?;
4205
4206 assert!(resolve.select_world(&[dummy], None).is_ok());
4207 assert!(resolve.select_world(&[dummy], Some("xx")).is_err());
4208 assert!(resolve.select_world(&[dummy], Some("")).is_err());
4209 assert!(resolve.select_world(&[dummy], Some("foo:bar/foo")).is_ok());
4210 assert!(
4211 resolve
4212 .select_world(&[dummy], Some("foo:bar/foo@0.1.0"))
4213 .is_ok()
4214 );
4215 assert!(resolve.select_world(&[dummy], Some("foo:baz/foo")).is_err());
4216 assert!(
4217 resolve
4218 .select_world(&[dummy], Some("foo:baz/foo@0.1.0"))
4219 .is_ok()
4220 );
4221 assert!(
4222 resolve
4223 .select_world(&[dummy], Some("foo:baz/foo@0.2.0"))
4224 .is_ok()
4225 );
4226 Ok(())
4227 }
4228
4229 #[test]
4232 fn select_world_multiple_packages() -> Result<()> {
4233 use wit_parser::Resolve;
4234
4235 let mut resolve = Resolve::default();
4236
4237 let stuff = resolve.push_str(
4239 "./my-test.wit",
4240 r#"
4241 package test:stuff;
4242
4243 world foo {
4244 // ...
4245 }
4246 "#,
4247 )?;
4248 assert!(resolve.select_world(&[stuff], None).is_ok());
4249 assert!(resolve.select_world(&[stuff], Some("foo")).is_ok());
4250
4251 let empty = resolve.push_str(
4254 "./my-test.wit",
4255 r#"
4256 package test:empty;
4257 "#,
4258 )?;
4259 assert!(resolve.select_world(&[stuff, empty], None).is_err());
4260 assert!(resolve.select_world(&[stuff, empty], Some("foo")).is_err());
4261 assert!(resolve.select_world(&[empty], None).is_err());
4262 assert!(resolve.select_world(&[empty], Some("foo")).is_err());
4263
4264 Ok(())
4265 }
4266
4267 #[test]
4269 fn select_world_versions() -> Result<()> {
4270 use wit_parser::Resolve;
4271
4272 let mut resolve = Resolve::default();
4273
4274 let _id = resolve.push_str(
4275 "./my-test.wit",
4276 r#"
4277 package example:distraction;
4278 "#,
4279 )?;
4280
4281 let versions_1 = resolve.push_str(
4284 "./my-test.wit",
4285 r#"
4286 package example:versions@1.0.0;
4287
4288 world foo { /* ... */ }
4289 "#,
4290 )?;
4291 assert!(resolve.select_world(&[versions_1], Some("foo")).is_ok());
4292 assert!(
4293 resolve
4294 .select_world(&[versions_1], Some("foo@1.0.0"))
4295 .is_err()
4296 );
4297 assert!(
4298 resolve
4299 .select_world(&[versions_1], Some("example:versions/foo"))
4300 .is_ok()
4301 );
4302 assert!(
4303 resolve
4304 .select_world(&[versions_1], Some("example:versions/foo@1.0.0"))
4305 .is_ok()
4306 );
4307
4308 let versions_2 = resolve.push_str(
4311 "./my-test.wit",
4312 r#"
4313 package example:versions@2.0.0;
4314
4315 world foo { /* ... */ }
4316 "#,
4317 )?;
4318 assert!(
4319 resolve
4320 .select_world(&[versions_1, versions_2], Some("foo"))
4321 .is_err()
4322 );
4323 assert!(
4324 resolve
4325 .select_world(&[versions_1, versions_2], Some("foo@1.0.0"))
4326 .is_err()
4327 );
4328 assert!(
4329 resolve
4330 .select_world(&[versions_1, versions_2], Some("foo@2.0.0"))
4331 .is_err()
4332 );
4333 assert!(
4334 resolve
4335 .select_world(&[versions_1, versions_2], Some("example:versions/foo"))
4336 .is_err()
4337 );
4338 assert!(
4339 resolve
4340 .select_world(
4341 &[versions_1, versions_2],
4342 Some("example:versions/foo@1.0.0")
4343 )
4344 .is_ok()
4345 );
4346 assert!(
4347 resolve
4348 .select_world(
4349 &[versions_1, versions_2],
4350 Some("example:versions/foo@2.0.0")
4351 )
4352 .is_ok()
4353 );
4354
4355 Ok(())
4356 }
4357
4358 #[test]
4360 fn select_world_override_qualification() -> Result<()> {
4361 use wit_parser::Resolve;
4362
4363 let mut resolve = Resolve::default();
4364
4365 let other = resolve.push_str(
4366 "./my-test.wit",
4367 r#"
4368 package example:other;
4369
4370 world foo { }
4371 "#,
4372 )?;
4373
4374 let fq = resolve.push_str(
4376 "./my-test.wit",
4377 r#"
4378 package example:fq;
4379
4380 world bar { }
4381 "#,
4382 )?;
4383 assert!(resolve.select_world(&[other, fq], Some("foo")).is_err());
4384 assert!(resolve.select_world(&[other, fq], Some("bar")).is_err());
4385 assert!(
4386 resolve
4387 .select_world(&[other, fq], Some("example:other/foo"))
4388 .is_ok()
4389 );
4390 assert!(
4391 resolve
4392 .select_world(&[other, fq], Some("example:fq/bar"))
4393 .is_ok()
4394 );
4395 assert!(
4396 resolve
4397 .select_world(&[other, fq], Some("example:other/bar"))
4398 .is_err()
4399 );
4400 assert!(
4401 resolve
4402 .select_world(&[other, fq], Some("example:fq/foo"))
4403 .is_err()
4404 );
4405
4406 Ok(())
4407 }
4408
4409 #[test]
4411 fn select_world_fully_qualified() -> Result<()> {
4412 use wit_parser::Resolve;
4413
4414 let mut resolve = Resolve::default();
4415
4416 let distraction = resolve.push_str(
4417 "./my-test.wit",
4418 r#"
4419 package example:distraction;
4420 "#,
4421 )?;
4422
4423 let multiworld = resolve.push_str(
4426 "./my-test.wit",
4427 r#"
4428 package example:multiworld;
4429
4430 world foo { /* ... */ }
4431
4432 world bar { /* ... */ }
4433 "#,
4434 )?;
4435 assert!(
4436 resolve
4437 .select_world(&[distraction, multiworld], None)
4438 .is_err()
4439 );
4440 assert!(
4441 resolve
4442 .select_world(&[distraction, multiworld], Some("foo"))
4443 .is_err()
4444 );
4445 assert!(
4446 resolve
4447 .select_world(&[distraction, multiworld], Some("example:multiworld/foo"))
4448 .is_ok()
4449 );
4450 assert!(
4451 resolve
4452 .select_world(&[distraction, multiworld], Some("bar"))
4453 .is_err()
4454 );
4455 assert!(
4456 resolve
4457 .select_world(&[distraction, multiworld], Some("example:multiworld/bar"))
4458 .is_ok()
4459 );
4460
4461 Ok(())
4462 }
4463
4464 #[test]
4466 fn select_world_packages() -> Result<()> {
4467 use wit_parser::Resolve;
4468
4469 let mut resolve = Resolve::default();
4470
4471 let wit1 = resolve.push_str(
4474 "./my-test.wit",
4475 r#"
4476 package example:wit1;
4477
4478 world foo {
4479 // ...
4480 }
4481 "#,
4482 )?;
4483 assert!(resolve.select_world(&[wit1], None).is_ok());
4484 assert!(resolve.select_world(&[wit1], Some("foo")).is_ok());
4485 assert!(
4486 resolve
4487 .select_world(&[wit1], Some("example:wit1/foo"))
4488 .is_ok()
4489 );
4490 assert!(resolve.select_world(&[wit1], Some("bar")).is_err());
4491 assert!(
4492 resolve
4493 .select_world(&[wit1], Some("example:wit2/foo"))
4494 .is_err()
4495 );
4496
4497 let wit2 = resolve.push_str(
4500 "./my-test.wit",
4501 r#"
4502 package example:wit2;
4503
4504 world foo { /* ... */ }
4505 "#,
4506 )?;
4507 assert!(resolve.select_world(&[wit1, wit2], None).is_err());
4508 assert!(resolve.select_world(&[wit1, wit2], Some("foo")).is_err());
4509 assert!(
4510 resolve
4511 .select_world(&[wit1, wit2], Some("example:wit1/foo"))
4512 .is_ok()
4513 );
4514 assert!(resolve.select_world(&[wit2], None).is_ok());
4515 assert!(resolve.select_world(&[wit2], Some("foo")).is_ok());
4516 assert!(
4517 resolve
4518 .select_world(&[wit2], Some("example:wit1/foo"))
4519 .is_ok()
4520 );
4521 assert!(resolve.select_world(&[wit1, wit2], Some("bar")).is_err());
4522 assert!(
4523 resolve
4524 .select_world(&[wit1, wit2], Some("example:wit2/foo"))
4525 .is_ok()
4526 );
4527 assert!(resolve.select_world(&[wit2], Some("bar")).is_err());
4528 assert!(
4529 resolve
4530 .select_world(&[wit2], Some("example:wit2/foo"))
4531 .is_ok()
4532 );
4533
4534 Ok(())
4535 }
4536}