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::{anyhow, bail, Context, Result};
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::{parse_use_path, ParsedUsePath};
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::{decode, DecodedWasm};
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 source_map.rewrite_error(|| Remap::default().append(self, unresolved))
528 }
529
530 pub fn push_group(&mut self, unresolved_group: UnresolvedPackageGroup) -> Result<PackageId> {
539 let (pkg_id, _) = self.sort_unresolved_packages(unresolved_group, Vec::new())?;
540 Ok(pkg_id)
541 }
542
543 pub fn push_str(&mut self, path: impl AsRef<Path>, contents: &str) -> Result<PackageId> {
550 self.push_group(UnresolvedPackageGroup::parse(path.as_ref(), contents)?)
551 }
552
553 pub fn all_bits_valid(&self, ty: &Type) -> bool {
554 match ty {
555 Type::U8
556 | Type::S8
557 | Type::U16
558 | Type::S16
559 | Type::U32
560 | Type::S32
561 | Type::U64
562 | Type::S64
563 | Type::F32
564 | Type::F64 => true,
565
566 Type::Bool | Type::Char | Type::String => false,
567
568 Type::Id(id) => match &self.types[*id].kind {
569 TypeDefKind::List(_)
570 | TypeDefKind::Variant(_)
571 | TypeDefKind::Enum(_)
572 | TypeDefKind::Option(_)
573 | TypeDefKind::Result(_)
574 | TypeDefKind::Future(_)
575 | TypeDefKind::Stream(_)
576 | TypeDefKind::ErrorContext => false,
577 TypeDefKind::Type(t) => self.all_bits_valid(t),
578
579 TypeDefKind::Handle(h) => match h {
580 crate::Handle::Own(_) => true,
581 crate::Handle::Borrow(_) => true,
582 },
583
584 TypeDefKind::Resource => false,
585 TypeDefKind::Record(r) => r.fields.iter().all(|f| self.all_bits_valid(&f.ty)),
586 TypeDefKind::Tuple(t) => t.types.iter().all(|t| self.all_bits_valid(t)),
587
588 TypeDefKind::Flags(_) => false,
592
593 TypeDefKind::Unknown => unreachable!(),
594 },
595 }
596 }
597
598 pub fn merge(&mut self, resolve: Resolve) -> Result<Remap> {
610 log::trace!(
611 "merging {} packages into {} packages",
612 resolve.packages.len(),
613 self.packages.len()
614 );
615
616 let mut map = MergeMap::new(&resolve, &self);
617 map.build()?;
618 let MergeMap {
619 package_map,
620 interface_map,
621 type_map,
622 world_map,
623 interfaces_to_add,
624 worlds_to_add,
625 ..
626 } = map;
627
628 let mut remap = Remap::default();
647 let Resolve {
648 types,
649 worlds,
650 interfaces,
651 packages,
652 package_names,
653 features: _,
654 ..
655 } = resolve;
656
657 let mut moved_types = Vec::new();
658 for (id, mut ty) in types {
659 let new_id = match type_map.get(&id).copied() {
660 Some(id) => {
661 update_stability(&ty.stability, &mut self.types[id].stability)?;
662 id
663 }
664 None => {
665 log::debug!("moving type {:?}", ty.name);
666 moved_types.push(id);
667 remap.update_typedef(self, &mut ty, None)?;
668 self.types.alloc(ty)
669 }
670 };
671 assert_eq!(remap.types.len(), id.index());
672 remap.types.push(Some(new_id));
673 }
674
675 let mut moved_interfaces = Vec::new();
676 for (id, mut iface) in interfaces {
677 let new_id = match interface_map.get(&id).copied() {
678 Some(id) => {
679 update_stability(&iface.stability, &mut self.interfaces[id].stability)?;
680 id
681 }
682 None => {
683 log::debug!("moving interface {:?}", iface.name);
684 moved_interfaces.push(id);
685 remap.update_interface(self, &mut iface, None)?;
686 self.interfaces.alloc(iface)
687 }
688 };
689 assert_eq!(remap.interfaces.len(), id.index());
690 remap.interfaces.push(Some(new_id));
691 }
692
693 let mut moved_worlds = Vec::new();
694 for (id, mut world) in worlds {
695 let new_id = match world_map.get(&id).copied() {
696 Some(id) => {
697 update_stability(&world.stability, &mut self.worlds[id].stability)?;
698 id
699 }
700 None => {
701 log::debug!("moving world {}", world.name);
702 moved_worlds.push(id);
703 let mut update = |map: &mut IndexMap<WorldKey, WorldItem>| -> Result<_> {
704 for (mut name, mut item) in mem::take(map) {
705 remap.update_world_key(&mut name, None)?;
706 match &mut item {
707 WorldItem::Function(f) => remap.update_function(self, f, None)?,
708 WorldItem::Interface { id, .. } => {
709 *id = remap.map_interface(*id, None)?
710 }
711 WorldItem::Type(i) => *i = remap.map_type(*i, None)?,
712 }
713 map.insert(name, item);
714 }
715 Ok(())
716 };
717 update(&mut world.imports)?;
718 update(&mut world.exports)?;
719 self.worlds.alloc(world)
720 }
721 };
722 assert_eq!(remap.worlds.len(), id.index());
723 remap.worlds.push(Some(new_id));
724 }
725
726 for (id, mut pkg) in packages {
727 let new_id = match package_map.get(&id).copied() {
728 Some(id) => id,
729 None => {
730 for (_, id) in pkg.interfaces.iter_mut() {
731 *id = remap.map_interface(*id, None)?;
732 }
733 for (_, id) in pkg.worlds.iter_mut() {
734 *id = remap.map_world(*id, None)?;
735 }
736 self.packages.alloc(pkg)
737 }
738 };
739 assert_eq!(remap.packages.len(), id.index());
740 remap.packages.push(new_id);
741 }
742
743 for (name, id) in package_names {
744 let id = remap.packages[id.index()];
745 if let Some(prev) = self.package_names.insert(name, id) {
746 assert_eq!(prev, id);
747 }
748 }
749
750 for id in moved_worlds {
758 let id = remap.map_world(id, None)?;
759 if let Some(pkg) = self.worlds[id].package.as_mut() {
760 *pkg = remap.packages[pkg.index()];
761 }
762 }
763 for id in moved_interfaces {
764 let id = remap.map_interface(id, None)?;
765 if let Some(pkg) = self.interfaces[id].package.as_mut() {
766 *pkg = remap.packages[pkg.index()];
767 }
768 }
769 for id in moved_types {
770 let id = remap.map_type(id, None)?;
771 match &mut self.types[id].owner {
772 TypeOwner::Interface(id) => *id = remap.map_interface(*id, None)?,
773 TypeOwner::World(id) => *id = remap.map_world(*id, None)?,
774 TypeOwner::None => {}
775 }
776 }
777
778 for (name, pkg, iface) in interfaces_to_add {
783 let prev = self.packages[pkg]
784 .interfaces
785 .insert(name, remap.map_interface(iface, None)?);
786 assert!(prev.is_none());
787 }
788 for (name, pkg, world) in worlds_to_add {
789 let prev = self.packages[pkg]
790 .worlds
791 .insert(name, remap.map_world(world, None)?);
792 assert!(prev.is_none());
793 }
794
795 log::trace!("now have {} packages", self.packages.len());
796
797 #[cfg(debug_assertions)]
798 self.assert_valid();
799 Ok(remap)
800 }
801
802 pub fn merge_worlds(&mut self, from: WorldId, into: WorldId) -> Result<()> {
813 let mut new_imports = Vec::new();
814 let mut new_exports = Vec::new();
815
816 let from_world = &self.worlds[from];
817 let into_world = &self.worlds[into];
818
819 log::trace!("merging {} into {}", from_world.name, into_world.name);
820
821 for (name, from_import) in from_world.imports.iter() {
829 let name_str = self.name_world_key(name);
830 match into_world.imports.get(name) {
831 Some(into_import) => {
832 log::trace!("info/from shared import on `{name_str}`");
833 self.merge_world_item(from_import, into_import)
834 .with_context(|| format!("failed to merge world import {name_str}"))?;
835 }
836 None => {
837 log::trace!("new import: `{name_str}`");
838 new_imports.push((name.clone(), from_import.clone()));
839 }
840 }
841 }
842
843 let mut must_be_imported = HashMap::new();
850 for (key, export) in into_world.exports.iter() {
851 for dep in self.world_item_direct_deps(export) {
852 if into_world.exports.contains_key(&WorldKey::Interface(dep)) {
853 continue;
854 }
855 self.foreach_interface_dep(dep, &mut |id| {
856 must_be_imported.insert(id, key.clone());
857 });
858 }
859 }
860
861 for (name, from_export) in from_world.exports.iter() {
864 let name_str = self.name_world_key(name);
865 match into_world.exports.get(name) {
866 Some(into_export) => {
867 log::trace!("info/from shared export on `{name_str}`");
868 self.merge_world_item(from_export, into_export)
869 .with_context(|| format!("failed to merge world export {name_str}"))?;
870 }
871 None => {
872 log::trace!("new export `{name_str}`");
873 self.ensure_can_add_world_export(
876 into_world,
877 name,
878 from_export,
879 &must_be_imported,
880 )
881 .with_context(|| {
882 format!("failed to add export `{}`", self.name_world_key(name))
883 })?;
884 new_exports.push((name.clone(), from_export.clone()));
885 }
886 }
887 }
888
889 let mut cloner = clone::Cloner::new(self, TypeOwner::World(from), TypeOwner::World(into));
903 cloner.register_world_type_overlap(from, into);
904 for (name, item) in new_imports.iter_mut().chain(&mut new_exports) {
905 cloner.world_item(name, item);
906 }
907
908 let into_world = &mut self.worlds[into];
910 for (name, import) in new_imports {
911 let prev = into_world.imports.insert(name, import);
912 assert!(prev.is_none());
913 }
914 for (name, export) in new_exports {
915 let prev = into_world.exports.insert(name, export);
916 assert!(prev.is_none());
917 }
918
919 #[cfg(debug_assertions)]
920 self.assert_valid();
921 Ok(())
922 }
923
924 fn merge_world_item(&self, from: &WorldItem, into: &WorldItem) -> Result<()> {
925 let mut map = MergeMap::new(self, self);
926 match (from, into) {
927 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
928 if from == into {
933 return Ok(());
934 }
935
936 map.build_interface(*from, *into)
946 .context("failed to merge interfaces")?;
947 }
948
949 (WorldItem::Function(from), WorldItem::Function(into)) => {
952 map.build_function(from, into)
953 .context("failed to merge functions")?;
954 }
955 (WorldItem::Type(from), WorldItem::Type(into)) => {
956 map.build_type_id(*from, *into)
957 .context("failed to merge types")?;
958 }
959
960 (WorldItem::Interface { .. }, _)
962 | (WorldItem::Function { .. }, _)
963 | (WorldItem::Type { .. }, _) => {
964 bail!("different kinds of items");
965 }
966 }
967 assert!(map.interfaces_to_add.is_empty());
968 assert!(map.worlds_to_add.is_empty());
969 Ok(())
970 }
971
972 fn ensure_can_add_world_export(
984 &self,
985 into: &World,
986 name: &WorldKey,
987 item: &WorldItem,
988 must_be_imported: &HashMap<InterfaceId, WorldKey>,
989 ) -> Result<()> {
990 assert!(!into.exports.contains_key(name));
991 let name = self.name_world_key(name);
992
993 for dep in self.world_item_direct_deps(item) {
997 if into.exports.contains_key(&WorldKey::Interface(dep)) {
998 continue;
999 }
1000 self.ensure_not_exported(into, dep)
1001 .with_context(|| format!("failed validating export of `{name}`"))?;
1002 }
1003
1004 if let WorldItem::Interface { id, .. } = item {
1008 if let Some(export) = must_be_imported.get(&id) {
1009 let export_name = self.name_world_key(export);
1010 bail!(
1011 "export `{export_name}` depends on `{name}` \
1012 previously as an import which will change meaning \
1013 if `{name}` is added as an export"
1014 );
1015 }
1016 }
1017
1018 Ok(())
1019 }
1020
1021 fn ensure_not_exported(&self, world: &World, id: InterfaceId) -> Result<()> {
1022 let key = WorldKey::Interface(id);
1023 let name = self.name_world_key(&key);
1024 if world.exports.contains_key(&key) {
1025 bail!(
1026 "world exports `{name}` but it's also transitively used by an \
1027 import \
1028 which means that this is not valid"
1029 )
1030 }
1031 for dep in self.interface_direct_deps(id) {
1032 self.ensure_not_exported(world, dep)
1033 .with_context(|| format!("failed validating transitive import dep `{name}`"))?;
1034 }
1035 Ok(())
1036 }
1037
1038 fn world_item_direct_deps(&self, item: &WorldItem) -> impl Iterator<Item = InterfaceId> + '_ {
1044 let mut interface = None;
1045 let mut ty = None;
1046 match item {
1047 WorldItem::Function(_) => {}
1048 WorldItem::Type(id) => ty = Some(*id),
1049 WorldItem::Interface { id, .. } => interface = Some(*id),
1050 }
1051
1052 interface
1053 .into_iter()
1054 .flat_map(move |id| self.interface_direct_deps(id))
1055 .chain(ty.and_then(|t| self.type_interface_dep(t)))
1056 }
1057
1058 fn foreach_interface_dep(&self, id: InterfaceId, f: &mut dyn FnMut(InterfaceId)) {
1062 f(id);
1063 for dep in self.interface_direct_deps(id) {
1064 self.foreach_interface_dep(dep, f);
1065 }
1066 }
1067
1068 pub fn id_of(&self, interface: InterfaceId) -> Option<String> {
1072 let interface = &self.interfaces[interface];
1073 Some(self.id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1074 }
1075
1076 pub fn canonicalized_id_of(&self, interface: InterfaceId) -> Option<String> {
1081 let interface = &self.interfaces[interface];
1082 Some(self.canonicalized_id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1083 }
1084
1085 pub fn importize(&mut self, world_id: WorldId, out_world_name: Option<String>) -> Result<()> {
1101 let world = &mut self.worlds[world_id];
1106 let pkg = &mut self.packages[world.package.unwrap()];
1107 pkg.worlds.shift_remove(&world.name);
1108 if let Some(name) = out_world_name {
1109 world.name = name.clone();
1110 pkg.worlds.insert(name, world_id);
1111 } else {
1112 world.name.push_str("-importized");
1113 pkg.worlds.insert(world.name.clone(), world_id);
1114 }
1115
1116 world.imports.retain(|_, item| match item {
1119 WorldItem::Type(_) => true,
1120 _ => false,
1121 });
1122
1123 for (name, export) in mem::take(&mut world.exports) {
1124 match (name.clone(), world.imports.insert(name, export)) {
1125 (_, None) => {}
1127
1128 (WorldKey::Name(name), Some(_)) => {
1130 bail!("world export `{name}` conflicts with import of same name");
1131 }
1132
1133 (WorldKey::Interface(_), _) => unreachable!(),
1136 }
1137 }
1138
1139 self.elaborate_world(world_id)?;
1142
1143 #[cfg(debug_assertions)]
1144 self.assert_valid();
1145 Ok(())
1146 }
1147
1148 pub fn id_of_name(&self, pkg: PackageId, name: &str) -> String {
1150 let package = &self.packages[pkg];
1151 let mut base = String::new();
1152 base.push_str(&package.name.namespace);
1153 base.push_str(":");
1154 base.push_str(&package.name.name);
1155 base.push_str("/");
1156 base.push_str(name);
1157 if let Some(version) = &package.name.version {
1158 base.push_str(&format!("@{version}"));
1159 }
1160 base
1161 }
1162
1163 pub fn canonicalized_id_of_name(&self, pkg: PackageId, name: &str) -> String {
1169 let package = &self.packages[pkg];
1170 let mut base = String::new();
1171 base.push_str(&package.name.namespace);
1172 base.push_str(":");
1173 base.push_str(&package.name.name);
1174 base.push_str("/");
1175 base.push_str(name);
1176 if let Some(version) = &package.name.version {
1177 base.push_str("@");
1178 let string = PackageName::version_compat_track_string(version);
1179 base.push_str(&string);
1180 }
1181 base
1182 }
1183
1184 pub fn select_world(&self, package: PackageId, world: Option<&str>) -> Result<WorldId> {
1295 let world_path = match world {
1296 Some(world) => Some(
1297 parse_use_path(world)
1298 .with_context(|| format!("failed to parse world specifier `{world}`"))?,
1299 ),
1300 None => None,
1301 };
1302
1303 let (pkg, world_name) = match world_path {
1304 Some(ParsedUsePath::Name(name)) => (package, name),
1305 Some(ParsedUsePath::Package(pkg, interface)) => {
1306 let pkg = match self.package_names.get(&pkg) {
1307 Some(pkg) => *pkg,
1308 None => {
1309 let mut candidates = self.package_names.iter().filter(|(name, _)| {
1310 pkg.version.is_none()
1311 && pkg.name == name.name
1312 && pkg.namespace == name.namespace
1313 && name.version.is_some()
1314 });
1315 let candidate = candidates.next();
1316 if let Some((c2, _)) = candidates.next() {
1317 let (c1, _) = candidate.unwrap();
1318 bail!(
1319 "package name `{pkg}` is available at both \
1320 versions {} and {} but which is not specified",
1321 c1.version.as_ref().unwrap(),
1322 c2.version.as_ref().unwrap(),
1323 );
1324 }
1325 match candidate {
1326 Some((_, id)) => *id,
1327 None => bail!("unknown package `{pkg}`"),
1328 }
1329 }
1330 };
1331 (pkg, interface.to_string())
1332 }
1333 None => {
1334 let pkg = &self.packages[package];
1335 let worlds = pkg
1336 .worlds
1337 .values()
1338 .map(|world| (package, *world))
1339 .collect::<Vec<_>>();
1340
1341 match &worlds[..] {
1342 [] => bail!("The main package `{}` contains no worlds", pkg.name),
1343 [(_, world)] => return Ok(*world),
1344 _ => bail!(
1345 "multiple worlds found; one must be explicitly chosen:{}",
1346 worlds
1347 .iter()
1348 .map(|(pkg, world)| format!(
1349 "\n {}/{}",
1350 self.packages[*pkg].name, self.worlds[*world].name
1351 ))
1352 .collect::<String>()
1353 ),
1354 }
1355 }
1356 };
1357 let pkg = &self.packages[pkg];
1358 pkg.worlds
1359 .get(&world_name)
1360 .copied()
1361 .ok_or_else(|| anyhow!("no world named `{world_name}` in package"))
1362 }
1363
1364 pub fn name_world_key(&self, key: &WorldKey) -> String {
1366 match key {
1367 WorldKey::Name(s) => s.to_string(),
1368 WorldKey::Interface(i) => self.id_of(*i).expect("unexpected anonymous interface"),
1369 }
1370 }
1371
1372 pub fn name_canonicalized_world_key(&self, key: &WorldKey) -> String {
1375 match key {
1376 WorldKey::Name(s) => s.to_string(),
1377 WorldKey::Interface(i) => self
1378 .canonicalized_id_of(*i)
1379 .expect("unexpected anonymous interface"),
1380 }
1381 }
1382
1383 pub fn type_interface_dep(&self, id: TypeId) -> Option<InterfaceId> {
1389 let ty = &self.types[id];
1390 let dep = match ty.kind {
1391 TypeDefKind::Type(Type::Id(id)) => id,
1392 _ => return None,
1393 };
1394 let other = &self.types[dep];
1395 if ty.owner == other.owner {
1396 None
1397 } else {
1398 match other.owner {
1399 TypeOwner::Interface(id) => Some(id),
1400 _ => unreachable!(),
1401 }
1402 }
1403 }
1404
1405 pub fn interface_direct_deps(&self, id: InterfaceId) -> impl Iterator<Item = InterfaceId> + '_ {
1415 self.interfaces[id]
1416 .types
1417 .iter()
1418 .filter_map(move |(_name, ty)| self.type_interface_dep(*ty))
1419 }
1420
1421 pub fn package_direct_deps(&self, id: PackageId) -> impl Iterator<Item = PackageId> + '_ {
1431 let pkg = &self.packages[id];
1432
1433 pkg.interfaces
1434 .iter()
1435 .flat_map(move |(_name, id)| self.interface_direct_deps(*id))
1436 .chain(pkg.worlds.iter().flat_map(move |(_name, id)| {
1437 let world = &self.worlds[*id];
1438 world
1439 .imports
1440 .iter()
1441 .chain(world.exports.iter())
1442 .filter_map(move |(_name, item)| match item {
1443 WorldItem::Interface { id, .. } => Some(*id),
1444 WorldItem::Function(_) => None,
1445 WorldItem::Type(t) => self.type_interface_dep(*t),
1446 })
1447 }))
1448 .filter_map(move |iface_id| {
1449 let pkg = self.interfaces[iface_id].package?;
1450 if pkg == id {
1451 None
1452 } else {
1453 Some(pkg)
1454 }
1455 })
1456 }
1457
1458 pub fn topological_packages(&self) -> Vec<PackageId> {
1464 let mut pushed = vec![false; self.packages.len()];
1465 let mut order = Vec::new();
1466 for (id, _) in self.packages.iter() {
1467 self.build_topological_package_ordering(id, &mut pushed, &mut order);
1468 }
1469 order
1470 }
1471
1472 fn build_topological_package_ordering(
1473 &self,
1474 id: PackageId,
1475 pushed: &mut Vec<bool>,
1476 order: &mut Vec<PackageId>,
1477 ) {
1478 if pushed[id.index()] {
1479 return;
1480 }
1481 for dep in self.package_direct_deps(id) {
1482 self.build_topological_package_ordering(dep, pushed, order);
1483 }
1484 order.push(id);
1485 pushed[id.index()] = true;
1486 }
1487
1488 #[doc(hidden)]
1489 pub fn assert_valid(&self) {
1490 let mut package_interfaces = Vec::new();
1491 let mut package_worlds = Vec::new();
1492 for (id, pkg) in self.packages.iter() {
1493 let mut interfaces = HashSet::new();
1494 for (name, iface) in pkg.interfaces.iter() {
1495 assert!(interfaces.insert(*iface));
1496 let iface = &self.interfaces[*iface];
1497 assert_eq!(name, iface.name.as_ref().unwrap());
1498 assert_eq!(iface.package.unwrap(), id);
1499 }
1500 package_interfaces.push(pkg.interfaces.values().copied().collect::<HashSet<_>>());
1501 let mut worlds = HashSet::new();
1502 for (name, world) in pkg.worlds.iter() {
1503 assert!(worlds.insert(*world));
1504 assert_eq!(
1505 pkg.worlds.get_key_value(name),
1506 Some((name, world)),
1507 "`MutableKeys` impl may have been used to change a key's hash or equality"
1508 );
1509 let world = &self.worlds[*world];
1510 assert_eq!(*name, world.name);
1511 assert_eq!(world.package.unwrap(), id);
1512 }
1513 package_worlds.push(pkg.worlds.values().copied().collect::<HashSet<_>>());
1514 }
1515
1516 let mut interface_types = Vec::new();
1517 for (id, iface) in self.interfaces.iter() {
1518 assert!(self.packages.get(iface.package.unwrap()).is_some());
1519 if iface.name.is_some() {
1520 assert!(package_interfaces[iface.package.unwrap().index()].contains(&id));
1521 }
1522
1523 for (name, ty) in iface.types.iter() {
1524 let ty = &self.types[*ty];
1525 assert_eq!(ty.name.as_ref(), Some(name));
1526 assert_eq!(ty.owner, TypeOwner::Interface(id));
1527 }
1528 interface_types.push(iface.types.values().copied().collect::<HashSet<_>>());
1529 for (name, f) in iface.functions.iter() {
1530 assert_eq!(*name, f.name);
1531 }
1532 }
1533
1534 let mut world_types = Vec::new();
1535 for (id, world) in self.worlds.iter() {
1536 log::debug!("validating world {}", &world.name);
1537 if let Some(package) = world.package {
1538 assert!(self.packages.get(package).is_some());
1539 assert!(package_worlds[package.index()].contains(&id));
1540 }
1541 assert!(world.includes.is_empty());
1542
1543 let mut types = HashSet::new();
1544 for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1545 log::debug!("validating world item: {}", self.name_world_key(name));
1546 match item {
1547 WorldItem::Interface { id, .. } => {
1548 if matches!(name, WorldKey::Name(_)) {
1551 assert_eq!(self.interfaces[*id].package, world.package);
1552 }
1553 }
1554 WorldItem::Function(f) => {
1555 assert!(!matches!(name, WorldKey::Interface(_)));
1556 assert_eq!(f.name, name.clone().unwrap_name());
1557 }
1558 WorldItem::Type(ty) => {
1559 assert!(!matches!(name, WorldKey::Interface(_)));
1560 assert!(types.insert(*ty));
1561 let ty = &self.types[*ty];
1562 assert_eq!(ty.name, Some(name.clone().unwrap_name()));
1563 assert_eq!(ty.owner, TypeOwner::World(id));
1564 }
1565 }
1566 }
1567 self.assert_world_elaborated(world);
1568 world_types.push(types);
1569 }
1570
1571 for (ty_id, ty) in self.types.iter() {
1572 match ty.owner {
1573 TypeOwner::Interface(id) => {
1574 assert!(self.interfaces.get(id).is_some());
1575 assert!(interface_types[id.index()].contains(&ty_id));
1576 }
1577 TypeOwner::World(id) => {
1578 assert!(self.worlds.get(id).is_some());
1579 assert!(world_types[id.index()].contains(&ty_id));
1580 }
1581 TypeOwner::None => {}
1582 }
1583 }
1584
1585 self.assert_topologically_sorted();
1586 }
1587
1588 fn assert_topologically_sorted(&self) {
1589 let mut positions = IndexMap::new();
1590 for id in self.topological_packages() {
1591 let pkg = &self.packages[id];
1592 log::debug!("pkg {}", pkg.name);
1593 let prev = positions.insert(Some(id), IndexSet::new());
1594 assert!(prev.is_none());
1595 }
1596 positions.insert(None, IndexSet::new());
1597
1598 for (id, iface) in self.interfaces.iter() {
1599 log::debug!("iface {:?}", iface.name);
1600 let ok = positions.get_mut(&iface.package).unwrap().insert(id);
1601 assert!(ok);
1602 }
1603
1604 for (_, world) in self.worlds.iter() {
1605 log::debug!("world {:?}", world.name);
1606
1607 let my_package = world.package;
1608 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1609
1610 for (_, item) in world.imports.iter().chain(&world.exports) {
1611 let id = match item {
1612 WorldItem::Interface { id, .. } => *id,
1613 _ => continue,
1614 };
1615 let other_package = self.interfaces[id].package;
1616 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1617
1618 assert!(other_package_pos <= my_package_pos);
1619 }
1620 }
1621
1622 for (_id, ty) in self.types.iter() {
1623 log::debug!("type {:?} {:?}", ty.name, ty.owner);
1624 let other_id = match ty.kind {
1625 TypeDefKind::Type(Type::Id(ty)) => ty,
1626 _ => continue,
1627 };
1628 let other = &self.types[other_id];
1629 if ty.kind == other.kind {
1630 continue;
1631 }
1632 let my_interface = match ty.owner {
1633 TypeOwner::Interface(id) => id,
1634 _ => continue,
1635 };
1636 let other_interface = match other.owner {
1637 TypeOwner::Interface(id) => id,
1638 _ => continue,
1639 };
1640
1641 let my_package = self.interfaces[my_interface].package;
1642 let other_package = self.interfaces[other_interface].package;
1643 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1644 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1645
1646 if my_package_pos == other_package_pos {
1647 let interfaces = &positions[&my_package];
1648 let my_interface_pos = interfaces.get_index_of(&my_interface).unwrap();
1649 let other_interface_pos = interfaces.get_index_of(&other_interface).unwrap();
1650 assert!(other_interface_pos <= my_interface_pos);
1651 } else {
1652 assert!(other_package_pos < my_package_pos);
1653 }
1654 }
1655 }
1656
1657 fn assert_world_elaborated(&self, world: &World) {
1658 for (key, item) in world.imports.iter() {
1659 log::debug!(
1660 "asserting elaborated world import {}",
1661 self.name_world_key(key)
1662 );
1663 match item {
1664 WorldItem::Type(t) => self.assert_world_imports_type_deps(world, key, *t),
1665
1666 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1668
1669 WorldItem::Interface { id, .. } => {
1671 for dep in self.interface_direct_deps(*id) {
1672 assert!(
1673 world.imports.contains_key(&WorldKey::Interface(dep)),
1674 "world import of {} is missing transitive dep of {}",
1675 self.name_world_key(key),
1676 self.id_of(dep).unwrap(),
1677 );
1678 }
1679 }
1680 }
1681 }
1682 for (key, item) in world.exports.iter() {
1683 log::debug!(
1684 "asserting elaborated world export {}",
1685 self.name_world_key(key)
1686 );
1687 match item {
1688 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1690
1691 WorldItem::Interface { id, .. } => {
1695 for dep in self.interface_direct_deps(*id) {
1696 let dep_key = WorldKey::Interface(dep);
1697 if world.exports.contains_key(&dep_key) {
1698 continue;
1699 }
1700 self.foreach_interface_dep(dep, &mut |dep| {
1701 let dep_key = WorldKey::Interface(dep);
1702 assert!(
1703 world.imports.contains_key(&dep_key),
1704 "world should import {} (required by {})",
1705 self.name_world_key(&dep_key),
1706 self.name_world_key(key),
1707 );
1708 assert!(
1709 !world.exports.contains_key(&dep_key),
1710 "world should not export {} (required by {})",
1711 self.name_world_key(&dep_key),
1712 self.name_world_key(key),
1713 );
1714 });
1715 }
1716 }
1717
1718 WorldItem::Type(_) => unreachable!(),
1720 }
1721 }
1722 }
1723
1724 fn assert_world_imports_type_deps(&self, world: &World, key: &WorldKey, ty: TypeId) {
1725 let ty = &self.types[ty];
1728 if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
1729 if let TypeOwner::Interface(id) = self.types[other].owner {
1730 let key = WorldKey::Interface(id);
1731 assert!(world.imports.contains_key(&key));
1732 return;
1733 }
1734 }
1735
1736 let mut visitor = MyVisit(self, Vec::new());
1740 visitor.visit_type_def(self, ty);
1741 for ty in visitor.1 {
1742 let ty = &self.types[ty];
1743 let Some(name) = ty.name.clone() else {
1744 continue;
1745 };
1746 let dep_key = WorldKey::Name(name);
1747 assert!(
1748 world.imports.contains_key(&dep_key),
1749 "world import `{}` should also force an import of `{}`",
1750 self.name_world_key(key),
1751 self.name_world_key(&dep_key),
1752 );
1753 }
1754
1755 struct MyVisit<'a>(&'a Resolve, Vec<TypeId>);
1756
1757 impl TypeIdVisitor for MyVisit<'_> {
1758 fn before_visit_type_id(&mut self, id: TypeId) -> bool {
1759 self.1.push(id);
1760 self.0.types[id].name.is_none()
1762 }
1763 }
1764 }
1765
1766 fn assert_world_function_imports_types(&self, world: &World, key: &WorldKey, func: &Function) {
1770 for ty in func
1771 .parameter_and_result_types()
1772 .chain(func.kind.resource().map(Type::Id))
1773 {
1774 let Type::Id(id) = ty else {
1775 continue;
1776 };
1777 self.assert_world_imports_type_deps(world, key, id);
1778 }
1779 }
1780
1781 fn include_stability(
1797 &self,
1798 stability: &Stability,
1799 pkg_id: &PackageId,
1800 span: Option<Span>,
1801 ) -> Result<bool> {
1802 let err = |msg: String| match span {
1803 Some(span) => Error::new(span, msg).into(),
1804 None => anyhow::Error::msg(msg),
1805 };
1806 Ok(match stability {
1807 Stability::Unknown => true,
1808 Stability::Stable { since, .. } => {
1811 let Some(p) = self.packages.get(*pkg_id) else {
1812 return Ok(true);
1820 };
1821
1822 let package_version = p.name.version.as_ref().ok_or_else(|| {
1825 err(format!(
1826 "package [{}] contains a feature gate with a version \
1827 specifier, so it must have a version",
1828 p.name
1829 ))
1830 })?;
1831
1832 if since > package_version {
1836 return Err(err(format!(
1837 "feature gate cannot reference unreleased version \
1838 {since} of package [{}] (current version {package_version})",
1839 p.name
1840 )));
1841 }
1842
1843 true
1844 }
1845 Stability::Unstable { feature, .. } => {
1846 self.features.contains(feature) || self.all_features
1847 }
1848 })
1849 }
1850
1851 fn include_type(&self, ty: &TypeDef, pkgid: PackageId, span: Span) -> Result<bool> {
1854 self.include_stability(&ty.stability, &pkgid, Some(span))
1855 .with_context(|| {
1856 format!(
1857 "failed to process feature gate for type [{}] in package [{}]",
1858 ty.name.as_ref().map(String::as_str).unwrap_or("<unknown>"),
1859 self.packages[pkgid].name,
1860 )
1861 })
1862 }
1863
1864 fn elaborate_world(&mut self, world_id: WorldId) -> Result<()> {
1876 let mut new_imports = IndexMap::new();
1880 let world = &self.worlds[world_id];
1881 for (name, item) in world.imports.iter() {
1882 match item {
1883 WorldItem::Interface { id, stability } => {
1886 self.elaborate_world_import(&mut new_imports, name.clone(), *id, &stability);
1887 }
1888
1889 WorldItem::Function(_) => {
1892 let prev = new_imports.insert(name.clone(), item.clone());
1893 assert!(prev.is_none());
1894 }
1895
1896 WorldItem::Type(id) => {
1900 if let Some(dep) = self.type_interface_dep(*id) {
1901 self.elaborate_world_import(
1902 &mut new_imports,
1903 WorldKey::Interface(dep),
1904 dep,
1905 &self.types[*id].stability,
1906 );
1907 }
1908 let prev = new_imports.insert(name.clone(), item.clone());
1909 assert!(prev.is_none());
1910 }
1911 }
1912 }
1913
1914 let mut new_exports = IndexMap::new();
1920 let mut export_interfaces = IndexMap::new();
1921 for (name, item) in world.exports.iter() {
1922 match item {
1923 WorldItem::Interface { id, stability } => {
1924 let prev = export_interfaces.insert(*id, (name.clone(), stability));
1925 assert!(prev.is_none());
1926 }
1927 WorldItem::Function(_) => {
1928 let prev = new_exports.insert(name.clone(), item.clone());
1929 assert!(prev.is_none());
1930 }
1931 WorldItem::Type(_) => unreachable!(),
1932 }
1933 }
1934
1935 self.elaborate_world_exports(&export_interfaces, &mut new_imports, &mut new_exports)?;
1936
1937 log::trace!("imports = {:?}", new_imports);
1940 log::trace!("exports = {:?}", new_exports);
1941 let world = &mut self.worlds[world_id];
1942 world.imports = new_imports;
1943 world.exports = new_exports;
1944
1945 Ok(())
1946 }
1947
1948 fn elaborate_world_import(
1949 &self,
1950 imports: &mut IndexMap<WorldKey, WorldItem>,
1951 key: WorldKey,
1952 id: InterfaceId,
1953 stability: &Stability,
1954 ) {
1955 if imports.contains_key(&key) {
1956 return;
1957 }
1958 for dep in self.interface_direct_deps(id) {
1959 self.elaborate_world_import(imports, WorldKey::Interface(dep), dep, stability);
1960 }
1961 let prev = imports.insert(
1962 key,
1963 WorldItem::Interface {
1964 id,
1965 stability: stability.clone(),
1966 },
1967 );
1968 assert!(prev.is_none());
1969 }
1970
1971 fn elaborate_world_exports(
2018 &self,
2019 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2020 imports: &mut IndexMap<WorldKey, WorldItem>,
2021 exports: &mut IndexMap<WorldKey, WorldItem>,
2022 ) -> Result<()> {
2023 let mut required_imports = HashSet::new();
2024 for (id, (key, stability)) in export_interfaces.iter() {
2025 let name = self.name_world_key(&key);
2026 let ok = add_world_export(
2027 self,
2028 imports,
2029 exports,
2030 export_interfaces,
2031 &mut required_imports,
2032 *id,
2033 key,
2034 true,
2035 stability,
2036 );
2037 if !ok {
2038 bail!(
2039 InvalidTransitiveDependency(name),
2057 );
2058 }
2059 }
2060 return Ok(());
2061
2062 fn add_world_export(
2063 resolve: &Resolve,
2064 imports: &mut IndexMap<WorldKey, WorldItem>,
2065 exports: &mut IndexMap<WorldKey, WorldItem>,
2066 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2067 required_imports: &mut HashSet<InterfaceId>,
2068 id: InterfaceId,
2069 key: &WorldKey,
2070 add_export: bool,
2071 stability: &Stability,
2072 ) -> bool {
2073 if exports.contains_key(key) {
2074 if add_export {
2075 return true;
2076 } else {
2077 return false;
2078 }
2079 }
2080 if !add_export && required_imports.contains(&id) {
2083 return true;
2084 }
2085 let ok = resolve.interface_direct_deps(id).all(|dep| {
2086 let key = WorldKey::Interface(dep);
2087 let add_export = add_export && export_interfaces.contains_key(&dep);
2088 add_world_export(
2089 resolve,
2090 imports,
2091 exports,
2092 export_interfaces,
2093 required_imports,
2094 dep,
2095 &key,
2096 add_export,
2097 stability,
2098 )
2099 });
2100 if !ok {
2101 return false;
2102 }
2103 let item = WorldItem::Interface {
2104 id,
2105 stability: stability.clone(),
2106 };
2107 if add_export {
2108 if required_imports.contains(&id) {
2109 return false;
2110 }
2111 exports.insert(key.clone(), item);
2112 } else {
2113 required_imports.insert(id);
2114 imports.insert(key.clone(), item);
2115 }
2116 true
2117 }
2118 }
2119
2120 pub fn merge_world_imports_based_on_semver(&mut self, world_id: WorldId) -> Result<()> {
2132 let world = &self.worlds[world_id];
2133
2134 let mut semver_tracks = HashMap::new();
2143 let mut to_remove = HashSet::new();
2144 for (key, _) in world.imports.iter() {
2145 let iface_id = match key {
2146 WorldKey::Interface(id) => *id,
2147 WorldKey::Name(_) => continue,
2148 };
2149 let (track, version) = match self.semver_track(iface_id) {
2150 Some(track) => track,
2151 None => continue,
2152 };
2153 log::debug!(
2154 "{} is on track {}/{}",
2155 self.id_of(iface_id).unwrap(),
2156 track.0,
2157 track.1,
2158 );
2159 match semver_tracks.entry(track.clone()) {
2160 hash_map::Entry::Vacant(e) => {
2161 e.insert((version, iface_id));
2162 }
2163 hash_map::Entry::Occupied(mut e) => match version.cmp(&e.get().0) {
2164 Ordering::Greater => {
2165 to_remove.insert(e.get().1);
2166 e.insert((version, iface_id));
2167 }
2168 Ordering::Equal => {}
2169 Ordering::Less => {
2170 to_remove.insert(iface_id);
2171 }
2172 },
2173 }
2174 }
2175
2176 let mut replacements = HashMap::new();
2179 for id in to_remove {
2180 let (track, _) = self.semver_track(id).unwrap();
2181 let (_, latest) = semver_tracks[&track];
2182 let prev = replacements.insert(id, latest);
2183 assert!(prev.is_none());
2184 }
2185
2186 for (to_replace, replace_with) in replacements.iter() {
2191 self.merge_world_item(
2192 &WorldItem::Interface {
2193 id: *to_replace,
2194 stability: Default::default(),
2195 },
2196 &WorldItem::Interface {
2197 id: *replace_with,
2198 stability: Default::default(),
2199 },
2200 )
2201 .with_context(|| {
2202 let old_name = self.id_of(*to_replace).unwrap();
2203 let new_name = self.id_of(*replace_with).unwrap();
2204 format!(
2205 "failed to upgrade `{old_name}` to `{new_name}`, was \
2206 this semver-compatible update not semver compatible?"
2207 )
2208 })?;
2209 }
2210
2211 for (to_replace, replace_with) in replacements.iter() {
2212 log::debug!(
2213 "REPLACE {} => {}",
2214 self.id_of(*to_replace).unwrap(),
2215 self.id_of(*replace_with).unwrap(),
2216 );
2217 }
2218
2219 for (key, item) in mem::take(&mut self.worlds[world_id].imports) {
2228 if let WorldItem::Interface { id, .. } = item {
2229 if replacements.contains_key(&id) {
2230 continue;
2231 }
2232 }
2233
2234 self.update_interface_deps_of_world_item(&item, &replacements);
2235
2236 let prev = self.worlds[world_id].imports.insert(key, item);
2237 assert!(prev.is_none());
2238 }
2239 for (key, item) in mem::take(&mut self.worlds[world_id].exports) {
2240 self.update_interface_deps_of_world_item(&item, &replacements);
2241 let prev = self.worlds[world_id].exports.insert(key, item);
2242 assert!(prev.is_none());
2243 }
2244
2245 let ids = self.worlds.iter().map(|(id, _)| id).collect::<Vec<_>>();
2251 for world_id in ids {
2252 self.elaborate_world(world_id).with_context(|| {
2253 let name = &self.worlds[world_id].name;
2254 format!(
2255 "failed to elaborate world `{name}` after deduplicating imports \
2256 based on semver"
2257 )
2258 })?;
2259 }
2260
2261 #[cfg(debug_assertions)]
2262 self.assert_valid();
2263
2264 Ok(())
2265 }
2266
2267 fn update_interface_deps_of_world_item(
2268 &mut self,
2269 item: &WorldItem,
2270 replacements: &HashMap<InterfaceId, InterfaceId>,
2271 ) {
2272 match *item {
2273 WorldItem::Type(t) => self.update_interface_dep_of_type(t, &replacements),
2274 WorldItem::Interface { id, .. } => {
2275 let types = self.interfaces[id]
2276 .types
2277 .values()
2278 .copied()
2279 .collect::<Vec<_>>();
2280 for ty in types {
2281 self.update_interface_dep_of_type(ty, &replacements);
2282 }
2283 }
2284 WorldItem::Function(_) => {}
2285 }
2286 }
2287
2288 fn semver_track(&self, id: InterfaceId) -> Option<((PackageName, String), &Version)> {
2299 let iface = &self.interfaces[id];
2300 let pkg = &self.packages[iface.package?];
2301 let version = pkg.name.version.as_ref()?;
2302 let mut name = pkg.name.clone();
2303 name.version = Some(PackageName::version_compat_track(version));
2304 Some(((name, iface.name.clone()?), version))
2305 }
2306
2307 fn update_interface_dep_of_type(
2311 &mut self,
2312 ty: TypeId,
2313 replacements: &HashMap<InterfaceId, InterfaceId>,
2314 ) {
2315 let to_replace = match self.type_interface_dep(ty) {
2316 Some(id) => id,
2317 None => return,
2318 };
2319 let replace_with = match replacements.get(&to_replace) {
2320 Some(id) => id,
2321 None => return,
2322 };
2323 let dep = match self.types[ty].kind {
2324 TypeDefKind::Type(Type::Id(id)) => id,
2325 _ => return,
2326 };
2327 let name = self.types[dep].name.as_ref().unwrap();
2328 let replacement_id = self.interfaces[*replace_with].types[name];
2331 self.types[ty].kind = TypeDefKind::Type(Type::Id(replacement_id));
2332 }
2333
2334 pub fn wasm_import_name(
2341 &self,
2342 mangling: ManglingAndAbi,
2343 import: WasmImport<'_>,
2344 ) -> (String, String) {
2345 match mangling {
2346 ManglingAndAbi::Standard32 => match import {
2347 WasmImport::Func { interface, func } => {
2348 let module = match interface {
2349 Some(key) => format!("cm32p2|{}", self.name_canonicalized_world_key(key)),
2350 None => format!("cm32p2"),
2351 };
2352 (module, func.name.clone())
2353 }
2354 WasmImport::ResourceIntrinsic {
2355 interface,
2356 resource,
2357 intrinsic,
2358 } => {
2359 let name = self.types[resource].name.as_ref().unwrap();
2360 let (prefix, name) = match intrinsic {
2361 ResourceIntrinsic::ImportedDrop => ("", format!("{name}_drop")),
2362 ResourceIntrinsic::ExportedDrop => ("_ex_", format!("{name}_drop")),
2363 ResourceIntrinsic::ExportedNew => ("_ex_", format!("{name}_new")),
2364 ResourceIntrinsic::ExportedRep => ("_ex_", format!("{name}_rep")),
2365 };
2366 let module = match interface {
2367 Some(key) => {
2368 format!("cm32p2|{prefix}{}", self.name_canonicalized_world_key(key))
2369 }
2370 None => {
2371 assert_eq!(prefix, "");
2372 format!("cm32p2")
2373 }
2374 };
2375 (module, name)
2376 }
2377 },
2378 ManglingAndAbi::Legacy(abi) => match import {
2379 WasmImport::Func { interface, func } => {
2380 let module = match interface {
2381 Some(key) => self.name_world_key(key),
2382 None => format!("$root"),
2383 };
2384 (module, format!("{}{}", abi.import_prefix(), func.name))
2385 }
2386 WasmImport::ResourceIntrinsic {
2387 interface,
2388 resource,
2389 intrinsic,
2390 } => {
2391 let name = self.types[resource].name.as_ref().unwrap();
2392 let (prefix, name) = match intrinsic {
2393 ResourceIntrinsic::ImportedDrop => ("", format!("[resource-drop]{name}")),
2394 ResourceIntrinsic::ExportedDrop => {
2395 ("[export]", format!("[resource-drop]{name}"))
2396 }
2397 ResourceIntrinsic::ExportedNew => {
2398 ("[export]", format!("[resource-new]{name}"))
2399 }
2400 ResourceIntrinsic::ExportedRep => {
2401 ("[export]", format!("[resource-rep]{name}"))
2402 }
2403 };
2404 let module = match interface {
2405 Some(key) => format!("{prefix}{}", self.name_world_key(key)),
2406 None => {
2407 assert_eq!(prefix, "");
2408 format!("$root")
2409 }
2410 };
2411 (module, format!("{}{name}", abi.import_prefix()))
2412 }
2413 },
2414 }
2415 }
2416
2417 pub fn wasm_export_name(&self, mangling: ManglingAndAbi, export: WasmExport<'_>) -> String {
2421 match mangling {
2422 ManglingAndAbi::Standard32 => match export {
2423 WasmExport::Func {
2424 interface,
2425 func,
2426 kind,
2427 } => {
2428 let mut name = String::from("cm32p2|");
2429 if let Some(interface) = interface {
2430 let s = self.name_canonicalized_world_key(interface);
2431 name.push_str(&s);
2432 }
2433 name.push_str("|");
2434 name.push_str(&func.name);
2435 match kind {
2436 WasmExportKind::Normal => {}
2437 WasmExportKind::PostReturn => name.push_str("_post"),
2438 WasmExportKind::Callback => todo!(
2439 "not yet supported: \
2440 async callback functions using standard name mangling"
2441 ),
2442 }
2443 name
2444 }
2445 WasmExport::ResourceDtor {
2446 interface,
2447 resource,
2448 } => {
2449 let name = self.types[resource].name.as_ref().unwrap();
2450 let interface = self.name_canonicalized_world_key(interface);
2451 format!("cm32p2|{interface}|{name}_dtor")
2452 }
2453 WasmExport::Memory => "cm32p2_memory".to_string(),
2454 WasmExport::Initialize => "cm32p2_initialize".to_string(),
2455 WasmExport::Realloc => "cm32p2_realloc".to_string(),
2456 },
2457 ManglingAndAbi::Legacy(abi) => match export {
2458 WasmExport::Func {
2459 interface,
2460 func,
2461 kind,
2462 } => {
2463 let mut name = abi.export_prefix().to_string();
2464 match kind {
2465 WasmExportKind::Normal => {}
2466 WasmExportKind::PostReturn => name.push_str("cabi_post_"),
2467 WasmExportKind::Callback => {
2468 assert!(matches!(abi, LiftLowerAbi::AsyncCallback));
2469 name = format!("[callback]{name}")
2470 }
2471 }
2472 if let Some(interface) = interface {
2473 let s = self.name_world_key(interface);
2474 name.push_str(&s);
2475 name.push_str("#");
2476 }
2477 name.push_str(&func.name);
2478 name
2479 }
2480 WasmExport::ResourceDtor {
2481 interface,
2482 resource,
2483 } => {
2484 let name = self.types[resource].name.as_ref().unwrap();
2485 let interface = self.name_world_key(interface);
2486 format!("{}{interface}#[dtor]{name}", abi.export_prefix())
2487 }
2488 WasmExport::Memory => "memory".to_string(),
2489 WasmExport::Initialize => "_initialize".to_string(),
2490 WasmExport::Realloc => "cabi_realloc".to_string(),
2491 },
2492 }
2493 }
2494}
2495
2496#[derive(Debug)]
2498pub enum WasmImport<'a> {
2499 Func {
2501 interface: Option<&'a WorldKey>,
2506
2507 func: &'a Function,
2509 },
2510
2511 ResourceIntrinsic {
2513 interface: Option<&'a WorldKey>,
2515
2516 resource: TypeId,
2518
2519 intrinsic: ResourceIntrinsic,
2521 },
2522}
2523
2524#[derive(Debug)]
2527pub enum ResourceIntrinsic {
2528 ImportedDrop,
2529 ExportedDrop,
2530 ExportedNew,
2531 ExportedRep,
2532}
2533
2534#[derive(Debug)]
2537pub enum WasmExportKind {
2538 Normal,
2540
2541 PostReturn,
2543
2544 Callback,
2546}
2547
2548#[derive(Debug)]
2551pub enum WasmExport<'a> {
2552 Func {
2554 interface: Option<&'a WorldKey>,
2557
2558 func: &'a Function,
2560
2561 kind: WasmExportKind,
2563 },
2564
2565 ResourceDtor {
2567 interface: &'a WorldKey,
2569 resource: TypeId,
2571 },
2572
2573 Memory,
2575
2576 Initialize,
2578
2579 Realloc,
2581}
2582
2583#[derive(Default)]
2586pub struct Remap {
2587 pub types: Vec<Option<TypeId>>,
2588 pub interfaces: Vec<Option<InterfaceId>>,
2589 pub worlds: Vec<Option<WorldId>>,
2590 pub packages: Vec<PackageId>,
2591
2592 own_handles: HashMap<TypeId, TypeId>,
2602
2603 type_has_borrow: Vec<Option<bool>>,
2604}
2605
2606fn apply_map<T>(map: &[Option<Id<T>>], id: Id<T>, desc: &str, span: Option<Span>) -> Result<Id<T>> {
2607 match map.get(id.index()) {
2608 Some(Some(id)) => Ok(*id),
2609 Some(None) => {
2610 let msg = format!(
2611 "found a reference to a {desc} which is excluded \
2612 due to its feature not being activated"
2613 );
2614 match span {
2615 Some(span) => Err(Error::new(span, msg).into()),
2616 None => bail!("{msg}"),
2617 }
2618 }
2619 None => panic!("request to remap a {desc} that has not yet been registered"),
2620 }
2621}
2622
2623impl Remap {
2624 pub fn map_type(&self, id: TypeId, span: Option<Span>) -> Result<TypeId> {
2625 apply_map(&self.types, id, "type", span)
2626 }
2627
2628 pub fn map_interface(&self, id: InterfaceId, span: Option<Span>) -> Result<InterfaceId> {
2629 apply_map(&self.interfaces, id, "interface", span)
2630 }
2631
2632 pub fn map_world(&self, id: WorldId, span: Option<Span>) -> Result<WorldId> {
2633 apply_map(&self.worlds, id, "world", span)
2634 }
2635
2636 fn append(
2637 &mut self,
2638 resolve: &mut Resolve,
2639 unresolved: UnresolvedPackage,
2640 ) -> Result<PackageId> {
2641 let pkgid = resolve.packages.alloc(Package {
2642 name: unresolved.name.clone(),
2643 docs: unresolved.docs.clone(),
2644 interfaces: Default::default(),
2645 worlds: Default::default(),
2646 });
2647 let prev = resolve.package_names.insert(unresolved.name.clone(), pkgid);
2648 assert!(prev.is_none());
2649
2650 self.process_foreign_deps(resolve, pkgid, &unresolved)?;
2651
2652 let foreign_types = self.types.len();
2653 let foreign_interfaces = self.interfaces.len();
2654 let foreign_worlds = self.worlds.len();
2655
2656 assert_eq!(unresolved.types.len(), unresolved.type_spans.len());
2662 for ((id, mut ty), span) in unresolved
2663 .types
2664 .into_iter()
2665 .zip(&unresolved.type_spans)
2666 .skip(foreign_types)
2667 {
2668 if !resolve.include_type(&ty, pkgid, *span)? {
2669 self.types.push(None);
2670 continue;
2671 }
2672
2673 self.update_typedef(resolve, &mut ty, Some(*span))?;
2674 let new_id = resolve.types.alloc(ty);
2675 assert_eq!(self.types.len(), id.index());
2676
2677 let new_id = match resolve.types[new_id] {
2678 TypeDef {
2683 name: None,
2684 owner: TypeOwner::None,
2685 kind: TypeDefKind::Handle(Handle::Own(id)),
2686 docs: _,
2687 stability: _,
2688 } => *self.own_handles.entry(id).or_insert(new_id),
2689
2690 _ => new_id,
2693 };
2694 self.types.push(Some(new_id));
2695 }
2696
2697 assert_eq!(
2700 unresolved.interfaces.len(),
2701 unresolved.interface_spans.len()
2702 );
2703 for ((id, mut iface), span) in unresolved
2704 .interfaces
2705 .into_iter()
2706 .zip(&unresolved.interface_spans)
2707 .skip(foreign_interfaces)
2708 {
2709 if !resolve
2710 .include_stability(&iface.stability, &pkgid, Some(span.span))
2711 .with_context(|| {
2712 format!(
2713 "failed to process feature gate for interface [{}] in package [{}]",
2714 iface
2715 .name
2716 .as_ref()
2717 .map(String::as_str)
2718 .unwrap_or("<unknown>"),
2719 resolve.packages[pkgid].name,
2720 )
2721 })?
2722 {
2723 self.interfaces.push(None);
2724 continue;
2725 }
2726 assert!(iface.package.is_none());
2727 iface.package = Some(pkgid);
2728 self.update_interface(resolve, &mut iface, Some(span))?;
2729 let new_id = resolve.interfaces.alloc(iface);
2730 assert_eq!(self.interfaces.len(), id.index());
2731 self.interfaces.push(Some(new_id));
2732 }
2733
2734 for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2737 let id = match id {
2738 Some(id) => *id,
2739 None => continue,
2740 };
2741 match &mut resolve.types[id].owner {
2742 TypeOwner::Interface(id) => {
2743 let span = unresolved.type_spans[i];
2744 *id = self.map_interface(*id, Some(span))
2745 .with_context(|| {
2746 "this type is not gated by a feature but its interface is gated by a feature"
2747 })?;
2748 }
2749 TypeOwner::World(_) | TypeOwner::None => {}
2750 }
2751 }
2752
2753 assert_eq!(unresolved.worlds.len(), unresolved.world_spans.len());
2761 for ((id, mut world), span) in unresolved
2762 .worlds
2763 .into_iter()
2764 .zip(&unresolved.world_spans)
2765 .skip(foreign_worlds)
2766 {
2767 if !resolve
2768 .include_stability(&world.stability, &pkgid, Some(span.span))
2769 .with_context(|| {
2770 format!(
2771 "failed to process feature gate for world [{}] in package [{}]",
2772 world.name, resolve.packages[pkgid].name,
2773 )
2774 })?
2775 {
2776 self.worlds.push(None);
2777 continue;
2778 }
2779 self.update_world(&mut world, resolve, &pkgid, &span)?;
2780
2781 let new_id = resolve.worlds.alloc(world);
2782 assert_eq!(self.worlds.len(), id.index());
2783 self.worlds.push(Some(new_id));
2784
2785 resolve.elaborate_world(new_id).with_context(|| {
2786 Error::new(
2787 span.span,
2788 format!(
2789 "failed to elaborate world imports/exports of `{}`",
2790 resolve.worlds[new_id].name
2791 ),
2792 )
2793 })?;
2794 }
2795
2796 for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2798 let id = match id {
2799 Some(id) => *id,
2800 None => continue,
2801 };
2802 match &mut resolve.types[id].owner {
2803 TypeOwner::World(id) => {
2804 let span = unresolved.type_spans[i];
2805 *id = self.map_world(*id, Some(span))
2806 .with_context(|| {
2807 "this type is not gated by a feature but its interface is gated by a feature"
2808 })?;
2809 }
2810 TypeOwner::Interface(_) | TypeOwner::None => {}
2811 }
2812 }
2813
2814 for id in self.interfaces.iter().skip(foreign_interfaces) {
2816 let id = match id {
2817 Some(id) => *id,
2818 None => continue,
2819 };
2820 let iface = &mut resolve.interfaces[id];
2821 iface.package = Some(pkgid);
2822 if let Some(name) = &iface.name {
2823 let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), id);
2824 assert!(prev.is_none());
2825 }
2826 }
2827 for id in self.worlds.iter().skip(foreign_worlds) {
2828 let id = match id {
2829 Some(id) => *id,
2830 None => continue,
2831 };
2832 let world = &mut resolve.worlds[id];
2833 world.package = Some(pkgid);
2834 let prev = resolve.packages[pkgid]
2835 .worlds
2836 .insert(world.name.clone(), id);
2837 assert!(prev.is_none());
2838 }
2839 Ok(pkgid)
2840 }
2841
2842 fn process_foreign_deps(
2843 &mut self,
2844 resolve: &mut Resolve,
2845 pkgid: PackageId,
2846 unresolved: &UnresolvedPackage,
2847 ) -> Result<()> {
2848 let mut world_to_package = HashMap::new();
2851 let mut interface_to_package = HashMap::new();
2852 for (i, (pkg_name, worlds_or_ifaces)) in unresolved.foreign_deps.iter().enumerate() {
2853 for (name, item) in worlds_or_ifaces {
2854 match item {
2855 AstItem::Interface(unresolved_interface_id) => {
2856 let prev = interface_to_package.insert(
2857 *unresolved_interface_id,
2858 (pkg_name, name, unresolved.foreign_dep_spans[i]),
2859 );
2860 assert!(prev.is_none());
2861 }
2862 AstItem::World(unresolved_world_id) => {
2863 let prev = world_to_package.insert(
2864 *unresolved_world_id,
2865 (pkg_name, name, unresolved.foreign_dep_spans[i]),
2866 );
2867 assert!(prev.is_none());
2868 }
2869 }
2870 }
2871 }
2872
2873 self.process_foreign_interfaces(unresolved, &interface_to_package, resolve)?;
2877
2878 self.process_foreign_worlds(unresolved, &world_to_package, resolve)?;
2882
2883 self.process_foreign_types(unresolved, pkgid, resolve)?;
2886
2887 for (id, span) in unresolved.required_resource_types.iter() {
2888 let Ok(mut id) = self.map_type(*id, Some(*span)) else {
2893 continue;
2894 };
2895 loop {
2896 match resolve.types[id].kind {
2897 TypeDefKind::Type(Type::Id(i)) => id = i,
2898 TypeDefKind::Resource => break,
2899 _ => bail!(Error::new(
2900 *span,
2901 format!("type used in a handle must be a resource"),
2902 )),
2903 }
2904 }
2905 }
2906
2907 #[cfg(debug_assertions)]
2908 resolve.assert_valid();
2909
2910 Ok(())
2911 }
2912
2913 fn process_foreign_interfaces(
2914 &mut self,
2915 unresolved: &UnresolvedPackage,
2916 interface_to_package: &HashMap<InterfaceId, (&PackageName, &String, Span)>,
2917 resolve: &mut Resolve,
2918 ) -> Result<(), anyhow::Error> {
2919 for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() {
2920 let (pkg_name, interface, span) = match interface_to_package.get(&unresolved_iface_id) {
2921 Some(items) => *items,
2922 None => break,
2926 };
2927 let pkgid = resolve
2928 .package_names
2929 .get(pkg_name)
2930 .copied()
2931 .ok_or_else(|| {
2932 PackageNotFoundError::new(
2933 span,
2934 pkg_name.clone(),
2935 resolve.package_names.keys().cloned().collect(),
2936 )
2937 })?;
2938
2939 assert!(unresolved_iface.functions.is_empty());
2941
2942 let pkg = &resolve.packages[pkgid];
2943 let span = &unresolved.interface_spans[unresolved_iface_id.index()];
2944 let iface_id = pkg
2945 .interfaces
2946 .get(interface)
2947 .copied()
2948 .ok_or_else(|| Error::new(span.span, "interface not found in package"))?;
2949 assert_eq!(self.interfaces.len(), unresolved_iface_id.index());
2950 self.interfaces.push(Some(iface_id));
2951 }
2952 for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) {
2953 assert!(
2954 interface_to_package.get(&id).is_none(),
2955 "found foreign interface after local interface"
2956 );
2957 }
2958 Ok(())
2959 }
2960
2961 fn process_foreign_worlds(
2962 &mut self,
2963 unresolved: &UnresolvedPackage,
2964 world_to_package: &HashMap<WorldId, (&PackageName, &String, Span)>,
2965 resolve: &mut Resolve,
2966 ) -> Result<(), anyhow::Error> {
2967 for (unresolved_world_id, _) in unresolved.worlds.iter() {
2968 let (pkg_name, world, span) = match world_to_package.get(&unresolved_world_id) {
2969 Some(items) => *items,
2970 None => break,
2973 };
2974
2975 let pkgid = resolve
2976 .package_names
2977 .get(pkg_name)
2978 .copied()
2979 .ok_or_else(|| Error::new(span, "package not found"))?;
2980 let pkg = &resolve.packages[pkgid];
2981 let span = &unresolved.world_spans[unresolved_world_id.index()];
2982 let world_id = pkg
2983 .worlds
2984 .get(world)
2985 .copied()
2986 .ok_or_else(|| Error::new(span.span, "world not found in package"))?;
2987 assert_eq!(self.worlds.len(), unresolved_world_id.index());
2988 self.worlds.push(Some(world_id));
2989 }
2990 for (id, _) in unresolved.worlds.iter().skip(self.worlds.len()) {
2991 assert!(
2992 world_to_package.get(&id).is_none(),
2993 "found foreign world after local world"
2994 );
2995 }
2996 Ok(())
2997 }
2998
2999 fn process_foreign_types(
3000 &mut self,
3001 unresolved: &UnresolvedPackage,
3002 pkgid: PackageId,
3003 resolve: &mut Resolve,
3004 ) -> Result<(), anyhow::Error> {
3005 for ((unresolved_type_id, unresolved_ty), span) in
3006 unresolved.types.iter().zip(&unresolved.type_spans)
3007 {
3008 match unresolved_ty.kind {
3012 TypeDefKind::Unknown => {}
3013 _ => break,
3014 }
3015
3016 if !resolve.include_type(unresolved_ty, pkgid, *span)? {
3017 self.types.push(None);
3018 continue;
3019 }
3020
3021 let unresolved_iface_id = match unresolved_ty.owner {
3022 TypeOwner::Interface(id) => id,
3023 _ => unreachable!(),
3024 };
3025 let iface_id = self.map_interface(unresolved_iface_id, None)?;
3026 let name = unresolved_ty.name.as_ref().unwrap();
3027 let span = unresolved.unknown_type_spans[unresolved_type_id.index()];
3028 let type_id = *resolve.interfaces[iface_id]
3029 .types
3030 .get(name)
3031 .ok_or_else(|| {
3032 Error::new(span, format!("type `{name}` not defined in interface"))
3033 })?;
3034 assert_eq!(self.types.len(), unresolved_type_id.index());
3035 self.types.push(Some(type_id));
3036 }
3037 for (_, ty) in unresolved.types.iter().skip(self.types.len()) {
3038 if let TypeDefKind::Unknown = ty.kind {
3039 panic!("unknown type after defined type");
3040 }
3041 }
3042 Ok(())
3043 }
3044
3045 fn update_typedef(
3046 &mut self,
3047 resolve: &mut Resolve,
3048 ty: &mut TypeDef,
3049 span: Option<Span>,
3050 ) -> Result<()> {
3051 use crate::TypeDefKind::*;
3054 match &mut ty.kind {
3055 Handle(handle) => match handle {
3056 crate::Handle::Own(ty) | crate::Handle::Borrow(ty) => {
3057 self.update_type_id(ty, span)?
3058 }
3059 },
3060 Resource => {}
3061 Record(r) => {
3062 for field in r.fields.iter_mut() {
3063 self.update_ty(resolve, &mut field.ty, span)
3064 .with_context(|| format!("failed to update field `{}`", field.name))?;
3065 }
3066 }
3067 Tuple(t) => {
3068 for ty in t.types.iter_mut() {
3069 self.update_ty(resolve, ty, span)?;
3070 }
3071 }
3072 Variant(v) => {
3073 for case in v.cases.iter_mut() {
3074 if let Some(t) = &mut case.ty {
3075 self.update_ty(resolve, t, span)?;
3076 }
3077 }
3078 }
3079 Option(t) | List(t) | Future(Some(t)) | Stream(Some(t)) => {
3080 self.update_ty(resolve, t, span)?
3081 }
3082 Result(r) => {
3083 if let Some(ty) = &mut r.ok {
3084 self.update_ty(resolve, ty, span)?;
3085 }
3086 if let Some(ty) = &mut r.err {
3087 self.update_ty(resolve, ty, span)?;
3088 }
3089 }
3090 ErrorContext => {}
3091
3092 Type(crate::Type::Id(id)) => self.update_type_id(id, span)?,
3097 Type(_) => {}
3098
3099 Flags(_) | Enum(_) | Future(None) | Stream(None) => {}
3101
3102 Unknown => unreachable!(),
3103 }
3104
3105 Ok(())
3106 }
3107
3108 fn update_ty(
3109 &mut self,
3110 resolve: &mut Resolve,
3111 ty: &mut Type,
3112 span: Option<Span>,
3113 ) -> Result<()> {
3114 let id = match ty {
3115 Type::Id(id) => id,
3116 _ => return Ok(()),
3117 };
3118 self.update_type_id(id, span)?;
3119
3120 let mut cur = *id;
3125 let points_to_resource = loop {
3126 match resolve.types[cur].kind {
3127 TypeDefKind::Type(Type::Id(id)) => cur = id,
3128 TypeDefKind::Resource => break true,
3129 _ => break false,
3130 }
3131 };
3132
3133 if points_to_resource {
3134 *id = *self.own_handles.entry(*id).or_insert_with(|| {
3135 resolve.types.alloc(TypeDef {
3136 name: None,
3137 owner: TypeOwner::None,
3138 kind: TypeDefKind::Handle(Handle::Own(*id)),
3139 docs: Default::default(),
3140 stability: Default::default(),
3141 })
3142 });
3143 }
3144 Ok(())
3145 }
3146
3147 fn update_type_id(&self, id: &mut TypeId, span: Option<Span>) -> Result<()> {
3148 *id = self.map_type(*id, span)?;
3149 Ok(())
3150 }
3151
3152 fn update_interface(
3153 &mut self,
3154 resolve: &mut Resolve,
3155 iface: &mut Interface,
3156 spans: Option<&InterfaceSpan>,
3157 ) -> Result<()> {
3158 iface.types.retain(|_, ty| self.types[ty.index()].is_some());
3159 let iface_pkg_id = iface.package.as_ref().unwrap_or_else(|| {
3160 panic!(
3161 "unexpectedly missing package on interface [{}]",
3162 iface
3163 .name
3164 .as_ref()
3165 .map(String::as_str)
3166 .unwrap_or("<unknown>"),
3167 )
3168 });
3169
3170 for (_name, ty) in iface.types.iter_mut() {
3173 self.update_type_id(ty, spans.map(|s| s.span))?;
3174 }
3175 if let Some(spans) = spans {
3176 assert_eq!(iface.functions.len(), spans.funcs.len());
3177 }
3178 for (i, (func_name, func)) in iface.functions.iter_mut().enumerate() {
3179 let span = spans.map(|s| s.funcs[i]);
3180 if !resolve
3181 .include_stability(&func.stability, iface_pkg_id, span)
3182 .with_context(|| {
3183 format!(
3184 "failed to process feature gate for function [{func_name}] in package [{}]",
3185 resolve.packages[*iface_pkg_id].name,
3186 )
3187 })?
3188 {
3189 continue;
3190 }
3191 self.update_function(resolve, func, span)
3192 .with_context(|| format!("failed to update function `{}`", func.name))?;
3193 }
3194
3195 for (name, func) in mem::take(&mut iface.functions) {
3198 if resolve.include_stability(&func.stability, iface_pkg_id, None)? {
3199 iface.functions.insert(name, func);
3200 }
3201 }
3202
3203 Ok(())
3204 }
3205
3206 fn update_function(
3207 &mut self,
3208 resolve: &mut Resolve,
3209 func: &mut Function,
3210 span: Option<Span>,
3211 ) -> Result<()> {
3212 match &mut func.kind {
3213 FunctionKind::Freestanding => {}
3214 FunctionKind::Method(id) | FunctionKind::Constructor(id) | FunctionKind::Static(id) => {
3215 self.update_type_id(id, span)?;
3216 }
3217 }
3218 for (_, ty) in func.params.iter_mut() {
3219 self.update_ty(resolve, ty, span)?;
3220 }
3221 if let Some(ty) = &mut func.result {
3222 self.update_ty(resolve, ty, span)?;
3223 }
3224
3225 if let Some(ty) = &func.result {
3226 if self.type_has_borrow(resolve, ty) {
3227 match span {
3228 Some(span) => {
3229 bail!(Error::new(
3230 span,
3231 format!(
3232 "function returns a type which contains \
3233 a `borrow<T>` which is not supported"
3234 )
3235 ))
3236 }
3237 None => unreachable!(),
3238 }
3239 }
3240 }
3241
3242 Ok(())
3243 }
3244
3245 fn update_world(
3246 &mut self,
3247 world: &mut World,
3248 resolve: &mut Resolve,
3249 pkg_id: &PackageId,
3250 spans: &WorldSpan,
3251 ) -> Result<()> {
3252 assert_eq!(world.imports.len(), spans.imports.len());
3253 assert_eq!(world.exports.len(), spans.exports.len());
3254
3255 let imports = mem::take(&mut world.imports).into_iter();
3259 let imports = imports.zip(&spans.imports).map(|p| (p, true));
3260 let exports = mem::take(&mut world.exports).into_iter();
3261 let exports = exports.zip(&spans.exports).map(|p| (p, false));
3262 for (((mut name, mut item), span), import) in imports.chain(exports) {
3263 if let WorldItem::Type(id) = &mut item {
3266 *id = self.map_type(*id, Some(*span))?;
3267 }
3268 let stability = item.stability(resolve);
3269 if !resolve
3270 .include_stability(stability, pkg_id, Some(*span))
3271 .with_context(|| format!("failed to process world item in `{}`", world.name))?
3272 {
3273 continue;
3274 }
3275 self.update_world_key(&mut name, Some(*span))?;
3276 match &mut item {
3277 WorldItem::Interface { id, .. } => {
3278 *id = self.map_interface(*id, Some(*span))?;
3279 }
3280 WorldItem::Function(f) => {
3281 self.update_function(resolve, f, Some(*span))?;
3282 }
3283 WorldItem::Type(_) => {
3284 }
3286 }
3287
3288 let dst = if import {
3289 &mut world.imports
3290 } else {
3291 &mut world.exports
3292 };
3293 let prev = dst.insert(name, item);
3294 assert!(prev.is_none());
3295 }
3296
3297 assert_eq!(world.includes.len(), spans.includes.len());
3300 let includes = mem::take(&mut world.includes);
3301 let include_names = mem::take(&mut world.include_names);
3302 for (((stability, include_world), span), names) in includes
3303 .into_iter()
3304 .zip(&spans.includes)
3305 .zip(&include_names)
3306 {
3307 if !resolve
3308 .include_stability(&stability, pkg_id, Some(*span))
3309 .with_context(|| {
3310 format!(
3311 "failed to process feature gate for included world [{}] in package [{}]",
3312 resolve.worlds[include_world].name.as_str(),
3313 resolve.packages[*pkg_id].name
3314 )
3315 })?
3316 {
3317 continue;
3318 }
3319 self.resolve_include(world, include_world, names, *span, resolve)?;
3320 }
3321
3322 Ok(())
3323 }
3324
3325 fn update_world_key(&self, key: &mut WorldKey, span: Option<Span>) -> Result<()> {
3326 match key {
3327 WorldKey::Name(_) => {}
3328 WorldKey::Interface(id) => {
3329 *id = self.map_interface(*id, span)?;
3330 }
3331 }
3332 Ok(())
3333 }
3334
3335 fn resolve_include(
3336 &self,
3337 world: &mut World,
3338 include_world: WorldId,
3339 names: &[IncludeName],
3340 span: Span,
3341 resolve: &Resolve,
3342 ) -> Result<()> {
3343 let include_world_id = self.map_world(include_world, Some(span))?;
3344 let include_world = &resolve.worlds[include_world_id];
3345 let mut names_ = names.to_owned();
3346
3347 for import in include_world.imports.iter() {
3349 self.remove_matching_name(import, &mut names_);
3350 }
3351 for export in include_world.exports.iter() {
3352 self.remove_matching_name(export, &mut names_);
3353 }
3354 if !names_.is_empty() {
3355 bail!(Error::new(
3356 span,
3357 format!("no import or export kebab-name `{}`. Note that an ID does not support renaming", names_[0].name),
3358 ));
3359 }
3360
3361 for import in include_world.imports.iter() {
3363 self.resolve_include_item(names, &mut world.imports, import, span, "import")?;
3364 }
3365
3366 for export in include_world.exports.iter() {
3367 self.resolve_include_item(names, &mut world.exports, export, span, "export")?;
3368 }
3369 Ok(())
3370 }
3371
3372 fn resolve_include_item(
3373 &self,
3374 names: &[IncludeName],
3375 items: &mut IndexMap<WorldKey, WorldItem>,
3376 item: (&WorldKey, &WorldItem),
3377 span: Span,
3378 item_type: &str,
3379 ) -> Result<()> {
3380 match item.0 {
3381 WorldKey::Name(n) => {
3382 let n = if let Some(found) = names
3383 .into_iter()
3384 .find(|include_name| include_name.name == n.clone())
3385 {
3386 found.as_.clone()
3387 } else {
3388 n.clone()
3389 };
3390
3391 let prev = items.insert(WorldKey::Name(n.clone()), item.1.clone());
3392 if prev.is_some() {
3393 bail!(Error::new(
3394 span,
3395 format!("{item_type} of `{n}` shadows previously {item_type}ed items"),
3396 ))
3397 }
3398 }
3399 key @ WorldKey::Interface(_) => {
3400 let prev = items.entry(key.clone()).or_insert(item.1.clone());
3401 match (&item.1, prev) {
3402 (
3403 WorldItem::Interface {
3404 id: aid,
3405 stability: astability,
3406 },
3407 WorldItem::Interface {
3408 id: bid,
3409 stability: bstability,
3410 },
3411 ) => {
3412 assert_eq!(*aid, *bid);
3413 update_stability(astability, bstability)?;
3414 }
3415 (WorldItem::Interface { .. }, _) => unreachable!(),
3416 (WorldItem::Function(_), _) => unreachable!(),
3417 (WorldItem::Type(_), _) => unreachable!(),
3418 }
3419 }
3420 };
3421 Ok(())
3422 }
3423
3424 fn remove_matching_name(&self, item: (&WorldKey, &WorldItem), names: &mut Vec<IncludeName>) {
3425 match item.0 {
3426 WorldKey::Name(n) => {
3427 names.retain(|name| name.name != n.clone());
3428 }
3429 _ => {}
3430 }
3431 }
3432
3433 fn type_has_borrow(&mut self, resolve: &Resolve, ty: &Type) -> bool {
3434 let id = match ty {
3435 Type::Id(id) => *id,
3436 _ => return false,
3437 };
3438
3439 if let Some(Some(has_borrow)) = self.type_has_borrow.get(id.index()) {
3440 return *has_borrow;
3441 }
3442
3443 let result = self.typedef_has_borrow(resolve, &resolve.types[id]);
3444 if self.type_has_borrow.len() <= id.index() {
3445 self.type_has_borrow.resize(id.index() + 1, None);
3446 }
3447 self.type_has_borrow[id.index()] = Some(result);
3448 result
3449 }
3450
3451 fn typedef_has_borrow(&mut self, resolve: &Resolve, ty: &TypeDef) -> bool {
3452 match &ty.kind {
3453 TypeDefKind::Type(t) => self.type_has_borrow(resolve, t),
3454 TypeDefKind::Variant(v) => v
3455 .cases
3456 .iter()
3457 .filter_map(|case| case.ty.as_ref())
3458 .any(|ty| self.type_has_borrow(resolve, ty)),
3459 TypeDefKind::Handle(Handle::Borrow(_)) => true,
3460 TypeDefKind::Handle(Handle::Own(_)) => false,
3461 TypeDefKind::Resource => false,
3462 TypeDefKind::Record(r) => r
3463 .fields
3464 .iter()
3465 .any(|case| self.type_has_borrow(resolve, &case.ty)),
3466 TypeDefKind::Flags(_) => false,
3467 TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.type_has_borrow(resolve, t)),
3468 TypeDefKind::Enum(_) => false,
3469 TypeDefKind::List(ty)
3470 | TypeDefKind::Future(Some(ty))
3471 | TypeDefKind::Stream(Some(ty))
3472 | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty),
3473 TypeDefKind::Result(r) => [&r.ok, &r.err]
3474 .iter()
3475 .filter_map(|t| t.as_ref())
3476 .any(|t| self.type_has_borrow(resolve, t)),
3477 TypeDefKind::Future(None) | TypeDefKind::Stream(None) | TypeDefKind::ErrorContext => {
3478 false
3479 }
3480 TypeDefKind::Unknown => unreachable!(),
3481 }
3482 }
3483}
3484
3485struct MergeMap<'a> {
3486 package_map: HashMap<PackageId, PackageId>,
3489
3490 interface_map: HashMap<InterfaceId, InterfaceId>,
3493
3494 type_map: HashMap<TypeId, TypeId>,
3497
3498 world_map: HashMap<WorldId, WorldId>,
3501
3502 interfaces_to_add: Vec<(String, PackageId, InterfaceId)>,
3510 worlds_to_add: Vec<(String, PackageId, WorldId)>,
3511
3512 from: &'a Resolve,
3514
3515 into: &'a Resolve,
3517}
3518
3519impl<'a> MergeMap<'a> {
3520 fn new(from: &'a Resolve, into: &'a Resolve) -> MergeMap<'a> {
3521 MergeMap {
3522 package_map: Default::default(),
3523 interface_map: Default::default(),
3524 type_map: Default::default(),
3525 world_map: Default::default(),
3526 interfaces_to_add: Default::default(),
3527 worlds_to_add: Default::default(),
3528 from,
3529 into,
3530 }
3531 }
3532
3533 fn build(&mut self) -> Result<()> {
3534 for from_id in self.from.topological_packages() {
3535 let from = &self.from.packages[from_id];
3536 let into_id = match self.into.package_names.get(&from.name) {
3537 Some(id) => *id,
3538
3539 None => {
3542 log::trace!("adding unique package {}", from.name);
3543 continue;
3544 }
3545 };
3546 log::trace!("merging duplicate package {}", from.name);
3547
3548 self.build_package(from_id, into_id).with_context(|| {
3549 format!("failed to merge package `{}` into existing copy", from.name)
3550 })?;
3551 }
3552
3553 Ok(())
3554 }
3555
3556 fn build_package(&mut self, from_id: PackageId, into_id: PackageId) -> Result<()> {
3557 let prev = self.package_map.insert(from_id, into_id);
3558 assert!(prev.is_none());
3559
3560 let from = &self.from.packages[from_id];
3561 let into = &self.into.packages[into_id];
3562
3563 for (name, from_interface_id) in from.interfaces.iter() {
3567 let into_interface_id = match into.interfaces.get(name) {
3568 Some(id) => *id,
3569 None => {
3570 log::trace!("adding unique interface {}", name);
3571 self.interfaces_to_add
3572 .push((name.clone(), into_id, *from_interface_id));
3573 continue;
3574 }
3575 };
3576
3577 log::trace!("merging duplicate interfaces {}", name);
3578 self.build_interface(*from_interface_id, into_interface_id)
3579 .with_context(|| format!("failed to merge interface `{name}`"))?;
3580 }
3581
3582 for (name, from_world_id) in from.worlds.iter() {
3583 let into_world_id = match into.worlds.get(name) {
3584 Some(id) => *id,
3585 None => {
3586 log::trace!("adding unique world {}", name);
3587 self.worlds_to_add
3588 .push((name.clone(), into_id, *from_world_id));
3589 continue;
3590 }
3591 };
3592
3593 log::trace!("merging duplicate worlds {}", name);
3594 self.build_world(*from_world_id, into_world_id)
3595 .with_context(|| format!("failed to merge world `{name}`"))?;
3596 }
3597
3598 Ok(())
3599 }
3600
3601 fn build_interface(&mut self, from_id: InterfaceId, into_id: InterfaceId) -> Result<()> {
3602 let prev = self.interface_map.insert(from_id, into_id);
3603 assert!(prev.is_none());
3604
3605 let from_interface = &self.from.interfaces[from_id];
3606 let into_interface = &self.into.interfaces[into_id];
3607
3608 for (name, from_type_id) in from_interface.types.iter() {
3622 let into_type_id = *into_interface
3623 .types
3624 .get(name)
3625 .ok_or_else(|| anyhow!("expected type `{name}` to be present"))?;
3626 let prev = self.type_map.insert(*from_type_id, into_type_id);
3627 assert!(prev.is_none());
3628
3629 self.build_type_id(*from_type_id, into_type_id)
3630 .with_context(|| format!("mismatch in type `{name}`"))?;
3631 }
3632
3633 for (name, from_func) in from_interface.functions.iter() {
3634 let into_func = match into_interface.functions.get(name) {
3635 Some(func) => func,
3636 None => bail!("expected function `{name}` to be present"),
3637 };
3638 self.build_function(from_func, into_func)
3639 .with_context(|| format!("mismatch in function `{name}`"))?;
3640 }
3641
3642 Ok(())
3643 }
3644
3645 fn build_type_id(&mut self, from_id: TypeId, into_id: TypeId) -> Result<()> {
3646 let _ = from_id;
3650 let _ = into_id;
3651 Ok(())
3652 }
3653
3654 fn build_type(&mut self, from_ty: &Type, into_ty: &Type) -> Result<()> {
3655 match (from_ty, into_ty) {
3656 (Type::Id(from), Type::Id(into)) => {
3657 self.build_type_id(*from, *into)?;
3658 }
3659 (from, into) if from != into => bail!("different kinds of types"),
3660 _ => {}
3661 }
3662 Ok(())
3663 }
3664
3665 fn build_function(&mut self, from_func: &Function, into_func: &Function) -> Result<()> {
3666 if from_func.name != into_func.name {
3667 bail!(
3668 "different function names `{}` and `{}`",
3669 from_func.name,
3670 into_func.name
3671 );
3672 }
3673 match (&from_func.kind, &into_func.kind) {
3674 (FunctionKind::Freestanding, FunctionKind::Freestanding) => {}
3675
3676 (FunctionKind::Method(from), FunctionKind::Method(into))
3677 | (FunctionKind::Constructor(from), FunctionKind::Constructor(into))
3678 | (FunctionKind::Static(from), FunctionKind::Static(into)) => self
3679 .build_type_id(*from, *into)
3680 .context("different function kind types")?,
3681
3682 (FunctionKind::Method(_), _)
3683 | (FunctionKind::Constructor(_), _)
3684 | (FunctionKind::Static(_), _)
3685 | (FunctionKind::Freestanding, _) => {
3686 bail!("different function kind types")
3687 }
3688 }
3689
3690 if from_func.params.len() != into_func.params.len() {
3691 bail!("different number of function parameters");
3692 }
3693 for ((from_name, from_ty), (into_name, into_ty)) in
3694 from_func.params.iter().zip(&into_func.params)
3695 {
3696 if from_name != into_name {
3697 bail!("different function parameter names: {from_name} != {into_name}");
3698 }
3699 self.build_type(from_ty, into_ty)
3700 .with_context(|| format!("different function parameter types for `{from_name}`"))?;
3701 }
3702 match (&from_func.result, &into_func.result) {
3703 (Some(from_ty), Some(into_ty)) => {
3704 self.build_type(from_ty, into_ty)
3705 .context("different function result types")?;
3706 }
3707 (None, None) => {}
3708 (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
3709 }
3710 Ok(())
3711 }
3712
3713 fn build_world(&mut self, from_id: WorldId, into_id: WorldId) -> Result<()> {
3714 let prev = self.world_map.insert(from_id, into_id);
3715 assert!(prev.is_none());
3716
3717 let from_world = &self.from.worlds[from_id];
3718 let into_world = &self.into.worlds[into_id];
3719
3720 if from_world.imports.len() != into_world.imports.len() {
3729 bail!("world contains different number of imports than expected");
3730 }
3731 if from_world.exports.len() != into_world.exports.len() {
3732 bail!("world contains different number of exports than expected");
3733 }
3734
3735 for (from_name, from) in from_world.imports.iter() {
3736 let into_name = self.map_name(from_name);
3737 let name_str = self.from.name_world_key(from_name);
3738 let into = into_world
3739 .imports
3740 .get(&into_name)
3741 .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?;
3742 self.match_world_item(from, into)
3743 .with_context(|| format!("import `{name_str}` didn't match target world"))?;
3744 }
3745
3746 for (from_name, from) in from_world.exports.iter() {
3747 let into_name = self.map_name(from_name);
3748 let name_str = self.from.name_world_key(from_name);
3749 let into = into_world
3750 .exports
3751 .get(&into_name)
3752 .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?;
3753 self.match_world_item(from, into)
3754 .with_context(|| format!("export `{name_str}` didn't match target world"))?;
3755 }
3756
3757 Ok(())
3758 }
3759
3760 fn map_name(&self, from_name: &WorldKey) -> WorldKey {
3761 match from_name {
3762 WorldKey::Name(s) => WorldKey::Name(s.clone()),
3763 WorldKey::Interface(id) => {
3764 WorldKey::Interface(self.interface_map.get(id).copied().unwrap_or(*id))
3765 }
3766 }
3767 }
3768
3769 fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> Result<()> {
3770 match (from, into) {
3771 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
3772 match (
3773 &self.from.interfaces[*from].name,
3774 &self.into.interfaces[*into].name,
3775 ) {
3776 (None, None) => self.build_interface(*from, *into)?,
3780
3781 _ => {
3786 if self.interface_map.get(&from) != Some(&into) {
3787 bail!("interfaces are not the same");
3788 }
3789 }
3790 }
3791 }
3792 (WorldItem::Function(from), WorldItem::Function(into)) => {
3793 let _ = (from, into);
3794 }
3797 (WorldItem::Type(from), WorldItem::Type(into)) => {
3798 let prev = self.type_map.insert(*from, *into);
3801 assert!(prev.is_none());
3802 }
3803
3804 (WorldItem::Interface { .. }, _)
3805 | (WorldItem::Function(_), _)
3806 | (WorldItem::Type(_), _) => {
3807 bail!("world items do not have the same type")
3808 }
3809 }
3810 Ok(())
3811 }
3812}
3813
3814fn update_stability(from: &Stability, into: &mut Stability) -> Result<()> {
3820 if from == into || from.is_unknown() {
3823 return Ok(());
3824 }
3825 if into.is_unknown() {
3828 *into = from.clone();
3829 return Ok(());
3830 }
3831
3832 bail!("mismatch in stability attributes")
3835}
3836
3837#[derive(Debug, Clone)]
3850pub struct InvalidTransitiveDependency(String);
3851
3852impl fmt::Display for InvalidTransitiveDependency {
3853 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3854 write!(
3855 f,
3856 "interface `{}` transitively depends on an interface in \
3857 incompatible ways",
3858 self.0
3859 )
3860 }
3861}
3862
3863impl std::error::Error for InvalidTransitiveDependency {}
3864
3865#[cfg(test)]
3866mod tests {
3867 use crate::Resolve;
3868 use anyhow::Result;
3869
3870 #[test]
3871 fn select_world() -> Result<()> {
3872 let mut resolve = Resolve::default();
3873 resolve.push_str(
3874 "test.wit",
3875 r#"
3876 package foo:bar@0.1.0;
3877
3878 world foo {}
3879 "#,
3880 )?;
3881 resolve.push_str(
3882 "test.wit",
3883 r#"
3884 package foo:baz@0.1.0;
3885
3886 world foo {}
3887 "#,
3888 )?;
3889 resolve.push_str(
3890 "test.wit",
3891 r#"
3892 package foo:baz@0.2.0;
3893
3894 world foo {}
3895 "#,
3896 )?;
3897
3898 let dummy = resolve.push_str(
3899 "test.wit",
3900 r#"
3901 package foo:dummy;
3902
3903 world foo {}
3904 "#,
3905 )?;
3906
3907 assert!(resolve.select_world(dummy, None).is_ok());
3908 assert!(resolve.select_world(dummy, Some("xx")).is_err());
3909 assert!(resolve.select_world(dummy, Some("")).is_err());
3910 assert!(resolve.select_world(dummy, Some("foo:bar/foo")).is_ok());
3911 assert!(resolve
3912 .select_world(dummy, Some("foo:bar/foo@0.1.0"))
3913 .is_ok());
3914 assert!(resolve.select_world(dummy, Some("foo:baz/foo")).is_err());
3915 assert!(resolve
3916 .select_world(dummy, Some("foo:baz/foo@0.1.0"))
3917 .is_ok());
3918 assert!(resolve
3919 .select_world(dummy, Some("foo:baz/foo@0.2.0"))
3920 .is_ok());
3921 Ok(())
3922 }
3923}