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