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.new_package = cloner.resolve.interfaces[new_id].package;
2648 cloner.interface(&mut new_id);
2649
2650 let exports = &mut cloner.resolve.worlds[world].exports;
2654 let (key, prev) = exports.get_index_mut(i).unwrap();
2655 match prev {
2656 WorldItem::Interface { id, .. } => *id = new_id,
2657 _ => unreachable!(),
2658 }
2659
2660 match key {
2661 WorldKey::Interface(_) => {
2667 exports
2668 .replace_index(i, WorldKey::Interface(new_id))
2669 .unwrap();
2670 }
2671
2672 WorldKey::Name(_) => {}
2675 }
2676 }
2677
2678 #[cfg(debug_assertions)]
2679 self.assert_valid();
2680 }
2681}
2682
2683#[derive(Debug)]
2685pub enum WasmImport<'a> {
2686 Func {
2688 interface: Option<&'a WorldKey>,
2693
2694 func: &'a Function,
2696 },
2697
2698 ResourceIntrinsic {
2700 interface: Option<&'a WorldKey>,
2702
2703 resource: TypeId,
2705
2706 intrinsic: ResourceIntrinsic,
2708 },
2709}
2710
2711#[derive(Debug)]
2714pub enum ResourceIntrinsic {
2715 ImportedDrop,
2716 ExportedDrop,
2717 ExportedNew,
2718 ExportedRep,
2719}
2720
2721#[derive(Debug)]
2724pub enum WasmExportKind {
2725 Normal,
2727
2728 PostReturn,
2730
2731 Callback,
2733}
2734
2735#[derive(Debug)]
2738pub enum WasmExport<'a> {
2739 Func {
2741 interface: Option<&'a WorldKey>,
2744
2745 func: &'a Function,
2747
2748 kind: WasmExportKind,
2750 },
2751
2752 ResourceDtor {
2754 interface: &'a WorldKey,
2756 resource: TypeId,
2758 },
2759
2760 Memory,
2762
2763 Initialize,
2765
2766 Realloc,
2768}
2769
2770#[derive(Default)]
2773pub struct Remap {
2774 pub types: Vec<Option<TypeId>>,
2775 pub interfaces: Vec<Option<InterfaceId>>,
2776 pub worlds: Vec<Option<WorldId>>,
2777 pub packages: Vec<PackageId>,
2778
2779 own_handles: HashMap<TypeId, TypeId>,
2789
2790 type_has_borrow: Vec<Option<bool>>,
2791}
2792
2793fn apply_map<T>(map: &[Option<Id<T>>], id: Id<T>, desc: &str, span: Span) -> Result<Id<T>> {
2794 match map.get(id.index()) {
2795 Some(Some(id)) => Ok(*id),
2796 Some(None) => {
2797 let msg = format!(
2798 "found a reference to a {desc} which is excluded \
2799 due to its feature not being activated"
2800 );
2801 Err(Error::new(span, msg).into())
2802 }
2803 None => panic!("request to remap a {desc} that has not yet been registered"),
2804 }
2805}
2806
2807fn rename(original_name: &str, include_name: &IncludeName) -> Option<String> {
2808 if original_name == include_name.name {
2809 return Some(include_name.as_.to_string());
2810 }
2811 let (kind, rest) = original_name.split_once(']')?;
2812 match rest.split_once('.') {
2813 Some((name, rest)) if name == include_name.name => {
2814 Some(format!("{kind}]{}.{rest}", include_name.as_))
2815 }
2816 _ if rest == include_name.name => Some(format!("{kind}]{}", include_name.as_)),
2817 _ => None,
2818 }
2819}
2820
2821impl Remap {
2822 pub fn map_type(&self, id: TypeId, span: Span) -> Result<TypeId> {
2823 apply_map(&self.types, id, "type", span)
2824 }
2825
2826 pub fn map_interface(&self, id: InterfaceId, span: Span) -> Result<InterfaceId> {
2827 apply_map(&self.interfaces, id, "interface", span)
2828 }
2829
2830 pub fn map_world(&self, id: WorldId, span: Span) -> Result<WorldId> {
2831 apply_map(&self.worlds, id, "world", span)
2832 }
2833
2834 fn append(
2835 &mut self,
2836 resolve: &mut Resolve,
2837 unresolved: UnresolvedPackage,
2838 ) -> Result<PackageId> {
2839 let pkgid = resolve.packages.alloc(Package {
2840 name: unresolved.name.clone(),
2841 docs: unresolved.docs.clone(),
2842 interfaces: Default::default(),
2843 worlds: Default::default(),
2844 });
2845 let prev = resolve.package_names.insert(unresolved.name.clone(), pkgid);
2846 if let Some(prev) = prev {
2847 resolve.package_names.insert(unresolved.name.clone(), prev);
2848 bail!(
2849 "attempting to re-add package `{}` when it's already present in this `Resolve`",
2850 unresolved.name,
2851 );
2852 }
2853
2854 self.process_foreign_deps(resolve, pkgid, &unresolved)?;
2855
2856 let foreign_types = self.types.len();
2857 let foreign_interfaces = self.interfaces.len();
2858 let foreign_worlds = self.worlds.len();
2859
2860 for (id, mut ty) in unresolved.types.into_iter().skip(foreign_types) {
2866 let span = ty.span;
2867 if !resolve.include_type(&ty, pkgid, span)? {
2868 self.types.push(None);
2869 continue;
2870 }
2871
2872 self.update_typedef(resolve, &mut ty, span)?;
2873 let new_id = resolve.types.alloc(ty);
2874 assert_eq!(self.types.len(), id.index());
2875
2876 let new_id = match resolve.types[new_id] {
2877 TypeDef {
2882 name: None,
2883 owner: TypeOwner::None,
2884 kind: TypeDefKind::Handle(Handle::Own(id)),
2885 docs: _,
2886 stability: _,
2887 span: _,
2888 } => *self.own_handles.entry(id).or_insert(new_id),
2889
2890 _ => new_id,
2893 };
2894 self.types.push(Some(new_id));
2895 }
2896
2897 for (id, mut iface) in unresolved.interfaces.into_iter().skip(foreign_interfaces) {
2900 let span = iface.span;
2901 if !resolve
2902 .include_stability(&iface.stability, &pkgid, span)
2903 .with_context(|| {
2904 format!(
2905 "failed to process feature gate for interface [{}] in package [{}]",
2906 iface
2907 .name
2908 .as_ref()
2909 .map(String::as_str)
2910 .unwrap_or("<unknown>"),
2911 resolve.packages[pkgid].name,
2912 )
2913 })?
2914 {
2915 self.interfaces.push(None);
2916 continue;
2917 }
2918 assert!(iface.package.is_none());
2919 iface.package = Some(pkgid);
2920 self.update_interface(resolve, &mut iface)?;
2921 let new_id = resolve.interfaces.alloc(iface);
2922 assert_eq!(self.interfaces.len(), id.index());
2923 self.interfaces.push(Some(new_id));
2924 }
2925
2926 for id in self.types.iter().skip(foreign_types) {
2929 let id = match id {
2930 Some(id) => *id,
2931 None => continue,
2932 };
2933 let span = resolve.types[id].span;
2934 match &mut resolve.types[id].owner {
2935 TypeOwner::Interface(iface_id) => {
2936 *iface_id = self.map_interface(*iface_id, span)
2937 .with_context(|| {
2938 "this type is not gated by a feature but its interface is gated by a feature"
2939 })?;
2940 }
2941 TypeOwner::World(_) | TypeOwner::None => {}
2942 }
2943 }
2944
2945 for (id, mut world) in unresolved.worlds.into_iter().skip(foreign_worlds) {
2953 let world_span = world.span;
2954 if !resolve
2955 .include_stability(&world.stability, &pkgid, world_span)
2956 .with_context(|| {
2957 format!(
2958 "failed to process feature gate for world [{}] in package [{}]",
2959 world.name, resolve.packages[pkgid].name,
2960 )
2961 })?
2962 {
2963 self.worlds.push(None);
2964 continue;
2965 }
2966 self.update_world(&mut world, resolve, &pkgid)?;
2967
2968 let new_id = resolve.worlds.alloc(world);
2969 assert_eq!(self.worlds.len(), id.index());
2970 self.worlds.push(Some(new_id));
2971 }
2972
2973 for id in self.types.iter().skip(foreign_types) {
2975 let id = match id {
2976 Some(id) => *id,
2977 None => continue,
2978 };
2979 let span = resolve.types[id].span;
2980 match &mut resolve.types[id].owner {
2981 TypeOwner::World(world_id) => {
2982 *world_id = self.map_world(*world_id, span)
2983 .with_context(|| {
2984 "this type is not gated by a feature but its interface is gated by a feature"
2985 })?;
2986 }
2987 TypeOwner::Interface(_) | TypeOwner::None => {}
2988 }
2989 }
2990
2991 for id in self.worlds.iter().skip(foreign_worlds) {
3008 let Some(id) = *id else {
3009 continue;
3010 };
3011 self.process_world_includes(id, resolve, &pkgid)?;
3012
3013 let world_span = resolve.worlds[id].span;
3014 resolve.elaborate_world(id).with_context(|| {
3015 Error::new(
3016 world_span,
3017 format!(
3018 "failed to elaborate world imports/exports of `{}`",
3019 resolve.worlds[id].name
3020 ),
3021 )
3022 })?;
3023 }
3024
3025 for id in self.interfaces.iter().skip(foreign_interfaces) {
3027 let id = match id {
3028 Some(id) => *id,
3029 None => continue,
3030 };
3031 let iface = &mut resolve.interfaces[id];
3032 iface.package = Some(pkgid);
3033 if let Some(name) = &iface.name {
3034 let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), id);
3035 assert!(prev.is_none());
3036 }
3037 }
3038 for id in self.worlds.iter().skip(foreign_worlds) {
3039 let id = match id {
3040 Some(id) => *id,
3041 None => continue,
3042 };
3043 let world = &mut resolve.worlds[id];
3044 world.package = Some(pkgid);
3045 let prev = resolve.packages[pkgid]
3046 .worlds
3047 .insert(world.name.clone(), id);
3048 assert!(prev.is_none());
3049 }
3050 Ok(pkgid)
3051 }
3052
3053 fn process_foreign_deps(
3054 &mut self,
3055 resolve: &mut Resolve,
3056 pkgid: PackageId,
3057 unresolved: &UnresolvedPackage,
3058 ) -> Result<()> {
3059 let mut world_to_package = HashMap::new();
3062 let mut interface_to_package = HashMap::new();
3063 for (i, (pkg_name, worlds_or_ifaces)) in unresolved.foreign_deps.iter().enumerate() {
3064 for (name, (item, stabilities)) in worlds_or_ifaces {
3065 match item {
3066 AstItem::Interface(unresolved_interface_id) => {
3067 let prev = interface_to_package.insert(
3068 *unresolved_interface_id,
3069 (pkg_name, name, unresolved.foreign_dep_spans[i], stabilities),
3070 );
3071 assert!(prev.is_none());
3072 }
3073 AstItem::World(unresolved_world_id) => {
3074 let prev = world_to_package.insert(
3075 *unresolved_world_id,
3076 (pkg_name, name, unresolved.foreign_dep_spans[i], stabilities),
3077 );
3078 assert!(prev.is_none());
3079 }
3080 }
3081 }
3082 }
3083
3084 self.process_foreign_interfaces(unresolved, &interface_to_package, resolve, &pkgid)?;
3088
3089 self.process_foreign_worlds(unresolved, &world_to_package, resolve, &pkgid)?;
3093
3094 self.process_foreign_types(unresolved, pkgid, resolve)?;
3097
3098 for (id, span) in unresolved.required_resource_types.iter() {
3099 let Ok(mut id) = self.map_type(*id, *span) else {
3104 continue;
3105 };
3106 loop {
3107 match resolve.types[id].kind {
3108 TypeDefKind::Type(Type::Id(i)) => id = i,
3109 TypeDefKind::Resource => break,
3110 _ => bail!(Error::new(
3111 *span,
3112 format!("type used in a handle must be a resource"),
3113 )),
3114 }
3115 }
3116 }
3117
3118 #[cfg(debug_assertions)]
3119 resolve.assert_valid();
3120
3121 Ok(())
3122 }
3123
3124 fn process_foreign_interfaces(
3125 &mut self,
3126 unresolved: &UnresolvedPackage,
3127 interface_to_package: &HashMap<InterfaceId, (&PackageName, &String, Span, &Vec<Stability>)>,
3128 resolve: &mut Resolve,
3129 parent_pkg_id: &PackageId,
3130 ) -> Result<(), anyhow::Error> {
3131 for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() {
3132 let (pkg_name, interface, span, stabilities) =
3133 match interface_to_package.get(&unresolved_iface_id) {
3134 Some(items) => *items,
3135 None => break,
3139 };
3140
3141 let pkgid = resolve
3142 .package_names
3143 .get(pkg_name)
3144 .copied()
3145 .ok_or_else(|| {
3146 PackageNotFoundError::new(
3147 span,
3148 pkg_name.clone(),
3149 resolve.package_names.keys().cloned().collect(),
3150 )
3151 })?;
3152
3153 assert!(unresolved_iface.functions.is_empty());
3155
3156 let pkg = &resolve.packages[pkgid];
3157 let iface_span = unresolved_iface.span;
3158
3159 let mut enabled = false;
3160 for stability in stabilities {
3161 if resolve.include_stability(stability, parent_pkg_id, iface_span)? {
3162 enabled = true;
3163 break;
3164 }
3165 }
3166
3167 if !enabled {
3168 self.interfaces.push(None);
3169 continue;
3170 }
3171
3172 let iface_id = pkg
3173 .interfaces
3174 .get(interface)
3175 .copied()
3176 .ok_or_else(|| Error::new(iface_span, "interface not found in package"))?;
3177 assert_eq!(self.interfaces.len(), unresolved_iface_id.index());
3178 self.interfaces.push(Some(iface_id));
3179 }
3180 for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) {
3181 assert!(
3182 interface_to_package.get(&id).is_none(),
3183 "found foreign interface after local interface"
3184 );
3185 }
3186 Ok(())
3187 }
3188
3189 fn process_foreign_worlds(
3190 &mut self,
3191 unresolved: &UnresolvedPackage,
3192 world_to_package: &HashMap<WorldId, (&PackageName, &String, Span, &Vec<Stability>)>,
3193 resolve: &mut Resolve,
3194 parent_pkg_id: &PackageId,
3195 ) -> Result<(), anyhow::Error> {
3196 for (unresolved_world_id, unresolved_world) in unresolved.worlds.iter() {
3197 let (pkg_name, world, span, stabilities) =
3198 match world_to_package.get(&unresolved_world_id) {
3199 Some(items) => *items,
3200 None => break,
3203 };
3204
3205 let pkgid = resolve
3206 .package_names
3207 .get(pkg_name)
3208 .copied()
3209 .ok_or_else(|| Error::new(span, "package not found"))?;
3210 let pkg = &resolve.packages[pkgid];
3211 let world_span = unresolved_world.span;
3212
3213 let mut enabled = false;
3214 for stability in stabilities {
3215 if resolve.include_stability(stability, parent_pkg_id, world_span)? {
3216 enabled = true;
3217 break;
3218 }
3219 }
3220
3221 if !enabled {
3222 self.worlds.push(None);
3223 continue;
3224 }
3225
3226 let world_id = pkg
3227 .worlds
3228 .get(world)
3229 .copied()
3230 .ok_or_else(|| Error::new(world_span, "world not found in package"))?;
3231 assert_eq!(self.worlds.len(), unresolved_world_id.index());
3232 self.worlds.push(Some(world_id));
3233 }
3234 for (id, _) in unresolved.worlds.iter().skip(self.worlds.len()) {
3235 assert!(
3236 world_to_package.get(&id).is_none(),
3237 "found foreign world after local world"
3238 );
3239 }
3240 Ok(())
3241 }
3242
3243 fn process_foreign_types(
3244 &mut self,
3245 unresolved: &UnresolvedPackage,
3246 pkgid: PackageId,
3247 resolve: &mut Resolve,
3248 ) -> Result<(), anyhow::Error> {
3249 for (unresolved_type_id, unresolved_ty) in unresolved.types.iter() {
3250 match unresolved_ty.kind {
3254 TypeDefKind::Unknown => {}
3255 _ => break,
3256 }
3257
3258 let span = unresolved_ty.span;
3259 if !resolve.include_type(unresolved_ty, pkgid, span)? {
3260 self.types.push(None);
3261 continue;
3262 }
3263
3264 let unresolved_iface_id = match unresolved_ty.owner {
3265 TypeOwner::Interface(id) => id,
3266 _ => unreachable!(),
3267 };
3268 let iface_id = self.map_interface(unresolved_iface_id, Default::default())?;
3269 let name = unresolved_ty.name.as_ref().unwrap();
3270 let span = unresolved.unknown_type_spans[unresolved_type_id.index()];
3271 let type_id = *resolve.interfaces[iface_id]
3272 .types
3273 .get(name)
3274 .ok_or_else(|| {
3275 Error::new(span, format!("type `{name}` not defined in interface"))
3276 })?;
3277 assert_eq!(self.types.len(), unresolved_type_id.index());
3278 self.types.push(Some(type_id));
3279 }
3280 for (_, ty) in unresolved.types.iter().skip(self.types.len()) {
3281 if let TypeDefKind::Unknown = ty.kind {
3282 panic!("unknown type after defined type");
3283 }
3284 }
3285 Ok(())
3286 }
3287
3288 fn update_typedef(
3289 &mut self,
3290 resolve: &mut Resolve,
3291 ty: &mut TypeDef,
3292 span: Span,
3293 ) -> Result<()> {
3294 use crate::TypeDefKind::*;
3297 match &mut ty.kind {
3298 Handle(handle) => match handle {
3299 crate::Handle::Own(ty) | crate::Handle::Borrow(ty) => {
3300 self.update_type_id(ty, span)?
3301 }
3302 },
3303 Resource => {}
3304 Record(r) => {
3305 for field in r.fields.iter_mut() {
3306 self.update_ty(resolve, &mut field.ty, span)
3307 .with_context(|| format!("failed to update field `{}`", field.name))?;
3308 }
3309 }
3310 Tuple(t) => {
3311 for ty in t.types.iter_mut() {
3312 self.update_ty(resolve, ty, span)?;
3313 }
3314 }
3315 Variant(v) => {
3316 for case in v.cases.iter_mut() {
3317 if let Some(t) = &mut case.ty {
3318 self.update_ty(resolve, t, span)?;
3319 }
3320 }
3321 }
3322 Option(t)
3323 | List(t, ..)
3324 | FixedLengthList(t, ..)
3325 | Future(Some(t))
3326 | Stream(Some(t)) => self.update_ty(resolve, t, span)?,
3327 Map(k, v) => {
3328 self.update_ty(resolve, k, span)?;
3329 self.update_ty(resolve, v, span)?;
3330 }
3331 Result(r) => {
3332 if let Some(ty) = &mut r.ok {
3333 self.update_ty(resolve, ty, span)?;
3334 }
3335 if let Some(ty) = &mut r.err {
3336 self.update_ty(resolve, ty, span)?;
3337 }
3338 }
3339
3340 Type(crate::Type::Id(id)) => self.update_type_id(id, span)?,
3345 Type(_) => {}
3346
3347 Flags(_) | Enum(_) | Future(None) | Stream(None) => {}
3349
3350 Unknown => unreachable!(),
3351 }
3352
3353 Ok(())
3354 }
3355
3356 fn update_ty(&mut self, resolve: &mut Resolve, ty: &mut Type, span: Span) -> Result<()> {
3357 let id = match ty {
3358 Type::Id(id) => id,
3359 _ => return Ok(()),
3360 };
3361 self.update_type_id(id, span)?;
3362
3363 let mut cur = *id;
3368 let points_to_resource = loop {
3369 match resolve.types[cur].kind {
3370 TypeDefKind::Type(Type::Id(id)) => cur = id,
3371 TypeDefKind::Resource => break true,
3372 _ => break false,
3373 }
3374 };
3375
3376 if points_to_resource {
3377 *id = *self.own_handles.entry(*id).or_insert_with(|| {
3378 resolve.types.alloc(TypeDef {
3379 name: None,
3380 owner: TypeOwner::None,
3381 kind: TypeDefKind::Handle(Handle::Own(*id)),
3382 docs: Default::default(),
3383 stability: Default::default(),
3384 span: Default::default(),
3385 })
3386 });
3387 }
3388 Ok(())
3389 }
3390
3391 fn update_type_id(&self, id: &mut TypeId, span: Span) -> Result<()> {
3392 *id = self.map_type(*id, span)?;
3393 Ok(())
3394 }
3395
3396 fn update_interface(&mut self, resolve: &mut Resolve, iface: &mut Interface) -> Result<()> {
3397 iface.types.retain(|_, ty| self.types[ty.index()].is_some());
3398 let iface_pkg_id = iface.package.as_ref().unwrap_or_else(|| {
3399 panic!(
3400 "unexpectedly missing package on interface [{}]",
3401 iface
3402 .name
3403 .as_ref()
3404 .map(String::as_str)
3405 .unwrap_or("<unknown>"),
3406 )
3407 });
3408
3409 for (_name, ty) in iface.types.iter_mut() {
3412 self.update_type_id(ty, iface.span)?;
3413 }
3414 for (func_name, func) in iface.functions.iter_mut() {
3415 let span = func.span;
3416 if !resolve
3417 .include_stability(&func.stability, iface_pkg_id, span)
3418 .with_context(|| {
3419 format!(
3420 "failed to process feature gate for function [{func_name}] in package [{}]",
3421 resolve.packages[*iface_pkg_id].name,
3422 )
3423 })?
3424 {
3425 continue;
3426 }
3427 self.update_function(resolve, func, span)
3428 .with_context(|| format!("failed to update function `{}`", func.name))?;
3429 }
3430
3431 for (name, func) in mem::take(&mut iface.functions) {
3434 if resolve.include_stability(&func.stability, iface_pkg_id, func.span)? {
3435 iface.functions.insert(name, func);
3436 }
3437 }
3438
3439 Ok(())
3440 }
3441
3442 fn update_function(
3443 &mut self,
3444 resolve: &mut Resolve,
3445 func: &mut Function,
3446 span: Span,
3447 ) -> Result<()> {
3448 if let Some(id) = func.kind.resource_mut() {
3449 self.update_type_id(id, span)?;
3450 }
3451 for param in func.params.iter_mut() {
3452 self.update_ty(resolve, &mut param.ty, span)?;
3453 }
3454 if let Some(ty) = &mut func.result {
3455 self.update_ty(resolve, ty, span)?;
3456 }
3457
3458 if let Some(ty) = &func.result {
3459 if self.type_has_borrow(resolve, ty) {
3460 bail!(Error::new(
3461 span,
3462 format!(
3463 "function returns a type which contains \
3464 a `borrow<T>` which is not supported"
3465 )
3466 ))
3467 }
3468 }
3469
3470 Ok(())
3471 }
3472
3473 fn update_world(
3474 &mut self,
3475 world: &mut World,
3476 resolve: &mut Resolve,
3477 pkg_id: &PackageId,
3478 ) -> Result<()> {
3479 let imports = mem::take(&mut world.imports).into_iter().map(|p| (p, true));
3483 let exports = mem::take(&mut world.exports)
3484 .into_iter()
3485 .map(|p| (p, false));
3486 for ((mut name, mut item), import) in imports.chain(exports) {
3487 let span = item.span();
3488 if let WorldItem::Type { id, .. } = &mut item {
3491 *id = self.map_type(*id, span)?;
3492 }
3493 let stability = item.stability(resolve);
3494 if !resolve
3495 .include_stability(stability, pkg_id, span)
3496 .with_context(|| format!("failed to process world item in `{}`", world.name))?
3497 {
3498 continue;
3499 }
3500 self.update_world_key(&mut name, span)?;
3501 match &mut item {
3502 WorldItem::Interface { id, .. } => {
3503 *id = self.map_interface(*id, span)?;
3504 }
3505 WorldItem::Function(f) => {
3506 self.update_function(resolve, f, span)?;
3507 }
3508 WorldItem::Type { .. } => {
3509 }
3511 }
3512
3513 let dst = if import {
3514 &mut world.imports
3515 } else {
3516 &mut world.exports
3517 };
3518 let prev = dst.insert(name, item);
3519 assert!(prev.is_none());
3520 }
3521
3522 Ok(())
3523 }
3524
3525 fn process_world_includes(
3526 &self,
3527 id: WorldId,
3528 resolve: &mut Resolve,
3529 pkg_id: &PackageId,
3530 ) -> Result<()> {
3531 let world = &mut resolve.worlds[id];
3532 let includes = mem::take(&mut world.includes);
3535 for include in includes {
3536 if !resolve
3537 .include_stability(&include.stability, pkg_id, include.span)
3538 .with_context(|| {
3539 format!(
3540 "failed to process feature gate for included world [{}] in package [{}]",
3541 resolve.worlds[include.id].name.as_str(),
3542 resolve.packages[*pkg_id].name
3543 )
3544 })?
3545 {
3546 continue;
3547 }
3548 self.resolve_include(
3549 id,
3550 include.id,
3551 &include.names,
3552 include.span,
3553 pkg_id,
3554 resolve,
3555 )?;
3556 }
3557
3558 Self::validate_world_case_insensitive_names(resolve, id)?;
3560
3561 Ok(())
3562 }
3563
3564 fn validate_world_case_insensitive_names(resolve: &Resolve, world_id: WorldId) -> Result<()> {
3568 let world = &resolve.worlds[world_id];
3569
3570 let validate_names = |items: &IndexMap<WorldKey, WorldItem>,
3572 item_type: &str|
3573 -> Result<()> {
3574 let mut seen_lowercase: HashMap<String, String> = HashMap::new();
3575
3576 for key in items.keys() {
3577 if let WorldKey::Name(name) = key {
3579 let lowercase_name = name.to_lowercase();
3580
3581 if let Some(existing_name) = seen_lowercase.get(&lowercase_name) {
3582 if existing_name != name {
3585 bail!(
3586 "{item_type} `{name}` conflicts with {item_type} `{existing_name}` \
3587 (kebab-case identifiers are case-insensitive)"
3588 );
3589 }
3590 }
3591
3592 seen_lowercase.insert(lowercase_name, name.clone());
3593 }
3594 }
3595
3596 Ok(())
3597 };
3598
3599 validate_names(&world.imports, "import")
3600 .with_context(|| format!("failed to validate imports in world `{}`", world.name))?;
3601 validate_names(&world.exports, "export")
3602 .with_context(|| format!("failed to validate exports in world `{}`", world.name))?;
3603
3604 Ok(())
3605 }
3606
3607 fn update_world_key(&self, key: &mut WorldKey, span: Span) -> Result<()> {
3608 match key {
3609 WorldKey::Name(_) => {}
3610 WorldKey::Interface(id) => {
3611 *id = self.map_interface(*id, span)?;
3612 }
3613 }
3614 Ok(())
3615 }
3616
3617 fn resolve_include(
3618 &self,
3619 id: WorldId,
3620 include_world_id_orig: WorldId,
3621 names: &[IncludeName],
3622 span: Span,
3623 pkg_id: &PackageId,
3624 resolve: &mut Resolve,
3625 ) -> Result<()> {
3626 let world = &resolve.worlds[id];
3627 let include_world_id = self.map_world(include_world_id_orig, span)?;
3628 let include_world = resolve.worlds[include_world_id].clone();
3629 let mut names_ = names.to_owned();
3630 let is_external_include = world.package != include_world.package;
3631
3632 for import in include_world.imports.iter() {
3634 self.remove_matching_name(import, &mut names_);
3635 }
3636 for export in include_world.exports.iter() {
3637 self.remove_matching_name(export, &mut names_);
3638 }
3639 if !names_.is_empty() {
3640 bail!(Error::new(
3641 span,
3642 format!(
3643 "no import or export kebab-name `{}`. Note that an ID does not support renaming",
3644 names_[0].name
3645 ),
3646 ));
3647 }
3648
3649 let mut maps = Default::default();
3650 let mut cloner = clone::Cloner::new(
3651 resolve,
3652 &mut maps,
3653 TypeOwner::World(if is_external_include {
3654 include_world_id
3655 } else {
3656 include_world_id
3657 }),
3659 TypeOwner::World(id),
3660 );
3661 cloner.new_package = Some(*pkg_id);
3662
3663 for import in include_world.imports.iter() {
3665 self.resolve_include_item(
3666 &mut cloner,
3667 names,
3668 |resolve| &mut resolve.worlds[id].imports,
3669 import,
3670 span,
3671 "import",
3672 is_external_include,
3673 )?;
3674 }
3675
3676 for export in include_world.exports.iter() {
3677 self.resolve_include_item(
3678 &mut cloner,
3679 names,
3680 |resolve| &mut resolve.worlds[id].exports,
3681 export,
3682 span,
3683 "export",
3684 is_external_include,
3685 )?;
3686 }
3687 Ok(())
3688 }
3689
3690 fn resolve_include_item(
3691 &self,
3692 cloner: &mut clone::Cloner<'_>,
3693 names: &[IncludeName],
3694 get_items: impl Fn(&mut Resolve) -> &mut IndexMap<WorldKey, WorldItem>,
3695 item: (&WorldKey, &WorldItem),
3696 span: Span,
3697 item_type: &str,
3698 is_external_include: bool,
3699 ) -> Result<()> {
3700 match item.0 {
3701 WorldKey::Name(n) => {
3702 let n = names
3703 .into_iter()
3704 .find_map(|include_name| rename(n, include_name))
3705 .unwrap_or(n.clone());
3706
3707 let mut new_item = item.1.clone();
3713 let key = WorldKey::Name(n.clone());
3714 cloner.world_item(&key, &mut new_item);
3715 match &mut new_item {
3716 WorldItem::Function(f) => f.name = n.clone(),
3717 WorldItem::Type { id, .. } => cloner.resolve.types[*id].name = Some(n.clone()),
3718 WorldItem::Interface { .. } => {}
3719 }
3720
3721 let prev = get_items(cloner.resolve).insert(key, new_item);
3722 if prev.is_some() {
3723 bail!(Error::new(
3724 span,
3725 format!("{item_type} of `{n}` shadows previously {item_type}ed items"),
3726 ))
3727 }
3728 }
3729 key @ WorldKey::Interface(_) => {
3730 let prev = get_items(cloner.resolve)
3731 .entry(key.clone())
3732 .or_insert(item.1.clone());
3733 match (&item.1, prev) {
3734 (
3735 WorldItem::Interface {
3736 id: aid,
3737 stability: astability,
3738 ..
3739 },
3740 WorldItem::Interface {
3741 id: bid,
3742 stability: bstability,
3743 ..
3744 },
3745 ) => {
3746 assert_eq!(*aid, *bid);
3747 merge_include_stability(astability, bstability, is_external_include)?;
3748 }
3749 (WorldItem::Interface { .. }, _) => unreachable!(),
3750 (WorldItem::Function(_), _) => unreachable!(),
3751 (WorldItem::Type { .. }, _) => unreachable!(),
3752 }
3753 }
3754 };
3755
3756 Ok(())
3757 }
3758
3759 fn remove_matching_name(&self, item: (&WorldKey, &WorldItem), names: &mut Vec<IncludeName>) {
3760 match item.0 {
3761 WorldKey::Name(n) => {
3762 names.retain(|name| rename(n, name).is_none());
3763 }
3764 _ => {}
3765 }
3766 }
3767
3768 fn type_has_borrow(&mut self, resolve: &Resolve, ty: &Type) -> bool {
3769 let id = match ty {
3770 Type::Id(id) => *id,
3771 _ => return false,
3772 };
3773
3774 if let Some(Some(has_borrow)) = self.type_has_borrow.get(id.index()) {
3775 return *has_borrow;
3776 }
3777
3778 let result = self.typedef_has_borrow(resolve, &resolve.types[id]);
3779 if self.type_has_borrow.len() <= id.index() {
3780 self.type_has_borrow.resize(id.index() + 1, None);
3781 }
3782 self.type_has_borrow[id.index()] = Some(result);
3783 result
3784 }
3785
3786 fn typedef_has_borrow(&mut self, resolve: &Resolve, ty: &TypeDef) -> bool {
3787 match &ty.kind {
3788 TypeDefKind::Type(t) => self.type_has_borrow(resolve, t),
3789 TypeDefKind::Variant(v) => v
3790 .cases
3791 .iter()
3792 .filter_map(|case| case.ty.as_ref())
3793 .any(|ty| self.type_has_borrow(resolve, ty)),
3794 TypeDefKind::Handle(Handle::Borrow(_)) => true,
3795 TypeDefKind::Handle(Handle::Own(_)) => false,
3796 TypeDefKind::Resource => false,
3797 TypeDefKind::Record(r) => r
3798 .fields
3799 .iter()
3800 .any(|case| self.type_has_borrow(resolve, &case.ty)),
3801 TypeDefKind::Flags(_) => false,
3802 TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.type_has_borrow(resolve, t)),
3803 TypeDefKind::Enum(_) => false,
3804 TypeDefKind::List(ty)
3805 | TypeDefKind::FixedLengthList(ty, ..)
3806 | TypeDefKind::Future(Some(ty))
3807 | TypeDefKind::Stream(Some(ty))
3808 | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty),
3809 TypeDefKind::Map(k, v) => {
3810 self.type_has_borrow(resolve, k) || self.type_has_borrow(resolve, v)
3811 }
3812 TypeDefKind::Result(r) => [&r.ok, &r.err]
3813 .iter()
3814 .filter_map(|t| t.as_ref())
3815 .any(|t| self.type_has_borrow(resolve, t)),
3816 TypeDefKind::Future(None) | TypeDefKind::Stream(None) => false,
3817 TypeDefKind::Unknown => unreachable!(),
3818 }
3819 }
3820}
3821
3822struct MergeMap<'a> {
3823 package_map: HashMap<PackageId, PackageId>,
3826
3827 interface_map: HashMap<InterfaceId, InterfaceId>,
3830
3831 type_map: HashMap<TypeId, TypeId>,
3834
3835 world_map: HashMap<WorldId, WorldId>,
3838
3839 interfaces_to_add: Vec<(String, PackageId, InterfaceId)>,
3847 worlds_to_add: Vec<(String, PackageId, WorldId)>,
3848
3849 from: &'a Resolve,
3851
3852 into: &'a Resolve,
3854}
3855
3856impl<'a> MergeMap<'a> {
3857 fn new(from: &'a Resolve, into: &'a Resolve) -> MergeMap<'a> {
3858 MergeMap {
3859 package_map: Default::default(),
3860 interface_map: Default::default(),
3861 type_map: Default::default(),
3862 world_map: Default::default(),
3863 interfaces_to_add: Default::default(),
3864 worlds_to_add: Default::default(),
3865 from,
3866 into,
3867 }
3868 }
3869
3870 fn build(&mut self) -> Result<()> {
3871 for from_id in self.from.topological_packages() {
3872 let from = &self.from.packages[from_id];
3873 let into_id = match self.into.package_names.get(&from.name) {
3874 Some(id) => *id,
3875
3876 None => {
3879 log::trace!("adding unique package {}", from.name);
3880 continue;
3881 }
3882 };
3883 log::trace!("merging duplicate package {}", from.name);
3884
3885 self.build_package(from_id, into_id).with_context(|| {
3886 format!("failed to merge package `{}` into existing copy", from.name)
3887 })?;
3888 }
3889
3890 Ok(())
3891 }
3892
3893 fn build_package(&mut self, from_id: PackageId, into_id: PackageId) -> Result<()> {
3894 let prev = self.package_map.insert(from_id, into_id);
3895 assert!(prev.is_none());
3896
3897 let from = &self.from.packages[from_id];
3898 let into = &self.into.packages[into_id];
3899
3900 for (name, from_interface_id) in from.interfaces.iter() {
3904 let into_interface_id = match into.interfaces.get(name) {
3905 Some(id) => *id,
3906 None => {
3907 log::trace!("adding unique interface {name}");
3908 self.interfaces_to_add
3909 .push((name.clone(), into_id, *from_interface_id));
3910 continue;
3911 }
3912 };
3913
3914 log::trace!("merging duplicate interfaces {name}");
3915 self.build_interface(*from_interface_id, into_interface_id)
3916 .with_context(|| format!("failed to merge interface `{name}`"))?;
3917 }
3918
3919 for (name, from_world_id) in from.worlds.iter() {
3920 let into_world_id = match into.worlds.get(name) {
3921 Some(id) => *id,
3922 None => {
3923 log::trace!("adding unique world {name}");
3924 self.worlds_to_add
3925 .push((name.clone(), into_id, *from_world_id));
3926 continue;
3927 }
3928 };
3929
3930 log::trace!("merging duplicate worlds {name}");
3931 self.build_world(*from_world_id, into_world_id)
3932 .with_context(|| format!("failed to merge world `{name}`"))?;
3933 }
3934
3935 Ok(())
3936 }
3937
3938 fn build_interface(&mut self, from_id: InterfaceId, into_id: InterfaceId) -> Result<()> {
3939 let prev = self.interface_map.insert(from_id, into_id);
3940 assert!(prev.is_none());
3941
3942 let from_interface = &self.from.interfaces[from_id];
3943 let into_interface = &self.into.interfaces[into_id];
3944
3945 for (name, from_type_id) in from_interface.types.iter() {
3959 let into_type_id = *into_interface
3960 .types
3961 .get(name)
3962 .ok_or_else(|| anyhow!("expected type `{name}` to be present"))?;
3963 let prev = self.type_map.insert(*from_type_id, into_type_id);
3964 assert!(prev.is_none());
3965
3966 self.build_type_id(*from_type_id, into_type_id)
3967 .with_context(|| format!("mismatch in type `{name}`"))?;
3968 }
3969
3970 for (name, from_func) in from_interface.functions.iter() {
3971 let into_func = match into_interface.functions.get(name) {
3972 Some(func) => func,
3973 None => bail!("expected function `{name}` to be present"),
3974 };
3975 self.build_function(from_func, into_func)
3976 .with_context(|| format!("mismatch in function `{name}`"))?;
3977 }
3978
3979 Ok(())
3980 }
3981
3982 fn build_type_id(&mut self, from_id: TypeId, into_id: TypeId) -> Result<()> {
3983 let _ = from_id;
3987 let _ = into_id;
3988 Ok(())
3989 }
3990
3991 fn build_type(&mut self, from_ty: &Type, into_ty: &Type) -> Result<()> {
3992 match (from_ty, into_ty) {
3993 (Type::Id(from), Type::Id(into)) => {
3994 self.build_type_id(*from, *into)?;
3995 }
3996 (from, into) if from != into => bail!("different kinds of types"),
3997 _ => {}
3998 }
3999 Ok(())
4000 }
4001
4002 fn build_function(&mut self, from_func: &Function, into_func: &Function) -> Result<()> {
4003 if from_func.name != into_func.name {
4004 bail!(
4005 "different function names `{}` and `{}`",
4006 from_func.name,
4007 into_func.name
4008 );
4009 }
4010 match (&from_func.kind, &into_func.kind) {
4011 (FunctionKind::Freestanding, FunctionKind::Freestanding) => {}
4012 (FunctionKind::AsyncFreestanding, FunctionKind::AsyncFreestanding) => {}
4013
4014 (FunctionKind::Method(from), FunctionKind::Method(into))
4015 | (FunctionKind::Static(from), FunctionKind::Static(into))
4016 | (FunctionKind::AsyncMethod(from), FunctionKind::AsyncMethod(into))
4017 | (FunctionKind::AsyncStatic(from), FunctionKind::AsyncStatic(into))
4018 | (FunctionKind::Constructor(from), FunctionKind::Constructor(into)) => {
4019 self.build_type_id(*from, *into)
4020 .context("different function kind types")?;
4021 }
4022
4023 (FunctionKind::Method(_), _)
4024 | (FunctionKind::Constructor(_), _)
4025 | (FunctionKind::Static(_), _)
4026 | (FunctionKind::Freestanding, _)
4027 | (FunctionKind::AsyncFreestanding, _)
4028 | (FunctionKind::AsyncMethod(_), _)
4029 | (FunctionKind::AsyncStatic(_), _) => {
4030 bail!("different function kind types")
4031 }
4032 }
4033
4034 if from_func.params.len() != into_func.params.len() {
4035 bail!("different number of function parameters");
4036 }
4037 for (from_param, into_param) in from_func.params.iter().zip(&into_func.params) {
4038 if from_param.name != into_param.name {
4039 bail!(
4040 "different function parameter names: {} != {}",
4041 from_param.name,
4042 into_param.name
4043 );
4044 }
4045 self.build_type(&from_param.ty, &into_param.ty)
4046 .with_context(|| {
4047 format!(
4048 "different function parameter types for `{}`",
4049 from_param.name
4050 )
4051 })?;
4052 }
4053 match (&from_func.result, &into_func.result) {
4054 (Some(from_ty), Some(into_ty)) => {
4055 self.build_type(from_ty, into_ty)
4056 .context("different function result types")?;
4057 }
4058 (None, None) => {}
4059 (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
4060 }
4061 Ok(())
4062 }
4063
4064 fn build_world(&mut self, from_id: WorldId, into_id: WorldId) -> Result<()> {
4065 let prev = self.world_map.insert(from_id, into_id);
4066 assert!(prev.is_none());
4067
4068 let from_world = &self.from.worlds[from_id];
4069 let into_world = &self.into.worlds[into_id];
4070
4071 if from_world.imports.len() != into_world.imports.len() {
4080 bail!("world contains different number of imports than expected");
4081 }
4082 if from_world.exports.len() != into_world.exports.len() {
4083 bail!("world contains different number of exports than expected");
4084 }
4085
4086 for (from_name, from) in from_world.imports.iter() {
4087 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4088 let name_str = self.from.name_world_key(from_name);
4089 let into = into_world
4090 .imports
4091 .get(&into_name)
4092 .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?;
4093 self.match_world_item(from, into)
4094 .with_context(|| format!("import `{name_str}` didn't match target world"))?;
4095 }
4096
4097 for (from_name, from) in from_world.exports.iter() {
4098 let into_name = MergeMap::map_name(from_name, &self.interface_map);
4099 let name_str = self.from.name_world_key(from_name);
4100 let into = into_world
4101 .exports
4102 .get(&into_name)
4103 .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?;
4104 self.match_world_item(from, into)
4105 .with_context(|| format!("export `{name_str}` didn't match target world"))?;
4106 }
4107
4108 Ok(())
4109 }
4110
4111 fn map_name(
4112 from_name: &WorldKey,
4113 interface_map: &HashMap<InterfaceId, InterfaceId>,
4114 ) -> WorldKey {
4115 match from_name {
4116 WorldKey::Name(s) => WorldKey::Name(s.clone()),
4117 WorldKey::Interface(id) => {
4118 WorldKey::Interface(interface_map.get(id).copied().unwrap_or(*id))
4119 }
4120 }
4121 }
4122
4123 fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> Result<()> {
4124 match (from, into) {
4125 (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
4126 match (
4127 &self.from.interfaces[*from].name,
4128 &self.into.interfaces[*into].name,
4129 ) {
4130 (None, None) => self.build_interface(*from, *into)?,
4134
4135 _ => {
4140 if self.interface_map.get(from) != Some(into) {
4141 bail!("interfaces are not the same");
4142 }
4143 }
4144 }
4145 }
4146 (WorldItem::Function(from), WorldItem::Function(into)) => {
4147 let _ = (from, into);
4148 }
4151 (WorldItem::Type { id: from, .. }, WorldItem::Type { id: into, .. }) => {
4152 let prev = self.type_map.insert(*from, *into);
4155 assert!(prev.is_none());
4156 }
4157
4158 (WorldItem::Interface { .. }, _)
4159 | (WorldItem::Function(_), _)
4160 | (WorldItem::Type { .. }, _) => {
4161 bail!("world items do not have the same type")
4162 }
4163 }
4164 Ok(())
4165 }
4166}
4167
4168fn update_stability(from: &Stability, into: &mut Stability) -> Result<()> {
4174 if from == into || from.is_unknown() {
4177 return Ok(());
4178 }
4179 if into.is_unknown() {
4182 *into = from.clone();
4183 return Ok(());
4184 }
4185
4186 bail!("mismatch in stability from '{:?}' to '{:?}'", from, into)
4189}
4190
4191fn merge_include_stability(
4192 from: &Stability,
4193 into: &mut Stability,
4194 is_external_include: bool,
4195) -> Result<()> {
4196 if is_external_include && from.is_stable() {
4197 log::trace!("dropped stability from external package");
4198 *into = Stability::Unknown;
4199 return Ok(());
4200 }
4201
4202 return update_stability(from, into);
4203}
4204
4205#[derive(Debug, Clone)]
4218pub struct InvalidTransitiveDependency(String);
4219
4220impl fmt::Display for InvalidTransitiveDependency {
4221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4222 write!(
4223 f,
4224 "interface `{}` transitively depends on an interface in \
4225 incompatible ways",
4226 self.0
4227 )
4228 }
4229}
4230
4231impl core::error::Error for InvalidTransitiveDependency {}
4232
4233#[cfg(test)]
4234mod tests {
4235 use crate::alloc::string::ToString;
4236 use crate::{Resolve, WorldItem, WorldKey};
4237 use anyhow::Result;
4238
4239 #[test]
4240 fn select_world() -> Result<()> {
4241 let mut resolve = Resolve::default();
4242 resolve.push_str(
4243 "test.wit",
4244 r#"
4245 package foo:bar@0.1.0;
4246
4247 world foo {}
4248 "#,
4249 )?;
4250 resolve.push_str(
4251 "test.wit",
4252 r#"
4253 package foo:baz@0.1.0;
4254
4255 world foo {}
4256 "#,
4257 )?;
4258 resolve.push_str(
4259 "test.wit",
4260 r#"
4261 package foo:baz@0.2.0;
4262
4263 world foo {}
4264 "#,
4265 )?;
4266
4267 let dummy = resolve.push_str(
4268 "test.wit",
4269 r#"
4270 package foo:dummy;
4271
4272 world foo {}
4273 "#,
4274 )?;
4275
4276 assert!(resolve.select_world(&[dummy], None).is_ok());
4277 assert!(resolve.select_world(&[dummy], Some("xx")).is_err());
4278 assert!(resolve.select_world(&[dummy], Some("")).is_err());
4279 assert!(resolve.select_world(&[dummy], Some("foo:bar/foo")).is_ok());
4280 assert!(
4281 resolve
4282 .select_world(&[dummy], Some("foo:bar/foo@0.1.0"))
4283 .is_ok()
4284 );
4285 assert!(resolve.select_world(&[dummy], Some("foo:baz/foo")).is_err());
4286 assert!(
4287 resolve
4288 .select_world(&[dummy], Some("foo:baz/foo@0.1.0"))
4289 .is_ok()
4290 );
4291 assert!(
4292 resolve
4293 .select_world(&[dummy], Some("foo:baz/foo@0.2.0"))
4294 .is_ok()
4295 );
4296 Ok(())
4297 }
4298
4299 #[test]
4302 fn select_world_multiple_packages() -> Result<()> {
4303 use wit_parser::Resolve;
4304
4305 let mut resolve = Resolve::default();
4306
4307 let stuff = resolve.push_str(
4309 "./my-test.wit",
4310 r#"
4311 package test:stuff;
4312
4313 world foo {
4314 // ...
4315 }
4316 "#,
4317 )?;
4318 assert!(resolve.select_world(&[stuff], None).is_ok());
4319 assert!(resolve.select_world(&[stuff], Some("foo")).is_ok());
4320
4321 let empty = resolve.push_str(
4324 "./my-test.wit",
4325 r#"
4326 package test:empty;
4327 "#,
4328 )?;
4329 assert!(resolve.select_world(&[stuff, empty], None).is_err());
4330 assert!(resolve.select_world(&[stuff, empty], Some("foo")).is_err());
4331 assert!(resolve.select_world(&[empty], None).is_err());
4332 assert!(resolve.select_world(&[empty], Some("foo")).is_err());
4333
4334 Ok(())
4335 }
4336
4337 #[test]
4339 fn select_world_versions() -> Result<()> {
4340 use wit_parser::Resolve;
4341
4342 let mut resolve = Resolve::default();
4343
4344 let _id = resolve.push_str(
4345 "./my-test.wit",
4346 r#"
4347 package example:distraction;
4348 "#,
4349 )?;
4350
4351 let versions_1 = resolve.push_str(
4354 "./my-test.wit",
4355 r#"
4356 package example:versions@1.0.0;
4357
4358 world foo { /* ... */ }
4359 "#,
4360 )?;
4361 assert!(resolve.select_world(&[versions_1], Some("foo")).is_ok());
4362 assert!(
4363 resolve
4364 .select_world(&[versions_1], Some("foo@1.0.0"))
4365 .is_err()
4366 );
4367 assert!(
4368 resolve
4369 .select_world(&[versions_1], Some("example:versions/foo"))
4370 .is_ok()
4371 );
4372 assert!(
4373 resolve
4374 .select_world(&[versions_1], Some("example:versions/foo@1.0.0"))
4375 .is_ok()
4376 );
4377
4378 let versions_2 = resolve.push_str(
4381 "./my-test.wit",
4382 r#"
4383 package example:versions@2.0.0;
4384
4385 world foo { /* ... */ }
4386 "#,
4387 )?;
4388 assert!(
4389 resolve
4390 .select_world(&[versions_1, versions_2], Some("foo"))
4391 .is_err()
4392 );
4393 assert!(
4394 resolve
4395 .select_world(&[versions_1, versions_2], Some("foo@1.0.0"))
4396 .is_err()
4397 );
4398 assert!(
4399 resolve
4400 .select_world(&[versions_1, versions_2], Some("foo@2.0.0"))
4401 .is_err()
4402 );
4403 assert!(
4404 resolve
4405 .select_world(&[versions_1, versions_2], Some("example:versions/foo"))
4406 .is_err()
4407 );
4408 assert!(
4409 resolve
4410 .select_world(
4411 &[versions_1, versions_2],
4412 Some("example:versions/foo@1.0.0")
4413 )
4414 .is_ok()
4415 );
4416 assert!(
4417 resolve
4418 .select_world(
4419 &[versions_1, versions_2],
4420 Some("example:versions/foo@2.0.0")
4421 )
4422 .is_ok()
4423 );
4424
4425 Ok(())
4426 }
4427
4428 #[test]
4430 fn select_world_override_qualification() -> Result<()> {
4431 use wit_parser::Resolve;
4432
4433 let mut resolve = Resolve::default();
4434
4435 let other = resolve.push_str(
4436 "./my-test.wit",
4437 r#"
4438 package example:other;
4439
4440 world foo { }
4441 "#,
4442 )?;
4443
4444 let fq = resolve.push_str(
4446 "./my-test.wit",
4447 r#"
4448 package example:fq;
4449
4450 world bar { }
4451 "#,
4452 )?;
4453 assert!(resolve.select_world(&[other, fq], Some("foo")).is_err());
4454 assert!(resolve.select_world(&[other, fq], Some("bar")).is_err());
4455 assert!(
4456 resolve
4457 .select_world(&[other, fq], Some("example:other/foo"))
4458 .is_ok()
4459 );
4460 assert!(
4461 resolve
4462 .select_world(&[other, fq], Some("example:fq/bar"))
4463 .is_ok()
4464 );
4465 assert!(
4466 resolve
4467 .select_world(&[other, fq], Some("example:other/bar"))
4468 .is_err()
4469 );
4470 assert!(
4471 resolve
4472 .select_world(&[other, fq], Some("example:fq/foo"))
4473 .is_err()
4474 );
4475
4476 Ok(())
4477 }
4478
4479 #[test]
4481 fn select_world_fully_qualified() -> Result<()> {
4482 use wit_parser::Resolve;
4483
4484 let mut resolve = Resolve::default();
4485
4486 let distraction = resolve.push_str(
4487 "./my-test.wit",
4488 r#"
4489 package example:distraction;
4490 "#,
4491 )?;
4492
4493 let multiworld = resolve.push_str(
4496 "./my-test.wit",
4497 r#"
4498 package example:multiworld;
4499
4500 world foo { /* ... */ }
4501
4502 world bar { /* ... */ }
4503 "#,
4504 )?;
4505 assert!(
4506 resolve
4507 .select_world(&[distraction, multiworld], None)
4508 .is_err()
4509 );
4510 assert!(
4511 resolve
4512 .select_world(&[distraction, multiworld], Some("foo"))
4513 .is_err()
4514 );
4515 assert!(
4516 resolve
4517 .select_world(&[distraction, multiworld], Some("example:multiworld/foo"))
4518 .is_ok()
4519 );
4520 assert!(
4521 resolve
4522 .select_world(&[distraction, multiworld], Some("bar"))
4523 .is_err()
4524 );
4525 assert!(
4526 resolve
4527 .select_world(&[distraction, multiworld], Some("example:multiworld/bar"))
4528 .is_ok()
4529 );
4530
4531 Ok(())
4532 }
4533
4534 #[test]
4536 fn select_world_packages() -> Result<()> {
4537 use wit_parser::Resolve;
4538
4539 let mut resolve = Resolve::default();
4540
4541 let wit1 = resolve.push_str(
4544 "./my-test.wit",
4545 r#"
4546 package example:wit1;
4547
4548 world foo {
4549 // ...
4550 }
4551 "#,
4552 )?;
4553 assert!(resolve.select_world(&[wit1], None).is_ok());
4554 assert!(resolve.select_world(&[wit1], Some("foo")).is_ok());
4555 assert!(
4556 resolve
4557 .select_world(&[wit1], Some("example:wit1/foo"))
4558 .is_ok()
4559 );
4560 assert!(resolve.select_world(&[wit1], Some("bar")).is_err());
4561 assert!(
4562 resolve
4563 .select_world(&[wit1], Some("example:wit2/foo"))
4564 .is_err()
4565 );
4566
4567 let wit2 = resolve.push_str(
4570 "./my-test.wit",
4571 r#"
4572 package example:wit2;
4573
4574 world foo { /* ... */ }
4575 "#,
4576 )?;
4577 assert!(resolve.select_world(&[wit1, wit2], None).is_err());
4578 assert!(resolve.select_world(&[wit1, wit2], Some("foo")).is_err());
4579 assert!(
4580 resolve
4581 .select_world(&[wit1, wit2], Some("example:wit1/foo"))
4582 .is_ok()
4583 );
4584 assert!(resolve.select_world(&[wit2], None).is_ok());
4585 assert!(resolve.select_world(&[wit2], Some("foo")).is_ok());
4586 assert!(
4587 resolve
4588 .select_world(&[wit2], Some("example:wit1/foo"))
4589 .is_ok()
4590 );
4591 assert!(resolve.select_world(&[wit1, wit2], Some("bar")).is_err());
4592 assert!(
4593 resolve
4594 .select_world(&[wit1, wit2], Some("example:wit2/foo"))
4595 .is_ok()
4596 );
4597 assert!(resolve.select_world(&[wit2], Some("bar")).is_err());
4598 assert!(
4599 resolve
4600 .select_world(&[wit2], Some("example:wit2/foo"))
4601 .is_ok()
4602 );
4603
4604 Ok(())
4605 }
4606
4607 #[test]
4608 fn span_preservation() -> Result<()> {
4609 let mut resolve = Resolve::default();
4610 let pkg = resolve.push_str(
4611 "test.wit",
4612 r#"
4613 package foo:bar;
4614
4615 interface my-iface {
4616 type my-type = u32;
4617 my-func: func();
4618 }
4619
4620 world my-world {
4621 export my-export: func();
4622 }
4623 "#,
4624 )?;
4625
4626 let iface_id = resolve.packages[pkg].interfaces["my-iface"];
4627 assert!(resolve.interfaces[iface_id].span.is_known());
4628
4629 let type_id = resolve.interfaces[iface_id].types["my-type"];
4630 assert!(resolve.types[type_id].span.is_known());
4631
4632 assert!(
4633 resolve.interfaces[iface_id].functions["my-func"]
4634 .span
4635 .is_known()
4636 );
4637
4638 let world_id = resolve.packages[pkg].worlds["my-world"];
4639 assert!(resolve.worlds[world_id].span.is_known());
4640
4641 let WorldItem::Function(f) =
4642 &resolve.worlds[world_id].exports[&WorldKey::Name("my-export".to_string())]
4643 else {
4644 panic!("expected function");
4645 };
4646 assert!(f.span.is_known());
4647
4648 Ok(())
4649 }
4650
4651 #[test]
4652 fn span_preservation_through_merge() -> Result<()> {
4653 let mut resolve1 = Resolve::default();
4654 resolve1.push_str(
4655 "test1.wit",
4656 r#"
4657 package foo:bar;
4658
4659 interface iface1 {
4660 type type1 = u32;
4661 func1: func();
4662 }
4663 "#,
4664 )?;
4665
4666 let mut resolve2 = Resolve::default();
4667 let pkg2 = resolve2.push_str(
4668 "test2.wit",
4669 r#"
4670 package foo:baz;
4671
4672 interface iface2 {
4673 type type2 = string;
4674 func2: func();
4675 }
4676 "#,
4677 )?;
4678
4679 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
4680 let remap = resolve1.merge(resolve2)?;
4681 let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
4682
4683 assert!(resolve1.interfaces[iface2_id].span.is_known());
4684
4685 let type2_id = resolve1.interfaces[iface2_id].types["type2"];
4686 assert!(resolve1.types[type2_id].span.is_known());
4687
4688 assert!(
4689 resolve1.interfaces[iface2_id].functions["func2"]
4690 .span
4691 .is_known()
4692 );
4693
4694 Ok(())
4695 }
4696
4697 #[test]
4698 fn span_preservation_through_include() -> Result<()> {
4699 let mut resolve = Resolve::default();
4700 let pkg = resolve.push_str(
4701 "test.wit",
4702 r#"
4703 package foo:bar;
4704
4705 world base {
4706 export my-func: func();
4707 }
4708
4709 world extended {
4710 include base;
4711 }
4712 "#,
4713 )?;
4714
4715 let base_id = resolve.packages[pkg].worlds["base"];
4716 let extended_id = resolve.packages[pkg].worlds["extended"];
4717
4718 let WorldItem::Function(base_func) =
4719 &resolve.worlds[base_id].exports[&WorldKey::Name("my-func".to_string())]
4720 else {
4721 panic!("expected function");
4722 };
4723 assert!(base_func.span.is_known());
4724
4725 let WorldItem::Function(extended_func) =
4726 &resolve.worlds[extended_id].exports[&WorldKey::Name("my-func".to_string())]
4727 else {
4728 panic!("expected function");
4729 };
4730 assert!(extended_func.span.is_known());
4731
4732 Ok(())
4733 }
4734
4735 #[test]
4736 fn span_preservation_through_include_with_rename() -> Result<()> {
4737 let mut resolve = Resolve::default();
4738 let pkg = resolve.push_str(
4739 "test.wit",
4740 r#"
4741 package foo:bar;
4742
4743 world base {
4744 export original-name: func();
4745 }
4746
4747 world extended {
4748 include base with { original-name as renamed-func }
4749 }
4750 "#,
4751 )?;
4752
4753 let extended_id = resolve.packages[pkg].worlds["extended"];
4754
4755 let WorldItem::Function(f) =
4756 &resolve.worlds[extended_id].exports[&WorldKey::Name("renamed-func".to_string())]
4757 else {
4758 panic!("expected function");
4759 };
4760 assert!(f.span.is_known());
4761
4762 assert!(
4763 !resolve.worlds[extended_id]
4764 .exports
4765 .contains_key(&WorldKey::Name("original-name".to_string()))
4766 );
4767
4768 Ok(())
4769 }
4770
4771 #[test]
4773 fn span_preservation_through_include_reverse_order() -> Result<()> {
4774 let mut resolve = Resolve::default();
4775 let pkg = resolve.push_str(
4776 "test.wit",
4777 r#"
4778 package foo:bar;
4779
4780 world extended {
4781 include base;
4782 }
4783
4784 world base {
4785 export my-func: func();
4786 }
4787 "#,
4788 )?;
4789
4790 let base_id = resolve.packages[pkg].worlds["base"];
4791 let extended_id = resolve.packages[pkg].worlds["extended"];
4792
4793 let WorldItem::Function(base_func) =
4794 &resolve.worlds[base_id].exports[&WorldKey::Name("my-func".to_string())]
4795 else {
4796 panic!("expected function");
4797 };
4798 assert!(base_func.span.is_known());
4799
4800 let WorldItem::Function(extended_func) =
4801 &resolve.worlds[extended_id].exports[&WorldKey::Name("my-func".to_string())]
4802 else {
4803 panic!("expected function");
4804 };
4805 assert!(extended_func.span.is_known());
4806
4807 Ok(())
4808 }
4809
4810 #[test]
4811 fn span_line_numbers() -> Result<()> {
4812 let mut resolve = Resolve::default();
4813 let pkg = resolve.push_source(
4814 "test.wit",
4815 "package foo:bar;
4816
4817interface my-iface {
4818 type my-type = u32;
4819 my-func: func();
4820}
4821
4822world my-world {
4823 export my-export: func();
4824}
4825",
4826 )?;
4827
4828 let iface_id = resolve.packages[pkg].interfaces["my-iface"];
4829 let iface_span = resolve.interfaces[iface_id].span;
4830 let iface_loc = resolve.render_location(iface_span);
4831 assert!(
4832 iface_loc.contains(":3:"),
4833 "interface location was {iface_loc}"
4834 );
4835
4836 let type_id = resolve.interfaces[iface_id].types["my-type"];
4837 let type_span = resolve.types[type_id].span;
4838 let type_loc = resolve.render_location(type_span);
4839 assert!(type_loc.contains(":4:"), "type location was {type_loc}");
4840
4841 let func_span = resolve.interfaces[iface_id].functions["my-func"].span;
4842 let func_loc = resolve.render_location(func_span);
4843 assert!(func_loc.contains(":5:"), "function location was {func_loc}");
4844
4845 let world_id = resolve.packages[pkg].worlds["my-world"];
4846 let world_span = resolve.worlds[world_id].span;
4847 let world_loc = resolve.render_location(world_span);
4848 assert!(world_loc.contains(":8:"), "world location was {world_loc}");
4849
4850 let WorldItem::Function(export_func) =
4851 &resolve.worlds[world_id].exports[&WorldKey::Name("my-export".to_string())]
4852 else {
4853 panic!("expected function");
4854 };
4855 let export_loc = resolve.render_location(export_func.span);
4856 assert!(
4857 export_loc.contains(":9:"),
4858 "export location was {export_loc}"
4859 );
4860
4861 Ok(())
4862 }
4863
4864 #[test]
4865 fn span_line_numbers_through_merge() -> Result<()> {
4866 let mut resolve1 = Resolve::default();
4867 resolve1.push_source(
4868 "first.wit",
4869 "package foo:first;
4870
4871interface iface1 {
4872 func1: func();
4873}
4874",
4875 )?;
4876
4877 let mut resolve2 = Resolve::default();
4878 let pkg2 = resolve2.push_source(
4879 "second.wit",
4880 "package foo:second;
4881
4882interface iface2 {
4883 func2: func();
4884}
4885",
4886 )?;
4887
4888 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
4889 let remap = resolve1.merge(resolve2)?;
4890 let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
4891
4892 let iface2_span = resolve1.interfaces[iface2_id].span;
4893 let iface2_loc = resolve1.render_location(iface2_span);
4894 assert!(
4895 iface2_loc.contains("second.wit"),
4896 "should reference second.wit, got {iface2_loc}"
4897 );
4898 assert!(
4899 iface2_loc.contains(":3:"),
4900 "interface should be on line 3, got {iface2_loc}"
4901 );
4902
4903 let func2_span = resolve1.interfaces[iface2_id].functions["func2"].span;
4904 let func2_loc = resolve1.render_location(func2_span);
4905 assert!(
4906 func2_loc.contains("second.wit"),
4907 "should reference second.wit, got {func2_loc}"
4908 );
4909 assert!(
4910 func2_loc.contains(":4:"),
4911 "function should be on line 4, got {func2_loc}"
4912 );
4913
4914 Ok(())
4915 }
4916
4917 #[test]
4918 fn span_line_numbers_multiple_sources() -> Result<()> {
4919 let mut resolve = Resolve::default();
4920
4921 let pkg1 = resolve.push_source(
4922 "first.wit",
4923 "package test:first;
4924
4925interface first-iface {
4926 first-func: func();
4927}
4928",
4929 )?;
4930
4931 let pkg2 = resolve.push_source(
4932 "second.wit",
4933 "package test:second;
4934
4935interface second-iface {
4936 second-func: func();
4937}
4938",
4939 )?;
4940
4941 let iface1_id = resolve.packages[pkg1].interfaces["first-iface"];
4942 let iface1_span = resolve.interfaces[iface1_id].span;
4943 let iface1_loc = resolve.render_location(iface1_span);
4944 assert!(
4945 iface1_loc.contains("first.wit"),
4946 "should reference first.wit, got {iface1_loc}"
4947 );
4948 assert!(
4949 iface1_loc.contains(":3:"),
4950 "interface should be on line 3, got {iface1_loc}"
4951 );
4952
4953 let func1_span = resolve.interfaces[iface1_id].functions["first-func"].span;
4954 let func1_loc = resolve.render_location(func1_span);
4955 assert!(
4956 func1_loc.contains("first.wit"),
4957 "should reference first.wit, got {func1_loc}"
4958 );
4959 assert!(
4960 func1_loc.contains(":4:"),
4961 "function should be on line 4, got {func1_loc}"
4962 );
4963
4964 let iface2_id = resolve.packages[pkg2].interfaces["second-iface"];
4965 let iface2_span = resolve.interfaces[iface2_id].span;
4966 let iface2_loc = resolve.render_location(iface2_span);
4967 assert!(
4968 iface2_loc.contains("second.wit"),
4969 "should reference second.wit, got {iface2_loc}"
4970 );
4971 assert!(
4972 iface2_loc.contains(":3:"),
4973 "interface should be on line 3, got {iface2_loc}"
4974 );
4975
4976 let func2_span = resolve.interfaces[iface2_id].functions["second-func"].span;
4977 let func2_loc = resolve.render_location(func2_span);
4978 assert!(
4979 func2_loc.contains("second.wit"),
4980 "should reference second.wit, got {func2_loc}"
4981 );
4982 assert!(
4983 func2_loc.contains(":4:"),
4984 "function should be on line 4, got {func2_loc}"
4985 );
4986
4987 Ok(())
4988 }
4989
4990 #[test]
4991 fn span_preservation_for_fields_and_cases() -> Result<()> {
4992 use crate::TypeDefKind;
4993
4994 let mut resolve = Resolve::default();
4995 let pkg = resolve.push_str(
4996 "test.wit",
4997 r#"
4998 package foo:bar;
4999
5000 interface my-iface {
5001 record my-record {
5002 field1: u32,
5003 field2: string,
5004 }
5005
5006 flags my-flags {
5007 flag1,
5008 flag2,
5009 }
5010
5011 variant my-variant {
5012 case1,
5013 case2(u32),
5014 }
5015
5016 enum my-enum {
5017 val1,
5018 val2,
5019 }
5020 }
5021 "#,
5022 )?;
5023
5024 let iface_id = resolve.packages[pkg].interfaces["my-iface"];
5025
5026 let record_id = resolve.interfaces[iface_id].types["my-record"];
5028 let TypeDefKind::Record(record) = &resolve.types[record_id].kind else {
5029 panic!("expected record");
5030 };
5031 assert!(record.fields[0].span.is_known(), "field1 should have span");
5032 assert!(record.fields[1].span.is_known(), "field2 should have span");
5033
5034 let flags_id = resolve.interfaces[iface_id].types["my-flags"];
5036 let TypeDefKind::Flags(flags) = &resolve.types[flags_id].kind else {
5037 panic!("expected flags");
5038 };
5039 assert!(flags.flags[0].span.is_known(), "flag1 should have span");
5040 assert!(flags.flags[1].span.is_known(), "flag2 should have span");
5041
5042 let variant_id = resolve.interfaces[iface_id].types["my-variant"];
5044 let TypeDefKind::Variant(variant) = &resolve.types[variant_id].kind else {
5045 panic!("expected variant");
5046 };
5047 assert!(variant.cases[0].span.is_known(), "case1 should have span");
5048 assert!(variant.cases[1].span.is_known(), "case2 should have span");
5049
5050 let enum_id = resolve.interfaces[iface_id].types["my-enum"];
5052 let TypeDefKind::Enum(e) = &resolve.types[enum_id].kind else {
5053 panic!("expected enum");
5054 };
5055 assert!(e.cases[0].span.is_known(), "val1 should have span");
5056 assert!(e.cases[1].span.is_known(), "val2 should have span");
5057
5058 Ok(())
5059 }
5060
5061 #[test]
5062 fn span_preservation_for_fields_through_merge() -> Result<()> {
5063 use crate::TypeDefKind;
5064
5065 let mut resolve1 = Resolve::default();
5066 resolve1.push_str(
5067 "test1.wit",
5068 r#"
5069 package foo:bar;
5070
5071 interface iface1 {
5072 record rec1 {
5073 f1: u32,
5074 }
5075 }
5076 "#,
5077 )?;
5078
5079 let mut resolve2 = Resolve::default();
5080 let pkg2 = resolve2.push_str(
5081 "test2.wit",
5082 r#"
5083 package foo:baz;
5084
5085 interface iface2 {
5086 record rec2 {
5087 f2: string,
5088 }
5089
5090 variant var2 {
5091 c2,
5092 }
5093 }
5094 "#,
5095 )?;
5096
5097 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5098 let rec2_old_id = resolve2.interfaces[iface2_old_id].types["rec2"];
5099 let var2_old_id = resolve2.interfaces[iface2_old_id].types["var2"];
5100
5101 let remap = resolve1.merge(resolve2)?;
5102
5103 let rec2_id = remap.types[rec2_old_id.index()].unwrap();
5104 let TypeDefKind::Record(record) = &resolve1.types[rec2_id].kind else {
5105 panic!("expected record");
5106 };
5107 assert!(
5108 record.fields[0].span.is_known(),
5109 "field should have span after merge"
5110 );
5111
5112 let var2_id = remap.types[var2_old_id.index()].unwrap();
5113 let TypeDefKind::Variant(variant) = &resolve1.types[var2_id].kind else {
5114 panic!("expected variant");
5115 };
5116 assert!(
5117 variant.cases[0].span.is_known(),
5118 "case should have span after merge"
5119 );
5120
5121 Ok(())
5122 }
5123
5124 #[test]
5125 fn param_spans_point_to_names() -> Result<()> {
5126 let source = "\
5127package foo:bar;
5128
5129interface iface {
5130 my-func: func(a: u32, b: string);
5131}
5132";
5133 let mut resolve = Resolve::default();
5134 let pkg = resolve.push_str("test.wit", source)?;
5135
5136 let iface_id = resolve.packages[pkg].interfaces["iface"];
5137 let func = &resolve.interfaces[iface_id].functions["my-func"];
5138 assert_eq!(func.params.len(), 2);
5139 for param in &func.params {
5140 let start = param.span.start() as usize;
5141 let end = param.span.end() as usize;
5142 let snippet = &source[start..end];
5143 assert_eq!(
5144 snippet, param.name,
5145 "param `{}` span points to {:?}",
5146 param.name, snippet
5147 );
5148 }
5149
5150 Ok(())
5151 }
5152
5153 #[test]
5154 fn param_spans_preserved_through_merge() -> Result<()> {
5155 let mut resolve1 = Resolve::default();
5156 resolve1.push_str(
5157 "test1.wit",
5158 r#"
5159 package foo:bar;
5160
5161 interface iface1 {
5162 f1: func(x: u32);
5163 }
5164 "#,
5165 )?;
5166
5167 let mut resolve2 = Resolve::default();
5168 let pkg2 = resolve2.push_str(
5169 "test2.wit",
5170 r#"
5171 package foo:baz;
5172
5173 interface iface2 {
5174 f2: func(y: string, z: bool);
5175 }
5176 "#,
5177 )?;
5178
5179 let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5180
5181 let remap = resolve1.merge(resolve2)?;
5182
5183 let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
5184 let func = &resolve1.interfaces[iface2_id].functions["f2"];
5185 for param in &func.params {
5186 assert!(
5187 param.span.is_known(),
5188 "param `{}` should have span after merge",
5189 param.name
5190 );
5191 }
5192
5193 Ok(())
5194 }
5195}