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