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 | Type::ErrorContext => 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(_) => false,
576 TypeDefKind::Type(t) => self.all_bits_valid(t),
577
578 TypeDefKind::Handle(h) => match h {
579 crate::Handle::Own(_) => true,
580 crate::Handle::Borrow(_) => true,
581 },
582
583 TypeDefKind::Resource => false,
584 TypeDefKind::Record(r) => r.fields.iter().all(|f| self.all_bits_valid(&f.ty)),
585 TypeDefKind::Tuple(t) => t.types.iter().all(|t| self.all_bits_valid(t)),
586
587 TypeDefKind::Flags(_) => false,
591
592 TypeDefKind::Unknown => unreachable!(),
593 },
594 }
595 }
596
597 pub fn merge(&mut self, resolve: Resolve) -> Result<Remap> {
609 log::trace!(
610 "merging {} packages into {} packages",
611 resolve.packages.len(),
612 self.packages.len()
613 );
614
615 let mut map = MergeMap::new(&resolve, &self);
616 map.build()?;
617 let MergeMap {
618 package_map,
619 interface_map,
620 type_map,
621 world_map,
622 interfaces_to_add,
623 worlds_to_add,
624 ..
625 } = map;
626
627 let mut remap = Remap::default();
646 let Resolve {
647 types,
648 worlds,
649 interfaces,
650 packages,
651 package_names,
652 features: _,
653 ..
654 } = resolve;
655
656 let mut moved_types = Vec::new();
657 for (id, mut ty) in types {
658 let new_id = match type_map.get(&id).copied() {
659 Some(id) => {
660 update_stability(&ty.stability, &mut self.types[id].stability)?;
661 id
662 }
663 None => {
664 log::debug!("moving type {:?}", ty.name);
665 moved_types.push(id);
666 remap.update_typedef(self, &mut ty, None)?;
667 self.types.alloc(ty)
668 }
669 };
670 assert_eq!(remap.types.len(), id.index());
671 remap.types.push(Some(new_id));
672 }
673
674 let mut moved_interfaces = Vec::new();
675 for (id, mut iface) in interfaces {
676 let new_id = match interface_map.get(&id).copied() {
677 Some(id) => {
678 update_stability(&iface.stability, &mut self.interfaces[id].stability)?;
679 id
680 }
681 None => {
682 log::debug!("moving interface {:?}", iface.name);
683 moved_interfaces.push(id);
684 remap.update_interface(self, &mut iface, None)?;
685 self.interfaces.alloc(iface)
686 }
687 };
688 assert_eq!(remap.interfaces.len(), id.index());
689 remap.interfaces.push(Some(new_id));
690 }
691
692 let mut moved_worlds = Vec::new();
693 for (id, mut world) in worlds {
694 let new_id = match world_map.get(&id).copied() {
695 Some(world_id) => {
696 update_stability(&world.stability, &mut self.worlds[world_id].stability)?;
697 for from_import in world.imports.iter() {
698 Resolve::update_world_imports_stability(
699 from_import,
700 &mut self.worlds[world_id].imports,
701 &interface_map,
702 )?;
703 }
704 for from_export in world.exports.iter() {
705 Resolve::update_world_imports_stability(
706 from_export,
707 &mut self.worlds[world_id].exports,
708 &interface_map,
709 )?;
710 }
711 world_id
712 }
713 None => {
714 log::debug!("moving world {}", world.name);
715 moved_worlds.push(id);
716 let mut update = |map: &mut IndexMap<WorldKey, WorldItem>| -> Result<_> {
717 for (mut name, mut item) in mem::take(map) {
718 remap.update_world_key(&mut name, None)?;
719 match &mut item {
720 WorldItem::Function(f) => remap.update_function(self, f, None)?,
721 WorldItem::Interface { id, .. } => {
722 *id = remap.map_interface(*id, None)?
723 }
724 WorldItem::Type(i) => *i = remap.map_type(*i, None)?,
725 }
726 map.insert(name, item);
727 }
728 Ok(())
729 };
730 update(&mut world.imports)?;
731 update(&mut world.exports)?;
732 self.worlds.alloc(world)
733 }
734 };
735 assert_eq!(remap.worlds.len(), id.index());
736 remap.worlds.push(Some(new_id));
737 }
738
739 for (id, mut pkg) in packages {
740 let new_id = match package_map.get(&id).copied() {
741 Some(id) => id,
742 None => {
743 for (_, id) in pkg.interfaces.iter_mut() {
744 *id = remap.map_interface(*id, None)?;
745 }
746 for (_, id) in pkg.worlds.iter_mut() {
747 *id = remap.map_world(*id, None)?;
748 }
749 self.packages.alloc(pkg)
750 }
751 };
752 assert_eq!(remap.packages.len(), id.index());
753 remap.packages.push(new_id);
754 }
755
756 for (name, id) in package_names {
757 let id = remap.packages[id.index()];
758 if let Some(prev) = self.package_names.insert(name, id) {
759 assert_eq!(prev, id);
760 }
761 }
762
763 for id in moved_worlds {
771 let id = remap.map_world(id, None)?;
772 if let Some(pkg) = self.worlds[id].package.as_mut() {
773 *pkg = remap.packages[pkg.index()];
774 }
775 }
776 for id in moved_interfaces {
777 let id = remap.map_interface(id, None)?;
778 if let Some(pkg) = self.interfaces[id].package.as_mut() {
779 *pkg = remap.packages[pkg.index()];
780 }
781 }
782 for id in moved_types {
783 let id = remap.map_type(id, None)?;
784 match &mut self.types[id].owner {
785 TypeOwner::Interface(id) => *id = remap.map_interface(*id, None)?,
786 TypeOwner::World(id) => *id = remap.map_world(*id, None)?,
787 TypeOwner::None => {}
788 }
789 }
790
791 for (name, pkg, iface) in interfaces_to_add {
796 let prev = self.packages[pkg]
797 .interfaces
798 .insert(name, remap.map_interface(iface, None)?);
799 assert!(prev.is_none());
800 }
801 for (name, pkg, world) in worlds_to_add {
802 let prev = self.packages[pkg]
803 .worlds
804 .insert(name, remap.map_world(world, None)?);
805 assert!(prev.is_none());
806 }
807
808 log::trace!("now have {} packages", self.packages.len());
809
810 #[cfg(debug_assertions)]
811 self.assert_valid();
812 Ok(remap)
813 }
814
815 fn update_world_imports_stability(
816 from_item: (&WorldKey, &WorldItem),
817 into_items: &mut IndexMap<WorldKey, WorldItem>,
818 interface_map: &HashMap<Id<Interface>, Id<Interface>>,
819 ) -> Result<()> {
820 match from_item.0 {
821 WorldKey::Name(_) => {
822 Ok(())
824 }
825 key @ WorldKey::Interface(_) => {
826 let new_key = MergeMap::map_name(key, interface_map);
827 if let Some(into) = into_items.get_mut(&new_key) {
828 match (from_item.1, into) {
829 (
830 WorldItem::Interface {
831 id: aid,
832 stability: astability,
833 },
834 WorldItem::Interface {
835 id: bid,
836 stability: bstability,
837 },
838 ) => {
839 let aid = interface_map.get(aid).copied().unwrap_or(*aid);
840 assert_eq!(aid, *bid);
841 update_stability(astability, bstability)?;
842 Ok(())
843 }
844 _ => unreachable!(),
845 }
846 } else {
847 unreachable!()
850 }
851 }
852 }
853 }
854
855 pub fn merge_worlds(&mut self, from: WorldId, into: WorldId) -> Result<()> {
866 let mut new_imports = Vec::new();
867 let mut new_exports = Vec::new();
868
869 let from_world = &self.worlds[from];
870 let into_world = &self.worlds[into];
871
872 log::trace!("merging {} into {}", from_world.name, into_world.name);
873
874 for (name, from_import) in from_world.imports.iter() {
882 let name_str = self.name_world_key(name);
883 match into_world.imports.get(name) {
884 Some(into_import) => {
885 log::trace!("info/from shared import on `{name_str}`");
886 self.merge_world_item(from_import, into_import)
887 .with_context(|| format!("failed to merge world import {name_str}"))?;
888 }
889 None => {
890 log::trace!("new import: `{name_str}`");
891 new_imports.push((name.clone(), from_import.clone()));
892 }
893 }
894 }
895
896 let mut must_be_imported = HashMap::new();
903 for (key, export) in into_world.exports.iter() {
904 for dep in self.world_item_direct_deps(export) {
905 if into_world.exports.contains_key(&WorldKey::Interface(dep)) {
906 continue;
907 }
908 self.foreach_interface_dep(dep, &mut |id| {
909 must_be_imported.insert(id, key.clone());
910 });
911 }
912 }
913
914 for (name, from_export) in from_world.exports.iter() {
917 let name_str = self.name_world_key(name);
918 match into_world.exports.get(name) {
919 Some(into_export) => {
920 log::trace!("info/from shared export on `{name_str}`");
921 self.merge_world_item(from_export, into_export)
922 .with_context(|| format!("failed to merge world export {name_str}"))?;
923 }
924 None => {
925 log::trace!("new export `{name_str}`");
926 self.ensure_can_add_world_export(
929 into_world,
930 name,
931 from_export,
932 &must_be_imported,
933 )
934 .with_context(|| {
935 format!("failed to add export `{}`", self.name_world_key(name))
936 })?;
937 new_exports.push((name.clone(), from_export.clone()));
938 }
939 }
940 }
941
942 let mut cloner = clone::Cloner::new(self, TypeOwner::World(from), TypeOwner::World(into));
956 cloner.register_world_type_overlap(from, into);
957 for (name, item) in new_imports.iter_mut().chain(&mut new_exports) {
958 cloner.world_item(name, item);
959 }
960
961 let into_world = &mut self.worlds[into];
963 for (name, import) in new_imports {
964 let prev = into_world.imports.insert(name, import);
965 assert!(prev.is_none());
966 }
967 for (name, export) in new_exports {
968 let prev = into_world.exports.insert(name, export);
969 assert!(prev.is_none());
970 }
971
972 #[cfg(debug_assertions)]
973 self.assert_valid();
974 Ok(())
975 }
976
977 fn merge_world_item(&self, from: &WorldItem, into: &WorldItem) -> Result<()> {
978 let mut map = MergeMap::new(self, self);
979 match (from, into) {
980 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
981 if from == into {
986 return Ok(());
987 }
988
989 map.build_interface(*from, *into)
999 .context("failed to merge interfaces")?;
1000 }
1001
1002 (WorldItem::Function(from), WorldItem::Function(into)) => {
1005 map.build_function(from, into)
1006 .context("failed to merge functions")?;
1007 }
1008 (WorldItem::Type(from), WorldItem::Type(into)) => {
1009 map.build_type_id(*from, *into)
1010 .context("failed to merge types")?;
1011 }
1012
1013 (WorldItem::Interface { .. }, _)
1015 | (WorldItem::Function { .. }, _)
1016 | (WorldItem::Type { .. }, _) => {
1017 bail!("different kinds of items");
1018 }
1019 }
1020 assert!(map.interfaces_to_add.is_empty());
1021 assert!(map.worlds_to_add.is_empty());
1022 Ok(())
1023 }
1024
1025 fn ensure_can_add_world_export(
1037 &self,
1038 into: &World,
1039 name: &WorldKey,
1040 item: &WorldItem,
1041 must_be_imported: &HashMap<InterfaceId, WorldKey>,
1042 ) -> Result<()> {
1043 assert!(!into.exports.contains_key(name));
1044 let name = self.name_world_key(name);
1045
1046 for dep in self.world_item_direct_deps(item) {
1050 if into.exports.contains_key(&WorldKey::Interface(dep)) {
1051 continue;
1052 }
1053 self.ensure_not_exported(into, dep)
1054 .with_context(|| format!("failed validating export of `{name}`"))?;
1055 }
1056
1057 if let WorldItem::Interface { id, .. } = item {
1061 if let Some(export) = must_be_imported.get(&id) {
1062 let export_name = self.name_world_key(export);
1063 bail!(
1064 "export `{export_name}` depends on `{name}` \
1065 previously as an import which will change meaning \
1066 if `{name}` is added as an export"
1067 );
1068 }
1069 }
1070
1071 Ok(())
1072 }
1073
1074 fn ensure_not_exported(&self, world: &World, id: InterfaceId) -> Result<()> {
1075 let key = WorldKey::Interface(id);
1076 let name = self.name_world_key(&key);
1077 if world.exports.contains_key(&key) {
1078 bail!(
1079 "world exports `{name}` but it's also transitively used by an \
1080 import \
1081 which means that this is not valid"
1082 )
1083 }
1084 for dep in self.interface_direct_deps(id) {
1085 self.ensure_not_exported(world, dep)
1086 .with_context(|| format!("failed validating transitive import dep `{name}`"))?;
1087 }
1088 Ok(())
1089 }
1090
1091 fn world_item_direct_deps(&self, item: &WorldItem) -> impl Iterator<Item = InterfaceId> + '_ {
1097 let mut interface = None;
1098 let mut ty = None;
1099 match item {
1100 WorldItem::Function(_) => {}
1101 WorldItem::Type(id) => ty = Some(*id),
1102 WorldItem::Interface { id, .. } => interface = Some(*id),
1103 }
1104
1105 interface
1106 .into_iter()
1107 .flat_map(move |id| self.interface_direct_deps(id))
1108 .chain(ty.and_then(|t| self.type_interface_dep(t)))
1109 }
1110
1111 fn foreach_interface_dep(&self, id: InterfaceId, f: &mut dyn FnMut(InterfaceId)) {
1115 f(id);
1116 for dep in self.interface_direct_deps(id) {
1117 self.foreach_interface_dep(dep, f);
1118 }
1119 }
1120
1121 pub fn id_of(&self, interface: InterfaceId) -> Option<String> {
1125 let interface = &self.interfaces[interface];
1126 Some(self.id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1127 }
1128
1129 pub fn canonicalized_id_of(&self, interface: InterfaceId) -> Option<String> {
1134 let interface = &self.interfaces[interface];
1135 Some(self.canonicalized_id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1136 }
1137
1138 pub fn importize(&mut self, world_id: WorldId, out_world_name: Option<String>) -> Result<()> {
1154 let world = &mut self.worlds[world_id];
1159 let pkg = &mut self.packages[world.package.unwrap()];
1160 pkg.worlds.shift_remove(&world.name);
1161 if let Some(name) = out_world_name {
1162 world.name = name.clone();
1163 pkg.worlds.insert(name, world_id);
1164 } else {
1165 world.name.push_str("-importized");
1166 pkg.worlds.insert(world.name.clone(), world_id);
1167 }
1168
1169 world.imports.retain(|_, item| match item {
1172 WorldItem::Type(_) => true,
1173 _ => false,
1174 });
1175
1176 for (name, export) in mem::take(&mut world.exports) {
1177 match (name.clone(), world.imports.insert(name, export)) {
1178 (_, None) => {}
1180
1181 (WorldKey::Name(name), Some(_)) => {
1183 bail!("world export `{name}` conflicts with import of same name");
1184 }
1185
1186 (WorldKey::Interface(_), _) => unreachable!(),
1189 }
1190 }
1191
1192 self.elaborate_world(world_id)?;
1195
1196 #[cfg(debug_assertions)]
1197 self.assert_valid();
1198 Ok(())
1199 }
1200
1201 pub fn id_of_name(&self, pkg: PackageId, name: &str) -> String {
1203 let package = &self.packages[pkg];
1204 let mut base = String::new();
1205 base.push_str(&package.name.namespace);
1206 base.push_str(":");
1207 base.push_str(&package.name.name);
1208 base.push_str("/");
1209 base.push_str(name);
1210 if let Some(version) = &package.name.version {
1211 base.push_str(&format!("@{version}"));
1212 }
1213 base
1214 }
1215
1216 pub fn canonicalized_id_of_name(&self, pkg: PackageId, name: &str) -> String {
1222 let package = &self.packages[pkg];
1223 let mut base = String::new();
1224 base.push_str(&package.name.namespace);
1225 base.push_str(":");
1226 base.push_str(&package.name.name);
1227 base.push_str("/");
1228 base.push_str(name);
1229 if let Some(version) = &package.name.version {
1230 base.push_str("@");
1231 let string = PackageName::version_compat_track_string(version);
1232 base.push_str(&string);
1233 }
1234 base
1235 }
1236
1237 pub fn select_world(&self, package: PackageId, world: Option<&str>) -> Result<WorldId> {
1348 let world_path = match world {
1349 Some(world) => Some(
1350 parse_use_path(world)
1351 .with_context(|| format!("failed to parse world specifier `{world}`"))?,
1352 ),
1353 None => None,
1354 };
1355
1356 let (pkg, world_name) = match world_path {
1357 Some(ParsedUsePath::Name(name)) => (package, name),
1358 Some(ParsedUsePath::Package(pkg, interface)) => {
1359 let pkg = match self.package_names.get(&pkg) {
1360 Some(pkg) => *pkg,
1361 None => {
1362 let mut candidates = self.package_names.iter().filter(|(name, _)| {
1363 pkg.version.is_none()
1364 && pkg.name == name.name
1365 && pkg.namespace == name.namespace
1366 && name.version.is_some()
1367 });
1368 let candidate = candidates.next();
1369 if let Some((c2, _)) = candidates.next() {
1370 let (c1, _) = candidate.unwrap();
1371 bail!(
1372 "package name `{pkg}` is available at both \
1373 versions {} and {} but which is not specified",
1374 c1.version.as_ref().unwrap(),
1375 c2.version.as_ref().unwrap(),
1376 );
1377 }
1378 match candidate {
1379 Some((_, id)) => *id,
1380 None => bail!("unknown package `{pkg}`"),
1381 }
1382 }
1383 };
1384 (pkg, interface.to_string())
1385 }
1386 None => {
1387 let pkg = &self.packages[package];
1388 let worlds = pkg
1389 .worlds
1390 .values()
1391 .map(|world| (package, *world))
1392 .collect::<Vec<_>>();
1393
1394 match &worlds[..] {
1395 [] => bail!("The main package `{}` contains no worlds", pkg.name),
1396 [(_, world)] => return Ok(*world),
1397 _ => bail!(
1398 "multiple worlds found; one must be explicitly chosen:{}",
1399 worlds
1400 .iter()
1401 .map(|(pkg, world)| format!(
1402 "\n {}/{}",
1403 self.packages[*pkg].name, self.worlds[*world].name
1404 ))
1405 .collect::<String>()
1406 ),
1407 }
1408 }
1409 };
1410 let pkg = &self.packages[pkg];
1411 pkg.worlds
1412 .get(&world_name)
1413 .copied()
1414 .ok_or_else(|| anyhow!("no world named `{world_name}` in package"))
1415 }
1416
1417 pub fn name_world_key(&self, key: &WorldKey) -> String {
1419 match key {
1420 WorldKey::Name(s) => s.to_string(),
1421 WorldKey::Interface(i) => self.id_of(*i).expect("unexpected anonymous interface"),
1422 }
1423 }
1424
1425 pub fn name_canonicalized_world_key(&self, key: &WorldKey) -> String {
1428 match key {
1429 WorldKey::Name(s) => s.to_string(),
1430 WorldKey::Interface(i) => self
1431 .canonicalized_id_of(*i)
1432 .expect("unexpected anonymous interface"),
1433 }
1434 }
1435
1436 pub fn type_interface_dep(&self, id: TypeId) -> Option<InterfaceId> {
1442 let ty = &self.types[id];
1443 let dep = match ty.kind {
1444 TypeDefKind::Type(Type::Id(id)) => id,
1445 _ => return None,
1446 };
1447 let other = &self.types[dep];
1448 if ty.owner == other.owner {
1449 None
1450 } else {
1451 match other.owner {
1452 TypeOwner::Interface(id) => Some(id),
1453 _ => unreachable!(),
1454 }
1455 }
1456 }
1457
1458 pub fn interface_direct_deps(&self, id: InterfaceId) -> impl Iterator<Item = InterfaceId> + '_ {
1468 self.interfaces[id]
1469 .types
1470 .iter()
1471 .filter_map(move |(_name, ty)| self.type_interface_dep(*ty))
1472 }
1473
1474 pub fn package_direct_deps(&self, id: PackageId) -> impl Iterator<Item = PackageId> + '_ {
1484 let pkg = &self.packages[id];
1485
1486 pkg.interfaces
1487 .iter()
1488 .flat_map(move |(_name, id)| self.interface_direct_deps(*id))
1489 .chain(pkg.worlds.iter().flat_map(move |(_name, id)| {
1490 let world = &self.worlds[*id];
1491 world
1492 .imports
1493 .iter()
1494 .chain(world.exports.iter())
1495 .filter_map(move |(_name, item)| match item {
1496 WorldItem::Interface { id, .. } => Some(*id),
1497 WorldItem::Function(_) => None,
1498 WorldItem::Type(t) => self.type_interface_dep(*t),
1499 })
1500 }))
1501 .filter_map(move |iface_id| {
1502 let pkg = self.interfaces[iface_id].package?;
1503 if pkg == id {
1504 None
1505 } else {
1506 Some(pkg)
1507 }
1508 })
1509 }
1510
1511 pub fn topological_packages(&self) -> Vec<PackageId> {
1517 let mut pushed = vec![false; self.packages.len()];
1518 let mut order = Vec::new();
1519 for (id, _) in self.packages.iter() {
1520 self.build_topological_package_ordering(id, &mut pushed, &mut order);
1521 }
1522 order
1523 }
1524
1525 fn build_topological_package_ordering(
1526 &self,
1527 id: PackageId,
1528 pushed: &mut Vec<bool>,
1529 order: &mut Vec<PackageId>,
1530 ) {
1531 if pushed[id.index()] {
1532 return;
1533 }
1534 for dep in self.package_direct_deps(id) {
1535 self.build_topological_package_ordering(dep, pushed, order);
1536 }
1537 order.push(id);
1538 pushed[id.index()] = true;
1539 }
1540
1541 #[doc(hidden)]
1542 pub fn assert_valid(&self) {
1543 let mut package_interfaces = Vec::new();
1544 let mut package_worlds = Vec::new();
1545 for (id, pkg) in self.packages.iter() {
1546 let mut interfaces = HashSet::new();
1547 for (name, iface) in pkg.interfaces.iter() {
1548 assert!(interfaces.insert(*iface));
1549 let iface = &self.interfaces[*iface];
1550 assert_eq!(name, iface.name.as_ref().unwrap());
1551 assert_eq!(iface.package.unwrap(), id);
1552 }
1553 package_interfaces.push(pkg.interfaces.values().copied().collect::<HashSet<_>>());
1554 let mut worlds = HashSet::new();
1555 for (name, world) in pkg.worlds.iter() {
1556 assert!(worlds.insert(*world));
1557 assert_eq!(
1558 pkg.worlds.get_key_value(name),
1559 Some((name, world)),
1560 "`MutableKeys` impl may have been used to change a key's hash or equality"
1561 );
1562 let world = &self.worlds[*world];
1563 assert_eq!(*name, world.name);
1564 assert_eq!(world.package.unwrap(), id);
1565 }
1566 package_worlds.push(pkg.worlds.values().copied().collect::<HashSet<_>>());
1567 }
1568
1569 let mut interface_types = Vec::new();
1570 for (id, iface) in self.interfaces.iter() {
1571 assert!(self.packages.get(iface.package.unwrap()).is_some());
1572 if iface.name.is_some() {
1573 assert!(package_interfaces[iface.package.unwrap().index()].contains(&id));
1574 }
1575
1576 for (name, ty) in iface.types.iter() {
1577 let ty = &self.types[*ty];
1578 assert_eq!(ty.name.as_ref(), Some(name));
1579 assert_eq!(ty.owner, TypeOwner::Interface(id));
1580 }
1581 interface_types.push(iface.types.values().copied().collect::<HashSet<_>>());
1582 for (name, f) in iface.functions.iter() {
1583 assert_eq!(*name, f.name);
1584 }
1585 }
1586
1587 let mut world_types = Vec::new();
1588 for (id, world) in self.worlds.iter() {
1589 log::debug!("validating world {}", &world.name);
1590 if let Some(package) = world.package {
1591 assert!(self.packages.get(package).is_some());
1592 assert!(package_worlds[package.index()].contains(&id));
1593 }
1594 assert!(world.includes.is_empty());
1595
1596 let mut types = HashSet::new();
1597 for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1598 log::debug!("validating world item: {}", self.name_world_key(name));
1599 match item {
1600 WorldItem::Interface { id, .. } => {
1601 if matches!(name, WorldKey::Name(_)) {
1604 assert_eq!(self.interfaces[*id].package, world.package);
1605 }
1606 }
1607 WorldItem::Function(f) => {
1608 assert!(!matches!(name, WorldKey::Interface(_)));
1609 assert_eq!(f.name, name.clone().unwrap_name());
1610 }
1611 WorldItem::Type(ty) => {
1612 assert!(!matches!(name, WorldKey::Interface(_)));
1613 assert!(types.insert(*ty));
1614 let ty = &self.types[*ty];
1615 assert_eq!(ty.name, Some(name.clone().unwrap_name()));
1616 assert_eq!(ty.owner, TypeOwner::World(id));
1617 }
1618 }
1619 }
1620 self.assert_world_elaborated(world);
1621 world_types.push(types);
1622 }
1623
1624 for (ty_id, ty) in self.types.iter() {
1625 match ty.owner {
1626 TypeOwner::Interface(id) => {
1627 assert!(self.interfaces.get(id).is_some());
1628 assert!(interface_types[id.index()].contains(&ty_id));
1629 }
1630 TypeOwner::World(id) => {
1631 assert!(self.worlds.get(id).is_some());
1632 assert!(world_types[id.index()].contains(&ty_id));
1633 }
1634 TypeOwner::None => {}
1635 }
1636 }
1637
1638 self.assert_topologically_sorted();
1639 }
1640
1641 fn assert_topologically_sorted(&self) {
1642 let mut positions = IndexMap::new();
1643 for id in self.topological_packages() {
1644 let pkg = &self.packages[id];
1645 log::debug!("pkg {}", pkg.name);
1646 let prev = positions.insert(Some(id), IndexSet::new());
1647 assert!(prev.is_none());
1648 }
1649 positions.insert(None, IndexSet::new());
1650
1651 for (id, iface) in self.interfaces.iter() {
1652 log::debug!("iface {:?}", iface.name);
1653 let ok = positions.get_mut(&iface.package).unwrap().insert(id);
1654 assert!(ok);
1655 }
1656
1657 for (_, world) in self.worlds.iter() {
1658 log::debug!("world {:?}", world.name);
1659
1660 let my_package = world.package;
1661 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1662
1663 for (_, item) in world.imports.iter().chain(&world.exports) {
1664 let id = match item {
1665 WorldItem::Interface { id, .. } => *id,
1666 _ => continue,
1667 };
1668 let other_package = self.interfaces[id].package;
1669 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1670
1671 assert!(other_package_pos <= my_package_pos);
1672 }
1673 }
1674
1675 for (_id, ty) in self.types.iter() {
1676 log::debug!("type {:?} {:?}", ty.name, ty.owner);
1677 let other_id = match ty.kind {
1678 TypeDefKind::Type(Type::Id(ty)) => ty,
1679 _ => continue,
1680 };
1681 let other = &self.types[other_id];
1682 if ty.kind == other.kind {
1683 continue;
1684 }
1685 let my_interface = match ty.owner {
1686 TypeOwner::Interface(id) => id,
1687 _ => continue,
1688 };
1689 let other_interface = match other.owner {
1690 TypeOwner::Interface(id) => id,
1691 _ => continue,
1692 };
1693
1694 let my_package = self.interfaces[my_interface].package;
1695 let other_package = self.interfaces[other_interface].package;
1696 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1697 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1698
1699 if my_package_pos == other_package_pos {
1700 let interfaces = &positions[&my_package];
1701 let my_interface_pos = interfaces.get_index_of(&my_interface).unwrap();
1702 let other_interface_pos = interfaces.get_index_of(&other_interface).unwrap();
1703 assert!(other_interface_pos <= my_interface_pos);
1704 } else {
1705 assert!(other_package_pos < my_package_pos);
1706 }
1707 }
1708 }
1709
1710 fn assert_world_elaborated(&self, world: &World) {
1711 for (key, item) in world.imports.iter() {
1712 log::debug!(
1713 "asserting elaborated world import {}",
1714 self.name_world_key(key)
1715 );
1716 match item {
1717 WorldItem::Type(t) => self.assert_world_imports_type_deps(world, key, *t),
1718
1719 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1721
1722 WorldItem::Interface { id, .. } => {
1724 for dep in self.interface_direct_deps(*id) {
1725 assert!(
1726 world.imports.contains_key(&WorldKey::Interface(dep)),
1727 "world import of {} is missing transitive dep of {}",
1728 self.name_world_key(key),
1729 self.id_of(dep).unwrap(),
1730 );
1731 }
1732 }
1733 }
1734 }
1735 for (key, item) in world.exports.iter() {
1736 log::debug!(
1737 "asserting elaborated world export {}",
1738 self.name_world_key(key)
1739 );
1740 match item {
1741 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1743
1744 WorldItem::Interface { id, .. } => {
1748 for dep in self.interface_direct_deps(*id) {
1749 let dep_key = WorldKey::Interface(dep);
1750 if world.exports.contains_key(&dep_key) {
1751 continue;
1752 }
1753 self.foreach_interface_dep(dep, &mut |dep| {
1754 let dep_key = WorldKey::Interface(dep);
1755 assert!(
1756 world.imports.contains_key(&dep_key),
1757 "world should import {} (required by {})",
1758 self.name_world_key(&dep_key),
1759 self.name_world_key(key),
1760 );
1761 assert!(
1762 !world.exports.contains_key(&dep_key),
1763 "world should not export {} (required by {})",
1764 self.name_world_key(&dep_key),
1765 self.name_world_key(key),
1766 );
1767 });
1768 }
1769 }
1770
1771 WorldItem::Type(_) => unreachable!(),
1773 }
1774 }
1775 }
1776
1777 fn assert_world_imports_type_deps(&self, world: &World, key: &WorldKey, ty: TypeId) {
1778 let ty = &self.types[ty];
1781 if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
1782 if let TypeOwner::Interface(id) = self.types[other].owner {
1783 let key = WorldKey::Interface(id);
1784 assert!(world.imports.contains_key(&key));
1785 return;
1786 }
1787 }
1788
1789 let mut visitor = MyVisit(self, Vec::new());
1793 visitor.visit_type_def(self, ty);
1794 for ty in visitor.1 {
1795 let ty = &self.types[ty];
1796 let Some(name) = ty.name.clone() else {
1797 continue;
1798 };
1799 let dep_key = WorldKey::Name(name);
1800 assert!(
1801 world.imports.contains_key(&dep_key),
1802 "world import `{}` should also force an import of `{}`",
1803 self.name_world_key(key),
1804 self.name_world_key(&dep_key),
1805 );
1806 }
1807
1808 struct MyVisit<'a>(&'a Resolve, Vec<TypeId>);
1809
1810 impl TypeIdVisitor for MyVisit<'_> {
1811 fn before_visit_type_id(&mut self, id: TypeId) -> bool {
1812 self.1.push(id);
1813 self.0.types[id].name.is_none()
1815 }
1816 }
1817 }
1818
1819 fn assert_world_function_imports_types(&self, world: &World, key: &WorldKey, func: &Function) {
1823 for ty in func
1824 .parameter_and_result_types()
1825 .chain(func.kind.resource().map(Type::Id))
1826 {
1827 let Type::Id(id) = ty else {
1828 continue;
1829 };
1830 self.assert_world_imports_type_deps(world, key, id);
1831 }
1832 }
1833
1834 fn include_stability(
1850 &self,
1851 stability: &Stability,
1852 pkg_id: &PackageId,
1853 span: Option<Span>,
1854 ) -> Result<bool> {
1855 let err = |msg: String| match span {
1856 Some(span) => Error::new(span, msg).into(),
1857 None => anyhow::Error::msg(msg),
1858 };
1859 Ok(match stability {
1860 Stability::Unknown => true,
1861 Stability::Stable { since, .. } => {
1864 let Some(p) = self.packages.get(*pkg_id) else {
1865 return Ok(true);
1873 };
1874
1875 let package_version = p.name.version.as_ref().ok_or_else(|| {
1878 err(format!(
1879 "package [{}] contains a feature gate with a version \
1880 specifier, so it must have a version",
1881 p.name
1882 ))
1883 })?;
1884
1885 if since > package_version {
1889 return Err(err(format!(
1890 "feature gate cannot reference unreleased version \
1891 {since} of package [{}] (current version {package_version})",
1892 p.name
1893 )));
1894 }
1895
1896 true
1897 }
1898 Stability::Unstable { feature, .. } => {
1899 self.features.contains(feature) || self.all_features
1900 }
1901 })
1902 }
1903
1904 fn include_type(&self, ty: &TypeDef, pkgid: PackageId, span: Span) -> Result<bool> {
1907 self.include_stability(&ty.stability, &pkgid, Some(span))
1908 .with_context(|| {
1909 format!(
1910 "failed to process feature gate for type [{}] in package [{}]",
1911 ty.name.as_ref().map(String::as_str).unwrap_or("<unknown>"),
1912 self.packages[pkgid].name,
1913 )
1914 })
1915 }
1916
1917 fn elaborate_world(&mut self, world_id: WorldId) -> Result<()> {
1929 let mut new_imports = IndexMap::new();
1933 let world = &self.worlds[world_id];
1934 for (name, item) in world.imports.iter() {
1935 match item {
1936 WorldItem::Interface { id, stability } => {
1939 self.elaborate_world_import(&mut new_imports, name.clone(), *id, &stability);
1940 }
1941
1942 WorldItem::Function(_) => {
1945 let prev = new_imports.insert(name.clone(), item.clone());
1946 assert!(prev.is_none());
1947 }
1948
1949 WorldItem::Type(id) => {
1953 if let Some(dep) = self.type_interface_dep(*id) {
1954 self.elaborate_world_import(
1955 &mut new_imports,
1956 WorldKey::Interface(dep),
1957 dep,
1958 &self.types[*id].stability,
1959 );
1960 }
1961 let prev = new_imports.insert(name.clone(), item.clone());
1962 assert!(prev.is_none());
1963 }
1964 }
1965 }
1966
1967 let mut new_exports = IndexMap::new();
1973 let mut export_interfaces = IndexMap::new();
1974 for (name, item) in world.exports.iter() {
1975 match item {
1976 WorldItem::Interface { id, stability } => {
1977 let prev = export_interfaces.insert(*id, (name.clone(), stability));
1978 assert!(prev.is_none());
1979 }
1980 WorldItem::Function(_) => {
1981 let prev = new_exports.insert(name.clone(), item.clone());
1982 assert!(prev.is_none());
1983 }
1984 WorldItem::Type(_) => unreachable!(),
1985 }
1986 }
1987
1988 self.elaborate_world_exports(&export_interfaces, &mut new_imports, &mut new_exports)?;
1989
1990 log::trace!("imports = {:?}", new_imports);
1993 log::trace!("exports = {:?}", new_exports);
1994 let world = &mut self.worlds[world_id];
1995 world.imports = new_imports;
1996 world.exports = new_exports;
1997
1998 Ok(())
1999 }
2000
2001 fn elaborate_world_import(
2002 &self,
2003 imports: &mut IndexMap<WorldKey, WorldItem>,
2004 key: WorldKey,
2005 id: InterfaceId,
2006 stability: &Stability,
2007 ) {
2008 if imports.contains_key(&key) {
2009 return;
2010 }
2011 for dep in self.interface_direct_deps(id) {
2012 self.elaborate_world_import(imports, WorldKey::Interface(dep), dep, stability);
2013 }
2014 let prev = imports.insert(
2015 key,
2016 WorldItem::Interface {
2017 id,
2018 stability: stability.clone(),
2019 },
2020 );
2021 assert!(prev.is_none());
2022 }
2023
2024 fn elaborate_world_exports(
2071 &self,
2072 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2073 imports: &mut IndexMap<WorldKey, WorldItem>,
2074 exports: &mut IndexMap<WorldKey, WorldItem>,
2075 ) -> Result<()> {
2076 let mut required_imports = HashSet::new();
2077 for (id, (key, stability)) in export_interfaces.iter() {
2078 let name = self.name_world_key(&key);
2079 let ok = add_world_export(
2080 self,
2081 imports,
2082 exports,
2083 export_interfaces,
2084 &mut required_imports,
2085 *id,
2086 key,
2087 true,
2088 stability,
2089 );
2090 if !ok {
2091 bail!(
2092 InvalidTransitiveDependency(name),
2110 );
2111 }
2112 }
2113 return Ok(());
2114
2115 fn add_world_export(
2116 resolve: &Resolve,
2117 imports: &mut IndexMap<WorldKey, WorldItem>,
2118 exports: &mut IndexMap<WorldKey, WorldItem>,
2119 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2120 required_imports: &mut HashSet<InterfaceId>,
2121 id: InterfaceId,
2122 key: &WorldKey,
2123 add_export: bool,
2124 stability: &Stability,
2125 ) -> bool {
2126 if exports.contains_key(key) {
2127 if add_export {
2128 return true;
2129 } else {
2130 return false;
2131 }
2132 }
2133 if !add_export && required_imports.contains(&id) {
2136 return true;
2137 }
2138 let ok = resolve.interface_direct_deps(id).all(|dep| {
2139 let key = WorldKey::Interface(dep);
2140 let add_export = add_export && export_interfaces.contains_key(&dep);
2141 add_world_export(
2142 resolve,
2143 imports,
2144 exports,
2145 export_interfaces,
2146 required_imports,
2147 dep,
2148 &key,
2149 add_export,
2150 stability,
2151 )
2152 });
2153 if !ok {
2154 return false;
2155 }
2156 let item = WorldItem::Interface {
2157 id,
2158 stability: stability.clone(),
2159 };
2160 if add_export {
2161 if required_imports.contains(&id) {
2162 return false;
2163 }
2164 exports.insert(key.clone(), item);
2165 } else {
2166 required_imports.insert(id);
2167 imports.insert(key.clone(), item);
2168 }
2169 true
2170 }
2171 }
2172
2173 pub fn merge_world_imports_based_on_semver(&mut self, world_id: WorldId) -> Result<()> {
2185 let world = &self.worlds[world_id];
2186
2187 let mut semver_tracks = HashMap::new();
2196 let mut to_remove = HashSet::new();
2197 for (key, _) in world.imports.iter() {
2198 let iface_id = match key {
2199 WorldKey::Interface(id) => *id,
2200 WorldKey::Name(_) => continue,
2201 };
2202 let (track, version) = match self.semver_track(iface_id) {
2203 Some(track) => track,
2204 None => continue,
2205 };
2206 log::debug!(
2207 "{} is on track {}/{}",
2208 self.id_of(iface_id).unwrap(),
2209 track.0,
2210 track.1,
2211 );
2212 match semver_tracks.entry(track.clone()) {
2213 hash_map::Entry::Vacant(e) => {
2214 e.insert((version, iface_id));
2215 }
2216 hash_map::Entry::Occupied(mut e) => match version.cmp(&e.get().0) {
2217 Ordering::Greater => {
2218 to_remove.insert(e.get().1);
2219 e.insert((version, iface_id));
2220 }
2221 Ordering::Equal => {}
2222 Ordering::Less => {
2223 to_remove.insert(iface_id);
2224 }
2225 },
2226 }
2227 }
2228
2229 let mut replacements = HashMap::new();
2232 for id in to_remove {
2233 let (track, _) = self.semver_track(id).unwrap();
2234 let (_, latest) = semver_tracks[&track];
2235 let prev = replacements.insert(id, latest);
2236 assert!(prev.is_none());
2237 }
2238
2239 for (to_replace, replace_with) in replacements.iter() {
2244 self.merge_world_item(
2245 &WorldItem::Interface {
2246 id: *to_replace,
2247 stability: Default::default(),
2248 },
2249 &WorldItem::Interface {
2250 id: *replace_with,
2251 stability: Default::default(),
2252 },
2253 )
2254 .with_context(|| {
2255 let old_name = self.id_of(*to_replace).unwrap();
2256 let new_name = self.id_of(*replace_with).unwrap();
2257 format!(
2258 "failed to upgrade `{old_name}` to `{new_name}`, was \
2259 this semver-compatible update not semver compatible?"
2260 )
2261 })?;
2262 }
2263
2264 for (to_replace, replace_with) in replacements.iter() {
2265 log::debug!(
2266 "REPLACE {} => {}",
2267 self.id_of(*to_replace).unwrap(),
2268 self.id_of(*replace_with).unwrap(),
2269 );
2270 }
2271
2272 for (key, item) in mem::take(&mut self.worlds[world_id].imports) {
2281 if let WorldItem::Interface { id, .. } = item {
2282 if replacements.contains_key(&id) {
2283 continue;
2284 }
2285 }
2286
2287 self.update_interface_deps_of_world_item(&item, &replacements);
2288
2289 let prev = self.worlds[world_id].imports.insert(key, item);
2290 assert!(prev.is_none());
2291 }
2292 for (key, item) in mem::take(&mut self.worlds[world_id].exports) {
2293 self.update_interface_deps_of_world_item(&item, &replacements);
2294 let prev = self.worlds[world_id].exports.insert(key, item);
2295 assert!(prev.is_none());
2296 }
2297
2298 let ids = self.worlds.iter().map(|(id, _)| id).collect::<Vec<_>>();
2304 for world_id in ids {
2305 self.elaborate_world(world_id).with_context(|| {
2306 let name = &self.worlds[world_id].name;
2307 format!(
2308 "failed to elaborate world `{name}` after deduplicating imports \
2309 based on semver"
2310 )
2311 })?;
2312 }
2313
2314 #[cfg(debug_assertions)]
2315 self.assert_valid();
2316
2317 Ok(())
2318 }
2319
2320 fn update_interface_deps_of_world_item(
2321 &mut self,
2322 item: &WorldItem,
2323 replacements: &HashMap<InterfaceId, InterfaceId>,
2324 ) {
2325 match *item {
2326 WorldItem::Type(t) => self.update_interface_dep_of_type(t, &replacements),
2327 WorldItem::Interface { id, .. } => {
2328 let types = self.interfaces[id]
2329 .types
2330 .values()
2331 .copied()
2332 .collect::<Vec<_>>();
2333 for ty in types {
2334 self.update_interface_dep_of_type(ty, &replacements);
2335 }
2336 }
2337 WorldItem::Function(_) => {}
2338 }
2339 }
2340
2341 fn semver_track(&self, id: InterfaceId) -> Option<((PackageName, String), &Version)> {
2352 let iface = &self.interfaces[id];
2353 let pkg = &self.packages[iface.package?];
2354 let version = pkg.name.version.as_ref()?;
2355 let mut name = pkg.name.clone();
2356 name.version = Some(PackageName::version_compat_track(version));
2357 Some(((name, iface.name.clone()?), version))
2358 }
2359
2360 fn update_interface_dep_of_type(
2364 &mut self,
2365 ty: TypeId,
2366 replacements: &HashMap<InterfaceId, InterfaceId>,
2367 ) {
2368 let to_replace = match self.type_interface_dep(ty) {
2369 Some(id) => id,
2370 None => return,
2371 };
2372 let replace_with = match replacements.get(&to_replace) {
2373 Some(id) => id,
2374 None => return,
2375 };
2376 let dep = match self.types[ty].kind {
2377 TypeDefKind::Type(Type::Id(id)) => id,
2378 _ => return,
2379 };
2380 let name = self.types[dep].name.as_ref().unwrap();
2381 let replacement_id = self.interfaces[*replace_with].types[name];
2384 self.types[ty].kind = TypeDefKind::Type(Type::Id(replacement_id));
2385 }
2386
2387 pub fn wasm_import_name(
2394 &self,
2395 mangling: ManglingAndAbi,
2396 import: WasmImport<'_>,
2397 ) -> (String, String) {
2398 match mangling {
2399 ManglingAndAbi::Standard32 => match import {
2400 WasmImport::Func { interface, func } => {
2401 let module = match interface {
2402 Some(key) => format!("cm32p2|{}", self.name_canonicalized_world_key(key)),
2403 None => format!("cm32p2"),
2404 };
2405 (module, func.name.clone())
2406 }
2407 WasmImport::ResourceIntrinsic {
2408 interface,
2409 resource,
2410 intrinsic,
2411 } => {
2412 let name = self.types[resource].name.as_ref().unwrap();
2413 let (prefix, name) = match intrinsic {
2414 ResourceIntrinsic::ImportedDrop => ("", format!("{name}_drop")),
2415 ResourceIntrinsic::ExportedDrop => ("_ex_", format!("{name}_drop")),
2416 ResourceIntrinsic::ExportedNew => ("_ex_", format!("{name}_new")),
2417 ResourceIntrinsic::ExportedRep => ("_ex_", format!("{name}_rep")),
2418 };
2419 let module = match interface {
2420 Some(key) => {
2421 format!("cm32p2|{prefix}{}", self.name_canonicalized_world_key(key))
2422 }
2423 None => {
2424 assert_eq!(prefix, "");
2425 format!("cm32p2")
2426 }
2427 };
2428 (module, name)
2429 }
2430 },
2431 ManglingAndAbi::Legacy(abi) => match import {
2432 WasmImport::Func { interface, func } => {
2433 let module = match interface {
2434 Some(key) => self.name_world_key(key),
2435 None => format!("$root"),
2436 };
2437 (module, format!("{}{}", abi.import_prefix(), func.name))
2438 }
2439 WasmImport::ResourceIntrinsic {
2440 interface,
2441 resource,
2442 intrinsic,
2443 } => {
2444 let name = self.types[resource].name.as_ref().unwrap();
2445 let (prefix, name) = match intrinsic {
2446 ResourceIntrinsic::ImportedDrop => ("", format!("[resource-drop]{name}")),
2447 ResourceIntrinsic::ExportedDrop => {
2448 ("[export]", format!("[resource-drop]{name}"))
2449 }
2450 ResourceIntrinsic::ExportedNew => {
2451 ("[export]", format!("[resource-new]{name}"))
2452 }
2453 ResourceIntrinsic::ExportedRep => {
2454 ("[export]", format!("[resource-rep]{name}"))
2455 }
2456 };
2457 let module = match interface {
2458 Some(key) => format!("{prefix}{}", self.name_world_key(key)),
2459 None => {
2460 assert_eq!(prefix, "");
2461 format!("$root")
2462 }
2463 };
2464 (module, format!("{}{name}", abi.import_prefix()))
2465 }
2466 },
2467 }
2468 }
2469
2470 pub fn wasm_export_name(&self, mangling: ManglingAndAbi, export: WasmExport<'_>) -> String {
2474 match mangling {
2475 ManglingAndAbi::Standard32 => match export {
2476 WasmExport::Func {
2477 interface,
2478 func,
2479 kind,
2480 } => {
2481 let mut name = String::from("cm32p2|");
2482 if let Some(interface) = interface {
2483 let s = self.name_canonicalized_world_key(interface);
2484 name.push_str(&s);
2485 }
2486 name.push_str("|");
2487 name.push_str(&func.name);
2488 match kind {
2489 WasmExportKind::Normal => {}
2490 WasmExportKind::PostReturn => name.push_str("_post"),
2491 WasmExportKind::Callback => todo!(
2492 "not yet supported: \
2493 async callback functions using standard name mangling"
2494 ),
2495 }
2496 name
2497 }
2498 WasmExport::ResourceDtor {
2499 interface,
2500 resource,
2501 } => {
2502 let name = self.types[resource].name.as_ref().unwrap();
2503 let interface = self.name_canonicalized_world_key(interface);
2504 format!("cm32p2|{interface}|{name}_dtor")
2505 }
2506 WasmExport::Memory => "cm32p2_memory".to_string(),
2507 WasmExport::Initialize => "cm32p2_initialize".to_string(),
2508 WasmExport::Realloc => "cm32p2_realloc".to_string(),
2509 },
2510 ManglingAndAbi::Legacy(abi) => match export {
2511 WasmExport::Func {
2512 interface,
2513 func,
2514 kind,
2515 } => {
2516 let mut name = abi.export_prefix().to_string();
2517 match kind {
2518 WasmExportKind::Normal => {}
2519 WasmExportKind::PostReturn => name.push_str("cabi_post_"),
2520 WasmExportKind::Callback => {
2521 assert!(matches!(abi, LiftLowerAbi::AsyncCallback));
2522 name = format!("[callback]{name}")
2523 }
2524 }
2525 if let Some(interface) = interface {
2526 let s = self.name_world_key(interface);
2527 name.push_str(&s);
2528 name.push_str("#");
2529 }
2530 name.push_str(&func.name);
2531 name
2532 }
2533 WasmExport::ResourceDtor {
2534 interface,
2535 resource,
2536 } => {
2537 let name = self.types[resource].name.as_ref().unwrap();
2538 let interface = self.name_world_key(interface);
2539 format!("{}{interface}#[dtor]{name}", abi.export_prefix())
2540 }
2541 WasmExport::Memory => "memory".to_string(),
2542 WasmExport::Initialize => "_initialize".to_string(),
2543 WasmExport::Realloc => "cabi_realloc".to_string(),
2544 },
2545 }
2546 }
2547}
2548
2549#[derive(Debug)]
2551pub enum WasmImport<'a> {
2552 Func {
2554 interface: Option<&'a WorldKey>,
2559
2560 func: &'a Function,
2562 },
2563
2564 ResourceIntrinsic {
2566 interface: Option<&'a WorldKey>,
2568
2569 resource: TypeId,
2571
2572 intrinsic: ResourceIntrinsic,
2574 },
2575}
2576
2577#[derive(Debug)]
2580pub enum ResourceIntrinsic {
2581 ImportedDrop,
2582 ExportedDrop,
2583 ExportedNew,
2584 ExportedRep,
2585}
2586
2587#[derive(Debug)]
2590pub enum WasmExportKind {
2591 Normal,
2593
2594 PostReturn,
2596
2597 Callback,
2599}
2600
2601#[derive(Debug)]
2604pub enum WasmExport<'a> {
2605 Func {
2607 interface: Option<&'a WorldKey>,
2610
2611 func: &'a Function,
2613
2614 kind: WasmExportKind,
2616 },
2617
2618 ResourceDtor {
2620 interface: &'a WorldKey,
2622 resource: TypeId,
2624 },
2625
2626 Memory,
2628
2629 Initialize,
2631
2632 Realloc,
2634}
2635
2636#[derive(Default)]
2639pub struct Remap {
2640 pub types: Vec<Option<TypeId>>,
2641 pub interfaces: Vec<Option<InterfaceId>>,
2642 pub worlds: Vec<Option<WorldId>>,
2643 pub packages: Vec<PackageId>,
2644
2645 own_handles: HashMap<TypeId, TypeId>,
2655
2656 type_has_borrow: Vec<Option<bool>>,
2657}
2658
2659fn apply_map<T>(map: &[Option<Id<T>>], id: Id<T>, desc: &str, span: Option<Span>) -> Result<Id<T>> {
2660 match map.get(id.index()) {
2661 Some(Some(id)) => Ok(*id),
2662 Some(None) => {
2663 let msg = format!(
2664 "found a reference to a {desc} which is excluded \
2665 due to its feature not being activated"
2666 );
2667 match span {
2668 Some(span) => Err(Error::new(span, msg).into()),
2669 None => bail!("{msg}"),
2670 }
2671 }
2672 None => panic!("request to remap a {desc} that has not yet been registered"),
2673 }
2674}
2675
2676impl Remap {
2677 pub fn map_type(&self, id: TypeId, span: Option<Span>) -> Result<TypeId> {
2678 apply_map(&self.types, id, "type", span)
2679 }
2680
2681 pub fn map_interface(&self, id: InterfaceId, span: Option<Span>) -> Result<InterfaceId> {
2682 apply_map(&self.interfaces, id, "interface", span)
2683 }
2684
2685 pub fn map_world(&self, id: WorldId, span: Option<Span>) -> Result<WorldId> {
2686 apply_map(&self.worlds, id, "world", span)
2687 }
2688
2689 fn append(
2690 &mut self,
2691 resolve: &mut Resolve,
2692 unresolved: UnresolvedPackage,
2693 ) -> Result<PackageId> {
2694 let pkgid = resolve.packages.alloc(Package {
2695 name: unresolved.name.clone(),
2696 docs: unresolved.docs.clone(),
2697 interfaces: Default::default(),
2698 worlds: Default::default(),
2699 });
2700 let prev = resolve.package_names.insert(unresolved.name.clone(), pkgid);
2701 if let Some(prev) = prev {
2702 resolve.package_names.insert(unresolved.name.clone(), prev);
2703 bail!(
2704 "attempting to re-add package `{}` when it's already present in this `Resolve`",
2705 unresolved.name,
2706 );
2707 }
2708
2709 self.process_foreign_deps(resolve, pkgid, &unresolved)?;
2710
2711 let foreign_types = self.types.len();
2712 let foreign_interfaces = self.interfaces.len();
2713 let foreign_worlds = self.worlds.len();
2714
2715 assert_eq!(unresolved.types.len(), unresolved.type_spans.len());
2721 for ((id, mut ty), span) in unresolved
2722 .types
2723 .into_iter()
2724 .zip(&unresolved.type_spans)
2725 .skip(foreign_types)
2726 {
2727 if !resolve.include_type(&ty, pkgid, *span)? {
2728 self.types.push(None);
2729 continue;
2730 }
2731
2732 self.update_typedef(resolve, &mut ty, Some(*span))?;
2733 let new_id = resolve.types.alloc(ty);
2734 assert_eq!(self.types.len(), id.index());
2735
2736 let new_id = match resolve.types[new_id] {
2737 TypeDef {
2742 name: None,
2743 owner: TypeOwner::None,
2744 kind: TypeDefKind::Handle(Handle::Own(id)),
2745 docs: _,
2746 stability: _,
2747 } => *self.own_handles.entry(id).or_insert(new_id),
2748
2749 _ => new_id,
2752 };
2753 self.types.push(Some(new_id));
2754 }
2755
2756 assert_eq!(
2759 unresolved.interfaces.len(),
2760 unresolved.interface_spans.len()
2761 );
2762 for ((id, mut iface), span) in unresolved
2763 .interfaces
2764 .into_iter()
2765 .zip(&unresolved.interface_spans)
2766 .skip(foreign_interfaces)
2767 {
2768 if !resolve
2769 .include_stability(&iface.stability, &pkgid, Some(span.span))
2770 .with_context(|| {
2771 format!(
2772 "failed to process feature gate for interface [{}] in package [{}]",
2773 iface
2774 .name
2775 .as_ref()
2776 .map(String::as_str)
2777 .unwrap_or("<unknown>"),
2778 resolve.packages[pkgid].name,
2779 )
2780 })?
2781 {
2782 self.interfaces.push(None);
2783 continue;
2784 }
2785 assert!(iface.package.is_none());
2786 iface.package = Some(pkgid);
2787 self.update_interface(resolve, &mut iface, Some(span))?;
2788 let new_id = resolve.interfaces.alloc(iface);
2789 assert_eq!(self.interfaces.len(), id.index());
2790 self.interfaces.push(Some(new_id));
2791 }
2792
2793 for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2796 let id = match id {
2797 Some(id) => *id,
2798 None => continue,
2799 };
2800 match &mut resolve.types[id].owner {
2801 TypeOwner::Interface(id) => {
2802 let span = unresolved.type_spans[i];
2803 *id = self.map_interface(*id, Some(span))
2804 .with_context(|| {
2805 "this type is not gated by a feature but its interface is gated by a feature"
2806 })?;
2807 }
2808 TypeOwner::World(_) | TypeOwner::None => {}
2809 }
2810 }
2811
2812 assert_eq!(unresolved.worlds.len(), unresolved.world_spans.len());
2820 for ((id, mut world), span) in unresolved
2821 .worlds
2822 .into_iter()
2823 .zip(&unresolved.world_spans)
2824 .skip(foreign_worlds)
2825 {
2826 if !resolve
2827 .include_stability(&world.stability, &pkgid, Some(span.span))
2828 .with_context(|| {
2829 format!(
2830 "failed to process feature gate for world [{}] in package [{}]",
2831 world.name, resolve.packages[pkgid].name,
2832 )
2833 })?
2834 {
2835 self.worlds.push(None);
2836 continue;
2837 }
2838 self.update_world(&mut world, resolve, &pkgid, &span)?;
2839
2840 let new_id = resolve.worlds.alloc(world);
2841 assert_eq!(self.worlds.len(), id.index());
2842 self.worlds.push(Some(new_id));
2843
2844 resolve.elaborate_world(new_id).with_context(|| {
2845 Error::new(
2846 span.span,
2847 format!(
2848 "failed to elaborate world imports/exports of `{}`",
2849 resolve.worlds[new_id].name
2850 ),
2851 )
2852 })?;
2853 }
2854
2855 for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2857 let id = match id {
2858 Some(id) => *id,
2859 None => continue,
2860 };
2861 match &mut resolve.types[id].owner {
2862 TypeOwner::World(id) => {
2863 let span = unresolved.type_spans[i];
2864 *id = self.map_world(*id, Some(span))
2865 .with_context(|| {
2866 "this type is not gated by a feature but its interface is gated by a feature"
2867 })?;
2868 }
2869 TypeOwner::Interface(_) | TypeOwner::None => {}
2870 }
2871 }
2872
2873 for id in self.interfaces.iter().skip(foreign_interfaces) {
2875 let id = match id {
2876 Some(id) => *id,
2877 None => continue,
2878 };
2879 let iface = &mut resolve.interfaces[id];
2880 iface.package = Some(pkgid);
2881 if let Some(name) = &iface.name {
2882 let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), id);
2883 assert!(prev.is_none());
2884 }
2885 }
2886 for id in self.worlds.iter().skip(foreign_worlds) {
2887 let id = match id {
2888 Some(id) => *id,
2889 None => continue,
2890 };
2891 let world = &mut resolve.worlds[id];
2892 world.package = Some(pkgid);
2893 let prev = resolve.packages[pkgid]
2894 .worlds
2895 .insert(world.name.clone(), id);
2896 assert!(prev.is_none());
2897 }
2898 Ok(pkgid)
2899 }
2900
2901 fn process_foreign_deps(
2902 &mut self,
2903 resolve: &mut Resolve,
2904 pkgid: PackageId,
2905 unresolved: &UnresolvedPackage,
2906 ) -> Result<()> {
2907 let mut world_to_package = HashMap::new();
2910 let mut interface_to_package = HashMap::new();
2911 for (i, (pkg_name, worlds_or_ifaces)) in unresolved.foreign_deps.iter().enumerate() {
2912 for (name, item) in worlds_or_ifaces {
2913 match item {
2914 AstItem::Interface(unresolved_interface_id) => {
2915 let prev = interface_to_package.insert(
2916 *unresolved_interface_id,
2917 (pkg_name, name, unresolved.foreign_dep_spans[i]),
2918 );
2919 assert!(prev.is_none());
2920 }
2921 AstItem::World(unresolved_world_id) => {
2922 let prev = world_to_package.insert(
2923 *unresolved_world_id,
2924 (pkg_name, name, unresolved.foreign_dep_spans[i]),
2925 );
2926 assert!(prev.is_none());
2927 }
2928 }
2929 }
2930 }
2931
2932 self.process_foreign_interfaces(unresolved, &interface_to_package, resolve)?;
2936
2937 self.process_foreign_worlds(unresolved, &world_to_package, resolve)?;
2941
2942 self.process_foreign_types(unresolved, pkgid, resolve)?;
2945
2946 for (id, span) in unresolved.required_resource_types.iter() {
2947 let Ok(mut id) = self.map_type(*id, Some(*span)) else {
2952 continue;
2953 };
2954 loop {
2955 match resolve.types[id].kind {
2956 TypeDefKind::Type(Type::Id(i)) => id = i,
2957 TypeDefKind::Resource => break,
2958 _ => bail!(Error::new(
2959 *span,
2960 format!("type used in a handle must be a resource"),
2961 )),
2962 }
2963 }
2964 }
2965
2966 #[cfg(debug_assertions)]
2967 resolve.assert_valid();
2968
2969 Ok(())
2970 }
2971
2972 fn process_foreign_interfaces(
2973 &mut self,
2974 unresolved: &UnresolvedPackage,
2975 interface_to_package: &HashMap<InterfaceId, (&PackageName, &String, Span)>,
2976 resolve: &mut Resolve,
2977 ) -> Result<(), anyhow::Error> {
2978 for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() {
2979 let (pkg_name, interface, span) = match interface_to_package.get(&unresolved_iface_id) {
2980 Some(items) => *items,
2981 None => break,
2985 };
2986 let pkgid = resolve
2987 .package_names
2988 .get(pkg_name)
2989 .copied()
2990 .ok_or_else(|| {
2991 PackageNotFoundError::new(
2992 span,
2993 pkg_name.clone(),
2994 resolve.package_names.keys().cloned().collect(),
2995 )
2996 })?;
2997
2998 assert!(unresolved_iface.functions.is_empty());
3000
3001 let pkg = &resolve.packages[pkgid];
3002 let span = &unresolved.interface_spans[unresolved_iface_id.index()];
3003 let iface_id = pkg
3004 .interfaces
3005 .get(interface)
3006 .copied()
3007 .ok_or_else(|| Error::new(span.span, "interface not found in package"))?;
3008 assert_eq!(self.interfaces.len(), unresolved_iface_id.index());
3009 self.interfaces.push(Some(iface_id));
3010 }
3011 for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) {
3012 assert!(
3013 interface_to_package.get(&id).is_none(),
3014 "found foreign interface after local interface"
3015 );
3016 }
3017 Ok(())
3018 }
3019
3020 fn process_foreign_worlds(
3021 &mut self,
3022 unresolved: &UnresolvedPackage,
3023 world_to_package: &HashMap<WorldId, (&PackageName, &String, Span)>,
3024 resolve: &mut Resolve,
3025 ) -> Result<(), anyhow::Error> {
3026 for (unresolved_world_id, _) in unresolved.worlds.iter() {
3027 let (pkg_name, world, span) = match world_to_package.get(&unresolved_world_id) {
3028 Some(items) => *items,
3029 None => break,
3032 };
3033
3034 let pkgid = resolve
3035 .package_names
3036 .get(pkg_name)
3037 .copied()
3038 .ok_or_else(|| Error::new(span, "package not found"))?;
3039 let pkg = &resolve.packages[pkgid];
3040 let span = &unresolved.world_spans[unresolved_world_id.index()];
3041 let world_id = pkg
3042 .worlds
3043 .get(world)
3044 .copied()
3045 .ok_or_else(|| Error::new(span.span, "world not found in package"))?;
3046 assert_eq!(self.worlds.len(), unresolved_world_id.index());
3047 self.worlds.push(Some(world_id));
3048 }
3049 for (id, _) in unresolved.worlds.iter().skip(self.worlds.len()) {
3050 assert!(
3051 world_to_package.get(&id).is_none(),
3052 "found foreign world after local world"
3053 );
3054 }
3055 Ok(())
3056 }
3057
3058 fn process_foreign_types(
3059 &mut self,
3060 unresolved: &UnresolvedPackage,
3061 pkgid: PackageId,
3062 resolve: &mut Resolve,
3063 ) -> Result<(), anyhow::Error> {
3064 for ((unresolved_type_id, unresolved_ty), span) in
3065 unresolved.types.iter().zip(&unresolved.type_spans)
3066 {
3067 match unresolved_ty.kind {
3071 TypeDefKind::Unknown => {}
3072 _ => break,
3073 }
3074
3075 if !resolve.include_type(unresolved_ty, pkgid, *span)? {
3076 self.types.push(None);
3077 continue;
3078 }
3079
3080 let unresolved_iface_id = match unresolved_ty.owner {
3081 TypeOwner::Interface(id) => id,
3082 _ => unreachable!(),
3083 };
3084 let iface_id = self.map_interface(unresolved_iface_id, None)?;
3085 let name = unresolved_ty.name.as_ref().unwrap();
3086 let span = unresolved.unknown_type_spans[unresolved_type_id.index()];
3087 let type_id = *resolve.interfaces[iface_id]
3088 .types
3089 .get(name)
3090 .ok_or_else(|| {
3091 Error::new(span, format!("type `{name}` not defined in interface"))
3092 })?;
3093 assert_eq!(self.types.len(), unresolved_type_id.index());
3094 self.types.push(Some(type_id));
3095 }
3096 for (_, ty) in unresolved.types.iter().skip(self.types.len()) {
3097 if let TypeDefKind::Unknown = ty.kind {
3098 panic!("unknown type after defined type");
3099 }
3100 }
3101 Ok(())
3102 }
3103
3104 fn update_typedef(
3105 &mut self,
3106 resolve: &mut Resolve,
3107 ty: &mut TypeDef,
3108 span: Option<Span>,
3109 ) -> Result<()> {
3110 use crate::TypeDefKind::*;
3113 match &mut ty.kind {
3114 Handle(handle) => match handle {
3115 crate::Handle::Own(ty) | crate::Handle::Borrow(ty) => {
3116 self.update_type_id(ty, span)?
3117 }
3118 },
3119 Resource => {}
3120 Record(r) => {
3121 for field in r.fields.iter_mut() {
3122 self.update_ty(resolve, &mut field.ty, span)
3123 .with_context(|| format!("failed to update field `{}`", field.name))?;
3124 }
3125 }
3126 Tuple(t) => {
3127 for ty in t.types.iter_mut() {
3128 self.update_ty(resolve, ty, span)?;
3129 }
3130 }
3131 Variant(v) => {
3132 for case in v.cases.iter_mut() {
3133 if let Some(t) = &mut case.ty {
3134 self.update_ty(resolve, t, span)?;
3135 }
3136 }
3137 }
3138 Option(t) | List(t) | Future(Some(t)) | Stream(Some(t)) => {
3139 self.update_ty(resolve, t, span)?
3140 }
3141 Result(r) => {
3142 if let Some(ty) = &mut r.ok {
3143 self.update_ty(resolve, ty, span)?;
3144 }
3145 if let Some(ty) = &mut r.err {
3146 self.update_ty(resolve, ty, span)?;
3147 }
3148 }
3149
3150 Type(crate::Type::Id(id)) => self.update_type_id(id, span)?,
3155 Type(_) => {}
3156
3157 Flags(_) | Enum(_) | Future(None) | Stream(None) => {}
3159
3160 Unknown => unreachable!(),
3161 }
3162
3163 Ok(())
3164 }
3165
3166 fn update_ty(
3167 &mut self,
3168 resolve: &mut Resolve,
3169 ty: &mut Type,
3170 span: Option<Span>,
3171 ) -> Result<()> {
3172 let id = match ty {
3173 Type::Id(id) => id,
3174 _ => return Ok(()),
3175 };
3176 self.update_type_id(id, span)?;
3177
3178 let mut cur = *id;
3183 let points_to_resource = loop {
3184 match resolve.types[cur].kind {
3185 TypeDefKind::Type(Type::Id(id)) => cur = id,
3186 TypeDefKind::Resource => break true,
3187 _ => break false,
3188 }
3189 };
3190
3191 if points_to_resource {
3192 *id = *self.own_handles.entry(*id).or_insert_with(|| {
3193 resolve.types.alloc(TypeDef {
3194 name: None,
3195 owner: TypeOwner::None,
3196 kind: TypeDefKind::Handle(Handle::Own(*id)),
3197 docs: Default::default(),
3198 stability: Default::default(),
3199 })
3200 });
3201 }
3202 Ok(())
3203 }
3204
3205 fn update_type_id(&self, id: &mut TypeId, span: Option<Span>) -> Result<()> {
3206 *id = self.map_type(*id, span)?;
3207 Ok(())
3208 }
3209
3210 fn update_interface(
3211 &mut self,
3212 resolve: &mut Resolve,
3213 iface: &mut Interface,
3214 spans: Option<&InterfaceSpan>,
3215 ) -> Result<()> {
3216 iface.types.retain(|_, ty| self.types[ty.index()].is_some());
3217 let iface_pkg_id = iface.package.as_ref().unwrap_or_else(|| {
3218 panic!(
3219 "unexpectedly missing package on interface [{}]",
3220 iface
3221 .name
3222 .as_ref()
3223 .map(String::as_str)
3224 .unwrap_or("<unknown>"),
3225 )
3226 });
3227
3228 for (_name, ty) in iface.types.iter_mut() {
3231 self.update_type_id(ty, spans.map(|s| s.span))?;
3232 }
3233 if let Some(spans) = spans {
3234 assert_eq!(iface.functions.len(), spans.funcs.len());
3235 }
3236 for (i, (func_name, func)) in iface.functions.iter_mut().enumerate() {
3237 let span = spans.map(|s| s.funcs[i]);
3238 if !resolve
3239 .include_stability(&func.stability, iface_pkg_id, span)
3240 .with_context(|| {
3241 format!(
3242 "failed to process feature gate for function [{func_name}] in package [{}]",
3243 resolve.packages[*iface_pkg_id].name,
3244 )
3245 })?
3246 {
3247 continue;
3248 }
3249 self.update_function(resolve, func, span)
3250 .with_context(|| format!("failed to update function `{}`", func.name))?;
3251 }
3252
3253 for (name, func) in mem::take(&mut iface.functions) {
3256 if resolve.include_stability(&func.stability, iface_pkg_id, None)? {
3257 iface.functions.insert(name, func);
3258 }
3259 }
3260
3261 Ok(())
3262 }
3263
3264 fn update_function(
3265 &mut self,
3266 resolve: &mut Resolve,
3267 func: &mut Function,
3268 span: Option<Span>,
3269 ) -> Result<()> {
3270 if let Some(id) = func.kind.resource_mut() {
3271 self.update_type_id(id, span)?;
3272 }
3273 for (_, ty) in func.params.iter_mut() {
3274 self.update_ty(resolve, ty, span)?;
3275 }
3276 if let Some(ty) = &mut func.result {
3277 self.update_ty(resolve, ty, span)?;
3278 }
3279
3280 if let Some(ty) = &func.result {
3281 if self.type_has_borrow(resolve, ty) {
3282 match span {
3283 Some(span) => {
3284 bail!(Error::new(
3285 span,
3286 format!(
3287 "function returns a type which contains \
3288 a `borrow<T>` which is not supported"
3289 )
3290 ))
3291 }
3292 None => unreachable!(),
3293 }
3294 }
3295 }
3296
3297 Ok(())
3298 }
3299
3300 fn update_world(
3301 &mut self,
3302 world: &mut World,
3303 resolve: &mut Resolve,
3304 pkg_id: &PackageId,
3305 spans: &WorldSpan,
3306 ) -> Result<()> {
3307 assert_eq!(world.imports.len(), spans.imports.len());
3308 assert_eq!(world.exports.len(), spans.exports.len());
3309
3310 let imports = mem::take(&mut world.imports).into_iter();
3314 let imports = imports.zip(&spans.imports).map(|p| (p, true));
3315 let exports = mem::take(&mut world.exports).into_iter();
3316 let exports = exports.zip(&spans.exports).map(|p| (p, false));
3317 for (((mut name, mut item), span), import) in imports.chain(exports) {
3318 if let WorldItem::Type(id) = &mut item {
3321 *id = self.map_type(*id, Some(*span))?;
3322 }
3323 let stability = item.stability(resolve);
3324 if !resolve
3325 .include_stability(stability, pkg_id, Some(*span))
3326 .with_context(|| format!("failed to process world item in `{}`", world.name))?
3327 {
3328 continue;
3329 }
3330 self.update_world_key(&mut name, Some(*span))?;
3331 match &mut item {
3332 WorldItem::Interface { id, .. } => {
3333 *id = self.map_interface(*id, Some(*span))?;
3334 }
3335 WorldItem::Function(f) => {
3336 self.update_function(resolve, f, Some(*span))?;
3337 }
3338 WorldItem::Type(_) => {
3339 }
3341 }
3342
3343 let dst = if import {
3344 &mut world.imports
3345 } else {
3346 &mut world.exports
3347 };
3348 let prev = dst.insert(name, item);
3349 assert!(prev.is_none());
3350 }
3351
3352 assert_eq!(world.includes.len(), spans.includes.len());
3355 let includes = mem::take(&mut world.includes);
3356 let include_names = mem::take(&mut world.include_names);
3357 for (((stability, include_world), span), names) in includes
3358 .into_iter()
3359 .zip(&spans.includes)
3360 .zip(&include_names)
3361 {
3362 if !resolve
3363 .include_stability(&stability, pkg_id, Some(*span))
3364 .with_context(|| {
3365 format!(
3366 "failed to process feature gate for included world [{}] in package [{}]",
3367 resolve.worlds[include_world].name.as_str(),
3368 resolve.packages[*pkg_id].name
3369 )
3370 })?
3371 {
3372 continue;
3373 }
3374 self.resolve_include(world, include_world, names, *span, resolve)?;
3375 }
3376
3377 Ok(())
3378 }
3379
3380 fn update_world_key(&self, key: &mut WorldKey, span: Option<Span>) -> Result<()> {
3381 match key {
3382 WorldKey::Name(_) => {}
3383 WorldKey::Interface(id) => {
3384 *id = self.map_interface(*id, span)?;
3385 }
3386 }
3387 Ok(())
3388 }
3389
3390 fn resolve_include(
3391 &self,
3392 world: &mut World,
3393 include_world: WorldId,
3394 names: &[IncludeName],
3395 span: Span,
3396 resolve: &Resolve,
3397 ) -> Result<()> {
3398 let include_world_id = self.map_world(include_world, Some(span))?;
3399 let include_world = &resolve.worlds[include_world_id];
3400 let mut names_ = names.to_owned();
3401
3402 for import in include_world.imports.iter() {
3404 self.remove_matching_name(import, &mut names_);
3405 }
3406 for export in include_world.exports.iter() {
3407 self.remove_matching_name(export, &mut names_);
3408 }
3409 if !names_.is_empty() {
3410 bail!(Error::new(
3411 span,
3412 format!("no import or export kebab-name `{}`. Note that an ID does not support renaming", names_[0].name),
3413 ));
3414 }
3415
3416 for import in include_world.imports.iter() {
3418 self.resolve_include_item(names, &mut world.imports, import, span, "import")?;
3419 }
3420
3421 for export in include_world.exports.iter() {
3422 self.resolve_include_item(names, &mut world.exports, export, span, "export")?;
3423 }
3424 Ok(())
3425 }
3426
3427 fn resolve_include_item(
3428 &self,
3429 names: &[IncludeName],
3430 items: &mut IndexMap<WorldKey, WorldItem>,
3431 item: (&WorldKey, &WorldItem),
3432 span: Span,
3433 item_type: &str,
3434 ) -> Result<()> {
3435 match item.0 {
3436 WorldKey::Name(n) => {
3437 let n = if let Some(found) = names
3438 .into_iter()
3439 .find(|include_name| include_name.name == n.clone())
3440 {
3441 found.as_.clone()
3442 } else {
3443 n.clone()
3444 };
3445
3446 let prev = items.insert(WorldKey::Name(n.clone()), item.1.clone());
3447 if prev.is_some() {
3448 bail!(Error::new(
3449 span,
3450 format!("{item_type} of `{n}` shadows previously {item_type}ed items"),
3451 ))
3452 }
3453 }
3454 key @ WorldKey::Interface(_) => {
3455 let prev = items.entry(key.clone()).or_insert(item.1.clone());
3456 match (&item.1, prev) {
3457 (
3458 WorldItem::Interface {
3459 id: aid,
3460 stability: astability,
3461 },
3462 WorldItem::Interface {
3463 id: bid,
3464 stability: bstability,
3465 },
3466 ) => {
3467 assert_eq!(*aid, *bid);
3468 merge_stability(astability, bstability)?;
3469 }
3470 (WorldItem::Interface { .. }, _) => unreachable!(),
3471 (WorldItem::Function(_), _) => unreachable!(),
3472 (WorldItem::Type(_), _) => unreachable!(),
3473 }
3474 }
3475 };
3476 Ok(())
3477 }
3478
3479 fn remove_matching_name(&self, item: (&WorldKey, &WorldItem), names: &mut Vec<IncludeName>) {
3480 match item.0 {
3481 WorldKey::Name(n) => {
3482 names.retain(|name| name.name != n.clone());
3483 }
3484 _ => {}
3485 }
3486 }
3487
3488 fn type_has_borrow(&mut self, resolve: &Resolve, ty: &Type) -> bool {
3489 let id = match ty {
3490 Type::Id(id) => *id,
3491 _ => return false,
3492 };
3493
3494 if let Some(Some(has_borrow)) = self.type_has_borrow.get(id.index()) {
3495 return *has_borrow;
3496 }
3497
3498 let result = self.typedef_has_borrow(resolve, &resolve.types[id]);
3499 if self.type_has_borrow.len() <= id.index() {
3500 self.type_has_borrow.resize(id.index() + 1, None);
3501 }
3502 self.type_has_borrow[id.index()] = Some(result);
3503 result
3504 }
3505
3506 fn typedef_has_borrow(&mut self, resolve: &Resolve, ty: &TypeDef) -> bool {
3507 match &ty.kind {
3508 TypeDefKind::Type(t) => self.type_has_borrow(resolve, t),
3509 TypeDefKind::Variant(v) => v
3510 .cases
3511 .iter()
3512 .filter_map(|case| case.ty.as_ref())
3513 .any(|ty| self.type_has_borrow(resolve, ty)),
3514 TypeDefKind::Handle(Handle::Borrow(_)) => true,
3515 TypeDefKind::Handle(Handle::Own(_)) => false,
3516 TypeDefKind::Resource => false,
3517 TypeDefKind::Record(r) => r
3518 .fields
3519 .iter()
3520 .any(|case| self.type_has_borrow(resolve, &case.ty)),
3521 TypeDefKind::Flags(_) => false,
3522 TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.type_has_borrow(resolve, t)),
3523 TypeDefKind::Enum(_) => false,
3524 TypeDefKind::List(ty)
3525 | TypeDefKind::Future(Some(ty))
3526 | TypeDefKind::Stream(Some(ty))
3527 | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty),
3528 TypeDefKind::Result(r) => [&r.ok, &r.err]
3529 .iter()
3530 .filter_map(|t| t.as_ref())
3531 .any(|t| self.type_has_borrow(resolve, t)),
3532 TypeDefKind::Future(None) | TypeDefKind::Stream(None) => false,
3533 TypeDefKind::Unknown => unreachable!(),
3534 }
3535 }
3536}
3537
3538struct MergeMap<'a> {
3539 package_map: HashMap<PackageId, PackageId>,
3542
3543 interface_map: HashMap<InterfaceId, InterfaceId>,
3546
3547 type_map: HashMap<TypeId, TypeId>,
3550
3551 world_map: HashMap<WorldId, WorldId>,
3554
3555 interfaces_to_add: Vec<(String, PackageId, InterfaceId)>,
3563 worlds_to_add: Vec<(String, PackageId, WorldId)>,
3564
3565 from: &'a Resolve,
3567
3568 into: &'a Resolve,
3570}
3571
3572impl<'a> MergeMap<'a> {
3573 fn new(from: &'a Resolve, into: &'a Resolve) -> MergeMap<'a> {
3574 MergeMap {
3575 package_map: Default::default(),
3576 interface_map: Default::default(),
3577 type_map: Default::default(),
3578 world_map: Default::default(),
3579 interfaces_to_add: Default::default(),
3580 worlds_to_add: Default::default(),
3581 from,
3582 into,
3583 }
3584 }
3585
3586 fn build(&mut self) -> Result<()> {
3587 for from_id in self.from.topological_packages() {
3588 let from = &self.from.packages[from_id];
3589 let into_id = match self.into.package_names.get(&from.name) {
3590 Some(id) => *id,
3591
3592 None => {
3595 log::trace!("adding unique package {}", from.name);
3596 continue;
3597 }
3598 };
3599 log::trace!("merging duplicate package {}", from.name);
3600
3601 self.build_package(from_id, into_id).with_context(|| {
3602 format!("failed to merge package `{}` into existing copy", from.name)
3603 })?;
3604 }
3605
3606 Ok(())
3607 }
3608
3609 fn build_package(&mut self, from_id: PackageId, into_id: PackageId) -> Result<()> {
3610 let prev = self.package_map.insert(from_id, into_id);
3611 assert!(prev.is_none());
3612
3613 let from = &self.from.packages[from_id];
3614 let into = &self.into.packages[into_id];
3615
3616 for (name, from_interface_id) in from.interfaces.iter() {
3620 let into_interface_id = match into.interfaces.get(name) {
3621 Some(id) => *id,
3622 None => {
3623 log::trace!("adding unique interface {}", name);
3624 self.interfaces_to_add
3625 .push((name.clone(), into_id, *from_interface_id));
3626 continue;
3627 }
3628 };
3629
3630 log::trace!("merging duplicate interfaces {}", name);
3631 self.build_interface(*from_interface_id, into_interface_id)
3632 .with_context(|| format!("failed to merge interface `{name}`"))?;
3633 }
3634
3635 for (name, from_world_id) in from.worlds.iter() {
3636 let into_world_id = match into.worlds.get(name) {
3637 Some(id) => *id,
3638 None => {
3639 log::trace!("adding unique world {}", name);
3640 self.worlds_to_add
3641 .push((name.clone(), into_id, *from_world_id));
3642 continue;
3643 }
3644 };
3645
3646 log::trace!("merging duplicate worlds {}", name);
3647 self.build_world(*from_world_id, into_world_id)
3648 .with_context(|| format!("failed to merge world `{name}`"))?;
3649 }
3650
3651 Ok(())
3652 }
3653
3654 fn build_interface(&mut self, from_id: InterfaceId, into_id: InterfaceId) -> Result<()> {
3655 let prev = self.interface_map.insert(from_id, into_id);
3656 assert!(prev.is_none());
3657
3658 let from_interface = &self.from.interfaces[from_id];
3659 let into_interface = &self.into.interfaces[into_id];
3660
3661 for (name, from_type_id) in from_interface.types.iter() {
3675 let into_type_id = *into_interface
3676 .types
3677 .get(name)
3678 .ok_or_else(|| anyhow!("expected type `{name}` to be present"))?;
3679 let prev = self.type_map.insert(*from_type_id, into_type_id);
3680 assert!(prev.is_none());
3681
3682 self.build_type_id(*from_type_id, into_type_id)
3683 .with_context(|| format!("mismatch in type `{name}`"))?;
3684 }
3685
3686 for (name, from_func) in from_interface.functions.iter() {
3687 let into_func = match into_interface.functions.get(name) {
3688 Some(func) => func,
3689 None => bail!("expected function `{name}` to be present"),
3690 };
3691 self.build_function(from_func, into_func)
3692 .with_context(|| format!("mismatch in function `{name}`"))?;
3693 }
3694
3695 Ok(())
3696 }
3697
3698 fn build_type_id(&mut self, from_id: TypeId, into_id: TypeId) -> Result<()> {
3699 let _ = from_id;
3703 let _ = into_id;
3704 Ok(())
3705 }
3706
3707 fn build_type(&mut self, from_ty: &Type, into_ty: &Type) -> Result<()> {
3708 match (from_ty, into_ty) {
3709 (Type::Id(from), Type::Id(into)) => {
3710 self.build_type_id(*from, *into)?;
3711 }
3712 (from, into) if from != into => bail!("different kinds of types"),
3713 _ => {}
3714 }
3715 Ok(())
3716 }
3717
3718 fn build_function(&mut self, from_func: &Function, into_func: &Function) -> Result<()> {
3719 if from_func.name != into_func.name {
3720 bail!(
3721 "different function names `{}` and `{}`",
3722 from_func.name,
3723 into_func.name
3724 );
3725 }
3726 match (&from_func.kind, &into_func.kind) {
3727 (FunctionKind::Freestanding, FunctionKind::Freestanding) => {}
3728 (FunctionKind::AsyncFreestanding, FunctionKind::AsyncFreestanding) => {}
3729
3730 (FunctionKind::Method(from), FunctionKind::Method(into))
3731 | (FunctionKind::Static(from), FunctionKind::Static(into))
3732 | (FunctionKind::AsyncMethod(from), FunctionKind::AsyncMethod(into))
3733 | (FunctionKind::AsyncStatic(from), FunctionKind::AsyncStatic(into))
3734 | (FunctionKind::Constructor(from), FunctionKind::Constructor(into)) => {
3735 self.build_type_id(*from, *into)
3736 .context("different function kind types")?;
3737 }
3738
3739 (FunctionKind::Method(_), _)
3740 | (FunctionKind::Constructor(_), _)
3741 | (FunctionKind::Static(_), _)
3742 | (FunctionKind::Freestanding, _)
3743 | (FunctionKind::AsyncFreestanding, _)
3744 | (FunctionKind::AsyncMethod(_), _)
3745 | (FunctionKind::AsyncStatic(_), _) => {
3746 bail!("different function kind types")
3747 }
3748 }
3749
3750 if from_func.params.len() != into_func.params.len() {
3751 bail!("different number of function parameters");
3752 }
3753 for ((from_name, from_ty), (into_name, into_ty)) in
3754 from_func.params.iter().zip(&into_func.params)
3755 {
3756 if from_name != into_name {
3757 bail!("different function parameter names: {from_name} != {into_name}");
3758 }
3759 self.build_type(from_ty, into_ty)
3760 .with_context(|| format!("different function parameter types for `{from_name}`"))?;
3761 }
3762 match (&from_func.result, &into_func.result) {
3763 (Some(from_ty), Some(into_ty)) => {
3764 self.build_type(from_ty, into_ty)
3765 .context("different function result types")?;
3766 }
3767 (None, None) => {}
3768 (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
3769 }
3770 Ok(())
3771 }
3772
3773 fn build_world(&mut self, from_id: WorldId, into_id: WorldId) -> Result<()> {
3774 let prev = self.world_map.insert(from_id, into_id);
3775 assert!(prev.is_none());
3776
3777 let from_world = &self.from.worlds[from_id];
3778 let into_world = &self.into.worlds[into_id];
3779
3780 if from_world.imports.len() != into_world.imports.len() {
3789 bail!("world contains different number of imports than expected");
3790 }
3791 if from_world.exports.len() != into_world.exports.len() {
3792 bail!("world contains different number of exports than expected");
3793 }
3794
3795 for (from_name, from) in from_world.imports.iter() {
3796 let into_name = MergeMap::map_name(from_name, &self.interface_map);
3797 let name_str = self.from.name_world_key(from_name);
3798 let into = into_world
3799 .imports
3800 .get(&into_name)
3801 .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?;
3802 self.match_world_item(from, into)
3803 .with_context(|| format!("import `{name_str}` didn't match target world"))?;
3804 }
3805
3806 for (from_name, from) in from_world.exports.iter() {
3807 let into_name = MergeMap::map_name(from_name, &self.interface_map);
3808 let name_str = self.from.name_world_key(from_name);
3809 let into = into_world
3810 .exports
3811 .get(&into_name)
3812 .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?;
3813 self.match_world_item(from, into)
3814 .with_context(|| format!("export `{name_str}` didn't match target world"))?;
3815 }
3816
3817 Ok(())
3818 }
3819
3820 fn map_name(
3821 from_name: &WorldKey,
3822 interface_map: &HashMap<InterfaceId, InterfaceId>,
3823 ) -> WorldKey {
3824 match from_name {
3825 WorldKey::Name(s) => WorldKey::Name(s.clone()),
3826 WorldKey::Interface(id) => {
3827 WorldKey::Interface(interface_map.get(id).copied().unwrap_or(*id))
3828 }
3829 }
3830 }
3831
3832 fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> Result<()> {
3833 match (from, into) {
3834 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
3835 match (
3836 &self.from.interfaces[*from].name,
3837 &self.into.interfaces[*into].name,
3838 ) {
3839 (None, None) => self.build_interface(*from, *into)?,
3843
3844 _ => {
3849 if self.interface_map.get(&from) != Some(&into) {
3850 bail!("interfaces are not the same");
3851 }
3852 }
3853 }
3854 }
3855 (WorldItem::Function(from), WorldItem::Function(into)) => {
3856 let _ = (from, into);
3857 }
3860 (WorldItem::Type(from), WorldItem::Type(into)) => {
3861 let prev = self.type_map.insert(*from, *into);
3864 assert!(prev.is_none());
3865 }
3866
3867 (WorldItem::Interface { .. }, _)
3868 | (WorldItem::Function(_), _)
3869 | (WorldItem::Type(_), _) => {
3870 bail!("world items do not have the same type")
3871 }
3872 }
3873 Ok(())
3874 }
3875}
3876
3877fn update_stability(from: &Stability, into: &mut Stability) -> Result<()> {
3883 if from == into || from.is_unknown() {
3886 return Ok(());
3887 }
3888 if into.is_unknown() {
3891 *into = from.clone();
3892 return Ok(());
3893 }
3894
3895 bail!("mismatch in stability from '{:?}' to '{:?}'", from, into)
3898}
3899
3900fn merge_stability(from: &Stability, into: &mut Stability) -> Result<()> {
3905 if from == into {
3908 return Ok(());
3909 }
3910
3911 if from > into {
3913 *into = from.clone();
3914 return Ok(());
3915 }
3916
3917 return Ok(());
3919}
3920
3921#[derive(Debug, Clone)]
3934pub struct InvalidTransitiveDependency(String);
3935
3936impl fmt::Display for InvalidTransitiveDependency {
3937 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3938 write!(
3939 f,
3940 "interface `{}` transitively depends on an interface in \
3941 incompatible ways",
3942 self.0
3943 )
3944 }
3945}
3946
3947impl std::error::Error for InvalidTransitiveDependency {}
3948
3949#[cfg(test)]
3950mod tests {
3951 use crate::Resolve;
3952 use anyhow::Result;
3953
3954 #[test]
3955 fn select_world() -> Result<()> {
3956 let mut resolve = Resolve::default();
3957 resolve.push_str(
3958 "test.wit",
3959 r#"
3960 package foo:bar@0.1.0;
3961
3962 world foo {}
3963 "#,
3964 )?;
3965 resolve.push_str(
3966 "test.wit",
3967 r#"
3968 package foo:baz@0.1.0;
3969
3970 world foo {}
3971 "#,
3972 )?;
3973 resolve.push_str(
3974 "test.wit",
3975 r#"
3976 package foo:baz@0.2.0;
3977
3978 world foo {}
3979 "#,
3980 )?;
3981
3982 let dummy = resolve.push_str(
3983 "test.wit",
3984 r#"
3985 package foo:dummy;
3986
3987 world foo {}
3988 "#,
3989 )?;
3990
3991 assert!(resolve.select_world(dummy, None).is_ok());
3992 assert!(resolve.select_world(dummy, Some("xx")).is_err());
3993 assert!(resolve.select_world(dummy, Some("")).is_err());
3994 assert!(resolve.select_world(dummy, Some("foo:bar/foo")).is_ok());
3995 assert!(resolve
3996 .select_world(dummy, Some("foo:bar/foo@0.1.0"))
3997 .is_ok());
3998 assert!(resolve.select_world(dummy, Some("foo:baz/foo")).is_err());
3999 assert!(resolve
4000 .select_world(dummy, Some("foo:baz/foo@0.1.0"))
4001 .is_ok());
4002 assert!(resolve
4003 .select_world(dummy, Some("foo:baz/foo@0.2.0"))
4004 .is_ok());
4005 Ok(())
4006 }
4007}