wit_parser/
resolve.rs

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::{Context, Result, anyhow, bail};
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::{ParsedUsePath, parse_use_path};
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
26pub use clone::CloneMaps;
27
28mod clone;
29
30/// Representation of a fully resolved set of WIT packages.
31///
32/// This structure contains a graph of WIT packages and all of their contents
33/// merged together into the contained arenas. All items are sorted
34/// topologically and everything here is fully resolved, so with a `Resolve` no
35/// name lookups are necessary and instead everything is index-based.
36///
37/// Working with a WIT package requires inserting it into a `Resolve` to ensure
38/// that all of its dependencies are satisfied. This will give the full picture
39/// of that package's types and such.
40///
41/// Each item in a `Resolve` has a parent link to trace it back to the original
42/// package as necessary.
43#[derive(Default, Clone, Debug)]
44#[cfg_attr(feature = "serde", derive(Serialize))]
45pub struct Resolve {
46    /// All known worlds within this `Resolve`.
47    ///
48    /// Each world points at a `PackageId` which is stored below. No ordering is
49    /// guaranteed between this list of worlds.
50    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
51    pub worlds: Arena<World>,
52
53    /// All known interfaces within this `Resolve`.
54    ///
55    /// Each interface points at a `PackageId` which is stored below. No
56    /// ordering is guaranteed between this list of interfaces.
57    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
58    pub interfaces: Arena<Interface>,
59
60    /// All known types within this `Resolve`.
61    ///
62    /// Types are topologically sorted such that any type referenced from one
63    /// type is guaranteed to be defined previously. Otherwise though these are
64    /// not sorted by interface for example.
65    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
66    pub types: Arena<TypeDef>,
67
68    /// All known packages within this `Resolve`.
69    ///
70    /// This list of packages is not sorted. Sorted packages can be queried
71    /// through [`Resolve::topological_packages`].
72    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_arena"))]
73    pub packages: Arena<Package>,
74
75    /// A map of package names to the ID of the package with that name.
76    #[cfg_attr(feature = "serde", serde(skip))]
77    pub package_names: IndexMap<PackageName, PackageId>,
78
79    /// Activated features for this [`Resolve`].
80    ///
81    /// This set of features is empty by default. This is consulted for
82    /// `@unstable` annotations in loaded WIT documents. Any items with
83    /// `@unstable` are filtered out unless their feature is present within this
84    /// set.
85    #[cfg_attr(feature = "serde", serde(skip))]
86    pub features: IndexSet<String>,
87
88    /// Activate all features for this [`Resolve`].
89    #[cfg_attr(feature = "serde", serde(skip))]
90    pub all_features: bool,
91}
92
93/// A WIT package within a `Resolve`.
94///
95/// A package is a collection of interfaces and worlds. Packages additionally
96/// have a unique identifier that affects generated components and uniquely
97/// identifiers this particular package.
98#[derive(Clone, Debug)]
99#[cfg_attr(feature = "serde", derive(Serialize))]
100pub struct Package {
101    /// A unique name corresponding to this package.
102    pub name: PackageName,
103
104    /// Documentation associated with this package.
105    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Docs::is_empty"))]
106    pub docs: Docs,
107
108    /// All interfaces contained in this packaged, keyed by the interface's
109    /// name.
110    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_id_map"))]
111    pub interfaces: IndexMap<String, InterfaceId>,
112
113    /// All worlds contained in this package, keyed by the world's name.
114    #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_id_map"))]
115    pub worlds: IndexMap<String, WorldId>,
116}
117
118pub type PackageId = Id<Package>;
119
120/// All the sources used during resolving a directory or path.
121#[derive(Clone, Debug)]
122pub struct PackageSourceMap {
123    sources: Vec<Vec<PathBuf>>,
124    package_id_to_source_map_idx: BTreeMap<PackageId, usize>,
125}
126
127impl PackageSourceMap {
128    fn from_single_source(package_id: PackageId, source: &Path) -> Self {
129        Self {
130            sources: vec![vec![source.to_path_buf()]],
131            package_id_to_source_map_idx: BTreeMap::from([(package_id, 0)]),
132        }
133    }
134
135    fn from_source_maps(
136        source_maps: Vec<SourceMap>,
137        package_id_to_source_map_idx: BTreeMap<PackageId, usize>,
138    ) -> PackageSourceMap {
139        for (package_id, idx) in &package_id_to_source_map_idx {
140            if *idx >= source_maps.len() {
141                panic!(
142                    "Invalid source map index: {}, package id: {:?}, source maps size: {}",
143                    idx,
144                    package_id,
145                    source_maps.len()
146                )
147            }
148        }
149
150        Self {
151            sources: source_maps
152                .into_iter()
153                .map(|source_map| {
154                    source_map
155                        .source_files()
156                        .map(|path| path.to_path_buf())
157                        .collect()
158                })
159                .collect(),
160            package_id_to_source_map_idx,
161        }
162    }
163
164    /// All unique source paths.
165    pub fn paths(&self) -> impl Iterator<Item = &Path> {
166        // Usually any two source map should not have duplicated source paths,
167        // but it can happen, e.g. with using [`Resolve::push_str`] directly.
168        // To be sure we use a set for deduplication here.
169        self.sources
170            .iter()
171            .flatten()
172            .map(|path_buf| path_buf.as_ref())
173            .collect::<IndexSet<&Path>>()
174            .into_iter()
175    }
176
177    /// Source paths for package
178    pub fn package_paths(&self, id: PackageId) -> Option<impl Iterator<Item = &Path>> {
179        self.package_id_to_source_map_idx
180            .get(&id)
181            .map(|&idx| self.sources[idx].iter().map(|path_buf| path_buf.as_ref()))
182    }
183}
184
185enum ParsedFile {
186    #[cfg(feature = "decoding")]
187    Package(PackageId),
188    Unresolved(UnresolvedPackageGroup),
189}
190
191/// Visitor helper for performing topological sort on a group of packages.
192fn visit<'a>(
193    pkg: &'a UnresolvedPackage,
194    pkg_details_map: &'a BTreeMap<PackageName, (UnresolvedPackage, usize)>,
195    order: &mut IndexSet<PackageName>,
196    visiting: &mut HashSet<&'a PackageName>,
197    source_maps: &[SourceMap],
198) -> Result<()> {
199    if order.contains(&pkg.name) {
200        return Ok(());
201    }
202
203    match pkg_details_map.get(&pkg.name) {
204        Some(pkg_details) => {
205            let (_, source_maps_index) = pkg_details;
206            source_maps[*source_maps_index].rewrite_error(|| {
207                for (i, (dep, _)) in pkg.foreign_deps.iter().enumerate() {
208                    let span = pkg.foreign_dep_spans[i];
209                    if !visiting.insert(dep) {
210                        bail!(Error::new(span, "package depends on itself"));
211                    }
212                    if let Some(dep) = pkg_details_map.get(dep) {
213                        let (dep_pkg, _) = dep;
214                        visit(dep_pkg, pkg_details_map, order, visiting, source_maps)?;
215                    }
216                    assert!(visiting.remove(dep));
217                }
218                assert!(order.insert(pkg.name.clone()));
219                Ok(())
220            })
221        }
222        None => panic!("No pkg_details found for package when doing topological sort"),
223    }
224}
225
226impl Resolve {
227    /// Creates a new [`Resolve`] with no packages/items inside of it.
228    pub fn new() -> Resolve {
229        Resolve::default()
230    }
231
232    /// Parse WIT packages from the input `path`.
233    ///
234    /// The input `path` can be one of:
235    ///
236    /// * A directory containing a WIT package with an optional `deps` directory
237    ///   for any dependent WIT packages it references.
238    /// * A single standalone WIT file.
239    /// * A wasm-encoded WIT package as a single file in the wasm binary format.
240    /// * A wasm-encoded WIT package as a single file in the wasm text format.
241    ///
242    /// In all of these cases packages are allowed to depend on previously
243    /// inserted packages into this `Resolve`. Resolution for packages is based
244    /// on the name of each package and reference.
245    ///
246    /// This method returns a `PackageId` and additionally a `PackageSourceMap`.
247    /// The `PackageId` represent the main package that was parsed. For example if a single WIT
248    /// file was specified  this will be the main package found in the file. For a directory this
249    /// will be all the main package in the directory itself. The `PackageId` value is useful
250    /// to pass to [`Resolve::select_world`] to take a user-specified world in a
251    /// conventional fashion and select which to use for bindings generation.
252    ///
253    /// The returned [`PackageSourceMap`] contains all the sources used during this operation.
254    /// This can be useful for systems that want to rebuild or regenerate bindings based on files modified,
255    /// or for ones which like to identify the used files for a package.
256    ///
257    /// More information can also be found at [`Resolve::push_dir`] and
258    /// [`Resolve::push_file`].
259    pub fn push_path(&mut self, path: impl AsRef<Path>) -> Result<(PackageId, PackageSourceMap)> {
260        self._push_path(path.as_ref())
261    }
262
263    fn _push_path(&mut self, path: &Path) -> Result<(PackageId, PackageSourceMap)> {
264        if path.is_dir() {
265            self.push_dir(path).with_context(|| {
266                format!(
267                    "failed to resolve directory while parsing WIT for path [{}]",
268                    path.display()
269                )
270            })
271        } else {
272            let id = self.push_file(path)?;
273            Ok((id, PackageSourceMap::from_single_source(id, path)))
274        }
275    }
276
277    fn sort_unresolved_packages(
278        &mut self,
279        main: UnresolvedPackageGroup,
280        deps: Vec<UnresolvedPackageGroup>,
281    ) -> Result<(PackageId, PackageSourceMap)> {
282        let mut pkg_details_map = BTreeMap::new();
283        let mut source_maps = Vec::new();
284
285        let mut insert = |group: UnresolvedPackageGroup| {
286            let UnresolvedPackageGroup {
287                main,
288                nested,
289                source_map,
290            } = group;
291            let i = source_maps.len();
292            source_maps.push(source_map);
293
294            for pkg in nested.into_iter().chain([main]) {
295                let name = pkg.name.clone();
296                let my_span = pkg.package_name_span;
297                let (prev_pkg, prev_i) = match pkg_details_map.insert(name.clone(), (pkg, i)) {
298                    Some(pair) => pair,
299                    None => continue,
300                };
301                let loc1 = source_maps[i].render_location(my_span);
302                let loc2 = source_maps[prev_i].render_location(prev_pkg.package_name_span);
303                bail!(
304                    "\
305package {name} is defined in two different locations:\n\
306  * {loc1}\n\
307  * {loc2}\n\
308                     "
309                )
310            }
311            Ok(())
312        };
313
314        let main_name = main.main.name.clone();
315        insert(main)?;
316        for dep in deps {
317            insert(dep)?;
318        }
319
320        // Perform a simple topological sort which will bail out on cycles
321        // and otherwise determine the order that packages must be added to
322        // this `Resolve`.
323        let mut order = IndexSet::new();
324        let mut visiting = HashSet::new();
325        for pkg_details in pkg_details_map.values() {
326            let (pkg, _) = pkg_details;
327            visit(
328                pkg,
329                &pkg_details_map,
330                &mut order,
331                &mut visiting,
332                &source_maps,
333            )?;
334        }
335
336        // Ensure that the final output is topologically sorted. Use a set to ensure that we render
337        // the buffers for each `SourceMap` only once, even though multiple packages may reference
338        // the same `SourceMap`.
339        let mut package_id_to_source_map_idx = BTreeMap::new();
340        let mut main_pkg_id = None;
341        for name in order {
342            let (pkg, source_map_index) = pkg_details_map.remove(&name).unwrap();
343            let source_map = &source_maps[source_map_index];
344            let is_main = pkg.name == main_name;
345            let id = self.push(pkg, source_map)?;
346            if is_main {
347                assert!(main_pkg_id.is_none());
348                main_pkg_id = Some(id);
349            }
350            package_id_to_source_map_idx.insert(id, source_map_index);
351        }
352
353        Ok((
354            main_pkg_id.unwrap(),
355            PackageSourceMap::from_source_maps(source_maps, package_id_to_source_map_idx),
356        ))
357    }
358
359    /// Parses the filesystem directory at `path` as a WIT package and returns
360    /// a fully resolved [`PackageId`] list as a result.
361    ///
362    /// The directory itself is parsed with [`UnresolvedPackageGroup::parse_dir`]
363    /// and then all packages found are inserted into this `Resolve`. The `path`
364    /// specified may have a `deps` subdirectory which is probed automatically
365    /// for any other WIT dependencies.
366    ///
367    /// The `deps` folder may contain:
368    ///
369    /// * `$path/deps/my-package/*.wit` - a directory that may contain multiple
370    ///   WIT files. This is parsed with [`UnresolvedPackageGroup::parse_dir`]
371    ///   and then inserted into this [`Resolve`]. Note that cannot recursively
372    ///   contain a `deps` directory.
373    /// * `$path/deps/my-package.wit` - a single-file WIT package. This is
374    ///   parsed with [`Resolve::push_file`] and then added to `self` for
375    ///   name resolution.
376    /// * `$path/deps/my-package.{wasm,wat}` - a wasm-encoded WIT package either
377    ///   in the text for binary format.
378    ///
379    /// In all cases entries in the `deps` folder are added to `self` first
380    /// before adding files found in `path` itself. All WIT packages found are
381    /// candidates for name-based resolution that other packages may use.
382    ///
383    /// This function returns a tuple of two values. The first value is a
384    /// [`PackageId`], which represents the main WIT package found within
385    /// `path`. This argument is useful for passing to [`Resolve::select_world`]
386    /// for choosing something to bindgen with.
387    ///
388    /// The second value returned is a [`PackageSourceMap`], which contains all the sources
389    /// that were parsed during resolving. This can be useful for:
390    /// * build systems that want to rebuild bindings whenever one of the files changed
391    /// * or other tools, which want to identify the sources for the resolved packages
392    pub fn push_dir(&mut self, path: impl AsRef<Path>) -> Result<(PackageId, PackageSourceMap)> {
393        self._push_dir(path.as_ref())
394    }
395
396    fn _push_dir(&mut self, path: &Path) -> Result<(PackageId, PackageSourceMap)> {
397        let top_pkg = UnresolvedPackageGroup::parse_dir(path)
398            .with_context(|| format!("failed to parse package: {}", path.display()))?;
399        let deps = path.join("deps");
400        let deps = self
401            .parse_deps_dir(&deps)
402            .with_context(|| format!("failed to parse dependency directory: {}", deps.display()))?;
403
404        self.sort_unresolved_packages(top_pkg, deps)
405    }
406
407    fn parse_deps_dir(&mut self, path: &Path) -> Result<Vec<UnresolvedPackageGroup>> {
408        let mut ret = Vec::new();
409        if !path.exists() {
410            return Ok(ret);
411        }
412        let mut entries = path
413            .read_dir()
414            .and_then(|i| i.collect::<std::io::Result<Vec<_>>>())
415            .context("failed to read directory")?;
416        entries.sort_by_key(|e| e.file_name());
417        for dep in entries {
418            let path = dep.path();
419            let pkg = if dep.file_type()?.is_dir() || path.metadata()?.is_dir() {
420                // If this entry is a directory or a symlink point to a
421                // directory then always parse it as an `UnresolvedPackage`
422                // since it's intentional to not support recursive `deps`
423                // directories.
424                UnresolvedPackageGroup::parse_dir(&path)
425                    .with_context(|| format!("failed to parse package: {}", path.display()))?
426            } else {
427                // If this entry is a file then we may want to ignore it but
428                // this may also be a standalone WIT file or a `*.wasm` or
429                // `*.wat` encoded package.
430                let filename = dep.file_name();
431                match Path::new(&filename).extension().and_then(|s| s.to_str()) {
432                    Some("wit") | Some("wat") | Some("wasm") => match self._push_file(&path)? {
433                        #[cfg(feature = "decoding")]
434                        ParsedFile::Package(_) => continue,
435                        ParsedFile::Unresolved(pkg) => pkg,
436                    },
437
438                    // Other files in deps dir are ignored for now to avoid
439                    // accidentally including things like `.DS_Store` files in
440                    // the call below to `parse_dir`.
441                    _ => continue,
442                }
443            };
444            ret.push(pkg);
445        }
446        Ok(ret)
447    }
448
449    /// Parses the contents of `path` from the filesystem and pushes the result
450    /// into this `Resolve`.
451    ///
452    /// The `path` referenced here can be one of:
453    ///
454    /// * A WIT file. Note that in this case this single WIT file will be the
455    ///   entire package and any dependencies it has must already be in `self`.
456    /// * A WIT package encoded as WebAssembly, either in text or binary form.
457    ///   In this the package and all of its dependencies are automatically
458    ///   inserted into `self`.
459    ///
460    /// In both situations the `PackageId`s of the resulting resolved packages
461    /// are returned from this method. The return value is mostly useful in
462    /// conjunction with [`Resolve::select_world`].
463    pub fn push_file(&mut self, path: impl AsRef<Path>) -> Result<PackageId> {
464        match self._push_file(path.as_ref())? {
465            #[cfg(feature = "decoding")]
466            ParsedFile::Package(id) => Ok(id),
467            ParsedFile::Unresolved(pkg) => self.push_group(pkg),
468        }
469    }
470
471    fn _push_file(&mut self, path: &Path) -> Result<ParsedFile> {
472        let contents = std::fs::read(path)
473            .with_context(|| format!("failed to read path for WIT [{}]", path.display()))?;
474
475        // If decoding is enabled at compile time then try to see if this is a
476        // wasm file.
477        #[cfg(feature = "decoding")]
478        {
479            use crate::decoding::{DecodedWasm, decode};
480
481            #[cfg(feature = "wat")]
482            let is_wasm = wat::Detect::from_bytes(&contents).is_wasm();
483            #[cfg(not(feature = "wat"))]
484            let is_wasm = wasmparser::Parser::is_component(&contents);
485
486            if is_wasm {
487                #[cfg(feature = "wat")]
488                let contents = wat::parse_bytes(&contents).map_err(|mut e| {
489                    e.set_path(path);
490                    e
491                })?;
492
493                match decode(&contents)? {
494                    DecodedWasm::Component(..) => {
495                        bail!("found an actual component instead of an encoded WIT package in wasm")
496                    }
497                    DecodedWasm::WitPackage(resolve, pkg) => {
498                        let remap = self.merge(resolve)?;
499                        return Ok(ParsedFile::Package(remap.packages[pkg.index()]));
500                    }
501                }
502            }
503        }
504
505        // If this wasn't a wasm file then assume it's a WIT file.
506        let text = match std::str::from_utf8(&contents) {
507            Ok(s) => s,
508            Err(_) => bail!("input file is not valid utf-8 [{}]", path.display()),
509        };
510        let pkgs = UnresolvedPackageGroup::parse(path, text)?;
511        Ok(ParsedFile::Unresolved(pkgs))
512    }
513
514    /// Appends a new [`UnresolvedPackage`] to this [`Resolve`], creating a
515    /// fully resolved package with no dangling references.
516    ///
517    /// All the dependencies of `unresolved` must already have been loaded
518    /// within this `Resolve` via previous calls to `push` or other methods such
519    /// as [`Resolve::push_path`].
520    ///
521    /// Any dependency resolution error or otherwise world-elaboration error
522    /// will be returned here, if successful a package identifier is returned
523    /// which corresponds to the package that was just inserted.
524    pub fn push(
525        &mut self,
526        unresolved: UnresolvedPackage,
527        source_map: &SourceMap,
528    ) -> Result<PackageId> {
529        let ret = source_map.rewrite_error(|| Remap::default().append(self, unresolved));
530        if ret.is_ok() {
531            #[cfg(debug_assertions)]
532            self.assert_valid();
533        }
534        ret
535    }
536
537    /// Appends new [`UnresolvedPackageGroup`] to this [`Resolve`], creating a
538    /// fully resolved package with no dangling references.
539    ///
540    /// Any dependency resolution error or otherwise world-elaboration error
541    /// will be returned here, if successful a package identifier is returned
542    /// which corresponds to the package that was just inserted.
543    ///
544    /// The returned [`PackageId`]s are listed in topologically sorted order.
545    pub fn push_group(&mut self, unresolved_group: UnresolvedPackageGroup) -> Result<PackageId> {
546        let (pkg_id, _) = self.sort_unresolved_packages(unresolved_group, Vec::new())?;
547        Ok(pkg_id)
548    }
549
550    /// Convenience method for combining [`UnresolvedPackageGroup::parse`] and
551    /// [`Resolve::push_group`].
552    ///
553    /// The `path` provided is used for error messages but otherwise is not
554    /// read. This method does not touch the filesystem. The `contents` provided
555    /// are the contents of a WIT package.
556    pub fn push_str(&mut self, path: impl AsRef<Path>, contents: &str) -> Result<PackageId> {
557        self.push_group(UnresolvedPackageGroup::parse(path.as_ref(), contents)?)
558    }
559
560    pub fn all_bits_valid(&self, ty: &Type) -> bool {
561        match ty {
562            Type::U8
563            | Type::S8
564            | Type::U16
565            | Type::S16
566            | Type::U32
567            | Type::S32
568            | Type::U64
569            | Type::S64
570            | Type::F32
571            | Type::F64 => true,
572
573            Type::Bool | Type::Char | Type::String | Type::ErrorContext => false,
574
575            Type::Id(id) => match &self.types[*id].kind {
576                TypeDefKind::List(_)
577                | TypeDefKind::Variant(_)
578                | TypeDefKind::Enum(_)
579                | TypeDefKind::Option(_)
580                | TypeDefKind::Result(_)
581                | TypeDefKind::Future(_)
582                | TypeDefKind::Stream(_) => false,
583                TypeDefKind::Type(t) | TypeDefKind::FixedSizeList(t, ..) => self.all_bits_valid(t),
584
585                TypeDefKind::Handle(h) => match h {
586                    crate::Handle::Own(_) => true,
587                    crate::Handle::Borrow(_) => true,
588                },
589
590                TypeDefKind::Resource => false,
591                TypeDefKind::Record(r) => r.fields.iter().all(|f| self.all_bits_valid(&f.ty)),
592                TypeDefKind::Tuple(t) => t.types.iter().all(|t| self.all_bits_valid(t)),
593
594                // FIXME: this could perhaps be `true` for multiples-of-32 but
595                // seems better to probably leave this as unconditionally
596                // `false` for now, may want to reconsider later?
597                TypeDefKind::Flags(_) => false,
598
599                TypeDefKind::Unknown => unreachable!(),
600            },
601        }
602    }
603
604    /// Merges all the contents of a different `Resolve` into this one. The
605    /// `Remap` structure returned provides a mapping from all old indices to
606    /// new indices
607    ///
608    /// This operation can fail if `resolve` disagrees with `self` about the
609    /// packages being inserted. Otherwise though this will additionally attempt
610    /// to "union" packages found in `resolve` with those found in `self`.
611    /// Unioning packages is keyed on the name/url of packages for those with
612    /// URLs present. If found then it's assumed that both `Resolve` instances
613    /// were originally created from the same contents and are two views
614    /// of the same package.
615    pub fn merge(&mut self, resolve: Resolve) -> Result<Remap> {
616        log::trace!(
617            "merging {} packages into {} packages",
618            resolve.packages.len(),
619            self.packages.len()
620        );
621
622        let mut map = MergeMap::new(&resolve, &self);
623        map.build()?;
624        let MergeMap {
625            package_map,
626            interface_map,
627            type_map,
628            world_map,
629            interfaces_to_add,
630            worlds_to_add,
631            ..
632        } = map;
633
634        // With a set of maps from ids in `resolve` to ids in `self` the next
635        // operation is to start moving over items and building a `Remap` to
636        // update ids.
637        //
638        // Each component field of `resolve` is moved into `self` so long as
639        // its ID is not within one of the maps above. If it's present in a map
640        // above then that means the item is already present in `self` so a new
641        // one need not be added. If it's not present in a map that means it's
642        // not present in `self` so it must be added to an arena.
643        //
644        // When adding an item to an arena one of the `remap.update_*` methods
645        // is additionally called to update all identifiers from pointers within
646        // `resolve` to becoming pointers within `self`.
647        //
648        // Altogether this should weave all the missing items in `self` from
649        // `resolve` into one structure while updating all identifiers to
650        // be local within `self`.
651
652        let mut remap = Remap::default();
653        let Resolve {
654            types,
655            worlds,
656            interfaces,
657            packages,
658            package_names,
659            features: _,
660            ..
661        } = resolve;
662
663        let mut moved_types = Vec::new();
664        for (id, mut ty) in types {
665            let new_id = match type_map.get(&id).copied() {
666                Some(id) => {
667                    update_stability(&ty.stability, &mut self.types[id].stability)?;
668                    id
669                }
670                None => {
671                    log::debug!("moving type {:?}", ty.name);
672                    moved_types.push(id);
673                    remap.update_typedef(self, &mut ty, None)?;
674                    self.types.alloc(ty)
675                }
676            };
677            assert_eq!(remap.types.len(), id.index());
678            remap.types.push(Some(new_id));
679        }
680
681        let mut moved_interfaces = Vec::new();
682        for (id, mut iface) in interfaces {
683            let new_id = match interface_map.get(&id).copied() {
684                Some(id) => {
685                    update_stability(&iface.stability, &mut self.interfaces[id].stability)?;
686                    id
687                }
688                None => {
689                    log::debug!("moving interface {:?}", iface.name);
690                    moved_interfaces.push(id);
691                    remap.update_interface(self, &mut iface, None)?;
692                    self.interfaces.alloc(iface)
693                }
694            };
695            assert_eq!(remap.interfaces.len(), id.index());
696            remap.interfaces.push(Some(new_id));
697        }
698
699        let mut moved_worlds = Vec::new();
700        for (id, mut world) in worlds {
701            let new_id = match world_map.get(&id).copied() {
702                Some(world_id) => {
703                    update_stability(&world.stability, &mut self.worlds[world_id].stability)?;
704                    for from_import in world.imports.iter() {
705                        Resolve::update_world_imports_stability(
706                            from_import,
707                            &mut self.worlds[world_id].imports,
708                            &interface_map,
709                        )?;
710                    }
711                    for from_export in world.exports.iter() {
712                        Resolve::update_world_imports_stability(
713                            from_export,
714                            &mut self.worlds[world_id].exports,
715                            &interface_map,
716                        )?;
717                    }
718                    world_id
719                }
720                None => {
721                    log::debug!("moving world {}", world.name);
722                    moved_worlds.push(id);
723                    let mut update = |map: &mut IndexMap<WorldKey, WorldItem>| -> Result<_> {
724                        for (mut name, mut item) in mem::take(map) {
725                            remap.update_world_key(&mut name, None)?;
726                            match &mut item {
727                                WorldItem::Function(f) => remap.update_function(self, f, None)?,
728                                WorldItem::Interface { id, .. } => {
729                                    *id = remap.map_interface(*id, None)?
730                                }
731                                WorldItem::Type(i) => *i = remap.map_type(*i, None)?,
732                            }
733                            map.insert(name, item);
734                        }
735                        Ok(())
736                    };
737                    update(&mut world.imports)?;
738                    update(&mut world.exports)?;
739                    self.worlds.alloc(world)
740                }
741            };
742            assert_eq!(remap.worlds.len(), id.index());
743            remap.worlds.push(Some(new_id));
744        }
745
746        for (id, mut pkg) in packages {
747            let new_id = match package_map.get(&id).copied() {
748                Some(id) => id,
749                None => {
750                    for (_, id) in pkg.interfaces.iter_mut() {
751                        *id = remap.map_interface(*id, None)?;
752                    }
753                    for (_, id) in pkg.worlds.iter_mut() {
754                        *id = remap.map_world(*id, None)?;
755                    }
756                    self.packages.alloc(pkg)
757                }
758            };
759            assert_eq!(remap.packages.len(), id.index());
760            remap.packages.push(new_id);
761        }
762
763        for (name, id) in package_names {
764            let id = remap.packages[id.index()];
765            if let Some(prev) = self.package_names.insert(name, id) {
766                assert_eq!(prev, id);
767            }
768        }
769
770        // Fixup all "parent" links now.
771        //
772        // Note that this is only done for items that are actually moved from
773        // `resolve` into `self`, which is tracked by the various `moved_*`
774        // lists built incrementally above. The ids in the `moved_*` lists
775        // are ids within `resolve`, so they're translated through `remap` to
776        // ids within `self`.
777        for id in moved_worlds {
778            let id = remap.map_world(id, None)?;
779            if let Some(pkg) = self.worlds[id].package.as_mut() {
780                *pkg = remap.packages[pkg.index()];
781            }
782        }
783        for id in moved_interfaces {
784            let id = remap.map_interface(id, None)?;
785            if let Some(pkg) = self.interfaces[id].package.as_mut() {
786                *pkg = remap.packages[pkg.index()];
787            }
788        }
789        for id in moved_types {
790            let id = remap.map_type(id, None)?;
791            match &mut self.types[id].owner {
792                TypeOwner::Interface(id) => *id = remap.map_interface(*id, None)?,
793                TypeOwner::World(id) => *id = remap.map_world(*id, None)?,
794                TypeOwner::None => {}
795            }
796        }
797
798        // And finally process items that were present in `resolve` but were
799        // not present in `self`. This is only done for merged packages as
800        // documents may be added to `self.documents` but wouldn't otherwise be
801        // present in the `documents` field of the corresponding package.
802        for (name, pkg, iface) in interfaces_to_add {
803            let prev = self.packages[pkg]
804                .interfaces
805                .insert(name, remap.map_interface(iface, None)?);
806            assert!(prev.is_none());
807        }
808        for (name, pkg, world) in worlds_to_add {
809            let prev = self.packages[pkg]
810                .worlds
811                .insert(name, remap.map_world(world, None)?);
812            assert!(prev.is_none());
813        }
814
815        log::trace!("now have {} packages", self.packages.len());
816
817        #[cfg(debug_assertions)]
818        self.assert_valid();
819        Ok(remap)
820    }
821
822    fn update_world_imports_stability(
823        from_item: (&WorldKey, &WorldItem),
824        into_items: &mut IndexMap<WorldKey, WorldItem>,
825        interface_map: &HashMap<Id<Interface>, Id<Interface>>,
826    ) -> Result<()> {
827        match from_item.0 {
828            WorldKey::Name(_) => {
829                // No stability info to update here, only updating import/include stability
830                Ok(())
831            }
832            key @ WorldKey::Interface(_) => {
833                let new_key = MergeMap::map_name(key, interface_map);
834                if let Some(into) = into_items.get_mut(&new_key) {
835                    match (from_item.1, into) {
836                        (
837                            WorldItem::Interface {
838                                id: aid,
839                                stability: astability,
840                            },
841                            WorldItem::Interface {
842                                id: bid,
843                                stability: bstability,
844                            },
845                        ) => {
846                            let aid = interface_map.get(aid).copied().unwrap_or(*aid);
847                            assert_eq!(aid, *bid);
848                            update_stability(astability, bstability)?;
849                            Ok(())
850                        }
851                        _ => unreachable!(),
852                    }
853                } else {
854                    // we've already matched all the imports/exports by the time we are calling this
855                    // so this is unreachable since we should always find the item
856                    unreachable!()
857                }
858            }
859        }
860    }
861
862    /// Merges the world `from` into the world `into`.
863    ///
864    /// This will attempt to merge one world into another, unioning all of its
865    /// imports and exports together. This is an operation performed by
866    /// `wit-component`, for example where two different worlds from two
867    /// different libraries were linked into the same core wasm file and are
868    /// producing a singular world that will be the final component's
869    /// interface.
870    ///
871    /// During the merge operation, some of the types and/or interfaces in
872    /// `from` might need to be cloned so that backreferences point to `into`
873    /// instead of `from`.  Any such clones will be added to `clone_maps`.
874    ///
875    /// This operation can fail if the imports/exports overlap.
876    pub fn merge_worlds(
877        &mut self,
878        from: WorldId,
879        into: WorldId,
880        clone_maps: &mut CloneMaps,
881    ) -> Result<()> {
882        let mut new_imports = Vec::new();
883        let mut new_exports = Vec::new();
884
885        let from_world = &self.worlds[from];
886        let into_world = &self.worlds[into];
887
888        log::trace!("merging {} into {}", from_world.name, into_world.name);
889
890        // First walk over all the imports of `from` world and figure out what
891        // to do with them.
892        //
893        // If the same item exists in `from` and `into` then merge it together
894        // below with `merge_world_item` which basically asserts they're the
895        // same. Otherwise queue up a new import since if `from` has more
896        // imports than `into` then it's fine to add new imports.
897        for (name, from_import) in from_world.imports.iter() {
898            let name_str = self.name_world_key(name);
899            match into_world.imports.get(name) {
900                Some(into_import) => {
901                    log::trace!("info/from shared import on `{name_str}`");
902                    self.merge_world_item(from_import, into_import)
903                        .with_context(|| format!("failed to merge world import {name_str}"))?;
904                }
905                None => {
906                    log::trace!("new import: `{name_str}`");
907                    new_imports.push((name.clone(), from_import.clone()));
908                }
909            }
910        }
911
912        // Build a set of interfaces which are required to be imported because
913        // of `into`'s exports. This set is then used below during
914        // `ensure_can_add_world_export`.
915        //
916        // This is the set of interfaces which exports depend on that are
917        // themselves not exports.
918        let mut must_be_imported = HashMap::new();
919        for (key, export) in into_world.exports.iter() {
920            for dep in self.world_item_direct_deps(export) {
921                if into_world.exports.contains_key(&WorldKey::Interface(dep)) {
922                    continue;
923                }
924                self.foreach_interface_dep(dep, &mut |id| {
925                    must_be_imported.insert(id, key.clone());
926                });
927            }
928        }
929
930        // Next walk over exports of `from` and process these similarly to
931        // imports.
932        for (name, from_export) in from_world.exports.iter() {
933            let name_str = self.name_world_key(name);
934            match into_world.exports.get(name) {
935                Some(into_export) => {
936                    log::trace!("info/from shared export on `{name_str}`");
937                    self.merge_world_item(from_export, into_export)
938                        .with_context(|| format!("failed to merge world export {name_str}"))?;
939                }
940                None => {
941                    log::trace!("new export `{name_str}`");
942                    // See comments in `ensure_can_add_world_export` for why
943                    // this is slightly different than imports.
944                    self.ensure_can_add_world_export(
945                        into_world,
946                        name,
947                        from_export,
948                        &must_be_imported,
949                    )
950                    .with_context(|| {
951                        format!("failed to add export `{}`", self.name_world_key(name))
952                    })?;
953                    new_exports.push((name.clone(), from_export.clone()));
954                }
955            }
956        }
957
958        // For all the new imports and exports they may need to be "cloned" to
959        // be able to belong to the new world. For example:
960        //
961        // * Anonymous interfaces have a `package` field which points to the
962        //   package of the containing world, but `from` and `into` may not be
963        //   in the same package.
964        //
965        // * Type imports have an `owner` field that point to `from`, but they
966        //   now need to point to `into` instead.
967        //
968        // Cloning is no trivial task, however, so cloning is delegated to a
969        // submodule to perform a "deep" clone and copy items into new arena
970        // entries as necessary.
971        let mut cloner = clone::Cloner::new(self, TypeOwner::World(from), TypeOwner::World(into));
972        cloner.register_world_type_overlap(from, into);
973        for (name, item) in new_imports.iter_mut().chain(&mut new_exports) {
974            cloner.world_item(name, item, clone_maps);
975        }
976
977        clone_maps.types.extend(cloner.types);
978
979        // Insert any new imports and new exports found first.
980        let into_world = &mut self.worlds[into];
981        for (name, import) in new_imports {
982            let prev = into_world.imports.insert(name, import);
983            assert!(prev.is_none());
984        }
985        for (name, export) in new_exports {
986            let prev = into_world.exports.insert(name, export);
987            assert!(prev.is_none());
988        }
989
990        #[cfg(debug_assertions)]
991        self.assert_valid();
992        Ok(())
993    }
994
995    fn merge_world_item(&self, from: &WorldItem, into: &WorldItem) -> Result<()> {
996        let mut map = MergeMap::new(self, self);
997        match (from, into) {
998            (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
999                // If these imports are the same that can happen, for
1000                // example, when both worlds to `import foo:bar/baz;`. That
1001                // foreign interface will point to the same interface within
1002                // `Resolve`.
1003                if from == into {
1004                    return Ok(());
1005                }
1006
1007                // .. otherwise this MUST be a case of
1008                // `import foo: interface { ... }`. If `from != into` but
1009                // both `from` and `into` have the same name then the
1010                // `WorldKey::Interface` case is ruled out as otherwise
1011                // they'd have different names.
1012                //
1013                // In the case of an anonymous interface all we can do is
1014                // ensure that the interfaces both match, so use `MergeMap`
1015                // for that.
1016                map.build_interface(*from, *into)
1017                    .context("failed to merge interfaces")?;
1018            }
1019
1020            // Like `WorldKey::Name` interfaces for functions and types the
1021            // structure is asserted to be the same.
1022            (WorldItem::Function(from), WorldItem::Function(into)) => {
1023                map.build_function(from, into)
1024                    .context("failed to merge functions")?;
1025            }
1026            (WorldItem::Type(from), WorldItem::Type(into)) => {
1027                map.build_type_id(*from, *into)
1028                    .context("failed to merge types")?;
1029            }
1030
1031            // Kind-level mismatches are caught here.
1032            (WorldItem::Interface { .. }, _)
1033            | (WorldItem::Function { .. }, _)
1034            | (WorldItem::Type { .. }, _) => {
1035                bail!("different kinds of items");
1036            }
1037        }
1038        assert!(map.interfaces_to_add.is_empty());
1039        assert!(map.worlds_to_add.is_empty());
1040        Ok(())
1041    }
1042
1043    /// This method ensures that the world export of `name` and `item` can be
1044    /// added to the world `into` without changing the meaning of `into`.
1045    ///
1046    /// All dependencies of world exports must either be:
1047    ///
1048    /// * An export themselves
1049    /// * An import with all transitive dependencies of the import also imported
1050    ///
1051    /// It's not possible to depend on an import which then also depends on an
1052    /// export at some point, for example. This method ensures that if `name`
1053    /// and `item` are added that this property is upheld.
1054    fn ensure_can_add_world_export(
1055        &self,
1056        into: &World,
1057        name: &WorldKey,
1058        item: &WorldItem,
1059        must_be_imported: &HashMap<InterfaceId, WorldKey>,
1060    ) -> Result<()> {
1061        assert!(!into.exports.contains_key(name));
1062        let name = self.name_world_key(name);
1063
1064        // First make sure that all of this item's dependencies are either
1065        // exported or the entire chain of imports rooted at that dependency are
1066        // all imported.
1067        for dep in self.world_item_direct_deps(item) {
1068            if into.exports.contains_key(&WorldKey::Interface(dep)) {
1069                continue;
1070            }
1071            self.ensure_not_exported(into, dep)
1072                .with_context(|| format!("failed validating export of `{name}`"))?;
1073        }
1074
1075        // Second make sure that this item, if it's an interface, will not alter
1076        // the meaning of the preexisting world by ensuring that it's not in the
1077        // set of "must be imported" items.
1078        if let WorldItem::Interface { id, .. } = item {
1079            if let Some(export) = must_be_imported.get(&id) {
1080                let export_name = self.name_world_key(export);
1081                bail!(
1082                    "export `{export_name}` depends on `{name}` \
1083                     previously as an import which will change meaning \
1084                     if `{name}` is added as an export"
1085                );
1086            }
1087        }
1088
1089        Ok(())
1090    }
1091
1092    fn ensure_not_exported(&self, world: &World, id: InterfaceId) -> Result<()> {
1093        let key = WorldKey::Interface(id);
1094        let name = self.name_world_key(&key);
1095        if world.exports.contains_key(&key) {
1096            bail!(
1097                "world exports `{name}` but it's also transitively used by an \
1098                     import \
1099                   which means that this is not valid"
1100            )
1101        }
1102        for dep in self.interface_direct_deps(id) {
1103            self.ensure_not_exported(world, dep)
1104                .with_context(|| format!("failed validating transitive import dep `{name}`"))?;
1105        }
1106        Ok(())
1107    }
1108
1109    /// Returns an iterator of all the direct interface dependencies of this
1110    /// `item`.
1111    ///
1112    /// Note that this doesn't include transitive dependencies, that must be
1113    /// followed manually.
1114    fn world_item_direct_deps(&self, item: &WorldItem) -> impl Iterator<Item = InterfaceId> + '_ {
1115        let mut interface = None;
1116        let mut ty = None;
1117        match item {
1118            WorldItem::Function(_) => {}
1119            WorldItem::Type(id) => ty = Some(*id),
1120            WorldItem::Interface { id, .. } => interface = Some(*id),
1121        }
1122
1123        interface
1124            .into_iter()
1125            .flat_map(move |id| self.interface_direct_deps(id))
1126            .chain(ty.and_then(|t| self.type_interface_dep(t)))
1127    }
1128
1129    /// Invokes `f` with `id` and all transitive interface dependencies of `id`.
1130    ///
1131    /// Note that `f` may be called with the same id multiple times.
1132    fn foreach_interface_dep(&self, id: InterfaceId, f: &mut dyn FnMut(InterfaceId)) {
1133        self._foreach_interface_dep(id, f, &mut HashSet::new())
1134    }
1135
1136    // Internal detail of `foreach_interface_dep` which uses a hash map to prune
1137    // the visit tree to ensure that this doesn't visit an exponential number of
1138    // interfaces.
1139    fn _foreach_interface_dep(
1140        &self,
1141        id: InterfaceId,
1142        f: &mut dyn FnMut(InterfaceId),
1143        visited: &mut HashSet<InterfaceId>,
1144    ) {
1145        if !visited.insert(id) {
1146            return;
1147        }
1148        f(id);
1149        for dep in self.interface_direct_deps(id) {
1150            self._foreach_interface_dep(dep, f, visited);
1151        }
1152    }
1153
1154    /// Returns the ID of the specified `interface`.
1155    ///
1156    /// Returns `None` for unnamed interfaces.
1157    pub fn id_of(&self, interface: InterfaceId) -> Option<String> {
1158        let interface = &self.interfaces[interface];
1159        Some(self.id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1160    }
1161
1162    /// Returns the "canonicalized interface name" of `interface`.
1163    ///
1164    /// Returns `None` for unnamed interfaces. See `BuildTargets.md` in the
1165    /// upstream component model repository for more information about this.
1166    pub fn canonicalized_id_of(&self, interface: InterfaceId) -> Option<String> {
1167        let interface = &self.interfaces[interface];
1168        Some(self.canonicalized_id_of_name(interface.package.unwrap(), interface.name.as_ref()?))
1169    }
1170
1171    /// Convert a world to an "importized" version where the world is updated
1172    /// in-place to reflect what it would look like to be imported.
1173    ///
1174    /// This is a transformation which is used as part of the process of
1175    /// importing a component today. For example when a component depends on
1176    /// another component this is useful for generating WIT which can be use to
1177    /// represent the component being imported. The general idea is that this
1178    /// function will update the `world_id` specified such it imports the
1179    /// functionality that it previously exported. The world will be left with
1180    /// no exports.
1181    ///
1182    /// This world is then suitable for merging into other worlds or generating
1183    /// bindings in a context that is importing the original world. This
1184    /// is intended to be used as part of language tooling when depending on
1185    /// other components.
1186    pub fn importize(&mut self, world_id: WorldId, out_world_name: Option<String>) -> Result<()> {
1187        // Rename the world to avoid having it get confused with the original
1188        // name of the world. Add `-importized` to it for now. Precisely how
1189        // this new world is created may want to be updated over time if this
1190        // becomes problematic.
1191        let world = &mut self.worlds[world_id];
1192        let pkg = &mut self.packages[world.package.unwrap()];
1193        pkg.worlds.shift_remove(&world.name);
1194        if let Some(name) = out_world_name {
1195            world.name = name.clone();
1196            pkg.worlds.insert(name, world_id);
1197        } else {
1198            world.name.push_str("-importized");
1199            pkg.worlds.insert(world.name.clone(), world_id);
1200        }
1201
1202        // Trim all non-type definitions from imports. Types can be used by
1203        // exported functions, for example, so they're preserved.
1204        world.imports.retain(|_, item| match item {
1205            WorldItem::Type(_) => true,
1206            _ => false,
1207        });
1208
1209        for (name, export) in mem::take(&mut world.exports) {
1210            match (name.clone(), world.imports.insert(name, export)) {
1211                // no previous item? this insertion was ok
1212                (_, None) => {}
1213
1214                // cannot overwrite an import with an export
1215                (WorldKey::Name(name), Some(_)) => {
1216                    bail!("world export `{name}` conflicts with import of same name");
1217                }
1218
1219                // Exports already don't overlap each other and the only imports
1220                // preserved above were types so this shouldn't be reachable.
1221                (WorldKey::Interface(_), _) => unreachable!(),
1222            }
1223        }
1224
1225        // Fill out any missing transitive interface imports by elaborating this
1226        // world which does that for us.
1227        self.elaborate_world(world_id)?;
1228
1229        #[cfg(debug_assertions)]
1230        self.assert_valid();
1231        Ok(())
1232    }
1233
1234    /// Returns the ID of the specified `name` within the `pkg`.
1235    pub fn id_of_name(&self, pkg: PackageId, name: &str) -> String {
1236        let package = &self.packages[pkg];
1237        let mut base = String::new();
1238        base.push_str(&package.name.namespace);
1239        base.push_str(":");
1240        base.push_str(&package.name.name);
1241        base.push_str("/");
1242        base.push_str(name);
1243        if let Some(version) = &package.name.version {
1244            base.push_str(&format!("@{version}"));
1245        }
1246        base
1247    }
1248
1249    /// Returns the "canonicalized interface name" of the specified `name`
1250    /// within the `pkg`.
1251    ///
1252    /// See `BuildTargets.md` in the upstream component model repository for
1253    /// more information about this.
1254    pub fn canonicalized_id_of_name(&self, pkg: PackageId, name: &str) -> String {
1255        let package = &self.packages[pkg];
1256        let mut base = String::new();
1257        base.push_str(&package.name.namespace);
1258        base.push_str(":");
1259        base.push_str(&package.name.name);
1260        base.push_str("/");
1261        base.push_str(name);
1262        if let Some(version) = &package.name.version {
1263            base.push_str("@");
1264            let string = PackageName::version_compat_track_string(version);
1265            base.push_str(&string);
1266        }
1267        base
1268    }
1269
1270    /// Selects a world from among the packages in a `Resolve`.
1271    ///
1272    /// A `Resolve` may have many packages, each with many worlds. Many WIT
1273    /// tools need a specific world to operate on. This function choses a
1274    /// world, failing if the choice is ambiguous.
1275    ///
1276    /// `main_packages` provides the package IDs returned by
1277    /// [`push_path`](Resolve::push_path), [`push_dir`](Resolve::push_dir),
1278    /// [`push_file`](Resolve::push_file), [`push_group`](Resolve::push_group),
1279    /// and [`push_str`](Resolve::push_str), which are the "main packages",
1280    /// as distinguished from any packages nested inside them.
1281    ///
1282    /// `world` is a world name such as from a `--world` command-line option or
1283    /// a `world:` macro parameter. `world` can be:
1284    ///
1285    /// * A kebab-name of a world, for example `"the-world"`. It is resolved
1286    ///   within the "main package", if there is exactly one.
1287    ///
1288    /// * An ID-based form of a world, for example `"wasi:http/proxy"`. Note
1289    ///   that a version does not need to be specified in this string if
1290    ///   there's only one package of the same name and it has a version. In
1291    ///   this situation the version can be omitted.
1292    ///
1293    /// * `None`. If there's exactly one "main package" and it contains exactly
1294    ///   one world, that world is chosen.
1295    ///
1296    /// If successful, the chosen `WorldId` is returned.
1297    ///
1298    /// # Examples
1299    ///
1300    /// ```
1301    /// use anyhow::Result;
1302    /// use wit_parser::Resolve;
1303    ///
1304    /// fn main() -> Result<()> {
1305    ///     let mut resolve = Resolve::default();
1306    ///
1307    ///     // If there's a single package and only one world, that world is
1308    ///     // the obvious choice.
1309    ///     let wit1 = resolve.push_str(
1310    ///         "./my-test.wit",
1311    ///         r#"
1312    ///             package example:wit1;
1313    ///
1314    ///             world foo {
1315    ///                 // ...
1316    ///             }
1317    ///         "#,
1318    ///     )?;
1319    ///     assert!(resolve.select_world(&[wit1], None).is_ok());
1320    ///
1321    ///     // If there are multiple packages, we need to be told which package
1322    ///     // to use, either by a "main package" or by a fully-qualified name.
1323    ///     let wit2 = resolve.push_str(
1324    ///         "./my-test.wit",
1325    ///         r#"
1326    ///             package example:wit2;
1327    ///
1328    ///             world foo { /* ... */ }
1329    ///         "#,
1330    ///     )?;
1331    ///     assert!(resolve.select_world(&[wit1, wit2], None).is_err());
1332    ///     assert!(resolve.select_world(&[wit1, wit2], Some("foo")).is_err());
1333    ///     // Fix: use fully-qualified names.
1334    ///     assert!(resolve.select_world(&[wit1, wit2], Some("example:wit1/foo")).is_ok());
1335    ///     assert!(resolve.select_world(&[wit1, wit2], Some("example:wit2/foo")).is_ok());
1336    ///
1337    ///     // If a package has multiple worlds, then we can't guess the world
1338    ///     // even if we know the package.
1339    ///     let wit3 = resolve.push_str(
1340    ///         "./my-test.wit",
1341    ///         r#"
1342    ///             package example:wit3;
1343    ///
1344    ///             world foo { /* ... */ }
1345    ///
1346    ///             world bar { /* ... */ }
1347    ///         "#,
1348    ///     )?;
1349    ///     assert!(resolve.select_world(&[wit3], None).is_err());
1350    ///     // Fix: pick between "foo" and "bar" here.
1351    ///     assert!(resolve.select_world(&[wit3], Some("foo")).is_ok());
1352    ///
1353    ///     // When selecting with a version it's ok to drop the version when
1354    ///     // there's only a single copy of that package in `Resolve`.
1355    ///     let wit5_1 = resolve.push_str(
1356    ///         "./my-test.wit",
1357    ///         r#"
1358    ///             package example:wit5@1.0.0;
1359    ///
1360    ///             world foo { /* ... */ }
1361    ///         "#,
1362    ///     )?;
1363    ///     assert!(resolve.select_world(&[wit5_1], Some("foo")).is_ok());
1364    ///     assert!(resolve.select_world(&[wit5_1], Some("example:wit5/foo")).is_ok());
1365    ///
1366    ///     // However when a single package has multiple versions in a resolve
1367    ///     // it's required to specify the version to select which one.
1368    ///     let wit5_2 = resolve.push_str(
1369    ///         "./my-test.wit",
1370    ///         r#"
1371    ///             package example:wit5@2.0.0;
1372    ///
1373    ///             world foo { /* ... */ }
1374    ///         "#,
1375    ///     )?;
1376    ///     assert!(resolve.select_world(&[wit5_1, wit5_2], Some("example:wit5/foo")).is_err());
1377    ///     // Fix: Pass explicit versions.
1378    ///     assert!(resolve.select_world(&[wit5_1, wit5_2], Some("example:wit5/foo@1.0.0")).is_ok());
1379    ///     assert!(resolve.select_world(&[wit5_1, wit5_2], Some("example:wit5/foo@2.0.0")).is_ok());
1380    ///
1381    ///     Ok(())
1382    /// }
1383    /// ```
1384    pub fn select_world(
1385        &self,
1386        main_packages: &[PackageId],
1387        world: Option<&str>,
1388    ) -> Result<WorldId> {
1389        // Determine if `world` is a kebab-name or an ID.
1390        let world_path = match world {
1391            Some(world) => Some(
1392                parse_use_path(world)
1393                    .with_context(|| format!("failed to parse world specifier `{world}`"))?,
1394            ),
1395            None => None,
1396        };
1397
1398        match world_path {
1399            // We have a world path. If needed, pick a package to resolve it in.
1400            Some(world_path) => {
1401                let (pkg, world_name) = match (main_packages, world_path) {
1402                    // We have no main packages; fail.
1403                    ([], _) => bail!("No main packages defined"),
1404
1405                    // We have exactly one main package.
1406                    ([main_package], ParsedUsePath::Name(name)) => (*main_package, name),
1407
1408                    // We have more than one main package; fail.
1409                    (_, ParsedUsePath::Name(_name)) => {
1410                        bail!(
1411                            "There are multiple main packages; a world must be explicitly chosen:{}",
1412                            self.worlds
1413                                .iter()
1414                                .map(|world| format!(
1415                                    "\n  {}",
1416                                    self.id_of_name(world.1.package.unwrap(), &world.1.name)
1417                                ))
1418                                .collect::<String>()
1419                        )
1420                    }
1421
1422                    // The world name is fully-qualified.
1423                    (_, ParsedUsePath::Package(pkg, world_name)) => {
1424                        let pkg = match self.package_names.get(&pkg) {
1425                            Some(pkg) => *pkg,
1426                            None => {
1427                                let mut candidates =
1428                                    self.package_names.iter().filter(|(name, _)| {
1429                                        pkg.version.is_none()
1430                                            && pkg.name == name.name
1431                                            && pkg.namespace == name.namespace
1432                                            && name.version.is_some()
1433                                    });
1434                                let candidate = candidates.next();
1435                                if let Some((c2, _)) = candidates.next() {
1436                                    let (c1, _) = candidate.unwrap();
1437                                    bail!(
1438                                        "package name `{pkg}` is available at both \
1439                                    versions {} and {} but which is not specified",
1440                                        c1.version.as_ref().unwrap(),
1441                                        c2.version.as_ref().unwrap(),
1442                                    );
1443                                }
1444                                match candidate {
1445                                    Some((_, id)) => *id,
1446                                    None => bail!("unknown package `{pkg}`"),
1447                                }
1448                            }
1449                        };
1450                        (pkg, world_name.to_string())
1451                    }
1452                };
1453
1454                // Now that we've picked the package, resolve the world name.
1455                let pkg = &self.packages[pkg];
1456                pkg.worlds.get(&world_name).copied().ok_or_else(|| {
1457                    anyhow!("World `{world_name}` not found in package `{}`", pkg.name)
1458                })
1459            }
1460
1461            // With no specified `world`, try to find a single obvious world.
1462            None => match main_packages {
1463                [] => bail!("No main packages defined"),
1464
1465                // Check for exactly one main package with exactly one world.
1466                [main_package] => {
1467                    let pkg = &self.packages[*main_package];
1468                    match pkg.worlds.len() {
1469                        0 => bail!("The main package `{}` contains no worlds", pkg.name),
1470                        1 => Ok(pkg.worlds[0]),
1471                        _ => bail!(
1472                            "There are multiple worlds in `{}`; one must be explicitly chosen:{}",
1473                            pkg.name,
1474                            pkg.worlds
1475                                .values()
1476                                .map(|world| format!(
1477                                    "\n  {}",
1478                                    self.id_of_name(*main_package, &self.worlds[*world].name)
1479                                ))
1480                                .collect::<String>()
1481                        ),
1482                    }
1483                }
1484
1485                // Multiple main packages and no world name; fail.
1486                _ => {
1487                    bail!(
1488                        "There are multiple main packages; a world must be explicitly chosen:{}",
1489                        self.worlds
1490                            .iter()
1491                            .map(|world| format!(
1492                                "\n  {}",
1493                                self.id_of_name(world.1.package.unwrap(), &world.1.name)
1494                            ))
1495                            .collect::<String>()
1496                    )
1497                }
1498            },
1499        }
1500    }
1501
1502    /// Assigns a human readable name to the `WorldKey` specified.
1503    pub fn name_world_key(&self, key: &WorldKey) -> String {
1504        match key {
1505            WorldKey::Name(s) => s.to_string(),
1506            WorldKey::Interface(i) => self.id_of(*i).expect("unexpected anonymous interface"),
1507        }
1508    }
1509
1510    /// Same as [`Resolve::name_world_key`] except that `WorldKey::Interfaces`
1511    /// uses [`Resolve::canonicalized_id_of`].
1512    pub fn name_canonicalized_world_key(&self, key: &WorldKey) -> String {
1513        match key {
1514            WorldKey::Name(s) => s.to_string(),
1515            WorldKey::Interface(i) => self
1516                .canonicalized_id_of(*i)
1517                .expect("unexpected anonymous interface"),
1518        }
1519    }
1520
1521    /// Returns the interface that `id` uses a type from, if it uses a type from
1522    /// a different interface than `id` is defined within.
1523    ///
1524    /// If `id` is not a use-of-a-type or it's using a type in the same
1525    /// interface then `None` is returned.
1526    pub fn type_interface_dep(&self, id: TypeId) -> Option<InterfaceId> {
1527        let ty = &self.types[id];
1528        let dep = match ty.kind {
1529            TypeDefKind::Type(Type::Id(id)) => id,
1530            _ => return None,
1531        };
1532        let other = &self.types[dep];
1533        if ty.owner == other.owner {
1534            None
1535        } else {
1536            match other.owner {
1537                TypeOwner::Interface(id) => Some(id),
1538                _ => unreachable!(),
1539            }
1540        }
1541    }
1542
1543    /// Returns an iterator of all interfaces that the interface `id` depends
1544    /// on.
1545    ///
1546    /// Interfaces may depend on others for type information to resolve type
1547    /// imports.
1548    ///
1549    /// Note that the returned iterator may yield the same interface as a
1550    /// dependency multiple times. Additionally only direct dependencies of `id`
1551    /// are yielded, not transitive dependencies.
1552    pub fn interface_direct_deps(&self, id: InterfaceId) -> impl Iterator<Item = InterfaceId> + '_ {
1553        self.interfaces[id]
1554            .types
1555            .iter()
1556            .filter_map(move |(_name, ty)| self.type_interface_dep(*ty))
1557    }
1558
1559    /// Returns an iterator of all packages that the package `id` depends
1560    /// on.
1561    ///
1562    /// Packages may depend on others for type information to resolve type
1563    /// imports or interfaces to resolve worlds.
1564    ///
1565    /// Note that the returned iterator may yield the same package as a
1566    /// dependency multiple times. Additionally only direct dependencies of `id`
1567    /// are yielded, not transitive dependencies.
1568    pub fn package_direct_deps(&self, id: PackageId) -> impl Iterator<Item = PackageId> + '_ {
1569        let pkg = &self.packages[id];
1570
1571        pkg.interfaces
1572            .iter()
1573            .flat_map(move |(_name, id)| self.interface_direct_deps(*id))
1574            .chain(pkg.worlds.iter().flat_map(move |(_name, id)| {
1575                let world = &self.worlds[*id];
1576                world
1577                    .imports
1578                    .iter()
1579                    .chain(world.exports.iter())
1580                    .filter_map(move |(_name, item)| match item {
1581                        WorldItem::Interface { id, .. } => Some(*id),
1582                        WorldItem::Function(_) => None,
1583                        WorldItem::Type(t) => self.type_interface_dep(*t),
1584                    })
1585            }))
1586            .filter_map(move |iface_id| {
1587                let pkg = self.interfaces[iface_id].package?;
1588                if pkg == id { None } else { Some(pkg) }
1589            })
1590    }
1591
1592    /// Returns a topological ordering of packages contained in this `Resolve`.
1593    ///
1594    /// This returns a list of `PackageId` such that when visited in order it's
1595    /// guaranteed that all dependencies will have been defined by prior items
1596    /// in the list.
1597    pub fn topological_packages(&self) -> Vec<PackageId> {
1598        let mut pushed = vec![false; self.packages.len()];
1599        let mut order = Vec::new();
1600        for (id, _) in self.packages.iter() {
1601            self.build_topological_package_ordering(id, &mut pushed, &mut order);
1602        }
1603        order
1604    }
1605
1606    fn build_topological_package_ordering(
1607        &self,
1608        id: PackageId,
1609        pushed: &mut Vec<bool>,
1610        order: &mut Vec<PackageId>,
1611    ) {
1612        if pushed[id.index()] {
1613            return;
1614        }
1615        for dep in self.package_direct_deps(id) {
1616            self.build_topological_package_ordering(dep, pushed, order);
1617        }
1618        order.push(id);
1619        pushed[id.index()] = true;
1620    }
1621
1622    #[doc(hidden)]
1623    pub fn assert_valid(&self) {
1624        let mut package_interfaces = Vec::new();
1625        let mut package_worlds = Vec::new();
1626        for (id, pkg) in self.packages.iter() {
1627            let mut interfaces = HashSet::new();
1628            for (name, iface) in pkg.interfaces.iter() {
1629                assert!(interfaces.insert(*iface));
1630                let iface = &self.interfaces[*iface];
1631                assert_eq!(name, iface.name.as_ref().unwrap());
1632                assert_eq!(iface.package.unwrap(), id);
1633            }
1634            package_interfaces.push(pkg.interfaces.values().copied().collect::<HashSet<_>>());
1635            let mut worlds = HashSet::new();
1636            for (name, world) in pkg.worlds.iter() {
1637                assert!(worlds.insert(*world));
1638                assert_eq!(
1639                    pkg.worlds.get_key_value(name),
1640                    Some((name, world)),
1641                    "`MutableKeys` impl may have been used to change a key's hash or equality"
1642                );
1643                let world = &self.worlds[*world];
1644                assert_eq!(*name, world.name);
1645                assert_eq!(world.package.unwrap(), id);
1646            }
1647            package_worlds.push(pkg.worlds.values().copied().collect::<HashSet<_>>());
1648        }
1649
1650        let mut interface_types = Vec::new();
1651        for (id, iface) in self.interfaces.iter() {
1652            assert!(self.packages.get(iface.package.unwrap()).is_some());
1653            if iface.name.is_some() {
1654                assert!(package_interfaces[iface.package.unwrap().index()].contains(&id));
1655            }
1656
1657            for (name, ty) in iface.types.iter() {
1658                let ty = &self.types[*ty];
1659                assert_eq!(ty.name.as_ref(), Some(name));
1660                assert_eq!(ty.owner, TypeOwner::Interface(id));
1661            }
1662            interface_types.push(iface.types.values().copied().collect::<HashSet<_>>());
1663            for (name, f) in iface.functions.iter() {
1664                assert_eq!(*name, f.name);
1665            }
1666        }
1667
1668        let mut world_types = Vec::new();
1669        for (id, world) in self.worlds.iter() {
1670            log::debug!("validating world {}", &world.name);
1671            if let Some(package) = world.package {
1672                assert!(self.packages.get(package).is_some());
1673                assert!(package_worlds[package.index()].contains(&id));
1674            }
1675            assert!(world.includes.is_empty());
1676
1677            let mut types = HashSet::new();
1678            for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1679                log::debug!("validating world item: {}", self.name_world_key(name));
1680                match item {
1681                    WorldItem::Interface { id, .. } => {
1682                        // anonymous interfaces must belong to the same package
1683                        // as the world's package.
1684                        if matches!(name, WorldKey::Name(_)) {
1685                            assert_eq!(self.interfaces[*id].package, world.package);
1686                        }
1687                    }
1688                    WorldItem::Function(f) => {
1689                        assert!(!matches!(name, WorldKey::Interface(_)));
1690                        assert_eq!(f.name, name.clone().unwrap_name());
1691                    }
1692                    WorldItem::Type(ty) => {
1693                        assert!(!matches!(name, WorldKey::Interface(_)));
1694                        assert!(types.insert(*ty));
1695                        let ty = &self.types[*ty];
1696                        assert_eq!(ty.name, Some(name.clone().unwrap_name()));
1697                        assert_eq!(ty.owner, TypeOwner::World(id));
1698                    }
1699                }
1700            }
1701            self.assert_world_elaborated(world);
1702            world_types.push(types);
1703        }
1704
1705        for (ty_id, ty) in self.types.iter() {
1706            match ty.owner {
1707                TypeOwner::Interface(id) => {
1708                    assert!(self.interfaces.get(id).is_some());
1709                    assert!(interface_types[id.index()].contains(&ty_id));
1710                }
1711                TypeOwner::World(id) => {
1712                    assert!(self.worlds.get(id).is_some());
1713                    assert!(world_types[id.index()].contains(&ty_id));
1714                }
1715                TypeOwner::None => {}
1716            }
1717        }
1718
1719        self.assert_topologically_sorted();
1720    }
1721
1722    fn assert_topologically_sorted(&self) {
1723        let mut positions = IndexMap::new();
1724        for id in self.topological_packages() {
1725            let pkg = &self.packages[id];
1726            log::debug!("pkg {}", pkg.name);
1727            let prev = positions.insert(Some(id), IndexSet::new());
1728            assert!(prev.is_none());
1729        }
1730        positions.insert(None, IndexSet::new());
1731
1732        for (id, iface) in self.interfaces.iter() {
1733            log::debug!("iface {:?}", iface.name);
1734            let ok = positions.get_mut(&iface.package).unwrap().insert(id);
1735            assert!(ok);
1736        }
1737
1738        for (_, world) in self.worlds.iter() {
1739            log::debug!("world {:?}", world.name);
1740
1741            let my_package = world.package;
1742            let my_package_pos = positions.get_index_of(&my_package).unwrap();
1743
1744            for (_, item) in world.imports.iter().chain(&world.exports) {
1745                let id = match item {
1746                    WorldItem::Interface { id, .. } => *id,
1747                    _ => continue,
1748                };
1749                let other_package = self.interfaces[id].package;
1750                let other_package_pos = positions.get_index_of(&other_package).unwrap();
1751
1752                assert!(other_package_pos <= my_package_pos);
1753            }
1754        }
1755
1756        for (_id, ty) in self.types.iter() {
1757            log::debug!("type {:?} {:?}", ty.name, ty.owner);
1758            let other_id = match ty.kind {
1759                TypeDefKind::Type(Type::Id(ty)) => ty,
1760                _ => continue,
1761            };
1762            let other = &self.types[other_id];
1763            if ty.kind == other.kind {
1764                continue;
1765            }
1766            let my_interface = match ty.owner {
1767                TypeOwner::Interface(id) => id,
1768                _ => continue,
1769            };
1770            let other_interface = match other.owner {
1771                TypeOwner::Interface(id) => id,
1772                _ => continue,
1773            };
1774
1775            let my_package = self.interfaces[my_interface].package;
1776            let other_package = self.interfaces[other_interface].package;
1777            let my_package_pos = positions.get_index_of(&my_package).unwrap();
1778            let other_package_pos = positions.get_index_of(&other_package).unwrap();
1779
1780            if my_package_pos == other_package_pos {
1781                let interfaces = &positions[&my_package];
1782                let my_interface_pos = interfaces.get_index_of(&my_interface).unwrap();
1783                let other_interface_pos = interfaces.get_index_of(&other_interface).unwrap();
1784                assert!(other_interface_pos <= my_interface_pos);
1785            } else {
1786                assert!(other_package_pos < my_package_pos);
1787            }
1788        }
1789    }
1790
1791    fn assert_world_elaborated(&self, world: &World) {
1792        for (key, item) in world.imports.iter() {
1793            log::debug!(
1794                "asserting elaborated world import {}",
1795                self.name_world_key(key)
1796            );
1797            match item {
1798                WorldItem::Type(t) => self.assert_world_imports_type_deps(world, key, *t),
1799
1800                // All types referred to must be imported.
1801                WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1802
1803                // All direct dependencies of this interface must be imported.
1804                WorldItem::Interface { id, .. } => {
1805                    for dep in self.interface_direct_deps(*id) {
1806                        assert!(
1807                            world.imports.contains_key(&WorldKey::Interface(dep)),
1808                            "world import of {} is missing transitive dep of {}",
1809                            self.name_world_key(key),
1810                            self.id_of(dep).unwrap(),
1811                        );
1812                    }
1813                }
1814            }
1815        }
1816        for (key, item) in world.exports.iter() {
1817            log::debug!(
1818                "asserting elaborated world export {}",
1819                self.name_world_key(key)
1820            );
1821            match item {
1822                // Types referred to by this function must be imported.
1823                WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1824
1825                // Dependencies of exported interfaces must also be exported, or
1826                // if imported then that entire chain of imports must be
1827                // imported and not exported.
1828                WorldItem::Interface { id, .. } => {
1829                    for dep in self.interface_direct_deps(*id) {
1830                        let dep_key = WorldKey::Interface(dep);
1831                        if world.exports.contains_key(&dep_key) {
1832                            continue;
1833                        }
1834                        self.foreach_interface_dep(dep, &mut |dep| {
1835                            let dep_key = WorldKey::Interface(dep);
1836                            assert!(
1837                                world.imports.contains_key(&dep_key),
1838                                "world should import {} (required by {})",
1839                                self.name_world_key(&dep_key),
1840                                self.name_world_key(key),
1841                            );
1842                            assert!(
1843                                !world.exports.contains_key(&dep_key),
1844                                "world should not export {} (required by {})",
1845                                self.name_world_key(&dep_key),
1846                                self.name_world_key(key),
1847                            );
1848                        });
1849                    }
1850                }
1851
1852                // exported types not allowed at this time
1853                WorldItem::Type(_) => unreachable!(),
1854            }
1855        }
1856    }
1857
1858    fn assert_world_imports_type_deps(&self, world: &World, key: &WorldKey, ty: TypeId) {
1859        // If this is a `use` statement then the referred-to interface must be
1860        // imported into this world.
1861        let ty = &self.types[ty];
1862        if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
1863            if let TypeOwner::Interface(id) = self.types[other].owner {
1864                let key = WorldKey::Interface(id);
1865                assert!(world.imports.contains_key(&key));
1866                return;
1867            }
1868        }
1869
1870        // ... otherwise any named type that this type refers to, one level
1871        // deep, must be imported into this world under that name.
1872
1873        let mut visitor = MyVisit(self, Vec::new());
1874        visitor.visit_type_def(self, ty);
1875        for ty in visitor.1 {
1876            let ty = &self.types[ty];
1877            let Some(name) = ty.name.clone() else {
1878                continue;
1879            };
1880            let dep_key = WorldKey::Name(name);
1881            assert!(
1882                world.imports.contains_key(&dep_key),
1883                "world import `{}` should also force an import of `{}`",
1884                self.name_world_key(key),
1885                self.name_world_key(&dep_key),
1886            );
1887        }
1888
1889        struct MyVisit<'a>(&'a Resolve, Vec<TypeId>);
1890
1891        impl TypeIdVisitor for MyVisit<'_> {
1892            fn before_visit_type_id(&mut self, id: TypeId) -> bool {
1893                self.1.push(id);
1894                // recurse into unnamed types to look at all named types
1895                self.0.types[id].name.is_none()
1896            }
1897        }
1898    }
1899
1900    /// This asserts that all types referred to by `func` are imported into
1901    /// `world` under `WorldKey::Name`. Note that this is only applicable to
1902    /// named type
1903    fn assert_world_function_imports_types(&self, world: &World, key: &WorldKey, func: &Function) {
1904        for ty in func
1905            .parameter_and_result_types()
1906            .chain(func.kind.resource().map(Type::Id))
1907        {
1908            let Type::Id(id) = ty else {
1909                continue;
1910            };
1911            self.assert_world_imports_type_deps(world, key, id);
1912        }
1913    }
1914
1915    /// Returns whether the `stability` annotation contained within `pkg_id`
1916    /// should be included or not.
1917    ///
1918    /// The `span` provided here is an optional span pointing to the item that
1919    /// is annotated with `stability`.
1920    ///
1921    /// Returns `Ok(true)` if the item is included, or `Ok(false)` if the item
1922    /// is not.
1923    ///
1924    /// # Errors
1925    ///
1926    /// Returns an error if the `pkg_id` isn't annotated with sufficient version
1927    /// information to have a `stability` annotation. For example if `pkg_id`
1928    /// has no version listed then an error will be returned if `stability`
1929    /// mentions a version.
1930    fn include_stability(
1931        &self,
1932        stability: &Stability,
1933        pkg_id: &PackageId,
1934        span: Option<Span>,
1935    ) -> Result<bool> {
1936        let err = |msg: String| match span {
1937            Some(span) => Error::new(span, msg).into(),
1938            None => anyhow::Error::msg(msg),
1939        };
1940        Ok(match stability {
1941            Stability::Unknown => true,
1942            // NOTE: deprecations are intentionally omitted -- an existing
1943            // `@since` takes precedence over `@deprecated`
1944            Stability::Stable { since, .. } => {
1945                let Some(p) = self.packages.get(*pkg_id) else {
1946                    // We can't check much without a package (possibly dealing
1947                    // with an item in an `UnresolvedPackage`), @since version &
1948                    // deprecations can't be checked because there's no package
1949                    // version to compare to.
1950                    //
1951                    // Feature requirements on stabilized features are ignored
1952                    // in resolved packages, so we do the same here.
1953                    return Ok(true);
1954                };
1955
1956                // Use of feature gating with version specifiers inside a
1957                // package that is not versioned is not allowed
1958                let package_version = p.name.version.as_ref().ok_or_else(|| {
1959                    err(format!(
1960                        "package [{}] contains a feature gate with a version \
1961                         specifier, so it must have a version",
1962                        p.name
1963                    ))
1964                })?;
1965
1966                // If the version on the feature gate is:
1967                // - released, then we can include it
1968                // - unreleased, then we must check the feature (if present)
1969                if since > package_version {
1970                    return Err(err(format!(
1971                        "feature gate cannot reference unreleased version \
1972                        {since} of package [{}] (current version {package_version})",
1973                        p.name
1974                    )));
1975                }
1976
1977                true
1978            }
1979            Stability::Unstable { feature, .. } => {
1980                self.features.contains(feature) || self.all_features
1981            }
1982        })
1983    }
1984
1985    /// Convenience wrapper around `include_stability` specialized for types
1986    /// with a more targeted error message.
1987    fn include_type(&self, ty: &TypeDef, pkgid: PackageId, span: Span) -> Result<bool> {
1988        self.include_stability(&ty.stability, &pkgid, Some(span))
1989            .with_context(|| {
1990                format!(
1991                    "failed to process feature gate for type [{}] in package [{}]",
1992                    ty.name.as_ref().map(String::as_str).unwrap_or("<unknown>"),
1993                    self.packages[pkgid].name,
1994                )
1995            })
1996    }
1997
1998    /// Performs the "elaboration process" necessary for the `world_id`
1999    /// specified to ensure that all of its transitive imports are listed.
2000    ///
2001    /// This function will take the unordered lists of the specified world's
2002    /// imports and exports and "elaborate" them to ensure that they're
2003    /// topographically sorted where all transitively required interfaces by
2004    /// imports, or exports, are listed. This will additionally validate that
2005    /// the exports are all valid and present, specifically with the restriction
2006    /// noted on `elaborate_world_exports`.
2007    ///
2008    /// The world is mutated in-place in this `Resolve`.
2009    fn elaborate_world(&mut self, world_id: WorldId) -> Result<()> {
2010        // First process all imports. This is easier than exports since the only
2011        // requirement here is that all interfaces need to be added with a
2012        // topological order between them.
2013        let mut new_imports = IndexMap::new();
2014        let world = &self.worlds[world_id];
2015
2016        // Sort the imports by "class" to ensure that this matches the order
2017        // that items are printed and that items are in topological order.
2018        //
2019        // When printing worlds in WIT:
2020        //
2021        // * interfaces come first
2022        // * types are next
2023        //   * type imports are first
2024        //   * type definitions are next
2025        //   * resource definitions have methods printed inline
2026        // * freestanding functions are last
2027        //
2028        // This reflects the topological order between items where types
2029        // can refer to imports and functions can refer to these types. Ordering
2030        // within a single class (e.g. imports depending on each other, types
2031        // referring to each other) is already preserved by other passes in this
2032        // file and general AST resolution. That means that a stable sort here
2033        // can be used to ensure that each class is in the right location
2034        // relative to the others.
2035        //
2036        // Overall this ensures that round-trips of WIT through wasm should
2037        // always produce the same result.
2038        let sort_key = |resolve: &Resolve, item: &WorldItem| match item {
2039            WorldItem::Interface { .. } => 0,
2040            WorldItem::Type(ty) => {
2041                let ty = &resolve.types[*ty];
2042                match ty.kind {
2043                    TypeDefKind::Type(Type::Id(t)) if resolve.types[t].owner != ty.owner => 1,
2044                    _ => 2,
2045                }
2046            }
2047            WorldItem::Function(f) => {
2048                if f.kind.resource().is_none() {
2049                    3
2050                } else {
2051                    4
2052                }
2053            }
2054        };
2055
2056        // Sort world items when we start to elaborate the world to start with a
2057        // topological view of items.
2058        let mut world_imports = world.imports.iter().collect::<Vec<_>>();
2059        world_imports.sort_by_key(|(_name, import)| sort_key(self, import));
2060        for (name, item) in world_imports {
2061            match item {
2062                // Interfaces get their dependencies added first followed by the
2063                // interface itself.
2064                WorldItem::Interface { id, stability } => {
2065                    self.elaborate_world_import(&mut new_imports, name.clone(), *id, &stability);
2066                }
2067
2068                // Functions are added as-is since their dependence on types in
2069                // the world should already be satisfied.
2070                WorldItem::Function(_) => {
2071                    let prev = new_imports.insert(name.clone(), item.clone());
2072                    assert!(prev.is_none());
2073                }
2074
2075                // Types may depend on an interface, in which case a (possibly)
2076                // recursive addition of that interface happens here. Afterwards
2077                // the type itself can be added safely.
2078                WorldItem::Type(id) => {
2079                    if let Some(dep) = self.type_interface_dep(*id) {
2080                        self.elaborate_world_import(
2081                            &mut new_imports,
2082                            WorldKey::Interface(dep),
2083                            dep,
2084                            &self.types[*id].stability,
2085                        );
2086                    }
2087                    let prev = new_imports.insert(name.clone(), item.clone());
2088                    assert!(prev.is_none());
2089                }
2090            }
2091        }
2092
2093        // Exports are trickier than imports, notably to uphold the invariant
2094        // required by `elaborate_world_exports`. To do this the exports are
2095        // partitioned into interfaces/functions. All functions are added to
2096        // the new exports list during this loop but interfaces are all deferred
2097        // to be handled in the `elaborate_world_exports` function.
2098        let mut new_exports = IndexMap::new();
2099        let mut export_interfaces = IndexMap::new();
2100        for (name, item) in world.exports.iter() {
2101            match item {
2102                WorldItem::Interface { id, stability } => {
2103                    let prev = export_interfaces.insert(*id, (name.clone(), stability));
2104                    assert!(prev.is_none());
2105                }
2106                WorldItem::Function(_) => {
2107                    let prev = new_exports.insert(name.clone(), item.clone());
2108                    assert!(prev.is_none());
2109                }
2110                WorldItem::Type(_) => unreachable!(),
2111            }
2112        }
2113
2114        self.elaborate_world_exports(&export_interfaces, &mut new_imports, &mut new_exports)?;
2115
2116        // In addition to sorting at the start of elaboration also sort here at
2117        // the end of elaboration to handle types being interspersed with
2118        // interfaces as they're found.
2119        new_imports.sort_by_cached_key(|_name, import| sort_key(self, import));
2120
2121        // And with all that done the world is updated in-place with
2122        // imports/exports.
2123        log::trace!("imports = {new_imports:?}");
2124        log::trace!("exports = {new_exports:?}");
2125        let world = &mut self.worlds[world_id];
2126        world.imports = new_imports;
2127        world.exports = new_exports;
2128
2129        Ok(())
2130    }
2131
2132    fn elaborate_world_import(
2133        &self,
2134        imports: &mut IndexMap<WorldKey, WorldItem>,
2135        key: WorldKey,
2136        id: InterfaceId,
2137        stability: &Stability,
2138    ) {
2139        if imports.contains_key(&key) {
2140            return;
2141        }
2142        for dep in self.interface_direct_deps(id) {
2143            self.elaborate_world_import(imports, WorldKey::Interface(dep), dep, stability);
2144        }
2145        let prev = imports.insert(
2146            key,
2147            WorldItem::Interface {
2148                id,
2149                stability: stability.clone(),
2150            },
2151        );
2152        assert!(prev.is_none());
2153    }
2154
2155    /// This function adds all of the interfaces in `export_interfaces` to the
2156    /// list of exports of the `world` specified.
2157    ///
2158    /// This method is more involved than adding imports because it is fallible.
2159    /// Chiefly what can happen is that the dependencies of all exports must be
2160    /// satisfied by other exports or imports, but not both. For example given a
2161    /// situation such as:
2162    ///
2163    /// ```wit
2164    /// interface a {
2165    ///     type t = u32
2166    /// }
2167    /// interface b {
2168    ///     use a.{t}
2169    /// }
2170    /// interface c {
2171    ///     use a.{t}
2172    ///     use b.{t as t2}
2173    /// }
2174    /// ```
2175    ///
2176    /// where `c` depends on `b` and `a` where `b` depends on `a`, then the
2177    /// purpose of this method is to reject this world:
2178    ///
2179    /// ```wit
2180    /// world foo {
2181    ///     export a
2182    ///     export c
2183    /// }
2184    /// ```
2185    ///
2186    /// The reasoning here is unfortunately subtle and is additionally the
2187    /// subject of WebAssembly/component-model#208. Effectively the `c`
2188    /// interface depends on `b`, but it's not listed explicitly as an import,
2189    /// so it's then implicitly added as an import. This then transitively
2190    /// depends on `a` so it's also added as an import. At this point though `c`
2191    /// also depends on `a`, and it's also exported, so naively it should depend
2192    /// on the export and not implicitly add an import. This means though that
2193    /// `c` has access to two copies of `a`, one imported and one exported. This
2194    /// is not valid, especially in the face of resource types.
2195    ///
2196    /// Overall this method is tasked with rejecting the above world by walking
2197    /// over all the exports and adding their dependencies. Each dependency is
2198    /// recorded with whether it's required to be imported, and then if an
2199    /// export is added for something that's required to be an error then the
2200    /// operation fails.
2201    fn elaborate_world_exports(
2202        &self,
2203        export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2204        imports: &mut IndexMap<WorldKey, WorldItem>,
2205        exports: &mut IndexMap<WorldKey, WorldItem>,
2206    ) -> Result<()> {
2207        let mut required_imports = HashSet::new();
2208        for (id, (key, stability)) in export_interfaces.iter() {
2209            let name = self.name_world_key(&key);
2210            let ok = add_world_export(
2211                self,
2212                imports,
2213                exports,
2214                export_interfaces,
2215                &mut required_imports,
2216                *id,
2217                key,
2218                true,
2219                stability,
2220            );
2221            if !ok {
2222                bail!(
2223                    // FIXME: this is not a great error message and basically no
2224                    // one will know what to do when it gets printed. Improving
2225                    // this error message, however, is a chunk of work that may
2226                    // not be best spent doing this at this time, so I'm writing
2227                    // this comment instead.
2228                    //
2229                    // More-or-less what should happen here is that a "path"
2230                    // from this interface to the conflicting interface should
2231                    // be printed. It should be explained why an import is being
2232                    // injected, why that's conflicting with an export, and
2233                    // ideally with a suggestion of "add this interface to the
2234                    // export list to fix this error".
2235                    //
2236                    // That's a lot of info that's not easy to get at without
2237                    // more refactoring, so it's left to a future date in the
2238                    // hopes that most folks won't actually run into this for
2239                    // the time being.
2240                    InvalidTransitiveDependency(name),
2241                );
2242            }
2243        }
2244        return Ok(());
2245
2246        fn add_world_export(
2247            resolve: &Resolve,
2248            imports: &mut IndexMap<WorldKey, WorldItem>,
2249            exports: &mut IndexMap<WorldKey, WorldItem>,
2250            export_interfaces: &IndexMap<InterfaceId, (WorldKey, &Stability)>,
2251            required_imports: &mut HashSet<InterfaceId>,
2252            id: InterfaceId,
2253            key: &WorldKey,
2254            add_export: bool,
2255            stability: &Stability,
2256        ) -> bool {
2257            if exports.contains_key(key) {
2258                if add_export {
2259                    return true;
2260                } else {
2261                    return false;
2262                }
2263            }
2264            // If this is an import and it's already in the `required_imports`
2265            // set then we can skip it as we've already visited this interface.
2266            if !add_export && required_imports.contains(&id) {
2267                return true;
2268            }
2269            let ok = resolve.interface_direct_deps(id).all(|dep| {
2270                let key = WorldKey::Interface(dep);
2271                let add_export = add_export && export_interfaces.contains_key(&dep);
2272                add_world_export(
2273                    resolve,
2274                    imports,
2275                    exports,
2276                    export_interfaces,
2277                    required_imports,
2278                    dep,
2279                    &key,
2280                    add_export,
2281                    stability,
2282                )
2283            });
2284            if !ok {
2285                return false;
2286            }
2287            let item = WorldItem::Interface {
2288                id,
2289                stability: stability.clone(),
2290            };
2291            if add_export {
2292                if required_imports.contains(&id) {
2293                    return false;
2294                }
2295                exports.insert(key.clone(), item);
2296            } else {
2297                required_imports.insert(id);
2298                imports.insert(key.clone(), item);
2299            }
2300            true
2301        }
2302    }
2303
2304    /// Remove duplicate imports from a world if they import from the same
2305    /// interface with semver-compatible versions.
2306    ///
2307    /// This will merge duplicate interfaces present at multiple versions in
2308    /// both a world by selecting the larger version of the two interfaces. This
2309    /// requires that the interfaces are indeed semver-compatible and it means
2310    /// that some imports might be removed and replaced. Note that this is only
2311    /// done within a single semver track, for example the world imports 0.2.0
2312    /// and 0.2.1 then the result afterwards will be that it imports
2313    /// 0.2.1. If, however, 0.3.0 where imported then the final result would
2314    /// import both 0.2.0 and 0.3.0.
2315    pub fn merge_world_imports_based_on_semver(&mut self, world_id: WorldId) -> Result<()> {
2316        let world = &self.worlds[world_id];
2317
2318        // The first pass here is to build a map of "semver tracks" where they
2319        // key is per-interface and the value is the maximal version found in
2320        // that semver-compatible-track plus the interface which is the maximal
2321        // version.
2322        //
2323        // At the same time a `to_remove` set is maintained to remember what
2324        // interfaces are being removed from `from` and `into`. All of
2325        // `to_remove` are placed with a known other version.
2326        let mut semver_tracks = HashMap::new();
2327        let mut to_remove = HashSet::new();
2328        for (key, _) in world.imports.iter() {
2329            let iface_id = match key {
2330                WorldKey::Interface(id) => *id,
2331                WorldKey::Name(_) => continue,
2332            };
2333            let (track, version) = match self.semver_track(iface_id) {
2334                Some(track) => track,
2335                None => continue,
2336            };
2337            log::debug!(
2338                "{} is on track {}/{}",
2339                self.id_of(iface_id).unwrap(),
2340                track.0,
2341                track.1,
2342            );
2343            match semver_tracks.entry(track.clone()) {
2344                hash_map::Entry::Vacant(e) => {
2345                    e.insert((version, iface_id));
2346                }
2347                hash_map::Entry::Occupied(mut e) => match version.cmp(&e.get().0) {
2348                    Ordering::Greater => {
2349                        to_remove.insert(e.get().1);
2350                        e.insert((version, iface_id));
2351                    }
2352                    Ordering::Equal => {}
2353                    Ordering::Less => {
2354                        to_remove.insert(iface_id);
2355                    }
2356                },
2357            }
2358        }
2359
2360        // Build a map of "this interface is replaced with this interface" using
2361        // the results of the loop above.
2362        let mut replacements = HashMap::new();
2363        for id in to_remove {
2364            let (track, _) = self.semver_track(id).unwrap();
2365            let (_, latest) = semver_tracks[&track];
2366            let prev = replacements.insert(id, latest);
2367            assert!(prev.is_none());
2368        }
2369
2370        // Validate that `merge_world_item` succeeds for merging all removed
2371        // interfaces with their replacement. This is a double-check that the
2372        // semver version is actually correct and all items present in the old
2373        // interface are in the new.
2374        for (to_replace, replace_with) in replacements.iter() {
2375            self.merge_world_item(
2376                &WorldItem::Interface {
2377                    id: *to_replace,
2378                    stability: Default::default(),
2379                },
2380                &WorldItem::Interface {
2381                    id: *replace_with,
2382                    stability: Default::default(),
2383                },
2384            )
2385            .with_context(|| {
2386                let old_name = self.id_of(*to_replace).unwrap();
2387                let new_name = self.id_of(*replace_with).unwrap();
2388                format!(
2389                    "failed to upgrade `{old_name}` to `{new_name}`, was \
2390                     this semver-compatible update not semver compatible?"
2391                )
2392            })?;
2393        }
2394
2395        for (to_replace, replace_with) in replacements.iter() {
2396            log::debug!(
2397                "REPLACE {} => {}",
2398                self.id_of(*to_replace).unwrap(),
2399                self.id_of(*replace_with).unwrap(),
2400            );
2401        }
2402
2403        // Finally perform the actual transformation of the imports/exports.
2404        // Here all imports are removed if they're replaced and otherwise all
2405        // imports have their dependencies updated, possibly transitively, to
2406        // point to the new interfaces in `replacements`.
2407        //
2408        // Afterwards exports are additionally updated, but only their
2409        // dependencies on imports which were remapped. Exports themselves are
2410        // not deduplicated and/or removed.
2411        for (key, item) in mem::take(&mut self.worlds[world_id].imports) {
2412            if let WorldItem::Interface { id, .. } = item {
2413                if replacements.contains_key(&id) {
2414                    continue;
2415                }
2416            }
2417
2418            self.update_interface_deps_of_world_item(&item, &replacements);
2419
2420            let prev = self.worlds[world_id].imports.insert(key, item);
2421            assert!(prev.is_none());
2422        }
2423        for (key, item) in mem::take(&mut self.worlds[world_id].exports) {
2424            self.update_interface_deps_of_world_item(&item, &replacements);
2425            let prev = self.worlds[world_id].exports.insert(key, item);
2426            assert!(prev.is_none());
2427        }
2428
2429        // Run through `elaborate_world` to reorder imports as appropriate and
2430        // fill anything back in if it's actually required by exports. For now
2431        // this doesn't tamper with exports at all. Also note that this is
2432        // applied to all worlds in this `Resolve` because interfaces were
2433        // modified directly.
2434        let ids = self.worlds.iter().map(|(id, _)| id).collect::<Vec<_>>();
2435        for world_id in ids {
2436            self.elaborate_world(world_id).with_context(|| {
2437                let name = &self.worlds[world_id].name;
2438                format!(
2439                    "failed to elaborate world `{name}` after deduplicating imports \
2440                     based on semver"
2441                )
2442            })?;
2443        }
2444
2445        #[cfg(debug_assertions)]
2446        self.assert_valid();
2447
2448        Ok(())
2449    }
2450
2451    fn update_interface_deps_of_world_item(
2452        &mut self,
2453        item: &WorldItem,
2454        replacements: &HashMap<InterfaceId, InterfaceId>,
2455    ) {
2456        match *item {
2457            WorldItem::Type(t) => self.update_interface_dep_of_type(t, &replacements),
2458            WorldItem::Interface { id, .. } => {
2459                let types = self.interfaces[id]
2460                    .types
2461                    .values()
2462                    .copied()
2463                    .collect::<Vec<_>>();
2464                for ty in types {
2465                    self.update_interface_dep_of_type(ty, &replacements);
2466                }
2467            }
2468            WorldItem::Function(_) => {}
2469        }
2470    }
2471
2472    /// Returns the "semver track" of an interface plus the interface's version.
2473    ///
2474    /// This function returns `None` if the interface `id` has a package without
2475    /// a version. If the version is present, however, the first element of the
2476    /// tuple returned is a "semver track" for the specific interface. The
2477    /// version listed in `PackageName` will be modified so all
2478    /// semver-compatible versions are listed the same way.
2479    ///
2480    /// The second element in the returned tuple is this interface's package's
2481    /// version.
2482    fn semver_track(&self, id: InterfaceId) -> Option<((PackageName, String), &Version)> {
2483        let iface = &self.interfaces[id];
2484        let pkg = &self.packages[iface.package?];
2485        let version = pkg.name.version.as_ref()?;
2486        let mut name = pkg.name.clone();
2487        name.version = Some(PackageName::version_compat_track(version));
2488        Some(((name, iface.name.clone()?), version))
2489    }
2490
2491    /// If `ty` is a definition where it's a `use` from another interface, then
2492    /// change what interface it's using from according to the pairs in the
2493    /// `replacements` map.
2494    fn update_interface_dep_of_type(
2495        &mut self,
2496        ty: TypeId,
2497        replacements: &HashMap<InterfaceId, InterfaceId>,
2498    ) {
2499        let to_replace = match self.type_interface_dep(ty) {
2500            Some(id) => id,
2501            None => return,
2502        };
2503        let replace_with = match replacements.get(&to_replace) {
2504            Some(id) => id,
2505            None => return,
2506        };
2507        let dep = match self.types[ty].kind {
2508            TypeDefKind::Type(Type::Id(id)) => id,
2509            _ => return,
2510        };
2511        let name = self.types[dep].name.as_ref().unwrap();
2512        // Note the infallible name indexing happening here. This should be
2513        // previously validated with `merge_world_item` to succeed.
2514        let replacement_id = self.interfaces[*replace_with].types[name];
2515        self.types[ty].kind = TypeDefKind::Type(Type::Id(replacement_id));
2516    }
2517
2518    /// Returns the core wasm module/field names for the specified `import`.
2519    ///
2520    /// This function will return the core wasm module/field that can be used to
2521    /// use `import` with the name `mangling` scheme specified as well. This can
2522    /// be useful for bindings generators, for example, and these names are
2523    /// recognized by `wit-component` and `wasm-tools component new`.
2524    pub fn wasm_import_name(
2525        &self,
2526        mangling: ManglingAndAbi,
2527        import: WasmImport<'_>,
2528    ) -> (String, String) {
2529        match mangling {
2530            ManglingAndAbi::Standard32 => match import {
2531                WasmImport::Func { interface, func } => {
2532                    let module = match interface {
2533                        Some(key) => format!("cm32p2|{}", self.name_canonicalized_world_key(key)),
2534                        None => format!("cm32p2"),
2535                    };
2536                    (module, func.name.clone())
2537                }
2538                WasmImport::ResourceIntrinsic {
2539                    interface,
2540                    resource,
2541                    intrinsic,
2542                } => {
2543                    let name = self.types[resource].name.as_ref().unwrap();
2544                    let (prefix, name) = match intrinsic {
2545                        ResourceIntrinsic::ImportedDrop => ("", format!("{name}_drop")),
2546                        ResourceIntrinsic::ExportedDrop => ("_ex_", format!("{name}_drop")),
2547                        ResourceIntrinsic::ExportedNew => ("_ex_", format!("{name}_new")),
2548                        ResourceIntrinsic::ExportedRep => ("_ex_", format!("{name}_rep")),
2549                    };
2550                    let module = match interface {
2551                        Some(key) => {
2552                            format!("cm32p2|{prefix}{}", self.name_canonicalized_world_key(key))
2553                        }
2554                        None => {
2555                            assert_eq!(prefix, "");
2556                            format!("cm32p2")
2557                        }
2558                    };
2559                    (module, name)
2560                }
2561            },
2562            ManglingAndAbi::Legacy(abi) => match import {
2563                WasmImport::Func { interface, func } => {
2564                    let module = match interface {
2565                        Some(key) => self.name_world_key(key),
2566                        None => format!("$root"),
2567                    };
2568                    (module, format!("{}{}", abi.import_prefix(), func.name))
2569                }
2570                WasmImport::ResourceIntrinsic {
2571                    interface,
2572                    resource,
2573                    intrinsic,
2574                } => {
2575                    let name = self.types[resource].name.as_ref().unwrap();
2576                    let (prefix, name) = match intrinsic {
2577                        ResourceIntrinsic::ImportedDrop => ("", format!("[resource-drop]{name}")),
2578                        ResourceIntrinsic::ExportedDrop => {
2579                            ("[export]", format!("[resource-drop]{name}"))
2580                        }
2581                        ResourceIntrinsic::ExportedNew => {
2582                            ("[export]", format!("[resource-new]{name}"))
2583                        }
2584                        ResourceIntrinsic::ExportedRep => {
2585                            ("[export]", format!("[resource-rep]{name}"))
2586                        }
2587                    };
2588                    let module = match interface {
2589                        Some(key) => format!("{prefix}{}", self.name_world_key(key)),
2590                        None => {
2591                            assert_eq!(prefix, "");
2592                            format!("$root")
2593                        }
2594                    };
2595                    (module, format!("{}{name}", abi.import_prefix()))
2596                }
2597            },
2598        }
2599    }
2600
2601    /// Returns the core wasm export name for the specified `export`.
2602    ///
2603    /// This is the same as [`Resolve::wasm_import_name`], except for exports.
2604    pub fn wasm_export_name(&self, mangling: ManglingAndAbi, export: WasmExport<'_>) -> String {
2605        match mangling {
2606            ManglingAndAbi::Standard32 => match export {
2607                WasmExport::Func {
2608                    interface,
2609                    func,
2610                    kind,
2611                } => {
2612                    let mut name = String::from("cm32p2|");
2613                    if let Some(interface) = interface {
2614                        let s = self.name_canonicalized_world_key(interface);
2615                        name.push_str(&s);
2616                    }
2617                    name.push_str("|");
2618                    name.push_str(&func.name);
2619                    match kind {
2620                        WasmExportKind::Normal => {}
2621                        WasmExportKind::PostReturn => name.push_str("_post"),
2622                        WasmExportKind::Callback => todo!(
2623                            "not yet supported: \
2624                             async callback functions using standard name mangling"
2625                        ),
2626                    }
2627                    name
2628                }
2629                WasmExport::ResourceDtor {
2630                    interface,
2631                    resource,
2632                } => {
2633                    let name = self.types[resource].name.as_ref().unwrap();
2634                    let interface = self.name_canonicalized_world_key(interface);
2635                    format!("cm32p2|{interface}|{name}_dtor")
2636                }
2637                WasmExport::Memory => "cm32p2_memory".to_string(),
2638                WasmExport::Initialize => "cm32p2_initialize".to_string(),
2639                WasmExport::Realloc => "cm32p2_realloc".to_string(),
2640            },
2641            ManglingAndAbi::Legacy(abi) => match export {
2642                WasmExport::Func {
2643                    interface,
2644                    func,
2645                    kind,
2646                } => {
2647                    let mut name = abi.export_prefix().to_string();
2648                    match kind {
2649                        WasmExportKind::Normal => {}
2650                        WasmExportKind::PostReturn => name.push_str("cabi_post_"),
2651                        WasmExportKind::Callback => {
2652                            assert!(matches!(abi, LiftLowerAbi::AsyncCallback));
2653                            name = format!("[callback]{name}")
2654                        }
2655                    }
2656                    if let Some(interface) = interface {
2657                        let s = self.name_world_key(interface);
2658                        name.push_str(&s);
2659                        name.push_str("#");
2660                    }
2661                    name.push_str(&func.name);
2662                    name
2663                }
2664                WasmExport::ResourceDtor {
2665                    interface,
2666                    resource,
2667                } => {
2668                    let name = self.types[resource].name.as_ref().unwrap();
2669                    let interface = self.name_world_key(interface);
2670                    format!("{}{interface}#[dtor]{name}", abi.export_prefix())
2671                }
2672                WasmExport::Memory => "memory".to_string(),
2673                WasmExport::Initialize => "_initialize".to_string(),
2674                WasmExport::Realloc => "cabi_realloc".to_string(),
2675            },
2676        }
2677    }
2678}
2679
2680/// Possible imports that can be passed to [`Resolve::wasm_import_name`].
2681#[derive(Debug)]
2682pub enum WasmImport<'a> {
2683    /// A WIT function is being imported. Optionally from an interface.
2684    Func {
2685        /// The name of the interface that the function is being imported from.
2686        ///
2687        /// If the function is imported directly from the world then this is
2688        /// `Noen`.
2689        interface: Option<&'a WorldKey>,
2690
2691        /// The function being imported.
2692        func: &'a Function,
2693    },
2694
2695    /// A resource-related intrinsic is being imported.
2696    ResourceIntrinsic {
2697        /// The optional interface to import from, same as `WasmImport::Func`.
2698        interface: Option<&'a WorldKey>,
2699
2700        /// The resource that's being operated on.
2701        resource: TypeId,
2702
2703        /// The intrinsic that's being imported.
2704        intrinsic: ResourceIntrinsic,
2705    },
2706}
2707
2708/// Intrinsic definitions to go with [`WasmImport::ResourceIntrinsic`] which
2709/// also goes with [`Resolve::wasm_import_name`].
2710#[derive(Debug)]
2711pub enum ResourceIntrinsic {
2712    ImportedDrop,
2713    ExportedDrop,
2714    ExportedNew,
2715    ExportedRep,
2716}
2717
2718/// Indicates whether a function export is a normal export, a post-return
2719/// function, or a callback function.
2720#[derive(Debug)]
2721pub enum WasmExportKind {
2722    /// Normal function export.
2723    Normal,
2724
2725    /// Post-return function.
2726    PostReturn,
2727
2728    /// Async callback function.
2729    Callback,
2730}
2731
2732/// Different kinds of exports that can be passed to
2733/// [`Resolve::wasm_export_name`] to export from core wasm modules.
2734#[derive(Debug)]
2735pub enum WasmExport<'a> {
2736    /// A WIT function is being exported, optionally from an interface.
2737    Func {
2738        /// An optional interface which owns `func`. Use `None` for top-level
2739        /// world function.
2740        interface: Option<&'a WorldKey>,
2741
2742        /// The function being exported.
2743        func: &'a Function,
2744
2745        /// Kind of function (normal, post-return, or callback) being exported.
2746        kind: WasmExportKind,
2747    },
2748
2749    /// A destructor for a resource exported from this module.
2750    ResourceDtor {
2751        /// The interface that owns the resource.
2752        interface: &'a WorldKey,
2753        /// The resource itself that the destructor is for.
2754        resource: TypeId,
2755    },
2756
2757    /// Linear memory, the one that the canonical ABI uses.
2758    Memory,
2759
2760    /// An initialization function (not the core wasm `start`).
2761    Initialize,
2762
2763    /// The general-purpose realloc hook.
2764    Realloc,
2765}
2766
2767/// Structure returned by [`Resolve::merge`] which contains mappings from
2768/// old-ids to new-ids after the merge.
2769#[derive(Default)]
2770pub struct Remap {
2771    pub types: Vec<Option<TypeId>>,
2772    pub interfaces: Vec<Option<InterfaceId>>,
2773    pub worlds: Vec<Option<WorldId>>,
2774    pub packages: Vec<PackageId>,
2775
2776    /// A cache of anonymous `own<T>` handles for resource types.
2777    ///
2778    /// The appending operation of `Remap` is the one responsible for
2779    /// translating references to `T` where `T` is a resource into `own<T>`
2780    /// instead. This map is used to deduplicate the `own<T>` types generated
2781    /// to generate as few as possible.
2782    ///
2783    /// The key of this map is the resource id `T` in the new resolve, and
2784    /// the value is the `own<T>` type pointing to `T`.
2785    own_handles: HashMap<TypeId, TypeId>,
2786
2787    type_has_borrow: Vec<Option<bool>>,
2788}
2789
2790fn apply_map<T>(map: &[Option<Id<T>>], id: Id<T>, desc: &str, span: Option<Span>) -> Result<Id<T>> {
2791    match map.get(id.index()) {
2792        Some(Some(id)) => Ok(*id),
2793        Some(None) => {
2794            let msg = format!(
2795                "found a reference to a {desc} which is excluded \
2796                 due to its feature not being activated"
2797            );
2798            match span {
2799                Some(span) => Err(Error::new(span, msg).into()),
2800                None => bail!("{msg}"),
2801            }
2802        }
2803        None => panic!("request to remap a {desc} that has not yet been registered"),
2804    }
2805}
2806
2807fn rename(original_name: &str, include_name: &IncludeName) -> Option<String> {
2808    if original_name == include_name.name {
2809        return Some(include_name.as_.to_string());
2810    }
2811    let (kind, rest) = original_name.split_once(']')?;
2812    match rest.split_once('.') {
2813        Some((name, rest)) if name == include_name.name => {
2814            Some(format!("{kind}]{}.{rest}", include_name.as_))
2815        }
2816        _ if rest == include_name.name => Some(format!("{kind}]{}", include_name.as_)),
2817        _ => None,
2818    }
2819}
2820
2821impl Remap {
2822    pub fn map_type(&self, id: TypeId, span: Option<Span>) -> Result<TypeId> {
2823        apply_map(&self.types, id, "type", span)
2824    }
2825
2826    pub fn map_interface(&self, id: InterfaceId, span: Option<Span>) -> Result<InterfaceId> {
2827        apply_map(&self.interfaces, id, "interface", span)
2828    }
2829
2830    pub fn map_world(&self, id: WorldId, span: Option<Span>) -> Result<WorldId> {
2831        apply_map(&self.worlds, id, "world", span)
2832    }
2833
2834    fn append(
2835        &mut self,
2836        resolve: &mut Resolve,
2837        unresolved: UnresolvedPackage,
2838    ) -> Result<PackageId> {
2839        let pkgid = resolve.packages.alloc(Package {
2840            name: unresolved.name.clone(),
2841            docs: unresolved.docs.clone(),
2842            interfaces: Default::default(),
2843            worlds: Default::default(),
2844        });
2845        let prev = resolve.package_names.insert(unresolved.name.clone(), pkgid);
2846        if let Some(prev) = prev {
2847            resolve.package_names.insert(unresolved.name.clone(), prev);
2848            bail!(
2849                "attempting to re-add package `{}` when it's already present in this `Resolve`",
2850                unresolved.name,
2851            );
2852        }
2853
2854        self.process_foreign_deps(resolve, pkgid, &unresolved)?;
2855
2856        let foreign_types = self.types.len();
2857        let foreign_interfaces = self.interfaces.len();
2858        let foreign_worlds = self.worlds.len();
2859
2860        // Copy over all types first, updating any intra-type references. Note
2861        // that types are sorted topologically which means this iteration
2862        // order should be sufficient. Also note though that the interface
2863        // owner of a type isn't updated here due to interfaces not being known
2864        // yet.
2865        assert_eq!(unresolved.types.len(), unresolved.type_spans.len());
2866        for ((id, mut ty), span) in unresolved
2867            .types
2868            .into_iter()
2869            .zip(&unresolved.type_spans)
2870            .skip(foreign_types)
2871        {
2872            if !resolve.include_type(&ty, pkgid, *span)? {
2873                self.types.push(None);
2874                continue;
2875            }
2876
2877            self.update_typedef(resolve, &mut ty, Some(*span))?;
2878            let new_id = resolve.types.alloc(ty);
2879            assert_eq!(self.types.len(), id.index());
2880
2881            let new_id = match resolve.types[new_id] {
2882                // If this is an `own<T>` handle then either replace it with a
2883                // preexisting `own<T>` handle which may have been generated in
2884                // `update_ty`. If that doesn't exist though then insert it into
2885                // the `own_handles` cache.
2886                TypeDef {
2887                    name: None,
2888                    owner: TypeOwner::None,
2889                    kind: TypeDefKind::Handle(Handle::Own(id)),
2890                    docs: _,
2891                    stability: _,
2892                } => *self.own_handles.entry(id).or_insert(new_id),
2893
2894                // Everything not-related to `own<T>` doesn't get its ID
2895                // modified.
2896                _ => new_id,
2897            };
2898            self.types.push(Some(new_id));
2899        }
2900
2901        // Next transfer all interfaces into `Resolve`, updating type ids
2902        // referenced along the way.
2903        assert_eq!(
2904            unresolved.interfaces.len(),
2905            unresolved.interface_spans.len()
2906        );
2907        for ((id, mut iface), span) in unresolved
2908            .interfaces
2909            .into_iter()
2910            .zip(&unresolved.interface_spans)
2911            .skip(foreign_interfaces)
2912        {
2913            if !resolve
2914                .include_stability(&iface.stability, &pkgid, Some(span.span))
2915                .with_context(|| {
2916                    format!(
2917                        "failed to process feature gate for interface [{}] in package [{}]",
2918                        iface
2919                            .name
2920                            .as_ref()
2921                            .map(String::as_str)
2922                            .unwrap_or("<unknown>"),
2923                        resolve.packages[pkgid].name,
2924                    )
2925                })?
2926            {
2927                self.interfaces.push(None);
2928                continue;
2929            }
2930            assert!(iface.package.is_none());
2931            iface.package = Some(pkgid);
2932            self.update_interface(resolve, &mut iface, Some(span))?;
2933            let new_id = resolve.interfaces.alloc(iface);
2934            assert_eq!(self.interfaces.len(), id.index());
2935            self.interfaces.push(Some(new_id));
2936        }
2937
2938        // Now that interfaces are identified go back through the types and
2939        // update their interface owners.
2940        for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2941            let id = match id {
2942                Some(id) => *id,
2943                None => continue,
2944            };
2945            match &mut resolve.types[id].owner {
2946                TypeOwner::Interface(id) => {
2947                    let span = unresolved.type_spans[i];
2948                    *id = self.map_interface(*id, Some(span))
2949                        .with_context(|| {
2950                            "this type is not gated by a feature but its interface is gated by a feature"
2951                        })?;
2952                }
2953                TypeOwner::World(_) | TypeOwner::None => {}
2954            }
2955        }
2956
2957        // Expand worlds. Note that this does NOT process `include` statements,
2958        // that's handled below. Instead this just handles world item updates
2959        // and resolves references to types/items within `Resolve`.
2960        //
2961        // This is done after types/interfaces are fully settled so the
2962        // transitive relation between interfaces, through types, is understood
2963        // here.
2964        assert_eq!(unresolved.worlds.len(), unresolved.world_spans.len());
2965        for ((id, mut world), span) in unresolved
2966            .worlds
2967            .into_iter()
2968            .zip(&unresolved.world_spans)
2969            .skip(foreign_worlds)
2970        {
2971            if !resolve
2972                .include_stability(&world.stability, &pkgid, Some(span.span))
2973                .with_context(|| {
2974                    format!(
2975                        "failed to process feature gate for world [{}] in package [{}]",
2976                        world.name, resolve.packages[pkgid].name,
2977                    )
2978                })?
2979            {
2980                self.worlds.push(None);
2981                continue;
2982            }
2983            self.update_world(&mut world, resolve, &pkgid, &span)?;
2984
2985            let new_id = resolve.worlds.alloc(world);
2986            assert_eq!(self.worlds.len(), id.index());
2987            self.worlds.push(Some(new_id));
2988        }
2989
2990        // As with interfaces, now update the ids of world-owned types.
2991        for (i, id) in self.types.iter().enumerate().skip(foreign_types) {
2992            let id = match id {
2993                Some(id) => *id,
2994                None => continue,
2995            };
2996            match &mut resolve.types[id].owner {
2997                TypeOwner::World(id) => {
2998                    let span = unresolved.type_spans[i];
2999                    *id = self.map_world(*id, Some(span))
3000                        .with_context(|| {
3001                            "this type is not gated by a feature but its interface is gated by a feature"
3002                        })?;
3003                }
3004                TypeOwner::Interface(_) | TypeOwner::None => {}
3005            }
3006        }
3007
3008        // After the above, process `include` statements for worlds and
3009        // additionally fully elaborate them. Processing of `include` is
3010        // deferred until after the steps above so the fully resolved state of
3011        // local types in this package are all available. This is required
3012        // because `include` may copy types between worlds when the type is
3013        // defined in the world itself.
3014        //
3015        // This step, after processing `include`, will also use
3016        // `elaborate_world` to fully expand the world in terms of
3017        // imports/exports and ensure that all necessary imports/exports are all
3018        // listed.
3019        //
3020        // Note that `self.worlds` is already sorted in topological order so if
3021        // one world refers to another via `include` then it's guaranteed that
3022        // the one we're referring to is already expanded and ready to be
3023        // included.
3024        assert_eq!(self.worlds.len(), unresolved.world_spans.len());
3025        for (id, span) in self
3026            .worlds
3027            .iter()
3028            .zip(unresolved.world_spans.iter())
3029            .skip(foreign_worlds)
3030        {
3031            let Some(id) = *id else {
3032                continue;
3033            };
3034            self.process_world_includes(id, resolve, &pkgid, &span)?;
3035
3036            resolve.elaborate_world(id).with_context(|| {
3037                Error::new(
3038                    span.span,
3039                    format!(
3040                        "failed to elaborate world imports/exports of `{}`",
3041                        resolve.worlds[id].name
3042                    ),
3043                )
3044            })?;
3045        }
3046
3047        // Fixup "parent" ids now that everything has been identified
3048        for id in self.interfaces.iter().skip(foreign_interfaces) {
3049            let id = match id {
3050                Some(id) => *id,
3051                None => continue,
3052            };
3053            let iface = &mut resolve.interfaces[id];
3054            iface.package = Some(pkgid);
3055            if let Some(name) = &iface.name {
3056                let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), id);
3057                assert!(prev.is_none());
3058            }
3059        }
3060        for id in self.worlds.iter().skip(foreign_worlds) {
3061            let id = match id {
3062                Some(id) => *id,
3063                None => continue,
3064            };
3065            let world = &mut resolve.worlds[id];
3066            world.package = Some(pkgid);
3067            let prev = resolve.packages[pkgid]
3068                .worlds
3069                .insert(world.name.clone(), id);
3070            assert!(prev.is_none());
3071        }
3072        Ok(pkgid)
3073    }
3074
3075    fn process_foreign_deps(
3076        &mut self,
3077        resolve: &mut Resolve,
3078        pkgid: PackageId,
3079        unresolved: &UnresolvedPackage,
3080    ) -> Result<()> {
3081        // Invert the `foreign_deps` map to be keyed by world id to get
3082        // used in the loops below.
3083        let mut world_to_package = HashMap::new();
3084        let mut interface_to_package = HashMap::new();
3085        for (i, (pkg_name, worlds_or_ifaces)) in unresolved.foreign_deps.iter().enumerate() {
3086            for (name, item) in worlds_or_ifaces {
3087                match item {
3088                    AstItem::Interface(unresolved_interface_id) => {
3089                        let prev = interface_to_package.insert(
3090                            *unresolved_interface_id,
3091                            (pkg_name, name, unresolved.foreign_dep_spans[i]),
3092                        );
3093                        assert!(prev.is_none());
3094                    }
3095                    AstItem::World(unresolved_world_id) => {
3096                        let prev = world_to_package.insert(
3097                            *unresolved_world_id,
3098                            (pkg_name, name, unresolved.foreign_dep_spans[i]),
3099                        );
3100                        assert!(prev.is_none());
3101                    }
3102                }
3103            }
3104        }
3105
3106        // Connect all interfaces referred to in `interface_to_package`, which
3107        // are at the front of `unresolved.interfaces`, to interfaces already
3108        // contained within `resolve`.
3109        self.process_foreign_interfaces(unresolved, &interface_to_package, resolve)?;
3110
3111        // Connect all worlds referred to in `world_to_package`, which
3112        // are at the front of `unresolved.worlds`, to worlds already
3113        // contained within `resolve`.
3114        self.process_foreign_worlds(unresolved, &world_to_package, resolve)?;
3115
3116        // Finally, iterate over all foreign-defined types and determine
3117        // what they map to.
3118        self.process_foreign_types(unresolved, pkgid, resolve)?;
3119
3120        for (id, span) in unresolved.required_resource_types.iter() {
3121            // Note that errors are ignored here because an error represents a
3122            // type that has been configured away. If a type is configured away
3123            // then any future use of it will generate an error so there's no
3124            // need to validate that it's a resource here.
3125            let Ok(mut id) = self.map_type(*id, Some(*span)) else {
3126                continue;
3127            };
3128            loop {
3129                match resolve.types[id].kind {
3130                    TypeDefKind::Type(Type::Id(i)) => id = i,
3131                    TypeDefKind::Resource => break,
3132                    _ => bail!(Error::new(
3133                        *span,
3134                        format!("type used in a handle must be a resource"),
3135                    )),
3136                }
3137            }
3138        }
3139
3140        #[cfg(debug_assertions)]
3141        resolve.assert_valid();
3142
3143        Ok(())
3144    }
3145
3146    fn process_foreign_interfaces(
3147        &mut self,
3148        unresolved: &UnresolvedPackage,
3149        interface_to_package: &HashMap<InterfaceId, (&PackageName, &String, Span)>,
3150        resolve: &mut Resolve,
3151    ) -> Result<(), anyhow::Error> {
3152        for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() {
3153            let (pkg_name, interface, span) = match interface_to_package.get(&unresolved_iface_id) {
3154                Some(items) => *items,
3155                // All foreign interfaces are defined first, so the first one
3156                // which is defined in a non-foreign document means that all
3157                // further interfaces will be non-foreign as well.
3158                None => break,
3159            };
3160            let pkgid = resolve
3161                .package_names
3162                .get(pkg_name)
3163                .copied()
3164                .ok_or_else(|| {
3165                    PackageNotFoundError::new(
3166                        span,
3167                        pkg_name.clone(),
3168                        resolve.package_names.keys().cloned().collect(),
3169                    )
3170                })?;
3171
3172            // Functions can't be imported so this should be empty.
3173            assert!(unresolved_iface.functions.is_empty());
3174
3175            let pkg = &resolve.packages[pkgid];
3176            let span = &unresolved.interface_spans[unresolved_iface_id.index()];
3177            let iface_id = pkg
3178                .interfaces
3179                .get(interface)
3180                .copied()
3181                .ok_or_else(|| Error::new(span.span, "interface not found in package"))?;
3182            assert_eq!(self.interfaces.len(), unresolved_iface_id.index());
3183            self.interfaces.push(Some(iface_id));
3184        }
3185        for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) {
3186            assert!(
3187                interface_to_package.get(&id).is_none(),
3188                "found foreign interface after local interface"
3189            );
3190        }
3191        Ok(())
3192    }
3193
3194    fn process_foreign_worlds(
3195        &mut self,
3196        unresolved: &UnresolvedPackage,
3197        world_to_package: &HashMap<WorldId, (&PackageName, &String, Span)>,
3198        resolve: &mut Resolve,
3199    ) -> Result<(), anyhow::Error> {
3200        for (unresolved_world_id, _) in unresolved.worlds.iter() {
3201            let (pkg_name, world, span) = match world_to_package.get(&unresolved_world_id) {
3202                Some(items) => *items,
3203                // Same as above, all worlds are foreign until we find a
3204                // non-foreign one.
3205                None => break,
3206            };
3207
3208            let pkgid = resolve
3209                .package_names
3210                .get(pkg_name)
3211                .copied()
3212                .ok_or_else(|| Error::new(span, "package not found"))?;
3213            let pkg = &resolve.packages[pkgid];
3214            let span = &unresolved.world_spans[unresolved_world_id.index()];
3215            let world_id = pkg
3216                .worlds
3217                .get(world)
3218                .copied()
3219                .ok_or_else(|| Error::new(span.span, "world not found in package"))?;
3220            assert_eq!(self.worlds.len(), unresolved_world_id.index());
3221            self.worlds.push(Some(world_id));
3222        }
3223        for (id, _) in unresolved.worlds.iter().skip(self.worlds.len()) {
3224            assert!(
3225                world_to_package.get(&id).is_none(),
3226                "found foreign world after local world"
3227            );
3228        }
3229        Ok(())
3230    }
3231
3232    fn process_foreign_types(
3233        &mut self,
3234        unresolved: &UnresolvedPackage,
3235        pkgid: PackageId,
3236        resolve: &mut Resolve,
3237    ) -> Result<(), anyhow::Error> {
3238        for ((unresolved_type_id, unresolved_ty), span) in
3239            unresolved.types.iter().zip(&unresolved.type_spans)
3240        {
3241            // All "Unknown" types should appear first so once we're no longer
3242            // in unknown territory it's package-defined types so break out of
3243            // this loop.
3244            match unresolved_ty.kind {
3245                TypeDefKind::Unknown => {}
3246                _ => break,
3247            }
3248
3249            if !resolve.include_type(unresolved_ty, pkgid, *span)? {
3250                self.types.push(None);
3251                continue;
3252            }
3253
3254            let unresolved_iface_id = match unresolved_ty.owner {
3255                TypeOwner::Interface(id) => id,
3256                _ => unreachable!(),
3257            };
3258            let iface_id = self.map_interface(unresolved_iface_id, None)?;
3259            let name = unresolved_ty.name.as_ref().unwrap();
3260            let span = unresolved.unknown_type_spans[unresolved_type_id.index()];
3261            let type_id = *resolve.interfaces[iface_id]
3262                .types
3263                .get(name)
3264                .ok_or_else(|| {
3265                    Error::new(span, format!("type `{name}` not defined in interface"))
3266                })?;
3267            assert_eq!(self.types.len(), unresolved_type_id.index());
3268            self.types.push(Some(type_id));
3269        }
3270        for (_, ty) in unresolved.types.iter().skip(self.types.len()) {
3271            if let TypeDefKind::Unknown = ty.kind {
3272                panic!("unknown type after defined type");
3273            }
3274        }
3275        Ok(())
3276    }
3277
3278    fn update_typedef(
3279        &mut self,
3280        resolve: &mut Resolve,
3281        ty: &mut TypeDef,
3282        span: Option<Span>,
3283    ) -> Result<()> {
3284        // NB: note that `ty.owner` is not updated here since interfaces
3285        // haven't been mapped yet and that's done in a separate step.
3286        use crate::TypeDefKind::*;
3287        match &mut ty.kind {
3288            Handle(handle) => match handle {
3289                crate::Handle::Own(ty) | crate::Handle::Borrow(ty) => {
3290                    self.update_type_id(ty, span)?
3291                }
3292            },
3293            Resource => {}
3294            Record(r) => {
3295                for field in r.fields.iter_mut() {
3296                    self.update_ty(resolve, &mut field.ty, span)
3297                        .with_context(|| format!("failed to update field `{}`", field.name))?;
3298                }
3299            }
3300            Tuple(t) => {
3301                for ty in t.types.iter_mut() {
3302                    self.update_ty(resolve, ty, span)?;
3303                }
3304            }
3305            Variant(v) => {
3306                for case in v.cases.iter_mut() {
3307                    if let Some(t) = &mut case.ty {
3308                        self.update_ty(resolve, t, span)?;
3309                    }
3310                }
3311            }
3312            Option(t) | List(t, ..) | FixedSizeList(t, ..) | Future(Some(t)) | Stream(Some(t)) => {
3313                self.update_ty(resolve, t, span)?
3314            }
3315            Result(r) => {
3316                if let Some(ty) = &mut r.ok {
3317                    self.update_ty(resolve, ty, span)?;
3318                }
3319                if let Some(ty) = &mut r.err {
3320                    self.update_ty(resolve, ty, span)?;
3321                }
3322            }
3323
3324            // Note that `update_ty` is specifically not used here as typedefs
3325            // because for the `type a = b` form that doesn't force `a` to be a
3326            // handle type if `b` is a resource type, instead `a` is
3327            // simultaneously usable as a resource and a handle type
3328            Type(crate::Type::Id(id)) => self.update_type_id(id, span)?,
3329            Type(_) => {}
3330
3331            // nothing to do for these as they're just names or empty
3332            Flags(_) | Enum(_) | Future(None) | Stream(None) => {}
3333
3334            Unknown => unreachable!(),
3335        }
3336
3337        Ok(())
3338    }
3339
3340    fn update_ty(
3341        &mut self,
3342        resolve: &mut Resolve,
3343        ty: &mut Type,
3344        span: Option<Span>,
3345    ) -> Result<()> {
3346        let id = match ty {
3347            Type::Id(id) => id,
3348            _ => return Ok(()),
3349        };
3350        self.update_type_id(id, span)?;
3351
3352        // If `id` points to a `Resource` type then this means that what was
3353        // just discovered was a reference to what will implicitly become an
3354        // `own<T>` handle. This `own` handle is implicitly allocated here
3355        // and handled during the merging process.
3356        let mut cur = *id;
3357        let points_to_resource = loop {
3358            match resolve.types[cur].kind {
3359                TypeDefKind::Type(Type::Id(id)) => cur = id,
3360                TypeDefKind::Resource => break true,
3361                _ => break false,
3362            }
3363        };
3364
3365        if points_to_resource {
3366            *id = *self.own_handles.entry(*id).or_insert_with(|| {
3367                resolve.types.alloc(TypeDef {
3368                    name: None,
3369                    owner: TypeOwner::None,
3370                    kind: TypeDefKind::Handle(Handle::Own(*id)),
3371                    docs: Default::default(),
3372                    stability: Default::default(),
3373                })
3374            });
3375        }
3376        Ok(())
3377    }
3378
3379    fn update_type_id(&self, id: &mut TypeId, span: Option<Span>) -> Result<()> {
3380        *id = self.map_type(*id, span)?;
3381        Ok(())
3382    }
3383
3384    fn update_interface(
3385        &mut self,
3386        resolve: &mut Resolve,
3387        iface: &mut Interface,
3388        spans: Option<&InterfaceSpan>,
3389    ) -> Result<()> {
3390        iface.types.retain(|_, ty| self.types[ty.index()].is_some());
3391        let iface_pkg_id = iface.package.as_ref().unwrap_or_else(|| {
3392            panic!(
3393                "unexpectedly missing package on interface [{}]",
3394                iface
3395                    .name
3396                    .as_ref()
3397                    .map(String::as_str)
3398                    .unwrap_or("<unknown>"),
3399            )
3400        });
3401
3402        // NB: note that `iface.doc` is not updated here since interfaces
3403        // haven't been mapped yet and that's done in a separate step.
3404        for (_name, ty) in iface.types.iter_mut() {
3405            self.update_type_id(ty, spans.map(|s| s.span))?;
3406        }
3407        if let Some(spans) = spans {
3408            assert_eq!(iface.functions.len(), spans.funcs.len());
3409        }
3410        for (i, (func_name, func)) in iface.functions.iter_mut().enumerate() {
3411            let span = spans.map(|s| s.funcs[i]);
3412            if !resolve
3413                .include_stability(&func.stability, iface_pkg_id, span)
3414                .with_context(|| {
3415                    format!(
3416                        "failed to process feature gate for function [{func_name}] in package [{}]",
3417                        resolve.packages[*iface_pkg_id].name,
3418                    )
3419                })?
3420            {
3421                continue;
3422            }
3423            self.update_function(resolve, func, span)
3424                .with_context(|| format!("failed to update function `{}`", func.name))?;
3425        }
3426
3427        // Filter out all of the existing functions in interface which fail the
3428        // `include_stability()` check, as they shouldn't be available.
3429        for (name, func) in mem::take(&mut iface.functions) {
3430            if resolve.include_stability(&func.stability, iface_pkg_id, None)? {
3431                iface.functions.insert(name, func);
3432            }
3433        }
3434
3435        Ok(())
3436    }
3437
3438    fn update_function(
3439        &mut self,
3440        resolve: &mut Resolve,
3441        func: &mut Function,
3442        span: Option<Span>,
3443    ) -> Result<()> {
3444        if let Some(id) = func.kind.resource_mut() {
3445            self.update_type_id(id, span)?;
3446        }
3447        for (_, ty) in func.params.iter_mut() {
3448            self.update_ty(resolve, ty, span)?;
3449        }
3450        if let Some(ty) = &mut func.result {
3451            self.update_ty(resolve, ty, span)?;
3452        }
3453
3454        if let Some(ty) = &func.result {
3455            if self.type_has_borrow(resolve, ty) {
3456                match span {
3457                    Some(span) => {
3458                        bail!(Error::new(
3459                            span,
3460                            format!(
3461                                "function returns a type which contains \
3462                                 a `borrow<T>` which is not supported"
3463                            )
3464                        ))
3465                    }
3466                    None => unreachable!(),
3467                }
3468            }
3469        }
3470
3471        Ok(())
3472    }
3473
3474    fn update_world(
3475        &mut self,
3476        world: &mut World,
3477        resolve: &mut Resolve,
3478        pkg_id: &PackageId,
3479        spans: &WorldSpan,
3480    ) -> Result<()> {
3481        assert_eq!(world.imports.len(), spans.imports.len());
3482        assert_eq!(world.exports.len(), spans.exports.len());
3483
3484        // Rewrite imports/exports with their updated versions. Note that this
3485        // may involve updating the key of the imports/exports maps so this
3486        // starts by emptying them out and then everything is re-inserted.
3487        let imports = mem::take(&mut world.imports).into_iter();
3488        let imports = imports.zip(&spans.imports).map(|p| (p, true));
3489        let exports = mem::take(&mut world.exports).into_iter();
3490        let exports = exports.zip(&spans.exports).map(|p| (p, false));
3491        for (((mut name, mut item), span), import) in imports.chain(exports) {
3492            // Update the `id` eagerly here so `item.stability(..)` below
3493            // works.
3494            if let WorldItem::Type(id) = &mut item {
3495                *id = self.map_type(*id, Some(*span))?;
3496            }
3497            let stability = item.stability(resolve);
3498            if !resolve
3499                .include_stability(stability, pkg_id, Some(*span))
3500                .with_context(|| format!("failed to process world item in `{}`", world.name))?
3501            {
3502                continue;
3503            }
3504            self.update_world_key(&mut name, Some(*span))?;
3505            match &mut item {
3506                WorldItem::Interface { id, .. } => {
3507                    *id = self.map_interface(*id, Some(*span))?;
3508                }
3509                WorldItem::Function(f) => {
3510                    self.update_function(resolve, f, Some(*span))?;
3511                }
3512                WorldItem::Type(_) => {
3513                    // already mapped above
3514                }
3515            }
3516
3517            let dst = if import {
3518                &mut world.imports
3519            } else {
3520                &mut world.exports
3521            };
3522            let prev = dst.insert(name, item);
3523            assert!(prev.is_none());
3524        }
3525
3526        Ok(())
3527    }
3528
3529    fn process_world_includes(
3530        &self,
3531        id: WorldId,
3532        resolve: &mut Resolve,
3533        pkg_id: &PackageId,
3534        spans: &WorldSpan,
3535    ) -> Result<()> {
3536        let world = &mut resolve.worlds[id];
3537        // Resolve all `include` statements of the world which will add more
3538        // entries to the imports/exports list for this world.
3539        assert_eq!(world.includes.len(), spans.includes.len());
3540        let includes = mem::take(&mut world.includes);
3541        let include_names = mem::take(&mut world.include_names);
3542        for (((stability, include_world), span), names) in includes
3543            .into_iter()
3544            .zip(&spans.includes)
3545            .zip(&include_names)
3546        {
3547            if !resolve
3548                .include_stability(&stability, pkg_id, Some(*span))
3549                .with_context(|| {
3550                    format!(
3551                        "failed to process feature gate for included world [{}] in package [{}]",
3552                        resolve.worlds[include_world].name.as_str(),
3553                        resolve.packages[*pkg_id].name
3554                    )
3555                })?
3556            {
3557                continue;
3558            }
3559            self.resolve_include(id, include_world, names, *span, pkg_id, resolve)?;
3560        }
3561
3562        Ok(())
3563    }
3564
3565    fn update_world_key(&self, key: &mut WorldKey, span: Option<Span>) -> Result<()> {
3566        match key {
3567            WorldKey::Name(_) => {}
3568            WorldKey::Interface(id) => {
3569                *id = self.map_interface(*id, span)?;
3570            }
3571        }
3572        Ok(())
3573    }
3574
3575    fn resolve_include(
3576        &self,
3577        id: WorldId,
3578        include_world_id_orig: WorldId,
3579        names: &[IncludeName],
3580        span: Span,
3581        pkg_id: &PackageId,
3582        resolve: &mut Resolve,
3583    ) -> Result<()> {
3584        let world = &resolve.worlds[id];
3585        let include_world_id = self.map_world(include_world_id_orig, Some(span))?;
3586        let include_world = resolve.worlds[include_world_id].clone();
3587        let mut names_ = names.to_owned();
3588        let is_external_include = world.package != include_world.package;
3589
3590        // remove all imports and exports that match the names we're including
3591        for import in include_world.imports.iter() {
3592            self.remove_matching_name(import, &mut names_);
3593        }
3594        for export in include_world.exports.iter() {
3595            self.remove_matching_name(export, &mut names_);
3596        }
3597        if !names_.is_empty() {
3598            bail!(Error::new(
3599                span,
3600                format!(
3601                    "no import or export kebab-name `{}`. Note that an ID does not support renaming",
3602                    names_[0].name
3603                ),
3604            ));
3605        }
3606
3607        let mut cloner = clone::Cloner::new(
3608            resolve,
3609            TypeOwner::World(if is_external_include {
3610                include_world_id
3611            } else {
3612                include_world_id
3613                // include_world_id_orig
3614            }),
3615            TypeOwner::World(id),
3616        );
3617        cloner.new_package = Some(*pkg_id);
3618
3619        // copy the imports and exports from the included world into the current world
3620        for import in include_world.imports.iter() {
3621            self.resolve_include_item(
3622                &mut cloner,
3623                names,
3624                |resolve| &mut resolve.worlds[id].imports,
3625                import,
3626                span,
3627                "import",
3628                is_external_include,
3629            )?;
3630        }
3631
3632        for export in include_world.exports.iter() {
3633            self.resolve_include_item(
3634                &mut cloner,
3635                names,
3636                |resolve| &mut resolve.worlds[id].exports,
3637                export,
3638                span,
3639                "export",
3640                is_external_include,
3641            )?;
3642        }
3643        Ok(())
3644    }
3645
3646    fn resolve_include_item(
3647        &self,
3648        cloner: &mut clone::Cloner<'_>,
3649        names: &[IncludeName],
3650        get_items: impl Fn(&mut Resolve) -> &mut IndexMap<WorldKey, WorldItem>,
3651        item: (&WorldKey, &WorldItem),
3652        span: Span,
3653        item_type: &str,
3654        is_external_include: bool,
3655    ) -> Result<()> {
3656        match item.0 {
3657            WorldKey::Name(n) => {
3658                let n = names
3659                    .into_iter()
3660                    .find_map(|include_name| rename(n, include_name))
3661                    .unwrap_or(n.clone());
3662
3663                // When the `with` option to the `include` directive is
3664                // specified and is used to rename a function that means that
3665                // the function's own original name needs to be updated, so
3666                // reflect the change not only in the world key but additionally
3667                // in the function itself.
3668                let mut new_item = item.1.clone();
3669                let key = WorldKey::Name(n.clone());
3670                cloner.world_item(&key, &mut new_item, &mut CloneMaps::default());
3671                match &mut new_item {
3672                    WorldItem::Function(f) => f.name = n.clone(),
3673                    WorldItem::Type(id) => cloner.resolve.types[*id].name = Some(n.clone()),
3674                    WorldItem::Interface { .. } => {}
3675                }
3676
3677                let prev = get_items(cloner.resolve).insert(key, new_item);
3678                if prev.is_some() {
3679                    bail!(Error::new(
3680                        span,
3681                        format!("{item_type} of `{n}` shadows previously {item_type}ed items"),
3682                    ))
3683                }
3684            }
3685            key @ WorldKey::Interface(_) => {
3686                let prev = get_items(cloner.resolve)
3687                    .entry(key.clone())
3688                    .or_insert(item.1.clone());
3689                match (&item.1, prev) {
3690                    (
3691                        WorldItem::Interface {
3692                            id: aid,
3693                            stability: astability,
3694                        },
3695                        WorldItem::Interface {
3696                            id: bid,
3697                            stability: bstability,
3698                        },
3699                    ) => {
3700                        assert_eq!(*aid, *bid);
3701                        merge_include_stability(astability, bstability, is_external_include)?;
3702                    }
3703                    (WorldItem::Interface { .. }, _) => unreachable!(),
3704                    (WorldItem::Function(_), _) => unreachable!(),
3705                    (WorldItem::Type(_), _) => unreachable!(),
3706                }
3707            }
3708        };
3709
3710        Ok(())
3711    }
3712
3713    fn remove_matching_name(&self, item: (&WorldKey, &WorldItem), names: &mut Vec<IncludeName>) {
3714        match item.0 {
3715            WorldKey::Name(n) => {
3716                names.retain(|name| rename(n, name).is_none());
3717            }
3718            _ => {}
3719        }
3720    }
3721
3722    fn type_has_borrow(&mut self, resolve: &Resolve, ty: &Type) -> bool {
3723        let id = match ty {
3724            Type::Id(id) => *id,
3725            _ => return false,
3726        };
3727
3728        if let Some(Some(has_borrow)) = self.type_has_borrow.get(id.index()) {
3729            return *has_borrow;
3730        }
3731
3732        let result = self.typedef_has_borrow(resolve, &resolve.types[id]);
3733        if self.type_has_borrow.len() <= id.index() {
3734            self.type_has_borrow.resize(id.index() + 1, None);
3735        }
3736        self.type_has_borrow[id.index()] = Some(result);
3737        result
3738    }
3739
3740    fn typedef_has_borrow(&mut self, resolve: &Resolve, ty: &TypeDef) -> bool {
3741        match &ty.kind {
3742            TypeDefKind::Type(t) => self.type_has_borrow(resolve, t),
3743            TypeDefKind::Variant(v) => v
3744                .cases
3745                .iter()
3746                .filter_map(|case| case.ty.as_ref())
3747                .any(|ty| self.type_has_borrow(resolve, ty)),
3748            TypeDefKind::Handle(Handle::Borrow(_)) => true,
3749            TypeDefKind::Handle(Handle::Own(_)) => false,
3750            TypeDefKind::Resource => false,
3751            TypeDefKind::Record(r) => r
3752                .fields
3753                .iter()
3754                .any(|case| self.type_has_borrow(resolve, &case.ty)),
3755            TypeDefKind::Flags(_) => false,
3756            TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.type_has_borrow(resolve, t)),
3757            TypeDefKind::Enum(_) => false,
3758            TypeDefKind::List(ty)
3759            | TypeDefKind::FixedSizeList(ty, ..)
3760            | TypeDefKind::Future(Some(ty))
3761            | TypeDefKind::Stream(Some(ty))
3762            | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty),
3763            TypeDefKind::Result(r) => [&r.ok, &r.err]
3764                .iter()
3765                .filter_map(|t| t.as_ref())
3766                .any(|t| self.type_has_borrow(resolve, t)),
3767            TypeDefKind::Future(None) | TypeDefKind::Stream(None) => false,
3768            TypeDefKind::Unknown => unreachable!(),
3769        }
3770    }
3771}
3772
3773struct MergeMap<'a> {
3774    /// A map of package ids in `from` to those in `into` for those that are
3775    /// found to be equivalent.
3776    package_map: HashMap<PackageId, PackageId>,
3777
3778    /// A map of interface ids in `from` to those in `into` for those that are
3779    /// found to be equivalent.
3780    interface_map: HashMap<InterfaceId, InterfaceId>,
3781
3782    /// A map of type ids in `from` to those in `into` for those that are
3783    /// found to be equivalent.
3784    type_map: HashMap<TypeId, TypeId>,
3785
3786    /// A map of world ids in `from` to those in `into` for those that are
3787    /// found to be equivalent.
3788    world_map: HashMap<WorldId, WorldId>,
3789
3790    /// A list of documents that need to be added to packages in `into`.
3791    ///
3792    /// The elements here are:
3793    ///
3794    /// * The name of the interface/world
3795    /// * The ID within `into` of the package being added to
3796    /// * The ID within `from` of the item being added.
3797    interfaces_to_add: Vec<(String, PackageId, InterfaceId)>,
3798    worlds_to_add: Vec<(String, PackageId, WorldId)>,
3799
3800    /// Which `Resolve` is being merged from.
3801    from: &'a Resolve,
3802
3803    /// Which `Resolve` is being merged into.
3804    into: &'a Resolve,
3805}
3806
3807impl<'a> MergeMap<'a> {
3808    fn new(from: &'a Resolve, into: &'a Resolve) -> MergeMap<'a> {
3809        MergeMap {
3810            package_map: Default::default(),
3811            interface_map: Default::default(),
3812            type_map: Default::default(),
3813            world_map: Default::default(),
3814            interfaces_to_add: Default::default(),
3815            worlds_to_add: Default::default(),
3816            from,
3817            into,
3818        }
3819    }
3820
3821    fn build(&mut self) -> Result<()> {
3822        for from_id in self.from.topological_packages() {
3823            let from = &self.from.packages[from_id];
3824            let into_id = match self.into.package_names.get(&from.name) {
3825                Some(id) => *id,
3826
3827                // This package, according to its name and url, is not present
3828                // in `self` so it needs to get added below.
3829                None => {
3830                    log::trace!("adding unique package {}", from.name);
3831                    continue;
3832                }
3833            };
3834            log::trace!("merging duplicate package {}", from.name);
3835
3836            self.build_package(from_id, into_id).with_context(|| {
3837                format!("failed to merge package `{}` into existing copy", from.name)
3838            })?;
3839        }
3840
3841        Ok(())
3842    }
3843
3844    fn build_package(&mut self, from_id: PackageId, into_id: PackageId) -> Result<()> {
3845        let prev = self.package_map.insert(from_id, into_id);
3846        assert!(prev.is_none());
3847
3848        let from = &self.from.packages[from_id];
3849        let into = &self.into.packages[into_id];
3850
3851        // If an interface is present in `from_id` but not present in `into_id`
3852        // then it can be copied over wholesale. That copy is scheduled to
3853        // happen within the `self.interfaces_to_add` list.
3854        for (name, from_interface_id) in from.interfaces.iter() {
3855            let into_interface_id = match into.interfaces.get(name) {
3856                Some(id) => *id,
3857                None => {
3858                    log::trace!("adding unique interface {name}");
3859                    self.interfaces_to_add
3860                        .push((name.clone(), into_id, *from_interface_id));
3861                    continue;
3862                }
3863            };
3864
3865            log::trace!("merging duplicate interfaces {name}");
3866            self.build_interface(*from_interface_id, into_interface_id)
3867                .with_context(|| format!("failed to merge interface `{name}`"))?;
3868        }
3869
3870        for (name, from_world_id) in from.worlds.iter() {
3871            let into_world_id = match into.worlds.get(name) {
3872                Some(id) => *id,
3873                None => {
3874                    log::trace!("adding unique world {name}");
3875                    self.worlds_to_add
3876                        .push((name.clone(), into_id, *from_world_id));
3877                    continue;
3878                }
3879            };
3880
3881            log::trace!("merging duplicate worlds {name}");
3882            self.build_world(*from_world_id, into_world_id)
3883                .with_context(|| format!("failed to merge world `{name}`"))?;
3884        }
3885
3886        Ok(())
3887    }
3888
3889    fn build_interface(&mut self, from_id: InterfaceId, into_id: InterfaceId) -> Result<()> {
3890        let prev = self.interface_map.insert(from_id, into_id);
3891        assert!(prev.is_none());
3892
3893        let from_interface = &self.from.interfaces[from_id];
3894        let into_interface = &self.into.interfaces[into_id];
3895
3896        // Unlike documents/interfaces above if an interface in `from`
3897        // differs from the interface in `into` then that's considered an
3898        // error. Changing interfaces can reflect changes in imports/exports
3899        // which may not be expected so it's currently required that all
3900        // interfaces, when merged, exactly match.
3901        //
3902        // One case to consider here, for example, is that if a world in
3903        // `into` exports the interface `into_id` then if `from_id` were to
3904        // add more items into `into` then it would unexpectedly require more
3905        // items to be exported which may not work. In an import context this
3906        // might work since it's "just more items available for import", but
3907        // for now a conservative route of "interfaces must match" is taken.
3908
3909        for (name, from_type_id) in from_interface.types.iter() {
3910            let into_type_id = *into_interface
3911                .types
3912                .get(name)
3913                .ok_or_else(|| anyhow!("expected type `{name}` to be present"))?;
3914            let prev = self.type_map.insert(*from_type_id, into_type_id);
3915            assert!(prev.is_none());
3916
3917            self.build_type_id(*from_type_id, into_type_id)
3918                .with_context(|| format!("mismatch in type `{name}`"))?;
3919        }
3920
3921        for (name, from_func) in from_interface.functions.iter() {
3922            let into_func = match into_interface.functions.get(name) {
3923                Some(func) => func,
3924                None => bail!("expected function `{name}` to be present"),
3925            };
3926            self.build_function(from_func, into_func)
3927                .with_context(|| format!("mismatch in function `{name}`"))?;
3928        }
3929
3930        Ok(())
3931    }
3932
3933    fn build_type_id(&mut self, from_id: TypeId, into_id: TypeId) -> Result<()> {
3934        // FIXME: ideally the types should be "structurally
3935        // equal" but that's not trivial to do in the face of
3936        // resources.
3937        let _ = from_id;
3938        let _ = into_id;
3939        Ok(())
3940    }
3941
3942    fn build_type(&mut self, from_ty: &Type, into_ty: &Type) -> Result<()> {
3943        match (from_ty, into_ty) {
3944            (Type::Id(from), Type::Id(into)) => {
3945                self.build_type_id(*from, *into)?;
3946            }
3947            (from, into) if from != into => bail!("different kinds of types"),
3948            _ => {}
3949        }
3950        Ok(())
3951    }
3952
3953    fn build_function(&mut self, from_func: &Function, into_func: &Function) -> Result<()> {
3954        if from_func.name != into_func.name {
3955            bail!(
3956                "different function names `{}` and `{}`",
3957                from_func.name,
3958                into_func.name
3959            );
3960        }
3961        match (&from_func.kind, &into_func.kind) {
3962            (FunctionKind::Freestanding, FunctionKind::Freestanding) => {}
3963            (FunctionKind::AsyncFreestanding, FunctionKind::AsyncFreestanding) => {}
3964
3965            (FunctionKind::Method(from), FunctionKind::Method(into))
3966            | (FunctionKind::Static(from), FunctionKind::Static(into))
3967            | (FunctionKind::AsyncMethod(from), FunctionKind::AsyncMethod(into))
3968            | (FunctionKind::AsyncStatic(from), FunctionKind::AsyncStatic(into))
3969            | (FunctionKind::Constructor(from), FunctionKind::Constructor(into)) => {
3970                self.build_type_id(*from, *into)
3971                    .context("different function kind types")?;
3972            }
3973
3974            (FunctionKind::Method(_), _)
3975            | (FunctionKind::Constructor(_), _)
3976            | (FunctionKind::Static(_), _)
3977            | (FunctionKind::Freestanding, _)
3978            | (FunctionKind::AsyncFreestanding, _)
3979            | (FunctionKind::AsyncMethod(_), _)
3980            | (FunctionKind::AsyncStatic(_), _) => {
3981                bail!("different function kind types")
3982            }
3983        }
3984
3985        if from_func.params.len() != into_func.params.len() {
3986            bail!("different number of function parameters");
3987        }
3988        for ((from_name, from_ty), (into_name, into_ty)) in
3989            from_func.params.iter().zip(&into_func.params)
3990        {
3991            if from_name != into_name {
3992                bail!("different function parameter names: {from_name} != {into_name}");
3993            }
3994            self.build_type(from_ty, into_ty)
3995                .with_context(|| format!("different function parameter types for `{from_name}`"))?;
3996        }
3997        match (&from_func.result, &into_func.result) {
3998            (Some(from_ty), Some(into_ty)) => {
3999                self.build_type(from_ty, into_ty)
4000                    .context("different function result types")?;
4001            }
4002            (None, None) => {}
4003            (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
4004        }
4005        Ok(())
4006    }
4007
4008    fn build_world(&mut self, from_id: WorldId, into_id: WorldId) -> Result<()> {
4009        let prev = self.world_map.insert(from_id, into_id);
4010        assert!(prev.is_none());
4011
4012        let from_world = &self.from.worlds[from_id];
4013        let into_world = &self.into.worlds[into_id];
4014
4015        // Same as interfaces worlds are expected to exactly match to avoid
4016        // unexpectedly changing a particular component's view of imports and
4017        // exports.
4018        //
4019        // FIXME: this should probably share functionality with
4020        // `Resolve::merge_worlds` to support adding imports but not changing
4021        // exports.
4022
4023        if from_world.imports.len() != into_world.imports.len() {
4024            bail!("world contains different number of imports than expected");
4025        }
4026        if from_world.exports.len() != into_world.exports.len() {
4027            bail!("world contains different number of exports than expected");
4028        }
4029
4030        for (from_name, from) in from_world.imports.iter() {
4031            let into_name = MergeMap::map_name(from_name, &self.interface_map);
4032            let name_str = self.from.name_world_key(from_name);
4033            let into = into_world
4034                .imports
4035                .get(&into_name)
4036                .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?;
4037            self.match_world_item(from, into)
4038                .with_context(|| format!("import `{name_str}` didn't match target world"))?;
4039        }
4040
4041        for (from_name, from) in from_world.exports.iter() {
4042            let into_name = MergeMap::map_name(from_name, &self.interface_map);
4043            let name_str = self.from.name_world_key(from_name);
4044            let into = into_world
4045                .exports
4046                .get(&into_name)
4047                .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?;
4048            self.match_world_item(from, into)
4049                .with_context(|| format!("export `{name_str}` didn't match target world"))?;
4050        }
4051
4052        Ok(())
4053    }
4054
4055    fn map_name(
4056        from_name: &WorldKey,
4057        interface_map: &HashMap<InterfaceId, InterfaceId>,
4058    ) -> WorldKey {
4059        match from_name {
4060            WorldKey::Name(s) => WorldKey::Name(s.clone()),
4061            WorldKey::Interface(id) => {
4062                WorldKey::Interface(interface_map.get(id).copied().unwrap_or(*id))
4063            }
4064        }
4065    }
4066
4067    fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> Result<()> {
4068        match (from, into) {
4069            (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
4070                match (
4071                    &self.from.interfaces[*from].name,
4072                    &self.into.interfaces[*into].name,
4073                ) {
4074                    // If one interface is unnamed then they must both be
4075                    // unnamed and they must both have the same structure for
4076                    // now.
4077                    (None, None) => self.build_interface(*from, *into)?,
4078
4079                    // Otherwise both interfaces must be named and they must
4080                    // have been previously found to be equivalent. Note that
4081                    // if either is unnamed it won't be present in
4082                    // `interface_map` so this'll return an error.
4083                    _ => {
4084                        if self.interface_map.get(&from) != Some(&into) {
4085                            bail!("interfaces are not the same");
4086                        }
4087                    }
4088                }
4089            }
4090            (WorldItem::Function(from), WorldItem::Function(into)) => {
4091                let _ = (from, into);
4092                // FIXME: should assert an check that `from` structurally
4093                // matches `into`
4094            }
4095            (WorldItem::Type(from), WorldItem::Type(into)) => {
4096                // FIXME: should assert an check that `from` structurally
4097                // matches `into`
4098                let prev = self.type_map.insert(*from, *into);
4099                assert!(prev.is_none());
4100            }
4101
4102            (WorldItem::Interface { .. }, _)
4103            | (WorldItem::Function(_), _)
4104            | (WorldItem::Type(_), _) => {
4105                bail!("world items do not have the same type")
4106            }
4107        }
4108        Ok(())
4109    }
4110}
4111
4112/// Updates stability annotations when merging `from` into `into`.
4113///
4114/// This is done to keep up-to-date stability information if possible.
4115/// Components for example don't carry stability information but WIT does so
4116/// this tries to move from "unknown" to stable/unstable if possible.
4117fn update_stability(from: &Stability, into: &mut Stability) -> Result<()> {
4118    // If `from` is unknown or the two stability annotations are equal then
4119    // there's nothing to do here.
4120    if from == into || from.is_unknown() {
4121        return Ok(());
4122    }
4123    // Otherwise if `into` is unknown then inherit the stability listed in
4124    // `from`.
4125    if into.is_unknown() {
4126        *into = from.clone();
4127        return Ok(());
4128    }
4129
4130    // Failing all that this means that the two attributes are different so
4131    // generate an error.
4132    bail!("mismatch in stability from '{:?}' to '{:?}'", from, into)
4133}
4134
4135fn merge_include_stability(
4136    from: &Stability,
4137    into: &mut Stability,
4138    is_external_include: bool,
4139) -> Result<()> {
4140    if is_external_include && from.is_stable() {
4141        log::trace!("dropped stability from external package");
4142        *into = Stability::Unknown;
4143        return Ok(());
4144    }
4145
4146    return update_stability(from, into);
4147}
4148
4149/// An error that can be returned during "world elaboration" during various
4150/// [`Resolve`] operations.
4151///
4152/// Methods on [`Resolve`] which mutate its internals, such as
4153/// [`Resolve::push_dir`] or [`Resolve::importize`] can fail if `world` imports
4154/// in WIT packages are invalid. This error indicates one of these situations
4155/// where an invalid dependency graph between imports and exports are detected.
4156///
4157/// Note that at this time this error is subtle and not easy to understand, and
4158/// work needs to be done to explain this better and additionally provide a
4159/// better error message. For now though this type enables callers to test for
4160/// the exact kind of error emitted.
4161#[derive(Debug, Clone)]
4162pub struct InvalidTransitiveDependency(String);
4163
4164impl fmt::Display for InvalidTransitiveDependency {
4165    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4166        write!(
4167            f,
4168            "interface `{}` transitively depends on an interface in \
4169             incompatible ways",
4170            self.0
4171        )
4172    }
4173}
4174
4175impl std::error::Error for InvalidTransitiveDependency {}
4176
4177#[cfg(test)]
4178mod tests {
4179    use crate::Resolve;
4180    use anyhow::Result;
4181
4182    #[test]
4183    fn select_world() -> Result<()> {
4184        let mut resolve = Resolve::default();
4185        resolve.push_str(
4186            "test.wit",
4187            r#"
4188                package foo:bar@0.1.0;
4189
4190                world foo {}
4191            "#,
4192        )?;
4193        resolve.push_str(
4194            "test.wit",
4195            r#"
4196                package foo:baz@0.1.0;
4197
4198                world foo {}
4199            "#,
4200        )?;
4201        resolve.push_str(
4202            "test.wit",
4203            r#"
4204                package foo:baz@0.2.0;
4205
4206                world foo {}
4207            "#,
4208        )?;
4209
4210        let dummy = resolve.push_str(
4211            "test.wit",
4212            r#"
4213                package foo:dummy;
4214
4215                world foo {}
4216            "#,
4217        )?;
4218
4219        assert!(resolve.select_world(&[dummy], None).is_ok());
4220        assert!(resolve.select_world(&[dummy], Some("xx")).is_err());
4221        assert!(resolve.select_world(&[dummy], Some("")).is_err());
4222        assert!(resolve.select_world(&[dummy], Some("foo:bar/foo")).is_ok());
4223        assert!(
4224            resolve
4225                .select_world(&[dummy], Some("foo:bar/foo@0.1.0"))
4226                .is_ok()
4227        );
4228        assert!(resolve.select_world(&[dummy], Some("foo:baz/foo")).is_err());
4229        assert!(
4230            resolve
4231                .select_world(&[dummy], Some("foo:baz/foo@0.1.0"))
4232                .is_ok()
4233        );
4234        assert!(
4235            resolve
4236                .select_world(&[dummy], Some("foo:baz/foo@0.2.0"))
4237                .is_ok()
4238        );
4239        Ok(())
4240    }
4241
4242    /// When there are multiple packages and there's no main package, don't
4243    /// pick a world just based on it being the only one that matches.
4244    #[test]
4245    fn select_world_multiple_packages() -> Result<()> {
4246        use wit_parser::Resolve;
4247
4248        let mut resolve = Resolve::default();
4249
4250        // Just one world in one package; we always succeed.
4251        let stuff = resolve.push_str(
4252            "./my-test.wit",
4253            r#"
4254                    package test:stuff;
4255
4256                    world foo {
4257                        // ...
4258                    }
4259                "#,
4260        )?;
4261        assert!(resolve.select_world(&[stuff], None).is_ok());
4262        assert!(resolve.select_world(&[stuff], Some("foo")).is_ok());
4263
4264        // Multiple packages, but still just one total world. Lookups
4265        // without a main package now fail.
4266        let empty = resolve.push_str(
4267            "./my-test.wit",
4268            r#"
4269                    package test:empty;
4270                "#,
4271        )?;
4272        assert!(resolve.select_world(&[stuff, empty], None).is_err());
4273        assert!(resolve.select_world(&[stuff, empty], Some("foo")).is_err());
4274        assert!(resolve.select_world(&[empty], None).is_err());
4275        assert!(resolve.select_world(&[empty], Some("foo")).is_err());
4276
4277        Ok(())
4278    }
4279
4280    /// Test selecting a world with multiple versions of a package name.
4281    #[test]
4282    fn select_world_versions() -> Result<()> {
4283        use wit_parser::Resolve;
4284
4285        let mut resolve = Resolve::default();
4286
4287        let _id = resolve.push_str(
4288            "./my-test.wit",
4289            r#"
4290                    package example:distraction;
4291                "#,
4292        )?;
4293
4294        // When selecting with a version it's ok to drop the version when
4295        // there's only a single copy of that package in `Resolve`.
4296        let versions_1 = resolve.push_str(
4297            "./my-test.wit",
4298            r#"
4299                    package example:versions@1.0.0;
4300
4301                    world foo { /* ... */ }
4302                "#,
4303        )?;
4304        assert!(resolve.select_world(&[versions_1], Some("foo")).is_ok());
4305        assert!(
4306            resolve
4307                .select_world(&[versions_1], Some("foo@1.0.0"))
4308                .is_err()
4309        );
4310        assert!(
4311            resolve
4312                .select_world(&[versions_1], Some("example:versions/foo"))
4313                .is_ok()
4314        );
4315        assert!(
4316            resolve
4317                .select_world(&[versions_1], Some("example:versions/foo@1.0.0"))
4318                .is_ok()
4319        );
4320
4321        // However when a single package has multiple versions in a resolve
4322        // it's required to specify the version to select which one.
4323        let versions_2 = resolve.push_str(
4324            "./my-test.wit",
4325            r#"
4326                    package example:versions@2.0.0;
4327
4328                    world foo { /* ... */ }
4329                "#,
4330        )?;
4331        assert!(
4332            resolve
4333                .select_world(&[versions_1, versions_2], Some("foo"))
4334                .is_err()
4335        );
4336        assert!(
4337            resolve
4338                .select_world(&[versions_1, versions_2], Some("foo@1.0.0"))
4339                .is_err()
4340        );
4341        assert!(
4342            resolve
4343                .select_world(&[versions_1, versions_2], Some("foo@2.0.0"))
4344                .is_err()
4345        );
4346        assert!(
4347            resolve
4348                .select_world(&[versions_1, versions_2], Some("example:versions/foo"))
4349                .is_err()
4350        );
4351        assert!(
4352            resolve
4353                .select_world(
4354                    &[versions_1, versions_2],
4355                    Some("example:versions/foo@1.0.0")
4356                )
4357                .is_ok()
4358        );
4359        assert!(
4360            resolve
4361                .select_world(
4362                    &[versions_1, versions_2],
4363                    Some("example:versions/foo@2.0.0")
4364                )
4365                .is_ok()
4366        );
4367
4368        Ok(())
4369    }
4370
4371    /// Test overriding a main package using name qualification
4372    #[test]
4373    fn select_world_override_qualification() -> Result<()> {
4374        use wit_parser::Resolve;
4375
4376        let mut resolve = Resolve::default();
4377
4378        let other = resolve.push_str(
4379            "./my-test.wit",
4380            r#"
4381                    package example:other;
4382
4383                    world foo { }
4384                "#,
4385        )?;
4386
4387        // A fully-qualified name overrides a main package.
4388        let fq = resolve.push_str(
4389            "./my-test.wit",
4390            r#"
4391                    package example:fq;
4392
4393                    world bar { }
4394                "#,
4395        )?;
4396        assert!(resolve.select_world(&[other, fq], Some("foo")).is_err());
4397        assert!(resolve.select_world(&[other, fq], Some("bar")).is_err());
4398        assert!(
4399            resolve
4400                .select_world(&[other, fq], Some("example:other/foo"))
4401                .is_ok()
4402        );
4403        assert!(
4404            resolve
4405                .select_world(&[other, fq], Some("example:fq/bar"))
4406                .is_ok()
4407        );
4408        assert!(
4409            resolve
4410                .select_world(&[other, fq], Some("example:other/bar"))
4411                .is_err()
4412        );
4413        assert!(
4414            resolve
4415                .select_world(&[other, fq], Some("example:fq/foo"))
4416                .is_err()
4417        );
4418
4419        Ok(())
4420    }
4421
4422    /// Test selecting with fully-qualified world names.
4423    #[test]
4424    fn select_world_fully_qualified() -> Result<()> {
4425        use wit_parser::Resolve;
4426
4427        let mut resolve = Resolve::default();
4428
4429        let distraction = resolve.push_str(
4430            "./my-test.wit",
4431            r#"
4432                    package example:distraction;
4433                "#,
4434        )?;
4435
4436        // If a package has multiple worlds, then we can't guess the world
4437        // even if we know the package.
4438        let multiworld = resolve.push_str(
4439            "./my-test.wit",
4440            r#"
4441                    package example:multiworld;
4442
4443                    world foo { /* ... */ }
4444
4445                    world bar { /* ... */ }
4446                "#,
4447        )?;
4448        assert!(
4449            resolve
4450                .select_world(&[distraction, multiworld], None)
4451                .is_err()
4452        );
4453        assert!(
4454            resolve
4455                .select_world(&[distraction, multiworld], Some("foo"))
4456                .is_err()
4457        );
4458        assert!(
4459            resolve
4460                .select_world(&[distraction, multiworld], Some("example:multiworld/foo"))
4461                .is_ok()
4462        );
4463        assert!(
4464            resolve
4465                .select_world(&[distraction, multiworld], Some("bar"))
4466                .is_err()
4467        );
4468        assert!(
4469            resolve
4470                .select_world(&[distraction, multiworld], Some("example:multiworld/bar"))
4471                .is_ok()
4472        );
4473
4474        Ok(())
4475    }
4476
4477    /// Test `select_world` with single and multiple packages.
4478    #[test]
4479    fn select_world_packages() -> Result<()> {
4480        use wit_parser::Resolve;
4481
4482        let mut resolve = Resolve::default();
4483
4484        // If there's a single package and only one world, that world is
4485        // the obvious choice.
4486        let wit1 = resolve.push_str(
4487            "./my-test.wit",
4488            r#"
4489                    package example:wit1;
4490
4491                    world foo {
4492                        // ...
4493                    }
4494                "#,
4495        )?;
4496        assert!(resolve.select_world(&[wit1], None).is_ok());
4497        assert!(resolve.select_world(&[wit1], Some("foo")).is_ok());
4498        assert!(
4499            resolve
4500                .select_world(&[wit1], Some("example:wit1/foo"))
4501                .is_ok()
4502        );
4503        assert!(resolve.select_world(&[wit1], Some("bar")).is_err());
4504        assert!(
4505            resolve
4506                .select_world(&[wit1], Some("example:wit2/foo"))
4507                .is_err()
4508        );
4509
4510        // If there are multiple packages, we need to be told which package
4511        // to use.
4512        let wit2 = resolve.push_str(
4513            "./my-test.wit",
4514            r#"
4515                    package example:wit2;
4516
4517                    world foo { /* ... */ }
4518                "#,
4519        )?;
4520        assert!(resolve.select_world(&[wit1, wit2], None).is_err());
4521        assert!(resolve.select_world(&[wit1, wit2], Some("foo")).is_err());
4522        assert!(
4523            resolve
4524                .select_world(&[wit1, wit2], Some("example:wit1/foo"))
4525                .is_ok()
4526        );
4527        assert!(resolve.select_world(&[wit2], None).is_ok());
4528        assert!(resolve.select_world(&[wit2], Some("foo")).is_ok());
4529        assert!(
4530            resolve
4531                .select_world(&[wit2], Some("example:wit1/foo"))
4532                .is_ok()
4533        );
4534        assert!(resolve.select_world(&[wit1, wit2], Some("bar")).is_err());
4535        assert!(
4536            resolve
4537                .select_world(&[wit1, wit2], Some("example:wit2/foo"))
4538                .is_ok()
4539        );
4540        assert!(resolve.select_world(&[wit2], Some("bar")).is_err());
4541        assert!(
4542            resolve
4543                .select_world(&[wit2], Some("example:wit2/foo"))
4544                .is_ok()
4545        );
4546
4547        Ok(())
4548    }
4549}