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