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::Variant(_)
578 | TypeDefKind::Enum(_)
579 | TypeDefKind::Option(_)
580 | TypeDefKind::Result(_)
581 | TypeDefKind::Future(_)
582 | TypeDefKind::Stream(_) => false,
583 TypeDefKind::Type(t) | TypeDefKind::FixedSizeList(t, ..) => self.all_bits_valid(t),
584
585 TypeDefKind::Handle(h) => match h {
586 crate::Handle::Own(_) => true,
587 crate::Handle::Borrow(_) => true,
588 },
589
590 TypeDefKind::Resource => false,
591 TypeDefKind::Record(r) => r.fields.iter().all(|f| self.all_bits_valid(&f.ty)),
592 TypeDefKind::Tuple(t) => t.types.iter().all(|t| self.all_bits_valid(t)),
593
594 TypeDefKind::Flags(_) => false,
598
599 TypeDefKind::Unknown => unreachable!(),
600 },
601 }
602 }
603
604 pub fn merge(&mut self, resolve: Resolve) -> Result<Remap> {
616 log::trace!(
617 "merging {} packages into {} packages",
618 resolve.packages.len(),
619 self.packages.len()
620 );
621
622 let mut map = MergeMap::new(&resolve, &self);
623 map.build()?;
624 let MergeMap {
625 package_map,
626 interface_map,
627 type_map,
628 world_map,
629 interfaces_to_add,
630 worlds_to_add,
631 ..
632 } = map;
633
634 let mut remap = Remap::default();
653 let Resolve {
654 types,
655 worlds,
656 interfaces,
657 packages,
658 package_names,
659 features: _,
660 ..
661 } = resolve;
662
663 let mut moved_types = Vec::new();
664 for (id, mut ty) in types {
665 let new_id = match type_map.get(&id).copied() {
666 Some(id) => {
667 update_stability(&ty.stability, &mut self.types[id].stability)?;
668 id
669 }
670 None => {
671 log::debug!("moving type {:?}", ty.name);
672 moved_types.push(id);
673 remap.update_typedef(self, &mut ty, None)?;
674 self.types.alloc(ty)
675 }
676 };
677 assert_eq!(remap.types.len(), id.index());
678 remap.types.push(Some(new_id));
679 }
680
681 let mut moved_interfaces = Vec::new();
682 for (id, mut iface) in interfaces {
683 let new_id = match interface_map.get(&id).copied() {
684 Some(id) => {
685 update_stability(&iface.stability, &mut self.interfaces[id].stability)?;
686 id
687 }
688 None => {
689 log::debug!("moving interface {:?}", iface.name);
690 moved_interfaces.push(id);
691 remap.update_interface(self, &mut iface, None)?;
692 self.interfaces.alloc(iface)
693 }
694 };
695 assert_eq!(remap.interfaces.len(), id.index());
696 remap.interfaces.push(Some(new_id));
697 }
698
699 let mut moved_worlds = Vec::new();
700 for (id, mut world) in worlds {
701 let new_id = match world_map.get(&id).copied() {
702 Some(world_id) => {
703 update_stability(&world.stability, &mut self.worlds[world_id].stability)?;
704 for from_import in world.imports.iter() {
705 Resolve::update_world_imports_stability(
706 from_import,
707 &mut self.worlds[world_id].imports,
708 &interface_map,
709 )?;
710 }
711 for from_export in world.exports.iter() {
712 Resolve::update_world_imports_stability(
713 from_export,
714 &mut self.worlds[world_id].exports,
715 &interface_map,
716 )?;
717 }
718 world_id
719 }
720 None => {
721 log::debug!("moving world {}", world.name);
722 moved_worlds.push(id);
723 let mut update = |map: &mut IndexMap<WorldKey, WorldItem>| -> Result<_> {
724 for (mut name, mut item) in mem::take(map) {
725 remap.update_world_key(&mut name, None)?;
726 match &mut item {
727 WorldItem::Function(f) => remap.update_function(self, f, None)?,
728 WorldItem::Interface { id, .. } => {
729 *id = remap.map_interface(*id, None)?
730 }
731 WorldItem::Type(i) => *i = remap.map_type(*i, None)?,
732 }
733 map.insert(name, item);
734 }
735 Ok(())
736 };
737 update(&mut world.imports)?;
738 update(&mut world.exports)?;
739 self.worlds.alloc(world)
740 }
741 };
742 assert_eq!(remap.worlds.len(), id.index());
743 remap.worlds.push(Some(new_id));
744 }
745
746 for (id, mut pkg) in packages {
747 let new_id = match package_map.get(&id).copied() {
748 Some(id) => id,
749 None => {
750 for (_, id) in pkg.interfaces.iter_mut() {
751 *id = remap.map_interface(*id, None)?;
752 }
753 for (_, id) in pkg.worlds.iter_mut() {
754 *id = remap.map_world(*id, None)?;
755 }
756 self.packages.alloc(pkg)
757 }
758 };
759 assert_eq!(remap.packages.len(), id.index());
760 remap.packages.push(new_id);
761 }
762
763 for (name, id) in package_names {
764 let id = remap.packages[id.index()];
765 if let Some(prev) = self.package_names.insert(name, id) {
766 assert_eq!(prev, id);
767 }
768 }
769
770 for id in moved_worlds {
778 let id = remap.map_world(id, None)?;
779 if let Some(pkg) = self.worlds[id].package.as_mut() {
780 *pkg = remap.packages[pkg.index()];
781 }
782 }
783 for id in moved_interfaces {
784 let id = remap.map_interface(id, None)?;
785 if let Some(pkg) = self.interfaces[id].package.as_mut() {
786 *pkg = remap.packages[pkg.index()];
787 }
788 }
789 for id in moved_types {
790 let id = remap.map_type(id, None)?;
791 match &mut self.types[id].owner {
792 TypeOwner::Interface(id) => *id = remap.map_interface(*id, None)?,
793 TypeOwner::World(id) => *id = remap.map_world(*id, None)?,
794 TypeOwner::None => {}
795 }
796 }
797
798 for (name, pkg, iface) in interfaces_to_add {
803 let prev = self.packages[pkg]
804 .interfaces
805 .insert(name, remap.map_interface(iface, None)?);
806 assert!(prev.is_none());
807 }
808 for (name, pkg, world) in worlds_to_add {
809 let prev = self.packages[pkg]
810 .worlds
811 .insert(name, remap.map_world(world, None)?);
812 assert!(prev.is_none());
813 }
814
815 log::trace!("now have {} packages", self.packages.len());
816
817 #[cfg(debug_assertions)]
818 self.assert_valid();
819 Ok(remap)
820 }
821
822 fn update_world_imports_stability(
823 from_item: (&WorldKey, &WorldItem),
824 into_items: &mut IndexMap<WorldKey, WorldItem>,
825 interface_map: &HashMap<Id<Interface>, Id<Interface>>,
826 ) -> Result<()> {
827 match from_item.0 {
828 WorldKey::Name(_) => {
829 Ok(())
831 }
832 key @ WorldKey::Interface(_) => {
833 let new_key = MergeMap::map_name(key, interface_map);
834 if let Some(into) = into_items.get_mut(&new_key) {
835 match (from_item.1, into) {
836 (
837 WorldItem::Interface {
838 id: aid,
839 stability: astability,
840 },
841 WorldItem::Interface {
842 id: bid,
843 stability: bstability,
844 },
845 ) => {
846 let aid = interface_map.get(aid).copied().unwrap_or(*aid);
847 assert_eq!(aid, *bid);
848 update_stability(astability, bstability)?;
849 Ok(())
850 }
851 _ => unreachable!(),
852 }
853 } else {
854 unreachable!()
857 }
858 }
859 }
860 }
861
862 pub fn merge_worlds(
877 &mut self,
878 from: WorldId,
879 into: WorldId,
880 clone_maps: &mut CloneMaps,
881 ) -> Result<()> {
882 let mut new_imports = Vec::new();
883 let mut new_exports = Vec::new();
884
885 let from_world = &self.worlds[from];
886 let into_world = &self.worlds[into];
887
888 log::trace!("merging {} into {}", from_world.name, into_world.name);
889
890 for (name, from_import) in from_world.imports.iter() {
898 let name_str = self.name_world_key(name);
899 match into_world.imports.get(name) {
900 Some(into_import) => {
901 log::trace!("info/from shared import on `{name_str}`");
902 self.merge_world_item(from_import, into_import)
903 .with_context(|| format!("failed to merge world import {name_str}"))?;
904 }
905 None => {
906 log::trace!("new import: `{name_str}`");
907 new_imports.push((name.clone(), from_import.clone()));
908 }
909 }
910 }
911
912 let mut must_be_imported = HashMap::new();
919 for (key, export) in into_world.exports.iter() {
920 for dep in self.world_item_direct_deps(export) {
921 if into_world.exports.contains_key(&WorldKey::Interface(dep)) {
922 continue;
923 }
924 self.foreach_interface_dep(dep, &mut |id| {
925 must_be_imported.insert(id, key.clone());
926 });
927 }
928 }
929
930 for (name, from_export) in from_world.exports.iter() {
933 let name_str = self.name_world_key(name);
934 match into_world.exports.get(name) {
935 Some(into_export) => {
936 log::trace!("info/from shared export on `{name_str}`");
937 self.merge_world_item(from_export, into_export)
938 .with_context(|| format!("failed to merge world export {name_str}"))?;
939 }
940 None => {
941 log::trace!("new export `{name_str}`");
942 self.ensure_can_add_world_export(
945 into_world,
946 name,
947 from_export,
948 &must_be_imported,
949 )
950 .with_context(|| {
951 format!("failed to add export `{}`", self.name_world_key(name))
952 })?;
953 new_exports.push((name.clone(), from_export.clone()));
954 }
955 }
956 }
957
958 let mut cloner = clone::Cloner::new(self, TypeOwner::World(from), TypeOwner::World(into));
972 cloner.register_world_type_overlap(from, into);
973 for (name, item) in new_imports.iter_mut().chain(&mut new_exports) {
974 cloner.world_item(name, item, clone_maps);
975 }
976
977 clone_maps.types.extend(cloner.types);
978
979 let into_world = &mut self.worlds[into];
981 for (name, import) in new_imports {
982 let prev = into_world.imports.insert(name, import);
983 assert!(prev.is_none());
984 }
985 for (name, export) in new_exports {
986 let prev = into_world.exports.insert(name, export);
987 assert!(prev.is_none());
988 }
989
990 #[cfg(debug_assertions)]
991 self.assert_valid();
992 Ok(())
993 }
994
995 fn merge_world_item(&self, from: &WorldItem, into: &WorldItem) -> Result<()> {
996 let mut map = MergeMap::new(self, self);
997 match (from, into) {
998 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
999 if from == into {
1004 return Ok(());
1005 }
1006
1007 map.build_interface(*from, *into)
1017 .context("failed to merge interfaces")?;
1018 }
1019
1020 (WorldItem::Function(from), WorldItem::Function(into)) => {
1023 map.build_function(from, into)
1024 .context("failed to merge functions")?;
1025 }
1026 (WorldItem::Type(from), WorldItem::Type(into)) => {
1027 map.build_type_id(*from, *into)
1028 .context("failed to merge types")?;
1029 }
1030
1031 (WorldItem::Interface { .. }, _)
1033 | (WorldItem::Function { .. }, _)
1034 | (WorldItem::Type { .. }, _) => {
1035 bail!("different kinds of items");
1036 }
1037 }
1038 assert!(map.interfaces_to_add.is_empty());
1039 assert!(map.worlds_to_add.is_empty());
1040 Ok(())
1041 }
1042
1043 fn ensure_can_add_world_export(
1055 &self,
1056 into: &World,
1057 name: &WorldKey,
1058 item: &WorldItem,
1059 must_be_imported: &HashMap<InterfaceId, WorldKey>,
1060 ) -> Result<()> {
1061 assert!(!into.exports.contains_key(name));
1062 let name = self.name_world_key(name);
1063
1064 for dep in self.world_item_direct_deps(item) {
1068 if into.exports.contains_key(&WorldKey::Interface(dep)) {
1069 continue;
1070 }
1071 self.ensure_not_exported(into, dep)
1072 .with_context(|| format!("failed validating export of `{name}`"))?;
1073 }
1074
1075 if let WorldItem::Interface { id, .. } = item {
1079 if let Some(export) = must_be_imported.get(&id) {
1080 let export_name = self.name_world_key(export);
1081 bail!(
1082 "export `{export_name}` depends on `{name}` \
1083 previously as an import which will change meaning \
1084 if `{name}` is added as an export"
1085 );
1086 }
1087 }
1088
1089 Ok(())
1090 }
1091
1092 fn ensure_not_exported(&self, world: &World, id: InterfaceId) -> Result<()> {
1093 let key = WorldKey::Interface(id);
1094 let name = self.name_world_key(&key);
1095 if world.exports.contains_key(&key) {
1096 bail!(
1097 "world exports `{name}` but it's also transitively used by an \
1098 import \
1099 which means that this is not valid"
1100 )
1101 }
1102 for dep in self.interface_direct_deps(id) {
1103 self.ensure_not_exported(world, dep)
1104 .with_context(|| format!("failed validating transitive import dep `{name}`"))?;
1105 }
1106 Ok(())
1107 }
1108
1109 fn world_item_direct_deps(&self, item: &WorldItem) -> impl Iterator<Item = InterfaceId> + '_ {
1115 let mut interface = None;
1116 let mut ty = None;
1117 match item {
1118 WorldItem::Function(_) => {}
1119 WorldItem::Type(id) => ty = Some(*id),
1120 WorldItem::Interface { id, .. } => interface = Some(*id),
1121 }
1122
1123 interface
1124 .into_iter()
1125 .flat_map(move |id| self.interface_direct_deps(id))
1126 .chain(ty.and_then(|t| self.type_interface_dep(t)))
1127 }
1128
1129 fn foreach_interface_dep(&self, id: InterfaceId, f: &mut dyn FnMut(InterfaceId)) {
1133 self._foreach_interface_dep(id, f, &mut HashSet::new())
1134 }
1135
1136 fn _foreach_interface_dep(
1140 &self,
1141 id: InterfaceId,
1142 f: &mut dyn FnMut(InterfaceId),
1143 visited: &mut HashSet<InterfaceId>,
1144 ) {
1145 if !visited.insert(id) {
1146 return;
1147 }
1148 f(id);
1149 for dep in self.interface_direct_deps(id) {
1150 self._foreach_interface_dep(dep, f, visited);
1151 }
1152 }
1153
1154 pub fn id_of(&self, interface: InterfaceId) -> Option<String> {
1158 let interface = &self.interfaces[interface];
1159 Some(self.id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1160 }
1161
1162 pub fn canonicalized_id_of(&self, interface: InterfaceId) -> Option<String> {
1167 let interface = &self.interfaces[interface];
1168 Some(self.canonicalized_id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1169 }
1170
1171 pub fn importize(&mut self, world_id: WorldId, out_world_name: Option<String>) -> Result<()> {
1187 let world = &mut self.worlds[world_id];
1192 let pkg = &mut self.packages[world.package.unwrap()];
1193 pkg.worlds.shift_remove(&world.name);
1194 if let Some(name) = out_world_name {
1195 world.name = name.clone();
1196 pkg.worlds.insert(name, world_id);
1197 } else {
1198 world.name.push_str("-importized");
1199 pkg.worlds.insert(world.name.clone(), world_id);
1200 }
1201
1202 world.imports.retain(|_, item| match item {
1205 WorldItem::Type(_) => true,
1206 _ => false,
1207 });
1208
1209 for (name, export) in mem::take(&mut world.exports) {
1210 match (name.clone(), world.imports.insert(name, export)) {
1211 (_, None) => {}
1213
1214 (WorldKey::Name(name), Some(_)) => {
1216 bail!("world export `{name}` conflicts with import of same name");
1217 }
1218
1219 (WorldKey::Interface(_), _) => unreachable!(),
1222 }
1223 }
1224
1225 self.elaborate_world(world_id)?;
1228
1229 #[cfg(debug_assertions)]
1230 self.assert_valid();
1231 Ok(())
1232 }
1233
1234 pub fn id_of_name(&self, pkg: PackageId, name: &str) -> String {
1236 let package = &self.packages[pkg];
1237 let mut base = String::new();
1238 base.push_str(&package.name.namespace);
1239 base.push_str(":");
1240 base.push_str(&package.name.name);
1241 base.push_str("/");
1242 base.push_str(name);
1243 if let Some(version) = &package.name.version {
1244 base.push_str(&format!("@{version}"));
1245 }
1246 base
1247 }
1248
1249 pub fn canonicalized_id_of_name(&self, pkg: PackageId, name: &str) -> String {
1255 let package = &self.packages[pkg];
1256 let mut base = String::new();
1257 base.push_str(&package.name.namespace);
1258 base.push_str(":");
1259 base.push_str(&package.name.name);
1260 base.push_str("/");
1261 base.push_str(name);
1262 if let Some(version) = &package.name.version {
1263 base.push_str("@");
1264 let string = PackageName::version_compat_track_string(version);
1265 base.push_str(&string);
1266 }
1267 base
1268 }
1269
1270 pub fn select_world(
1385 &self,
1386 main_packages: &[PackageId],
1387 world: Option<&str>,
1388 ) -> Result<WorldId> {
1389 let world_path = match world {
1391 Some(world) => Some(
1392 parse_use_path(world)
1393 .with_context(|| format!("failed to parse world specifier `{world}`"))?,
1394 ),
1395 None => None,
1396 };
1397
1398 match world_path {
1399 Some(world_path) => {
1401 let (pkg, world_name) = match (main_packages, world_path) {
1402 ([], _) => bail!("No main packages defined"),
1404
1405 ([main_package], ParsedUsePath::Name(name)) => (*main_package, name),
1407
1408 (_, ParsedUsePath::Name(_name)) => {
1410 bail!(
1411 "There are multiple main packages; a world must be explicitly chosen:{}",
1412 self.worlds
1413 .iter()
1414 .map(|world| format!(
1415 "\n {}",
1416 self.id_of_name(world.1.package.unwrap(), &world.1.name)
1417 ))
1418 .collect::<String>()
1419 )
1420 }
1421
1422 (_, ParsedUsePath::Package(pkg, world_name)) => {
1424 let pkg = match self.package_names.get(&pkg) {
1425 Some(pkg) => *pkg,
1426 None => {
1427 let mut candidates =
1428 self.package_names.iter().filter(|(name, _)| {
1429 pkg.version.is_none()
1430 && pkg.name == name.name
1431 && pkg.namespace == name.namespace
1432 && name.version.is_some()
1433 });
1434 let candidate = candidates.next();
1435 if let Some((c2, _)) = candidates.next() {
1436 let (c1, _) = candidate.unwrap();
1437 bail!(
1438 "package name `{pkg}` is available at both \
1439 versions {} and {} but which is not specified",
1440 c1.version.as_ref().unwrap(),
1441 c2.version.as_ref().unwrap(),
1442 );
1443 }
1444 match candidate {
1445 Some((_, id)) => *id,
1446 None => bail!("unknown package `{pkg}`"),
1447 }
1448 }
1449 };
1450 (pkg, world_name.to_string())
1451 }
1452 };
1453
1454 let pkg = &self.packages[pkg];
1456 pkg.worlds.get(&world_name).copied().ok_or_else(|| {
1457 anyhow!("World `{world_name}` not found in package `{}`", pkg.name)
1458 })
1459 }
1460
1461 None => match main_packages {
1463 [] => bail!("No main packages defined"),
1464
1465 [main_package] => {
1467 let pkg = &self.packages[*main_package];
1468 match pkg.worlds.len() {
1469 0 => bail!("The main package `{}` contains no worlds", pkg.name),
1470 1 => Ok(pkg.worlds[0]),
1471 _ => bail!(
1472 "There are multiple worlds in `{}`; one must be explicitly chosen:{}",
1473 pkg.name,
1474 pkg.worlds
1475 .values()
1476 .map(|world| format!(
1477 "\n {}",
1478 self.id_of_name(*main_package, &self.worlds[*world].name)
1479 ))
1480 .collect::<String>()
1481 ),
1482 }
1483 }
1484
1485 _ => {
1487 bail!(
1488 "There are multiple main packages; a world must be explicitly chosen:{}",
1489 self.worlds
1490 .iter()
1491 .map(|world| format!(
1492 "\n {}",
1493 self.id_of_name(world.1.package.unwrap(), &world.1.name)
1494 ))
1495 .collect::<String>()
1496 )
1497 }
1498 },
1499 }
1500 }
1501
1502 pub fn name_world_key(&self, key: &WorldKey) -> String {
1504 match key {
1505 WorldKey::Name(s) => s.to_string(),
1506 WorldKey::Interface(i) => self.id_of(*i).expect("unexpected anonymous interface"),
1507 }
1508 }
1509
1510 pub fn name_canonicalized_world_key(&self, key: &WorldKey) -> String {
1513 match key {
1514 WorldKey::Name(s) => s.to_string(),
1515 WorldKey::Interface(i) => self
1516 .canonicalized_id_of(*i)
1517 .expect("unexpected anonymous interface"),
1518 }
1519 }
1520
1521 pub fn type_interface_dep(&self, id: TypeId) -> Option<InterfaceId> {
1527 let ty = &self.types[id];
1528 let dep = match ty.kind {
1529 TypeDefKind::Type(Type::Id(id)) => id,
1530 _ => return None,
1531 };
1532 let other = &self.types[dep];
1533 if ty.owner == other.owner {
1534 None
1535 } else {
1536 match other.owner {
1537 TypeOwner::Interface(id) => Some(id),
1538 _ => unreachable!(),
1539 }
1540 }
1541 }
1542
1543 pub fn interface_direct_deps(&self, id: InterfaceId) -> impl Iterator<Item = InterfaceId> + '_ {
1553 self.interfaces[id]
1554 .types
1555 .iter()
1556 .filter_map(move |(_name, ty)| self.type_interface_dep(*ty))
1557 }
1558
1559 pub fn package_direct_deps(&self, id: PackageId) -> impl Iterator<Item = PackageId> + '_ {
1569 let pkg = &self.packages[id];
1570
1571 pkg.interfaces
1572 .iter()
1573 .flat_map(move |(_name, id)| self.interface_direct_deps(*id))
1574 .chain(pkg.worlds.iter().flat_map(move |(_name, id)| {
1575 let world = &self.worlds[*id];
1576 world
1577 .imports
1578 .iter()
1579 .chain(world.exports.iter())
1580 .filter_map(move |(_name, item)| match item {
1581 WorldItem::Interface { id, .. } => Some(*id),
1582 WorldItem::Function(_) => None,
1583 WorldItem::Type(t) => self.type_interface_dep(*t),
1584 })
1585 }))
1586 .filter_map(move |iface_id| {
1587 let pkg = self.interfaces[iface_id].package?;
1588 if pkg == id { None } else { Some(pkg) }
1589 })
1590 }
1591
1592 pub fn topological_packages(&self) -> Vec<PackageId> {
1598 let mut pushed = vec![false; self.packages.len()];
1599 let mut order = Vec::new();
1600 for (id, _) in self.packages.iter() {
1601 self.build_topological_package_ordering(id, &mut pushed, &mut order);
1602 }
1603 order
1604 }
1605
1606 fn build_topological_package_ordering(
1607 &self,
1608 id: PackageId,
1609 pushed: &mut Vec<bool>,
1610 order: &mut Vec<PackageId>,
1611 ) {
1612 if pushed[id.index()] {
1613 return;
1614 }
1615 for dep in self.package_direct_deps(id) {
1616 self.build_topological_package_ordering(dep, pushed, order);
1617 }
1618 order.push(id);
1619 pushed[id.index()] = true;
1620 }
1621
1622 #[doc(hidden)]
1623 pub fn assert_valid(&self) {
1624 let mut package_interfaces = Vec::new();
1625 let mut package_worlds = Vec::new();
1626 for (id, pkg) in self.packages.iter() {
1627 let mut interfaces = HashSet::new();
1628 for (name, iface) in pkg.interfaces.iter() {
1629 assert!(interfaces.insert(*iface));
1630 let iface = &self.interfaces[*iface];
1631 assert_eq!(name, iface.name.as_ref().unwrap());
1632 assert_eq!(iface.package.unwrap(), id);
1633 }
1634 package_interfaces.push(pkg.interfaces.values().copied().collect::<HashSet<_>>());
1635 let mut worlds = HashSet::new();
1636 for (name, world) in pkg.worlds.iter() {
1637 assert!(worlds.insert(*world));
1638 assert_eq!(
1639 pkg.worlds.get_key_value(name),
1640 Some((name, world)),
1641 "`MutableKeys` impl may have been used to change a key's hash or equality"
1642 );
1643 let world = &self.worlds[*world];
1644 assert_eq!(*name, world.name);
1645 assert_eq!(world.package.unwrap(), id);
1646 }
1647 package_worlds.push(pkg.worlds.values().copied().collect::<HashSet<_>>());
1648 }
1649
1650 let mut interface_types = Vec::new();
1651 for (id, iface) in self.interfaces.iter() {
1652 assert!(self.packages.get(iface.package.unwrap()).is_some());
1653 if iface.name.is_some() {
1654 assert!(package_interfaces[iface.package.unwrap().index()].contains(&id));
1655 }
1656
1657 for (name, ty) in iface.types.iter() {
1658 let ty = &self.types[*ty];
1659 assert_eq!(ty.name.as_ref(), Some(name));
1660 assert_eq!(ty.owner, TypeOwner::Interface(id));
1661 }
1662 interface_types.push(iface.types.values().copied().collect::<HashSet<_>>());
1663 for (name, f) in iface.functions.iter() {
1664 assert_eq!(*name, f.name);
1665 }
1666 }
1667
1668 let mut world_types = Vec::new();
1669 for (id, world) in self.worlds.iter() {
1670 log::debug!("validating world {}", &world.name);
1671 if let Some(package) = world.package {
1672 assert!(self.packages.get(package).is_some());
1673 assert!(package_worlds[package.index()].contains(&id));
1674 }
1675 assert!(world.includes.is_empty());
1676
1677 let mut types = HashSet::new();
1678 for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1679 log::debug!("validating world item: {}", self.name_world_key(name));
1680 match item {
1681 WorldItem::Interface { id, .. } => {
1682 if matches!(name, WorldKey::Name(_)) {
1685 assert_eq!(self.interfaces[*id].package, world.package);
1686 }
1687 }
1688 WorldItem::Function(f) => {
1689 assert!(!matches!(name, WorldKey::Interface(_)));
1690 assert_eq!(f.name, name.clone().unwrap_name());
1691 }
1692 WorldItem::Type(ty) => {
1693 assert!(!matches!(name, WorldKey::Interface(_)));
1694 assert!(types.insert(*ty));
1695 let ty = &self.types[*ty];
1696 assert_eq!(ty.name, Some(name.clone().unwrap_name()));
1697 assert_eq!(ty.owner, TypeOwner::World(id));
1698 }
1699 }
1700 }
1701 self.assert_world_elaborated(world);
1702 world_types.push(types);
1703 }
1704
1705 for (ty_id, ty) in self.types.iter() {
1706 match ty.owner {
1707 TypeOwner::Interface(id) => {
1708 assert!(self.interfaces.get(id).is_some());
1709 assert!(interface_types[id.index()].contains(&ty_id));
1710 }
1711 TypeOwner::World(id) => {
1712 assert!(self.worlds.get(id).is_some());
1713 assert!(world_types[id.index()].contains(&ty_id));
1714 }
1715 TypeOwner::None => {}
1716 }
1717 }
1718
1719 self.assert_topologically_sorted();
1720 }
1721
1722 fn assert_topologically_sorted(&self) {
1723 let mut positions = IndexMap::new();
1724 for id in self.topological_packages() {
1725 let pkg = &self.packages[id];
1726 log::debug!("pkg {}", pkg.name);
1727 let prev = positions.insert(Some(id), IndexSet::new());
1728 assert!(prev.is_none());
1729 }
1730 positions.insert(None, IndexSet::new());
1731
1732 for (id, iface) in self.interfaces.iter() {
1733 log::debug!("iface {:?}", iface.name);
1734 let ok = positions.get_mut(&iface.package).unwrap().insert(id);
1735 assert!(ok);
1736 }
1737
1738 for (_, world) in self.worlds.iter() {
1739 log::debug!("world {:?}", world.name);
1740
1741 let my_package = world.package;
1742 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1743
1744 for (_, item) in world.imports.iter().chain(&world.exports) {
1745 let id = match item {
1746 WorldItem::Interface { id, .. } => *id,
1747 _ => continue,
1748 };
1749 let other_package = self.interfaces[id].package;
1750 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1751
1752 assert!(other_package_pos <= my_package_pos);
1753 }
1754 }
1755
1756 for (_id, ty) in self.types.iter() {
1757 log::debug!("type {:?} {:?}", ty.name, ty.owner);
1758 let other_id = match ty.kind {
1759 TypeDefKind::Type(Type::Id(ty)) => ty,
1760 _ => continue,
1761 };
1762 let other = &self.types[other_id];
1763 if ty.kind == other.kind {
1764 continue;
1765 }
1766 let my_interface = match ty.owner {
1767 TypeOwner::Interface(id) => id,
1768 _ => continue,
1769 };
1770 let other_interface = match other.owner {
1771 TypeOwner::Interface(id) => id,
1772 _ => continue,
1773 };
1774
1775 let my_package = self.interfaces[my_interface].package;
1776 let other_package = self.interfaces[other_interface].package;
1777 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1778 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1779
1780 if my_package_pos == other_package_pos {
1781 let interfaces = &positions[&my_package];
1782 let my_interface_pos = interfaces.get_index_of(&my_interface).unwrap();
1783 let other_interface_pos = interfaces.get_index_of(&other_interface).unwrap();
1784 assert!(other_interface_pos <= my_interface_pos);
1785 } else {
1786 assert!(other_package_pos < my_package_pos);
1787 }
1788 }
1789 }
1790
1791 fn assert_world_elaborated(&self, world: &World) {
1792 for (key, item) in world.imports.iter() {
1793 log::debug!(
1794 "asserting elaborated world import {}",
1795 self.name_world_key(key)
1796 );
1797 match item {
1798 WorldItem::Type(t) => self.assert_world_imports_type_deps(world, key, *t),
1799
1800 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1802
1803 WorldItem::Interface { id, .. } => {
1805 for dep in self.interface_direct_deps(*id) {
1806 assert!(
1807 world.imports.contains_key(&WorldKey::Interface(dep)),
1808 "world import of {} is missing transitive dep of {}",
1809 self.name_world_key(key),
1810 self.id_of(dep).unwrap(),
1811 );
1812 }
1813 }
1814 }
1815 }
1816 for (key, item) in world.exports.iter() {
1817 log::debug!(
1818 "asserting elaborated world export {}",
1819 self.name_world_key(key)
1820 );
1821 match item {
1822 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1824
1825 WorldItem::Interface { id, .. } => {
1829 for dep in self.interface_direct_deps(*id) {
1830 let dep_key = WorldKey::Interface(dep);
1831 if world.exports.contains_key(&dep_key) {
1832 continue;
1833 }
1834 self.foreach_interface_dep(dep, &mut |dep| {
1835 let dep_key = WorldKey::Interface(dep);
1836 assert!(
1837 world.imports.contains_key(&dep_key),
1838 "world should import {} (required by {})",
1839 self.name_world_key(&dep_key),
1840 self.name_world_key(key),
1841 );
1842 assert!(
1843 !world.exports.contains_key(&dep_key),
1844 "world should not export {} (required by {})",
1845 self.name_world_key(&dep_key),
1846 self.name_world_key(key),
1847 );
1848 });
1849 }
1850 }
1851
1852 WorldItem::Type(_) => unreachable!(),
1854 }
1855 }
1856 }
1857
1858 fn assert_world_imports_type_deps(&self, world: &World, key: &WorldKey, ty: TypeId) {
1859 let ty = &self.types[ty];
1862 if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
1863 if let TypeOwner::Interface(id) = self.types[other].owner {
1864 let key = WorldKey::Interface(id);
1865 assert!(world.imports.contains_key(&key));
1866 return;
1867 }
1868 }
1869
1870 let mut visitor = MyVisit(self, Vec::new());
1874 visitor.visit_type_def(self, ty);
1875 for ty in visitor.1 {
1876 let ty = &self.types[ty];
1877 let Some(name) = ty.name.clone() else {
1878 continue;
1879 };
1880 let dep_key = WorldKey::Name(name);
1881 assert!(
1882 world.imports.contains_key(&dep_key),
1883 "world import `{}` should also force an import of `{}`",
1884 self.name_world_key(key),
1885 self.name_world_key(&dep_key),
1886 );
1887 }
1888
1889 struct MyVisit<'a>(&'a Resolve, Vec<TypeId>);
1890
1891 impl TypeIdVisitor for MyVisit<'_> {
1892 fn before_visit_type_id(&mut self, id: TypeId) -> bool {
1893 self.1.push(id);
1894 self.0.types[id].name.is_none()
1896 }
1897 }
1898 }
1899
1900 fn assert_world_function_imports_types(&self, world: &World, key: &WorldKey, func: &Function) {
1904 for ty in func
1905 .parameter_and_result_types()
1906 .chain(func.kind.resource().map(Type::Id))
1907 {
1908 let Type::Id(id) = ty else {
1909 continue;
1910 };
1911 self.assert_world_imports_type_deps(world, key, id);
1912 }
1913 }
1914
1915 fn include_stability(
1931 &self,
1932 stability: &Stability,
1933 pkg_id: &PackageId,
1934 span: Option<Span>,
1935 ) -> Result<bool> {
1936 let err = |msg: String| match span {
1937 Some(span) => Error::new(span, msg).into(),
1938 None => anyhow::Error::msg(msg),
1939 };
1940 Ok(match stability {
1941 Stability::Unknown => true,
1942 Stability::Stable { since, .. } => {
1945 let Some(p) = self.packages.get(*pkg_id) else {
1946 return Ok(true);
1954 };
1955
1956 let package_version = p.name.version.as_ref().ok_or_else(|| {
1959 err(format!(
1960 "package [{}] contains a feature gate with a version \
1961 specifier, so it must have a version",
1962 p.name
1963 ))
1964 })?;
1965
1966 if since > package_version {
1970 return Err(err(format!(
1971 "feature gate cannot reference unreleased version \
1972 {since} of package [{}] (current version {package_version})",
1973 p.name
1974 )));
1975 }
1976
1977 true
1978 }
1979 Stability::Unstable { feature, .. } => {
1980 self.features.contains(feature) || self.all_features
1981 }
1982 })
1983 }
1984
1985 fn include_type(&self, ty: &TypeDef, pkgid: PackageId, span: Span) -> Result<bool> {
1988 self.include_stability(&ty.stability, &pkgid, Some(span))
1989 .with_context(|| {
1990 format!(
1991 "failed to process feature gate for type [{}] in package [{}]",
1992 ty.name.as_ref().map(String::as_str).unwrap_or("<unknown>"),
1993 self.packages[pkgid].name,
1994 )
1995 })
1996 }
1997
1998 fn elaborate_world(&mut self, world_id: WorldId) -> Result<()> {
2010 let mut new_imports = IndexMap::new();
2014 let world = &self.worlds[world_id];
2015
2016 let sort_key = |resolve: &Resolve, item: &WorldItem| match item {
2039 WorldItem::Interface { .. } => 0,
2040 WorldItem::Type(ty) => {
2041 let ty = &resolve.types[*ty];
2042 match ty.kind {
2043 TypeDefKind::Type(Type::Id(t)) if resolve.types[t].owner != ty.owner => 1,
2044 _ => 2,
2045 }
2046 }
2047 WorldItem::Function(f) => {
2048 if f.kind.resource().is_none() {
2049 3
2050 } else {
2051 4
2052 }
2053 }
2054 };
2055
2056 let mut world_imports = world.imports.iter().collect::<Vec<_>>();
2059 world_imports.sort_by_key(|(_name, import)| sort_key(self, import));
2060 for (name, item) in world_imports {
2061 match item {
2062 WorldItem::Interface { id, stability } => {
2065 self.elaborate_world_import(&mut new_imports, name.clone(), *id, &stability);
2066 }
2067
2068 WorldItem::Function(_) => {
2071 let prev = new_imports.insert(name.clone(), item.clone());
2072 assert!(prev.is_none());
2073 }
2074
2075 WorldItem::Type(id) => {
2079 if let Some(dep) = self.type_interface_dep(*id) {
2080 self.elaborate_world_import(
2081 &mut new_imports,
2082 WorldKey::Interface(dep),
2083 dep,
2084 &self.types[*id].stability,
2085 );
2086 }
2087 let prev = new_imports.insert(name.clone(), item.clone());
2088 assert!(prev.is_none());
2089 }
2090 }
2091 }
2092
2093 let mut new_exports = IndexMap::new();
2099 let mut export_interfaces = IndexMap::new();
2100 for (name, item) in world.exports.iter() {
2101 match item {
2102 WorldItem::Interface { id, stability } => {
2103 let prev = export_interfaces.insert(*id, (name.clone(), stability));
2104 assert!(prev.is_none());
2105 }
2106 WorldItem::Function(_) => {
2107 let prev = new_exports.insert(name.clone(), item.clone());
2108 assert!(prev.is_none());
2109 }
2110 WorldItem::Type(_) => unreachable!(),
2111 }
2112 }
2113
2114 self.elaborate_world_exports(&export_interfaces, &mut new_imports, &mut new_exports)?;
2115
2116 new_imports.sort_by_cached_key(|_name, import| sort_key(self, import));
2120
2121 log::trace!("imports = {new_imports:?}");
2124 log::trace!("exports = {new_exports:?}");
2125 let world = &mut self.worlds[world_id];
2126 world.imports = new_imports;
2127 world.exports = new_exports;
2128
2129 Ok(())
2130 }
2131
2132 fn elaborate_world_import(
2133 &self,
2134 imports: &mut IndexMap<WorldKey, WorldItem>,
2135 key: WorldKey,
2136 id: InterfaceId,
2137 stability: &Stability,
2138 ) {
2139 if imports.contains_key(&key) {
2140 return;
2141 }
2142 for dep in self.interface_direct_deps(id) {
2143 self.elaborate_world_import(imports, WorldKey::Interface(dep), dep, stability);
2144 }
2145 let prev = imports.insert(
2146 key,
2147 WorldItem::Interface {
2148 id,
2149 stability: stability.clone(),
2150 },
2151 );
2152 assert!(prev.is_none());
2153 }
2154
2155 fn elaborate_world_exports(
2202 &self,
2203 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2204 imports: &mut IndexMap<WorldKey, WorldItem>,
2205 exports: &mut IndexMap<WorldKey, WorldItem>,
2206 ) -> Result<()> {
2207 let mut required_imports = HashSet::new();
2208 for (id, (key, stability)) in export_interfaces.iter() {
2209 let name = self.name_world_key(&key);
2210 let ok = add_world_export(
2211 self,
2212 imports,
2213 exports,
2214 export_interfaces,
2215 &mut required_imports,
2216 *id,
2217 key,
2218 true,
2219 stability,
2220 );
2221 if !ok {
2222 bail!(
2223 InvalidTransitiveDependency(name),
2241 );
2242 }
2243 }
2244 return Ok(());
2245
2246 fn add_world_export(
2247 resolve: &Resolve,
2248 imports: &mut IndexMap<WorldKey, WorldItem>,
2249 exports: &mut IndexMap<WorldKey, WorldItem>,
2250 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2251 required_imports: &mut HashSet<InterfaceId>,
2252 id: InterfaceId,
2253 key: &WorldKey,
2254 add_export: bool,
2255 stability: &Stability,
2256 ) -> bool {
2257 if exports.contains_key(key) {
2258 if add_export {
2259 return true;
2260 } else {
2261 return false;
2262 }
2263 }
2264 if !add_export && required_imports.contains(&id) {
2267 return true;
2268 }
2269 let ok = resolve.interface_direct_deps(id).all(|dep| {
2270 let key = WorldKey::Interface(dep);
2271 let add_export = add_export && export_interfaces.contains_key(&dep);
2272 add_world_export(
2273 resolve,
2274 imports,
2275 exports,
2276 export_interfaces,
2277 required_imports,
2278 dep,
2279 &key,
2280 add_export,
2281 stability,
2282 )
2283 });
2284 if !ok {
2285 return false;
2286 }
2287 let item = WorldItem::Interface {
2288 id,
2289 stability: stability.clone(),
2290 };
2291 if add_export {
2292 if required_imports.contains(&id) {
2293 return false;
2294 }
2295 exports.insert(key.clone(), item);
2296 } else {
2297 required_imports.insert(id);
2298 imports.insert(key.clone(), item);
2299 }
2300 true
2301 }
2302 }
2303
2304 pub fn merge_world_imports_based_on_semver(&mut self, world_id: WorldId) -> Result<()> {
2316 let world = &self.worlds[world_id];
2317
2318 let mut semver_tracks = HashMap::new();
2327 let mut to_remove = HashSet::new();
2328 for (key, _) in world.imports.iter() {
2329 let iface_id = match key {
2330 WorldKey::Interface(id) => *id,
2331 WorldKey::Name(_) => continue,
2332 };
2333 let (track, version) = match self.semver_track(iface_id) {
2334 Some(track) => track,
2335 None => continue,
2336 };
2337 log::debug!(
2338 "{} is on track {}/{}",
2339 self.id_of(iface_id).unwrap(),
2340 track.0,
2341 track.1,
2342 );
2343 match semver_tracks.entry(track.clone()) {
2344 hash_map::Entry::Vacant(e) => {
2345 e.insert((version, iface_id));
2346 }
2347 hash_map::Entry::Occupied(mut e) => match version.cmp(&e.get().0) {
2348 Ordering::Greater => {
2349 to_remove.insert(e.get().1);
2350 e.insert((version, iface_id));
2351 }
2352 Ordering::Equal => {}
2353 Ordering::Less => {
2354 to_remove.insert(iface_id);
2355 }
2356 },
2357 }
2358 }
2359
2360 let mut replacements = HashMap::new();
2363 for id in to_remove {
2364 let (track, _) = self.semver_track(id).unwrap();
2365 let (_, latest) = semver_tracks[&track];
2366 let prev = replacements.insert(id, latest);
2367 assert!(prev.is_none());
2368 }
2369
2370 for (to_replace, replace_with) in replacements.iter() {
2375 self.merge_world_item(
2376 &WorldItem::Interface {
2377 id: *to_replace,
2378 stability: Default::default(),
2379 },
2380 &WorldItem::Interface {
2381 id: *replace_with,
2382 stability: Default::default(),
2383 },
2384 )
2385 .with_context(|| {
2386 let old_name = self.id_of(*to_replace).unwrap();
2387 let new_name = self.id_of(*replace_with).unwrap();
2388 format!(
2389 "failed to upgrade `{old_name}` to `{new_name}`, was \
2390 this semver-compatible update not semver compatible?"
2391 )
2392 })?;
2393 }
2394
2395 for (to_replace, replace_with) in replacements.iter() {
2396 log::debug!(
2397 "REPLACE {} => {}",
2398 self.id_of(*to_replace).unwrap(),
2399 self.id_of(*replace_with).unwrap(),
2400 );
2401 }
2402
2403 for (key, item) in mem::take(&mut self.worlds[world_id].imports) {
2412 if let WorldItem::Interface { id, .. } = item {
2413 if replacements.contains_key(&id) {
2414 continue;
2415 }
2416 }
2417
2418 self.update_interface_deps_of_world_item(&item, &replacements);
2419
2420 let prev = self.worlds[world_id].imports.insert(key, item);
2421 assert!(prev.is_none());
2422 }
2423 for (key, item) in mem::take(&mut self.worlds[world_id].exports) {
2424 self.update_interface_deps_of_world_item(&item, &replacements);
2425 let prev = self.worlds[world_id].exports.insert(key, item);
2426 assert!(prev.is_none());
2427 }
2428
2429 let ids = self.worlds.iter().map(|(id, _)| id).collect::<Vec<_>>();
2435 for world_id in ids {
2436 self.elaborate_world(world_id).with_context(|| {
2437 let name = &self.worlds[world_id].name;
2438 format!(
2439 "failed to elaborate world `{name}` after deduplicating imports \
2440 based on semver"
2441 )
2442 })?;
2443 }
2444
2445 #[cfg(debug_assertions)]
2446 self.assert_valid();
2447
2448 Ok(())
2449 }
2450
2451 fn update_interface_deps_of_world_item(
2452 &mut self,
2453 item: &WorldItem,
2454 replacements: &HashMap<InterfaceId, InterfaceId>,
2455 ) {
2456 match *item {
2457 WorldItem::Type(t) => self.update_interface_dep_of_type(t, &replacements),
2458 WorldItem::Interface { id, .. } => {
2459 let types = self.interfaces[id]
2460 .types
2461 .values()
2462 .copied()
2463 .collect::<Vec<_>>();
2464 for ty in types {
2465 self.update_interface_dep_of_type(ty, &replacements);
2466 }
2467 }
2468 WorldItem::Function(_) => {}
2469 }
2470 }
2471
2472 fn semver_track(&self, id: InterfaceId) -> Option<((PackageName, String), &Version)> {
2483 let iface = &self.interfaces[id];
2484 let pkg = &self.packages[iface.package?];
2485 let version = pkg.name.version.as_ref()?;
2486 let mut name = pkg.name.clone();
2487 name.version = Some(PackageName::version_compat_track(version));
2488 Some(((name, iface.name.clone()?), version))
2489 }
2490
2491 fn update_interface_dep_of_type(
2495 &mut self,
2496 ty: TypeId,
2497 replacements: &HashMap<InterfaceId, InterfaceId>,
2498 ) {
2499 let to_replace = match self.type_interface_dep(ty) {
2500 Some(id) => id,
2501 None => return,
2502 };
2503 let replace_with = match replacements.get(&to_replace) {
2504 Some(id) => id,
2505 None => return,
2506 };
2507 let dep = match self.types[ty].kind {
2508 TypeDefKind::Type(Type::Id(id)) => id,
2509 _ => return,
2510 };
2511 let name = self.types[dep].name.as_ref().unwrap();
2512 let replacement_id = self.interfaces[*replace_with].types[name];
2515 self.types[ty].kind = TypeDefKind::Type(Type::Id(replacement_id));
2516 }
2517
2518 pub fn wasm_import_name(
2525 &self,
2526 mangling: ManglingAndAbi,
2527 import: WasmImport<'_>,
2528 ) -> (String, String) {
2529 match mangling {
2530 ManglingAndAbi::Standard32 => match import {
2531 WasmImport::Func { interface, func } => {
2532 let module = match interface {
2533 Some(key) => format!("cm32p2|{}", self.name_canonicalized_world_key(key)),
2534 None => format!("cm32p2"),
2535 };
2536 (module, func.name.clone())
2537 }
2538 WasmImport::ResourceIntrinsic {
2539 interface,
2540 resource,
2541 intrinsic,
2542 } => {
2543 let name = self.types[resource].name.as_ref().unwrap();
2544 let (prefix, name) = match intrinsic {
2545 ResourceIntrinsic::ImportedDrop => ("", format!("{name}_drop")),
2546 ResourceIntrinsic::ExportedDrop => ("_ex_", format!("{name}_drop")),
2547 ResourceIntrinsic::ExportedNew => ("_ex_", format!("{name}_new")),
2548 ResourceIntrinsic::ExportedRep => ("_ex_", format!("{name}_rep")),
2549 };
2550 let module = match interface {
2551 Some(key) => {
2552 format!("cm32p2|{prefix}{}", self.name_canonicalized_world_key(key))
2553 }
2554 None => {
2555 assert_eq!(prefix, "");
2556 format!("cm32p2")
2557 }
2558 };
2559 (module, name)
2560 }
2561 },
2562 ManglingAndAbi::Legacy(abi) => match import {
2563 WasmImport::Func { interface, func } => {
2564 let module = match interface {
2565 Some(key) => self.name_world_key(key),
2566 None => format!("$root"),
2567 };
2568 (module, format!("{}{}", abi.import_prefix(), func.name))
2569 }
2570 WasmImport::ResourceIntrinsic {
2571 interface,
2572 resource,
2573 intrinsic,
2574 } => {
2575 let name = self.types[resource].name.as_ref().unwrap();
2576 let (prefix, name) = match intrinsic {
2577 ResourceIntrinsic::ImportedDrop => ("", format!("[resource-drop]{name}")),
2578 ResourceIntrinsic::ExportedDrop => {
2579 ("[export]", format!("[resource-drop]{name}"))
2580 }
2581 ResourceIntrinsic::ExportedNew => {
2582 ("[export]", format!("[resource-new]{name}"))
2583 }
2584 ResourceIntrinsic::ExportedRep => {
2585 ("[export]", format!("[resource-rep]{name}"))
2586 }
2587 };
2588 let module = match interface {
2589 Some(key) => format!("{prefix}{}", self.name_world_key(key)),
2590 None => {
2591 assert_eq!(prefix, "");
2592 format!("$root")
2593 }
2594 };
2595 (module, format!("{}{name}", abi.import_prefix()))
2596 }
2597 },
2598 }
2599 }
2600
2601 pub fn wasm_export_name(&self, mangling: ManglingAndAbi, export: WasmExport<'_>) -> String {
2605 match mangling {
2606 ManglingAndAbi::Standard32 => match export {
2607 WasmExport::Func {
2608 interface,
2609 func,
2610 kind,
2611 } => {
2612 let mut name = String::from("cm32p2|");
2613 if let Some(interface) = interface {
2614 let s = self.name_canonicalized_world_key(interface);
2615 name.push_str(&s);
2616 }
2617 name.push_str("|");
2618 name.push_str(&func.name);
2619 match kind {
2620 WasmExportKind::Normal => {}
2621 WasmExportKind::PostReturn => name.push_str("_post"),
2622 WasmExportKind::Callback => todo!(
2623 "not yet supported: \
2624 async callback functions using standard name mangling"
2625 ),
2626 }
2627 name
2628 }
2629 WasmExport::ResourceDtor {
2630 interface,
2631 resource,
2632 } => {
2633 let name = self.types[resource].name.as_ref().unwrap();
2634 let interface = self.name_canonicalized_world_key(interface);
2635 format!("cm32p2|{interface}|{name}_dtor")
2636 }
2637 WasmExport::Memory => "cm32p2_memory".to_string(),
2638 WasmExport::Initialize => "cm32p2_initialize".to_string(),
2639 WasmExport::Realloc => "cm32p2_realloc".to_string(),
2640 },
2641 ManglingAndAbi::Legacy(abi) => match export {
2642 WasmExport::Func {
2643 interface,
2644 func,
2645 kind,
2646 } => {
2647 let mut name = abi.export_prefix().to_string();
2648 match kind {
2649 WasmExportKind::Normal => {}
2650 WasmExportKind::PostReturn => name.push_str("cabi_post_"),
2651 WasmExportKind::Callback => {
2652 assert!(matches!(abi, LiftLowerAbi::AsyncCallback));
2653 name = format!("[callback]{name}")
2654 }
2655 }
2656 if let Some(interface) = interface {
2657 let s = self.name_world_key(interface);
2658 name.push_str(&s);
2659 name.push_str("#");
2660 }
2661 name.push_str(&func.name);
2662 name
2663 }
2664 WasmExport::ResourceDtor {
2665 interface,
2666 resource,
2667 } => {
2668 let name = self.types[resource].name.as_ref().unwrap();
2669 let interface = self.name_world_key(interface);
2670 format!("{}{interface}#[dtor]{name}", abi.export_prefix())
2671 }
2672 WasmExport::Memory => "memory".to_string(),
2673 WasmExport::Initialize => "_initialize".to_string(),
2674 WasmExport::Realloc => "cabi_realloc".to_string(),
2675 },
2676 }
2677 }
2678}
2679
2680#[derive(Debug)]
2682pub enum WasmImport<'a> {
2683 Func {
2685 interface: Option<&'a WorldKey>,
2690
2691 func: &'a Function,
2693 },
2694
2695 ResourceIntrinsic {
2697 interface: Option<&'a WorldKey>,
2699
2700 resource: TypeId,
2702
2703 intrinsic: ResourceIntrinsic,
2705 },
2706}
2707
2708#[derive(Debug)]
2711pub enum ResourceIntrinsic {
2712 ImportedDrop,
2713 ExportedDrop,
2714 ExportedNew,
2715 ExportedRep,
2716}
2717
2718#[derive(Debug)]
2721pub enum WasmExportKind {
2722 Normal,
2724
2725 PostReturn,
2727
2728 Callback,
2730}
2731
2732#[derive(Debug)]
2735pub enum WasmExport<'a> {
2736 Func {
2738 interface: Option<&'a WorldKey>,
2741
2742 func: &'a Function,
2744
2745 kind: WasmExportKind,
2747 },
2748
2749 ResourceDtor {
2751 interface: &'a WorldKey,
2753 resource: TypeId,
2755 },
2756
2757 Memory,
2759
2760 Initialize,
2762
2763 Realloc,
2765}
2766
2767#[derive(Default)]
2770pub struct Remap {
2771 pub types: Vec<Option<TypeId>>,
2772 pub interfaces: Vec<Option<InterfaceId>>,
2773 pub worlds: Vec<Option<WorldId>>,
2774 pub packages: Vec<PackageId>,
2775
2776 own_handles: HashMap<TypeId, TypeId>,
2786
2787 type_has_borrow: Vec<Option<bool>>,
2788}
2789
2790fn apply_map<T>(map: &[Option<Id<T>>], id: Id<T>, desc: &str, span: Option<Span>) -> Result<Id<T>> {
2791 match map.get(id.index()) {
2792 Some(Some(id)) => Ok(*id),
2793 Some(None) => {
2794 let msg = format!(
2795 "found a reference to a {desc} which is excluded \
2796 due to its feature not being activated"
2797 );
2798 match span {
2799 Some(span) => Err(Error::new(span, msg).into()),
2800 None => bail!("{msg}"),
2801 }
2802 }
2803 None => panic!("request to remap a {desc} that has not yet been registered"),
2804 }
2805}
2806
2807fn rename(original_name: &str, include_name: &IncludeName) -> Option<String> {
2808 if original_name == include_name.name {
2809 return Some(include_name.as_.to_string());
2810 }
2811 let (kind, rest) = original_name.split_once(']')?;
2812 match rest.split_once('.') {
2813 Some((name, rest)) if name == include_name.name => {
2814 Some(format!("{kind}]{}.{rest}", include_name.as_))
2815 }
2816 _ if rest == include_name.name => Some(format!("{kind}]{}", include_name.as_)),
2817 _ => None,
2818 }
2819}
2820
2821impl Remap {
2822 pub fn map_type(&self, id: TypeId, span: Option<Span>) -> Result<TypeId> {
2823 apply_map(&self.types, id, "type", span)
2824 }
2825
2826 pub fn map_interface(&self, id: InterfaceId, span: Option<Span>) -> Result<InterfaceId> {
2827 apply_map(&self.interfaces, id, "interface", span)
2828 }
2829
2830 pub fn map_world(&self, id: WorldId, span: Option<Span>) -> Result<WorldId> {
2831 apply_map(&self.worlds, id, "world", span)
2832 }
2833
2834 fn append(
2835 &mut self,
2836 resolve: &mut Resolve,
2837 unresolved: UnresolvedPackage,
2838 ) -> Result<PackageId> {
2839 let pkgid = resolve.packages.alloc(Package {
2840 name: unresolved.name.clone(),
2841 docs: unresolved.docs.clone(),
2842 interfaces: Default::default(),
2843 worlds: Default::default(),
2844 });
2845 let prev = resolve.package_names.insert(unresolved.name.clone(), pkgid);
2846 if let Some(prev) = prev {
2847 resolve.package_names.insert(unresolved.name.clone(), prev);
2848 bail!(
2849 "attempting to re-add package `{}` when it's already present in this `Resolve`",
2850 unresolved.name,
2851 );
2852 }
2853
2854 self.process_foreign_deps(resolve, pkgid, &unresolved)?;
2855
2856 let foreign_types = self.types.len();
2857 let foreign_interfaces = self.interfaces.len();
2858 let foreign_worlds = self.worlds.len();
2859
2860 assert_eq!(unresolved.types.len(), unresolved.type_spans.len());
2866 for ((id, mut ty), span) in unresolved
2867 .types
2868 .into_iter()
2869 .zip(&unresolved.type_spans)
2870 .skip(foreign_types)
2871 {
2872 if !resolve.include_type(&ty, pkgid, *span)? {
2873 self.types.push(None);
2874 continue;
2875 }
2876
2877 self.update_typedef(resolve, &mut ty, Some(*span))?;
2878 let new_id = resolve.types.alloc(ty);
2879 assert_eq!(self.types.len(), id.index());
2880
2881 let new_id = match resolve.types[new_id] {
2882 TypeDef {
2887 name: None,
2888 owner: TypeOwner::None,
2889 kind: TypeDefKind::Handle(Handle::Own(id)),
2890 docs: _,
2891 stability: _,
2892 } => *self.own_handles.entry(id).or_insert(new_id),
2893
2894 _ => new_id,
2897 };
2898 self.types.push(Some(new_id));
2899 }
2900
2901 assert_eq!(
2904 unresolved.interfaces.len(),
2905 unresolved.interface_spans.len()
2906 );
2907 for ((id, mut iface), span) in unresolved
2908 .interfaces
2909 .into_iter()
2910 .zip(&unresolved.interface_spans)
2911 .skip(foreign_interfaces)
2912 {
2913 if !resolve
2914 .include_stability(&iface.stability, &pkgid, Some(span.span))
2915 .with_context(|| {
2916 format!(
2917 "failed to process feature gate for interface [{}] in package [{}]",
2918 iface
2919 .name
2920 .as_ref()
2921 .map(String::as_str)
2922 .unwrap_or("<unknown>"),
2923 resolve.packages[pkgid].name,
2924 )
2925 })?
2926 {
2927 self.interfaces.push(None);
2928 continue;
2929 }
2930 assert!(iface.package.is_none());
2931 iface.package = Some(pkgid);
2932 self.update_interface(resolve, &mut iface, Some(span))?;
2933 let new_id = resolve.interfaces.alloc(iface);
2934 assert_eq!(self.interfaces.len(), id.index());
2935 self.interfaces.push(Some(new_id));
2936 }
2937
2938 for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2941 let id = match id {
2942 Some(id) => *id,
2943 None => continue,
2944 };
2945 match &mut resolve.types[id].owner {
2946 TypeOwner::Interface(id) => {
2947 let span = unresolved.type_spans[i];
2948 *id = self.map_interface(*id, Some(span))
2949 .with_context(|| {
2950 "this type is not gated by a feature but its interface is gated by a feature"
2951 })?;
2952 }
2953 TypeOwner::World(_) | TypeOwner::None => {}
2954 }
2955 }
2956
2957 assert_eq!(unresolved.worlds.len(), unresolved.world_spans.len());
2965 for ((id, mut world), span) in unresolved
2966 .worlds
2967 .into_iter()
2968 .zip(&unresolved.world_spans)
2969 .skip(foreign_worlds)
2970 {
2971 if !resolve
2972 .include_stability(&world.stability, &pkgid, Some(span.span))
2973 .with_context(|| {
2974 format!(
2975 "failed to process feature gate for world [{}] in package [{}]",
2976 world.name, resolve.packages[pkgid].name,
2977 )
2978 })?
2979 {
2980 self.worlds.push(None);
2981 continue;
2982 }
2983 self.update_world(&mut world, resolve, &pkgid, &span)?;
2984
2985 let new_id = resolve.worlds.alloc(world);
2986 assert_eq!(self.worlds.len(), id.index());
2987 self.worlds.push(Some(new_id));
2988 }
2989
2990 for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2992 let id = match id {
2993 Some(id) => *id,
2994 None => continue,
2995 };
2996 match &mut resolve.types[id].owner {
2997 TypeOwner::World(id) => {
2998 let span = unresolved.type_spans[i];
2999 *id = self.map_world(*id, Some(span))
3000 .with_context(|| {
3001 "this type is not gated by a feature but its interface is gated by a feature"
3002 })?;
3003 }
3004 TypeOwner::Interface(_) | TypeOwner::None => {}
3005 }
3006 }
3007
3008 assert_eq!(self.worlds.len(), unresolved.world_spans.len());
3025 for (id, span) in self
3026 .worlds
3027 .iter()
3028 .zip(unresolved.world_spans.iter())
3029 .skip(foreign_worlds)
3030 {
3031 let Some(id) = *id else {
3032 continue;
3033 };
3034 self.process_world_includes(id, resolve, &pkgid, &span)?;
3035
3036 resolve.elaborate_world(id).with_context(|| {
3037 Error::new(
3038 span.span,
3039 format!(
3040 "failed to elaborate world imports/exports of `{}`",
3041 resolve.worlds[id].name
3042 ),
3043 )
3044 })?;
3045 }
3046
3047 for id in self.interfaces.iter().skip(foreign_interfaces) {
3049 let id = match id {
3050 Some(id) => *id,
3051 None => continue,
3052 };
3053 let iface = &mut resolve.interfaces[id];
3054 iface.package = Some(pkgid);
3055 if let Some(name) = &iface.name {
3056 let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), id);
3057 assert!(prev.is_none());
3058 }
3059 }
3060 for id in self.worlds.iter().skip(foreign_worlds) {
3061 let id = match id {
3062 Some(id) => *id,
3063 None => continue,
3064 };
3065 let world = &mut resolve.worlds[id];
3066 world.package = Some(pkgid);
3067 let prev = resolve.packages[pkgid]
3068 .worlds
3069 .insert(world.name.clone(), id);
3070 assert!(prev.is_none());
3071 }
3072 Ok(pkgid)
3073 }
3074
3075 fn process_foreign_deps(
3076 &mut self,
3077 resolve: &mut Resolve,
3078 pkgid: PackageId,
3079 unresolved: &UnresolvedPackage,
3080 ) -> Result<()> {
3081 let mut world_to_package = HashMap::new();
3084 let mut interface_to_package = HashMap::new();
3085 for (i, (pkg_name, worlds_or_ifaces)) in unresolved.foreign_deps.iter().enumerate() {
3086 for (name, item) in worlds_or_ifaces {
3087 match item {
3088 AstItem::Interface(unresolved_interface_id) => {
3089 let prev = interface_to_package.insert(
3090 *unresolved_interface_id,
3091 (pkg_name, name, unresolved.foreign_dep_spans[i]),
3092 );
3093 assert!(prev.is_none());
3094 }
3095 AstItem::World(unresolved_world_id) => {
3096 let prev = world_to_package.insert(
3097 *unresolved_world_id,
3098 (pkg_name, name, unresolved.foreign_dep_spans[i]),
3099 );
3100 assert!(prev.is_none());
3101 }
3102 }
3103 }
3104 }
3105
3106 self.process_foreign_interfaces(unresolved, &interface_to_package, resolve)?;
3110
3111 self.process_foreign_worlds(unresolved, &world_to_package, resolve)?;
3115
3116 self.process_foreign_types(unresolved, pkgid, resolve)?;
3119
3120 for (id, span) in unresolved.required_resource_types.iter() {
3121 let Ok(mut id) = self.map_type(*id, Some(*span)) else {
3126 continue;
3127 };
3128 loop {
3129 match resolve.types[id].kind {
3130 TypeDefKind::Type(Type::Id(i)) => id = i,
3131 TypeDefKind::Resource => break,
3132 _ => bail!(Error::new(
3133 *span,
3134 format!("type used in a handle must be a resource"),
3135 )),
3136 }
3137 }
3138 }
3139
3140 #[cfg(debug_assertions)]
3141 resolve.assert_valid();
3142
3143 Ok(())
3144 }
3145
3146 fn process_foreign_interfaces(
3147 &mut self,
3148 unresolved: &UnresolvedPackage,
3149 interface_to_package: &HashMap<InterfaceId, (&PackageName, &String, Span)>,
3150 resolve: &mut Resolve,
3151 ) -> Result<(), anyhow::Error> {
3152 for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() {
3153 let (pkg_name, interface, span) = match interface_to_package.get(&unresolved_iface_id) {
3154 Some(items) => *items,
3155 None => break,
3159 };
3160 let pkgid = resolve
3161 .package_names
3162 .get(pkg_name)
3163 .copied()
3164 .ok_or_else(|| {
3165 PackageNotFoundError::new(
3166 span,
3167 pkg_name.clone(),
3168 resolve.package_names.keys().cloned().collect(),
3169 )
3170 })?;
3171
3172 assert!(unresolved_iface.functions.is_empty());
3174
3175 let pkg = &resolve.packages[pkgid];
3176 let span = &unresolved.interface_spans[unresolved_iface_id.index()];
3177 let iface_id = pkg
3178 .interfaces
3179 .get(interface)
3180 .copied()
3181 .ok_or_else(|| Error::new(span.span, "interface not found in package"))?;
3182 assert_eq!(self.interfaces.len(), unresolved_iface_id.index());
3183 self.interfaces.push(Some(iface_id));
3184 }
3185 for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) {
3186 assert!(
3187 interface_to_package.get(&id).is_none(),
3188 "found foreign interface after local interface"
3189 );
3190 }
3191 Ok(())
3192 }
3193
3194 fn process_foreign_worlds(
3195 &mut self,
3196 unresolved: &UnresolvedPackage,
3197 world_to_package: &HashMap<WorldId, (&PackageName, &String, Span)>,
3198 resolve: &mut Resolve,
3199 ) -> Result<(), anyhow::Error> {
3200 for (unresolved_world_id, _) in unresolved.worlds.iter() {
3201 let (pkg_name, world, span) = match world_to_package.get(&unresolved_world_id) {
3202 Some(items) => *items,
3203 None => break,
3206 };
3207
3208 let pkgid = resolve
3209 .package_names
3210 .get(pkg_name)
3211 .copied()
3212 .ok_or_else(|| Error::new(span, "package not found"))?;
3213 let pkg = &resolve.packages[pkgid];
3214 let span = &unresolved.world_spans[unresolved_world_id.index()];
3215 let world_id = pkg
3216 .worlds
3217 .get(world)
3218 .copied()
3219 .ok_or_else(|| Error::new(span.span, "world not found in package"))?;
3220 assert_eq!(self.worlds.len(), unresolved_world_id.index());
3221 self.worlds.push(Some(world_id));
3222 }
3223 for (id, _) in unresolved.worlds.iter().skip(self.worlds.len()) {
3224 assert!(
3225 world_to_package.get(&id).is_none(),
3226 "found foreign world after local world"
3227 );
3228 }
3229 Ok(())
3230 }
3231
3232 fn process_foreign_types(
3233 &mut self,
3234 unresolved: &UnresolvedPackage,
3235 pkgid: PackageId,
3236 resolve: &mut Resolve,
3237 ) -> Result<(), anyhow::Error> {
3238 for ((unresolved_type_id, unresolved_ty), span) in
3239 unresolved.types.iter().zip(&unresolved.type_spans)
3240 {
3241 match unresolved_ty.kind {
3245 TypeDefKind::Unknown => {}
3246 _ => break,
3247 }
3248
3249 if !resolve.include_type(unresolved_ty, pkgid, *span)? {
3250 self.types.push(None);
3251 continue;
3252 }
3253
3254 let unresolved_iface_id = match unresolved_ty.owner {
3255 TypeOwner::Interface(id) => id,
3256 _ => unreachable!(),
3257 };
3258 let iface_id = self.map_interface(unresolved_iface_id, None)?;
3259 let name = unresolved_ty.name.as_ref().unwrap();
3260 let span = unresolved.unknown_type_spans[unresolved_type_id.index()];
3261 let type_id = *resolve.interfaces[iface_id]
3262 .types
3263 .get(name)
3264 .ok_or_else(|| {
3265 Error::new(span, format!("type `{name}` not defined in interface"))
3266 })?;
3267 assert_eq!(self.types.len(), unresolved_type_id.index());
3268 self.types.push(Some(type_id));
3269 }
3270 for (_, ty) in unresolved.types.iter().skip(self.types.len()) {
3271 if let TypeDefKind::Unknown = ty.kind {
3272 panic!("unknown type after defined type");
3273 }
3274 }
3275 Ok(())
3276 }
3277
3278 fn update_typedef(
3279 &mut self,
3280 resolve: &mut Resolve,
3281 ty: &mut TypeDef,
3282 span: Option<Span>,
3283 ) -> Result<()> {
3284 use crate::TypeDefKind::*;
3287 match &mut ty.kind {
3288 Handle(handle) => match handle {
3289 crate::Handle::Own(ty) | crate::Handle::Borrow(ty) => {
3290 self.update_type_id(ty, span)?
3291 }
3292 },
3293 Resource => {}
3294 Record(r) => {
3295 for field in r.fields.iter_mut() {
3296 self.update_ty(resolve, &mut field.ty, span)
3297 .with_context(|| format!("failed to update field `{}`", field.name))?;
3298 }
3299 }
3300 Tuple(t) => {
3301 for ty in t.types.iter_mut() {
3302 self.update_ty(resolve, ty, span)?;
3303 }
3304 }
3305 Variant(v) => {
3306 for case in v.cases.iter_mut() {
3307 if let Some(t) = &mut case.ty {
3308 self.update_ty(resolve, t, span)?;
3309 }
3310 }
3311 }
3312 Option(t) | List(t, ..) | FixedSizeList(t, ..) | Future(Some(t)) | Stream(Some(t)) => {
3313 self.update_ty(resolve, t, span)?
3314 }
3315 Result(r) => {
3316 if let Some(ty) = &mut r.ok {
3317 self.update_ty(resolve, ty, span)?;
3318 }
3319 if let Some(ty) = &mut r.err {
3320 self.update_ty(resolve, ty, span)?;
3321 }
3322 }
3323
3324 Type(crate::Type::Id(id)) => self.update_type_id(id, span)?,
3329 Type(_) => {}
3330
3331 Flags(_) | Enum(_) | Future(None) | Stream(None) => {}
3333
3334 Unknown => unreachable!(),
3335 }
3336
3337 Ok(())
3338 }
3339
3340 fn update_ty(
3341 &mut self,
3342 resolve: &mut Resolve,
3343 ty: &mut Type,
3344 span: Option<Span>,
3345 ) -> Result<()> {
3346 let id = match ty {
3347 Type::Id(id) => id,
3348 _ => return Ok(()),
3349 };
3350 self.update_type_id(id, span)?;
3351
3352 let mut cur = *id;
3357 let points_to_resource = loop {
3358 match resolve.types[cur].kind {
3359 TypeDefKind::Type(Type::Id(id)) => cur = id,
3360 TypeDefKind::Resource => break true,
3361 _ => break false,
3362 }
3363 };
3364
3365 if points_to_resource {
3366 *id = *self.own_handles.entry(*id).or_insert_with(|| {
3367 resolve.types.alloc(TypeDef {
3368 name: None,
3369 owner: TypeOwner::None,
3370 kind: TypeDefKind::Handle(Handle::Own(*id)),
3371 docs: Default::default(),
3372 stability: Default::default(),
3373 })
3374 });
3375 }
3376 Ok(())
3377 }
3378
3379 fn update_type_id(&self, id: &mut TypeId, span: Option<Span>) -> Result<()> {
3380 *id = self.map_type(*id, span)?;
3381 Ok(())
3382 }
3383
3384 fn update_interface(
3385 &mut self,
3386 resolve: &mut Resolve,
3387 iface: &mut Interface,
3388 spans: Option<&InterfaceSpan>,
3389 ) -> Result<()> {
3390 iface.types.retain(|_, ty| self.types[ty.index()].is_some());
3391 let iface_pkg_id = iface.package.as_ref().unwrap_or_else(|| {
3392 panic!(
3393 "unexpectedly missing package on interface [{}]",
3394 iface
3395 .name
3396 .as_ref()
3397 .map(String::as_str)
3398 .unwrap_or("<unknown>"),
3399 )
3400 });
3401
3402 for (_name, ty) in iface.types.iter_mut() {
3405 self.update_type_id(ty, spans.map(|s| s.span))?;
3406 }
3407 if let Some(spans) = spans {
3408 assert_eq!(iface.functions.len(), spans.funcs.len());
3409 }
3410 for (i, (func_name, func)) in iface.functions.iter_mut().enumerate() {
3411 let span = spans.map(|s| s.funcs[i]);
3412 if !resolve
3413 .include_stability(&func.stability, iface_pkg_id, span)
3414 .with_context(|| {
3415 format!(
3416 "failed to process feature gate for function [{func_name}] in package [{}]",
3417 resolve.packages[*iface_pkg_id].name,
3418 )
3419 })?
3420 {
3421 continue;
3422 }
3423 self.update_function(resolve, func, span)
3424 .with_context(|| format!("failed to update function `{}`", func.name))?;
3425 }
3426
3427 for (name, func) in mem::take(&mut iface.functions) {
3430 if resolve.include_stability(&func.stability, iface_pkg_id, None)? {
3431 iface.functions.insert(name, func);
3432 }
3433 }
3434
3435 Ok(())
3436 }
3437
3438 fn update_function(
3439 &mut self,
3440 resolve: &mut Resolve,
3441 func: &mut Function,
3442 span: Option<Span>,
3443 ) -> Result<()> {
3444 if let Some(id) = func.kind.resource_mut() {
3445 self.update_type_id(id, span)?;
3446 }
3447 for (_, ty) in func.params.iter_mut() {
3448 self.update_ty(resolve, ty, span)?;
3449 }
3450 if let Some(ty) = &mut func.result {
3451 self.update_ty(resolve, ty, span)?;
3452 }
3453
3454 if let Some(ty) = &func.result {
3455 if self.type_has_borrow(resolve, ty) {
3456 match span {
3457 Some(span) => {
3458 bail!(Error::new(
3459 span,
3460 format!(
3461 "function returns a type which contains \
3462 a `borrow<T>` which is not supported"
3463 )
3464 ))
3465 }
3466 None => unreachable!(),
3467 }
3468 }
3469 }
3470
3471 Ok(())
3472 }
3473
3474 fn update_world(
3475 &mut self,
3476 world: &mut World,
3477 resolve: &mut Resolve,
3478 pkg_id: &PackageId,
3479 spans: &WorldSpan,
3480 ) -> Result<()> {
3481 assert_eq!(world.imports.len(), spans.imports.len());
3482 assert_eq!(world.exports.len(), spans.exports.len());
3483
3484 let imports = mem::take(&mut world.imports).into_iter();
3488 let imports = imports.zip(&spans.imports).map(|p| (p, true));
3489 let exports = mem::take(&mut world.exports).into_iter();
3490 let exports = exports.zip(&spans.exports).map(|p| (p, false));
3491 for (((mut name, mut item), span), import) in imports.chain(exports) {
3492 if let WorldItem::Type(id) = &mut item {
3495 *id = self.map_type(*id, Some(*span))?;
3496 }
3497 let stability = item.stability(resolve);
3498 if !resolve
3499 .include_stability(stability, pkg_id, Some(*span))
3500 .with_context(|| format!("failed to process world item in `{}`", world.name))?
3501 {
3502 continue;
3503 }
3504 self.update_world_key(&mut name, Some(*span))?;
3505 match &mut item {
3506 WorldItem::Interface { id, .. } => {
3507 *id = self.map_interface(*id, Some(*span))?;
3508 }
3509 WorldItem::Function(f) => {
3510 self.update_function(resolve, f, Some(*span))?;
3511 }
3512 WorldItem::Type(_) => {
3513 }
3515 }
3516
3517 let dst = if import {
3518 &mut world.imports
3519 } else {
3520 &mut world.exports
3521 };
3522 let prev = dst.insert(name, item);
3523 assert!(prev.is_none());
3524 }
3525
3526 Ok(())
3527 }
3528
3529 fn process_world_includes(
3530 &self,
3531 id: WorldId,
3532 resolve: &mut Resolve,
3533 pkg_id: &PackageId,
3534 spans: &WorldSpan,
3535 ) -> Result<()> {
3536 let world = &mut resolve.worlds[id];
3537 assert_eq!(world.includes.len(), spans.includes.len());
3540 let includes = mem::take(&mut world.includes);
3541 let include_names = mem::take(&mut world.include_names);
3542 for (((stability, include_world), span), names) in includes
3543 .into_iter()
3544 .zip(&spans.includes)
3545 .zip(&include_names)
3546 {
3547 if !resolve
3548 .include_stability(&stability, pkg_id, Some(*span))
3549 .with_context(|| {
3550 format!(
3551 "failed to process feature gate for included world [{}] in package [{}]",
3552 resolve.worlds[include_world].name.as_str(),
3553 resolve.packages[*pkg_id].name
3554 )
3555 })?
3556 {
3557 continue;
3558 }
3559 self.resolve_include(id, include_world, names, *span, pkg_id, resolve)?;
3560 }
3561
3562 Ok(())
3563 }
3564
3565 fn update_world_key(&self, key: &mut WorldKey, span: Option<Span>) -> Result<()> {
3566 match key {
3567 WorldKey::Name(_) => {}
3568 WorldKey::Interface(id) => {
3569 *id = self.map_interface(*id, span)?;
3570 }
3571 }
3572 Ok(())
3573 }
3574
3575 fn resolve_include(
3576 &self,
3577 id: WorldId,
3578 include_world_id_orig: WorldId,
3579 names: &[IncludeName],
3580 span: Span,
3581 pkg_id: &PackageId,
3582 resolve: &mut Resolve,
3583 ) -> Result<()> {
3584 let world = &resolve.worlds[id];
3585 let include_world_id = self.map_world(include_world_id_orig, Some(span))?;
3586 let include_world = resolve.worlds[include_world_id].clone();
3587 let mut names_ = names.to_owned();
3588 let is_external_include = world.package != include_world.package;
3589
3590 for import in include_world.imports.iter() {
3592 self.remove_matching_name(import, &mut names_);
3593 }
3594 for export in include_world.exports.iter() {
3595 self.remove_matching_name(export, &mut names_);
3596 }
3597 if !names_.is_empty() {
3598 bail!(Error::new(
3599 span,
3600 format!(
3601 "no import or export kebab-name `{}`. Note that an ID does not support renaming",
3602 names_[0].name
3603 ),
3604 ));
3605 }
3606
3607 let mut cloner = clone::Cloner::new(
3608 resolve,
3609 TypeOwner::World(if is_external_include {
3610 include_world_id
3611 } else {
3612 include_world_id
3613 }),
3615 TypeOwner::World(id),
3616 );
3617 cloner.new_package = Some(*pkg_id);
3618
3619 for import in include_world.imports.iter() {
3621 self.resolve_include_item(
3622 &mut cloner,
3623 names,
3624 |resolve| &mut resolve.worlds[id].imports,
3625 import,
3626 span,
3627 "import",
3628 is_external_include,
3629 )?;
3630 }
3631
3632 for export in include_world.exports.iter() {
3633 self.resolve_include_item(
3634 &mut cloner,
3635 names,
3636 |resolve| &mut resolve.worlds[id].exports,
3637 export,
3638 span,
3639 "export",
3640 is_external_include,
3641 )?;
3642 }
3643 Ok(())
3644 }
3645
3646 fn resolve_include_item(
3647 &self,
3648 cloner: &mut clone::Cloner<'_>,
3649 names: &[IncludeName],
3650 get_items: impl Fn(&mut Resolve) -> &mut IndexMap<WorldKey, WorldItem>,
3651 item: (&WorldKey, &WorldItem),
3652 span: Span,
3653 item_type: &str,
3654 is_external_include: bool,
3655 ) -> Result<()> {
3656 match item.0 {
3657 WorldKey::Name(n) => {
3658 let n = names
3659 .into_iter()
3660 .find_map(|include_name| rename(n, include_name))
3661 .unwrap_or(n.clone());
3662
3663 let mut new_item = item.1.clone();
3669 let key = WorldKey::Name(n.clone());
3670 cloner.world_item(&key, &mut new_item, &mut CloneMaps::default());
3671 match &mut new_item {
3672 WorldItem::Function(f) => f.name = n.clone(),
3673 WorldItem::Type(id) => cloner.resolve.types[*id].name = Some(n.clone()),
3674 WorldItem::Interface { .. } => {}
3675 }
3676
3677 let prev = get_items(cloner.resolve).insert(key, new_item);
3678 if prev.is_some() {
3679 bail!(Error::new(
3680 span,
3681 format!("{item_type} of `{n}` shadows previously {item_type}ed items"),
3682 ))
3683 }
3684 }
3685 key @ WorldKey::Interface(_) => {
3686 let prev = get_items(cloner.resolve)
3687 .entry(key.clone())
3688 .or_insert(item.1.clone());
3689 match (&item.1, prev) {
3690 (
3691 WorldItem::Interface {
3692 id: aid,
3693 stability: astability,
3694 },
3695 WorldItem::Interface {
3696 id: bid,
3697 stability: bstability,
3698 },
3699 ) => {
3700 assert_eq!(*aid, *bid);
3701 merge_include_stability(astability, bstability, is_external_include)?;
3702 }
3703 (WorldItem::Interface { .. }, _) => unreachable!(),
3704 (WorldItem::Function(_), _) => unreachable!(),
3705 (WorldItem::Type(_), _) => unreachable!(),
3706 }
3707 }
3708 };
3709
3710 Ok(())
3711 }
3712
3713 fn remove_matching_name(&self, item: (&WorldKey, &WorldItem), names: &mut Vec<IncludeName>) {
3714 match item.0 {
3715 WorldKey::Name(n) => {
3716 names.retain(|name| rename(n, name).is_none());
3717 }
3718 _ => {}
3719 }
3720 }
3721
3722 fn type_has_borrow(&mut self, resolve: &Resolve, ty: &Type) -> bool {
3723 let id = match ty {
3724 Type::Id(id) => *id,
3725 _ => return false,
3726 };
3727
3728 if let Some(Some(has_borrow)) = self.type_has_borrow.get(id.index()) {
3729 return *has_borrow;
3730 }
3731
3732 let result = self.typedef_has_borrow(resolve, &resolve.types[id]);
3733 if self.type_has_borrow.len() <= id.index() {
3734 self.type_has_borrow.resize(id.index() + 1, None);
3735 }
3736 self.type_has_borrow[id.index()] = Some(result);
3737 result
3738 }
3739
3740 fn typedef_has_borrow(&mut self, resolve: &Resolve, ty: &TypeDef) -> bool {
3741 match &ty.kind {
3742 TypeDefKind::Type(t) => self.type_has_borrow(resolve, t),
3743 TypeDefKind::Variant(v) => v
3744 .cases
3745 .iter()
3746 .filter_map(|case| case.ty.as_ref())
3747 .any(|ty| self.type_has_borrow(resolve, ty)),
3748 TypeDefKind::Handle(Handle::Borrow(_)) => true,
3749 TypeDefKind::Handle(Handle::Own(_)) => false,
3750 TypeDefKind::Resource => false,
3751 TypeDefKind::Record(r) => r
3752 .fields
3753 .iter()
3754 .any(|case| self.type_has_borrow(resolve, &case.ty)),
3755 TypeDefKind::Flags(_) => false,
3756 TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.type_has_borrow(resolve, t)),
3757 TypeDefKind::Enum(_) => false,
3758 TypeDefKind::List(ty)
3759 | TypeDefKind::FixedSizeList(ty, ..)
3760 | TypeDefKind::Future(Some(ty))
3761 | TypeDefKind::Stream(Some(ty))
3762 | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty),
3763 TypeDefKind::Result(r) => [&r.ok, &r.err]
3764 .iter()
3765 .filter_map(|t| t.as_ref())
3766 .any(|t| self.type_has_borrow(resolve, t)),
3767 TypeDefKind::Future(None) | TypeDefKind::Stream(None) => false,
3768 TypeDefKind::Unknown => unreachable!(),
3769 }
3770 }
3771}
3772
3773struct MergeMap<'a> {
3774 package_map: HashMap<PackageId, PackageId>,
3777
3778 interface_map: HashMap<InterfaceId, InterfaceId>,
3781
3782 type_map: HashMap<TypeId, TypeId>,
3785
3786 world_map: HashMap<WorldId, WorldId>,
3789
3790 interfaces_to_add: Vec<(String, PackageId, InterfaceId)>,
3798 worlds_to_add: Vec<(String, PackageId, WorldId)>,
3799
3800 from: &'a Resolve,
3802
3803 into: &'a Resolve,
3805}
3806
3807impl<'a> MergeMap<'a> {
3808 fn new(from: &'a Resolve, into: &'a Resolve) -> MergeMap<'a> {
3809 MergeMap {
3810 package_map: Default::default(),
3811 interface_map: Default::default(),
3812 type_map: Default::default(),
3813 world_map: Default::default(),
3814 interfaces_to_add: Default::default(),
3815 worlds_to_add: Default::default(),
3816 from,
3817 into,
3818 }
3819 }
3820
3821 fn build(&mut self) -> Result<()> {
3822 for from_id in self.from.topological_packages() {
3823 let from = &self.from.packages[from_id];
3824 let into_id = match self.into.package_names.get(&from.name) {
3825 Some(id) => *id,
3826
3827 None => {
3830 log::trace!("adding unique package {}", from.name);
3831 continue;
3832 }
3833 };
3834 log::trace!("merging duplicate package {}", from.name);
3835
3836 self.build_package(from_id, into_id).with_context(|| {
3837 format!("failed to merge package `{}` into existing copy", from.name)
3838 })?;
3839 }
3840
3841 Ok(())
3842 }
3843
3844 fn build_package(&mut self, from_id: PackageId, into_id: PackageId) -> Result<()> {
3845 let prev = self.package_map.insert(from_id, into_id);
3846 assert!(prev.is_none());
3847
3848 let from = &self.from.packages[from_id];
3849 let into = &self.into.packages[into_id];
3850
3851 for (name, from_interface_id) in from.interfaces.iter() {
3855 let into_interface_id = match into.interfaces.get(name) {
3856 Some(id) => *id,
3857 None => {
3858 log::trace!("adding unique interface {name}");
3859 self.interfaces_to_add
3860 .push((name.clone(), into_id, *from_interface_id));
3861 continue;
3862 }
3863 };
3864
3865 log::trace!("merging duplicate interfaces {name}");
3866 self.build_interface(*from_interface_id, into_interface_id)
3867 .with_context(|| format!("failed to merge interface `{name}`"))?;
3868 }
3869
3870 for (name, from_world_id) in from.worlds.iter() {
3871 let into_world_id = match into.worlds.get(name) {
3872 Some(id) => *id,
3873 None => {
3874 log::trace!("adding unique world {name}");
3875 self.worlds_to_add
3876 .push((name.clone(), into_id, *from_world_id));
3877 continue;
3878 }
3879 };
3880
3881 log::trace!("merging duplicate worlds {name}");
3882 self.build_world(*from_world_id, into_world_id)
3883 .with_context(|| format!("failed to merge world `{name}`"))?;
3884 }
3885
3886 Ok(())
3887 }
3888
3889 fn build_interface(&mut self, from_id: InterfaceId, into_id: InterfaceId) -> Result<()> {
3890 let prev = self.interface_map.insert(from_id, into_id);
3891 assert!(prev.is_none());
3892
3893 let from_interface = &self.from.interfaces[from_id];
3894 let into_interface = &self.into.interfaces[into_id];
3895
3896 for (name, from_type_id) in from_interface.types.iter() {
3910 let into_type_id = *into_interface
3911 .types
3912 .get(name)
3913 .ok_or_else(|| anyhow!("expected type `{name}` to be present"))?;
3914 let prev = self.type_map.insert(*from_type_id, into_type_id);
3915 assert!(prev.is_none());
3916
3917 self.build_type_id(*from_type_id, into_type_id)
3918 .with_context(|| format!("mismatch in type `{name}`"))?;
3919 }
3920
3921 for (name, from_func) in from_interface.functions.iter() {
3922 let into_func = match into_interface.functions.get(name) {
3923 Some(func) => func,
3924 None => bail!("expected function `{name}` to be present"),
3925 };
3926 self.build_function(from_func, into_func)
3927 .with_context(|| format!("mismatch in function `{name}`"))?;
3928 }
3929
3930 Ok(())
3931 }
3932
3933 fn build_type_id(&mut self, from_id: TypeId, into_id: TypeId) -> Result<()> {
3934 let _ = from_id;
3938 let _ = into_id;
3939 Ok(())
3940 }
3941
3942 fn build_type(&mut self, from_ty: &Type, into_ty: &Type) -> Result<()> {
3943 match (from_ty, into_ty) {
3944 (Type::Id(from), Type::Id(into)) => {
3945 self.build_type_id(*from, *into)?;
3946 }
3947 (from, into) if from != into => bail!("different kinds of types"),
3948 _ => {}
3949 }
3950 Ok(())
3951 }
3952
3953 fn build_function(&mut self, from_func: &Function, into_func: &Function) -> Result<()> {
3954 if from_func.name != into_func.name {
3955 bail!(
3956 "different function names `{}` and `{}`",
3957 from_func.name,
3958 into_func.name
3959 );
3960 }
3961 match (&from_func.kind, &into_func.kind) {
3962 (FunctionKind::Freestanding, FunctionKind::Freestanding) => {}
3963 (FunctionKind::AsyncFreestanding, FunctionKind::AsyncFreestanding) => {}
3964
3965 (FunctionKind::Method(from), FunctionKind::Method(into))
3966 | (FunctionKind::Static(from), FunctionKind::Static(into))
3967 | (FunctionKind::AsyncMethod(from), FunctionKind::AsyncMethod(into))
3968 | (FunctionKind::AsyncStatic(from), FunctionKind::AsyncStatic(into))
3969 | (FunctionKind::Constructor(from), FunctionKind::Constructor(into)) => {
3970 self.build_type_id(*from, *into)
3971 .context("different function kind types")?;
3972 }
3973
3974 (FunctionKind::Method(_), _)
3975 | (FunctionKind::Constructor(_), _)
3976 | (FunctionKind::Static(_), _)
3977 | (FunctionKind::Freestanding, _)
3978 | (FunctionKind::AsyncFreestanding, _)
3979 | (FunctionKind::AsyncMethod(_), _)
3980 | (FunctionKind::AsyncStatic(_), _) => {
3981 bail!("different function kind types")
3982 }
3983 }
3984
3985 if from_func.params.len() != into_func.params.len() {
3986 bail!("different number of function parameters");
3987 }
3988 for ((from_name, from_ty), (into_name, into_ty)) in
3989 from_func.params.iter().zip(&into_func.params)
3990 {
3991 if from_name != into_name {
3992 bail!("different function parameter names: {from_name} != {into_name}");
3993 }
3994 self.build_type(from_ty, into_ty)
3995 .with_context(|| format!("different function parameter types for `{from_name}`"))?;
3996 }
3997 match (&from_func.result, &into_func.result) {
3998 (Some(from_ty), Some(into_ty)) => {
3999 self.build_type(from_ty, into_ty)
4000 .context("different function result types")?;
4001 }
4002 (None, None) => {}
4003 (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
4004 }
4005 Ok(())
4006 }
4007
4008 fn build_world(&mut self, from_id: WorldId, into_id: WorldId) -> Result<()> {
4009 let prev = self.world_map.insert(from_id, into_id);
4010 assert!(prev.is_none());
4011
4012 let from_world = &self.from.worlds[from_id];
4013 let into_world = &self.into.worlds[into_id];
4014
4015 if from_world.imports.len() != into_world.imports.len() {
4024 bail!("world contains different number of imports than expected");
4025 }
4026 if from_world.exports.len() != into_world.exports.len() {
4027 bail!("world contains different number of exports than expected");
4028 }
4029
4030 for (from_name, from) in from_world.imports.iter() {
4031 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4032 let name_str = self.from.name_world_key(from_name);
4033 let into = into_world
4034 .imports
4035 .get(&into_name)
4036 .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?;
4037 self.match_world_item(from, into)
4038 .with_context(|| format!("import `{name_str}` didn't match target world"))?;
4039 }
4040
4041 for (from_name, from) in from_world.exports.iter() {
4042 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4043 let name_str = self.from.name_world_key(from_name);
4044 let into = into_world
4045 .exports
4046 .get(&into_name)
4047 .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?;
4048 self.match_world_item(from, into)
4049 .with_context(|| format!("export `{name_str}` didn't match target world"))?;
4050 }
4051
4052 Ok(())
4053 }
4054
4055 fn map_name(
4056 from_name: &WorldKey,
4057 interface_map: &HashMap<InterfaceId, InterfaceId>,
4058 ) -> WorldKey {
4059 match from_name {
4060 WorldKey::Name(s) => WorldKey::Name(s.clone()),
4061 WorldKey::Interface(id) => {
4062 WorldKey::Interface(interface_map.get(id).copied().unwrap_or(*id))
4063 }
4064 }
4065 }
4066
4067 fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> Result<()> {
4068 match (from, into) {
4069 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
4070 match (
4071 &self.from.interfaces[*from].name,
4072 &self.into.interfaces[*into].name,
4073 ) {
4074 (None, None) => self.build_interface(*from, *into)?,
4078
4079 _ => {
4084 if self.interface_map.get(&from) != Some(&into) {
4085 bail!("interfaces are not the same");
4086 }
4087 }
4088 }
4089 }
4090 (WorldItem::Function(from), WorldItem::Function(into)) => {
4091 let _ = (from, into);
4092 }
4095 (WorldItem::Type(from), WorldItem::Type(into)) => {
4096 let prev = self.type_map.insert(*from, *into);
4099 assert!(prev.is_none());
4100 }
4101
4102 (WorldItem::Interface { .. }, _)
4103 | (WorldItem::Function(_), _)
4104 | (WorldItem::Type(_), _) => {
4105 bail!("world items do not have the same type")
4106 }
4107 }
4108 Ok(())
4109 }
4110}
4111
4112fn update_stability(from: &Stability, into: &mut Stability) -> Result<()> {
4118 if from == into || from.is_unknown() {
4121 return Ok(());
4122 }
4123 if into.is_unknown() {
4126 *into = from.clone();
4127 return Ok(());
4128 }
4129
4130 bail!("mismatch in stability from '{:?}' to '{:?}'", from, into)
4133}
4134
4135fn merge_include_stability(
4136 from: &Stability,
4137 into: &mut Stability,
4138 is_external_include: bool,
4139) -> Result<()> {
4140 if is_external_include && from.is_stable() {
4141 log::trace!("dropped stability from external package");
4142 *into = Stability::Unknown;
4143 return Ok(());
4144 }
4145
4146 return update_stability(from, into);
4147}
4148
4149#[derive(Debug, Clone)]
4162pub struct InvalidTransitiveDependency(String);
4163
4164impl fmt::Display for InvalidTransitiveDependency {
4165 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4166 write!(
4167 f,
4168 "interface `{}` transitively depends on an interface in \
4169 incompatible ways",
4170 self.0
4171 )
4172 }
4173}
4174
4175impl std::error::Error for InvalidTransitiveDependency {}
4176
4177#[cfg(test)]
4178mod tests {
4179 use crate::Resolve;
4180 use anyhow::Result;
4181
4182 #[test]
4183 fn select_world() -> Result<()> {
4184 let mut resolve = Resolve::default();
4185 resolve.push_str(
4186 "test.wit",
4187 r#"
4188 package foo:bar@0.1.0;
4189
4190 world foo {}
4191 "#,
4192 )?;
4193 resolve.push_str(
4194 "test.wit",
4195 r#"
4196 package foo:baz@0.1.0;
4197
4198 world foo {}
4199 "#,
4200 )?;
4201 resolve.push_str(
4202 "test.wit",
4203 r#"
4204 package foo:baz@0.2.0;
4205
4206 world foo {}
4207 "#,
4208 )?;
4209
4210 let dummy = resolve.push_str(
4211 "test.wit",
4212 r#"
4213 package foo:dummy;
4214
4215 world foo {}
4216 "#,
4217 )?;
4218
4219 assert!(resolve.select_world(&[dummy], None).is_ok());
4220 assert!(resolve.select_world(&[dummy], Some("xx")).is_err());
4221 assert!(resolve.select_world(&[dummy], Some("")).is_err());
4222 assert!(resolve.select_world(&[dummy], Some("foo:bar/foo")).is_ok());
4223 assert!(
4224 resolve
4225 .select_world(&[dummy], Some("foo:bar/foo@0.1.0"))
4226 .is_ok()
4227 );
4228 assert!(resolve.select_world(&[dummy], Some("foo:baz/foo")).is_err());
4229 assert!(
4230 resolve
4231 .select_world(&[dummy], Some("foo:baz/foo@0.1.0"))
4232 .is_ok()
4233 );
4234 assert!(
4235 resolve
4236 .select_world(&[dummy], Some("foo:baz/foo@0.2.0"))
4237 .is_ok()
4238 );
4239 Ok(())
4240 }
4241
4242 #[test]
4245 fn select_world_multiple_packages() -> Result<()> {
4246 use wit_parser::Resolve;
4247
4248 let mut resolve = Resolve::default();
4249
4250 let stuff = resolve.push_str(
4252 "./my-test.wit",
4253 r#"
4254 package test:stuff;
4255
4256 world foo {
4257 // ...
4258 }
4259 "#,
4260 )?;
4261 assert!(resolve.select_world(&[stuff], None).is_ok());
4262 assert!(resolve.select_world(&[stuff], Some("foo")).is_ok());
4263
4264 let empty = resolve.push_str(
4267 "./my-test.wit",
4268 r#"
4269 package test:empty;
4270 "#,
4271 )?;
4272 assert!(resolve.select_world(&[stuff, empty], None).is_err());
4273 assert!(resolve.select_world(&[stuff, empty], Some("foo")).is_err());
4274 assert!(resolve.select_world(&[empty], None).is_err());
4275 assert!(resolve.select_world(&[empty], Some("foo")).is_err());
4276
4277 Ok(())
4278 }
4279
4280 #[test]
4282 fn select_world_versions() -> Result<()> {
4283 use wit_parser::Resolve;
4284
4285 let mut resolve = Resolve::default();
4286
4287 let _id = resolve.push_str(
4288 "./my-test.wit",
4289 r#"
4290 package example:distraction;
4291 "#,
4292 )?;
4293
4294 let versions_1 = resolve.push_str(
4297 "./my-test.wit",
4298 r#"
4299 package example:versions@1.0.0;
4300
4301 world foo { /* ... */ }
4302 "#,
4303 )?;
4304 assert!(resolve.select_world(&[versions_1], Some("foo")).is_ok());
4305 assert!(
4306 resolve
4307 .select_world(&[versions_1], Some("foo@1.0.0"))
4308 .is_err()
4309 );
4310 assert!(
4311 resolve
4312 .select_world(&[versions_1], Some("example:versions/foo"))
4313 .is_ok()
4314 );
4315 assert!(
4316 resolve
4317 .select_world(&[versions_1], Some("example:versions/foo@1.0.0"))
4318 .is_ok()
4319 );
4320
4321 let versions_2 = resolve.push_str(
4324 "./my-test.wit",
4325 r#"
4326 package example:versions@2.0.0;
4327
4328 world foo { /* ... */ }
4329 "#,
4330 )?;
4331 assert!(
4332 resolve
4333 .select_world(&[versions_1, versions_2], Some("foo"))
4334 .is_err()
4335 );
4336 assert!(
4337 resolve
4338 .select_world(&[versions_1, versions_2], Some("foo@1.0.0"))
4339 .is_err()
4340 );
4341 assert!(
4342 resolve
4343 .select_world(&[versions_1, versions_2], Some("foo@2.0.0"))
4344 .is_err()
4345 );
4346 assert!(
4347 resolve
4348 .select_world(&[versions_1, versions_2], Some("example:versions/foo"))
4349 .is_err()
4350 );
4351 assert!(
4352 resolve
4353 .select_world(
4354 &[versions_1, versions_2],
4355 Some("example:versions/foo@1.0.0")
4356 )
4357 .is_ok()
4358 );
4359 assert!(
4360 resolve
4361 .select_world(
4362 &[versions_1, versions_2],
4363 Some("example:versions/foo@2.0.0")
4364 )
4365 .is_ok()
4366 );
4367
4368 Ok(())
4369 }
4370
4371 #[test]
4373 fn select_world_override_qualification() -> Result<()> {
4374 use wit_parser::Resolve;
4375
4376 let mut resolve = Resolve::default();
4377
4378 let other = resolve.push_str(
4379 "./my-test.wit",
4380 r#"
4381 package example:other;
4382
4383 world foo { }
4384 "#,
4385 )?;
4386
4387 let fq = resolve.push_str(
4389 "./my-test.wit",
4390 r#"
4391 package example:fq;
4392
4393 world bar { }
4394 "#,
4395 )?;
4396 assert!(resolve.select_world(&[other, fq], Some("foo")).is_err());
4397 assert!(resolve.select_world(&[other, fq], Some("bar")).is_err());
4398 assert!(
4399 resolve
4400 .select_world(&[other, fq], Some("example:other/foo"))
4401 .is_ok()
4402 );
4403 assert!(
4404 resolve
4405 .select_world(&[other, fq], Some("example:fq/bar"))
4406 .is_ok()
4407 );
4408 assert!(
4409 resolve
4410 .select_world(&[other, fq], Some("example:other/bar"))
4411 .is_err()
4412 );
4413 assert!(
4414 resolve
4415 .select_world(&[other, fq], Some("example:fq/foo"))
4416 .is_err()
4417 );
4418
4419 Ok(())
4420 }
4421
4422 #[test]
4424 fn select_world_fully_qualified() -> Result<()> {
4425 use wit_parser::Resolve;
4426
4427 let mut resolve = Resolve::default();
4428
4429 let distraction = resolve.push_str(
4430 "./my-test.wit",
4431 r#"
4432 package example:distraction;
4433 "#,
4434 )?;
4435
4436 let multiworld = resolve.push_str(
4439 "./my-test.wit",
4440 r#"
4441 package example:multiworld;
4442
4443 world foo { /* ... */ }
4444
4445 world bar { /* ... */ }
4446 "#,
4447 )?;
4448 assert!(
4449 resolve
4450 .select_world(&[distraction, multiworld], None)
4451 .is_err()
4452 );
4453 assert!(
4454 resolve
4455 .select_world(&[distraction, multiworld], Some("foo"))
4456 .is_err()
4457 );
4458 assert!(
4459 resolve
4460 .select_world(&[distraction, multiworld], Some("example:multiworld/foo"))
4461 .is_ok()
4462 );
4463 assert!(
4464 resolve
4465 .select_world(&[distraction, multiworld], Some("bar"))
4466 .is_err()
4467 );
4468 assert!(
4469 resolve
4470 .select_world(&[distraction, multiworld], Some("example:multiworld/bar"))
4471 .is_ok()
4472 );
4473
4474 Ok(())
4475 }
4476
4477 #[test]
4479 fn select_world_packages() -> Result<()> {
4480 use wit_parser::Resolve;
4481
4482 let mut resolve = Resolve::default();
4483
4484 let wit1 = resolve.push_str(
4487 "./my-test.wit",
4488 r#"
4489 package example:wit1;
4490
4491 world foo {
4492 // ...
4493 }
4494 "#,
4495 )?;
4496 assert!(resolve.select_world(&[wit1], None).is_ok());
4497 assert!(resolve.select_world(&[wit1], Some("foo")).is_ok());
4498 assert!(
4499 resolve
4500 .select_world(&[wit1], Some("example:wit1/foo"))
4501 .is_ok()
4502 );
4503 assert!(resolve.select_world(&[wit1], Some("bar")).is_err());
4504 assert!(
4505 resolve
4506 .select_world(&[wit1], Some("example:wit2/foo"))
4507 .is_err()
4508 );
4509
4510 let wit2 = resolve.push_str(
4513 "./my-test.wit",
4514 r#"
4515 package example:wit2;
4516
4517 world foo { /* ... */ }
4518 "#,
4519 )?;
4520 assert!(resolve.select_world(&[wit1, wit2], None).is_err());
4521 assert!(resolve.select_world(&[wit1, wit2], Some("foo")).is_err());
4522 assert!(
4523 resolve
4524 .select_world(&[wit1, wit2], Some("example:wit1/foo"))
4525 .is_ok()
4526 );
4527 assert!(resolve.select_world(&[wit2], None).is_ok());
4528 assert!(resolve.select_world(&[wit2], Some("foo")).is_ok());
4529 assert!(
4530 resolve
4531 .select_world(&[wit2], Some("example:wit1/foo"))
4532 .is_ok()
4533 );
4534 assert!(resolve.select_world(&[wit1, wit2], Some("bar")).is_err());
4535 assert!(
4536 resolve
4537 .select_world(&[wit1, wit2], Some("example:wit2/foo"))
4538 .is_ok()
4539 );
4540 assert!(resolve.select_world(&[wit2], Some("bar")).is_err());
4541 assert!(
4542 resolve
4543 .select_world(&[wit2], Some("example:wit2/foo"))
4544 .is_ok()
4545 );
4546
4547 Ok(())
4548 }
4549}