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