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(&self, package: PackageId, world: Option<&str>) -> Result<WorldId> {
1368 let world_path = match world {
1369 Some(world) => Some(
1370 parse_use_path(world)
1371 .with_context(|| format!("failed to parse world specifier `{world}`"))?,
1372 ),
1373 None => None,
1374 };
1375
1376 let (pkg, world_name) = match world_path {
1377 Some(ParsedUsePath::Name(name)) => (package, name),
1378 Some(ParsedUsePath::Package(pkg, interface)) => {
1379 let pkg = match self.package_names.get(&pkg) {
1380 Some(pkg) => *pkg,
1381 None => {
1382 let mut candidates = self.package_names.iter().filter(|(name, _)| {
1383 pkg.version.is_none()
1384 && pkg.name == name.name
1385 && pkg.namespace == name.namespace
1386 && name.version.is_some()
1387 });
1388 let candidate = candidates.next();
1389 if let Some((c2, _)) = candidates.next() {
1390 let (c1, _) = candidate.unwrap();
1391 bail!(
1392 "package name `{pkg}` is available at both \
1393 versions {} and {} but which is not specified",
1394 c1.version.as_ref().unwrap(),
1395 c2.version.as_ref().unwrap(),
1396 );
1397 }
1398 match candidate {
1399 Some((_, id)) => *id,
1400 None => bail!("unknown package `{pkg}`"),
1401 }
1402 }
1403 };
1404 (pkg, interface.to_string())
1405 }
1406 None => {
1407 let pkg = &self.packages[package];
1408 let worlds = pkg
1409 .worlds
1410 .values()
1411 .map(|world| (package, *world))
1412 .collect::<Vec<_>>();
1413
1414 match &worlds[..] {
1415 [] => bail!("The main package `{}` contains no worlds", pkg.name),
1416 [(_, world)] => return Ok(*world),
1417 _ => bail!(
1418 "multiple worlds found; one must be explicitly chosen:{}",
1419 worlds
1420 .iter()
1421 .map(|(pkg, world)| format!(
1422 "\n {}/{}",
1423 self.packages[*pkg].name, self.worlds[*world].name
1424 ))
1425 .collect::<String>()
1426 ),
1427 }
1428 }
1429 };
1430 let pkg = &self.packages[pkg];
1431 pkg.worlds
1432 .get(&world_name)
1433 .copied()
1434 .ok_or_else(|| anyhow!("no world named `{world_name}` in package"))
1435 }
1436
1437 pub fn name_world_key(&self, key: &WorldKey) -> String {
1439 match key {
1440 WorldKey::Name(s) => s.to_string(),
1441 WorldKey::Interface(i) => self.id_of(*i).expect("unexpected anonymous interface"),
1442 }
1443 }
1444
1445 pub fn name_canonicalized_world_key(&self, key: &WorldKey) -> String {
1448 match key {
1449 WorldKey::Name(s) => s.to_string(),
1450 WorldKey::Interface(i) => self
1451 .canonicalized_id_of(*i)
1452 .expect("unexpected anonymous interface"),
1453 }
1454 }
1455
1456 pub fn type_interface_dep(&self, id: TypeId) -> Option<InterfaceId> {
1462 let ty = &self.types[id];
1463 let dep = match ty.kind {
1464 TypeDefKind::Type(Type::Id(id)) => id,
1465 _ => return None,
1466 };
1467 let other = &self.types[dep];
1468 if ty.owner == other.owner {
1469 None
1470 } else {
1471 match other.owner {
1472 TypeOwner::Interface(id) => Some(id),
1473 _ => unreachable!(),
1474 }
1475 }
1476 }
1477
1478 pub fn interface_direct_deps(&self, id: InterfaceId) -> impl Iterator<Item = InterfaceId> + '_ {
1488 self.interfaces[id]
1489 .types
1490 .iter()
1491 .filter_map(move |(_name, ty)| self.type_interface_dep(*ty))
1492 }
1493
1494 pub fn package_direct_deps(&self, id: PackageId) -> impl Iterator<Item = PackageId> + '_ {
1504 let pkg = &self.packages[id];
1505
1506 pkg.interfaces
1507 .iter()
1508 .flat_map(move |(_name, id)| self.interface_direct_deps(*id))
1509 .chain(pkg.worlds.iter().flat_map(move |(_name, id)| {
1510 let world = &self.worlds[*id];
1511 world
1512 .imports
1513 .iter()
1514 .chain(world.exports.iter())
1515 .filter_map(move |(_name, item)| match item {
1516 WorldItem::Interface { id, .. } => Some(*id),
1517 WorldItem::Function(_) => None,
1518 WorldItem::Type(t) => self.type_interface_dep(*t),
1519 })
1520 }))
1521 .filter_map(move |iface_id| {
1522 let pkg = self.interfaces[iface_id].package?;
1523 if pkg == id { None } else { Some(pkg) }
1524 })
1525 }
1526
1527 pub fn topological_packages(&self) -> Vec<PackageId> {
1533 let mut pushed = vec![false; self.packages.len()];
1534 let mut order = Vec::new();
1535 for (id, _) in self.packages.iter() {
1536 self.build_topological_package_ordering(id, &mut pushed, &mut order);
1537 }
1538 order
1539 }
1540
1541 fn build_topological_package_ordering(
1542 &self,
1543 id: PackageId,
1544 pushed: &mut Vec<bool>,
1545 order: &mut Vec<PackageId>,
1546 ) {
1547 if pushed[id.index()] {
1548 return;
1549 }
1550 for dep in self.package_direct_deps(id) {
1551 self.build_topological_package_ordering(dep, pushed, order);
1552 }
1553 order.push(id);
1554 pushed[id.index()] = true;
1555 }
1556
1557 #[doc(hidden)]
1558 pub fn assert_valid(&self) {
1559 let mut package_interfaces = Vec::new();
1560 let mut package_worlds = Vec::new();
1561 for (id, pkg) in self.packages.iter() {
1562 let mut interfaces = HashSet::new();
1563 for (name, iface) in pkg.interfaces.iter() {
1564 assert!(interfaces.insert(*iface));
1565 let iface = &self.interfaces[*iface];
1566 assert_eq!(name, iface.name.as_ref().unwrap());
1567 assert_eq!(iface.package.unwrap(), id);
1568 }
1569 package_interfaces.push(pkg.interfaces.values().copied().collect::<HashSet<_>>());
1570 let mut worlds = HashSet::new();
1571 for (name, world) in pkg.worlds.iter() {
1572 assert!(worlds.insert(*world));
1573 assert_eq!(
1574 pkg.worlds.get_key_value(name),
1575 Some((name, world)),
1576 "`MutableKeys` impl may have been used to change a key's hash or equality"
1577 );
1578 let world = &self.worlds[*world];
1579 assert_eq!(*name, world.name);
1580 assert_eq!(world.package.unwrap(), id);
1581 }
1582 package_worlds.push(pkg.worlds.values().copied().collect::<HashSet<_>>());
1583 }
1584
1585 let mut interface_types = Vec::new();
1586 for (id, iface) in self.interfaces.iter() {
1587 assert!(self.packages.get(iface.package.unwrap()).is_some());
1588 if iface.name.is_some() {
1589 assert!(package_interfaces[iface.package.unwrap().index()].contains(&id));
1590 }
1591
1592 for (name, ty) in iface.types.iter() {
1593 let ty = &self.types[*ty];
1594 assert_eq!(ty.name.as_ref(), Some(name));
1595 assert_eq!(ty.owner, TypeOwner::Interface(id));
1596 }
1597 interface_types.push(iface.types.values().copied().collect::<HashSet<_>>());
1598 for (name, f) in iface.functions.iter() {
1599 assert_eq!(*name, f.name);
1600 }
1601 }
1602
1603 let mut world_types = Vec::new();
1604 for (id, world) in self.worlds.iter() {
1605 log::debug!("validating world {}", &world.name);
1606 if let Some(package) = world.package {
1607 assert!(self.packages.get(package).is_some());
1608 assert!(package_worlds[package.index()].contains(&id));
1609 }
1610 assert!(world.includes.is_empty());
1611
1612 let mut types = HashSet::new();
1613 for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1614 log::debug!("validating world item: {}", self.name_world_key(name));
1615 match item {
1616 WorldItem::Interface { id, .. } => {
1617 if matches!(name, WorldKey::Name(_)) {
1620 assert_eq!(self.interfaces[*id].package, world.package);
1621 }
1622 }
1623 WorldItem::Function(f) => {
1624 assert!(!matches!(name, WorldKey::Interface(_)));
1625 assert_eq!(f.name, name.clone().unwrap_name());
1626 }
1627 WorldItem::Type(ty) => {
1628 assert!(!matches!(name, WorldKey::Interface(_)));
1629 assert!(types.insert(*ty));
1630 let ty = &self.types[*ty];
1631 assert_eq!(ty.name, Some(name.clone().unwrap_name()));
1632 assert_eq!(ty.owner, TypeOwner::World(id));
1633 }
1634 }
1635 }
1636 self.assert_world_elaborated(world);
1637 world_types.push(types);
1638 }
1639
1640 for (ty_id, ty) in self.types.iter() {
1641 match ty.owner {
1642 TypeOwner::Interface(id) => {
1643 assert!(self.interfaces.get(id).is_some());
1644 assert!(interface_types[id.index()].contains(&ty_id));
1645 }
1646 TypeOwner::World(id) => {
1647 assert!(self.worlds.get(id).is_some());
1648 assert!(world_types[id.index()].contains(&ty_id));
1649 }
1650 TypeOwner::None => {}
1651 }
1652 }
1653
1654 self.assert_topologically_sorted();
1655 }
1656
1657 fn assert_topologically_sorted(&self) {
1658 let mut positions = IndexMap::new();
1659 for id in self.topological_packages() {
1660 let pkg = &self.packages[id];
1661 log::debug!("pkg {}", pkg.name);
1662 let prev = positions.insert(Some(id), IndexSet::new());
1663 assert!(prev.is_none());
1664 }
1665 positions.insert(None, IndexSet::new());
1666
1667 for (id, iface) in self.interfaces.iter() {
1668 log::debug!("iface {:?}", iface.name);
1669 let ok = positions.get_mut(&iface.package).unwrap().insert(id);
1670 assert!(ok);
1671 }
1672
1673 for (_, world) in self.worlds.iter() {
1674 log::debug!("world {:?}", world.name);
1675
1676 let my_package = world.package;
1677 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1678
1679 for (_, item) in world.imports.iter().chain(&world.exports) {
1680 let id = match item {
1681 WorldItem::Interface { id, .. } => *id,
1682 _ => continue,
1683 };
1684 let other_package = self.interfaces[id].package;
1685 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1686
1687 assert!(other_package_pos <= my_package_pos);
1688 }
1689 }
1690
1691 for (_id, ty) in self.types.iter() {
1692 log::debug!("type {:?} {:?}", ty.name, ty.owner);
1693 let other_id = match ty.kind {
1694 TypeDefKind::Type(Type::Id(ty)) => ty,
1695 _ => continue,
1696 };
1697 let other = &self.types[other_id];
1698 if ty.kind == other.kind {
1699 continue;
1700 }
1701 let my_interface = match ty.owner {
1702 TypeOwner::Interface(id) => id,
1703 _ => continue,
1704 };
1705 let other_interface = match other.owner {
1706 TypeOwner::Interface(id) => id,
1707 _ => continue,
1708 };
1709
1710 let my_package = self.interfaces[my_interface].package;
1711 let other_package = self.interfaces[other_interface].package;
1712 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1713 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1714
1715 if my_package_pos == other_package_pos {
1716 let interfaces = &positions[&my_package];
1717 let my_interface_pos = interfaces.get_index_of(&my_interface).unwrap();
1718 let other_interface_pos = interfaces.get_index_of(&other_interface).unwrap();
1719 assert!(other_interface_pos <= my_interface_pos);
1720 } else {
1721 assert!(other_package_pos < my_package_pos);
1722 }
1723 }
1724 }
1725
1726 fn assert_world_elaborated(&self, world: &World) {
1727 for (key, item) in world.imports.iter() {
1728 log::debug!(
1729 "asserting elaborated world import {}",
1730 self.name_world_key(key)
1731 );
1732 match item {
1733 WorldItem::Type(t) => self.assert_world_imports_type_deps(world, key, *t),
1734
1735 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1737
1738 WorldItem::Interface { id, .. } => {
1740 for dep in self.interface_direct_deps(*id) {
1741 assert!(
1742 world.imports.contains_key(&WorldKey::Interface(dep)),
1743 "world import of {} is missing transitive dep of {}",
1744 self.name_world_key(key),
1745 self.id_of(dep).unwrap(),
1746 );
1747 }
1748 }
1749 }
1750 }
1751 for (key, item) in world.exports.iter() {
1752 log::debug!(
1753 "asserting elaborated world export {}",
1754 self.name_world_key(key)
1755 );
1756 match item {
1757 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1759
1760 WorldItem::Interface { id, .. } => {
1764 for dep in self.interface_direct_deps(*id) {
1765 let dep_key = WorldKey::Interface(dep);
1766 if world.exports.contains_key(&dep_key) {
1767 continue;
1768 }
1769 self.foreach_interface_dep(dep, &mut |dep| {
1770 let dep_key = WorldKey::Interface(dep);
1771 assert!(
1772 world.imports.contains_key(&dep_key),
1773 "world should import {} (required by {})",
1774 self.name_world_key(&dep_key),
1775 self.name_world_key(key),
1776 );
1777 assert!(
1778 !world.exports.contains_key(&dep_key),
1779 "world should not export {} (required by {})",
1780 self.name_world_key(&dep_key),
1781 self.name_world_key(key),
1782 );
1783 });
1784 }
1785 }
1786
1787 WorldItem::Type(_) => unreachable!(),
1789 }
1790 }
1791 }
1792
1793 fn assert_world_imports_type_deps(&self, world: &World, key: &WorldKey, ty: TypeId) {
1794 let ty = &self.types[ty];
1797 if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
1798 if let TypeOwner::Interface(id) = self.types[other].owner {
1799 let key = WorldKey::Interface(id);
1800 assert!(world.imports.contains_key(&key));
1801 return;
1802 }
1803 }
1804
1805 let mut visitor = MyVisit(self, Vec::new());
1809 visitor.visit_type_def(self, ty);
1810 for ty in visitor.1 {
1811 let ty = &self.types[ty];
1812 let Some(name) = ty.name.clone() else {
1813 continue;
1814 };
1815 let dep_key = WorldKey::Name(name);
1816 assert!(
1817 world.imports.contains_key(&dep_key),
1818 "world import `{}` should also force an import of `{}`",
1819 self.name_world_key(key),
1820 self.name_world_key(&dep_key),
1821 );
1822 }
1823
1824 struct MyVisit<'a>(&'a Resolve, Vec<TypeId>);
1825
1826 impl TypeIdVisitor for MyVisit<'_> {
1827 fn before_visit_type_id(&mut self, id: TypeId) -> bool {
1828 self.1.push(id);
1829 self.0.types[id].name.is_none()
1831 }
1832 }
1833 }
1834
1835 fn assert_world_function_imports_types(&self, world: &World, key: &WorldKey, func: &Function) {
1839 for ty in func
1840 .parameter_and_result_types()
1841 .chain(func.kind.resource().map(Type::Id))
1842 {
1843 let Type::Id(id) = ty else {
1844 continue;
1845 };
1846 self.assert_world_imports_type_deps(world, key, id);
1847 }
1848 }
1849
1850 fn include_stability(
1866 &self,
1867 stability: &Stability,
1868 pkg_id: &PackageId,
1869 span: Option<Span>,
1870 ) -> Result<bool> {
1871 let err = |msg: String| match span {
1872 Some(span) => Error::new(span, msg).into(),
1873 None => anyhow::Error::msg(msg),
1874 };
1875 Ok(match stability {
1876 Stability::Unknown => true,
1877 Stability::Stable { since, .. } => {
1880 let Some(p) = self.packages.get(*pkg_id) else {
1881 return Ok(true);
1889 };
1890
1891 let package_version = p.name.version.as_ref().ok_or_else(|| {
1894 err(format!(
1895 "package [{}] contains a feature gate with a version \
1896 specifier, so it must have a version",
1897 p.name
1898 ))
1899 })?;
1900
1901 if since > package_version {
1905 return Err(err(format!(
1906 "feature gate cannot reference unreleased version \
1907 {since} of package [{}] (current version {package_version})",
1908 p.name
1909 )));
1910 }
1911
1912 true
1913 }
1914 Stability::Unstable { feature, .. } => {
1915 self.features.contains(feature) || self.all_features
1916 }
1917 })
1918 }
1919
1920 fn include_type(&self, ty: &TypeDef, pkgid: PackageId, span: Span) -> Result<bool> {
1923 self.include_stability(&ty.stability, &pkgid, Some(span))
1924 .with_context(|| {
1925 format!(
1926 "failed to process feature gate for type [{}] in package [{}]",
1927 ty.name.as_ref().map(String::as_str).unwrap_or("<unknown>"),
1928 self.packages[pkgid].name,
1929 )
1930 })
1931 }
1932
1933 fn elaborate_world(&mut self, world_id: WorldId) -> Result<()> {
1945 let mut new_imports = IndexMap::new();
1949 let world = &self.worlds[world_id];
1950
1951 let sort_key = |resolve: &Resolve, item: &WorldItem| match item {
1974 WorldItem::Interface { .. } => 0,
1975 WorldItem::Type(ty) => {
1976 let ty = &resolve.types[*ty];
1977 match ty.kind {
1978 TypeDefKind::Type(Type::Id(t)) if resolve.types[t].owner != ty.owner => 1,
1979 _ => 2,
1980 }
1981 }
1982 WorldItem::Function(f) => {
1983 if f.kind.resource().is_none() {
1984 3
1985 } else {
1986 4
1987 }
1988 }
1989 };
1990
1991 let mut world_imports = world.imports.iter().collect::<Vec<_>>();
1994 world_imports.sort_by_key(|(_name, import)| sort_key(self, import));
1995 for (name, item) in world_imports {
1996 match item {
1997 WorldItem::Interface { id, stability } => {
2000 self.elaborate_world_import(&mut new_imports, name.clone(), *id, &stability);
2001 }
2002
2003 WorldItem::Function(_) => {
2006 let prev = new_imports.insert(name.clone(), item.clone());
2007 assert!(prev.is_none());
2008 }
2009
2010 WorldItem::Type(id) => {
2014 if let Some(dep) = self.type_interface_dep(*id) {
2015 self.elaborate_world_import(
2016 &mut new_imports,
2017 WorldKey::Interface(dep),
2018 dep,
2019 &self.types[*id].stability,
2020 );
2021 }
2022 let prev = new_imports.insert(name.clone(), item.clone());
2023 assert!(prev.is_none());
2024 }
2025 }
2026 }
2027
2028 let mut new_exports = IndexMap::new();
2034 let mut export_interfaces = IndexMap::new();
2035 for (name, item) in world.exports.iter() {
2036 match item {
2037 WorldItem::Interface { id, stability } => {
2038 let prev = export_interfaces.insert(*id, (name.clone(), stability));
2039 assert!(prev.is_none());
2040 }
2041 WorldItem::Function(_) => {
2042 let prev = new_exports.insert(name.clone(), item.clone());
2043 assert!(prev.is_none());
2044 }
2045 WorldItem::Type(_) => unreachable!(),
2046 }
2047 }
2048
2049 self.elaborate_world_exports(&export_interfaces, &mut new_imports, &mut new_exports)?;
2050
2051 new_imports.sort_by_cached_key(|_name, import| sort_key(self, import));
2055
2056 log::trace!("imports = {:?}", new_imports);
2059 log::trace!("exports = {:?}", new_exports);
2060 let world = &mut self.worlds[world_id];
2061 world.imports = new_imports;
2062 world.exports = new_exports;
2063
2064 Ok(())
2065 }
2066
2067 fn elaborate_world_import(
2068 &self,
2069 imports: &mut IndexMap<WorldKey, WorldItem>,
2070 key: WorldKey,
2071 id: InterfaceId,
2072 stability: &Stability,
2073 ) {
2074 if imports.contains_key(&key) {
2075 return;
2076 }
2077 for dep in self.interface_direct_deps(id) {
2078 self.elaborate_world_import(imports, WorldKey::Interface(dep), dep, stability);
2079 }
2080 let prev = imports.insert(
2081 key,
2082 WorldItem::Interface {
2083 id,
2084 stability: stability.clone(),
2085 },
2086 );
2087 assert!(prev.is_none());
2088 }
2089
2090 fn elaborate_world_exports(
2137 &self,
2138 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2139 imports: &mut IndexMap<WorldKey, WorldItem>,
2140 exports: &mut IndexMap<WorldKey, WorldItem>,
2141 ) -> Result<()> {
2142 let mut required_imports = HashSet::new();
2143 for (id, (key, stability)) in export_interfaces.iter() {
2144 let name = self.name_world_key(&key);
2145 let ok = add_world_export(
2146 self,
2147 imports,
2148 exports,
2149 export_interfaces,
2150 &mut required_imports,
2151 *id,
2152 key,
2153 true,
2154 stability,
2155 );
2156 if !ok {
2157 bail!(
2158 InvalidTransitiveDependency(name),
2176 );
2177 }
2178 }
2179 return Ok(());
2180
2181 fn add_world_export(
2182 resolve: &Resolve,
2183 imports: &mut IndexMap<WorldKey, WorldItem>,
2184 exports: &mut IndexMap<WorldKey, WorldItem>,
2185 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2186 required_imports: &mut HashSet<InterfaceId>,
2187 id: InterfaceId,
2188 key: &WorldKey,
2189 add_export: bool,
2190 stability: &Stability,
2191 ) -> bool {
2192 if exports.contains_key(key) {
2193 if add_export {
2194 return true;
2195 } else {
2196 return false;
2197 }
2198 }
2199 if !add_export && required_imports.contains(&id) {
2202 return true;
2203 }
2204 let ok = resolve.interface_direct_deps(id).all(|dep| {
2205 let key = WorldKey::Interface(dep);
2206 let add_export = add_export && export_interfaces.contains_key(&dep);
2207 add_world_export(
2208 resolve,
2209 imports,
2210 exports,
2211 export_interfaces,
2212 required_imports,
2213 dep,
2214 &key,
2215 add_export,
2216 stability,
2217 )
2218 });
2219 if !ok {
2220 return false;
2221 }
2222 let item = WorldItem::Interface {
2223 id,
2224 stability: stability.clone(),
2225 };
2226 if add_export {
2227 if required_imports.contains(&id) {
2228 return false;
2229 }
2230 exports.insert(key.clone(), item);
2231 } else {
2232 required_imports.insert(id);
2233 imports.insert(key.clone(), item);
2234 }
2235 true
2236 }
2237 }
2238
2239 pub fn merge_world_imports_based_on_semver(&mut self, world_id: WorldId) -> Result<()> {
2251 let world = &self.worlds[world_id];
2252
2253 let mut semver_tracks = HashMap::new();
2262 let mut to_remove = HashSet::new();
2263 for (key, _) in world.imports.iter() {
2264 let iface_id = match key {
2265 WorldKey::Interface(id) => *id,
2266 WorldKey::Name(_) => continue,
2267 };
2268 let (track, version) = match self.semver_track(iface_id) {
2269 Some(track) => track,
2270 None => continue,
2271 };
2272 log::debug!(
2273 "{} is on track {}/{}",
2274 self.id_of(iface_id).unwrap(),
2275 track.0,
2276 track.1,
2277 );
2278 match semver_tracks.entry(track.clone()) {
2279 hash_map::Entry::Vacant(e) => {
2280 e.insert((version, iface_id));
2281 }
2282 hash_map::Entry::Occupied(mut e) => match version.cmp(&e.get().0) {
2283 Ordering::Greater => {
2284 to_remove.insert(e.get().1);
2285 e.insert((version, iface_id));
2286 }
2287 Ordering::Equal => {}
2288 Ordering::Less => {
2289 to_remove.insert(iface_id);
2290 }
2291 },
2292 }
2293 }
2294
2295 let mut replacements = HashMap::new();
2298 for id in to_remove {
2299 let (track, _) = self.semver_track(id).unwrap();
2300 let (_, latest) = semver_tracks[&track];
2301 let prev = replacements.insert(id, latest);
2302 assert!(prev.is_none());
2303 }
2304
2305 for (to_replace, replace_with) in replacements.iter() {
2310 self.merge_world_item(
2311 &WorldItem::Interface {
2312 id: *to_replace,
2313 stability: Default::default(),
2314 },
2315 &WorldItem::Interface {
2316 id: *replace_with,
2317 stability: Default::default(),
2318 },
2319 )
2320 .with_context(|| {
2321 let old_name = self.id_of(*to_replace).unwrap();
2322 let new_name = self.id_of(*replace_with).unwrap();
2323 format!(
2324 "failed to upgrade `{old_name}` to `{new_name}`, was \
2325 this semver-compatible update not semver compatible?"
2326 )
2327 })?;
2328 }
2329
2330 for (to_replace, replace_with) in replacements.iter() {
2331 log::debug!(
2332 "REPLACE {} => {}",
2333 self.id_of(*to_replace).unwrap(),
2334 self.id_of(*replace_with).unwrap(),
2335 );
2336 }
2337
2338 for (key, item) in mem::take(&mut self.worlds[world_id].imports) {
2347 if let WorldItem::Interface { id, .. } = item {
2348 if replacements.contains_key(&id) {
2349 continue;
2350 }
2351 }
2352
2353 self.update_interface_deps_of_world_item(&item, &replacements);
2354
2355 let prev = self.worlds[world_id].imports.insert(key, item);
2356 assert!(prev.is_none());
2357 }
2358 for (key, item) in mem::take(&mut self.worlds[world_id].exports) {
2359 self.update_interface_deps_of_world_item(&item, &replacements);
2360 let prev = self.worlds[world_id].exports.insert(key, item);
2361 assert!(prev.is_none());
2362 }
2363
2364 let ids = self.worlds.iter().map(|(id, _)| id).collect::<Vec<_>>();
2370 for world_id in ids {
2371 self.elaborate_world(world_id).with_context(|| {
2372 let name = &self.worlds[world_id].name;
2373 format!(
2374 "failed to elaborate world `{name}` after deduplicating imports \
2375 based on semver"
2376 )
2377 })?;
2378 }
2379
2380 #[cfg(debug_assertions)]
2381 self.assert_valid();
2382
2383 Ok(())
2384 }
2385
2386 fn update_interface_deps_of_world_item(
2387 &mut self,
2388 item: &WorldItem,
2389 replacements: &HashMap<InterfaceId, InterfaceId>,
2390 ) {
2391 match *item {
2392 WorldItem::Type(t) => self.update_interface_dep_of_type(t, &replacements),
2393 WorldItem::Interface { id, .. } => {
2394 let types = self.interfaces[id]
2395 .types
2396 .values()
2397 .copied()
2398 .collect::<Vec<_>>();
2399 for ty in types {
2400 self.update_interface_dep_of_type(ty, &replacements);
2401 }
2402 }
2403 WorldItem::Function(_) => {}
2404 }
2405 }
2406
2407 fn semver_track(&self, id: InterfaceId) -> Option<((PackageName, String), &Version)> {
2418 let iface = &self.interfaces[id];
2419 let pkg = &self.packages[iface.package?];
2420 let version = pkg.name.version.as_ref()?;
2421 let mut name = pkg.name.clone();
2422 name.version = Some(PackageName::version_compat_track(version));
2423 Some(((name, iface.name.clone()?), version))
2424 }
2425
2426 fn update_interface_dep_of_type(
2430 &mut self,
2431 ty: TypeId,
2432 replacements: &HashMap<InterfaceId, InterfaceId>,
2433 ) {
2434 let to_replace = match self.type_interface_dep(ty) {
2435 Some(id) => id,
2436 None => return,
2437 };
2438 let replace_with = match replacements.get(&to_replace) {
2439 Some(id) => id,
2440 None => return,
2441 };
2442 let dep = match self.types[ty].kind {
2443 TypeDefKind::Type(Type::Id(id)) => id,
2444 _ => return,
2445 };
2446 let name = self.types[dep].name.as_ref().unwrap();
2447 let replacement_id = self.interfaces[*replace_with].types[name];
2450 self.types[ty].kind = TypeDefKind::Type(Type::Id(replacement_id));
2451 }
2452
2453 pub fn wasm_import_name(
2460 &self,
2461 mangling: ManglingAndAbi,
2462 import: WasmImport<'_>,
2463 ) -> (String, String) {
2464 match mangling {
2465 ManglingAndAbi::Standard32 => match import {
2466 WasmImport::Func { interface, func } => {
2467 let module = match interface {
2468 Some(key) => format!("cm32p2|{}", self.name_canonicalized_world_key(key)),
2469 None => format!("cm32p2"),
2470 };
2471 (module, func.name.clone())
2472 }
2473 WasmImport::ResourceIntrinsic {
2474 interface,
2475 resource,
2476 intrinsic,
2477 } => {
2478 let name = self.types[resource].name.as_ref().unwrap();
2479 let (prefix, name) = match intrinsic {
2480 ResourceIntrinsic::ImportedDrop => ("", format!("{name}_drop")),
2481 ResourceIntrinsic::ExportedDrop => ("_ex_", format!("{name}_drop")),
2482 ResourceIntrinsic::ExportedNew => ("_ex_", format!("{name}_new")),
2483 ResourceIntrinsic::ExportedRep => ("_ex_", format!("{name}_rep")),
2484 };
2485 let module = match interface {
2486 Some(key) => {
2487 format!("cm32p2|{prefix}{}", self.name_canonicalized_world_key(key))
2488 }
2489 None => {
2490 assert_eq!(prefix, "");
2491 format!("cm32p2")
2492 }
2493 };
2494 (module, name)
2495 }
2496 },
2497 ManglingAndAbi::Legacy(abi) => match import {
2498 WasmImport::Func { interface, func } => {
2499 let module = match interface {
2500 Some(key) => self.name_world_key(key),
2501 None => format!("$root"),
2502 };
2503 (module, format!("{}{}", abi.import_prefix(), func.name))
2504 }
2505 WasmImport::ResourceIntrinsic {
2506 interface,
2507 resource,
2508 intrinsic,
2509 } => {
2510 let name = self.types[resource].name.as_ref().unwrap();
2511 let (prefix, name) = match intrinsic {
2512 ResourceIntrinsic::ImportedDrop => ("", format!("[resource-drop]{name}")),
2513 ResourceIntrinsic::ExportedDrop => {
2514 ("[export]", format!("[resource-drop]{name}"))
2515 }
2516 ResourceIntrinsic::ExportedNew => {
2517 ("[export]", format!("[resource-new]{name}"))
2518 }
2519 ResourceIntrinsic::ExportedRep => {
2520 ("[export]", format!("[resource-rep]{name}"))
2521 }
2522 };
2523 let module = match interface {
2524 Some(key) => format!("{prefix}{}", self.name_world_key(key)),
2525 None => {
2526 assert_eq!(prefix, "");
2527 format!("$root")
2528 }
2529 };
2530 (module, format!("{}{name}", abi.import_prefix()))
2531 }
2532 },
2533 }
2534 }
2535
2536 pub fn wasm_export_name(&self, mangling: ManglingAndAbi, export: WasmExport<'_>) -> String {
2540 match mangling {
2541 ManglingAndAbi::Standard32 => match export {
2542 WasmExport::Func {
2543 interface,
2544 func,
2545 kind,
2546 } => {
2547 let mut name = String::from("cm32p2|");
2548 if let Some(interface) = interface {
2549 let s = self.name_canonicalized_world_key(interface);
2550 name.push_str(&s);
2551 }
2552 name.push_str("|");
2553 name.push_str(&func.name);
2554 match kind {
2555 WasmExportKind::Normal => {}
2556 WasmExportKind::PostReturn => name.push_str("_post"),
2557 WasmExportKind::Callback => todo!(
2558 "not yet supported: \
2559 async callback functions using standard name mangling"
2560 ),
2561 }
2562 name
2563 }
2564 WasmExport::ResourceDtor {
2565 interface,
2566 resource,
2567 } => {
2568 let name = self.types[resource].name.as_ref().unwrap();
2569 let interface = self.name_canonicalized_world_key(interface);
2570 format!("cm32p2|{interface}|{name}_dtor")
2571 }
2572 WasmExport::Memory => "cm32p2_memory".to_string(),
2573 WasmExport::Initialize => "cm32p2_initialize".to_string(),
2574 WasmExport::Realloc => "cm32p2_realloc".to_string(),
2575 },
2576 ManglingAndAbi::Legacy(abi) => match export {
2577 WasmExport::Func {
2578 interface,
2579 func,
2580 kind,
2581 } => {
2582 let mut name = abi.export_prefix().to_string();
2583 match kind {
2584 WasmExportKind::Normal => {}
2585 WasmExportKind::PostReturn => name.push_str("cabi_post_"),
2586 WasmExportKind::Callback => {
2587 assert!(matches!(abi, LiftLowerAbi::AsyncCallback));
2588 name = format!("[callback]{name}")
2589 }
2590 }
2591 if let Some(interface) = interface {
2592 let s = self.name_world_key(interface);
2593 name.push_str(&s);
2594 name.push_str("#");
2595 }
2596 name.push_str(&func.name);
2597 name
2598 }
2599 WasmExport::ResourceDtor {
2600 interface,
2601 resource,
2602 } => {
2603 let name = self.types[resource].name.as_ref().unwrap();
2604 let interface = self.name_world_key(interface);
2605 format!("{}{interface}#[dtor]{name}", abi.export_prefix())
2606 }
2607 WasmExport::Memory => "memory".to_string(),
2608 WasmExport::Initialize => "_initialize".to_string(),
2609 WasmExport::Realloc => "cabi_realloc".to_string(),
2610 },
2611 }
2612 }
2613}
2614
2615#[derive(Debug)]
2617pub enum WasmImport<'a> {
2618 Func {
2620 interface: Option<&'a WorldKey>,
2625
2626 func: &'a Function,
2628 },
2629
2630 ResourceIntrinsic {
2632 interface: Option<&'a WorldKey>,
2634
2635 resource: TypeId,
2637
2638 intrinsic: ResourceIntrinsic,
2640 },
2641}
2642
2643#[derive(Debug)]
2646pub enum ResourceIntrinsic {
2647 ImportedDrop,
2648 ExportedDrop,
2649 ExportedNew,
2650 ExportedRep,
2651}
2652
2653#[derive(Debug)]
2656pub enum WasmExportKind {
2657 Normal,
2659
2660 PostReturn,
2662
2663 Callback,
2665}
2666
2667#[derive(Debug)]
2670pub enum WasmExport<'a> {
2671 Func {
2673 interface: Option<&'a WorldKey>,
2676
2677 func: &'a Function,
2679
2680 kind: WasmExportKind,
2682 },
2683
2684 ResourceDtor {
2686 interface: &'a WorldKey,
2688 resource: TypeId,
2690 },
2691
2692 Memory,
2694
2695 Initialize,
2697
2698 Realloc,
2700}
2701
2702#[derive(Default)]
2705pub struct Remap {
2706 pub types: Vec<Option<TypeId>>,
2707 pub interfaces: Vec<Option<InterfaceId>>,
2708 pub worlds: Vec<Option<WorldId>>,
2709 pub packages: Vec<PackageId>,
2710
2711 own_handles: HashMap<TypeId, TypeId>,
2721
2722 type_has_borrow: Vec<Option<bool>>,
2723}
2724
2725fn apply_map<T>(map: &[Option<Id<T>>], id: Id<T>, desc: &str, span: Option<Span>) -> Result<Id<T>> {
2726 match map.get(id.index()) {
2727 Some(Some(id)) => Ok(*id),
2728 Some(None) => {
2729 let msg = format!(
2730 "found a reference to a {desc} which is excluded \
2731 due to its feature not being activated"
2732 );
2733 match span {
2734 Some(span) => Err(Error::new(span, msg).into()),
2735 None => bail!("{msg}"),
2736 }
2737 }
2738 None => panic!("request to remap a {desc} that has not yet been registered"),
2739 }
2740}
2741
2742impl Remap {
2743 pub fn map_type(&self, id: TypeId, span: Option<Span>) -> Result<TypeId> {
2744 apply_map(&self.types, id, "type", span)
2745 }
2746
2747 pub fn map_interface(&self, id: InterfaceId, span: Option<Span>) -> Result<InterfaceId> {
2748 apply_map(&self.interfaces, id, "interface", span)
2749 }
2750
2751 pub fn map_world(&self, id: WorldId, span: Option<Span>) -> Result<WorldId> {
2752 apply_map(&self.worlds, id, "world", span)
2753 }
2754
2755 fn append(
2756 &mut self,
2757 resolve: &mut Resolve,
2758 unresolved: UnresolvedPackage,
2759 ) -> Result<PackageId> {
2760 let pkgid = resolve.packages.alloc(Package {
2761 name: unresolved.name.clone(),
2762 docs: unresolved.docs.clone(),
2763 interfaces: Default::default(),
2764 worlds: Default::default(),
2765 });
2766 let prev = resolve.package_names.insert(unresolved.name.clone(), pkgid);
2767 if let Some(prev) = prev {
2768 resolve.package_names.insert(unresolved.name.clone(), prev);
2769 bail!(
2770 "attempting to re-add package `{}` when it's already present in this `Resolve`",
2771 unresolved.name,
2772 );
2773 }
2774
2775 self.process_foreign_deps(resolve, pkgid, &unresolved)?;
2776
2777 let foreign_types = self.types.len();
2778 let foreign_interfaces = self.interfaces.len();
2779 let foreign_worlds = self.worlds.len();
2780
2781 assert_eq!(unresolved.types.len(), unresolved.type_spans.len());
2787 for ((id, mut ty), span) in unresolved
2788 .types
2789 .into_iter()
2790 .zip(&unresolved.type_spans)
2791 .skip(foreign_types)
2792 {
2793 if !resolve.include_type(&ty, pkgid, *span)? {
2794 self.types.push(None);
2795 continue;
2796 }
2797
2798 self.update_typedef(resolve, &mut ty, Some(*span))?;
2799 let new_id = resolve.types.alloc(ty);
2800 assert_eq!(self.types.len(), id.index());
2801
2802 let new_id = match resolve.types[new_id] {
2803 TypeDef {
2808 name: None,
2809 owner: TypeOwner::None,
2810 kind: TypeDefKind::Handle(Handle::Own(id)),
2811 docs: _,
2812 stability: _,
2813 } => *self.own_handles.entry(id).or_insert(new_id),
2814
2815 _ => new_id,
2818 };
2819 self.types.push(Some(new_id));
2820 }
2821
2822 assert_eq!(
2825 unresolved.interfaces.len(),
2826 unresolved.interface_spans.len()
2827 );
2828 for ((id, mut iface), span) in unresolved
2829 .interfaces
2830 .into_iter()
2831 .zip(&unresolved.interface_spans)
2832 .skip(foreign_interfaces)
2833 {
2834 if !resolve
2835 .include_stability(&iface.stability, &pkgid, Some(span.span))
2836 .with_context(|| {
2837 format!(
2838 "failed to process feature gate for interface [{}] in package [{}]",
2839 iface
2840 .name
2841 .as_ref()
2842 .map(String::as_str)
2843 .unwrap_or("<unknown>"),
2844 resolve.packages[pkgid].name,
2845 )
2846 })?
2847 {
2848 self.interfaces.push(None);
2849 continue;
2850 }
2851 assert!(iface.package.is_none());
2852 iface.package = Some(pkgid);
2853 self.update_interface(resolve, &mut iface, Some(span))?;
2854 let new_id = resolve.interfaces.alloc(iface);
2855 assert_eq!(self.interfaces.len(), id.index());
2856 self.interfaces.push(Some(new_id));
2857 }
2858
2859 for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2862 let id = match id {
2863 Some(id) => *id,
2864 None => continue,
2865 };
2866 match &mut resolve.types[id].owner {
2867 TypeOwner::Interface(id) => {
2868 let span = unresolved.type_spans[i];
2869 *id = self.map_interface(*id, Some(span))
2870 .with_context(|| {
2871 "this type is not gated by a feature but its interface is gated by a feature"
2872 })?;
2873 }
2874 TypeOwner::World(_) | TypeOwner::None => {}
2875 }
2876 }
2877
2878 assert_eq!(unresolved.worlds.len(), unresolved.world_spans.len());
2886 for ((id, mut world), span) in unresolved
2887 .worlds
2888 .into_iter()
2889 .zip(&unresolved.world_spans)
2890 .skip(foreign_worlds)
2891 {
2892 if !resolve
2893 .include_stability(&world.stability, &pkgid, Some(span.span))
2894 .with_context(|| {
2895 format!(
2896 "failed to process feature gate for world [{}] in package [{}]",
2897 world.name, resolve.packages[pkgid].name,
2898 )
2899 })?
2900 {
2901 self.worlds.push(None);
2902 continue;
2903 }
2904 self.update_world(&mut world, resolve, &pkgid, &span)?;
2905
2906 let new_id = resolve.worlds.alloc(world);
2907 assert_eq!(self.worlds.len(), id.index());
2908 self.worlds.push(Some(new_id));
2909 }
2910
2911 for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2913 let id = match id {
2914 Some(id) => *id,
2915 None => continue,
2916 };
2917 match &mut resolve.types[id].owner {
2918 TypeOwner::World(id) => {
2919 let span = unresolved.type_spans[i];
2920 *id = self.map_world(*id, Some(span))
2921 .with_context(|| {
2922 "this type is not gated by a feature but its interface is gated by a feature"
2923 })?;
2924 }
2925 TypeOwner::Interface(_) | TypeOwner::None => {}
2926 }
2927 }
2928
2929 assert_eq!(self.worlds.len(), unresolved.world_spans.len());
2946 for (id, span) in self
2947 .worlds
2948 .iter()
2949 .zip(unresolved.world_spans.iter())
2950 .skip(foreign_worlds)
2951 {
2952 let Some(id) = *id else {
2953 continue;
2954 };
2955 self.process_world_includes(id, resolve, &pkgid, &span)?;
2956
2957 resolve.elaborate_world(id).with_context(|| {
2958 Error::new(
2959 span.span,
2960 format!(
2961 "failed to elaborate world imports/exports of `{}`",
2962 resolve.worlds[id].name
2963 ),
2964 )
2965 })?;
2966 }
2967
2968 for id in self.interfaces.iter().skip(foreign_interfaces) {
2970 let id = match id {
2971 Some(id) => *id,
2972 None => continue,
2973 };
2974 let iface = &mut resolve.interfaces[id];
2975 iface.package = Some(pkgid);
2976 if let Some(name) = &iface.name {
2977 let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), id);
2978 assert!(prev.is_none());
2979 }
2980 }
2981 for id in self.worlds.iter().skip(foreign_worlds) {
2982 let id = match id {
2983 Some(id) => *id,
2984 None => continue,
2985 };
2986 let world = &mut resolve.worlds[id];
2987 world.package = Some(pkgid);
2988 let prev = resolve.packages[pkgid]
2989 .worlds
2990 .insert(world.name.clone(), id);
2991 assert!(prev.is_none());
2992 }
2993 Ok(pkgid)
2994 }
2995
2996 fn process_foreign_deps(
2997 &mut self,
2998 resolve: &mut Resolve,
2999 pkgid: PackageId,
3000 unresolved: &UnresolvedPackage,
3001 ) -> Result<()> {
3002 let mut world_to_package = HashMap::new();
3005 let mut interface_to_package = HashMap::new();
3006 for (i, (pkg_name, worlds_or_ifaces)) in unresolved.foreign_deps.iter().enumerate() {
3007 for (name, item) in worlds_or_ifaces {
3008 match item {
3009 AstItem::Interface(unresolved_interface_id) => {
3010 let prev = interface_to_package.insert(
3011 *unresolved_interface_id,
3012 (pkg_name, name, unresolved.foreign_dep_spans[i]),
3013 );
3014 assert!(prev.is_none());
3015 }
3016 AstItem::World(unresolved_world_id) => {
3017 let prev = world_to_package.insert(
3018 *unresolved_world_id,
3019 (pkg_name, name, unresolved.foreign_dep_spans[i]),
3020 );
3021 assert!(prev.is_none());
3022 }
3023 }
3024 }
3025 }
3026
3027 self.process_foreign_interfaces(unresolved, &interface_to_package, resolve)?;
3031
3032 self.process_foreign_worlds(unresolved, &world_to_package, resolve)?;
3036
3037 self.process_foreign_types(unresolved, pkgid, resolve)?;
3040
3041 for (id, span) in unresolved.required_resource_types.iter() {
3042 let Ok(mut id) = self.map_type(*id, Some(*span)) else {
3047 continue;
3048 };
3049 loop {
3050 match resolve.types[id].kind {
3051 TypeDefKind::Type(Type::Id(i)) => id = i,
3052 TypeDefKind::Resource => break,
3053 _ => bail!(Error::new(
3054 *span,
3055 format!("type used in a handle must be a resource"),
3056 )),
3057 }
3058 }
3059 }
3060
3061 #[cfg(debug_assertions)]
3062 resolve.assert_valid();
3063
3064 Ok(())
3065 }
3066
3067 fn process_foreign_interfaces(
3068 &mut self,
3069 unresolved: &UnresolvedPackage,
3070 interface_to_package: &HashMap<InterfaceId, (&PackageName, &String, Span)>,
3071 resolve: &mut Resolve,
3072 ) -> Result<(), anyhow::Error> {
3073 for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() {
3074 let (pkg_name, interface, span) = match interface_to_package.get(&unresolved_iface_id) {
3075 Some(items) => *items,
3076 None => break,
3080 };
3081 let pkgid = resolve
3082 .package_names
3083 .get(pkg_name)
3084 .copied()
3085 .ok_or_else(|| {
3086 PackageNotFoundError::new(
3087 span,
3088 pkg_name.clone(),
3089 resolve.package_names.keys().cloned().collect(),
3090 )
3091 })?;
3092
3093 assert!(unresolved_iface.functions.is_empty());
3095
3096 let pkg = &resolve.packages[pkgid];
3097 let span = &unresolved.interface_spans[unresolved_iface_id.index()];
3098 let iface_id = pkg
3099 .interfaces
3100 .get(interface)
3101 .copied()
3102 .ok_or_else(|| Error::new(span.span, "interface not found in package"))?;
3103 assert_eq!(self.interfaces.len(), unresolved_iface_id.index());
3104 self.interfaces.push(Some(iface_id));
3105 }
3106 for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) {
3107 assert!(
3108 interface_to_package.get(&id).is_none(),
3109 "found foreign interface after local interface"
3110 );
3111 }
3112 Ok(())
3113 }
3114
3115 fn process_foreign_worlds(
3116 &mut self,
3117 unresolved: &UnresolvedPackage,
3118 world_to_package: &HashMap<WorldId, (&PackageName, &String, Span)>,
3119 resolve: &mut Resolve,
3120 ) -> Result<(), anyhow::Error> {
3121 for (unresolved_world_id, _) in unresolved.worlds.iter() {
3122 let (pkg_name, world, span) = match world_to_package.get(&unresolved_world_id) {
3123 Some(items) => *items,
3124 None => break,
3127 };
3128
3129 let pkgid = resolve
3130 .package_names
3131 .get(pkg_name)
3132 .copied()
3133 .ok_or_else(|| Error::new(span, "package not found"))?;
3134 let pkg = &resolve.packages[pkgid];
3135 let span = &unresolved.world_spans[unresolved_world_id.index()];
3136 let world_id = pkg
3137 .worlds
3138 .get(world)
3139 .copied()
3140 .ok_or_else(|| Error::new(span.span, "world not found in package"))?;
3141 assert_eq!(self.worlds.len(), unresolved_world_id.index());
3142 self.worlds.push(Some(world_id));
3143 }
3144 for (id, _) in unresolved.worlds.iter().skip(self.worlds.len()) {
3145 assert!(
3146 world_to_package.get(&id).is_none(),
3147 "found foreign world after local world"
3148 );
3149 }
3150 Ok(())
3151 }
3152
3153 fn process_foreign_types(
3154 &mut self,
3155 unresolved: &UnresolvedPackage,
3156 pkgid: PackageId,
3157 resolve: &mut Resolve,
3158 ) -> Result<(), anyhow::Error> {
3159 for ((unresolved_type_id, unresolved_ty), span) in
3160 unresolved.types.iter().zip(&unresolved.type_spans)
3161 {
3162 match unresolved_ty.kind {
3166 TypeDefKind::Unknown => {}
3167 _ => break,
3168 }
3169
3170 if !resolve.include_type(unresolved_ty, pkgid, *span)? {
3171 self.types.push(None);
3172 continue;
3173 }
3174
3175 let unresolved_iface_id = match unresolved_ty.owner {
3176 TypeOwner::Interface(id) => id,
3177 _ => unreachable!(),
3178 };
3179 let iface_id = self.map_interface(unresolved_iface_id, None)?;
3180 let name = unresolved_ty.name.as_ref().unwrap();
3181 let span = unresolved.unknown_type_spans[unresolved_type_id.index()];
3182 let type_id = *resolve.interfaces[iface_id]
3183 .types
3184 .get(name)
3185 .ok_or_else(|| {
3186 Error::new(span, format!("type `{name}` not defined in interface"))
3187 })?;
3188 assert_eq!(self.types.len(), unresolved_type_id.index());
3189 self.types.push(Some(type_id));
3190 }
3191 for (_, ty) in unresolved.types.iter().skip(self.types.len()) {
3192 if let TypeDefKind::Unknown = ty.kind {
3193 panic!("unknown type after defined type");
3194 }
3195 }
3196 Ok(())
3197 }
3198
3199 fn update_typedef(
3200 &mut self,
3201 resolve: &mut Resolve,
3202 ty: &mut TypeDef,
3203 span: Option<Span>,
3204 ) -> Result<()> {
3205 use crate::TypeDefKind::*;
3208 match &mut ty.kind {
3209 Handle(handle) => match handle {
3210 crate::Handle::Own(ty) | crate::Handle::Borrow(ty) => {
3211 self.update_type_id(ty, span)?
3212 }
3213 },
3214 Resource => {}
3215 Record(r) => {
3216 for field in r.fields.iter_mut() {
3217 self.update_ty(resolve, &mut field.ty, span)
3218 .with_context(|| format!("failed to update field `{}`", field.name))?;
3219 }
3220 }
3221 Tuple(t) => {
3222 for ty in t.types.iter_mut() {
3223 self.update_ty(resolve, ty, span)?;
3224 }
3225 }
3226 Variant(v) => {
3227 for case in v.cases.iter_mut() {
3228 if let Some(t) = &mut case.ty {
3229 self.update_ty(resolve, t, span)?;
3230 }
3231 }
3232 }
3233 Option(t) | List(t, ..) | FixedSizeList(t, ..) | Future(Some(t)) | Stream(Some(t)) => {
3234 self.update_ty(resolve, t, span)?
3235 }
3236 Result(r) => {
3237 if let Some(ty) = &mut r.ok {
3238 self.update_ty(resolve, ty, span)?;
3239 }
3240 if let Some(ty) = &mut r.err {
3241 self.update_ty(resolve, ty, span)?;
3242 }
3243 }
3244
3245 Type(crate::Type::Id(id)) => self.update_type_id(id, span)?,
3250 Type(_) => {}
3251
3252 Flags(_) | Enum(_) | Future(None) | Stream(None) => {}
3254
3255 Unknown => unreachable!(),
3256 }
3257
3258 Ok(())
3259 }
3260
3261 fn update_ty(
3262 &mut self,
3263 resolve: &mut Resolve,
3264 ty: &mut Type,
3265 span: Option<Span>,
3266 ) -> Result<()> {
3267 let id = match ty {
3268 Type::Id(id) => id,
3269 _ => return Ok(()),
3270 };
3271 self.update_type_id(id, span)?;
3272
3273 let mut cur = *id;
3278 let points_to_resource = loop {
3279 match resolve.types[cur].kind {
3280 TypeDefKind::Type(Type::Id(id)) => cur = id,
3281 TypeDefKind::Resource => break true,
3282 _ => break false,
3283 }
3284 };
3285
3286 if points_to_resource {
3287 *id = *self.own_handles.entry(*id).or_insert_with(|| {
3288 resolve.types.alloc(TypeDef {
3289 name: None,
3290 owner: TypeOwner::None,
3291 kind: TypeDefKind::Handle(Handle::Own(*id)),
3292 docs: Default::default(),
3293 stability: Default::default(),
3294 })
3295 });
3296 }
3297 Ok(())
3298 }
3299
3300 fn update_type_id(&self, id: &mut TypeId, span: Option<Span>) -> Result<()> {
3301 *id = self.map_type(*id, span)?;
3302 Ok(())
3303 }
3304
3305 fn update_interface(
3306 &mut self,
3307 resolve: &mut Resolve,
3308 iface: &mut Interface,
3309 spans: Option<&InterfaceSpan>,
3310 ) -> Result<()> {
3311 iface.types.retain(|_, ty| self.types[ty.index()].is_some());
3312 let iface_pkg_id = iface.package.as_ref().unwrap_or_else(|| {
3313 panic!(
3314 "unexpectedly missing package on interface [{}]",
3315 iface
3316 .name
3317 .as_ref()
3318 .map(String::as_str)
3319 .unwrap_or("<unknown>"),
3320 )
3321 });
3322
3323 for (_name, ty) in iface.types.iter_mut() {
3326 self.update_type_id(ty, spans.map(|s| s.span))?;
3327 }
3328 if let Some(spans) = spans {
3329 assert_eq!(iface.functions.len(), spans.funcs.len());
3330 }
3331 for (i, (func_name, func)) in iface.functions.iter_mut().enumerate() {
3332 let span = spans.map(|s| s.funcs[i]);
3333 if !resolve
3334 .include_stability(&func.stability, iface_pkg_id, span)
3335 .with_context(|| {
3336 format!(
3337 "failed to process feature gate for function [{func_name}] in package [{}]",
3338 resolve.packages[*iface_pkg_id].name,
3339 )
3340 })?
3341 {
3342 continue;
3343 }
3344 self.update_function(resolve, func, span)
3345 .with_context(|| format!("failed to update function `{}`", func.name))?;
3346 }
3347
3348 for (name, func) in mem::take(&mut iface.functions) {
3351 if resolve.include_stability(&func.stability, iface_pkg_id, None)? {
3352 iface.functions.insert(name, func);
3353 }
3354 }
3355
3356 Ok(())
3357 }
3358
3359 fn update_function(
3360 &mut self,
3361 resolve: &mut Resolve,
3362 func: &mut Function,
3363 span: Option<Span>,
3364 ) -> Result<()> {
3365 if let Some(id) = func.kind.resource_mut() {
3366 self.update_type_id(id, span)?;
3367 }
3368 for (_, ty) in func.params.iter_mut() {
3369 self.update_ty(resolve, ty, span)?;
3370 }
3371 if let Some(ty) = &mut func.result {
3372 self.update_ty(resolve, ty, span)?;
3373 }
3374
3375 if let Some(ty) = &func.result {
3376 if self.type_has_borrow(resolve, ty) {
3377 match span {
3378 Some(span) => {
3379 bail!(Error::new(
3380 span,
3381 format!(
3382 "function returns a type which contains \
3383 a `borrow<T>` which is not supported"
3384 )
3385 ))
3386 }
3387 None => unreachable!(),
3388 }
3389 }
3390 }
3391
3392 Ok(())
3393 }
3394
3395 fn update_world(
3396 &mut self,
3397 world: &mut World,
3398 resolve: &mut Resolve,
3399 pkg_id: &PackageId,
3400 spans: &WorldSpan,
3401 ) -> Result<()> {
3402 assert_eq!(world.imports.len(), spans.imports.len());
3403 assert_eq!(world.exports.len(), spans.exports.len());
3404
3405 let imports = mem::take(&mut world.imports).into_iter();
3409 let imports = imports.zip(&spans.imports).map(|p| (p, true));
3410 let exports = mem::take(&mut world.exports).into_iter();
3411 let exports = exports.zip(&spans.exports).map(|p| (p, false));
3412 for (((mut name, mut item), span), import) in imports.chain(exports) {
3413 if let WorldItem::Type(id) = &mut item {
3416 *id = self.map_type(*id, Some(*span))?;
3417 }
3418 let stability = item.stability(resolve);
3419 if !resolve
3420 .include_stability(stability, pkg_id, Some(*span))
3421 .with_context(|| format!("failed to process world item in `{}`", world.name))?
3422 {
3423 continue;
3424 }
3425 self.update_world_key(&mut name, Some(*span))?;
3426 match &mut item {
3427 WorldItem::Interface { id, .. } => {
3428 *id = self.map_interface(*id, Some(*span))?;
3429 }
3430 WorldItem::Function(f) => {
3431 self.update_function(resolve, f, Some(*span))?;
3432 }
3433 WorldItem::Type(_) => {
3434 }
3436 }
3437
3438 let dst = if import {
3439 &mut world.imports
3440 } else {
3441 &mut world.exports
3442 };
3443 let prev = dst.insert(name, item);
3444 assert!(prev.is_none());
3445 }
3446
3447 Ok(())
3448 }
3449
3450 fn process_world_includes(
3451 &self,
3452 id: WorldId,
3453 resolve: &mut Resolve,
3454 pkg_id: &PackageId,
3455 spans: &WorldSpan,
3456 ) -> Result<()> {
3457 let world = &mut resolve.worlds[id];
3458 assert_eq!(world.includes.len(), spans.includes.len());
3461 let includes = mem::take(&mut world.includes);
3462 let include_names = mem::take(&mut world.include_names);
3463 for (((stability, include_world), span), names) in includes
3464 .into_iter()
3465 .zip(&spans.includes)
3466 .zip(&include_names)
3467 {
3468 if !resolve
3469 .include_stability(&stability, pkg_id, Some(*span))
3470 .with_context(|| {
3471 format!(
3472 "failed to process feature gate for included world [{}] in package [{}]",
3473 resolve.worlds[include_world].name.as_str(),
3474 resolve.packages[*pkg_id].name
3475 )
3476 })?
3477 {
3478 continue;
3479 }
3480 self.resolve_include(id, include_world, names, *span, pkg_id, resolve)?;
3481 }
3482
3483 Ok(())
3484 }
3485
3486 fn update_world_key(&self, key: &mut WorldKey, span: Option<Span>) -> Result<()> {
3487 match key {
3488 WorldKey::Name(_) => {}
3489 WorldKey::Interface(id) => {
3490 *id = self.map_interface(*id, span)?;
3491 }
3492 }
3493 Ok(())
3494 }
3495
3496 fn resolve_include(
3497 &self,
3498 id: WorldId,
3499 include_world_id_orig: WorldId,
3500 names: &[IncludeName],
3501 span: Span,
3502 pkg_id: &PackageId,
3503 resolve: &mut Resolve,
3504 ) -> Result<()> {
3505 let world = &resolve.worlds[id];
3506 let include_world_id = self.map_world(include_world_id_orig, Some(span))?;
3507 let include_world = resolve.worlds[include_world_id].clone();
3508 let mut names_ = names.to_owned();
3509 let is_external_include = world.package != include_world.package;
3510
3511 for import in include_world.imports.iter() {
3513 self.remove_matching_name(import, &mut names_);
3514 }
3515 for export in include_world.exports.iter() {
3516 self.remove_matching_name(export, &mut names_);
3517 }
3518 if !names_.is_empty() {
3519 bail!(Error::new(
3520 span,
3521 format!(
3522 "no import or export kebab-name `{}`. Note that an ID does not support renaming",
3523 names_[0].name
3524 ),
3525 ));
3526 }
3527
3528 let mut cloner = clone::Cloner::new(
3529 resolve,
3530 TypeOwner::World(if is_external_include {
3531 include_world_id
3532 } else {
3533 include_world_id
3534 }),
3536 TypeOwner::World(id),
3537 );
3538 cloner.new_package = Some(*pkg_id);
3539
3540 for import in include_world.imports.iter() {
3542 self.resolve_include_item(
3543 &mut cloner,
3544 names,
3545 |resolve| &mut resolve.worlds[id].imports,
3546 import,
3547 span,
3548 "import",
3549 is_external_include,
3550 )?;
3551 }
3552
3553 for export in include_world.exports.iter() {
3554 self.resolve_include_item(
3555 &mut cloner,
3556 names,
3557 |resolve| &mut resolve.worlds[id].exports,
3558 export,
3559 span,
3560 "export",
3561 is_external_include,
3562 )?;
3563 }
3564 Ok(())
3565 }
3566
3567 fn resolve_include_item(
3568 &self,
3569 cloner: &mut clone::Cloner<'_>,
3570 names: &[IncludeName],
3571 get_items: impl Fn(&mut Resolve) -> &mut IndexMap<WorldKey, WorldItem>,
3572 item: (&WorldKey, &WorldItem),
3573 span: Span,
3574 item_type: &str,
3575 is_external_include: bool,
3576 ) -> Result<()> {
3577 match item.0 {
3578 WorldKey::Name(n) => {
3579 let n = if let Some(found) = names
3580 .into_iter()
3581 .find(|include_name| include_name.name == n.clone())
3582 {
3583 found.as_.clone()
3584 } else {
3585 n.clone()
3586 };
3587
3588 let mut new_item = item.1.clone();
3594 let key = WorldKey::Name(n.clone());
3595 cloner.world_item(&key, &mut new_item);
3596 match &mut new_item {
3597 WorldItem::Function(f) => f.name = n.clone(),
3598 WorldItem::Type(id) => cloner.resolve.types[*id].name = Some(n.clone()),
3599 WorldItem::Interface { .. } => {}
3600 }
3601
3602 let prev = get_items(cloner.resolve).insert(key, new_item);
3603 if prev.is_some() {
3604 bail!(Error::new(
3605 span,
3606 format!("{item_type} of `{n}` shadows previously {item_type}ed items"),
3607 ))
3608 }
3609 }
3610 key @ WorldKey::Interface(_) => {
3611 let prev = get_items(cloner.resolve)
3612 .entry(key.clone())
3613 .or_insert(item.1.clone());
3614 match (&item.1, prev) {
3615 (
3616 WorldItem::Interface {
3617 id: aid,
3618 stability: astability,
3619 },
3620 WorldItem::Interface {
3621 id: bid,
3622 stability: bstability,
3623 },
3624 ) => {
3625 assert_eq!(*aid, *bid);
3626 merge_include_stability(astability, bstability, is_external_include)?;
3627 }
3628 (WorldItem::Interface { .. }, _) => unreachable!(),
3629 (WorldItem::Function(_), _) => unreachable!(),
3630 (WorldItem::Type(_), _) => unreachable!(),
3631 }
3632 }
3633 };
3634
3635 Ok(())
3636 }
3637
3638 fn remove_matching_name(&self, item: (&WorldKey, &WorldItem), names: &mut Vec<IncludeName>) {
3639 match item.0 {
3640 WorldKey::Name(n) => {
3641 names.retain(|name| name.name != n.clone());
3642 }
3643 _ => {}
3644 }
3645 }
3646
3647 fn type_has_borrow(&mut self, resolve: &Resolve, ty: &Type) -> bool {
3648 let id = match ty {
3649 Type::Id(id) => *id,
3650 _ => return false,
3651 };
3652
3653 if let Some(Some(has_borrow)) = self.type_has_borrow.get(id.index()) {
3654 return *has_borrow;
3655 }
3656
3657 let result = self.typedef_has_borrow(resolve, &resolve.types[id]);
3658 if self.type_has_borrow.len() <= id.index() {
3659 self.type_has_borrow.resize(id.index() + 1, None);
3660 }
3661 self.type_has_borrow[id.index()] = Some(result);
3662 result
3663 }
3664
3665 fn typedef_has_borrow(&mut self, resolve: &Resolve, ty: &TypeDef) -> bool {
3666 match &ty.kind {
3667 TypeDefKind::Type(t) => self.type_has_borrow(resolve, t),
3668 TypeDefKind::Variant(v) => v
3669 .cases
3670 .iter()
3671 .filter_map(|case| case.ty.as_ref())
3672 .any(|ty| self.type_has_borrow(resolve, ty)),
3673 TypeDefKind::Handle(Handle::Borrow(_)) => true,
3674 TypeDefKind::Handle(Handle::Own(_)) => false,
3675 TypeDefKind::Resource => false,
3676 TypeDefKind::Record(r) => r
3677 .fields
3678 .iter()
3679 .any(|case| self.type_has_borrow(resolve, &case.ty)),
3680 TypeDefKind::Flags(_) => false,
3681 TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.type_has_borrow(resolve, t)),
3682 TypeDefKind::Enum(_) => false,
3683 TypeDefKind::List(ty)
3684 | TypeDefKind::FixedSizeList(ty, ..)
3685 | TypeDefKind::Future(Some(ty))
3686 | TypeDefKind::Stream(Some(ty))
3687 | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty),
3688 TypeDefKind::Result(r) => [&r.ok, &r.err]
3689 .iter()
3690 .filter_map(|t| t.as_ref())
3691 .any(|t| self.type_has_borrow(resolve, t)),
3692 TypeDefKind::Future(None) | TypeDefKind::Stream(None) => false,
3693 TypeDefKind::Unknown => unreachable!(),
3694 }
3695 }
3696}
3697
3698struct MergeMap<'a> {
3699 package_map: HashMap<PackageId, PackageId>,
3702
3703 interface_map: HashMap<InterfaceId, InterfaceId>,
3706
3707 type_map: HashMap<TypeId, TypeId>,
3710
3711 world_map: HashMap<WorldId, WorldId>,
3714
3715 interfaces_to_add: Vec<(String, PackageId, InterfaceId)>,
3723 worlds_to_add: Vec<(String, PackageId, WorldId)>,
3724
3725 from: &'a Resolve,
3727
3728 into: &'a Resolve,
3730}
3731
3732impl<'a> MergeMap<'a> {
3733 fn new(from: &'a Resolve, into: &'a Resolve) -> MergeMap<'a> {
3734 MergeMap {
3735 package_map: Default::default(),
3736 interface_map: Default::default(),
3737 type_map: Default::default(),
3738 world_map: Default::default(),
3739 interfaces_to_add: Default::default(),
3740 worlds_to_add: Default::default(),
3741 from,
3742 into,
3743 }
3744 }
3745
3746 fn build(&mut self) -> Result<()> {
3747 for from_id in self.from.topological_packages() {
3748 let from = &self.from.packages[from_id];
3749 let into_id = match self.into.package_names.get(&from.name) {
3750 Some(id) => *id,
3751
3752 None => {
3755 log::trace!("adding unique package {}", from.name);
3756 continue;
3757 }
3758 };
3759 log::trace!("merging duplicate package {}", from.name);
3760
3761 self.build_package(from_id, into_id).with_context(|| {
3762 format!("failed to merge package `{}` into existing copy", from.name)
3763 })?;
3764 }
3765
3766 Ok(())
3767 }
3768
3769 fn build_package(&mut self, from_id: PackageId, into_id: PackageId) -> Result<()> {
3770 let prev = self.package_map.insert(from_id, into_id);
3771 assert!(prev.is_none());
3772
3773 let from = &self.from.packages[from_id];
3774 let into = &self.into.packages[into_id];
3775
3776 for (name, from_interface_id) in from.interfaces.iter() {
3780 let into_interface_id = match into.interfaces.get(name) {
3781 Some(id) => *id,
3782 None => {
3783 log::trace!("adding unique interface {}", name);
3784 self.interfaces_to_add
3785 .push((name.clone(), into_id, *from_interface_id));
3786 continue;
3787 }
3788 };
3789
3790 log::trace!("merging duplicate interfaces {}", name);
3791 self.build_interface(*from_interface_id, into_interface_id)
3792 .with_context(|| format!("failed to merge interface `{name}`"))?;
3793 }
3794
3795 for (name, from_world_id) in from.worlds.iter() {
3796 let into_world_id = match into.worlds.get(name) {
3797 Some(id) => *id,
3798 None => {
3799 log::trace!("adding unique world {}", name);
3800 self.worlds_to_add
3801 .push((name.clone(), into_id, *from_world_id));
3802 continue;
3803 }
3804 };
3805
3806 log::trace!("merging duplicate worlds {}", name);
3807 self.build_world(*from_world_id, into_world_id)
3808 .with_context(|| format!("failed to merge world `{name}`"))?;
3809 }
3810
3811 Ok(())
3812 }
3813
3814 fn build_interface(&mut self, from_id: InterfaceId, into_id: InterfaceId) -> Result<()> {
3815 let prev = self.interface_map.insert(from_id, into_id);
3816 assert!(prev.is_none());
3817
3818 let from_interface = &self.from.interfaces[from_id];
3819 let into_interface = &self.into.interfaces[into_id];
3820
3821 for (name, from_type_id) in from_interface.types.iter() {
3835 let into_type_id = *into_interface
3836 .types
3837 .get(name)
3838 .ok_or_else(|| anyhow!("expected type `{name}` to be present"))?;
3839 let prev = self.type_map.insert(*from_type_id, into_type_id);
3840 assert!(prev.is_none());
3841
3842 self.build_type_id(*from_type_id, into_type_id)
3843 .with_context(|| format!("mismatch in type `{name}`"))?;
3844 }
3845
3846 for (name, from_func) in from_interface.functions.iter() {
3847 let into_func = match into_interface.functions.get(name) {
3848 Some(func) => func,
3849 None => bail!("expected function `{name}` to be present"),
3850 };
3851 self.build_function(from_func, into_func)
3852 .with_context(|| format!("mismatch in function `{name}`"))?;
3853 }
3854
3855 Ok(())
3856 }
3857
3858 fn build_type_id(&mut self, from_id: TypeId, into_id: TypeId) -> Result<()> {
3859 let _ = from_id;
3863 let _ = into_id;
3864 Ok(())
3865 }
3866
3867 fn build_type(&mut self, from_ty: &Type, into_ty: &Type) -> Result<()> {
3868 match (from_ty, into_ty) {
3869 (Type::Id(from), Type::Id(into)) => {
3870 self.build_type_id(*from, *into)?;
3871 }
3872 (from, into) if from != into => bail!("different kinds of types"),
3873 _ => {}
3874 }
3875 Ok(())
3876 }
3877
3878 fn build_function(&mut self, from_func: &Function, into_func: &Function) -> Result<()> {
3879 if from_func.name != into_func.name {
3880 bail!(
3881 "different function names `{}` and `{}`",
3882 from_func.name,
3883 into_func.name
3884 );
3885 }
3886 match (&from_func.kind, &into_func.kind) {
3887 (FunctionKind::Freestanding, FunctionKind::Freestanding) => {}
3888 (FunctionKind::AsyncFreestanding, FunctionKind::AsyncFreestanding) => {}
3889
3890 (FunctionKind::Method(from), FunctionKind::Method(into))
3891 | (FunctionKind::Static(from), FunctionKind::Static(into))
3892 | (FunctionKind::AsyncMethod(from), FunctionKind::AsyncMethod(into))
3893 | (FunctionKind::AsyncStatic(from), FunctionKind::AsyncStatic(into))
3894 | (FunctionKind::Constructor(from), FunctionKind::Constructor(into)) => {
3895 self.build_type_id(*from, *into)
3896 .context("different function kind types")?;
3897 }
3898
3899 (FunctionKind::Method(_), _)
3900 | (FunctionKind::Constructor(_), _)
3901 | (FunctionKind::Static(_), _)
3902 | (FunctionKind::Freestanding, _)
3903 | (FunctionKind::AsyncFreestanding, _)
3904 | (FunctionKind::AsyncMethod(_), _)
3905 | (FunctionKind::AsyncStatic(_), _) => {
3906 bail!("different function kind types")
3907 }
3908 }
3909
3910 if from_func.params.len() != into_func.params.len() {
3911 bail!("different number of function parameters");
3912 }
3913 for ((from_name, from_ty), (into_name, into_ty)) in
3914 from_func.params.iter().zip(&into_func.params)
3915 {
3916 if from_name != into_name {
3917 bail!("different function parameter names: {from_name} != {into_name}");
3918 }
3919 self.build_type(from_ty, into_ty)
3920 .with_context(|| format!("different function parameter types for `{from_name}`"))?;
3921 }
3922 match (&from_func.result, &into_func.result) {
3923 (Some(from_ty), Some(into_ty)) => {
3924 self.build_type(from_ty, into_ty)
3925 .context("different function result types")?;
3926 }
3927 (None, None) => {}
3928 (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
3929 }
3930 Ok(())
3931 }
3932
3933 fn build_world(&mut self, from_id: WorldId, into_id: WorldId) -> Result<()> {
3934 let prev = self.world_map.insert(from_id, into_id);
3935 assert!(prev.is_none());
3936
3937 let from_world = &self.from.worlds[from_id];
3938 let into_world = &self.into.worlds[into_id];
3939
3940 if from_world.imports.len() != into_world.imports.len() {
3949 bail!("world contains different number of imports than expected");
3950 }
3951 if from_world.exports.len() != into_world.exports.len() {
3952 bail!("world contains different number of exports than expected");
3953 }
3954
3955 for (from_name, from) in from_world.imports.iter() {
3956 let into_name = MergeMap::map_name(from_name, &self.interface_map);
3957 let name_str = self.from.name_world_key(from_name);
3958 let into = into_world
3959 .imports
3960 .get(&into_name)
3961 .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?;
3962 self.match_world_item(from, into)
3963 .with_context(|| format!("import `{name_str}` didn't match target world"))?;
3964 }
3965
3966 for (from_name, from) in from_world.exports.iter() {
3967 let into_name = MergeMap::map_name(from_name, &self.interface_map);
3968 let name_str = self.from.name_world_key(from_name);
3969 let into = into_world
3970 .exports
3971 .get(&into_name)
3972 .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?;
3973 self.match_world_item(from, into)
3974 .with_context(|| format!("export `{name_str}` didn't match target world"))?;
3975 }
3976
3977 Ok(())
3978 }
3979
3980 fn map_name(
3981 from_name: &WorldKey,
3982 interface_map: &HashMap<InterfaceId, InterfaceId>,
3983 ) -> WorldKey {
3984 match from_name {
3985 WorldKey::Name(s) => WorldKey::Name(s.clone()),
3986 WorldKey::Interface(id) => {
3987 WorldKey::Interface(interface_map.get(id).copied().unwrap_or(*id))
3988 }
3989 }
3990 }
3991
3992 fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> Result<()> {
3993 match (from, into) {
3994 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
3995 match (
3996 &self.from.interfaces[*from].name,
3997 &self.into.interfaces[*into].name,
3998 ) {
3999 (None, None) => self.build_interface(*from, *into)?,
4003
4004 _ => {
4009 if self.interface_map.get(&from) != Some(&into) {
4010 bail!("interfaces are not the same");
4011 }
4012 }
4013 }
4014 }
4015 (WorldItem::Function(from), WorldItem::Function(into)) => {
4016 let _ = (from, into);
4017 }
4020 (WorldItem::Type(from), WorldItem::Type(into)) => {
4021 let prev = self.type_map.insert(*from, *into);
4024 assert!(prev.is_none());
4025 }
4026
4027 (WorldItem::Interface { .. }, _)
4028 | (WorldItem::Function(_), _)
4029 | (WorldItem::Type(_), _) => {
4030 bail!("world items do not have the same type")
4031 }
4032 }
4033 Ok(())
4034 }
4035}
4036
4037fn update_stability(from: &Stability, into: &mut Stability) -> Result<()> {
4043 if from == into || from.is_unknown() {
4046 return Ok(());
4047 }
4048 if into.is_unknown() {
4051 *into = from.clone();
4052 return Ok(());
4053 }
4054
4055 bail!("mismatch in stability from '{:?}' to '{:?}'", from, into)
4058}
4059
4060fn merge_include_stability(
4061 from: &Stability,
4062 into: &mut Stability,
4063 is_external_include: bool,
4064) -> Result<()> {
4065 if is_external_include && from.is_stable() {
4066 log::trace!("dropped stability from external package");
4067 *into = Stability::Unknown;
4068 return Ok(());
4069 }
4070
4071 return update_stability(from, into);
4072}
4073
4074#[derive(Debug, Clone)]
4087pub struct InvalidTransitiveDependency(String);
4088
4089impl fmt::Display for InvalidTransitiveDependency {
4090 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4091 write!(
4092 f,
4093 "interface `{}` transitively depends on an interface in \
4094 incompatible ways",
4095 self.0
4096 )
4097 }
4098}
4099
4100impl std::error::Error for InvalidTransitiveDependency {}
4101
4102#[cfg(test)]
4103mod tests {
4104 use crate::Resolve;
4105 use anyhow::Result;
4106
4107 #[test]
4108 fn select_world() -> Result<()> {
4109 let mut resolve = Resolve::default();
4110 resolve.push_str(
4111 "test.wit",
4112 r#"
4113 package foo:bar@0.1.0;
4114
4115 world foo {}
4116 "#,
4117 )?;
4118 resolve.push_str(
4119 "test.wit",
4120 r#"
4121 package foo:baz@0.1.0;
4122
4123 world foo {}
4124 "#,
4125 )?;
4126 resolve.push_str(
4127 "test.wit",
4128 r#"
4129 package foo:baz@0.2.0;
4130
4131 world foo {}
4132 "#,
4133 )?;
4134
4135 let dummy = resolve.push_str(
4136 "test.wit",
4137 r#"
4138 package foo:dummy;
4139
4140 world foo {}
4141 "#,
4142 )?;
4143
4144 assert!(resolve.select_world(dummy, None).is_ok());
4145 assert!(resolve.select_world(dummy, Some("xx")).is_err());
4146 assert!(resolve.select_world(dummy, Some("")).is_err());
4147 assert!(resolve.select_world(dummy, Some("foo:bar/foo")).is_ok());
4148 assert!(
4149 resolve
4150 .select_world(dummy, Some("foo:bar/foo@0.1.0"))
4151 .is_ok()
4152 );
4153 assert!(resolve.select_world(dummy, Some("foo:baz/foo")).is_err());
4154 assert!(
4155 resolve
4156 .select_world(dummy, Some("foo:baz/foo@0.1.0"))
4157 .is_ok()
4158 );
4159 assert!(
4160 resolve
4161 .select_world(dummy, Some("foo:baz/foo@0.2.0"))
4162 .is_ok()
4163 );
4164 Ok(())
4165 }
4166}