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