1use std::cmp::Ordering;
2use std::collections::hash_map;
3use std::collections::{BTreeMap, HashMap, HashSet};
4use std::fmt;
5use std::mem;
6use std::path::{Path, PathBuf};
7
8use anyhow::{anyhow, bail, Context, Result};
9use id_arena::{Arena, Id};
10use indexmap::{IndexMap, IndexSet};
11use semver::Version;
12#[cfg(feature = "serde")]
13use serde_derive::Serialize;
14
15use crate::ast::lex::Span;
16use crate::ast::{parse_use_path, ParsedUsePath};
17#[cfg(feature = "serde")]
18use crate::serde_::{serialize_arena, serialize_id_map};
19use crate::{
20    AstItem, Docs, Error, Function, FunctionKind, Handle, IncludeName, Interface, InterfaceId,
21    InterfaceSpan, LiftLowerAbi, ManglingAndAbi, PackageName, PackageNotFoundError, SourceMap,
22    Stability, Type, TypeDef, TypeDefKind, TypeId, TypeIdVisitor, TypeOwner, UnresolvedPackage,
23    UnresolvedPackageGroup, World, WorldId, WorldItem, WorldKey, WorldSpan,
24};
25
26mod clone;
27
28#[derive(Default, Clone, Debug)]
42#[cfg_attr(feature = "serde", derive(Serialize))]
43pub struct Resolve {
44    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
49    pub worlds: Arena<World>,
50
51    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
56    pub interfaces: Arena<Interface>,
57
58    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
64    pub types: Arena<TypeDef>,
65
66    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
71    pub packages: Arena<Package>,
72
73    #[cfg_attr(feature = "serde", serde(skip))]
75    pub package_names: IndexMap<PackageName, PackageId>,
76
77    #[cfg_attr(feature = "serde", serde(skip))]
84    pub features: IndexSet<String>,
85
86    #[cfg_attr(feature = "serde", serde(skip))]
88    pub all_features: bool,
89}
90
91#[derive(Clone, Debug)]
97#[cfg_attr(feature = "serde", derive(Serialize))]
98pub struct Package {
99    pub name: PackageName,
101
102    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Docs::is_empty"))]
104    pub docs: Docs,
105
106    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_id_map"))]
109    pub interfaces: IndexMap<String, InterfaceId>,
110
111    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_id_map"))]
113    pub worlds: IndexMap<String, WorldId>,
114}
115
116pub type PackageId = Id<Package>;
117
118#[derive(Clone, Debug)]
120pub struct PackageSourceMap {
121    sources: Vec<Vec<PathBuf>>,
122    package_id_to_source_map_idx: BTreeMap<PackageId, usize>,
123}
124
125impl PackageSourceMap {
126    fn from_single_source(package_id: PackageId, source: &Path) -> Self {
127        Self {
128            sources: vec![vec![source.to_path_buf()]],
129            package_id_to_source_map_idx: BTreeMap::from([(package_id, 0)]),
130        }
131    }
132
133    fn from_source_maps(
134        source_maps: Vec<SourceMap>,
135        package_id_to_source_map_idx: BTreeMap<PackageId, usize>,
136    ) -> PackageSourceMap {
137        for (package_id, idx) in &package_id_to_source_map_idx {
138            if *idx >= source_maps.len() {
139                panic!(
140                    "Invalid source map index: {}, package id: {:?}, source maps size: {}",
141                    idx,
142                    package_id,
143                    source_maps.len()
144                )
145            }
146        }
147
148        Self {
149            sources: source_maps
150                .into_iter()
151                .map(|source_map| {
152                    source_map
153                        .source_files()
154                        .map(|path| path.to_path_buf())
155                        .collect()
156                })
157                .collect(),
158            package_id_to_source_map_idx,
159        }
160    }
161
162    pub fn paths(&self) -> impl Iterator<Item = &Path> {
164        self.sources
168            .iter()
169            .flatten()
170            .map(|path_buf| path_buf.as_ref())
171            .collect::<HashSet<&Path>>()
172            .into_iter()
173    }
174
175    pub fn package_paths(&self, id: PackageId) -> Option<impl Iterator<Item = &Path>> {
177        self.package_id_to_source_map_idx
178            .get(&id)
179            .map(|&idx| self.sources[idx].iter().map(|path_buf| path_buf.as_ref()))
180    }
181}
182
183enum ParsedFile {
184    #[cfg(feature = "decoding")]
185    Package(PackageId),
186    Unresolved(UnresolvedPackageGroup),
187}
188
189fn visit<'a>(
191    pkg: &'a UnresolvedPackage,
192    pkg_details_map: &'a BTreeMap<PackageName, (UnresolvedPackage, usize)>,
193    order: &mut IndexSet<PackageName>,
194    visiting: &mut HashSet<&'a PackageName>,
195    source_maps: &[SourceMap],
196) -> Result<()> {
197    if order.contains(&pkg.name) {
198        return Ok(());
199    }
200
201    match pkg_details_map.get(&pkg.name) {
202        Some(pkg_details) => {
203            let (_, source_maps_index) = pkg_details;
204            source_maps[*source_maps_index].rewrite_error(|| {
205                for (i, (dep, _)) in pkg.foreign_deps.iter().enumerate() {
206                    let span = pkg.foreign_dep_spans[i];
207                    if !visiting.insert(dep) {
208                        bail!(Error::new(span, "package depends on itself"));
209                    }
210                    if let Some(dep) = pkg_details_map.get(dep) {
211                        let (dep_pkg, _) = dep;
212                        visit(dep_pkg, pkg_details_map, order, visiting, source_maps)?;
213                    }
214                    assert!(visiting.remove(dep));
215                }
216                assert!(order.insert(pkg.name.clone()));
217                Ok(())
218            })
219        }
220        None => panic!("No pkg_details found for package when doing topological sort"),
221    }
222}
223
224impl Resolve {
225    pub fn new() -> Resolve {
227        Resolve::default()
228    }
229
230    pub fn push_path(&mut self, path: impl AsRef<Path>) -> Result<(PackageId, PackageSourceMap)> {
258        self._push_path(path.as_ref())
259    }
260
261    fn _push_path(&mut self, path: &Path) -> Result<(PackageId, PackageSourceMap)> {
262        if path.is_dir() {
263            self.push_dir(path).with_context(|| {
264                format!(
265                    "failed to resolve directory while parsing WIT for path [{}]",
266                    path.display()
267                )
268            })
269        } else {
270            let id = self.push_file(path)?;
271            Ok((id, PackageSourceMap::from_single_source(id, path)))
272        }
273    }
274
275    fn sort_unresolved_packages(
276        &mut self,
277        main: UnresolvedPackageGroup,
278        deps: Vec<UnresolvedPackageGroup>,
279    ) -> Result<(PackageId, PackageSourceMap)> {
280        let mut pkg_details_map = BTreeMap::new();
281        let mut source_maps = Vec::new();
282
283        let mut insert = |group: UnresolvedPackageGroup| {
284            let UnresolvedPackageGroup {
285                main,
286                nested,
287                source_map,
288            } = group;
289            let i = source_maps.len();
290            source_maps.push(source_map);
291
292            for pkg in nested.into_iter().chain([main]) {
293                let name = pkg.name.clone();
294                let my_span = pkg.package_name_span;
295                let (prev_pkg, prev_i) = match pkg_details_map.insert(name.clone(), (pkg, i)) {
296                    Some(pair) => pair,
297                    None => continue,
298                };
299                let loc1 = source_maps[i].render_location(my_span);
300                let loc2 = source_maps[prev_i].render_location(prev_pkg.package_name_span);
301                bail!(
302                    "\
303package {name} is defined in two different locations:\n\
304  * {loc1}\n\
305  * {loc2}\n\
306                     "
307                )
308            }
309            Ok(())
310        };
311
312        let main_name = main.main.name.clone();
313        insert(main)?;
314        for dep in deps {
315            insert(dep)?;
316        }
317
318        let mut order = IndexSet::new();
322        let mut visiting = HashSet::new();
323        for pkg_details in pkg_details_map.values() {
324            let (pkg, _) = pkg_details;
325            visit(
326                pkg,
327                &pkg_details_map,
328                &mut order,
329                &mut visiting,
330                &source_maps,
331            )?;
332        }
333
334        let mut package_id_to_source_map_idx = BTreeMap::new();
338        let mut main_pkg_id = None;
339        for name in order {
340            let (pkg, source_map_index) = pkg_details_map.remove(&name).unwrap();
341            let source_map = &source_maps[source_map_index];
342            let is_main = pkg.name == main_name;
343            let id = self.push(pkg, source_map)?;
344            if is_main {
345                assert!(main_pkg_id.is_none());
346                main_pkg_id = Some(id);
347            }
348            package_id_to_source_map_idx.insert(id, source_map_index);
349        }
350
351        Ok((
352            main_pkg_id.unwrap(),
353            PackageSourceMap::from_source_maps(source_maps, package_id_to_source_map_idx),
354        ))
355    }
356
357    pub fn push_dir(&mut self, path: impl AsRef<Path>) -> Result<(PackageId, PackageSourceMap)> {
391        self._push_dir(path.as_ref())
392    }
393
394    fn _push_dir(&mut self, path: &Path) -> Result<(PackageId, PackageSourceMap)> {
395        let top_pkg = UnresolvedPackageGroup::parse_dir(path)
396            .with_context(|| format!("failed to parse package: {}", path.display()))?;
397        let deps = path.join("deps");
398        let deps = self
399            .parse_deps_dir(&deps)
400            .with_context(|| format!("failed to parse dependency directory: {}", deps.display()))?;
401
402        self.sort_unresolved_packages(top_pkg, deps)
403    }
404
405    fn parse_deps_dir(&mut self, path: &Path) -> Result<Vec<UnresolvedPackageGroup>> {
406        let mut ret = Vec::new();
407        if !path.exists() {
408            return Ok(ret);
409        }
410        let mut entries = path
411            .read_dir()
412            .and_then(|i| i.collect::<std::io::Result<Vec<_>>>())
413            .context("failed to read directory")?;
414        entries.sort_by_key(|e| e.file_name());
415        for dep in entries {
416            let path = dep.path();
417            let pkg = if dep.file_type()?.is_dir() || path.metadata()?.is_dir() {
418                UnresolvedPackageGroup::parse_dir(&path)
423                    .with_context(|| format!("failed to parse package: {}", path.display()))?
424            } else {
425                let filename = dep.file_name();
429                match Path::new(&filename).extension().and_then(|s| s.to_str()) {
430                    Some("wit") | Some("wat") | Some("wasm") => match self._push_file(&path)? {
431                        #[cfg(feature = "decoding")]
432                        ParsedFile::Package(_) => continue,
433                        ParsedFile::Unresolved(pkg) => pkg,
434                    },
435
436                    _ => continue,
440                }
441            };
442            ret.push(pkg);
443        }
444        Ok(ret)
445    }
446
447    pub fn push_file(&mut self, path: impl AsRef<Path>) -> Result<PackageId> {
462        match self._push_file(path.as_ref())? {
463            #[cfg(feature = "decoding")]
464            ParsedFile::Package(id) => Ok(id),
465            ParsedFile::Unresolved(pkg) => self.push_group(pkg),
466        }
467    }
468
469    fn _push_file(&mut self, path: &Path) -> Result<ParsedFile> {
470        let contents = std::fs::read(path)
471            .with_context(|| format!("failed to read path for WIT [{}]", path.display()))?;
472
473        #[cfg(feature = "decoding")]
476        {
477            use crate::decoding::{decode, DecodedWasm};
478
479            #[cfg(feature = "wat")]
480            let is_wasm = wat::Detect::from_bytes(&contents).is_wasm();
481            #[cfg(not(feature = "wat"))]
482            let is_wasm = wasmparser::Parser::is_component(&contents);
483
484            if is_wasm {
485                #[cfg(feature = "wat")]
486                let contents = wat::parse_bytes(&contents).map_err(|mut e| {
487                    e.set_path(path);
488                    e
489                })?;
490
491                match decode(&contents)? {
492                    DecodedWasm::Component(..) => {
493                        bail!("found an actual component instead of an encoded WIT package in wasm")
494                    }
495                    DecodedWasm::WitPackage(resolve, pkg) => {
496                        let remap = self.merge(resolve)?;
497                        return Ok(ParsedFile::Package(remap.packages[pkg.index()]));
498                    }
499                }
500            }
501        }
502
503        let text = match std::str::from_utf8(&contents) {
505            Ok(s) => s,
506            Err(_) => bail!("input file is not valid utf-8 [{}]", path.display()),
507        };
508        let pkgs = UnresolvedPackageGroup::parse(path, text)?;
509        Ok(ParsedFile::Unresolved(pkgs))
510    }
511
512    pub fn push(
523        &mut self,
524        unresolved: UnresolvedPackage,
525        source_map: &SourceMap,
526    ) -> Result<PackageId> {
527        source_map.rewrite_error(|| Remap::default().append(self, unresolved))
528    }
529
530    pub fn push_group(&mut self, unresolved_group: UnresolvedPackageGroup) -> Result<PackageId> {
539        let (pkg_id, _) = self.sort_unresolved_packages(unresolved_group, Vec::new())?;
540        Ok(pkg_id)
541    }
542
543    pub fn push_str(&mut self, path: impl AsRef<Path>, contents: &str) -> Result<PackageId> {
550        self.push_group(UnresolvedPackageGroup::parse(path.as_ref(), contents)?)
551    }
552
553    pub fn all_bits_valid(&self, ty: &Type) -> bool {
554        match ty {
555            Type::U8
556            | Type::S8
557            | Type::U16
558            | Type::S16
559            | Type::U32
560            | Type::S32
561            | Type::U64
562            | Type::S64
563            | Type::F32
564            | Type::F64 => true,
565
566            Type::Bool | Type::Char | Type::String | Type::ErrorContext => false,
567
568            Type::Id(id) => match &self.types[*id].kind {
569                TypeDefKind::List(_)
570                | TypeDefKind::Variant(_)
571                | TypeDefKind::Enum(_)
572                | TypeDefKind::Option(_)
573                | TypeDefKind::Result(_)
574                | TypeDefKind::Future(_)
575                | TypeDefKind::Stream(_) => false,
576                TypeDefKind::Type(t) | TypeDefKind::FixedSizeList(t, ..) => self.all_bits_valid(t),
577
578                TypeDefKind::Handle(h) => match h {
579                    crate::Handle::Own(_) => true,
580                    crate::Handle::Borrow(_) => true,
581                },
582
583                TypeDefKind::Resource => false,
584                TypeDefKind::Record(r) => r.fields.iter().all(|f| self.all_bits_valid(&f.ty)),
585                TypeDefKind::Tuple(t) => t.types.iter().all(|t| self.all_bits_valid(t)),
586
587                TypeDefKind::Flags(_) => false,
591
592                TypeDefKind::Unknown => unreachable!(),
593            },
594        }
595    }
596
597    pub fn merge(&mut self, resolve: Resolve) -> Result<Remap> {
609        log::trace!(
610            "merging {} packages into {} packages",
611            resolve.packages.len(),
612            self.packages.len()
613        );
614
615        let mut map = MergeMap::new(&resolve, &self);
616        map.build()?;
617        let MergeMap {
618            package_map,
619            interface_map,
620            type_map,
621            world_map,
622            interfaces_to_add,
623            worlds_to_add,
624            ..
625        } = map;
626
627        let mut remap = Remap::default();
646        let Resolve {
647            types,
648            worlds,
649            interfaces,
650            packages,
651            package_names,
652            features: _,
653            ..
654        } = resolve;
655
656        let mut moved_types = Vec::new();
657        for (id, mut ty) in types {
658            let new_id = match type_map.get(&id).copied() {
659                Some(id) => {
660                    update_stability(&ty.stability, &mut self.types[id].stability)?;
661                    id
662                }
663                None => {
664                    log::debug!("moving type {:?}", ty.name);
665                    moved_types.push(id);
666                    remap.update_typedef(self, &mut ty, None)?;
667                    self.types.alloc(ty)
668                }
669            };
670            assert_eq!(remap.types.len(), id.index());
671            remap.types.push(Some(new_id));
672        }
673
674        let mut moved_interfaces = Vec::new();
675        for (id, mut iface) in interfaces {
676            let new_id = match interface_map.get(&id).copied() {
677                Some(id) => {
678                    update_stability(&iface.stability, &mut self.interfaces[id].stability)?;
679                    id
680                }
681                None => {
682                    log::debug!("moving interface {:?}", iface.name);
683                    moved_interfaces.push(id);
684                    remap.update_interface(self, &mut iface, None)?;
685                    self.interfaces.alloc(iface)
686                }
687            };
688            assert_eq!(remap.interfaces.len(), id.index());
689            remap.interfaces.push(Some(new_id));
690        }
691
692        let mut moved_worlds = Vec::new();
693        for (id, mut world) in worlds {
694            let new_id = match world_map.get(&id).copied() {
695                Some(world_id) => {
696                    update_stability(&world.stability, &mut self.worlds[world_id].stability)?;
697                    for from_import in world.imports.iter() {
698                        Resolve::update_world_imports_stability(
699                            from_import,
700                            &mut self.worlds[world_id].imports,
701                            &interface_map,
702                        )?;
703                    }
704                    for from_export in world.exports.iter() {
705                        Resolve::update_world_imports_stability(
706                            from_export,
707                            &mut self.worlds[world_id].exports,
708                            &interface_map,
709                        )?;
710                    }
711                    world_id
712                }
713                None => {
714                    log::debug!("moving world {}", world.name);
715                    moved_worlds.push(id);
716                    let mut update = |map: &mut IndexMap<WorldKey, WorldItem>| -> Result<_> {
717                        for (mut name, mut item) in mem::take(map) {
718                            remap.update_world_key(&mut name, None)?;
719                            match &mut item {
720                                WorldItem::Function(f) => remap.update_function(self, f, None)?,
721                                WorldItem::Interface { id, .. } => {
722                                    *id = remap.map_interface(*id, None)?
723                                }
724                                WorldItem::Type(i) => *i = remap.map_type(*i, None)?,
725                            }
726                            map.insert(name, item);
727                        }
728                        Ok(())
729                    };
730                    update(&mut world.imports)?;
731                    update(&mut world.exports)?;
732                    self.worlds.alloc(world)
733                }
734            };
735            assert_eq!(remap.worlds.len(), id.index());
736            remap.worlds.push(Some(new_id));
737        }
738
739        for (id, mut pkg) in packages {
740            let new_id = match package_map.get(&id).copied() {
741                Some(id) => id,
742                None => {
743                    for (_, id) in pkg.interfaces.iter_mut() {
744                        *id = remap.map_interface(*id, None)?;
745                    }
746                    for (_, id) in pkg.worlds.iter_mut() {
747                        *id = remap.map_world(*id, None)?;
748                    }
749                    self.packages.alloc(pkg)
750                }
751            };
752            assert_eq!(remap.packages.len(), id.index());
753            remap.packages.push(new_id);
754        }
755
756        for (name, id) in package_names {
757            let id = remap.packages[id.index()];
758            if let Some(prev) = self.package_names.insert(name, id) {
759                assert_eq!(prev, id);
760            }
761        }
762
763        for id in moved_worlds {
771            let id = remap.map_world(id, None)?;
772            if let Some(pkg) = self.worlds[id].package.as_mut() {
773                *pkg = remap.packages[pkg.index()];
774            }
775        }
776        for id in moved_interfaces {
777            let id = remap.map_interface(id, None)?;
778            if let Some(pkg) = self.interfaces[id].package.as_mut() {
779                *pkg = remap.packages[pkg.index()];
780            }
781        }
782        for id in moved_types {
783            let id = remap.map_type(id, None)?;
784            match &mut self.types[id].owner {
785                TypeOwner::Interface(id) => *id = remap.map_interface(*id, None)?,
786                TypeOwner::World(id) => *id = remap.map_world(*id, None)?,
787                TypeOwner::None => {}
788            }
789        }
790
791        for (name, pkg, iface) in interfaces_to_add {
796            let prev = self.packages[pkg]
797                .interfaces
798                .insert(name, remap.map_interface(iface, None)?);
799            assert!(prev.is_none());
800        }
801        for (name, pkg, world) in worlds_to_add {
802            let prev = self.packages[pkg]
803                .worlds
804                .insert(name, remap.map_world(world, None)?);
805            assert!(prev.is_none());
806        }
807
808        log::trace!("now have {} packages", self.packages.len());
809
810        #[cfg(debug_assertions)]
811        self.assert_valid();
812        Ok(remap)
813    }
814
815    fn update_world_imports_stability(
816        from_item: (&WorldKey, &WorldItem),
817        into_items: &mut IndexMap<WorldKey, WorldItem>,
818        interface_map: &HashMap<Id<Interface>, Id<Interface>>,
819    ) -> Result<()> {
820        match from_item.0 {
821            WorldKey::Name(_) => {
822                Ok(())
824            }
825            key @ WorldKey::Interface(_) => {
826                let new_key = MergeMap::map_name(key, interface_map);
827                if let Some(into) = into_items.get_mut(&new_key) {
828                    match (from_item.1, into) {
829                        (
830                            WorldItem::Interface {
831                                id: aid,
832                                stability: astability,
833                            },
834                            WorldItem::Interface {
835                                id: bid,
836                                stability: bstability,
837                            },
838                        ) => {
839                            let aid = interface_map.get(aid).copied().unwrap_or(*aid);
840                            assert_eq!(aid, *bid);
841                            update_stability(astability, bstability)?;
842                            Ok(())
843                        }
844                        _ => unreachable!(),
845                    }
846                } else {
847                    unreachable!()
850                }
851            }
852        }
853    }
854
855    pub fn merge_worlds(&mut self, from: WorldId, into: WorldId) -> Result<()> {
866        let mut new_imports = Vec::new();
867        let mut new_exports = Vec::new();
868
869        let from_world = &self.worlds[from];
870        let into_world = &self.worlds[into];
871
872        log::trace!("merging {} into {}", from_world.name, into_world.name);
873
874        for (name, from_import) in from_world.imports.iter() {
882            let name_str = self.name_world_key(name);
883            match into_world.imports.get(name) {
884                Some(into_import) => {
885                    log::trace!("info/from shared import on `{name_str}`");
886                    self.merge_world_item(from_import, into_import)
887                        .with_context(|| format!("failed to merge world import {name_str}"))?;
888                }
889                None => {
890                    log::trace!("new import: `{name_str}`");
891                    new_imports.push((name.clone(), from_import.clone()));
892                }
893            }
894        }
895
896        let mut must_be_imported = HashMap::new();
903        for (key, export) in into_world.exports.iter() {
904            for dep in self.world_item_direct_deps(export) {
905                if into_world.exports.contains_key(&WorldKey::Interface(dep)) {
906                    continue;
907                }
908                self.foreach_interface_dep(dep, &mut |id| {
909                    must_be_imported.insert(id, key.clone());
910                });
911            }
912        }
913
914        for (name, from_export) in from_world.exports.iter() {
917            let name_str = self.name_world_key(name);
918            match into_world.exports.get(name) {
919                Some(into_export) => {
920                    log::trace!("info/from shared export on `{name_str}`");
921                    self.merge_world_item(from_export, into_export)
922                        .with_context(|| format!("failed to merge world export {name_str}"))?;
923                }
924                None => {
925                    log::trace!("new export `{name_str}`");
926                    self.ensure_can_add_world_export(
929                        into_world,
930                        name,
931                        from_export,
932                        &must_be_imported,
933                    )
934                    .with_context(|| {
935                        format!("failed to add export `{}`", self.name_world_key(name))
936                    })?;
937                    new_exports.push((name.clone(), from_export.clone()));
938                }
939            }
940        }
941
942        let mut cloner = clone::Cloner::new(self, TypeOwner::World(from), TypeOwner::World(into));
956        cloner.register_world_type_overlap(from, into);
957        for (name, item) in new_imports.iter_mut().chain(&mut new_exports) {
958            cloner.world_item(name, item);
959        }
960
961        let into_world = &mut self.worlds[into];
963        for (name, import) in new_imports {
964            let prev = into_world.imports.insert(name, import);
965            assert!(prev.is_none());
966        }
967        for (name, export) in new_exports {
968            let prev = into_world.exports.insert(name, export);
969            assert!(prev.is_none());
970        }
971
972        #[cfg(debug_assertions)]
973        self.assert_valid();
974        Ok(())
975    }
976
977    fn merge_world_item(&self, from: &WorldItem, into: &WorldItem) -> Result<()> {
978        let mut map = MergeMap::new(self, self);
979        match (from, into) {
980            (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
981                if from == into {
986                    return Ok(());
987                }
988
989                map.build_interface(*from, *into)
999                    .context("failed to merge interfaces")?;
1000            }
1001
1002            (WorldItem::Function(from), WorldItem::Function(into)) => {
1005                map.build_function(from, into)
1006                    .context("failed to merge functions")?;
1007            }
1008            (WorldItem::Type(from), WorldItem::Type(into)) => {
1009                map.build_type_id(*from, *into)
1010                    .context("failed to merge types")?;
1011            }
1012
1013            (WorldItem::Interface { .. }, _)
1015            | (WorldItem::Function { .. }, _)
1016            | (WorldItem::Type { .. }, _) => {
1017                bail!("different kinds of items");
1018            }
1019        }
1020        assert!(map.interfaces_to_add.is_empty());
1021        assert!(map.worlds_to_add.is_empty());
1022        Ok(())
1023    }
1024
1025    fn ensure_can_add_world_export(
1037        &self,
1038        into: &World,
1039        name: &WorldKey,
1040        item: &WorldItem,
1041        must_be_imported: &HashMap<InterfaceId, WorldKey>,
1042    ) -> Result<()> {
1043        assert!(!into.exports.contains_key(name));
1044        let name = self.name_world_key(name);
1045
1046        for dep in self.world_item_direct_deps(item) {
1050            if into.exports.contains_key(&WorldKey::Interface(dep)) {
1051                continue;
1052            }
1053            self.ensure_not_exported(into, dep)
1054                .with_context(|| format!("failed validating export of `{name}`"))?;
1055        }
1056
1057        if let WorldItem::Interface { id, .. } = item {
1061            if let Some(export) = must_be_imported.get(&id) {
1062                let export_name = self.name_world_key(export);
1063                bail!(
1064                    "export `{export_name}` depends on `{name}` \
1065                     previously as an import which will change meaning \
1066                     if `{name}` is added as an export"
1067                );
1068            }
1069        }
1070
1071        Ok(())
1072    }
1073
1074    fn ensure_not_exported(&self, world: &World, id: InterfaceId) -> Result<()> {
1075        let key = WorldKey::Interface(id);
1076        let name = self.name_world_key(&key);
1077        if world.exports.contains_key(&key) {
1078            bail!(
1079                "world exports `{name}` but it's also transitively used by an \
1080                     import \
1081                   which means that this is not valid"
1082            )
1083        }
1084        for dep in self.interface_direct_deps(id) {
1085            self.ensure_not_exported(world, dep)
1086                .with_context(|| format!("failed validating transitive import dep `{name}`"))?;
1087        }
1088        Ok(())
1089    }
1090
1091    fn world_item_direct_deps(&self, item: &WorldItem) -> impl Iterator<Item = InterfaceId> + '_ {
1097        let mut interface = None;
1098        let mut ty = None;
1099        match item {
1100            WorldItem::Function(_) => {}
1101            WorldItem::Type(id) => ty = Some(*id),
1102            WorldItem::Interface { id, .. } => interface = Some(*id),
1103        }
1104
1105        interface
1106            .into_iter()
1107            .flat_map(move |id| self.interface_direct_deps(id))
1108            .chain(ty.and_then(|t| self.type_interface_dep(t)))
1109    }
1110
1111    fn foreach_interface_dep(&self, id: InterfaceId, f: &mut dyn FnMut(InterfaceId)) {
1115        f(id);
1116        for dep in self.interface_direct_deps(id) {
1117            self.foreach_interface_dep(dep, f);
1118        }
1119    }
1120
1121    pub fn id_of(&self, interface: InterfaceId) -> Option<String> {
1125        let interface = &self.interfaces[interface];
1126        Some(self.id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1127    }
1128
1129    pub fn canonicalized_id_of(&self, interface: InterfaceId) -> Option<String> {
1134        let interface = &self.interfaces[interface];
1135        Some(self.canonicalized_id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1136    }
1137
1138    pub fn importize(&mut self, world_id: WorldId, out_world_name: Option<String>) -> Result<()> {
1154        let world = &mut self.worlds[world_id];
1159        let pkg = &mut self.packages[world.package.unwrap()];
1160        pkg.worlds.shift_remove(&world.name);
1161        if let Some(name) = out_world_name {
1162            world.name = name.clone();
1163            pkg.worlds.insert(name, world_id);
1164        } else {
1165            world.name.push_str("-importized");
1166            pkg.worlds.insert(world.name.clone(), world_id);
1167        }
1168
1169        world.imports.retain(|_, item| match item {
1172            WorldItem::Type(_) => true,
1173            _ => false,
1174        });
1175
1176        for (name, export) in mem::take(&mut world.exports) {
1177            match (name.clone(), world.imports.insert(name, export)) {
1178                (_, None) => {}
1180
1181                (WorldKey::Name(name), Some(_)) => {
1183                    bail!("world export `{name}` conflicts with import of same name");
1184                }
1185
1186                (WorldKey::Interface(_), _) => unreachable!(),
1189            }
1190        }
1191
1192        self.elaborate_world(world_id)?;
1195
1196        #[cfg(debug_assertions)]
1197        self.assert_valid();
1198        Ok(())
1199    }
1200
1201    pub fn id_of_name(&self, pkg: PackageId, name: &str) -> String {
1203        let package = &self.packages[pkg];
1204        let mut base = String::new();
1205        base.push_str(&package.name.namespace);
1206        base.push_str(":");
1207        base.push_str(&package.name.name);
1208        base.push_str("/");
1209        base.push_str(name);
1210        if let Some(version) = &package.name.version {
1211            base.push_str(&format!("@{version}"));
1212        }
1213        base
1214    }
1215
1216    pub fn canonicalized_id_of_name(&self, pkg: PackageId, name: &str) -> String {
1222        let package = &self.packages[pkg];
1223        let mut base = String::new();
1224        base.push_str(&package.name.namespace);
1225        base.push_str(":");
1226        base.push_str(&package.name.name);
1227        base.push_str("/");
1228        base.push_str(name);
1229        if let Some(version) = &package.name.version {
1230            base.push_str("@");
1231            let string = PackageName::version_compat_track_string(version);
1232            base.push_str(&string);
1233        }
1234        base
1235    }
1236
1237    pub fn select_world(&self, package: PackageId, world: Option<&str>) -> Result<WorldId> {
1348        let world_path = match world {
1349            Some(world) => Some(
1350                parse_use_path(world)
1351                    .with_context(|| format!("failed to parse world specifier `{world}`"))?,
1352            ),
1353            None => None,
1354        };
1355
1356        let (pkg, world_name) = match world_path {
1357            Some(ParsedUsePath::Name(name)) => (package, name),
1358            Some(ParsedUsePath::Package(pkg, interface)) => {
1359                let pkg = match self.package_names.get(&pkg) {
1360                    Some(pkg) => *pkg,
1361                    None => {
1362                        let mut candidates = self.package_names.iter().filter(|(name, _)| {
1363                            pkg.version.is_none()
1364                                && pkg.name == name.name
1365                                && pkg.namespace == name.namespace
1366                                && name.version.is_some()
1367                        });
1368                        let candidate = candidates.next();
1369                        if let Some((c2, _)) = candidates.next() {
1370                            let (c1, _) = candidate.unwrap();
1371                            bail!(
1372                                "package name `{pkg}` is available at both \
1373                                 versions {} and {} but which is not specified",
1374                                c1.version.as_ref().unwrap(),
1375                                c2.version.as_ref().unwrap(),
1376                            );
1377                        }
1378                        match candidate {
1379                            Some((_, id)) => *id,
1380                            None => bail!("unknown package `{pkg}`"),
1381                        }
1382                    }
1383                };
1384                (pkg, interface.to_string())
1385            }
1386            None => {
1387                let pkg = &self.packages[package];
1388                let worlds = pkg
1389                    .worlds
1390                    .values()
1391                    .map(|world| (package, *world))
1392                    .collect::<Vec<_>>();
1393
1394                match &worlds[..] {
1395                    [] => bail!("The main package `{}` contains no worlds", pkg.name),
1396                    [(_, world)] => return Ok(*world),
1397                    _ => bail!(
1398                        "multiple worlds found; one must be explicitly chosen:{}",
1399                        worlds
1400                            .iter()
1401                            .map(|(pkg, world)| format!(
1402                                "\n  {}/{}",
1403                                self.packages[*pkg].name, self.worlds[*world].name
1404                            ))
1405                            .collect::<String>()
1406                    ),
1407                }
1408            }
1409        };
1410        let pkg = &self.packages[pkg];
1411        pkg.worlds
1412            .get(&world_name)
1413            .copied()
1414            .ok_or_else(|| anyhow!("no world named `{world_name}` in package"))
1415    }
1416
1417    pub fn name_world_key(&self, key: &WorldKey) -> String {
1419        match key {
1420            WorldKey::Name(s) => s.to_string(),
1421            WorldKey::Interface(i) => self.id_of(*i).expect("unexpected anonymous interface"),
1422        }
1423    }
1424
1425    pub fn name_canonicalized_world_key(&self, key: &WorldKey) -> String {
1428        match key {
1429            WorldKey::Name(s) => s.to_string(),
1430            WorldKey::Interface(i) => self
1431                .canonicalized_id_of(*i)
1432                .expect("unexpected anonymous interface"),
1433        }
1434    }
1435
1436    pub fn type_interface_dep(&self, id: TypeId) -> Option<InterfaceId> {
1442        let ty = &self.types[id];
1443        let dep = match ty.kind {
1444            TypeDefKind::Type(Type::Id(id)) => id,
1445            _ => return None,
1446        };
1447        let other = &self.types[dep];
1448        if ty.owner == other.owner {
1449            None
1450        } else {
1451            match other.owner {
1452                TypeOwner::Interface(id) => Some(id),
1453                _ => unreachable!(),
1454            }
1455        }
1456    }
1457
1458    pub fn interface_direct_deps(&self, id: InterfaceId) -> impl Iterator<Item = InterfaceId> + '_ {
1468        self.interfaces[id]
1469            .types
1470            .iter()
1471            .filter_map(move |(_name, ty)| self.type_interface_dep(*ty))
1472    }
1473
1474    pub fn package_direct_deps(&self, id: PackageId) -> impl Iterator<Item = PackageId> + '_ {
1484        let pkg = &self.packages[id];
1485
1486        pkg.interfaces
1487            .iter()
1488            .flat_map(move |(_name, id)| self.interface_direct_deps(*id))
1489            .chain(pkg.worlds.iter().flat_map(move |(_name, id)| {
1490                let world = &self.worlds[*id];
1491                world
1492                    .imports
1493                    .iter()
1494                    .chain(world.exports.iter())
1495                    .filter_map(move |(_name, item)| match item {
1496                        WorldItem::Interface { id, .. } => Some(*id),
1497                        WorldItem::Function(_) => None,
1498                        WorldItem::Type(t) => self.type_interface_dep(*t),
1499                    })
1500            }))
1501            .filter_map(move |iface_id| {
1502                let pkg = self.interfaces[iface_id].package?;
1503                if pkg == id {
1504                    None
1505                } else {
1506                    Some(pkg)
1507                }
1508            })
1509    }
1510
1511    pub fn topological_packages(&self) -> Vec<PackageId> {
1517        let mut pushed = vec![false; self.packages.len()];
1518        let mut order = Vec::new();
1519        for (id, _) in self.packages.iter() {
1520            self.build_topological_package_ordering(id, &mut pushed, &mut order);
1521        }
1522        order
1523    }
1524
1525    fn build_topological_package_ordering(
1526        &self,
1527        id: PackageId,
1528        pushed: &mut Vec<bool>,
1529        order: &mut Vec<PackageId>,
1530    ) {
1531        if pushed[id.index()] {
1532            return;
1533        }
1534        for dep in self.package_direct_deps(id) {
1535            self.build_topological_package_ordering(dep, pushed, order);
1536        }
1537        order.push(id);
1538        pushed[id.index()] = true;
1539    }
1540
1541    #[doc(hidden)]
1542    pub fn assert_valid(&self) {
1543        let mut package_interfaces = Vec::new();
1544        let mut package_worlds = Vec::new();
1545        for (id, pkg) in self.packages.iter() {
1546            let mut interfaces = HashSet::new();
1547            for (name, iface) in pkg.interfaces.iter() {
1548                assert!(interfaces.insert(*iface));
1549                let iface = &self.interfaces[*iface];
1550                assert_eq!(name, iface.name.as_ref().unwrap());
1551                assert_eq!(iface.package.unwrap(), id);
1552            }
1553            package_interfaces.push(pkg.interfaces.values().copied().collect::<HashSet<_>>());
1554            let mut worlds = HashSet::new();
1555            for (name, world) in pkg.worlds.iter() {
1556                assert!(worlds.insert(*world));
1557                assert_eq!(
1558                    pkg.worlds.get_key_value(name),
1559                    Some((name, world)),
1560                    "`MutableKeys` impl may have been used to change a key's hash or equality"
1561                );
1562                let world = &self.worlds[*world];
1563                assert_eq!(*name, world.name);
1564                assert_eq!(world.package.unwrap(), id);
1565            }
1566            package_worlds.push(pkg.worlds.values().copied().collect::<HashSet<_>>());
1567        }
1568
1569        let mut interface_types = Vec::new();
1570        for (id, iface) in self.interfaces.iter() {
1571            assert!(self.packages.get(iface.package.unwrap()).is_some());
1572            if iface.name.is_some() {
1573                assert!(package_interfaces[iface.package.unwrap().index()].contains(&id));
1574            }
1575
1576            for (name, ty) in iface.types.iter() {
1577                let ty = &self.types[*ty];
1578                assert_eq!(ty.name.as_ref(), Some(name));
1579                assert_eq!(ty.owner, TypeOwner::Interface(id));
1580            }
1581            interface_types.push(iface.types.values().copied().collect::<HashSet<_>>());
1582            for (name, f) in iface.functions.iter() {
1583                assert_eq!(*name, f.name);
1584            }
1585        }
1586
1587        let mut world_types = Vec::new();
1588        for (id, world) in self.worlds.iter() {
1589            log::debug!("validating world {}", &world.name);
1590            if let Some(package) = world.package {
1591                assert!(self.packages.get(package).is_some());
1592                assert!(package_worlds[package.index()].contains(&id));
1593            }
1594            assert!(world.includes.is_empty());
1595
1596            let mut types = HashSet::new();
1597            for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1598                log::debug!("validating world item: {}", self.name_world_key(name));
1599                match item {
1600                    WorldItem::Interface { id, .. } => {
1601                        if matches!(name, WorldKey::Name(_)) {
1604                            assert_eq!(self.interfaces[*id].package, world.package);
1605                        }
1606                    }
1607                    WorldItem::Function(f) => {
1608                        assert!(!matches!(name, WorldKey::Interface(_)));
1609                        assert_eq!(f.name, name.clone().unwrap_name());
1610                    }
1611                    WorldItem::Type(ty) => {
1612                        assert!(!matches!(name, WorldKey::Interface(_)));
1613                        assert!(types.insert(*ty));
1614                        let ty = &self.types[*ty];
1615                        assert_eq!(ty.name, Some(name.clone().unwrap_name()));
1616                        assert_eq!(ty.owner, TypeOwner::World(id));
1617                    }
1618                }
1619            }
1620            self.assert_world_elaborated(world);
1621            world_types.push(types);
1622        }
1623
1624        for (ty_id, ty) in self.types.iter() {
1625            match ty.owner {
1626                TypeOwner::Interface(id) => {
1627                    assert!(self.interfaces.get(id).is_some());
1628                    assert!(interface_types[id.index()].contains(&ty_id));
1629                }
1630                TypeOwner::World(id) => {
1631                    assert!(self.worlds.get(id).is_some());
1632                    assert!(world_types[id.index()].contains(&ty_id));
1633                }
1634                TypeOwner::None => {}
1635            }
1636        }
1637
1638        self.assert_topologically_sorted();
1639    }
1640
1641    fn assert_topologically_sorted(&self) {
1642        let mut positions = IndexMap::new();
1643        for id in self.topological_packages() {
1644            let pkg = &self.packages[id];
1645            log::debug!("pkg {}", pkg.name);
1646            let prev = positions.insert(Some(id), IndexSet::new());
1647            assert!(prev.is_none());
1648        }
1649        positions.insert(None, IndexSet::new());
1650
1651        for (id, iface) in self.interfaces.iter() {
1652            log::debug!("iface {:?}", iface.name);
1653            let ok = positions.get_mut(&iface.package).unwrap().insert(id);
1654            assert!(ok);
1655        }
1656
1657        for (_, world) in self.worlds.iter() {
1658            log::debug!("world {:?}", world.name);
1659
1660            let my_package = world.package;
1661            let my_package_pos = positions.get_index_of(&my_package).unwrap();
1662
1663            for (_, item) in world.imports.iter().chain(&world.exports) {
1664                let id = match item {
1665                    WorldItem::Interface { id, .. } => *id,
1666                    _ => continue,
1667                };
1668                let other_package = self.interfaces[id].package;
1669                let other_package_pos = positions.get_index_of(&other_package).unwrap();
1670
1671                assert!(other_package_pos <= my_package_pos);
1672            }
1673        }
1674
1675        for (_id, ty) in self.types.iter() {
1676            log::debug!("type {:?} {:?}", ty.name, ty.owner);
1677            let other_id = match ty.kind {
1678                TypeDefKind::Type(Type::Id(ty)) => ty,
1679                _ => continue,
1680            };
1681            let other = &self.types[other_id];
1682            if ty.kind == other.kind {
1683                continue;
1684            }
1685            let my_interface = match ty.owner {
1686                TypeOwner::Interface(id) => id,
1687                _ => continue,
1688            };
1689            let other_interface = match other.owner {
1690                TypeOwner::Interface(id) => id,
1691                _ => continue,
1692            };
1693
1694            let my_package = self.interfaces[my_interface].package;
1695            let other_package = self.interfaces[other_interface].package;
1696            let my_package_pos = positions.get_index_of(&my_package).unwrap();
1697            let other_package_pos = positions.get_index_of(&other_package).unwrap();
1698
1699            if my_package_pos == other_package_pos {
1700                let interfaces = &positions[&my_package];
1701                let my_interface_pos = interfaces.get_index_of(&my_interface).unwrap();
1702                let other_interface_pos = interfaces.get_index_of(&other_interface).unwrap();
1703                assert!(other_interface_pos <= my_interface_pos);
1704            } else {
1705                assert!(other_package_pos < my_package_pos);
1706            }
1707        }
1708    }
1709
1710    fn assert_world_elaborated(&self, world: &World) {
1711        for (key, item) in world.imports.iter() {
1712            log::debug!(
1713                "asserting elaborated world import {}",
1714                self.name_world_key(key)
1715            );
1716            match item {
1717                WorldItem::Type(t) => self.assert_world_imports_type_deps(world, key, *t),
1718
1719                WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1721
1722                WorldItem::Interface { id, .. } => {
1724                    for dep in self.interface_direct_deps(*id) {
1725                        assert!(
1726                            world.imports.contains_key(&WorldKey::Interface(dep)),
1727                            "world import of {} is missing transitive dep of {}",
1728                            self.name_world_key(key),
1729                            self.id_of(dep).unwrap(),
1730                        );
1731                    }
1732                }
1733            }
1734        }
1735        for (key, item) in world.exports.iter() {
1736            log::debug!(
1737                "asserting elaborated world export {}",
1738                self.name_world_key(key)
1739            );
1740            match item {
1741                WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1743
1744                WorldItem::Interface { id, .. } => {
1748                    for dep in self.interface_direct_deps(*id) {
1749                        let dep_key = WorldKey::Interface(dep);
1750                        if world.exports.contains_key(&dep_key) {
1751                            continue;
1752                        }
1753                        self.foreach_interface_dep(dep, &mut |dep| {
1754                            let dep_key = WorldKey::Interface(dep);
1755                            assert!(
1756                                world.imports.contains_key(&dep_key),
1757                                "world should import {} (required by {})",
1758                                self.name_world_key(&dep_key),
1759                                self.name_world_key(key),
1760                            );
1761                            assert!(
1762                                !world.exports.contains_key(&dep_key),
1763                                "world should not export {} (required by {})",
1764                                self.name_world_key(&dep_key),
1765                                self.name_world_key(key),
1766                            );
1767                        });
1768                    }
1769                }
1770
1771                WorldItem::Type(_) => unreachable!(),
1773            }
1774        }
1775    }
1776
1777    fn assert_world_imports_type_deps(&self, world: &World, key: &WorldKey, ty: TypeId) {
1778        let ty = &self.types[ty];
1781        if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
1782            if let TypeOwner::Interface(id) = self.types[other].owner {
1783                let key = WorldKey::Interface(id);
1784                assert!(world.imports.contains_key(&key));
1785                return;
1786            }
1787        }
1788
1789        let mut visitor = MyVisit(self, Vec::new());
1793        visitor.visit_type_def(self, ty);
1794        for ty in visitor.1 {
1795            let ty = &self.types[ty];
1796            let Some(name) = ty.name.clone() else {
1797                continue;
1798            };
1799            let dep_key = WorldKey::Name(name);
1800            assert!(
1801                world.imports.contains_key(&dep_key),
1802                "world import `{}` should also force an import of `{}`",
1803                self.name_world_key(key),
1804                self.name_world_key(&dep_key),
1805            );
1806        }
1807
1808        struct MyVisit<'a>(&'a Resolve, Vec<TypeId>);
1809
1810        impl TypeIdVisitor for MyVisit<'_> {
1811            fn before_visit_type_id(&mut self, id: TypeId) -> bool {
1812                self.1.push(id);
1813                self.0.types[id].name.is_none()
1815            }
1816        }
1817    }
1818
1819    fn assert_world_function_imports_types(&self, world: &World, key: &WorldKey, func: &Function) {
1823        for ty in func
1824            .parameter_and_result_types()
1825            .chain(func.kind.resource().map(Type::Id))
1826        {
1827            let Type::Id(id) = ty else {
1828                continue;
1829            };
1830            self.assert_world_imports_type_deps(world, key, id);
1831        }
1832    }
1833
1834    fn include_stability(
1850        &self,
1851        stability: &Stability,
1852        pkg_id: &PackageId,
1853        span: Option<Span>,
1854    ) -> Result<bool> {
1855        let err = |msg: String| match span {
1856            Some(span) => Error::new(span, msg).into(),
1857            None => anyhow::Error::msg(msg),
1858        };
1859        Ok(match stability {
1860            Stability::Unknown => true,
1861            Stability::Stable { since, .. } => {
1864                let Some(p) = self.packages.get(*pkg_id) else {
1865                    return Ok(true);
1873                };
1874
1875                let package_version = p.name.version.as_ref().ok_or_else(|| {
1878                    err(format!(
1879                        "package [{}] contains a feature gate with a version \
1880                         specifier, so it must have a version",
1881                        p.name
1882                    ))
1883                })?;
1884
1885                if since > package_version {
1889                    return Err(err(format!(
1890                        "feature gate cannot reference unreleased version \
1891                        {since} of package [{}] (current version {package_version})",
1892                        p.name
1893                    )));
1894                }
1895
1896                true
1897            }
1898            Stability::Unstable { feature, .. } => {
1899                self.features.contains(feature) || self.all_features
1900            }
1901        })
1902    }
1903
1904    fn include_type(&self, ty: &TypeDef, pkgid: PackageId, span: Span) -> Result<bool> {
1907        self.include_stability(&ty.stability, &pkgid, Some(span))
1908            .with_context(|| {
1909                format!(
1910                    "failed to process feature gate for type [{}] in package [{}]",
1911                    ty.name.as_ref().map(String::as_str).unwrap_or("<unknown>"),
1912                    self.packages[pkgid].name,
1913                )
1914            })
1915    }
1916
1917    fn elaborate_world(&mut self, world_id: WorldId) -> Result<()> {
1929        let mut new_imports = IndexMap::new();
1933        let world = &self.worlds[world_id];
1934
1935        let sort_key = |resolve: &Resolve, item: &WorldItem| match item {
1958            WorldItem::Interface { .. } => 0,
1959            WorldItem::Type(ty) => {
1960                let ty = &resolve.types[*ty];
1961                match ty.kind {
1962                    TypeDefKind::Type(Type::Id(t)) if resolve.types[t].owner != ty.owner => 1,
1963                    _ => 2,
1964                }
1965            }
1966            WorldItem::Function(f) => {
1967                if f.kind.resource().is_none() {
1968                    3
1969                } else {
1970                    4
1971                }
1972            }
1973        };
1974
1975        let mut world_imports = world.imports.iter().collect::<Vec<_>>();
1978        world_imports.sort_by_key(|(_name, import)| sort_key(self, import));
1979        for (name, item) in world_imports {
1980            match item {
1981                WorldItem::Interface { id, stability } => {
1984                    self.elaborate_world_import(&mut new_imports, name.clone(), *id, &stability);
1985                }
1986
1987                WorldItem::Function(_) => {
1990                    let prev = new_imports.insert(name.clone(), item.clone());
1991                    assert!(prev.is_none());
1992                }
1993
1994                WorldItem::Type(id) => {
1998                    if let Some(dep) = self.type_interface_dep(*id) {
1999                        self.elaborate_world_import(
2000                            &mut new_imports,
2001                            WorldKey::Interface(dep),
2002                            dep,
2003                            &self.types[*id].stability,
2004                        );
2005                    }
2006                    let prev = new_imports.insert(name.clone(), item.clone());
2007                    assert!(prev.is_none());
2008                }
2009            }
2010        }
2011
2012        let mut new_exports = IndexMap::new();
2018        let mut export_interfaces = IndexMap::new();
2019        for (name, item) in world.exports.iter() {
2020            match item {
2021                WorldItem::Interface { id, stability } => {
2022                    let prev = export_interfaces.insert(*id, (name.clone(), stability));
2023                    assert!(prev.is_none());
2024                }
2025                WorldItem::Function(_) => {
2026                    let prev = new_exports.insert(name.clone(), item.clone());
2027                    assert!(prev.is_none());
2028                }
2029                WorldItem::Type(_) => unreachable!(),
2030            }
2031        }
2032
2033        self.elaborate_world_exports(&export_interfaces, &mut new_imports, &mut new_exports)?;
2034
2035        new_imports.sort_by_cached_key(|_name, import| sort_key(self, import));
2039
2040        log::trace!("imports = {:?}", new_imports);
2043        log::trace!("exports = {:?}", new_exports);
2044        let world = &mut self.worlds[world_id];
2045        world.imports = new_imports;
2046        world.exports = new_exports;
2047
2048        Ok(())
2049    }
2050
2051    fn elaborate_world_import(
2052        &self,
2053        imports: &mut IndexMap<WorldKey, WorldItem>,
2054        key: WorldKey,
2055        id: InterfaceId,
2056        stability: &Stability,
2057    ) {
2058        if imports.contains_key(&key) {
2059            return;
2060        }
2061        for dep in self.interface_direct_deps(id) {
2062            self.elaborate_world_import(imports, WorldKey::Interface(dep), dep, stability);
2063        }
2064        let prev = imports.insert(
2065            key,
2066            WorldItem::Interface {
2067                id,
2068                stability: stability.clone(),
2069            },
2070        );
2071        assert!(prev.is_none());
2072    }
2073
2074    fn elaborate_world_exports(
2121        &self,
2122        export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2123        imports: &mut IndexMap<WorldKey, WorldItem>,
2124        exports: &mut IndexMap<WorldKey, WorldItem>,
2125    ) -> Result<()> {
2126        let mut required_imports = HashSet::new();
2127        for (id, (key, stability)) in export_interfaces.iter() {
2128            let name = self.name_world_key(&key);
2129            let ok = add_world_export(
2130                self,
2131                imports,
2132                exports,
2133                export_interfaces,
2134                &mut required_imports,
2135                *id,
2136                key,
2137                true,
2138                stability,
2139            );
2140            if !ok {
2141                bail!(
2142                    InvalidTransitiveDependency(name),
2160                );
2161            }
2162        }
2163        return Ok(());
2164
2165        fn add_world_export(
2166            resolve: &Resolve,
2167            imports: &mut IndexMap<WorldKey, WorldItem>,
2168            exports: &mut IndexMap<WorldKey, WorldItem>,
2169            export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2170            required_imports: &mut HashSet<InterfaceId>,
2171            id: InterfaceId,
2172            key: &WorldKey,
2173            add_export: bool,
2174            stability: &Stability,
2175        ) -> bool {
2176            if exports.contains_key(key) {
2177                if add_export {
2178                    return true;
2179                } else {
2180                    return false;
2181                }
2182            }
2183            if !add_export && required_imports.contains(&id) {
2186                return true;
2187            }
2188            let ok = resolve.interface_direct_deps(id).all(|dep| {
2189                let key = WorldKey::Interface(dep);
2190                let add_export = add_export && export_interfaces.contains_key(&dep);
2191                add_world_export(
2192                    resolve,
2193                    imports,
2194                    exports,
2195                    export_interfaces,
2196                    required_imports,
2197                    dep,
2198                    &key,
2199                    add_export,
2200                    stability,
2201                )
2202            });
2203            if !ok {
2204                return false;
2205            }
2206            let item = WorldItem::Interface {
2207                id,
2208                stability: stability.clone(),
2209            };
2210            if add_export {
2211                if required_imports.contains(&id) {
2212                    return false;
2213                }
2214                exports.insert(key.clone(), item);
2215            } else {
2216                required_imports.insert(id);
2217                imports.insert(key.clone(), item);
2218            }
2219            true
2220        }
2221    }
2222
2223    pub fn merge_world_imports_based_on_semver(&mut self, world_id: WorldId) -> Result<()> {
2235        let world = &self.worlds[world_id];
2236
2237        let mut semver_tracks = HashMap::new();
2246        let mut to_remove = HashSet::new();
2247        for (key, _) in world.imports.iter() {
2248            let iface_id = match key {
2249                WorldKey::Interface(id) => *id,
2250                WorldKey::Name(_) => continue,
2251            };
2252            let (track, version) = match self.semver_track(iface_id) {
2253                Some(track) => track,
2254                None => continue,
2255            };
2256            log::debug!(
2257                "{} is on track {}/{}",
2258                self.id_of(iface_id).unwrap(),
2259                track.0,
2260                track.1,
2261            );
2262            match semver_tracks.entry(track.clone()) {
2263                hash_map::Entry::Vacant(e) => {
2264                    e.insert((version, iface_id));
2265                }
2266                hash_map::Entry::Occupied(mut e) => match version.cmp(&e.get().0) {
2267                    Ordering::Greater => {
2268                        to_remove.insert(e.get().1);
2269                        e.insert((version, iface_id));
2270                    }
2271                    Ordering::Equal => {}
2272                    Ordering::Less => {
2273                        to_remove.insert(iface_id);
2274                    }
2275                },
2276            }
2277        }
2278
2279        let mut replacements = HashMap::new();
2282        for id in to_remove {
2283            let (track, _) = self.semver_track(id).unwrap();
2284            let (_, latest) = semver_tracks[&track];
2285            let prev = replacements.insert(id, latest);
2286            assert!(prev.is_none());
2287        }
2288
2289        for (to_replace, replace_with) in replacements.iter() {
2294            self.merge_world_item(
2295                &WorldItem::Interface {
2296                    id: *to_replace,
2297                    stability: Default::default(),
2298                },
2299                &WorldItem::Interface {
2300                    id: *replace_with,
2301                    stability: Default::default(),
2302                },
2303            )
2304            .with_context(|| {
2305                let old_name = self.id_of(*to_replace).unwrap();
2306                let new_name = self.id_of(*replace_with).unwrap();
2307                format!(
2308                    "failed to upgrade `{old_name}` to `{new_name}`, was \
2309                     this semver-compatible update not semver compatible?"
2310                )
2311            })?;
2312        }
2313
2314        for (to_replace, replace_with) in replacements.iter() {
2315            log::debug!(
2316                "REPLACE {} => {}",
2317                self.id_of(*to_replace).unwrap(),
2318                self.id_of(*replace_with).unwrap(),
2319            );
2320        }
2321
2322        for (key, item) in mem::take(&mut self.worlds[world_id].imports) {
2331            if let WorldItem::Interface { id, .. } = item {
2332                if replacements.contains_key(&id) {
2333                    continue;
2334                }
2335            }
2336
2337            self.update_interface_deps_of_world_item(&item, &replacements);
2338
2339            let prev = self.worlds[world_id].imports.insert(key, item);
2340            assert!(prev.is_none());
2341        }
2342        for (key, item) in mem::take(&mut self.worlds[world_id].exports) {
2343            self.update_interface_deps_of_world_item(&item, &replacements);
2344            let prev = self.worlds[world_id].exports.insert(key, item);
2345            assert!(prev.is_none());
2346        }
2347
2348        let ids = self.worlds.iter().map(|(id, _)| id).collect::<Vec<_>>();
2354        for world_id in ids {
2355            self.elaborate_world(world_id).with_context(|| {
2356                let name = &self.worlds[world_id].name;
2357                format!(
2358                    "failed to elaborate world `{name}` after deduplicating imports \
2359                     based on semver"
2360                )
2361            })?;
2362        }
2363
2364        #[cfg(debug_assertions)]
2365        self.assert_valid();
2366
2367        Ok(())
2368    }
2369
2370    fn update_interface_deps_of_world_item(
2371        &mut self,
2372        item: &WorldItem,
2373        replacements: &HashMap<InterfaceId, InterfaceId>,
2374    ) {
2375        match *item {
2376            WorldItem::Type(t) => self.update_interface_dep_of_type(t, &replacements),
2377            WorldItem::Interface { id, .. } => {
2378                let types = self.interfaces[id]
2379                    .types
2380                    .values()
2381                    .copied()
2382                    .collect::<Vec<_>>();
2383                for ty in types {
2384                    self.update_interface_dep_of_type(ty, &replacements);
2385                }
2386            }
2387            WorldItem::Function(_) => {}
2388        }
2389    }
2390
2391    fn semver_track(&self, id: InterfaceId) -> Option<((PackageName, String), &Version)> {
2402        let iface = &self.interfaces[id];
2403        let pkg = &self.packages[iface.package?];
2404        let version = pkg.name.version.as_ref()?;
2405        let mut name = pkg.name.clone();
2406        name.version = Some(PackageName::version_compat_track(version));
2407        Some(((name, iface.name.clone()?), version))
2408    }
2409
2410    fn update_interface_dep_of_type(
2414        &mut self,
2415        ty: TypeId,
2416        replacements: &HashMap<InterfaceId, InterfaceId>,
2417    ) {
2418        let to_replace = match self.type_interface_dep(ty) {
2419            Some(id) => id,
2420            None => return,
2421        };
2422        let replace_with = match replacements.get(&to_replace) {
2423            Some(id) => id,
2424            None => return,
2425        };
2426        let dep = match self.types[ty].kind {
2427            TypeDefKind::Type(Type::Id(id)) => id,
2428            _ => return,
2429        };
2430        let name = self.types[dep].name.as_ref().unwrap();
2431        let replacement_id = self.interfaces[*replace_with].types[name];
2434        self.types[ty].kind = TypeDefKind::Type(Type::Id(replacement_id));
2435    }
2436
2437    pub fn wasm_import_name(
2444        &self,
2445        mangling: ManglingAndAbi,
2446        import: WasmImport<'_>,
2447    ) -> (String, String) {
2448        match mangling {
2449            ManglingAndAbi::Standard32 => match import {
2450                WasmImport::Func { interface, func } => {
2451                    let module = match interface {
2452                        Some(key) => format!("cm32p2|{}", self.name_canonicalized_world_key(key)),
2453                        None => format!("cm32p2"),
2454                    };
2455                    (module, func.name.clone())
2456                }
2457                WasmImport::ResourceIntrinsic {
2458                    interface,
2459                    resource,
2460                    intrinsic,
2461                } => {
2462                    let name = self.types[resource].name.as_ref().unwrap();
2463                    let (prefix, name) = match intrinsic {
2464                        ResourceIntrinsic::ImportedDrop => ("", format!("{name}_drop")),
2465                        ResourceIntrinsic::ExportedDrop => ("_ex_", format!("{name}_drop")),
2466                        ResourceIntrinsic::ExportedNew => ("_ex_", format!("{name}_new")),
2467                        ResourceIntrinsic::ExportedRep => ("_ex_", format!("{name}_rep")),
2468                    };
2469                    let module = match interface {
2470                        Some(key) => {
2471                            format!("cm32p2|{prefix}{}", self.name_canonicalized_world_key(key))
2472                        }
2473                        None => {
2474                            assert_eq!(prefix, "");
2475                            format!("cm32p2")
2476                        }
2477                    };
2478                    (module, name)
2479                }
2480            },
2481            ManglingAndAbi::Legacy(abi) => match import {
2482                WasmImport::Func { interface, func } => {
2483                    let module = match interface {
2484                        Some(key) => self.name_world_key(key),
2485                        None => format!("$root"),
2486                    };
2487                    (module, format!("{}{}", abi.import_prefix(), func.name))
2488                }
2489                WasmImport::ResourceIntrinsic {
2490                    interface,
2491                    resource,
2492                    intrinsic,
2493                } => {
2494                    let name = self.types[resource].name.as_ref().unwrap();
2495                    let (prefix, name) = match intrinsic {
2496                        ResourceIntrinsic::ImportedDrop => ("", format!("[resource-drop]{name}")),
2497                        ResourceIntrinsic::ExportedDrop => {
2498                            ("[export]", format!("[resource-drop]{name}"))
2499                        }
2500                        ResourceIntrinsic::ExportedNew => {
2501                            ("[export]", format!("[resource-new]{name}"))
2502                        }
2503                        ResourceIntrinsic::ExportedRep => {
2504                            ("[export]", format!("[resource-rep]{name}"))
2505                        }
2506                    };
2507                    let module = match interface {
2508                        Some(key) => format!("{prefix}{}", self.name_world_key(key)),
2509                        None => {
2510                            assert_eq!(prefix, "");
2511                            format!("$root")
2512                        }
2513                    };
2514                    (module, format!("{}{name}", abi.import_prefix()))
2515                }
2516            },
2517        }
2518    }
2519
2520    pub fn wasm_export_name(&self, mangling: ManglingAndAbi, export: WasmExport<'_>) -> String {
2524        match mangling {
2525            ManglingAndAbi::Standard32 => match export {
2526                WasmExport::Func {
2527                    interface,
2528                    func,
2529                    kind,
2530                } => {
2531                    let mut name = String::from("cm32p2|");
2532                    if let Some(interface) = interface {
2533                        let s = self.name_canonicalized_world_key(interface);
2534                        name.push_str(&s);
2535                    }
2536                    name.push_str("|");
2537                    name.push_str(&func.name);
2538                    match kind {
2539                        WasmExportKind::Normal => {}
2540                        WasmExportKind::PostReturn => name.push_str("_post"),
2541                        WasmExportKind::Callback => todo!(
2542                            "not yet supported: \
2543                             async callback functions using standard name mangling"
2544                        ),
2545                    }
2546                    name
2547                }
2548                WasmExport::ResourceDtor {
2549                    interface,
2550                    resource,
2551                } => {
2552                    let name = self.types[resource].name.as_ref().unwrap();
2553                    let interface = self.name_canonicalized_world_key(interface);
2554                    format!("cm32p2|{interface}|{name}_dtor")
2555                }
2556                WasmExport::Memory => "cm32p2_memory".to_string(),
2557                WasmExport::Initialize => "cm32p2_initialize".to_string(),
2558                WasmExport::Realloc => "cm32p2_realloc".to_string(),
2559            },
2560            ManglingAndAbi::Legacy(abi) => match export {
2561                WasmExport::Func {
2562                    interface,
2563                    func,
2564                    kind,
2565                } => {
2566                    let mut name = abi.export_prefix().to_string();
2567                    match kind {
2568                        WasmExportKind::Normal => {}
2569                        WasmExportKind::PostReturn => name.push_str("cabi_post_"),
2570                        WasmExportKind::Callback => {
2571                            assert!(matches!(abi, LiftLowerAbi::AsyncCallback));
2572                            name = format!("[callback]{name}")
2573                        }
2574                    }
2575                    if let Some(interface) = interface {
2576                        let s = self.name_world_key(interface);
2577                        name.push_str(&s);
2578                        name.push_str("#");
2579                    }
2580                    name.push_str(&func.name);
2581                    name
2582                }
2583                WasmExport::ResourceDtor {
2584                    interface,
2585                    resource,
2586                } => {
2587                    let name = self.types[resource].name.as_ref().unwrap();
2588                    let interface = self.name_world_key(interface);
2589                    format!("{}{interface}#[dtor]{name}", abi.export_prefix())
2590                }
2591                WasmExport::Memory => "memory".to_string(),
2592                WasmExport::Initialize => "_initialize".to_string(),
2593                WasmExport::Realloc => "cabi_realloc".to_string(),
2594            },
2595        }
2596    }
2597}
2598
2599#[derive(Debug)]
2601pub enum WasmImport<'a> {
2602    Func {
2604        interface: Option<&'a WorldKey>,
2609
2610        func: &'a Function,
2612    },
2613
2614    ResourceIntrinsic {
2616        interface: Option<&'a WorldKey>,
2618
2619        resource: TypeId,
2621
2622        intrinsic: ResourceIntrinsic,
2624    },
2625}
2626
2627#[derive(Debug)]
2630pub enum ResourceIntrinsic {
2631    ImportedDrop,
2632    ExportedDrop,
2633    ExportedNew,
2634    ExportedRep,
2635}
2636
2637#[derive(Debug)]
2640pub enum WasmExportKind {
2641    Normal,
2643
2644    PostReturn,
2646
2647    Callback,
2649}
2650
2651#[derive(Debug)]
2654pub enum WasmExport<'a> {
2655    Func {
2657        interface: Option<&'a WorldKey>,
2660
2661        func: &'a Function,
2663
2664        kind: WasmExportKind,
2666    },
2667
2668    ResourceDtor {
2670        interface: &'a WorldKey,
2672        resource: TypeId,
2674    },
2675
2676    Memory,
2678
2679    Initialize,
2681
2682    Realloc,
2684}
2685
2686#[derive(Default)]
2689pub struct Remap {
2690    pub types: Vec<Option<TypeId>>,
2691    pub interfaces: Vec<Option<InterfaceId>>,
2692    pub worlds: Vec<Option<WorldId>>,
2693    pub packages: Vec<PackageId>,
2694
2695    own_handles: HashMap<TypeId, TypeId>,
2705
2706    type_has_borrow: Vec<Option<bool>>,
2707}
2708
2709fn apply_map<T>(map: &[Option<Id<T>>], id: Id<T>, desc: &str, span: Option<Span>) -> Result<Id<T>> {
2710    match map.get(id.index()) {
2711        Some(Some(id)) => Ok(*id),
2712        Some(None) => {
2713            let msg = format!(
2714                "found a reference to a {desc} which is excluded \
2715                 due to its feature not being activated"
2716            );
2717            match span {
2718                Some(span) => Err(Error::new(span, msg).into()),
2719                None => bail!("{msg}"),
2720            }
2721        }
2722        None => panic!("request to remap a {desc} that has not yet been registered"),
2723    }
2724}
2725
2726impl Remap {
2727    pub fn map_type(&self, id: TypeId, span: Option<Span>) -> Result<TypeId> {
2728        apply_map(&self.types, id, "type", span)
2729    }
2730
2731    pub fn map_interface(&self, id: InterfaceId, span: Option<Span>) -> Result<InterfaceId> {
2732        apply_map(&self.interfaces, id, "interface", span)
2733    }
2734
2735    pub fn map_world(&self, id: WorldId, span: Option<Span>) -> Result<WorldId> {
2736        apply_map(&self.worlds, id, "world", span)
2737    }
2738
2739    fn append(
2740        &mut self,
2741        resolve: &mut Resolve,
2742        unresolved: UnresolvedPackage,
2743    ) -> Result<PackageId> {
2744        let pkgid = resolve.packages.alloc(Package {
2745            name: unresolved.name.clone(),
2746            docs: unresolved.docs.clone(),
2747            interfaces: Default::default(),
2748            worlds: Default::default(),
2749        });
2750        let prev = resolve.package_names.insert(unresolved.name.clone(), pkgid);
2751        if let Some(prev) = prev {
2752            resolve.package_names.insert(unresolved.name.clone(), prev);
2753            bail!(
2754                "attempting to re-add package `{}` when it's already present in this `Resolve`",
2755                unresolved.name,
2756            );
2757        }
2758
2759        self.process_foreign_deps(resolve, pkgid, &unresolved)?;
2760
2761        let foreign_types = self.types.len();
2762        let foreign_interfaces = self.interfaces.len();
2763        let foreign_worlds = self.worlds.len();
2764
2765        assert_eq!(unresolved.types.len(), unresolved.type_spans.len());
2771        for ((id, mut ty), span) in unresolved
2772            .types
2773            .into_iter()
2774            .zip(&unresolved.type_spans)
2775            .skip(foreign_types)
2776        {
2777            if !resolve.include_type(&ty, pkgid, *span)? {
2778                self.types.push(None);
2779                continue;
2780            }
2781
2782            self.update_typedef(resolve, &mut ty, Some(*span))?;
2783            let new_id = resolve.types.alloc(ty);
2784            assert_eq!(self.types.len(), id.index());
2785
2786            let new_id = match resolve.types[new_id] {
2787                TypeDef {
2792                    name: None,
2793                    owner: TypeOwner::None,
2794                    kind: TypeDefKind::Handle(Handle::Own(id)),
2795                    docs: _,
2796                    stability: _,
2797                } => *self.own_handles.entry(id).or_insert(new_id),
2798
2799                _ => new_id,
2802            };
2803            self.types.push(Some(new_id));
2804        }
2805
2806        assert_eq!(
2809            unresolved.interfaces.len(),
2810            unresolved.interface_spans.len()
2811        );
2812        for ((id, mut iface), span) in unresolved
2813            .interfaces
2814            .into_iter()
2815            .zip(&unresolved.interface_spans)
2816            .skip(foreign_interfaces)
2817        {
2818            if !resolve
2819                .include_stability(&iface.stability, &pkgid, Some(span.span))
2820                .with_context(|| {
2821                    format!(
2822                        "failed to process feature gate for interface [{}] in package [{}]",
2823                        iface
2824                            .name
2825                            .as_ref()
2826                            .map(String::as_str)
2827                            .unwrap_or("<unknown>"),
2828                        resolve.packages[pkgid].name,
2829                    )
2830                })?
2831            {
2832                self.interfaces.push(None);
2833                continue;
2834            }
2835            assert!(iface.package.is_none());
2836            iface.package = Some(pkgid);
2837            self.update_interface(resolve, &mut iface, Some(span))?;
2838            let new_id = resolve.interfaces.alloc(iface);
2839            assert_eq!(self.interfaces.len(), id.index());
2840            self.interfaces.push(Some(new_id));
2841        }
2842
2843        for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2846            let id = match id {
2847                Some(id) => *id,
2848                None => continue,
2849            };
2850            match &mut resolve.types[id].owner {
2851                TypeOwner::Interface(id) => {
2852                    let span = unresolved.type_spans[i];
2853                    *id = self.map_interface(*id, Some(span))
2854                        .with_context(|| {
2855                            "this type is not gated by a feature but its interface is gated by a feature"
2856                        })?;
2857                }
2858                TypeOwner::World(_) | TypeOwner::None => {}
2859            }
2860        }
2861
2862        assert_eq!(unresolved.worlds.len(), unresolved.world_spans.len());
2870        for ((id, mut world), span) in unresolved
2871            .worlds
2872            .into_iter()
2873            .zip(&unresolved.world_spans)
2874            .skip(foreign_worlds)
2875        {
2876            if !resolve
2877                .include_stability(&world.stability, &pkgid, Some(span.span))
2878                .with_context(|| {
2879                    format!(
2880                        "failed to process feature gate for world [{}] in package [{}]",
2881                        world.name, resolve.packages[pkgid].name,
2882                    )
2883                })?
2884            {
2885                self.worlds.push(None);
2886                continue;
2887            }
2888            self.update_world(&mut world, resolve, &pkgid, &span)?;
2889
2890            let new_id = resolve.worlds.alloc(world);
2891            assert_eq!(self.worlds.len(), id.index());
2892            self.worlds.push(Some(new_id));
2893
2894            resolve.elaborate_world(new_id).with_context(|| {
2895                Error::new(
2896                    span.span,
2897                    format!(
2898                        "failed to elaborate world imports/exports of `{}`",
2899                        resolve.worlds[new_id].name
2900                    ),
2901                )
2902            })?;
2903        }
2904
2905        for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2907            let id = match id {
2908                Some(id) => *id,
2909                None => continue,
2910            };
2911            match &mut resolve.types[id].owner {
2912                TypeOwner::World(id) => {
2913                    let span = unresolved.type_spans[i];
2914                    *id = self.map_world(*id, Some(span))
2915                        .with_context(|| {
2916                            "this type is not gated by a feature but its interface is gated by a feature"
2917                        })?;
2918                }
2919                TypeOwner::Interface(_) | TypeOwner::None => {}
2920            }
2921        }
2922
2923        for id in self.interfaces.iter().skip(foreign_interfaces) {
2925            let id = match id {
2926                Some(id) => *id,
2927                None => continue,
2928            };
2929            let iface = &mut resolve.interfaces[id];
2930            iface.package = Some(pkgid);
2931            if let Some(name) = &iface.name {
2932                let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), id);
2933                assert!(prev.is_none());
2934            }
2935        }
2936        for id in self.worlds.iter().skip(foreign_worlds) {
2937            let id = match id {
2938                Some(id) => *id,
2939                None => continue,
2940            };
2941            let world = &mut resolve.worlds[id];
2942            world.package = Some(pkgid);
2943            let prev = resolve.packages[pkgid]
2944                .worlds
2945                .insert(world.name.clone(), id);
2946            assert!(prev.is_none());
2947        }
2948        Ok(pkgid)
2949    }
2950
2951    fn process_foreign_deps(
2952        &mut self,
2953        resolve: &mut Resolve,
2954        pkgid: PackageId,
2955        unresolved: &UnresolvedPackage,
2956    ) -> Result<()> {
2957        let mut world_to_package = HashMap::new();
2960        let mut interface_to_package = HashMap::new();
2961        for (i, (pkg_name, worlds_or_ifaces)) in unresolved.foreign_deps.iter().enumerate() {
2962            for (name, item) in worlds_or_ifaces {
2963                match item {
2964                    AstItem::Interface(unresolved_interface_id) => {
2965                        let prev = interface_to_package.insert(
2966                            *unresolved_interface_id,
2967                            (pkg_name, name, unresolved.foreign_dep_spans[i]),
2968                        );
2969                        assert!(prev.is_none());
2970                    }
2971                    AstItem::World(unresolved_world_id) => {
2972                        let prev = world_to_package.insert(
2973                            *unresolved_world_id,
2974                            (pkg_name, name, unresolved.foreign_dep_spans[i]),
2975                        );
2976                        assert!(prev.is_none());
2977                    }
2978                }
2979            }
2980        }
2981
2982        self.process_foreign_interfaces(unresolved, &interface_to_package, resolve)?;
2986
2987        self.process_foreign_worlds(unresolved, &world_to_package, resolve)?;
2991
2992        self.process_foreign_types(unresolved, pkgid, resolve)?;
2995
2996        for (id, span) in unresolved.required_resource_types.iter() {
2997            let Ok(mut id) = self.map_type(*id, Some(*span)) else {
3002                continue;
3003            };
3004            loop {
3005                match resolve.types[id].kind {
3006                    TypeDefKind::Type(Type::Id(i)) => id = i,
3007                    TypeDefKind::Resource => break,
3008                    _ => bail!(Error::new(
3009                        *span,
3010                        format!("type used in a handle must be a resource"),
3011                    )),
3012                }
3013            }
3014        }
3015
3016        #[cfg(debug_assertions)]
3017        resolve.assert_valid();
3018
3019        Ok(())
3020    }
3021
3022    fn process_foreign_interfaces(
3023        &mut self,
3024        unresolved: &UnresolvedPackage,
3025        interface_to_package: &HashMap<InterfaceId, (&PackageName, &String, Span)>,
3026        resolve: &mut Resolve,
3027    ) -> Result<(), anyhow::Error> {
3028        for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() {
3029            let (pkg_name, interface, span) = match interface_to_package.get(&unresolved_iface_id) {
3030                Some(items) => *items,
3031                None => break,
3035            };
3036            let pkgid = resolve
3037                .package_names
3038                .get(pkg_name)
3039                .copied()
3040                .ok_or_else(|| {
3041                    PackageNotFoundError::new(
3042                        span,
3043                        pkg_name.clone(),
3044                        resolve.package_names.keys().cloned().collect(),
3045                    )
3046                })?;
3047
3048            assert!(unresolved_iface.functions.is_empty());
3050
3051            let pkg = &resolve.packages[pkgid];
3052            let span = &unresolved.interface_spans[unresolved_iface_id.index()];
3053            let iface_id = pkg
3054                .interfaces
3055                .get(interface)
3056                .copied()
3057                .ok_or_else(|| Error::new(span.span, "interface not found in package"))?;
3058            assert_eq!(self.interfaces.len(), unresolved_iface_id.index());
3059            self.interfaces.push(Some(iface_id));
3060        }
3061        for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) {
3062            assert!(
3063                interface_to_package.get(&id).is_none(),
3064                "found foreign interface after local interface"
3065            );
3066        }
3067        Ok(())
3068    }
3069
3070    fn process_foreign_worlds(
3071        &mut self,
3072        unresolved: &UnresolvedPackage,
3073        world_to_package: &HashMap<WorldId, (&PackageName, &String, Span)>,
3074        resolve: &mut Resolve,
3075    ) -> Result<(), anyhow::Error> {
3076        for (unresolved_world_id, _) in unresolved.worlds.iter() {
3077            let (pkg_name, world, span) = match world_to_package.get(&unresolved_world_id) {
3078                Some(items) => *items,
3079                None => break,
3082            };
3083
3084            let pkgid = resolve
3085                .package_names
3086                .get(pkg_name)
3087                .copied()
3088                .ok_or_else(|| Error::new(span, "package not found"))?;
3089            let pkg = &resolve.packages[pkgid];
3090            let span = &unresolved.world_spans[unresolved_world_id.index()];
3091            let world_id = pkg
3092                .worlds
3093                .get(world)
3094                .copied()
3095                .ok_or_else(|| Error::new(span.span, "world not found in package"))?;
3096            assert_eq!(self.worlds.len(), unresolved_world_id.index());
3097            self.worlds.push(Some(world_id));
3098        }
3099        for (id, _) in unresolved.worlds.iter().skip(self.worlds.len()) {
3100            assert!(
3101                world_to_package.get(&id).is_none(),
3102                "found foreign world after local world"
3103            );
3104        }
3105        Ok(())
3106    }
3107
3108    fn process_foreign_types(
3109        &mut self,
3110        unresolved: &UnresolvedPackage,
3111        pkgid: PackageId,
3112        resolve: &mut Resolve,
3113    ) -> Result<(), anyhow::Error> {
3114        for ((unresolved_type_id, unresolved_ty), span) in
3115            unresolved.types.iter().zip(&unresolved.type_spans)
3116        {
3117            match unresolved_ty.kind {
3121                TypeDefKind::Unknown => {}
3122                _ => break,
3123            }
3124
3125            if !resolve.include_type(unresolved_ty, pkgid, *span)? {
3126                self.types.push(None);
3127                continue;
3128            }
3129
3130            let unresolved_iface_id = match unresolved_ty.owner {
3131                TypeOwner::Interface(id) => id,
3132                _ => unreachable!(),
3133            };
3134            let iface_id = self.map_interface(unresolved_iface_id, None)?;
3135            let name = unresolved_ty.name.as_ref().unwrap();
3136            let span = unresolved.unknown_type_spans[unresolved_type_id.index()];
3137            let type_id = *resolve.interfaces[iface_id]
3138                .types
3139                .get(name)
3140                .ok_or_else(|| {
3141                    Error::new(span, format!("type `{name}` not defined in interface"))
3142                })?;
3143            assert_eq!(self.types.len(), unresolved_type_id.index());
3144            self.types.push(Some(type_id));
3145        }
3146        for (_, ty) in unresolved.types.iter().skip(self.types.len()) {
3147            if let TypeDefKind::Unknown = ty.kind {
3148                panic!("unknown type after defined type");
3149            }
3150        }
3151        Ok(())
3152    }
3153
3154    fn update_typedef(
3155        &mut self,
3156        resolve: &mut Resolve,
3157        ty: &mut TypeDef,
3158        span: Option<Span>,
3159    ) -> Result<()> {
3160        use crate::TypeDefKind::*;
3163        match &mut ty.kind {
3164            Handle(handle) => match handle {
3165                crate::Handle::Own(ty) | crate::Handle::Borrow(ty) => {
3166                    self.update_type_id(ty, span)?
3167                }
3168            },
3169            Resource => {}
3170            Record(r) => {
3171                for field in r.fields.iter_mut() {
3172                    self.update_ty(resolve, &mut field.ty, span)
3173                        .with_context(|| format!("failed to update field `{}`", field.name))?;
3174                }
3175            }
3176            Tuple(t) => {
3177                for ty in t.types.iter_mut() {
3178                    self.update_ty(resolve, ty, span)?;
3179                }
3180            }
3181            Variant(v) => {
3182                for case in v.cases.iter_mut() {
3183                    if let Some(t) = &mut case.ty {
3184                        self.update_ty(resolve, t, span)?;
3185                    }
3186                }
3187            }
3188            Option(t) | List(t, ..) | FixedSizeList(t, ..) | Future(Some(t)) | Stream(Some(t)) => {
3189                self.update_ty(resolve, t, span)?
3190            }
3191            Result(r) => {
3192                if let Some(ty) = &mut r.ok {
3193                    self.update_ty(resolve, ty, span)?;
3194                }
3195                if let Some(ty) = &mut r.err {
3196                    self.update_ty(resolve, ty, span)?;
3197                }
3198            }
3199
3200            Type(crate::Type::Id(id)) => self.update_type_id(id, span)?,
3205            Type(_) => {}
3206
3207            Flags(_) | Enum(_) | Future(None) | Stream(None) => {}
3209
3210            Unknown => unreachable!(),
3211        }
3212
3213        Ok(())
3214    }
3215
3216    fn update_ty(
3217        &mut self,
3218        resolve: &mut Resolve,
3219        ty: &mut Type,
3220        span: Option<Span>,
3221    ) -> Result<()> {
3222        let id = match ty {
3223            Type::Id(id) => id,
3224            _ => return Ok(()),
3225        };
3226        self.update_type_id(id, span)?;
3227
3228        let mut cur = *id;
3233        let points_to_resource = loop {
3234            match resolve.types[cur].kind {
3235                TypeDefKind::Type(Type::Id(id)) => cur = id,
3236                TypeDefKind::Resource => break true,
3237                _ => break false,
3238            }
3239        };
3240
3241        if points_to_resource {
3242            *id = *self.own_handles.entry(*id).or_insert_with(|| {
3243                resolve.types.alloc(TypeDef {
3244                    name: None,
3245                    owner: TypeOwner::None,
3246                    kind: TypeDefKind::Handle(Handle::Own(*id)),
3247                    docs: Default::default(),
3248                    stability: Default::default(),
3249                })
3250            });
3251        }
3252        Ok(())
3253    }
3254
3255    fn update_type_id(&self, id: &mut TypeId, span: Option<Span>) -> Result<()> {
3256        *id = self.map_type(*id, span)?;
3257        Ok(())
3258    }
3259
3260    fn update_interface(
3261        &mut self,
3262        resolve: &mut Resolve,
3263        iface: &mut Interface,
3264        spans: Option<&InterfaceSpan>,
3265    ) -> Result<()> {
3266        iface.types.retain(|_, ty| self.types[ty.index()].is_some());
3267        let iface_pkg_id = iface.package.as_ref().unwrap_or_else(|| {
3268            panic!(
3269                "unexpectedly missing package on interface [{}]",
3270                iface
3271                    .name
3272                    .as_ref()
3273                    .map(String::as_str)
3274                    .unwrap_or("<unknown>"),
3275            )
3276        });
3277
3278        for (_name, ty) in iface.types.iter_mut() {
3281            self.update_type_id(ty, spans.map(|s| s.span))?;
3282        }
3283        if let Some(spans) = spans {
3284            assert_eq!(iface.functions.len(), spans.funcs.len());
3285        }
3286        for (i, (func_name, func)) in iface.functions.iter_mut().enumerate() {
3287            let span = spans.map(|s| s.funcs[i]);
3288            if !resolve
3289                .include_stability(&func.stability, iface_pkg_id, span)
3290                .with_context(|| {
3291                    format!(
3292                        "failed to process feature gate for function [{func_name}] in package [{}]",
3293                        resolve.packages[*iface_pkg_id].name,
3294                    )
3295                })?
3296            {
3297                continue;
3298            }
3299            self.update_function(resolve, func, span)
3300                .with_context(|| format!("failed to update function `{}`", func.name))?;
3301        }
3302
3303        for (name, func) in mem::take(&mut iface.functions) {
3306            if resolve.include_stability(&func.stability, iface_pkg_id, None)? {
3307                iface.functions.insert(name, func);
3308            }
3309        }
3310
3311        Ok(())
3312    }
3313
3314    fn update_function(
3315        &mut self,
3316        resolve: &mut Resolve,
3317        func: &mut Function,
3318        span: Option<Span>,
3319    ) -> Result<()> {
3320        if let Some(id) = func.kind.resource_mut() {
3321            self.update_type_id(id, span)?;
3322        }
3323        for (_, ty) in func.params.iter_mut() {
3324            self.update_ty(resolve, ty, span)?;
3325        }
3326        if let Some(ty) = &mut func.result {
3327            self.update_ty(resolve, ty, span)?;
3328        }
3329
3330        if let Some(ty) = &func.result {
3331            if self.type_has_borrow(resolve, ty) {
3332                match span {
3333                    Some(span) => {
3334                        bail!(Error::new(
3335                            span,
3336                            format!(
3337                                "function returns a type which contains \
3338                                 a `borrow<T>` which is not supported"
3339                            )
3340                        ))
3341                    }
3342                    None => unreachable!(),
3343                }
3344            }
3345        }
3346
3347        Ok(())
3348    }
3349
3350    fn update_world(
3351        &mut self,
3352        world: &mut World,
3353        resolve: &mut Resolve,
3354        pkg_id: &PackageId,
3355        spans: &WorldSpan,
3356    ) -> Result<()> {
3357        assert_eq!(world.imports.len(), spans.imports.len());
3358        assert_eq!(world.exports.len(), spans.exports.len());
3359
3360        let imports = mem::take(&mut world.imports).into_iter();
3364        let imports = imports.zip(&spans.imports).map(|p| (p, true));
3365        let exports = mem::take(&mut world.exports).into_iter();
3366        let exports = exports.zip(&spans.exports).map(|p| (p, false));
3367        for (((mut name, mut item), span), import) in imports.chain(exports) {
3368            if let WorldItem::Type(id) = &mut item {
3371                *id = self.map_type(*id, Some(*span))?;
3372            }
3373            let stability = item.stability(resolve);
3374            if !resolve
3375                .include_stability(stability, pkg_id, Some(*span))
3376                .with_context(|| format!("failed to process world item in `{}`", world.name))?
3377            {
3378                continue;
3379            }
3380            self.update_world_key(&mut name, Some(*span))?;
3381            match &mut item {
3382                WorldItem::Interface { id, .. } => {
3383                    *id = self.map_interface(*id, Some(*span))?;
3384                }
3385                WorldItem::Function(f) => {
3386                    self.update_function(resolve, f, Some(*span))?;
3387                }
3388                WorldItem::Type(_) => {
3389                    }
3391            }
3392
3393            let dst = if import {
3394                &mut world.imports
3395            } else {
3396                &mut world.exports
3397            };
3398            let prev = dst.insert(name, item);
3399            assert!(prev.is_none());
3400        }
3401
3402        assert_eq!(world.includes.len(), spans.includes.len());
3405        let includes = mem::take(&mut world.includes);
3406        let include_names = mem::take(&mut world.include_names);
3407        for (((stability, include_world), span), names) in includes
3408            .into_iter()
3409            .zip(&spans.includes)
3410            .zip(&include_names)
3411        {
3412            if !resolve
3413                .include_stability(&stability, pkg_id, Some(*span))
3414                .with_context(|| {
3415                    format!(
3416                        "failed to process feature gate for included world [{}] in package [{}]",
3417                        resolve.worlds[include_world].name.as_str(),
3418                        resolve.packages[*pkg_id].name
3419                    )
3420                })?
3421            {
3422                continue;
3423            }
3424            self.resolve_include(world, include_world, names, *span, resolve)?;
3425        }
3426
3427        Ok(())
3428    }
3429
3430    fn update_world_key(&self, key: &mut WorldKey, span: Option<Span>) -> Result<()> {
3431        match key {
3432            WorldKey::Name(_) => {}
3433            WorldKey::Interface(id) => {
3434                *id = self.map_interface(*id, span)?;
3435            }
3436        }
3437        Ok(())
3438    }
3439
3440    fn resolve_include(
3441        &self,
3442        world: &mut World,
3443        include_world: WorldId,
3444        names: &[IncludeName],
3445        span: Span,
3446        resolve: &Resolve,
3447    ) -> Result<()> {
3448        let include_world_id = self.map_world(include_world, Some(span))?;
3449        let include_world = &resolve.worlds[include_world_id];
3450        let mut names_ = names.to_owned();
3451        let is_external_include = world.package != include_world.package;
3452
3453        for import in include_world.imports.iter() {
3455            self.remove_matching_name(import, &mut names_);
3456        }
3457        for export in include_world.exports.iter() {
3458            self.remove_matching_name(export, &mut names_);
3459        }
3460        if !names_.is_empty() {
3461            bail!(Error::new(
3462                span,
3463                format!("no import or export kebab-name `{}`. Note that an ID does not support renaming", names_[0].name),
3464            ));
3465        }
3466
3467        for import in include_world.imports.iter() {
3469            self.resolve_include_item(
3470                names,
3471                &mut world.imports,
3472                import,
3473                span,
3474                "import",
3475                is_external_include,
3476            )?;
3477        }
3478
3479        for export in include_world.exports.iter() {
3480            self.resolve_include_item(
3481                names,
3482                &mut world.exports,
3483                export,
3484                span,
3485                "export",
3486                is_external_include,
3487            )?;
3488        }
3489        Ok(())
3490    }
3491
3492    fn resolve_include_item(
3493        &self,
3494        names: &[IncludeName],
3495        items: &mut IndexMap<WorldKey, WorldItem>,
3496        item: (&WorldKey, &WorldItem),
3497        span: Span,
3498        item_type: &str,
3499        is_external_include: bool,
3500    ) -> Result<()> {
3501        match item.0 {
3502            WorldKey::Name(n) => {
3503                let n = if let Some(found) = names
3504                    .into_iter()
3505                    .find(|include_name| include_name.name == n.clone())
3506                {
3507                    found.as_.clone()
3508                } else {
3509                    n.clone()
3510                };
3511
3512                let prev = items.insert(WorldKey::Name(n.clone()), item.1.clone());
3513                if prev.is_some() {
3514                    bail!(Error::new(
3515                        span,
3516                        format!("{item_type} of `{n}` shadows previously {item_type}ed items"),
3517                    ))
3518                }
3519            }
3520            key @ WorldKey::Interface(_) => {
3521                let prev = items.entry(key.clone()).or_insert(item.1.clone());
3522                match (&item.1, prev) {
3523                    (
3524                        WorldItem::Interface {
3525                            id: aid,
3526                            stability: astability,
3527                        },
3528                        WorldItem::Interface {
3529                            id: bid,
3530                            stability: bstability,
3531                        },
3532                    ) => {
3533                        assert_eq!(*aid, *bid);
3534                        merge_include_stability(astability, bstability, is_external_include)?;
3535                    }
3536                    (WorldItem::Interface { .. }, _) => unreachable!(),
3537                    (WorldItem::Function(_), _) => unreachable!(),
3538                    (WorldItem::Type(_), _) => unreachable!(),
3539                }
3540            }
3541        };
3542        Ok(())
3543    }
3544
3545    fn remove_matching_name(&self, item: (&WorldKey, &WorldItem), names: &mut Vec<IncludeName>) {
3546        match item.0 {
3547            WorldKey::Name(n) => {
3548                names.retain(|name| name.name != n.clone());
3549            }
3550            _ => {}
3551        }
3552    }
3553
3554    fn type_has_borrow(&mut self, resolve: &Resolve, ty: &Type) -> bool {
3555        let id = match ty {
3556            Type::Id(id) => *id,
3557            _ => return false,
3558        };
3559
3560        if let Some(Some(has_borrow)) = self.type_has_borrow.get(id.index()) {
3561            return *has_borrow;
3562        }
3563
3564        let result = self.typedef_has_borrow(resolve, &resolve.types[id]);
3565        if self.type_has_borrow.len() <= id.index() {
3566            self.type_has_borrow.resize(id.index() + 1, None);
3567        }
3568        self.type_has_borrow[id.index()] = Some(result);
3569        result
3570    }
3571
3572    fn typedef_has_borrow(&mut self, resolve: &Resolve, ty: &TypeDef) -> bool {
3573        match &ty.kind {
3574            TypeDefKind::Type(t) => self.type_has_borrow(resolve, t),
3575            TypeDefKind::Variant(v) => v
3576                .cases
3577                .iter()
3578                .filter_map(|case| case.ty.as_ref())
3579                .any(|ty| self.type_has_borrow(resolve, ty)),
3580            TypeDefKind::Handle(Handle::Borrow(_)) => true,
3581            TypeDefKind::Handle(Handle::Own(_)) => false,
3582            TypeDefKind::Resource => false,
3583            TypeDefKind::Record(r) => r
3584                .fields
3585                .iter()
3586                .any(|case| self.type_has_borrow(resolve, &case.ty)),
3587            TypeDefKind::Flags(_) => false,
3588            TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.type_has_borrow(resolve, t)),
3589            TypeDefKind::Enum(_) => false,
3590            TypeDefKind::List(ty)
3591            | TypeDefKind::FixedSizeList(ty, ..)
3592            | TypeDefKind::Future(Some(ty))
3593            | TypeDefKind::Stream(Some(ty))
3594            | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty),
3595            TypeDefKind::Result(r) => [&r.ok, &r.err]
3596                .iter()
3597                .filter_map(|t| t.as_ref())
3598                .any(|t| self.type_has_borrow(resolve, t)),
3599            TypeDefKind::Future(None) | TypeDefKind::Stream(None) => false,
3600            TypeDefKind::Unknown => unreachable!(),
3601        }
3602    }
3603}
3604
3605struct MergeMap<'a> {
3606    package_map: HashMap<PackageId, PackageId>,
3609
3610    interface_map: HashMap<InterfaceId, InterfaceId>,
3613
3614    type_map: HashMap<TypeId, TypeId>,
3617
3618    world_map: HashMap<WorldId, WorldId>,
3621
3622    interfaces_to_add: Vec<(String, PackageId, InterfaceId)>,
3630    worlds_to_add: Vec<(String, PackageId, WorldId)>,
3631
3632    from: &'a Resolve,
3634
3635    into: &'a Resolve,
3637}
3638
3639impl<'a> MergeMap<'a> {
3640    fn new(from: &'a Resolve, into: &'a Resolve) -> MergeMap<'a> {
3641        MergeMap {
3642            package_map: Default::default(),
3643            interface_map: Default::default(),
3644            type_map: Default::default(),
3645            world_map: Default::default(),
3646            interfaces_to_add: Default::default(),
3647            worlds_to_add: Default::default(),
3648            from,
3649            into,
3650        }
3651    }
3652
3653    fn build(&mut self) -> Result<()> {
3654        for from_id in self.from.topological_packages() {
3655            let from = &self.from.packages[from_id];
3656            let into_id = match self.into.package_names.get(&from.name) {
3657                Some(id) => *id,
3658
3659                None => {
3662                    log::trace!("adding unique package {}", from.name);
3663                    continue;
3664                }
3665            };
3666            log::trace!("merging duplicate package {}", from.name);
3667
3668            self.build_package(from_id, into_id).with_context(|| {
3669                format!("failed to merge package `{}` into existing copy", from.name)
3670            })?;
3671        }
3672
3673        Ok(())
3674    }
3675
3676    fn build_package(&mut self, from_id: PackageId, into_id: PackageId) -> Result<()> {
3677        let prev = self.package_map.insert(from_id, into_id);
3678        assert!(prev.is_none());
3679
3680        let from = &self.from.packages[from_id];
3681        let into = &self.into.packages[into_id];
3682
3683        for (name, from_interface_id) in from.interfaces.iter() {
3687            let into_interface_id = match into.interfaces.get(name) {
3688                Some(id) => *id,
3689                None => {
3690                    log::trace!("adding unique interface {}", name);
3691                    self.interfaces_to_add
3692                        .push((name.clone(), into_id, *from_interface_id));
3693                    continue;
3694                }
3695            };
3696
3697            log::trace!("merging duplicate interfaces {}", name);
3698            self.build_interface(*from_interface_id, into_interface_id)
3699                .with_context(|| format!("failed to merge interface `{name}`"))?;
3700        }
3701
3702        for (name, from_world_id) in from.worlds.iter() {
3703            let into_world_id = match into.worlds.get(name) {
3704                Some(id) => *id,
3705                None => {
3706                    log::trace!("adding unique world {}", name);
3707                    self.worlds_to_add
3708                        .push((name.clone(), into_id, *from_world_id));
3709                    continue;
3710                }
3711            };
3712
3713            log::trace!("merging duplicate worlds {}", name);
3714            self.build_world(*from_world_id, into_world_id)
3715                .with_context(|| format!("failed to merge world `{name}`"))?;
3716        }
3717
3718        Ok(())
3719    }
3720
3721    fn build_interface(&mut self, from_id: InterfaceId, into_id: InterfaceId) -> Result<()> {
3722        let prev = self.interface_map.insert(from_id, into_id);
3723        assert!(prev.is_none());
3724
3725        let from_interface = &self.from.interfaces[from_id];
3726        let into_interface = &self.into.interfaces[into_id];
3727
3728        for (name, from_type_id) in from_interface.types.iter() {
3742            let into_type_id = *into_interface
3743                .types
3744                .get(name)
3745                .ok_or_else(|| anyhow!("expected type `{name}` to be present"))?;
3746            let prev = self.type_map.insert(*from_type_id, into_type_id);
3747            assert!(prev.is_none());
3748
3749            self.build_type_id(*from_type_id, into_type_id)
3750                .with_context(|| format!("mismatch in type `{name}`"))?;
3751        }
3752
3753        for (name, from_func) in from_interface.functions.iter() {
3754            let into_func = match into_interface.functions.get(name) {
3755                Some(func) => func,
3756                None => bail!("expected function `{name}` to be present"),
3757            };
3758            self.build_function(from_func, into_func)
3759                .with_context(|| format!("mismatch in function `{name}`"))?;
3760        }
3761
3762        Ok(())
3763    }
3764
3765    fn build_type_id(&mut self, from_id: TypeId, into_id: TypeId) -> Result<()> {
3766        let _ = from_id;
3770        let _ = into_id;
3771        Ok(())
3772    }
3773
3774    fn build_type(&mut self, from_ty: &Type, into_ty: &Type) -> Result<()> {
3775        match (from_ty, into_ty) {
3776            (Type::Id(from), Type::Id(into)) => {
3777                self.build_type_id(*from, *into)?;
3778            }
3779            (from, into) if from != into => bail!("different kinds of types"),
3780            _ => {}
3781        }
3782        Ok(())
3783    }
3784
3785    fn build_function(&mut self, from_func: &Function, into_func: &Function) -> Result<()> {
3786        if from_func.name != into_func.name {
3787            bail!(
3788                "different function names `{}` and `{}`",
3789                from_func.name,
3790                into_func.name
3791            );
3792        }
3793        match (&from_func.kind, &into_func.kind) {
3794            (FunctionKind::Freestanding, FunctionKind::Freestanding) => {}
3795            (FunctionKind::AsyncFreestanding, FunctionKind::AsyncFreestanding) => {}
3796
3797            (FunctionKind::Method(from), FunctionKind::Method(into))
3798            | (FunctionKind::Static(from), FunctionKind::Static(into))
3799            | (FunctionKind::AsyncMethod(from), FunctionKind::AsyncMethod(into))
3800            | (FunctionKind::AsyncStatic(from), FunctionKind::AsyncStatic(into))
3801            | (FunctionKind::Constructor(from), FunctionKind::Constructor(into)) => {
3802                self.build_type_id(*from, *into)
3803                    .context("different function kind types")?;
3804            }
3805
3806            (FunctionKind::Method(_), _)
3807            | (FunctionKind::Constructor(_), _)
3808            | (FunctionKind::Static(_), _)
3809            | (FunctionKind::Freestanding, _)
3810            | (FunctionKind::AsyncFreestanding, _)
3811            | (FunctionKind::AsyncMethod(_), _)
3812            | (FunctionKind::AsyncStatic(_), _) => {
3813                bail!("different function kind types")
3814            }
3815        }
3816
3817        if from_func.params.len() != into_func.params.len() {
3818            bail!("different number of function parameters");
3819        }
3820        for ((from_name, from_ty), (into_name, into_ty)) in
3821            from_func.params.iter().zip(&into_func.params)
3822        {
3823            if from_name != into_name {
3824                bail!("different function parameter names: {from_name} != {into_name}");
3825            }
3826            self.build_type(from_ty, into_ty)
3827                .with_context(|| format!("different function parameter types for `{from_name}`"))?;
3828        }
3829        match (&from_func.result, &into_func.result) {
3830            (Some(from_ty), Some(into_ty)) => {
3831                self.build_type(from_ty, into_ty)
3832                    .context("different function result types")?;
3833            }
3834            (None, None) => {}
3835            (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
3836        }
3837        Ok(())
3838    }
3839
3840    fn build_world(&mut self, from_id: WorldId, into_id: WorldId) -> Result<()> {
3841        let prev = self.world_map.insert(from_id, into_id);
3842        assert!(prev.is_none());
3843
3844        let from_world = &self.from.worlds[from_id];
3845        let into_world = &self.into.worlds[into_id];
3846
3847        if from_world.imports.len() != into_world.imports.len() {
3856            bail!("world contains different number of imports than expected");
3857        }
3858        if from_world.exports.len() != into_world.exports.len() {
3859            bail!("world contains different number of exports than expected");
3860        }
3861
3862        for (from_name, from) in from_world.imports.iter() {
3863            let into_name = MergeMap::map_name(from_name, &self.interface_map);
3864            let name_str = self.from.name_world_key(from_name);
3865            let into = into_world
3866                .imports
3867                .get(&into_name)
3868                .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?;
3869            self.match_world_item(from, into)
3870                .with_context(|| format!("import `{name_str}` didn't match target world"))?;
3871        }
3872
3873        for (from_name, from) in from_world.exports.iter() {
3874            let into_name = MergeMap::map_name(from_name, &self.interface_map);
3875            let name_str = self.from.name_world_key(from_name);
3876            let into = into_world
3877                .exports
3878                .get(&into_name)
3879                .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?;
3880            self.match_world_item(from, into)
3881                .with_context(|| format!("export `{name_str}` didn't match target world"))?;
3882        }
3883
3884        Ok(())
3885    }
3886
3887    fn map_name(
3888        from_name: &WorldKey,
3889        interface_map: &HashMap<InterfaceId, InterfaceId>,
3890    ) -> WorldKey {
3891        match from_name {
3892            WorldKey::Name(s) => WorldKey::Name(s.clone()),
3893            WorldKey::Interface(id) => {
3894                WorldKey::Interface(interface_map.get(id).copied().unwrap_or(*id))
3895            }
3896        }
3897    }
3898
3899    fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> Result<()> {
3900        match (from, into) {
3901            (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
3902                match (
3903                    &self.from.interfaces[*from].name,
3904                    &self.into.interfaces[*into].name,
3905                ) {
3906                    (None, None) => self.build_interface(*from, *into)?,
3910
3911                    _ => {
3916                        if self.interface_map.get(&from) != Some(&into) {
3917                            bail!("interfaces are not the same");
3918                        }
3919                    }
3920                }
3921            }
3922            (WorldItem::Function(from), WorldItem::Function(into)) => {
3923                let _ = (from, into);
3924                }
3927            (WorldItem::Type(from), WorldItem::Type(into)) => {
3928                let prev = self.type_map.insert(*from, *into);
3931                assert!(prev.is_none());
3932            }
3933
3934            (WorldItem::Interface { .. }, _)
3935            | (WorldItem::Function(_), _)
3936            | (WorldItem::Type(_), _) => {
3937                bail!("world items do not have the same type")
3938            }
3939        }
3940        Ok(())
3941    }
3942}
3943
3944fn update_stability(from: &Stability, into: &mut Stability) -> Result<()> {
3950    if from == into || from.is_unknown() {
3953        return Ok(());
3954    }
3955    if into.is_unknown() {
3958        *into = from.clone();
3959        return Ok(());
3960    }
3961
3962    bail!("mismatch in stability from '{:?}' to '{:?}'", from, into)
3965}
3966
3967fn merge_include_stability(
3968    from: &Stability,
3969    into: &mut Stability,
3970    is_external_include: bool,
3971) -> Result<()> {
3972    if is_external_include && from.is_stable() {
3973        log::trace!("dropped stability from external package");
3974        *into = Stability::Unknown;
3975        return Ok(());
3976    }
3977
3978    return update_stability(from, into);
3979}
3980
3981#[derive(Debug, Clone)]
3994pub struct InvalidTransitiveDependency(String);
3995
3996impl fmt::Display for InvalidTransitiveDependency {
3997    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3998        write!(
3999            f,
4000            "interface `{}` transitively depends on an interface in \
4001             incompatible ways",
4002            self.0
4003        )
4004    }
4005}
4006
4007impl std::error::Error for InvalidTransitiveDependency {}
4008
4009#[cfg(test)]
4010mod tests {
4011    use crate::Resolve;
4012    use anyhow::Result;
4013
4014    #[test]
4015    fn select_world() -> Result<()> {
4016        let mut resolve = Resolve::default();
4017        resolve.push_str(
4018            "test.wit",
4019            r#"
4020                package foo:bar@0.1.0;
4021
4022                world foo {}
4023            "#,
4024        )?;
4025        resolve.push_str(
4026            "test.wit",
4027            r#"
4028                package foo:baz@0.1.0;
4029
4030                world foo {}
4031            "#,
4032        )?;
4033        resolve.push_str(
4034            "test.wit",
4035            r#"
4036                package foo:baz@0.2.0;
4037
4038                world foo {}
4039            "#,
4040        )?;
4041
4042        let dummy = resolve.push_str(
4043            "test.wit",
4044            r#"
4045                package foo:dummy;
4046
4047                world foo {}
4048            "#,
4049        )?;
4050
4051        assert!(resolve.select_world(dummy, None).is_ok());
4052        assert!(resolve.select_world(dummy, Some("xx")).is_err());
4053        assert!(resolve.select_world(dummy, Some("")).is_err());
4054        assert!(resolve.select_world(dummy, Some("foo:bar/foo")).is_ok());
4055        assert!(resolve
4056            .select_world(dummy, Some("foo:bar/foo@0.1.0"))
4057            .is_ok());
4058        assert!(resolve.select_world(dummy, Some("foo:baz/foo")).is_err());
4059        assert!(resolve
4060            .select_world(dummy, Some("foo:baz/foo@0.1.0"))
4061            .is_ok());
4062        assert!(resolve
4063            .select_world(dummy, Some("foo:baz/foo@0.2.0"))
4064            .is_ok());
4065        Ok(())
4066    }
4067}