Skip to main content

wit_parser/resolve/
mod.rs

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