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