1use alloc::borrow::ToOwned;
2use alloc::collections::BTreeMap;
3use alloc::string::{String, ToString};
4use alloc::vec::Vec;
5use alloc::{format, vec};
6use core::cmp::Ordering;
7use core::mem;
8
9use crate::resolve::error::{ResolveError, ResolveErrorKind};
10use crate::*;
11use anyhow::{Context, anyhow, bail};
12#[cfg(not(feature = "std"))]
13use hashbrown::hash_map::Entry;
14use id_arena::{Arena, Id};
15use semver::Version;
16#[cfg(feature = "serde")]
17use serde_derive::Serialize;
18#[cfg(feature = "std")]
19use std::collections::hash_map::Entry;
20
21use crate::ast::lex::Span;
22use crate::ast::{ParsedUsePath, parse_use_path};
23#[cfg(feature = "serde")]
24use crate::serde_::{serialize_arena, serialize_id_map};
25use crate::{
26 AstItem, Docs, Function, FunctionKind, Handle, IncludeName, Interface, InterfaceId,
27 LiftLowerAbi, ManglingAndAbi, PackageName, SourceMap, Stability, Type, TypeDef, TypeDefKind,
28 TypeId, TypeIdVisitor, TypeOwner, UnresolvedPackage, UnresolvedPackageGroup, World, WorldId,
29 WorldItem, WorldKey,
30};
31
32pub use clone::CloneMaps;
33
34mod clone;
35pub mod error;
36
37#[cfg(feature = "std")]
38mod fs;
39#[cfg(feature = "std")]
40pub use fs::PackageSourceMap;
41
42#[derive(Default, Clone, Debug)]
56#[cfg_attr(feature = "serde", derive(Serialize))]
57pub struct Resolve {
58 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
63 pub worlds: Arena<World>,
64
65 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
70 pub interfaces: Arena<Interface>,
71
72 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
78 pub types: Arena<TypeDef>,
79
80 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
85 pub packages: Arena<Package>,
86
87 #[cfg_attr(feature = "serde", serde(skip))]
89 pub package_names: IndexMap<PackageName, PackageId>,
90
91 #[cfg_attr(feature = "serde", serde(skip))]
98 pub features: IndexSet<String>,
99
100 #[cfg_attr(feature = "serde", serde(skip))]
102 pub all_features: bool,
103
104 #[cfg_attr(feature = "serde", serde(skip))]
106 pub source_map: SourceMap,
107}
108
109#[derive(Clone, Debug)]
115#[cfg_attr(feature = "serde", derive(Serialize))]
116pub struct Package {
117 pub name: PackageName,
119
120 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Docs::is_empty"))]
122 pub docs: Docs,
123
124 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_id_map"))]
127 pub interfaces: IndexMap<String, InterfaceId>,
128
129 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_id_map"))]
131 pub worlds: IndexMap<String, WorldId>,
132}
133
134pub type PackageId = Id<Package>;
135
136#[derive(Clone, Debug)]
138pub struct PackageSources {
139 sources: Vec<Vec<String>>,
140 package_id_to_source_map_idx: BTreeMap<PackageId, usize>,
141}
142
143impl PackageSources {
144 pub fn from_single_source(package_id: PackageId, source: &str) -> Self {
145 Self {
146 sources: vec![vec![source.to_owned()]],
147 package_id_to_source_map_idx: BTreeMap::from([(package_id, 0)]),
148 }
149 }
150
151 pub fn from_source_maps(
152 source_maps: Vec<SourceMap>,
153 package_id_to_source_map_idx: BTreeMap<PackageId, usize>,
154 ) -> PackageSources {
155 for (package_id, idx) in &package_id_to_source_map_idx {
156 if *idx >= source_maps.len() {
157 panic!(
158 "Invalid source map index: {}, package id: {:?}, source maps size: {}",
159 idx,
160 package_id,
161 source_maps.len()
162 )
163 }
164 }
165
166 Self {
167 sources: source_maps
168 .into_iter()
169 .map(|source_map| source_map.source_names().map(|s| s.to_owned()).collect())
170 .collect(),
171 package_id_to_source_map_idx,
172 }
173 }
174
175 pub fn source_names(&self) -> impl Iterator<Item = &str> {
177 self.sources
178 .iter()
179 .flatten()
180 .map(|s| s.as_str())
181 .collect::<IndexSet<&str>>()
182 .into_iter()
183 }
184
185 pub fn package_source_names(&self, id: PackageId) -> Option<impl Iterator<Item = &str>> {
187 self.package_id_to_source_map_idx
188 .get(&id)
189 .map(|&idx| self.sources[idx].iter().map(|s| s.as_str()))
190 }
191}
192
193fn visit<'a>(
195 pkg: &'a UnresolvedPackage,
196 pkg_details_map: &'a BTreeMap<PackageName, (UnresolvedPackage, usize)>,
197 order: &mut IndexSet<PackageName>,
198 visiting: &mut HashSet<&'a PackageName>,
199 source_map_offsets: &[u32],
200) -> ResolveResult<()> {
201 if order.contains(&pkg.name) {
202 return Ok(());
203 }
204
205 let (_, source_map_index) = pkg_details_map
206 .get(&pkg.name)
207 .expect("No pkg_details found for package when doing topological sort");
208 let offset = source_map_offsets[*source_map_index];
209 for (i, (dep, _)) in pkg.foreign_deps.iter().enumerate() {
210 let mut span = pkg.foreign_dep_spans[i];
211 span.adjust(offset);
212 if !visiting.insert(dep) {
213 return Err(ResolveError::from(ResolveErrorKind::PackageCycle {
214 package: dep.clone(),
215 span,
216 }));
217 }
218 if let Some((dep_pkg, _)) = pkg_details_map.get(dep) {
219 visit(
220 dep_pkg,
221 pkg_details_map,
222 order,
223 visiting,
224 source_map_offsets,
225 )?;
226 }
227 assert!(visiting.remove(dep));
228 }
229 assert!(order.insert(pkg.name.clone()));
230 Ok(())
231}
232
233impl Resolve {
234 pub fn new() -> Resolve {
236 Resolve::default()
237 }
238
239 fn sort_unresolved_packages(
243 &mut self,
244 main: UnresolvedPackageGroup,
245 deps: Vec<UnresolvedPackageGroup>,
246 ) -> ResolveResult<(PackageId, PackageSources)> {
247 let mut source_maps: Vec<SourceMap> = Vec::new();
248 let mut all_packages: Vec<(UnresolvedPackage, usize)> = Vec::new();
249
250 let mut collect = |group: UnresolvedPackageGroup| {
251 let UnresolvedPackageGroup {
252 main,
253 nested,
254 source_map,
255 } = group;
256 let i = source_maps.len();
257 source_maps.push(source_map);
258 for pkg in nested.into_iter().chain([main]) {
259 all_packages.push((pkg, i));
260 }
261 };
262
263 let main_name = main.main.name.clone();
264 collect(main);
265 for dep in deps {
266 collect(dep);
267 }
268
269 let source_map_offsets: Vec<u32> = source_maps
274 .iter()
275 .map(|sm| self.push_source_map(sm.clone()))
276 .collect();
277
278 let mut pkg_details_map: BTreeMap<PackageName, (UnresolvedPackage, usize)> =
279 BTreeMap::new();
280 for (pkg, source_map_index) in all_packages {
281 let name = pkg.name.clone();
282 let my_span = pkg.package_name_span;
283 let offset = source_map_offsets[source_map_index];
284 if let Some((prev_pkg, prev_source_map_index)) =
285 pkg_details_map.insert(name.clone(), (pkg, source_map_index))
286 {
287 let prev_offset = source_map_offsets[prev_source_map_index];
288 let mut span1 = my_span;
289 span1.adjust(offset);
290 let mut span2 = prev_pkg.package_name_span;
291 span2.adjust(prev_offset);
292 return Err(ResolveError::from(ResolveErrorKind::DuplicatePackage {
293 name,
294 span1,
295 span2,
296 }));
297 }
298 }
299
300 let mut order = IndexSet::default();
304 {
305 let mut visiting = HashSet::new();
306 for (pkg, _) in pkg_details_map.values() {
307 visit(
308 pkg,
309 &pkg_details_map,
310 &mut order,
311 &mut visiting,
312 &source_map_offsets,
313 )?;
314 }
315 }
316
317 let mut package_id_to_source_map_idx = BTreeMap::new();
318 let mut main_pkg_id = None;
319 for name in order {
320 let (pkg, source_map_index) = pkg_details_map.remove(&name).unwrap();
321 let span_offset = source_map_offsets[source_map_index];
322 let is_main = pkg.name == main_name;
323 let id = self.push(pkg, span_offset)?;
324 if is_main {
325 assert!(main_pkg_id.is_none());
326 main_pkg_id = Some(id);
327 }
328 package_id_to_source_map_idx.insert(id, source_map_index);
329 }
330
331 Ok((
332 main_pkg_id.unwrap(),
333 PackageSources::from_source_maps(source_maps, package_id_to_source_map_idx),
334 ))
335 }
336
337 pub fn push_source_map(&mut self, source_map: SourceMap) -> u32 {
344 self.source_map.append(source_map)
345 }
346
347 pub fn push(
362 &mut self,
363 mut unresolved: UnresolvedPackage,
364 span_offset: u32,
365 ) -> ResolveResult<PackageId> {
366 unresolved.adjust_spans(span_offset);
367 let ret = Remap::default().append(self, unresolved);
368 if ret.is_ok() {
369 #[cfg(debug_assertions)]
370 self.assert_valid();
371 }
372 ret
373 }
374
375 pub fn push_group(
384 &mut self,
385 unresolved_group: UnresolvedPackageGroup,
386 ) -> ResolveResult<PackageId> {
387 let (pkg_id, _) = self.sort_unresolved_packages(unresolved_group, Vec::new())?;
388 Ok(pkg_id)
389 }
390
391 pub fn push_groups(
402 &mut self,
403 main: UnresolvedPackageGroup,
404 deps: Vec<UnresolvedPackageGroup>,
405 ) -> ResolveResult<PackageId> {
406 let (pkg_id, _) = self.sort_unresolved_packages(main, deps)?;
407 Ok(pkg_id)
408 }
409
410 pub fn push_source(&mut self, path: &str, contents: &str) -> anyhow::Result<PackageId> {
416 let mut map = SourceMap::default();
417 map.push_str(path, contents);
418 let group = self.parse_source_map(map)?;
419 Ok(self.push_group(group)?)
420 }
421
422 pub(crate) fn parse_source_map(
429 &mut self,
430 map: SourceMap,
431 ) -> anyhow::Result<UnresolvedPackageGroup> {
432 map.parse().map_err(|(map, mut e)| {
433 let offset = self.source_map.append(map);
434 e.adjust_spans(offset);
435 e.into()
436 })
437 }
438
439 pub fn render_location(&self, span: Span) -> String {
441 self.source_map.render_location(span)
442 }
443
444 #[cfg(feature = "std")]
447 pub fn render_error(&self, err: &anyhow::Error) -> String {
448 crate::render_anyhow_error(err, &self.source_map)
449 }
450
451 pub fn all_bits_valid(&self, ty: &Type) -> bool {
452 match ty {
453 Type::U8
454 | Type::S8
455 | Type::U16
456 | Type::S16
457 | Type::U32
458 | Type::S32
459 | Type::U64
460 | Type::S64
461 | Type::F32
462 | Type::F64 => true,
463
464 Type::Bool | Type::Char | Type::String | Type::ErrorContext => false,
465
466 Type::Id(id) => match &self.types[*id].kind {
467 TypeDefKind::List(_)
468 | TypeDefKind::Map(_, _)
469 | TypeDefKind::Variant(_)
470 | TypeDefKind::Enum(_)
471 | TypeDefKind::Option(_)
472 | TypeDefKind::Result(_)
473 | TypeDefKind::Future(_)
474 | TypeDefKind::Stream(_) => false,
475 TypeDefKind::Type(t) | TypeDefKind::FixedLengthList(t, ..) => {
476 self.all_bits_valid(t)
477 }
478
479 TypeDefKind::Handle(h) => match h {
480 crate::Handle::Own(_) => true,
481 crate::Handle::Borrow(_) => true,
482 },
483
484 TypeDefKind::Resource => false,
485 TypeDefKind::Record(r) => r.fields.iter().all(|f| self.all_bits_valid(&f.ty)),
486 TypeDefKind::Tuple(t) => t.types.iter().all(|t| self.all_bits_valid(t)),
487
488 TypeDefKind::Flags(_) => false,
492
493 TypeDefKind::Unknown => unreachable!(),
494 },
495 }
496 }
497
498 pub fn merge(&mut self, resolve: Resolve) -> anyhow::Result<Remap> {
510 log::trace!(
511 "merging {} packages into {} packages",
512 resolve.packages.len(),
513 self.packages.len()
514 );
515
516 let mut map = MergeMap::new(&resolve, &self);
517 map.build()?;
518 let MergeMap {
519 package_map,
520 interface_map,
521 type_map,
522 world_map,
523 interfaces_to_add,
524 worlds_to_add,
525 ..
526 } = map;
527
528 let mut remap = Remap::default();
547 let Resolve {
548 types,
549 worlds,
550 interfaces,
551 packages,
552 package_names,
553 features: _,
554 source_map,
555 ..
556 } = resolve;
557
558 let span_offset = self.source_map.append(source_map);
559
560 let mut moved_types = Vec::new();
561 for (id, mut ty) in types {
562 let new_id = match type_map.get(&id).copied() {
563 Some(id) => {
564 update_stability(&ty.stability, &mut self.types[id].stability, ty.span)?;
565 id
566 }
567 None => {
568 log::debug!("moving type {:?}", ty.name);
569 moved_types.push(id);
570 remap.update_typedef(self, &mut ty, Default::default())?;
571 ty.adjust_spans(span_offset);
572 self.types.alloc(ty)
573 }
574 };
575 assert_eq!(remap.types.len(), id.index());
576 remap.types.push(Some(new_id));
577 }
578
579 let mut moved_interfaces = Vec::new();
580 for (id, mut iface) in interfaces {
581 let new_id = match interface_map.get(&id).copied() {
582 Some(into_id) => {
583 update_stability(
584 &iface.stability,
585 &mut self.interfaces[into_id].stability,
586 iface.span,
587 )?;
588
589 for (name, from_type_id) in iface.types.iter() {
595 if self.interfaces[into_id].types.contains_key(name) {
596 continue;
597 }
598 let new_type_id = remap.map_type(*from_type_id, Default::default())?;
599 self.interfaces[into_id]
600 .types
601 .insert(name.clone(), new_type_id);
602 }
603
604 let extra_funcs: Vec<_> = iface
608 .functions
609 .into_iter()
610 .filter(|(name, _)| {
611 !self.interfaces[into_id]
612 .functions
613 .contains_key(name.as_str())
614 })
615 .collect();
616 for (name, mut func) in extra_funcs {
617 remap.update_function(self, &mut func, Default::default())?;
618 func.adjust_spans(span_offset);
619 self.interfaces[into_id].functions.insert(name, func);
620 }
621
622 into_id
623 }
624 None => {
625 log::debug!("moving interface {:?}", iface.name);
626 moved_interfaces.push(id);
627 remap.update_interface(self, &mut iface)?;
628 iface.adjust_spans(span_offset);
629 self.interfaces.alloc(iface)
630 }
631 };
632 assert_eq!(remap.interfaces.len(), id.index());
633 remap.interfaces.push(Some(new_id));
634 }
635
636 let mut moved_worlds = Vec::new();
637 for (id, mut world) in worlds {
638 let new_id = match world_map.get(&id).copied() {
639 Some(world_id) => {
640 update_stability(
641 &world.stability,
642 &mut self.worlds[world_id].stability,
643 world.span,
644 )?;
645 for from_import in world.imports.iter() {
646 Resolve::update_world_imports_stability(
647 from_import,
648 &mut self.worlds[world_id].imports,
649 &interface_map,
650 )?;
651 }
652 for from_export in world.exports.iter() {
653 Resolve::update_world_imports_stability(
654 from_export,
655 &mut self.worlds[world_id].exports,
656 &interface_map,
657 )?;
658 }
659 world_id
660 }
661 None => {
662 log::debug!("moving world {}", world.name);
663 moved_worlds.push(id);
664 let mut update =
665 |map: &mut IndexMap<WorldKey, WorldItem>| -> anyhow::Result<_> {
666 for (mut name, mut item) in mem::take(map) {
667 remap.update_world_key(&mut name, Default::default())?;
668 match &mut item {
669 WorldItem::Function(f) => {
670 remap.update_function(self, f, Default::default())?
671 }
672 WorldItem::Interface { id, .. } => {
673 *id = remap.map_interface(*id, Default::default())?;
674 }
675 WorldItem::Type { id, .. } => {
676 *id = remap.map_type(*id, Default::default())?
677 }
678 }
679 map.insert(name, item);
680 }
681 Ok(())
682 };
683 update(&mut world.imports)?;
684 update(&mut world.exports)?;
685 world.adjust_spans(span_offset);
686 self.worlds.alloc(world)
687 }
688 };
689 assert_eq!(remap.worlds.len(), id.index());
690 remap.worlds.push(Some(new_id));
691 }
692
693 for (id, mut pkg) in packages {
694 let new_id = match package_map.get(&id).copied() {
695 Some(id) => id,
696 None => {
697 for (_, id) in pkg.interfaces.iter_mut() {
698 *id = remap.map_interface(*id, Default::default())?;
699 }
700 for (_, id) in pkg.worlds.iter_mut() {
701 *id = remap.map_world(*id, Default::default())?;
702 }
703 self.packages.alloc(pkg)
704 }
705 };
706 assert_eq!(remap.packages.len(), id.index());
707 remap.packages.push(new_id);
708 }
709
710 for (name, id) in package_names {
711 let id = remap.packages[id.index()];
712 if let Some(prev) = self.package_names.insert(name, id) {
713 assert_eq!(prev, id);
714 }
715 }
716
717 for id in moved_worlds {
725 let id = remap.map_world(id, Default::default())?;
726 if let Some(pkg) = self.worlds[id].package.as_mut() {
727 *pkg = remap.packages[pkg.index()];
728 }
729 }
730 for id in moved_interfaces {
731 let id = remap.map_interface(id, Default::default())?;
732 if let Some(pkg) = self.interfaces[id].package.as_mut() {
733 *pkg = remap.packages[pkg.index()];
734 }
735 if let Some(clone_of) = self.interfaces[id].clone_of.as_mut() {
736 *clone_of = remap.map_interface(*clone_of, Default::default())?;
737 }
738 }
739 for id in moved_types {
740 let id = remap.map_type(id, Default::default())?;
741 match &mut self.types[id].owner {
742 TypeOwner::Interface(id) => *id = remap.map_interface(*id, Default::default())?,
743 TypeOwner::World(id) => *id = remap.map_world(*id, Default::default())?,
744 TypeOwner::None => {}
745 }
746 }
747
748 for (name, pkg, iface) in interfaces_to_add {
753 let prev = self.packages[pkg]
754 .interfaces
755 .insert(name, remap.map_interface(iface, Default::default())?);
756 assert!(prev.is_none());
757 }
758 for (name, pkg, world) in worlds_to_add {
759 let prev = self.packages[pkg]
760 .worlds
761 .insert(name, remap.map_world(world, Default::default())?);
762 assert!(prev.is_none());
763 }
764
765 log::trace!("now have {} packages", self.packages.len());
766
767 let world_ids: Vec<_> = self.worlds.iter().map(|(id, _)| id).collect();
771 for world_id in world_ids {
772 let world_span = self.worlds[world_id].span;
773 self.elaborate_world(world_id, world_span)?;
774 }
775
776 #[cfg(debug_assertions)]
777 self.assert_valid();
778 Ok(remap)
779 }
780
781 fn update_world_imports_stability(
782 from_item: (&WorldKey, &WorldItem),
783 into_items: &mut IndexMap<WorldKey, WorldItem>,
784 interface_map: &HashMap<Id<Interface>, Id<Interface>>,
785 ) -> anyhow::Result<()> {
786 match from_item.0 {
787 WorldKey::Name(_) => {
788 Ok(())
790 }
791 key @ WorldKey::Interface(_) => {
792 let new_key = MergeMap::map_name(key, interface_map);
793 if let Some(into) = into_items.get_mut(&new_key) {
794 match (from_item.1, into) {
795 (
796 WorldItem::Interface {
797 id: aid,
798 stability: astability,
799 span: aspan,
800 ..
801 },
802 WorldItem::Interface {
803 id: bid,
804 stability: bstability,
805 ..
806 },
807 ) => {
808 let aid = interface_map.get(aid).copied().unwrap_or(*aid);
809 assert_eq!(aid, *bid);
810 update_stability(astability, bstability, *aspan)?;
811 Ok(())
812 }
813 _ => unreachable!(),
814 }
815 } else {
816 unreachable!()
819 }
820 }
821 }
822 }
823
824 pub fn merge_worlds(
839 &mut self,
840 from: WorldId,
841 into: WorldId,
842 clone_maps: &mut CloneMaps,
843 ) -> anyhow::Result<()> {
844 let mut new_imports = Vec::new();
845 let mut new_exports = Vec::new();
846
847 let from_world = &self.worlds[from];
848 let into_world = &self.worlds[into];
849
850 log::trace!("merging {} into {}", from_world.name, into_world.name);
851
852 for (name, from_import) in from_world.imports.iter() {
860 let name_str = self.name_world_key(name);
861 match into_world.imports.get(name) {
862 Some(into_import) => {
863 log::trace!("info/from shared import on `{name_str}`");
864 self.merge_world_item(from_import, into_import)
865 .with_context(|| format!("failed to merge world import {name_str}"))?;
866 }
867 None => {
868 log::trace!("new import: `{name_str}`");
869 new_imports.push((name.clone(), from_import.clone()));
870 }
871 }
872 }
873
874 let mut must_be_imported = HashMap::new();
881 for (key, export) in into_world.exports.iter() {
882 for dep in self.world_item_direct_deps(export) {
883 if into_world.exports.contains_key(&WorldKey::Interface(dep)) {
884 continue;
885 }
886 self.foreach_interface_dep(dep, &mut |id| {
887 must_be_imported.insert(id, key.clone());
888 });
889 }
890 }
891
892 for (name, from_export) in from_world.exports.iter() {
895 let name_str = self.name_world_key(name);
896 match into_world.exports.get(name) {
897 Some(into_export) => {
898 log::trace!("info/from shared export on `{name_str}`");
899 self.merge_world_item(from_export, into_export)
900 .with_context(|| format!("failed to merge world export {name_str}"))?;
901 }
902 None => {
903 log::trace!("new export `{name_str}`");
904 self.ensure_can_add_world_export(
907 into_world,
908 name,
909 from_export,
910 &must_be_imported,
911 )
912 .with_context(|| {
913 format!("failed to add export `{}`", self.name_world_key(name))
914 })?;
915 new_exports.push((name.clone(), from_export.clone()));
916 }
917 }
918 }
919
920 let mut cloner = clone::Cloner::new(
934 self,
935 clone_maps,
936 TypeOwner::World(from),
937 TypeOwner::World(into),
938 );
939 cloner.register_world_type_overlap(from, into);
940 for (name, item) in new_imports.iter_mut().chain(&mut new_exports) {
941 cloner.world_item(name, item);
942 }
943
944 let into_world = &mut self.worlds[into];
946 for (name, import) in new_imports {
947 let prev = into_world.imports.insert(name, import);
948 assert!(prev.is_none());
949 }
950 for (name, export) in new_exports {
951 let prev = into_world.exports.insert(name, export);
952 assert!(prev.is_none());
953 }
954
955 #[cfg(debug_assertions)]
956 self.assert_valid();
957 Ok(())
958 }
959
960 fn merge_world_item(&self, from: &WorldItem, into: &WorldItem) -> anyhow::Result<()> {
961 let mut map = MergeMap::new(self, self);
962 match (from, into) {
963 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
964 if from == into {
969 return Ok(());
970 }
971
972 map.build_interface(*from, *into)
982 .context("failed to merge interfaces")?;
983 }
984
985 (WorldItem::Function(from), WorldItem::Function(into)) => {
988 map.build_function(from, into)
989 .context("failed to merge functions")?;
990 }
991 (WorldItem::Type { id: from, .. }, WorldItem::Type { id: into, .. }) => {
992 map.build_type_id(*from, *into)
993 .context("failed to merge types")?;
994 }
995
996 (WorldItem::Interface { .. }, _)
998 | (WorldItem::Function { .. }, _)
999 | (WorldItem::Type { .. }, _) => {
1000 bail!("different kinds of items");
1001 }
1002 }
1003 assert!(map.interfaces_to_add.is_empty());
1004 assert!(map.worlds_to_add.is_empty());
1005 Ok(())
1006 }
1007
1008 fn ensure_can_add_world_export(
1020 &self,
1021 into: &World,
1022 name: &WorldKey,
1023 item: &WorldItem,
1024 must_be_imported: &HashMap<InterfaceId, WorldKey>,
1025 ) -> anyhow::Result<()> {
1026 assert!(!into.exports.contains_key(name));
1027 let name = self.name_world_key(name);
1028
1029 for dep in self.world_item_direct_deps(item) {
1033 if into.exports.contains_key(&WorldKey::Interface(dep)) {
1034 continue;
1035 }
1036 self.ensure_not_exported(into, dep)
1037 .with_context(|| format!("failed validating export of `{name}`"))?;
1038 }
1039
1040 if let WorldItem::Interface { id, .. } = item {
1044 if let Some(export) = must_be_imported.get(id) {
1045 let export_name = self.name_world_key(export);
1046 bail!(
1047 "export `{export_name}` depends on `{name}` \
1048 previously as an import which will change meaning \
1049 if `{name}` is added as an export"
1050 );
1051 }
1052 }
1053
1054 Ok(())
1055 }
1056
1057 fn ensure_not_exported(&self, world: &World, id: InterfaceId) -> anyhow::Result<()> {
1058 let key = WorldKey::Interface(id);
1059 let name = self.name_world_key(&key);
1060 if world.exports.contains_key(&key) {
1061 bail!(
1062 "world exports `{name}` but it's also transitively used by an \
1063 import \
1064 which means that this is not valid"
1065 )
1066 }
1067 for dep in self.interface_direct_deps(id) {
1068 self.ensure_not_exported(world, dep)
1069 .with_context(|| format!("failed validating transitive import dep `{name}`"))?;
1070 }
1071 Ok(())
1072 }
1073
1074 fn world_item_direct_deps(&self, item: &WorldItem) -> impl Iterator<Item = InterfaceId> + '_ {
1080 let mut interface = None;
1081 let mut ty = None;
1082 match item {
1083 WorldItem::Function(_) => {}
1084 WorldItem::Type { id, .. } => ty = Some(*id),
1085 WorldItem::Interface { id, .. } => interface = Some(*id),
1086 }
1087
1088 interface
1089 .into_iter()
1090 .flat_map(move |id| self.interface_direct_deps(id))
1091 .chain(ty.and_then(|t| self.type_interface_dep(t)))
1092 }
1093
1094 fn foreach_interface_dep(&self, id: InterfaceId, f: &mut dyn FnMut(InterfaceId)) {
1098 self._foreach_interface_dep(id, f, &mut HashSet::new())
1099 }
1100
1101 fn _foreach_interface_dep(
1105 &self,
1106 id: InterfaceId,
1107 f: &mut dyn FnMut(InterfaceId),
1108 visited: &mut HashSet<InterfaceId>,
1109 ) {
1110 if !visited.insert(id) {
1111 return;
1112 }
1113 f(id);
1114 for dep in self.interface_direct_deps(id) {
1115 self._foreach_interface_dep(dep, f, visited);
1116 }
1117 }
1118
1119 pub fn id_of(&self, interface: InterfaceId) -> Option<String> {
1123 let interface = &self.interfaces[interface];
1124 Some(self.id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1125 }
1126
1127 pub fn canonicalized_id_of(&self, interface: InterfaceId) -> Option<String> {
1132 let interface = &self.interfaces[interface];
1133 Some(self.canonicalized_id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1134 }
1135
1136 fn rename_world(
1141 &mut self,
1142 world_id: WorldId,
1143 out_world_name: Option<String>,
1144 default_suffix: &str,
1145 ) {
1146 let world = &mut self.worlds[world_id];
1147 let pkg = &mut self.packages[world.package.unwrap()];
1148 pkg.worlds.shift_remove(&world.name);
1149 if let Some(name) = out_world_name {
1150 world.name = name.clone();
1151 pkg.worlds.insert(name, world_id);
1152 } else {
1153 world.name.push_str(default_suffix);
1154 pkg.worlds.insert(world.name.clone(), world_id);
1155 }
1156 }
1157
1158 pub fn importize(
1174 &mut self,
1175 world_id: WorldId,
1176 out_world_name: Option<String>,
1177 ) -> anyhow::Result<()> {
1178 self.rename_world(world_id, out_world_name, "-importized");
1179
1180 let world = &mut self.worlds[world_id];
1183 world.imports.retain(|_, item| match item {
1184 WorldItem::Type { .. } => true,
1185 _ => false,
1186 });
1187
1188 for (name, export) in mem::take(&mut world.exports) {
1189 match (name.clone(), world.imports.insert(name, export)) {
1190 (_, None) => {}
1192
1193 (WorldKey::Name(name), Some(_)) => {
1195 bail!("world export `{name}` conflicts with import of same name");
1196 }
1197
1198 (WorldKey::Interface(_), _) => unreachable!(),
1201 }
1202 }
1203
1204 let world_span = world.span;
1207 self.elaborate_world(world_id, world_span)?;
1208
1209 #[cfg(debug_assertions)]
1210 self.assert_valid();
1211 Ok(())
1212 }
1213
1214 pub fn exportize(
1233 &mut self,
1234 world_id: WorldId,
1235 out_world_name: Option<String>,
1236 filter: Option<&dyn Fn(&WorldKey, &WorldItem) -> bool>,
1237 ) -> anyhow::Result<()> {
1238 self.rename_world(world_id, out_world_name, "-exportized");
1239
1240 let world = &mut self.worlds[world_id];
1241 world.exports.clear();
1242
1243 let old_imports = mem::take(&mut world.imports);
1244 for (name, import) in old_imports {
1245 let should_move = match &filter {
1246 Some(f) => f(&name, &import),
1247 None => true,
1248 };
1249 if should_move {
1250 world.exports.insert(name, import);
1251 } else {
1252 world.imports.insert(name, import);
1253 }
1254 }
1255
1256 let world_span = world.span;
1259 self.elaborate_world(world_id, world_span)?;
1260
1261 #[cfg(debug_assertions)]
1262 self.assert_valid();
1263 Ok(())
1264 }
1265
1266 pub fn id_of_name(&self, pkg: PackageId, name: &str) -> String {
1268 let package = &self.packages[pkg];
1269 let mut base = String::new();
1270 base.push_str(&package.name.namespace);
1271 base.push_str(":");
1272 base.push_str(&package.name.name);
1273 base.push_str("/");
1274 base.push_str(name);
1275 if let Some(version) = &package.name.version {
1276 base.push_str(&format!("@{version}"));
1277 }
1278 base
1279 }
1280
1281 pub fn canonicalized_id_of_name(&self, pkg: PackageId, name: &str) -> String {
1287 let package = &self.packages[pkg];
1288 let mut base = String::new();
1289 base.push_str(&package.name.namespace);
1290 base.push_str(":");
1291 base.push_str(&package.name.name);
1292 base.push_str("/");
1293 base.push_str(name);
1294 if let Some(version) = &package.name.version {
1295 base.push_str("@");
1296 let (string, _) = PackageName::version_compat_track_string(version);
1297 base.push_str(&string);
1298 }
1299 base
1300 }
1301
1302 pub fn select_world(
1417 &self,
1418 main_packages: &[PackageId],
1419 world: Option<&str>,
1420 ) -> anyhow::Result<WorldId> {
1421 let world_path = match world {
1423 Some(world) => Some(
1424 parse_use_path(world)
1425 .with_context(|| format!("failed to parse world specifier `{world}`"))?,
1426 ),
1427 None => None,
1428 };
1429
1430 match world_path {
1431 Some(world_path) => {
1433 let (pkg, world_name) = match (main_packages, world_path) {
1434 ([], _) => bail!("No main packages defined"),
1436
1437 ([main_package], ParsedUsePath::Name(name)) => (*main_package, name),
1439
1440 (_, ParsedUsePath::Name(_name)) => {
1442 bail!(
1443 "There are multiple main packages; a world must be explicitly chosen:{}",
1444 self.worlds
1445 .iter()
1446 .map(|world| format!(
1447 "\n {}",
1448 self.id_of_name(world.1.package.unwrap(), &world.1.name)
1449 ))
1450 .collect::<String>()
1451 )
1452 }
1453
1454 (_, ParsedUsePath::Package(pkg, world_name)) => {
1456 let pkg = match self.package_names.get(&pkg) {
1457 Some(pkg) => *pkg,
1458 None => {
1459 let mut candidates =
1460 self.package_names.iter().filter(|(name, _)| {
1461 pkg.version.is_none()
1462 && pkg.name == name.name
1463 && pkg.namespace == name.namespace
1464 && name.version.is_some()
1465 });
1466 let candidate = candidates.next();
1467 if let Some((c2, _)) = candidates.next() {
1468 let (c1, _) = candidate.unwrap();
1469 bail!(
1470 "package name `{pkg}` is available at both \
1471 versions {} and {} but which is not specified",
1472 c1.version.as_ref().unwrap(),
1473 c2.version.as_ref().unwrap(),
1474 );
1475 }
1476 match candidate {
1477 Some((_, id)) => *id,
1478 None => bail!("unknown package `{pkg}`"),
1479 }
1480 }
1481 };
1482 (pkg, world_name.to_string())
1483 }
1484 };
1485
1486 let pkg = &self.packages[pkg];
1488 pkg.worlds.get(&world_name).copied().ok_or_else(|| {
1489 anyhow!("World `{world_name}` not found in package `{}`", pkg.name)
1490 })
1491 }
1492
1493 None => match main_packages {
1495 [] => bail!("No main packages defined"),
1496
1497 [main_package] => {
1499 let pkg = &self.packages[*main_package];
1500 match pkg.worlds.len() {
1501 0 => bail!("The main package `{}` contains no worlds", pkg.name),
1502 1 => Ok(pkg.worlds[0]),
1503 _ => bail!(
1504 "There are multiple worlds in `{}`; one must be explicitly chosen:{}",
1505 pkg.name,
1506 pkg.worlds
1507 .values()
1508 .map(|world| format!(
1509 "\n {}",
1510 self.id_of_name(*main_package, &self.worlds[*world].name)
1511 ))
1512 .collect::<String>()
1513 ),
1514 }
1515 }
1516
1517 _ => {
1519 bail!(
1520 "There are multiple main packages; a world must be explicitly chosen:{}",
1521 self.worlds
1522 .iter()
1523 .map(|world| format!(
1524 "\n {}",
1525 self.id_of_name(world.1.package.unwrap(), &world.1.name)
1526 ))
1527 .collect::<String>()
1528 )
1529 }
1530 },
1531 }
1532 }
1533
1534 pub fn name_world_key(&self, key: &WorldKey) -> String {
1536 match key {
1537 WorldKey::Name(s) => s.to_string(),
1538 WorldKey::Interface(i) => self.id_of(*i).expect("unexpected anonymous interface"),
1539 }
1540 }
1541
1542 pub fn name_canonicalized_world_key(&self, key: &WorldKey) -> String {
1545 match key {
1546 WorldKey::Name(s) => s.to_string(),
1547 WorldKey::Interface(i) => self
1548 .canonicalized_id_of(*i)
1549 .expect("unexpected anonymous interface"),
1550 }
1551 }
1552
1553 pub fn implements_interface(&self, key: &WorldKey, item: &WorldItem) -> Option<InterfaceId> {
1558 if let WorldKey::Name(_) = key {
1559 if let WorldItem::Interface { id, .. } = item {
1560 if self.interfaces[*id].name.is_some() {
1561 return Some(*id);
1562 }
1563 }
1564 }
1565 None
1566 }
1567
1568 pub fn version_suffix_of(&self, id: InterfaceId) -> Option<String> {
1572 let pkg = self.interfaces[id].package?;
1573 let version = self.packages[pkg].name.version.as_ref()?;
1574 let (_, suffix) = PackageName::version_compat_track(version);
1575 suffix
1576 }
1577
1578 pub fn external_id_value(&self, key: &WorldKey, item: &WorldItem) -> Option<String> {
1583 let _ = key;
1584 match item {
1585 WorldItem::Interface { external_id, .. } => external_id.clone(),
1586 WorldItem::Function(f) => f.external_id.clone(),
1587 WorldItem::Type { id, .. } => self.types[*id].external_id.clone(),
1588 }
1589 }
1590
1591 pub fn type_interface_dep(&self, id: TypeId) -> Option<InterfaceId> {
1597 let ty = &self.types[id];
1598 let dep = match ty.kind {
1599 TypeDefKind::Type(Type::Id(id)) => id,
1600 _ => return None,
1601 };
1602 let other = &self.types[dep];
1603 if ty.owner == other.owner {
1604 None
1605 } else {
1606 match other.owner {
1607 TypeOwner::Interface(id) => Some(id),
1608 _ => unreachable!(),
1609 }
1610 }
1611 }
1612
1613 pub fn interface_direct_deps(&self, id: InterfaceId) -> impl Iterator<Item = InterfaceId> + '_ {
1623 self.interfaces[id]
1624 .types
1625 .iter()
1626 .filter_map(move |(_name, ty)| self.type_interface_dep(*ty))
1627 }
1628
1629 pub fn package_direct_deps(&self, id: PackageId) -> impl Iterator<Item = PackageId> + '_ {
1639 let pkg = &self.packages[id];
1640
1641 pkg.interfaces
1642 .iter()
1643 .flat_map(move |(_name, id)| self.interface_direct_deps(*id))
1644 .chain(pkg.worlds.iter().flat_map(move |(_name, id)| {
1645 let world = &self.worlds[*id];
1646 world
1647 .imports
1648 .iter()
1649 .chain(world.exports.iter())
1650 .filter_map(move |(_name, item)| match item {
1651 WorldItem::Interface { id, .. } => Some(*id),
1652 WorldItem::Function(_) => None,
1653 WorldItem::Type { id, .. } => self.type_interface_dep(*id),
1654 })
1655 }))
1656 .filter_map(move |iface_id| {
1657 let pkg = self.interfaces[iface_id].package?;
1658 if pkg == id { None } else { Some(pkg) }
1659 })
1660 }
1661
1662 pub fn topological_packages(&self) -> Vec<PackageId> {
1668 let mut pushed = vec![false; self.packages.len()];
1669 let mut order = Vec::new();
1670 for (id, _) in self.packages.iter() {
1671 self.build_topological_package_ordering(id, &mut pushed, &mut order);
1672 }
1673 order
1674 }
1675
1676 fn build_topological_package_ordering(
1677 &self,
1678 id: PackageId,
1679 pushed: &mut Vec<bool>,
1680 order: &mut Vec<PackageId>,
1681 ) {
1682 if pushed[id.index()] {
1683 return;
1684 }
1685 for dep in self.package_direct_deps(id) {
1686 self.build_topological_package_ordering(dep, pushed, order);
1687 }
1688 order.push(id);
1689 pushed[id.index()] = true;
1690 }
1691
1692 #[doc(hidden)]
1693 pub fn assert_valid(&self) {
1694 let mut package_interfaces = Vec::new();
1695 let mut package_worlds = Vec::new();
1696 for (id, pkg) in self.packages.iter() {
1697 let mut interfaces = HashSet::new();
1698 for (name, iface) in pkg.interfaces.iter() {
1699 assert!(interfaces.insert(*iface));
1700 let iface = &self.interfaces[*iface];
1701 assert_eq!(name, iface.name.as_ref().unwrap());
1702 assert_eq!(iface.package.unwrap(), id);
1703 }
1704 package_interfaces.push(pkg.interfaces.values().copied().collect::<HashSet<_>>());
1705 let mut worlds = HashSet::new();
1706 for (name, world) in pkg.worlds.iter() {
1707 assert!(worlds.insert(*world));
1708 assert_eq!(
1709 pkg.worlds.get_key_value(name),
1710 Some((name, world)),
1711 "`MutableKeys` impl may have been used to change a key's hash or equality"
1712 );
1713 let world = &self.worlds[*world];
1714 assert_eq!(*name, world.name);
1715 assert_eq!(world.package.unwrap(), id);
1716 }
1717 package_worlds.push(pkg.worlds.values().copied().collect::<HashSet<_>>());
1718 }
1719
1720 let mut interface_types = Vec::new();
1721 for (id, iface) in self.interfaces.iter() {
1722 assert!(self.packages.get(iface.package.unwrap()).is_some());
1723 if iface.name.is_some() {
1724 match iface.clone_of {
1725 Some(other) => {
1726 assert_eq!(iface.name, self.interfaces[other].name);
1727 }
1728 None => {
1729 assert!(package_interfaces[iface.package.unwrap().index()].contains(&id));
1730 }
1731 }
1732 }
1733
1734 for (name, ty) in iface.types.iter() {
1735 let ty = &self.types[*ty];
1736 assert_eq!(ty.name.as_ref(), Some(name));
1737 assert_eq!(ty.owner, TypeOwner::Interface(id));
1738 }
1739 interface_types.push(iface.types.values().copied().collect::<HashSet<_>>());
1740 for (name, f) in iface.functions.iter() {
1741 assert_eq!(*name, f.name);
1742 }
1743 }
1744
1745 let mut world_types = Vec::new();
1746 for (id, world) in self.worlds.iter() {
1747 log::debug!("validating world {}", &world.name);
1748 if let Some(package) = world.package {
1749 assert!(self.packages.get(package).is_some());
1750 assert!(package_worlds[package.index()].contains(&id));
1751 }
1752 assert!(world.includes.is_empty());
1753
1754 let mut types = HashSet::new();
1755 for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1756 log::debug!("validating world item: {}", self.name_world_key(name));
1757 match item {
1758 WorldItem::Interface { id, .. } => {
1759 if matches!(name, WorldKey::Name(_)) {
1763 let iface = &self.interfaces[*id];
1764 if iface.name.is_none() {
1765 assert_eq!(iface.package, world.package);
1766 }
1767 }
1768 }
1769 WorldItem::Function(f) => {
1770 assert!(!matches!(name, WorldKey::Interface(_)));
1771 assert_eq!(f.name, name.clone().unwrap_name());
1772 }
1773 WorldItem::Type { id: ty, .. } => {
1774 assert!(!matches!(name, WorldKey::Interface(_)));
1775 assert!(types.insert(*ty));
1776 let ty = &self.types[*ty];
1777 assert_eq!(ty.name, Some(name.clone().unwrap_name()));
1778 assert_eq!(ty.owner, TypeOwner::World(id));
1779 }
1780 }
1781 }
1782 self.assert_world_elaborated(world);
1783 world_types.push(types);
1784 }
1785
1786 for (ty_id, ty) in self.types.iter() {
1787 match ty.owner {
1788 TypeOwner::Interface(id) => {
1789 assert!(self.interfaces.get(id).is_some());
1790 assert!(interface_types[id.index()].contains(&ty_id));
1791 }
1792 TypeOwner::World(id) => {
1793 assert!(self.worlds.get(id).is_some());
1794 assert!(world_types[id.index()].contains(&ty_id));
1795 }
1796 TypeOwner::None => {}
1797 }
1798 }
1799
1800 self.assert_topologically_sorted();
1801 }
1802
1803 fn assert_topologically_sorted(&self) {
1804 let mut positions = IndexMap::default();
1805 for id in self.topological_packages() {
1806 let pkg = &self.packages[id];
1807 log::debug!("pkg {}", pkg.name);
1808 let prev = positions.insert(Some(id), IndexSet::default());
1809 assert!(prev.is_none());
1810 }
1811 positions.insert(None, IndexSet::default());
1812
1813 for (id, iface) in self.interfaces.iter() {
1814 log::debug!("iface {:?}", iface.name);
1815 let ok = positions.get_mut(&iface.package).unwrap().insert(id);
1816 assert!(ok);
1817 }
1818
1819 for (_, world) in self.worlds.iter() {
1820 log::debug!("world {:?}", world.name);
1821
1822 let my_package = world.package;
1823 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1824
1825 for (_, item) in world.imports.iter().chain(&world.exports) {
1826 let id = match item {
1827 WorldItem::Interface { id, .. } => *id,
1828 _ => continue,
1829 };
1830 let other_package = self.interfaces[id].package;
1831 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1832
1833 assert!(other_package_pos <= my_package_pos);
1834 }
1835 }
1836
1837 for (_id, ty) in self.types.iter() {
1838 log::debug!("type {:?} {:?}", ty.name, ty.owner);
1839 let other_id = match ty.kind {
1840 TypeDefKind::Type(Type::Id(ty)) => ty,
1841 _ => continue,
1842 };
1843 let other = &self.types[other_id];
1844 if ty.kind == other.kind {
1845 continue;
1846 }
1847 let my_interface = match ty.owner {
1848 TypeOwner::Interface(id) => id,
1849 _ => continue,
1850 };
1851 let other_interface = match other.owner {
1852 TypeOwner::Interface(id) => id,
1853 _ => continue,
1854 };
1855
1856 let my_package = self.interfaces[my_interface].package;
1857 let other_package = self.interfaces[other_interface].package;
1858 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1859 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1860
1861 assert!(other_package_pos <= my_package_pos);
1862 }
1863 }
1864
1865 fn assert_world_elaborated(&self, world: &World) {
1866 for (key, item) in world.imports.iter() {
1867 log::debug!(
1868 "asserting elaborated world import {}",
1869 self.name_world_key(key)
1870 );
1871 match item {
1872 WorldItem::Type { id, .. } => self.assert_world_imports_type_deps(world, key, *id),
1873
1874 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1876
1877 WorldItem::Interface { id, .. } => {
1879 for dep in self.interface_direct_deps(*id) {
1880 assert!(
1881 world.imports.contains_key(&WorldKey::Interface(dep)),
1882 "world import of {} is missing transitive dep of {}",
1883 self.name_world_key(key),
1884 self.id_of(dep).unwrap(),
1885 );
1886 }
1887 }
1888 }
1889 }
1890 for (key, item) in world.exports.iter() {
1891 log::debug!(
1892 "asserting elaborated world export {}",
1893 self.name_world_key(key)
1894 );
1895 match item {
1896 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1898
1899 WorldItem::Interface { id, .. } => {
1903 for dep in self.interface_direct_deps(*id) {
1904 let dep_key = WorldKey::Interface(dep);
1905 if world.exports.contains_key(&dep_key) {
1906 continue;
1907 }
1908 self.foreach_interface_dep(dep, &mut |dep| {
1909 let dep_key = WorldKey::Interface(dep);
1910 assert!(
1911 world.imports.contains_key(&dep_key),
1912 "world should import {} (required by {})",
1913 self.name_world_key(&dep_key),
1914 self.name_world_key(key),
1915 );
1916 assert!(
1917 !world.exports.contains_key(&dep_key),
1918 "world should not export {} (required by {})",
1919 self.name_world_key(&dep_key),
1920 self.name_world_key(key),
1921 );
1922 });
1923 }
1924 }
1925
1926 WorldItem::Type { .. } => unreachable!(),
1928 }
1929 }
1930 }
1931
1932 fn assert_world_imports_type_deps(&self, world: &World, key: &WorldKey, ty: TypeId) {
1933 let ty = &self.types[ty];
1936 if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
1937 if let TypeOwner::Interface(id) = self.types[other].owner {
1938 let key = WorldKey::Interface(id);
1939 assert!(world.imports.contains_key(&key));
1940 return;
1941 }
1942 }
1943
1944 let mut visitor = MyVisit(self, Vec::new());
1948 visitor.visit_type_def(self, ty);
1949 for ty in visitor.1 {
1950 let ty = &self.types[ty];
1951 let Some(name) = ty.name.clone() else {
1952 continue;
1953 };
1954 let dep_key = WorldKey::Name(name);
1955 assert!(
1956 world.imports.contains_key(&dep_key),
1957 "world import `{}` should also force an import of `{}`",
1958 self.name_world_key(key),
1959 self.name_world_key(&dep_key),
1960 );
1961 }
1962
1963 struct MyVisit<'a>(&'a Resolve, Vec<TypeId>);
1964
1965 impl TypeIdVisitor for MyVisit<'_> {
1966 fn before_visit_type_id(&mut self, id: TypeId) -> bool {
1967 self.1.push(id);
1968 self.0.types[id].name.is_none()
1970 }
1971 }
1972 }
1973
1974 fn assert_world_function_imports_types(&self, world: &World, key: &WorldKey, func: &Function) {
1978 for ty in func
1979 .parameter_and_result_types()
1980 .chain(func.kind.resource().map(Type::Id))
1981 {
1982 let Type::Id(id) = ty else {
1983 continue;
1984 };
1985 self.assert_world_imports_type_deps(world, key, id);
1986 }
1987 }
1988
1989 fn include_stability(
2005 &self,
2006 stability: &Stability,
2007 pkg_id: &PackageId,
2008 span: Span,
2009 ) -> ResolveResult<bool> {
2010 Ok(match stability {
2011 Stability::Unknown => true,
2012 Stability::Stable { since, .. } => {
2015 let Some(p) = self.packages.get(*pkg_id) else {
2016 return Ok(true);
2024 };
2025
2026 let package_version = p.name.version.as_ref().ok_or_else(|| {
2029 ResolveError::new_semantic(
2030 span,
2031 format!(
2032 "package [{}] contains a feature gate with a version \
2033 specifier, so it must have a version",
2034 p.name
2035 ),
2036 )
2037 })?;
2038
2039 if since > package_version {
2043 return Err(ResolveError::new_semantic(
2044 span,
2045 format!(
2046 "feature gate cannot reference unreleased version \
2047 {since} of package [{}] (current version {package_version})",
2048 p.name
2049 ),
2050 ));
2051 }
2052
2053 true
2054 }
2055 Stability::Unstable { feature, .. } => {
2056 self.features.contains(feature) || self.all_features
2057 }
2058 })
2059 }
2060
2061 fn elaborate_world(&mut self, world_id: WorldId, span: Span) -> ResolveResult<()> {
2073 let mut new_imports = IndexMap::default();
2077 let world = &self.worlds[world_id];
2078
2079 let sort_key = |resolve: &Resolve, item: &WorldItem| match item {
2102 WorldItem::Interface { .. } => 0,
2103 WorldItem::Type { id, .. } => {
2104 let ty = &resolve.types[*id];
2105 match ty.kind {
2106 TypeDefKind::Type(Type::Id(t)) if resolve.types[t].owner != ty.owner => 1,
2107 _ => 2,
2108 }
2109 }
2110 WorldItem::Function(f) => {
2111 if f.kind.resource().is_none() {
2112 3
2113 } else {
2114 4
2115 }
2116 }
2117 };
2118
2119 let mut world_imports = world.imports.iter().collect::<Vec<_>>();
2122 world_imports.sort_by_key(|(_name, import)| sort_key(self, import));
2123 for (name, item) in world_imports {
2124 match item {
2125 WorldItem::Interface {
2128 id,
2129 stability,
2130 docs,
2131 external_id,
2132 ..
2133 } => {
2134 self.elaborate_world_import(
2135 &mut new_imports,
2136 name.clone(),
2137 *id,
2138 &stability,
2139 docs,
2140 external_id.as_deref(),
2141 );
2142 }
2143
2144 WorldItem::Function(_) => {
2147 let prev = new_imports.insert(name.clone(), item.clone());
2148 assert!(prev.is_none());
2149 }
2150
2151 WorldItem::Type { id, .. } => {
2155 if let Some(dep) = self.type_interface_dep(*id) {
2156 self.elaborate_world_import(
2157 &mut new_imports,
2158 WorldKey::Interface(dep),
2159 dep,
2160 &self.types[*id].stability,
2161 &Docs::default(),
2162 None,
2163 );
2164 }
2165 let prev = new_imports.insert(name.clone(), item.clone());
2166 assert!(prev.is_none());
2167 }
2168 }
2169 }
2170
2171 let mut new_exports = IndexMap::default();
2177 let mut export_interfaces = IndexMap::default();
2178 for (name, item) in world.exports.iter() {
2179 match item {
2180 WorldItem::Interface { .. } => {
2181 let prev = export_interfaces.insert(name.clone(), item.clone());
2182 assert!(prev.is_none());
2183 }
2184 WorldItem::Function(_) => {
2185 let prev = new_exports.insert(name.clone(), item.clone());
2186 assert!(prev.is_none());
2187 }
2188 WorldItem::Type { .. } => unreachable!(),
2189 }
2190 }
2191
2192 self.elaborate_world_exports(&export_interfaces, &mut new_imports, &mut new_exports, span)?;
2193
2194 new_imports.sort_by_cached_key(|_name, import| sort_key(self, import));
2198
2199 log::trace!("imports = {new_imports:?}");
2202 log::trace!("exports = {new_exports:?}");
2203 let world = &mut self.worlds[world_id];
2204 world.imports = new_imports;
2205 world.exports = new_exports;
2206
2207 Ok(())
2208 }
2209
2210 fn elaborate_world_import(
2211 &self,
2212 imports: &mut IndexMap<WorldKey, WorldItem>,
2213 key: WorldKey,
2214 id: InterfaceId,
2215 stability: &Stability,
2216 docs: &Docs,
2217 external_id: Option<&str>,
2218 ) {
2219 if imports.contains_key(&key) {
2220 return;
2221 }
2222 for dep in self.interface_direct_deps(id) {
2225 self.elaborate_world_import(
2226 imports,
2227 WorldKey::Interface(dep),
2228 dep,
2229 stability,
2230 &Docs::default(),
2231 None,
2232 );
2233 }
2234 let prev = imports.insert(
2235 key,
2236 WorldItem::Interface {
2237 id,
2238 stability: stability.clone(),
2239 docs: docs.clone(),
2240 span: Default::default(),
2241 external_id: external_id.map(|s| s.to_string()),
2242 },
2243 );
2244 assert!(prev.is_none());
2245 }
2246
2247 fn elaborate_world_exports(
2294 &self,
2295 export_interfaces: &IndexMap<WorldKey, WorldItem>,
2296 imports: &mut IndexMap<WorldKey, WorldItem>,
2297 exports: &mut IndexMap<WorldKey, WorldItem>,
2298 span: Span,
2299 ) -> ResolveResult<()> {
2300 let mut required_imports = HashSet::new();
2301 for (key, item) in export_interfaces.iter() {
2302 let name = self.name_world_key(&key);
2303 let ok = add_world_export(
2304 self,
2305 imports,
2306 exports,
2307 &export_interfaces,
2308 &mut required_imports,
2309 key.clone(),
2310 item.clone(),
2311 true,
2312 );
2313 if !ok {
2314 return Err(ResolveError::from(
2332 ResolveErrorKind::InvalidTransitiveDependency { name, span },
2333 ));
2334 }
2335 }
2336 return Ok(());
2337
2338 fn add_world_export(
2339 resolve: &Resolve,
2340 imports: &mut IndexMap<WorldKey, WorldItem>,
2341 exports: &mut IndexMap<WorldKey, WorldItem>,
2342 export_interfaces: &IndexMap<WorldKey, WorldItem>,
2343 required_imports: &mut HashSet<InterfaceId>,
2344 key: WorldKey,
2345 item: WorldItem,
2346 add_export: bool,
2347 ) -> bool {
2348 if exports.contains_key(&key) {
2349 if add_export {
2350 return true;
2351 } else {
2352 return false;
2353 }
2354 }
2355 let (id, stability, external_id) = match &item {
2356 WorldItem::Interface {
2357 id,
2358 stability,
2359 external_id,
2360 ..
2361 } => (*id, stability, external_id),
2362 _ => unreachable!(),
2363 };
2364 if !add_export && required_imports.contains(&id) {
2367 return true;
2368 }
2369 let ok = resolve.interface_direct_deps(id).all(|dep| {
2370 let item = WorldItem::Interface {
2371 id: dep,
2372 stability: stability.clone(),
2373 docs: Default::default(),
2374 span: Default::default(),
2375 external_id: external_id.clone(),
2376 };
2377 let key = WorldKey::Interface(dep);
2378 let add_export = add_export && export_interfaces.contains_key(&key);
2379 add_world_export(
2380 resolve,
2381 imports,
2382 exports,
2383 export_interfaces,
2384 required_imports,
2385 key,
2386 item,
2387 add_export,
2388 )
2389 });
2390 if !ok {
2391 return false;
2392 }
2393 if add_export {
2394 if required_imports.contains(&id) {
2395 return false;
2396 }
2397 let prev = exports.insert(key.clone(), item);
2398 assert!(prev.is_none());
2399 } else {
2400 required_imports.insert(id);
2401 if !imports.contains_key(&key) {
2402 imports.insert(key.clone(), item);
2403 }
2404 }
2405 true
2406 }
2407 }
2408
2409 pub fn merge_world_imports_based_on_semver(&mut self, world_id: WorldId) -> anyhow::Result<()> {
2421 let world = &self.worlds[world_id];
2422
2423 let mut semver_tracks = HashMap::new();
2432 let mut to_remove = HashSet::new();
2433 for (key, _) in world.imports.iter() {
2434 let iface_id = match key {
2435 WorldKey::Interface(id) => *id,
2436 WorldKey::Name(_) => continue,
2437 };
2438 let (track, version) = match self.semver_track(iface_id) {
2439 Some(track) => track,
2440 None => continue,
2441 };
2442 log::debug!(
2443 "{} is on track {}/{}",
2444 self.id_of(iface_id).unwrap(),
2445 track.0,
2446 track.1,
2447 );
2448 match semver_tracks.entry(track) {
2449 Entry::Vacant(e) => {
2450 e.insert((version, iface_id));
2451 }
2452 Entry::Occupied(mut e) => match version.cmp(&e.get().0) {
2453 Ordering::Greater => {
2454 to_remove.insert(e.get().1);
2455 e.insert((version, iface_id));
2456 }
2457 Ordering::Equal => {}
2458 Ordering::Less => {
2459 to_remove.insert(iface_id);
2460 }
2461 },
2462 }
2463 }
2464
2465 let mut replacements = HashMap::new();
2468 for id in to_remove {
2469 let (track, _) = self.semver_track(id).unwrap();
2470 let (_, latest) = semver_tracks[&track];
2471 let prev = replacements.insert(id, latest);
2472 assert!(prev.is_none());
2473 }
2474 drop(semver_tracks);
2477
2478 for (to_replace, replace_with) in replacements.iter() {
2483 self.merge_world_item(
2484 &WorldItem::Interface {
2485 id: *to_replace,
2486 stability: Default::default(),
2487 docs: Default::default(),
2488 span: Default::default(),
2489 external_id: Default::default(),
2490 },
2491 &WorldItem::Interface {
2492 id: *replace_with,
2493 stability: Default::default(),
2494 docs: Default::default(),
2495 span: Default::default(),
2496 external_id: Default::default(),
2497 },
2498 )
2499 .with_context(|| {
2500 let old_name = self.id_of(*to_replace).unwrap();
2501 let new_name = self.id_of(*replace_with).unwrap();
2502 format!(
2503 "failed to upgrade `{old_name}` to `{new_name}`, was \
2504 this semver-compatible update not semver compatible?"
2505 )
2506 })?;
2507 }
2508
2509 for (to_replace, replace_with) in replacements.iter() {
2510 log::debug!(
2511 "REPLACE {} => {}",
2512 self.id_of(*to_replace).unwrap(),
2513 self.id_of(*replace_with).unwrap(),
2514 );
2515 }
2516
2517 for (key, item) in mem::take(&mut self.worlds[world_id].imports) {
2526 if let WorldItem::Interface { id, .. } = item {
2527 if replacements.contains_key(&id) {
2528 if let WorldKey::Interface(_) = key {
2529 continue;
2530 }
2531 }
2533 }
2534
2535 self.update_interface_deps_of_world_item(&item, &replacements);
2536
2537 let prev = self.worlds[world_id].imports.insert(key, item);
2538 assert!(prev.is_none());
2539 }
2540 for (key, item) in mem::take(&mut self.worlds[world_id].exports) {
2541 self.update_interface_deps_of_world_item(&item, &replacements);
2542 let prev = self.worlds[world_id].exports.insert(key, item);
2543 assert!(prev.is_none());
2544 }
2545
2546 let ids = self.worlds.iter().map(|(id, _)| id).collect::<Vec<_>>();
2552 for world_id in ids {
2553 let world_span = self.worlds[world_id].span;
2554 self.elaborate_world(world_id, world_span)?;
2555 }
2556
2557 #[cfg(debug_assertions)]
2558 self.assert_valid();
2559
2560 Ok(())
2561 }
2562
2563 fn update_interface_deps_of_world_item(
2564 &mut self,
2565 item: &WorldItem,
2566 replacements: &HashMap<InterfaceId, InterfaceId>,
2567 ) {
2568 match *item {
2569 WorldItem::Type { id, .. } => self.update_interface_dep_of_type(id, &replacements),
2570 WorldItem::Interface { id, .. } => {
2571 let types = self.interfaces[id]
2572 .types
2573 .values()
2574 .copied()
2575 .collect::<Vec<_>>();
2576 for ty in types {
2577 self.update_interface_dep_of_type(ty, &replacements);
2578 }
2579 }
2580 WorldItem::Function(_) => {}
2581 }
2582 }
2583
2584 fn semver_track(&self, id: InterfaceId) -> Option<((PackageName, String), &Version)> {
2595 let iface = &self.interfaces[id];
2596 let pkg = &self.packages[iface.package?];
2597 let version = pkg.name.version.as_ref()?;
2598 let mut name = pkg.name.clone();
2599 name.version = Some(PackageName::version_compat_track(version).0);
2600 Some(((name, iface.name.clone()?), version))
2601 }
2602
2603 fn update_interface_dep_of_type(
2607 &mut self,
2608 ty: TypeId,
2609 replacements: &HashMap<InterfaceId, InterfaceId>,
2610 ) {
2611 let to_replace = match self.type_interface_dep(ty) {
2612 Some(id) => id,
2613 None => return,
2614 };
2615 let replace_with = match replacements.get(&to_replace) {
2616 Some(id) => id,
2617 None => return,
2618 };
2619 let dep = match self.types[ty].kind {
2620 TypeDefKind::Type(Type::Id(id)) => id,
2621 _ => return,
2622 };
2623 let name = self.types[dep].name.as_ref().unwrap();
2624 let replacement_id = self.interfaces[*replace_with].types[name];
2627 self.types[ty].kind = TypeDefKind::Type(Type::Id(replacement_id));
2628 }
2629
2630 pub fn wasm_import_name(
2637 &self,
2638 mangling: ManglingAndAbi,
2639 import: WasmImport<'_>,
2640 ) -> (String, String) {
2641 match mangling {
2642 ManglingAndAbi::Standard32 => match import {
2643 WasmImport::Func { interface, func } => {
2644 let module = match interface {
2645 Some(key) => format!("cm32p2|{}", self.name_canonicalized_world_key(key)),
2646 None => format!("cm32p2"),
2647 };
2648 (module, func.name.clone())
2649 }
2650 WasmImport::ResourceIntrinsic {
2651 interface,
2652 resource,
2653 intrinsic,
2654 } => {
2655 let name = self.types[resource].name.as_ref().unwrap();
2656 let (prefix, name) = match intrinsic {
2657 ResourceIntrinsic::ImportedDrop => ("", format!("{name}_drop")),
2658 ResourceIntrinsic::ExportedDrop => ("_ex_", format!("{name}_drop")),
2659 ResourceIntrinsic::ExportedNew => ("_ex_", format!("{name}_new")),
2660 ResourceIntrinsic::ExportedRep => ("_ex_", format!("{name}_rep")),
2661 };
2662 let module = match interface {
2663 Some(key) => {
2664 format!("cm32p2|{prefix}{}", self.name_canonicalized_world_key(key))
2665 }
2666 None => {
2667 assert_eq!(prefix, "");
2668 format!("cm32p2")
2669 }
2670 };
2671 (module, name)
2672 }
2673 WasmImport::FutureIntrinsic { .. } | WasmImport::StreamIntrinsic { .. } => {
2674 panic!(
2675 "at the time of writing, standard32 name mangling only supports the \
2676 synchronous ABI and does not define future/stream intrinsic imports; \
2677 use legacy mangling for these imports"
2678 )
2679 }
2680 },
2681 ManglingAndAbi::Legacy(abi) => match import {
2682 WasmImport::Func { interface, func } => {
2683 let module = match interface {
2684 Some(key) => self.name_world_key(key),
2685 None => format!("$root"),
2686 };
2687 (module, format!("{}{}", abi.import_prefix(), func.name))
2688 }
2689 WasmImport::ResourceIntrinsic {
2690 interface,
2691 resource,
2692 intrinsic,
2693 } => {
2694 let name = self.types[resource].name.as_ref().unwrap();
2695 let (prefix, name) = match intrinsic {
2696 ResourceIntrinsic::ImportedDrop => ("", format!("[resource-drop]{name}")),
2697 ResourceIntrinsic::ExportedDrop => {
2698 ("[export]", format!("[resource-drop]{name}"))
2699 }
2700 ResourceIntrinsic::ExportedNew => {
2701 ("[export]", format!("[resource-new]{name}"))
2702 }
2703 ResourceIntrinsic::ExportedRep => {
2704 ("[export]", format!("[resource-rep]{name}"))
2705 }
2706 };
2707 let module = match interface {
2708 Some(key) => format!("{prefix}{}", self.name_world_key(key)),
2709 None => {
2710 assert_eq!(prefix, "");
2711 format!("$root")
2712 }
2713 };
2714 (module, format!("{}{name}", abi.import_prefix()))
2715 }
2716 WasmImport::FutureIntrinsic {
2717 interface,
2718 func,
2719 ty,
2720 intrinsic,
2721 exported,
2722 async_,
2723 } => {
2724 let module_prefix = if exported { "[export]" } else { "" };
2725 let module = match interface {
2726 Some(key) => format!("{module_prefix}{}", self.name_world_key(key)),
2727 None => format!("{module_prefix}$root"),
2728 };
2729 let type_index = match ty {
2730 Some(ty) => func
2731 .find_futures_and_streams(self)
2732 .into_iter()
2733 .position(|candidate| candidate == ty)
2734 .unwrap_or_else(|| {
2735 panic!(
2736 "future type {ty:?} not found in `find_futures_and_streams` for `{}`",
2737 func.name
2738 )
2739 })
2740 .to_string(),
2741 None => "unit".to_string(),
2742 };
2743 let (async_prefix, name) = match intrinsic {
2744 FutureIntrinsic::New => {
2745 assert!(!async_, "future.new cannot be async-lowered");
2746 ("", "new")
2747 }
2748 FutureIntrinsic::Read => {
2749 (if async_ { "[async-lower]" } else { "" }, "read")
2750 }
2751 FutureIntrinsic::Write => {
2752 (if async_ { "[async-lower]" } else { "" }, "write")
2753 }
2754 FutureIntrinsic::Forward => {
2755 assert!(!async_, "future.forward cannot be async-lowered");
2756 ("", "forward")
2757 }
2758 FutureIntrinsic::CancelRead => {
2759 (if async_ { "[async-lower]" } else { "" }, "cancel-read")
2760 }
2761 FutureIntrinsic::CancelWrite => {
2762 (if async_ { "[async-lower]" } else { "" }, "cancel-write")
2763 }
2764 FutureIntrinsic::DropReadable => {
2765 assert!(!async_, "future.drop-readable cannot be async-lowered");
2766 ("", "drop-readable")
2767 }
2768 FutureIntrinsic::DropWritable => {
2769 assert!(!async_, "future.drop-writable cannot be async-lowered");
2770 ("", "drop-writable")
2771 }
2772 };
2773 (
2774 module,
2775 format!("{async_prefix}[future-{name}-{type_index}]{}", func.name),
2776 )
2777 }
2778 WasmImport::StreamIntrinsic {
2779 interface,
2780 func,
2781 ty,
2782 intrinsic,
2783 exported,
2784 async_,
2785 } => {
2786 let module_prefix = if exported { "[export]" } else { "" };
2787 let module = match interface {
2788 Some(key) => format!("{module_prefix}{}", self.name_world_key(key)),
2789 None => format!("{module_prefix}$root"),
2790 };
2791 let type_index = match ty {
2792 Some(ty) => func
2793 .find_futures_and_streams(self)
2794 .into_iter()
2795 .position(|candidate| candidate == ty)
2796 .unwrap_or_else(|| {
2797 panic!(
2798 "stream type {ty:?} not found in `find_futures_and_streams` for `{}`",
2799 func.name
2800 )
2801 })
2802 .to_string(),
2803 None => "unit".to_string(),
2804 };
2805 let (async_prefix, name) = match intrinsic {
2806 StreamIntrinsic::New => {
2807 assert!(!async_, "stream.new cannot be async-lowered");
2808 ("", "new")
2809 }
2810 StreamIntrinsic::Read => {
2811 (if async_ { "[async-lower]" } else { "" }, "read")
2812 }
2813 StreamIntrinsic::Write => {
2814 (if async_ { "[async-lower]" } else { "" }, "write")
2815 }
2816 StreamIntrinsic::Forward => {
2817 assert!(!async_, "stream.forward cannot be async-lowered");
2818 ("", "forward")
2819 }
2820 StreamIntrinsic::CancelRead => {
2821 (if async_ { "[async-lower]" } else { "" }, "cancel-read")
2822 }
2823 StreamIntrinsic::CancelWrite => {
2824 (if async_ { "[async-lower]" } else { "" }, "cancel-write")
2825 }
2826 StreamIntrinsic::DropReadable => {
2827 assert!(!async_, "stream.drop-readable cannot be async-lowered");
2828 ("", "drop-readable")
2829 }
2830 StreamIntrinsic::DropWritable => {
2831 assert!(!async_, "stream.drop-writable cannot be async-lowered");
2832 ("", "drop-writable")
2833 }
2834 };
2835 (
2836 module,
2837 format!("{async_prefix}[stream-{name}-{type_index}]{}", func.name),
2838 )
2839 }
2840 },
2841 }
2842 }
2843
2844 pub fn wasm_export_name(&self, mangling: ManglingAndAbi, export: WasmExport<'_>) -> String {
2848 match mangling {
2849 ManglingAndAbi::Standard32 => match export {
2850 WasmExport::Func {
2851 interface,
2852 func,
2853 kind,
2854 } => {
2855 let mut name = String::from("cm32p2|");
2856 if let Some(interface) = interface {
2857 let s = self.name_canonicalized_world_key(interface);
2858 name.push_str(&s);
2859 }
2860 name.push_str("|");
2861 name.push_str(&func.name);
2862 match kind {
2863 WasmExportKind::Normal => {}
2864 WasmExportKind::PostReturn => name.push_str("_post"),
2865 WasmExportKind::Callback => todo!(
2866 "not yet supported: \
2867 async callback functions using standard name mangling"
2868 ),
2869 }
2870 name
2871 }
2872 WasmExport::ResourceDtor {
2873 interface,
2874 resource,
2875 } => {
2876 let name = self.types[resource].name.as_ref().unwrap();
2877 let interface = self.name_canonicalized_world_key(interface);
2878 format!("cm32p2|{interface}|{name}_dtor")
2879 }
2880 WasmExport::Memory => "cm32p2_memory".to_string(),
2881 WasmExport::Initialize => "cm32p2_initialize".to_string(),
2882 WasmExport::Realloc => "cm32p2_realloc".to_string(),
2883 },
2884 ManglingAndAbi::Legacy(abi) => match export {
2885 WasmExport::Func {
2886 interface,
2887 func,
2888 kind,
2889 } => {
2890 let mut name = abi.export_prefix().to_string();
2891 match kind {
2892 WasmExportKind::Normal => {}
2893 WasmExportKind::PostReturn => name.push_str("cabi_post_"),
2894 WasmExportKind::Callback => {
2895 assert!(matches!(abi, LiftLowerAbi::AsyncCallback));
2896 name = format!("[callback]{name}")
2897 }
2898 }
2899 if let Some(interface) = interface {
2900 let s = self.name_world_key(interface);
2901 name.push_str(&s);
2902 name.push_str("#");
2903 }
2904 name.push_str(&func.name);
2905 name
2906 }
2907 WasmExport::ResourceDtor {
2908 interface,
2909 resource,
2910 } => {
2911 let name = self.types[resource].name.as_ref().unwrap();
2912 let interface = self.name_world_key(interface);
2913 format!("{}{interface}#[dtor]{name}", abi.export_prefix())
2914 }
2915 WasmExport::Memory => "memory".to_string(),
2916 WasmExport::Initialize => "_initialize".to_string(),
2917 WasmExport::Realloc => "cabi_realloc".to_string(),
2918 },
2919 }
2920 }
2921
2922 pub fn generate_nominal_type_ids(&mut self, world_id: WorldId) {
2962 let mut seen = HashSet::new();
2963 let mut interface_keys_rewritten = HashSet::new();
2964 let mut maps = CloneMaps::default();
2965
2966 let world = &mut self.worlds[world_id];
2969 let mut imports = mem::take(&mut world.imports);
2970 let mut exports = mem::take(&mut world.exports);
2971
2972 log::trace!("nominalizing world imports");
2976 self.nominalize_world_items(
2977 &mut maps,
2978 world_id,
2979 &mut imports,
2980 &mut seen,
2981 &mut interface_keys_rewritten,
2982 );
2983 log::trace!("nominalizing world exports");
2984 self.nominalize_world_items(
2985 &mut maps,
2986 world_id,
2987 &mut exports,
2988 &mut seen,
2989 &mut interface_keys_rewritten,
2990 );
2991
2992 let world = &mut self.worlds[world_id];
2994 assert!(world.imports.is_empty());
2995 assert!(world.exports.is_empty());
2996 world.imports = imports;
2997 world.exports = exports;
2998
2999 #[cfg(debug_assertions)]
3000 self.assert_valid();
3001 }
3002
3003 fn nominalize_world_items(
3026 &mut self,
3027 maps: &mut CloneMaps,
3028 world: WorldId,
3029 items: &mut IndexMap<WorldKey, WorldItem>,
3030 seen: &mut HashSet<InterfaceId>,
3031 interface_keys_rewritten: &mut HashSet<InterfaceId>,
3032 ) {
3033 let mut order = items.iter().enumerate().collect::<Vec<_>>();
3131 order.sort_by_key(|(_, (key, item))| match (key, item) {
3132 (WorldKey::Name(_), WorldItem::Interface { .. }) => 1,
3133 _ => 0,
3134 });
3135 let mut to_rewrite = IndexMap::default();
3136 for (i, (key, item)) in order {
3137 let id = match item {
3138 WorldItem::Interface { id, .. } => *id,
3139
3140 WorldItem::Function(_) | WorldItem::Type { .. } => continue,
3143 };
3144
3145 let duplicated = !seen.insert(id);
3151 let any_dep_rewritten = self
3152 .interface_direct_deps(id)
3153 .any(|dep| interface_keys_rewritten.contains(&dep));
3154 if !(duplicated || any_dep_rewritten) {
3155 log::trace!("{} already nominal", self.name_world_key(key));
3156 continue;
3157 }
3158 log::trace!("{} getting rewritten nominal", self.name_world_key(key));
3159
3160 let is_name = matches!(key, WorldKey::Name(_));
3165 if !is_name {
3166 assert!(interface_keys_rewritten.insert(id));
3167 }
3168
3169 to_rewrite
3170 .entry(id)
3171 .or_insert(Vec::new())
3172 .push((i, is_name));
3173 }
3174
3175 for (id, mut list) in to_rewrite {
3206 list.sort_by_key(|(_, is_name)| if *is_name { 0 } else { 1 });
3207 for (i, is_name) in list {
3208 let prev_maps = if is_name { Some(maps.clone()) } else { None };
3209
3210 let mut cloner = clone::Cloner::new(
3211 self,
3212 maps,
3213 TypeOwner::World(world),
3214 TypeOwner::World(world),
3215 );
3216
3217 let mut new_id = id;
3218 cloner.new_package = cloner.resolve.interfaces[id].package;
3219 cloner.interface(&mut new_id);
3220 let (key, prev) = items.get_index_mut(i).unwrap();
3221 match prev {
3222 WorldItem::Interface { id, .. } => *id = new_id,
3223 _ => unreachable!(),
3224 }
3225
3226 match key {
3227 WorldKey::Interface(_) => {
3233 items.replace_index(i, WorldKey::Interface(new_id)).unwrap();
3234 }
3235
3236 WorldKey::Name(_) => {}
3239 }
3240
3241 if let Some(prev) = prev_maps {
3242 *maps = prev;
3243 }
3244 }
3245 }
3246 }
3247}
3248
3249#[derive(Debug)]
3251pub enum WasmImport<'a> {
3252 Func {
3254 interface: Option<&'a WorldKey>,
3259
3260 func: &'a Function,
3262 },
3263
3264 ResourceIntrinsic {
3266 interface: Option<&'a WorldKey>,
3268
3269 resource: TypeId,
3271
3272 intrinsic: ResourceIntrinsic,
3274 },
3275
3276 FutureIntrinsic {
3278 interface: Option<&'a WorldKey>,
3280
3281 func: &'a Function,
3283
3284 ty: Option<TypeId>,
3288
3289 intrinsic: FutureIntrinsic,
3291
3292 exported: bool,
3296
3297 async_: bool,
3301 },
3302
3303 StreamIntrinsic {
3305 interface: Option<&'a WorldKey>,
3307
3308 func: &'a Function,
3310
3311 ty: Option<TypeId>,
3315
3316 intrinsic: StreamIntrinsic,
3318
3319 exported: bool,
3323
3324 async_: bool,
3328 },
3329}
3330
3331#[derive(Debug)]
3334pub enum ResourceIntrinsic {
3335 ImportedDrop,
3336 ExportedDrop,
3337 ExportedNew,
3338 ExportedRep,
3339}
3340
3341#[derive(Debug)]
3344pub enum FutureIntrinsic {
3345 New,
3346 Read,
3347 Write,
3348 Forward,
3349 CancelRead,
3350 CancelWrite,
3351 DropReadable,
3352 DropWritable,
3353}
3354
3355#[derive(Debug)]
3358pub enum StreamIntrinsic {
3359 New,
3360 Read,
3361 Write,
3362 Forward,
3363 CancelRead,
3364 CancelWrite,
3365 DropReadable,
3366 DropWritable,
3367}
3368
3369#[derive(Debug)]
3372pub enum WasmExportKind {
3373 Normal,
3375
3376 PostReturn,
3378
3379 Callback,
3381}
3382
3383#[derive(Debug)]
3386pub enum WasmExport<'a> {
3387 Func {
3389 interface: Option<&'a WorldKey>,
3392
3393 func: &'a Function,
3395
3396 kind: WasmExportKind,
3398 },
3399
3400 ResourceDtor {
3402 interface: &'a WorldKey,
3404 resource: TypeId,
3406 },
3407
3408 Memory,
3410
3411 Initialize,
3413
3414 Realloc,
3416}
3417
3418#[derive(Default)]
3421pub struct Remap {
3422 pub types: Vec<Option<TypeId>>,
3423 pub interfaces: Vec<Option<InterfaceId>>,
3424 pub worlds: Vec<Option<WorldId>>,
3425 pub packages: Vec<PackageId>,
3426
3427 own_handles: HashMap<TypeId, TypeId>,
3437
3438 type_has_borrow: Vec<Option<bool>>,
3439}
3440
3441fn apply_map<T>(map: &[Option<Id<T>>], id: Id<T>, desc: &str, span: Span) -> ResolveResult<Id<T>> {
3442 match map.get(id.index()) {
3443 Some(Some(id)) => Ok(*id),
3444 Some(None) => {
3445 let msg = format!(
3446 "found a reference to a {desc} which is excluded \
3447 due to its feature not being activated"
3448 );
3449 Err(ResolveError::new_semantic(span, msg))
3450 }
3451 None => panic!("request to remap a {desc} that has not yet been registered"),
3452 }
3453}
3454
3455fn rename(original_name: &str, include_name: &IncludeName) -> Option<String> {
3456 let mut prefix_len = 0;
3458 while original_name[prefix_len..].starts_with('[') {
3459 let close = original_name[prefix_len..].find(']')?;
3460 prefix_len += close + 1;
3461 }
3462 let (prefix, rest) = original_name.split_at(prefix_len);
3463
3464 match rest.split_once('.') {
3465 Some((resource, func)) if resource == include_name.name => {
3467 Some(format!("{prefix}{}.{func}", include_name.as_))
3468 }
3469 None if rest == include_name.name => Some(format!("{prefix}{}", include_name.as_)),
3471 _ => None,
3472 }
3473}
3474
3475impl Remap {
3476 pub fn map_type(&self, id: TypeId, span: Span) -> ResolveResult<TypeId> {
3477 apply_map(&self.types, id, "type", span)
3478 }
3479
3480 pub fn map_interface(&self, id: InterfaceId, span: Span) -> ResolveResult<InterfaceId> {
3481 apply_map(&self.interfaces, id, "interface", span)
3482 }
3483
3484 pub fn map_world(&self, id: WorldId, span: Span) -> ResolveResult<WorldId> {
3485 apply_map(&self.worlds, id, "world", span)
3486 }
3487
3488 pub fn map_world_for_type(&self, id: WorldId, span: Span) -> ResolveResult<WorldId> {
3489 self.map_world(id, span).map_err(|e| {
3490 ResolveError::new_semantic(
3491 span,
3492 format!("{e}; this type is not gated by a feature but its world is"),
3493 )
3494 })
3495 }
3496
3497 pub fn map_interface_for_type(
3498 &self,
3499 id: InterfaceId,
3500 span: Span,
3501 ) -> ResolveResult<InterfaceId> {
3502 self.map_interface(id, span).map_err(|e| {
3503 ResolveError::new_semantic(
3504 span,
3505 format!("{e}; this type is not gated by a feature but its interface is"),
3506 )
3507 })
3508 }
3509
3510 fn append(
3511 &mut self,
3512 resolve: &mut Resolve,
3513 unresolved: UnresolvedPackage,
3514 ) -> ResolveResult<PackageId> {
3515 let pkgid = resolve.packages.alloc(Package {
3516 name: unresolved.name.clone(),
3517 docs: unresolved.docs.clone(),
3518 interfaces: Default::default(),
3519 worlds: Default::default(),
3520 });
3521 assert!(
3522 !resolve.package_names.contains_key(&unresolved.name),
3523 "attempting to re-add package `{}` when it's already present in this `Resolve`",
3524 unresolved.name,
3525 );
3526 resolve.package_names.insert(unresolved.name.clone(), pkgid);
3527 self.process_foreign_deps(resolve, pkgid, &unresolved)?;
3528
3529 let foreign_types = self.types.len();
3530 let foreign_interfaces = self.interfaces.len();
3531 let foreign_worlds = self.worlds.len();
3532
3533 for (id, mut ty) in unresolved.types.into_iter().skip(foreign_types) {
3539 let span = ty.span;
3540 if !resolve.include_stability(&ty.stability, &pkgid, span)? {
3541 self.types.push(None);
3542 continue;
3543 }
3544
3545 self.update_typedef(resolve, &mut ty, span)?;
3546 let new_id = resolve.types.alloc(ty);
3547 assert_eq!(self.types.len(), id.index());
3548
3549 let new_id = match resolve.types[new_id] {
3550 TypeDef {
3555 name: None,
3556 owner: TypeOwner::None,
3557 kind: TypeDefKind::Handle(Handle::Own(id)),
3558 docs: _,
3559 stability: _,
3560 span: _,
3561 external_id: _,
3562 } => *self.own_handles.entry(id).or_insert(new_id),
3563
3564 _ => new_id,
3567 };
3568 self.types.push(Some(new_id));
3569 }
3570
3571 for (id, mut iface) in unresolved.interfaces.into_iter().skip(foreign_interfaces) {
3574 let span = iface.span;
3575 if !resolve.include_stability(&iface.stability, &pkgid, span)? {
3576 self.interfaces.push(None);
3577 continue;
3578 }
3579 assert!(iface.package.is_none());
3580 iface.package = Some(pkgid);
3581 self.update_interface(resolve, &mut iface)?;
3582 let new_id = resolve.interfaces.alloc(iface);
3583 assert_eq!(self.interfaces.len(), id.index());
3584 self.interfaces.push(Some(new_id));
3585 }
3586
3587 for id in self.types.iter().skip(foreign_types) {
3590 let id = match id {
3591 Some(id) => *id,
3592 None => continue,
3593 };
3594 let span = resolve.types[id].span;
3595 match &mut resolve.types[id].owner {
3596 TypeOwner::Interface(iface_id) => {
3597 *iface_id = self.map_interface_for_type(*iface_id, span)?;
3598 }
3599 TypeOwner::World(_) | TypeOwner::None => {}
3600 }
3601 }
3602
3603 for (id, mut world) in unresolved.worlds.into_iter().skip(foreign_worlds) {
3611 let world_span = world.span;
3612 if !resolve.include_stability(&world.stability, &pkgid, world_span)? {
3613 self.worlds.push(None);
3614 continue;
3615 }
3616 self.update_world(&mut world, resolve, &pkgid)?;
3617
3618 let new_id = resolve.worlds.alloc(world);
3619 assert_eq!(self.worlds.len(), id.index());
3620 self.worlds.push(Some(new_id));
3621 }
3622
3623 for id in self.types.iter().skip(foreign_types) {
3625 let id = match id {
3626 Some(id) => *id,
3627 None => continue,
3628 };
3629 let span = resolve.types[id].span;
3630 match &mut resolve.types[id].owner {
3631 TypeOwner::World(world_id) => {
3632 *world_id = self.map_world_for_type(*world_id, span)?;
3633 }
3634 TypeOwner::Interface(_) | TypeOwner::None => {}
3635 }
3636 }
3637
3638 for id in self.worlds.iter().skip(foreign_worlds) {
3655 let Some(id) = *id else {
3656 continue;
3657 };
3658 self.process_world_includes(id, resolve, &pkgid)?;
3659
3660 let world_span = resolve.worlds[id].span;
3661 resolve.elaborate_world(id, world_span)?;
3662 }
3663
3664 for id in self.interfaces.iter().skip(foreign_interfaces) {
3666 let id = match id {
3667 Some(id) => *id,
3668 None => continue,
3669 };
3670 let iface = &mut resolve.interfaces[id];
3671 iface.package = Some(pkgid);
3672 if let Some(name) = &iface.name {
3673 let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), id);
3674 assert!(prev.is_none());
3675 }
3676 }
3677 for id in self.worlds.iter().skip(foreign_worlds) {
3678 let id = match id {
3679 Some(id) => *id,
3680 None => continue,
3681 };
3682 let world = &mut resolve.worlds[id];
3683 world.package = Some(pkgid);
3684 let prev = resolve.packages[pkgid]
3685 .worlds
3686 .insert(world.name.clone(), id);
3687 assert!(prev.is_none());
3688 }
3689 Ok(pkgid)
3690 }
3691
3692 fn process_foreign_deps(
3693 &mut self,
3694 resolve: &mut Resolve,
3695 pkgid: PackageId,
3696 unresolved: &UnresolvedPackage,
3697 ) -> ResolveResult<()> {
3698 let mut world_to_package = HashMap::new();
3701 let mut interface_to_package = HashMap::new();
3702 for (i, (pkg_name, worlds_or_ifaces)) in unresolved.foreign_deps.iter().enumerate() {
3703 for (name, (item, stabilities)) in worlds_or_ifaces {
3704 match item {
3705 AstItem::Interface(unresolved_interface_id) => {
3706 let prev = interface_to_package.insert(
3707 *unresolved_interface_id,
3708 (pkg_name, name, unresolved.foreign_dep_spans[i], stabilities),
3709 );
3710 assert!(prev.is_none());
3711 }
3712 AstItem::World(unresolved_world_id) => {
3713 let prev = world_to_package.insert(
3714 *unresolved_world_id,
3715 (pkg_name, name, unresolved.foreign_dep_spans[i], stabilities),
3716 );
3717 assert!(prev.is_none());
3718 }
3719 }
3720 }
3721 }
3722
3723 self.process_foreign_interfaces(unresolved, &interface_to_package, resolve, &pkgid)?;
3727
3728 self.process_foreign_worlds(unresolved, &world_to_package, resolve, &pkgid)?;
3732
3733 self.process_foreign_types(unresolved, pkgid, resolve)?;
3736
3737 for (id, span) in unresolved.required_resource_types.iter() {
3738 let Ok(mut id) = self.map_type(*id, *span) else {
3743 continue;
3744 };
3745 loop {
3746 match resolve.types[id].kind {
3747 TypeDefKind::Type(Type::Id(i)) => id = i,
3748 TypeDefKind::Resource => break,
3749 _ => {
3750 return Err(ResolveError::new_semantic(
3751 *span,
3752 "type used in a handle must be a resource",
3753 ));
3754 }
3755 }
3756 }
3757 }
3758
3759 #[cfg(debug_assertions)]
3760 resolve.assert_valid();
3761
3762 Ok(())
3763 }
3764
3765 fn process_foreign_interfaces(
3766 &mut self,
3767 unresolved: &UnresolvedPackage,
3768 interface_to_package: &HashMap<InterfaceId, (&PackageName, &String, Span, &Vec<Stability>)>,
3769 resolve: &mut Resolve,
3770 parent_pkg_id: &PackageId,
3771 ) -> ResolveResult<()> {
3772 for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() {
3773 let (pkg_name, interface, span, stabilities) =
3774 match interface_to_package.get(&unresolved_iface_id) {
3775 Some(items) => *items,
3776 None => break,
3780 };
3781
3782 let pkgid = resolve
3783 .package_names
3784 .get(pkg_name)
3785 .copied()
3786 .ok_or_else(|| {
3787 ResolveError::from(ResolveErrorKind::PackageNotFound {
3788 span,
3789 requested: pkg_name.clone(),
3790 known: resolve.package_names.keys().cloned().collect(),
3791 })
3792 })?;
3793
3794 assert!(unresolved_iface.functions.is_empty());
3796
3797 let pkg = &resolve.packages[pkgid];
3798 let iface_span = unresolved_iface.span;
3799
3800 let mut enabled = false;
3801 for stability in stabilities {
3802 if resolve.include_stability(stability, parent_pkg_id, iface_span)? {
3803 enabled = true;
3804 break;
3805 }
3806 }
3807
3808 if !enabled {
3809 self.interfaces.push(None);
3810 continue;
3811 }
3812
3813 let iface_id = pkg.interfaces.get(interface).copied().ok_or_else(|| {
3814 ResolveError::from(ResolveErrorKind::InterfaceNotFound {
3815 span: iface_span,
3816 requested: interface.to_string(),
3817 package: pkg.name.clone(),
3818 })
3819 })?;
3820 assert_eq!(self.interfaces.len(), unresolved_iface_id.index());
3821 self.interfaces.push(Some(iface_id));
3822 }
3823 for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) {
3824 assert!(
3825 interface_to_package.get(&id).is_none(),
3826 "found foreign interface after local interface"
3827 );
3828 }
3829 Ok(())
3830 }
3831
3832 fn process_foreign_worlds(
3833 &mut self,
3834 unresolved: &UnresolvedPackage,
3835 world_to_package: &HashMap<WorldId, (&PackageName, &String, Span, &Vec<Stability>)>,
3836 resolve: &mut Resolve,
3837 parent_pkg_id: &PackageId,
3838 ) -> ResolveResult<()> {
3839 for (unresolved_world_id, unresolved_world) in unresolved.worlds.iter() {
3840 let (pkg_name, world, span, stabilities) =
3841 match world_to_package.get(&unresolved_world_id) {
3842 Some(items) => *items,
3843 None => break,
3846 };
3847
3848 let pkgid = resolve
3849 .package_names
3850 .get(pkg_name)
3851 .copied()
3852 .ok_or_else(|| {
3853 ResolveError::from(ResolveErrorKind::PackageNotFound {
3854 span,
3855 requested: pkg_name.clone(),
3856 known: resolve.package_names.keys().cloned().collect(),
3857 })
3858 })?;
3859 let pkg = &resolve.packages[pkgid];
3860 let world_span = unresolved_world.span;
3861
3862 let mut enabled = false;
3863 for stability in stabilities {
3864 if resolve.include_stability(stability, parent_pkg_id, world_span)? {
3865 enabled = true;
3866 break;
3867 }
3868 }
3869
3870 if !enabled {
3871 self.worlds.push(None);
3872 continue;
3873 }
3874
3875 let world_id = pkg.worlds.get(world).copied().ok_or_else(|| {
3876 ResolveError::from(ResolveErrorKind::WorldNotFound {
3877 span: world_span,
3878 requested: world.to_string(),
3879 package: pkg.name.clone(),
3880 })
3881 })?;
3882 assert_eq!(self.worlds.len(), unresolved_world_id.index());
3883 self.worlds.push(Some(world_id));
3884 }
3885 for (id, _) in unresolved.worlds.iter().skip(self.worlds.len()) {
3886 assert!(
3887 world_to_package.get(&id).is_none(),
3888 "found foreign world after local world"
3889 );
3890 }
3891 Ok(())
3892 }
3893
3894 fn process_foreign_types(
3895 &mut self,
3896 unresolved: &UnresolvedPackage,
3897 pkgid: PackageId,
3898 resolve: &mut Resolve,
3899 ) -> ResolveResult<()> {
3900 for (unresolved_type_id, unresolved_ty) in unresolved.types.iter() {
3901 match unresolved_ty.kind {
3905 TypeDefKind::Unknown => {}
3906 _ => break,
3907 }
3908
3909 let span = unresolved_ty.span;
3910 if !resolve.include_stability(&unresolved_ty.stability, &pkgid, span)? {
3911 self.types.push(None);
3912 continue;
3913 }
3914
3915 let unresolved_iface_id = match unresolved_ty.owner {
3916 TypeOwner::Interface(id) => id,
3917 _ => unreachable!(),
3918 };
3919 let iface_id = self.map_interface(unresolved_iface_id, Default::default())?;
3920 let name = unresolved_ty.name.as_ref().unwrap();
3921 let span = unresolved.unknown_type_spans[unresolved_type_id.index()];
3922 let type_id = *resolve.interfaces[iface_id]
3923 .types
3924 .get(name)
3925 .ok_or_else(|| {
3926 ResolveError::new_semantic(
3927 span,
3928 format!("type `{name}` not defined in interface"),
3929 )
3930 })?;
3931 assert_eq!(self.types.len(), unresolved_type_id.index());
3932 self.types.push(Some(type_id));
3933 }
3934 for (_, ty) in unresolved.types.iter().skip(self.types.len()) {
3935 if let TypeDefKind::Unknown = ty.kind {
3936 panic!("unknown type after defined type");
3937 }
3938 }
3939 Ok(())
3940 }
3941
3942 fn update_typedef(
3943 &mut self,
3944 resolve: &mut Resolve,
3945 ty: &mut TypeDef,
3946 span: Span,
3947 ) -> ResolveResult<()> {
3948 use crate::TypeDefKind::*;
3951 match &mut ty.kind {
3952 Handle(handle) => match handle {
3953 crate::Handle::Own(ty) | crate::Handle::Borrow(ty) => {
3954 self.update_type_id(ty, span)?
3955 }
3956 },
3957 Resource => {}
3958 Record(r) => {
3959 for field in r.fields.iter_mut() {
3960 self.update_ty(resolve, &mut field.ty, field.span)?
3961 }
3962 }
3963 Tuple(t) => {
3964 for ty in t.types.iter_mut() {
3965 self.update_ty(resolve, ty, span)?;
3966 }
3967 }
3968 Variant(v) => {
3969 for case in v.cases.iter_mut() {
3970 if let Some(t) = &mut case.ty {
3971 self.update_ty(resolve, t, span)?;
3972 }
3973 }
3974 }
3975 Option(t)
3976 | List(t, ..)
3977 | FixedLengthList(t, ..)
3978 | Future(Some(t))
3979 | Stream(Some(t)) => self.update_ty(resolve, t, span)?,
3980 Map(k, v) => {
3981 self.update_ty(resolve, k, span)?;
3982 self.update_ty(resolve, v, span)?;
3983 }
3984 Result(r) => {
3985 if let Some(ty) = &mut r.ok {
3986 self.update_ty(resolve, ty, span)?;
3987 }
3988 if let Some(ty) = &mut r.err {
3989 self.update_ty(resolve, ty, span)?;
3990 }
3991 }
3992
3993 Type(crate::Type::Id(id)) => self.update_type_id(id, span)?,
3998 Type(_) => {}
3999
4000 Flags(_) | Enum(_) | Future(None) | Stream(None) => {}
4002
4003 Unknown => unreachable!(),
4004 }
4005
4006 Ok(())
4007 }
4008
4009 fn update_ty(&mut self, resolve: &mut Resolve, ty: &mut Type, span: Span) -> ResolveResult<()> {
4010 let id = match ty {
4011 Type::Id(id) => id,
4012 _ => return Ok(()),
4013 };
4014 self.update_type_id(id, span)?;
4015
4016 let mut cur = *id;
4021 let points_to_resource = loop {
4022 match resolve.types[cur].kind {
4023 TypeDefKind::Type(Type::Id(id)) => cur = id,
4024 TypeDefKind::Resource => break true,
4025 _ => break false,
4026 }
4027 };
4028
4029 if points_to_resource {
4030 *id = *self.own_handles.entry(*id).or_insert_with(|| {
4031 resolve.types.alloc(TypeDef {
4032 name: None,
4033 owner: TypeOwner::None,
4034 kind: TypeDefKind::Handle(Handle::Own(*id)),
4035 docs: Default::default(),
4036 stability: Default::default(),
4037 span: Default::default(),
4038 external_id: None,
4039 })
4040 });
4041 }
4042 Ok(())
4043 }
4044
4045 fn update_type_id(&self, id: &mut TypeId, span: Span) -> ResolveResult<()> {
4046 *id = self.map_type(*id, span)?;
4047 Ok(())
4048 }
4049
4050 fn update_interface(
4051 &mut self,
4052 resolve: &mut Resolve,
4053 iface: &mut Interface,
4054 ) -> ResolveResult<()> {
4055 iface.types.retain(|_, ty| self.types[ty.index()].is_some());
4056 let iface_pkg_id = iface.package.as_ref().unwrap_or_else(|| {
4057 panic!(
4058 "unexpectedly missing package on interface [{}]",
4059 iface
4060 .name
4061 .as_ref()
4062 .map(String::as_str)
4063 .unwrap_or("<unknown>"),
4064 )
4065 });
4066
4067 for (_name, ty) in iface.types.iter_mut() {
4070 self.update_type_id(ty, iface.span)?;
4071 }
4072 for (_, func) in iface.functions.iter_mut() {
4073 let span = func.span;
4074 if !resolve.include_stability(&func.stability, iface_pkg_id, span)? {
4075 continue;
4076 }
4077 self.update_function(resolve, func, span)?
4078 }
4079
4080 for (name, func) in mem::take(&mut iface.functions) {
4083 if resolve.include_stability(&func.stability, iface_pkg_id, func.span)? {
4084 iface.functions.insert(name, func);
4085 }
4086 }
4087
4088 Ok(())
4089 }
4090
4091 fn update_function(
4092 &mut self,
4093 resolve: &mut Resolve,
4094 func: &mut Function,
4095 span: Span,
4096 ) -> ResolveResult<()> {
4097 if let Some(id) = func.kind.resource_mut() {
4098 self.update_type_id(id, span)?;
4099 }
4100 for param in func.params.iter_mut() {
4101 self.update_ty(resolve, &mut param.ty, span)?;
4102 }
4103 if let Some(ty) = &mut func.result {
4104 self.update_ty(resolve, ty, span)?;
4105 }
4106
4107 if let Some(ty) = &func.result {
4108 if self.type_has_borrow(resolve, ty) {
4109 return Err(ResolveError::new_semantic(
4110 span,
4111 format!(
4112 "function `{}` returns a type which contains a `borrow<T>` which is not supported",
4113 func.name,
4114 ),
4115 ));
4116 }
4117 }
4118
4119 Ok(())
4120 }
4121
4122 fn update_world(
4123 &mut self,
4124 world: &mut World,
4125 resolve: &mut Resolve,
4126 pkg_id: &PackageId,
4127 ) -> ResolveResult<()> {
4128 let imports = mem::take(&mut world.imports).into_iter().map(|p| (p, true));
4132 let exports = mem::take(&mut world.exports)
4133 .into_iter()
4134 .map(|p| (p, false));
4135 for ((mut name, mut item), import) in imports.chain(exports) {
4136 let span = item.span();
4137 if let WorldItem::Type { id, .. } = &mut item {
4140 *id = self.map_type(*id, span)?;
4141 }
4142 let stability = item.stability(resolve);
4143 if !resolve.include_stability(stability, pkg_id, span)? {
4144 continue;
4145 }
4146 self.update_world_key(&mut name, span)?;
4147 match &mut item {
4148 WorldItem::Interface { id, .. } => {
4149 *id = self.map_interface(*id, span)?;
4150 }
4151 WorldItem::Function(f) => {
4152 self.update_function(resolve, f, span)?;
4153 }
4154 WorldItem::Type { .. } => {
4155 }
4157 }
4158
4159 let dst = if import {
4160 &mut world.imports
4161 } else {
4162 &mut world.exports
4163 };
4164 let prev = dst.insert(name, item);
4165 assert!(prev.is_none());
4166 }
4167
4168 Ok(())
4169 }
4170
4171 fn process_world_includes(
4172 &self,
4173 id: WorldId,
4174 resolve: &mut Resolve,
4175 pkg_id: &PackageId,
4176 ) -> ResolveResult<()> {
4177 let world = &mut resolve.worlds[id];
4178 let includes = mem::take(&mut world.includes);
4181 for include in includes {
4182 if !resolve.include_stability(&include.stability, pkg_id, include.span)? {
4183 continue;
4184 }
4185 self.resolve_include(
4186 id,
4187 include.id,
4188 &include.names,
4189 include.span,
4190 pkg_id,
4191 resolve,
4192 )?;
4193 }
4194
4195 Self::validate_world_strongly_unique_names(resolve, id)?;
4197
4198 let world = &mut resolve.worlds[id];
4202 place_setters_after_getters(&mut world.imports, world_item_func);
4203 place_setters_after_getters(&mut world.exports, world_item_func);
4204 for (items, item_type) in [(&world.imports, "import"), (&world.exports, "export")] {
4205 for item in items.values() {
4206 if let Some(f) = world_item_func(item)
4207 && f.kind.accessor() == Some(AccessorKind::Setter)
4208 {
4209 let getter = f.name.replacen("[set]", "[get]", 1);
4210 if !items.contains_key(&WorldKey::Name(getter.clone())) {
4211 return Err(ResolveError::new_semantic(
4212 item.span(),
4213 format!(
4214 "{item_type} `{}` in world `{}` has no corresponding getter `{getter}`",
4215 f.name, world.name,
4216 ),
4217 ));
4218 }
4219 }
4220 }
4221 }
4222
4223 Ok(())
4224 }
4225
4226 fn validate_world_strongly_unique_names(
4228 resolve: &Resolve,
4229 world_id: WorldId,
4230 ) -> ResolveResult<()> {
4231 use wasmparser::names::ComponentName;
4232
4233 let world = &resolve.worlds[world_id];
4234
4235 let validate_names =
4236 |items: &IndexMap<WorldKey, WorldItem>, item_type: &str| -> ResolveResult<()> {
4237 let mut seen: HashMap<ComponentName, &str> = HashMap::new();
4238
4239 for key in items.keys() {
4240 let WorldKey::Name(name) = key else {
4243 continue;
4244 };
4245 let Ok(component_name) = crate::parse_component_name(name) else {
4246 continue;
4247 };
4248
4249 if let Some(existing_name) = seen.get(&component_name) {
4250 return Err(ResolveError::new_semantic(
4254 Span::default(),
4255 format!(
4256 "{item_type} `{name}` in world `{}` conflicts with \
4257 {item_type} `{existing_name}` \
4258 (names must be strongly unique)",
4259 world.name,
4260 ),
4261 ));
4262 }
4263
4264 seen.insert(component_name, name);
4265 }
4266
4267 Ok(())
4268 };
4269
4270 validate_names(&world.imports, "import")?;
4271 validate_names(&world.exports, "export")?;
4272
4273 Ok(())
4274 }
4275
4276 fn update_world_key(&self, key: &mut WorldKey, span: Span) -> ResolveResult<()> {
4277 match key {
4278 WorldKey::Name(_) => {}
4279 WorldKey::Interface(id) => {
4280 *id = self.map_interface(*id, span)?;
4281 }
4282 }
4283 Ok(())
4284 }
4285
4286 fn resolve_include(
4287 &self,
4288 id: WorldId,
4289 include_world_id_orig: WorldId,
4290 names: &[IncludeName],
4291 span: Span,
4292 pkg_id: &PackageId,
4293 resolve: &mut Resolve,
4294 ) -> ResolveResult<()> {
4295 let world = &resolve.worlds[id];
4296 let include_world_id = self.map_world(include_world_id_orig, span)?;
4297 let include_world = resolve.worlds[include_world_id].clone();
4298 let mut names_ = names.to_owned();
4299 let is_external_include = world.package != include_world.package;
4300
4301 for import in include_world.imports.iter() {
4303 self.remove_matching_name(import, &mut names_);
4304 }
4305 for export in include_world.exports.iter() {
4306 self.remove_matching_name(export, &mut names_);
4307 }
4308 if !names_.is_empty() {
4309 return Err(ResolveError::new_semantic(
4310 span,
4311 format!(
4312 "no import or export kebab-name `{}`. Note that an ID does not support renaming",
4313 names_[0].name
4314 ),
4315 ));
4316 }
4317
4318 let mut maps = Default::default();
4319 let mut cloner = clone::Cloner::new(
4320 resolve,
4321 &mut maps,
4322 TypeOwner::World(if is_external_include {
4323 include_world_id
4324 } else {
4325 include_world_id
4326 }),
4328 TypeOwner::World(id),
4329 );
4330 cloner.new_package = Some(*pkg_id);
4331
4332 for import in include_world.imports.iter() {
4334 self.resolve_include_item(
4335 &mut cloner,
4336 names,
4337 |resolve| &mut resolve.worlds[id].imports,
4338 import,
4339 span,
4340 "import",
4341 is_external_include,
4342 )?;
4343 }
4344
4345 for export in include_world.exports.iter() {
4346 self.resolve_include_item(
4347 &mut cloner,
4348 names,
4349 |resolve| &mut resolve.worlds[id].exports,
4350 export,
4351 span,
4352 "export",
4353 is_external_include,
4354 )?;
4355 }
4356 Ok(())
4357 }
4358
4359 fn resolve_include_item(
4360 &self,
4361 cloner: &mut clone::Cloner<'_>,
4362 names: &[IncludeName],
4363 get_items: impl Fn(&mut Resolve) -> &mut IndexMap<WorldKey, WorldItem>,
4364 item: (&WorldKey, &WorldItem),
4365 span: Span,
4366 item_type: &str,
4367 is_external_include: bool,
4368 ) -> ResolveResult<()> {
4369 match item.0 {
4370 WorldKey::Name(n) => {
4371 let n = names
4372 .into_iter()
4373 .find_map(|include_name| rename(n, include_name))
4374 .unwrap_or(n.clone());
4375
4376 let mut new_item = item.1.clone();
4382 let key = WorldKey::Name(n.clone());
4383 cloner.world_item(&key, &mut new_item);
4384 match &mut new_item {
4385 WorldItem::Function(f) => f.name = n.clone(),
4386 WorldItem::Type { id, .. } => cloner.resolve.types[*id].name = Some(n.clone()),
4387 WorldItem::Interface { .. } => {}
4388 }
4389
4390 let prev = get_items(cloner.resolve).insert(key, new_item);
4391 if prev.is_some() {
4392 return Err(ResolveError::from(ResolveErrorKind::ItemShadowing {
4393 span,
4394 item_type: item_type.to_owned(),
4395 name: n,
4396 }));
4397 }
4398 }
4399 key @ WorldKey::Interface(_) => {
4400 let prev = get_items(cloner.resolve)
4401 .entry(key.clone())
4402 .or_insert(item.1.clone());
4403 match (&item.1, prev) {
4404 (
4405 WorldItem::Interface {
4406 id: aid,
4407 stability: astability,
4408 span: aspan,
4409 ..
4410 },
4411 WorldItem::Interface {
4412 id: bid,
4413 stability: bstability,
4414 ..
4415 },
4416 ) => {
4417 assert_eq!(*aid, *bid);
4418 merge_include_stability(
4419 astability,
4420 bstability,
4421 is_external_include,
4422 *aspan,
4423 )?;
4424 }
4425 (WorldItem::Interface { .. }, _) => unreachable!(),
4426 (WorldItem::Function(_), _) => unreachable!(),
4427 (WorldItem::Type { .. }, _) => unreachable!(),
4428 }
4429 }
4430 };
4431
4432 Ok(())
4433 }
4434
4435 fn remove_matching_name(&self, item: (&WorldKey, &WorldItem), names: &mut Vec<IncludeName>) {
4436 match item.0 {
4437 WorldKey::Name(n) => {
4438 names.retain(|name| rename(n, name).is_none());
4439 }
4440 _ => {}
4441 }
4442 }
4443
4444 fn type_has_borrow(&mut self, resolve: &Resolve, ty: &Type) -> bool {
4445 let id = match ty {
4446 Type::Id(id) => *id,
4447 _ => return false,
4448 };
4449
4450 if let Some(Some(has_borrow)) = self.type_has_borrow.get(id.index()) {
4451 return *has_borrow;
4452 }
4453
4454 let result = self.typedef_has_borrow(resolve, &resolve.types[id]);
4455 if self.type_has_borrow.len() <= id.index() {
4456 self.type_has_borrow.resize(id.index() + 1, None);
4457 }
4458 self.type_has_borrow[id.index()] = Some(result);
4459 result
4460 }
4461
4462 fn typedef_has_borrow(&mut self, resolve: &Resolve, ty: &TypeDef) -> bool {
4463 match &ty.kind {
4464 TypeDefKind::Type(t) => self.type_has_borrow(resolve, t),
4465 TypeDefKind::Variant(v) => v
4466 .cases
4467 .iter()
4468 .filter_map(|case| case.ty.as_ref())
4469 .any(|ty| self.type_has_borrow(resolve, ty)),
4470 TypeDefKind::Handle(Handle::Borrow(_)) => true,
4471 TypeDefKind::Handle(Handle::Own(_)) => false,
4472 TypeDefKind::Resource => false,
4473 TypeDefKind::Record(r) => r
4474 .fields
4475 .iter()
4476 .any(|case| self.type_has_borrow(resolve, &case.ty)),
4477 TypeDefKind::Flags(_) => false,
4478 TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.type_has_borrow(resolve, t)),
4479 TypeDefKind::Enum(_) => false,
4480 TypeDefKind::List(ty)
4481 | TypeDefKind::FixedLengthList(ty, ..)
4482 | TypeDefKind::Future(Some(ty))
4483 | TypeDefKind::Stream(Some(ty))
4484 | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty),
4485 TypeDefKind::Map(k, v) => {
4486 self.type_has_borrow(resolve, k) || self.type_has_borrow(resolve, v)
4487 }
4488 TypeDefKind::Result(r) => [&r.ok, &r.err]
4489 .iter()
4490 .filter_map(|t| t.as_ref())
4491 .any(|t| self.type_has_borrow(resolve, t)),
4492 TypeDefKind::Future(None) | TypeDefKind::Stream(None) => false,
4493 TypeDefKind::Unknown => unreachable!(),
4494 }
4495 }
4496}
4497
4498struct MergeMap<'a> {
4499 package_map: HashMap<PackageId, PackageId>,
4502
4503 interface_map: HashMap<InterfaceId, InterfaceId>,
4506
4507 type_map: HashMap<TypeId, TypeId>,
4510
4511 world_map: HashMap<WorldId, WorldId>,
4514
4515 interfaces_to_add: Vec<(String, PackageId, InterfaceId)>,
4523 worlds_to_add: Vec<(String, PackageId, WorldId)>,
4524
4525 from: &'a Resolve,
4527
4528 into: &'a Resolve,
4530}
4531
4532impl<'a> MergeMap<'a> {
4533 fn new(from: &'a Resolve, into: &'a Resolve) -> MergeMap<'a> {
4534 MergeMap {
4535 package_map: Default::default(),
4536 interface_map: Default::default(),
4537 type_map: Default::default(),
4538 world_map: Default::default(),
4539 interfaces_to_add: Default::default(),
4540 worlds_to_add: Default::default(),
4541 from,
4542 into,
4543 }
4544 }
4545
4546 fn build(&mut self) -> anyhow::Result<()> {
4547 for from_id in self.from.topological_packages() {
4548 let from = &self.from.packages[from_id];
4549 let into_id = match self.into.package_names.get(&from.name) {
4550 Some(id) => *id,
4551
4552 None => {
4555 log::trace!("adding unique package {}", from.name);
4556 continue;
4557 }
4558 };
4559 log::trace!("merging duplicate package {}", from.name);
4560
4561 self.build_package(from_id, into_id).with_context(|| {
4562 format!("failed to merge package `{}` into existing copy", from.name)
4563 })?;
4564 }
4565
4566 Ok(())
4567 }
4568
4569 fn build_package(&mut self, from_id: PackageId, into_id: PackageId) -> anyhow::Result<()> {
4570 let prev = self.package_map.insert(from_id, into_id);
4571 assert!(prev.is_none());
4572
4573 let from = &self.from.packages[from_id];
4574 let into = &self.into.packages[into_id];
4575
4576 for (name, from_interface_id) in from.interfaces.iter() {
4580 let into_interface_id = match into.interfaces.get(name) {
4581 Some(id) => *id,
4582 None => {
4583 log::trace!("adding unique interface {name}");
4584 self.interfaces_to_add
4585 .push((name.clone(), into_id, *from_interface_id));
4586 continue;
4587 }
4588 };
4589
4590 log::trace!("merging duplicate interfaces {name}");
4591 self.build_interface(*from_interface_id, into_interface_id)
4592 .with_context(|| format!("failed to merge interface `{name}`"))?;
4593 }
4594
4595 for (name, from_world_id) in from.worlds.iter() {
4596 let into_world_id = match into.worlds.get(name) {
4597 Some(id) => *id,
4598 None => {
4599 log::trace!("adding unique world {name}");
4600 self.worlds_to_add
4601 .push((name.clone(), into_id, *from_world_id));
4602 continue;
4603 }
4604 };
4605
4606 log::trace!("merging duplicate worlds {name}");
4607 self.build_world(*from_world_id, into_world_id)
4608 .with_context(|| format!("failed to merge world `{name}`"))?;
4609 }
4610
4611 Ok(())
4612 }
4613
4614 fn build_interface(
4615 &mut self,
4616 from_id: InterfaceId,
4617 into_id: InterfaceId,
4618 ) -> anyhow::Result<()> {
4619 let prev = self.interface_map.insert(from_id, into_id);
4620 assert!(prev.is_none());
4621
4622 let from_interface = &self.from.interfaces[from_id];
4623 let into_interface = &self.into.interfaces[into_id];
4624
4625 for (name, from_type_id) in from_interface.types.iter() {
4633 let into_type_id = match into_interface.types.get(name) {
4634 Some(id) => *id,
4635 None => continue,
4638 };
4639 let prev = self.type_map.insert(*from_type_id, into_type_id);
4640 assert!(prev.is_none());
4641
4642 self.build_type_id(*from_type_id, into_type_id)
4643 .with_context(|| format!("mismatch in type `{name}`"))?;
4644 }
4645
4646 for (name, from_func) in from_interface.functions.iter() {
4647 let into_func = match into_interface.functions.get(name) {
4648 Some(func) => func,
4649 None => continue,
4652 };
4653 self.build_function(from_func, into_func)
4654 .with_context(|| format!("mismatch in function `{name}`"))?;
4655 }
4656
4657 Ok(())
4658 }
4659
4660 fn build_type_id(&mut self, from_id: TypeId, into_id: TypeId) -> anyhow::Result<()> {
4661 let _ = from_id;
4665 let _ = into_id;
4666 Ok(())
4667 }
4668
4669 fn build_type(&mut self, from_ty: &Type, into_ty: &Type) -> anyhow::Result<()> {
4670 match (from_ty, into_ty) {
4671 (Type::Id(from), Type::Id(into)) => {
4672 self.build_type_id(*from, *into)?;
4673 }
4674 (from, into) if from != into => bail!("different kinds of types"),
4675 _ => {}
4676 }
4677 Ok(())
4678 }
4679
4680 fn build_function(&mut self, from_func: &Function, into_func: &Function) -> anyhow::Result<()> {
4681 if from_func.name != into_func.name {
4682 bail!(
4683 "different function names `{}` and `{}`",
4684 from_func.name,
4685 into_func.name
4686 );
4687 }
4688 match (&from_func.kind, &into_func.kind) {
4689 (FunctionKind::Freestanding, FunctionKind::Freestanding) => {}
4690 (FunctionKind::AsyncFreestanding, FunctionKind::AsyncFreestanding) => {}
4691 (FunctionKind::Getter, FunctionKind::Getter) => {}
4692 (FunctionKind::Setter, FunctionKind::Setter) => {}
4693
4694 (FunctionKind::Method(from), FunctionKind::Method(into))
4695 | (FunctionKind::Static(from), FunctionKind::Static(into))
4696 | (FunctionKind::AsyncMethod(from), FunctionKind::AsyncMethod(into))
4697 | (FunctionKind::AsyncStatic(from), FunctionKind::AsyncStatic(into))
4698 | (FunctionKind::MethodGetter(from), FunctionKind::MethodGetter(into))
4699 | (FunctionKind::MethodSetter(from), FunctionKind::MethodSetter(into))
4700 | (FunctionKind::StaticGetter(from), FunctionKind::StaticGetter(into))
4701 | (FunctionKind::StaticSetter(from), FunctionKind::StaticSetter(into))
4702 | (FunctionKind::Constructor(from), FunctionKind::Constructor(into)) => {
4703 self.build_type_id(*from, *into)
4704 .context("different function kind types")?;
4705 }
4706
4707 (FunctionKind::Method(_), _)
4708 | (FunctionKind::Constructor(_), _)
4709 | (FunctionKind::Static(_), _)
4710 | (FunctionKind::Freestanding, _)
4711 | (FunctionKind::AsyncFreestanding, _)
4712 | (FunctionKind::AsyncMethod(_), _)
4713 | (FunctionKind::AsyncStatic(_), _)
4714 | (FunctionKind::Getter, _)
4715 | (FunctionKind::Setter, _)
4716 | (FunctionKind::MethodGetter(_), _)
4717 | (FunctionKind::MethodSetter(_), _)
4718 | (FunctionKind::StaticGetter(_), _)
4719 | (FunctionKind::StaticSetter(_), _) => {
4720 bail!("different function kind types")
4721 }
4722 }
4723
4724 if from_func.params.len() != into_func.params.len() {
4725 bail!("different number of function parameters");
4726 }
4727 for (from_param, into_param) in from_func.params.iter().zip(&into_func.params) {
4728 if from_param.name != into_param.name {
4729 bail!(
4730 "different function parameter names: {} != {}",
4731 from_param.name,
4732 into_param.name
4733 );
4734 }
4735 self.build_type(&from_param.ty, &into_param.ty)
4736 .with_context(|| {
4737 format!(
4738 "different function parameter types for `{}`",
4739 from_param.name
4740 )
4741 })?;
4742 }
4743 match (&from_func.result, &into_func.result) {
4744 (Some(from_ty), Some(into_ty)) => {
4745 self.build_type(from_ty, into_ty)
4746 .context("different function result types")?;
4747 }
4748 (None, None) => {}
4749 (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
4750 }
4751 Ok(())
4752 }
4753
4754 fn build_world(&mut self, from_id: WorldId, into_id: WorldId) -> anyhow::Result<()> {
4755 let prev = self.world_map.insert(from_id, into_id);
4756 assert!(prev.is_none());
4757
4758 let from_world = &self.from.worlds[from_id];
4759 let into_world = &self.into.worlds[into_id];
4760
4761 if from_world.imports.len() != into_world.imports.len() {
4770 bail!("world contains different number of imports than expected");
4771 }
4772 if from_world.exports.len() != into_world.exports.len() {
4773 bail!("world contains different number of exports than expected");
4774 }
4775
4776 for (from_name, from) in from_world.imports.iter() {
4777 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4778 let name_str = self.from.name_world_key(from_name);
4779 let into = into_world
4780 .imports
4781 .get(&into_name)
4782 .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?;
4783 self.match_world_item(from, into)
4784 .with_context(|| format!("import `{name_str}` didn't match target world"))?;
4785 }
4786
4787 for (from_name, from) in from_world.exports.iter() {
4788 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4789 let name_str = self.from.name_world_key(from_name);
4790 let into = into_world
4791 .exports
4792 .get(&into_name)
4793 .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?;
4794 self.match_world_item(from, into)
4795 .with_context(|| format!("export `{name_str}` didn't match target world"))?;
4796 }
4797
4798 Ok(())
4799 }
4800
4801 fn map_name(
4802 from_name: &WorldKey,
4803 interface_map: &HashMap<InterfaceId, InterfaceId>,
4804 ) -> WorldKey {
4805 match from_name {
4806 WorldKey::Name(s) => WorldKey::Name(s.clone()),
4807 WorldKey::Interface(id) => {
4808 WorldKey::Interface(interface_map.get(id).copied().unwrap_or(*id))
4809 }
4810 }
4811 }
4812
4813 fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> anyhow::Result<()> {
4814 match (from, into) {
4815 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
4816 match (
4817 &self.from.interfaces[*from].name,
4818 &self.into.interfaces[*into].name,
4819 ) {
4820 (None, None) => self.build_interface(*from, *into)?,
4824
4825 _ => {
4830 if self.interface_map.get(from) != Some(into) {
4831 bail!("interfaces are not the same");
4832 }
4833 }
4834 }
4835 }
4836 (WorldItem::Function(from), WorldItem::Function(into)) => {
4837 let _ = (from, into);
4838 }
4841 (WorldItem::Type { id: from, .. }, WorldItem::Type { id: into, .. }) => {
4842 let prev = self.type_map.insert(*from, *into);
4845 assert!(prev.is_none());
4846 }
4847
4848 (WorldItem::Interface { .. }, _)
4849 | (WorldItem::Function(_), _)
4850 | (WorldItem::Type { .. }, _) => {
4851 bail!("world items do not have the same type")
4852 }
4853 }
4854 Ok(())
4855 }
4856}
4857
4858fn update_stability(from: &Stability, into: &mut Stability, span: Span) -> ResolveResult<()> {
4864 if from == into || from.is_unknown() {
4867 return Ok(());
4868 }
4869 if into.is_unknown() {
4872 *into = from.clone();
4873 return Ok(());
4874 }
4875
4876 Err(ResolveError::from(ResolveErrorKind::StabilityMismatch {
4879 span,
4880 from: from.clone(),
4881 into: into.clone(),
4882 }))
4883}
4884
4885fn merge_include_stability(
4886 from: &Stability,
4887 into: &mut Stability,
4888 is_external_include: bool,
4889 span: Span,
4890) -> ResolveResult<()> {
4891 if is_external_include && from.is_stable() {
4892 log::trace!("dropped stability from external package");
4893 *into = Stability::Unknown;
4894 return Ok(());
4895 }
4896
4897 update_stability(from, into, span)
4898}
4899
4900#[cfg(test)]
4901mod tests {
4902 use crate::alloc::format;
4903 use crate::alloc::string::{String, ToString};
4904 use crate::alloc::vec::Vec;
4905 use crate::{Resolve, SourceMap, WorldItem, WorldKey};
4906 use anyhow::Result;
4907
4908 #[test]
4909 fn select_world() -> Result<()> {
4910 let mut resolve = Resolve::default();
4911 resolve.push_str(
4912 "test.wit",
4913 r#"
4914 package foo:bar@0.1.0;
4915
4916 world foo {}
4917 "#,
4918 )?;
4919 resolve.push_str(
4920 "test.wit",
4921 r#"
4922 package foo:baz@0.1.0;
4923
4924 world foo {}
4925 "#,
4926 )?;
4927 resolve.push_str(
4928 "test.wit",
4929 r#"
4930 package foo:baz@0.2.0;
4931
4932 world foo {}
4933 "#,
4934 )?;
4935
4936 let dummy = resolve.push_str(
4937 "test.wit",
4938 r#"
4939 package foo:dummy;
4940
4941 world foo {}
4942 "#,
4943 )?;
4944
4945 assert!(resolve.select_world(&[dummy], None).is_ok());
4946 assert!(resolve.select_world(&[dummy], Some("xx")).is_err());
4947 assert!(resolve.select_world(&[dummy], Some("")).is_err());
4948 assert!(resolve.select_world(&[dummy], Some("foo:bar/foo")).is_ok());
4949 assert!(
4950 resolve
4951 .select_world(&[dummy], Some("foo:bar/foo@0.1.0"))
4952 .is_ok()
4953 );
4954 assert!(resolve.select_world(&[dummy], Some("foo:baz/foo")).is_err());
4955 assert!(
4956 resolve
4957 .select_world(&[dummy], Some("foo:baz/foo@0.1.0"))
4958 .is_ok()
4959 );
4960 assert!(
4961 resolve
4962 .select_world(&[dummy], Some("foo:baz/foo@0.2.0"))
4963 .is_ok()
4964 );
4965 Ok(())
4966 }
4967
4968 #[test]
4969 fn wasm_import_name_future_and_stream_intrinsics() -> Result<()> {
4970 use crate::{FutureIntrinsic, LiftLowerAbi, ManglingAndAbi, StreamIntrinsic, WasmImport};
4971
4972 let mut resolve = Resolve::default();
4973 let pkg = resolve.push_str(
4974 "test.wit",
4975 r#"
4976 package foo:bar;
4977
4978 interface iface {
4979 iface-func: func(x: future<u32>) -> stream<u32>;
4980 }
4981
4982 world w {
4983 import import-func: func(x: future<future<u32>>, y: u32) -> stream<string>;
4984 export export-func: func(x: future, y: stream);
4985 import iface;
4986 export iface;
4987 }
4988 "#,
4989 )?;
4990 let world = resolve.packages[pkg].worlds["w"];
4991 let world = &resolve.worlds[world];
4992 let mangling = ManglingAndAbi::Legacy(LiftLowerAbi::AsyncStackful);
4993
4994 let WorldItem::Function(import_func) =
4995 &world.imports[&WorldKey::Name("import-func".to_string())]
4996 else {
4997 panic!("expected `import-func` to be a top-level world import");
4998 };
4999 let WorldItem::Function(export_func) =
5000 &world.exports[&WorldKey::Name("export-func".to_string())]
5001 else {
5002 panic!("expected `export-func` to be a top-level world export");
5003 };
5004 let import_types = import_func.find_futures_and_streams(&resolve);
5005 assert_eq!(import_types.len(), 3);
5006
5007 let (interface_key, interface_func) = world
5008 .imports
5009 .iter()
5010 .find_map(|(key, item)| match item {
5011 WorldItem::Interface { id, .. } => Some((
5012 key.clone(),
5013 &resolve.interfaces[*id].functions["iface-func"],
5014 )),
5015 _ => None,
5016 })
5017 .expect("expected interface import");
5018 let interface_types = interface_func.find_futures_and_streams(&resolve);
5019 assert_eq!(interface_types.len(), 2);
5020
5021 let (module, name) = resolve.wasm_import_name(
5022 mangling,
5023 WasmImport::FutureIntrinsic {
5024 interface: None,
5025 func: import_func,
5026 ty: Some(import_types[0]),
5027 intrinsic: FutureIntrinsic::New,
5028 exported: false,
5029 async_: false,
5030 },
5031 );
5032 assert_eq!(module, "$root");
5033 assert_eq!(name, "[future-new-0]import-func");
5034
5035 let (module, name) = resolve.wasm_import_name(
5036 mangling,
5037 WasmImport::FutureIntrinsic {
5038 interface: None,
5039 func: import_func,
5040 ty: Some(import_types[1]),
5041 intrinsic: FutureIntrinsic::Read,
5042 exported: false,
5043 async_: true,
5044 },
5045 );
5046 assert_eq!(module, "$root");
5047 assert_eq!(name, "[async-lower][future-read-1]import-func");
5048
5049 let (module, name) = resolve.wasm_import_name(
5050 mangling,
5051 WasmImport::FutureIntrinsic {
5052 interface: None,
5053 func: import_func,
5054 ty: Some(import_types[1]),
5055 intrinsic: FutureIntrinsic::Forward,
5056 exported: false,
5057 async_: false,
5058 },
5059 );
5060 assert_eq!(module, "$root");
5061 assert_eq!(name, "[future-forward-1]import-func");
5062
5063 let (module, name) = resolve.wasm_import_name(
5064 mangling,
5065 WasmImport::StreamIntrinsic {
5066 interface: None,
5067 func: import_func,
5068 ty: Some(import_types[2]),
5069 intrinsic: StreamIntrinsic::Forward,
5070 exported: false,
5071 async_: false,
5072 },
5073 );
5074 assert_eq!(module, "$root");
5075 assert_eq!(name, "[stream-forward-2]import-func");
5076
5077 let (module, name) = resolve.wasm_import_name(
5078 mangling,
5079 WasmImport::StreamIntrinsic {
5080 interface: None,
5081 func: import_func,
5082 ty: Some(import_types[2]),
5083 intrinsic: StreamIntrinsic::CancelRead,
5084 exported: false,
5085 async_: true,
5086 },
5087 );
5088 assert_eq!(module, "$root");
5089 assert_eq!(name, "[async-lower][stream-cancel-read-2]import-func");
5090
5091 let (module, name) = resolve.wasm_import_name(
5092 mangling,
5093 WasmImport::FutureIntrinsic {
5094 interface: None,
5095 func: export_func,
5096 ty: None,
5097 intrinsic: FutureIntrinsic::DropReadable,
5098 exported: true,
5099 async_: false,
5100 },
5101 );
5102 assert_eq!(module, "[export]$root");
5103 assert_eq!(name, "[future-drop-readable-unit]export-func");
5104
5105 let (module, name) = resolve.wasm_import_name(
5106 mangling,
5107 WasmImport::StreamIntrinsic {
5108 interface: None,
5109 func: export_func,
5110 ty: None,
5111 intrinsic: StreamIntrinsic::Write,
5112 exported: true,
5113 async_: true,
5114 },
5115 );
5116 assert_eq!(module, "[export]$root");
5117 assert_eq!(name, "[async-lower][stream-write-unit]export-func");
5118
5119 let (module, name) = resolve.wasm_import_name(
5120 mangling,
5121 WasmImport::StreamIntrinsic {
5122 interface: Some(&interface_key),
5123 func: interface_func,
5124 ty: Some(interface_types[1]),
5125 intrinsic: StreamIntrinsic::Read,
5126 exported: true,
5127 async_: false,
5128 },
5129 );
5130 assert_eq!(
5131 module,
5132 format!("[export]{}", resolve.name_world_key(&interface_key))
5133 );
5134 assert_eq!(name, "[stream-read-1]iface-func");
5135
5136 Ok(())
5137 }
5138
5139 #[test]
5142 fn select_world_multiple_packages() -> Result<()> {
5143 use wit_parser::Resolve;
5144
5145 let mut resolve = Resolve::default();
5146
5147 let stuff = resolve.push_str(
5149 "./my-test.wit",
5150 r#"
5151 package test:stuff;
5152
5153 world foo {
5154 // ...
5155 }
5156 "#,
5157 )?;
5158 assert!(resolve.select_world(&[stuff], None).is_ok());
5159 assert!(resolve.select_world(&[stuff], Some("foo")).is_ok());
5160
5161 let empty = resolve.push_str(
5164 "./my-test.wit",
5165 r#"
5166 package test:empty;
5167 "#,
5168 )?;
5169 assert!(resolve.select_world(&[stuff, empty], None).is_err());
5170 assert!(resolve.select_world(&[stuff, empty], Some("foo")).is_err());
5171 assert!(resolve.select_world(&[empty], None).is_err());
5172 assert!(resolve.select_world(&[empty], Some("foo")).is_err());
5173
5174 Ok(())
5175 }
5176
5177 #[test]
5179 fn select_world_versions() -> Result<()> {
5180 use wit_parser::Resolve;
5181
5182 let mut resolve = Resolve::default();
5183
5184 let _id = resolve.push_str(
5185 "./my-test.wit",
5186 r#"
5187 package example:distraction;
5188 "#,
5189 )?;
5190
5191 let versions_1 = resolve.push_str(
5194 "./my-test.wit",
5195 r#"
5196 package example:versions@1.0.0;
5197
5198 world foo { /* ... */ }
5199 "#,
5200 )?;
5201 assert!(resolve.select_world(&[versions_1], Some("foo")).is_ok());
5202 assert!(
5203 resolve
5204 .select_world(&[versions_1], Some("foo@1.0.0"))
5205 .is_err()
5206 );
5207 assert!(
5208 resolve
5209 .select_world(&[versions_1], Some("example:versions/foo"))
5210 .is_ok()
5211 );
5212 assert!(
5213 resolve
5214 .select_world(&[versions_1], Some("example:versions/foo@1.0.0"))
5215 .is_ok()
5216 );
5217
5218 let versions_2 = resolve.push_str(
5221 "./my-test.wit",
5222 r#"
5223 package example:versions@2.0.0;
5224
5225 world foo { /* ... */ }
5226 "#,
5227 )?;
5228 assert!(
5229 resolve
5230 .select_world(&[versions_1, versions_2], Some("foo"))
5231 .is_err()
5232 );
5233 assert!(
5234 resolve
5235 .select_world(&[versions_1, versions_2], Some("foo@1.0.0"))
5236 .is_err()
5237 );
5238 assert!(
5239 resolve
5240 .select_world(&[versions_1, versions_2], Some("foo@2.0.0"))
5241 .is_err()
5242 );
5243 assert!(
5244 resolve
5245 .select_world(&[versions_1, versions_2], Some("example:versions/foo"))
5246 .is_err()
5247 );
5248 assert!(
5249 resolve
5250 .select_world(
5251 &[versions_1, versions_2],
5252 Some("example:versions/foo@1.0.0")
5253 )
5254 .is_ok()
5255 );
5256 assert!(
5257 resolve
5258 .select_world(
5259 &[versions_1, versions_2],
5260 Some("example:versions/foo@2.0.0")
5261 )
5262 .is_ok()
5263 );
5264
5265 Ok(())
5266 }
5267
5268 #[test]
5270 fn select_world_override_qualification() -> Result<()> {
5271 use wit_parser::Resolve;
5272
5273 let mut resolve = Resolve::default();
5274
5275 let other = resolve.push_str(
5276 "./my-test.wit",
5277 r#"
5278 package example:other;
5279
5280 world foo { }
5281 "#,
5282 )?;
5283
5284 let fq = resolve.push_str(
5286 "./my-test.wit",
5287 r#"
5288 package example:fq;
5289
5290 world bar { }
5291 "#,
5292 )?;
5293 assert!(resolve.select_world(&[other, fq], Some("foo")).is_err());
5294 assert!(resolve.select_world(&[other, fq], Some("bar")).is_err());
5295 assert!(
5296 resolve
5297 .select_world(&[other, fq], Some("example:other/foo"))
5298 .is_ok()
5299 );
5300 assert!(
5301 resolve
5302 .select_world(&[other, fq], Some("example:fq/bar"))
5303 .is_ok()
5304 );
5305 assert!(
5306 resolve
5307 .select_world(&[other, fq], Some("example:other/bar"))
5308 .is_err()
5309 );
5310 assert!(
5311 resolve
5312 .select_world(&[other, fq], Some("example:fq/foo"))
5313 .is_err()
5314 );
5315
5316 Ok(())
5317 }
5318
5319 #[test]
5321 fn select_world_fully_qualified() -> Result<()> {
5322 use wit_parser::Resolve;
5323
5324 let mut resolve = Resolve::default();
5325
5326 let distraction = resolve.push_str(
5327 "./my-test.wit",
5328 r#"
5329 package example:distraction;
5330 "#,
5331 )?;
5332
5333 let multiworld = resolve.push_str(
5336 "./my-test.wit",
5337 r#"
5338 package example:multiworld;
5339
5340 world foo { /* ... */ }
5341
5342 world bar { /* ... */ }
5343 "#,
5344 )?;
5345 assert!(
5346 resolve
5347 .select_world(&[distraction, multiworld], None)
5348 .is_err()
5349 );
5350 assert!(
5351 resolve
5352 .select_world(&[distraction, multiworld], Some("foo"))
5353 .is_err()
5354 );
5355 assert!(
5356 resolve
5357 .select_world(&[distraction, multiworld], Some("example:multiworld/foo"))
5358 .is_ok()
5359 );
5360 assert!(
5361 resolve
5362 .select_world(&[distraction, multiworld], Some("bar"))
5363 .is_err()
5364 );
5365 assert!(
5366 resolve
5367 .select_world(&[distraction, multiworld], Some("example:multiworld/bar"))
5368 .is_ok()
5369 );
5370
5371 Ok(())
5372 }
5373
5374 #[test]
5376 fn select_world_packages() -> Result<()> {
5377 use wit_parser::Resolve;
5378
5379 let mut resolve = Resolve::default();
5380
5381 let wit1 = resolve.push_str(
5384 "./my-test.wit",
5385 r#"
5386 package example:wit1;
5387
5388 world foo {
5389 // ...
5390 }
5391 "#,
5392 )?;
5393 assert!(resolve.select_world(&[wit1], None).is_ok());
5394 assert!(resolve.select_world(&[wit1], Some("foo")).is_ok());
5395 assert!(
5396 resolve
5397 .select_world(&[wit1], Some("example:wit1/foo"))
5398 .is_ok()
5399 );
5400 assert!(resolve.select_world(&[wit1], Some("bar")).is_err());
5401 assert!(
5402 resolve
5403 .select_world(&[wit1], Some("example:wit2/foo"))
5404 .is_err()
5405 );
5406
5407 let wit2 = resolve.push_str(
5410 "./my-test.wit",
5411 r#"
5412 package example:wit2;
5413
5414 world foo { /* ... */ }
5415 "#,
5416 )?;
5417 assert!(resolve.select_world(&[wit1, wit2], None).is_err());
5418 assert!(resolve.select_world(&[wit1, wit2], Some("foo")).is_err());
5419 assert!(
5420 resolve
5421 .select_world(&[wit1, wit2], Some("example:wit1/foo"))
5422 .is_ok()
5423 );
5424 assert!(resolve.select_world(&[wit2], None).is_ok());
5425 assert!(resolve.select_world(&[wit2], Some("foo")).is_ok());
5426 assert!(
5427 resolve
5428 .select_world(&[wit2], Some("example:wit1/foo"))
5429 .is_ok()
5430 );
5431 assert!(resolve.select_world(&[wit1, wit2], Some("bar")).is_err());
5432 assert!(
5433 resolve
5434 .select_world(&[wit1, wit2], Some("example:wit2/foo"))
5435 .is_ok()
5436 );
5437 assert!(resolve.select_world(&[wit2], Some("bar")).is_err());
5438 assert!(
5439 resolve
5440 .select_world(&[wit2], Some("example:wit2/foo"))
5441 .is_ok()
5442 );
5443
5444 Ok(())
5445 }
5446
5447 #[test]
5448 fn span_preservation() -> Result<()> {
5449 let mut resolve = Resolve::default();
5450 let pkg = resolve.push_str(
5451 "test.wit",
5452 r#"
5453 package foo:bar;
5454
5455 interface my-iface {
5456 type my-type = u32;
5457 my-func: func();
5458 }
5459
5460 world my-world {
5461 export my-export: func();
5462 }
5463 "#,
5464 )?;
5465
5466 let iface_id = resolve.packages[pkg].interfaces["my-iface"];
5467 assert!(resolve.interfaces[iface_id].span.is_known());
5468
5469 let type_id = resolve.interfaces[iface_id].types["my-type"];
5470 assert!(resolve.types[type_id].span.is_known());
5471
5472 assert!(
5473 resolve.interfaces[iface_id].functions["my-func"]
5474 .span
5475 .is_known()
5476 );
5477
5478 let world_id = resolve.packages[pkg].worlds["my-world"];
5479 assert!(resolve.worlds[world_id].span.is_known());
5480
5481 let WorldItem::Function(f) =
5482 &resolve.worlds[world_id].exports[&WorldKey::Name("my-export".to_string())]
5483 else {
5484 panic!("expected function");
5485 };
5486 assert!(f.span.is_known());
5487
5488 Ok(())
5489 }
5490
5491 #[test]
5492 fn span_preservation_through_merge() -> Result<()> {
5493 let mut resolve1 = Resolve::default();
5494 resolve1.push_str(
5495 "test1.wit",
5496 r#"
5497 package foo:bar;
5498
5499 interface iface1 {
5500 type type1 = u32;
5501 func1: func();
5502 }
5503 "#,
5504 )?;
5505
5506 let mut resolve2 = Resolve::default();
5507 let pkg2 = resolve2.push_str(
5508 "test2.wit",
5509 r#"
5510 package foo:baz;
5511
5512 interface iface2 {
5513 type type2 = string;
5514 func2: func();
5515 }
5516 "#,
5517 )?;
5518
5519 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5520 let remap = resolve1.merge(resolve2)?;
5521 let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
5522
5523 assert!(resolve1.interfaces[iface2_id].span.is_known());
5524
5525 let type2_id = resolve1.interfaces[iface2_id].types["type2"];
5526 assert!(resolve1.types[type2_id].span.is_known());
5527
5528 assert!(
5529 resolve1.interfaces[iface2_id].functions["func2"]
5530 .span
5531 .is_known()
5532 );
5533
5534 Ok(())
5535 }
5536
5537 #[test]
5538 fn span_preservation_through_include() -> Result<()> {
5539 let mut resolve = Resolve::default();
5540 let pkg = resolve.push_str(
5541 "test.wit",
5542 r#"
5543 package foo:bar;
5544
5545 world base {
5546 export my-func: func();
5547 }
5548
5549 world extended {
5550 include base;
5551 }
5552 "#,
5553 )?;
5554
5555 let base_id = resolve.packages[pkg].worlds["base"];
5556 let extended_id = resolve.packages[pkg].worlds["extended"];
5557
5558 let WorldItem::Function(base_func) =
5559 &resolve.worlds[base_id].exports[&WorldKey::Name("my-func".to_string())]
5560 else {
5561 panic!("expected function");
5562 };
5563 assert!(base_func.span.is_known());
5564
5565 let WorldItem::Function(extended_func) =
5566 &resolve.worlds[extended_id].exports[&WorldKey::Name("my-func".to_string())]
5567 else {
5568 panic!("expected function");
5569 };
5570 assert!(extended_func.span.is_known());
5571
5572 Ok(())
5573 }
5574
5575 #[test]
5576 fn span_preservation_through_include_with_rename() -> Result<()> {
5577 let mut resolve = Resolve::default();
5578 let pkg = resolve.push_str(
5579 "test.wit",
5580 r#"
5581 package foo:bar;
5582
5583 world base {
5584 export original-name: func();
5585 }
5586
5587 world extended {
5588 include base with { original-name as renamed-func }
5589 }
5590 "#,
5591 )?;
5592
5593 let extended_id = resolve.packages[pkg].worlds["extended"];
5594
5595 let WorldItem::Function(f) =
5596 &resolve.worlds[extended_id].exports[&WorldKey::Name("renamed-func".to_string())]
5597 else {
5598 panic!("expected function");
5599 };
5600 assert!(f.span.is_known());
5601
5602 assert!(
5603 !resolve.worlds[extended_id]
5604 .exports
5605 .contains_key(&WorldKey::Name("original-name".to_string()))
5606 );
5607
5608 Ok(())
5609 }
5610
5611 #[test]
5613 fn span_preservation_through_include_reverse_order() -> Result<()> {
5614 let mut resolve = Resolve::default();
5615 let pkg = resolve.push_str(
5616 "test.wit",
5617 r#"
5618 package foo:bar;
5619
5620 world extended {
5621 include base;
5622 }
5623
5624 world base {
5625 export my-func: func();
5626 }
5627 "#,
5628 )?;
5629
5630 let base_id = resolve.packages[pkg].worlds["base"];
5631 let extended_id = resolve.packages[pkg].worlds["extended"];
5632
5633 let WorldItem::Function(base_func) =
5634 &resolve.worlds[base_id].exports[&WorldKey::Name("my-func".to_string())]
5635 else {
5636 panic!("expected function");
5637 };
5638 assert!(base_func.span.is_known());
5639
5640 let WorldItem::Function(extended_func) =
5641 &resolve.worlds[extended_id].exports[&WorldKey::Name("my-func".to_string())]
5642 else {
5643 panic!("expected function");
5644 };
5645 assert!(extended_func.span.is_known());
5646
5647 Ok(())
5648 }
5649
5650 #[test]
5651 fn span_line_numbers() -> Result<()> {
5652 let mut resolve = Resolve::default();
5653 let pkg = resolve.push_source(
5654 "test.wit",
5655 "package foo:bar;
5656
5657interface my-iface {
5658 type my-type = u32;
5659 my-func: func();
5660}
5661
5662world my-world {
5663 export my-export: func();
5664}
5665",
5666 )?;
5667
5668 let iface_id = resolve.packages[pkg].interfaces["my-iface"];
5669 let iface_span = resolve.interfaces[iface_id].span;
5670 let iface_loc = resolve.render_location(iface_span);
5671 assert!(
5672 iface_loc.contains(":3:"),
5673 "interface location was {iface_loc}"
5674 );
5675
5676 let type_id = resolve.interfaces[iface_id].types["my-type"];
5677 let type_span = resolve.types[type_id].span;
5678 let type_loc = resolve.render_location(type_span);
5679 assert!(type_loc.contains(":4:"), "type location was {type_loc}");
5680
5681 let func_span = resolve.interfaces[iface_id].functions["my-func"].span;
5682 let func_loc = resolve.render_location(func_span);
5683 assert!(func_loc.contains(":5:"), "function location was {func_loc}");
5684
5685 let world_id = resolve.packages[pkg].worlds["my-world"];
5686 let world_span = resolve.worlds[world_id].span;
5687 let world_loc = resolve.render_location(world_span);
5688 assert!(world_loc.contains(":8:"), "world location was {world_loc}");
5689
5690 let WorldItem::Function(export_func) =
5691 &resolve.worlds[world_id].exports[&WorldKey::Name("my-export".to_string())]
5692 else {
5693 panic!("expected function");
5694 };
5695 let export_loc = resolve.render_location(export_func.span);
5696 assert!(
5697 export_loc.contains(":9:"),
5698 "export location was {export_loc}"
5699 );
5700
5701 Ok(())
5702 }
5703
5704 #[test]
5705 fn span_line_numbers_through_merge() -> Result<()> {
5706 let mut resolve1 = Resolve::default();
5707 resolve1.push_source(
5708 "first.wit",
5709 "package foo:first;
5710
5711interface iface1 {
5712 func1: func();
5713}
5714",
5715 )?;
5716
5717 let mut resolve2 = Resolve::default();
5718 let pkg2 = resolve2.push_source(
5719 "second.wit",
5720 "package foo:second;
5721
5722interface iface2 {
5723 func2: func();
5724}
5725",
5726 )?;
5727
5728 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5729 let remap = resolve1.merge(resolve2)?;
5730 let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
5731
5732 let iface2_span = resolve1.interfaces[iface2_id].span;
5733 let iface2_loc = resolve1.render_location(iface2_span);
5734 assert!(
5735 iface2_loc.contains("second.wit"),
5736 "should reference second.wit, got {iface2_loc}"
5737 );
5738 assert!(
5739 iface2_loc.contains(":3:"),
5740 "interface should be on line 3, got {iface2_loc}"
5741 );
5742
5743 let func2_span = resolve1.interfaces[iface2_id].functions["func2"].span;
5744 let func2_loc = resolve1.render_location(func2_span);
5745 assert!(
5746 func2_loc.contains("second.wit"),
5747 "should reference second.wit, got {func2_loc}"
5748 );
5749 assert!(
5750 func2_loc.contains(":4:"),
5751 "function should be on line 4, got {func2_loc}"
5752 );
5753
5754 Ok(())
5755 }
5756
5757 #[test]
5758 fn span_line_numbers_multiple_sources() -> Result<()> {
5759 let mut resolve = Resolve::default();
5760
5761 let pkg1 = resolve.push_source(
5762 "first.wit",
5763 "package test:first;
5764
5765interface first-iface {
5766 first-func: func();
5767}
5768",
5769 )?;
5770
5771 let pkg2 = resolve.push_source(
5772 "second.wit",
5773 "package test:second;
5774
5775interface second-iface {
5776 second-func: func();
5777}
5778",
5779 )?;
5780
5781 let iface1_id = resolve.packages[pkg1].interfaces["first-iface"];
5782 let iface1_span = resolve.interfaces[iface1_id].span;
5783 let iface1_loc = resolve.render_location(iface1_span);
5784 assert!(
5785 iface1_loc.contains("first.wit"),
5786 "should reference first.wit, got {iface1_loc}"
5787 );
5788 assert!(
5789 iface1_loc.contains(":3:"),
5790 "interface should be on line 3, got {iface1_loc}"
5791 );
5792
5793 let func1_span = resolve.interfaces[iface1_id].functions["first-func"].span;
5794 let func1_loc = resolve.render_location(func1_span);
5795 assert!(
5796 func1_loc.contains("first.wit"),
5797 "should reference first.wit, got {func1_loc}"
5798 );
5799 assert!(
5800 func1_loc.contains(":4:"),
5801 "function should be on line 4, got {func1_loc}"
5802 );
5803
5804 let iface2_id = resolve.packages[pkg2].interfaces["second-iface"];
5805 let iface2_span = resolve.interfaces[iface2_id].span;
5806 let iface2_loc = resolve.render_location(iface2_span);
5807 assert!(
5808 iface2_loc.contains("second.wit"),
5809 "should reference second.wit, got {iface2_loc}"
5810 );
5811 assert!(
5812 iface2_loc.contains(":3:"),
5813 "interface should be on line 3, got {iface2_loc}"
5814 );
5815
5816 let func2_span = resolve.interfaces[iface2_id].functions["second-func"].span;
5817 let func2_loc = resolve.render_location(func2_span);
5818 assert!(
5819 func2_loc.contains("second.wit"),
5820 "should reference second.wit, got {func2_loc}"
5821 );
5822 assert!(
5823 func2_loc.contains(":4:"),
5824 "function should be on line 4, got {func2_loc}"
5825 );
5826
5827 Ok(())
5828 }
5829
5830 #[test]
5831 fn span_preservation_for_fields_and_cases() -> Result<()> {
5832 use crate::TypeDefKind;
5833
5834 let mut resolve = Resolve::default();
5835 let pkg = resolve.push_str(
5836 "test.wit",
5837 r#"
5838 package foo:bar;
5839
5840 interface my-iface {
5841 record my-record {
5842 field1: u32,
5843 field2: string,
5844 }
5845
5846 flags my-flags {
5847 flag1,
5848 flag2,
5849 }
5850
5851 variant my-variant {
5852 case1,
5853 case2(u32),
5854 }
5855
5856 enum my-enum {
5857 val1,
5858 val2,
5859 }
5860 }
5861 "#,
5862 )?;
5863
5864 let iface_id = resolve.packages[pkg].interfaces["my-iface"];
5865
5866 let record_id = resolve.interfaces[iface_id].types["my-record"];
5868 let TypeDefKind::Record(record) = &resolve.types[record_id].kind else {
5869 panic!("expected record");
5870 };
5871 assert!(record.fields[0].span.is_known(), "field1 should have span");
5872 assert!(record.fields[1].span.is_known(), "field2 should have span");
5873
5874 let flags_id = resolve.interfaces[iface_id].types["my-flags"];
5876 let TypeDefKind::Flags(flags) = &resolve.types[flags_id].kind else {
5877 panic!("expected flags");
5878 };
5879 assert!(flags.flags[0].span.is_known(), "flag1 should have span");
5880 assert!(flags.flags[1].span.is_known(), "flag2 should have span");
5881
5882 let variant_id = resolve.interfaces[iface_id].types["my-variant"];
5884 let TypeDefKind::Variant(variant) = &resolve.types[variant_id].kind else {
5885 panic!("expected variant");
5886 };
5887 assert!(variant.cases[0].span.is_known(), "case1 should have span");
5888 assert!(variant.cases[1].span.is_known(), "case2 should have span");
5889
5890 let enum_id = resolve.interfaces[iface_id].types["my-enum"];
5892 let TypeDefKind::Enum(e) = &resolve.types[enum_id].kind else {
5893 panic!("expected enum");
5894 };
5895 assert!(e.cases[0].span.is_known(), "val1 should have span");
5896 assert!(e.cases[1].span.is_known(), "val2 should have span");
5897
5898 Ok(())
5899 }
5900
5901 #[test]
5902 fn span_preservation_for_fields_through_merge() -> Result<()> {
5903 use crate::TypeDefKind;
5904
5905 let mut resolve1 = Resolve::default();
5906 resolve1.push_str(
5907 "test1.wit",
5908 r#"
5909 package foo:bar;
5910
5911 interface iface1 {
5912 record rec1 {
5913 f1: u32,
5914 }
5915 }
5916 "#,
5917 )?;
5918
5919 let mut resolve2 = Resolve::default();
5920 let pkg2 = resolve2.push_str(
5921 "test2.wit",
5922 r#"
5923 package foo:baz;
5924
5925 interface iface2 {
5926 record rec2 {
5927 f2: string,
5928 }
5929
5930 variant var2 {
5931 c2,
5932 }
5933 }
5934 "#,
5935 )?;
5936
5937 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5938 let rec2_old_id = resolve2.interfaces[iface2_old_id].types["rec2"];
5939 let var2_old_id = resolve2.interfaces[iface2_old_id].types["var2"];
5940
5941 let remap = resolve1.merge(resolve2)?;
5942
5943 let rec2_id = remap.types[rec2_old_id.index()].unwrap();
5944 let TypeDefKind::Record(record) = &resolve1.types[rec2_id].kind else {
5945 panic!("expected record");
5946 };
5947 assert!(
5948 record.fields[0].span.is_known(),
5949 "field should have span after merge"
5950 );
5951
5952 let var2_id = remap.types[var2_old_id.index()].unwrap();
5953 let TypeDefKind::Variant(variant) = &resolve1.types[var2_id].kind else {
5954 panic!("expected variant");
5955 };
5956 assert!(
5957 variant.cases[0].span.is_known(),
5958 "case should have span after merge"
5959 );
5960
5961 Ok(())
5962 }
5963
5964 #[test]
5965 fn param_spans_point_to_names() -> Result<()> {
5966 let source = "\
5967package foo:bar;
5968
5969interface iface {
5970 my-func: func(a: u32, b: string);
5971}
5972";
5973 let mut resolve = Resolve::default();
5974 let pkg = resolve.push_str("test.wit", source)?;
5975
5976 let iface_id = resolve.packages[pkg].interfaces["iface"];
5977 let func = &resolve.interfaces[iface_id].functions["my-func"];
5978 assert_eq!(func.params.len(), 2);
5979 for param in &func.params {
5980 let start = param.span.start() as usize;
5981 let end = param.span.end() as usize;
5982 let snippet = &source[start..end];
5983 assert_eq!(
5984 snippet, param.name,
5985 "param `{}` span points to {:?}",
5986 param.name, snippet
5987 );
5988 }
5989
5990 Ok(())
5991 }
5992
5993 #[test]
5994 fn push_groups_resolves_dep_before_main() -> Result<()> {
5995 let dep = {
5998 let mut map = SourceMap::default();
5999 map.push_str(
6000 "file:///dep.wit",
6001 "package foo:dep;\ninterface i { type t = u32; }",
6002 );
6003 map.parse().map_err(|(_, e)| e)?
6004 };
6005 let main = {
6006 let mut map = SourceMap::default();
6007 map.push_str(
6008 "file:///main.wit",
6009 "package foo:main;\ninterface j { use foo:dep/i.{t}; type u = t; }",
6010 );
6011 map.parse().map_err(|(_, e)| e)?
6012 };
6013 let mut resolve = Resolve::default();
6014 resolve.push_groups(main, Vec::from([dep]))?;
6015 assert_eq!(resolve.packages.len(), 2);
6016 Ok(())
6017 }
6018
6019 #[test]
6020 fn push_groups_cycle_error_contains_location() {
6021 let a = {
6025 let mut map = SourceMap::default();
6026 map.push_str(
6027 "file:///a.wit",
6028 "package foo:a;\ninterface i { use foo:b/j.{}; }",
6029 );
6030 map.parse().unwrap()
6031 };
6032 let b = {
6033 let mut map = SourceMap::default();
6034 map.push_str(
6035 "file:///b.wit",
6036 "package foo:b;\ninterface j { use foo:a/i.{}; }",
6037 );
6038 map.parse().unwrap()
6039 };
6040 let mut resolve = Resolve::default();
6041 let err = resolve.push_groups(a, Vec::from([b])).unwrap_err();
6042 let msg = err.render(&resolve.source_map);
6043 assert!(
6044 msg.contains("file:///"),
6045 "cycle error should contain a file URI, got: {msg}"
6046 );
6047 }
6048
6049 #[test]
6050 fn param_spans_preserved_through_merge() -> Result<()> {
6051 let mut resolve1 = Resolve::default();
6052 resolve1.push_str(
6053 "test1.wit",
6054 r#"
6055 package foo:bar;
6056
6057 interface iface1 {
6058 f1: func(x: u32);
6059 }
6060 "#,
6061 )?;
6062
6063 let mut resolve2 = Resolve::default();
6064 let pkg2 = resolve2.push_str(
6065 "test2.wit",
6066 r#"
6067 package foo:baz;
6068
6069 interface iface2 {
6070 f2: func(y: string, z: bool);
6071 }
6072 "#,
6073 )?;
6074
6075 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
6076
6077 let remap = resolve1.merge(resolve2)?;
6078
6079 let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
6080 let func = &resolve1.interfaces[iface2_id].functions["f2"];
6081 for param in &func.params {
6082 assert!(
6083 param.span.is_known(),
6084 "param `{}` should have span after merge",
6085 param.name
6086 );
6087 }
6088
6089 Ok(())
6090 }
6091
6092 #[test]
6097 fn exportize_importize_roundtrip() -> Result<()> {
6098 let mut resolve = Resolve::default();
6099 let pkg = resolve.push_str(
6100 "test.wit",
6101 r#"
6102 package foo:bar;
6103
6104 interface types {
6105 type my-type = u32;
6106 }
6107
6108 interface api {
6109 use types.{my-type};
6110 do-something: func(a: my-type) -> my-type;
6111 }
6112
6113 world w {
6114 export api;
6115 }
6116 "#,
6117 )?;
6118 let world_id = resolve.packages[pkg].worlds["w"];
6119
6120 let original_export_keys: Vec<String> = resolve.worlds[world_id]
6122 .exports
6123 .keys()
6124 .map(|k| resolve.name_world_key(k))
6125 .collect();
6126 assert!(!original_export_keys.is_empty());
6127 assert!(resolve.worlds[world_id].imports.iter().all(|(_, item)| {
6128 matches!(item, WorldItem::Interface { .. })
6131 }));
6132
6133 resolve.importize(world_id, Some("w-temp".to_string()))?;
6135 assert!(
6136 resolve.worlds[world_id].exports.is_empty(),
6137 "importize should leave no exports"
6138 );
6139 for key in &original_export_keys {
6141 assert!(
6142 resolve.worlds[world_id]
6143 .imports
6144 .keys()
6145 .any(|k| resolve.name_world_key(k) == *key),
6146 "expected `{key}` to be an import after importize"
6147 );
6148 }
6149
6150 resolve.exportize(world_id, Some("w-final".to_string()), None)?;
6152 assert!(
6153 !resolve.worlds[world_id].exports.is_empty(),
6154 "exportize should produce exports"
6155 );
6156 let final_export_keys: Vec<String> = resolve.worlds[world_id]
6158 .exports
6159 .keys()
6160 .map(|k| resolve.name_world_key(k))
6161 .collect();
6162 for key in &original_export_keys {
6163 assert!(
6164 final_export_keys.contains(key),
6165 "expected `{key}` to be an export after round-trip, got exports: {final_export_keys:?}"
6166 );
6167 }
6168
6169 Ok(())
6170 }
6171
6172 #[test]
6173 fn include_with_renames_resource_accessors() -> Result<()> {
6174 let mut resolve = Resolve::default();
6175 let pkg = resolve.push_str(
6176 "test.wit",
6177 r#"
6178 package foo:foo;
6179
6180 world base {
6181 resource r {
6182 p: get() -> u32;
6183 p: set(v: u32);
6184 s: static get() -> u32;
6185 s: static set(v: u32);
6186 m: func();
6187 }
6188 }
6189
6190 world derived {
6191 include base with { r as r2 }
6192 }
6193 "#,
6194 )?;
6195
6196 let world_id = resolve.packages[pkg].worlds["derived"];
6197 let mut imports: Vec<String> = resolve.worlds[world_id]
6198 .imports
6199 .keys()
6200 .map(|k| resolve.name_world_key(k))
6201 .collect();
6202 imports.sort();
6203
6204 let mut expected: Vec<String> = [
6205 "r2",
6206 "[method][get]r2.p",
6207 "[method][set]r2.p",
6208 "[static][get]r2.s",
6209 "[static][set]r2.s",
6210 "[method]r2.m",
6211 ]
6212 .iter()
6213 .map(|s| s.to_string())
6214 .collect();
6215 expected.sort();
6216
6217 assert_eq!(imports, expected);
6218 Ok(())
6219 }
6220}