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::fmt;
8use core::mem;
9
10use crate::*;
11use anyhow::{Context, Result, 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, Error, Function, FunctionKind, Handle, IncludeName, Interface, InterfaceId,
27 LiftLowerAbi, ManglingAndAbi, PackageName, PackageNotFoundError, SourceMap, Stability, Type,
28 TypeDef, TypeDefKind, TypeId, TypeIdVisitor, TypeOwner, UnresolvedPackage,
29 UnresolvedPackageGroup, World, WorldId, WorldItem, WorldKey,
30};
31
32pub use clone::CloneMaps;
33
34mod clone;
35
36#[cfg(feature = "std")]
37mod fs;
38#[cfg(feature = "std")]
39pub use fs::PackageSourceMap;
40
41#[derive(Default, Clone, Debug)]
55#[cfg_attr(feature = "serde", derive(Serialize))]
56pub struct Resolve {
57 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
62 pub worlds: Arena<World>,
63
64 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
69 pub interfaces: Arena<Interface>,
70
71 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
77 pub types: Arena<TypeDef>,
78
79 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
84 pub packages: Arena<Package>,
85
86 #[cfg_attr(feature = "serde", serde(skip))]
88 pub package_names: IndexMap<PackageName, PackageId>,
89
90 #[cfg_attr(feature = "serde", serde(skip))]
97 pub features: IndexSet<String>,
98
99 #[cfg_attr(feature = "serde", serde(skip))]
101 pub all_features: bool,
102
103 #[cfg_attr(feature = "serde", serde(skip))]
105 pub source_map: SourceMap,
106}
107
108#[derive(Clone, Debug)]
114#[cfg_attr(feature = "serde", derive(Serialize))]
115pub struct Package {
116 pub name: PackageName,
118
119 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Docs::is_empty"))]
121 pub docs: Docs,
122
123 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_id_map"))]
126 pub interfaces: IndexMap<String, InterfaceId>,
127
128 #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_id_map"))]
130 pub worlds: IndexMap<String, WorldId>,
131}
132
133pub type PackageId = Id<Package>;
134
135#[derive(Clone, Debug)]
137pub struct PackageSources {
138 sources: Vec<Vec<String>>,
139 package_id_to_source_map_idx: BTreeMap<PackageId, usize>,
140}
141
142impl PackageSources {
143 pub fn from_single_source(package_id: PackageId, source: &str) -> Self {
144 Self {
145 sources: vec![vec![source.to_owned()]],
146 package_id_to_source_map_idx: BTreeMap::from([(package_id, 0)]),
147 }
148 }
149
150 pub fn from_source_maps(
151 source_maps: Vec<SourceMap>,
152 package_id_to_source_map_idx: BTreeMap<PackageId, usize>,
153 ) -> PackageSources {
154 for (package_id, idx) in &package_id_to_source_map_idx {
155 if *idx >= source_maps.len() {
156 panic!(
157 "Invalid source map index: {}, package id: {:?}, source maps size: {}",
158 idx,
159 package_id,
160 source_maps.len()
161 )
162 }
163 }
164
165 Self {
166 sources: source_maps
167 .into_iter()
168 .map(|source_map| source_map.source_names().map(|s| s.to_owned()).collect())
169 .collect(),
170 package_id_to_source_map_idx,
171 }
172 }
173
174 pub fn source_names(&self) -> impl Iterator<Item = &str> {
176 self.sources
177 .iter()
178 .flatten()
179 .map(|s| s.as_str())
180 .collect::<IndexSet<&str>>()
181 .into_iter()
182 }
183
184 pub fn package_source_names(&self, id: PackageId) -> Option<impl Iterator<Item = &str>> {
186 self.package_id_to_source_map_idx
187 .get(&id)
188 .map(|&idx| self.sources[idx].iter().map(|s| s.as_str()))
189 }
190}
191
192fn visit<'a>(
194 pkg: &'a UnresolvedPackage,
195 pkg_details_map: &'a BTreeMap<PackageName, (UnresolvedPackage, usize)>,
196 order: &mut IndexSet<PackageName>,
197 visiting: &mut HashSet<&'a PackageName>,
198 source_maps: &[SourceMap],
199) -> Result<()> {
200 if order.contains(&pkg.name) {
201 return Ok(());
202 }
203
204 match pkg_details_map.get(&pkg.name) {
205 Some(pkg_details) => {
206 let (_, source_maps_index) = pkg_details;
207 source_maps[*source_maps_index].rewrite_error(|| {
208 for (i, (dep, _)) in pkg.foreign_deps.iter().enumerate() {
209 let span = pkg.foreign_dep_spans[i];
210 if !visiting.insert(dep) {
211 bail!(Error::new(span, "package depends on itself"));
212 }
213 if let Some(dep) = pkg_details_map.get(dep) {
214 let (dep_pkg, _) = dep;
215 visit(dep_pkg, pkg_details_map, order, visiting, source_maps)?;
216 }
217 assert!(visiting.remove(dep));
218 }
219 assert!(order.insert(pkg.name.clone()));
220 Ok(())
221 })
222 }
223 None => panic!("No pkg_details found for package when doing topological sort"),
224 }
225}
226
227impl Resolve {
228 pub fn new() -> Resolve {
230 Resolve::default()
231 }
232
233 fn sort_unresolved_packages(
254 &mut self,
255 main: UnresolvedPackageGroup,
256 deps: Vec<UnresolvedPackageGroup>,
257 ) -> Result<(PackageId, PackageSources)> {
258 let mut pkg_details_map = BTreeMap::new();
259 let mut source_maps = Vec::new();
260
261 let mut insert = |group: UnresolvedPackageGroup| {
262 let UnresolvedPackageGroup {
263 main,
264 nested,
265 source_map,
266 } = group;
267 let i = source_maps.len();
268 source_maps.push(source_map);
269
270 for pkg in nested.into_iter().chain([main]) {
271 let name = pkg.name.clone();
272 let my_span = pkg.package_name_span;
273 let (prev_pkg, prev_i) = match pkg_details_map.insert(name.clone(), (pkg, i)) {
274 Some(pair) => pair,
275 None => continue,
276 };
277 let loc1 = source_maps[i].render_location(my_span);
278 let loc2 = source_maps[prev_i].render_location(prev_pkg.package_name_span);
279 bail!(
280 "\
281package {name} is defined in two different locations:\n\
282 * {loc1}\n\
283 * {loc2}\n\
284 "
285 )
286 }
287 Ok(())
288 };
289
290 let main_name = main.main.name.clone();
291 insert(main)?;
292 for dep in deps {
293 insert(dep)?;
294 }
295
296 let mut order = IndexSet::default();
300 {
301 let mut visiting = HashSet::new();
302 for pkg_details in pkg_details_map.values() {
303 let (pkg, _) = pkg_details;
304 visit(
305 pkg,
306 &pkg_details_map,
307 &mut order,
308 &mut visiting,
309 &source_maps,
310 )?;
311 }
312 }
313
314 let mut package_id_to_source_map_idx = BTreeMap::new();
317 let mut main_pkg_id = None;
318 let mut source_map_offsets: HashMap<usize, u32> = HashMap::new();
319 for name in order {
320 let (pkg, source_map_index) = pkg_details_map.remove(&name).unwrap();
321 let source_map = &source_maps[source_map_index];
322 let is_main = pkg.name == main_name;
323
324 let span_offset = *source_map_offsets
326 .entry(source_map_index)
327 .or_insert_with(|| self.push_source_map(source_map.clone()));
328
329 let id = self.push(pkg, span_offset)?;
330 if is_main {
331 assert!(main_pkg_id.is_none());
332 main_pkg_id = Some(id);
333 }
334 package_id_to_source_map_idx.insert(id, source_map_index);
335 }
336
337 Ok((
338 main_pkg_id.unwrap(),
339 PackageSources::from_source_maps(source_maps, package_id_to_source_map_idx),
340 ))
341 }
342
343 pub fn push_source_map(&mut self, source_map: SourceMap) -> u32 {
350 self.source_map.append(source_map)
351 }
352
353 pub fn push(
368 &mut self,
369 mut unresolved: UnresolvedPackage,
370 span_offset: u32,
371 ) -> Result<PackageId> {
372 unresolved.adjust_spans(span_offset);
373 let ret = Remap::default().append(self, unresolved);
374 if ret.is_ok() {
375 #[cfg(debug_assertions)]
376 self.assert_valid();
377 }
378 self.source_map.rewrite_error(|| ret)
379 }
380
381 pub fn push_group(&mut self, unresolved_group: UnresolvedPackageGroup) -> Result<PackageId> {
390 let (pkg_id, _) = self.sort_unresolved_packages(unresolved_group, Vec::new())?;
391 Ok(pkg_id)
392 }
393
394 pub fn push_source(&mut self, path: &str, contents: &str) -> Result<PackageId> {
400 let mut map = SourceMap::default();
401 map.push_str(path, contents);
402 self.push_group(
403 map.parse()
404 .map_err(|(map, e)| anyhow::anyhow!("{}", e.highlight(&map)))?,
405 )
406 }
407
408 pub fn render_location(&self, span: Span) -> String {
410 self.source_map.render_location(span)
411 }
412
413 pub fn all_bits_valid(&self, ty: &Type) -> bool {
414 match ty {
415 Type::U8
416 | Type::S8
417 | Type::U16
418 | Type::S16
419 | Type::U32
420 | Type::S32
421 | Type::U64
422 | Type::S64
423 | Type::F32
424 | Type::F64 => true,
425
426 Type::Bool | Type::Char | Type::String | Type::ErrorContext => false,
427
428 Type::Id(id) => match &self.types[*id].kind {
429 TypeDefKind::List(_)
430 | TypeDefKind::Map(_, _)
431 | TypeDefKind::Variant(_)
432 | TypeDefKind::Enum(_)
433 | TypeDefKind::Option(_)
434 | TypeDefKind::Result(_)
435 | TypeDefKind::Future(_)
436 | TypeDefKind::Stream(_) => false,
437 TypeDefKind::Type(t) | TypeDefKind::FixedLengthList(t, ..) => {
438 self.all_bits_valid(t)
439 }
440
441 TypeDefKind::Handle(h) => match h {
442 crate::Handle::Own(_) => true,
443 crate::Handle::Borrow(_) => true,
444 },
445
446 TypeDefKind::Resource => false,
447 TypeDefKind::Record(r) => r.fields.iter().all(|f| self.all_bits_valid(&f.ty)),
448 TypeDefKind::Tuple(t) => t.types.iter().all(|t| self.all_bits_valid(t)),
449
450 TypeDefKind::Flags(_) => false,
454
455 TypeDefKind::Unknown => unreachable!(),
456 },
457 }
458 }
459
460 pub fn merge(&mut self, resolve: Resolve) -> Result<Remap> {
472 log::trace!(
473 "merging {} packages into {} packages",
474 resolve.packages.len(),
475 self.packages.len()
476 );
477
478 let mut map = MergeMap::new(&resolve, &self);
479 map.build()?;
480 let MergeMap {
481 package_map,
482 interface_map,
483 type_map,
484 world_map,
485 interfaces_to_add,
486 worlds_to_add,
487 ..
488 } = map;
489
490 let mut remap = Remap::default();
509 let Resolve {
510 types,
511 worlds,
512 interfaces,
513 packages,
514 package_names,
515 features: _,
516 source_map,
517 ..
518 } = resolve;
519
520 let span_offset = self.source_map.append(source_map);
521
522 let mut moved_types = Vec::new();
523 for (id, mut ty) in types {
524 let new_id = match type_map.get(&id).copied() {
525 Some(id) => {
526 update_stability(&ty.stability, &mut self.types[id].stability)?;
527 id
528 }
529 None => {
530 log::debug!("moving type {:?}", ty.name);
531 moved_types.push(id);
532 remap.update_typedef(self, &mut ty, Default::default())?;
533 ty.adjust_spans(span_offset);
534 self.types.alloc(ty)
535 }
536 };
537 assert_eq!(remap.types.len(), id.index());
538 remap.types.push(Some(new_id));
539 }
540
541 let mut moved_interfaces = Vec::new();
542 for (id, mut iface) in interfaces {
543 let new_id = match interface_map.get(&id).copied() {
544 Some(id) => {
545 update_stability(&iface.stability, &mut self.interfaces[id].stability)?;
546 id
547 }
548 None => {
549 log::debug!("moving interface {:?}", iface.name);
550 moved_interfaces.push(id);
551 remap.update_interface(self, &mut iface)?;
552 iface.adjust_spans(span_offset);
553 self.interfaces.alloc(iface)
554 }
555 };
556 assert_eq!(remap.interfaces.len(), id.index());
557 remap.interfaces.push(Some(new_id));
558 }
559
560 let mut moved_worlds = Vec::new();
561 for (id, mut world) in worlds {
562 let new_id = match world_map.get(&id).copied() {
563 Some(world_id) => {
564 update_stability(&world.stability, &mut self.worlds[world_id].stability)?;
565 for from_import in world.imports.iter() {
566 Resolve::update_world_imports_stability(
567 from_import,
568 &mut self.worlds[world_id].imports,
569 &interface_map,
570 )?;
571 }
572 for from_export in world.exports.iter() {
573 Resolve::update_world_imports_stability(
574 from_export,
575 &mut self.worlds[world_id].exports,
576 &interface_map,
577 )?;
578 }
579 world_id
580 }
581 None => {
582 log::debug!("moving world {}", world.name);
583 moved_worlds.push(id);
584 let mut update = |map: &mut IndexMap<WorldKey, WorldItem>| -> Result<_> {
585 for (mut name, mut item) in mem::take(map) {
586 remap.update_world_key(&mut name, Default::default())?;
587 match &mut item {
588 WorldItem::Function(f) => {
589 remap.update_function(self, f, Default::default())?
590 }
591 WorldItem::Interface { id, .. } => {
592 *id = remap.map_interface(*id, Default::default())?
593 }
594 WorldItem::Type { id, .. } => {
595 *id = remap.map_type(*id, Default::default())?
596 }
597 }
598 map.insert(name, item);
599 }
600 Ok(())
601 };
602 update(&mut world.imports)?;
603 update(&mut world.exports)?;
604 world.adjust_spans(span_offset);
605 self.worlds.alloc(world)
606 }
607 };
608 assert_eq!(remap.worlds.len(), id.index());
609 remap.worlds.push(Some(new_id));
610 }
611
612 for (id, mut pkg) in packages {
613 let new_id = match package_map.get(&id).copied() {
614 Some(id) => id,
615 None => {
616 for (_, id) in pkg.interfaces.iter_mut() {
617 *id = remap.map_interface(*id, Default::default())?;
618 }
619 for (_, id) in pkg.worlds.iter_mut() {
620 *id = remap.map_world(*id, Default::default())?;
621 }
622 self.packages.alloc(pkg)
623 }
624 };
625 assert_eq!(remap.packages.len(), id.index());
626 remap.packages.push(new_id);
627 }
628
629 for (name, id) in package_names {
630 let id = remap.packages[id.index()];
631 if let Some(prev) = self.package_names.insert(name, id) {
632 assert_eq!(prev, id);
633 }
634 }
635
636 for id in moved_worlds {
644 let id = remap.map_world(id, Default::default())?;
645 if let Some(pkg) = self.worlds[id].package.as_mut() {
646 *pkg = remap.packages[pkg.index()];
647 }
648 }
649 for id in moved_interfaces {
650 let id = remap.map_interface(id, Default::default())?;
651 if let Some(pkg) = self.interfaces[id].package.as_mut() {
652 *pkg = remap.packages[pkg.index()];
653 }
654 }
655 for id in moved_types {
656 let id = remap.map_type(id, Default::default())?;
657 match &mut self.types[id].owner {
658 TypeOwner::Interface(id) => *id = remap.map_interface(*id, Default::default())?,
659 TypeOwner::World(id) => *id = remap.map_world(*id, Default::default())?,
660 TypeOwner::None => {}
661 }
662 }
663
664 for (name, pkg, iface) in interfaces_to_add {
669 let prev = self.packages[pkg]
670 .interfaces
671 .insert(name, remap.map_interface(iface, Default::default())?);
672 assert!(prev.is_none());
673 }
674 for (name, pkg, world) in worlds_to_add {
675 let prev = self.packages[pkg]
676 .worlds
677 .insert(name, remap.map_world(world, Default::default())?);
678 assert!(prev.is_none());
679 }
680
681 log::trace!("now have {} packages", self.packages.len());
682
683 #[cfg(debug_assertions)]
684 self.assert_valid();
685 Ok(remap)
686 }
687
688 fn update_world_imports_stability(
689 from_item: (&WorldKey, &WorldItem),
690 into_items: &mut IndexMap<WorldKey, WorldItem>,
691 interface_map: &HashMap<Id<Interface>, Id<Interface>>,
692 ) -> Result<()> {
693 match from_item.0 {
694 WorldKey::Name(_) => {
695 Ok(())
697 }
698 key @ WorldKey::Interface(_) => {
699 let new_key = MergeMap::map_name(key, interface_map);
700 if let Some(into) = into_items.get_mut(&new_key) {
701 match (from_item.1, into) {
702 (
703 WorldItem::Interface {
704 id: aid,
705 stability: astability,
706 ..
707 },
708 WorldItem::Interface {
709 id: bid,
710 stability: bstability,
711 ..
712 },
713 ) => {
714 let aid = interface_map.get(aid).copied().unwrap_or(*aid);
715 assert_eq!(aid, *bid);
716 update_stability(astability, bstability)?;
717 Ok(())
718 }
719 _ => unreachable!(),
720 }
721 } else {
722 unreachable!()
725 }
726 }
727 }
728 }
729
730 pub fn merge_worlds(
745 &mut self,
746 from: WorldId,
747 into: WorldId,
748 clone_maps: &mut CloneMaps,
749 ) -> Result<()> {
750 let mut new_imports = Vec::new();
751 let mut new_exports = Vec::new();
752
753 let from_world = &self.worlds[from];
754 let into_world = &self.worlds[into];
755
756 log::trace!("merging {} into {}", from_world.name, into_world.name);
757
758 for (name, from_import) in from_world.imports.iter() {
766 let name_str = self.name_world_key(name);
767 match into_world.imports.get(name) {
768 Some(into_import) => {
769 log::trace!("info/from shared import on `{name_str}`");
770 self.merge_world_item(from_import, into_import)
771 .with_context(|| format!("failed to merge world import {name_str}"))?;
772 }
773 None => {
774 log::trace!("new import: `{name_str}`");
775 new_imports.push((name.clone(), from_import.clone()));
776 }
777 }
778 }
779
780 let mut must_be_imported = HashMap::new();
787 for (key, export) in into_world.exports.iter() {
788 for dep in self.world_item_direct_deps(export) {
789 if into_world.exports.contains_key(&WorldKey::Interface(dep)) {
790 continue;
791 }
792 self.foreach_interface_dep(dep, &mut |id| {
793 must_be_imported.insert(id, key.clone());
794 });
795 }
796 }
797
798 for (name, from_export) in from_world.exports.iter() {
801 let name_str = self.name_world_key(name);
802 match into_world.exports.get(name) {
803 Some(into_export) => {
804 log::trace!("info/from shared export on `{name_str}`");
805 self.merge_world_item(from_export, into_export)
806 .with_context(|| format!("failed to merge world export {name_str}"))?;
807 }
808 None => {
809 log::trace!("new export `{name_str}`");
810 self.ensure_can_add_world_export(
813 into_world,
814 name,
815 from_export,
816 &must_be_imported,
817 )
818 .with_context(|| {
819 format!("failed to add export `{}`", self.name_world_key(name))
820 })?;
821 new_exports.push((name.clone(), from_export.clone()));
822 }
823 }
824 }
825
826 let mut cloner = clone::Cloner::new(
840 self,
841 clone_maps,
842 TypeOwner::World(from),
843 TypeOwner::World(into),
844 );
845 cloner.register_world_type_overlap(from, into);
846 for (name, item) in new_imports.iter_mut().chain(&mut new_exports) {
847 cloner.world_item(name, item);
848 }
849
850 let into_world = &mut self.worlds[into];
852 for (name, import) in new_imports {
853 let prev = into_world.imports.insert(name, import);
854 assert!(prev.is_none());
855 }
856 for (name, export) in new_exports {
857 let prev = into_world.exports.insert(name, export);
858 assert!(prev.is_none());
859 }
860
861 #[cfg(debug_assertions)]
862 self.assert_valid();
863 Ok(())
864 }
865
866 fn merge_world_item(&self, from: &WorldItem, into: &WorldItem) -> Result<()> {
867 let mut map = MergeMap::new(self, self);
868 match (from, into) {
869 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
870 if from == into {
875 return Ok(());
876 }
877
878 map.build_interface(*from, *into)
888 .context("failed to merge interfaces")?;
889 }
890
891 (WorldItem::Function(from), WorldItem::Function(into)) => {
894 map.build_function(from, into)
895 .context("failed to merge functions")?;
896 }
897 (WorldItem::Type { id: from, .. }, WorldItem::Type { id: into, .. }) => {
898 map.build_type_id(*from, *into)
899 .context("failed to merge types")?;
900 }
901
902 (WorldItem::Interface { .. }, _)
904 | (WorldItem::Function { .. }, _)
905 | (WorldItem::Type { .. }, _) => {
906 bail!("different kinds of items");
907 }
908 }
909 assert!(map.interfaces_to_add.is_empty());
910 assert!(map.worlds_to_add.is_empty());
911 Ok(())
912 }
913
914 fn ensure_can_add_world_export(
926 &self,
927 into: &World,
928 name: &WorldKey,
929 item: &WorldItem,
930 must_be_imported: &HashMap<InterfaceId, WorldKey>,
931 ) -> Result<()> {
932 assert!(!into.exports.contains_key(name));
933 let name = self.name_world_key(name);
934
935 for dep in self.world_item_direct_deps(item) {
939 if into.exports.contains_key(&WorldKey::Interface(dep)) {
940 continue;
941 }
942 self.ensure_not_exported(into, dep)
943 .with_context(|| format!("failed validating export of `{name}`"))?;
944 }
945
946 if let WorldItem::Interface { id, .. } = item {
950 if let Some(export) = must_be_imported.get(id) {
951 let export_name = self.name_world_key(export);
952 bail!(
953 "export `{export_name}` depends on `{name}` \
954 previously as an import which will change meaning \
955 if `{name}` is added as an export"
956 );
957 }
958 }
959
960 Ok(())
961 }
962
963 fn ensure_not_exported(&self, world: &World, id: InterfaceId) -> Result<()> {
964 let key = WorldKey::Interface(id);
965 let name = self.name_world_key(&key);
966 if world.exports.contains_key(&key) {
967 bail!(
968 "world exports `{name}` but it's also transitively used by an \
969 import \
970 which means that this is not valid"
971 )
972 }
973 for dep in self.interface_direct_deps(id) {
974 self.ensure_not_exported(world, dep)
975 .with_context(|| format!("failed validating transitive import dep `{name}`"))?;
976 }
977 Ok(())
978 }
979
980 fn world_item_direct_deps(&self, item: &WorldItem) -> impl Iterator<Item = InterfaceId> + '_ {
986 let mut interface = None;
987 let mut ty = None;
988 match item {
989 WorldItem::Function(_) => {}
990 WorldItem::Type { id, .. } => ty = Some(*id),
991 WorldItem::Interface { id, .. } => interface = Some(*id),
992 }
993
994 interface
995 .into_iter()
996 .flat_map(move |id| self.interface_direct_deps(id))
997 .chain(ty.and_then(|t| self.type_interface_dep(t)))
998 }
999
1000 fn foreach_interface_dep(&self, id: InterfaceId, f: &mut dyn FnMut(InterfaceId)) {
1004 self._foreach_interface_dep(id, f, &mut HashSet::new())
1005 }
1006
1007 fn _foreach_interface_dep(
1011 &self,
1012 id: InterfaceId,
1013 f: &mut dyn FnMut(InterfaceId),
1014 visited: &mut HashSet<InterfaceId>,
1015 ) {
1016 if !visited.insert(id) {
1017 return;
1018 }
1019 f(id);
1020 for dep in self.interface_direct_deps(id) {
1021 self._foreach_interface_dep(dep, f, visited);
1022 }
1023 }
1024
1025 pub fn id_of(&self, interface: InterfaceId) -> Option<String> {
1029 let interface = &self.interfaces[interface];
1030 Some(self.id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1031 }
1032
1033 pub fn canonicalized_id_of(&self, interface: InterfaceId) -> Option<String> {
1038 let interface = &self.interfaces[interface];
1039 Some(self.canonicalized_id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1040 }
1041
1042 pub fn importize(&mut self, world_id: WorldId, out_world_name: Option<String>) -> Result<()> {
1058 let world = &mut self.worlds[world_id];
1063 let pkg = &mut self.packages[world.package.unwrap()];
1064 pkg.worlds.shift_remove(&world.name);
1065 if let Some(name) = out_world_name {
1066 world.name = name.clone();
1067 pkg.worlds.insert(name, world_id);
1068 } else {
1069 world.name.push_str("-importized");
1070 pkg.worlds.insert(world.name.clone(), world_id);
1071 }
1072
1073 world.imports.retain(|_, item| match item {
1076 WorldItem::Type { .. } => true,
1077 _ => false,
1078 });
1079
1080 for (name, export) in mem::take(&mut world.exports) {
1081 match (name.clone(), world.imports.insert(name, export)) {
1082 (_, None) => {}
1084
1085 (WorldKey::Name(name), Some(_)) => {
1087 bail!("world export `{name}` conflicts with import of same name");
1088 }
1089
1090 (WorldKey::Interface(_), _) => unreachable!(),
1093 }
1094 }
1095
1096 self.elaborate_world(world_id)?;
1099
1100 #[cfg(debug_assertions)]
1101 self.assert_valid();
1102 Ok(())
1103 }
1104
1105 pub fn id_of_name(&self, pkg: PackageId, name: &str) -> String {
1107 let package = &self.packages[pkg];
1108 let mut base = String::new();
1109 base.push_str(&package.name.namespace);
1110 base.push_str(":");
1111 base.push_str(&package.name.name);
1112 base.push_str("/");
1113 base.push_str(name);
1114 if let Some(version) = &package.name.version {
1115 base.push_str(&format!("@{version}"));
1116 }
1117 base
1118 }
1119
1120 pub fn canonicalized_id_of_name(&self, pkg: PackageId, name: &str) -> String {
1126 let package = &self.packages[pkg];
1127 let mut base = String::new();
1128 base.push_str(&package.name.namespace);
1129 base.push_str(":");
1130 base.push_str(&package.name.name);
1131 base.push_str("/");
1132 base.push_str(name);
1133 if let Some(version) = &package.name.version {
1134 base.push_str("@");
1135 let string = PackageName::version_compat_track_string(version);
1136 base.push_str(&string);
1137 }
1138 base
1139 }
1140
1141 pub fn select_world(
1256 &self,
1257 main_packages: &[PackageId],
1258 world: Option<&str>,
1259 ) -> Result<WorldId> {
1260 let world_path = match world {
1262 Some(world) => Some(
1263 parse_use_path(world)
1264 .with_context(|| format!("failed to parse world specifier `{world}`"))?,
1265 ),
1266 None => None,
1267 };
1268
1269 match world_path {
1270 Some(world_path) => {
1272 let (pkg, world_name) = match (main_packages, world_path) {
1273 ([], _) => bail!("No main packages defined"),
1275
1276 ([main_package], ParsedUsePath::Name(name)) => (*main_package, name),
1278
1279 (_, ParsedUsePath::Name(_name)) => {
1281 bail!(
1282 "There are multiple main packages; a world must be explicitly chosen:{}",
1283 self.worlds
1284 .iter()
1285 .map(|world| format!(
1286 "\n {}",
1287 self.id_of_name(world.1.package.unwrap(), &world.1.name)
1288 ))
1289 .collect::<String>()
1290 )
1291 }
1292
1293 (_, ParsedUsePath::Package(pkg, world_name)) => {
1295 let pkg = match self.package_names.get(&pkg) {
1296 Some(pkg) => *pkg,
1297 None => {
1298 let mut candidates =
1299 self.package_names.iter().filter(|(name, _)| {
1300 pkg.version.is_none()
1301 && pkg.name == name.name
1302 && pkg.namespace == name.namespace
1303 && name.version.is_some()
1304 });
1305 let candidate = candidates.next();
1306 if let Some((c2, _)) = candidates.next() {
1307 let (c1, _) = candidate.unwrap();
1308 bail!(
1309 "package name `{pkg}` is available at both \
1310 versions {} and {} but which is not specified",
1311 c1.version.as_ref().unwrap(),
1312 c2.version.as_ref().unwrap(),
1313 );
1314 }
1315 match candidate {
1316 Some((_, id)) => *id,
1317 None => bail!("unknown package `{pkg}`"),
1318 }
1319 }
1320 };
1321 (pkg, world_name.to_string())
1322 }
1323 };
1324
1325 let pkg = &self.packages[pkg];
1327 pkg.worlds.get(&world_name).copied().ok_or_else(|| {
1328 anyhow!("World `{world_name}` not found in package `{}`", pkg.name)
1329 })
1330 }
1331
1332 None => match main_packages {
1334 [] => bail!("No main packages defined"),
1335
1336 [main_package] => {
1338 let pkg = &self.packages[*main_package];
1339 match pkg.worlds.len() {
1340 0 => bail!("The main package `{}` contains no worlds", pkg.name),
1341 1 => Ok(pkg.worlds[0]),
1342 _ => bail!(
1343 "There are multiple worlds in `{}`; one must be explicitly chosen:{}",
1344 pkg.name,
1345 pkg.worlds
1346 .values()
1347 .map(|world| format!(
1348 "\n {}",
1349 self.id_of_name(*main_package, &self.worlds[*world].name)
1350 ))
1351 .collect::<String>()
1352 ),
1353 }
1354 }
1355
1356 _ => {
1358 bail!(
1359 "There are multiple main packages; a world must be explicitly chosen:{}",
1360 self.worlds
1361 .iter()
1362 .map(|world| format!(
1363 "\n {}",
1364 self.id_of_name(world.1.package.unwrap(), &world.1.name)
1365 ))
1366 .collect::<String>()
1367 )
1368 }
1369 },
1370 }
1371 }
1372
1373 pub fn name_world_key(&self, key: &WorldKey) -> String {
1375 match key {
1376 WorldKey::Name(s) => s.to_string(),
1377 WorldKey::Interface(i) => self.id_of(*i).expect("unexpected anonymous interface"),
1378 }
1379 }
1380
1381 pub fn name_canonicalized_world_key(&self, key: &WorldKey) -> String {
1384 match key {
1385 WorldKey::Name(s) => s.to_string(),
1386 WorldKey::Interface(i) => self
1387 .canonicalized_id_of(*i)
1388 .expect("unexpected anonymous interface"),
1389 }
1390 }
1391
1392 pub fn type_interface_dep(&self, id: TypeId) -> Option<InterfaceId> {
1398 let ty = &self.types[id];
1399 let dep = match ty.kind {
1400 TypeDefKind::Type(Type::Id(id)) => id,
1401 _ => return None,
1402 };
1403 let other = &self.types[dep];
1404 if ty.owner == other.owner {
1405 None
1406 } else {
1407 match other.owner {
1408 TypeOwner::Interface(id) => Some(id),
1409 _ => unreachable!(),
1410 }
1411 }
1412 }
1413
1414 pub fn interface_direct_deps(&self, id: InterfaceId) -> impl Iterator<Item = InterfaceId> + '_ {
1424 self.interfaces[id]
1425 .types
1426 .iter()
1427 .filter_map(move |(_name, ty)| self.type_interface_dep(*ty))
1428 }
1429
1430 pub fn package_direct_deps(&self, id: PackageId) -> impl Iterator<Item = PackageId> + '_ {
1440 let pkg = &self.packages[id];
1441
1442 pkg.interfaces
1443 .iter()
1444 .flat_map(move |(_name, id)| self.interface_direct_deps(*id))
1445 .chain(pkg.worlds.iter().flat_map(move |(_name, id)| {
1446 let world = &self.worlds[*id];
1447 world
1448 .imports
1449 .iter()
1450 .chain(world.exports.iter())
1451 .filter_map(move |(_name, item)| match item {
1452 WorldItem::Interface { id, .. } => Some(*id),
1453 WorldItem::Function(_) => None,
1454 WorldItem::Type { id, .. } => self.type_interface_dep(*id),
1455 })
1456 }))
1457 .filter_map(move |iface_id| {
1458 let pkg = self.interfaces[iface_id].package?;
1459 if pkg == id { None } else { Some(pkg) }
1460 })
1461 }
1462
1463 pub fn topological_packages(&self) -> Vec<PackageId> {
1469 let mut pushed = vec![false; self.packages.len()];
1470 let mut order = Vec::new();
1471 for (id, _) in self.packages.iter() {
1472 self.build_topological_package_ordering(id, &mut pushed, &mut order);
1473 }
1474 order
1475 }
1476
1477 fn build_topological_package_ordering(
1478 &self,
1479 id: PackageId,
1480 pushed: &mut Vec<bool>,
1481 order: &mut Vec<PackageId>,
1482 ) {
1483 if pushed[id.index()] {
1484 return;
1485 }
1486 for dep in self.package_direct_deps(id) {
1487 self.build_topological_package_ordering(dep, pushed, order);
1488 }
1489 order.push(id);
1490 pushed[id.index()] = true;
1491 }
1492
1493 #[doc(hidden)]
1494 pub fn assert_valid(&self) {
1495 let mut package_interfaces = Vec::new();
1496 let mut package_worlds = Vec::new();
1497 for (id, pkg) in self.packages.iter() {
1498 let mut interfaces = HashSet::new();
1499 for (name, iface) in pkg.interfaces.iter() {
1500 assert!(interfaces.insert(*iface));
1501 let iface = &self.interfaces[*iface];
1502 assert_eq!(name, iface.name.as_ref().unwrap());
1503 assert_eq!(iface.package.unwrap(), id);
1504 }
1505 package_interfaces.push(pkg.interfaces.values().copied().collect::<HashSet<_>>());
1506 let mut worlds = HashSet::new();
1507 for (name, world) in pkg.worlds.iter() {
1508 assert!(worlds.insert(*world));
1509 assert_eq!(
1510 pkg.worlds.get_key_value(name),
1511 Some((name, world)),
1512 "`MutableKeys` impl may have been used to change a key's hash or equality"
1513 );
1514 let world = &self.worlds[*world];
1515 assert_eq!(*name, world.name);
1516 assert_eq!(world.package.unwrap(), id);
1517 }
1518 package_worlds.push(pkg.worlds.values().copied().collect::<HashSet<_>>());
1519 }
1520
1521 let mut interface_types = Vec::new();
1522 for (id, iface) in self.interfaces.iter() {
1523 assert!(self.packages.get(iface.package.unwrap()).is_some());
1524 if iface.name.is_some() {
1525 match iface.clone_of {
1526 Some(other) => {
1527 assert_eq!(iface.name, self.interfaces[other].name);
1528 }
1529 None => {
1530 assert!(package_interfaces[iface.package.unwrap().index()].contains(&id));
1531 }
1532 }
1533 }
1534
1535 for (name, ty) in iface.types.iter() {
1536 let ty = &self.types[*ty];
1537 assert_eq!(ty.name.as_ref(), Some(name));
1538 assert_eq!(ty.owner, TypeOwner::Interface(id));
1539 }
1540 interface_types.push(iface.types.values().copied().collect::<HashSet<_>>());
1541 for (name, f) in iface.functions.iter() {
1542 assert_eq!(*name, f.name);
1543 }
1544 }
1545
1546 let mut world_types = Vec::new();
1547 for (id, world) in self.worlds.iter() {
1548 log::debug!("validating world {}", &world.name);
1549 if let Some(package) = world.package {
1550 assert!(self.packages.get(package).is_some());
1551 assert!(package_worlds[package.index()].contains(&id));
1552 }
1553 assert!(world.includes.is_empty());
1554
1555 let mut types = HashSet::new();
1556 for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1557 log::debug!("validating world item: {}", self.name_world_key(name));
1558 match item {
1559 WorldItem::Interface { id, .. } => {
1560 if matches!(name, WorldKey::Name(_)) {
1563 assert_eq!(self.interfaces[*id].package, world.package);
1564 }
1565 }
1566 WorldItem::Function(f) => {
1567 assert!(!matches!(name, WorldKey::Interface(_)));
1568 assert_eq!(f.name, name.clone().unwrap_name());
1569 }
1570 WorldItem::Type { id: ty, .. } => {
1571 assert!(!matches!(name, WorldKey::Interface(_)));
1572 assert!(types.insert(*ty));
1573 let ty = &self.types[*ty];
1574 assert_eq!(ty.name, Some(name.clone().unwrap_name()));
1575 assert_eq!(ty.owner, TypeOwner::World(id));
1576 }
1577 }
1578 }
1579 self.assert_world_elaborated(world);
1580 world_types.push(types);
1581 }
1582
1583 for (ty_id, ty) in self.types.iter() {
1584 match ty.owner {
1585 TypeOwner::Interface(id) => {
1586 assert!(self.interfaces.get(id).is_some());
1587 assert!(interface_types[id.index()].contains(&ty_id));
1588 }
1589 TypeOwner::World(id) => {
1590 assert!(self.worlds.get(id).is_some());
1591 assert!(world_types[id.index()].contains(&ty_id));
1592 }
1593 TypeOwner::None => {}
1594 }
1595 }
1596
1597 self.assert_topologically_sorted();
1598 }
1599
1600 fn assert_topologically_sorted(&self) {
1601 let mut positions = IndexMap::default();
1602 for id in self.topological_packages() {
1603 let pkg = &self.packages[id];
1604 log::debug!("pkg {}", pkg.name);
1605 let prev = positions.insert(Some(id), IndexSet::default());
1606 assert!(prev.is_none());
1607 }
1608 positions.insert(None, IndexSet::default());
1609
1610 for (id, iface) in self.interfaces.iter() {
1611 log::debug!("iface {:?}", iface.name);
1612 let ok = positions.get_mut(&iface.package).unwrap().insert(id);
1613 assert!(ok);
1614 }
1615
1616 for (_, world) in self.worlds.iter() {
1617 log::debug!("world {:?}", world.name);
1618
1619 let my_package = world.package;
1620 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1621
1622 for (_, item) in world.imports.iter().chain(&world.exports) {
1623 let id = match item {
1624 WorldItem::Interface { id, .. } => *id,
1625 _ => continue,
1626 };
1627 let other_package = self.interfaces[id].package;
1628 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1629
1630 assert!(other_package_pos <= my_package_pos);
1631 }
1632 }
1633
1634 for (_id, ty) in self.types.iter() {
1635 log::debug!("type {:?} {:?}", ty.name, ty.owner);
1636 let other_id = match ty.kind {
1637 TypeDefKind::Type(Type::Id(ty)) => ty,
1638 _ => continue,
1639 };
1640 let other = &self.types[other_id];
1641 if ty.kind == other.kind {
1642 continue;
1643 }
1644 let my_interface = match ty.owner {
1645 TypeOwner::Interface(id) => id,
1646 _ => continue,
1647 };
1648 let other_interface = match other.owner {
1649 TypeOwner::Interface(id) => id,
1650 _ => continue,
1651 };
1652
1653 let my_package = self.interfaces[my_interface].package;
1654 let other_package = self.interfaces[other_interface].package;
1655 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1656 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1657
1658 if my_package_pos == other_package_pos {
1659 let interfaces = &positions[&my_package];
1660 let my_interface_pos = interfaces.get_index_of(&my_interface).unwrap();
1661 let other_interface_pos = interfaces.get_index_of(&other_interface).unwrap();
1662 assert!(other_interface_pos <= my_interface_pos);
1663 } else {
1664 assert!(other_package_pos < my_package_pos);
1665 }
1666 }
1667 }
1668
1669 fn assert_world_elaborated(&self, world: &World) {
1670 for (key, item) in world.imports.iter() {
1671 log::debug!(
1672 "asserting elaborated world import {}",
1673 self.name_world_key(key)
1674 );
1675 match item {
1676 WorldItem::Type { id, .. } => self.assert_world_imports_type_deps(world, key, *id),
1677
1678 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1680
1681 WorldItem::Interface { id, .. } => {
1683 for dep in self.interface_direct_deps(*id) {
1684 assert!(
1685 world.imports.contains_key(&WorldKey::Interface(dep)),
1686 "world import of {} is missing transitive dep of {}",
1687 self.name_world_key(key),
1688 self.id_of(dep).unwrap(),
1689 );
1690 }
1691 }
1692 }
1693 }
1694 for (key, item) in world.exports.iter() {
1695 log::debug!(
1696 "asserting elaborated world export {}",
1697 self.name_world_key(key)
1698 );
1699 match item {
1700 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1702
1703 WorldItem::Interface { id, .. } => {
1707 for dep in self.interface_direct_deps(*id) {
1708 let dep_key = WorldKey::Interface(dep);
1709 if world.exports.contains_key(&dep_key) {
1710 continue;
1711 }
1712 self.foreach_interface_dep(dep, &mut |dep| {
1713 let dep_key = WorldKey::Interface(dep);
1714 assert!(
1715 world.imports.contains_key(&dep_key),
1716 "world should import {} (required by {})",
1717 self.name_world_key(&dep_key),
1718 self.name_world_key(key),
1719 );
1720 assert!(
1721 !world.exports.contains_key(&dep_key),
1722 "world should not export {} (required by {})",
1723 self.name_world_key(&dep_key),
1724 self.name_world_key(key),
1725 );
1726 });
1727 }
1728 }
1729
1730 WorldItem::Type { .. } => unreachable!(),
1732 }
1733 }
1734 }
1735
1736 fn assert_world_imports_type_deps(&self, world: &World, key: &WorldKey, ty: TypeId) {
1737 let ty = &self.types[ty];
1740 if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
1741 if let TypeOwner::Interface(id) = self.types[other].owner {
1742 let key = WorldKey::Interface(id);
1743 assert!(world.imports.contains_key(&key));
1744 return;
1745 }
1746 }
1747
1748 let mut visitor = MyVisit(self, Vec::new());
1752 visitor.visit_type_def(self, ty);
1753 for ty in visitor.1 {
1754 let ty = &self.types[ty];
1755 let Some(name) = ty.name.clone() else {
1756 continue;
1757 };
1758 let dep_key = WorldKey::Name(name);
1759 assert!(
1760 world.imports.contains_key(&dep_key),
1761 "world import `{}` should also force an import of `{}`",
1762 self.name_world_key(key),
1763 self.name_world_key(&dep_key),
1764 );
1765 }
1766
1767 struct MyVisit<'a>(&'a Resolve, Vec<TypeId>);
1768
1769 impl TypeIdVisitor for MyVisit<'_> {
1770 fn before_visit_type_id(&mut self, id: TypeId) -> bool {
1771 self.1.push(id);
1772 self.0.types[id].name.is_none()
1774 }
1775 }
1776 }
1777
1778 fn assert_world_function_imports_types(&self, world: &World, key: &WorldKey, func: &Function) {
1782 for ty in func
1783 .parameter_and_result_types()
1784 .chain(func.kind.resource().map(Type::Id))
1785 {
1786 let Type::Id(id) = ty else {
1787 continue;
1788 };
1789 self.assert_world_imports_type_deps(world, key, id);
1790 }
1791 }
1792
1793 fn include_stability(
1809 &self,
1810 stability: &Stability,
1811 pkg_id: &PackageId,
1812 span: Span,
1813 ) -> Result<bool> {
1814 let err = |msg: String| -> anyhow::Error { Error::new(span, msg).into() };
1815 Ok(match stability {
1816 Stability::Unknown => true,
1817 Stability::Stable { since, .. } => {
1820 let Some(p) = self.packages.get(*pkg_id) else {
1821 return Ok(true);
1829 };
1830
1831 let package_version = p.name.version.as_ref().ok_or_else(|| {
1834 err(format!(
1835 "package [{}] contains a feature gate with a version \
1836 specifier, so it must have a version",
1837 p.name
1838 ))
1839 })?;
1840
1841 if since > package_version {
1845 return Err(err(format!(
1846 "feature gate cannot reference unreleased version \
1847 {since} of package [{}] (current version {package_version})",
1848 p.name
1849 )));
1850 }
1851
1852 true
1853 }
1854 Stability::Unstable { feature, .. } => {
1855 self.features.contains(feature) || self.all_features
1856 }
1857 })
1858 }
1859
1860 fn include_type(&self, ty: &TypeDef, pkgid: PackageId, span: Span) -> Result<bool> {
1863 self.include_stability(&ty.stability, &pkgid, span)
1864 .with_context(|| {
1865 format!(
1866 "failed to process feature gate for type [{}] in package [{}]",
1867 ty.name.as_ref().map(String::as_str).unwrap_or("<unknown>"),
1868 self.packages[pkgid].name,
1869 )
1870 })
1871 }
1872
1873 fn elaborate_world(&mut self, world_id: WorldId) -> Result<()> {
1885 let mut new_imports = IndexMap::default();
1889 let world = &self.worlds[world_id];
1890
1891 let sort_key = |resolve: &Resolve, item: &WorldItem| match item {
1914 WorldItem::Interface { .. } => 0,
1915 WorldItem::Type { id, .. } => {
1916 let ty = &resolve.types[*id];
1917 match ty.kind {
1918 TypeDefKind::Type(Type::Id(t)) if resolve.types[t].owner != ty.owner => 1,
1919 _ => 2,
1920 }
1921 }
1922 WorldItem::Function(f) => {
1923 if f.kind.resource().is_none() {
1924 3
1925 } else {
1926 4
1927 }
1928 }
1929 };
1930
1931 let mut world_imports = world.imports.iter().collect::<Vec<_>>();
1934 world_imports.sort_by_key(|(_name, import)| sort_key(self, import));
1935 for (name, item) in world_imports {
1936 match item {
1937 WorldItem::Interface { id, stability, .. } => {
1940 self.elaborate_world_import(&mut new_imports, name.clone(), *id, &stability);
1941 }
1942
1943 WorldItem::Function(_) => {
1946 let prev = new_imports.insert(name.clone(), item.clone());
1947 assert!(prev.is_none());
1948 }
1949
1950 WorldItem::Type { id, .. } => {
1954 if let Some(dep) = self.type_interface_dep(*id) {
1955 self.elaborate_world_import(
1956 &mut new_imports,
1957 WorldKey::Interface(dep),
1958 dep,
1959 &self.types[*id].stability,
1960 );
1961 }
1962 let prev = new_imports.insert(name.clone(), item.clone());
1963 assert!(prev.is_none());
1964 }
1965 }
1966 }
1967
1968 let mut new_exports = IndexMap::default();
1974 let mut export_interfaces = IndexMap::default();
1975 for (name, item) in world.exports.iter() {
1976 match item {
1977 WorldItem::Interface { id, stability, .. } => {
1978 let prev = export_interfaces.insert(*id, (name.clone(), stability));
1979 assert!(prev.is_none());
1980 }
1981 WorldItem::Function(_) => {
1982 let prev = new_exports.insert(name.clone(), item.clone());
1983 assert!(prev.is_none());
1984 }
1985 WorldItem::Type { .. } => unreachable!(),
1986 }
1987 }
1988
1989 self.elaborate_world_exports(&export_interfaces, &mut new_imports, &mut new_exports)?;
1990
1991 new_imports.sort_by_cached_key(|_name, import| sort_key(self, import));
1995
1996 log::trace!("imports = {new_imports:?}");
1999 log::trace!("exports = {new_exports:?}");
2000 let world = &mut self.worlds[world_id];
2001 world.imports = new_imports;
2002 world.exports = new_exports;
2003
2004 Ok(())
2005 }
2006
2007 fn elaborate_world_import(
2008 &self,
2009 imports: &mut IndexMap<WorldKey, WorldItem>,
2010 key: WorldKey,
2011 id: InterfaceId,
2012 stability: &Stability,
2013 ) {
2014 if imports.contains_key(&key) {
2015 return;
2016 }
2017 for dep in self.interface_direct_deps(id) {
2018 self.elaborate_world_import(imports, WorldKey::Interface(dep), dep, stability);
2019 }
2020 let prev = imports.insert(
2021 key,
2022 WorldItem::Interface {
2023 id,
2024 stability: stability.clone(),
2025 span: Default::default(),
2026 },
2027 );
2028 assert!(prev.is_none());
2029 }
2030
2031 fn elaborate_world_exports(
2078 &self,
2079 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2080 imports: &mut IndexMap<WorldKey, WorldItem>,
2081 exports: &mut IndexMap<WorldKey, WorldItem>,
2082 ) -> Result<()> {
2083 let mut required_imports = HashSet::new();
2084 for (id, (key, stability)) in export_interfaces.iter() {
2085 let name = self.name_world_key(&key);
2086 let ok = add_world_export(
2087 self,
2088 imports,
2089 exports,
2090 export_interfaces,
2091 &mut required_imports,
2092 *id,
2093 key,
2094 true,
2095 stability,
2096 );
2097 if !ok {
2098 bail!(
2099 InvalidTransitiveDependency(name),
2117 );
2118 }
2119 }
2120 return Ok(());
2121
2122 fn add_world_export(
2123 resolve: &Resolve,
2124 imports: &mut IndexMap<WorldKey, WorldItem>,
2125 exports: &mut IndexMap<WorldKey, WorldItem>,
2126 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2127 required_imports: &mut HashSet<InterfaceId>,
2128 id: InterfaceId,
2129 key: &WorldKey,
2130 add_export: bool,
2131 stability: &Stability,
2132 ) -> bool {
2133 if exports.contains_key(key) {
2134 if add_export {
2135 return true;
2136 } else {
2137 return false;
2138 }
2139 }
2140 if !add_export && required_imports.contains(&id) {
2143 return true;
2144 }
2145 let ok = resolve.interface_direct_deps(id).all(|dep| {
2146 let key = WorldKey::Interface(dep);
2147 let add_export = add_export && export_interfaces.contains_key(&dep);
2148 add_world_export(
2149 resolve,
2150 imports,
2151 exports,
2152 export_interfaces,
2153 required_imports,
2154 dep,
2155 &key,
2156 add_export,
2157 stability,
2158 )
2159 });
2160 if !ok {
2161 return false;
2162 }
2163 let item = WorldItem::Interface {
2164 id,
2165 stability: stability.clone(),
2166 span: Default::default(),
2167 };
2168 if add_export {
2169 if required_imports.contains(&id) {
2170 return false;
2171 }
2172 exports.insert(key.clone(), item);
2173 } else {
2174 required_imports.insert(id);
2175 imports.insert(key.clone(), item);
2176 }
2177 true
2178 }
2179 }
2180
2181 pub fn merge_world_imports_based_on_semver(&mut self, world_id: WorldId) -> Result<()> {
2193 let world = &self.worlds[world_id];
2194
2195 let mut semver_tracks = HashMap::new();
2204 let mut to_remove = HashSet::new();
2205 for (key, _) in world.imports.iter() {
2206 let iface_id = match key {
2207 WorldKey::Interface(id) => *id,
2208 WorldKey::Name(_) => continue,
2209 };
2210 let (track, version) = match self.semver_track(iface_id) {
2211 Some(track) => track,
2212 None => continue,
2213 };
2214 log::debug!(
2215 "{} is on track {}/{}",
2216 self.id_of(iface_id).unwrap(),
2217 track.0,
2218 track.1,
2219 );
2220 match semver_tracks.entry(track.clone()) {
2221 Entry::Vacant(e) => {
2222 e.insert((version, iface_id));
2223 }
2224 Entry::Occupied(mut e) => match version.cmp(&e.get().0) {
2225 Ordering::Greater => {
2226 to_remove.insert(e.get().1);
2227 e.insert((version, iface_id));
2228 }
2229 Ordering::Equal => {}
2230 Ordering::Less => {
2231 to_remove.insert(iface_id);
2232 }
2233 },
2234 }
2235 }
2236
2237 let mut replacements = HashMap::new();
2240 for id in to_remove {
2241 let (track, _) = self.semver_track(id).unwrap();
2242 let (_, latest) = semver_tracks[&track];
2243 let prev = replacements.insert(id, latest);
2244 assert!(prev.is_none());
2245 }
2246 drop(semver_tracks);
2249
2250 for (to_replace, replace_with) in replacements.iter() {
2255 self.merge_world_item(
2256 &WorldItem::Interface {
2257 id: *to_replace,
2258 stability: Default::default(),
2259 span: Default::default(),
2260 },
2261 &WorldItem::Interface {
2262 id: *replace_with,
2263 stability: Default::default(),
2264 span: Default::default(),
2265 },
2266 )
2267 .with_context(|| {
2268 let old_name = self.id_of(*to_replace).unwrap();
2269 let new_name = self.id_of(*replace_with).unwrap();
2270 format!(
2271 "failed to upgrade `{old_name}` to `{new_name}`, was \
2272 this semver-compatible update not semver compatible?"
2273 )
2274 })?;
2275 }
2276
2277 for (to_replace, replace_with) in replacements.iter() {
2278 log::debug!(
2279 "REPLACE {} => {}",
2280 self.id_of(*to_replace).unwrap(),
2281 self.id_of(*replace_with).unwrap(),
2282 );
2283 }
2284
2285 for (key, item) in mem::take(&mut self.worlds[world_id].imports) {
2294 if let WorldItem::Interface { id, .. } = item {
2295 if replacements.contains_key(&id) {
2296 continue;
2297 }
2298 }
2299
2300 self.update_interface_deps_of_world_item(&item, &replacements);
2301
2302 let prev = self.worlds[world_id].imports.insert(key, item);
2303 assert!(prev.is_none());
2304 }
2305 for (key, item) in mem::take(&mut self.worlds[world_id].exports) {
2306 self.update_interface_deps_of_world_item(&item, &replacements);
2307 let prev = self.worlds[world_id].exports.insert(key, item);
2308 assert!(prev.is_none());
2309 }
2310
2311 let ids = self.worlds.iter().map(|(id, _)| id).collect::<Vec<_>>();
2317 for world_id in ids {
2318 self.elaborate_world(world_id).with_context(|| {
2319 let name = &self.worlds[world_id].name;
2320 format!(
2321 "failed to elaborate world `{name}` after deduplicating imports \
2322 based on semver"
2323 )
2324 })?;
2325 }
2326
2327 #[cfg(debug_assertions)]
2328 self.assert_valid();
2329
2330 Ok(())
2331 }
2332
2333 fn update_interface_deps_of_world_item(
2334 &mut self,
2335 item: &WorldItem,
2336 replacements: &HashMap<InterfaceId, InterfaceId>,
2337 ) {
2338 match *item {
2339 WorldItem::Type { id, .. } => self.update_interface_dep_of_type(id, &replacements),
2340 WorldItem::Interface { id, .. } => {
2341 let types = self.interfaces[id]
2342 .types
2343 .values()
2344 .copied()
2345 .collect::<Vec<_>>();
2346 for ty in types {
2347 self.update_interface_dep_of_type(ty, &replacements);
2348 }
2349 }
2350 WorldItem::Function(_) => {}
2351 }
2352 }
2353
2354 fn semver_track(&self, id: InterfaceId) -> Option<((PackageName, String), &Version)> {
2365 let iface = &self.interfaces[id];
2366 let pkg = &self.packages[iface.package?];
2367 let version = pkg.name.version.as_ref()?;
2368 let mut name = pkg.name.clone();
2369 name.version = Some(PackageName::version_compat_track(version));
2370 Some(((name, iface.name.clone()?), version))
2371 }
2372
2373 fn update_interface_dep_of_type(
2377 &mut self,
2378 ty: TypeId,
2379 replacements: &HashMap<InterfaceId, InterfaceId>,
2380 ) {
2381 let to_replace = match self.type_interface_dep(ty) {
2382 Some(id) => id,
2383 None => return,
2384 };
2385 let replace_with = match replacements.get(&to_replace) {
2386 Some(id) => id,
2387 None => return,
2388 };
2389 let dep = match self.types[ty].kind {
2390 TypeDefKind::Type(Type::Id(id)) => id,
2391 _ => return,
2392 };
2393 let name = self.types[dep].name.as_ref().unwrap();
2394 let replacement_id = self.interfaces[*replace_with].types[name];
2397 self.types[ty].kind = TypeDefKind::Type(Type::Id(replacement_id));
2398 }
2399
2400 pub fn wasm_import_name(
2407 &self,
2408 mangling: ManglingAndAbi,
2409 import: WasmImport<'_>,
2410 ) -> (String, String) {
2411 match mangling {
2412 ManglingAndAbi::Standard32 => match import {
2413 WasmImport::Func { interface, func } => {
2414 let module = match interface {
2415 Some(key) => format!("cm32p2|{}", self.name_canonicalized_world_key(key)),
2416 None => format!("cm32p2"),
2417 };
2418 (module, func.name.clone())
2419 }
2420 WasmImport::ResourceIntrinsic {
2421 interface,
2422 resource,
2423 intrinsic,
2424 } => {
2425 let name = self.types[resource].name.as_ref().unwrap();
2426 let (prefix, name) = match intrinsic {
2427 ResourceIntrinsic::ImportedDrop => ("", format!("{name}_drop")),
2428 ResourceIntrinsic::ExportedDrop => ("_ex_", format!("{name}_drop")),
2429 ResourceIntrinsic::ExportedNew => ("_ex_", format!("{name}_new")),
2430 ResourceIntrinsic::ExportedRep => ("_ex_", format!("{name}_rep")),
2431 };
2432 let module = match interface {
2433 Some(key) => {
2434 format!("cm32p2|{prefix}{}", self.name_canonicalized_world_key(key))
2435 }
2436 None => {
2437 assert_eq!(prefix, "");
2438 format!("cm32p2")
2439 }
2440 };
2441 (module, name)
2442 }
2443 WasmImport::FutureIntrinsic { .. } | WasmImport::StreamIntrinsic { .. } => {
2444 panic!(
2445 "at the time of writing, standard32 name mangling only supports the \
2446 synchronous ABI and does not define future/stream intrinsic imports; \
2447 use legacy mangling for these imports"
2448 )
2449 }
2450 },
2451 ManglingAndAbi::Legacy(abi) => match import {
2452 WasmImport::Func { interface, func } => {
2453 let module = match interface {
2454 Some(key) => self.name_world_key(key),
2455 None => format!("$root"),
2456 };
2457 (module, format!("{}{}", abi.import_prefix(), func.name))
2458 }
2459 WasmImport::ResourceIntrinsic {
2460 interface,
2461 resource,
2462 intrinsic,
2463 } => {
2464 let name = self.types[resource].name.as_ref().unwrap();
2465 let (prefix, name) = match intrinsic {
2466 ResourceIntrinsic::ImportedDrop => ("", format!("[resource-drop]{name}")),
2467 ResourceIntrinsic::ExportedDrop => {
2468 ("[export]", format!("[resource-drop]{name}"))
2469 }
2470 ResourceIntrinsic::ExportedNew => {
2471 ("[export]", format!("[resource-new]{name}"))
2472 }
2473 ResourceIntrinsic::ExportedRep => {
2474 ("[export]", format!("[resource-rep]{name}"))
2475 }
2476 };
2477 let module = match interface {
2478 Some(key) => format!("{prefix}{}", self.name_world_key(key)),
2479 None => {
2480 assert_eq!(prefix, "");
2481 format!("$root")
2482 }
2483 };
2484 (module, format!("{}{name}", abi.import_prefix()))
2485 }
2486 WasmImport::FutureIntrinsic {
2487 interface,
2488 func,
2489 ty,
2490 intrinsic,
2491 exported,
2492 async_,
2493 } => {
2494 let module_prefix = if exported { "[export]" } else { "" };
2495 let module = match interface {
2496 Some(key) => format!("{module_prefix}{}", self.name_world_key(key)),
2497 None => format!("{module_prefix}$root"),
2498 };
2499 let type_index = match ty {
2500 Some(ty) => func
2501 .find_futures_and_streams(self)
2502 .into_iter()
2503 .position(|candidate| candidate == ty)
2504 .unwrap_or_else(|| {
2505 panic!(
2506 "future type {ty:?} not found in `find_futures_and_streams` for `{}`",
2507 func.name
2508 )
2509 })
2510 .to_string(),
2511 None => "unit".to_string(),
2512 };
2513 let (async_prefix, name) = match intrinsic {
2514 FutureIntrinsic::New => {
2515 assert!(!async_, "future.new cannot be async-lowered");
2516 ("", "new")
2517 }
2518 FutureIntrinsic::Read => {
2519 (if async_ { "[async-lower]" } else { "" }, "read")
2520 }
2521 FutureIntrinsic::Write => {
2522 (if async_ { "[async-lower]" } else { "" }, "write")
2523 }
2524 FutureIntrinsic::CancelRead => {
2525 (if async_ { "[async-lower]" } else { "" }, "cancel-read")
2526 }
2527 FutureIntrinsic::CancelWrite => {
2528 (if async_ { "[async-lower]" } else { "" }, "cancel-write")
2529 }
2530 FutureIntrinsic::DropReadable => {
2531 assert!(!async_, "future.drop-readable cannot be async-lowered");
2532 ("", "drop-readable")
2533 }
2534 FutureIntrinsic::DropWritable => {
2535 assert!(!async_, "future.drop-writable cannot be async-lowered");
2536 ("", "drop-writable")
2537 }
2538 };
2539 (
2540 module,
2541 format!("{async_prefix}[future-{name}-{type_index}]{}", func.name),
2542 )
2543 }
2544 WasmImport::StreamIntrinsic {
2545 interface,
2546 func,
2547 ty,
2548 intrinsic,
2549 exported,
2550 async_,
2551 } => {
2552 let module_prefix = if exported { "[export]" } else { "" };
2553 let module = match interface {
2554 Some(key) => format!("{module_prefix}{}", self.name_world_key(key)),
2555 None => format!("{module_prefix}$root"),
2556 };
2557 let type_index = match ty {
2558 Some(ty) => func
2559 .find_futures_and_streams(self)
2560 .into_iter()
2561 .position(|candidate| candidate == ty)
2562 .unwrap_or_else(|| {
2563 panic!(
2564 "stream type {ty:?} not found in `find_futures_and_streams` for `{}`",
2565 func.name
2566 )
2567 })
2568 .to_string(),
2569 None => "unit".to_string(),
2570 };
2571 let (async_prefix, name) = match intrinsic {
2572 StreamIntrinsic::New => {
2573 assert!(!async_, "stream.new cannot be async-lowered");
2574 ("", "new")
2575 }
2576 StreamIntrinsic::Read => {
2577 (if async_ { "[async-lower]" } else { "" }, "read")
2578 }
2579 StreamIntrinsic::Write => {
2580 (if async_ { "[async-lower]" } else { "" }, "write")
2581 }
2582 StreamIntrinsic::CancelRead => {
2583 (if async_ { "[async-lower]" } else { "" }, "cancel-read")
2584 }
2585 StreamIntrinsic::CancelWrite => {
2586 (if async_ { "[async-lower]" } else { "" }, "cancel-write")
2587 }
2588 StreamIntrinsic::DropReadable => {
2589 assert!(!async_, "stream.drop-readable cannot be async-lowered");
2590 ("", "drop-readable")
2591 }
2592 StreamIntrinsic::DropWritable => {
2593 assert!(!async_, "stream.drop-writable cannot be async-lowered");
2594 ("", "drop-writable")
2595 }
2596 };
2597 (
2598 module,
2599 format!("{async_prefix}[stream-{name}-{type_index}]{}", func.name),
2600 )
2601 }
2602 },
2603 }
2604 }
2605
2606 pub fn wasm_export_name(&self, mangling: ManglingAndAbi, export: WasmExport<'_>) -> String {
2610 match mangling {
2611 ManglingAndAbi::Standard32 => match export {
2612 WasmExport::Func {
2613 interface,
2614 func,
2615 kind,
2616 } => {
2617 let mut name = String::from("cm32p2|");
2618 if let Some(interface) = interface {
2619 let s = self.name_canonicalized_world_key(interface);
2620 name.push_str(&s);
2621 }
2622 name.push_str("|");
2623 name.push_str(&func.name);
2624 match kind {
2625 WasmExportKind::Normal => {}
2626 WasmExportKind::PostReturn => name.push_str("_post"),
2627 WasmExportKind::Callback => todo!(
2628 "not yet supported: \
2629 async callback functions using standard name mangling"
2630 ),
2631 }
2632 name
2633 }
2634 WasmExport::ResourceDtor {
2635 interface,
2636 resource,
2637 } => {
2638 let name = self.types[resource].name.as_ref().unwrap();
2639 let interface = self.name_canonicalized_world_key(interface);
2640 format!("cm32p2|{interface}|{name}_dtor")
2641 }
2642 WasmExport::Memory => "cm32p2_memory".to_string(),
2643 WasmExport::Initialize => "cm32p2_initialize".to_string(),
2644 WasmExport::Realloc => "cm32p2_realloc".to_string(),
2645 },
2646 ManglingAndAbi::Legacy(abi) => match export {
2647 WasmExport::Func {
2648 interface,
2649 func,
2650 kind,
2651 } => {
2652 let mut name = abi.export_prefix().to_string();
2653 match kind {
2654 WasmExportKind::Normal => {}
2655 WasmExportKind::PostReturn => name.push_str("cabi_post_"),
2656 WasmExportKind::Callback => {
2657 assert!(matches!(abi, LiftLowerAbi::AsyncCallback));
2658 name = format!("[callback]{name}")
2659 }
2660 }
2661 if let Some(interface) = interface {
2662 let s = self.name_world_key(interface);
2663 name.push_str(&s);
2664 name.push_str("#");
2665 }
2666 name.push_str(&func.name);
2667 name
2668 }
2669 WasmExport::ResourceDtor {
2670 interface,
2671 resource,
2672 } => {
2673 let name = self.types[resource].name.as_ref().unwrap();
2674 let interface = self.name_world_key(interface);
2675 format!("{}{interface}#[dtor]{name}", abi.export_prefix())
2676 }
2677 WasmExport::Memory => "memory".to_string(),
2678 WasmExport::Initialize => "_initialize".to_string(),
2679 WasmExport::Realloc => "cabi_realloc".to_string(),
2680 },
2681 }
2682 }
2683
2684 pub fn generate_nominal_type_ids(&mut self, world: WorldId) {
2724 let mut imports = HashSet::new();
2725
2726 for import in self.worlds[world].imports.values() {
2729 if let WorldItem::Interface { id, .. } = import {
2730 imports.insert(*id);
2731 }
2732 }
2733
2734 let mut to_clone = IndexMap::default();
2735 for (i, export) in self.worlds[world].exports.values().enumerate() {
2736 let id = match export {
2737 WorldItem::Interface { id, .. } => *id,
2738
2739 WorldItem::Function(_) => continue,
2742
2743 WorldItem::Type { .. } => unreachable!(),
2744 };
2745
2746 let imported_and_exported = imports.contains(&id);
2750 let any_dep_rewritten = self
2751 .interface_direct_deps(id)
2752 .any(|dep| to_clone.contains_key(&dep));
2753 if !(imported_and_exported || any_dep_rewritten) {
2754 continue;
2755 }
2756
2757 to_clone.insert(id, i);
2758 }
2759
2760 let mut maps = CloneMaps::default();
2761 let mut cloner = clone::Cloner::new(
2762 self,
2763 &mut maps,
2764 TypeOwner::World(world),
2765 TypeOwner::World(world),
2766 );
2767 for (id, i) in to_clone {
2768 let mut new_id = id;
2774 cloner.new_package = cloner.resolve.interfaces[new_id].package;
2775 cloner.interface(&mut new_id);
2776
2777 let exports = &mut cloner.resolve.worlds[world].exports;
2781 let (key, prev) = exports.get_index_mut(i).unwrap();
2782 match prev {
2783 WorldItem::Interface { id, .. } => *id = new_id,
2784 _ => unreachable!(),
2785 }
2786
2787 match key {
2788 WorldKey::Interface(_) => {
2794 exports
2795 .replace_index(i, WorldKey::Interface(new_id))
2796 .unwrap();
2797 }
2798
2799 WorldKey::Name(_) => {}
2802 }
2803 }
2804
2805 #[cfg(debug_assertions)]
2806 self.assert_valid();
2807 }
2808}
2809
2810#[derive(Debug)]
2812pub enum WasmImport<'a> {
2813 Func {
2815 interface: Option<&'a WorldKey>,
2820
2821 func: &'a Function,
2823 },
2824
2825 ResourceIntrinsic {
2827 interface: Option<&'a WorldKey>,
2829
2830 resource: TypeId,
2832
2833 intrinsic: ResourceIntrinsic,
2835 },
2836
2837 FutureIntrinsic {
2839 interface: Option<&'a WorldKey>,
2841
2842 func: &'a Function,
2844
2845 ty: Option<TypeId>,
2849
2850 intrinsic: FutureIntrinsic,
2852
2853 exported: bool,
2857
2858 async_: bool,
2862 },
2863
2864 StreamIntrinsic {
2866 interface: Option<&'a WorldKey>,
2868
2869 func: &'a Function,
2871
2872 ty: Option<TypeId>,
2876
2877 intrinsic: StreamIntrinsic,
2879
2880 exported: bool,
2884
2885 async_: bool,
2889 },
2890}
2891
2892#[derive(Debug)]
2895pub enum ResourceIntrinsic {
2896 ImportedDrop,
2897 ExportedDrop,
2898 ExportedNew,
2899 ExportedRep,
2900}
2901
2902#[derive(Debug)]
2905pub enum FutureIntrinsic {
2906 New,
2907 Read,
2908 Write,
2909 CancelRead,
2910 CancelWrite,
2911 DropReadable,
2912 DropWritable,
2913}
2914
2915#[derive(Debug)]
2918pub enum StreamIntrinsic {
2919 New,
2920 Read,
2921 Write,
2922 CancelRead,
2923 CancelWrite,
2924 DropReadable,
2925 DropWritable,
2926}
2927
2928#[derive(Debug)]
2931pub enum WasmExportKind {
2932 Normal,
2934
2935 PostReturn,
2937
2938 Callback,
2940}
2941
2942#[derive(Debug)]
2945pub enum WasmExport<'a> {
2946 Func {
2948 interface: Option<&'a WorldKey>,
2951
2952 func: &'a Function,
2954
2955 kind: WasmExportKind,
2957 },
2958
2959 ResourceDtor {
2961 interface: &'a WorldKey,
2963 resource: TypeId,
2965 },
2966
2967 Memory,
2969
2970 Initialize,
2972
2973 Realloc,
2975}
2976
2977#[derive(Default)]
2980pub struct Remap {
2981 pub types: Vec<Option<TypeId>>,
2982 pub interfaces: Vec<Option<InterfaceId>>,
2983 pub worlds: Vec<Option<WorldId>>,
2984 pub packages: Vec<PackageId>,
2985
2986 own_handles: HashMap<TypeId, TypeId>,
2996
2997 type_has_borrow: Vec<Option<bool>>,
2998}
2999
3000fn apply_map<T>(map: &[Option<Id<T>>], id: Id<T>, desc: &str, span: Span) -> Result<Id<T>> {
3001 match map.get(id.index()) {
3002 Some(Some(id)) => Ok(*id),
3003 Some(None) => {
3004 let msg = format!(
3005 "found a reference to a {desc} which is excluded \
3006 due to its feature not being activated"
3007 );
3008 Err(Error::new(span, msg).into())
3009 }
3010 None => panic!("request to remap a {desc} that has not yet been registered"),
3011 }
3012}
3013
3014fn rename(original_name: &str, include_name: &IncludeName) -> Option<String> {
3015 if original_name == include_name.name {
3016 return Some(include_name.as_.to_string());
3017 }
3018 let (kind, rest) = original_name.split_once(']')?;
3019 match rest.split_once('.') {
3020 Some((name, rest)) if name == include_name.name => {
3021 Some(format!("{kind}]{}.{rest}", include_name.as_))
3022 }
3023 _ if rest == include_name.name => Some(format!("{kind}]{}", include_name.as_)),
3024 _ => None,
3025 }
3026}
3027
3028impl Remap {
3029 pub fn map_type(&self, id: TypeId, span: Span) -> Result<TypeId> {
3030 apply_map(&self.types, id, "type", span)
3031 }
3032
3033 pub fn map_interface(&self, id: InterfaceId, span: Span) -> Result<InterfaceId> {
3034 apply_map(&self.interfaces, id, "interface", span)
3035 }
3036
3037 pub fn map_world(&self, id: WorldId, span: Span) -> Result<WorldId> {
3038 apply_map(&self.worlds, id, "world", span)
3039 }
3040
3041 fn append(
3042 &mut self,
3043 resolve: &mut Resolve,
3044 unresolved: UnresolvedPackage,
3045 ) -> Result<PackageId> {
3046 let pkgid = resolve.packages.alloc(Package {
3047 name: unresolved.name.clone(),
3048 docs: unresolved.docs.clone(),
3049 interfaces: Default::default(),
3050 worlds: Default::default(),
3051 });
3052 let prev = resolve.package_names.insert(unresolved.name.clone(), pkgid);
3053 if let Some(prev) = prev {
3054 resolve.package_names.insert(unresolved.name.clone(), prev);
3055 bail!(
3056 "attempting to re-add package `{}` when it's already present in this `Resolve`",
3057 unresolved.name,
3058 );
3059 }
3060
3061 self.process_foreign_deps(resolve, pkgid, &unresolved)?;
3062
3063 let foreign_types = self.types.len();
3064 let foreign_interfaces = self.interfaces.len();
3065 let foreign_worlds = self.worlds.len();
3066
3067 for (id, mut ty) in unresolved.types.into_iter().skip(foreign_types) {
3073 let span = ty.span;
3074 if !resolve.include_type(&ty, pkgid, span)? {
3075 self.types.push(None);
3076 continue;
3077 }
3078
3079 self.update_typedef(resolve, &mut ty, span)?;
3080 let new_id = resolve.types.alloc(ty);
3081 assert_eq!(self.types.len(), id.index());
3082
3083 let new_id = match resolve.types[new_id] {
3084 TypeDef {
3089 name: None,
3090 owner: TypeOwner::None,
3091 kind: TypeDefKind::Handle(Handle::Own(id)),
3092 docs: _,
3093 stability: _,
3094 span: _,
3095 } => *self.own_handles.entry(id).or_insert(new_id),
3096
3097 _ => new_id,
3100 };
3101 self.types.push(Some(new_id));
3102 }
3103
3104 for (id, mut iface) in unresolved.interfaces.into_iter().skip(foreign_interfaces) {
3107 let span = iface.span;
3108 if !resolve
3109 .include_stability(&iface.stability, &pkgid, span)
3110 .with_context(|| {
3111 format!(
3112 "failed to process feature gate for interface [{}] in package [{}]",
3113 iface
3114 .name
3115 .as_ref()
3116 .map(String::as_str)
3117 .unwrap_or("<unknown>"),
3118 resolve.packages[pkgid].name,
3119 )
3120 })?
3121 {
3122 self.interfaces.push(None);
3123 continue;
3124 }
3125 assert!(iface.package.is_none());
3126 iface.package = Some(pkgid);
3127 self.update_interface(resolve, &mut iface)?;
3128 let new_id = resolve.interfaces.alloc(iface);
3129 assert_eq!(self.interfaces.len(), id.index());
3130 self.interfaces.push(Some(new_id));
3131 }
3132
3133 for id in self.types.iter().skip(foreign_types) {
3136 let id = match id {
3137 Some(id) => *id,
3138 None => continue,
3139 };
3140 let span = resolve.types[id].span;
3141 match &mut resolve.types[id].owner {
3142 TypeOwner::Interface(iface_id) => {
3143 *iface_id = self.map_interface(*iface_id, span)
3144 .with_context(|| {
3145 "this type is not gated by a feature but its interface is gated by a feature"
3146 })?;
3147 }
3148 TypeOwner::World(_) | TypeOwner::None => {}
3149 }
3150 }
3151
3152 for (id, mut world) in unresolved.worlds.into_iter().skip(foreign_worlds) {
3160 let world_span = world.span;
3161 if !resolve
3162 .include_stability(&world.stability, &pkgid, world_span)
3163 .with_context(|| {
3164 format!(
3165 "failed to process feature gate for world [{}] in package [{}]",
3166 world.name, resolve.packages[pkgid].name,
3167 )
3168 })?
3169 {
3170 self.worlds.push(None);
3171 continue;
3172 }
3173 self.update_world(&mut world, resolve, &pkgid)?;
3174
3175 let new_id = resolve.worlds.alloc(world);
3176 assert_eq!(self.worlds.len(), id.index());
3177 self.worlds.push(Some(new_id));
3178 }
3179
3180 for id in self.types.iter().skip(foreign_types) {
3182 let id = match id {
3183 Some(id) => *id,
3184 None => continue,
3185 };
3186 let span = resolve.types[id].span;
3187 match &mut resolve.types[id].owner {
3188 TypeOwner::World(world_id) => {
3189 *world_id = self.map_world(*world_id, span)
3190 .with_context(|| {
3191 "this type is not gated by a feature but its interface is gated by a feature"
3192 })?;
3193 }
3194 TypeOwner::Interface(_) | TypeOwner::None => {}
3195 }
3196 }
3197
3198 for id in self.worlds.iter().skip(foreign_worlds) {
3215 let Some(id) = *id else {
3216 continue;
3217 };
3218 self.process_world_includes(id, resolve, &pkgid)?;
3219
3220 let world_span = resolve.worlds[id].span;
3221 resolve.elaborate_world(id).with_context(|| {
3222 Error::new(
3223 world_span,
3224 format!(
3225 "failed to elaborate world imports/exports of `{}`",
3226 resolve.worlds[id].name
3227 ),
3228 )
3229 })?;
3230 }
3231
3232 for id in self.interfaces.iter().skip(foreign_interfaces) {
3234 let id = match id {
3235 Some(id) => *id,
3236 None => continue,
3237 };
3238 let iface = &mut resolve.interfaces[id];
3239 iface.package = Some(pkgid);
3240 if let Some(name) = &iface.name {
3241 let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), id);
3242 assert!(prev.is_none());
3243 }
3244 }
3245 for id in self.worlds.iter().skip(foreign_worlds) {
3246 let id = match id {
3247 Some(id) => *id,
3248 None => continue,
3249 };
3250 let world = &mut resolve.worlds[id];
3251 world.package = Some(pkgid);
3252 let prev = resolve.packages[pkgid]
3253 .worlds
3254 .insert(world.name.clone(), id);
3255 assert!(prev.is_none());
3256 }
3257 Ok(pkgid)
3258 }
3259
3260 fn process_foreign_deps(
3261 &mut self,
3262 resolve: &mut Resolve,
3263 pkgid: PackageId,
3264 unresolved: &UnresolvedPackage,
3265 ) -> Result<()> {
3266 let mut world_to_package = HashMap::new();
3269 let mut interface_to_package = HashMap::new();
3270 for (i, (pkg_name, worlds_or_ifaces)) in unresolved.foreign_deps.iter().enumerate() {
3271 for (name, (item, stabilities)) in worlds_or_ifaces {
3272 match item {
3273 AstItem::Interface(unresolved_interface_id) => {
3274 let prev = interface_to_package.insert(
3275 *unresolved_interface_id,
3276 (pkg_name, name, unresolved.foreign_dep_spans[i], stabilities),
3277 );
3278 assert!(prev.is_none());
3279 }
3280 AstItem::World(unresolved_world_id) => {
3281 let prev = world_to_package.insert(
3282 *unresolved_world_id,
3283 (pkg_name, name, unresolved.foreign_dep_spans[i], stabilities),
3284 );
3285 assert!(prev.is_none());
3286 }
3287 }
3288 }
3289 }
3290
3291 self.process_foreign_interfaces(unresolved, &interface_to_package, resolve, &pkgid)?;
3295
3296 self.process_foreign_worlds(unresolved, &world_to_package, resolve, &pkgid)?;
3300
3301 self.process_foreign_types(unresolved, pkgid, resolve)?;
3304
3305 for (id, span) in unresolved.required_resource_types.iter() {
3306 let Ok(mut id) = self.map_type(*id, *span) else {
3311 continue;
3312 };
3313 loop {
3314 match resolve.types[id].kind {
3315 TypeDefKind::Type(Type::Id(i)) => id = i,
3316 TypeDefKind::Resource => break,
3317 _ => bail!(Error::new(
3318 *span,
3319 format!("type used in a handle must be a resource"),
3320 )),
3321 }
3322 }
3323 }
3324
3325 #[cfg(debug_assertions)]
3326 resolve.assert_valid();
3327
3328 Ok(())
3329 }
3330
3331 fn process_foreign_interfaces(
3332 &mut self,
3333 unresolved: &UnresolvedPackage,
3334 interface_to_package: &HashMap<InterfaceId, (&PackageName, &String, Span, &Vec<Stability>)>,
3335 resolve: &mut Resolve,
3336 parent_pkg_id: &PackageId,
3337 ) -> Result<(), anyhow::Error> {
3338 for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() {
3339 let (pkg_name, interface, span, stabilities) =
3340 match interface_to_package.get(&unresolved_iface_id) {
3341 Some(items) => *items,
3342 None => break,
3346 };
3347
3348 let pkgid = resolve
3349 .package_names
3350 .get(pkg_name)
3351 .copied()
3352 .ok_or_else(|| {
3353 PackageNotFoundError::new(
3354 span,
3355 pkg_name.clone(),
3356 resolve.package_names.keys().cloned().collect(),
3357 )
3358 })?;
3359
3360 assert!(unresolved_iface.functions.is_empty());
3362
3363 let pkg = &resolve.packages[pkgid];
3364 let iface_span = unresolved_iface.span;
3365
3366 let mut enabled = false;
3367 for stability in stabilities {
3368 if resolve.include_stability(stability, parent_pkg_id, iface_span)? {
3369 enabled = true;
3370 break;
3371 }
3372 }
3373
3374 if !enabled {
3375 self.interfaces.push(None);
3376 continue;
3377 }
3378
3379 let iface_id = pkg
3380 .interfaces
3381 .get(interface)
3382 .copied()
3383 .ok_or_else(|| Error::new(iface_span, "interface not found in package"))?;
3384 assert_eq!(self.interfaces.len(), unresolved_iface_id.index());
3385 self.interfaces.push(Some(iface_id));
3386 }
3387 for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) {
3388 assert!(
3389 interface_to_package.get(&id).is_none(),
3390 "found foreign interface after local interface"
3391 );
3392 }
3393 Ok(())
3394 }
3395
3396 fn process_foreign_worlds(
3397 &mut self,
3398 unresolved: &UnresolvedPackage,
3399 world_to_package: &HashMap<WorldId, (&PackageName, &String, Span, &Vec<Stability>)>,
3400 resolve: &mut Resolve,
3401 parent_pkg_id: &PackageId,
3402 ) -> Result<(), anyhow::Error> {
3403 for (unresolved_world_id, unresolved_world) in unresolved.worlds.iter() {
3404 let (pkg_name, world, span, stabilities) =
3405 match world_to_package.get(&unresolved_world_id) {
3406 Some(items) => *items,
3407 None => break,
3410 };
3411
3412 let pkgid = resolve
3413 .package_names
3414 .get(pkg_name)
3415 .copied()
3416 .ok_or_else(|| Error::new(span, "package not found"))?;
3417 let pkg = &resolve.packages[pkgid];
3418 let world_span = unresolved_world.span;
3419
3420 let mut enabled = false;
3421 for stability in stabilities {
3422 if resolve.include_stability(stability, parent_pkg_id, world_span)? {
3423 enabled = true;
3424 break;
3425 }
3426 }
3427
3428 if !enabled {
3429 self.worlds.push(None);
3430 continue;
3431 }
3432
3433 let world_id = pkg
3434 .worlds
3435 .get(world)
3436 .copied()
3437 .ok_or_else(|| Error::new(world_span, "world not found in package"))?;
3438 assert_eq!(self.worlds.len(), unresolved_world_id.index());
3439 self.worlds.push(Some(world_id));
3440 }
3441 for (id, _) in unresolved.worlds.iter().skip(self.worlds.len()) {
3442 assert!(
3443 world_to_package.get(&id).is_none(),
3444 "found foreign world after local world"
3445 );
3446 }
3447 Ok(())
3448 }
3449
3450 fn process_foreign_types(
3451 &mut self,
3452 unresolved: &UnresolvedPackage,
3453 pkgid: PackageId,
3454 resolve: &mut Resolve,
3455 ) -> Result<(), anyhow::Error> {
3456 for (unresolved_type_id, unresolved_ty) in unresolved.types.iter() {
3457 match unresolved_ty.kind {
3461 TypeDefKind::Unknown => {}
3462 _ => break,
3463 }
3464
3465 let span = unresolved_ty.span;
3466 if !resolve.include_type(unresolved_ty, pkgid, span)? {
3467 self.types.push(None);
3468 continue;
3469 }
3470
3471 let unresolved_iface_id = match unresolved_ty.owner {
3472 TypeOwner::Interface(id) => id,
3473 _ => unreachable!(),
3474 };
3475 let iface_id = self.map_interface(unresolved_iface_id, Default::default())?;
3476 let name = unresolved_ty.name.as_ref().unwrap();
3477 let span = unresolved.unknown_type_spans[unresolved_type_id.index()];
3478 let type_id = *resolve.interfaces[iface_id]
3479 .types
3480 .get(name)
3481 .ok_or_else(|| {
3482 Error::new(span, format!("type `{name}` not defined in interface"))
3483 })?;
3484 assert_eq!(self.types.len(), unresolved_type_id.index());
3485 self.types.push(Some(type_id));
3486 }
3487 for (_, ty) in unresolved.types.iter().skip(self.types.len()) {
3488 if let TypeDefKind::Unknown = ty.kind {
3489 panic!("unknown type after defined type");
3490 }
3491 }
3492 Ok(())
3493 }
3494
3495 fn update_typedef(
3496 &mut self,
3497 resolve: &mut Resolve,
3498 ty: &mut TypeDef,
3499 span: Span,
3500 ) -> Result<()> {
3501 use crate::TypeDefKind::*;
3504 match &mut ty.kind {
3505 Handle(handle) => match handle {
3506 crate::Handle::Own(ty) | crate::Handle::Borrow(ty) => {
3507 self.update_type_id(ty, span)?
3508 }
3509 },
3510 Resource => {}
3511 Record(r) => {
3512 for field in r.fields.iter_mut() {
3513 self.update_ty(resolve, &mut field.ty, span)
3514 .with_context(|| format!("failed to update field `{}`", field.name))?;
3515 }
3516 }
3517 Tuple(t) => {
3518 for ty in t.types.iter_mut() {
3519 self.update_ty(resolve, ty, span)?;
3520 }
3521 }
3522 Variant(v) => {
3523 for case in v.cases.iter_mut() {
3524 if let Some(t) = &mut case.ty {
3525 self.update_ty(resolve, t, span)?;
3526 }
3527 }
3528 }
3529 Option(t)
3530 | List(t, ..)
3531 | FixedLengthList(t, ..)
3532 | Future(Some(t))
3533 | Stream(Some(t)) => self.update_ty(resolve, t, span)?,
3534 Map(k, v) => {
3535 self.update_ty(resolve, k, span)?;
3536 self.update_ty(resolve, v, span)?;
3537 }
3538 Result(r) => {
3539 if let Some(ty) = &mut r.ok {
3540 self.update_ty(resolve, ty, span)?;
3541 }
3542 if let Some(ty) = &mut r.err {
3543 self.update_ty(resolve, ty, span)?;
3544 }
3545 }
3546
3547 Type(crate::Type::Id(id)) => self.update_type_id(id, span)?,
3552 Type(_) => {}
3553
3554 Flags(_) | Enum(_) | Future(None) | Stream(None) => {}
3556
3557 Unknown => unreachable!(),
3558 }
3559
3560 Ok(())
3561 }
3562
3563 fn update_ty(&mut self, resolve: &mut Resolve, ty: &mut Type, span: Span) -> Result<()> {
3564 let id = match ty {
3565 Type::Id(id) => id,
3566 _ => return Ok(()),
3567 };
3568 self.update_type_id(id, span)?;
3569
3570 let mut cur = *id;
3575 let points_to_resource = loop {
3576 match resolve.types[cur].kind {
3577 TypeDefKind::Type(Type::Id(id)) => cur = id,
3578 TypeDefKind::Resource => break true,
3579 _ => break false,
3580 }
3581 };
3582
3583 if points_to_resource {
3584 *id = *self.own_handles.entry(*id).or_insert_with(|| {
3585 resolve.types.alloc(TypeDef {
3586 name: None,
3587 owner: TypeOwner::None,
3588 kind: TypeDefKind::Handle(Handle::Own(*id)),
3589 docs: Default::default(),
3590 stability: Default::default(),
3591 span: Default::default(),
3592 })
3593 });
3594 }
3595 Ok(())
3596 }
3597
3598 fn update_type_id(&self, id: &mut TypeId, span: Span) -> Result<()> {
3599 *id = self.map_type(*id, span)?;
3600 Ok(())
3601 }
3602
3603 fn update_interface(&mut self, resolve: &mut Resolve, iface: &mut Interface) -> Result<()> {
3604 iface.types.retain(|_, ty| self.types[ty.index()].is_some());
3605 let iface_pkg_id = iface.package.as_ref().unwrap_or_else(|| {
3606 panic!(
3607 "unexpectedly missing package on interface [{}]",
3608 iface
3609 .name
3610 .as_ref()
3611 .map(String::as_str)
3612 .unwrap_or("<unknown>"),
3613 )
3614 });
3615
3616 for (_name, ty) in iface.types.iter_mut() {
3619 self.update_type_id(ty, iface.span)?;
3620 }
3621 for (func_name, func) in iface.functions.iter_mut() {
3622 let span = func.span;
3623 if !resolve
3624 .include_stability(&func.stability, iface_pkg_id, span)
3625 .with_context(|| {
3626 format!(
3627 "failed to process feature gate for function [{func_name}] in package [{}]",
3628 resolve.packages[*iface_pkg_id].name,
3629 )
3630 })?
3631 {
3632 continue;
3633 }
3634 self.update_function(resolve, func, span)
3635 .with_context(|| format!("failed to update function `{}`", func.name))?;
3636 }
3637
3638 for (name, func) in mem::take(&mut iface.functions) {
3641 if resolve.include_stability(&func.stability, iface_pkg_id, func.span)? {
3642 iface.functions.insert(name, func);
3643 }
3644 }
3645
3646 Ok(())
3647 }
3648
3649 fn update_function(
3650 &mut self,
3651 resolve: &mut Resolve,
3652 func: &mut Function,
3653 span: Span,
3654 ) -> Result<()> {
3655 if let Some(id) = func.kind.resource_mut() {
3656 self.update_type_id(id, span)?;
3657 }
3658 for param in func.params.iter_mut() {
3659 self.update_ty(resolve, &mut param.ty, span)?;
3660 }
3661 if let Some(ty) = &mut func.result {
3662 self.update_ty(resolve, ty, span)?;
3663 }
3664
3665 if let Some(ty) = &func.result {
3666 if self.type_has_borrow(resolve, ty) {
3667 bail!(Error::new(
3668 span,
3669 format!(
3670 "function returns a type which contains \
3671 a `borrow<T>` which is not supported"
3672 )
3673 ))
3674 }
3675 }
3676
3677 Ok(())
3678 }
3679
3680 fn update_world(
3681 &mut self,
3682 world: &mut World,
3683 resolve: &mut Resolve,
3684 pkg_id: &PackageId,
3685 ) -> Result<()> {
3686 let imports = mem::take(&mut world.imports).into_iter().map(|p| (p, true));
3690 let exports = mem::take(&mut world.exports)
3691 .into_iter()
3692 .map(|p| (p, false));
3693 for ((mut name, mut item), import) in imports.chain(exports) {
3694 let span = item.span();
3695 if let WorldItem::Type { id, .. } = &mut item {
3698 *id = self.map_type(*id, span)?;
3699 }
3700 let stability = item.stability(resolve);
3701 if !resolve
3702 .include_stability(stability, pkg_id, span)
3703 .with_context(|| format!("failed to process world item in `{}`", world.name))?
3704 {
3705 continue;
3706 }
3707 self.update_world_key(&mut name, span)?;
3708 match &mut item {
3709 WorldItem::Interface { id, .. } => {
3710 *id = self.map_interface(*id, span)?;
3711 }
3712 WorldItem::Function(f) => {
3713 self.update_function(resolve, f, span)?;
3714 }
3715 WorldItem::Type { .. } => {
3716 }
3718 }
3719
3720 let dst = if import {
3721 &mut world.imports
3722 } else {
3723 &mut world.exports
3724 };
3725 let prev = dst.insert(name, item);
3726 assert!(prev.is_none());
3727 }
3728
3729 Ok(())
3730 }
3731
3732 fn process_world_includes(
3733 &self,
3734 id: WorldId,
3735 resolve: &mut Resolve,
3736 pkg_id: &PackageId,
3737 ) -> Result<()> {
3738 let world = &mut resolve.worlds[id];
3739 let includes = mem::take(&mut world.includes);
3742 for include in includes {
3743 if !resolve
3744 .include_stability(&include.stability, pkg_id, include.span)
3745 .with_context(|| {
3746 format!(
3747 "failed to process feature gate for included world [{}] in package [{}]",
3748 resolve.worlds[include.id].name.as_str(),
3749 resolve.packages[*pkg_id].name
3750 )
3751 })?
3752 {
3753 continue;
3754 }
3755 self.resolve_include(
3756 id,
3757 include.id,
3758 &include.names,
3759 include.span,
3760 pkg_id,
3761 resolve,
3762 )?;
3763 }
3764
3765 Self::validate_world_case_insensitive_names(resolve, id)?;
3767
3768 Ok(())
3769 }
3770
3771 fn validate_world_case_insensitive_names(resolve: &Resolve, world_id: WorldId) -> Result<()> {
3775 let world = &resolve.worlds[world_id];
3776
3777 let validate_names = |items: &IndexMap<WorldKey, WorldItem>,
3779 item_type: &str|
3780 -> Result<()> {
3781 let mut seen_lowercase: HashMap<String, String> = HashMap::new();
3782
3783 for key in items.keys() {
3784 if let WorldKey::Name(name) = key {
3786 let lowercase_name = name.to_lowercase();
3787
3788 if let Some(existing_name) = seen_lowercase.get(&lowercase_name) {
3789 if existing_name != name {
3792 bail!(
3793 "{item_type} `{name}` conflicts with {item_type} `{existing_name}` \
3794 (kebab-case identifiers are case-insensitive)"
3795 );
3796 }
3797 }
3798
3799 seen_lowercase.insert(lowercase_name, name.clone());
3800 }
3801 }
3802
3803 Ok(())
3804 };
3805
3806 validate_names(&world.imports, "import")
3807 .with_context(|| format!("failed to validate imports in world `{}`", world.name))?;
3808 validate_names(&world.exports, "export")
3809 .with_context(|| format!("failed to validate exports in world `{}`", world.name))?;
3810
3811 Ok(())
3812 }
3813
3814 fn update_world_key(&self, key: &mut WorldKey, span: Span) -> Result<()> {
3815 match key {
3816 WorldKey::Name(_) => {}
3817 WorldKey::Interface(id) => {
3818 *id = self.map_interface(*id, span)?;
3819 }
3820 }
3821 Ok(())
3822 }
3823
3824 fn resolve_include(
3825 &self,
3826 id: WorldId,
3827 include_world_id_orig: WorldId,
3828 names: &[IncludeName],
3829 span: Span,
3830 pkg_id: &PackageId,
3831 resolve: &mut Resolve,
3832 ) -> Result<()> {
3833 let world = &resolve.worlds[id];
3834 let include_world_id = self.map_world(include_world_id_orig, span)?;
3835 let include_world = resolve.worlds[include_world_id].clone();
3836 let mut names_ = names.to_owned();
3837 let is_external_include = world.package != include_world.package;
3838
3839 for import in include_world.imports.iter() {
3841 self.remove_matching_name(import, &mut names_);
3842 }
3843 for export in include_world.exports.iter() {
3844 self.remove_matching_name(export, &mut names_);
3845 }
3846 if !names_.is_empty() {
3847 bail!(Error::new(
3848 span,
3849 format!(
3850 "no import or export kebab-name `{}`. Note that an ID does not support renaming",
3851 names_[0].name
3852 ),
3853 ));
3854 }
3855
3856 let mut maps = Default::default();
3857 let mut cloner = clone::Cloner::new(
3858 resolve,
3859 &mut maps,
3860 TypeOwner::World(if is_external_include {
3861 include_world_id
3862 } else {
3863 include_world_id
3864 }),
3866 TypeOwner::World(id),
3867 );
3868 cloner.new_package = Some(*pkg_id);
3869
3870 for import in include_world.imports.iter() {
3872 self.resolve_include_item(
3873 &mut cloner,
3874 names,
3875 |resolve| &mut resolve.worlds[id].imports,
3876 import,
3877 span,
3878 "import",
3879 is_external_include,
3880 )?;
3881 }
3882
3883 for export in include_world.exports.iter() {
3884 self.resolve_include_item(
3885 &mut cloner,
3886 names,
3887 |resolve| &mut resolve.worlds[id].exports,
3888 export,
3889 span,
3890 "export",
3891 is_external_include,
3892 )?;
3893 }
3894 Ok(())
3895 }
3896
3897 fn resolve_include_item(
3898 &self,
3899 cloner: &mut clone::Cloner<'_>,
3900 names: &[IncludeName],
3901 get_items: impl Fn(&mut Resolve) -> &mut IndexMap<WorldKey, WorldItem>,
3902 item: (&WorldKey, &WorldItem),
3903 span: Span,
3904 item_type: &str,
3905 is_external_include: bool,
3906 ) -> Result<()> {
3907 match item.0 {
3908 WorldKey::Name(n) => {
3909 let n = names
3910 .into_iter()
3911 .find_map(|include_name| rename(n, include_name))
3912 .unwrap_or(n.clone());
3913
3914 let mut new_item = item.1.clone();
3920 let key = WorldKey::Name(n.clone());
3921 cloner.world_item(&key, &mut new_item);
3922 match &mut new_item {
3923 WorldItem::Function(f) => f.name = n.clone(),
3924 WorldItem::Type { id, .. } => cloner.resolve.types[*id].name = Some(n.clone()),
3925 WorldItem::Interface { .. } => {}
3926 }
3927
3928 let prev = get_items(cloner.resolve).insert(key, new_item);
3929 if prev.is_some() {
3930 bail!(Error::new(
3931 span,
3932 format!("{item_type} of `{n}` shadows previously {item_type}ed items"),
3933 ))
3934 }
3935 }
3936 key @ WorldKey::Interface(_) => {
3937 let prev = get_items(cloner.resolve)
3938 .entry(key.clone())
3939 .or_insert(item.1.clone());
3940 match (&item.1, prev) {
3941 (
3942 WorldItem::Interface {
3943 id: aid,
3944 stability: astability,
3945 ..
3946 },
3947 WorldItem::Interface {
3948 id: bid,
3949 stability: bstability,
3950 ..
3951 },
3952 ) => {
3953 assert_eq!(*aid, *bid);
3954 merge_include_stability(astability, bstability, is_external_include)?;
3955 }
3956 (WorldItem::Interface { .. }, _) => unreachable!(),
3957 (WorldItem::Function(_), _) => unreachable!(),
3958 (WorldItem::Type { .. }, _) => unreachable!(),
3959 }
3960 }
3961 };
3962
3963 Ok(())
3964 }
3965
3966 fn remove_matching_name(&self, item: (&WorldKey, &WorldItem), names: &mut Vec<IncludeName>) {
3967 match item.0 {
3968 WorldKey::Name(n) => {
3969 names.retain(|name| rename(n, name).is_none());
3970 }
3971 _ => {}
3972 }
3973 }
3974
3975 fn type_has_borrow(&mut self, resolve: &Resolve, ty: &Type) -> bool {
3976 let id = match ty {
3977 Type::Id(id) => *id,
3978 _ => return false,
3979 };
3980
3981 if let Some(Some(has_borrow)) = self.type_has_borrow.get(id.index()) {
3982 return *has_borrow;
3983 }
3984
3985 let result = self.typedef_has_borrow(resolve, &resolve.types[id]);
3986 if self.type_has_borrow.len() <= id.index() {
3987 self.type_has_borrow.resize(id.index() + 1, None);
3988 }
3989 self.type_has_borrow[id.index()] = Some(result);
3990 result
3991 }
3992
3993 fn typedef_has_borrow(&mut self, resolve: &Resolve, ty: &TypeDef) -> bool {
3994 match &ty.kind {
3995 TypeDefKind::Type(t) => self.type_has_borrow(resolve, t),
3996 TypeDefKind::Variant(v) => v
3997 .cases
3998 .iter()
3999 .filter_map(|case| case.ty.as_ref())
4000 .any(|ty| self.type_has_borrow(resolve, ty)),
4001 TypeDefKind::Handle(Handle::Borrow(_)) => true,
4002 TypeDefKind::Handle(Handle::Own(_)) => false,
4003 TypeDefKind::Resource => false,
4004 TypeDefKind::Record(r) => r
4005 .fields
4006 .iter()
4007 .any(|case| self.type_has_borrow(resolve, &case.ty)),
4008 TypeDefKind::Flags(_) => false,
4009 TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.type_has_borrow(resolve, t)),
4010 TypeDefKind::Enum(_) => false,
4011 TypeDefKind::List(ty)
4012 | TypeDefKind::FixedLengthList(ty, ..)
4013 | TypeDefKind::Future(Some(ty))
4014 | TypeDefKind::Stream(Some(ty))
4015 | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty),
4016 TypeDefKind::Map(k, v) => {
4017 self.type_has_borrow(resolve, k) || self.type_has_borrow(resolve, v)
4018 }
4019 TypeDefKind::Result(r) => [&r.ok, &r.err]
4020 .iter()
4021 .filter_map(|t| t.as_ref())
4022 .any(|t| self.type_has_borrow(resolve, t)),
4023 TypeDefKind::Future(None) | TypeDefKind::Stream(None) => false,
4024 TypeDefKind::Unknown => unreachable!(),
4025 }
4026 }
4027}
4028
4029struct MergeMap<'a> {
4030 package_map: HashMap<PackageId, PackageId>,
4033
4034 interface_map: HashMap<InterfaceId, InterfaceId>,
4037
4038 type_map: HashMap<TypeId, TypeId>,
4041
4042 world_map: HashMap<WorldId, WorldId>,
4045
4046 interfaces_to_add: Vec<(String, PackageId, InterfaceId)>,
4054 worlds_to_add: Vec<(String, PackageId, WorldId)>,
4055
4056 from: &'a Resolve,
4058
4059 into: &'a Resolve,
4061}
4062
4063impl<'a> MergeMap<'a> {
4064 fn new(from: &'a Resolve, into: &'a Resolve) -> MergeMap<'a> {
4065 MergeMap {
4066 package_map: Default::default(),
4067 interface_map: Default::default(),
4068 type_map: Default::default(),
4069 world_map: Default::default(),
4070 interfaces_to_add: Default::default(),
4071 worlds_to_add: Default::default(),
4072 from,
4073 into,
4074 }
4075 }
4076
4077 fn build(&mut self) -> Result<()> {
4078 for from_id in self.from.topological_packages() {
4079 let from = &self.from.packages[from_id];
4080 let into_id = match self.into.package_names.get(&from.name) {
4081 Some(id) => *id,
4082
4083 None => {
4086 log::trace!("adding unique package {}", from.name);
4087 continue;
4088 }
4089 };
4090 log::trace!("merging duplicate package {}", from.name);
4091
4092 self.build_package(from_id, into_id).with_context(|| {
4093 format!("failed to merge package `{}` into existing copy", from.name)
4094 })?;
4095 }
4096
4097 Ok(())
4098 }
4099
4100 fn build_package(&mut self, from_id: PackageId, into_id: PackageId) -> Result<()> {
4101 let prev = self.package_map.insert(from_id, into_id);
4102 assert!(prev.is_none());
4103
4104 let from = &self.from.packages[from_id];
4105 let into = &self.into.packages[into_id];
4106
4107 for (name, from_interface_id) in from.interfaces.iter() {
4111 let into_interface_id = match into.interfaces.get(name) {
4112 Some(id) => *id,
4113 None => {
4114 log::trace!("adding unique interface {name}");
4115 self.interfaces_to_add
4116 .push((name.clone(), into_id, *from_interface_id));
4117 continue;
4118 }
4119 };
4120
4121 log::trace!("merging duplicate interfaces {name}");
4122 self.build_interface(*from_interface_id, into_interface_id)
4123 .with_context(|| format!("failed to merge interface `{name}`"))?;
4124 }
4125
4126 for (name, from_world_id) in from.worlds.iter() {
4127 let into_world_id = match into.worlds.get(name) {
4128 Some(id) => *id,
4129 None => {
4130 log::trace!("adding unique world {name}");
4131 self.worlds_to_add
4132 .push((name.clone(), into_id, *from_world_id));
4133 continue;
4134 }
4135 };
4136
4137 log::trace!("merging duplicate worlds {name}");
4138 self.build_world(*from_world_id, into_world_id)
4139 .with_context(|| format!("failed to merge world `{name}`"))?;
4140 }
4141
4142 Ok(())
4143 }
4144
4145 fn build_interface(&mut self, from_id: InterfaceId, into_id: InterfaceId) -> Result<()> {
4146 let prev = self.interface_map.insert(from_id, into_id);
4147 assert!(prev.is_none());
4148
4149 let from_interface = &self.from.interfaces[from_id];
4150 let into_interface = &self.into.interfaces[into_id];
4151
4152 for (name, from_type_id) in from_interface.types.iter() {
4166 let into_type_id = *into_interface
4167 .types
4168 .get(name)
4169 .ok_or_else(|| anyhow!("expected type `{name}` to be present"))?;
4170 let prev = self.type_map.insert(*from_type_id, into_type_id);
4171 assert!(prev.is_none());
4172
4173 self.build_type_id(*from_type_id, into_type_id)
4174 .with_context(|| format!("mismatch in type `{name}`"))?;
4175 }
4176
4177 for (name, from_func) in from_interface.functions.iter() {
4178 let into_func = match into_interface.functions.get(name) {
4179 Some(func) => func,
4180 None => bail!("expected function `{name}` to be present"),
4181 };
4182 self.build_function(from_func, into_func)
4183 .with_context(|| format!("mismatch in function `{name}`"))?;
4184 }
4185
4186 Ok(())
4187 }
4188
4189 fn build_type_id(&mut self, from_id: TypeId, into_id: TypeId) -> Result<()> {
4190 let _ = from_id;
4194 let _ = into_id;
4195 Ok(())
4196 }
4197
4198 fn build_type(&mut self, from_ty: &Type, into_ty: &Type) -> Result<()> {
4199 match (from_ty, into_ty) {
4200 (Type::Id(from), Type::Id(into)) => {
4201 self.build_type_id(*from, *into)?;
4202 }
4203 (from, into) if from != into => bail!("different kinds of types"),
4204 _ => {}
4205 }
4206 Ok(())
4207 }
4208
4209 fn build_function(&mut self, from_func: &Function, into_func: &Function) -> Result<()> {
4210 if from_func.name != into_func.name {
4211 bail!(
4212 "different function names `{}` and `{}`",
4213 from_func.name,
4214 into_func.name
4215 );
4216 }
4217 match (&from_func.kind, &into_func.kind) {
4218 (FunctionKind::Freestanding, FunctionKind::Freestanding) => {}
4219 (FunctionKind::AsyncFreestanding, FunctionKind::AsyncFreestanding) => {}
4220
4221 (FunctionKind::Method(from), FunctionKind::Method(into))
4222 | (FunctionKind::Static(from), FunctionKind::Static(into))
4223 | (FunctionKind::AsyncMethod(from), FunctionKind::AsyncMethod(into))
4224 | (FunctionKind::AsyncStatic(from), FunctionKind::AsyncStatic(into))
4225 | (FunctionKind::Constructor(from), FunctionKind::Constructor(into)) => {
4226 self.build_type_id(*from, *into)
4227 .context("different function kind types")?;
4228 }
4229
4230 (FunctionKind::Method(_), _)
4231 | (FunctionKind::Constructor(_), _)
4232 | (FunctionKind::Static(_), _)
4233 | (FunctionKind::Freestanding, _)
4234 | (FunctionKind::AsyncFreestanding, _)
4235 | (FunctionKind::AsyncMethod(_), _)
4236 | (FunctionKind::AsyncStatic(_), _) => {
4237 bail!("different function kind types")
4238 }
4239 }
4240
4241 if from_func.params.len() != into_func.params.len() {
4242 bail!("different number of function parameters");
4243 }
4244 for (from_param, into_param) in from_func.params.iter().zip(&into_func.params) {
4245 if from_param.name != into_param.name {
4246 bail!(
4247 "different function parameter names: {} != {}",
4248 from_param.name,
4249 into_param.name
4250 );
4251 }
4252 self.build_type(&from_param.ty, &into_param.ty)
4253 .with_context(|| {
4254 format!(
4255 "different function parameter types for `{}`",
4256 from_param.name
4257 )
4258 })?;
4259 }
4260 match (&from_func.result, &into_func.result) {
4261 (Some(from_ty), Some(into_ty)) => {
4262 self.build_type(from_ty, into_ty)
4263 .context("different function result types")?;
4264 }
4265 (None, None) => {}
4266 (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
4267 }
4268 Ok(())
4269 }
4270
4271 fn build_world(&mut self, from_id: WorldId, into_id: WorldId) -> Result<()> {
4272 let prev = self.world_map.insert(from_id, into_id);
4273 assert!(prev.is_none());
4274
4275 let from_world = &self.from.worlds[from_id];
4276 let into_world = &self.into.worlds[into_id];
4277
4278 if from_world.imports.len() != into_world.imports.len() {
4287 bail!("world contains different number of imports than expected");
4288 }
4289 if from_world.exports.len() != into_world.exports.len() {
4290 bail!("world contains different number of exports than expected");
4291 }
4292
4293 for (from_name, from) in from_world.imports.iter() {
4294 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4295 let name_str = self.from.name_world_key(from_name);
4296 let into = into_world
4297 .imports
4298 .get(&into_name)
4299 .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?;
4300 self.match_world_item(from, into)
4301 .with_context(|| format!("import `{name_str}` didn't match target world"))?;
4302 }
4303
4304 for (from_name, from) in from_world.exports.iter() {
4305 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4306 let name_str = self.from.name_world_key(from_name);
4307 let into = into_world
4308 .exports
4309 .get(&into_name)
4310 .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?;
4311 self.match_world_item(from, into)
4312 .with_context(|| format!("export `{name_str}` didn't match target world"))?;
4313 }
4314
4315 Ok(())
4316 }
4317
4318 fn map_name(
4319 from_name: &WorldKey,
4320 interface_map: &HashMap<InterfaceId, InterfaceId>,
4321 ) -> WorldKey {
4322 match from_name {
4323 WorldKey::Name(s) => WorldKey::Name(s.clone()),
4324 WorldKey::Interface(id) => {
4325 WorldKey::Interface(interface_map.get(id).copied().unwrap_or(*id))
4326 }
4327 }
4328 }
4329
4330 fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> Result<()> {
4331 match (from, into) {
4332 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
4333 match (
4334 &self.from.interfaces[*from].name,
4335 &self.into.interfaces[*into].name,
4336 ) {
4337 (None, None) => self.build_interface(*from, *into)?,
4341
4342 _ => {
4347 if self.interface_map.get(from) != Some(into) {
4348 bail!("interfaces are not the same");
4349 }
4350 }
4351 }
4352 }
4353 (WorldItem::Function(from), WorldItem::Function(into)) => {
4354 let _ = (from, into);
4355 }
4358 (WorldItem::Type { id: from, .. }, WorldItem::Type { id: into, .. }) => {
4359 let prev = self.type_map.insert(*from, *into);
4362 assert!(prev.is_none());
4363 }
4364
4365 (WorldItem::Interface { .. }, _)
4366 | (WorldItem::Function(_), _)
4367 | (WorldItem::Type { .. }, _) => {
4368 bail!("world items do not have the same type")
4369 }
4370 }
4371 Ok(())
4372 }
4373}
4374
4375fn update_stability(from: &Stability, into: &mut Stability) -> Result<()> {
4381 if from == into || from.is_unknown() {
4384 return Ok(());
4385 }
4386 if into.is_unknown() {
4389 *into = from.clone();
4390 return Ok(());
4391 }
4392
4393 bail!("mismatch in stability from '{:?}' to '{:?}'", from, into)
4396}
4397
4398fn merge_include_stability(
4399 from: &Stability,
4400 into: &mut Stability,
4401 is_external_include: bool,
4402) -> Result<()> {
4403 if is_external_include && from.is_stable() {
4404 log::trace!("dropped stability from external package");
4405 *into = Stability::Unknown;
4406 return Ok(());
4407 }
4408
4409 return update_stability(from, into);
4410}
4411
4412#[derive(Debug, Clone)]
4425pub struct InvalidTransitiveDependency(String);
4426
4427impl fmt::Display for InvalidTransitiveDependency {
4428 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4429 write!(
4430 f,
4431 "interface `{}` transitively depends on an interface in \
4432 incompatible ways",
4433 self.0
4434 )
4435 }
4436}
4437
4438impl core::error::Error for InvalidTransitiveDependency {}
4439
4440#[cfg(test)]
4441mod tests {
4442 use crate::alloc::format;
4443 use crate::alloc::string::ToString;
4444 use crate::{Resolve, WorldItem, WorldKey};
4445 use anyhow::Result;
4446
4447 #[test]
4448 fn select_world() -> Result<()> {
4449 let mut resolve = Resolve::default();
4450 resolve.push_str(
4451 "test.wit",
4452 r#"
4453 package foo:bar@0.1.0;
4454
4455 world foo {}
4456 "#,
4457 )?;
4458 resolve.push_str(
4459 "test.wit",
4460 r#"
4461 package foo:baz@0.1.0;
4462
4463 world foo {}
4464 "#,
4465 )?;
4466 resolve.push_str(
4467 "test.wit",
4468 r#"
4469 package foo:baz@0.2.0;
4470
4471 world foo {}
4472 "#,
4473 )?;
4474
4475 let dummy = resolve.push_str(
4476 "test.wit",
4477 r#"
4478 package foo:dummy;
4479
4480 world foo {}
4481 "#,
4482 )?;
4483
4484 assert!(resolve.select_world(&[dummy], None).is_ok());
4485 assert!(resolve.select_world(&[dummy], Some("xx")).is_err());
4486 assert!(resolve.select_world(&[dummy], Some("")).is_err());
4487 assert!(resolve.select_world(&[dummy], Some("foo:bar/foo")).is_ok());
4488 assert!(
4489 resolve
4490 .select_world(&[dummy], Some("foo:bar/foo@0.1.0"))
4491 .is_ok()
4492 );
4493 assert!(resolve.select_world(&[dummy], Some("foo:baz/foo")).is_err());
4494 assert!(
4495 resolve
4496 .select_world(&[dummy], Some("foo:baz/foo@0.1.0"))
4497 .is_ok()
4498 );
4499 assert!(
4500 resolve
4501 .select_world(&[dummy], Some("foo:baz/foo@0.2.0"))
4502 .is_ok()
4503 );
4504 Ok(())
4505 }
4506
4507 #[test]
4508 fn wasm_import_name_future_and_stream_intrinsics() -> Result<()> {
4509 use crate::{FutureIntrinsic, LiftLowerAbi, ManglingAndAbi, StreamIntrinsic, WasmImport};
4510
4511 let mut resolve = Resolve::default();
4512 let pkg = resolve.push_str(
4513 "test.wit",
4514 r#"
4515 package foo:bar;
4516
4517 interface iface {
4518 iface-func: func(x: future<u32>) -> stream<u32>;
4519 }
4520
4521 world w {
4522 import import-func: func(x: future<future<u32>>, y: u32) -> stream<string>;
4523 export export-func: func(x: future, y: stream);
4524 import iface;
4525 export iface;
4526 }
4527 "#,
4528 )?;
4529 let world = resolve.packages[pkg].worlds["w"];
4530 let world = &resolve.worlds[world];
4531 let mangling = ManglingAndAbi::Legacy(LiftLowerAbi::AsyncStackful);
4532
4533 let WorldItem::Function(import_func) =
4534 &world.imports[&WorldKey::Name("import-func".to_string())]
4535 else {
4536 panic!("expected `import-func` to be a top-level world import");
4537 };
4538 let WorldItem::Function(export_func) =
4539 &world.exports[&WorldKey::Name("export-func".to_string())]
4540 else {
4541 panic!("expected `export-func` to be a top-level world export");
4542 };
4543 let import_types = import_func.find_futures_and_streams(&resolve);
4544 assert_eq!(import_types.len(), 3);
4545
4546 let (interface_key, interface_func) = world
4547 .imports
4548 .iter()
4549 .find_map(|(key, item)| match item {
4550 WorldItem::Interface { id, .. } => Some((
4551 key.clone(),
4552 &resolve.interfaces[*id].functions["iface-func"],
4553 )),
4554 _ => None,
4555 })
4556 .expect("expected interface import");
4557 let interface_types = interface_func.find_futures_and_streams(&resolve);
4558 assert_eq!(interface_types.len(), 2);
4559
4560 let (module, name) = resolve.wasm_import_name(
4561 mangling,
4562 WasmImport::FutureIntrinsic {
4563 interface: None,
4564 func: import_func,
4565 ty: Some(import_types[0]),
4566 intrinsic: FutureIntrinsic::New,
4567 exported: false,
4568 async_: false,
4569 },
4570 );
4571 assert_eq!(module, "$root");
4572 assert_eq!(name, "[future-new-0]import-func");
4573
4574 let (module, name) = resolve.wasm_import_name(
4575 mangling,
4576 WasmImport::FutureIntrinsic {
4577 interface: None,
4578 func: import_func,
4579 ty: Some(import_types[1]),
4580 intrinsic: FutureIntrinsic::Read,
4581 exported: false,
4582 async_: true,
4583 },
4584 );
4585 assert_eq!(module, "$root");
4586 assert_eq!(name, "[async-lower][future-read-1]import-func");
4587
4588 let (module, name) = resolve.wasm_import_name(
4589 mangling,
4590 WasmImport::StreamIntrinsic {
4591 interface: None,
4592 func: import_func,
4593 ty: Some(import_types[2]),
4594 intrinsic: StreamIntrinsic::CancelRead,
4595 exported: false,
4596 async_: true,
4597 },
4598 );
4599 assert_eq!(module, "$root");
4600 assert_eq!(name, "[async-lower][stream-cancel-read-2]import-func");
4601
4602 let (module, name) = resolve.wasm_import_name(
4603 mangling,
4604 WasmImport::FutureIntrinsic {
4605 interface: None,
4606 func: export_func,
4607 ty: None,
4608 intrinsic: FutureIntrinsic::DropReadable,
4609 exported: true,
4610 async_: false,
4611 },
4612 );
4613 assert_eq!(module, "[export]$root");
4614 assert_eq!(name, "[future-drop-readable-unit]export-func");
4615
4616 let (module, name) = resolve.wasm_import_name(
4617 mangling,
4618 WasmImport::StreamIntrinsic {
4619 interface: None,
4620 func: export_func,
4621 ty: None,
4622 intrinsic: StreamIntrinsic::Write,
4623 exported: true,
4624 async_: true,
4625 },
4626 );
4627 assert_eq!(module, "[export]$root");
4628 assert_eq!(name, "[async-lower][stream-write-unit]export-func");
4629
4630 let (module, name) = resolve.wasm_import_name(
4631 mangling,
4632 WasmImport::StreamIntrinsic {
4633 interface: Some(&interface_key),
4634 func: interface_func,
4635 ty: Some(interface_types[1]),
4636 intrinsic: StreamIntrinsic::Read,
4637 exported: true,
4638 async_: false,
4639 },
4640 );
4641 assert_eq!(
4642 module,
4643 format!("[export]{}", resolve.name_world_key(&interface_key))
4644 );
4645 assert_eq!(name, "[stream-read-1]iface-func");
4646
4647 Ok(())
4648 }
4649
4650 #[test]
4653 fn select_world_multiple_packages() -> Result<()> {
4654 use wit_parser::Resolve;
4655
4656 let mut resolve = Resolve::default();
4657
4658 let stuff = resolve.push_str(
4660 "./my-test.wit",
4661 r#"
4662 package test:stuff;
4663
4664 world foo {
4665 // ...
4666 }
4667 "#,
4668 )?;
4669 assert!(resolve.select_world(&[stuff], None).is_ok());
4670 assert!(resolve.select_world(&[stuff], Some("foo")).is_ok());
4671
4672 let empty = resolve.push_str(
4675 "./my-test.wit",
4676 r#"
4677 package test:empty;
4678 "#,
4679 )?;
4680 assert!(resolve.select_world(&[stuff, empty], None).is_err());
4681 assert!(resolve.select_world(&[stuff, empty], Some("foo")).is_err());
4682 assert!(resolve.select_world(&[empty], None).is_err());
4683 assert!(resolve.select_world(&[empty], Some("foo")).is_err());
4684
4685 Ok(())
4686 }
4687
4688 #[test]
4690 fn select_world_versions() -> Result<()> {
4691 use wit_parser::Resolve;
4692
4693 let mut resolve = Resolve::default();
4694
4695 let _id = resolve.push_str(
4696 "./my-test.wit",
4697 r#"
4698 package example:distraction;
4699 "#,
4700 )?;
4701
4702 let versions_1 = resolve.push_str(
4705 "./my-test.wit",
4706 r#"
4707 package example:versions@1.0.0;
4708
4709 world foo { /* ... */ }
4710 "#,
4711 )?;
4712 assert!(resolve.select_world(&[versions_1], Some("foo")).is_ok());
4713 assert!(
4714 resolve
4715 .select_world(&[versions_1], Some("foo@1.0.0"))
4716 .is_err()
4717 );
4718 assert!(
4719 resolve
4720 .select_world(&[versions_1], Some("example:versions/foo"))
4721 .is_ok()
4722 );
4723 assert!(
4724 resolve
4725 .select_world(&[versions_1], Some("example:versions/foo@1.0.0"))
4726 .is_ok()
4727 );
4728
4729 let versions_2 = resolve.push_str(
4732 "./my-test.wit",
4733 r#"
4734 package example:versions@2.0.0;
4735
4736 world foo { /* ... */ }
4737 "#,
4738 )?;
4739 assert!(
4740 resolve
4741 .select_world(&[versions_1, versions_2], Some("foo"))
4742 .is_err()
4743 );
4744 assert!(
4745 resolve
4746 .select_world(&[versions_1, versions_2], Some("foo@1.0.0"))
4747 .is_err()
4748 );
4749 assert!(
4750 resolve
4751 .select_world(&[versions_1, versions_2], Some("foo@2.0.0"))
4752 .is_err()
4753 );
4754 assert!(
4755 resolve
4756 .select_world(&[versions_1, versions_2], Some("example:versions/foo"))
4757 .is_err()
4758 );
4759 assert!(
4760 resolve
4761 .select_world(
4762 &[versions_1, versions_2],
4763 Some("example:versions/foo@1.0.0")
4764 )
4765 .is_ok()
4766 );
4767 assert!(
4768 resolve
4769 .select_world(
4770 &[versions_1, versions_2],
4771 Some("example:versions/foo@2.0.0")
4772 )
4773 .is_ok()
4774 );
4775
4776 Ok(())
4777 }
4778
4779 #[test]
4781 fn select_world_override_qualification() -> Result<()> {
4782 use wit_parser::Resolve;
4783
4784 let mut resolve = Resolve::default();
4785
4786 let other = resolve.push_str(
4787 "./my-test.wit",
4788 r#"
4789 package example:other;
4790
4791 world foo { }
4792 "#,
4793 )?;
4794
4795 let fq = resolve.push_str(
4797 "./my-test.wit",
4798 r#"
4799 package example:fq;
4800
4801 world bar { }
4802 "#,
4803 )?;
4804 assert!(resolve.select_world(&[other, fq], Some("foo")).is_err());
4805 assert!(resolve.select_world(&[other, fq], Some("bar")).is_err());
4806 assert!(
4807 resolve
4808 .select_world(&[other, fq], Some("example:other/foo"))
4809 .is_ok()
4810 );
4811 assert!(
4812 resolve
4813 .select_world(&[other, fq], Some("example:fq/bar"))
4814 .is_ok()
4815 );
4816 assert!(
4817 resolve
4818 .select_world(&[other, fq], Some("example:other/bar"))
4819 .is_err()
4820 );
4821 assert!(
4822 resolve
4823 .select_world(&[other, fq], Some("example:fq/foo"))
4824 .is_err()
4825 );
4826
4827 Ok(())
4828 }
4829
4830 #[test]
4832 fn select_world_fully_qualified() -> Result<()> {
4833 use wit_parser::Resolve;
4834
4835 let mut resolve = Resolve::default();
4836
4837 let distraction = resolve.push_str(
4838 "./my-test.wit",
4839 r#"
4840 package example:distraction;
4841 "#,
4842 )?;
4843
4844 let multiworld = resolve.push_str(
4847 "./my-test.wit",
4848 r#"
4849 package example:multiworld;
4850
4851 world foo { /* ... */ }
4852
4853 world bar { /* ... */ }
4854 "#,
4855 )?;
4856 assert!(
4857 resolve
4858 .select_world(&[distraction, multiworld], None)
4859 .is_err()
4860 );
4861 assert!(
4862 resolve
4863 .select_world(&[distraction, multiworld], Some("foo"))
4864 .is_err()
4865 );
4866 assert!(
4867 resolve
4868 .select_world(&[distraction, multiworld], Some("example:multiworld/foo"))
4869 .is_ok()
4870 );
4871 assert!(
4872 resolve
4873 .select_world(&[distraction, multiworld], Some("bar"))
4874 .is_err()
4875 );
4876 assert!(
4877 resolve
4878 .select_world(&[distraction, multiworld], Some("example:multiworld/bar"))
4879 .is_ok()
4880 );
4881
4882 Ok(())
4883 }
4884
4885 #[test]
4887 fn select_world_packages() -> Result<()> {
4888 use wit_parser::Resolve;
4889
4890 let mut resolve = Resolve::default();
4891
4892 let wit1 = resolve.push_str(
4895 "./my-test.wit",
4896 r#"
4897 package example:wit1;
4898
4899 world foo {
4900 // ...
4901 }
4902 "#,
4903 )?;
4904 assert!(resolve.select_world(&[wit1], None).is_ok());
4905 assert!(resolve.select_world(&[wit1], Some("foo")).is_ok());
4906 assert!(
4907 resolve
4908 .select_world(&[wit1], Some("example:wit1/foo"))
4909 .is_ok()
4910 );
4911 assert!(resolve.select_world(&[wit1], Some("bar")).is_err());
4912 assert!(
4913 resolve
4914 .select_world(&[wit1], Some("example:wit2/foo"))
4915 .is_err()
4916 );
4917
4918 let wit2 = resolve.push_str(
4921 "./my-test.wit",
4922 r#"
4923 package example:wit2;
4924
4925 world foo { /* ... */ }
4926 "#,
4927 )?;
4928 assert!(resolve.select_world(&[wit1, wit2], None).is_err());
4929 assert!(resolve.select_world(&[wit1, wit2], Some("foo")).is_err());
4930 assert!(
4931 resolve
4932 .select_world(&[wit1, wit2], Some("example:wit1/foo"))
4933 .is_ok()
4934 );
4935 assert!(resolve.select_world(&[wit2], None).is_ok());
4936 assert!(resolve.select_world(&[wit2], Some("foo")).is_ok());
4937 assert!(
4938 resolve
4939 .select_world(&[wit2], Some("example:wit1/foo"))
4940 .is_ok()
4941 );
4942 assert!(resolve.select_world(&[wit1, wit2], Some("bar")).is_err());
4943 assert!(
4944 resolve
4945 .select_world(&[wit1, wit2], Some("example:wit2/foo"))
4946 .is_ok()
4947 );
4948 assert!(resolve.select_world(&[wit2], Some("bar")).is_err());
4949 assert!(
4950 resolve
4951 .select_world(&[wit2], Some("example:wit2/foo"))
4952 .is_ok()
4953 );
4954
4955 Ok(())
4956 }
4957
4958 #[test]
4959 fn span_preservation() -> Result<()> {
4960 let mut resolve = Resolve::default();
4961 let pkg = resolve.push_str(
4962 "test.wit",
4963 r#"
4964 package foo:bar;
4965
4966 interface my-iface {
4967 type my-type = u32;
4968 my-func: func();
4969 }
4970
4971 world my-world {
4972 export my-export: func();
4973 }
4974 "#,
4975 )?;
4976
4977 let iface_id = resolve.packages[pkg].interfaces["my-iface"];
4978 assert!(resolve.interfaces[iface_id].span.is_known());
4979
4980 let type_id = resolve.interfaces[iface_id].types["my-type"];
4981 assert!(resolve.types[type_id].span.is_known());
4982
4983 assert!(
4984 resolve.interfaces[iface_id].functions["my-func"]
4985 .span
4986 .is_known()
4987 );
4988
4989 let world_id = resolve.packages[pkg].worlds["my-world"];
4990 assert!(resolve.worlds[world_id].span.is_known());
4991
4992 let WorldItem::Function(f) =
4993 &resolve.worlds[world_id].exports[&WorldKey::Name("my-export".to_string())]
4994 else {
4995 panic!("expected function");
4996 };
4997 assert!(f.span.is_known());
4998
4999 Ok(())
5000 }
5001
5002 #[test]
5003 fn span_preservation_through_merge() -> Result<()> {
5004 let mut resolve1 = Resolve::default();
5005 resolve1.push_str(
5006 "test1.wit",
5007 r#"
5008 package foo:bar;
5009
5010 interface iface1 {
5011 type type1 = u32;
5012 func1: func();
5013 }
5014 "#,
5015 )?;
5016
5017 let mut resolve2 = Resolve::default();
5018 let pkg2 = resolve2.push_str(
5019 "test2.wit",
5020 r#"
5021 package foo:baz;
5022
5023 interface iface2 {
5024 type type2 = string;
5025 func2: func();
5026 }
5027 "#,
5028 )?;
5029
5030 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5031 let remap = resolve1.merge(resolve2)?;
5032 let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
5033
5034 assert!(resolve1.interfaces[iface2_id].span.is_known());
5035
5036 let type2_id = resolve1.interfaces[iface2_id].types["type2"];
5037 assert!(resolve1.types[type2_id].span.is_known());
5038
5039 assert!(
5040 resolve1.interfaces[iface2_id].functions["func2"]
5041 .span
5042 .is_known()
5043 );
5044
5045 Ok(())
5046 }
5047
5048 #[test]
5049 fn span_preservation_through_include() -> Result<()> {
5050 let mut resolve = Resolve::default();
5051 let pkg = resolve.push_str(
5052 "test.wit",
5053 r#"
5054 package foo:bar;
5055
5056 world base {
5057 export my-func: func();
5058 }
5059
5060 world extended {
5061 include base;
5062 }
5063 "#,
5064 )?;
5065
5066 let base_id = resolve.packages[pkg].worlds["base"];
5067 let extended_id = resolve.packages[pkg].worlds["extended"];
5068
5069 let WorldItem::Function(base_func) =
5070 &resolve.worlds[base_id].exports[&WorldKey::Name("my-func".to_string())]
5071 else {
5072 panic!("expected function");
5073 };
5074 assert!(base_func.span.is_known());
5075
5076 let WorldItem::Function(extended_func) =
5077 &resolve.worlds[extended_id].exports[&WorldKey::Name("my-func".to_string())]
5078 else {
5079 panic!("expected function");
5080 };
5081 assert!(extended_func.span.is_known());
5082
5083 Ok(())
5084 }
5085
5086 #[test]
5087 fn span_preservation_through_include_with_rename() -> Result<()> {
5088 let mut resolve = Resolve::default();
5089 let pkg = resolve.push_str(
5090 "test.wit",
5091 r#"
5092 package foo:bar;
5093
5094 world base {
5095 export original-name: func();
5096 }
5097
5098 world extended {
5099 include base with { original-name as renamed-func }
5100 }
5101 "#,
5102 )?;
5103
5104 let extended_id = resolve.packages[pkg].worlds["extended"];
5105
5106 let WorldItem::Function(f) =
5107 &resolve.worlds[extended_id].exports[&WorldKey::Name("renamed-func".to_string())]
5108 else {
5109 panic!("expected function");
5110 };
5111 assert!(f.span.is_known());
5112
5113 assert!(
5114 !resolve.worlds[extended_id]
5115 .exports
5116 .contains_key(&WorldKey::Name("original-name".to_string()))
5117 );
5118
5119 Ok(())
5120 }
5121
5122 #[test]
5124 fn span_preservation_through_include_reverse_order() -> Result<()> {
5125 let mut resolve = Resolve::default();
5126 let pkg = resolve.push_str(
5127 "test.wit",
5128 r#"
5129 package foo:bar;
5130
5131 world extended {
5132 include base;
5133 }
5134
5135 world base {
5136 export my-func: func();
5137 }
5138 "#,
5139 )?;
5140
5141 let base_id = resolve.packages[pkg].worlds["base"];
5142 let extended_id = resolve.packages[pkg].worlds["extended"];
5143
5144 let WorldItem::Function(base_func) =
5145 &resolve.worlds[base_id].exports[&WorldKey::Name("my-func".to_string())]
5146 else {
5147 panic!("expected function");
5148 };
5149 assert!(base_func.span.is_known());
5150
5151 let WorldItem::Function(extended_func) =
5152 &resolve.worlds[extended_id].exports[&WorldKey::Name("my-func".to_string())]
5153 else {
5154 panic!("expected function");
5155 };
5156 assert!(extended_func.span.is_known());
5157
5158 Ok(())
5159 }
5160
5161 #[test]
5162 fn span_line_numbers() -> Result<()> {
5163 let mut resolve = Resolve::default();
5164 let pkg = resolve.push_source(
5165 "test.wit",
5166 "package foo:bar;
5167
5168interface my-iface {
5169 type my-type = u32;
5170 my-func: func();
5171}
5172
5173world my-world {
5174 export my-export: func();
5175}
5176",
5177 )?;
5178
5179 let iface_id = resolve.packages[pkg].interfaces["my-iface"];
5180 let iface_span = resolve.interfaces[iface_id].span;
5181 let iface_loc = resolve.render_location(iface_span);
5182 assert!(
5183 iface_loc.contains(":3:"),
5184 "interface location was {iface_loc}"
5185 );
5186
5187 let type_id = resolve.interfaces[iface_id].types["my-type"];
5188 let type_span = resolve.types[type_id].span;
5189 let type_loc = resolve.render_location(type_span);
5190 assert!(type_loc.contains(":4:"), "type location was {type_loc}");
5191
5192 let func_span = resolve.interfaces[iface_id].functions["my-func"].span;
5193 let func_loc = resolve.render_location(func_span);
5194 assert!(func_loc.contains(":5:"), "function location was {func_loc}");
5195
5196 let world_id = resolve.packages[pkg].worlds["my-world"];
5197 let world_span = resolve.worlds[world_id].span;
5198 let world_loc = resolve.render_location(world_span);
5199 assert!(world_loc.contains(":8:"), "world location was {world_loc}");
5200
5201 let WorldItem::Function(export_func) =
5202 &resolve.worlds[world_id].exports[&WorldKey::Name("my-export".to_string())]
5203 else {
5204 panic!("expected function");
5205 };
5206 let export_loc = resolve.render_location(export_func.span);
5207 assert!(
5208 export_loc.contains(":9:"),
5209 "export location was {export_loc}"
5210 );
5211
5212 Ok(())
5213 }
5214
5215 #[test]
5216 fn span_line_numbers_through_merge() -> Result<()> {
5217 let mut resolve1 = Resolve::default();
5218 resolve1.push_source(
5219 "first.wit",
5220 "package foo:first;
5221
5222interface iface1 {
5223 func1: func();
5224}
5225",
5226 )?;
5227
5228 let mut resolve2 = Resolve::default();
5229 let pkg2 = resolve2.push_source(
5230 "second.wit",
5231 "package foo:second;
5232
5233interface iface2 {
5234 func2: func();
5235}
5236",
5237 )?;
5238
5239 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5240 let remap = resolve1.merge(resolve2)?;
5241 let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
5242
5243 let iface2_span = resolve1.interfaces[iface2_id].span;
5244 let iface2_loc = resolve1.render_location(iface2_span);
5245 assert!(
5246 iface2_loc.contains("second.wit"),
5247 "should reference second.wit, got {iface2_loc}"
5248 );
5249 assert!(
5250 iface2_loc.contains(":3:"),
5251 "interface should be on line 3, got {iface2_loc}"
5252 );
5253
5254 let func2_span = resolve1.interfaces[iface2_id].functions["func2"].span;
5255 let func2_loc = resolve1.render_location(func2_span);
5256 assert!(
5257 func2_loc.contains("second.wit"),
5258 "should reference second.wit, got {func2_loc}"
5259 );
5260 assert!(
5261 func2_loc.contains(":4:"),
5262 "function should be on line 4, got {func2_loc}"
5263 );
5264
5265 Ok(())
5266 }
5267
5268 #[test]
5269 fn span_line_numbers_multiple_sources() -> Result<()> {
5270 let mut resolve = Resolve::default();
5271
5272 let pkg1 = resolve.push_source(
5273 "first.wit",
5274 "package test:first;
5275
5276interface first-iface {
5277 first-func: func();
5278}
5279",
5280 )?;
5281
5282 let pkg2 = resolve.push_source(
5283 "second.wit",
5284 "package test:second;
5285
5286interface second-iface {
5287 second-func: func();
5288}
5289",
5290 )?;
5291
5292 let iface1_id = resolve.packages[pkg1].interfaces["first-iface"];
5293 let iface1_span = resolve.interfaces[iface1_id].span;
5294 let iface1_loc = resolve.render_location(iface1_span);
5295 assert!(
5296 iface1_loc.contains("first.wit"),
5297 "should reference first.wit, got {iface1_loc}"
5298 );
5299 assert!(
5300 iface1_loc.contains(":3:"),
5301 "interface should be on line 3, got {iface1_loc}"
5302 );
5303
5304 let func1_span = resolve.interfaces[iface1_id].functions["first-func"].span;
5305 let func1_loc = resolve.render_location(func1_span);
5306 assert!(
5307 func1_loc.contains("first.wit"),
5308 "should reference first.wit, got {func1_loc}"
5309 );
5310 assert!(
5311 func1_loc.contains(":4:"),
5312 "function should be on line 4, got {func1_loc}"
5313 );
5314
5315 let iface2_id = resolve.packages[pkg2].interfaces["second-iface"];
5316 let iface2_span = resolve.interfaces[iface2_id].span;
5317 let iface2_loc = resolve.render_location(iface2_span);
5318 assert!(
5319 iface2_loc.contains("second.wit"),
5320 "should reference second.wit, got {iface2_loc}"
5321 );
5322 assert!(
5323 iface2_loc.contains(":3:"),
5324 "interface should be on line 3, got {iface2_loc}"
5325 );
5326
5327 let func2_span = resolve.interfaces[iface2_id].functions["second-func"].span;
5328 let func2_loc = resolve.render_location(func2_span);
5329 assert!(
5330 func2_loc.contains("second.wit"),
5331 "should reference second.wit, got {func2_loc}"
5332 );
5333 assert!(
5334 func2_loc.contains(":4:"),
5335 "function should be on line 4, got {func2_loc}"
5336 );
5337
5338 Ok(())
5339 }
5340
5341 #[test]
5342 fn span_preservation_for_fields_and_cases() -> Result<()> {
5343 use crate::TypeDefKind;
5344
5345 let mut resolve = Resolve::default();
5346 let pkg = resolve.push_str(
5347 "test.wit",
5348 r#"
5349 package foo:bar;
5350
5351 interface my-iface {
5352 record my-record {
5353 field1: u32,
5354 field2: string,
5355 }
5356
5357 flags my-flags {
5358 flag1,
5359 flag2,
5360 }
5361
5362 variant my-variant {
5363 case1,
5364 case2(u32),
5365 }
5366
5367 enum my-enum {
5368 val1,
5369 val2,
5370 }
5371 }
5372 "#,
5373 )?;
5374
5375 let iface_id = resolve.packages[pkg].interfaces["my-iface"];
5376
5377 let record_id = resolve.interfaces[iface_id].types["my-record"];
5379 let TypeDefKind::Record(record) = &resolve.types[record_id].kind else {
5380 panic!("expected record");
5381 };
5382 assert!(record.fields[0].span.is_known(), "field1 should have span");
5383 assert!(record.fields[1].span.is_known(), "field2 should have span");
5384
5385 let flags_id = resolve.interfaces[iface_id].types["my-flags"];
5387 let TypeDefKind::Flags(flags) = &resolve.types[flags_id].kind else {
5388 panic!("expected flags");
5389 };
5390 assert!(flags.flags[0].span.is_known(), "flag1 should have span");
5391 assert!(flags.flags[1].span.is_known(), "flag2 should have span");
5392
5393 let variant_id = resolve.interfaces[iface_id].types["my-variant"];
5395 let TypeDefKind::Variant(variant) = &resolve.types[variant_id].kind else {
5396 panic!("expected variant");
5397 };
5398 assert!(variant.cases[0].span.is_known(), "case1 should have span");
5399 assert!(variant.cases[1].span.is_known(), "case2 should have span");
5400
5401 let enum_id = resolve.interfaces[iface_id].types["my-enum"];
5403 let TypeDefKind::Enum(e) = &resolve.types[enum_id].kind else {
5404 panic!("expected enum");
5405 };
5406 assert!(e.cases[0].span.is_known(), "val1 should have span");
5407 assert!(e.cases[1].span.is_known(), "val2 should have span");
5408
5409 Ok(())
5410 }
5411
5412 #[test]
5413 fn span_preservation_for_fields_through_merge() -> Result<()> {
5414 use crate::TypeDefKind;
5415
5416 let mut resolve1 = Resolve::default();
5417 resolve1.push_str(
5418 "test1.wit",
5419 r#"
5420 package foo:bar;
5421
5422 interface iface1 {
5423 record rec1 {
5424 f1: u32,
5425 }
5426 }
5427 "#,
5428 )?;
5429
5430 let mut resolve2 = Resolve::default();
5431 let pkg2 = resolve2.push_str(
5432 "test2.wit",
5433 r#"
5434 package foo:baz;
5435
5436 interface iface2 {
5437 record rec2 {
5438 f2: string,
5439 }
5440
5441 variant var2 {
5442 c2,
5443 }
5444 }
5445 "#,
5446 )?;
5447
5448 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5449 let rec2_old_id = resolve2.interfaces[iface2_old_id].types["rec2"];
5450 let var2_old_id = resolve2.interfaces[iface2_old_id].types["var2"];
5451
5452 let remap = resolve1.merge(resolve2)?;
5453
5454 let rec2_id = remap.types[rec2_old_id.index()].unwrap();
5455 let TypeDefKind::Record(record) = &resolve1.types[rec2_id].kind else {
5456 panic!("expected record");
5457 };
5458 assert!(
5459 record.fields[0].span.is_known(),
5460 "field should have span after merge"
5461 );
5462
5463 let var2_id = remap.types[var2_old_id.index()].unwrap();
5464 let TypeDefKind::Variant(variant) = &resolve1.types[var2_id].kind else {
5465 panic!("expected variant");
5466 };
5467 assert!(
5468 variant.cases[0].span.is_known(),
5469 "case should have span after merge"
5470 );
5471
5472 Ok(())
5473 }
5474
5475 #[test]
5476 fn param_spans_point_to_names() -> Result<()> {
5477 let source = "\
5478package foo:bar;
5479
5480interface iface {
5481 my-func: func(a: u32, b: string);
5482}
5483";
5484 let mut resolve = Resolve::default();
5485 let pkg = resolve.push_str("test.wit", source)?;
5486
5487 let iface_id = resolve.packages[pkg].interfaces["iface"];
5488 let func = &resolve.interfaces[iface_id].functions["my-func"];
5489 assert_eq!(func.params.len(), 2);
5490 for param in &func.params {
5491 let start = param.span.start() as usize;
5492 let end = param.span.end() as usize;
5493 let snippet = &source[start..end];
5494 assert_eq!(
5495 snippet, param.name,
5496 "param `{}` span points to {:?}",
5497 param.name, snippet
5498 );
5499 }
5500
5501 Ok(())
5502 }
5503
5504 #[test]
5505 fn param_spans_preserved_through_merge() -> Result<()> {
5506 let mut resolve1 = Resolve::default();
5507 resolve1.push_str(
5508 "test1.wit",
5509 r#"
5510 package foo:bar;
5511
5512 interface iface1 {
5513 f1: func(x: u32);
5514 }
5515 "#,
5516 )?;
5517
5518 let mut resolve2 = Resolve::default();
5519 let pkg2 = resolve2.push_str(
5520 "test2.wit",
5521 r#"
5522 package foo:baz;
5523
5524 interface iface2 {
5525 f2: func(y: string, z: bool);
5526 }
5527 "#,
5528 )?;
5529
5530 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5531
5532 let remap = resolve1.merge(resolve2)?;
5533
5534 let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
5535 let func = &resolve1.interfaces[iface2_id].functions["f2"];
5536 for param in &func.params {
5537 assert!(
5538 param.span.is_known(),
5539 "param `{}` should have span after merge",
5540 param.name
5541 );
5542 }
5543
5544 Ok(())
5545 }
5546}