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) | TypeDefKind::FixedSizeList(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
1935 let sort_key = |resolve: &Resolve, item: &WorldItem| match item {
1958 WorldItem::Interface { .. } => 0,
1959 WorldItem::Type(ty) => {
1960 let ty = &resolve.types[*ty];
1961 match ty.kind {
1962 TypeDefKind::Type(Type::Id(t)) if resolve.types[t].owner != ty.owner => 1,
1963 _ => 2,
1964 }
1965 }
1966 WorldItem::Function(f) => {
1967 if f.kind.resource().is_none() {
1968 3
1969 } else {
1970 4
1971 }
1972 }
1973 };
1974
1975 let mut world_imports = world.imports.iter().collect::<Vec<_>>();
1978 world_imports.sort_by_key(|(_name, import)| sort_key(self, import));
1979 for (name, item) in world_imports {
1980 match item {
1981 WorldItem::Interface { id, stability } => {
1984 self.elaborate_world_import(&mut new_imports, name.clone(), *id, &stability);
1985 }
1986
1987 WorldItem::Function(_) => {
1990 let prev = new_imports.insert(name.clone(), item.clone());
1991 assert!(prev.is_none());
1992 }
1993
1994 WorldItem::Type(id) => {
1998 if let Some(dep) = self.type_interface_dep(*id) {
1999 self.elaborate_world_import(
2000 &mut new_imports,
2001 WorldKey::Interface(dep),
2002 dep,
2003 &self.types[*id].stability,
2004 );
2005 }
2006 let prev = new_imports.insert(name.clone(), item.clone());
2007 assert!(prev.is_none());
2008 }
2009 }
2010 }
2011
2012 let mut new_exports = IndexMap::new();
2018 let mut export_interfaces = IndexMap::new();
2019 for (name, item) in world.exports.iter() {
2020 match item {
2021 WorldItem::Interface { id, stability } => {
2022 let prev = export_interfaces.insert(*id, (name.clone(), stability));
2023 assert!(prev.is_none());
2024 }
2025 WorldItem::Function(_) => {
2026 let prev = new_exports.insert(name.clone(), item.clone());
2027 assert!(prev.is_none());
2028 }
2029 WorldItem::Type(_) => unreachable!(),
2030 }
2031 }
2032
2033 self.elaborate_world_exports(&export_interfaces, &mut new_imports, &mut new_exports)?;
2034
2035 new_imports.sort_by_cached_key(|_name, import| sort_key(self, import));
2039
2040 log::trace!("imports = {:?}", new_imports);
2043 log::trace!("exports = {:?}", new_exports);
2044 let world = &mut self.worlds[world_id];
2045 world.imports = new_imports;
2046 world.exports = new_exports;
2047
2048 Ok(())
2049 }
2050
2051 fn elaborate_world_import(
2052 &self,
2053 imports: &mut IndexMap<WorldKey, WorldItem>,
2054 key: WorldKey,
2055 id: InterfaceId,
2056 stability: &Stability,
2057 ) {
2058 if imports.contains_key(&key) {
2059 return;
2060 }
2061 for dep in self.interface_direct_deps(id) {
2062 self.elaborate_world_import(imports, WorldKey::Interface(dep), dep, stability);
2063 }
2064 let prev = imports.insert(
2065 key,
2066 WorldItem::Interface {
2067 id,
2068 stability: stability.clone(),
2069 },
2070 );
2071 assert!(prev.is_none());
2072 }
2073
2074 fn elaborate_world_exports(
2121 &self,
2122 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2123 imports: &mut IndexMap<WorldKey, WorldItem>,
2124 exports: &mut IndexMap<WorldKey, WorldItem>,
2125 ) -> Result<()> {
2126 let mut required_imports = HashSet::new();
2127 for (id, (key, stability)) in export_interfaces.iter() {
2128 let name = self.name_world_key(&key);
2129 let ok = add_world_export(
2130 self,
2131 imports,
2132 exports,
2133 export_interfaces,
2134 &mut required_imports,
2135 *id,
2136 key,
2137 true,
2138 stability,
2139 );
2140 if !ok {
2141 bail!(
2142 InvalidTransitiveDependency(name),
2160 );
2161 }
2162 }
2163 return Ok(());
2164
2165 fn add_world_export(
2166 resolve: &Resolve,
2167 imports: &mut IndexMap<WorldKey, WorldItem>,
2168 exports: &mut IndexMap<WorldKey, WorldItem>,
2169 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2170 required_imports: &mut HashSet<InterfaceId>,
2171 id: InterfaceId,
2172 key: &WorldKey,
2173 add_export: bool,
2174 stability: &Stability,
2175 ) -> bool {
2176 if exports.contains_key(key) {
2177 if add_export {
2178 return true;
2179 } else {
2180 return false;
2181 }
2182 }
2183 if !add_export && required_imports.contains(&id) {
2186 return true;
2187 }
2188 let ok = resolve.interface_direct_deps(id).all(|dep| {
2189 let key = WorldKey::Interface(dep);
2190 let add_export = add_export && export_interfaces.contains_key(&dep);
2191 add_world_export(
2192 resolve,
2193 imports,
2194 exports,
2195 export_interfaces,
2196 required_imports,
2197 dep,
2198 &key,
2199 add_export,
2200 stability,
2201 )
2202 });
2203 if !ok {
2204 return false;
2205 }
2206 let item = WorldItem::Interface {
2207 id,
2208 stability: stability.clone(),
2209 };
2210 if add_export {
2211 if required_imports.contains(&id) {
2212 return false;
2213 }
2214 exports.insert(key.clone(), item);
2215 } else {
2216 required_imports.insert(id);
2217 imports.insert(key.clone(), item);
2218 }
2219 true
2220 }
2221 }
2222
2223 pub fn merge_world_imports_based_on_semver(&mut self, world_id: WorldId) -> Result<()> {
2235 let world = &self.worlds[world_id];
2236
2237 let mut semver_tracks = HashMap::new();
2246 let mut to_remove = HashSet::new();
2247 for (key, _) in world.imports.iter() {
2248 let iface_id = match key {
2249 WorldKey::Interface(id) => *id,
2250 WorldKey::Name(_) => continue,
2251 };
2252 let (track, version) = match self.semver_track(iface_id) {
2253 Some(track) => track,
2254 None => continue,
2255 };
2256 log::debug!(
2257 "{} is on track {}/{}",
2258 self.id_of(iface_id).unwrap(),
2259 track.0,
2260 track.1,
2261 );
2262 match semver_tracks.entry(track.clone()) {
2263 hash_map::Entry::Vacant(e) => {
2264 e.insert((version, iface_id));
2265 }
2266 hash_map::Entry::Occupied(mut e) => match version.cmp(&e.get().0) {
2267 Ordering::Greater => {
2268 to_remove.insert(e.get().1);
2269 e.insert((version, iface_id));
2270 }
2271 Ordering::Equal => {}
2272 Ordering::Less => {
2273 to_remove.insert(iface_id);
2274 }
2275 },
2276 }
2277 }
2278
2279 let mut replacements = HashMap::new();
2282 for id in to_remove {
2283 let (track, _) = self.semver_track(id).unwrap();
2284 let (_, latest) = semver_tracks[&track];
2285 let prev = replacements.insert(id, latest);
2286 assert!(prev.is_none());
2287 }
2288
2289 for (to_replace, replace_with) in replacements.iter() {
2294 self.merge_world_item(
2295 &WorldItem::Interface {
2296 id: *to_replace,
2297 stability: Default::default(),
2298 },
2299 &WorldItem::Interface {
2300 id: *replace_with,
2301 stability: Default::default(),
2302 },
2303 )
2304 .with_context(|| {
2305 let old_name = self.id_of(*to_replace).unwrap();
2306 let new_name = self.id_of(*replace_with).unwrap();
2307 format!(
2308 "failed to upgrade `{old_name}` to `{new_name}`, was \
2309 this semver-compatible update not semver compatible?"
2310 )
2311 })?;
2312 }
2313
2314 for (to_replace, replace_with) in replacements.iter() {
2315 log::debug!(
2316 "REPLACE {} => {}",
2317 self.id_of(*to_replace).unwrap(),
2318 self.id_of(*replace_with).unwrap(),
2319 );
2320 }
2321
2322 for (key, item) in mem::take(&mut self.worlds[world_id].imports) {
2331 if let WorldItem::Interface { id, .. } = item {
2332 if replacements.contains_key(&id) {
2333 continue;
2334 }
2335 }
2336
2337 self.update_interface_deps_of_world_item(&item, &replacements);
2338
2339 let prev = self.worlds[world_id].imports.insert(key, item);
2340 assert!(prev.is_none());
2341 }
2342 for (key, item) in mem::take(&mut self.worlds[world_id].exports) {
2343 self.update_interface_deps_of_world_item(&item, &replacements);
2344 let prev = self.worlds[world_id].exports.insert(key, item);
2345 assert!(prev.is_none());
2346 }
2347
2348 let ids = self.worlds.iter().map(|(id, _)| id).collect::<Vec<_>>();
2354 for world_id in ids {
2355 self.elaborate_world(world_id).with_context(|| {
2356 let name = &self.worlds[world_id].name;
2357 format!(
2358 "failed to elaborate world `{name}` after deduplicating imports \
2359 based on semver"
2360 )
2361 })?;
2362 }
2363
2364 #[cfg(debug_assertions)]
2365 self.assert_valid();
2366
2367 Ok(())
2368 }
2369
2370 fn update_interface_deps_of_world_item(
2371 &mut self,
2372 item: &WorldItem,
2373 replacements: &HashMap<InterfaceId, InterfaceId>,
2374 ) {
2375 match *item {
2376 WorldItem::Type(t) => self.update_interface_dep_of_type(t, &replacements),
2377 WorldItem::Interface { id, .. } => {
2378 let types = self.interfaces[id]
2379 .types
2380 .values()
2381 .copied()
2382 .collect::<Vec<_>>();
2383 for ty in types {
2384 self.update_interface_dep_of_type(ty, &replacements);
2385 }
2386 }
2387 WorldItem::Function(_) => {}
2388 }
2389 }
2390
2391 fn semver_track(&self, id: InterfaceId) -> Option<((PackageName, String), &Version)> {
2402 let iface = &self.interfaces[id];
2403 let pkg = &self.packages[iface.package?];
2404 let version = pkg.name.version.as_ref()?;
2405 let mut name = pkg.name.clone();
2406 name.version = Some(PackageName::version_compat_track(version));
2407 Some(((name, iface.name.clone()?), version))
2408 }
2409
2410 fn update_interface_dep_of_type(
2414 &mut self,
2415 ty: TypeId,
2416 replacements: &HashMap<InterfaceId, InterfaceId>,
2417 ) {
2418 let to_replace = match self.type_interface_dep(ty) {
2419 Some(id) => id,
2420 None => return,
2421 };
2422 let replace_with = match replacements.get(&to_replace) {
2423 Some(id) => id,
2424 None => return,
2425 };
2426 let dep = match self.types[ty].kind {
2427 TypeDefKind::Type(Type::Id(id)) => id,
2428 _ => return,
2429 };
2430 let name = self.types[dep].name.as_ref().unwrap();
2431 let replacement_id = self.interfaces[*replace_with].types[name];
2434 self.types[ty].kind = TypeDefKind::Type(Type::Id(replacement_id));
2435 }
2436
2437 pub fn wasm_import_name(
2444 &self,
2445 mangling: ManglingAndAbi,
2446 import: WasmImport<'_>,
2447 ) -> (String, String) {
2448 match mangling {
2449 ManglingAndAbi::Standard32 => match import {
2450 WasmImport::Func { interface, func } => {
2451 let module = match interface {
2452 Some(key) => format!("cm32p2|{}", self.name_canonicalized_world_key(key)),
2453 None => format!("cm32p2"),
2454 };
2455 (module, func.name.clone())
2456 }
2457 WasmImport::ResourceIntrinsic {
2458 interface,
2459 resource,
2460 intrinsic,
2461 } => {
2462 let name = self.types[resource].name.as_ref().unwrap();
2463 let (prefix, name) = match intrinsic {
2464 ResourceIntrinsic::ImportedDrop => ("", format!("{name}_drop")),
2465 ResourceIntrinsic::ExportedDrop => ("_ex_", format!("{name}_drop")),
2466 ResourceIntrinsic::ExportedNew => ("_ex_", format!("{name}_new")),
2467 ResourceIntrinsic::ExportedRep => ("_ex_", format!("{name}_rep")),
2468 };
2469 let module = match interface {
2470 Some(key) => {
2471 format!("cm32p2|{prefix}{}", self.name_canonicalized_world_key(key))
2472 }
2473 None => {
2474 assert_eq!(prefix, "");
2475 format!("cm32p2")
2476 }
2477 };
2478 (module, name)
2479 }
2480 },
2481 ManglingAndAbi::Legacy(abi) => match import {
2482 WasmImport::Func { interface, func } => {
2483 let module = match interface {
2484 Some(key) => self.name_world_key(key),
2485 None => format!("$root"),
2486 };
2487 (module, format!("{}{}", abi.import_prefix(), func.name))
2488 }
2489 WasmImport::ResourceIntrinsic {
2490 interface,
2491 resource,
2492 intrinsic,
2493 } => {
2494 let name = self.types[resource].name.as_ref().unwrap();
2495 let (prefix, name) = match intrinsic {
2496 ResourceIntrinsic::ImportedDrop => ("", format!("[resource-drop]{name}")),
2497 ResourceIntrinsic::ExportedDrop => {
2498 ("[export]", format!("[resource-drop]{name}"))
2499 }
2500 ResourceIntrinsic::ExportedNew => {
2501 ("[export]", format!("[resource-new]{name}"))
2502 }
2503 ResourceIntrinsic::ExportedRep => {
2504 ("[export]", format!("[resource-rep]{name}"))
2505 }
2506 };
2507 let module = match interface {
2508 Some(key) => format!("{prefix}{}", self.name_world_key(key)),
2509 None => {
2510 assert_eq!(prefix, "");
2511 format!("$root")
2512 }
2513 };
2514 (module, format!("{}{name}", abi.import_prefix()))
2515 }
2516 },
2517 }
2518 }
2519
2520 pub fn wasm_export_name(&self, mangling: ManglingAndAbi, export: WasmExport<'_>) -> String {
2524 match mangling {
2525 ManglingAndAbi::Standard32 => match export {
2526 WasmExport::Func {
2527 interface,
2528 func,
2529 kind,
2530 } => {
2531 let mut name = String::from("cm32p2|");
2532 if let Some(interface) = interface {
2533 let s = self.name_canonicalized_world_key(interface);
2534 name.push_str(&s);
2535 }
2536 name.push_str("|");
2537 name.push_str(&func.name);
2538 match kind {
2539 WasmExportKind::Normal => {}
2540 WasmExportKind::PostReturn => name.push_str("_post"),
2541 WasmExportKind::Callback => todo!(
2542 "not yet supported: \
2543 async callback functions using standard name mangling"
2544 ),
2545 }
2546 name
2547 }
2548 WasmExport::ResourceDtor {
2549 interface,
2550 resource,
2551 } => {
2552 let name = self.types[resource].name.as_ref().unwrap();
2553 let interface = self.name_canonicalized_world_key(interface);
2554 format!("cm32p2|{interface}|{name}_dtor")
2555 }
2556 WasmExport::Memory => "cm32p2_memory".to_string(),
2557 WasmExport::Initialize => "cm32p2_initialize".to_string(),
2558 WasmExport::Realloc => "cm32p2_realloc".to_string(),
2559 },
2560 ManglingAndAbi::Legacy(abi) => match export {
2561 WasmExport::Func {
2562 interface,
2563 func,
2564 kind,
2565 } => {
2566 let mut name = abi.export_prefix().to_string();
2567 match kind {
2568 WasmExportKind::Normal => {}
2569 WasmExportKind::PostReturn => name.push_str("cabi_post_"),
2570 WasmExportKind::Callback => {
2571 assert!(matches!(abi, LiftLowerAbi::AsyncCallback));
2572 name = format!("[callback]{name}")
2573 }
2574 }
2575 if let Some(interface) = interface {
2576 let s = self.name_world_key(interface);
2577 name.push_str(&s);
2578 name.push_str("#");
2579 }
2580 name.push_str(&func.name);
2581 name
2582 }
2583 WasmExport::ResourceDtor {
2584 interface,
2585 resource,
2586 } => {
2587 let name = self.types[resource].name.as_ref().unwrap();
2588 let interface = self.name_world_key(interface);
2589 format!("{}{interface}#[dtor]{name}", abi.export_prefix())
2590 }
2591 WasmExport::Memory => "memory".to_string(),
2592 WasmExport::Initialize => "_initialize".to_string(),
2593 WasmExport::Realloc => "cabi_realloc".to_string(),
2594 },
2595 }
2596 }
2597}
2598
2599#[derive(Debug)]
2601pub enum WasmImport<'a> {
2602 Func {
2604 interface: Option<&'a WorldKey>,
2609
2610 func: &'a Function,
2612 },
2613
2614 ResourceIntrinsic {
2616 interface: Option<&'a WorldKey>,
2618
2619 resource: TypeId,
2621
2622 intrinsic: ResourceIntrinsic,
2624 },
2625}
2626
2627#[derive(Debug)]
2630pub enum ResourceIntrinsic {
2631 ImportedDrop,
2632 ExportedDrop,
2633 ExportedNew,
2634 ExportedRep,
2635}
2636
2637#[derive(Debug)]
2640pub enum WasmExportKind {
2641 Normal,
2643
2644 PostReturn,
2646
2647 Callback,
2649}
2650
2651#[derive(Debug)]
2654pub enum WasmExport<'a> {
2655 Func {
2657 interface: Option<&'a WorldKey>,
2660
2661 func: &'a Function,
2663
2664 kind: WasmExportKind,
2666 },
2667
2668 ResourceDtor {
2670 interface: &'a WorldKey,
2672 resource: TypeId,
2674 },
2675
2676 Memory,
2678
2679 Initialize,
2681
2682 Realloc,
2684}
2685
2686#[derive(Default)]
2689pub struct Remap {
2690 pub types: Vec<Option<TypeId>>,
2691 pub interfaces: Vec<Option<InterfaceId>>,
2692 pub worlds: Vec<Option<WorldId>>,
2693 pub packages: Vec<PackageId>,
2694
2695 own_handles: HashMap<TypeId, TypeId>,
2705
2706 type_has_borrow: Vec<Option<bool>>,
2707}
2708
2709fn apply_map<T>(map: &[Option<Id<T>>], id: Id<T>, desc: &str, span: Option<Span>) -> Result<Id<T>> {
2710 match map.get(id.index()) {
2711 Some(Some(id)) => Ok(*id),
2712 Some(None) => {
2713 let msg = format!(
2714 "found a reference to a {desc} which is excluded \
2715 due to its feature not being activated"
2716 );
2717 match span {
2718 Some(span) => Err(Error::new(span, msg).into()),
2719 None => bail!("{msg}"),
2720 }
2721 }
2722 None => panic!("request to remap a {desc} that has not yet been registered"),
2723 }
2724}
2725
2726impl Remap {
2727 pub fn map_type(&self, id: TypeId, span: Option<Span>) -> Result<TypeId> {
2728 apply_map(&self.types, id, "type", span)
2729 }
2730
2731 pub fn map_interface(&self, id: InterfaceId, span: Option<Span>) -> Result<InterfaceId> {
2732 apply_map(&self.interfaces, id, "interface", span)
2733 }
2734
2735 pub fn map_world(&self, id: WorldId, span: Option<Span>) -> Result<WorldId> {
2736 apply_map(&self.worlds, id, "world", span)
2737 }
2738
2739 fn append(
2740 &mut self,
2741 resolve: &mut Resolve,
2742 unresolved: UnresolvedPackage,
2743 ) -> Result<PackageId> {
2744 let pkgid = resolve.packages.alloc(Package {
2745 name: unresolved.name.clone(),
2746 docs: unresolved.docs.clone(),
2747 interfaces: Default::default(),
2748 worlds: Default::default(),
2749 });
2750 let prev = resolve.package_names.insert(unresolved.name.clone(), pkgid);
2751 if let Some(prev) = prev {
2752 resolve.package_names.insert(unresolved.name.clone(), prev);
2753 bail!(
2754 "attempting to re-add package `{}` when it's already present in this `Resolve`",
2755 unresolved.name,
2756 );
2757 }
2758
2759 self.process_foreign_deps(resolve, pkgid, &unresolved)?;
2760
2761 let foreign_types = self.types.len();
2762 let foreign_interfaces = self.interfaces.len();
2763 let foreign_worlds = self.worlds.len();
2764
2765 assert_eq!(unresolved.types.len(), unresolved.type_spans.len());
2771 for ((id, mut ty), span) in unresolved
2772 .types
2773 .into_iter()
2774 .zip(&unresolved.type_spans)
2775 .skip(foreign_types)
2776 {
2777 if !resolve.include_type(&ty, pkgid, *span)? {
2778 self.types.push(None);
2779 continue;
2780 }
2781
2782 self.update_typedef(resolve, &mut ty, Some(*span))?;
2783 let new_id = resolve.types.alloc(ty);
2784 assert_eq!(self.types.len(), id.index());
2785
2786 let new_id = match resolve.types[new_id] {
2787 TypeDef {
2792 name: None,
2793 owner: TypeOwner::None,
2794 kind: TypeDefKind::Handle(Handle::Own(id)),
2795 docs: _,
2796 stability: _,
2797 } => *self.own_handles.entry(id).or_insert(new_id),
2798
2799 _ => new_id,
2802 };
2803 self.types.push(Some(new_id));
2804 }
2805
2806 assert_eq!(
2809 unresolved.interfaces.len(),
2810 unresolved.interface_spans.len()
2811 );
2812 for ((id, mut iface), span) in unresolved
2813 .interfaces
2814 .into_iter()
2815 .zip(&unresolved.interface_spans)
2816 .skip(foreign_interfaces)
2817 {
2818 if !resolve
2819 .include_stability(&iface.stability, &pkgid, Some(span.span))
2820 .with_context(|| {
2821 format!(
2822 "failed to process feature gate for interface [{}] in package [{}]",
2823 iface
2824 .name
2825 .as_ref()
2826 .map(String::as_str)
2827 .unwrap_or("<unknown>"),
2828 resolve.packages[pkgid].name,
2829 )
2830 })?
2831 {
2832 self.interfaces.push(None);
2833 continue;
2834 }
2835 assert!(iface.package.is_none());
2836 iface.package = Some(pkgid);
2837 self.update_interface(resolve, &mut iface, Some(span))?;
2838 let new_id = resolve.interfaces.alloc(iface);
2839 assert_eq!(self.interfaces.len(), id.index());
2840 self.interfaces.push(Some(new_id));
2841 }
2842
2843 for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2846 let id = match id {
2847 Some(id) => *id,
2848 None => continue,
2849 };
2850 match &mut resolve.types[id].owner {
2851 TypeOwner::Interface(id) => {
2852 let span = unresolved.type_spans[i];
2853 *id = self.map_interface(*id, Some(span))
2854 .with_context(|| {
2855 "this type is not gated by a feature but its interface is gated by a feature"
2856 })?;
2857 }
2858 TypeOwner::World(_) | TypeOwner::None => {}
2859 }
2860 }
2861
2862 assert_eq!(unresolved.worlds.len(), unresolved.world_spans.len());
2870 for ((id, mut world), span) in unresolved
2871 .worlds
2872 .into_iter()
2873 .zip(&unresolved.world_spans)
2874 .skip(foreign_worlds)
2875 {
2876 if !resolve
2877 .include_stability(&world.stability, &pkgid, Some(span.span))
2878 .with_context(|| {
2879 format!(
2880 "failed to process feature gate for world [{}] in package [{}]",
2881 world.name, resolve.packages[pkgid].name,
2882 )
2883 })?
2884 {
2885 self.worlds.push(None);
2886 continue;
2887 }
2888 self.update_world(&mut world, resolve, &pkgid, &span)?;
2889
2890 let new_id = resolve.worlds.alloc(world);
2891 assert_eq!(self.worlds.len(), id.index());
2892 self.worlds.push(Some(new_id));
2893
2894 resolve.elaborate_world(new_id).with_context(|| {
2895 Error::new(
2896 span.span,
2897 format!(
2898 "failed to elaborate world imports/exports of `{}`",
2899 resolve.worlds[new_id].name
2900 ),
2901 )
2902 })?;
2903 }
2904
2905 for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2907 let id = match id {
2908 Some(id) => *id,
2909 None => continue,
2910 };
2911 match &mut resolve.types[id].owner {
2912 TypeOwner::World(id) => {
2913 let span = unresolved.type_spans[i];
2914 *id = self.map_world(*id, Some(span))
2915 .with_context(|| {
2916 "this type is not gated by a feature but its interface is gated by a feature"
2917 })?;
2918 }
2919 TypeOwner::Interface(_) | TypeOwner::None => {}
2920 }
2921 }
2922
2923 for id in self.interfaces.iter().skip(foreign_interfaces) {
2925 let id = match id {
2926 Some(id) => *id,
2927 None => continue,
2928 };
2929 let iface = &mut resolve.interfaces[id];
2930 iface.package = Some(pkgid);
2931 if let Some(name) = &iface.name {
2932 let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), id);
2933 assert!(prev.is_none());
2934 }
2935 }
2936 for id in self.worlds.iter().skip(foreign_worlds) {
2937 let id = match id {
2938 Some(id) => *id,
2939 None => continue,
2940 };
2941 let world = &mut resolve.worlds[id];
2942 world.package = Some(pkgid);
2943 let prev = resolve.packages[pkgid]
2944 .worlds
2945 .insert(world.name.clone(), id);
2946 assert!(prev.is_none());
2947 }
2948 Ok(pkgid)
2949 }
2950
2951 fn process_foreign_deps(
2952 &mut self,
2953 resolve: &mut Resolve,
2954 pkgid: PackageId,
2955 unresolved: &UnresolvedPackage,
2956 ) -> Result<()> {
2957 let mut world_to_package = HashMap::new();
2960 let mut interface_to_package = HashMap::new();
2961 for (i, (pkg_name, worlds_or_ifaces)) in unresolved.foreign_deps.iter().enumerate() {
2962 for (name, item) in worlds_or_ifaces {
2963 match item {
2964 AstItem::Interface(unresolved_interface_id) => {
2965 let prev = interface_to_package.insert(
2966 *unresolved_interface_id,
2967 (pkg_name, name, unresolved.foreign_dep_spans[i]),
2968 );
2969 assert!(prev.is_none());
2970 }
2971 AstItem::World(unresolved_world_id) => {
2972 let prev = world_to_package.insert(
2973 *unresolved_world_id,
2974 (pkg_name, name, unresolved.foreign_dep_spans[i]),
2975 );
2976 assert!(prev.is_none());
2977 }
2978 }
2979 }
2980 }
2981
2982 self.process_foreign_interfaces(unresolved, &interface_to_package, resolve)?;
2986
2987 self.process_foreign_worlds(unresolved, &world_to_package, resolve)?;
2991
2992 self.process_foreign_types(unresolved, pkgid, resolve)?;
2995
2996 for (id, span) in unresolved.required_resource_types.iter() {
2997 let Ok(mut id) = self.map_type(*id, Some(*span)) else {
3002 continue;
3003 };
3004 loop {
3005 match resolve.types[id].kind {
3006 TypeDefKind::Type(Type::Id(i)) => id = i,
3007 TypeDefKind::Resource => break,
3008 _ => bail!(Error::new(
3009 *span,
3010 format!("type used in a handle must be a resource"),
3011 )),
3012 }
3013 }
3014 }
3015
3016 #[cfg(debug_assertions)]
3017 resolve.assert_valid();
3018
3019 Ok(())
3020 }
3021
3022 fn process_foreign_interfaces(
3023 &mut self,
3024 unresolved: &UnresolvedPackage,
3025 interface_to_package: &HashMap<InterfaceId, (&PackageName, &String, Span)>,
3026 resolve: &mut Resolve,
3027 ) -> Result<(), anyhow::Error> {
3028 for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() {
3029 let (pkg_name, interface, span) = match interface_to_package.get(&unresolved_iface_id) {
3030 Some(items) => *items,
3031 None => break,
3035 };
3036 let pkgid = resolve
3037 .package_names
3038 .get(pkg_name)
3039 .copied()
3040 .ok_or_else(|| {
3041 PackageNotFoundError::new(
3042 span,
3043 pkg_name.clone(),
3044 resolve.package_names.keys().cloned().collect(),
3045 )
3046 })?;
3047
3048 assert!(unresolved_iface.functions.is_empty());
3050
3051 let pkg = &resolve.packages[pkgid];
3052 let span = &unresolved.interface_spans[unresolved_iface_id.index()];
3053 let iface_id = pkg
3054 .interfaces
3055 .get(interface)
3056 .copied()
3057 .ok_or_else(|| Error::new(span.span, "interface not found in package"))?;
3058 assert_eq!(self.interfaces.len(), unresolved_iface_id.index());
3059 self.interfaces.push(Some(iface_id));
3060 }
3061 for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) {
3062 assert!(
3063 interface_to_package.get(&id).is_none(),
3064 "found foreign interface after local interface"
3065 );
3066 }
3067 Ok(())
3068 }
3069
3070 fn process_foreign_worlds(
3071 &mut self,
3072 unresolved: &UnresolvedPackage,
3073 world_to_package: &HashMap<WorldId, (&PackageName, &String, Span)>,
3074 resolve: &mut Resolve,
3075 ) -> Result<(), anyhow::Error> {
3076 for (unresolved_world_id, _) in unresolved.worlds.iter() {
3077 let (pkg_name, world, span) = match world_to_package.get(&unresolved_world_id) {
3078 Some(items) => *items,
3079 None => break,
3082 };
3083
3084 let pkgid = resolve
3085 .package_names
3086 .get(pkg_name)
3087 .copied()
3088 .ok_or_else(|| Error::new(span, "package not found"))?;
3089 let pkg = &resolve.packages[pkgid];
3090 let span = &unresolved.world_spans[unresolved_world_id.index()];
3091 let world_id = pkg
3092 .worlds
3093 .get(world)
3094 .copied()
3095 .ok_or_else(|| Error::new(span.span, "world not found in package"))?;
3096 assert_eq!(self.worlds.len(), unresolved_world_id.index());
3097 self.worlds.push(Some(world_id));
3098 }
3099 for (id, _) in unresolved.worlds.iter().skip(self.worlds.len()) {
3100 assert!(
3101 world_to_package.get(&id).is_none(),
3102 "found foreign world after local world"
3103 );
3104 }
3105 Ok(())
3106 }
3107
3108 fn process_foreign_types(
3109 &mut self,
3110 unresolved: &UnresolvedPackage,
3111 pkgid: PackageId,
3112 resolve: &mut Resolve,
3113 ) -> Result<(), anyhow::Error> {
3114 for ((unresolved_type_id, unresolved_ty), span) in
3115 unresolved.types.iter().zip(&unresolved.type_spans)
3116 {
3117 match unresolved_ty.kind {
3121 TypeDefKind::Unknown => {}
3122 _ => break,
3123 }
3124
3125 if !resolve.include_type(unresolved_ty, pkgid, *span)? {
3126 self.types.push(None);
3127 continue;
3128 }
3129
3130 let unresolved_iface_id = match unresolved_ty.owner {
3131 TypeOwner::Interface(id) => id,
3132 _ => unreachable!(),
3133 };
3134 let iface_id = self.map_interface(unresolved_iface_id, None)?;
3135 let name = unresolved_ty.name.as_ref().unwrap();
3136 let span = unresolved.unknown_type_spans[unresolved_type_id.index()];
3137 let type_id = *resolve.interfaces[iface_id]
3138 .types
3139 .get(name)
3140 .ok_or_else(|| {
3141 Error::new(span, format!("type `{name}` not defined in interface"))
3142 })?;
3143 assert_eq!(self.types.len(), unresolved_type_id.index());
3144 self.types.push(Some(type_id));
3145 }
3146 for (_, ty) in unresolved.types.iter().skip(self.types.len()) {
3147 if let TypeDefKind::Unknown = ty.kind {
3148 panic!("unknown type after defined type");
3149 }
3150 }
3151 Ok(())
3152 }
3153
3154 fn update_typedef(
3155 &mut self,
3156 resolve: &mut Resolve,
3157 ty: &mut TypeDef,
3158 span: Option<Span>,
3159 ) -> Result<()> {
3160 use crate::TypeDefKind::*;
3163 match &mut ty.kind {
3164 Handle(handle) => match handle {
3165 crate::Handle::Own(ty) | crate::Handle::Borrow(ty) => {
3166 self.update_type_id(ty, span)?
3167 }
3168 },
3169 Resource => {}
3170 Record(r) => {
3171 for field in r.fields.iter_mut() {
3172 self.update_ty(resolve, &mut field.ty, span)
3173 .with_context(|| format!("failed to update field `{}`", field.name))?;
3174 }
3175 }
3176 Tuple(t) => {
3177 for ty in t.types.iter_mut() {
3178 self.update_ty(resolve, ty, span)?;
3179 }
3180 }
3181 Variant(v) => {
3182 for case in v.cases.iter_mut() {
3183 if let Some(t) = &mut case.ty {
3184 self.update_ty(resolve, t, span)?;
3185 }
3186 }
3187 }
3188 Option(t) | List(t, ..) | FixedSizeList(t, ..) | Future(Some(t)) | Stream(Some(t)) => {
3189 self.update_ty(resolve, t, span)?
3190 }
3191 Result(r) => {
3192 if let Some(ty) = &mut r.ok {
3193 self.update_ty(resolve, ty, span)?;
3194 }
3195 if let Some(ty) = &mut r.err {
3196 self.update_ty(resolve, ty, span)?;
3197 }
3198 }
3199
3200 Type(crate::Type::Id(id)) => self.update_type_id(id, span)?,
3205 Type(_) => {}
3206
3207 Flags(_) | Enum(_) | Future(None) | Stream(None) => {}
3209
3210 Unknown => unreachable!(),
3211 }
3212
3213 Ok(())
3214 }
3215
3216 fn update_ty(
3217 &mut self,
3218 resolve: &mut Resolve,
3219 ty: &mut Type,
3220 span: Option<Span>,
3221 ) -> Result<()> {
3222 let id = match ty {
3223 Type::Id(id) => id,
3224 _ => return Ok(()),
3225 };
3226 self.update_type_id(id, span)?;
3227
3228 let mut cur = *id;
3233 let points_to_resource = loop {
3234 match resolve.types[cur].kind {
3235 TypeDefKind::Type(Type::Id(id)) => cur = id,
3236 TypeDefKind::Resource => break true,
3237 _ => break false,
3238 }
3239 };
3240
3241 if points_to_resource {
3242 *id = *self.own_handles.entry(*id).or_insert_with(|| {
3243 resolve.types.alloc(TypeDef {
3244 name: None,
3245 owner: TypeOwner::None,
3246 kind: TypeDefKind::Handle(Handle::Own(*id)),
3247 docs: Default::default(),
3248 stability: Default::default(),
3249 })
3250 });
3251 }
3252 Ok(())
3253 }
3254
3255 fn update_type_id(&self, id: &mut TypeId, span: Option<Span>) -> Result<()> {
3256 *id = self.map_type(*id, span)?;
3257 Ok(())
3258 }
3259
3260 fn update_interface(
3261 &mut self,
3262 resolve: &mut Resolve,
3263 iface: &mut Interface,
3264 spans: Option<&InterfaceSpan>,
3265 ) -> Result<()> {
3266 iface.types.retain(|_, ty| self.types[ty.index()].is_some());
3267 let iface_pkg_id = iface.package.as_ref().unwrap_or_else(|| {
3268 panic!(
3269 "unexpectedly missing package on interface [{}]",
3270 iface
3271 .name
3272 .as_ref()
3273 .map(String::as_str)
3274 .unwrap_or("<unknown>"),
3275 )
3276 });
3277
3278 for (_name, ty) in iface.types.iter_mut() {
3281 self.update_type_id(ty, spans.map(|s| s.span))?;
3282 }
3283 if let Some(spans) = spans {
3284 assert_eq!(iface.functions.len(), spans.funcs.len());
3285 }
3286 for (i, (func_name, func)) in iface.functions.iter_mut().enumerate() {
3287 let span = spans.map(|s| s.funcs[i]);
3288 if !resolve
3289 .include_stability(&func.stability, iface_pkg_id, span)
3290 .with_context(|| {
3291 format!(
3292 "failed to process feature gate for function [{func_name}] in package [{}]",
3293 resolve.packages[*iface_pkg_id].name,
3294 )
3295 })?
3296 {
3297 continue;
3298 }
3299 self.update_function(resolve, func, span)
3300 .with_context(|| format!("failed to update function `{}`", func.name))?;
3301 }
3302
3303 for (name, func) in mem::take(&mut iface.functions) {
3306 if resolve.include_stability(&func.stability, iface_pkg_id, None)? {
3307 iface.functions.insert(name, func);
3308 }
3309 }
3310
3311 Ok(())
3312 }
3313
3314 fn update_function(
3315 &mut self,
3316 resolve: &mut Resolve,
3317 func: &mut Function,
3318 span: Option<Span>,
3319 ) -> Result<()> {
3320 if let Some(id) = func.kind.resource_mut() {
3321 self.update_type_id(id, span)?;
3322 }
3323 for (_, ty) in func.params.iter_mut() {
3324 self.update_ty(resolve, ty, span)?;
3325 }
3326 if let Some(ty) = &mut func.result {
3327 self.update_ty(resolve, ty, span)?;
3328 }
3329
3330 if let Some(ty) = &func.result {
3331 if self.type_has_borrow(resolve, ty) {
3332 match span {
3333 Some(span) => {
3334 bail!(Error::new(
3335 span,
3336 format!(
3337 "function returns a type which contains \
3338 a `borrow<T>` which is not supported"
3339 )
3340 ))
3341 }
3342 None => unreachable!(),
3343 }
3344 }
3345 }
3346
3347 Ok(())
3348 }
3349
3350 fn update_world(
3351 &mut self,
3352 world: &mut World,
3353 resolve: &mut Resolve,
3354 pkg_id: &PackageId,
3355 spans: &WorldSpan,
3356 ) -> Result<()> {
3357 assert_eq!(world.imports.len(), spans.imports.len());
3358 assert_eq!(world.exports.len(), spans.exports.len());
3359
3360 let imports = mem::take(&mut world.imports).into_iter();
3364 let imports = imports.zip(&spans.imports).map(|p| (p, true));
3365 let exports = mem::take(&mut world.exports).into_iter();
3366 let exports = exports.zip(&spans.exports).map(|p| (p, false));
3367 for (((mut name, mut item), span), import) in imports.chain(exports) {
3368 if let WorldItem::Type(id) = &mut item {
3371 *id = self.map_type(*id, Some(*span))?;
3372 }
3373 let stability = item.stability(resolve);
3374 if !resolve
3375 .include_stability(stability, pkg_id, Some(*span))
3376 .with_context(|| format!("failed to process world item in `{}`", world.name))?
3377 {
3378 continue;
3379 }
3380 self.update_world_key(&mut name, Some(*span))?;
3381 match &mut item {
3382 WorldItem::Interface { id, .. } => {
3383 *id = self.map_interface(*id, Some(*span))?;
3384 }
3385 WorldItem::Function(f) => {
3386 self.update_function(resolve, f, Some(*span))?;
3387 }
3388 WorldItem::Type(_) => {
3389 }
3391 }
3392
3393 let dst = if import {
3394 &mut world.imports
3395 } else {
3396 &mut world.exports
3397 };
3398 let prev = dst.insert(name, item);
3399 assert!(prev.is_none());
3400 }
3401
3402 assert_eq!(world.includes.len(), spans.includes.len());
3405 let includes = mem::take(&mut world.includes);
3406 let include_names = mem::take(&mut world.include_names);
3407 for (((stability, include_world), span), names) in includes
3408 .into_iter()
3409 .zip(&spans.includes)
3410 .zip(&include_names)
3411 {
3412 if !resolve
3413 .include_stability(&stability, pkg_id, Some(*span))
3414 .with_context(|| {
3415 format!(
3416 "failed to process feature gate for included world [{}] in package [{}]",
3417 resolve.worlds[include_world].name.as_str(),
3418 resolve.packages[*pkg_id].name
3419 )
3420 })?
3421 {
3422 continue;
3423 }
3424 self.resolve_include(world, include_world, names, *span, resolve)?;
3425 }
3426
3427 Ok(())
3428 }
3429
3430 fn update_world_key(&self, key: &mut WorldKey, span: Option<Span>) -> Result<()> {
3431 match key {
3432 WorldKey::Name(_) => {}
3433 WorldKey::Interface(id) => {
3434 *id = self.map_interface(*id, span)?;
3435 }
3436 }
3437 Ok(())
3438 }
3439
3440 fn resolve_include(
3441 &self,
3442 world: &mut World,
3443 include_world: WorldId,
3444 names: &[IncludeName],
3445 span: Span,
3446 resolve: &Resolve,
3447 ) -> Result<()> {
3448 let include_world_id = self.map_world(include_world, Some(span))?;
3449 let include_world = &resolve.worlds[include_world_id];
3450 let mut names_ = names.to_owned();
3451 let is_external_include = world.package != include_world.package;
3452
3453 for import in include_world.imports.iter() {
3455 self.remove_matching_name(import, &mut names_);
3456 }
3457 for export in include_world.exports.iter() {
3458 self.remove_matching_name(export, &mut names_);
3459 }
3460 if !names_.is_empty() {
3461 bail!(Error::new(
3462 span,
3463 format!("no import or export kebab-name `{}`. Note that an ID does not support renaming", names_[0].name),
3464 ));
3465 }
3466
3467 for import in include_world.imports.iter() {
3469 self.resolve_include_item(
3470 names,
3471 &mut world.imports,
3472 import,
3473 span,
3474 "import",
3475 is_external_include,
3476 )?;
3477 }
3478
3479 for export in include_world.exports.iter() {
3480 self.resolve_include_item(
3481 names,
3482 &mut world.exports,
3483 export,
3484 span,
3485 "export",
3486 is_external_include,
3487 )?;
3488 }
3489 Ok(())
3490 }
3491
3492 fn resolve_include_item(
3493 &self,
3494 names: &[IncludeName],
3495 items: &mut IndexMap<WorldKey, WorldItem>,
3496 item: (&WorldKey, &WorldItem),
3497 span: Span,
3498 item_type: &str,
3499 is_external_include: bool,
3500 ) -> Result<()> {
3501 match item.0 {
3502 WorldKey::Name(n) => {
3503 let n = if let Some(found) = names
3504 .into_iter()
3505 .find(|include_name| include_name.name == n.clone())
3506 {
3507 found.as_.clone()
3508 } else {
3509 n.clone()
3510 };
3511
3512 let prev = items.insert(WorldKey::Name(n.clone()), item.1.clone());
3513 if prev.is_some() {
3514 bail!(Error::new(
3515 span,
3516 format!("{item_type} of `{n}` shadows previously {item_type}ed items"),
3517 ))
3518 }
3519 }
3520 key @ WorldKey::Interface(_) => {
3521 let prev = items.entry(key.clone()).or_insert(item.1.clone());
3522 match (&item.1, prev) {
3523 (
3524 WorldItem::Interface {
3525 id: aid,
3526 stability: astability,
3527 },
3528 WorldItem::Interface {
3529 id: bid,
3530 stability: bstability,
3531 },
3532 ) => {
3533 assert_eq!(*aid, *bid);
3534 merge_include_stability(astability, bstability, is_external_include)?;
3535 }
3536 (WorldItem::Interface { .. }, _) => unreachable!(),
3537 (WorldItem::Function(_), _) => unreachable!(),
3538 (WorldItem::Type(_), _) => unreachable!(),
3539 }
3540 }
3541 };
3542 Ok(())
3543 }
3544
3545 fn remove_matching_name(&self, item: (&WorldKey, &WorldItem), names: &mut Vec<IncludeName>) {
3546 match item.0 {
3547 WorldKey::Name(n) => {
3548 names.retain(|name| name.name != n.clone());
3549 }
3550 _ => {}
3551 }
3552 }
3553
3554 fn type_has_borrow(&mut self, resolve: &Resolve, ty: &Type) -> bool {
3555 let id = match ty {
3556 Type::Id(id) => *id,
3557 _ => return false,
3558 };
3559
3560 if let Some(Some(has_borrow)) = self.type_has_borrow.get(id.index()) {
3561 return *has_borrow;
3562 }
3563
3564 let result = self.typedef_has_borrow(resolve, &resolve.types[id]);
3565 if self.type_has_borrow.len() <= id.index() {
3566 self.type_has_borrow.resize(id.index() + 1, None);
3567 }
3568 self.type_has_borrow[id.index()] = Some(result);
3569 result
3570 }
3571
3572 fn typedef_has_borrow(&mut self, resolve: &Resolve, ty: &TypeDef) -> bool {
3573 match &ty.kind {
3574 TypeDefKind::Type(t) => self.type_has_borrow(resolve, t),
3575 TypeDefKind::Variant(v) => v
3576 .cases
3577 .iter()
3578 .filter_map(|case| case.ty.as_ref())
3579 .any(|ty| self.type_has_borrow(resolve, ty)),
3580 TypeDefKind::Handle(Handle::Borrow(_)) => true,
3581 TypeDefKind::Handle(Handle::Own(_)) => false,
3582 TypeDefKind::Resource => false,
3583 TypeDefKind::Record(r) => r
3584 .fields
3585 .iter()
3586 .any(|case| self.type_has_borrow(resolve, &case.ty)),
3587 TypeDefKind::Flags(_) => false,
3588 TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.type_has_borrow(resolve, t)),
3589 TypeDefKind::Enum(_) => false,
3590 TypeDefKind::List(ty)
3591 | TypeDefKind::FixedSizeList(ty, ..)
3592 | TypeDefKind::Future(Some(ty))
3593 | TypeDefKind::Stream(Some(ty))
3594 | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty),
3595 TypeDefKind::Result(r) => [&r.ok, &r.err]
3596 .iter()
3597 .filter_map(|t| t.as_ref())
3598 .any(|t| self.type_has_borrow(resolve, t)),
3599 TypeDefKind::Future(None) | TypeDefKind::Stream(None) => false,
3600 TypeDefKind::Unknown => unreachable!(),
3601 }
3602 }
3603}
3604
3605struct MergeMap<'a> {
3606 package_map: HashMap<PackageId, PackageId>,
3609
3610 interface_map: HashMap<InterfaceId, InterfaceId>,
3613
3614 type_map: HashMap<TypeId, TypeId>,
3617
3618 world_map: HashMap<WorldId, WorldId>,
3621
3622 interfaces_to_add: Vec<(String, PackageId, InterfaceId)>,
3630 worlds_to_add: Vec<(String, PackageId, WorldId)>,
3631
3632 from: &'a Resolve,
3634
3635 into: &'a Resolve,
3637}
3638
3639impl<'a> MergeMap<'a> {
3640 fn new(from: &'a Resolve, into: &'a Resolve) -> MergeMap<'a> {
3641 MergeMap {
3642 package_map: Default::default(),
3643 interface_map: Default::default(),
3644 type_map: Default::default(),
3645 world_map: Default::default(),
3646 interfaces_to_add: Default::default(),
3647 worlds_to_add: Default::default(),
3648 from,
3649 into,
3650 }
3651 }
3652
3653 fn build(&mut self) -> Result<()> {
3654 for from_id in self.from.topological_packages() {
3655 let from = &self.from.packages[from_id];
3656 let into_id = match self.into.package_names.get(&from.name) {
3657 Some(id) => *id,
3658
3659 None => {
3662 log::trace!("adding unique package {}", from.name);
3663 continue;
3664 }
3665 };
3666 log::trace!("merging duplicate package {}", from.name);
3667
3668 self.build_package(from_id, into_id).with_context(|| {
3669 format!("failed to merge package `{}` into existing copy", from.name)
3670 })?;
3671 }
3672
3673 Ok(())
3674 }
3675
3676 fn build_package(&mut self, from_id: PackageId, into_id: PackageId) -> Result<()> {
3677 let prev = self.package_map.insert(from_id, into_id);
3678 assert!(prev.is_none());
3679
3680 let from = &self.from.packages[from_id];
3681 let into = &self.into.packages[into_id];
3682
3683 for (name, from_interface_id) in from.interfaces.iter() {
3687 let into_interface_id = match into.interfaces.get(name) {
3688 Some(id) => *id,
3689 None => {
3690 log::trace!("adding unique interface {}", name);
3691 self.interfaces_to_add
3692 .push((name.clone(), into_id, *from_interface_id));
3693 continue;
3694 }
3695 };
3696
3697 log::trace!("merging duplicate interfaces {}", name);
3698 self.build_interface(*from_interface_id, into_interface_id)
3699 .with_context(|| format!("failed to merge interface `{name}`"))?;
3700 }
3701
3702 for (name, from_world_id) in from.worlds.iter() {
3703 let into_world_id = match into.worlds.get(name) {
3704 Some(id) => *id,
3705 None => {
3706 log::trace!("adding unique world {}", name);
3707 self.worlds_to_add
3708 .push((name.clone(), into_id, *from_world_id));
3709 continue;
3710 }
3711 };
3712
3713 log::trace!("merging duplicate worlds {}", name);
3714 self.build_world(*from_world_id, into_world_id)
3715 .with_context(|| format!("failed to merge world `{name}`"))?;
3716 }
3717
3718 Ok(())
3719 }
3720
3721 fn build_interface(&mut self, from_id: InterfaceId, into_id: InterfaceId) -> Result<()> {
3722 let prev = self.interface_map.insert(from_id, into_id);
3723 assert!(prev.is_none());
3724
3725 let from_interface = &self.from.interfaces[from_id];
3726 let into_interface = &self.into.interfaces[into_id];
3727
3728 for (name, from_type_id) in from_interface.types.iter() {
3742 let into_type_id = *into_interface
3743 .types
3744 .get(name)
3745 .ok_or_else(|| anyhow!("expected type `{name}` to be present"))?;
3746 let prev = self.type_map.insert(*from_type_id, into_type_id);
3747 assert!(prev.is_none());
3748
3749 self.build_type_id(*from_type_id, into_type_id)
3750 .with_context(|| format!("mismatch in type `{name}`"))?;
3751 }
3752
3753 for (name, from_func) in from_interface.functions.iter() {
3754 let into_func = match into_interface.functions.get(name) {
3755 Some(func) => func,
3756 None => bail!("expected function `{name}` to be present"),
3757 };
3758 self.build_function(from_func, into_func)
3759 .with_context(|| format!("mismatch in function `{name}`"))?;
3760 }
3761
3762 Ok(())
3763 }
3764
3765 fn build_type_id(&mut self, from_id: TypeId, into_id: TypeId) -> Result<()> {
3766 let _ = from_id;
3770 let _ = into_id;
3771 Ok(())
3772 }
3773
3774 fn build_type(&mut self, from_ty: &Type, into_ty: &Type) -> Result<()> {
3775 match (from_ty, into_ty) {
3776 (Type::Id(from), Type::Id(into)) => {
3777 self.build_type_id(*from, *into)?;
3778 }
3779 (from, into) if from != into => bail!("different kinds of types"),
3780 _ => {}
3781 }
3782 Ok(())
3783 }
3784
3785 fn build_function(&mut self, from_func: &Function, into_func: &Function) -> Result<()> {
3786 if from_func.name != into_func.name {
3787 bail!(
3788 "different function names `{}` and `{}`",
3789 from_func.name,
3790 into_func.name
3791 );
3792 }
3793 match (&from_func.kind, &into_func.kind) {
3794 (FunctionKind::Freestanding, FunctionKind::Freestanding) => {}
3795 (FunctionKind::AsyncFreestanding, FunctionKind::AsyncFreestanding) => {}
3796
3797 (FunctionKind::Method(from), FunctionKind::Method(into))
3798 | (FunctionKind::Static(from), FunctionKind::Static(into))
3799 | (FunctionKind::AsyncMethod(from), FunctionKind::AsyncMethod(into))
3800 | (FunctionKind::AsyncStatic(from), FunctionKind::AsyncStatic(into))
3801 | (FunctionKind::Constructor(from), FunctionKind::Constructor(into)) => {
3802 self.build_type_id(*from, *into)
3803 .context("different function kind types")?;
3804 }
3805
3806 (FunctionKind::Method(_), _)
3807 | (FunctionKind::Constructor(_), _)
3808 | (FunctionKind::Static(_), _)
3809 | (FunctionKind::Freestanding, _)
3810 | (FunctionKind::AsyncFreestanding, _)
3811 | (FunctionKind::AsyncMethod(_), _)
3812 | (FunctionKind::AsyncStatic(_), _) => {
3813 bail!("different function kind types")
3814 }
3815 }
3816
3817 if from_func.params.len() != into_func.params.len() {
3818 bail!("different number of function parameters");
3819 }
3820 for ((from_name, from_ty), (into_name, into_ty)) in
3821 from_func.params.iter().zip(&into_func.params)
3822 {
3823 if from_name != into_name {
3824 bail!("different function parameter names: {from_name} != {into_name}");
3825 }
3826 self.build_type(from_ty, into_ty)
3827 .with_context(|| format!("different function parameter types for `{from_name}`"))?;
3828 }
3829 match (&from_func.result, &into_func.result) {
3830 (Some(from_ty), Some(into_ty)) => {
3831 self.build_type(from_ty, into_ty)
3832 .context("different function result types")?;
3833 }
3834 (None, None) => {}
3835 (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
3836 }
3837 Ok(())
3838 }
3839
3840 fn build_world(&mut self, from_id: WorldId, into_id: WorldId) -> Result<()> {
3841 let prev = self.world_map.insert(from_id, into_id);
3842 assert!(prev.is_none());
3843
3844 let from_world = &self.from.worlds[from_id];
3845 let into_world = &self.into.worlds[into_id];
3846
3847 if from_world.imports.len() != into_world.imports.len() {
3856 bail!("world contains different number of imports than expected");
3857 }
3858 if from_world.exports.len() != into_world.exports.len() {
3859 bail!("world contains different number of exports than expected");
3860 }
3861
3862 for (from_name, from) in from_world.imports.iter() {
3863 let into_name = MergeMap::map_name(from_name, &self.interface_map);
3864 let name_str = self.from.name_world_key(from_name);
3865 let into = into_world
3866 .imports
3867 .get(&into_name)
3868 .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?;
3869 self.match_world_item(from, into)
3870 .with_context(|| format!("import `{name_str}` didn't match target world"))?;
3871 }
3872
3873 for (from_name, from) in from_world.exports.iter() {
3874 let into_name = MergeMap::map_name(from_name, &self.interface_map);
3875 let name_str = self.from.name_world_key(from_name);
3876 let into = into_world
3877 .exports
3878 .get(&into_name)
3879 .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?;
3880 self.match_world_item(from, into)
3881 .with_context(|| format!("export `{name_str}` didn't match target world"))?;
3882 }
3883
3884 Ok(())
3885 }
3886
3887 fn map_name(
3888 from_name: &WorldKey,
3889 interface_map: &HashMap<InterfaceId, InterfaceId>,
3890 ) -> WorldKey {
3891 match from_name {
3892 WorldKey::Name(s) => WorldKey::Name(s.clone()),
3893 WorldKey::Interface(id) => {
3894 WorldKey::Interface(interface_map.get(id).copied().unwrap_or(*id))
3895 }
3896 }
3897 }
3898
3899 fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> Result<()> {
3900 match (from, into) {
3901 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
3902 match (
3903 &self.from.interfaces[*from].name,
3904 &self.into.interfaces[*into].name,
3905 ) {
3906 (None, None) => self.build_interface(*from, *into)?,
3910
3911 _ => {
3916 if self.interface_map.get(&from) != Some(&into) {
3917 bail!("interfaces are not the same");
3918 }
3919 }
3920 }
3921 }
3922 (WorldItem::Function(from), WorldItem::Function(into)) => {
3923 let _ = (from, into);
3924 }
3927 (WorldItem::Type(from), WorldItem::Type(into)) => {
3928 let prev = self.type_map.insert(*from, *into);
3931 assert!(prev.is_none());
3932 }
3933
3934 (WorldItem::Interface { .. }, _)
3935 | (WorldItem::Function(_), _)
3936 | (WorldItem::Type(_), _) => {
3937 bail!("world items do not have the same type")
3938 }
3939 }
3940 Ok(())
3941 }
3942}
3943
3944fn update_stability(from: &Stability, into: &mut Stability) -> Result<()> {
3950 if from == into || from.is_unknown() {
3953 return Ok(());
3954 }
3955 if into.is_unknown() {
3958 *into = from.clone();
3959 return Ok(());
3960 }
3961
3962 bail!("mismatch in stability from '{:?}' to '{:?}'", from, into)
3965}
3966
3967fn merge_include_stability(
3968 from: &Stability,
3969 into: &mut Stability,
3970 is_external_include: bool,
3971) -> Result<()> {
3972 if is_external_include && from.is_stable() {
3973 log::trace!("dropped stability from external package");
3974 *into = Stability::Unknown;
3975 return Ok(());
3976 }
3977
3978 return update_stability(from, into);
3979}
3980
3981#[derive(Debug, Clone)]
3994pub struct InvalidTransitiveDependency(String);
3995
3996impl fmt::Display for InvalidTransitiveDependency {
3997 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3998 write!(
3999 f,
4000 "interface `{}` transitively depends on an interface in \
4001 incompatible ways",
4002 self.0
4003 )
4004 }
4005}
4006
4007impl std::error::Error for InvalidTransitiveDependency {}
4008
4009#[cfg(test)]
4010mod tests {
4011 use crate::Resolve;
4012 use anyhow::Result;
4013
4014 #[test]
4015 fn select_world() -> Result<()> {
4016 let mut resolve = Resolve::default();
4017 resolve.push_str(
4018 "test.wit",
4019 r#"
4020 package foo:bar@0.1.0;
4021
4022 world foo {}
4023 "#,
4024 )?;
4025 resolve.push_str(
4026 "test.wit",
4027 r#"
4028 package foo:baz@0.1.0;
4029
4030 world foo {}
4031 "#,
4032 )?;
4033 resolve.push_str(
4034 "test.wit",
4035 r#"
4036 package foo:baz@0.2.0;
4037
4038 world foo {}
4039 "#,
4040 )?;
4041
4042 let dummy = resolve.push_str(
4043 "test.wit",
4044 r#"
4045 package foo:dummy;
4046
4047 world foo {}
4048 "#,
4049 )?;
4050
4051 assert!(resolve.select_world(dummy, None).is_ok());
4052 assert!(resolve.select_world(dummy, Some("xx")).is_err());
4053 assert!(resolve.select_world(dummy, Some("")).is_err());
4054 assert!(resolve.select_world(dummy, Some("foo:bar/foo")).is_ok());
4055 assert!(resolve
4056 .select_world(dummy, Some("foo:bar/foo@0.1.0"))
4057 .is_ok());
4058 assert!(resolve.select_world(dummy, Some("foo:baz/foo")).is_err());
4059 assert!(resolve
4060 .select_world(dummy, Some("foo:baz/foo@0.1.0"))
4061 .is_ok());
4062 assert!(resolve
4063 .select_world(dummy, Some("foo:baz/foo@0.2.0"))
4064 .is_ok());
4065 Ok(())
4066 }
4067}