1use std::cmp::Ordering;
2use std::collections::hash_map;
3use std::collections::{BTreeMap, HashMap, HashSet};
4use std::fmt;
5use std::mem;
6use std::path::{Path, PathBuf};
7
8use anyhow::{Context, Result, anyhow, bail};
9use id_arena::{Arena, Id};
10use indexmap::{IndexMap, IndexSet};
11use semver::Version;
12#[cfg(feature = "serde")]
13use serde_derive::Serialize;
14
15use crate::ast::lex::Span;
16use crate::ast::{ParsedUsePath, parse_use_path};
17#[cfg(feature = "serde")]
18use crate::serde_::{serialize_arena, serialize_id_map};
19use crate::{
20 AstItem, Docs, Error, Function, FunctionKind, Handle, IncludeName, Interface, InterfaceId,
21 InterfaceSpan, LiftLowerAbi, ManglingAndAbi, PackageName, PackageNotFoundError, SourceMap,
22 Stability, Type, TypeDef, TypeDefKind, TypeId, TypeIdVisitor, TypeOwner, UnresolvedPackage,
23 UnresolvedPackageGroup, World, WorldId, WorldItem, WorldKey, WorldSpan,
24};
25
26pub use clone::CloneMaps;
27
28mod clone;
29
30#[derive(Default, Clone, Debug)]
44#[cfg_attr(feature = "serde", derive(Serialize))]
45pub struct Resolve {
46 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
51 pub worlds: Arena<World>,
52
53 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
58 pub interfaces: Arena<Interface>,
59
60 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
66 pub types: Arena<TypeDef>,
67
68 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
73 pub packages: Arena<Package>,
74
75 #[cfg_attr(feature = "serde", serde(skip))]
77 pub package_names: IndexMap<PackageName, PackageId>,
78
79 #[cfg_attr(feature = "serde", serde(skip))]
86 pub features: IndexSet<String>,
87
88 #[cfg_attr(feature = "serde", serde(skip))]
90 pub all_features: bool,
91}
92
93#[derive(Clone, Debug)]
99#[cfg_attr(feature = "serde", derive(Serialize))]
100pub struct Package {
101 pub name: PackageName,
103
104 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Docs::is_empty"))]
106 pub docs: Docs,
107
108 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_id_map"))]
111 pub interfaces: IndexMap<String, InterfaceId>,
112
113 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_id_map"))]
115 pub worlds: IndexMap<String, WorldId>,
116}
117
118pub type PackageId = Id<Package>;
119
120#[derive(Clone, Debug)]
122pub struct PackageSourceMap {
123 sources: Vec<Vec<PathBuf>>,
124 package_id_to_source_map_idx: BTreeMap<PackageId, usize>,
125}
126
127impl PackageSourceMap {
128 fn from_single_source(package_id: PackageId, source: &Path) -> Self {
129 Self {
130 sources: vec![vec![source.to_path_buf()]],
131 package_id_to_source_map_idx: BTreeMap::from([(package_id, 0)]),
132 }
133 }
134
135 fn from_source_maps(
136 source_maps: Vec<SourceMap>,
137 package_id_to_source_map_idx: BTreeMap<PackageId, usize>,
138 ) -> PackageSourceMap {
139 for (package_id, idx) in &package_id_to_source_map_idx {
140 if *idx >= source_maps.len() {
141 panic!(
142 "Invalid source map index: {}, package id: {:?}, source maps size: {}",
143 idx,
144 package_id,
145 source_maps.len()
146 )
147 }
148 }
149
150 Self {
151 sources: source_maps
152 .into_iter()
153 .map(|source_map| {
154 source_map
155 .source_files()
156 .map(|path| path.to_path_buf())
157 .collect()
158 })
159 .collect(),
160 package_id_to_source_map_idx,
161 }
162 }
163
164 pub fn paths(&self) -> impl Iterator<Item = &Path> {
166 self.sources
170 .iter()
171 .flatten()
172 .map(|path_buf| path_buf.as_ref())
173 .collect::<IndexSet<&Path>>()
174 .into_iter()
175 }
176
177 pub fn package_paths(&self, id: PackageId) -> Option<impl Iterator<Item = &Path>> {
179 self.package_id_to_source_map_idx
180 .get(&id)
181 .map(|&idx| self.sources[idx].iter().map(|path_buf| path_buf.as_ref()))
182 }
183}
184
185enum ParsedFile {
186 #[cfg(feature = "decoding")]
187 Package(PackageId),
188 Unresolved(UnresolvedPackageGroup),
189}
190
191fn visit<'a>(
193 pkg: &'a UnresolvedPackage,
194 pkg_details_map: &'a BTreeMap<PackageName, (UnresolvedPackage, usize)>,
195 order: &mut IndexSet<PackageName>,
196 visiting: &mut HashSet<&'a PackageName>,
197 source_maps: &[SourceMap],
198) -> Result<()> {
199 if order.contains(&pkg.name) {
200 return Ok(());
201 }
202
203 match pkg_details_map.get(&pkg.name) {
204 Some(pkg_details) => {
205 let (_, source_maps_index) = pkg_details;
206 source_maps[*source_maps_index].rewrite_error(|| {
207 for (i, (dep, _)) in pkg.foreign_deps.iter().enumerate() {
208 let span = pkg.foreign_dep_spans[i];
209 if !visiting.insert(dep) {
210 bail!(Error::new(span, "package depends on itself"));
211 }
212 if let Some(dep) = pkg_details_map.get(dep) {
213 let (dep_pkg, _) = dep;
214 visit(dep_pkg, pkg_details_map, order, visiting, source_maps)?;
215 }
216 assert!(visiting.remove(dep));
217 }
218 assert!(order.insert(pkg.name.clone()));
219 Ok(())
220 })
221 }
222 None => panic!("No pkg_details found for package when doing topological sort"),
223 }
224}
225
226impl Resolve {
227 pub fn new() -> Resolve {
229 Resolve::default()
230 }
231
232 pub fn push_path(&mut self, path: impl AsRef<Path>) -> Result<(PackageId, PackageSourceMap)> {
260 self._push_path(path.as_ref())
261 }
262
263 fn _push_path(&mut self, path: &Path) -> Result<(PackageId, PackageSourceMap)> {
264 if path.is_dir() {
265 self.push_dir(path).with_context(|| {
266 format!(
267 "failed to resolve directory while parsing WIT for path [{}]",
268 path.display()
269 )
270 })
271 } else {
272 let id = self.push_file(path)?;
273 Ok((id, PackageSourceMap::from_single_source(id, path)))
274 }
275 }
276
277 fn sort_unresolved_packages(
278 &mut self,
279 main: UnresolvedPackageGroup,
280 deps: Vec<UnresolvedPackageGroup>,
281 ) -> Result<(PackageId, PackageSourceMap)> {
282 let mut pkg_details_map = BTreeMap::new();
283 let mut source_maps = Vec::new();
284
285 let mut insert = |group: UnresolvedPackageGroup| {
286 let UnresolvedPackageGroup {
287 main,
288 nested,
289 source_map,
290 } = group;
291 let i = source_maps.len();
292 source_maps.push(source_map);
293
294 for pkg in nested.into_iter().chain([main]) {
295 let name = pkg.name.clone();
296 let my_span = pkg.package_name_span;
297 let (prev_pkg, prev_i) = match pkg_details_map.insert(name.clone(), (pkg, i)) {
298 Some(pair) => pair,
299 None => continue,
300 };
301 let loc1 = source_maps[i].render_location(my_span);
302 let loc2 = source_maps[prev_i].render_location(prev_pkg.package_name_span);
303 bail!(
304 "\
305package {name} is defined in two different locations:\n\
306 * {loc1}\n\
307 * {loc2}\n\
308 "
309 )
310 }
311 Ok(())
312 };
313
314 let main_name = main.main.name.clone();
315 insert(main)?;
316 for dep in deps {
317 insert(dep)?;
318 }
319
320 let mut order = IndexSet::new();
324 let mut visiting = HashSet::new();
325 for pkg_details in pkg_details_map.values() {
326 let (pkg, _) = pkg_details;
327 visit(
328 pkg,
329 &pkg_details_map,
330 &mut order,
331 &mut visiting,
332 &source_maps,
333 )?;
334 }
335
336 let mut package_id_to_source_map_idx = BTreeMap::new();
340 let mut main_pkg_id = None;
341 for name in order {
342 let (pkg, source_map_index) = pkg_details_map.remove(&name).unwrap();
343 let source_map = &source_maps[source_map_index];
344 let is_main = pkg.name == main_name;
345 let id = self.push(pkg, source_map)?;
346 if is_main {
347 assert!(main_pkg_id.is_none());
348 main_pkg_id = Some(id);
349 }
350 package_id_to_source_map_idx.insert(id, source_map_index);
351 }
352
353 Ok((
354 main_pkg_id.unwrap(),
355 PackageSourceMap::from_source_maps(source_maps, package_id_to_source_map_idx),
356 ))
357 }
358
359 pub fn push_dir(&mut self, path: impl AsRef<Path>) -> Result<(PackageId, PackageSourceMap)> {
393 self._push_dir(path.as_ref())
394 }
395
396 fn _push_dir(&mut self, path: &Path) -> Result<(PackageId, PackageSourceMap)> {
397 let top_pkg = UnresolvedPackageGroup::parse_dir(path)
398 .with_context(|| format!("failed to parse package: {}", path.display()))?;
399 let deps = path.join("deps");
400 let deps = self
401 .parse_deps_dir(&deps)
402 .with_context(|| format!("failed to parse dependency directory: {}", deps.display()))?;
403
404 self.sort_unresolved_packages(top_pkg, deps)
405 }
406
407 fn parse_deps_dir(&mut self, path: &Path) -> Result<Vec<UnresolvedPackageGroup>> {
408 let mut ret = Vec::new();
409 if !path.exists() {
410 return Ok(ret);
411 }
412 let mut entries = path
413 .read_dir()
414 .and_then(|i| i.collect::<std::io::Result<Vec<_>>>())
415 .context("failed to read directory")?;
416 entries.sort_by_key(|e| e.file_name());
417 for dep in entries {
418 let path = dep.path();
419 let pkg = if dep.file_type()?.is_dir() || path.metadata()?.is_dir() {
420 UnresolvedPackageGroup::parse_dir(&path)
425 .with_context(|| format!("failed to parse package: {}", path.display()))?
426 } else {
427 let filename = dep.file_name();
431 match Path::new(&filename).extension().and_then(|s| s.to_str()) {
432 Some("wit") | Some("wat") | Some("wasm") => match self._push_file(&path)? {
433 #[cfg(feature = "decoding")]
434 ParsedFile::Package(_) => continue,
435 ParsedFile::Unresolved(pkg) => pkg,
436 },
437
438 _ => continue,
442 }
443 };
444 ret.push(pkg);
445 }
446 Ok(ret)
447 }
448
449 pub fn push_file(&mut self, path: impl AsRef<Path>) -> Result<PackageId> {
464 match self._push_file(path.as_ref())? {
465 #[cfg(feature = "decoding")]
466 ParsedFile::Package(id) => Ok(id),
467 ParsedFile::Unresolved(pkg) => self.push_group(pkg),
468 }
469 }
470
471 fn _push_file(&mut self, path: &Path) -> Result<ParsedFile> {
472 let contents = std::fs::read(path)
473 .with_context(|| format!("failed to read path for WIT [{}]", path.display()))?;
474
475 #[cfg(feature = "decoding")]
478 {
479 use crate::decoding::{DecodedWasm, decode};
480
481 #[cfg(feature = "wat")]
482 let is_wasm = wat::Detect::from_bytes(&contents).is_wasm();
483 #[cfg(not(feature = "wat"))]
484 let is_wasm = wasmparser::Parser::is_component(&contents);
485
486 if is_wasm {
487 #[cfg(feature = "wat")]
488 let contents = wat::parse_bytes(&contents).map_err(|mut e| {
489 e.set_path(path);
490 e
491 })?;
492
493 match decode(&contents)? {
494 DecodedWasm::Component(..) => {
495 bail!("found an actual component instead of an encoded WIT package in wasm")
496 }
497 DecodedWasm::WitPackage(resolve, pkg) => {
498 let remap = self.merge(resolve)?;
499 return Ok(ParsedFile::Package(remap.packages[pkg.index()]));
500 }
501 }
502 }
503 }
504
505 let text = match std::str::from_utf8(&contents) {
507 Ok(s) => s,
508 Err(_) => bail!("input file is not valid utf-8 [{}]", path.display()),
509 };
510 let pkgs = UnresolvedPackageGroup::parse(path, text)?;
511 Ok(ParsedFile::Unresolved(pkgs))
512 }
513
514 pub fn push(
525 &mut self,
526 unresolved: UnresolvedPackage,
527 source_map: &SourceMap,
528 ) -> Result<PackageId> {
529 let ret = source_map.rewrite_error(|| Remap::default().append(self, unresolved));
530 if ret.is_ok() {
531 #[cfg(debug_assertions)]
532 self.assert_valid();
533 }
534 ret
535 }
536
537 pub fn push_group(&mut self, unresolved_group: UnresolvedPackageGroup) -> Result<PackageId> {
546 let (pkg_id, _) = self.sort_unresolved_packages(unresolved_group, Vec::new())?;
547 Ok(pkg_id)
548 }
549
550 pub fn push_str(&mut self, path: impl AsRef<Path>, contents: &str) -> Result<PackageId> {
557 self.push_group(UnresolvedPackageGroup::parse(path.as_ref(), contents)?)
558 }
559
560 pub fn all_bits_valid(&self, ty: &Type) -> bool {
561 match ty {
562 Type::U8
563 | Type::S8
564 | Type::U16
565 | Type::S16
566 | Type::U32
567 | Type::S32
568 | Type::U64
569 | Type::S64
570 | Type::F32
571 | Type::F64 => true,
572
573 Type::Bool | Type::Char | Type::String | Type::ErrorContext => false,
574
575 Type::Id(id) => match &self.types[*id].kind {
576 TypeDefKind::List(_)
577 | TypeDefKind::Map(_, _)
578 | TypeDefKind::Variant(_)
579 | TypeDefKind::Enum(_)
580 | TypeDefKind::Option(_)
581 | TypeDefKind::Result(_)
582 | TypeDefKind::Future(_)
583 | TypeDefKind::Stream(_) => false,
584 TypeDefKind::Type(t) | TypeDefKind::FixedSizeList(t, ..) => self.all_bits_valid(t),
585
586 TypeDefKind::Handle(h) => match h {
587 crate::Handle::Own(_) => true,
588 crate::Handle::Borrow(_) => true,
589 },
590
591 TypeDefKind::Resource => false,
592 TypeDefKind::Record(r) => r.fields.iter().all(|f| self.all_bits_valid(&f.ty)),
593 TypeDefKind::Tuple(t) => t.types.iter().all(|t| self.all_bits_valid(t)),
594
595 TypeDefKind::Flags(_) => false,
599
600 TypeDefKind::Unknown => unreachable!(),
601 },
602 }
603 }
604
605 pub fn merge(&mut self, resolve: Resolve) -> Result<Remap> {
617 log::trace!(
618 "merging {} packages into {} packages",
619 resolve.packages.len(),
620 self.packages.len()
621 );
622
623 let mut map = MergeMap::new(&resolve, &self);
624 map.build()?;
625 let MergeMap {
626 package_map,
627 interface_map,
628 type_map,
629 world_map,
630 interfaces_to_add,
631 worlds_to_add,
632 ..
633 } = map;
634
635 let mut remap = Remap::default();
654 let Resolve {
655 types,
656 worlds,
657 interfaces,
658 packages,
659 package_names,
660 features: _,
661 ..
662 } = resolve;
663
664 let mut moved_types = Vec::new();
665 for (id, mut ty) in types {
666 let new_id = match type_map.get(&id).copied() {
667 Some(id) => {
668 update_stability(&ty.stability, &mut self.types[id].stability)?;
669 id
670 }
671 None => {
672 log::debug!("moving type {:?}", ty.name);
673 moved_types.push(id);
674 remap.update_typedef(self, &mut ty, None)?;
675 self.types.alloc(ty)
676 }
677 };
678 assert_eq!(remap.types.len(), id.index());
679 remap.types.push(Some(new_id));
680 }
681
682 let mut moved_interfaces = Vec::new();
683 for (id, mut iface) in interfaces {
684 let new_id = match interface_map.get(&id).copied() {
685 Some(id) => {
686 update_stability(&iface.stability, &mut self.interfaces[id].stability)?;
687 id
688 }
689 None => {
690 log::debug!("moving interface {:?}", iface.name);
691 moved_interfaces.push(id);
692 remap.update_interface(self, &mut iface, None)?;
693 self.interfaces.alloc(iface)
694 }
695 };
696 assert_eq!(remap.interfaces.len(), id.index());
697 remap.interfaces.push(Some(new_id));
698 }
699
700 let mut moved_worlds = Vec::new();
701 for (id, mut world) in worlds {
702 let new_id = match world_map.get(&id).copied() {
703 Some(world_id) => {
704 update_stability(&world.stability, &mut self.worlds[world_id].stability)?;
705 for from_import in world.imports.iter() {
706 Resolve::update_world_imports_stability(
707 from_import,
708 &mut self.worlds[world_id].imports,
709 &interface_map,
710 )?;
711 }
712 for from_export in world.exports.iter() {
713 Resolve::update_world_imports_stability(
714 from_export,
715 &mut self.worlds[world_id].exports,
716 &interface_map,
717 )?;
718 }
719 world_id
720 }
721 None => {
722 log::debug!("moving world {}", world.name);
723 moved_worlds.push(id);
724 let mut update = |map: &mut IndexMap<WorldKey, WorldItem>| -> Result<_> {
725 for (mut name, mut item) in mem::take(map) {
726 remap.update_world_key(&mut name, None)?;
727 match &mut item {
728 WorldItem::Function(f) => remap.update_function(self, f, None)?,
729 WorldItem::Interface { id, .. } => {
730 *id = remap.map_interface(*id, None)?
731 }
732 WorldItem::Type(i) => *i = remap.map_type(*i, None)?,
733 }
734 map.insert(name, item);
735 }
736 Ok(())
737 };
738 update(&mut world.imports)?;
739 update(&mut world.exports)?;
740 self.worlds.alloc(world)
741 }
742 };
743 assert_eq!(remap.worlds.len(), id.index());
744 remap.worlds.push(Some(new_id));
745 }
746
747 for (id, mut pkg) in packages {
748 let new_id = match package_map.get(&id).copied() {
749 Some(id) => id,
750 None => {
751 for (_, id) in pkg.interfaces.iter_mut() {
752 *id = remap.map_interface(*id, None)?;
753 }
754 for (_, id) in pkg.worlds.iter_mut() {
755 *id = remap.map_world(*id, None)?;
756 }
757 self.packages.alloc(pkg)
758 }
759 };
760 assert_eq!(remap.packages.len(), id.index());
761 remap.packages.push(new_id);
762 }
763
764 for (name, id) in package_names {
765 let id = remap.packages[id.index()];
766 if let Some(prev) = self.package_names.insert(name, id) {
767 assert_eq!(prev, id);
768 }
769 }
770
771 for id in moved_worlds {
779 let id = remap.map_world(id, None)?;
780 if let Some(pkg) = self.worlds[id].package.as_mut() {
781 *pkg = remap.packages[pkg.index()];
782 }
783 }
784 for id in moved_interfaces {
785 let id = remap.map_interface(id, None)?;
786 if let Some(pkg) = self.interfaces[id].package.as_mut() {
787 *pkg = remap.packages[pkg.index()];
788 }
789 }
790 for id in moved_types {
791 let id = remap.map_type(id, None)?;
792 match &mut self.types[id].owner {
793 TypeOwner::Interface(id) => *id = remap.map_interface(*id, None)?,
794 TypeOwner::World(id) => *id = remap.map_world(*id, None)?,
795 TypeOwner::None => {}
796 }
797 }
798
799 for (name, pkg, iface) in interfaces_to_add {
804 let prev = self.packages[pkg]
805 .interfaces
806 .insert(name, remap.map_interface(iface, None)?);
807 assert!(prev.is_none());
808 }
809 for (name, pkg, world) in worlds_to_add {
810 let prev = self.packages[pkg]
811 .worlds
812 .insert(name, remap.map_world(world, None)?);
813 assert!(prev.is_none());
814 }
815
816 log::trace!("now have {} packages", self.packages.len());
817
818 #[cfg(debug_assertions)]
819 self.assert_valid();
820 Ok(remap)
821 }
822
823 fn update_world_imports_stability(
824 from_item: (&WorldKey, &WorldItem),
825 into_items: &mut IndexMap<WorldKey, WorldItem>,
826 interface_map: &HashMap<Id<Interface>, Id<Interface>>,
827 ) -> Result<()> {
828 match from_item.0 {
829 WorldKey::Name(_) => {
830 Ok(())
832 }
833 key @ WorldKey::Interface(_) => {
834 let new_key = MergeMap::map_name(key, interface_map);
835 if let Some(into) = into_items.get_mut(&new_key) {
836 match (from_item.1, into) {
837 (
838 WorldItem::Interface {
839 id: aid,
840 stability: astability,
841 },
842 WorldItem::Interface {
843 id: bid,
844 stability: bstability,
845 },
846 ) => {
847 let aid = interface_map.get(aid).copied().unwrap_or(*aid);
848 assert_eq!(aid, *bid);
849 update_stability(astability, bstability)?;
850 Ok(())
851 }
852 _ => unreachable!(),
853 }
854 } else {
855 unreachable!()
858 }
859 }
860 }
861 }
862
863 pub fn merge_worlds(
878 &mut self,
879 from: WorldId,
880 into: WorldId,
881 clone_maps: &mut CloneMaps,
882 ) -> Result<()> {
883 let mut new_imports = Vec::new();
884 let mut new_exports = Vec::new();
885
886 let from_world = &self.worlds[from];
887 let into_world = &self.worlds[into];
888
889 log::trace!("merging {} into {}", from_world.name, into_world.name);
890
891 for (name, from_import) in from_world.imports.iter() {
899 let name_str = self.name_world_key(name);
900 match into_world.imports.get(name) {
901 Some(into_import) => {
902 log::trace!("info/from shared import on `{name_str}`");
903 self.merge_world_item(from_import, into_import)
904 .with_context(|| format!("failed to merge world import {name_str}"))?;
905 }
906 None => {
907 log::trace!("new import: `{name_str}`");
908 new_imports.push((name.clone(), from_import.clone()));
909 }
910 }
911 }
912
913 let mut must_be_imported = HashMap::new();
920 for (key, export) in into_world.exports.iter() {
921 for dep in self.world_item_direct_deps(export) {
922 if into_world.exports.contains_key(&WorldKey::Interface(dep)) {
923 continue;
924 }
925 self.foreach_interface_dep(dep, &mut |id| {
926 must_be_imported.insert(id, key.clone());
927 });
928 }
929 }
930
931 for (name, from_export) in from_world.exports.iter() {
934 let name_str = self.name_world_key(name);
935 match into_world.exports.get(name) {
936 Some(into_export) => {
937 log::trace!("info/from shared export on `{name_str}`");
938 self.merge_world_item(from_export, into_export)
939 .with_context(|| format!("failed to merge world export {name_str}"))?;
940 }
941 None => {
942 log::trace!("new export `{name_str}`");
943 self.ensure_can_add_world_export(
946 into_world,
947 name,
948 from_export,
949 &must_be_imported,
950 )
951 .with_context(|| {
952 format!("failed to add export `{}`", self.name_world_key(name))
953 })?;
954 new_exports.push((name.clone(), from_export.clone()));
955 }
956 }
957 }
958
959 let mut cloner = clone::Cloner::new(self, TypeOwner::World(from), TypeOwner::World(into));
973 cloner.register_world_type_overlap(from, into);
974 for (name, item) in new_imports.iter_mut().chain(&mut new_exports) {
975 cloner.world_item(name, item, clone_maps);
976 }
977
978 clone_maps.types.extend(cloner.types);
979
980 let into_world = &mut self.worlds[into];
982 for (name, import) in new_imports {
983 let prev = into_world.imports.insert(name, import);
984 assert!(prev.is_none());
985 }
986 for (name, export) in new_exports {
987 let prev = into_world.exports.insert(name, export);
988 assert!(prev.is_none());
989 }
990
991 #[cfg(debug_assertions)]
992 self.assert_valid();
993 Ok(())
994 }
995
996 fn merge_world_item(&self, from: &WorldItem, into: &WorldItem) -> Result<()> {
997 let mut map = MergeMap::new(self, self);
998 match (from, into) {
999 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
1000 if from == into {
1005 return Ok(());
1006 }
1007
1008 map.build_interface(*from, *into)
1018 .context("failed to merge interfaces")?;
1019 }
1020
1021 (WorldItem::Function(from), WorldItem::Function(into)) => {
1024 map.build_function(from, into)
1025 .context("failed to merge functions")?;
1026 }
1027 (WorldItem::Type(from), WorldItem::Type(into)) => {
1028 map.build_type_id(*from, *into)
1029 .context("failed to merge types")?;
1030 }
1031
1032 (WorldItem::Interface { .. }, _)
1034 | (WorldItem::Function { .. }, _)
1035 | (WorldItem::Type { .. }, _) => {
1036 bail!("different kinds of items");
1037 }
1038 }
1039 assert!(map.interfaces_to_add.is_empty());
1040 assert!(map.worlds_to_add.is_empty());
1041 Ok(())
1042 }
1043
1044 fn ensure_can_add_world_export(
1056 &self,
1057 into: &World,
1058 name: &WorldKey,
1059 item: &WorldItem,
1060 must_be_imported: &HashMap<InterfaceId, WorldKey>,
1061 ) -> Result<()> {
1062 assert!(!into.exports.contains_key(name));
1063 let name = self.name_world_key(name);
1064
1065 for dep in self.world_item_direct_deps(item) {
1069 if into.exports.contains_key(&WorldKey::Interface(dep)) {
1070 continue;
1071 }
1072 self.ensure_not_exported(into, dep)
1073 .with_context(|| format!("failed validating export of `{name}`"))?;
1074 }
1075
1076 if let WorldItem::Interface { id, .. } = item {
1080 if let Some(export) = must_be_imported.get(&id) {
1081 let export_name = self.name_world_key(export);
1082 bail!(
1083 "export `{export_name}` depends on `{name}` \
1084 previously as an import which will change meaning \
1085 if `{name}` is added as an export"
1086 );
1087 }
1088 }
1089
1090 Ok(())
1091 }
1092
1093 fn ensure_not_exported(&self, world: &World, id: InterfaceId) -> Result<()> {
1094 let key = WorldKey::Interface(id);
1095 let name = self.name_world_key(&key);
1096 if world.exports.contains_key(&key) {
1097 bail!(
1098 "world exports `{name}` but it's also transitively used by an \
1099 import \
1100 which means that this is not valid"
1101 )
1102 }
1103 for dep in self.interface_direct_deps(id) {
1104 self.ensure_not_exported(world, dep)
1105 .with_context(|| format!("failed validating transitive import dep `{name}`"))?;
1106 }
1107 Ok(())
1108 }
1109
1110 fn world_item_direct_deps(&self, item: &WorldItem) -> impl Iterator<Item = InterfaceId> + '_ {
1116 let mut interface = None;
1117 let mut ty = None;
1118 match item {
1119 WorldItem::Function(_) => {}
1120 WorldItem::Type(id) => ty = Some(*id),
1121 WorldItem::Interface { id, .. } => interface = Some(*id),
1122 }
1123
1124 interface
1125 .into_iter()
1126 .flat_map(move |id| self.interface_direct_deps(id))
1127 .chain(ty.and_then(|t| self.type_interface_dep(t)))
1128 }
1129
1130 fn foreach_interface_dep(&self, id: InterfaceId, f: &mut dyn FnMut(InterfaceId)) {
1134 self._foreach_interface_dep(id, f, &mut HashSet::new())
1135 }
1136
1137 fn _foreach_interface_dep(
1141 &self,
1142 id: InterfaceId,
1143 f: &mut dyn FnMut(InterfaceId),
1144 visited: &mut HashSet<InterfaceId>,
1145 ) {
1146 if !visited.insert(id) {
1147 return;
1148 }
1149 f(id);
1150 for dep in self.interface_direct_deps(id) {
1151 self._foreach_interface_dep(dep, f, visited);
1152 }
1153 }
1154
1155 pub fn id_of(&self, interface: InterfaceId) -> Option<String> {
1159 let interface = &self.interfaces[interface];
1160 Some(self.id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1161 }
1162
1163 pub fn canonicalized_id_of(&self, interface: InterfaceId) -> Option<String> {
1168 let interface = &self.interfaces[interface];
1169 Some(self.canonicalized_id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1170 }
1171
1172 pub fn importize(&mut self, world_id: WorldId, out_world_name: Option<String>) -> Result<()> {
1188 let world = &mut self.worlds[world_id];
1193 let pkg = &mut self.packages[world.package.unwrap()];
1194 pkg.worlds.shift_remove(&world.name);
1195 if let Some(name) = out_world_name {
1196 world.name = name.clone();
1197 pkg.worlds.insert(name, world_id);
1198 } else {
1199 world.name.push_str("-importized");
1200 pkg.worlds.insert(world.name.clone(), world_id);
1201 }
1202
1203 world.imports.retain(|_, item| match item {
1206 WorldItem::Type(_) => true,
1207 _ => false,
1208 });
1209
1210 for (name, export) in mem::take(&mut world.exports) {
1211 match (name.clone(), world.imports.insert(name, export)) {
1212 (_, None) => {}
1214
1215 (WorldKey::Name(name), Some(_)) => {
1217 bail!("world export `{name}` conflicts with import of same name");
1218 }
1219
1220 (WorldKey::Interface(_), _) => unreachable!(),
1223 }
1224 }
1225
1226 self.elaborate_world(world_id)?;
1229
1230 #[cfg(debug_assertions)]
1231 self.assert_valid();
1232 Ok(())
1233 }
1234
1235 pub fn id_of_name(&self, pkg: PackageId, name: &str) -> String {
1237 let package = &self.packages[pkg];
1238 let mut base = String::new();
1239 base.push_str(&package.name.namespace);
1240 base.push_str(":");
1241 base.push_str(&package.name.name);
1242 base.push_str("/");
1243 base.push_str(name);
1244 if let Some(version) = &package.name.version {
1245 base.push_str(&format!("@{version}"));
1246 }
1247 base
1248 }
1249
1250 pub fn canonicalized_id_of_name(&self, pkg: PackageId, name: &str) -> String {
1256 let package = &self.packages[pkg];
1257 let mut base = String::new();
1258 base.push_str(&package.name.namespace);
1259 base.push_str(":");
1260 base.push_str(&package.name.name);
1261 base.push_str("/");
1262 base.push_str(name);
1263 if let Some(version) = &package.name.version {
1264 base.push_str("@");
1265 let string = PackageName::version_compat_track_string(version);
1266 base.push_str(&string);
1267 }
1268 base
1269 }
1270
1271 pub fn select_world(
1386 &self,
1387 main_packages: &[PackageId],
1388 world: Option<&str>,
1389 ) -> Result<WorldId> {
1390 let world_path = match world {
1392 Some(world) => Some(
1393 parse_use_path(world)
1394 .with_context(|| format!("failed to parse world specifier `{world}`"))?,
1395 ),
1396 None => None,
1397 };
1398
1399 match world_path {
1400 Some(world_path) => {
1402 let (pkg, world_name) = match (main_packages, world_path) {
1403 ([], _) => bail!("No main packages defined"),
1405
1406 ([main_package], ParsedUsePath::Name(name)) => (*main_package, name),
1408
1409 (_, ParsedUsePath::Name(_name)) => {
1411 bail!(
1412 "There are multiple main packages; a world must be explicitly chosen:{}",
1413 self.worlds
1414 .iter()
1415 .map(|world| format!(
1416 "\n {}",
1417 self.id_of_name(world.1.package.unwrap(), &world.1.name)
1418 ))
1419 .collect::<String>()
1420 )
1421 }
1422
1423 (_, ParsedUsePath::Package(pkg, world_name)) => {
1425 let pkg = match self.package_names.get(&pkg) {
1426 Some(pkg) => *pkg,
1427 None => {
1428 let mut candidates =
1429 self.package_names.iter().filter(|(name, _)| {
1430 pkg.version.is_none()
1431 && pkg.name == name.name
1432 && pkg.namespace == name.namespace
1433 && name.version.is_some()
1434 });
1435 let candidate = candidates.next();
1436 if let Some((c2, _)) = candidates.next() {
1437 let (c1, _) = candidate.unwrap();
1438 bail!(
1439 "package name `{pkg}` is available at both \
1440 versions {} and {} but which is not specified",
1441 c1.version.as_ref().unwrap(),
1442 c2.version.as_ref().unwrap(),
1443 );
1444 }
1445 match candidate {
1446 Some((_, id)) => *id,
1447 None => bail!("unknown package `{pkg}`"),
1448 }
1449 }
1450 };
1451 (pkg, world_name.to_string())
1452 }
1453 };
1454
1455 let pkg = &self.packages[pkg];
1457 pkg.worlds.get(&world_name).copied().ok_or_else(|| {
1458 anyhow!("World `{world_name}` not found in package `{}`", pkg.name)
1459 })
1460 }
1461
1462 None => match main_packages {
1464 [] => bail!("No main packages defined"),
1465
1466 [main_package] => {
1468 let pkg = &self.packages[*main_package];
1469 match pkg.worlds.len() {
1470 0 => bail!("The main package `{}` contains no worlds", pkg.name),
1471 1 => Ok(pkg.worlds[0]),
1472 _ => bail!(
1473 "There are multiple worlds in `{}`; one must be explicitly chosen:{}",
1474 pkg.name,
1475 pkg.worlds
1476 .values()
1477 .map(|world| format!(
1478 "\n {}",
1479 self.id_of_name(*main_package, &self.worlds[*world].name)
1480 ))
1481 .collect::<String>()
1482 ),
1483 }
1484 }
1485
1486 _ => {
1488 bail!(
1489 "There are multiple main packages; a world must be explicitly chosen:{}",
1490 self.worlds
1491 .iter()
1492 .map(|world| format!(
1493 "\n {}",
1494 self.id_of_name(world.1.package.unwrap(), &world.1.name)
1495 ))
1496 .collect::<String>()
1497 )
1498 }
1499 },
1500 }
1501 }
1502
1503 pub fn name_world_key(&self, key: &WorldKey) -> String {
1505 match key {
1506 WorldKey::Name(s) => s.to_string(),
1507 WorldKey::Interface(i) => self.id_of(*i).expect("unexpected anonymous interface"),
1508 }
1509 }
1510
1511 pub fn name_canonicalized_world_key(&self, key: &WorldKey) -> String {
1514 match key {
1515 WorldKey::Name(s) => s.to_string(),
1516 WorldKey::Interface(i) => self
1517 .canonicalized_id_of(*i)
1518 .expect("unexpected anonymous interface"),
1519 }
1520 }
1521
1522 pub fn type_interface_dep(&self, id: TypeId) -> Option<InterfaceId> {
1528 let ty = &self.types[id];
1529 let dep = match ty.kind {
1530 TypeDefKind::Type(Type::Id(id)) => id,
1531 _ => return None,
1532 };
1533 let other = &self.types[dep];
1534 if ty.owner == other.owner {
1535 None
1536 } else {
1537 match other.owner {
1538 TypeOwner::Interface(id) => Some(id),
1539 _ => unreachable!(),
1540 }
1541 }
1542 }
1543
1544 pub fn interface_direct_deps(&self, id: InterfaceId) -> impl Iterator<Item = InterfaceId> + '_ {
1554 self.interfaces[id]
1555 .types
1556 .iter()
1557 .filter_map(move |(_name, ty)| self.type_interface_dep(*ty))
1558 }
1559
1560 pub fn package_direct_deps(&self, id: PackageId) -> impl Iterator<Item = PackageId> + '_ {
1570 let pkg = &self.packages[id];
1571
1572 pkg.interfaces
1573 .iter()
1574 .flat_map(move |(_name, id)| self.interface_direct_deps(*id))
1575 .chain(pkg.worlds.iter().flat_map(move |(_name, id)| {
1576 let world = &self.worlds[*id];
1577 world
1578 .imports
1579 .iter()
1580 .chain(world.exports.iter())
1581 .filter_map(move |(_name, item)| match item {
1582 WorldItem::Interface { id, .. } => Some(*id),
1583 WorldItem::Function(_) => None,
1584 WorldItem::Type(t) => self.type_interface_dep(*t),
1585 })
1586 }))
1587 .filter_map(move |iface_id| {
1588 let pkg = self.interfaces[iface_id].package?;
1589 if pkg == id { None } else { Some(pkg) }
1590 })
1591 }
1592
1593 pub fn topological_packages(&self) -> Vec<PackageId> {
1599 let mut pushed = vec![false; self.packages.len()];
1600 let mut order = Vec::new();
1601 for (id, _) in self.packages.iter() {
1602 self.build_topological_package_ordering(id, &mut pushed, &mut order);
1603 }
1604 order
1605 }
1606
1607 fn build_topological_package_ordering(
1608 &self,
1609 id: PackageId,
1610 pushed: &mut Vec<bool>,
1611 order: &mut Vec<PackageId>,
1612 ) {
1613 if pushed[id.index()] {
1614 return;
1615 }
1616 for dep in self.package_direct_deps(id) {
1617 self.build_topological_package_ordering(dep, pushed, order);
1618 }
1619 order.push(id);
1620 pushed[id.index()] = true;
1621 }
1622
1623 #[doc(hidden)]
1624 pub fn assert_valid(&self) {
1625 let mut package_interfaces = Vec::new();
1626 let mut package_worlds = Vec::new();
1627 for (id, pkg) in self.packages.iter() {
1628 let mut interfaces = HashSet::new();
1629 for (name, iface) in pkg.interfaces.iter() {
1630 assert!(interfaces.insert(*iface));
1631 let iface = &self.interfaces[*iface];
1632 assert_eq!(name, iface.name.as_ref().unwrap());
1633 assert_eq!(iface.package.unwrap(), id);
1634 }
1635 package_interfaces.push(pkg.interfaces.values().copied().collect::<HashSet<_>>());
1636 let mut worlds = HashSet::new();
1637 for (name, world) in pkg.worlds.iter() {
1638 assert!(worlds.insert(*world));
1639 assert_eq!(
1640 pkg.worlds.get_key_value(name),
1641 Some((name, world)),
1642 "`MutableKeys` impl may have been used to change a key's hash or equality"
1643 );
1644 let world = &self.worlds[*world];
1645 assert_eq!(*name, world.name);
1646 assert_eq!(world.package.unwrap(), id);
1647 }
1648 package_worlds.push(pkg.worlds.values().copied().collect::<HashSet<_>>());
1649 }
1650
1651 let mut interface_types = Vec::new();
1652 for (id, iface) in self.interfaces.iter() {
1653 assert!(self.packages.get(iface.package.unwrap()).is_some());
1654 if iface.name.is_some() {
1655 assert!(package_interfaces[iface.package.unwrap().index()].contains(&id));
1656 }
1657
1658 for (name, ty) in iface.types.iter() {
1659 let ty = &self.types[*ty];
1660 assert_eq!(ty.name.as_ref(), Some(name));
1661 assert_eq!(ty.owner, TypeOwner::Interface(id));
1662 }
1663 interface_types.push(iface.types.values().copied().collect::<HashSet<_>>());
1664 for (name, f) in iface.functions.iter() {
1665 assert_eq!(*name, f.name);
1666 }
1667 }
1668
1669 let mut world_types = Vec::new();
1670 for (id, world) in self.worlds.iter() {
1671 log::debug!("validating world {}", &world.name);
1672 if let Some(package) = world.package {
1673 assert!(self.packages.get(package).is_some());
1674 assert!(package_worlds[package.index()].contains(&id));
1675 }
1676 assert!(world.includes.is_empty());
1677
1678 let mut types = HashSet::new();
1679 for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1680 log::debug!("validating world item: {}", self.name_world_key(name));
1681 match item {
1682 WorldItem::Interface { id, .. } => {
1683 if matches!(name, WorldKey::Name(_)) {
1686 assert_eq!(self.interfaces[*id].package, world.package);
1687 }
1688 }
1689 WorldItem::Function(f) => {
1690 assert!(!matches!(name, WorldKey::Interface(_)));
1691 assert_eq!(f.name, name.clone().unwrap_name());
1692 }
1693 WorldItem::Type(ty) => {
1694 assert!(!matches!(name, WorldKey::Interface(_)));
1695 assert!(types.insert(*ty));
1696 let ty = &self.types[*ty];
1697 assert_eq!(ty.name, Some(name.clone().unwrap_name()));
1698 assert_eq!(ty.owner, TypeOwner::World(id));
1699 }
1700 }
1701 }
1702 self.assert_world_elaborated(world);
1703 world_types.push(types);
1704 }
1705
1706 for (ty_id, ty) in self.types.iter() {
1707 match ty.owner {
1708 TypeOwner::Interface(id) => {
1709 assert!(self.interfaces.get(id).is_some());
1710 assert!(interface_types[id.index()].contains(&ty_id));
1711 }
1712 TypeOwner::World(id) => {
1713 assert!(self.worlds.get(id).is_some());
1714 assert!(world_types[id.index()].contains(&ty_id));
1715 }
1716 TypeOwner::None => {}
1717 }
1718 }
1719
1720 self.assert_topologically_sorted();
1721 }
1722
1723 fn assert_topologically_sorted(&self) {
1724 let mut positions = IndexMap::new();
1725 for id in self.topological_packages() {
1726 let pkg = &self.packages[id];
1727 log::debug!("pkg {}", pkg.name);
1728 let prev = positions.insert(Some(id), IndexSet::new());
1729 assert!(prev.is_none());
1730 }
1731 positions.insert(None, IndexSet::new());
1732
1733 for (id, iface) in self.interfaces.iter() {
1734 log::debug!("iface {:?}", iface.name);
1735 let ok = positions.get_mut(&iface.package).unwrap().insert(id);
1736 assert!(ok);
1737 }
1738
1739 for (_, world) in self.worlds.iter() {
1740 log::debug!("world {:?}", world.name);
1741
1742 let my_package = world.package;
1743 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1744
1745 for (_, item) in world.imports.iter().chain(&world.exports) {
1746 let id = match item {
1747 WorldItem::Interface { id, .. } => *id,
1748 _ => continue,
1749 };
1750 let other_package = self.interfaces[id].package;
1751 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1752
1753 assert!(other_package_pos <= my_package_pos);
1754 }
1755 }
1756
1757 for (_id, ty) in self.types.iter() {
1758 log::debug!("type {:?} {:?}", ty.name, ty.owner);
1759 let other_id = match ty.kind {
1760 TypeDefKind::Type(Type::Id(ty)) => ty,
1761 _ => continue,
1762 };
1763 let other = &self.types[other_id];
1764 if ty.kind == other.kind {
1765 continue;
1766 }
1767 let my_interface = match ty.owner {
1768 TypeOwner::Interface(id) => id,
1769 _ => continue,
1770 };
1771 let other_interface = match other.owner {
1772 TypeOwner::Interface(id) => id,
1773 _ => continue,
1774 };
1775
1776 let my_package = self.interfaces[my_interface].package;
1777 let other_package = self.interfaces[other_interface].package;
1778 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1779 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1780
1781 if my_package_pos == other_package_pos {
1782 let interfaces = &positions[&my_package];
1783 let my_interface_pos = interfaces.get_index_of(&my_interface).unwrap();
1784 let other_interface_pos = interfaces.get_index_of(&other_interface).unwrap();
1785 assert!(other_interface_pos <= my_interface_pos);
1786 } else {
1787 assert!(other_package_pos < my_package_pos);
1788 }
1789 }
1790 }
1791
1792 fn assert_world_elaborated(&self, world: &World) {
1793 for (key, item) in world.imports.iter() {
1794 log::debug!(
1795 "asserting elaborated world import {}",
1796 self.name_world_key(key)
1797 );
1798 match item {
1799 WorldItem::Type(t) => self.assert_world_imports_type_deps(world, key, *t),
1800
1801 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1803
1804 WorldItem::Interface { id, .. } => {
1806 for dep in self.interface_direct_deps(*id) {
1807 assert!(
1808 world.imports.contains_key(&WorldKey::Interface(dep)),
1809 "world import of {} is missing transitive dep of {}",
1810 self.name_world_key(key),
1811 self.id_of(dep).unwrap(),
1812 );
1813 }
1814 }
1815 }
1816 }
1817 for (key, item) in world.exports.iter() {
1818 log::debug!(
1819 "asserting elaborated world export {}",
1820 self.name_world_key(key)
1821 );
1822 match item {
1823 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1825
1826 WorldItem::Interface { id, .. } => {
1830 for dep in self.interface_direct_deps(*id) {
1831 let dep_key = WorldKey::Interface(dep);
1832 if world.exports.contains_key(&dep_key) {
1833 continue;
1834 }
1835 self.foreach_interface_dep(dep, &mut |dep| {
1836 let dep_key = WorldKey::Interface(dep);
1837 assert!(
1838 world.imports.contains_key(&dep_key),
1839 "world should import {} (required by {})",
1840 self.name_world_key(&dep_key),
1841 self.name_world_key(key),
1842 );
1843 assert!(
1844 !world.exports.contains_key(&dep_key),
1845 "world should not export {} (required by {})",
1846 self.name_world_key(&dep_key),
1847 self.name_world_key(key),
1848 );
1849 });
1850 }
1851 }
1852
1853 WorldItem::Type(_) => unreachable!(),
1855 }
1856 }
1857 }
1858
1859 fn assert_world_imports_type_deps(&self, world: &World, key: &WorldKey, ty: TypeId) {
1860 let ty = &self.types[ty];
1863 if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
1864 if let TypeOwner::Interface(id) = self.types[other].owner {
1865 let key = WorldKey::Interface(id);
1866 assert!(world.imports.contains_key(&key));
1867 return;
1868 }
1869 }
1870
1871 let mut visitor = MyVisit(self, Vec::new());
1875 visitor.visit_type_def(self, ty);
1876 for ty in visitor.1 {
1877 let ty = &self.types[ty];
1878 let Some(name) = ty.name.clone() else {
1879 continue;
1880 };
1881 let dep_key = WorldKey::Name(name);
1882 assert!(
1883 world.imports.contains_key(&dep_key),
1884 "world import `{}` should also force an import of `{}`",
1885 self.name_world_key(key),
1886 self.name_world_key(&dep_key),
1887 );
1888 }
1889
1890 struct MyVisit<'a>(&'a Resolve, Vec<TypeId>);
1891
1892 impl TypeIdVisitor for MyVisit<'_> {
1893 fn before_visit_type_id(&mut self, id: TypeId) -> bool {
1894 self.1.push(id);
1895 self.0.types[id].name.is_none()
1897 }
1898 }
1899 }
1900
1901 fn assert_world_function_imports_types(&self, world: &World, key: &WorldKey, func: &Function) {
1905 for ty in func
1906 .parameter_and_result_types()
1907 .chain(func.kind.resource().map(Type::Id))
1908 {
1909 let Type::Id(id) = ty else {
1910 continue;
1911 };
1912 self.assert_world_imports_type_deps(world, key, id);
1913 }
1914 }
1915
1916 fn include_stability(
1932 &self,
1933 stability: &Stability,
1934 pkg_id: &PackageId,
1935 span: Option<Span>,
1936 ) -> Result<bool> {
1937 let err = |msg: String| match span {
1938 Some(span) => Error::new(span, msg).into(),
1939 None => anyhow::Error::msg(msg),
1940 };
1941 Ok(match stability {
1942 Stability::Unknown => true,
1943 Stability::Stable { since, .. } => {
1946 let Some(p) = self.packages.get(*pkg_id) else {
1947 return Ok(true);
1955 };
1956
1957 let package_version = p.name.version.as_ref().ok_or_else(|| {
1960 err(format!(
1961 "package [{}] contains a feature gate with a version \
1962 specifier, so it must have a version",
1963 p.name
1964 ))
1965 })?;
1966
1967 if since > package_version {
1971 return Err(err(format!(
1972 "feature gate cannot reference unreleased version \
1973 {since} of package [{}] (current version {package_version})",
1974 p.name
1975 )));
1976 }
1977
1978 true
1979 }
1980 Stability::Unstable { feature, .. } => {
1981 self.features.contains(feature) || self.all_features
1982 }
1983 })
1984 }
1985
1986 fn include_type(&self, ty: &TypeDef, pkgid: PackageId, span: Span) -> Result<bool> {
1989 self.include_stability(&ty.stability, &pkgid, Some(span))
1990 .with_context(|| {
1991 format!(
1992 "failed to process feature gate for type [{}] in package [{}]",
1993 ty.name.as_ref().map(String::as_str).unwrap_or("<unknown>"),
1994 self.packages[pkgid].name,
1995 )
1996 })
1997 }
1998
1999 fn elaborate_world(&mut self, world_id: WorldId) -> Result<()> {
2011 let mut new_imports = IndexMap::new();
2015 let world = &self.worlds[world_id];
2016
2017 let sort_key = |resolve: &Resolve, item: &WorldItem| match item {
2040 WorldItem::Interface { .. } => 0,
2041 WorldItem::Type(ty) => {
2042 let ty = &resolve.types[*ty];
2043 match ty.kind {
2044 TypeDefKind::Type(Type::Id(t)) if resolve.types[t].owner != ty.owner => 1,
2045 _ => 2,
2046 }
2047 }
2048 WorldItem::Function(f) => {
2049 if f.kind.resource().is_none() {
2050 3
2051 } else {
2052 4
2053 }
2054 }
2055 };
2056
2057 let mut world_imports = world.imports.iter().collect::<Vec<_>>();
2060 world_imports.sort_by_key(|(_name, import)| sort_key(self, import));
2061 for (name, item) in world_imports {
2062 match item {
2063 WorldItem::Interface { id, stability } => {
2066 self.elaborate_world_import(&mut new_imports, name.clone(), *id, &stability);
2067 }
2068
2069 WorldItem::Function(_) => {
2072 let prev = new_imports.insert(name.clone(), item.clone());
2073 assert!(prev.is_none());
2074 }
2075
2076 WorldItem::Type(id) => {
2080 if let Some(dep) = self.type_interface_dep(*id) {
2081 self.elaborate_world_import(
2082 &mut new_imports,
2083 WorldKey::Interface(dep),
2084 dep,
2085 &self.types[*id].stability,
2086 );
2087 }
2088 let prev = new_imports.insert(name.clone(), item.clone());
2089 assert!(prev.is_none());
2090 }
2091 }
2092 }
2093
2094 let mut new_exports = IndexMap::new();
2100 let mut export_interfaces = IndexMap::new();
2101 for (name, item) in world.exports.iter() {
2102 match item {
2103 WorldItem::Interface { id, stability } => {
2104 let prev = export_interfaces.insert(*id, (name.clone(), stability));
2105 assert!(prev.is_none());
2106 }
2107 WorldItem::Function(_) => {
2108 let prev = new_exports.insert(name.clone(), item.clone());
2109 assert!(prev.is_none());
2110 }
2111 WorldItem::Type(_) => unreachable!(),
2112 }
2113 }
2114
2115 self.elaborate_world_exports(&export_interfaces, &mut new_imports, &mut new_exports)?;
2116
2117 new_imports.sort_by_cached_key(|_name, import| sort_key(self, import));
2121
2122 log::trace!("imports = {new_imports:?}");
2125 log::trace!("exports = {new_exports:?}");
2126 let world = &mut self.worlds[world_id];
2127 world.imports = new_imports;
2128 world.exports = new_exports;
2129
2130 Ok(())
2131 }
2132
2133 fn elaborate_world_import(
2134 &self,
2135 imports: &mut IndexMap<WorldKey, WorldItem>,
2136 key: WorldKey,
2137 id: InterfaceId,
2138 stability: &Stability,
2139 ) {
2140 if imports.contains_key(&key) {
2141 return;
2142 }
2143 for dep in self.interface_direct_deps(id) {
2144 self.elaborate_world_import(imports, WorldKey::Interface(dep), dep, stability);
2145 }
2146 let prev = imports.insert(
2147 key,
2148 WorldItem::Interface {
2149 id,
2150 stability: stability.clone(),
2151 },
2152 );
2153 assert!(prev.is_none());
2154 }
2155
2156 fn elaborate_world_exports(
2203 &self,
2204 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2205 imports: &mut IndexMap<WorldKey, WorldItem>,
2206 exports: &mut IndexMap<WorldKey, WorldItem>,
2207 ) -> Result<()> {
2208 let mut required_imports = HashSet::new();
2209 for (id, (key, stability)) in export_interfaces.iter() {
2210 let name = self.name_world_key(&key);
2211 let ok = add_world_export(
2212 self,
2213 imports,
2214 exports,
2215 export_interfaces,
2216 &mut required_imports,
2217 *id,
2218 key,
2219 true,
2220 stability,
2221 );
2222 if !ok {
2223 bail!(
2224 InvalidTransitiveDependency(name),
2242 );
2243 }
2244 }
2245 return Ok(());
2246
2247 fn add_world_export(
2248 resolve: &Resolve,
2249 imports: &mut IndexMap<WorldKey, WorldItem>,
2250 exports: &mut IndexMap<WorldKey, WorldItem>,
2251 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2252 required_imports: &mut HashSet<InterfaceId>,
2253 id: InterfaceId,
2254 key: &WorldKey,
2255 add_export: bool,
2256 stability: &Stability,
2257 ) -> bool {
2258 if exports.contains_key(key) {
2259 if add_export {
2260 return true;
2261 } else {
2262 return false;
2263 }
2264 }
2265 if !add_export && required_imports.contains(&id) {
2268 return true;
2269 }
2270 let ok = resolve.interface_direct_deps(id).all(|dep| {
2271 let key = WorldKey::Interface(dep);
2272 let add_export = add_export && export_interfaces.contains_key(&dep);
2273 add_world_export(
2274 resolve,
2275 imports,
2276 exports,
2277 export_interfaces,
2278 required_imports,
2279 dep,
2280 &key,
2281 add_export,
2282 stability,
2283 )
2284 });
2285 if !ok {
2286 return false;
2287 }
2288 let item = WorldItem::Interface {
2289 id,
2290 stability: stability.clone(),
2291 };
2292 if add_export {
2293 if required_imports.contains(&id) {
2294 return false;
2295 }
2296 exports.insert(key.clone(), item);
2297 } else {
2298 required_imports.insert(id);
2299 imports.insert(key.clone(), item);
2300 }
2301 true
2302 }
2303 }
2304
2305 pub fn merge_world_imports_based_on_semver(&mut self, world_id: WorldId) -> Result<()> {
2317 let world = &self.worlds[world_id];
2318
2319 let mut semver_tracks = HashMap::new();
2328 let mut to_remove = HashSet::new();
2329 for (key, _) in world.imports.iter() {
2330 let iface_id = match key {
2331 WorldKey::Interface(id) => *id,
2332 WorldKey::Name(_) => continue,
2333 };
2334 let (track, version) = match self.semver_track(iface_id) {
2335 Some(track) => track,
2336 None => continue,
2337 };
2338 log::debug!(
2339 "{} is on track {}/{}",
2340 self.id_of(iface_id).unwrap(),
2341 track.0,
2342 track.1,
2343 );
2344 match semver_tracks.entry(track.clone()) {
2345 hash_map::Entry::Vacant(e) => {
2346 e.insert((version, iface_id));
2347 }
2348 hash_map::Entry::Occupied(mut e) => match version.cmp(&e.get().0) {
2349 Ordering::Greater => {
2350 to_remove.insert(e.get().1);
2351 e.insert((version, iface_id));
2352 }
2353 Ordering::Equal => {}
2354 Ordering::Less => {
2355 to_remove.insert(iface_id);
2356 }
2357 },
2358 }
2359 }
2360
2361 let mut replacements = HashMap::new();
2364 for id in to_remove {
2365 let (track, _) = self.semver_track(id).unwrap();
2366 let (_, latest) = semver_tracks[&track];
2367 let prev = replacements.insert(id, latest);
2368 assert!(prev.is_none());
2369 }
2370
2371 for (to_replace, replace_with) in replacements.iter() {
2376 self.merge_world_item(
2377 &WorldItem::Interface {
2378 id: *to_replace,
2379 stability: Default::default(),
2380 },
2381 &WorldItem::Interface {
2382 id: *replace_with,
2383 stability: Default::default(),
2384 },
2385 )
2386 .with_context(|| {
2387 let old_name = self.id_of(*to_replace).unwrap();
2388 let new_name = self.id_of(*replace_with).unwrap();
2389 format!(
2390 "failed to upgrade `{old_name}` to `{new_name}`, was \
2391 this semver-compatible update not semver compatible?"
2392 )
2393 })?;
2394 }
2395
2396 for (to_replace, replace_with) in replacements.iter() {
2397 log::debug!(
2398 "REPLACE {} => {}",
2399 self.id_of(*to_replace).unwrap(),
2400 self.id_of(*replace_with).unwrap(),
2401 );
2402 }
2403
2404 for (key, item) in mem::take(&mut self.worlds[world_id].imports) {
2413 if let WorldItem::Interface { id, .. } = item {
2414 if replacements.contains_key(&id) {
2415 continue;
2416 }
2417 }
2418
2419 self.update_interface_deps_of_world_item(&item, &replacements);
2420
2421 let prev = self.worlds[world_id].imports.insert(key, item);
2422 assert!(prev.is_none());
2423 }
2424 for (key, item) in mem::take(&mut self.worlds[world_id].exports) {
2425 self.update_interface_deps_of_world_item(&item, &replacements);
2426 let prev = self.worlds[world_id].exports.insert(key, item);
2427 assert!(prev.is_none());
2428 }
2429
2430 let ids = self.worlds.iter().map(|(id, _)| id).collect::<Vec<_>>();
2436 for world_id in ids {
2437 self.elaborate_world(world_id).with_context(|| {
2438 let name = &self.worlds[world_id].name;
2439 format!(
2440 "failed to elaborate world `{name}` after deduplicating imports \
2441 based on semver"
2442 )
2443 })?;
2444 }
2445
2446 #[cfg(debug_assertions)]
2447 self.assert_valid();
2448
2449 Ok(())
2450 }
2451
2452 fn update_interface_deps_of_world_item(
2453 &mut self,
2454 item: &WorldItem,
2455 replacements: &HashMap<InterfaceId, InterfaceId>,
2456 ) {
2457 match *item {
2458 WorldItem::Type(t) => self.update_interface_dep_of_type(t, &replacements),
2459 WorldItem::Interface { id, .. } => {
2460 let types = self.interfaces[id]
2461 .types
2462 .values()
2463 .copied()
2464 .collect::<Vec<_>>();
2465 for ty in types {
2466 self.update_interface_dep_of_type(ty, &replacements);
2467 }
2468 }
2469 WorldItem::Function(_) => {}
2470 }
2471 }
2472
2473 fn semver_track(&self, id: InterfaceId) -> Option<((PackageName, String), &Version)> {
2484 let iface = &self.interfaces[id];
2485 let pkg = &self.packages[iface.package?];
2486 let version = pkg.name.version.as_ref()?;
2487 let mut name = pkg.name.clone();
2488 name.version = Some(PackageName::version_compat_track(version));
2489 Some(((name, iface.name.clone()?), version))
2490 }
2491
2492 fn update_interface_dep_of_type(
2496 &mut self,
2497 ty: TypeId,
2498 replacements: &HashMap<InterfaceId, InterfaceId>,
2499 ) {
2500 let to_replace = match self.type_interface_dep(ty) {
2501 Some(id) => id,
2502 None => return,
2503 };
2504 let replace_with = match replacements.get(&to_replace) {
2505 Some(id) => id,
2506 None => return,
2507 };
2508 let dep = match self.types[ty].kind {
2509 TypeDefKind::Type(Type::Id(id)) => id,
2510 _ => return,
2511 };
2512 let name = self.types[dep].name.as_ref().unwrap();
2513 let replacement_id = self.interfaces[*replace_with].types[name];
2516 self.types[ty].kind = TypeDefKind::Type(Type::Id(replacement_id));
2517 }
2518
2519 pub fn wasm_import_name(
2526 &self,
2527 mangling: ManglingAndAbi,
2528 import: WasmImport<'_>,
2529 ) -> (String, String) {
2530 match mangling {
2531 ManglingAndAbi::Standard32 => match import {
2532 WasmImport::Func { interface, func } => {
2533 let module = match interface {
2534 Some(key) => format!("cm32p2|{}", self.name_canonicalized_world_key(key)),
2535 None => format!("cm32p2"),
2536 };
2537 (module, func.name.clone())
2538 }
2539 WasmImport::ResourceIntrinsic {
2540 interface,
2541 resource,
2542 intrinsic,
2543 } => {
2544 let name = self.types[resource].name.as_ref().unwrap();
2545 let (prefix, name) = match intrinsic {
2546 ResourceIntrinsic::ImportedDrop => ("", format!("{name}_drop")),
2547 ResourceIntrinsic::ExportedDrop => ("_ex_", format!("{name}_drop")),
2548 ResourceIntrinsic::ExportedNew => ("_ex_", format!("{name}_new")),
2549 ResourceIntrinsic::ExportedRep => ("_ex_", format!("{name}_rep")),
2550 };
2551 let module = match interface {
2552 Some(key) => {
2553 format!("cm32p2|{prefix}{}", self.name_canonicalized_world_key(key))
2554 }
2555 None => {
2556 assert_eq!(prefix, "");
2557 format!("cm32p2")
2558 }
2559 };
2560 (module, name)
2561 }
2562 },
2563 ManglingAndAbi::Legacy(abi) => match import {
2564 WasmImport::Func { interface, func } => {
2565 let module = match interface {
2566 Some(key) => self.name_world_key(key),
2567 None => format!("$root"),
2568 };
2569 (module, format!("{}{}", abi.import_prefix(), func.name))
2570 }
2571 WasmImport::ResourceIntrinsic {
2572 interface,
2573 resource,
2574 intrinsic,
2575 } => {
2576 let name = self.types[resource].name.as_ref().unwrap();
2577 let (prefix, name) = match intrinsic {
2578 ResourceIntrinsic::ImportedDrop => ("", format!("[resource-drop]{name}")),
2579 ResourceIntrinsic::ExportedDrop => {
2580 ("[export]", format!("[resource-drop]{name}"))
2581 }
2582 ResourceIntrinsic::ExportedNew => {
2583 ("[export]", format!("[resource-new]{name}"))
2584 }
2585 ResourceIntrinsic::ExportedRep => {
2586 ("[export]", format!("[resource-rep]{name}"))
2587 }
2588 };
2589 let module = match interface {
2590 Some(key) => format!("{prefix}{}", self.name_world_key(key)),
2591 None => {
2592 assert_eq!(prefix, "");
2593 format!("$root")
2594 }
2595 };
2596 (module, format!("{}{name}", abi.import_prefix()))
2597 }
2598 },
2599 }
2600 }
2601
2602 pub fn wasm_export_name(&self, mangling: ManglingAndAbi, export: WasmExport<'_>) -> String {
2606 match mangling {
2607 ManglingAndAbi::Standard32 => match export {
2608 WasmExport::Func {
2609 interface,
2610 func,
2611 kind,
2612 } => {
2613 let mut name = String::from("cm32p2|");
2614 if let Some(interface) = interface {
2615 let s = self.name_canonicalized_world_key(interface);
2616 name.push_str(&s);
2617 }
2618 name.push_str("|");
2619 name.push_str(&func.name);
2620 match kind {
2621 WasmExportKind::Normal => {}
2622 WasmExportKind::PostReturn => name.push_str("_post"),
2623 WasmExportKind::Callback => todo!(
2624 "not yet supported: \
2625 async callback functions using standard name mangling"
2626 ),
2627 }
2628 name
2629 }
2630 WasmExport::ResourceDtor {
2631 interface,
2632 resource,
2633 } => {
2634 let name = self.types[resource].name.as_ref().unwrap();
2635 let interface = self.name_canonicalized_world_key(interface);
2636 format!("cm32p2|{interface}|{name}_dtor")
2637 }
2638 WasmExport::Memory => "cm32p2_memory".to_string(),
2639 WasmExport::Initialize => "cm32p2_initialize".to_string(),
2640 WasmExport::Realloc => "cm32p2_realloc".to_string(),
2641 },
2642 ManglingAndAbi::Legacy(abi) => match export {
2643 WasmExport::Func {
2644 interface,
2645 func,
2646 kind,
2647 } => {
2648 let mut name = abi.export_prefix().to_string();
2649 match kind {
2650 WasmExportKind::Normal => {}
2651 WasmExportKind::PostReturn => name.push_str("cabi_post_"),
2652 WasmExportKind::Callback => {
2653 assert!(matches!(abi, LiftLowerAbi::AsyncCallback));
2654 name = format!("[callback]{name}")
2655 }
2656 }
2657 if let Some(interface) = interface {
2658 let s = self.name_world_key(interface);
2659 name.push_str(&s);
2660 name.push_str("#");
2661 }
2662 name.push_str(&func.name);
2663 name
2664 }
2665 WasmExport::ResourceDtor {
2666 interface,
2667 resource,
2668 } => {
2669 let name = self.types[resource].name.as_ref().unwrap();
2670 let interface = self.name_world_key(interface);
2671 format!("{}{interface}#[dtor]{name}", abi.export_prefix())
2672 }
2673 WasmExport::Memory => "memory".to_string(),
2674 WasmExport::Initialize => "_initialize".to_string(),
2675 WasmExport::Realloc => "cabi_realloc".to_string(),
2676 },
2677 }
2678 }
2679}
2680
2681#[derive(Debug)]
2683pub enum WasmImport<'a> {
2684 Func {
2686 interface: Option<&'a WorldKey>,
2691
2692 func: &'a Function,
2694 },
2695
2696 ResourceIntrinsic {
2698 interface: Option<&'a WorldKey>,
2700
2701 resource: TypeId,
2703
2704 intrinsic: ResourceIntrinsic,
2706 },
2707}
2708
2709#[derive(Debug)]
2712pub enum ResourceIntrinsic {
2713 ImportedDrop,
2714 ExportedDrop,
2715 ExportedNew,
2716 ExportedRep,
2717}
2718
2719#[derive(Debug)]
2722pub enum WasmExportKind {
2723 Normal,
2725
2726 PostReturn,
2728
2729 Callback,
2731}
2732
2733#[derive(Debug)]
2736pub enum WasmExport<'a> {
2737 Func {
2739 interface: Option<&'a WorldKey>,
2742
2743 func: &'a Function,
2745
2746 kind: WasmExportKind,
2748 },
2749
2750 ResourceDtor {
2752 interface: &'a WorldKey,
2754 resource: TypeId,
2756 },
2757
2758 Memory,
2760
2761 Initialize,
2763
2764 Realloc,
2766}
2767
2768#[derive(Default)]
2771pub struct Remap {
2772 pub types: Vec<Option<TypeId>>,
2773 pub interfaces: Vec<Option<InterfaceId>>,
2774 pub worlds: Vec<Option<WorldId>>,
2775 pub packages: Vec<PackageId>,
2776
2777 own_handles: HashMap<TypeId, TypeId>,
2787
2788 type_has_borrow: Vec<Option<bool>>,
2789}
2790
2791fn apply_map<T>(map: &[Option<Id<T>>], id: Id<T>, desc: &str, span: Option<Span>) -> Result<Id<T>> {
2792 match map.get(id.index()) {
2793 Some(Some(id)) => Ok(*id),
2794 Some(None) => {
2795 let msg = format!(
2796 "found a reference to a {desc} which is excluded \
2797 due to its feature not being activated"
2798 );
2799 match span {
2800 Some(span) => Err(Error::new(span, msg).into()),
2801 None => bail!("{msg}"),
2802 }
2803 }
2804 None => panic!("request to remap a {desc} that has not yet been registered"),
2805 }
2806}
2807
2808fn rename(original_name: &str, include_name: &IncludeName) -> Option<String> {
2809 if original_name == include_name.name {
2810 return Some(include_name.as_.to_string());
2811 }
2812 let (kind, rest) = original_name.split_once(']')?;
2813 match rest.split_once('.') {
2814 Some((name, rest)) if name == include_name.name => {
2815 Some(format!("{kind}]{}.{rest}", include_name.as_))
2816 }
2817 _ if rest == include_name.name => Some(format!("{kind}]{}", include_name.as_)),
2818 _ => None,
2819 }
2820}
2821
2822impl Remap {
2823 pub fn map_type(&self, id: TypeId, span: Option<Span>) -> Result<TypeId> {
2824 apply_map(&self.types, id, "type", span)
2825 }
2826
2827 pub fn map_interface(&self, id: InterfaceId, span: Option<Span>) -> Result<InterfaceId> {
2828 apply_map(&self.interfaces, id, "interface", span)
2829 }
2830
2831 pub fn map_world(&self, id: WorldId, span: Option<Span>) -> Result<WorldId> {
2832 apply_map(&self.worlds, id, "world", span)
2833 }
2834
2835 fn append(
2836 &mut self,
2837 resolve: &mut Resolve,
2838 unresolved: UnresolvedPackage,
2839 ) -> Result<PackageId> {
2840 let pkgid = resolve.packages.alloc(Package {
2841 name: unresolved.name.clone(),
2842 docs: unresolved.docs.clone(),
2843 interfaces: Default::default(),
2844 worlds: Default::default(),
2845 });
2846 let prev = resolve.package_names.insert(unresolved.name.clone(), pkgid);
2847 if let Some(prev) = prev {
2848 resolve.package_names.insert(unresolved.name.clone(), prev);
2849 bail!(
2850 "attempting to re-add package `{}` when it's already present in this `Resolve`",
2851 unresolved.name,
2852 );
2853 }
2854
2855 self.process_foreign_deps(resolve, pkgid, &unresolved)?;
2856
2857 let foreign_types = self.types.len();
2858 let foreign_interfaces = self.interfaces.len();
2859 let foreign_worlds = self.worlds.len();
2860
2861 assert_eq!(unresolved.types.len(), unresolved.type_spans.len());
2867 for ((id, mut ty), span) in unresolved
2868 .types
2869 .into_iter()
2870 .zip(&unresolved.type_spans)
2871 .skip(foreign_types)
2872 {
2873 if !resolve.include_type(&ty, pkgid, *span)? {
2874 self.types.push(None);
2875 continue;
2876 }
2877
2878 self.update_typedef(resolve, &mut ty, Some(*span))?;
2879 let new_id = resolve.types.alloc(ty);
2880 assert_eq!(self.types.len(), id.index());
2881
2882 let new_id = match resolve.types[new_id] {
2883 TypeDef {
2888 name: None,
2889 owner: TypeOwner::None,
2890 kind: TypeDefKind::Handle(Handle::Own(id)),
2891 docs: _,
2892 stability: _,
2893 } => *self.own_handles.entry(id).or_insert(new_id),
2894
2895 _ => new_id,
2898 };
2899 self.types.push(Some(new_id));
2900 }
2901
2902 assert_eq!(
2905 unresolved.interfaces.len(),
2906 unresolved.interface_spans.len()
2907 );
2908 for ((id, mut iface), span) in unresolved
2909 .interfaces
2910 .into_iter()
2911 .zip(&unresolved.interface_spans)
2912 .skip(foreign_interfaces)
2913 {
2914 if !resolve
2915 .include_stability(&iface.stability, &pkgid, Some(span.span))
2916 .with_context(|| {
2917 format!(
2918 "failed to process feature gate for interface [{}] in package [{}]",
2919 iface
2920 .name
2921 .as_ref()
2922 .map(String::as_str)
2923 .unwrap_or("<unknown>"),
2924 resolve.packages[pkgid].name,
2925 )
2926 })?
2927 {
2928 self.interfaces.push(None);
2929 continue;
2930 }
2931 assert!(iface.package.is_none());
2932 iface.package = Some(pkgid);
2933 self.update_interface(resolve, &mut iface, Some(span))?;
2934 let new_id = resolve.interfaces.alloc(iface);
2935 assert_eq!(self.interfaces.len(), id.index());
2936 self.interfaces.push(Some(new_id));
2937 }
2938
2939 for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2942 let id = match id {
2943 Some(id) => *id,
2944 None => continue,
2945 };
2946 match &mut resolve.types[id].owner {
2947 TypeOwner::Interface(id) => {
2948 let span = unresolved.type_spans[i];
2949 *id = self.map_interface(*id, Some(span))
2950 .with_context(|| {
2951 "this type is not gated by a feature but its interface is gated by a feature"
2952 })?;
2953 }
2954 TypeOwner::World(_) | TypeOwner::None => {}
2955 }
2956 }
2957
2958 assert_eq!(unresolved.worlds.len(), unresolved.world_spans.len());
2966 for ((id, mut world), span) in unresolved
2967 .worlds
2968 .into_iter()
2969 .zip(&unresolved.world_spans)
2970 .skip(foreign_worlds)
2971 {
2972 if !resolve
2973 .include_stability(&world.stability, &pkgid, Some(span.span))
2974 .with_context(|| {
2975 format!(
2976 "failed to process feature gate for world [{}] in package [{}]",
2977 world.name, resolve.packages[pkgid].name,
2978 )
2979 })?
2980 {
2981 self.worlds.push(None);
2982 continue;
2983 }
2984 self.update_world(&mut world, resolve, &pkgid, &span)?;
2985
2986 let new_id = resolve.worlds.alloc(world);
2987 assert_eq!(self.worlds.len(), id.index());
2988 self.worlds.push(Some(new_id));
2989 }
2990
2991 for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2993 let id = match id {
2994 Some(id) => *id,
2995 None => continue,
2996 };
2997 match &mut resolve.types[id].owner {
2998 TypeOwner::World(id) => {
2999 let span = unresolved.type_spans[i];
3000 *id = self.map_world(*id, Some(span))
3001 .with_context(|| {
3002 "this type is not gated by a feature but its interface is gated by a feature"
3003 })?;
3004 }
3005 TypeOwner::Interface(_) | TypeOwner::None => {}
3006 }
3007 }
3008
3009 assert_eq!(self.worlds.len(), unresolved.world_spans.len());
3026 for (id, span) in self
3027 .worlds
3028 .iter()
3029 .zip(unresolved.world_spans.iter())
3030 .skip(foreign_worlds)
3031 {
3032 let Some(id) = *id else {
3033 continue;
3034 };
3035 self.process_world_includes(id, resolve, &pkgid, &span)?;
3036
3037 resolve.elaborate_world(id).with_context(|| {
3038 Error::new(
3039 span.span,
3040 format!(
3041 "failed to elaborate world imports/exports of `{}`",
3042 resolve.worlds[id].name
3043 ),
3044 )
3045 })?;
3046 }
3047
3048 for id in self.interfaces.iter().skip(foreign_interfaces) {
3050 let id = match id {
3051 Some(id) => *id,
3052 None => continue,
3053 };
3054 let iface = &mut resolve.interfaces[id];
3055 iface.package = Some(pkgid);
3056 if let Some(name) = &iface.name {
3057 let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), id);
3058 assert!(prev.is_none());
3059 }
3060 }
3061 for id in self.worlds.iter().skip(foreign_worlds) {
3062 let id = match id {
3063 Some(id) => *id,
3064 None => continue,
3065 };
3066 let world = &mut resolve.worlds[id];
3067 world.package = Some(pkgid);
3068 let prev = resolve.packages[pkgid]
3069 .worlds
3070 .insert(world.name.clone(), id);
3071 assert!(prev.is_none());
3072 }
3073 Ok(pkgid)
3074 }
3075
3076 fn process_foreign_deps(
3077 &mut self,
3078 resolve: &mut Resolve,
3079 pkgid: PackageId,
3080 unresolved: &UnresolvedPackage,
3081 ) -> Result<()> {
3082 let mut world_to_package = HashMap::new();
3085 let mut interface_to_package = HashMap::new();
3086 for (i, (pkg_name, worlds_or_ifaces)) in unresolved.foreign_deps.iter().enumerate() {
3087 for (name, (item, stabilities)) in worlds_or_ifaces {
3088 match item {
3089 AstItem::Interface(unresolved_interface_id) => {
3090 let prev = interface_to_package.insert(
3091 *unresolved_interface_id,
3092 (pkg_name, name, unresolved.foreign_dep_spans[i], stabilities),
3093 );
3094 assert!(prev.is_none());
3095 }
3096 AstItem::World(unresolved_world_id) => {
3097 let prev = world_to_package.insert(
3098 *unresolved_world_id,
3099 (pkg_name, name, unresolved.foreign_dep_spans[i], stabilities),
3100 );
3101 assert!(prev.is_none());
3102 }
3103 }
3104 }
3105 }
3106
3107 self.process_foreign_interfaces(unresolved, &interface_to_package, resolve, &pkgid)?;
3111
3112 self.process_foreign_worlds(unresolved, &world_to_package, resolve, &pkgid)?;
3116
3117 self.process_foreign_types(unresolved, pkgid, resolve)?;
3120
3121 for (id, span) in unresolved.required_resource_types.iter() {
3122 let Ok(mut id) = self.map_type(*id, Some(*span)) else {
3127 continue;
3128 };
3129 loop {
3130 match resolve.types[id].kind {
3131 TypeDefKind::Type(Type::Id(i)) => id = i,
3132 TypeDefKind::Resource => break,
3133 _ => bail!(Error::new(
3134 *span,
3135 format!("type used in a handle must be a resource"),
3136 )),
3137 }
3138 }
3139 }
3140
3141 #[cfg(debug_assertions)]
3142 resolve.assert_valid();
3143
3144 Ok(())
3145 }
3146
3147 fn process_foreign_interfaces(
3148 &mut self,
3149 unresolved: &UnresolvedPackage,
3150 interface_to_package: &HashMap<InterfaceId, (&PackageName, &String, Span, &Vec<Stability>)>,
3151 resolve: &mut Resolve,
3152 parent_pkg_id: &PackageId,
3153 ) -> Result<(), anyhow::Error> {
3154 for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() {
3155 let (pkg_name, interface, span, stabilities) =
3156 match interface_to_package.get(&unresolved_iface_id) {
3157 Some(items) => *items,
3158 None => break,
3162 };
3163
3164 let pkgid = resolve
3165 .package_names
3166 .get(pkg_name)
3167 .copied()
3168 .ok_or_else(|| {
3169 PackageNotFoundError::new(
3170 span,
3171 pkg_name.clone(),
3172 resolve.package_names.keys().cloned().collect(),
3173 )
3174 })?;
3175
3176 assert!(unresolved_iface.functions.is_empty());
3178
3179 let pkg = &resolve.packages[pkgid];
3180 let span = &unresolved.interface_spans[unresolved_iface_id.index()];
3181
3182 let mut enabled = false;
3183 for stability in stabilities {
3184 if resolve.include_stability(stability, parent_pkg_id, Some(span.span))? {
3185 enabled = true;
3186 break;
3187 }
3188 }
3189
3190 if !enabled {
3191 self.interfaces.push(None);
3192 continue;
3193 }
3194
3195 let iface_id = pkg
3196 .interfaces
3197 .get(interface)
3198 .copied()
3199 .ok_or_else(|| Error::new(span.span, "interface not found in package"))?;
3200 assert_eq!(self.interfaces.len(), unresolved_iface_id.index());
3201 self.interfaces.push(Some(iface_id));
3202 }
3203 for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) {
3204 assert!(
3205 interface_to_package.get(&id).is_none(),
3206 "found foreign interface after local interface"
3207 );
3208 }
3209 Ok(())
3210 }
3211
3212 fn process_foreign_worlds(
3213 &mut self,
3214 unresolved: &UnresolvedPackage,
3215 world_to_package: &HashMap<WorldId, (&PackageName, &String, Span, &Vec<Stability>)>,
3216 resolve: &mut Resolve,
3217 parent_pkg_id: &PackageId,
3218 ) -> Result<(), anyhow::Error> {
3219 for (unresolved_world_id, _) in unresolved.worlds.iter() {
3220 let (pkg_name, world, span, stabilities) =
3221 match world_to_package.get(&unresolved_world_id) {
3222 Some(items) => *items,
3223 None => break,
3226 };
3227
3228 let pkgid = resolve
3229 .package_names
3230 .get(pkg_name)
3231 .copied()
3232 .ok_or_else(|| Error::new(span, "package not found"))?;
3233 let pkg = &resolve.packages[pkgid];
3234 let span = &unresolved.world_spans[unresolved_world_id.index()];
3235
3236 let mut enabled = false;
3237 for stability in stabilities {
3238 if resolve.include_stability(stability, parent_pkg_id, Some(span.span))? {
3239 enabled = true;
3240 break;
3241 }
3242 }
3243
3244 if !enabled {
3245 self.worlds.push(None);
3246 continue;
3247 }
3248
3249 let world_id = pkg
3250 .worlds
3251 .get(world)
3252 .copied()
3253 .ok_or_else(|| Error::new(span.span, "world not found in package"))?;
3254 assert_eq!(self.worlds.len(), unresolved_world_id.index());
3255 self.worlds.push(Some(world_id));
3256 }
3257 for (id, _) in unresolved.worlds.iter().skip(self.worlds.len()) {
3258 assert!(
3259 world_to_package.get(&id).is_none(),
3260 "found foreign world after local world"
3261 );
3262 }
3263 Ok(())
3264 }
3265
3266 fn process_foreign_types(
3267 &mut self,
3268 unresolved: &UnresolvedPackage,
3269 pkgid: PackageId,
3270 resolve: &mut Resolve,
3271 ) -> Result<(), anyhow::Error> {
3272 for ((unresolved_type_id, unresolved_ty), span) in
3273 unresolved.types.iter().zip(&unresolved.type_spans)
3274 {
3275 match unresolved_ty.kind {
3279 TypeDefKind::Unknown => {}
3280 _ => break,
3281 }
3282
3283 if !resolve.include_type(unresolved_ty, pkgid, *span)? {
3284 self.types.push(None);
3285 continue;
3286 }
3287
3288 let unresolved_iface_id = match unresolved_ty.owner {
3289 TypeOwner::Interface(id) => id,
3290 _ => unreachable!(),
3291 };
3292 let iface_id = self.map_interface(unresolved_iface_id, None)?;
3293 let name = unresolved_ty.name.as_ref().unwrap();
3294 let span = unresolved.unknown_type_spans[unresolved_type_id.index()];
3295 let type_id = *resolve.interfaces[iface_id]
3296 .types
3297 .get(name)
3298 .ok_or_else(|| {
3299 Error::new(span, format!("type `{name}` not defined in interface"))
3300 })?;
3301 assert_eq!(self.types.len(), unresolved_type_id.index());
3302 self.types.push(Some(type_id));
3303 }
3304 for (_, ty) in unresolved.types.iter().skip(self.types.len()) {
3305 if let TypeDefKind::Unknown = ty.kind {
3306 panic!("unknown type after defined type");
3307 }
3308 }
3309 Ok(())
3310 }
3311
3312 fn update_typedef(
3313 &mut self,
3314 resolve: &mut Resolve,
3315 ty: &mut TypeDef,
3316 span: Option<Span>,
3317 ) -> Result<()> {
3318 use crate::TypeDefKind::*;
3321 match &mut ty.kind {
3322 Handle(handle) => match handle {
3323 crate::Handle::Own(ty) | crate::Handle::Borrow(ty) => {
3324 self.update_type_id(ty, span)?
3325 }
3326 },
3327 Resource => {}
3328 Record(r) => {
3329 for field in r.fields.iter_mut() {
3330 self.update_ty(resolve, &mut field.ty, span)
3331 .with_context(|| format!("failed to update field `{}`", field.name))?;
3332 }
3333 }
3334 Tuple(t) => {
3335 for ty in t.types.iter_mut() {
3336 self.update_ty(resolve, ty, span)?;
3337 }
3338 }
3339 Variant(v) => {
3340 for case in v.cases.iter_mut() {
3341 if let Some(t) = &mut case.ty {
3342 self.update_ty(resolve, t, span)?;
3343 }
3344 }
3345 }
3346 Option(t) | List(t, ..) | FixedSizeList(t, ..) | Future(Some(t)) | Stream(Some(t)) => {
3347 self.update_ty(resolve, t, span)?
3348 }
3349 Map(k, v) => {
3350 self.update_ty(resolve, k, span)?;
3351 self.update_ty(resolve, v, span)?;
3352 }
3353 Result(r) => {
3354 if let Some(ty) = &mut r.ok {
3355 self.update_ty(resolve, ty, span)?;
3356 }
3357 if let Some(ty) = &mut r.err {
3358 self.update_ty(resolve, ty, span)?;
3359 }
3360 }
3361
3362 Type(crate::Type::Id(id)) => self.update_type_id(id, span)?,
3367 Type(_) => {}
3368
3369 Flags(_) | Enum(_) | Future(None) | Stream(None) => {}
3371
3372 Unknown => unreachable!(),
3373 }
3374
3375 Ok(())
3376 }
3377
3378 fn update_ty(
3379 &mut self,
3380 resolve: &mut Resolve,
3381 ty: &mut Type,
3382 span: Option<Span>,
3383 ) -> Result<()> {
3384 let id = match ty {
3385 Type::Id(id) => id,
3386 _ => return Ok(()),
3387 };
3388 self.update_type_id(id, span)?;
3389
3390 let mut cur = *id;
3395 let points_to_resource = loop {
3396 match resolve.types[cur].kind {
3397 TypeDefKind::Type(Type::Id(id)) => cur = id,
3398 TypeDefKind::Resource => break true,
3399 _ => break false,
3400 }
3401 };
3402
3403 if points_to_resource {
3404 *id = *self.own_handles.entry(*id).or_insert_with(|| {
3405 resolve.types.alloc(TypeDef {
3406 name: None,
3407 owner: TypeOwner::None,
3408 kind: TypeDefKind::Handle(Handle::Own(*id)),
3409 docs: Default::default(),
3410 stability: Default::default(),
3411 })
3412 });
3413 }
3414 Ok(())
3415 }
3416
3417 fn update_type_id(&self, id: &mut TypeId, span: Option<Span>) -> Result<()> {
3418 *id = self.map_type(*id, span)?;
3419 Ok(())
3420 }
3421
3422 fn update_interface(
3423 &mut self,
3424 resolve: &mut Resolve,
3425 iface: &mut Interface,
3426 spans: Option<&InterfaceSpan>,
3427 ) -> Result<()> {
3428 iface.types.retain(|_, ty| self.types[ty.index()].is_some());
3429 let iface_pkg_id = iface.package.as_ref().unwrap_or_else(|| {
3430 panic!(
3431 "unexpectedly missing package on interface [{}]",
3432 iface
3433 .name
3434 .as_ref()
3435 .map(String::as_str)
3436 .unwrap_or("<unknown>"),
3437 )
3438 });
3439
3440 for (_name, ty) in iface.types.iter_mut() {
3443 self.update_type_id(ty, spans.map(|s| s.span))?;
3444 }
3445 if let Some(spans) = spans {
3446 assert_eq!(iface.functions.len(), spans.funcs.len());
3447 }
3448 for (i, (func_name, func)) in iface.functions.iter_mut().enumerate() {
3449 let span = spans.map(|s| s.funcs[i]);
3450 if !resolve
3451 .include_stability(&func.stability, iface_pkg_id, span)
3452 .with_context(|| {
3453 format!(
3454 "failed to process feature gate for function [{func_name}] in package [{}]",
3455 resolve.packages[*iface_pkg_id].name,
3456 )
3457 })?
3458 {
3459 continue;
3460 }
3461 self.update_function(resolve, func, span)
3462 .with_context(|| format!("failed to update function `{}`", func.name))?;
3463 }
3464
3465 for (name, func) in mem::take(&mut iface.functions) {
3468 if resolve.include_stability(&func.stability, iface_pkg_id, None)? {
3469 iface.functions.insert(name, func);
3470 }
3471 }
3472
3473 Ok(())
3474 }
3475
3476 fn update_function(
3477 &mut self,
3478 resolve: &mut Resolve,
3479 func: &mut Function,
3480 span: Option<Span>,
3481 ) -> Result<()> {
3482 if let Some(id) = func.kind.resource_mut() {
3483 self.update_type_id(id, span)?;
3484 }
3485 for (_, ty) in func.params.iter_mut() {
3486 self.update_ty(resolve, ty, span)?;
3487 }
3488 if let Some(ty) = &mut func.result {
3489 self.update_ty(resolve, ty, span)?;
3490 }
3491
3492 if let Some(ty) = &func.result {
3493 if self.type_has_borrow(resolve, ty) {
3494 match span {
3495 Some(span) => {
3496 bail!(Error::new(
3497 span,
3498 format!(
3499 "function returns a type which contains \
3500 a `borrow<T>` which is not supported"
3501 )
3502 ))
3503 }
3504 None => unreachable!(),
3505 }
3506 }
3507 }
3508
3509 Ok(())
3510 }
3511
3512 fn update_world(
3513 &mut self,
3514 world: &mut World,
3515 resolve: &mut Resolve,
3516 pkg_id: &PackageId,
3517 spans: &WorldSpan,
3518 ) -> Result<()> {
3519 assert_eq!(world.imports.len(), spans.imports.len());
3520 assert_eq!(world.exports.len(), spans.exports.len());
3521
3522 let imports = mem::take(&mut world.imports).into_iter();
3526 let imports = imports.zip(&spans.imports).map(|p| (p, true));
3527 let exports = mem::take(&mut world.exports).into_iter();
3528 let exports = exports.zip(&spans.exports).map(|p| (p, false));
3529 for (((mut name, mut item), span), import) in imports.chain(exports) {
3530 if let WorldItem::Type(id) = &mut item {
3533 *id = self.map_type(*id, Some(*span))?;
3534 }
3535 let stability = item.stability(resolve);
3536 if !resolve
3537 .include_stability(stability, pkg_id, Some(*span))
3538 .with_context(|| format!("failed to process world item in `{}`", world.name))?
3539 {
3540 continue;
3541 }
3542 self.update_world_key(&mut name, Some(*span))?;
3543 match &mut item {
3544 WorldItem::Interface { id, .. } => {
3545 *id = self.map_interface(*id, Some(*span))?;
3546 }
3547 WorldItem::Function(f) => {
3548 self.update_function(resolve, f, Some(*span))?;
3549 }
3550 WorldItem::Type(_) => {
3551 }
3553 }
3554
3555 let dst = if import {
3556 &mut world.imports
3557 } else {
3558 &mut world.exports
3559 };
3560 let prev = dst.insert(name, item);
3561 assert!(prev.is_none());
3562 }
3563
3564 Ok(())
3565 }
3566
3567 fn process_world_includes(
3568 &self,
3569 id: WorldId,
3570 resolve: &mut Resolve,
3571 pkg_id: &PackageId,
3572 spans: &WorldSpan,
3573 ) -> Result<()> {
3574 let world = &mut resolve.worlds[id];
3575 assert_eq!(world.includes.len(), spans.includes.len());
3578 let includes = mem::take(&mut world.includes);
3579 let include_names = mem::take(&mut world.include_names);
3580 for (((stability, include_world), span), names) in includes
3581 .into_iter()
3582 .zip(&spans.includes)
3583 .zip(&include_names)
3584 {
3585 if !resolve
3586 .include_stability(&stability, pkg_id, Some(*span))
3587 .with_context(|| {
3588 format!(
3589 "failed to process feature gate for included world [{}] in package [{}]",
3590 resolve.worlds[include_world].name.as_str(),
3591 resolve.packages[*pkg_id].name
3592 )
3593 })?
3594 {
3595 continue;
3596 }
3597 self.resolve_include(id, include_world, names, *span, pkg_id, resolve)?;
3598 }
3599
3600 Self::validate_world_case_insensitive_names(resolve, id)?;
3602
3603 Ok(())
3604 }
3605
3606 fn validate_world_case_insensitive_names(resolve: &Resolve, world_id: WorldId) -> Result<()> {
3610 let world = &resolve.worlds[world_id];
3611
3612 let validate_names = |items: &IndexMap<WorldKey, WorldItem>,
3614 item_type: &str|
3615 -> Result<()> {
3616 let mut seen_lowercase: HashMap<String, String> = HashMap::new();
3617
3618 for key in items.keys() {
3619 if let WorldKey::Name(name) = key {
3621 let lowercase_name = name.to_lowercase();
3622
3623 if let Some(existing_name) = seen_lowercase.get(&lowercase_name) {
3624 if existing_name != name {
3627 bail!(
3628 "{item_type} `{name}` conflicts with {item_type} `{existing_name}` \
3629 (kebab-case identifiers are case-insensitive)"
3630 );
3631 }
3632 }
3633
3634 seen_lowercase.insert(lowercase_name, name.clone());
3635 }
3636 }
3637
3638 Ok(())
3639 };
3640
3641 validate_names(&world.imports, "import")
3642 .with_context(|| format!("failed to validate imports in world `{}`", world.name))?;
3643 validate_names(&world.exports, "export")
3644 .with_context(|| format!("failed to validate exports in world `{}`", world.name))?;
3645
3646 Ok(())
3647 }
3648
3649 fn update_world_key(&self, key: &mut WorldKey, span: Option<Span>) -> Result<()> {
3650 match key {
3651 WorldKey::Name(_) => {}
3652 WorldKey::Interface(id) => {
3653 *id = self.map_interface(*id, span)?;
3654 }
3655 }
3656 Ok(())
3657 }
3658
3659 fn resolve_include(
3660 &self,
3661 id: WorldId,
3662 include_world_id_orig: WorldId,
3663 names: &[IncludeName],
3664 span: Span,
3665 pkg_id: &PackageId,
3666 resolve: &mut Resolve,
3667 ) -> Result<()> {
3668 let world = &resolve.worlds[id];
3669 let include_world_id = self.map_world(include_world_id_orig, Some(span))?;
3670 let include_world = resolve.worlds[include_world_id].clone();
3671 let mut names_ = names.to_owned();
3672 let is_external_include = world.package != include_world.package;
3673
3674 for import in include_world.imports.iter() {
3676 self.remove_matching_name(import, &mut names_);
3677 }
3678 for export in include_world.exports.iter() {
3679 self.remove_matching_name(export, &mut names_);
3680 }
3681 if !names_.is_empty() {
3682 bail!(Error::new(
3683 span,
3684 format!(
3685 "no import or export kebab-name `{}`. Note that an ID does not support renaming",
3686 names_[0].name
3687 ),
3688 ));
3689 }
3690
3691 let mut cloner = clone::Cloner::new(
3692 resolve,
3693 TypeOwner::World(if is_external_include {
3694 include_world_id
3695 } else {
3696 include_world_id
3697 }),
3699 TypeOwner::World(id),
3700 );
3701 cloner.new_package = Some(*pkg_id);
3702
3703 for import in include_world.imports.iter() {
3705 self.resolve_include_item(
3706 &mut cloner,
3707 names,
3708 |resolve| &mut resolve.worlds[id].imports,
3709 import,
3710 span,
3711 "import",
3712 is_external_include,
3713 )?;
3714 }
3715
3716 for export in include_world.exports.iter() {
3717 self.resolve_include_item(
3718 &mut cloner,
3719 names,
3720 |resolve| &mut resolve.worlds[id].exports,
3721 export,
3722 span,
3723 "export",
3724 is_external_include,
3725 )?;
3726 }
3727 Ok(())
3728 }
3729
3730 fn resolve_include_item(
3731 &self,
3732 cloner: &mut clone::Cloner<'_>,
3733 names: &[IncludeName],
3734 get_items: impl Fn(&mut Resolve) -> &mut IndexMap<WorldKey, WorldItem>,
3735 item: (&WorldKey, &WorldItem),
3736 span: Span,
3737 item_type: &str,
3738 is_external_include: bool,
3739 ) -> Result<()> {
3740 match item.0 {
3741 WorldKey::Name(n) => {
3742 let n = names
3743 .into_iter()
3744 .find_map(|include_name| rename(n, include_name))
3745 .unwrap_or(n.clone());
3746
3747 let mut new_item = item.1.clone();
3753 let key = WorldKey::Name(n.clone());
3754 cloner.world_item(&key, &mut new_item, &mut CloneMaps::default());
3755 match &mut new_item {
3756 WorldItem::Function(f) => f.name = n.clone(),
3757 WorldItem::Type(id) => cloner.resolve.types[*id].name = Some(n.clone()),
3758 WorldItem::Interface { .. } => {}
3759 }
3760
3761 let prev = get_items(cloner.resolve).insert(key, new_item);
3762 if prev.is_some() {
3763 bail!(Error::new(
3764 span,
3765 format!("{item_type} of `{n}` shadows previously {item_type}ed items"),
3766 ))
3767 }
3768 }
3769 key @ WorldKey::Interface(_) => {
3770 let prev = get_items(cloner.resolve)
3771 .entry(key.clone())
3772 .or_insert(item.1.clone());
3773 match (&item.1, prev) {
3774 (
3775 WorldItem::Interface {
3776 id: aid,
3777 stability: astability,
3778 },
3779 WorldItem::Interface {
3780 id: bid,
3781 stability: bstability,
3782 },
3783 ) => {
3784 assert_eq!(*aid, *bid);
3785 merge_include_stability(astability, bstability, is_external_include)?;
3786 }
3787 (WorldItem::Interface { .. }, _) => unreachable!(),
3788 (WorldItem::Function(_), _) => unreachable!(),
3789 (WorldItem::Type(_), _) => unreachable!(),
3790 }
3791 }
3792 };
3793
3794 Ok(())
3795 }
3796
3797 fn remove_matching_name(&self, item: (&WorldKey, &WorldItem), names: &mut Vec<IncludeName>) {
3798 match item.0 {
3799 WorldKey::Name(n) => {
3800 names.retain(|name| rename(n, name).is_none());
3801 }
3802 _ => {}
3803 }
3804 }
3805
3806 fn type_has_borrow(&mut self, resolve: &Resolve, ty: &Type) -> bool {
3807 let id = match ty {
3808 Type::Id(id) => *id,
3809 _ => return false,
3810 };
3811
3812 if let Some(Some(has_borrow)) = self.type_has_borrow.get(id.index()) {
3813 return *has_borrow;
3814 }
3815
3816 let result = self.typedef_has_borrow(resolve, &resolve.types[id]);
3817 if self.type_has_borrow.len() <= id.index() {
3818 self.type_has_borrow.resize(id.index() + 1, None);
3819 }
3820 self.type_has_borrow[id.index()] = Some(result);
3821 result
3822 }
3823
3824 fn typedef_has_borrow(&mut self, resolve: &Resolve, ty: &TypeDef) -> bool {
3825 match &ty.kind {
3826 TypeDefKind::Type(t) => self.type_has_borrow(resolve, t),
3827 TypeDefKind::Variant(v) => v
3828 .cases
3829 .iter()
3830 .filter_map(|case| case.ty.as_ref())
3831 .any(|ty| self.type_has_borrow(resolve, ty)),
3832 TypeDefKind::Handle(Handle::Borrow(_)) => true,
3833 TypeDefKind::Handle(Handle::Own(_)) => false,
3834 TypeDefKind::Resource => false,
3835 TypeDefKind::Record(r) => r
3836 .fields
3837 .iter()
3838 .any(|case| self.type_has_borrow(resolve, &case.ty)),
3839 TypeDefKind::Flags(_) => false,
3840 TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.type_has_borrow(resolve, t)),
3841 TypeDefKind::Enum(_) => false,
3842 TypeDefKind::List(ty)
3843 | TypeDefKind::FixedSizeList(ty, ..)
3844 | TypeDefKind::Future(Some(ty))
3845 | TypeDefKind::Stream(Some(ty))
3846 | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty),
3847 TypeDefKind::Map(k, v) => {
3848 self.type_has_borrow(resolve, k) || self.type_has_borrow(resolve, v)
3849 }
3850 TypeDefKind::Result(r) => [&r.ok, &r.err]
3851 .iter()
3852 .filter_map(|t| t.as_ref())
3853 .any(|t| self.type_has_borrow(resolve, t)),
3854 TypeDefKind::Future(None) | TypeDefKind::Stream(None) => false,
3855 TypeDefKind::Unknown => unreachable!(),
3856 }
3857 }
3858}
3859
3860struct MergeMap<'a> {
3861 package_map: HashMap<PackageId, PackageId>,
3864
3865 interface_map: HashMap<InterfaceId, InterfaceId>,
3868
3869 type_map: HashMap<TypeId, TypeId>,
3872
3873 world_map: HashMap<WorldId, WorldId>,
3876
3877 interfaces_to_add: Vec<(String, PackageId, InterfaceId)>,
3885 worlds_to_add: Vec<(String, PackageId, WorldId)>,
3886
3887 from: &'a Resolve,
3889
3890 into: &'a Resolve,
3892}
3893
3894impl<'a> MergeMap<'a> {
3895 fn new(from: &'a Resolve, into: &'a Resolve) -> MergeMap<'a> {
3896 MergeMap {
3897 package_map: Default::default(),
3898 interface_map: Default::default(),
3899 type_map: Default::default(),
3900 world_map: Default::default(),
3901 interfaces_to_add: Default::default(),
3902 worlds_to_add: Default::default(),
3903 from,
3904 into,
3905 }
3906 }
3907
3908 fn build(&mut self) -> Result<()> {
3909 for from_id in self.from.topological_packages() {
3910 let from = &self.from.packages[from_id];
3911 let into_id = match self.into.package_names.get(&from.name) {
3912 Some(id) => *id,
3913
3914 None => {
3917 log::trace!("adding unique package {}", from.name);
3918 continue;
3919 }
3920 };
3921 log::trace!("merging duplicate package {}", from.name);
3922
3923 self.build_package(from_id, into_id).with_context(|| {
3924 format!("failed to merge package `{}` into existing copy", from.name)
3925 })?;
3926 }
3927
3928 Ok(())
3929 }
3930
3931 fn build_package(&mut self, from_id: PackageId, into_id: PackageId) -> Result<()> {
3932 let prev = self.package_map.insert(from_id, into_id);
3933 assert!(prev.is_none());
3934
3935 let from = &self.from.packages[from_id];
3936 let into = &self.into.packages[into_id];
3937
3938 for (name, from_interface_id) in from.interfaces.iter() {
3942 let into_interface_id = match into.interfaces.get(name) {
3943 Some(id) => *id,
3944 None => {
3945 log::trace!("adding unique interface {name}");
3946 self.interfaces_to_add
3947 .push((name.clone(), into_id, *from_interface_id));
3948 continue;
3949 }
3950 };
3951
3952 log::trace!("merging duplicate interfaces {name}");
3953 self.build_interface(*from_interface_id, into_interface_id)
3954 .with_context(|| format!("failed to merge interface `{name}`"))?;
3955 }
3956
3957 for (name, from_world_id) in from.worlds.iter() {
3958 let into_world_id = match into.worlds.get(name) {
3959 Some(id) => *id,
3960 None => {
3961 log::trace!("adding unique world {name}");
3962 self.worlds_to_add
3963 .push((name.clone(), into_id, *from_world_id));
3964 continue;
3965 }
3966 };
3967
3968 log::trace!("merging duplicate worlds {name}");
3969 self.build_world(*from_world_id, into_world_id)
3970 .with_context(|| format!("failed to merge world `{name}`"))?;
3971 }
3972
3973 Ok(())
3974 }
3975
3976 fn build_interface(&mut self, from_id: InterfaceId, into_id: InterfaceId) -> Result<()> {
3977 let prev = self.interface_map.insert(from_id, into_id);
3978 assert!(prev.is_none());
3979
3980 let from_interface = &self.from.interfaces[from_id];
3981 let into_interface = &self.into.interfaces[into_id];
3982
3983 for (name, from_type_id) in from_interface.types.iter() {
3997 let into_type_id = *into_interface
3998 .types
3999 .get(name)
4000 .ok_or_else(|| anyhow!("expected type `{name}` to be present"))?;
4001 let prev = self.type_map.insert(*from_type_id, into_type_id);
4002 assert!(prev.is_none());
4003
4004 self.build_type_id(*from_type_id, into_type_id)
4005 .with_context(|| format!("mismatch in type `{name}`"))?;
4006 }
4007
4008 for (name, from_func) in from_interface.functions.iter() {
4009 let into_func = match into_interface.functions.get(name) {
4010 Some(func) => func,
4011 None => bail!("expected function `{name}` to be present"),
4012 };
4013 self.build_function(from_func, into_func)
4014 .with_context(|| format!("mismatch in function `{name}`"))?;
4015 }
4016
4017 Ok(())
4018 }
4019
4020 fn build_type_id(&mut self, from_id: TypeId, into_id: TypeId) -> Result<()> {
4021 let _ = from_id;
4025 let _ = into_id;
4026 Ok(())
4027 }
4028
4029 fn build_type(&mut self, from_ty: &Type, into_ty: &Type) -> Result<()> {
4030 match (from_ty, into_ty) {
4031 (Type::Id(from), Type::Id(into)) => {
4032 self.build_type_id(*from, *into)?;
4033 }
4034 (from, into) if from != into => bail!("different kinds of types"),
4035 _ => {}
4036 }
4037 Ok(())
4038 }
4039
4040 fn build_function(&mut self, from_func: &Function, into_func: &Function) -> Result<()> {
4041 if from_func.name != into_func.name {
4042 bail!(
4043 "different function names `{}` and `{}`",
4044 from_func.name,
4045 into_func.name
4046 );
4047 }
4048 match (&from_func.kind, &into_func.kind) {
4049 (FunctionKind::Freestanding, FunctionKind::Freestanding) => {}
4050 (FunctionKind::AsyncFreestanding, FunctionKind::AsyncFreestanding) => {}
4051
4052 (FunctionKind::Method(from), FunctionKind::Method(into))
4053 | (FunctionKind::Static(from), FunctionKind::Static(into))
4054 | (FunctionKind::AsyncMethod(from), FunctionKind::AsyncMethod(into))
4055 | (FunctionKind::AsyncStatic(from), FunctionKind::AsyncStatic(into))
4056 | (FunctionKind::Constructor(from), FunctionKind::Constructor(into)) => {
4057 self.build_type_id(*from, *into)
4058 .context("different function kind types")?;
4059 }
4060
4061 (FunctionKind::Method(_), _)
4062 | (FunctionKind::Constructor(_), _)
4063 | (FunctionKind::Static(_), _)
4064 | (FunctionKind::Freestanding, _)
4065 | (FunctionKind::AsyncFreestanding, _)
4066 | (FunctionKind::AsyncMethod(_), _)
4067 | (FunctionKind::AsyncStatic(_), _) => {
4068 bail!("different function kind types")
4069 }
4070 }
4071
4072 if from_func.params.len() != into_func.params.len() {
4073 bail!("different number of function parameters");
4074 }
4075 for ((from_name, from_ty), (into_name, into_ty)) in
4076 from_func.params.iter().zip(&into_func.params)
4077 {
4078 if from_name != into_name {
4079 bail!("different function parameter names: {from_name} != {into_name}");
4080 }
4081 self.build_type(from_ty, into_ty)
4082 .with_context(|| format!("different function parameter types for `{from_name}`"))?;
4083 }
4084 match (&from_func.result, &into_func.result) {
4085 (Some(from_ty), Some(into_ty)) => {
4086 self.build_type(from_ty, into_ty)
4087 .context("different function result types")?;
4088 }
4089 (None, None) => {}
4090 (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
4091 }
4092 Ok(())
4093 }
4094
4095 fn build_world(&mut self, from_id: WorldId, into_id: WorldId) -> Result<()> {
4096 let prev = self.world_map.insert(from_id, into_id);
4097 assert!(prev.is_none());
4098
4099 let from_world = &self.from.worlds[from_id];
4100 let into_world = &self.into.worlds[into_id];
4101
4102 if from_world.imports.len() != into_world.imports.len() {
4111 bail!("world contains different number of imports than expected");
4112 }
4113 if from_world.exports.len() != into_world.exports.len() {
4114 bail!("world contains different number of exports than expected");
4115 }
4116
4117 for (from_name, from) in from_world.imports.iter() {
4118 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4119 let name_str = self.from.name_world_key(from_name);
4120 let into = into_world
4121 .imports
4122 .get(&into_name)
4123 .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?;
4124 self.match_world_item(from, into)
4125 .with_context(|| format!("import `{name_str}` didn't match target world"))?;
4126 }
4127
4128 for (from_name, from) in from_world.exports.iter() {
4129 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4130 let name_str = self.from.name_world_key(from_name);
4131 let into = into_world
4132 .exports
4133 .get(&into_name)
4134 .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?;
4135 self.match_world_item(from, into)
4136 .with_context(|| format!("export `{name_str}` didn't match target world"))?;
4137 }
4138
4139 Ok(())
4140 }
4141
4142 fn map_name(
4143 from_name: &WorldKey,
4144 interface_map: &HashMap<InterfaceId, InterfaceId>,
4145 ) -> WorldKey {
4146 match from_name {
4147 WorldKey::Name(s) => WorldKey::Name(s.clone()),
4148 WorldKey::Interface(id) => {
4149 WorldKey::Interface(interface_map.get(id).copied().unwrap_or(*id))
4150 }
4151 }
4152 }
4153
4154 fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> Result<()> {
4155 match (from, into) {
4156 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
4157 match (
4158 &self.from.interfaces[*from].name,
4159 &self.into.interfaces[*into].name,
4160 ) {
4161 (None, None) => self.build_interface(*from, *into)?,
4165
4166 _ => {
4171 if self.interface_map.get(&from) != Some(&into) {
4172 bail!("interfaces are not the same");
4173 }
4174 }
4175 }
4176 }
4177 (WorldItem::Function(from), WorldItem::Function(into)) => {
4178 let _ = (from, into);
4179 }
4182 (WorldItem::Type(from), WorldItem::Type(into)) => {
4183 let prev = self.type_map.insert(*from, *into);
4186 assert!(prev.is_none());
4187 }
4188
4189 (WorldItem::Interface { .. }, _)
4190 | (WorldItem::Function(_), _)
4191 | (WorldItem::Type(_), _) => {
4192 bail!("world items do not have the same type")
4193 }
4194 }
4195 Ok(())
4196 }
4197}
4198
4199fn update_stability(from: &Stability, into: &mut Stability) -> Result<()> {
4205 if from == into || from.is_unknown() {
4208 return Ok(());
4209 }
4210 if into.is_unknown() {
4213 *into = from.clone();
4214 return Ok(());
4215 }
4216
4217 bail!("mismatch in stability from '{:?}' to '{:?}'", from, into)
4220}
4221
4222fn merge_include_stability(
4223 from: &Stability,
4224 into: &mut Stability,
4225 is_external_include: bool,
4226) -> Result<()> {
4227 if is_external_include && from.is_stable() {
4228 log::trace!("dropped stability from external package");
4229 *into = Stability::Unknown;
4230 return Ok(());
4231 }
4232
4233 return update_stability(from, into);
4234}
4235
4236#[derive(Debug, Clone)]
4249pub struct InvalidTransitiveDependency(String);
4250
4251impl fmt::Display for InvalidTransitiveDependency {
4252 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4253 write!(
4254 f,
4255 "interface `{}` transitively depends on an interface in \
4256 incompatible ways",
4257 self.0
4258 )
4259 }
4260}
4261
4262impl std::error::Error for InvalidTransitiveDependency {}
4263
4264#[cfg(test)]
4265mod tests {
4266 use crate::Resolve;
4267 use anyhow::Result;
4268
4269 #[test]
4270 fn select_world() -> Result<()> {
4271 let mut resolve = Resolve::default();
4272 resolve.push_str(
4273 "test.wit",
4274 r#"
4275 package foo:bar@0.1.0;
4276
4277 world foo {}
4278 "#,
4279 )?;
4280 resolve.push_str(
4281 "test.wit",
4282 r#"
4283 package foo:baz@0.1.0;
4284
4285 world foo {}
4286 "#,
4287 )?;
4288 resolve.push_str(
4289 "test.wit",
4290 r#"
4291 package foo:baz@0.2.0;
4292
4293 world foo {}
4294 "#,
4295 )?;
4296
4297 let dummy = resolve.push_str(
4298 "test.wit",
4299 r#"
4300 package foo:dummy;
4301
4302 world foo {}
4303 "#,
4304 )?;
4305
4306 assert!(resolve.select_world(&[dummy], None).is_ok());
4307 assert!(resolve.select_world(&[dummy], Some("xx")).is_err());
4308 assert!(resolve.select_world(&[dummy], Some("")).is_err());
4309 assert!(resolve.select_world(&[dummy], Some("foo:bar/foo")).is_ok());
4310 assert!(
4311 resolve
4312 .select_world(&[dummy], Some("foo:bar/foo@0.1.0"))
4313 .is_ok()
4314 );
4315 assert!(resolve.select_world(&[dummy], Some("foo:baz/foo")).is_err());
4316 assert!(
4317 resolve
4318 .select_world(&[dummy], Some("foo:baz/foo@0.1.0"))
4319 .is_ok()
4320 );
4321 assert!(
4322 resolve
4323 .select_world(&[dummy], Some("foo:baz/foo@0.2.0"))
4324 .is_ok()
4325 );
4326 Ok(())
4327 }
4328
4329 #[test]
4332 fn select_world_multiple_packages() -> Result<()> {
4333 use wit_parser::Resolve;
4334
4335 let mut resolve = Resolve::default();
4336
4337 let stuff = resolve.push_str(
4339 "./my-test.wit",
4340 r#"
4341 package test:stuff;
4342
4343 world foo {
4344 // ...
4345 }
4346 "#,
4347 )?;
4348 assert!(resolve.select_world(&[stuff], None).is_ok());
4349 assert!(resolve.select_world(&[stuff], Some("foo")).is_ok());
4350
4351 let empty = resolve.push_str(
4354 "./my-test.wit",
4355 r#"
4356 package test:empty;
4357 "#,
4358 )?;
4359 assert!(resolve.select_world(&[stuff, empty], None).is_err());
4360 assert!(resolve.select_world(&[stuff, empty], Some("foo")).is_err());
4361 assert!(resolve.select_world(&[empty], None).is_err());
4362 assert!(resolve.select_world(&[empty], Some("foo")).is_err());
4363
4364 Ok(())
4365 }
4366
4367 #[test]
4369 fn select_world_versions() -> Result<()> {
4370 use wit_parser::Resolve;
4371
4372 let mut resolve = Resolve::default();
4373
4374 let _id = resolve.push_str(
4375 "./my-test.wit",
4376 r#"
4377 package example:distraction;
4378 "#,
4379 )?;
4380
4381 let versions_1 = resolve.push_str(
4384 "./my-test.wit",
4385 r#"
4386 package example:versions@1.0.0;
4387
4388 world foo { /* ... */ }
4389 "#,
4390 )?;
4391 assert!(resolve.select_world(&[versions_1], Some("foo")).is_ok());
4392 assert!(
4393 resolve
4394 .select_world(&[versions_1], Some("foo@1.0.0"))
4395 .is_err()
4396 );
4397 assert!(
4398 resolve
4399 .select_world(&[versions_1], Some("example:versions/foo"))
4400 .is_ok()
4401 );
4402 assert!(
4403 resolve
4404 .select_world(&[versions_1], Some("example:versions/foo@1.0.0"))
4405 .is_ok()
4406 );
4407
4408 let versions_2 = resolve.push_str(
4411 "./my-test.wit",
4412 r#"
4413 package example:versions@2.0.0;
4414
4415 world foo { /* ... */ }
4416 "#,
4417 )?;
4418 assert!(
4419 resolve
4420 .select_world(&[versions_1, versions_2], Some("foo"))
4421 .is_err()
4422 );
4423 assert!(
4424 resolve
4425 .select_world(&[versions_1, versions_2], Some("foo@1.0.0"))
4426 .is_err()
4427 );
4428 assert!(
4429 resolve
4430 .select_world(&[versions_1, versions_2], Some("foo@2.0.0"))
4431 .is_err()
4432 );
4433 assert!(
4434 resolve
4435 .select_world(&[versions_1, versions_2], Some("example:versions/foo"))
4436 .is_err()
4437 );
4438 assert!(
4439 resolve
4440 .select_world(
4441 &[versions_1, versions_2],
4442 Some("example:versions/foo@1.0.0")
4443 )
4444 .is_ok()
4445 );
4446 assert!(
4447 resolve
4448 .select_world(
4449 &[versions_1, versions_2],
4450 Some("example:versions/foo@2.0.0")
4451 )
4452 .is_ok()
4453 );
4454
4455 Ok(())
4456 }
4457
4458 #[test]
4460 fn select_world_override_qualification() -> Result<()> {
4461 use wit_parser::Resolve;
4462
4463 let mut resolve = Resolve::default();
4464
4465 let other = resolve.push_str(
4466 "./my-test.wit",
4467 r#"
4468 package example:other;
4469
4470 world foo { }
4471 "#,
4472 )?;
4473
4474 let fq = resolve.push_str(
4476 "./my-test.wit",
4477 r#"
4478 package example:fq;
4479
4480 world bar { }
4481 "#,
4482 )?;
4483 assert!(resolve.select_world(&[other, fq], Some("foo")).is_err());
4484 assert!(resolve.select_world(&[other, fq], Some("bar")).is_err());
4485 assert!(
4486 resolve
4487 .select_world(&[other, fq], Some("example:other/foo"))
4488 .is_ok()
4489 );
4490 assert!(
4491 resolve
4492 .select_world(&[other, fq], Some("example:fq/bar"))
4493 .is_ok()
4494 );
4495 assert!(
4496 resolve
4497 .select_world(&[other, fq], Some("example:other/bar"))
4498 .is_err()
4499 );
4500 assert!(
4501 resolve
4502 .select_world(&[other, fq], Some("example:fq/foo"))
4503 .is_err()
4504 );
4505
4506 Ok(())
4507 }
4508
4509 #[test]
4511 fn select_world_fully_qualified() -> Result<()> {
4512 use wit_parser::Resolve;
4513
4514 let mut resolve = Resolve::default();
4515
4516 let distraction = resolve.push_str(
4517 "./my-test.wit",
4518 r#"
4519 package example:distraction;
4520 "#,
4521 )?;
4522
4523 let multiworld = resolve.push_str(
4526 "./my-test.wit",
4527 r#"
4528 package example:multiworld;
4529
4530 world foo { /* ... */ }
4531
4532 world bar { /* ... */ }
4533 "#,
4534 )?;
4535 assert!(
4536 resolve
4537 .select_world(&[distraction, multiworld], None)
4538 .is_err()
4539 );
4540 assert!(
4541 resolve
4542 .select_world(&[distraction, multiworld], Some("foo"))
4543 .is_err()
4544 );
4545 assert!(
4546 resolve
4547 .select_world(&[distraction, multiworld], Some("example:multiworld/foo"))
4548 .is_ok()
4549 );
4550 assert!(
4551 resolve
4552 .select_world(&[distraction, multiworld], Some("bar"))
4553 .is_err()
4554 );
4555 assert!(
4556 resolve
4557 .select_world(&[distraction, multiworld], Some("example:multiworld/bar"))
4558 .is_ok()
4559 );
4560
4561 Ok(())
4562 }
4563
4564 #[test]
4566 fn select_world_packages() -> Result<()> {
4567 use wit_parser::Resolve;
4568
4569 let mut resolve = Resolve::default();
4570
4571 let wit1 = resolve.push_str(
4574 "./my-test.wit",
4575 r#"
4576 package example:wit1;
4577
4578 world foo {
4579 // ...
4580 }
4581 "#,
4582 )?;
4583 assert!(resolve.select_world(&[wit1], None).is_ok());
4584 assert!(resolve.select_world(&[wit1], Some("foo")).is_ok());
4585 assert!(
4586 resolve
4587 .select_world(&[wit1], Some("example:wit1/foo"))
4588 .is_ok()
4589 );
4590 assert!(resolve.select_world(&[wit1], Some("bar")).is_err());
4591 assert!(
4592 resolve
4593 .select_world(&[wit1], Some("example:wit2/foo"))
4594 .is_err()
4595 );
4596
4597 let wit2 = resolve.push_str(
4600 "./my-test.wit",
4601 r#"
4602 package example:wit2;
4603
4604 world foo { /* ... */ }
4605 "#,
4606 )?;
4607 assert!(resolve.select_world(&[wit1, wit2], None).is_err());
4608 assert!(resolve.select_world(&[wit1, wit2], Some("foo")).is_err());
4609 assert!(
4610 resolve
4611 .select_world(&[wit1, wit2], Some("example:wit1/foo"))
4612 .is_ok()
4613 );
4614 assert!(resolve.select_world(&[wit2], None).is_ok());
4615 assert!(resolve.select_world(&[wit2], Some("foo")).is_ok());
4616 assert!(
4617 resolve
4618 .select_world(&[wit2], Some("example:wit1/foo"))
4619 .is_ok()
4620 );
4621 assert!(resolve.select_world(&[wit1, wit2], Some("bar")).is_err());
4622 assert!(
4623 resolve
4624 .select_world(&[wit1, wit2], Some("example:wit2/foo"))
4625 .is_ok()
4626 );
4627 assert!(resolve.select_world(&[wit2], Some("bar")).is_err());
4628 assert!(
4629 resolve
4630 .select_world(&[wit2], Some("example:wit2/foo"))
4631 .is_ok()
4632 );
4633
4634 Ok(())
4635 }
4636}