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 = map
423 .parse()
424 .map_err(|(map, e)| anyhow::anyhow!("{}", e.highlight(&map)))?;
425 Ok(self.push_group(group)?)
426 }
427
428 pub fn render_location(&self, span: Span) -> String {
430 self.source_map.render_location(span)
431 }
432
433 pub fn all_bits_valid(&self, ty: &Type) -> bool {
434 match ty {
435 Type::U8
436 | Type::S8
437 | Type::U16
438 | Type::S16
439 | Type::U32
440 | Type::S32
441 | Type::U64
442 | Type::S64
443 | Type::F32
444 | Type::F64 => true,
445
446 Type::Bool | Type::Char | Type::String | Type::ErrorContext => false,
447
448 Type::Id(id) => match &self.types[*id].kind {
449 TypeDefKind::List(_)
450 | TypeDefKind::Map(_, _)
451 | TypeDefKind::Variant(_)
452 | TypeDefKind::Enum(_)
453 | TypeDefKind::Option(_)
454 | TypeDefKind::Result(_)
455 | TypeDefKind::Future(_)
456 | TypeDefKind::Stream(_) => false,
457 TypeDefKind::Type(t) | TypeDefKind::FixedLengthList(t, ..) => {
458 self.all_bits_valid(t)
459 }
460
461 TypeDefKind::Handle(h) => match h {
462 crate::Handle::Own(_) => true,
463 crate::Handle::Borrow(_) => true,
464 },
465
466 TypeDefKind::Resource => false,
467 TypeDefKind::Record(r) => r.fields.iter().all(|f| self.all_bits_valid(&f.ty)),
468 TypeDefKind::Tuple(t) => t.types.iter().all(|t| self.all_bits_valid(t)),
469
470 TypeDefKind::Flags(_) => false,
474
475 TypeDefKind::Unknown => unreachable!(),
476 },
477 }
478 }
479
480 pub fn merge(&mut self, resolve: Resolve) -> anyhow::Result<Remap> {
492 log::trace!(
493 "merging {} packages into {} packages",
494 resolve.packages.len(),
495 self.packages.len()
496 );
497
498 let mut map = MergeMap::new(&resolve, &self);
499 map.build()?;
500 let MergeMap {
501 package_map,
502 interface_map,
503 type_map,
504 world_map,
505 interfaces_to_add,
506 worlds_to_add,
507 ..
508 } = map;
509
510 let mut remap = Remap::default();
529 let Resolve {
530 types,
531 worlds,
532 interfaces,
533 packages,
534 package_names,
535 features: _,
536 source_map,
537 ..
538 } = resolve;
539
540 let span_offset = self.source_map.append(source_map);
541
542 let mut moved_types = Vec::new();
543 for (id, mut ty) in types {
544 let new_id = match type_map.get(&id).copied() {
545 Some(id) => {
546 update_stability(&ty.stability, &mut self.types[id].stability, ty.span)?;
547 id
548 }
549 None => {
550 log::debug!("moving type {:?}", ty.name);
551 moved_types.push(id);
552 remap.update_typedef(self, &mut ty, Default::default())?;
553 ty.adjust_spans(span_offset);
554 self.types.alloc(ty)
555 }
556 };
557 assert_eq!(remap.types.len(), id.index());
558 remap.types.push(Some(new_id));
559 }
560
561 let mut moved_interfaces = Vec::new();
562 for (id, mut iface) in interfaces {
563 let new_id = match interface_map.get(&id).copied() {
564 Some(into_id) => {
565 update_stability(
566 &iface.stability,
567 &mut self.interfaces[into_id].stability,
568 iface.span,
569 )?;
570
571 for (name, from_type_id) in iface.types.iter() {
577 if self.interfaces[into_id].types.contains_key(name) {
578 continue;
579 }
580 let new_type_id = remap.map_type(*from_type_id, Default::default())?;
581 self.interfaces[into_id]
582 .types
583 .insert(name.clone(), new_type_id);
584 }
585
586 let extra_funcs: Vec<_> = iface
590 .functions
591 .into_iter()
592 .filter(|(name, _)| {
593 !self.interfaces[into_id]
594 .functions
595 .contains_key(name.as_str())
596 })
597 .collect();
598 for (name, mut func) in extra_funcs {
599 remap.update_function(self, &mut func, Default::default())?;
600 func.adjust_spans(span_offset);
601 self.interfaces[into_id].functions.insert(name, func);
602 }
603
604 into_id
605 }
606 None => {
607 log::debug!("moving interface {:?}", iface.name);
608 moved_interfaces.push(id);
609 remap.update_interface(self, &mut iface)?;
610 iface.adjust_spans(span_offset);
611 self.interfaces.alloc(iface)
612 }
613 };
614 assert_eq!(remap.interfaces.len(), id.index());
615 remap.interfaces.push(Some(new_id));
616 }
617
618 let mut moved_worlds = Vec::new();
619 for (id, mut world) in worlds {
620 let new_id = match world_map.get(&id).copied() {
621 Some(world_id) => {
622 update_stability(
623 &world.stability,
624 &mut self.worlds[world_id].stability,
625 world.span,
626 )?;
627 for from_import in world.imports.iter() {
628 Resolve::update_world_imports_stability(
629 from_import,
630 &mut self.worlds[world_id].imports,
631 &interface_map,
632 )?;
633 }
634 for from_export in world.exports.iter() {
635 Resolve::update_world_imports_stability(
636 from_export,
637 &mut self.worlds[world_id].exports,
638 &interface_map,
639 )?;
640 }
641 world_id
642 }
643 None => {
644 log::debug!("moving world {}", world.name);
645 moved_worlds.push(id);
646 let mut update =
647 |map: &mut IndexMap<WorldKey, WorldItem>| -> anyhow::Result<_> {
648 for (mut name, mut item) in mem::take(map) {
649 remap.update_world_key(&mut name, Default::default())?;
650 match &mut item {
651 WorldItem::Function(f) => {
652 remap.update_function(self, f, Default::default())?
653 }
654 WorldItem::Interface { id, .. } => {
655 *id = remap.map_interface(*id, Default::default())?;
656 }
657 WorldItem::Type { id, .. } => {
658 *id = remap.map_type(*id, Default::default())?
659 }
660 }
661 map.insert(name, item);
662 }
663 Ok(())
664 };
665 update(&mut world.imports)?;
666 update(&mut world.exports)?;
667 world.adjust_spans(span_offset);
668 self.worlds.alloc(world)
669 }
670 };
671 assert_eq!(remap.worlds.len(), id.index());
672 remap.worlds.push(Some(new_id));
673 }
674
675 for (id, mut pkg) in packages {
676 let new_id = match package_map.get(&id).copied() {
677 Some(id) => id,
678 None => {
679 for (_, id) in pkg.interfaces.iter_mut() {
680 *id = remap.map_interface(*id, Default::default())?;
681 }
682 for (_, id) in pkg.worlds.iter_mut() {
683 *id = remap.map_world(*id, Default::default())?;
684 }
685 self.packages.alloc(pkg)
686 }
687 };
688 assert_eq!(remap.packages.len(), id.index());
689 remap.packages.push(new_id);
690 }
691
692 for (name, id) in package_names {
693 let id = remap.packages[id.index()];
694 if let Some(prev) = self.package_names.insert(name, id) {
695 assert_eq!(prev, id);
696 }
697 }
698
699 for id in moved_worlds {
707 let id = remap.map_world(id, Default::default())?;
708 if let Some(pkg) = self.worlds[id].package.as_mut() {
709 *pkg = remap.packages[pkg.index()];
710 }
711 }
712 for id in moved_interfaces {
713 let id = remap.map_interface(id, Default::default())?;
714 if let Some(pkg) = self.interfaces[id].package.as_mut() {
715 *pkg = remap.packages[pkg.index()];
716 }
717 if let Some(clone_of) = self.interfaces[id].clone_of.as_mut() {
718 *clone_of = remap.map_interface(*clone_of, Default::default())?;
719 }
720 }
721 for id in moved_types {
722 let id = remap.map_type(id, Default::default())?;
723 match &mut self.types[id].owner {
724 TypeOwner::Interface(id) => *id = remap.map_interface(*id, Default::default())?,
725 TypeOwner::World(id) => *id = remap.map_world(*id, Default::default())?,
726 TypeOwner::None => {}
727 }
728 }
729
730 for (name, pkg, iface) in interfaces_to_add {
735 let prev = self.packages[pkg]
736 .interfaces
737 .insert(name, remap.map_interface(iface, Default::default())?);
738 assert!(prev.is_none());
739 }
740 for (name, pkg, world) in worlds_to_add {
741 let prev = self.packages[pkg]
742 .worlds
743 .insert(name, remap.map_world(world, Default::default())?);
744 assert!(prev.is_none());
745 }
746
747 log::trace!("now have {} packages", self.packages.len());
748
749 let world_ids: Vec<_> = self.worlds.iter().map(|(id, _)| id).collect();
753 for world_id in world_ids {
754 let world_span = self.worlds[world_id].span;
755 self.elaborate_world(world_id, world_span)?;
756 }
757
758 #[cfg(debug_assertions)]
759 self.assert_valid();
760 Ok(remap)
761 }
762
763 fn update_world_imports_stability(
764 from_item: (&WorldKey, &WorldItem),
765 into_items: &mut IndexMap<WorldKey, WorldItem>,
766 interface_map: &HashMap<Id<Interface>, Id<Interface>>,
767 ) -> anyhow::Result<()> {
768 match from_item.0 {
769 WorldKey::Name(_) => {
770 Ok(())
772 }
773 key @ WorldKey::Interface(_) => {
774 let new_key = MergeMap::map_name(key, interface_map);
775 if let Some(into) = into_items.get_mut(&new_key) {
776 match (from_item.1, into) {
777 (
778 WorldItem::Interface {
779 id: aid,
780 stability: astability,
781 span: aspan,
782 },
783 WorldItem::Interface {
784 id: bid,
785 stability: bstability,
786 ..
787 },
788 ) => {
789 let aid = interface_map.get(aid).copied().unwrap_or(*aid);
790 assert_eq!(aid, *bid);
791 update_stability(astability, bstability, *aspan)?;
792 Ok(())
793 }
794 _ => unreachable!(),
795 }
796 } else {
797 unreachable!()
800 }
801 }
802 }
803 }
804
805 pub fn merge_worlds(
820 &mut self,
821 from: WorldId,
822 into: WorldId,
823 clone_maps: &mut CloneMaps,
824 ) -> anyhow::Result<()> {
825 let mut new_imports = Vec::new();
826 let mut new_exports = Vec::new();
827
828 let from_world = &self.worlds[from];
829 let into_world = &self.worlds[into];
830
831 log::trace!("merging {} into {}", from_world.name, into_world.name);
832
833 for (name, from_import) in from_world.imports.iter() {
841 let name_str = self.name_world_key(name);
842 match into_world.imports.get(name) {
843 Some(into_import) => {
844 log::trace!("info/from shared import on `{name_str}`");
845 self.merge_world_item(from_import, into_import)
846 .with_context(|| format!("failed to merge world import {name_str}"))?;
847 }
848 None => {
849 log::trace!("new import: `{name_str}`");
850 new_imports.push((name.clone(), from_import.clone()));
851 }
852 }
853 }
854
855 let mut must_be_imported = HashMap::new();
862 for (key, export) in into_world.exports.iter() {
863 for dep in self.world_item_direct_deps(export) {
864 if into_world.exports.contains_key(&WorldKey::Interface(dep)) {
865 continue;
866 }
867 self.foreach_interface_dep(dep, &mut |id| {
868 must_be_imported.insert(id, key.clone());
869 });
870 }
871 }
872
873 for (name, from_export) in from_world.exports.iter() {
876 let name_str = self.name_world_key(name);
877 match into_world.exports.get(name) {
878 Some(into_export) => {
879 log::trace!("info/from shared export on `{name_str}`");
880 self.merge_world_item(from_export, into_export)
881 .with_context(|| format!("failed to merge world export {name_str}"))?;
882 }
883 None => {
884 log::trace!("new export `{name_str}`");
885 self.ensure_can_add_world_export(
888 into_world,
889 name,
890 from_export,
891 &must_be_imported,
892 )
893 .with_context(|| {
894 format!("failed to add export `{}`", self.name_world_key(name))
895 })?;
896 new_exports.push((name.clone(), from_export.clone()));
897 }
898 }
899 }
900
901 let mut cloner = clone::Cloner::new(
915 self,
916 clone_maps,
917 TypeOwner::World(from),
918 TypeOwner::World(into),
919 );
920 cloner.register_world_type_overlap(from, into);
921 for (name, item) in new_imports.iter_mut().chain(&mut new_exports) {
922 cloner.world_item(name, item);
923 }
924
925 let into_world = &mut self.worlds[into];
927 for (name, import) in new_imports {
928 let prev = into_world.imports.insert(name, import);
929 assert!(prev.is_none());
930 }
931 for (name, export) in new_exports {
932 let prev = into_world.exports.insert(name, export);
933 assert!(prev.is_none());
934 }
935
936 #[cfg(debug_assertions)]
937 self.assert_valid();
938 Ok(())
939 }
940
941 fn merge_world_item(&self, from: &WorldItem, into: &WorldItem) -> anyhow::Result<()> {
942 let mut map = MergeMap::new(self, self);
943 match (from, into) {
944 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
945 if from == into {
950 return Ok(());
951 }
952
953 map.build_interface(*from, *into)
963 .context("failed to merge interfaces")?;
964 }
965
966 (WorldItem::Function(from), WorldItem::Function(into)) => {
969 map.build_function(from, into)
970 .context("failed to merge functions")?;
971 }
972 (WorldItem::Type { id: from, .. }, WorldItem::Type { id: into, .. }) => {
973 map.build_type_id(*from, *into)
974 .context("failed to merge types")?;
975 }
976
977 (WorldItem::Interface { .. }, _)
979 | (WorldItem::Function { .. }, _)
980 | (WorldItem::Type { .. }, _) => {
981 bail!("different kinds of items");
982 }
983 }
984 assert!(map.interfaces_to_add.is_empty());
985 assert!(map.worlds_to_add.is_empty());
986 Ok(())
987 }
988
989 fn ensure_can_add_world_export(
1001 &self,
1002 into: &World,
1003 name: &WorldKey,
1004 item: &WorldItem,
1005 must_be_imported: &HashMap<InterfaceId, WorldKey>,
1006 ) -> anyhow::Result<()> {
1007 assert!(!into.exports.contains_key(name));
1008 let name = self.name_world_key(name);
1009
1010 for dep in self.world_item_direct_deps(item) {
1014 if into.exports.contains_key(&WorldKey::Interface(dep)) {
1015 continue;
1016 }
1017 self.ensure_not_exported(into, dep)
1018 .with_context(|| format!("failed validating export of `{name}`"))?;
1019 }
1020
1021 if let WorldItem::Interface { id, .. } = item {
1025 if let Some(export) = must_be_imported.get(id) {
1026 let export_name = self.name_world_key(export);
1027 bail!(
1028 "export `{export_name}` depends on `{name}` \
1029 previously as an import which will change meaning \
1030 if `{name}` is added as an export"
1031 );
1032 }
1033 }
1034
1035 Ok(())
1036 }
1037
1038 fn ensure_not_exported(&self, world: &World, id: InterfaceId) -> anyhow::Result<()> {
1039 let key = WorldKey::Interface(id);
1040 let name = self.name_world_key(&key);
1041 if world.exports.contains_key(&key) {
1042 bail!(
1043 "world exports `{name}` but it's also transitively used by an \
1044 import \
1045 which means that this is not valid"
1046 )
1047 }
1048 for dep in self.interface_direct_deps(id) {
1049 self.ensure_not_exported(world, dep)
1050 .with_context(|| format!("failed validating transitive import dep `{name}`"))?;
1051 }
1052 Ok(())
1053 }
1054
1055 fn world_item_direct_deps(&self, item: &WorldItem) -> impl Iterator<Item = InterfaceId> + '_ {
1061 let mut interface = None;
1062 let mut ty = None;
1063 match item {
1064 WorldItem::Function(_) => {}
1065 WorldItem::Type { id, .. } => ty = Some(*id),
1066 WorldItem::Interface { id, .. } => interface = Some(*id),
1067 }
1068
1069 interface
1070 .into_iter()
1071 .flat_map(move |id| self.interface_direct_deps(id))
1072 .chain(ty.and_then(|t| self.type_interface_dep(t)))
1073 }
1074
1075 fn foreach_interface_dep(&self, id: InterfaceId, f: &mut dyn FnMut(InterfaceId)) {
1079 self._foreach_interface_dep(id, f, &mut HashSet::new())
1080 }
1081
1082 fn _foreach_interface_dep(
1086 &self,
1087 id: InterfaceId,
1088 f: &mut dyn FnMut(InterfaceId),
1089 visited: &mut HashSet<InterfaceId>,
1090 ) {
1091 if !visited.insert(id) {
1092 return;
1093 }
1094 f(id);
1095 for dep in self.interface_direct_deps(id) {
1096 self._foreach_interface_dep(dep, f, visited);
1097 }
1098 }
1099
1100 pub fn id_of(&self, interface: InterfaceId) -> Option<String> {
1104 let interface = &self.interfaces[interface];
1105 Some(self.id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1106 }
1107
1108 pub fn canonicalized_id_of(&self, interface: InterfaceId) -> Option<String> {
1113 let interface = &self.interfaces[interface];
1114 Some(self.canonicalized_id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1115 }
1116
1117 fn rename_world(
1122 &mut self,
1123 world_id: WorldId,
1124 out_world_name: Option<String>,
1125 default_suffix: &str,
1126 ) {
1127 let world = &mut self.worlds[world_id];
1128 let pkg = &mut self.packages[world.package.unwrap()];
1129 pkg.worlds.shift_remove(&world.name);
1130 if let Some(name) = out_world_name {
1131 world.name = name.clone();
1132 pkg.worlds.insert(name, world_id);
1133 } else {
1134 world.name.push_str(default_suffix);
1135 pkg.worlds.insert(world.name.clone(), world_id);
1136 }
1137 }
1138
1139 pub fn importize(
1155 &mut self,
1156 world_id: WorldId,
1157 out_world_name: Option<String>,
1158 ) -> anyhow::Result<()> {
1159 self.rename_world(world_id, out_world_name, "-importized");
1160
1161 let world = &mut self.worlds[world_id];
1164 world.imports.retain(|_, item| match item {
1165 WorldItem::Type { .. } => true,
1166 _ => false,
1167 });
1168
1169 for (name, export) in mem::take(&mut world.exports) {
1170 match (name.clone(), world.imports.insert(name, export)) {
1171 (_, None) => {}
1173
1174 (WorldKey::Name(name), Some(_)) => {
1176 bail!("world export `{name}` conflicts with import of same name");
1177 }
1178
1179 (WorldKey::Interface(_), _) => unreachable!(),
1182 }
1183 }
1184
1185 let world_span = world.span;
1188 self.elaborate_world(world_id, world_span)?;
1189
1190 #[cfg(debug_assertions)]
1191 self.assert_valid();
1192 Ok(())
1193 }
1194
1195 pub fn exportize(
1214 &mut self,
1215 world_id: WorldId,
1216 out_world_name: Option<String>,
1217 filter: Option<&dyn Fn(&WorldKey, &WorldItem) -> bool>,
1218 ) -> anyhow::Result<()> {
1219 self.rename_world(world_id, out_world_name, "-exportized");
1220
1221 let world = &mut self.worlds[world_id];
1222 world.exports.clear();
1223
1224 let old_imports = mem::take(&mut world.imports);
1225 for (name, import) in old_imports {
1226 let should_move = match &filter {
1227 Some(f) => f(&name, &import),
1228 None => true,
1229 };
1230 if should_move {
1231 world.exports.insert(name, import);
1232 } else {
1233 world.imports.insert(name, import);
1234 }
1235 }
1236
1237 let world_span = world.span;
1240 self.elaborate_world(world_id, world_span)?;
1241
1242 #[cfg(debug_assertions)]
1243 self.assert_valid();
1244 Ok(())
1245 }
1246
1247 pub fn id_of_name(&self, pkg: PackageId, name: &str) -> String {
1249 let package = &self.packages[pkg];
1250 let mut base = String::new();
1251 base.push_str(&package.name.namespace);
1252 base.push_str(":");
1253 base.push_str(&package.name.name);
1254 base.push_str("/");
1255 base.push_str(name);
1256 if let Some(version) = &package.name.version {
1257 base.push_str(&format!("@{version}"));
1258 }
1259 base
1260 }
1261
1262 pub fn canonicalized_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("@");
1277 let string = PackageName::version_compat_track_string(version);
1278 base.push_str(&string);
1279 }
1280 base
1281 }
1282
1283 pub fn select_world(
1398 &self,
1399 main_packages: &[PackageId],
1400 world: Option<&str>,
1401 ) -> anyhow::Result<WorldId> {
1402 let world_path = match world {
1404 Some(world) => Some(
1405 parse_use_path(world)
1406 .with_context(|| format!("failed to parse world specifier `{world}`"))?,
1407 ),
1408 None => None,
1409 };
1410
1411 match world_path {
1412 Some(world_path) => {
1414 let (pkg, world_name) = match (main_packages, world_path) {
1415 ([], _) => bail!("No main packages defined"),
1417
1418 ([main_package], ParsedUsePath::Name(name)) => (*main_package, name),
1420
1421 (_, ParsedUsePath::Name(_name)) => {
1423 bail!(
1424 "There are multiple main packages; a world must be explicitly chosen:{}",
1425 self.worlds
1426 .iter()
1427 .map(|world| format!(
1428 "\n {}",
1429 self.id_of_name(world.1.package.unwrap(), &world.1.name)
1430 ))
1431 .collect::<String>()
1432 )
1433 }
1434
1435 (_, ParsedUsePath::Package(pkg, world_name)) => {
1437 let pkg = match self.package_names.get(&pkg) {
1438 Some(pkg) => *pkg,
1439 None => {
1440 let mut candidates =
1441 self.package_names.iter().filter(|(name, _)| {
1442 pkg.version.is_none()
1443 && pkg.name == name.name
1444 && pkg.namespace == name.namespace
1445 && name.version.is_some()
1446 });
1447 let candidate = candidates.next();
1448 if let Some((c2, _)) = candidates.next() {
1449 let (c1, _) = candidate.unwrap();
1450 bail!(
1451 "package name `{pkg}` is available at both \
1452 versions {} and {} but which is not specified",
1453 c1.version.as_ref().unwrap(),
1454 c2.version.as_ref().unwrap(),
1455 );
1456 }
1457 match candidate {
1458 Some((_, id)) => *id,
1459 None => bail!("unknown package `{pkg}`"),
1460 }
1461 }
1462 };
1463 (pkg, world_name.to_string())
1464 }
1465 };
1466
1467 let pkg = &self.packages[pkg];
1469 pkg.worlds.get(&world_name).copied().ok_or_else(|| {
1470 anyhow!("World `{world_name}` not found in package `{}`", pkg.name)
1471 })
1472 }
1473
1474 None => match main_packages {
1476 [] => bail!("No main packages defined"),
1477
1478 [main_package] => {
1480 let pkg = &self.packages[*main_package];
1481 match pkg.worlds.len() {
1482 0 => bail!("The main package `{}` contains no worlds", pkg.name),
1483 1 => Ok(pkg.worlds[0]),
1484 _ => bail!(
1485 "There are multiple worlds in `{}`; one must be explicitly chosen:{}",
1486 pkg.name,
1487 pkg.worlds
1488 .values()
1489 .map(|world| format!(
1490 "\n {}",
1491 self.id_of_name(*main_package, &self.worlds[*world].name)
1492 ))
1493 .collect::<String>()
1494 ),
1495 }
1496 }
1497
1498 _ => {
1500 bail!(
1501 "There are multiple main packages; a world must be explicitly chosen:{}",
1502 self.worlds
1503 .iter()
1504 .map(|world| format!(
1505 "\n {}",
1506 self.id_of_name(world.1.package.unwrap(), &world.1.name)
1507 ))
1508 .collect::<String>()
1509 )
1510 }
1511 },
1512 }
1513 }
1514
1515 pub fn name_world_key(&self, key: &WorldKey) -> String {
1517 match key {
1518 WorldKey::Name(s) => s.to_string(),
1519 WorldKey::Interface(i) => self.id_of(*i).expect("unexpected anonymous interface"),
1520 }
1521 }
1522
1523 pub fn name_canonicalized_world_key(&self, key: &WorldKey) -> String {
1526 match key {
1527 WorldKey::Name(s) => s.to_string(),
1528 WorldKey::Interface(i) => self
1529 .canonicalized_id_of(*i)
1530 .expect("unexpected anonymous interface"),
1531 }
1532 }
1533
1534 pub fn implements_value(&self, key: &WorldKey, item: &WorldItem) -> Option<String> {
1539 if let WorldKey::Name(_) = key {
1540 if let WorldItem::Interface { id, .. } = item {
1541 if self.interfaces[*id].name.is_some() {
1542 return Some(self.id_of(*id).unwrap().into());
1543 }
1544 }
1545 }
1546 None
1547 }
1548
1549 pub fn type_interface_dep(&self, id: TypeId) -> Option<InterfaceId> {
1555 let ty = &self.types[id];
1556 let dep = match ty.kind {
1557 TypeDefKind::Type(Type::Id(id)) => id,
1558 _ => return None,
1559 };
1560 let other = &self.types[dep];
1561 if ty.owner == other.owner {
1562 None
1563 } else {
1564 match other.owner {
1565 TypeOwner::Interface(id) => Some(id),
1566 _ => unreachable!(),
1567 }
1568 }
1569 }
1570
1571 pub fn interface_direct_deps(&self, id: InterfaceId) -> impl Iterator<Item = InterfaceId> + '_ {
1581 self.interfaces[id]
1582 .types
1583 .iter()
1584 .filter_map(move |(_name, ty)| self.type_interface_dep(*ty))
1585 }
1586
1587 pub fn package_direct_deps(&self, id: PackageId) -> impl Iterator<Item = PackageId> + '_ {
1597 let pkg = &self.packages[id];
1598
1599 pkg.interfaces
1600 .iter()
1601 .flat_map(move |(_name, id)| self.interface_direct_deps(*id))
1602 .chain(pkg.worlds.iter().flat_map(move |(_name, id)| {
1603 let world = &self.worlds[*id];
1604 world
1605 .imports
1606 .iter()
1607 .chain(world.exports.iter())
1608 .filter_map(move |(_name, item)| match item {
1609 WorldItem::Interface { id, .. } => Some(*id),
1610 WorldItem::Function(_) => None,
1611 WorldItem::Type { id, .. } => self.type_interface_dep(*id),
1612 })
1613 }))
1614 .filter_map(move |iface_id| {
1615 let pkg = self.interfaces[iface_id].package?;
1616 if pkg == id { None } else { Some(pkg) }
1617 })
1618 }
1619
1620 pub fn topological_packages(&self) -> Vec<PackageId> {
1626 let mut pushed = vec![false; self.packages.len()];
1627 let mut order = Vec::new();
1628 for (id, _) in self.packages.iter() {
1629 self.build_topological_package_ordering(id, &mut pushed, &mut order);
1630 }
1631 order
1632 }
1633
1634 fn build_topological_package_ordering(
1635 &self,
1636 id: PackageId,
1637 pushed: &mut Vec<bool>,
1638 order: &mut Vec<PackageId>,
1639 ) {
1640 if pushed[id.index()] {
1641 return;
1642 }
1643 for dep in self.package_direct_deps(id) {
1644 self.build_topological_package_ordering(dep, pushed, order);
1645 }
1646 order.push(id);
1647 pushed[id.index()] = true;
1648 }
1649
1650 #[doc(hidden)]
1651 pub fn assert_valid(&self) {
1652 let mut package_interfaces = Vec::new();
1653 let mut package_worlds = Vec::new();
1654 for (id, pkg) in self.packages.iter() {
1655 let mut interfaces = HashSet::new();
1656 for (name, iface) in pkg.interfaces.iter() {
1657 assert!(interfaces.insert(*iface));
1658 let iface = &self.interfaces[*iface];
1659 assert_eq!(name, iface.name.as_ref().unwrap());
1660 assert_eq!(iface.package.unwrap(), id);
1661 }
1662 package_interfaces.push(pkg.interfaces.values().copied().collect::<HashSet<_>>());
1663 let mut worlds = HashSet::new();
1664 for (name, world) in pkg.worlds.iter() {
1665 assert!(worlds.insert(*world));
1666 assert_eq!(
1667 pkg.worlds.get_key_value(name),
1668 Some((name, world)),
1669 "`MutableKeys` impl may have been used to change a key's hash or equality"
1670 );
1671 let world = &self.worlds[*world];
1672 assert_eq!(*name, world.name);
1673 assert_eq!(world.package.unwrap(), id);
1674 }
1675 package_worlds.push(pkg.worlds.values().copied().collect::<HashSet<_>>());
1676 }
1677
1678 let mut interface_types = Vec::new();
1679 for (id, iface) in self.interfaces.iter() {
1680 assert!(self.packages.get(iface.package.unwrap()).is_some());
1681 if iface.name.is_some() {
1682 match iface.clone_of {
1683 Some(other) => {
1684 assert_eq!(iface.name, self.interfaces[other].name);
1685 }
1686 None => {
1687 assert!(package_interfaces[iface.package.unwrap().index()].contains(&id));
1688 }
1689 }
1690 }
1691
1692 for (name, ty) in iface.types.iter() {
1693 let ty = &self.types[*ty];
1694 assert_eq!(ty.name.as_ref(), Some(name));
1695 assert_eq!(ty.owner, TypeOwner::Interface(id));
1696 }
1697 interface_types.push(iface.types.values().copied().collect::<HashSet<_>>());
1698 for (name, f) in iface.functions.iter() {
1699 assert_eq!(*name, f.name);
1700 }
1701 }
1702
1703 let mut world_types = Vec::new();
1704 for (id, world) in self.worlds.iter() {
1705 log::debug!("validating world {}", &world.name);
1706 if let Some(package) = world.package {
1707 assert!(self.packages.get(package).is_some());
1708 assert!(package_worlds[package.index()].contains(&id));
1709 }
1710 assert!(world.includes.is_empty());
1711
1712 let mut types = HashSet::new();
1713 for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1714 log::debug!("validating world item: {}", self.name_world_key(name));
1715 match item {
1716 WorldItem::Interface { id, .. } => {
1717 if matches!(name, WorldKey::Name(_)) {
1721 let iface = &self.interfaces[*id];
1722 if iface.name.is_none() {
1723 assert_eq!(iface.package, world.package);
1724 }
1725 }
1726 }
1727 WorldItem::Function(f) => {
1728 assert!(!matches!(name, WorldKey::Interface(_)));
1729 assert_eq!(f.name, name.clone().unwrap_name());
1730 }
1731 WorldItem::Type { id: ty, .. } => {
1732 assert!(!matches!(name, WorldKey::Interface(_)));
1733 assert!(types.insert(*ty));
1734 let ty = &self.types[*ty];
1735 assert_eq!(ty.name, Some(name.clone().unwrap_name()));
1736 assert_eq!(ty.owner, TypeOwner::World(id));
1737 }
1738 }
1739 }
1740 self.assert_world_elaborated(world);
1741 world_types.push(types);
1742 }
1743
1744 for (ty_id, ty) in self.types.iter() {
1745 match ty.owner {
1746 TypeOwner::Interface(id) => {
1747 assert!(self.interfaces.get(id).is_some());
1748 assert!(interface_types[id.index()].contains(&ty_id));
1749 }
1750 TypeOwner::World(id) => {
1751 assert!(self.worlds.get(id).is_some());
1752 assert!(world_types[id.index()].contains(&ty_id));
1753 }
1754 TypeOwner::None => {}
1755 }
1756 }
1757
1758 self.assert_topologically_sorted();
1759 }
1760
1761 fn assert_topologically_sorted(&self) {
1762 let mut positions = IndexMap::default();
1763 for id in self.topological_packages() {
1764 let pkg = &self.packages[id];
1765 log::debug!("pkg {}", pkg.name);
1766 let prev = positions.insert(Some(id), IndexSet::default());
1767 assert!(prev.is_none());
1768 }
1769 positions.insert(None, IndexSet::default());
1770
1771 for (id, iface) in self.interfaces.iter() {
1772 log::debug!("iface {:?}", iface.name);
1773 let ok = positions.get_mut(&iface.package).unwrap().insert(id);
1774 assert!(ok);
1775 }
1776
1777 for (_, world) in self.worlds.iter() {
1778 log::debug!("world {:?}", world.name);
1779
1780 let my_package = world.package;
1781 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1782
1783 for (_, item) in world.imports.iter().chain(&world.exports) {
1784 let id = match item {
1785 WorldItem::Interface { id, .. } => *id,
1786 _ => continue,
1787 };
1788 let other_package = self.interfaces[id].package;
1789 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1790
1791 assert!(other_package_pos <= my_package_pos);
1792 }
1793 }
1794
1795 for (_id, ty) in self.types.iter() {
1796 log::debug!("type {:?} {:?}", ty.name, ty.owner);
1797 let other_id = match ty.kind {
1798 TypeDefKind::Type(Type::Id(ty)) => ty,
1799 _ => continue,
1800 };
1801 let other = &self.types[other_id];
1802 if ty.kind == other.kind {
1803 continue;
1804 }
1805 let my_interface = match ty.owner {
1806 TypeOwner::Interface(id) => id,
1807 _ => continue,
1808 };
1809 let other_interface = match other.owner {
1810 TypeOwner::Interface(id) => id,
1811 _ => continue,
1812 };
1813
1814 let my_package = self.interfaces[my_interface].package;
1815 let other_package = self.interfaces[other_interface].package;
1816 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1817 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1818
1819 assert!(other_package_pos <= my_package_pos);
1820 }
1821 }
1822
1823 fn assert_world_elaborated(&self, world: &World) {
1824 for (key, item) in world.imports.iter() {
1825 log::debug!(
1826 "asserting elaborated world import {}",
1827 self.name_world_key(key)
1828 );
1829 match item {
1830 WorldItem::Type { id, .. } => self.assert_world_imports_type_deps(world, key, *id),
1831
1832 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1834
1835 WorldItem::Interface { id, .. } => {
1837 for dep in self.interface_direct_deps(*id) {
1838 assert!(
1839 world.imports.contains_key(&WorldKey::Interface(dep)),
1840 "world import of {} is missing transitive dep of {}",
1841 self.name_world_key(key),
1842 self.id_of(dep).unwrap(),
1843 );
1844 }
1845 }
1846 }
1847 }
1848 for (key, item) in world.exports.iter() {
1849 log::debug!(
1850 "asserting elaborated world export {}",
1851 self.name_world_key(key)
1852 );
1853 match item {
1854 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1856
1857 WorldItem::Interface { id, .. } => {
1861 for dep in self.interface_direct_deps(*id) {
1862 let dep_key = WorldKey::Interface(dep);
1863 if world.exports.contains_key(&dep_key) {
1864 continue;
1865 }
1866 self.foreach_interface_dep(dep, &mut |dep| {
1867 let dep_key = WorldKey::Interface(dep);
1868 assert!(
1869 world.imports.contains_key(&dep_key),
1870 "world should import {} (required by {})",
1871 self.name_world_key(&dep_key),
1872 self.name_world_key(key),
1873 );
1874 assert!(
1875 !world.exports.contains_key(&dep_key),
1876 "world should not export {} (required by {})",
1877 self.name_world_key(&dep_key),
1878 self.name_world_key(key),
1879 );
1880 });
1881 }
1882 }
1883
1884 WorldItem::Type { .. } => unreachable!(),
1886 }
1887 }
1888 }
1889
1890 fn assert_world_imports_type_deps(&self, world: &World, key: &WorldKey, ty: TypeId) {
1891 let ty = &self.types[ty];
1894 if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
1895 if let TypeOwner::Interface(id) = self.types[other].owner {
1896 let key = WorldKey::Interface(id);
1897 assert!(world.imports.contains_key(&key));
1898 return;
1899 }
1900 }
1901
1902 let mut visitor = MyVisit(self, Vec::new());
1906 visitor.visit_type_def(self, ty);
1907 for ty in visitor.1 {
1908 let ty = &self.types[ty];
1909 let Some(name) = ty.name.clone() else {
1910 continue;
1911 };
1912 let dep_key = WorldKey::Name(name);
1913 assert!(
1914 world.imports.contains_key(&dep_key),
1915 "world import `{}` should also force an import of `{}`",
1916 self.name_world_key(key),
1917 self.name_world_key(&dep_key),
1918 );
1919 }
1920
1921 struct MyVisit<'a>(&'a Resolve, Vec<TypeId>);
1922
1923 impl TypeIdVisitor for MyVisit<'_> {
1924 fn before_visit_type_id(&mut self, id: TypeId) -> bool {
1925 self.1.push(id);
1926 self.0.types[id].name.is_none()
1928 }
1929 }
1930 }
1931
1932 fn assert_world_function_imports_types(&self, world: &World, key: &WorldKey, func: &Function) {
1936 for ty in func
1937 .parameter_and_result_types()
1938 .chain(func.kind.resource().map(Type::Id))
1939 {
1940 let Type::Id(id) = ty else {
1941 continue;
1942 };
1943 self.assert_world_imports_type_deps(world, key, id);
1944 }
1945 }
1946
1947 fn include_stability(
1963 &self,
1964 stability: &Stability,
1965 pkg_id: &PackageId,
1966 span: Span,
1967 ) -> ResolveResult<bool> {
1968 Ok(match stability {
1969 Stability::Unknown => true,
1970 Stability::Stable { since, .. } => {
1973 let Some(p) = self.packages.get(*pkg_id) else {
1974 return Ok(true);
1982 };
1983
1984 let package_version = p.name.version.as_ref().ok_or_else(|| {
1987 ResolveError::new_semantic(
1988 span,
1989 format!(
1990 "package [{}] contains a feature gate with a version \
1991 specifier, so it must have a version",
1992 p.name
1993 ),
1994 )
1995 })?;
1996
1997 if since > package_version {
2001 return Err(ResolveError::new_semantic(
2002 span,
2003 format!(
2004 "feature gate cannot reference unreleased version \
2005 {since} of package [{}] (current version {package_version})",
2006 p.name
2007 ),
2008 ));
2009 }
2010
2011 true
2012 }
2013 Stability::Unstable { feature, .. } => {
2014 self.features.contains(feature) || self.all_features
2015 }
2016 })
2017 }
2018
2019 fn elaborate_world(&mut self, world_id: WorldId, span: Span) -> ResolveResult<()> {
2031 let mut new_imports = IndexMap::default();
2035 let world = &self.worlds[world_id];
2036
2037 let sort_key = |resolve: &Resolve, item: &WorldItem| match item {
2060 WorldItem::Interface { .. } => 0,
2061 WorldItem::Type { id, .. } => {
2062 let ty = &resolve.types[*id];
2063 match ty.kind {
2064 TypeDefKind::Type(Type::Id(t)) if resolve.types[t].owner != ty.owner => 1,
2065 _ => 2,
2066 }
2067 }
2068 WorldItem::Function(f) => {
2069 if f.kind.resource().is_none() {
2070 3
2071 } else {
2072 4
2073 }
2074 }
2075 };
2076
2077 let mut world_imports = world.imports.iter().collect::<Vec<_>>();
2080 world_imports.sort_by_key(|(_name, import)| sort_key(self, import));
2081 for (name, item) in world_imports {
2082 match item {
2083 WorldItem::Interface { id, stability, .. } => {
2086 self.elaborate_world_import(&mut new_imports, name.clone(), *id, &stability);
2087 }
2088
2089 WorldItem::Function(_) => {
2092 let prev = new_imports.insert(name.clone(), item.clone());
2093 assert!(prev.is_none());
2094 }
2095
2096 WorldItem::Type { id, .. } => {
2100 if let Some(dep) = self.type_interface_dep(*id) {
2101 self.elaborate_world_import(
2102 &mut new_imports,
2103 WorldKey::Interface(dep),
2104 dep,
2105 &self.types[*id].stability,
2106 );
2107 }
2108 let prev = new_imports.insert(name.clone(), item.clone());
2109 assert!(prev.is_none());
2110 }
2111 }
2112 }
2113
2114 let mut new_exports = IndexMap::default();
2120 let mut export_interfaces = IndexMap::default();
2121 for (name, item) in world.exports.iter() {
2122 match item {
2123 WorldItem::Interface { .. } => {
2124 let prev = export_interfaces.insert(name.clone(), item.clone());
2125 assert!(prev.is_none());
2126 }
2127 WorldItem::Function(_) => {
2128 let prev = new_exports.insert(name.clone(), item.clone());
2129 assert!(prev.is_none());
2130 }
2131 WorldItem::Type { .. } => unreachable!(),
2132 }
2133 }
2134
2135 self.elaborate_world_exports(&export_interfaces, &mut new_imports, &mut new_exports, span)?;
2136
2137 new_imports.sort_by_cached_key(|_name, import| sort_key(self, import));
2141
2142 log::trace!("imports = {new_imports:?}");
2145 log::trace!("exports = {new_exports:?}");
2146 let world = &mut self.worlds[world_id];
2147 world.imports = new_imports;
2148 world.exports = new_exports;
2149
2150 Ok(())
2151 }
2152
2153 fn elaborate_world_import(
2154 &self,
2155 imports: &mut IndexMap<WorldKey, WorldItem>,
2156 key: WorldKey,
2157 id: InterfaceId,
2158 stability: &Stability,
2159 ) {
2160 if imports.contains_key(&key) {
2161 return;
2162 }
2163 for dep in self.interface_direct_deps(id) {
2164 self.elaborate_world_import(imports, WorldKey::Interface(dep), dep, stability);
2165 }
2166 let prev = imports.insert(
2167 key,
2168 WorldItem::Interface {
2169 id,
2170 stability: stability.clone(),
2171 span: Default::default(),
2172 },
2173 );
2174 assert!(prev.is_none());
2175 }
2176
2177 fn elaborate_world_exports(
2224 &self,
2225 export_interfaces: &IndexMap<WorldKey, WorldItem>,
2226 imports: &mut IndexMap<WorldKey, WorldItem>,
2227 exports: &mut IndexMap<WorldKey, WorldItem>,
2228 span: Span,
2229 ) -> ResolveResult<()> {
2230 let mut required_imports = HashSet::new();
2231 for (key, item) in export_interfaces.iter() {
2232 let name = self.name_world_key(&key);
2233 let ok = add_world_export(
2234 self,
2235 imports,
2236 exports,
2237 &export_interfaces,
2238 &mut required_imports,
2239 key.clone(),
2240 item.clone(),
2241 true,
2242 );
2243 if !ok {
2244 return Err(ResolveError::from(
2262 ResolveErrorKind::InvalidTransitiveDependency { name, span },
2263 ));
2264 }
2265 }
2266 return Ok(());
2267
2268 fn add_world_export(
2269 resolve: &Resolve,
2270 imports: &mut IndexMap<WorldKey, WorldItem>,
2271 exports: &mut IndexMap<WorldKey, WorldItem>,
2272 export_interfaces: &IndexMap<WorldKey, WorldItem>,
2273 required_imports: &mut HashSet<InterfaceId>,
2274 key: WorldKey,
2275 item: WorldItem,
2276 add_export: bool,
2277 ) -> bool {
2278 if exports.contains_key(&key) {
2279 if add_export {
2280 return true;
2281 } else {
2282 return false;
2283 }
2284 }
2285 let (id, stability) = match &item {
2286 WorldItem::Interface { id, stability, .. } => (*id, stability),
2287 _ => unreachable!(),
2288 };
2289 if !add_export && required_imports.contains(&id) {
2292 return true;
2293 }
2294 let ok = resolve.interface_direct_deps(id).all(|dep| {
2295 let item = WorldItem::Interface {
2296 id: dep,
2297 stability: stability.clone(),
2298 span: Default::default(),
2299 };
2300 let key = WorldKey::Interface(dep);
2301 let add_export = add_export && export_interfaces.contains_key(&key);
2302 add_world_export(
2303 resolve,
2304 imports,
2305 exports,
2306 export_interfaces,
2307 required_imports,
2308 key,
2309 item,
2310 add_export,
2311 )
2312 });
2313 if !ok {
2314 return false;
2315 }
2316 if add_export {
2317 if required_imports.contains(&id) {
2318 return false;
2319 }
2320 let prev = exports.insert(key.clone(), item);
2321 assert!(prev.is_none());
2322 } else {
2323 required_imports.insert(id);
2324 if !imports.contains_key(&key) {
2325 imports.insert(key.clone(), item);
2326 }
2327 }
2328 true
2329 }
2330 }
2331
2332 pub fn merge_world_imports_based_on_semver(&mut self, world_id: WorldId) -> anyhow::Result<()> {
2344 let world = &self.worlds[world_id];
2345
2346 let mut semver_tracks = HashMap::new();
2355 let mut to_remove = HashSet::new();
2356 for (key, _) in world.imports.iter() {
2357 let iface_id = match key {
2358 WorldKey::Interface(id) => *id,
2359 WorldKey::Name(_) => continue,
2360 };
2361 let (track, version) = match self.semver_track(iface_id) {
2362 Some(track) => track,
2363 None => continue,
2364 };
2365 log::debug!(
2366 "{} is on track {}/{}",
2367 self.id_of(iface_id).unwrap(),
2368 track.0,
2369 track.1,
2370 );
2371 match semver_tracks.entry(track.clone()) {
2372 Entry::Vacant(e) => {
2373 e.insert((version, iface_id));
2374 }
2375 Entry::Occupied(mut e) => match version.cmp(&e.get().0) {
2376 Ordering::Greater => {
2377 to_remove.insert(e.get().1);
2378 e.insert((version, iface_id));
2379 }
2380 Ordering::Equal => {}
2381 Ordering::Less => {
2382 to_remove.insert(iface_id);
2383 }
2384 },
2385 }
2386 }
2387
2388 let mut replacements = HashMap::new();
2391 for id in to_remove {
2392 let (track, _) = self.semver_track(id).unwrap();
2393 let (_, latest) = semver_tracks[&track];
2394 let prev = replacements.insert(id, latest);
2395 assert!(prev.is_none());
2396 }
2397 drop(semver_tracks);
2400
2401 for (to_replace, replace_with) in replacements.iter() {
2406 self.merge_world_item(
2407 &WorldItem::Interface {
2408 id: *to_replace,
2409 stability: Default::default(),
2410 span: Default::default(),
2411 },
2412 &WorldItem::Interface {
2413 id: *replace_with,
2414 stability: Default::default(),
2415 span: Default::default(),
2416 },
2417 )
2418 .with_context(|| {
2419 let old_name = self.id_of(*to_replace).unwrap();
2420 let new_name = self.id_of(*replace_with).unwrap();
2421 format!(
2422 "failed to upgrade `{old_name}` to `{new_name}`, was \
2423 this semver-compatible update not semver compatible?"
2424 )
2425 })?;
2426 }
2427
2428 for (to_replace, replace_with) in replacements.iter() {
2429 log::debug!(
2430 "REPLACE {} => {}",
2431 self.id_of(*to_replace).unwrap(),
2432 self.id_of(*replace_with).unwrap(),
2433 );
2434 }
2435
2436 for (key, item) in mem::take(&mut self.worlds[world_id].imports) {
2445 if let WorldItem::Interface { id, .. } = item {
2446 if replacements.contains_key(&id) {
2447 continue;
2448 }
2449 }
2450
2451 self.update_interface_deps_of_world_item(&item, &replacements);
2452
2453 let prev = self.worlds[world_id].imports.insert(key, item);
2454 assert!(prev.is_none());
2455 }
2456 for (key, item) in mem::take(&mut self.worlds[world_id].exports) {
2457 self.update_interface_deps_of_world_item(&item, &replacements);
2458 let prev = self.worlds[world_id].exports.insert(key, item);
2459 assert!(prev.is_none());
2460 }
2461
2462 let ids = self.worlds.iter().map(|(id, _)| id).collect::<Vec<_>>();
2468 for world_id in ids {
2469 let world_span = self.worlds[world_id].span;
2470 self.elaborate_world(world_id, world_span)?;
2471 }
2472
2473 #[cfg(debug_assertions)]
2474 self.assert_valid();
2475
2476 Ok(())
2477 }
2478
2479 fn update_interface_deps_of_world_item(
2480 &mut self,
2481 item: &WorldItem,
2482 replacements: &HashMap<InterfaceId, InterfaceId>,
2483 ) {
2484 match *item {
2485 WorldItem::Type { id, .. } => self.update_interface_dep_of_type(id, &replacements),
2486 WorldItem::Interface { id, .. } => {
2487 let types = self.interfaces[id]
2488 .types
2489 .values()
2490 .copied()
2491 .collect::<Vec<_>>();
2492 for ty in types {
2493 self.update_interface_dep_of_type(ty, &replacements);
2494 }
2495 }
2496 WorldItem::Function(_) => {}
2497 }
2498 }
2499
2500 fn semver_track(&self, id: InterfaceId) -> Option<((PackageName, String), &Version)> {
2511 let iface = &self.interfaces[id];
2512 let pkg = &self.packages[iface.package?];
2513 let version = pkg.name.version.as_ref()?;
2514 let mut name = pkg.name.clone();
2515 name.version = Some(PackageName::version_compat_track(version));
2516 Some(((name, iface.name.clone()?), version))
2517 }
2518
2519 fn update_interface_dep_of_type(
2523 &mut self,
2524 ty: TypeId,
2525 replacements: &HashMap<InterfaceId, InterfaceId>,
2526 ) {
2527 let to_replace = match self.type_interface_dep(ty) {
2528 Some(id) => id,
2529 None => return,
2530 };
2531 let replace_with = match replacements.get(&to_replace) {
2532 Some(id) => id,
2533 None => return,
2534 };
2535 let dep = match self.types[ty].kind {
2536 TypeDefKind::Type(Type::Id(id)) => id,
2537 _ => return,
2538 };
2539 let name = self.types[dep].name.as_ref().unwrap();
2540 let replacement_id = self.interfaces[*replace_with].types[name];
2543 self.types[ty].kind = TypeDefKind::Type(Type::Id(replacement_id));
2544 }
2545
2546 pub fn wasm_import_name(
2553 &self,
2554 mangling: ManglingAndAbi,
2555 import: WasmImport<'_>,
2556 ) -> (String, String) {
2557 match mangling {
2558 ManglingAndAbi::Standard32 => match import {
2559 WasmImport::Func { interface, func } => {
2560 let module = match interface {
2561 Some(key) => format!("cm32p2|{}", self.name_canonicalized_world_key(key)),
2562 None => format!("cm32p2"),
2563 };
2564 (module, func.name.clone())
2565 }
2566 WasmImport::ResourceIntrinsic {
2567 interface,
2568 resource,
2569 intrinsic,
2570 } => {
2571 let name = self.types[resource].name.as_ref().unwrap();
2572 let (prefix, name) = match intrinsic {
2573 ResourceIntrinsic::ImportedDrop => ("", format!("{name}_drop")),
2574 ResourceIntrinsic::ExportedDrop => ("_ex_", format!("{name}_drop")),
2575 ResourceIntrinsic::ExportedNew => ("_ex_", format!("{name}_new")),
2576 ResourceIntrinsic::ExportedRep => ("_ex_", format!("{name}_rep")),
2577 };
2578 let module = match interface {
2579 Some(key) => {
2580 format!("cm32p2|{prefix}{}", self.name_canonicalized_world_key(key))
2581 }
2582 None => {
2583 assert_eq!(prefix, "");
2584 format!("cm32p2")
2585 }
2586 };
2587 (module, name)
2588 }
2589 WasmImport::FutureIntrinsic { .. } | WasmImport::StreamIntrinsic { .. } => {
2590 panic!(
2591 "at the time of writing, standard32 name mangling only supports the \
2592 synchronous ABI and does not define future/stream intrinsic imports; \
2593 use legacy mangling for these imports"
2594 )
2595 }
2596 },
2597 ManglingAndAbi::Legacy(abi) => match import {
2598 WasmImport::Func { interface, func } => {
2599 let module = match interface {
2600 Some(key) => self.name_world_key(key),
2601 None => format!("$root"),
2602 };
2603 (module, format!("{}{}", abi.import_prefix(), func.name))
2604 }
2605 WasmImport::ResourceIntrinsic {
2606 interface,
2607 resource,
2608 intrinsic,
2609 } => {
2610 let name = self.types[resource].name.as_ref().unwrap();
2611 let (prefix, name) = match intrinsic {
2612 ResourceIntrinsic::ImportedDrop => ("", format!("[resource-drop]{name}")),
2613 ResourceIntrinsic::ExportedDrop => {
2614 ("[export]", format!("[resource-drop]{name}"))
2615 }
2616 ResourceIntrinsic::ExportedNew => {
2617 ("[export]", format!("[resource-new]{name}"))
2618 }
2619 ResourceIntrinsic::ExportedRep => {
2620 ("[export]", format!("[resource-rep]{name}"))
2621 }
2622 };
2623 let module = match interface {
2624 Some(key) => format!("{prefix}{}", self.name_world_key(key)),
2625 None => {
2626 assert_eq!(prefix, "");
2627 format!("$root")
2628 }
2629 };
2630 (module, format!("{}{name}", abi.import_prefix()))
2631 }
2632 WasmImport::FutureIntrinsic {
2633 interface,
2634 func,
2635 ty,
2636 intrinsic,
2637 exported,
2638 async_,
2639 } => {
2640 let module_prefix = if exported { "[export]" } else { "" };
2641 let module = match interface {
2642 Some(key) => format!("{module_prefix}{}", self.name_world_key(key)),
2643 None => format!("{module_prefix}$root"),
2644 };
2645 let type_index = match ty {
2646 Some(ty) => func
2647 .find_futures_and_streams(self)
2648 .into_iter()
2649 .position(|candidate| candidate == ty)
2650 .unwrap_or_else(|| {
2651 panic!(
2652 "future type {ty:?} not found in `find_futures_and_streams` for `{}`",
2653 func.name
2654 )
2655 })
2656 .to_string(),
2657 None => "unit".to_string(),
2658 };
2659 let (async_prefix, name) = match intrinsic {
2660 FutureIntrinsic::New => {
2661 assert!(!async_, "future.new cannot be async-lowered");
2662 ("", "new")
2663 }
2664 FutureIntrinsic::Read => {
2665 (if async_ { "[async-lower]" } else { "" }, "read")
2666 }
2667 FutureIntrinsic::Write => {
2668 (if async_ { "[async-lower]" } else { "" }, "write")
2669 }
2670 FutureIntrinsic::CancelRead => {
2671 (if async_ { "[async-lower]" } else { "" }, "cancel-read")
2672 }
2673 FutureIntrinsic::CancelWrite => {
2674 (if async_ { "[async-lower]" } else { "" }, "cancel-write")
2675 }
2676 FutureIntrinsic::DropReadable => {
2677 assert!(!async_, "future.drop-readable cannot be async-lowered");
2678 ("", "drop-readable")
2679 }
2680 FutureIntrinsic::DropWritable => {
2681 assert!(!async_, "future.drop-writable cannot be async-lowered");
2682 ("", "drop-writable")
2683 }
2684 };
2685 (
2686 module,
2687 format!("{async_prefix}[future-{name}-{type_index}]{}", func.name),
2688 )
2689 }
2690 WasmImport::StreamIntrinsic {
2691 interface,
2692 func,
2693 ty,
2694 intrinsic,
2695 exported,
2696 async_,
2697 } => {
2698 let module_prefix = if exported { "[export]" } else { "" };
2699 let module = match interface {
2700 Some(key) => format!("{module_prefix}{}", self.name_world_key(key)),
2701 None => format!("{module_prefix}$root"),
2702 };
2703 let type_index = match ty {
2704 Some(ty) => func
2705 .find_futures_and_streams(self)
2706 .into_iter()
2707 .position(|candidate| candidate == ty)
2708 .unwrap_or_else(|| {
2709 panic!(
2710 "stream type {ty:?} not found in `find_futures_and_streams` for `{}`",
2711 func.name
2712 )
2713 })
2714 .to_string(),
2715 None => "unit".to_string(),
2716 };
2717 let (async_prefix, name) = match intrinsic {
2718 StreamIntrinsic::New => {
2719 assert!(!async_, "stream.new cannot be async-lowered");
2720 ("", "new")
2721 }
2722 StreamIntrinsic::Read => {
2723 (if async_ { "[async-lower]" } else { "" }, "read")
2724 }
2725 StreamIntrinsic::Write => {
2726 (if async_ { "[async-lower]" } else { "" }, "write")
2727 }
2728 StreamIntrinsic::CancelRead => {
2729 (if async_ { "[async-lower]" } else { "" }, "cancel-read")
2730 }
2731 StreamIntrinsic::CancelWrite => {
2732 (if async_ { "[async-lower]" } else { "" }, "cancel-write")
2733 }
2734 StreamIntrinsic::DropReadable => {
2735 assert!(!async_, "stream.drop-readable cannot be async-lowered");
2736 ("", "drop-readable")
2737 }
2738 StreamIntrinsic::DropWritable => {
2739 assert!(!async_, "stream.drop-writable cannot be async-lowered");
2740 ("", "drop-writable")
2741 }
2742 };
2743 (
2744 module,
2745 format!("{async_prefix}[stream-{name}-{type_index}]{}", func.name),
2746 )
2747 }
2748 },
2749 }
2750 }
2751
2752 pub fn wasm_export_name(&self, mangling: ManglingAndAbi, export: WasmExport<'_>) -> String {
2756 match mangling {
2757 ManglingAndAbi::Standard32 => match export {
2758 WasmExport::Func {
2759 interface,
2760 func,
2761 kind,
2762 } => {
2763 let mut name = String::from("cm32p2|");
2764 if let Some(interface) = interface {
2765 let s = self.name_canonicalized_world_key(interface);
2766 name.push_str(&s);
2767 }
2768 name.push_str("|");
2769 name.push_str(&func.name);
2770 match kind {
2771 WasmExportKind::Normal => {}
2772 WasmExportKind::PostReturn => name.push_str("_post"),
2773 WasmExportKind::Callback => todo!(
2774 "not yet supported: \
2775 async callback functions using standard name mangling"
2776 ),
2777 }
2778 name
2779 }
2780 WasmExport::ResourceDtor {
2781 interface,
2782 resource,
2783 } => {
2784 let name = self.types[resource].name.as_ref().unwrap();
2785 let interface = self.name_canonicalized_world_key(interface);
2786 format!("cm32p2|{interface}|{name}_dtor")
2787 }
2788 WasmExport::Memory => "cm32p2_memory".to_string(),
2789 WasmExport::Initialize => "cm32p2_initialize".to_string(),
2790 WasmExport::Realloc => "cm32p2_realloc".to_string(),
2791 },
2792 ManglingAndAbi::Legacy(abi) => match export {
2793 WasmExport::Func {
2794 interface,
2795 func,
2796 kind,
2797 } => {
2798 let mut name = abi.export_prefix().to_string();
2799 match kind {
2800 WasmExportKind::Normal => {}
2801 WasmExportKind::PostReturn => name.push_str("cabi_post_"),
2802 WasmExportKind::Callback => {
2803 assert!(matches!(abi, LiftLowerAbi::AsyncCallback));
2804 name = format!("[callback]{name}")
2805 }
2806 }
2807 if let Some(interface) = interface {
2808 let s = self.name_world_key(interface);
2809 name.push_str(&s);
2810 name.push_str("#");
2811 }
2812 name.push_str(&func.name);
2813 name
2814 }
2815 WasmExport::ResourceDtor {
2816 interface,
2817 resource,
2818 } => {
2819 let name = self.types[resource].name.as_ref().unwrap();
2820 let interface = self.name_world_key(interface);
2821 format!("{}{interface}#[dtor]{name}", abi.export_prefix())
2822 }
2823 WasmExport::Memory => "memory".to_string(),
2824 WasmExport::Initialize => "_initialize".to_string(),
2825 WasmExport::Realloc => "cabi_realloc".to_string(),
2826 },
2827 }
2828 }
2829
2830 pub fn generate_nominal_type_ids(&mut self, world_id: WorldId) {
2870 let mut seen = HashSet::new();
2871 let mut interface_keys_rewritten = HashSet::new();
2872 let mut maps = CloneMaps::default();
2873
2874 let world = &mut self.worlds[world_id];
2877 let mut imports = mem::take(&mut world.imports);
2878 let mut exports = mem::take(&mut world.exports);
2879
2880 log::trace!("nominalizing world imports");
2884 self.nominalize_world_items(
2885 &mut maps,
2886 world_id,
2887 &mut imports,
2888 &mut seen,
2889 &mut interface_keys_rewritten,
2890 );
2891 log::trace!("nominalizing world exports");
2892 self.nominalize_world_items(
2893 &mut maps,
2894 world_id,
2895 &mut exports,
2896 &mut seen,
2897 &mut interface_keys_rewritten,
2898 );
2899
2900 let world = &mut self.worlds[world_id];
2902 assert!(world.imports.is_empty());
2903 assert!(world.exports.is_empty());
2904 world.imports = imports;
2905 world.exports = exports;
2906
2907 #[cfg(debug_assertions)]
2908 self.assert_valid();
2909 }
2910
2911 fn nominalize_world_items(
2934 &mut self,
2935 maps: &mut CloneMaps,
2936 world: WorldId,
2937 items: &mut IndexMap<WorldKey, WorldItem>,
2938 seen: &mut HashSet<InterfaceId>,
2939 interface_keys_rewritten: &mut HashSet<InterfaceId>,
2940 ) {
2941 let mut order = items.iter().enumerate().collect::<Vec<_>>();
3039 order.sort_by_key(|(_, (key, item))| match (key, item) {
3040 (WorldKey::Name(_), WorldItem::Interface { .. }) => 1,
3041 _ => 0,
3042 });
3043 let mut to_rewrite = IndexMap::default();
3044 for (i, (key, item)) in order {
3045 let id = match item {
3046 WorldItem::Interface { id, .. } => *id,
3047
3048 WorldItem::Function(_) | WorldItem::Type { .. } => continue,
3051 };
3052
3053 let duplicated = !seen.insert(id);
3059 let any_dep_rewritten = self
3060 .interface_direct_deps(id)
3061 .any(|dep| interface_keys_rewritten.contains(&dep));
3062 if !(duplicated || any_dep_rewritten) {
3063 log::trace!("{} already nominal", self.name_world_key(key));
3064 continue;
3065 }
3066 log::trace!("{} getting rewritten nominal", self.name_world_key(key));
3067
3068 let is_name = matches!(key, WorldKey::Name(_));
3073 if !is_name {
3074 assert!(interface_keys_rewritten.insert(id));
3075 }
3076
3077 to_rewrite
3078 .entry(id)
3079 .or_insert(Vec::new())
3080 .push((i, is_name));
3081 }
3082
3083 for (id, mut list) in to_rewrite {
3114 list.sort_by_key(|(_, is_name)| if *is_name { 0 } else { 1 });
3115 for (i, is_name) in list {
3116 let prev_maps = if is_name { Some(maps.clone()) } else { None };
3117
3118 let mut cloner = clone::Cloner::new(
3119 self,
3120 maps,
3121 TypeOwner::World(world),
3122 TypeOwner::World(world),
3123 );
3124
3125 let mut new_id = id;
3126 cloner.new_package = cloner.resolve.interfaces[id].package;
3127 cloner.interface(&mut new_id);
3128 let (key, prev) = items.get_index_mut(i).unwrap();
3129 match prev {
3130 WorldItem::Interface { id, .. } => *id = new_id,
3131 _ => unreachable!(),
3132 }
3133
3134 match key {
3135 WorldKey::Interface(_) => {
3141 items.replace_index(i, WorldKey::Interface(new_id)).unwrap();
3142 }
3143
3144 WorldKey::Name(_) => {}
3147 }
3148
3149 if let Some(prev) = prev_maps {
3150 *maps = prev;
3151 }
3152 }
3153 }
3154 }
3155}
3156
3157#[derive(Debug)]
3159pub enum WasmImport<'a> {
3160 Func {
3162 interface: Option<&'a WorldKey>,
3167
3168 func: &'a Function,
3170 },
3171
3172 ResourceIntrinsic {
3174 interface: Option<&'a WorldKey>,
3176
3177 resource: TypeId,
3179
3180 intrinsic: ResourceIntrinsic,
3182 },
3183
3184 FutureIntrinsic {
3186 interface: Option<&'a WorldKey>,
3188
3189 func: &'a Function,
3191
3192 ty: Option<TypeId>,
3196
3197 intrinsic: FutureIntrinsic,
3199
3200 exported: bool,
3204
3205 async_: bool,
3209 },
3210
3211 StreamIntrinsic {
3213 interface: Option<&'a WorldKey>,
3215
3216 func: &'a Function,
3218
3219 ty: Option<TypeId>,
3223
3224 intrinsic: StreamIntrinsic,
3226
3227 exported: bool,
3231
3232 async_: bool,
3236 },
3237}
3238
3239#[derive(Debug)]
3242pub enum ResourceIntrinsic {
3243 ImportedDrop,
3244 ExportedDrop,
3245 ExportedNew,
3246 ExportedRep,
3247}
3248
3249#[derive(Debug)]
3252pub enum FutureIntrinsic {
3253 New,
3254 Read,
3255 Write,
3256 CancelRead,
3257 CancelWrite,
3258 DropReadable,
3259 DropWritable,
3260}
3261
3262#[derive(Debug)]
3265pub enum StreamIntrinsic {
3266 New,
3267 Read,
3268 Write,
3269 CancelRead,
3270 CancelWrite,
3271 DropReadable,
3272 DropWritable,
3273}
3274
3275#[derive(Debug)]
3278pub enum WasmExportKind {
3279 Normal,
3281
3282 PostReturn,
3284
3285 Callback,
3287}
3288
3289#[derive(Debug)]
3292pub enum WasmExport<'a> {
3293 Func {
3295 interface: Option<&'a WorldKey>,
3298
3299 func: &'a Function,
3301
3302 kind: WasmExportKind,
3304 },
3305
3306 ResourceDtor {
3308 interface: &'a WorldKey,
3310 resource: TypeId,
3312 },
3313
3314 Memory,
3316
3317 Initialize,
3319
3320 Realloc,
3322}
3323
3324#[derive(Default)]
3327pub struct Remap {
3328 pub types: Vec<Option<TypeId>>,
3329 pub interfaces: Vec<Option<InterfaceId>>,
3330 pub worlds: Vec<Option<WorldId>>,
3331 pub packages: Vec<PackageId>,
3332
3333 own_handles: HashMap<TypeId, TypeId>,
3343
3344 type_has_borrow: Vec<Option<bool>>,
3345}
3346
3347fn apply_map<T>(map: &[Option<Id<T>>], id: Id<T>, desc: &str, span: Span) -> ResolveResult<Id<T>> {
3348 match map.get(id.index()) {
3349 Some(Some(id)) => Ok(*id),
3350 Some(None) => {
3351 let msg = format!(
3352 "found a reference to a {desc} which is excluded \
3353 due to its feature not being activated"
3354 );
3355 Err(ResolveError::new_semantic(span, msg))
3356 }
3357 None => panic!("request to remap a {desc} that has not yet been registered"),
3358 }
3359}
3360
3361fn rename(original_name: &str, include_name: &IncludeName) -> Option<String> {
3362 if original_name == include_name.name {
3363 return Some(include_name.as_.to_string());
3364 }
3365 let (kind, rest) = original_name.split_once(']')?;
3366 match rest.split_once('.') {
3367 Some((name, rest)) if name == include_name.name => {
3368 Some(format!("{kind}]{}.{rest}", include_name.as_))
3369 }
3370 _ if rest == include_name.name => Some(format!("{kind}]{}", include_name.as_)),
3371 _ => None,
3372 }
3373}
3374
3375impl Remap {
3376 pub fn map_type(&self, id: TypeId, span: Span) -> ResolveResult<TypeId> {
3377 apply_map(&self.types, id, "type", span)
3378 }
3379
3380 pub fn map_interface(&self, id: InterfaceId, span: Span) -> ResolveResult<InterfaceId> {
3381 apply_map(&self.interfaces, id, "interface", span)
3382 }
3383
3384 pub fn map_world(&self, id: WorldId, span: Span) -> ResolveResult<WorldId> {
3385 apply_map(&self.worlds, id, "world", span)
3386 }
3387
3388 pub fn map_world_for_type(&self, id: WorldId, span: Span) -> ResolveResult<WorldId> {
3389 self.map_world(id, span).map_err(|e| {
3390 ResolveError::new_semantic(
3391 span,
3392 format!("{e}; this type is not gated by a feature but its world is"),
3393 )
3394 })
3395 }
3396
3397 pub fn map_interface_for_type(
3398 &self,
3399 id: InterfaceId,
3400 span: Span,
3401 ) -> ResolveResult<InterfaceId> {
3402 self.map_interface(id, span).map_err(|e| {
3403 ResolveError::new_semantic(
3404 span,
3405 format!("{e}; this type is not gated by a feature but its interface is"),
3406 )
3407 })
3408 }
3409
3410 fn append(
3411 &mut self,
3412 resolve: &mut Resolve,
3413 unresolved: UnresolvedPackage,
3414 ) -> ResolveResult<PackageId> {
3415 let pkgid = resolve.packages.alloc(Package {
3416 name: unresolved.name.clone(),
3417 docs: unresolved.docs.clone(),
3418 interfaces: Default::default(),
3419 worlds: Default::default(),
3420 });
3421 assert!(
3422 !resolve.package_names.contains_key(&unresolved.name),
3423 "attempting to re-add package `{}` when it's already present in this `Resolve`",
3424 unresolved.name,
3425 );
3426 resolve.package_names.insert(unresolved.name.clone(), pkgid);
3427 self.process_foreign_deps(resolve, pkgid, &unresolved)?;
3428
3429 let foreign_types = self.types.len();
3430 let foreign_interfaces = self.interfaces.len();
3431 let foreign_worlds = self.worlds.len();
3432
3433 for (id, mut ty) in unresolved.types.into_iter().skip(foreign_types) {
3439 let span = ty.span;
3440 if !resolve.include_stability(&ty.stability, &pkgid, span)? {
3441 self.types.push(None);
3442 continue;
3443 }
3444
3445 self.update_typedef(resolve, &mut ty, span)?;
3446 let new_id = resolve.types.alloc(ty);
3447 assert_eq!(self.types.len(), id.index());
3448
3449 let new_id = match resolve.types[new_id] {
3450 TypeDef {
3455 name: None,
3456 owner: TypeOwner::None,
3457 kind: TypeDefKind::Handle(Handle::Own(id)),
3458 docs: _,
3459 stability: _,
3460 span: _,
3461 } => *self.own_handles.entry(id).or_insert(new_id),
3462
3463 _ => new_id,
3466 };
3467 self.types.push(Some(new_id));
3468 }
3469
3470 for (id, mut iface) in unresolved.interfaces.into_iter().skip(foreign_interfaces) {
3473 let span = iface.span;
3474 if !resolve.include_stability(&iface.stability, &pkgid, span)? {
3475 self.interfaces.push(None);
3476 continue;
3477 }
3478 assert!(iface.package.is_none());
3479 iface.package = Some(pkgid);
3480 self.update_interface(resolve, &mut iface)?;
3481 let new_id = resolve.interfaces.alloc(iface);
3482 assert_eq!(self.interfaces.len(), id.index());
3483 self.interfaces.push(Some(new_id));
3484 }
3485
3486 for id in self.types.iter().skip(foreign_types) {
3489 let id = match id {
3490 Some(id) => *id,
3491 None => continue,
3492 };
3493 let span = resolve.types[id].span;
3494 match &mut resolve.types[id].owner {
3495 TypeOwner::Interface(iface_id) => {
3496 *iface_id = self.map_interface_for_type(*iface_id, span)?;
3497 }
3498 TypeOwner::World(_) | TypeOwner::None => {}
3499 }
3500 }
3501
3502 for (id, mut world) in unresolved.worlds.into_iter().skip(foreign_worlds) {
3510 let world_span = world.span;
3511 if !resolve.include_stability(&world.stability, &pkgid, world_span)? {
3512 self.worlds.push(None);
3513 continue;
3514 }
3515 self.update_world(&mut world, resolve, &pkgid)?;
3516
3517 let new_id = resolve.worlds.alloc(world);
3518 assert_eq!(self.worlds.len(), id.index());
3519 self.worlds.push(Some(new_id));
3520 }
3521
3522 for id in self.types.iter().skip(foreign_types) {
3524 let id = match id {
3525 Some(id) => *id,
3526 None => continue,
3527 };
3528 let span = resolve.types[id].span;
3529 match &mut resolve.types[id].owner {
3530 TypeOwner::World(world_id) => {
3531 *world_id = self.map_world_for_type(*world_id, span)?;
3532 }
3533 TypeOwner::Interface(_) | TypeOwner::None => {}
3534 }
3535 }
3536
3537 for id in self.worlds.iter().skip(foreign_worlds) {
3554 let Some(id) = *id else {
3555 continue;
3556 };
3557 self.process_world_includes(id, resolve, &pkgid)?;
3558
3559 let world_span = resolve.worlds[id].span;
3560 resolve.elaborate_world(id, world_span)?;
3561 }
3562
3563 for id in self.interfaces.iter().skip(foreign_interfaces) {
3565 let id = match id {
3566 Some(id) => *id,
3567 None => continue,
3568 };
3569 let iface = &mut resolve.interfaces[id];
3570 iface.package = Some(pkgid);
3571 if let Some(name) = &iface.name {
3572 let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), id);
3573 assert!(prev.is_none());
3574 }
3575 }
3576 for id in self.worlds.iter().skip(foreign_worlds) {
3577 let id = match id {
3578 Some(id) => *id,
3579 None => continue,
3580 };
3581 let world = &mut resolve.worlds[id];
3582 world.package = Some(pkgid);
3583 let prev = resolve.packages[pkgid]
3584 .worlds
3585 .insert(world.name.clone(), id);
3586 assert!(prev.is_none());
3587 }
3588 Ok(pkgid)
3589 }
3590
3591 fn process_foreign_deps(
3592 &mut self,
3593 resolve: &mut Resolve,
3594 pkgid: PackageId,
3595 unresolved: &UnresolvedPackage,
3596 ) -> ResolveResult<()> {
3597 let mut world_to_package = HashMap::new();
3600 let mut interface_to_package = HashMap::new();
3601 for (i, (pkg_name, worlds_or_ifaces)) in unresolved.foreign_deps.iter().enumerate() {
3602 for (name, (item, stabilities)) in worlds_or_ifaces {
3603 match item {
3604 AstItem::Interface(unresolved_interface_id) => {
3605 let prev = interface_to_package.insert(
3606 *unresolved_interface_id,
3607 (pkg_name, name, unresolved.foreign_dep_spans[i], stabilities),
3608 );
3609 assert!(prev.is_none());
3610 }
3611 AstItem::World(unresolved_world_id) => {
3612 let prev = world_to_package.insert(
3613 *unresolved_world_id,
3614 (pkg_name, name, unresolved.foreign_dep_spans[i], stabilities),
3615 );
3616 assert!(prev.is_none());
3617 }
3618 }
3619 }
3620 }
3621
3622 self.process_foreign_interfaces(unresolved, &interface_to_package, resolve, &pkgid)?;
3626
3627 self.process_foreign_worlds(unresolved, &world_to_package, resolve, &pkgid)?;
3631
3632 self.process_foreign_types(unresolved, pkgid, resolve)?;
3635
3636 for (id, span) in unresolved.required_resource_types.iter() {
3637 let Ok(mut id) = self.map_type(*id, *span) else {
3642 continue;
3643 };
3644 loop {
3645 match resolve.types[id].kind {
3646 TypeDefKind::Type(Type::Id(i)) => id = i,
3647 TypeDefKind::Resource => break,
3648 _ => {
3649 return Err(ResolveError::new_semantic(
3650 *span,
3651 "type used in a handle must be a resource",
3652 ));
3653 }
3654 }
3655 }
3656 }
3657
3658 #[cfg(debug_assertions)]
3659 resolve.assert_valid();
3660
3661 Ok(())
3662 }
3663
3664 fn process_foreign_interfaces(
3665 &mut self,
3666 unresolved: &UnresolvedPackage,
3667 interface_to_package: &HashMap<InterfaceId, (&PackageName, &String, Span, &Vec<Stability>)>,
3668 resolve: &mut Resolve,
3669 parent_pkg_id: &PackageId,
3670 ) -> ResolveResult<()> {
3671 for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() {
3672 let (pkg_name, interface, span, stabilities) =
3673 match interface_to_package.get(&unresolved_iface_id) {
3674 Some(items) => *items,
3675 None => break,
3679 };
3680
3681 let pkgid = resolve
3682 .package_names
3683 .get(pkg_name)
3684 .copied()
3685 .ok_or_else(|| {
3686 ResolveError::from(ResolveErrorKind::PackageNotFound {
3687 span,
3688 requested: pkg_name.clone(),
3689 known: resolve.package_names.keys().cloned().collect(),
3690 })
3691 })?;
3692
3693 assert!(unresolved_iface.functions.is_empty());
3695
3696 let pkg = &resolve.packages[pkgid];
3697 let iface_span = unresolved_iface.span;
3698
3699 let mut enabled = false;
3700 for stability in stabilities {
3701 if resolve.include_stability(stability, parent_pkg_id, iface_span)? {
3702 enabled = true;
3703 break;
3704 }
3705 }
3706
3707 if !enabled {
3708 self.interfaces.push(None);
3709 continue;
3710 }
3711
3712 let iface_id = pkg.interfaces.get(interface).copied().ok_or_else(|| {
3713 ResolveError::new_semantic(iface_span, "interface not found in package")
3714 })?;
3715 assert_eq!(self.interfaces.len(), unresolved_iface_id.index());
3716 self.interfaces.push(Some(iface_id));
3717 }
3718 for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) {
3719 assert!(
3720 interface_to_package.get(&id).is_none(),
3721 "found foreign interface after local interface"
3722 );
3723 }
3724 Ok(())
3725 }
3726
3727 fn process_foreign_worlds(
3728 &mut self,
3729 unresolved: &UnresolvedPackage,
3730 world_to_package: &HashMap<WorldId, (&PackageName, &String, Span, &Vec<Stability>)>,
3731 resolve: &mut Resolve,
3732 parent_pkg_id: &PackageId,
3733 ) -> ResolveResult<()> {
3734 for (unresolved_world_id, unresolved_world) in unresolved.worlds.iter() {
3735 let (pkg_name, world, span, stabilities) =
3736 match world_to_package.get(&unresolved_world_id) {
3737 Some(items) => *items,
3738 None => break,
3741 };
3742
3743 let pkgid = resolve
3744 .package_names
3745 .get(pkg_name)
3746 .copied()
3747 .ok_or_else(|| {
3748 ResolveError::from(ResolveErrorKind::PackageNotFound {
3749 span,
3750 requested: pkg_name.clone(),
3751 known: resolve.package_names.keys().cloned().collect(),
3752 })
3753 })?;
3754 let pkg = &resolve.packages[pkgid];
3755 let world_span = unresolved_world.span;
3756
3757 let mut enabled = false;
3758 for stability in stabilities {
3759 if resolve.include_stability(stability, parent_pkg_id, world_span)? {
3760 enabled = true;
3761 break;
3762 }
3763 }
3764
3765 if !enabled {
3766 self.worlds.push(None);
3767 continue;
3768 }
3769
3770 let world_id = pkg.worlds.get(world).copied().ok_or_else(|| {
3771 ResolveError::new_semantic(world_span, "world not found in package")
3772 })?;
3773 assert_eq!(self.worlds.len(), unresolved_world_id.index());
3774 self.worlds.push(Some(world_id));
3775 }
3776 for (id, _) in unresolved.worlds.iter().skip(self.worlds.len()) {
3777 assert!(
3778 world_to_package.get(&id).is_none(),
3779 "found foreign world after local world"
3780 );
3781 }
3782 Ok(())
3783 }
3784
3785 fn process_foreign_types(
3786 &mut self,
3787 unresolved: &UnresolvedPackage,
3788 pkgid: PackageId,
3789 resolve: &mut Resolve,
3790 ) -> ResolveResult<()> {
3791 for (unresolved_type_id, unresolved_ty) in unresolved.types.iter() {
3792 match unresolved_ty.kind {
3796 TypeDefKind::Unknown => {}
3797 _ => break,
3798 }
3799
3800 let span = unresolved_ty.span;
3801 if !resolve.include_stability(&unresolved_ty.stability, &pkgid, span)? {
3802 self.types.push(None);
3803 continue;
3804 }
3805
3806 let unresolved_iface_id = match unresolved_ty.owner {
3807 TypeOwner::Interface(id) => id,
3808 _ => unreachable!(),
3809 };
3810 let iface_id = self.map_interface(unresolved_iface_id, Default::default())?;
3811 let name = unresolved_ty.name.as_ref().unwrap();
3812 let span = unresolved.unknown_type_spans[unresolved_type_id.index()];
3813 let type_id = *resolve.interfaces[iface_id]
3814 .types
3815 .get(name)
3816 .ok_or_else(|| {
3817 ResolveError::new_semantic(
3818 span,
3819 format!("type `{name}` not defined in interface"),
3820 )
3821 })?;
3822 assert_eq!(self.types.len(), unresolved_type_id.index());
3823 self.types.push(Some(type_id));
3824 }
3825 for (_, ty) in unresolved.types.iter().skip(self.types.len()) {
3826 if let TypeDefKind::Unknown = ty.kind {
3827 panic!("unknown type after defined type");
3828 }
3829 }
3830 Ok(())
3831 }
3832
3833 fn update_typedef(
3834 &mut self,
3835 resolve: &mut Resolve,
3836 ty: &mut TypeDef,
3837 span: Span,
3838 ) -> ResolveResult<()> {
3839 use crate::TypeDefKind::*;
3842 match &mut ty.kind {
3843 Handle(handle) => match handle {
3844 crate::Handle::Own(ty) | crate::Handle::Borrow(ty) => {
3845 self.update_type_id(ty, span)?
3846 }
3847 },
3848 Resource => {}
3849 Record(r) => {
3850 for field in r.fields.iter_mut() {
3851 self.update_ty(resolve, &mut field.ty, field.span)?
3852 }
3853 }
3854 Tuple(t) => {
3855 for ty in t.types.iter_mut() {
3856 self.update_ty(resolve, ty, span)?;
3857 }
3858 }
3859 Variant(v) => {
3860 for case in v.cases.iter_mut() {
3861 if let Some(t) = &mut case.ty {
3862 self.update_ty(resolve, t, span)?;
3863 }
3864 }
3865 }
3866 Option(t)
3867 | List(t, ..)
3868 | FixedLengthList(t, ..)
3869 | Future(Some(t))
3870 | Stream(Some(t)) => self.update_ty(resolve, t, span)?,
3871 Map(k, v) => {
3872 self.update_ty(resolve, k, span)?;
3873 self.update_ty(resolve, v, span)?;
3874 }
3875 Result(r) => {
3876 if let Some(ty) = &mut r.ok {
3877 self.update_ty(resolve, ty, span)?;
3878 }
3879 if let Some(ty) = &mut r.err {
3880 self.update_ty(resolve, ty, span)?;
3881 }
3882 }
3883
3884 Type(crate::Type::Id(id)) => self.update_type_id(id, span)?,
3889 Type(_) => {}
3890
3891 Flags(_) | Enum(_) | Future(None) | Stream(None) => {}
3893
3894 Unknown => unreachable!(),
3895 }
3896
3897 Ok(())
3898 }
3899
3900 fn update_ty(&mut self, resolve: &mut Resolve, ty: &mut Type, span: Span) -> ResolveResult<()> {
3901 let id = match ty {
3902 Type::Id(id) => id,
3903 _ => return Ok(()),
3904 };
3905 self.update_type_id(id, span)?;
3906
3907 let mut cur = *id;
3912 let points_to_resource = loop {
3913 match resolve.types[cur].kind {
3914 TypeDefKind::Type(Type::Id(id)) => cur = id,
3915 TypeDefKind::Resource => break true,
3916 _ => break false,
3917 }
3918 };
3919
3920 if points_to_resource {
3921 *id = *self.own_handles.entry(*id).or_insert_with(|| {
3922 resolve.types.alloc(TypeDef {
3923 name: None,
3924 owner: TypeOwner::None,
3925 kind: TypeDefKind::Handle(Handle::Own(*id)),
3926 docs: Default::default(),
3927 stability: Default::default(),
3928 span: Default::default(),
3929 })
3930 });
3931 }
3932 Ok(())
3933 }
3934
3935 fn update_type_id(&self, id: &mut TypeId, span: Span) -> ResolveResult<()> {
3936 *id = self.map_type(*id, span)?;
3937 Ok(())
3938 }
3939
3940 fn update_interface(
3941 &mut self,
3942 resolve: &mut Resolve,
3943 iface: &mut Interface,
3944 ) -> ResolveResult<()> {
3945 iface.types.retain(|_, ty| self.types[ty.index()].is_some());
3946 let iface_pkg_id = iface.package.as_ref().unwrap_or_else(|| {
3947 panic!(
3948 "unexpectedly missing package on interface [{}]",
3949 iface
3950 .name
3951 .as_ref()
3952 .map(String::as_str)
3953 .unwrap_or("<unknown>"),
3954 )
3955 });
3956
3957 for (_name, ty) in iface.types.iter_mut() {
3960 self.update_type_id(ty, iface.span)?;
3961 }
3962 for (_, func) in iface.functions.iter_mut() {
3963 let span = func.span;
3964 if !resolve.include_stability(&func.stability, iface_pkg_id, span)? {
3965 continue;
3966 }
3967 self.update_function(resolve, func, span)?
3968 }
3969
3970 for (name, func) in mem::take(&mut iface.functions) {
3973 if resolve.include_stability(&func.stability, iface_pkg_id, func.span)? {
3974 iface.functions.insert(name, func);
3975 }
3976 }
3977
3978 Ok(())
3979 }
3980
3981 fn update_function(
3982 &mut self,
3983 resolve: &mut Resolve,
3984 func: &mut Function,
3985 span: Span,
3986 ) -> ResolveResult<()> {
3987 if let Some(id) = func.kind.resource_mut() {
3988 self.update_type_id(id, span)?;
3989 }
3990 for param in func.params.iter_mut() {
3991 self.update_ty(resolve, &mut param.ty, span)?;
3992 }
3993 if let Some(ty) = &mut func.result {
3994 self.update_ty(resolve, ty, span)?;
3995 }
3996
3997 if let Some(ty) = &func.result {
3998 if self.type_has_borrow(resolve, ty) {
3999 return Err(ResolveError::new_semantic(
4000 span,
4001 format!(
4002 "function `{}` returns a type which contains a `borrow<T>` which is not supported",
4003 func.name,
4004 ),
4005 ));
4006 }
4007 }
4008
4009 Ok(())
4010 }
4011
4012 fn update_world(
4013 &mut self,
4014 world: &mut World,
4015 resolve: &mut Resolve,
4016 pkg_id: &PackageId,
4017 ) -> ResolveResult<()> {
4018 let imports = mem::take(&mut world.imports).into_iter().map(|p| (p, true));
4022 let exports = mem::take(&mut world.exports)
4023 .into_iter()
4024 .map(|p| (p, false));
4025 for ((mut name, mut item), import) in imports.chain(exports) {
4026 let span = item.span();
4027 if let WorldItem::Type { id, .. } = &mut item {
4030 *id = self.map_type(*id, span)?;
4031 }
4032 let stability = item.stability(resolve);
4033 if !resolve.include_stability(stability, pkg_id, span)? {
4034 continue;
4035 }
4036 self.update_world_key(&mut name, span)?;
4037 match &mut item {
4038 WorldItem::Interface { id, .. } => {
4039 *id = self.map_interface(*id, span)?;
4040 }
4041 WorldItem::Function(f) => {
4042 self.update_function(resolve, f, span)?;
4043 }
4044 WorldItem::Type { .. } => {
4045 }
4047 }
4048
4049 let dst = if import {
4050 &mut world.imports
4051 } else {
4052 &mut world.exports
4053 };
4054 let prev = dst.insert(name, item);
4055 assert!(prev.is_none());
4056 }
4057
4058 Ok(())
4059 }
4060
4061 fn process_world_includes(
4062 &self,
4063 id: WorldId,
4064 resolve: &mut Resolve,
4065 pkg_id: &PackageId,
4066 ) -> ResolveResult<()> {
4067 let world = &mut resolve.worlds[id];
4068 let includes = mem::take(&mut world.includes);
4071 for include in includes {
4072 if !resolve.include_stability(&include.stability, pkg_id, include.span)? {
4073 continue;
4074 }
4075 self.resolve_include(
4076 id,
4077 include.id,
4078 &include.names,
4079 include.span,
4080 pkg_id,
4081 resolve,
4082 )?;
4083 }
4084
4085 Self::validate_world_case_insensitive_names(resolve, id)?;
4087
4088 Ok(())
4089 }
4090
4091 fn validate_world_case_insensitive_names(
4095 resolve: &Resolve,
4096 world_id: WorldId,
4097 ) -> ResolveResult<()> {
4098 let world = &resolve.worlds[world_id];
4099
4100 let validate_names =
4102 |items: &IndexMap<WorldKey, WorldItem>, item_type: &str| -> ResolveResult<()> {
4103 let mut seen_lowercase: HashMap<String, String> = HashMap::new();
4104
4105 for key in items.keys() {
4106 if let WorldKey::Name(name) = key {
4108 let lowercase_name = name.to_lowercase();
4109
4110 if let Some(existing_name) = seen_lowercase.get(&lowercase_name) {
4111 if existing_name != name {
4114 return Err(ResolveError::new_semantic(
4118 Span::default(),
4119 format!(
4120 "{item_type} `{name}` in world `{}` conflicts with \
4121 {item_type} `{existing_name}` \
4122 (kebab-case identifiers are case-insensitive)",
4123 world.name,
4124 ),
4125 ));
4126 }
4127 }
4128
4129 seen_lowercase.insert(lowercase_name, name.clone());
4130 }
4131 }
4132
4133 Ok(())
4134 };
4135
4136 validate_names(&world.imports, "import")?;
4137 validate_names(&world.exports, "export")?;
4138
4139 Ok(())
4140 }
4141
4142 fn update_world_key(&self, key: &mut WorldKey, span: Span) -> ResolveResult<()> {
4143 match key {
4144 WorldKey::Name(_) => {}
4145 WorldKey::Interface(id) => {
4146 *id = self.map_interface(*id, span)?;
4147 }
4148 }
4149 Ok(())
4150 }
4151
4152 fn resolve_include(
4153 &self,
4154 id: WorldId,
4155 include_world_id_orig: WorldId,
4156 names: &[IncludeName],
4157 span: Span,
4158 pkg_id: &PackageId,
4159 resolve: &mut Resolve,
4160 ) -> ResolveResult<()> {
4161 let world = &resolve.worlds[id];
4162 let include_world_id = self.map_world(include_world_id_orig, span)?;
4163 let include_world = resolve.worlds[include_world_id].clone();
4164 let mut names_ = names.to_owned();
4165 let is_external_include = world.package != include_world.package;
4166
4167 for import in include_world.imports.iter() {
4169 self.remove_matching_name(import, &mut names_);
4170 }
4171 for export in include_world.exports.iter() {
4172 self.remove_matching_name(export, &mut names_);
4173 }
4174 if !names_.is_empty() {
4175 return Err(ResolveError::new_semantic(
4176 span,
4177 format!(
4178 "no import or export kebab-name `{}`. Note that an ID does not support renaming",
4179 names_[0].name
4180 ),
4181 ));
4182 }
4183
4184 let mut maps = Default::default();
4185 let mut cloner = clone::Cloner::new(
4186 resolve,
4187 &mut maps,
4188 TypeOwner::World(if is_external_include {
4189 include_world_id
4190 } else {
4191 include_world_id
4192 }),
4194 TypeOwner::World(id),
4195 );
4196 cloner.new_package = Some(*pkg_id);
4197
4198 for import in include_world.imports.iter() {
4200 self.resolve_include_item(
4201 &mut cloner,
4202 names,
4203 |resolve| &mut resolve.worlds[id].imports,
4204 import,
4205 span,
4206 "import",
4207 is_external_include,
4208 )?;
4209 }
4210
4211 for export in include_world.exports.iter() {
4212 self.resolve_include_item(
4213 &mut cloner,
4214 names,
4215 |resolve| &mut resolve.worlds[id].exports,
4216 export,
4217 span,
4218 "export",
4219 is_external_include,
4220 )?;
4221 }
4222 Ok(())
4223 }
4224
4225 fn resolve_include_item(
4226 &self,
4227 cloner: &mut clone::Cloner<'_>,
4228 names: &[IncludeName],
4229 get_items: impl Fn(&mut Resolve) -> &mut IndexMap<WorldKey, WorldItem>,
4230 item: (&WorldKey, &WorldItem),
4231 span: Span,
4232 item_type: &str,
4233 is_external_include: bool,
4234 ) -> ResolveResult<()> {
4235 match item.0 {
4236 WorldKey::Name(n) => {
4237 let n = names
4238 .into_iter()
4239 .find_map(|include_name| rename(n, include_name))
4240 .unwrap_or(n.clone());
4241
4242 let mut new_item = item.1.clone();
4248 let key = WorldKey::Name(n.clone());
4249 cloner.world_item(&key, &mut new_item);
4250 match &mut new_item {
4251 WorldItem::Function(f) => f.name = n.clone(),
4252 WorldItem::Type { id, .. } => cloner.resolve.types[*id].name = Some(n.clone()),
4253 WorldItem::Interface { .. } => {}
4254 }
4255
4256 let prev = get_items(cloner.resolve).insert(key, new_item);
4257 if prev.is_some() {
4258 return Err(ResolveError::from(ResolveErrorKind::ItemShadowing {
4259 span,
4260 item_type: item_type.to_owned(),
4261 name: n,
4262 }));
4263 }
4264 }
4265 key @ WorldKey::Interface(_) => {
4266 let prev = get_items(cloner.resolve)
4267 .entry(key.clone())
4268 .or_insert(item.1.clone());
4269 match (&item.1, prev) {
4270 (
4271 WorldItem::Interface {
4272 id: aid,
4273 stability: astability,
4274 span: aspan,
4275 },
4276 WorldItem::Interface {
4277 id: bid,
4278 stability: bstability,
4279 ..
4280 },
4281 ) => {
4282 assert_eq!(*aid, *bid);
4283 merge_include_stability(
4284 astability,
4285 bstability,
4286 is_external_include,
4287 *aspan,
4288 )?;
4289 }
4290 (WorldItem::Interface { .. }, _) => unreachable!(),
4291 (WorldItem::Function(_), _) => unreachable!(),
4292 (WorldItem::Type { .. }, _) => unreachable!(),
4293 }
4294 }
4295 };
4296
4297 Ok(())
4298 }
4299
4300 fn remove_matching_name(&self, item: (&WorldKey, &WorldItem), names: &mut Vec<IncludeName>) {
4301 match item.0 {
4302 WorldKey::Name(n) => {
4303 names.retain(|name| rename(n, name).is_none());
4304 }
4305 _ => {}
4306 }
4307 }
4308
4309 fn type_has_borrow(&mut self, resolve: &Resolve, ty: &Type) -> bool {
4310 let id = match ty {
4311 Type::Id(id) => *id,
4312 _ => return false,
4313 };
4314
4315 if let Some(Some(has_borrow)) = self.type_has_borrow.get(id.index()) {
4316 return *has_borrow;
4317 }
4318
4319 let result = self.typedef_has_borrow(resolve, &resolve.types[id]);
4320 if self.type_has_borrow.len() <= id.index() {
4321 self.type_has_borrow.resize(id.index() + 1, None);
4322 }
4323 self.type_has_borrow[id.index()] = Some(result);
4324 result
4325 }
4326
4327 fn typedef_has_borrow(&mut self, resolve: &Resolve, ty: &TypeDef) -> bool {
4328 match &ty.kind {
4329 TypeDefKind::Type(t) => self.type_has_borrow(resolve, t),
4330 TypeDefKind::Variant(v) => v
4331 .cases
4332 .iter()
4333 .filter_map(|case| case.ty.as_ref())
4334 .any(|ty| self.type_has_borrow(resolve, ty)),
4335 TypeDefKind::Handle(Handle::Borrow(_)) => true,
4336 TypeDefKind::Handle(Handle::Own(_)) => false,
4337 TypeDefKind::Resource => false,
4338 TypeDefKind::Record(r) => r
4339 .fields
4340 .iter()
4341 .any(|case| self.type_has_borrow(resolve, &case.ty)),
4342 TypeDefKind::Flags(_) => false,
4343 TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.type_has_borrow(resolve, t)),
4344 TypeDefKind::Enum(_) => false,
4345 TypeDefKind::List(ty)
4346 | TypeDefKind::FixedLengthList(ty, ..)
4347 | TypeDefKind::Future(Some(ty))
4348 | TypeDefKind::Stream(Some(ty))
4349 | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty),
4350 TypeDefKind::Map(k, v) => {
4351 self.type_has_borrow(resolve, k) || self.type_has_borrow(resolve, v)
4352 }
4353 TypeDefKind::Result(r) => [&r.ok, &r.err]
4354 .iter()
4355 .filter_map(|t| t.as_ref())
4356 .any(|t| self.type_has_borrow(resolve, t)),
4357 TypeDefKind::Future(None) | TypeDefKind::Stream(None) => false,
4358 TypeDefKind::Unknown => unreachable!(),
4359 }
4360 }
4361}
4362
4363struct MergeMap<'a> {
4364 package_map: HashMap<PackageId, PackageId>,
4367
4368 interface_map: HashMap<InterfaceId, InterfaceId>,
4371
4372 type_map: HashMap<TypeId, TypeId>,
4375
4376 world_map: HashMap<WorldId, WorldId>,
4379
4380 interfaces_to_add: Vec<(String, PackageId, InterfaceId)>,
4388 worlds_to_add: Vec<(String, PackageId, WorldId)>,
4389
4390 from: &'a Resolve,
4392
4393 into: &'a Resolve,
4395}
4396
4397impl<'a> MergeMap<'a> {
4398 fn new(from: &'a Resolve, into: &'a Resolve) -> MergeMap<'a> {
4399 MergeMap {
4400 package_map: Default::default(),
4401 interface_map: Default::default(),
4402 type_map: Default::default(),
4403 world_map: Default::default(),
4404 interfaces_to_add: Default::default(),
4405 worlds_to_add: Default::default(),
4406 from,
4407 into,
4408 }
4409 }
4410
4411 fn build(&mut self) -> anyhow::Result<()> {
4412 for from_id in self.from.topological_packages() {
4413 let from = &self.from.packages[from_id];
4414 let into_id = match self.into.package_names.get(&from.name) {
4415 Some(id) => *id,
4416
4417 None => {
4420 log::trace!("adding unique package {}", from.name);
4421 continue;
4422 }
4423 };
4424 log::trace!("merging duplicate package {}", from.name);
4425
4426 self.build_package(from_id, into_id).with_context(|| {
4427 format!("failed to merge package `{}` into existing copy", from.name)
4428 })?;
4429 }
4430
4431 Ok(())
4432 }
4433
4434 fn build_package(&mut self, from_id: PackageId, into_id: PackageId) -> anyhow::Result<()> {
4435 let prev = self.package_map.insert(from_id, into_id);
4436 assert!(prev.is_none());
4437
4438 let from = &self.from.packages[from_id];
4439 let into = &self.into.packages[into_id];
4440
4441 for (name, from_interface_id) in from.interfaces.iter() {
4445 let into_interface_id = match into.interfaces.get(name) {
4446 Some(id) => *id,
4447 None => {
4448 log::trace!("adding unique interface {name}");
4449 self.interfaces_to_add
4450 .push((name.clone(), into_id, *from_interface_id));
4451 continue;
4452 }
4453 };
4454
4455 log::trace!("merging duplicate interfaces {name}");
4456 self.build_interface(*from_interface_id, into_interface_id)
4457 .with_context(|| format!("failed to merge interface `{name}`"))?;
4458 }
4459
4460 for (name, from_world_id) in from.worlds.iter() {
4461 let into_world_id = match into.worlds.get(name) {
4462 Some(id) => *id,
4463 None => {
4464 log::trace!("adding unique world {name}");
4465 self.worlds_to_add
4466 .push((name.clone(), into_id, *from_world_id));
4467 continue;
4468 }
4469 };
4470
4471 log::trace!("merging duplicate worlds {name}");
4472 self.build_world(*from_world_id, into_world_id)
4473 .with_context(|| format!("failed to merge world `{name}`"))?;
4474 }
4475
4476 Ok(())
4477 }
4478
4479 fn build_interface(
4480 &mut self,
4481 from_id: InterfaceId,
4482 into_id: InterfaceId,
4483 ) -> anyhow::Result<()> {
4484 let prev = self.interface_map.insert(from_id, into_id);
4485 assert!(prev.is_none());
4486
4487 let from_interface = &self.from.interfaces[from_id];
4488 let into_interface = &self.into.interfaces[into_id];
4489
4490 for (name, from_type_id) in from_interface.types.iter() {
4498 let into_type_id = match into_interface.types.get(name) {
4499 Some(id) => *id,
4500 None => continue,
4503 };
4504 let prev = self.type_map.insert(*from_type_id, into_type_id);
4505 assert!(prev.is_none());
4506
4507 self.build_type_id(*from_type_id, into_type_id)
4508 .with_context(|| format!("mismatch in type `{name}`"))?;
4509 }
4510
4511 for (name, from_func) in from_interface.functions.iter() {
4512 let into_func = match into_interface.functions.get(name) {
4513 Some(func) => func,
4514 None => continue,
4517 };
4518 self.build_function(from_func, into_func)
4519 .with_context(|| format!("mismatch in function `{name}`"))?;
4520 }
4521
4522 Ok(())
4523 }
4524
4525 fn build_type_id(&mut self, from_id: TypeId, into_id: TypeId) -> anyhow::Result<()> {
4526 let _ = from_id;
4530 let _ = into_id;
4531 Ok(())
4532 }
4533
4534 fn build_type(&mut self, from_ty: &Type, into_ty: &Type) -> anyhow::Result<()> {
4535 match (from_ty, into_ty) {
4536 (Type::Id(from), Type::Id(into)) => {
4537 self.build_type_id(*from, *into)?;
4538 }
4539 (from, into) if from != into => bail!("different kinds of types"),
4540 _ => {}
4541 }
4542 Ok(())
4543 }
4544
4545 fn build_function(&mut self, from_func: &Function, into_func: &Function) -> anyhow::Result<()> {
4546 if from_func.name != into_func.name {
4547 bail!(
4548 "different function names `{}` and `{}`",
4549 from_func.name,
4550 into_func.name
4551 );
4552 }
4553 match (&from_func.kind, &into_func.kind) {
4554 (FunctionKind::Freestanding, FunctionKind::Freestanding) => {}
4555 (FunctionKind::AsyncFreestanding, FunctionKind::AsyncFreestanding) => {}
4556
4557 (FunctionKind::Method(from), FunctionKind::Method(into))
4558 | (FunctionKind::Static(from), FunctionKind::Static(into))
4559 | (FunctionKind::AsyncMethod(from), FunctionKind::AsyncMethod(into))
4560 | (FunctionKind::AsyncStatic(from), FunctionKind::AsyncStatic(into))
4561 | (FunctionKind::Constructor(from), FunctionKind::Constructor(into)) => {
4562 self.build_type_id(*from, *into)
4563 .context("different function kind types")?;
4564 }
4565
4566 (FunctionKind::Method(_), _)
4567 | (FunctionKind::Constructor(_), _)
4568 | (FunctionKind::Static(_), _)
4569 | (FunctionKind::Freestanding, _)
4570 | (FunctionKind::AsyncFreestanding, _)
4571 | (FunctionKind::AsyncMethod(_), _)
4572 | (FunctionKind::AsyncStatic(_), _) => {
4573 bail!("different function kind types")
4574 }
4575 }
4576
4577 if from_func.params.len() != into_func.params.len() {
4578 bail!("different number of function parameters");
4579 }
4580 for (from_param, into_param) in from_func.params.iter().zip(&into_func.params) {
4581 if from_param.name != into_param.name {
4582 bail!(
4583 "different function parameter names: {} != {}",
4584 from_param.name,
4585 into_param.name
4586 );
4587 }
4588 self.build_type(&from_param.ty, &into_param.ty)
4589 .with_context(|| {
4590 format!(
4591 "different function parameter types for `{}`",
4592 from_param.name
4593 )
4594 })?;
4595 }
4596 match (&from_func.result, &into_func.result) {
4597 (Some(from_ty), Some(into_ty)) => {
4598 self.build_type(from_ty, into_ty)
4599 .context("different function result types")?;
4600 }
4601 (None, None) => {}
4602 (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
4603 }
4604 Ok(())
4605 }
4606
4607 fn build_world(&mut self, from_id: WorldId, into_id: WorldId) -> anyhow::Result<()> {
4608 let prev = self.world_map.insert(from_id, into_id);
4609 assert!(prev.is_none());
4610
4611 let from_world = &self.from.worlds[from_id];
4612 let into_world = &self.into.worlds[into_id];
4613
4614 if from_world.imports.len() != into_world.imports.len() {
4623 bail!("world contains different number of imports than expected");
4624 }
4625 if from_world.exports.len() != into_world.exports.len() {
4626 bail!("world contains different number of exports than expected");
4627 }
4628
4629 for (from_name, from) in from_world.imports.iter() {
4630 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4631 let name_str = self.from.name_world_key(from_name);
4632 let into = into_world
4633 .imports
4634 .get(&into_name)
4635 .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?;
4636 self.match_world_item(from, into)
4637 .with_context(|| format!("import `{name_str}` didn't match target world"))?;
4638 }
4639
4640 for (from_name, from) in from_world.exports.iter() {
4641 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4642 let name_str = self.from.name_world_key(from_name);
4643 let into = into_world
4644 .exports
4645 .get(&into_name)
4646 .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?;
4647 self.match_world_item(from, into)
4648 .with_context(|| format!("export `{name_str}` didn't match target world"))?;
4649 }
4650
4651 Ok(())
4652 }
4653
4654 fn map_name(
4655 from_name: &WorldKey,
4656 interface_map: &HashMap<InterfaceId, InterfaceId>,
4657 ) -> WorldKey {
4658 match from_name {
4659 WorldKey::Name(s) => WorldKey::Name(s.clone()),
4660 WorldKey::Interface(id) => {
4661 WorldKey::Interface(interface_map.get(id).copied().unwrap_or(*id))
4662 }
4663 }
4664 }
4665
4666 fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> anyhow::Result<()> {
4667 match (from, into) {
4668 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
4669 match (
4670 &self.from.interfaces[*from].name,
4671 &self.into.interfaces[*into].name,
4672 ) {
4673 (None, None) => self.build_interface(*from, *into)?,
4677
4678 _ => {
4683 if self.interface_map.get(from) != Some(into) {
4684 bail!("interfaces are not the same");
4685 }
4686 }
4687 }
4688 }
4689 (WorldItem::Function(from), WorldItem::Function(into)) => {
4690 let _ = (from, into);
4691 }
4694 (WorldItem::Type { id: from, .. }, WorldItem::Type { id: into, .. }) => {
4695 let prev = self.type_map.insert(*from, *into);
4698 assert!(prev.is_none());
4699 }
4700
4701 (WorldItem::Interface { .. }, _)
4702 | (WorldItem::Function(_), _)
4703 | (WorldItem::Type { .. }, _) => {
4704 bail!("world items do not have the same type")
4705 }
4706 }
4707 Ok(())
4708 }
4709}
4710
4711fn update_stability(from: &Stability, into: &mut Stability, span: Span) -> ResolveResult<()> {
4717 if from == into || from.is_unknown() {
4720 return Ok(());
4721 }
4722 if into.is_unknown() {
4725 *into = from.clone();
4726 return Ok(());
4727 }
4728
4729 Err(ResolveError::from(ResolveErrorKind::StabilityMismatch {
4732 span,
4733 from: from.clone(),
4734 into: into.clone(),
4735 }))
4736}
4737
4738fn merge_include_stability(
4739 from: &Stability,
4740 into: &mut Stability,
4741 is_external_include: bool,
4742 span: Span,
4743) -> ResolveResult<()> {
4744 if is_external_include && from.is_stable() {
4745 log::trace!("dropped stability from external package");
4746 *into = Stability::Unknown;
4747 return Ok(());
4748 }
4749
4750 update_stability(from, into, span)
4751}
4752
4753#[cfg(test)]
4754mod tests {
4755 use crate::alloc::format;
4756 use crate::alloc::string::{String, ToString};
4757 use crate::alloc::vec::Vec;
4758 use crate::{Resolve, SourceMap, WorldItem, WorldKey};
4759 use anyhow::Result;
4760
4761 #[test]
4762 fn select_world() -> Result<()> {
4763 let mut resolve = Resolve::default();
4764 resolve.push_str(
4765 "test.wit",
4766 r#"
4767 package foo:bar@0.1.0;
4768
4769 world foo {}
4770 "#,
4771 )?;
4772 resolve.push_str(
4773 "test.wit",
4774 r#"
4775 package foo:baz@0.1.0;
4776
4777 world foo {}
4778 "#,
4779 )?;
4780 resolve.push_str(
4781 "test.wit",
4782 r#"
4783 package foo:baz@0.2.0;
4784
4785 world foo {}
4786 "#,
4787 )?;
4788
4789 let dummy = resolve.push_str(
4790 "test.wit",
4791 r#"
4792 package foo:dummy;
4793
4794 world foo {}
4795 "#,
4796 )?;
4797
4798 assert!(resolve.select_world(&[dummy], None).is_ok());
4799 assert!(resolve.select_world(&[dummy], Some("xx")).is_err());
4800 assert!(resolve.select_world(&[dummy], Some("")).is_err());
4801 assert!(resolve.select_world(&[dummy], Some("foo:bar/foo")).is_ok());
4802 assert!(
4803 resolve
4804 .select_world(&[dummy], Some("foo:bar/foo@0.1.0"))
4805 .is_ok()
4806 );
4807 assert!(resolve.select_world(&[dummy], Some("foo:baz/foo")).is_err());
4808 assert!(
4809 resolve
4810 .select_world(&[dummy], Some("foo:baz/foo@0.1.0"))
4811 .is_ok()
4812 );
4813 assert!(
4814 resolve
4815 .select_world(&[dummy], Some("foo:baz/foo@0.2.0"))
4816 .is_ok()
4817 );
4818 Ok(())
4819 }
4820
4821 #[test]
4822 fn wasm_import_name_future_and_stream_intrinsics() -> Result<()> {
4823 use crate::{FutureIntrinsic, LiftLowerAbi, ManglingAndAbi, StreamIntrinsic, WasmImport};
4824
4825 let mut resolve = Resolve::default();
4826 let pkg = resolve.push_str(
4827 "test.wit",
4828 r#"
4829 package foo:bar;
4830
4831 interface iface {
4832 iface-func: func(x: future<u32>) -> stream<u32>;
4833 }
4834
4835 world w {
4836 import import-func: func(x: future<future<u32>>, y: u32) -> stream<string>;
4837 export export-func: func(x: future, y: stream);
4838 import iface;
4839 export iface;
4840 }
4841 "#,
4842 )?;
4843 let world = resolve.packages[pkg].worlds["w"];
4844 let world = &resolve.worlds[world];
4845 let mangling = ManglingAndAbi::Legacy(LiftLowerAbi::AsyncStackful);
4846
4847 let WorldItem::Function(import_func) =
4848 &world.imports[&WorldKey::Name("import-func".to_string())]
4849 else {
4850 panic!("expected `import-func` to be a top-level world import");
4851 };
4852 let WorldItem::Function(export_func) =
4853 &world.exports[&WorldKey::Name("export-func".to_string())]
4854 else {
4855 panic!("expected `export-func` to be a top-level world export");
4856 };
4857 let import_types = import_func.find_futures_and_streams(&resolve);
4858 assert_eq!(import_types.len(), 3);
4859
4860 let (interface_key, interface_func) = world
4861 .imports
4862 .iter()
4863 .find_map(|(key, item)| match item {
4864 WorldItem::Interface { id, .. } => Some((
4865 key.clone(),
4866 &resolve.interfaces[*id].functions["iface-func"],
4867 )),
4868 _ => None,
4869 })
4870 .expect("expected interface import");
4871 let interface_types = interface_func.find_futures_and_streams(&resolve);
4872 assert_eq!(interface_types.len(), 2);
4873
4874 let (module, name) = resolve.wasm_import_name(
4875 mangling,
4876 WasmImport::FutureIntrinsic {
4877 interface: None,
4878 func: import_func,
4879 ty: Some(import_types[0]),
4880 intrinsic: FutureIntrinsic::New,
4881 exported: false,
4882 async_: false,
4883 },
4884 );
4885 assert_eq!(module, "$root");
4886 assert_eq!(name, "[future-new-0]import-func");
4887
4888 let (module, name) = resolve.wasm_import_name(
4889 mangling,
4890 WasmImport::FutureIntrinsic {
4891 interface: None,
4892 func: import_func,
4893 ty: Some(import_types[1]),
4894 intrinsic: FutureIntrinsic::Read,
4895 exported: false,
4896 async_: true,
4897 },
4898 );
4899 assert_eq!(module, "$root");
4900 assert_eq!(name, "[async-lower][future-read-1]import-func");
4901
4902 let (module, name) = resolve.wasm_import_name(
4903 mangling,
4904 WasmImport::StreamIntrinsic {
4905 interface: None,
4906 func: import_func,
4907 ty: Some(import_types[2]),
4908 intrinsic: StreamIntrinsic::CancelRead,
4909 exported: false,
4910 async_: true,
4911 },
4912 );
4913 assert_eq!(module, "$root");
4914 assert_eq!(name, "[async-lower][stream-cancel-read-2]import-func");
4915
4916 let (module, name) = resolve.wasm_import_name(
4917 mangling,
4918 WasmImport::FutureIntrinsic {
4919 interface: None,
4920 func: export_func,
4921 ty: None,
4922 intrinsic: FutureIntrinsic::DropReadable,
4923 exported: true,
4924 async_: false,
4925 },
4926 );
4927 assert_eq!(module, "[export]$root");
4928 assert_eq!(name, "[future-drop-readable-unit]export-func");
4929
4930 let (module, name) = resolve.wasm_import_name(
4931 mangling,
4932 WasmImport::StreamIntrinsic {
4933 interface: None,
4934 func: export_func,
4935 ty: None,
4936 intrinsic: StreamIntrinsic::Write,
4937 exported: true,
4938 async_: true,
4939 },
4940 );
4941 assert_eq!(module, "[export]$root");
4942 assert_eq!(name, "[async-lower][stream-write-unit]export-func");
4943
4944 let (module, name) = resolve.wasm_import_name(
4945 mangling,
4946 WasmImport::StreamIntrinsic {
4947 interface: Some(&interface_key),
4948 func: interface_func,
4949 ty: Some(interface_types[1]),
4950 intrinsic: StreamIntrinsic::Read,
4951 exported: true,
4952 async_: false,
4953 },
4954 );
4955 assert_eq!(
4956 module,
4957 format!("[export]{}", resolve.name_world_key(&interface_key))
4958 );
4959 assert_eq!(name, "[stream-read-1]iface-func");
4960
4961 Ok(())
4962 }
4963
4964 #[test]
4967 fn select_world_multiple_packages() -> Result<()> {
4968 use wit_parser::Resolve;
4969
4970 let mut resolve = Resolve::default();
4971
4972 let stuff = resolve.push_str(
4974 "./my-test.wit",
4975 r#"
4976 package test:stuff;
4977
4978 world foo {
4979 // ...
4980 }
4981 "#,
4982 )?;
4983 assert!(resolve.select_world(&[stuff], None).is_ok());
4984 assert!(resolve.select_world(&[stuff], Some("foo")).is_ok());
4985
4986 let empty = resolve.push_str(
4989 "./my-test.wit",
4990 r#"
4991 package test:empty;
4992 "#,
4993 )?;
4994 assert!(resolve.select_world(&[stuff, empty], None).is_err());
4995 assert!(resolve.select_world(&[stuff, empty], Some("foo")).is_err());
4996 assert!(resolve.select_world(&[empty], None).is_err());
4997 assert!(resolve.select_world(&[empty], Some("foo")).is_err());
4998
4999 Ok(())
5000 }
5001
5002 #[test]
5004 fn select_world_versions() -> Result<()> {
5005 use wit_parser::Resolve;
5006
5007 let mut resolve = Resolve::default();
5008
5009 let _id = resolve.push_str(
5010 "./my-test.wit",
5011 r#"
5012 package example:distraction;
5013 "#,
5014 )?;
5015
5016 let versions_1 = resolve.push_str(
5019 "./my-test.wit",
5020 r#"
5021 package example:versions@1.0.0;
5022
5023 world foo { /* ... */ }
5024 "#,
5025 )?;
5026 assert!(resolve.select_world(&[versions_1], Some("foo")).is_ok());
5027 assert!(
5028 resolve
5029 .select_world(&[versions_1], Some("foo@1.0.0"))
5030 .is_err()
5031 );
5032 assert!(
5033 resolve
5034 .select_world(&[versions_1], Some("example:versions/foo"))
5035 .is_ok()
5036 );
5037 assert!(
5038 resolve
5039 .select_world(&[versions_1], Some("example:versions/foo@1.0.0"))
5040 .is_ok()
5041 );
5042
5043 let versions_2 = resolve.push_str(
5046 "./my-test.wit",
5047 r#"
5048 package example:versions@2.0.0;
5049
5050 world foo { /* ... */ }
5051 "#,
5052 )?;
5053 assert!(
5054 resolve
5055 .select_world(&[versions_1, versions_2], Some("foo"))
5056 .is_err()
5057 );
5058 assert!(
5059 resolve
5060 .select_world(&[versions_1, versions_2], Some("foo@1.0.0"))
5061 .is_err()
5062 );
5063 assert!(
5064 resolve
5065 .select_world(&[versions_1, versions_2], Some("foo@2.0.0"))
5066 .is_err()
5067 );
5068 assert!(
5069 resolve
5070 .select_world(&[versions_1, versions_2], Some("example:versions/foo"))
5071 .is_err()
5072 );
5073 assert!(
5074 resolve
5075 .select_world(
5076 &[versions_1, versions_2],
5077 Some("example:versions/foo@1.0.0")
5078 )
5079 .is_ok()
5080 );
5081 assert!(
5082 resolve
5083 .select_world(
5084 &[versions_1, versions_2],
5085 Some("example:versions/foo@2.0.0")
5086 )
5087 .is_ok()
5088 );
5089
5090 Ok(())
5091 }
5092
5093 #[test]
5095 fn select_world_override_qualification() -> Result<()> {
5096 use wit_parser::Resolve;
5097
5098 let mut resolve = Resolve::default();
5099
5100 let other = resolve.push_str(
5101 "./my-test.wit",
5102 r#"
5103 package example:other;
5104
5105 world foo { }
5106 "#,
5107 )?;
5108
5109 let fq = resolve.push_str(
5111 "./my-test.wit",
5112 r#"
5113 package example:fq;
5114
5115 world bar { }
5116 "#,
5117 )?;
5118 assert!(resolve.select_world(&[other, fq], Some("foo")).is_err());
5119 assert!(resolve.select_world(&[other, fq], Some("bar")).is_err());
5120 assert!(
5121 resolve
5122 .select_world(&[other, fq], Some("example:other/foo"))
5123 .is_ok()
5124 );
5125 assert!(
5126 resolve
5127 .select_world(&[other, fq], Some("example:fq/bar"))
5128 .is_ok()
5129 );
5130 assert!(
5131 resolve
5132 .select_world(&[other, fq], Some("example:other/bar"))
5133 .is_err()
5134 );
5135 assert!(
5136 resolve
5137 .select_world(&[other, fq], Some("example:fq/foo"))
5138 .is_err()
5139 );
5140
5141 Ok(())
5142 }
5143
5144 #[test]
5146 fn select_world_fully_qualified() -> Result<()> {
5147 use wit_parser::Resolve;
5148
5149 let mut resolve = Resolve::default();
5150
5151 let distraction = resolve.push_str(
5152 "./my-test.wit",
5153 r#"
5154 package example:distraction;
5155 "#,
5156 )?;
5157
5158 let multiworld = resolve.push_str(
5161 "./my-test.wit",
5162 r#"
5163 package example:multiworld;
5164
5165 world foo { /* ... */ }
5166
5167 world bar { /* ... */ }
5168 "#,
5169 )?;
5170 assert!(
5171 resolve
5172 .select_world(&[distraction, multiworld], None)
5173 .is_err()
5174 );
5175 assert!(
5176 resolve
5177 .select_world(&[distraction, multiworld], Some("foo"))
5178 .is_err()
5179 );
5180 assert!(
5181 resolve
5182 .select_world(&[distraction, multiworld], Some("example:multiworld/foo"))
5183 .is_ok()
5184 );
5185 assert!(
5186 resolve
5187 .select_world(&[distraction, multiworld], Some("bar"))
5188 .is_err()
5189 );
5190 assert!(
5191 resolve
5192 .select_world(&[distraction, multiworld], Some("example:multiworld/bar"))
5193 .is_ok()
5194 );
5195
5196 Ok(())
5197 }
5198
5199 #[test]
5201 fn select_world_packages() -> Result<()> {
5202 use wit_parser::Resolve;
5203
5204 let mut resolve = Resolve::default();
5205
5206 let wit1 = resolve.push_str(
5209 "./my-test.wit",
5210 r#"
5211 package example:wit1;
5212
5213 world foo {
5214 // ...
5215 }
5216 "#,
5217 )?;
5218 assert!(resolve.select_world(&[wit1], None).is_ok());
5219 assert!(resolve.select_world(&[wit1], Some("foo")).is_ok());
5220 assert!(
5221 resolve
5222 .select_world(&[wit1], Some("example:wit1/foo"))
5223 .is_ok()
5224 );
5225 assert!(resolve.select_world(&[wit1], Some("bar")).is_err());
5226 assert!(
5227 resolve
5228 .select_world(&[wit1], Some("example:wit2/foo"))
5229 .is_err()
5230 );
5231
5232 let wit2 = resolve.push_str(
5235 "./my-test.wit",
5236 r#"
5237 package example:wit2;
5238
5239 world foo { /* ... */ }
5240 "#,
5241 )?;
5242 assert!(resolve.select_world(&[wit1, wit2], None).is_err());
5243 assert!(resolve.select_world(&[wit1, wit2], Some("foo")).is_err());
5244 assert!(
5245 resolve
5246 .select_world(&[wit1, wit2], Some("example:wit1/foo"))
5247 .is_ok()
5248 );
5249 assert!(resolve.select_world(&[wit2], None).is_ok());
5250 assert!(resolve.select_world(&[wit2], Some("foo")).is_ok());
5251 assert!(
5252 resolve
5253 .select_world(&[wit2], Some("example:wit1/foo"))
5254 .is_ok()
5255 );
5256 assert!(resolve.select_world(&[wit1, wit2], Some("bar")).is_err());
5257 assert!(
5258 resolve
5259 .select_world(&[wit1, wit2], Some("example:wit2/foo"))
5260 .is_ok()
5261 );
5262 assert!(resolve.select_world(&[wit2], Some("bar")).is_err());
5263 assert!(
5264 resolve
5265 .select_world(&[wit2], Some("example:wit2/foo"))
5266 .is_ok()
5267 );
5268
5269 Ok(())
5270 }
5271
5272 #[test]
5273 fn span_preservation() -> Result<()> {
5274 let mut resolve = Resolve::default();
5275 let pkg = resolve.push_str(
5276 "test.wit",
5277 r#"
5278 package foo:bar;
5279
5280 interface my-iface {
5281 type my-type = u32;
5282 my-func: func();
5283 }
5284
5285 world my-world {
5286 export my-export: func();
5287 }
5288 "#,
5289 )?;
5290
5291 let iface_id = resolve.packages[pkg].interfaces["my-iface"];
5292 assert!(resolve.interfaces[iface_id].span.is_known());
5293
5294 let type_id = resolve.interfaces[iface_id].types["my-type"];
5295 assert!(resolve.types[type_id].span.is_known());
5296
5297 assert!(
5298 resolve.interfaces[iface_id].functions["my-func"]
5299 .span
5300 .is_known()
5301 );
5302
5303 let world_id = resolve.packages[pkg].worlds["my-world"];
5304 assert!(resolve.worlds[world_id].span.is_known());
5305
5306 let WorldItem::Function(f) =
5307 &resolve.worlds[world_id].exports[&WorldKey::Name("my-export".to_string())]
5308 else {
5309 panic!("expected function");
5310 };
5311 assert!(f.span.is_known());
5312
5313 Ok(())
5314 }
5315
5316 #[test]
5317 fn span_preservation_through_merge() -> Result<()> {
5318 let mut resolve1 = Resolve::default();
5319 resolve1.push_str(
5320 "test1.wit",
5321 r#"
5322 package foo:bar;
5323
5324 interface iface1 {
5325 type type1 = u32;
5326 func1: func();
5327 }
5328 "#,
5329 )?;
5330
5331 let mut resolve2 = Resolve::default();
5332 let pkg2 = resolve2.push_str(
5333 "test2.wit",
5334 r#"
5335 package foo:baz;
5336
5337 interface iface2 {
5338 type type2 = string;
5339 func2: func();
5340 }
5341 "#,
5342 )?;
5343
5344 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5345 let remap = resolve1.merge(resolve2)?;
5346 let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
5347
5348 assert!(resolve1.interfaces[iface2_id].span.is_known());
5349
5350 let type2_id = resolve1.interfaces[iface2_id].types["type2"];
5351 assert!(resolve1.types[type2_id].span.is_known());
5352
5353 assert!(
5354 resolve1.interfaces[iface2_id].functions["func2"]
5355 .span
5356 .is_known()
5357 );
5358
5359 Ok(())
5360 }
5361
5362 #[test]
5363 fn span_preservation_through_include() -> Result<()> {
5364 let mut resolve = Resolve::default();
5365 let pkg = resolve.push_str(
5366 "test.wit",
5367 r#"
5368 package foo:bar;
5369
5370 world base {
5371 export my-func: func();
5372 }
5373
5374 world extended {
5375 include base;
5376 }
5377 "#,
5378 )?;
5379
5380 let base_id = resolve.packages[pkg].worlds["base"];
5381 let extended_id = resolve.packages[pkg].worlds["extended"];
5382
5383 let WorldItem::Function(base_func) =
5384 &resolve.worlds[base_id].exports[&WorldKey::Name("my-func".to_string())]
5385 else {
5386 panic!("expected function");
5387 };
5388 assert!(base_func.span.is_known());
5389
5390 let WorldItem::Function(extended_func) =
5391 &resolve.worlds[extended_id].exports[&WorldKey::Name("my-func".to_string())]
5392 else {
5393 panic!("expected function");
5394 };
5395 assert!(extended_func.span.is_known());
5396
5397 Ok(())
5398 }
5399
5400 #[test]
5401 fn span_preservation_through_include_with_rename() -> Result<()> {
5402 let mut resolve = Resolve::default();
5403 let pkg = resolve.push_str(
5404 "test.wit",
5405 r#"
5406 package foo:bar;
5407
5408 world base {
5409 export original-name: func();
5410 }
5411
5412 world extended {
5413 include base with { original-name as renamed-func }
5414 }
5415 "#,
5416 )?;
5417
5418 let extended_id = resolve.packages[pkg].worlds["extended"];
5419
5420 let WorldItem::Function(f) =
5421 &resolve.worlds[extended_id].exports[&WorldKey::Name("renamed-func".to_string())]
5422 else {
5423 panic!("expected function");
5424 };
5425 assert!(f.span.is_known());
5426
5427 assert!(
5428 !resolve.worlds[extended_id]
5429 .exports
5430 .contains_key(&WorldKey::Name("original-name".to_string()))
5431 );
5432
5433 Ok(())
5434 }
5435
5436 #[test]
5438 fn span_preservation_through_include_reverse_order() -> Result<()> {
5439 let mut resolve = Resolve::default();
5440 let pkg = resolve.push_str(
5441 "test.wit",
5442 r#"
5443 package foo:bar;
5444
5445 world extended {
5446 include base;
5447 }
5448
5449 world base {
5450 export my-func: func();
5451 }
5452 "#,
5453 )?;
5454
5455 let base_id = resolve.packages[pkg].worlds["base"];
5456 let extended_id = resolve.packages[pkg].worlds["extended"];
5457
5458 let WorldItem::Function(base_func) =
5459 &resolve.worlds[base_id].exports[&WorldKey::Name("my-func".to_string())]
5460 else {
5461 panic!("expected function");
5462 };
5463 assert!(base_func.span.is_known());
5464
5465 let WorldItem::Function(extended_func) =
5466 &resolve.worlds[extended_id].exports[&WorldKey::Name("my-func".to_string())]
5467 else {
5468 panic!("expected function");
5469 };
5470 assert!(extended_func.span.is_known());
5471
5472 Ok(())
5473 }
5474
5475 #[test]
5476 fn span_line_numbers() -> Result<()> {
5477 let mut resolve = Resolve::default();
5478 let pkg = resolve.push_source(
5479 "test.wit",
5480 "package foo:bar;
5481
5482interface my-iface {
5483 type my-type = u32;
5484 my-func: func();
5485}
5486
5487world my-world {
5488 export my-export: func();
5489}
5490",
5491 )?;
5492
5493 let iface_id = resolve.packages[pkg].interfaces["my-iface"];
5494 let iface_span = resolve.interfaces[iface_id].span;
5495 let iface_loc = resolve.render_location(iface_span);
5496 assert!(
5497 iface_loc.contains(":3:"),
5498 "interface location was {iface_loc}"
5499 );
5500
5501 let type_id = resolve.interfaces[iface_id].types["my-type"];
5502 let type_span = resolve.types[type_id].span;
5503 let type_loc = resolve.render_location(type_span);
5504 assert!(type_loc.contains(":4:"), "type location was {type_loc}");
5505
5506 let func_span = resolve.interfaces[iface_id].functions["my-func"].span;
5507 let func_loc = resolve.render_location(func_span);
5508 assert!(func_loc.contains(":5:"), "function location was {func_loc}");
5509
5510 let world_id = resolve.packages[pkg].worlds["my-world"];
5511 let world_span = resolve.worlds[world_id].span;
5512 let world_loc = resolve.render_location(world_span);
5513 assert!(world_loc.contains(":8:"), "world location was {world_loc}");
5514
5515 let WorldItem::Function(export_func) =
5516 &resolve.worlds[world_id].exports[&WorldKey::Name("my-export".to_string())]
5517 else {
5518 panic!("expected function");
5519 };
5520 let export_loc = resolve.render_location(export_func.span);
5521 assert!(
5522 export_loc.contains(":9:"),
5523 "export location was {export_loc}"
5524 );
5525
5526 Ok(())
5527 }
5528
5529 #[test]
5530 fn span_line_numbers_through_merge() -> Result<()> {
5531 let mut resolve1 = Resolve::default();
5532 resolve1.push_source(
5533 "first.wit",
5534 "package foo:first;
5535
5536interface iface1 {
5537 func1: func();
5538}
5539",
5540 )?;
5541
5542 let mut resolve2 = Resolve::default();
5543 let pkg2 = resolve2.push_source(
5544 "second.wit",
5545 "package foo:second;
5546
5547interface iface2 {
5548 func2: func();
5549}
5550",
5551 )?;
5552
5553 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5554 let remap = resolve1.merge(resolve2)?;
5555 let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
5556
5557 let iface2_span = resolve1.interfaces[iface2_id].span;
5558 let iface2_loc = resolve1.render_location(iface2_span);
5559 assert!(
5560 iface2_loc.contains("second.wit"),
5561 "should reference second.wit, got {iface2_loc}"
5562 );
5563 assert!(
5564 iface2_loc.contains(":3:"),
5565 "interface should be on line 3, got {iface2_loc}"
5566 );
5567
5568 let func2_span = resolve1.interfaces[iface2_id].functions["func2"].span;
5569 let func2_loc = resolve1.render_location(func2_span);
5570 assert!(
5571 func2_loc.contains("second.wit"),
5572 "should reference second.wit, got {func2_loc}"
5573 );
5574 assert!(
5575 func2_loc.contains(":4:"),
5576 "function should be on line 4, got {func2_loc}"
5577 );
5578
5579 Ok(())
5580 }
5581
5582 #[test]
5583 fn span_line_numbers_multiple_sources() -> Result<()> {
5584 let mut resolve = Resolve::default();
5585
5586 let pkg1 = resolve.push_source(
5587 "first.wit",
5588 "package test:first;
5589
5590interface first-iface {
5591 first-func: func();
5592}
5593",
5594 )?;
5595
5596 let pkg2 = resolve.push_source(
5597 "second.wit",
5598 "package test:second;
5599
5600interface second-iface {
5601 second-func: func();
5602}
5603",
5604 )?;
5605
5606 let iface1_id = resolve.packages[pkg1].interfaces["first-iface"];
5607 let iface1_span = resolve.interfaces[iface1_id].span;
5608 let iface1_loc = resolve.render_location(iface1_span);
5609 assert!(
5610 iface1_loc.contains("first.wit"),
5611 "should reference first.wit, got {iface1_loc}"
5612 );
5613 assert!(
5614 iface1_loc.contains(":3:"),
5615 "interface should be on line 3, got {iface1_loc}"
5616 );
5617
5618 let func1_span = resolve.interfaces[iface1_id].functions["first-func"].span;
5619 let func1_loc = resolve.render_location(func1_span);
5620 assert!(
5621 func1_loc.contains("first.wit"),
5622 "should reference first.wit, got {func1_loc}"
5623 );
5624 assert!(
5625 func1_loc.contains(":4:"),
5626 "function should be on line 4, got {func1_loc}"
5627 );
5628
5629 let iface2_id = resolve.packages[pkg2].interfaces["second-iface"];
5630 let iface2_span = resolve.interfaces[iface2_id].span;
5631 let iface2_loc = resolve.render_location(iface2_span);
5632 assert!(
5633 iface2_loc.contains("second.wit"),
5634 "should reference second.wit, got {iface2_loc}"
5635 );
5636 assert!(
5637 iface2_loc.contains(":3:"),
5638 "interface should be on line 3, got {iface2_loc}"
5639 );
5640
5641 let func2_span = resolve.interfaces[iface2_id].functions["second-func"].span;
5642 let func2_loc = resolve.render_location(func2_span);
5643 assert!(
5644 func2_loc.contains("second.wit"),
5645 "should reference second.wit, got {func2_loc}"
5646 );
5647 assert!(
5648 func2_loc.contains(":4:"),
5649 "function should be on line 4, got {func2_loc}"
5650 );
5651
5652 Ok(())
5653 }
5654
5655 #[test]
5656 fn span_preservation_for_fields_and_cases() -> Result<()> {
5657 use crate::TypeDefKind;
5658
5659 let mut resolve = Resolve::default();
5660 let pkg = resolve.push_str(
5661 "test.wit",
5662 r#"
5663 package foo:bar;
5664
5665 interface my-iface {
5666 record my-record {
5667 field1: u32,
5668 field2: string,
5669 }
5670
5671 flags my-flags {
5672 flag1,
5673 flag2,
5674 }
5675
5676 variant my-variant {
5677 case1,
5678 case2(u32),
5679 }
5680
5681 enum my-enum {
5682 val1,
5683 val2,
5684 }
5685 }
5686 "#,
5687 )?;
5688
5689 let iface_id = resolve.packages[pkg].interfaces["my-iface"];
5690
5691 let record_id = resolve.interfaces[iface_id].types["my-record"];
5693 let TypeDefKind::Record(record) = &resolve.types[record_id].kind else {
5694 panic!("expected record");
5695 };
5696 assert!(record.fields[0].span.is_known(), "field1 should have span");
5697 assert!(record.fields[1].span.is_known(), "field2 should have span");
5698
5699 let flags_id = resolve.interfaces[iface_id].types["my-flags"];
5701 let TypeDefKind::Flags(flags) = &resolve.types[flags_id].kind else {
5702 panic!("expected flags");
5703 };
5704 assert!(flags.flags[0].span.is_known(), "flag1 should have span");
5705 assert!(flags.flags[1].span.is_known(), "flag2 should have span");
5706
5707 let variant_id = resolve.interfaces[iface_id].types["my-variant"];
5709 let TypeDefKind::Variant(variant) = &resolve.types[variant_id].kind else {
5710 panic!("expected variant");
5711 };
5712 assert!(variant.cases[0].span.is_known(), "case1 should have span");
5713 assert!(variant.cases[1].span.is_known(), "case2 should have span");
5714
5715 let enum_id = resolve.interfaces[iface_id].types["my-enum"];
5717 let TypeDefKind::Enum(e) = &resolve.types[enum_id].kind else {
5718 panic!("expected enum");
5719 };
5720 assert!(e.cases[0].span.is_known(), "val1 should have span");
5721 assert!(e.cases[1].span.is_known(), "val2 should have span");
5722
5723 Ok(())
5724 }
5725
5726 #[test]
5727 fn span_preservation_for_fields_through_merge() -> Result<()> {
5728 use crate::TypeDefKind;
5729
5730 let mut resolve1 = Resolve::default();
5731 resolve1.push_str(
5732 "test1.wit",
5733 r#"
5734 package foo:bar;
5735
5736 interface iface1 {
5737 record rec1 {
5738 f1: u32,
5739 }
5740 }
5741 "#,
5742 )?;
5743
5744 let mut resolve2 = Resolve::default();
5745 let pkg2 = resolve2.push_str(
5746 "test2.wit",
5747 r#"
5748 package foo:baz;
5749
5750 interface iface2 {
5751 record rec2 {
5752 f2: string,
5753 }
5754
5755 variant var2 {
5756 c2,
5757 }
5758 }
5759 "#,
5760 )?;
5761
5762 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5763 let rec2_old_id = resolve2.interfaces[iface2_old_id].types["rec2"];
5764 let var2_old_id = resolve2.interfaces[iface2_old_id].types["var2"];
5765
5766 let remap = resolve1.merge(resolve2)?;
5767
5768 let rec2_id = remap.types[rec2_old_id.index()].unwrap();
5769 let TypeDefKind::Record(record) = &resolve1.types[rec2_id].kind else {
5770 panic!("expected record");
5771 };
5772 assert!(
5773 record.fields[0].span.is_known(),
5774 "field should have span after merge"
5775 );
5776
5777 let var2_id = remap.types[var2_old_id.index()].unwrap();
5778 let TypeDefKind::Variant(variant) = &resolve1.types[var2_id].kind else {
5779 panic!("expected variant");
5780 };
5781 assert!(
5782 variant.cases[0].span.is_known(),
5783 "case should have span after merge"
5784 );
5785
5786 Ok(())
5787 }
5788
5789 #[test]
5790 fn param_spans_point_to_names() -> Result<()> {
5791 let source = "\
5792package foo:bar;
5793
5794interface iface {
5795 my-func: func(a: u32, b: string);
5796}
5797";
5798 let mut resolve = Resolve::default();
5799 let pkg = resolve.push_str("test.wit", source)?;
5800
5801 let iface_id = resolve.packages[pkg].interfaces["iface"];
5802 let func = &resolve.interfaces[iface_id].functions["my-func"];
5803 assert_eq!(func.params.len(), 2);
5804 for param in &func.params {
5805 let start = param.span.start() as usize;
5806 let end = param.span.end() as usize;
5807 let snippet = &source[start..end];
5808 assert_eq!(
5809 snippet, param.name,
5810 "param `{}` span points to {:?}",
5811 param.name, snippet
5812 );
5813 }
5814
5815 Ok(())
5816 }
5817
5818 #[test]
5819 fn push_groups_resolves_dep_before_main() -> Result<()> {
5820 let dep = {
5823 let mut map = SourceMap::default();
5824 map.push_str(
5825 "file:///dep.wit",
5826 "package foo:dep;\ninterface i { type t = u32; }",
5827 );
5828 map.parse().map_err(|(_, e)| e)?
5829 };
5830 let main = {
5831 let mut map = SourceMap::default();
5832 map.push_str(
5833 "file:///main.wit",
5834 "package foo:main;\ninterface j { use foo:dep/i.{t}; type u = t; }",
5835 );
5836 map.parse().map_err(|(_, e)| e)?
5837 };
5838 let mut resolve = Resolve::default();
5839 resolve.push_groups(main, Vec::from([dep]))?;
5840 assert_eq!(resolve.packages.len(), 2);
5841 Ok(())
5842 }
5843
5844 #[test]
5845 fn push_groups_cycle_error_contains_location() {
5846 let a = {
5850 let mut map = SourceMap::default();
5851 map.push_str(
5852 "file:///a.wit",
5853 "package foo:a;\ninterface i { use foo:b/j.{}; }",
5854 );
5855 map.parse().unwrap()
5856 };
5857 let b = {
5858 let mut map = SourceMap::default();
5859 map.push_str(
5860 "file:///b.wit",
5861 "package foo:b;\ninterface j { use foo:a/i.{}; }",
5862 );
5863 map.parse().unwrap()
5864 };
5865 let mut resolve = Resolve::default();
5866 let err = resolve.push_groups(a, Vec::from([b])).unwrap_err();
5867 let msg = err.highlight(&resolve.source_map);
5868 assert!(
5869 msg.contains("file:///"),
5870 "cycle error should contain a file URI, got: {msg}"
5871 );
5872 }
5873
5874 #[test]
5875 fn param_spans_preserved_through_merge() -> Result<()> {
5876 let mut resolve1 = Resolve::default();
5877 resolve1.push_str(
5878 "test1.wit",
5879 r#"
5880 package foo:bar;
5881
5882 interface iface1 {
5883 f1: func(x: u32);
5884 }
5885 "#,
5886 )?;
5887
5888 let mut resolve2 = Resolve::default();
5889 let pkg2 = resolve2.push_str(
5890 "test2.wit",
5891 r#"
5892 package foo:baz;
5893
5894 interface iface2 {
5895 f2: func(y: string, z: bool);
5896 }
5897 "#,
5898 )?;
5899
5900 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5901
5902 let remap = resolve1.merge(resolve2)?;
5903
5904 let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
5905 let func = &resolve1.interfaces[iface2_id].functions["f2"];
5906 for param in &func.params {
5907 assert!(
5908 param.span.is_known(),
5909 "param `{}` should have span after merge",
5910 param.name
5911 );
5912 }
5913
5914 Ok(())
5915 }
5916
5917 #[test]
5922 fn exportize_importize_roundtrip() -> Result<()> {
5923 let mut resolve = Resolve::default();
5924 let pkg = resolve.push_str(
5925 "test.wit",
5926 r#"
5927 package foo:bar;
5928
5929 interface types {
5930 type my-type = u32;
5931 }
5932
5933 interface api {
5934 use types.{my-type};
5935 do-something: func(a: my-type) -> my-type;
5936 }
5937
5938 world w {
5939 export api;
5940 }
5941 "#,
5942 )?;
5943 let world_id = resolve.packages[pkg].worlds["w"];
5944
5945 let original_export_keys: Vec<String> = resolve.worlds[world_id]
5947 .exports
5948 .keys()
5949 .map(|k| resolve.name_world_key(k))
5950 .collect();
5951 assert!(!original_export_keys.is_empty());
5952 assert!(resolve.worlds[world_id].imports.iter().all(|(_, item)| {
5953 matches!(item, WorldItem::Interface { .. })
5956 }));
5957
5958 resolve.importize(world_id, Some("w-temp".to_string()))?;
5960 assert!(
5961 resolve.worlds[world_id].exports.is_empty(),
5962 "importize should leave no exports"
5963 );
5964 for key in &original_export_keys {
5966 assert!(
5967 resolve.worlds[world_id]
5968 .imports
5969 .keys()
5970 .any(|k| resolve.name_world_key(k) == *key),
5971 "expected `{key}` to be an import after importize"
5972 );
5973 }
5974
5975 resolve.exportize(world_id, Some("w-final".to_string()), None)?;
5977 assert!(
5978 !resolve.worlds[world_id].exports.is_empty(),
5979 "exportize should produce exports"
5980 );
5981 let final_export_keys: Vec<String> = resolve.worlds[world_id]
5983 .exports
5984 .keys()
5985 .map(|k| resolve.name_world_key(k))
5986 .collect();
5987 for key in &original_export_keys {
5988 assert!(
5989 final_export_keys.contains(key),
5990 "expected `{key}` to be an export after round-trip, got exports: {final_export_keys:?}"
5991 );
5992 }
5993
5994 Ok(())
5995 }
5996}