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> {
401 self.push_group(UnresolvedPackageGroup::parse_str(path, contents)?)
402 }
403
404 pub fn render_location(&self, span: Span) -> String {
406 self.source_map.render_location(span)
407 }
408
409 pub fn all_bits_valid(&self, ty: &Type) -> bool {
410 match ty {
411 Type::U8
412 | Type::S8
413 | Type::U16
414 | Type::S16
415 | Type::U32
416 | Type::S32
417 | Type::U64
418 | Type::S64
419 | Type::F32
420 | Type::F64 => true,
421
422 Type::Bool | Type::Char | Type::String | Type::ErrorContext => false,
423
424 Type::Id(id) => match &self.types[*id].kind {
425 TypeDefKind::List(_)
426 | TypeDefKind::Map(_, _)
427 | TypeDefKind::Variant(_)
428 | TypeDefKind::Enum(_)
429 | TypeDefKind::Option(_)
430 | TypeDefKind::Result(_)
431 | TypeDefKind::Future(_)
432 | TypeDefKind::Stream(_) => false,
433 TypeDefKind::Type(t) | TypeDefKind::FixedLengthList(t, ..) => {
434 self.all_bits_valid(t)
435 }
436
437 TypeDefKind::Handle(h) => match h {
438 crate::Handle::Own(_) => true,
439 crate::Handle::Borrow(_) => true,
440 },
441
442 TypeDefKind::Resource => false,
443 TypeDefKind::Record(r) => r.fields.iter().all(|f| self.all_bits_valid(&f.ty)),
444 TypeDefKind::Tuple(t) => t.types.iter().all(|t| self.all_bits_valid(t)),
445
446 TypeDefKind::Flags(_) => false,
450
451 TypeDefKind::Unknown => unreachable!(),
452 },
453 }
454 }
455
456 pub fn merge(&mut self, resolve: Resolve) -> Result<Remap> {
468 log::trace!(
469 "merging {} packages into {} packages",
470 resolve.packages.len(),
471 self.packages.len()
472 );
473
474 let mut map = MergeMap::new(&resolve, &self);
475 map.build()?;
476 let MergeMap {
477 package_map,
478 interface_map,
479 type_map,
480 world_map,
481 interfaces_to_add,
482 worlds_to_add,
483 ..
484 } = map;
485
486 let mut remap = Remap::default();
505 let Resolve {
506 types,
507 worlds,
508 interfaces,
509 packages,
510 package_names,
511 features: _,
512 source_map,
513 ..
514 } = resolve;
515
516 let span_offset = self.source_map.append(source_map);
517
518 let mut moved_types = Vec::new();
519 for (id, mut ty) in types {
520 let new_id = match type_map.get(&id).copied() {
521 Some(id) => {
522 update_stability(&ty.stability, &mut self.types[id].stability)?;
523 id
524 }
525 None => {
526 log::debug!("moving type {:?}", ty.name);
527 moved_types.push(id);
528 remap.update_typedef(self, &mut ty, Default::default())?;
529 ty.adjust_spans(span_offset);
530 self.types.alloc(ty)
531 }
532 };
533 assert_eq!(remap.types.len(), id.index());
534 remap.types.push(Some(new_id));
535 }
536
537 let mut moved_interfaces = Vec::new();
538 for (id, mut iface) in interfaces {
539 let new_id = match interface_map.get(&id).copied() {
540 Some(id) => {
541 update_stability(&iface.stability, &mut self.interfaces[id].stability)?;
542 id
543 }
544 None => {
545 log::debug!("moving interface {:?}", iface.name);
546 moved_interfaces.push(id);
547 remap.update_interface(self, &mut iface)?;
548 iface.adjust_spans(span_offset);
549 self.interfaces.alloc(iface)
550 }
551 };
552 assert_eq!(remap.interfaces.len(), id.index());
553 remap.interfaces.push(Some(new_id));
554 }
555
556 let mut moved_worlds = Vec::new();
557 for (id, mut world) in worlds {
558 let new_id = match world_map.get(&id).copied() {
559 Some(world_id) => {
560 update_stability(&world.stability, &mut self.worlds[world_id].stability)?;
561 for from_import in world.imports.iter() {
562 Resolve::update_world_imports_stability(
563 from_import,
564 &mut self.worlds[world_id].imports,
565 &interface_map,
566 )?;
567 }
568 for from_export in world.exports.iter() {
569 Resolve::update_world_imports_stability(
570 from_export,
571 &mut self.worlds[world_id].exports,
572 &interface_map,
573 )?;
574 }
575 world_id
576 }
577 None => {
578 log::debug!("moving world {}", world.name);
579 moved_worlds.push(id);
580 let mut update = |map: &mut IndexMap<WorldKey, WorldItem>| -> Result<_> {
581 for (mut name, mut item) in mem::take(map) {
582 remap.update_world_key(&mut name, Default::default())?;
583 match &mut item {
584 WorldItem::Function(f) => {
585 remap.update_function(self, f, Default::default())?
586 }
587 WorldItem::Interface { id, .. } => {
588 *id = remap.map_interface(*id, Default::default())?
589 }
590 WorldItem::Type { id, .. } => {
591 *id = remap.map_type(*id, Default::default())?
592 }
593 }
594 map.insert(name, item);
595 }
596 Ok(())
597 };
598 update(&mut world.imports)?;
599 update(&mut world.exports)?;
600 world.adjust_spans(span_offset);
601 self.worlds.alloc(world)
602 }
603 };
604 assert_eq!(remap.worlds.len(), id.index());
605 remap.worlds.push(Some(new_id));
606 }
607
608 for (id, mut pkg) in packages {
609 let new_id = match package_map.get(&id).copied() {
610 Some(id) => id,
611 None => {
612 for (_, id) in pkg.interfaces.iter_mut() {
613 *id = remap.map_interface(*id, Default::default())?;
614 }
615 for (_, id) in pkg.worlds.iter_mut() {
616 *id = remap.map_world(*id, Default::default())?;
617 }
618 self.packages.alloc(pkg)
619 }
620 };
621 assert_eq!(remap.packages.len(), id.index());
622 remap.packages.push(new_id);
623 }
624
625 for (name, id) in package_names {
626 let id = remap.packages[id.index()];
627 if let Some(prev) = self.package_names.insert(name, id) {
628 assert_eq!(prev, id);
629 }
630 }
631
632 for id in moved_worlds {
640 let id = remap.map_world(id, Default::default())?;
641 if let Some(pkg) = self.worlds[id].package.as_mut() {
642 *pkg = remap.packages[pkg.index()];
643 }
644 }
645 for id in moved_interfaces {
646 let id = remap.map_interface(id, Default::default())?;
647 if let Some(pkg) = self.interfaces[id].package.as_mut() {
648 *pkg = remap.packages[pkg.index()];
649 }
650 }
651 for id in moved_types {
652 let id = remap.map_type(id, Default::default())?;
653 match &mut self.types[id].owner {
654 TypeOwner::Interface(id) => *id = remap.map_interface(*id, Default::default())?,
655 TypeOwner::World(id) => *id = remap.map_world(*id, Default::default())?,
656 TypeOwner::None => {}
657 }
658 }
659
660 for (name, pkg, iface) in interfaces_to_add {
665 let prev = self.packages[pkg]
666 .interfaces
667 .insert(name, remap.map_interface(iface, Default::default())?);
668 assert!(prev.is_none());
669 }
670 for (name, pkg, world) in worlds_to_add {
671 let prev = self.packages[pkg]
672 .worlds
673 .insert(name, remap.map_world(world, Default::default())?);
674 assert!(prev.is_none());
675 }
676
677 log::trace!("now have {} packages", self.packages.len());
678
679 #[cfg(debug_assertions)]
680 self.assert_valid();
681 Ok(remap)
682 }
683
684 fn update_world_imports_stability(
685 from_item: (&WorldKey, &WorldItem),
686 into_items: &mut IndexMap<WorldKey, WorldItem>,
687 interface_map: &HashMap<Id<Interface>, Id<Interface>>,
688 ) -> Result<()> {
689 match from_item.0 {
690 WorldKey::Name(_) => {
691 Ok(())
693 }
694 key @ WorldKey::Interface(_) => {
695 let new_key = MergeMap::map_name(key, interface_map);
696 if let Some(into) = into_items.get_mut(&new_key) {
697 match (from_item.1, into) {
698 (
699 WorldItem::Interface {
700 id: aid,
701 stability: astability,
702 ..
703 },
704 WorldItem::Interface {
705 id: bid,
706 stability: bstability,
707 ..
708 },
709 ) => {
710 let aid = interface_map.get(aid).copied().unwrap_or(*aid);
711 assert_eq!(aid, *bid);
712 update_stability(astability, bstability)?;
713 Ok(())
714 }
715 _ => unreachable!(),
716 }
717 } else {
718 unreachable!()
721 }
722 }
723 }
724 }
725
726 pub fn merge_worlds(
741 &mut self,
742 from: WorldId,
743 into: WorldId,
744 clone_maps: &mut CloneMaps,
745 ) -> Result<()> {
746 let mut new_imports = Vec::new();
747 let mut new_exports = Vec::new();
748
749 let from_world = &self.worlds[from];
750 let into_world = &self.worlds[into];
751
752 log::trace!("merging {} into {}", from_world.name, into_world.name);
753
754 for (name, from_import) in from_world.imports.iter() {
762 let name_str = self.name_world_key(name);
763 match into_world.imports.get(name) {
764 Some(into_import) => {
765 log::trace!("info/from shared import on `{name_str}`");
766 self.merge_world_item(from_import, into_import)
767 .with_context(|| format!("failed to merge world import {name_str}"))?;
768 }
769 None => {
770 log::trace!("new import: `{name_str}`");
771 new_imports.push((name.clone(), from_import.clone()));
772 }
773 }
774 }
775
776 let mut must_be_imported = HashMap::new();
783 for (key, export) in into_world.exports.iter() {
784 for dep in self.world_item_direct_deps(export) {
785 if into_world.exports.contains_key(&WorldKey::Interface(dep)) {
786 continue;
787 }
788 self.foreach_interface_dep(dep, &mut |id| {
789 must_be_imported.insert(id, key.clone());
790 });
791 }
792 }
793
794 for (name, from_export) in from_world.exports.iter() {
797 let name_str = self.name_world_key(name);
798 match into_world.exports.get(name) {
799 Some(into_export) => {
800 log::trace!("info/from shared export on `{name_str}`");
801 self.merge_world_item(from_export, into_export)
802 .with_context(|| format!("failed to merge world export {name_str}"))?;
803 }
804 None => {
805 log::trace!("new export `{name_str}`");
806 self.ensure_can_add_world_export(
809 into_world,
810 name,
811 from_export,
812 &must_be_imported,
813 )
814 .with_context(|| {
815 format!("failed to add export `{}`", self.name_world_key(name))
816 })?;
817 new_exports.push((name.clone(), from_export.clone()));
818 }
819 }
820 }
821
822 let mut cloner = clone::Cloner::new(
836 self,
837 clone_maps,
838 TypeOwner::World(from),
839 TypeOwner::World(into),
840 );
841 cloner.register_world_type_overlap(from, into);
842 for (name, item) in new_imports.iter_mut().chain(&mut new_exports) {
843 cloner.world_item(name, item);
844 }
845
846 let into_world = &mut self.worlds[into];
848 for (name, import) in new_imports {
849 let prev = into_world.imports.insert(name, import);
850 assert!(prev.is_none());
851 }
852 for (name, export) in new_exports {
853 let prev = into_world.exports.insert(name, export);
854 assert!(prev.is_none());
855 }
856
857 #[cfg(debug_assertions)]
858 self.assert_valid();
859 Ok(())
860 }
861
862 fn merge_world_item(&self, from: &WorldItem, into: &WorldItem) -> Result<()> {
863 let mut map = MergeMap::new(self, self);
864 match (from, into) {
865 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
866 if from == into {
871 return Ok(());
872 }
873
874 map.build_interface(*from, *into)
884 .context("failed to merge interfaces")?;
885 }
886
887 (WorldItem::Function(from), WorldItem::Function(into)) => {
890 map.build_function(from, into)
891 .context("failed to merge functions")?;
892 }
893 (WorldItem::Type { id: from, .. }, WorldItem::Type { id: into, .. }) => {
894 map.build_type_id(*from, *into)
895 .context("failed to merge types")?;
896 }
897
898 (WorldItem::Interface { .. }, _)
900 | (WorldItem::Function { .. }, _)
901 | (WorldItem::Type { .. }, _) => {
902 bail!("different kinds of items");
903 }
904 }
905 assert!(map.interfaces_to_add.is_empty());
906 assert!(map.worlds_to_add.is_empty());
907 Ok(())
908 }
909
910 fn ensure_can_add_world_export(
922 &self,
923 into: &World,
924 name: &WorldKey,
925 item: &WorldItem,
926 must_be_imported: &HashMap<InterfaceId, WorldKey>,
927 ) -> Result<()> {
928 assert!(!into.exports.contains_key(name));
929 let name = self.name_world_key(name);
930
931 for dep in self.world_item_direct_deps(item) {
935 if into.exports.contains_key(&WorldKey::Interface(dep)) {
936 continue;
937 }
938 self.ensure_not_exported(into, dep)
939 .with_context(|| format!("failed validating export of `{name}`"))?;
940 }
941
942 if let WorldItem::Interface { id, .. } = item {
946 if let Some(export) = must_be_imported.get(id) {
947 let export_name = self.name_world_key(export);
948 bail!(
949 "export `{export_name}` depends on `{name}` \
950 previously as an import which will change meaning \
951 if `{name}` is added as an export"
952 );
953 }
954 }
955
956 Ok(())
957 }
958
959 fn ensure_not_exported(&self, world: &World, id: InterfaceId) -> Result<()> {
960 let key = WorldKey::Interface(id);
961 let name = self.name_world_key(&key);
962 if world.exports.contains_key(&key) {
963 bail!(
964 "world exports `{name}` but it's also transitively used by an \
965 import \
966 which means that this is not valid"
967 )
968 }
969 for dep in self.interface_direct_deps(id) {
970 self.ensure_not_exported(world, dep)
971 .with_context(|| format!("failed validating transitive import dep `{name}`"))?;
972 }
973 Ok(())
974 }
975
976 fn world_item_direct_deps(&self, item: &WorldItem) -> impl Iterator<Item = InterfaceId> + '_ {
982 let mut interface = None;
983 let mut ty = None;
984 match item {
985 WorldItem::Function(_) => {}
986 WorldItem::Type { id, .. } => ty = Some(*id),
987 WorldItem::Interface { id, .. } => interface = Some(*id),
988 }
989
990 interface
991 .into_iter()
992 .flat_map(move |id| self.interface_direct_deps(id))
993 .chain(ty.and_then(|t| self.type_interface_dep(t)))
994 }
995
996 fn foreach_interface_dep(&self, id: InterfaceId, f: &mut dyn FnMut(InterfaceId)) {
1000 self._foreach_interface_dep(id, f, &mut HashSet::new())
1001 }
1002
1003 fn _foreach_interface_dep(
1007 &self,
1008 id: InterfaceId,
1009 f: &mut dyn FnMut(InterfaceId),
1010 visited: &mut HashSet<InterfaceId>,
1011 ) {
1012 if !visited.insert(id) {
1013 return;
1014 }
1015 f(id);
1016 for dep in self.interface_direct_deps(id) {
1017 self._foreach_interface_dep(dep, f, visited);
1018 }
1019 }
1020
1021 pub fn id_of(&self, interface: InterfaceId) -> Option<String> {
1025 let interface = &self.interfaces[interface];
1026 Some(self.id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1027 }
1028
1029 pub fn canonicalized_id_of(&self, interface: InterfaceId) -> Option<String> {
1034 let interface = &self.interfaces[interface];
1035 Some(self.canonicalized_id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1036 }
1037
1038 pub fn importize(&mut self, world_id: WorldId, out_world_name: Option<String>) -> Result<()> {
1054 let world = &mut self.worlds[world_id];
1059 let pkg = &mut self.packages[world.package.unwrap()];
1060 pkg.worlds.shift_remove(&world.name);
1061 if let Some(name) = out_world_name {
1062 world.name = name.clone();
1063 pkg.worlds.insert(name, world_id);
1064 } else {
1065 world.name.push_str("-importized");
1066 pkg.worlds.insert(world.name.clone(), world_id);
1067 }
1068
1069 world.imports.retain(|_, item| match item {
1072 WorldItem::Type { .. } => true,
1073 _ => false,
1074 });
1075
1076 for (name, export) in mem::take(&mut world.exports) {
1077 match (name.clone(), world.imports.insert(name, export)) {
1078 (_, None) => {}
1080
1081 (WorldKey::Name(name), Some(_)) => {
1083 bail!("world export `{name}` conflicts with import of same name");
1084 }
1085
1086 (WorldKey::Interface(_), _) => unreachable!(),
1089 }
1090 }
1091
1092 self.elaborate_world(world_id)?;
1095
1096 #[cfg(debug_assertions)]
1097 self.assert_valid();
1098 Ok(())
1099 }
1100
1101 pub fn id_of_name(&self, pkg: PackageId, name: &str) -> String {
1103 let package = &self.packages[pkg];
1104 let mut base = String::new();
1105 base.push_str(&package.name.namespace);
1106 base.push_str(":");
1107 base.push_str(&package.name.name);
1108 base.push_str("/");
1109 base.push_str(name);
1110 if let Some(version) = &package.name.version {
1111 base.push_str(&format!("@{version}"));
1112 }
1113 base
1114 }
1115
1116 pub fn canonicalized_id_of_name(&self, pkg: PackageId, name: &str) -> String {
1122 let package = &self.packages[pkg];
1123 let mut base = String::new();
1124 base.push_str(&package.name.namespace);
1125 base.push_str(":");
1126 base.push_str(&package.name.name);
1127 base.push_str("/");
1128 base.push_str(name);
1129 if let Some(version) = &package.name.version {
1130 base.push_str("@");
1131 let string = PackageName::version_compat_track_string(version);
1132 base.push_str(&string);
1133 }
1134 base
1135 }
1136
1137 pub fn select_world(
1252 &self,
1253 main_packages: &[PackageId],
1254 world: Option<&str>,
1255 ) -> Result<WorldId> {
1256 let world_path = match world {
1258 Some(world) => Some(
1259 parse_use_path(world)
1260 .with_context(|| format!("failed to parse world specifier `{world}`"))?,
1261 ),
1262 None => None,
1263 };
1264
1265 match world_path {
1266 Some(world_path) => {
1268 let (pkg, world_name) = match (main_packages, world_path) {
1269 ([], _) => bail!("No main packages defined"),
1271
1272 ([main_package], ParsedUsePath::Name(name)) => (*main_package, name),
1274
1275 (_, ParsedUsePath::Name(_name)) => {
1277 bail!(
1278 "There are multiple main packages; a world must be explicitly chosen:{}",
1279 self.worlds
1280 .iter()
1281 .map(|world| format!(
1282 "\n {}",
1283 self.id_of_name(world.1.package.unwrap(), &world.1.name)
1284 ))
1285 .collect::<String>()
1286 )
1287 }
1288
1289 (_, ParsedUsePath::Package(pkg, world_name)) => {
1291 let pkg = match self.package_names.get(&pkg) {
1292 Some(pkg) => *pkg,
1293 None => {
1294 let mut candidates =
1295 self.package_names.iter().filter(|(name, _)| {
1296 pkg.version.is_none()
1297 && pkg.name == name.name
1298 && pkg.namespace == name.namespace
1299 && name.version.is_some()
1300 });
1301 let candidate = candidates.next();
1302 if let Some((c2, _)) = candidates.next() {
1303 let (c1, _) = candidate.unwrap();
1304 bail!(
1305 "package name `{pkg}` is available at both \
1306 versions {} and {} but which is not specified",
1307 c1.version.as_ref().unwrap(),
1308 c2.version.as_ref().unwrap(),
1309 );
1310 }
1311 match candidate {
1312 Some((_, id)) => *id,
1313 None => bail!("unknown package `{pkg}`"),
1314 }
1315 }
1316 };
1317 (pkg, world_name.to_string())
1318 }
1319 };
1320
1321 let pkg = &self.packages[pkg];
1323 pkg.worlds.get(&world_name).copied().ok_or_else(|| {
1324 anyhow!("World `{world_name}` not found in package `{}`", pkg.name)
1325 })
1326 }
1327
1328 None => match main_packages {
1330 [] => bail!("No main packages defined"),
1331
1332 [main_package] => {
1334 let pkg = &self.packages[*main_package];
1335 match pkg.worlds.len() {
1336 0 => bail!("The main package `{}` contains no worlds", pkg.name),
1337 1 => Ok(pkg.worlds[0]),
1338 _ => bail!(
1339 "There are multiple worlds in `{}`; one must be explicitly chosen:{}",
1340 pkg.name,
1341 pkg.worlds
1342 .values()
1343 .map(|world| format!(
1344 "\n {}",
1345 self.id_of_name(*main_package, &self.worlds[*world].name)
1346 ))
1347 .collect::<String>()
1348 ),
1349 }
1350 }
1351
1352 _ => {
1354 bail!(
1355 "There are multiple main packages; a world must be explicitly chosen:{}",
1356 self.worlds
1357 .iter()
1358 .map(|world| format!(
1359 "\n {}",
1360 self.id_of_name(world.1.package.unwrap(), &world.1.name)
1361 ))
1362 .collect::<String>()
1363 )
1364 }
1365 },
1366 }
1367 }
1368
1369 pub fn name_world_key(&self, key: &WorldKey) -> String {
1371 match key {
1372 WorldKey::Name(s) => s.to_string(),
1373 WorldKey::Interface(i) => self.id_of(*i).expect("unexpected anonymous interface"),
1374 }
1375 }
1376
1377 pub fn name_canonicalized_world_key(&self, key: &WorldKey) -> String {
1380 match key {
1381 WorldKey::Name(s) => s.to_string(),
1382 WorldKey::Interface(i) => self
1383 .canonicalized_id_of(*i)
1384 .expect("unexpected anonymous interface"),
1385 }
1386 }
1387
1388 pub fn type_interface_dep(&self, id: TypeId) -> Option<InterfaceId> {
1394 let ty = &self.types[id];
1395 let dep = match ty.kind {
1396 TypeDefKind::Type(Type::Id(id)) => id,
1397 _ => return None,
1398 };
1399 let other = &self.types[dep];
1400 if ty.owner == other.owner {
1401 None
1402 } else {
1403 match other.owner {
1404 TypeOwner::Interface(id) => Some(id),
1405 _ => unreachable!(),
1406 }
1407 }
1408 }
1409
1410 pub fn interface_direct_deps(&self, id: InterfaceId) -> impl Iterator<Item = InterfaceId> + '_ {
1420 self.interfaces[id]
1421 .types
1422 .iter()
1423 .filter_map(move |(_name, ty)| self.type_interface_dep(*ty))
1424 }
1425
1426 pub fn package_direct_deps(&self, id: PackageId) -> impl Iterator<Item = PackageId> + '_ {
1436 let pkg = &self.packages[id];
1437
1438 pkg.interfaces
1439 .iter()
1440 .flat_map(move |(_name, id)| self.interface_direct_deps(*id))
1441 .chain(pkg.worlds.iter().flat_map(move |(_name, id)| {
1442 let world = &self.worlds[*id];
1443 world
1444 .imports
1445 .iter()
1446 .chain(world.exports.iter())
1447 .filter_map(move |(_name, item)| match item {
1448 WorldItem::Interface { id, .. } => Some(*id),
1449 WorldItem::Function(_) => None,
1450 WorldItem::Type { id, .. } => self.type_interface_dep(*id),
1451 })
1452 }))
1453 .filter_map(move |iface_id| {
1454 let pkg = self.interfaces[iface_id].package?;
1455 if pkg == id { None } else { Some(pkg) }
1456 })
1457 }
1458
1459 pub fn topological_packages(&self) -> Vec<PackageId> {
1465 let mut pushed = vec![false; self.packages.len()];
1466 let mut order = Vec::new();
1467 for (id, _) in self.packages.iter() {
1468 self.build_topological_package_ordering(id, &mut pushed, &mut order);
1469 }
1470 order
1471 }
1472
1473 fn build_topological_package_ordering(
1474 &self,
1475 id: PackageId,
1476 pushed: &mut Vec<bool>,
1477 order: &mut Vec<PackageId>,
1478 ) {
1479 if pushed[id.index()] {
1480 return;
1481 }
1482 for dep in self.package_direct_deps(id) {
1483 self.build_topological_package_ordering(dep, pushed, order);
1484 }
1485 order.push(id);
1486 pushed[id.index()] = true;
1487 }
1488
1489 #[doc(hidden)]
1490 pub fn assert_valid(&self) {
1491 let mut package_interfaces = Vec::new();
1492 let mut package_worlds = Vec::new();
1493 for (id, pkg) in self.packages.iter() {
1494 let mut interfaces = HashSet::new();
1495 for (name, iface) in pkg.interfaces.iter() {
1496 assert!(interfaces.insert(*iface));
1497 let iface = &self.interfaces[*iface];
1498 assert_eq!(name, iface.name.as_ref().unwrap());
1499 assert_eq!(iface.package.unwrap(), id);
1500 }
1501 package_interfaces.push(pkg.interfaces.values().copied().collect::<HashSet<_>>());
1502 let mut worlds = HashSet::new();
1503 for (name, world) in pkg.worlds.iter() {
1504 assert!(worlds.insert(*world));
1505 assert_eq!(
1506 pkg.worlds.get_key_value(name),
1507 Some((name, world)),
1508 "`MutableKeys` impl may have been used to change a key's hash or equality"
1509 );
1510 let world = &self.worlds[*world];
1511 assert_eq!(*name, world.name);
1512 assert_eq!(world.package.unwrap(), id);
1513 }
1514 package_worlds.push(pkg.worlds.values().copied().collect::<HashSet<_>>());
1515 }
1516
1517 let mut interface_types = Vec::new();
1518 for (id, iface) in self.interfaces.iter() {
1519 assert!(self.packages.get(iface.package.unwrap()).is_some());
1520 if iface.name.is_some() {
1521 match iface.clone_of {
1522 Some(other) => {
1523 assert_eq!(iface.name, self.interfaces[other].name);
1524 }
1525 None => {
1526 assert!(package_interfaces[iface.package.unwrap().index()].contains(&id));
1527 }
1528 }
1529 }
1530
1531 for (name, ty) in iface.types.iter() {
1532 let ty = &self.types[*ty];
1533 assert_eq!(ty.name.as_ref(), Some(name));
1534 assert_eq!(ty.owner, TypeOwner::Interface(id));
1535 }
1536 interface_types.push(iface.types.values().copied().collect::<HashSet<_>>());
1537 for (name, f) in iface.functions.iter() {
1538 assert_eq!(*name, f.name);
1539 }
1540 }
1541
1542 let mut world_types = Vec::new();
1543 for (id, world) in self.worlds.iter() {
1544 log::debug!("validating world {}", &world.name);
1545 if let Some(package) = world.package {
1546 assert!(self.packages.get(package).is_some());
1547 assert!(package_worlds[package.index()].contains(&id));
1548 }
1549 assert!(world.includes.is_empty());
1550
1551 let mut types = HashSet::new();
1552 for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1553 log::debug!("validating world item: {}", self.name_world_key(name));
1554 match item {
1555 WorldItem::Interface { id, .. } => {
1556 if matches!(name, WorldKey::Name(_)) {
1559 assert_eq!(self.interfaces[*id].package, world.package);
1560 }
1561 }
1562 WorldItem::Function(f) => {
1563 assert!(!matches!(name, WorldKey::Interface(_)));
1564 assert_eq!(f.name, name.clone().unwrap_name());
1565 }
1566 WorldItem::Type { id: ty, .. } => {
1567 assert!(!matches!(name, WorldKey::Interface(_)));
1568 assert!(types.insert(*ty));
1569 let ty = &self.types[*ty];
1570 assert_eq!(ty.name, Some(name.clone().unwrap_name()));
1571 assert_eq!(ty.owner, TypeOwner::World(id));
1572 }
1573 }
1574 }
1575 self.assert_world_elaborated(world);
1576 world_types.push(types);
1577 }
1578
1579 for (ty_id, ty) in self.types.iter() {
1580 match ty.owner {
1581 TypeOwner::Interface(id) => {
1582 assert!(self.interfaces.get(id).is_some());
1583 assert!(interface_types[id.index()].contains(&ty_id));
1584 }
1585 TypeOwner::World(id) => {
1586 assert!(self.worlds.get(id).is_some());
1587 assert!(world_types[id.index()].contains(&ty_id));
1588 }
1589 TypeOwner::None => {}
1590 }
1591 }
1592
1593 self.assert_topologically_sorted();
1594 }
1595
1596 fn assert_topologically_sorted(&self) {
1597 let mut positions = IndexMap::default();
1598 for id in self.topological_packages() {
1599 let pkg = &self.packages[id];
1600 log::debug!("pkg {}", pkg.name);
1601 let prev = positions.insert(Some(id), IndexSet::default());
1602 assert!(prev.is_none());
1603 }
1604 positions.insert(None, IndexSet::default());
1605
1606 for (id, iface) in self.interfaces.iter() {
1607 log::debug!("iface {:?}", iface.name);
1608 let ok = positions.get_mut(&iface.package).unwrap().insert(id);
1609 assert!(ok);
1610 }
1611
1612 for (_, world) in self.worlds.iter() {
1613 log::debug!("world {:?}", world.name);
1614
1615 let my_package = world.package;
1616 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1617
1618 for (_, item) in world.imports.iter().chain(&world.exports) {
1619 let id = match item {
1620 WorldItem::Interface { id, .. } => *id,
1621 _ => continue,
1622 };
1623 let other_package = self.interfaces[id].package;
1624 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1625
1626 assert!(other_package_pos <= my_package_pos);
1627 }
1628 }
1629
1630 for (_id, ty) in self.types.iter() {
1631 log::debug!("type {:?} {:?}", ty.name, ty.owner);
1632 let other_id = match ty.kind {
1633 TypeDefKind::Type(Type::Id(ty)) => ty,
1634 _ => continue,
1635 };
1636 let other = &self.types[other_id];
1637 if ty.kind == other.kind {
1638 continue;
1639 }
1640 let my_interface = match ty.owner {
1641 TypeOwner::Interface(id) => id,
1642 _ => continue,
1643 };
1644 let other_interface = match other.owner {
1645 TypeOwner::Interface(id) => id,
1646 _ => continue,
1647 };
1648
1649 let my_package = self.interfaces[my_interface].package;
1650 let other_package = self.interfaces[other_interface].package;
1651 let my_package_pos = positions.get_index_of(&my_package).unwrap();
1652 let other_package_pos = positions.get_index_of(&other_package).unwrap();
1653
1654 if my_package_pos == other_package_pos {
1655 let interfaces = &positions[&my_package];
1656 let my_interface_pos = interfaces.get_index_of(&my_interface).unwrap();
1657 let other_interface_pos = interfaces.get_index_of(&other_interface).unwrap();
1658 assert!(other_interface_pos <= my_interface_pos);
1659 } else {
1660 assert!(other_package_pos < my_package_pos);
1661 }
1662 }
1663 }
1664
1665 fn assert_world_elaborated(&self, world: &World) {
1666 for (key, item) in world.imports.iter() {
1667 log::debug!(
1668 "asserting elaborated world import {}",
1669 self.name_world_key(key)
1670 );
1671 match item {
1672 WorldItem::Type { id, .. } => self.assert_world_imports_type_deps(world, key, *id),
1673
1674 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1676
1677 WorldItem::Interface { id, .. } => {
1679 for dep in self.interface_direct_deps(*id) {
1680 assert!(
1681 world.imports.contains_key(&WorldKey::Interface(dep)),
1682 "world import of {} is missing transitive dep of {}",
1683 self.name_world_key(key),
1684 self.id_of(dep).unwrap(),
1685 );
1686 }
1687 }
1688 }
1689 }
1690 for (key, item) in world.exports.iter() {
1691 log::debug!(
1692 "asserting elaborated world export {}",
1693 self.name_world_key(key)
1694 );
1695 match item {
1696 WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1698
1699 WorldItem::Interface { id, .. } => {
1703 for dep in self.interface_direct_deps(*id) {
1704 let dep_key = WorldKey::Interface(dep);
1705 if world.exports.contains_key(&dep_key) {
1706 continue;
1707 }
1708 self.foreach_interface_dep(dep, &mut |dep| {
1709 let dep_key = WorldKey::Interface(dep);
1710 assert!(
1711 world.imports.contains_key(&dep_key),
1712 "world should import {} (required by {})",
1713 self.name_world_key(&dep_key),
1714 self.name_world_key(key),
1715 );
1716 assert!(
1717 !world.exports.contains_key(&dep_key),
1718 "world should not export {} (required by {})",
1719 self.name_world_key(&dep_key),
1720 self.name_world_key(key),
1721 );
1722 });
1723 }
1724 }
1725
1726 WorldItem::Type { .. } => unreachable!(),
1728 }
1729 }
1730 }
1731
1732 fn assert_world_imports_type_deps(&self, world: &World, key: &WorldKey, ty: TypeId) {
1733 let ty = &self.types[ty];
1736 if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
1737 if let TypeOwner::Interface(id) = self.types[other].owner {
1738 let key = WorldKey::Interface(id);
1739 assert!(world.imports.contains_key(&key));
1740 return;
1741 }
1742 }
1743
1744 let mut visitor = MyVisit(self, Vec::new());
1748 visitor.visit_type_def(self, ty);
1749 for ty in visitor.1 {
1750 let ty = &self.types[ty];
1751 let Some(name) = ty.name.clone() else {
1752 continue;
1753 };
1754 let dep_key = WorldKey::Name(name);
1755 assert!(
1756 world.imports.contains_key(&dep_key),
1757 "world import `{}` should also force an import of `{}`",
1758 self.name_world_key(key),
1759 self.name_world_key(&dep_key),
1760 );
1761 }
1762
1763 struct MyVisit<'a>(&'a Resolve, Vec<TypeId>);
1764
1765 impl TypeIdVisitor for MyVisit<'_> {
1766 fn before_visit_type_id(&mut self, id: TypeId) -> bool {
1767 self.1.push(id);
1768 self.0.types[id].name.is_none()
1770 }
1771 }
1772 }
1773
1774 fn assert_world_function_imports_types(&self, world: &World, key: &WorldKey, func: &Function) {
1778 for ty in func
1779 .parameter_and_result_types()
1780 .chain(func.kind.resource().map(Type::Id))
1781 {
1782 let Type::Id(id) = ty else {
1783 continue;
1784 };
1785 self.assert_world_imports_type_deps(world, key, id);
1786 }
1787 }
1788
1789 fn include_stability(
1805 &self,
1806 stability: &Stability,
1807 pkg_id: &PackageId,
1808 span: Span,
1809 ) -> Result<bool> {
1810 let err = |msg: String| -> anyhow::Error { Error::new(span, msg).into() };
1811 Ok(match stability {
1812 Stability::Unknown => true,
1813 Stability::Stable { since, .. } => {
1816 let Some(p) = self.packages.get(*pkg_id) else {
1817 return Ok(true);
1825 };
1826
1827 let package_version = p.name.version.as_ref().ok_or_else(|| {
1830 err(format!(
1831 "package [{}] contains a feature gate with a version \
1832 specifier, so it must have a version",
1833 p.name
1834 ))
1835 })?;
1836
1837 if since > package_version {
1841 return Err(err(format!(
1842 "feature gate cannot reference unreleased version \
1843 {since} of package [{}] (current version {package_version})",
1844 p.name
1845 )));
1846 }
1847
1848 true
1849 }
1850 Stability::Unstable { feature, .. } => {
1851 self.features.contains(feature) || self.all_features
1852 }
1853 })
1854 }
1855
1856 fn include_type(&self, ty: &TypeDef, pkgid: PackageId, span: Span) -> Result<bool> {
1859 self.include_stability(&ty.stability, &pkgid, span)
1860 .with_context(|| {
1861 format!(
1862 "failed to process feature gate for type [{}] in package [{}]",
1863 ty.name.as_ref().map(String::as_str).unwrap_or("<unknown>"),
1864 self.packages[pkgid].name,
1865 )
1866 })
1867 }
1868
1869 fn elaborate_world(&mut self, world_id: WorldId) -> Result<()> {
1881 let mut new_imports = IndexMap::default();
1885 let world = &self.worlds[world_id];
1886
1887 let sort_key = |resolve: &Resolve, item: &WorldItem| match item {
1910 WorldItem::Interface { .. } => 0,
1911 WorldItem::Type { id, .. } => {
1912 let ty = &resolve.types[*id];
1913 match ty.kind {
1914 TypeDefKind::Type(Type::Id(t)) if resolve.types[t].owner != ty.owner => 1,
1915 _ => 2,
1916 }
1917 }
1918 WorldItem::Function(f) => {
1919 if f.kind.resource().is_none() {
1920 3
1921 } else {
1922 4
1923 }
1924 }
1925 };
1926
1927 let mut world_imports = world.imports.iter().collect::<Vec<_>>();
1930 world_imports.sort_by_key(|(_name, import)| sort_key(self, import));
1931 for (name, item) in world_imports {
1932 match item {
1933 WorldItem::Interface { id, stability, .. } => {
1936 self.elaborate_world_import(&mut new_imports, name.clone(), *id, &stability);
1937 }
1938
1939 WorldItem::Function(_) => {
1942 let prev = new_imports.insert(name.clone(), item.clone());
1943 assert!(prev.is_none());
1944 }
1945
1946 WorldItem::Type { id, .. } => {
1950 if let Some(dep) = self.type_interface_dep(*id) {
1951 self.elaborate_world_import(
1952 &mut new_imports,
1953 WorldKey::Interface(dep),
1954 dep,
1955 &self.types[*id].stability,
1956 );
1957 }
1958 let prev = new_imports.insert(name.clone(), item.clone());
1959 assert!(prev.is_none());
1960 }
1961 }
1962 }
1963
1964 let mut new_exports = IndexMap::default();
1970 let mut export_interfaces = IndexMap::default();
1971 for (name, item) in world.exports.iter() {
1972 match item {
1973 WorldItem::Interface { id, stability, .. } => {
1974 let prev = export_interfaces.insert(*id, (name.clone(), stability));
1975 assert!(prev.is_none());
1976 }
1977 WorldItem::Function(_) => {
1978 let prev = new_exports.insert(name.clone(), item.clone());
1979 assert!(prev.is_none());
1980 }
1981 WorldItem::Type { .. } => unreachable!(),
1982 }
1983 }
1984
1985 self.elaborate_world_exports(&export_interfaces, &mut new_imports, &mut new_exports)?;
1986
1987 new_imports.sort_by_cached_key(|_name, import| sort_key(self, import));
1991
1992 log::trace!("imports = {new_imports:?}");
1995 log::trace!("exports = {new_exports:?}");
1996 let world = &mut self.worlds[world_id];
1997 world.imports = new_imports;
1998 world.exports = new_exports;
1999
2000 Ok(())
2001 }
2002
2003 fn elaborate_world_import(
2004 &self,
2005 imports: &mut IndexMap<WorldKey, WorldItem>,
2006 key: WorldKey,
2007 id: InterfaceId,
2008 stability: &Stability,
2009 ) {
2010 if imports.contains_key(&key) {
2011 return;
2012 }
2013 for dep in self.interface_direct_deps(id) {
2014 self.elaborate_world_import(imports, WorldKey::Interface(dep), dep, stability);
2015 }
2016 let prev = imports.insert(
2017 key,
2018 WorldItem::Interface {
2019 id,
2020 stability: stability.clone(),
2021 span: Default::default(),
2022 },
2023 );
2024 assert!(prev.is_none());
2025 }
2026
2027 fn elaborate_world_exports(
2074 &self,
2075 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2076 imports: &mut IndexMap<WorldKey, WorldItem>,
2077 exports: &mut IndexMap<WorldKey, WorldItem>,
2078 ) -> Result<()> {
2079 let mut required_imports = HashSet::new();
2080 for (id, (key, stability)) in export_interfaces.iter() {
2081 let name = self.name_world_key(&key);
2082 let ok = add_world_export(
2083 self,
2084 imports,
2085 exports,
2086 export_interfaces,
2087 &mut required_imports,
2088 *id,
2089 key,
2090 true,
2091 stability,
2092 );
2093 if !ok {
2094 bail!(
2095 InvalidTransitiveDependency(name),
2113 );
2114 }
2115 }
2116 return Ok(());
2117
2118 fn add_world_export(
2119 resolve: &Resolve,
2120 imports: &mut IndexMap<WorldKey, WorldItem>,
2121 exports: &mut IndexMap<WorldKey, WorldItem>,
2122 export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2123 required_imports: &mut HashSet<InterfaceId>,
2124 id: InterfaceId,
2125 key: &WorldKey,
2126 add_export: bool,
2127 stability: &Stability,
2128 ) -> bool {
2129 if exports.contains_key(key) {
2130 if add_export {
2131 return true;
2132 } else {
2133 return false;
2134 }
2135 }
2136 if !add_export && required_imports.contains(&id) {
2139 return true;
2140 }
2141 let ok = resolve.interface_direct_deps(id).all(|dep| {
2142 let key = WorldKey::Interface(dep);
2143 let add_export = add_export && export_interfaces.contains_key(&dep);
2144 add_world_export(
2145 resolve,
2146 imports,
2147 exports,
2148 export_interfaces,
2149 required_imports,
2150 dep,
2151 &key,
2152 add_export,
2153 stability,
2154 )
2155 });
2156 if !ok {
2157 return false;
2158 }
2159 let item = WorldItem::Interface {
2160 id,
2161 stability: stability.clone(),
2162 span: Default::default(),
2163 };
2164 if add_export {
2165 if required_imports.contains(&id) {
2166 return false;
2167 }
2168 exports.insert(key.clone(), item);
2169 } else {
2170 required_imports.insert(id);
2171 imports.insert(key.clone(), item);
2172 }
2173 true
2174 }
2175 }
2176
2177 pub fn merge_world_imports_based_on_semver(&mut self, world_id: WorldId) -> Result<()> {
2189 let world = &self.worlds[world_id];
2190
2191 let mut semver_tracks = HashMap::new();
2200 let mut to_remove = HashSet::new();
2201 for (key, _) in world.imports.iter() {
2202 let iface_id = match key {
2203 WorldKey::Interface(id) => *id,
2204 WorldKey::Name(_) => continue,
2205 };
2206 let (track, version) = match self.semver_track(iface_id) {
2207 Some(track) => track,
2208 None => continue,
2209 };
2210 log::debug!(
2211 "{} is on track {}/{}",
2212 self.id_of(iface_id).unwrap(),
2213 track.0,
2214 track.1,
2215 );
2216 match semver_tracks.entry(track.clone()) {
2217 Entry::Vacant(e) => {
2218 e.insert((version, iface_id));
2219 }
2220 Entry::Occupied(mut e) => match version.cmp(&e.get().0) {
2221 Ordering::Greater => {
2222 to_remove.insert(e.get().1);
2223 e.insert((version, iface_id));
2224 }
2225 Ordering::Equal => {}
2226 Ordering::Less => {
2227 to_remove.insert(iface_id);
2228 }
2229 },
2230 }
2231 }
2232
2233 let mut replacements = HashMap::new();
2236 for id in to_remove {
2237 let (track, _) = self.semver_track(id).unwrap();
2238 let (_, latest) = semver_tracks[&track];
2239 let prev = replacements.insert(id, latest);
2240 assert!(prev.is_none());
2241 }
2242 drop(semver_tracks);
2245
2246 for (to_replace, replace_with) in replacements.iter() {
2251 self.merge_world_item(
2252 &WorldItem::Interface {
2253 id: *to_replace,
2254 stability: Default::default(),
2255 span: Default::default(),
2256 },
2257 &WorldItem::Interface {
2258 id: *replace_with,
2259 stability: Default::default(),
2260 span: Default::default(),
2261 },
2262 )
2263 .with_context(|| {
2264 let old_name = self.id_of(*to_replace).unwrap();
2265 let new_name = self.id_of(*replace_with).unwrap();
2266 format!(
2267 "failed to upgrade `{old_name}` to `{new_name}`, was \
2268 this semver-compatible update not semver compatible?"
2269 )
2270 })?;
2271 }
2272
2273 for (to_replace, replace_with) in replacements.iter() {
2274 log::debug!(
2275 "REPLACE {} => {}",
2276 self.id_of(*to_replace).unwrap(),
2277 self.id_of(*replace_with).unwrap(),
2278 );
2279 }
2280
2281 for (key, item) in mem::take(&mut self.worlds[world_id].imports) {
2290 if let WorldItem::Interface { id, .. } = item {
2291 if replacements.contains_key(&id) {
2292 continue;
2293 }
2294 }
2295
2296 self.update_interface_deps_of_world_item(&item, &replacements);
2297
2298 let prev = self.worlds[world_id].imports.insert(key, item);
2299 assert!(prev.is_none());
2300 }
2301 for (key, item) in mem::take(&mut self.worlds[world_id].exports) {
2302 self.update_interface_deps_of_world_item(&item, &replacements);
2303 let prev = self.worlds[world_id].exports.insert(key, item);
2304 assert!(prev.is_none());
2305 }
2306
2307 let ids = self.worlds.iter().map(|(id, _)| id).collect::<Vec<_>>();
2313 for world_id in ids {
2314 self.elaborate_world(world_id).with_context(|| {
2315 let name = &self.worlds[world_id].name;
2316 format!(
2317 "failed to elaborate world `{name}` after deduplicating imports \
2318 based on semver"
2319 )
2320 })?;
2321 }
2322
2323 #[cfg(debug_assertions)]
2324 self.assert_valid();
2325
2326 Ok(())
2327 }
2328
2329 fn update_interface_deps_of_world_item(
2330 &mut self,
2331 item: &WorldItem,
2332 replacements: &HashMap<InterfaceId, InterfaceId>,
2333 ) {
2334 match *item {
2335 WorldItem::Type { id, .. } => self.update_interface_dep_of_type(id, &replacements),
2336 WorldItem::Interface { id, .. } => {
2337 let types = self.interfaces[id]
2338 .types
2339 .values()
2340 .copied()
2341 .collect::<Vec<_>>();
2342 for ty in types {
2343 self.update_interface_dep_of_type(ty, &replacements);
2344 }
2345 }
2346 WorldItem::Function(_) => {}
2347 }
2348 }
2349
2350 fn semver_track(&self, id: InterfaceId) -> Option<((PackageName, String), &Version)> {
2361 let iface = &self.interfaces[id];
2362 let pkg = &self.packages[iface.package?];
2363 let version = pkg.name.version.as_ref()?;
2364 let mut name = pkg.name.clone();
2365 name.version = Some(PackageName::version_compat_track(version));
2366 Some(((name, iface.name.clone()?), version))
2367 }
2368
2369 fn update_interface_dep_of_type(
2373 &mut self,
2374 ty: TypeId,
2375 replacements: &HashMap<InterfaceId, InterfaceId>,
2376 ) {
2377 let to_replace = match self.type_interface_dep(ty) {
2378 Some(id) => id,
2379 None => return,
2380 };
2381 let replace_with = match replacements.get(&to_replace) {
2382 Some(id) => id,
2383 None => return,
2384 };
2385 let dep = match self.types[ty].kind {
2386 TypeDefKind::Type(Type::Id(id)) => id,
2387 _ => return,
2388 };
2389 let name = self.types[dep].name.as_ref().unwrap();
2390 let replacement_id = self.interfaces[*replace_with].types[name];
2393 self.types[ty].kind = TypeDefKind::Type(Type::Id(replacement_id));
2394 }
2395
2396 pub fn wasm_import_name(
2403 &self,
2404 mangling: ManglingAndAbi,
2405 import: WasmImport<'_>,
2406 ) -> (String, String) {
2407 match mangling {
2408 ManglingAndAbi::Standard32 => match import {
2409 WasmImport::Func { interface, func } => {
2410 let module = match interface {
2411 Some(key) => format!("cm32p2|{}", self.name_canonicalized_world_key(key)),
2412 None => format!("cm32p2"),
2413 };
2414 (module, func.name.clone())
2415 }
2416 WasmImport::ResourceIntrinsic {
2417 interface,
2418 resource,
2419 intrinsic,
2420 } => {
2421 let name = self.types[resource].name.as_ref().unwrap();
2422 let (prefix, name) = match intrinsic {
2423 ResourceIntrinsic::ImportedDrop => ("", format!("{name}_drop")),
2424 ResourceIntrinsic::ExportedDrop => ("_ex_", format!("{name}_drop")),
2425 ResourceIntrinsic::ExportedNew => ("_ex_", format!("{name}_new")),
2426 ResourceIntrinsic::ExportedRep => ("_ex_", format!("{name}_rep")),
2427 };
2428 let module = match interface {
2429 Some(key) => {
2430 format!("cm32p2|{prefix}{}", self.name_canonicalized_world_key(key))
2431 }
2432 None => {
2433 assert_eq!(prefix, "");
2434 format!("cm32p2")
2435 }
2436 };
2437 (module, name)
2438 }
2439 },
2440 ManglingAndAbi::Legacy(abi) => match import {
2441 WasmImport::Func { interface, func } => {
2442 let module = match interface {
2443 Some(key) => self.name_world_key(key),
2444 None => format!("$root"),
2445 };
2446 (module, format!("{}{}", abi.import_prefix(), func.name))
2447 }
2448 WasmImport::ResourceIntrinsic {
2449 interface,
2450 resource,
2451 intrinsic,
2452 } => {
2453 let name = self.types[resource].name.as_ref().unwrap();
2454 let (prefix, name) = match intrinsic {
2455 ResourceIntrinsic::ImportedDrop => ("", format!("[resource-drop]{name}")),
2456 ResourceIntrinsic::ExportedDrop => {
2457 ("[export]", format!("[resource-drop]{name}"))
2458 }
2459 ResourceIntrinsic::ExportedNew => {
2460 ("[export]", format!("[resource-new]{name}"))
2461 }
2462 ResourceIntrinsic::ExportedRep => {
2463 ("[export]", format!("[resource-rep]{name}"))
2464 }
2465 };
2466 let module = match interface {
2467 Some(key) => format!("{prefix}{}", self.name_world_key(key)),
2468 None => {
2469 assert_eq!(prefix, "");
2470 format!("$root")
2471 }
2472 };
2473 (module, format!("{}{name}", abi.import_prefix()))
2474 }
2475 },
2476 }
2477 }
2478
2479 pub fn wasm_export_name(&self, mangling: ManglingAndAbi, export: WasmExport<'_>) -> String {
2483 match mangling {
2484 ManglingAndAbi::Standard32 => match export {
2485 WasmExport::Func {
2486 interface,
2487 func,
2488 kind,
2489 } => {
2490 let mut name = String::from("cm32p2|");
2491 if let Some(interface) = interface {
2492 let s = self.name_canonicalized_world_key(interface);
2493 name.push_str(&s);
2494 }
2495 name.push_str("|");
2496 name.push_str(&func.name);
2497 match kind {
2498 WasmExportKind::Normal => {}
2499 WasmExportKind::PostReturn => name.push_str("_post"),
2500 WasmExportKind::Callback => todo!(
2501 "not yet supported: \
2502 async callback functions using standard name mangling"
2503 ),
2504 }
2505 name
2506 }
2507 WasmExport::ResourceDtor {
2508 interface,
2509 resource,
2510 } => {
2511 let name = self.types[resource].name.as_ref().unwrap();
2512 let interface = self.name_canonicalized_world_key(interface);
2513 format!("cm32p2|{interface}|{name}_dtor")
2514 }
2515 WasmExport::Memory => "cm32p2_memory".to_string(),
2516 WasmExport::Initialize => "cm32p2_initialize".to_string(),
2517 WasmExport::Realloc => "cm32p2_realloc".to_string(),
2518 },
2519 ManglingAndAbi::Legacy(abi) => match export {
2520 WasmExport::Func {
2521 interface,
2522 func,
2523 kind,
2524 } => {
2525 let mut name = abi.export_prefix().to_string();
2526 match kind {
2527 WasmExportKind::Normal => {}
2528 WasmExportKind::PostReturn => name.push_str("cabi_post_"),
2529 WasmExportKind::Callback => {
2530 assert!(matches!(abi, LiftLowerAbi::AsyncCallback));
2531 name = format!("[callback]{name}")
2532 }
2533 }
2534 if let Some(interface) = interface {
2535 let s = self.name_world_key(interface);
2536 name.push_str(&s);
2537 name.push_str("#");
2538 }
2539 name.push_str(&func.name);
2540 name
2541 }
2542 WasmExport::ResourceDtor {
2543 interface,
2544 resource,
2545 } => {
2546 let name = self.types[resource].name.as_ref().unwrap();
2547 let interface = self.name_world_key(interface);
2548 format!("{}{interface}#[dtor]{name}", abi.export_prefix())
2549 }
2550 WasmExport::Memory => "memory".to_string(),
2551 WasmExport::Initialize => "_initialize".to_string(),
2552 WasmExport::Realloc => "cabi_realloc".to_string(),
2553 },
2554 }
2555 }
2556
2557 pub fn generate_nominal_type_ids(&mut self, world: WorldId) {
2597 let mut imports = HashSet::new();
2598
2599 for import in self.worlds[world].imports.values() {
2602 if let WorldItem::Interface { id, .. } = import {
2603 imports.insert(*id);
2604 }
2605 }
2606
2607 let mut to_clone = IndexMap::default();
2608 for (i, export) in self.worlds[world].exports.values().enumerate() {
2609 let id = match export {
2610 WorldItem::Interface { id, .. } => *id,
2611
2612 WorldItem::Function(_) => continue,
2615
2616 WorldItem::Type { .. } => unreachable!(),
2617 };
2618
2619 let imported_and_exported = imports.contains(&id);
2623 let any_dep_rewritten = self
2624 .interface_direct_deps(id)
2625 .any(|dep| to_clone.contains_key(&dep));
2626 if !(imported_and_exported || any_dep_rewritten) {
2627 continue;
2628 }
2629
2630 to_clone.insert(id, i);
2631 }
2632
2633 let mut maps = CloneMaps::default();
2634 let mut cloner = clone::Cloner::new(
2635 self,
2636 &mut maps,
2637 TypeOwner::World(world),
2638 TypeOwner::World(world),
2639 );
2640 for (id, i) in to_clone {
2641 let mut new_id = id;
2647 cloner.interface(&mut new_id);
2648
2649 let exports = &mut cloner.resolve.worlds[world].exports;
2653 let (key, prev) = exports.get_index_mut(i).unwrap();
2654 match prev {
2655 WorldItem::Interface { id, .. } => *id = new_id,
2656 _ => unreachable!(),
2657 }
2658
2659 match key {
2660 WorldKey::Interface(_) => {
2666 exports
2667 .replace_index(i, WorldKey::Interface(new_id))
2668 .unwrap();
2669 }
2670
2671 WorldKey::Name(_) => {}
2674 }
2675 }
2676
2677 #[cfg(debug_assertions)]
2678 self.assert_valid();
2679 }
2680}
2681
2682#[derive(Debug)]
2684pub enum WasmImport<'a> {
2685 Func {
2687 interface: Option<&'a WorldKey>,
2692
2693 func: &'a Function,
2695 },
2696
2697 ResourceIntrinsic {
2699 interface: Option<&'a WorldKey>,
2701
2702 resource: TypeId,
2704
2705 intrinsic: ResourceIntrinsic,
2707 },
2708}
2709
2710#[derive(Debug)]
2713pub enum ResourceIntrinsic {
2714 ImportedDrop,
2715 ExportedDrop,
2716 ExportedNew,
2717 ExportedRep,
2718}
2719
2720#[derive(Debug)]
2723pub enum WasmExportKind {
2724 Normal,
2726
2727 PostReturn,
2729
2730 Callback,
2732}
2733
2734#[derive(Debug)]
2737pub enum WasmExport<'a> {
2738 Func {
2740 interface: Option<&'a WorldKey>,
2743
2744 func: &'a Function,
2746
2747 kind: WasmExportKind,
2749 },
2750
2751 ResourceDtor {
2753 interface: &'a WorldKey,
2755 resource: TypeId,
2757 },
2758
2759 Memory,
2761
2762 Initialize,
2764
2765 Realloc,
2767}
2768
2769#[derive(Default)]
2772pub struct Remap {
2773 pub types: Vec<Option<TypeId>>,
2774 pub interfaces: Vec<Option<InterfaceId>>,
2775 pub worlds: Vec<Option<WorldId>>,
2776 pub packages: Vec<PackageId>,
2777
2778 own_handles: HashMap<TypeId, TypeId>,
2788
2789 type_has_borrow: Vec<Option<bool>>,
2790}
2791
2792fn apply_map<T>(map: &[Option<Id<T>>], id: Id<T>, desc: &str, span: Span) -> Result<Id<T>> {
2793 match map.get(id.index()) {
2794 Some(Some(id)) => Ok(*id),
2795 Some(None) => {
2796 let msg = format!(
2797 "found a reference to a {desc} which is excluded \
2798 due to its feature not being activated"
2799 );
2800 Err(Error::new(span, msg).into())
2801 }
2802 None => panic!("request to remap a {desc} that has not yet been registered"),
2803 }
2804}
2805
2806fn rename(original_name: &str, include_name: &IncludeName) -> Option<String> {
2807 if original_name == include_name.name {
2808 return Some(include_name.as_.to_string());
2809 }
2810 let (kind, rest) = original_name.split_once(']')?;
2811 match rest.split_once('.') {
2812 Some((name, rest)) if name == include_name.name => {
2813 Some(format!("{kind}]{}.{rest}", include_name.as_))
2814 }
2815 _ if rest == include_name.name => Some(format!("{kind}]{}", include_name.as_)),
2816 _ => None,
2817 }
2818}
2819
2820impl Remap {
2821 pub fn map_type(&self, id: TypeId, span: Span) -> Result<TypeId> {
2822 apply_map(&self.types, id, "type", span)
2823 }
2824
2825 pub fn map_interface(&self, id: InterfaceId, span: Span) -> Result<InterfaceId> {
2826 apply_map(&self.interfaces, id, "interface", span)
2827 }
2828
2829 pub fn map_world(&self, id: WorldId, span: Span) -> Result<WorldId> {
2830 apply_map(&self.worlds, id, "world", span)
2831 }
2832
2833 fn append(
2834 &mut self,
2835 resolve: &mut Resolve,
2836 unresolved: UnresolvedPackage,
2837 ) -> Result<PackageId> {
2838 let pkgid = resolve.packages.alloc(Package {
2839 name: unresolved.name.clone(),
2840 docs: unresolved.docs.clone(),
2841 interfaces: Default::default(),
2842 worlds: Default::default(),
2843 });
2844 let prev = resolve.package_names.insert(unresolved.name.clone(), pkgid);
2845 if let Some(prev) = prev {
2846 resolve.package_names.insert(unresolved.name.clone(), prev);
2847 bail!(
2848 "attempting to re-add package `{}` when it's already present in this `Resolve`",
2849 unresolved.name,
2850 );
2851 }
2852
2853 self.process_foreign_deps(resolve, pkgid, &unresolved)?;
2854
2855 let foreign_types = self.types.len();
2856 let foreign_interfaces = self.interfaces.len();
2857 let foreign_worlds = self.worlds.len();
2858
2859 for (id, mut ty) in unresolved.types.into_iter().skip(foreign_types) {
2865 let span = ty.span;
2866 if !resolve.include_type(&ty, pkgid, span)? {
2867 self.types.push(None);
2868 continue;
2869 }
2870
2871 self.update_typedef(resolve, &mut ty, span)?;
2872 let new_id = resolve.types.alloc(ty);
2873 assert_eq!(self.types.len(), id.index());
2874
2875 let new_id = match resolve.types[new_id] {
2876 TypeDef {
2881 name: None,
2882 owner: TypeOwner::None,
2883 kind: TypeDefKind::Handle(Handle::Own(id)),
2884 docs: _,
2885 stability: _,
2886 span: _,
2887 } => *self.own_handles.entry(id).or_insert(new_id),
2888
2889 _ => new_id,
2892 };
2893 self.types.push(Some(new_id));
2894 }
2895
2896 for (id, mut iface) in unresolved.interfaces.into_iter().skip(foreign_interfaces) {
2899 let span = iface.span;
2900 if !resolve
2901 .include_stability(&iface.stability, &pkgid, span)
2902 .with_context(|| {
2903 format!(
2904 "failed to process feature gate for interface [{}] in package [{}]",
2905 iface
2906 .name
2907 .as_ref()
2908 .map(String::as_str)
2909 .unwrap_or("<unknown>"),
2910 resolve.packages[pkgid].name,
2911 )
2912 })?
2913 {
2914 self.interfaces.push(None);
2915 continue;
2916 }
2917 assert!(iface.package.is_none());
2918 iface.package = Some(pkgid);
2919 self.update_interface(resolve, &mut iface)?;
2920 let new_id = resolve.interfaces.alloc(iface);
2921 assert_eq!(self.interfaces.len(), id.index());
2922 self.interfaces.push(Some(new_id));
2923 }
2924
2925 for id in self.types.iter().skip(foreign_types) {
2928 let id = match id {
2929 Some(id) => *id,
2930 None => continue,
2931 };
2932 let span = resolve.types[id].span;
2933 match &mut resolve.types[id].owner {
2934 TypeOwner::Interface(iface_id) => {
2935 *iface_id = self.map_interface(*iface_id, span)
2936 .with_context(|| {
2937 "this type is not gated by a feature but its interface is gated by a feature"
2938 })?;
2939 }
2940 TypeOwner::World(_) | TypeOwner::None => {}
2941 }
2942 }
2943
2944 for (id, mut world) in unresolved.worlds.into_iter().skip(foreign_worlds) {
2952 let world_span = world.span;
2953 if !resolve
2954 .include_stability(&world.stability, &pkgid, world_span)
2955 .with_context(|| {
2956 format!(
2957 "failed to process feature gate for world [{}] in package [{}]",
2958 world.name, resolve.packages[pkgid].name,
2959 )
2960 })?
2961 {
2962 self.worlds.push(None);
2963 continue;
2964 }
2965 self.update_world(&mut world, resolve, &pkgid)?;
2966
2967 let new_id = resolve.worlds.alloc(world);
2968 assert_eq!(self.worlds.len(), id.index());
2969 self.worlds.push(Some(new_id));
2970 }
2971
2972 for id in self.types.iter().skip(foreign_types) {
2974 let id = match id {
2975 Some(id) => *id,
2976 None => continue,
2977 };
2978 let span = resolve.types[id].span;
2979 match &mut resolve.types[id].owner {
2980 TypeOwner::World(world_id) => {
2981 *world_id = self.map_world(*world_id, span)
2982 .with_context(|| {
2983 "this type is not gated by a feature but its interface is gated by a feature"
2984 })?;
2985 }
2986 TypeOwner::Interface(_) | TypeOwner::None => {}
2987 }
2988 }
2989
2990 for id in self.worlds.iter().skip(foreign_worlds) {
3007 let Some(id) = *id else {
3008 continue;
3009 };
3010 self.process_world_includes(id, resolve, &pkgid)?;
3011
3012 let world_span = resolve.worlds[id].span;
3013 resolve.elaborate_world(id).with_context(|| {
3014 Error::new(
3015 world_span,
3016 format!(
3017 "failed to elaborate world imports/exports of `{}`",
3018 resolve.worlds[id].name
3019 ),
3020 )
3021 })?;
3022 }
3023
3024 for id in self.interfaces.iter().skip(foreign_interfaces) {
3026 let id = match id {
3027 Some(id) => *id,
3028 None => continue,
3029 };
3030 let iface = &mut resolve.interfaces[id];
3031 iface.package = Some(pkgid);
3032 if let Some(name) = &iface.name {
3033 let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), id);
3034 assert!(prev.is_none());
3035 }
3036 }
3037 for id in self.worlds.iter().skip(foreign_worlds) {
3038 let id = match id {
3039 Some(id) => *id,
3040 None => continue,
3041 };
3042 let world = &mut resolve.worlds[id];
3043 world.package = Some(pkgid);
3044 let prev = resolve.packages[pkgid]
3045 .worlds
3046 .insert(world.name.clone(), id);
3047 assert!(prev.is_none());
3048 }
3049 Ok(pkgid)
3050 }
3051
3052 fn process_foreign_deps(
3053 &mut self,
3054 resolve: &mut Resolve,
3055 pkgid: PackageId,
3056 unresolved: &UnresolvedPackage,
3057 ) -> Result<()> {
3058 let mut world_to_package = HashMap::new();
3061 let mut interface_to_package = HashMap::new();
3062 for (i, (pkg_name, worlds_or_ifaces)) in unresolved.foreign_deps.iter().enumerate() {
3063 for (name, (item, stabilities)) in worlds_or_ifaces {
3064 match item {
3065 AstItem::Interface(unresolved_interface_id) => {
3066 let prev = interface_to_package.insert(
3067 *unresolved_interface_id,
3068 (pkg_name, name, unresolved.foreign_dep_spans[i], stabilities),
3069 );
3070 assert!(prev.is_none());
3071 }
3072 AstItem::World(unresolved_world_id) => {
3073 let prev = world_to_package.insert(
3074 *unresolved_world_id,
3075 (pkg_name, name, unresolved.foreign_dep_spans[i], stabilities),
3076 );
3077 assert!(prev.is_none());
3078 }
3079 }
3080 }
3081 }
3082
3083 self.process_foreign_interfaces(unresolved, &interface_to_package, resolve, &pkgid)?;
3087
3088 self.process_foreign_worlds(unresolved, &world_to_package, resolve, &pkgid)?;
3092
3093 self.process_foreign_types(unresolved, pkgid, resolve)?;
3096
3097 for (id, span) in unresolved.required_resource_types.iter() {
3098 let Ok(mut id) = self.map_type(*id, *span) else {
3103 continue;
3104 };
3105 loop {
3106 match resolve.types[id].kind {
3107 TypeDefKind::Type(Type::Id(i)) => id = i,
3108 TypeDefKind::Resource => break,
3109 _ => bail!(Error::new(
3110 *span,
3111 format!("type used in a handle must be a resource"),
3112 )),
3113 }
3114 }
3115 }
3116
3117 #[cfg(debug_assertions)]
3118 resolve.assert_valid();
3119
3120 Ok(())
3121 }
3122
3123 fn process_foreign_interfaces(
3124 &mut self,
3125 unresolved: &UnresolvedPackage,
3126 interface_to_package: &HashMap<InterfaceId, (&PackageName, &String, Span, &Vec<Stability>)>,
3127 resolve: &mut Resolve,
3128 parent_pkg_id: &PackageId,
3129 ) -> Result<(), anyhow::Error> {
3130 for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() {
3131 let (pkg_name, interface, span, stabilities) =
3132 match interface_to_package.get(&unresolved_iface_id) {
3133 Some(items) => *items,
3134 None => break,
3138 };
3139
3140 let pkgid = resolve
3141 .package_names
3142 .get(pkg_name)
3143 .copied()
3144 .ok_or_else(|| {
3145 PackageNotFoundError::new(
3146 span,
3147 pkg_name.clone(),
3148 resolve.package_names.keys().cloned().collect(),
3149 )
3150 })?;
3151
3152 assert!(unresolved_iface.functions.is_empty());
3154
3155 let pkg = &resolve.packages[pkgid];
3156 let iface_span = unresolved_iface.span;
3157
3158 let mut enabled = false;
3159 for stability in stabilities {
3160 if resolve.include_stability(stability, parent_pkg_id, iface_span)? {
3161 enabled = true;
3162 break;
3163 }
3164 }
3165
3166 if !enabled {
3167 self.interfaces.push(None);
3168 continue;
3169 }
3170
3171 let iface_id = pkg
3172 .interfaces
3173 .get(interface)
3174 .copied()
3175 .ok_or_else(|| Error::new(iface_span, "interface not found in package"))?;
3176 assert_eq!(self.interfaces.len(), unresolved_iface_id.index());
3177 self.interfaces.push(Some(iface_id));
3178 }
3179 for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) {
3180 assert!(
3181 interface_to_package.get(&id).is_none(),
3182 "found foreign interface after local interface"
3183 );
3184 }
3185 Ok(())
3186 }
3187
3188 fn process_foreign_worlds(
3189 &mut self,
3190 unresolved: &UnresolvedPackage,
3191 world_to_package: &HashMap<WorldId, (&PackageName, &String, Span, &Vec<Stability>)>,
3192 resolve: &mut Resolve,
3193 parent_pkg_id: &PackageId,
3194 ) -> Result<(), anyhow::Error> {
3195 for (unresolved_world_id, unresolved_world) in unresolved.worlds.iter() {
3196 let (pkg_name, world, span, stabilities) =
3197 match world_to_package.get(&unresolved_world_id) {
3198 Some(items) => *items,
3199 None => break,
3202 };
3203
3204 let pkgid = resolve
3205 .package_names
3206 .get(pkg_name)
3207 .copied()
3208 .ok_or_else(|| Error::new(span, "package not found"))?;
3209 let pkg = &resolve.packages[pkgid];
3210 let world_span = unresolved_world.span;
3211
3212 let mut enabled = false;
3213 for stability in stabilities {
3214 if resolve.include_stability(stability, parent_pkg_id, world_span)? {
3215 enabled = true;
3216 break;
3217 }
3218 }
3219
3220 if !enabled {
3221 self.worlds.push(None);
3222 continue;
3223 }
3224
3225 let world_id = pkg
3226 .worlds
3227 .get(world)
3228 .copied()
3229 .ok_or_else(|| Error::new(world_span, "world not found in package"))?;
3230 assert_eq!(self.worlds.len(), unresolved_world_id.index());
3231 self.worlds.push(Some(world_id));
3232 }
3233 for (id, _) in unresolved.worlds.iter().skip(self.worlds.len()) {
3234 assert!(
3235 world_to_package.get(&id).is_none(),
3236 "found foreign world after local world"
3237 );
3238 }
3239 Ok(())
3240 }
3241
3242 fn process_foreign_types(
3243 &mut self,
3244 unresolved: &UnresolvedPackage,
3245 pkgid: PackageId,
3246 resolve: &mut Resolve,
3247 ) -> Result<(), anyhow::Error> {
3248 for (unresolved_type_id, unresolved_ty) in unresolved.types.iter() {
3249 match unresolved_ty.kind {
3253 TypeDefKind::Unknown => {}
3254 _ => break,
3255 }
3256
3257 let span = unresolved_ty.span;
3258 if !resolve.include_type(unresolved_ty, pkgid, span)? {
3259 self.types.push(None);
3260 continue;
3261 }
3262
3263 let unresolved_iface_id = match unresolved_ty.owner {
3264 TypeOwner::Interface(id) => id,
3265 _ => unreachable!(),
3266 };
3267 let iface_id = self.map_interface(unresolved_iface_id, Default::default())?;
3268 let name = unresolved_ty.name.as_ref().unwrap();
3269 let span = unresolved.unknown_type_spans[unresolved_type_id.index()];
3270 let type_id = *resolve.interfaces[iface_id]
3271 .types
3272 .get(name)
3273 .ok_or_else(|| {
3274 Error::new(span, format!("type `{name}` not defined in interface"))
3275 })?;
3276 assert_eq!(self.types.len(), unresolved_type_id.index());
3277 self.types.push(Some(type_id));
3278 }
3279 for (_, ty) in unresolved.types.iter().skip(self.types.len()) {
3280 if let TypeDefKind::Unknown = ty.kind {
3281 panic!("unknown type after defined type");
3282 }
3283 }
3284 Ok(())
3285 }
3286
3287 fn update_typedef(
3288 &mut self,
3289 resolve: &mut Resolve,
3290 ty: &mut TypeDef,
3291 span: Span,
3292 ) -> Result<()> {
3293 use crate::TypeDefKind::*;
3296 match &mut ty.kind {
3297 Handle(handle) => match handle {
3298 crate::Handle::Own(ty) | crate::Handle::Borrow(ty) => {
3299 self.update_type_id(ty, span)?
3300 }
3301 },
3302 Resource => {}
3303 Record(r) => {
3304 for field in r.fields.iter_mut() {
3305 self.update_ty(resolve, &mut field.ty, span)
3306 .with_context(|| format!("failed to update field `{}`", field.name))?;
3307 }
3308 }
3309 Tuple(t) => {
3310 for ty in t.types.iter_mut() {
3311 self.update_ty(resolve, ty, span)?;
3312 }
3313 }
3314 Variant(v) => {
3315 for case in v.cases.iter_mut() {
3316 if let Some(t) = &mut case.ty {
3317 self.update_ty(resolve, t, span)?;
3318 }
3319 }
3320 }
3321 Option(t)
3322 | List(t, ..)
3323 | FixedLengthList(t, ..)
3324 | Future(Some(t))
3325 | Stream(Some(t)) => self.update_ty(resolve, t, span)?,
3326 Map(k, v) => {
3327 self.update_ty(resolve, k, span)?;
3328 self.update_ty(resolve, v, span)?;
3329 }
3330 Result(r) => {
3331 if let Some(ty) = &mut r.ok {
3332 self.update_ty(resolve, ty, span)?;
3333 }
3334 if let Some(ty) = &mut r.err {
3335 self.update_ty(resolve, ty, span)?;
3336 }
3337 }
3338
3339 Type(crate::Type::Id(id)) => self.update_type_id(id, span)?,
3344 Type(_) => {}
3345
3346 Flags(_) | Enum(_) | Future(None) | Stream(None) => {}
3348
3349 Unknown => unreachable!(),
3350 }
3351
3352 Ok(())
3353 }
3354
3355 fn update_ty(&mut self, resolve: &mut Resolve, ty: &mut Type, span: Span) -> Result<()> {
3356 let id = match ty {
3357 Type::Id(id) => id,
3358 _ => return Ok(()),
3359 };
3360 self.update_type_id(id, span)?;
3361
3362 let mut cur = *id;
3367 let points_to_resource = loop {
3368 match resolve.types[cur].kind {
3369 TypeDefKind::Type(Type::Id(id)) => cur = id,
3370 TypeDefKind::Resource => break true,
3371 _ => break false,
3372 }
3373 };
3374
3375 if points_to_resource {
3376 *id = *self.own_handles.entry(*id).or_insert_with(|| {
3377 resolve.types.alloc(TypeDef {
3378 name: None,
3379 owner: TypeOwner::None,
3380 kind: TypeDefKind::Handle(Handle::Own(*id)),
3381 docs: Default::default(),
3382 stability: Default::default(),
3383 span: Default::default(),
3384 })
3385 });
3386 }
3387 Ok(())
3388 }
3389
3390 fn update_type_id(&self, id: &mut TypeId, span: Span) -> Result<()> {
3391 *id = self.map_type(*id, span)?;
3392 Ok(())
3393 }
3394
3395 fn update_interface(&mut self, resolve: &mut Resolve, iface: &mut Interface) -> Result<()> {
3396 iface.types.retain(|_, ty| self.types[ty.index()].is_some());
3397 let iface_pkg_id = iface.package.as_ref().unwrap_or_else(|| {
3398 panic!(
3399 "unexpectedly missing package on interface [{}]",
3400 iface
3401 .name
3402 .as_ref()
3403 .map(String::as_str)
3404 .unwrap_or("<unknown>"),
3405 )
3406 });
3407
3408 for (_name, ty) in iface.types.iter_mut() {
3411 self.update_type_id(ty, iface.span)?;
3412 }
3413 for (func_name, func) in iface.functions.iter_mut() {
3414 let span = func.span;
3415 if !resolve
3416 .include_stability(&func.stability, iface_pkg_id, span)
3417 .with_context(|| {
3418 format!(
3419 "failed to process feature gate for function [{func_name}] in package [{}]",
3420 resolve.packages[*iface_pkg_id].name,
3421 )
3422 })?
3423 {
3424 continue;
3425 }
3426 self.update_function(resolve, func, span)
3427 .with_context(|| format!("failed to update function `{}`", func.name))?;
3428 }
3429
3430 for (name, func) in mem::take(&mut iface.functions) {
3433 if resolve.include_stability(&func.stability, iface_pkg_id, func.span)? {
3434 iface.functions.insert(name, func);
3435 }
3436 }
3437
3438 Ok(())
3439 }
3440
3441 fn update_function(
3442 &mut self,
3443 resolve: &mut Resolve,
3444 func: &mut Function,
3445 span: Span,
3446 ) -> Result<()> {
3447 if let Some(id) = func.kind.resource_mut() {
3448 self.update_type_id(id, span)?;
3449 }
3450 for param in func.params.iter_mut() {
3451 self.update_ty(resolve, &mut param.ty, span)?;
3452 }
3453 if let Some(ty) = &mut func.result {
3454 self.update_ty(resolve, ty, span)?;
3455 }
3456
3457 if let Some(ty) = &func.result {
3458 if self.type_has_borrow(resolve, ty) {
3459 bail!(Error::new(
3460 span,
3461 format!(
3462 "function returns a type which contains \
3463 a `borrow<T>` which is not supported"
3464 )
3465 ))
3466 }
3467 }
3468
3469 Ok(())
3470 }
3471
3472 fn update_world(
3473 &mut self,
3474 world: &mut World,
3475 resolve: &mut Resolve,
3476 pkg_id: &PackageId,
3477 ) -> Result<()> {
3478 let imports = mem::take(&mut world.imports).into_iter().map(|p| (p, true));
3482 let exports = mem::take(&mut world.exports)
3483 .into_iter()
3484 .map(|p| (p, false));
3485 for ((mut name, mut item), import) in imports.chain(exports) {
3486 let span = item.span();
3487 if let WorldItem::Type { id, .. } = &mut item {
3490 *id = self.map_type(*id, span)?;
3491 }
3492 let stability = item.stability(resolve);
3493 if !resolve
3494 .include_stability(stability, pkg_id, span)
3495 .with_context(|| format!("failed to process world item in `{}`", world.name))?
3496 {
3497 continue;
3498 }
3499 self.update_world_key(&mut name, span)?;
3500 match &mut item {
3501 WorldItem::Interface { id, .. } => {
3502 *id = self.map_interface(*id, span)?;
3503 }
3504 WorldItem::Function(f) => {
3505 self.update_function(resolve, f, span)?;
3506 }
3507 WorldItem::Type { .. } => {
3508 }
3510 }
3511
3512 let dst = if import {
3513 &mut world.imports
3514 } else {
3515 &mut world.exports
3516 };
3517 let prev = dst.insert(name, item);
3518 assert!(prev.is_none());
3519 }
3520
3521 Ok(())
3522 }
3523
3524 fn process_world_includes(
3525 &self,
3526 id: WorldId,
3527 resolve: &mut Resolve,
3528 pkg_id: &PackageId,
3529 ) -> Result<()> {
3530 let world = &mut resolve.worlds[id];
3531 let includes = mem::take(&mut world.includes);
3534 for include in includes {
3535 if !resolve
3536 .include_stability(&include.stability, pkg_id, include.span)
3537 .with_context(|| {
3538 format!(
3539 "failed to process feature gate for included world [{}] in package [{}]",
3540 resolve.worlds[include.id].name.as_str(),
3541 resolve.packages[*pkg_id].name
3542 )
3543 })?
3544 {
3545 continue;
3546 }
3547 self.resolve_include(
3548 id,
3549 include.id,
3550 &include.names,
3551 include.span,
3552 pkg_id,
3553 resolve,
3554 )?;
3555 }
3556
3557 Self::validate_world_case_insensitive_names(resolve, id)?;
3559
3560 Ok(())
3561 }
3562
3563 fn validate_world_case_insensitive_names(resolve: &Resolve, world_id: WorldId) -> Result<()> {
3567 let world = &resolve.worlds[world_id];
3568
3569 let validate_names = |items: &IndexMap<WorldKey, WorldItem>,
3571 item_type: &str|
3572 -> Result<()> {
3573 let mut seen_lowercase: HashMap<String, String> = HashMap::new();
3574
3575 for key in items.keys() {
3576 if let WorldKey::Name(name) = key {
3578 let lowercase_name = name.to_lowercase();
3579
3580 if let Some(existing_name) = seen_lowercase.get(&lowercase_name) {
3581 if existing_name != name {
3584 bail!(
3585 "{item_type} `{name}` conflicts with {item_type} `{existing_name}` \
3586 (kebab-case identifiers are case-insensitive)"
3587 );
3588 }
3589 }
3590
3591 seen_lowercase.insert(lowercase_name, name.clone());
3592 }
3593 }
3594
3595 Ok(())
3596 };
3597
3598 validate_names(&world.imports, "import")
3599 .with_context(|| format!("failed to validate imports in world `{}`", world.name))?;
3600 validate_names(&world.exports, "export")
3601 .with_context(|| format!("failed to validate exports in world `{}`", world.name))?;
3602
3603 Ok(())
3604 }
3605
3606 fn update_world_key(&self, key: &mut WorldKey, span: Span) -> Result<()> {
3607 match key {
3608 WorldKey::Name(_) => {}
3609 WorldKey::Interface(id) => {
3610 *id = self.map_interface(*id, span)?;
3611 }
3612 }
3613 Ok(())
3614 }
3615
3616 fn resolve_include(
3617 &self,
3618 id: WorldId,
3619 include_world_id_orig: WorldId,
3620 names: &[IncludeName],
3621 span: Span,
3622 pkg_id: &PackageId,
3623 resolve: &mut Resolve,
3624 ) -> Result<()> {
3625 let world = &resolve.worlds[id];
3626 let include_world_id = self.map_world(include_world_id_orig, span)?;
3627 let include_world = resolve.worlds[include_world_id].clone();
3628 let mut names_ = names.to_owned();
3629 let is_external_include = world.package != include_world.package;
3630
3631 for import in include_world.imports.iter() {
3633 self.remove_matching_name(import, &mut names_);
3634 }
3635 for export in include_world.exports.iter() {
3636 self.remove_matching_name(export, &mut names_);
3637 }
3638 if !names_.is_empty() {
3639 bail!(Error::new(
3640 span,
3641 format!(
3642 "no import or export kebab-name `{}`. Note that an ID does not support renaming",
3643 names_[0].name
3644 ),
3645 ));
3646 }
3647
3648 let mut maps = Default::default();
3649 let mut cloner = clone::Cloner::new(
3650 resolve,
3651 &mut maps,
3652 TypeOwner::World(if is_external_include {
3653 include_world_id
3654 } else {
3655 include_world_id
3656 }),
3658 TypeOwner::World(id),
3659 );
3660 cloner.new_package = Some(*pkg_id);
3661
3662 for import in include_world.imports.iter() {
3664 self.resolve_include_item(
3665 &mut cloner,
3666 names,
3667 |resolve| &mut resolve.worlds[id].imports,
3668 import,
3669 span,
3670 "import",
3671 is_external_include,
3672 )?;
3673 }
3674
3675 for export in include_world.exports.iter() {
3676 self.resolve_include_item(
3677 &mut cloner,
3678 names,
3679 |resolve| &mut resolve.worlds[id].exports,
3680 export,
3681 span,
3682 "export",
3683 is_external_include,
3684 )?;
3685 }
3686 Ok(())
3687 }
3688
3689 fn resolve_include_item(
3690 &self,
3691 cloner: &mut clone::Cloner<'_>,
3692 names: &[IncludeName],
3693 get_items: impl Fn(&mut Resolve) -> &mut IndexMap<WorldKey, WorldItem>,
3694 item: (&WorldKey, &WorldItem),
3695 span: Span,
3696 item_type: &str,
3697 is_external_include: bool,
3698 ) -> Result<()> {
3699 match item.0 {
3700 WorldKey::Name(n) => {
3701 let n = names
3702 .into_iter()
3703 .find_map(|include_name| rename(n, include_name))
3704 .unwrap_or(n.clone());
3705
3706 let mut new_item = item.1.clone();
3712 let key = WorldKey::Name(n.clone());
3713 cloner.world_item(&key, &mut new_item);
3714 match &mut new_item {
3715 WorldItem::Function(f) => f.name = n.clone(),
3716 WorldItem::Type { id, .. } => cloner.resolve.types[*id].name = Some(n.clone()),
3717 WorldItem::Interface { .. } => {}
3718 }
3719
3720 let prev = get_items(cloner.resolve).insert(key, new_item);
3721 if prev.is_some() {
3722 bail!(Error::new(
3723 span,
3724 format!("{item_type} of `{n}` shadows previously {item_type}ed items"),
3725 ))
3726 }
3727 }
3728 key @ WorldKey::Interface(_) => {
3729 let prev = get_items(cloner.resolve)
3730 .entry(key.clone())
3731 .or_insert(item.1.clone());
3732 match (&item.1, prev) {
3733 (
3734 WorldItem::Interface {
3735 id: aid,
3736 stability: astability,
3737 ..
3738 },
3739 WorldItem::Interface {
3740 id: bid,
3741 stability: bstability,
3742 ..
3743 },
3744 ) => {
3745 assert_eq!(*aid, *bid);
3746 merge_include_stability(astability, bstability, is_external_include)?;
3747 }
3748 (WorldItem::Interface { .. }, _) => unreachable!(),
3749 (WorldItem::Function(_), _) => unreachable!(),
3750 (WorldItem::Type { .. }, _) => unreachable!(),
3751 }
3752 }
3753 };
3754
3755 Ok(())
3756 }
3757
3758 fn remove_matching_name(&self, item: (&WorldKey, &WorldItem), names: &mut Vec<IncludeName>) {
3759 match item.0 {
3760 WorldKey::Name(n) => {
3761 names.retain(|name| rename(n, name).is_none());
3762 }
3763 _ => {}
3764 }
3765 }
3766
3767 fn type_has_borrow(&mut self, resolve: &Resolve, ty: &Type) -> bool {
3768 let id = match ty {
3769 Type::Id(id) => *id,
3770 _ => return false,
3771 };
3772
3773 if let Some(Some(has_borrow)) = self.type_has_borrow.get(id.index()) {
3774 return *has_borrow;
3775 }
3776
3777 let result = self.typedef_has_borrow(resolve, &resolve.types[id]);
3778 if self.type_has_borrow.len() <= id.index() {
3779 self.type_has_borrow.resize(id.index() + 1, None);
3780 }
3781 self.type_has_borrow[id.index()] = Some(result);
3782 result
3783 }
3784
3785 fn typedef_has_borrow(&mut self, resolve: &Resolve, ty: &TypeDef) -> bool {
3786 match &ty.kind {
3787 TypeDefKind::Type(t) => self.type_has_borrow(resolve, t),
3788 TypeDefKind::Variant(v) => v
3789 .cases
3790 .iter()
3791 .filter_map(|case| case.ty.as_ref())
3792 .any(|ty| self.type_has_borrow(resolve, ty)),
3793 TypeDefKind::Handle(Handle::Borrow(_)) => true,
3794 TypeDefKind::Handle(Handle::Own(_)) => false,
3795 TypeDefKind::Resource => false,
3796 TypeDefKind::Record(r) => r
3797 .fields
3798 .iter()
3799 .any(|case| self.type_has_borrow(resolve, &case.ty)),
3800 TypeDefKind::Flags(_) => false,
3801 TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.type_has_borrow(resolve, t)),
3802 TypeDefKind::Enum(_) => false,
3803 TypeDefKind::List(ty)
3804 | TypeDefKind::FixedLengthList(ty, ..)
3805 | TypeDefKind::Future(Some(ty))
3806 | TypeDefKind::Stream(Some(ty))
3807 | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty),
3808 TypeDefKind::Map(k, v) => {
3809 self.type_has_borrow(resolve, k) || self.type_has_borrow(resolve, v)
3810 }
3811 TypeDefKind::Result(r) => [&r.ok, &r.err]
3812 .iter()
3813 .filter_map(|t| t.as_ref())
3814 .any(|t| self.type_has_borrow(resolve, t)),
3815 TypeDefKind::Future(None) | TypeDefKind::Stream(None) => false,
3816 TypeDefKind::Unknown => unreachable!(),
3817 }
3818 }
3819}
3820
3821struct MergeMap<'a> {
3822 package_map: HashMap<PackageId, PackageId>,
3825
3826 interface_map: HashMap<InterfaceId, InterfaceId>,
3829
3830 type_map: HashMap<TypeId, TypeId>,
3833
3834 world_map: HashMap<WorldId, WorldId>,
3837
3838 interfaces_to_add: Vec<(String, PackageId, InterfaceId)>,
3846 worlds_to_add: Vec<(String, PackageId, WorldId)>,
3847
3848 from: &'a Resolve,
3850
3851 into: &'a Resolve,
3853}
3854
3855impl<'a> MergeMap<'a> {
3856 fn new(from: &'a Resolve, into: &'a Resolve) -> MergeMap<'a> {
3857 MergeMap {
3858 package_map: Default::default(),
3859 interface_map: Default::default(),
3860 type_map: Default::default(),
3861 world_map: Default::default(),
3862 interfaces_to_add: Default::default(),
3863 worlds_to_add: Default::default(),
3864 from,
3865 into,
3866 }
3867 }
3868
3869 fn build(&mut self) -> Result<()> {
3870 for from_id in self.from.topological_packages() {
3871 let from = &self.from.packages[from_id];
3872 let into_id = match self.into.package_names.get(&from.name) {
3873 Some(id) => *id,
3874
3875 None => {
3878 log::trace!("adding unique package {}", from.name);
3879 continue;
3880 }
3881 };
3882 log::trace!("merging duplicate package {}", from.name);
3883
3884 self.build_package(from_id, into_id).with_context(|| {
3885 format!("failed to merge package `{}` into existing copy", from.name)
3886 })?;
3887 }
3888
3889 Ok(())
3890 }
3891
3892 fn build_package(&mut self, from_id: PackageId, into_id: PackageId) -> Result<()> {
3893 let prev = self.package_map.insert(from_id, into_id);
3894 assert!(prev.is_none());
3895
3896 let from = &self.from.packages[from_id];
3897 let into = &self.into.packages[into_id];
3898
3899 for (name, from_interface_id) in from.interfaces.iter() {
3903 let into_interface_id = match into.interfaces.get(name) {
3904 Some(id) => *id,
3905 None => {
3906 log::trace!("adding unique interface {name}");
3907 self.interfaces_to_add
3908 .push((name.clone(), into_id, *from_interface_id));
3909 continue;
3910 }
3911 };
3912
3913 log::trace!("merging duplicate interfaces {name}");
3914 self.build_interface(*from_interface_id, into_interface_id)
3915 .with_context(|| format!("failed to merge interface `{name}`"))?;
3916 }
3917
3918 for (name, from_world_id) in from.worlds.iter() {
3919 let into_world_id = match into.worlds.get(name) {
3920 Some(id) => *id,
3921 None => {
3922 log::trace!("adding unique world {name}");
3923 self.worlds_to_add
3924 .push((name.clone(), into_id, *from_world_id));
3925 continue;
3926 }
3927 };
3928
3929 log::trace!("merging duplicate worlds {name}");
3930 self.build_world(*from_world_id, into_world_id)
3931 .with_context(|| format!("failed to merge world `{name}`"))?;
3932 }
3933
3934 Ok(())
3935 }
3936
3937 fn build_interface(&mut self, from_id: InterfaceId, into_id: InterfaceId) -> Result<()> {
3938 let prev = self.interface_map.insert(from_id, into_id);
3939 assert!(prev.is_none());
3940
3941 let from_interface = &self.from.interfaces[from_id];
3942 let into_interface = &self.into.interfaces[into_id];
3943
3944 for (name, from_type_id) in from_interface.types.iter() {
3958 let into_type_id = *into_interface
3959 .types
3960 .get(name)
3961 .ok_or_else(|| anyhow!("expected type `{name}` to be present"))?;
3962 let prev = self.type_map.insert(*from_type_id, into_type_id);
3963 assert!(prev.is_none());
3964
3965 self.build_type_id(*from_type_id, into_type_id)
3966 .with_context(|| format!("mismatch in type `{name}`"))?;
3967 }
3968
3969 for (name, from_func) in from_interface.functions.iter() {
3970 let into_func = match into_interface.functions.get(name) {
3971 Some(func) => func,
3972 None => bail!("expected function `{name}` to be present"),
3973 };
3974 self.build_function(from_func, into_func)
3975 .with_context(|| format!("mismatch in function `{name}`"))?;
3976 }
3977
3978 Ok(())
3979 }
3980
3981 fn build_type_id(&mut self, from_id: TypeId, into_id: TypeId) -> Result<()> {
3982 let _ = from_id;
3986 let _ = into_id;
3987 Ok(())
3988 }
3989
3990 fn build_type(&mut self, from_ty: &Type, into_ty: &Type) -> Result<()> {
3991 match (from_ty, into_ty) {
3992 (Type::Id(from), Type::Id(into)) => {
3993 self.build_type_id(*from, *into)?;
3994 }
3995 (from, into) if from != into => bail!("different kinds of types"),
3996 _ => {}
3997 }
3998 Ok(())
3999 }
4000
4001 fn build_function(&mut self, from_func: &Function, into_func: &Function) -> Result<()> {
4002 if from_func.name != into_func.name {
4003 bail!(
4004 "different function names `{}` and `{}`",
4005 from_func.name,
4006 into_func.name
4007 );
4008 }
4009 match (&from_func.kind, &into_func.kind) {
4010 (FunctionKind::Freestanding, FunctionKind::Freestanding) => {}
4011 (FunctionKind::AsyncFreestanding, FunctionKind::AsyncFreestanding) => {}
4012
4013 (FunctionKind::Method(from), FunctionKind::Method(into))
4014 | (FunctionKind::Static(from), FunctionKind::Static(into))
4015 | (FunctionKind::AsyncMethod(from), FunctionKind::AsyncMethod(into))
4016 | (FunctionKind::AsyncStatic(from), FunctionKind::AsyncStatic(into))
4017 | (FunctionKind::Constructor(from), FunctionKind::Constructor(into)) => {
4018 self.build_type_id(*from, *into)
4019 .context("different function kind types")?;
4020 }
4021
4022 (FunctionKind::Method(_), _)
4023 | (FunctionKind::Constructor(_), _)
4024 | (FunctionKind::Static(_), _)
4025 | (FunctionKind::Freestanding, _)
4026 | (FunctionKind::AsyncFreestanding, _)
4027 | (FunctionKind::AsyncMethod(_), _)
4028 | (FunctionKind::AsyncStatic(_), _) => {
4029 bail!("different function kind types")
4030 }
4031 }
4032
4033 if from_func.params.len() != into_func.params.len() {
4034 bail!("different number of function parameters");
4035 }
4036 for (from_param, into_param) in from_func.params.iter().zip(&into_func.params) {
4037 if from_param.name != into_param.name {
4038 bail!(
4039 "different function parameter names: {} != {}",
4040 from_param.name,
4041 into_param.name
4042 );
4043 }
4044 self.build_type(&from_param.ty, &into_param.ty)
4045 .with_context(|| {
4046 format!(
4047 "different function parameter types for `{}`",
4048 from_param.name
4049 )
4050 })?;
4051 }
4052 match (&from_func.result, &into_func.result) {
4053 (Some(from_ty), Some(into_ty)) => {
4054 self.build_type(from_ty, into_ty)
4055 .context("different function result types")?;
4056 }
4057 (None, None) => {}
4058 (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
4059 }
4060 Ok(())
4061 }
4062
4063 fn build_world(&mut self, from_id: WorldId, into_id: WorldId) -> Result<()> {
4064 let prev = self.world_map.insert(from_id, into_id);
4065 assert!(prev.is_none());
4066
4067 let from_world = &self.from.worlds[from_id];
4068 let into_world = &self.into.worlds[into_id];
4069
4070 if from_world.imports.len() != into_world.imports.len() {
4079 bail!("world contains different number of imports than expected");
4080 }
4081 if from_world.exports.len() != into_world.exports.len() {
4082 bail!("world contains different number of exports than expected");
4083 }
4084
4085 for (from_name, from) in from_world.imports.iter() {
4086 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4087 let name_str = self.from.name_world_key(from_name);
4088 let into = into_world
4089 .imports
4090 .get(&into_name)
4091 .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?;
4092 self.match_world_item(from, into)
4093 .with_context(|| format!("import `{name_str}` didn't match target world"))?;
4094 }
4095
4096 for (from_name, from) in from_world.exports.iter() {
4097 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4098 let name_str = self.from.name_world_key(from_name);
4099 let into = into_world
4100 .exports
4101 .get(&into_name)
4102 .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?;
4103 self.match_world_item(from, into)
4104 .with_context(|| format!("export `{name_str}` didn't match target world"))?;
4105 }
4106
4107 Ok(())
4108 }
4109
4110 fn map_name(
4111 from_name: &WorldKey,
4112 interface_map: &HashMap<InterfaceId, InterfaceId>,
4113 ) -> WorldKey {
4114 match from_name {
4115 WorldKey::Name(s) => WorldKey::Name(s.clone()),
4116 WorldKey::Interface(id) => {
4117 WorldKey::Interface(interface_map.get(id).copied().unwrap_or(*id))
4118 }
4119 }
4120 }
4121
4122 fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> Result<()> {
4123 match (from, into) {
4124 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
4125 match (
4126 &self.from.interfaces[*from].name,
4127 &self.into.interfaces[*into].name,
4128 ) {
4129 (None, None) => self.build_interface(*from, *into)?,
4133
4134 _ => {
4139 if self.interface_map.get(from) != Some(into) {
4140 bail!("interfaces are not the same");
4141 }
4142 }
4143 }
4144 }
4145 (WorldItem::Function(from), WorldItem::Function(into)) => {
4146 let _ = (from, into);
4147 }
4150 (WorldItem::Type { id: from, .. }, WorldItem::Type { id: into, .. }) => {
4151 let prev = self.type_map.insert(*from, *into);
4154 assert!(prev.is_none());
4155 }
4156
4157 (WorldItem::Interface { .. }, _)
4158 | (WorldItem::Function(_), _)
4159 | (WorldItem::Type { .. }, _) => {
4160 bail!("world items do not have the same type")
4161 }
4162 }
4163 Ok(())
4164 }
4165}
4166
4167fn update_stability(from: &Stability, into: &mut Stability) -> Result<()> {
4173 if from == into || from.is_unknown() {
4176 return Ok(());
4177 }
4178 if into.is_unknown() {
4181 *into = from.clone();
4182 return Ok(());
4183 }
4184
4185 bail!("mismatch in stability from '{:?}' to '{:?}'", from, into)
4188}
4189
4190fn merge_include_stability(
4191 from: &Stability,
4192 into: &mut Stability,
4193 is_external_include: bool,
4194) -> Result<()> {
4195 if is_external_include && from.is_stable() {
4196 log::trace!("dropped stability from external package");
4197 *into = Stability::Unknown;
4198 return Ok(());
4199 }
4200
4201 return update_stability(from, into);
4202}
4203
4204#[derive(Debug, Clone)]
4217pub struct InvalidTransitiveDependency(String);
4218
4219impl fmt::Display for InvalidTransitiveDependency {
4220 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4221 write!(
4222 f,
4223 "interface `{}` transitively depends on an interface in \
4224 incompatible ways",
4225 self.0
4226 )
4227 }
4228}
4229
4230impl core::error::Error for InvalidTransitiveDependency {}
4231
4232#[cfg(test)]
4233mod tests {
4234 use crate::alloc::string::ToString;
4235 use crate::{Resolve, WorldItem, WorldKey};
4236 use anyhow::Result;
4237
4238 #[test]
4239 fn select_world() -> Result<()> {
4240 let mut resolve = Resolve::default();
4241 resolve.push_str(
4242 "test.wit",
4243 r#"
4244 package foo:bar@0.1.0;
4245
4246 world foo {}
4247 "#,
4248 )?;
4249 resolve.push_str(
4250 "test.wit",
4251 r#"
4252 package foo:baz@0.1.0;
4253
4254 world foo {}
4255 "#,
4256 )?;
4257 resolve.push_str(
4258 "test.wit",
4259 r#"
4260 package foo:baz@0.2.0;
4261
4262 world foo {}
4263 "#,
4264 )?;
4265
4266 let dummy = resolve.push_str(
4267 "test.wit",
4268 r#"
4269 package foo:dummy;
4270
4271 world foo {}
4272 "#,
4273 )?;
4274
4275 assert!(resolve.select_world(&[dummy], None).is_ok());
4276 assert!(resolve.select_world(&[dummy], Some("xx")).is_err());
4277 assert!(resolve.select_world(&[dummy], Some("")).is_err());
4278 assert!(resolve.select_world(&[dummy], Some("foo:bar/foo")).is_ok());
4279 assert!(
4280 resolve
4281 .select_world(&[dummy], Some("foo:bar/foo@0.1.0"))
4282 .is_ok()
4283 );
4284 assert!(resolve.select_world(&[dummy], Some("foo:baz/foo")).is_err());
4285 assert!(
4286 resolve
4287 .select_world(&[dummy], Some("foo:baz/foo@0.1.0"))
4288 .is_ok()
4289 );
4290 assert!(
4291 resolve
4292 .select_world(&[dummy], Some("foo:baz/foo@0.2.0"))
4293 .is_ok()
4294 );
4295 Ok(())
4296 }
4297
4298 #[test]
4301 fn select_world_multiple_packages() -> Result<()> {
4302 use wit_parser::Resolve;
4303
4304 let mut resolve = Resolve::default();
4305
4306 let stuff = resolve.push_str(
4308 "./my-test.wit",
4309 r#"
4310 package test:stuff;
4311
4312 world foo {
4313 // ...
4314 }
4315 "#,
4316 )?;
4317 assert!(resolve.select_world(&[stuff], None).is_ok());
4318 assert!(resolve.select_world(&[stuff], Some("foo")).is_ok());
4319
4320 let empty = resolve.push_str(
4323 "./my-test.wit",
4324 r#"
4325 package test:empty;
4326 "#,
4327 )?;
4328 assert!(resolve.select_world(&[stuff, empty], None).is_err());
4329 assert!(resolve.select_world(&[stuff, empty], Some("foo")).is_err());
4330 assert!(resolve.select_world(&[empty], None).is_err());
4331 assert!(resolve.select_world(&[empty], Some("foo")).is_err());
4332
4333 Ok(())
4334 }
4335
4336 #[test]
4338 fn select_world_versions() -> Result<()> {
4339 use wit_parser::Resolve;
4340
4341 let mut resolve = Resolve::default();
4342
4343 let _id = resolve.push_str(
4344 "./my-test.wit",
4345 r#"
4346 package example:distraction;
4347 "#,
4348 )?;
4349
4350 let versions_1 = resolve.push_str(
4353 "./my-test.wit",
4354 r#"
4355 package example:versions@1.0.0;
4356
4357 world foo { /* ... */ }
4358 "#,
4359 )?;
4360 assert!(resolve.select_world(&[versions_1], Some("foo")).is_ok());
4361 assert!(
4362 resolve
4363 .select_world(&[versions_1], Some("foo@1.0.0"))
4364 .is_err()
4365 );
4366 assert!(
4367 resolve
4368 .select_world(&[versions_1], Some("example:versions/foo"))
4369 .is_ok()
4370 );
4371 assert!(
4372 resolve
4373 .select_world(&[versions_1], Some("example:versions/foo@1.0.0"))
4374 .is_ok()
4375 );
4376
4377 let versions_2 = resolve.push_str(
4380 "./my-test.wit",
4381 r#"
4382 package example:versions@2.0.0;
4383
4384 world foo { /* ... */ }
4385 "#,
4386 )?;
4387 assert!(
4388 resolve
4389 .select_world(&[versions_1, versions_2], Some("foo"))
4390 .is_err()
4391 );
4392 assert!(
4393 resolve
4394 .select_world(&[versions_1, versions_2], Some("foo@1.0.0"))
4395 .is_err()
4396 );
4397 assert!(
4398 resolve
4399 .select_world(&[versions_1, versions_2], Some("foo@2.0.0"))
4400 .is_err()
4401 );
4402 assert!(
4403 resolve
4404 .select_world(&[versions_1, versions_2], Some("example:versions/foo"))
4405 .is_err()
4406 );
4407 assert!(
4408 resolve
4409 .select_world(
4410 &[versions_1, versions_2],
4411 Some("example:versions/foo@1.0.0")
4412 )
4413 .is_ok()
4414 );
4415 assert!(
4416 resolve
4417 .select_world(
4418 &[versions_1, versions_2],
4419 Some("example:versions/foo@2.0.0")
4420 )
4421 .is_ok()
4422 );
4423
4424 Ok(())
4425 }
4426
4427 #[test]
4429 fn select_world_override_qualification() -> Result<()> {
4430 use wit_parser::Resolve;
4431
4432 let mut resolve = Resolve::default();
4433
4434 let other = resolve.push_str(
4435 "./my-test.wit",
4436 r#"
4437 package example:other;
4438
4439 world foo { }
4440 "#,
4441 )?;
4442
4443 let fq = resolve.push_str(
4445 "./my-test.wit",
4446 r#"
4447 package example:fq;
4448
4449 world bar { }
4450 "#,
4451 )?;
4452 assert!(resolve.select_world(&[other, fq], Some("foo")).is_err());
4453 assert!(resolve.select_world(&[other, fq], Some("bar")).is_err());
4454 assert!(
4455 resolve
4456 .select_world(&[other, fq], Some("example:other/foo"))
4457 .is_ok()
4458 );
4459 assert!(
4460 resolve
4461 .select_world(&[other, fq], Some("example:fq/bar"))
4462 .is_ok()
4463 );
4464 assert!(
4465 resolve
4466 .select_world(&[other, fq], Some("example:other/bar"))
4467 .is_err()
4468 );
4469 assert!(
4470 resolve
4471 .select_world(&[other, fq], Some("example:fq/foo"))
4472 .is_err()
4473 );
4474
4475 Ok(())
4476 }
4477
4478 #[test]
4480 fn select_world_fully_qualified() -> Result<()> {
4481 use wit_parser::Resolve;
4482
4483 let mut resolve = Resolve::default();
4484
4485 let distraction = resolve.push_str(
4486 "./my-test.wit",
4487 r#"
4488 package example:distraction;
4489 "#,
4490 )?;
4491
4492 let multiworld = resolve.push_str(
4495 "./my-test.wit",
4496 r#"
4497 package example:multiworld;
4498
4499 world foo { /* ... */ }
4500
4501 world bar { /* ... */ }
4502 "#,
4503 )?;
4504 assert!(
4505 resolve
4506 .select_world(&[distraction, multiworld], None)
4507 .is_err()
4508 );
4509 assert!(
4510 resolve
4511 .select_world(&[distraction, multiworld], Some("foo"))
4512 .is_err()
4513 );
4514 assert!(
4515 resolve
4516 .select_world(&[distraction, multiworld], Some("example:multiworld/foo"))
4517 .is_ok()
4518 );
4519 assert!(
4520 resolve
4521 .select_world(&[distraction, multiworld], Some("bar"))
4522 .is_err()
4523 );
4524 assert!(
4525 resolve
4526 .select_world(&[distraction, multiworld], Some("example:multiworld/bar"))
4527 .is_ok()
4528 );
4529
4530 Ok(())
4531 }
4532
4533 #[test]
4535 fn select_world_packages() -> Result<()> {
4536 use wit_parser::Resolve;
4537
4538 let mut resolve = Resolve::default();
4539
4540 let wit1 = resolve.push_str(
4543 "./my-test.wit",
4544 r#"
4545 package example:wit1;
4546
4547 world foo {
4548 // ...
4549 }
4550 "#,
4551 )?;
4552 assert!(resolve.select_world(&[wit1], None).is_ok());
4553 assert!(resolve.select_world(&[wit1], Some("foo")).is_ok());
4554 assert!(
4555 resolve
4556 .select_world(&[wit1], Some("example:wit1/foo"))
4557 .is_ok()
4558 );
4559 assert!(resolve.select_world(&[wit1], Some("bar")).is_err());
4560 assert!(
4561 resolve
4562 .select_world(&[wit1], Some("example:wit2/foo"))
4563 .is_err()
4564 );
4565
4566 let wit2 = resolve.push_str(
4569 "./my-test.wit",
4570 r#"
4571 package example:wit2;
4572
4573 world foo { /* ... */ }
4574 "#,
4575 )?;
4576 assert!(resolve.select_world(&[wit1, wit2], None).is_err());
4577 assert!(resolve.select_world(&[wit1, wit2], Some("foo")).is_err());
4578 assert!(
4579 resolve
4580 .select_world(&[wit1, wit2], Some("example:wit1/foo"))
4581 .is_ok()
4582 );
4583 assert!(resolve.select_world(&[wit2], None).is_ok());
4584 assert!(resolve.select_world(&[wit2], Some("foo")).is_ok());
4585 assert!(
4586 resolve
4587 .select_world(&[wit2], Some("example:wit1/foo"))
4588 .is_ok()
4589 );
4590 assert!(resolve.select_world(&[wit1, wit2], Some("bar")).is_err());
4591 assert!(
4592 resolve
4593 .select_world(&[wit1, wit2], Some("example:wit2/foo"))
4594 .is_ok()
4595 );
4596 assert!(resolve.select_world(&[wit2], Some("bar")).is_err());
4597 assert!(
4598 resolve
4599 .select_world(&[wit2], Some("example:wit2/foo"))
4600 .is_ok()
4601 );
4602
4603 Ok(())
4604 }
4605
4606 #[test]
4607 fn span_preservation() -> Result<()> {
4608 let mut resolve = Resolve::default();
4609 let pkg = resolve.push_str(
4610 "test.wit",
4611 r#"
4612 package foo:bar;
4613
4614 interface my-iface {
4615 type my-type = u32;
4616 my-func: func();
4617 }
4618
4619 world my-world {
4620 export my-export: func();
4621 }
4622 "#,
4623 )?;
4624
4625 let iface_id = resolve.packages[pkg].interfaces["my-iface"];
4626 assert!(resolve.interfaces[iface_id].span.is_known());
4627
4628 let type_id = resolve.interfaces[iface_id].types["my-type"];
4629 assert!(resolve.types[type_id].span.is_known());
4630
4631 assert!(
4632 resolve.interfaces[iface_id].functions["my-func"]
4633 .span
4634 .is_known()
4635 );
4636
4637 let world_id = resolve.packages[pkg].worlds["my-world"];
4638 assert!(resolve.worlds[world_id].span.is_known());
4639
4640 let WorldItem::Function(f) =
4641 &resolve.worlds[world_id].exports[&WorldKey::Name("my-export".to_string())]
4642 else {
4643 panic!("expected function");
4644 };
4645 assert!(f.span.is_known());
4646
4647 Ok(())
4648 }
4649
4650 #[test]
4651 fn span_preservation_through_merge() -> Result<()> {
4652 let mut resolve1 = Resolve::default();
4653 resolve1.push_str(
4654 "test1.wit",
4655 r#"
4656 package foo:bar;
4657
4658 interface iface1 {
4659 type type1 = u32;
4660 func1: func();
4661 }
4662 "#,
4663 )?;
4664
4665 let mut resolve2 = Resolve::default();
4666 let pkg2 = resolve2.push_str(
4667 "test2.wit",
4668 r#"
4669 package foo:baz;
4670
4671 interface iface2 {
4672 type type2 = string;
4673 func2: func();
4674 }
4675 "#,
4676 )?;
4677
4678 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
4679 let remap = resolve1.merge(resolve2)?;
4680 let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
4681
4682 assert!(resolve1.interfaces[iface2_id].span.is_known());
4683
4684 let type2_id = resolve1.interfaces[iface2_id].types["type2"];
4685 assert!(resolve1.types[type2_id].span.is_known());
4686
4687 assert!(
4688 resolve1.interfaces[iface2_id].functions["func2"]
4689 .span
4690 .is_known()
4691 );
4692
4693 Ok(())
4694 }
4695
4696 #[test]
4697 fn span_preservation_through_include() -> Result<()> {
4698 let mut resolve = Resolve::default();
4699 let pkg = resolve.push_str(
4700 "test.wit",
4701 r#"
4702 package foo:bar;
4703
4704 world base {
4705 export my-func: func();
4706 }
4707
4708 world extended {
4709 include base;
4710 }
4711 "#,
4712 )?;
4713
4714 let base_id = resolve.packages[pkg].worlds["base"];
4715 let extended_id = resolve.packages[pkg].worlds["extended"];
4716
4717 let WorldItem::Function(base_func) =
4718 &resolve.worlds[base_id].exports[&WorldKey::Name("my-func".to_string())]
4719 else {
4720 panic!("expected function");
4721 };
4722 assert!(base_func.span.is_known());
4723
4724 let WorldItem::Function(extended_func) =
4725 &resolve.worlds[extended_id].exports[&WorldKey::Name("my-func".to_string())]
4726 else {
4727 panic!("expected function");
4728 };
4729 assert!(extended_func.span.is_known());
4730
4731 Ok(())
4732 }
4733
4734 #[test]
4735 fn span_preservation_through_include_with_rename() -> Result<()> {
4736 let mut resolve = Resolve::default();
4737 let pkg = resolve.push_str(
4738 "test.wit",
4739 r#"
4740 package foo:bar;
4741
4742 world base {
4743 export original-name: func();
4744 }
4745
4746 world extended {
4747 include base with { original-name as renamed-func }
4748 }
4749 "#,
4750 )?;
4751
4752 let extended_id = resolve.packages[pkg].worlds["extended"];
4753
4754 let WorldItem::Function(f) =
4755 &resolve.worlds[extended_id].exports[&WorldKey::Name("renamed-func".to_string())]
4756 else {
4757 panic!("expected function");
4758 };
4759 assert!(f.span.is_known());
4760
4761 assert!(
4762 !resolve.worlds[extended_id]
4763 .exports
4764 .contains_key(&WorldKey::Name("original-name".to_string()))
4765 );
4766
4767 Ok(())
4768 }
4769
4770 #[test]
4772 fn span_preservation_through_include_reverse_order() -> Result<()> {
4773 let mut resolve = Resolve::default();
4774 let pkg = resolve.push_str(
4775 "test.wit",
4776 r#"
4777 package foo:bar;
4778
4779 world extended {
4780 include base;
4781 }
4782
4783 world base {
4784 export my-func: func();
4785 }
4786 "#,
4787 )?;
4788
4789 let base_id = resolve.packages[pkg].worlds["base"];
4790 let extended_id = resolve.packages[pkg].worlds["extended"];
4791
4792 let WorldItem::Function(base_func) =
4793 &resolve.worlds[base_id].exports[&WorldKey::Name("my-func".to_string())]
4794 else {
4795 panic!("expected function");
4796 };
4797 assert!(base_func.span.is_known());
4798
4799 let WorldItem::Function(extended_func) =
4800 &resolve.worlds[extended_id].exports[&WorldKey::Name("my-func".to_string())]
4801 else {
4802 panic!("expected function");
4803 };
4804 assert!(extended_func.span.is_known());
4805
4806 Ok(())
4807 }
4808
4809 #[test]
4810 fn span_line_numbers() -> Result<()> {
4811 let mut resolve = Resolve::default();
4812 let pkg = resolve.push_source(
4813 "test.wit",
4814 "package foo:bar;
4815
4816interface my-iface {
4817 type my-type = u32;
4818 my-func: func();
4819}
4820
4821world my-world {
4822 export my-export: func();
4823}
4824",
4825 )?;
4826
4827 let iface_id = resolve.packages[pkg].interfaces["my-iface"];
4828 let iface_span = resolve.interfaces[iface_id].span;
4829 let iface_loc = resolve.render_location(iface_span);
4830 assert!(
4831 iface_loc.contains(":3:"),
4832 "interface location was {iface_loc}"
4833 );
4834
4835 let type_id = resolve.interfaces[iface_id].types["my-type"];
4836 let type_span = resolve.types[type_id].span;
4837 let type_loc = resolve.render_location(type_span);
4838 assert!(type_loc.contains(":4:"), "type location was {type_loc}");
4839
4840 let func_span = resolve.interfaces[iface_id].functions["my-func"].span;
4841 let func_loc = resolve.render_location(func_span);
4842 assert!(func_loc.contains(":5:"), "function location was {func_loc}");
4843
4844 let world_id = resolve.packages[pkg].worlds["my-world"];
4845 let world_span = resolve.worlds[world_id].span;
4846 let world_loc = resolve.render_location(world_span);
4847 assert!(world_loc.contains(":8:"), "world location was {world_loc}");
4848
4849 let WorldItem::Function(export_func) =
4850 &resolve.worlds[world_id].exports[&WorldKey::Name("my-export".to_string())]
4851 else {
4852 panic!("expected function");
4853 };
4854 let export_loc = resolve.render_location(export_func.span);
4855 assert!(
4856 export_loc.contains(":9:"),
4857 "export location was {export_loc}"
4858 );
4859
4860 Ok(())
4861 }
4862
4863 #[test]
4864 fn span_line_numbers_through_merge() -> Result<()> {
4865 let mut resolve1 = Resolve::default();
4866 resolve1.push_source(
4867 "first.wit",
4868 "package foo:first;
4869
4870interface iface1 {
4871 func1: func();
4872}
4873",
4874 )?;
4875
4876 let mut resolve2 = Resolve::default();
4877 let pkg2 = resolve2.push_source(
4878 "second.wit",
4879 "package foo:second;
4880
4881interface iface2 {
4882 func2: func();
4883}
4884",
4885 )?;
4886
4887 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
4888 let remap = resolve1.merge(resolve2)?;
4889 let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
4890
4891 let iface2_span = resolve1.interfaces[iface2_id].span;
4892 let iface2_loc = resolve1.render_location(iface2_span);
4893 assert!(
4894 iface2_loc.contains("second.wit"),
4895 "should reference second.wit, got {iface2_loc}"
4896 );
4897 assert!(
4898 iface2_loc.contains(":3:"),
4899 "interface should be on line 3, got {iface2_loc}"
4900 );
4901
4902 let func2_span = resolve1.interfaces[iface2_id].functions["func2"].span;
4903 let func2_loc = resolve1.render_location(func2_span);
4904 assert!(
4905 func2_loc.contains("second.wit"),
4906 "should reference second.wit, got {func2_loc}"
4907 );
4908 assert!(
4909 func2_loc.contains(":4:"),
4910 "function should be on line 4, got {func2_loc}"
4911 );
4912
4913 Ok(())
4914 }
4915
4916 #[test]
4917 fn span_line_numbers_multiple_sources() -> Result<()> {
4918 let mut resolve = Resolve::default();
4919
4920 let pkg1 = resolve.push_source(
4921 "first.wit",
4922 "package test:first;
4923
4924interface first-iface {
4925 first-func: func();
4926}
4927",
4928 )?;
4929
4930 let pkg2 = resolve.push_source(
4931 "second.wit",
4932 "package test:second;
4933
4934interface second-iface {
4935 second-func: func();
4936}
4937",
4938 )?;
4939
4940 let iface1_id = resolve.packages[pkg1].interfaces["first-iface"];
4941 let iface1_span = resolve.interfaces[iface1_id].span;
4942 let iface1_loc = resolve.render_location(iface1_span);
4943 assert!(
4944 iface1_loc.contains("first.wit"),
4945 "should reference first.wit, got {iface1_loc}"
4946 );
4947 assert!(
4948 iface1_loc.contains(":3:"),
4949 "interface should be on line 3, got {iface1_loc}"
4950 );
4951
4952 let func1_span = resolve.interfaces[iface1_id].functions["first-func"].span;
4953 let func1_loc = resolve.render_location(func1_span);
4954 assert!(
4955 func1_loc.contains("first.wit"),
4956 "should reference first.wit, got {func1_loc}"
4957 );
4958 assert!(
4959 func1_loc.contains(":4:"),
4960 "function should be on line 4, got {func1_loc}"
4961 );
4962
4963 let iface2_id = resolve.packages[pkg2].interfaces["second-iface"];
4964 let iface2_span = resolve.interfaces[iface2_id].span;
4965 let iface2_loc = resolve.render_location(iface2_span);
4966 assert!(
4967 iface2_loc.contains("second.wit"),
4968 "should reference second.wit, got {iface2_loc}"
4969 );
4970 assert!(
4971 iface2_loc.contains(":3:"),
4972 "interface should be on line 3, got {iface2_loc}"
4973 );
4974
4975 let func2_span = resolve.interfaces[iface2_id].functions["second-func"].span;
4976 let func2_loc = resolve.render_location(func2_span);
4977 assert!(
4978 func2_loc.contains("second.wit"),
4979 "should reference second.wit, got {func2_loc}"
4980 );
4981 assert!(
4982 func2_loc.contains(":4:"),
4983 "function should be on line 4, got {func2_loc}"
4984 );
4985
4986 Ok(())
4987 }
4988
4989 #[test]
4990 fn span_preservation_for_fields_and_cases() -> Result<()> {
4991 use crate::TypeDefKind;
4992
4993 let mut resolve = Resolve::default();
4994 let pkg = resolve.push_str(
4995 "test.wit",
4996 r#"
4997 package foo:bar;
4998
4999 interface my-iface {
5000 record my-record {
5001 field1: u32,
5002 field2: string,
5003 }
5004
5005 flags my-flags {
5006 flag1,
5007 flag2,
5008 }
5009
5010 variant my-variant {
5011 case1,
5012 case2(u32),
5013 }
5014
5015 enum my-enum {
5016 val1,
5017 val2,
5018 }
5019 }
5020 "#,
5021 )?;
5022
5023 let iface_id = resolve.packages[pkg].interfaces["my-iface"];
5024
5025 let record_id = resolve.interfaces[iface_id].types["my-record"];
5027 let TypeDefKind::Record(record) = &resolve.types[record_id].kind else {
5028 panic!("expected record");
5029 };
5030 assert!(record.fields[0].span.is_known(), "field1 should have span");
5031 assert!(record.fields[1].span.is_known(), "field2 should have span");
5032
5033 let flags_id = resolve.interfaces[iface_id].types["my-flags"];
5035 let TypeDefKind::Flags(flags) = &resolve.types[flags_id].kind else {
5036 panic!("expected flags");
5037 };
5038 assert!(flags.flags[0].span.is_known(), "flag1 should have span");
5039 assert!(flags.flags[1].span.is_known(), "flag2 should have span");
5040
5041 let variant_id = resolve.interfaces[iface_id].types["my-variant"];
5043 let TypeDefKind::Variant(variant) = &resolve.types[variant_id].kind else {
5044 panic!("expected variant");
5045 };
5046 assert!(variant.cases[0].span.is_known(), "case1 should have span");
5047 assert!(variant.cases[1].span.is_known(), "case2 should have span");
5048
5049 let enum_id = resolve.interfaces[iface_id].types["my-enum"];
5051 let TypeDefKind::Enum(e) = &resolve.types[enum_id].kind else {
5052 panic!("expected enum");
5053 };
5054 assert!(e.cases[0].span.is_known(), "val1 should have span");
5055 assert!(e.cases[1].span.is_known(), "val2 should have span");
5056
5057 Ok(())
5058 }
5059
5060 #[test]
5061 fn span_preservation_for_fields_through_merge() -> Result<()> {
5062 use crate::TypeDefKind;
5063
5064 let mut resolve1 = Resolve::default();
5065 resolve1.push_str(
5066 "test1.wit",
5067 r#"
5068 package foo:bar;
5069
5070 interface iface1 {
5071 record rec1 {
5072 f1: u32,
5073 }
5074 }
5075 "#,
5076 )?;
5077
5078 let mut resolve2 = Resolve::default();
5079 let pkg2 = resolve2.push_str(
5080 "test2.wit",
5081 r#"
5082 package foo:baz;
5083
5084 interface iface2 {
5085 record rec2 {
5086 f2: string,
5087 }
5088
5089 variant var2 {
5090 c2,
5091 }
5092 }
5093 "#,
5094 )?;
5095
5096 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5097 let rec2_old_id = resolve2.interfaces[iface2_old_id].types["rec2"];
5098 let var2_old_id = resolve2.interfaces[iface2_old_id].types["var2"];
5099
5100 let remap = resolve1.merge(resolve2)?;
5101
5102 let rec2_id = remap.types[rec2_old_id.index()].unwrap();
5103 let TypeDefKind::Record(record) = &resolve1.types[rec2_id].kind else {
5104 panic!("expected record");
5105 };
5106 assert!(
5107 record.fields[0].span.is_known(),
5108 "field should have span after merge"
5109 );
5110
5111 let var2_id = remap.types[var2_old_id.index()].unwrap();
5112 let TypeDefKind::Variant(variant) = &resolve1.types[var2_id].kind else {
5113 panic!("expected variant");
5114 };
5115 assert!(
5116 variant.cases[0].span.is_known(),
5117 "case should have span after merge"
5118 );
5119
5120 Ok(())
5121 }
5122
5123 #[test]
5124 fn param_spans_point_to_names() -> Result<()> {
5125 let source = "\
5126package foo:bar;
5127
5128interface iface {
5129 my-func: func(a: u32, b: string);
5130}
5131";
5132 let mut resolve = Resolve::default();
5133 let pkg = resolve.push_str("test.wit", source)?;
5134
5135 let iface_id = resolve.packages[pkg].interfaces["iface"];
5136 let func = &resolve.interfaces[iface_id].functions["my-func"];
5137 assert_eq!(func.params.len(), 2);
5138 for param in &func.params {
5139 let start = param.span.start() as usize;
5140 let end = param.span.end() as usize;
5141 let snippet = &source[start..end];
5142 assert_eq!(
5143 snippet, param.name,
5144 "param `{}` span points to {:?}",
5145 param.name, snippet
5146 );
5147 }
5148
5149 Ok(())
5150 }
5151
5152 #[test]
5153 fn param_spans_preserved_through_merge() -> Result<()> {
5154 let mut resolve1 = Resolve::default();
5155 resolve1.push_str(
5156 "test1.wit",
5157 r#"
5158 package foo:bar;
5159
5160 interface iface1 {
5161 f1: func(x: u32);
5162 }
5163 "#,
5164 )?;
5165
5166 let mut resolve2 = Resolve::default();
5167 let pkg2 = resolve2.push_str(
5168 "test2.wit",
5169 r#"
5170 package foo:baz;
5171
5172 interface iface2 {
5173 f2: func(y: string, z: bool);
5174 }
5175 "#,
5176 )?;
5177
5178 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5179
5180 let remap = resolve1.merge(resolve2)?;
5181
5182 let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
5183 let func = &resolve1.interfaces[iface2_id].functions["f2"];
5184 for param in &func.params {
5185 assert!(
5186 param.span.is_known(),
5187 "param `{}` should have span after merge",
5188 param.name
5189 );
5190 }
5191
5192 Ok(())
5193 }
5194}