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` value 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_value(&self, key: &WorldKey, item: &WorldItem) -> Option<String> {
1558        if let WorldKey::Name(_) = key {
1559            if let WorldItem::Interface { id, .. } = item {
1560                if self.interfaces[*id].name.is_some() {
1561                    return Some(self.id_of(*id).unwrap().into());
1562                }
1563            }
1564        }
1565        None
1566    }
1567
1568    /// Returns the component model `external-id` value for the world import of
1569    /// `key` and `item`.
1570    ///
1571    /// See the component model explainer and 🏷️ for more information on this feature.
1572    pub fn external_id_value(&self, key: &WorldKey, item: &WorldItem) -> Option<String> {
1573        let _ = key;
1574        match item {
1575            WorldItem::Interface { external_id, .. } => external_id.clone(),
1576            WorldItem::Function(f) => f.external_id.clone(),
1577            WorldItem::Type { id, .. } => self.types[*id].external_id.clone(),
1578        }
1579    }
1580
1581    /// Returns the interface that `id` uses a type from, if it uses a type from
1582    /// a different interface than `id` is defined within.
1583    ///
1584    /// If `id` is not a use-of-a-type or it's using a type in the same
1585    /// interface then `None` is returned.
1586    pub fn type_interface_dep(&self, id: TypeId) -> Option<InterfaceId> {
1587        let ty = &self.types[id];
1588        let dep = match ty.kind {
1589            TypeDefKind::Type(Type::Id(id)) => id,
1590            _ => return None,
1591        };
1592        let other = &self.types[dep];
1593        if ty.owner == other.owner {
1594            None
1595        } else {
1596            match other.owner {
1597                TypeOwner::Interface(id) => Some(id),
1598                _ => unreachable!(),
1599            }
1600        }
1601    }
1602
1603    /// Returns an iterator of all interfaces that the interface `id` depends
1604    /// on.
1605    ///
1606    /// Interfaces may depend on others for type information to resolve type
1607    /// imports.
1608    ///
1609    /// Note that the returned iterator may yield the same interface as a
1610    /// dependency multiple times. Additionally only direct dependencies of `id`
1611    /// are yielded, not transitive dependencies.
1612    pub fn interface_direct_deps(&self, id: InterfaceId) -> impl Iterator<Item = InterfaceId> + '_ {
1613        self.interfaces[id]
1614            .types
1615            .iter()
1616            .filter_map(move |(_name, ty)| self.type_interface_dep(*ty))
1617    }
1618
1619    /// Returns an iterator of all packages that the package `id` depends
1620    /// on.
1621    ///
1622    /// Packages may depend on others for type information to resolve type
1623    /// imports or interfaces to resolve worlds.
1624    ///
1625    /// Note that the returned iterator may yield the same package as a
1626    /// dependency multiple times. Additionally only direct dependencies of `id`
1627    /// are yielded, not transitive dependencies.
1628    pub fn package_direct_deps(&self, id: PackageId) -> impl Iterator<Item = PackageId> + '_ {
1629        let pkg = &self.packages[id];
1630
1631        pkg.interfaces
1632            .iter()
1633            .flat_map(move |(_name, id)| self.interface_direct_deps(*id))
1634            .chain(pkg.worlds.iter().flat_map(move |(_name, id)| {
1635                let world = &self.worlds[*id];
1636                world
1637                    .imports
1638                    .iter()
1639                    .chain(world.exports.iter())
1640                    .filter_map(move |(_name, item)| match item {
1641                        WorldItem::Interface { id, .. } => Some(*id),
1642                        WorldItem::Function(_) => None,
1643                        WorldItem::Type { id, .. } => self.type_interface_dep(*id),
1644                    })
1645            }))
1646            .filter_map(move |iface_id| {
1647                let pkg = self.interfaces[iface_id].package?;
1648                if pkg == id { None } else { Some(pkg) }
1649            })
1650    }
1651
1652    /// Returns a topological ordering of packages contained in this `Resolve`.
1653    ///
1654    /// This returns a list of `PackageId` such that when visited in order it's
1655    /// guaranteed that all dependencies will have been defined by prior items
1656    /// in the list.
1657    pub fn topological_packages(&self) -> Vec<PackageId> {
1658        let mut pushed = vec![false; self.packages.len()];
1659        let mut order = Vec::new();
1660        for (id, _) in self.packages.iter() {
1661            self.build_topological_package_ordering(id, &mut pushed, &mut order);
1662        }
1663        order
1664    }
1665
1666    fn build_topological_package_ordering(
1667        &self,
1668        id: PackageId,
1669        pushed: &mut Vec<bool>,
1670        order: &mut Vec<PackageId>,
1671    ) {
1672        if pushed[id.index()] {
1673            return;
1674        }
1675        for dep in self.package_direct_deps(id) {
1676            self.build_topological_package_ordering(dep, pushed, order);
1677        }
1678        order.push(id);
1679        pushed[id.index()] = true;
1680    }
1681
1682    #[doc(hidden)]
1683    pub fn assert_valid(&self) {
1684        let mut package_interfaces = Vec::new();
1685        let mut package_worlds = Vec::new();
1686        for (id, pkg) in self.packages.iter() {
1687            let mut interfaces = HashSet::new();
1688            for (name, iface) in pkg.interfaces.iter() {
1689                assert!(interfaces.insert(*iface));
1690                let iface = &self.interfaces[*iface];
1691                assert_eq!(name, iface.name.as_ref().unwrap());
1692                assert_eq!(iface.package.unwrap(), id);
1693            }
1694            package_interfaces.push(pkg.interfaces.values().copied().collect::<HashSet<_>>());
1695            let mut worlds = HashSet::new();
1696            for (name, world) in pkg.worlds.iter() {
1697                assert!(worlds.insert(*world));
1698                assert_eq!(
1699                    pkg.worlds.get_key_value(name),
1700                    Some((name, world)),
1701                    "`MutableKeys` impl may have been used to change a key's hash or equality"
1702                );
1703                let world = &self.worlds[*world];
1704                assert_eq!(*name, world.name);
1705                assert_eq!(world.package.unwrap(), id);
1706            }
1707            package_worlds.push(pkg.worlds.values().copied().collect::<HashSet<_>>());
1708        }
1709
1710        let mut interface_types = Vec::new();
1711        for (id, iface) in self.interfaces.iter() {
1712            assert!(self.packages.get(iface.package.unwrap()).is_some());
1713            if iface.name.is_some() {
1714                match iface.clone_of {
1715                    Some(other) => {
1716                        assert_eq!(iface.name, self.interfaces[other].name);
1717                    }
1718                    None => {
1719                        assert!(package_interfaces[iface.package.unwrap().index()].contains(&id));
1720                    }
1721                }
1722            }
1723
1724            for (name, ty) in iface.types.iter() {
1725                let ty = &self.types[*ty];
1726                assert_eq!(ty.name.as_ref(), Some(name));
1727                assert_eq!(ty.owner, TypeOwner::Interface(id));
1728            }
1729            interface_types.push(iface.types.values().copied().collect::<HashSet<_>>());
1730            for (name, f) in iface.functions.iter() {
1731                assert_eq!(*name, f.name);
1732            }
1733        }
1734
1735        let mut world_types = Vec::new();
1736        for (id, world) in self.worlds.iter() {
1737            log::debug!("validating world {}", &world.name);
1738            if let Some(package) = world.package {
1739                assert!(self.packages.get(package).is_some());
1740                assert!(package_worlds[package.index()].contains(&id));
1741            }
1742            assert!(world.includes.is_empty());
1743
1744            let mut types = HashSet::new();
1745            for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1746                log::debug!("validating world item: {}", self.name_world_key(name));
1747                match item {
1748                    WorldItem::Interface { id, .. } => {
1749                        // Anonymous interfaces must belong to the same package,
1750                        // but interfaces through `implements` can be in any
1751                        // package.
1752                        if matches!(name, WorldKey::Name(_)) {
1753                            let iface = &self.interfaces[*id];
1754                            if iface.name.is_none() {
1755                                assert_eq!(iface.package, world.package);
1756                            }
1757                        }
1758                    }
1759                    WorldItem::Function(f) => {
1760                        assert!(!matches!(name, WorldKey::Interface(_)));
1761                        assert_eq!(f.name, name.clone().unwrap_name());
1762                    }
1763                    WorldItem::Type { id: ty, .. } => {
1764                        assert!(!matches!(name, WorldKey::Interface(_)));
1765                        assert!(types.insert(*ty));
1766                        let ty = &self.types[*ty];
1767                        assert_eq!(ty.name, Some(name.clone().unwrap_name()));
1768                        assert_eq!(ty.owner, TypeOwner::World(id));
1769                    }
1770                }
1771            }
1772            self.assert_world_elaborated(world);
1773            world_types.push(types);
1774        }
1775
1776        for (ty_id, ty) in self.types.iter() {
1777            match ty.owner {
1778                TypeOwner::Interface(id) => {
1779                    assert!(self.interfaces.get(id).is_some());
1780                    assert!(interface_types[id.index()].contains(&ty_id));
1781                }
1782                TypeOwner::World(id) => {
1783                    assert!(self.worlds.get(id).is_some());
1784                    assert!(world_types[id.index()].contains(&ty_id));
1785                }
1786                TypeOwner::None => {}
1787            }
1788        }
1789
1790        self.assert_topologically_sorted();
1791    }
1792
1793    fn assert_topologically_sorted(&self) {
1794        let mut positions = IndexMap::default();
1795        for id in self.topological_packages() {
1796            let pkg = &self.packages[id];
1797            log::debug!("pkg {}", pkg.name);
1798            let prev = positions.insert(Some(id), IndexSet::default());
1799            assert!(prev.is_none());
1800        }
1801        positions.insert(None, IndexSet::default());
1802
1803        for (id, iface) in self.interfaces.iter() {
1804            log::debug!("iface {:?}", iface.name);
1805            let ok = positions.get_mut(&iface.package).unwrap().insert(id);
1806            assert!(ok);
1807        }
1808
1809        for (_, world) in self.worlds.iter() {
1810            log::debug!("world {:?}", world.name);
1811
1812            let my_package = world.package;
1813            let my_package_pos = positions.get_index_of(&my_package).unwrap();
1814
1815            for (_, item) in world.imports.iter().chain(&world.exports) {
1816                let id = match item {
1817                    WorldItem::Interface { id, .. } => *id,
1818                    _ => continue,
1819                };
1820                let other_package = self.interfaces[id].package;
1821                let other_package_pos = positions.get_index_of(&other_package).unwrap();
1822
1823                assert!(other_package_pos <= my_package_pos);
1824            }
1825        }
1826
1827        for (_id, ty) in self.types.iter() {
1828            log::debug!("type {:?} {:?}", ty.name, ty.owner);
1829            let other_id = match ty.kind {
1830                TypeDefKind::Type(Type::Id(ty)) => ty,
1831                _ => continue,
1832            };
1833            let other = &self.types[other_id];
1834            if ty.kind == other.kind {
1835                continue;
1836            }
1837            let my_interface = match ty.owner {
1838                TypeOwner::Interface(id) => id,
1839                _ => continue,
1840            };
1841            let other_interface = match other.owner {
1842                TypeOwner::Interface(id) => id,
1843                _ => continue,
1844            };
1845
1846            let my_package = self.interfaces[my_interface].package;
1847            let other_package = self.interfaces[other_interface].package;
1848            let my_package_pos = positions.get_index_of(&my_package).unwrap();
1849            let other_package_pos = positions.get_index_of(&other_package).unwrap();
1850
1851            assert!(other_package_pos <= my_package_pos);
1852        }
1853    }
1854
1855    fn assert_world_elaborated(&self, world: &World) {
1856        for (key, item) in world.imports.iter() {
1857            log::debug!(
1858                "asserting elaborated world import {}",
1859                self.name_world_key(key)
1860            );
1861            match item {
1862                WorldItem::Type { id, .. } => self.assert_world_imports_type_deps(world, key, *id),
1863
1864                // All types referred to must be imported.
1865                WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1866
1867                // All direct dependencies of this interface must be imported.
1868                WorldItem::Interface { id, .. } => {
1869                    for dep in self.interface_direct_deps(*id) {
1870                        assert!(
1871                            world.imports.contains_key(&WorldKey::Interface(dep)),
1872                            "world import of {} is missing transitive dep of {}",
1873                            self.name_world_key(key),
1874                            self.id_of(dep).unwrap(),
1875                        );
1876                    }
1877                }
1878            }
1879        }
1880        for (key, item) in world.exports.iter() {
1881            log::debug!(
1882                "asserting elaborated world export {}",
1883                self.name_world_key(key)
1884            );
1885            match item {
1886                // Types referred to by this function must be imported.
1887                WorldItem::Function(f) => self.assert_world_function_imports_types(world, key, f),
1888
1889                // Dependencies of exported interfaces must also be exported, or
1890                // if imported then that entire chain of imports must be
1891                // imported and not exported.
1892                WorldItem::Interface { id, .. } => {
1893                    for dep in self.interface_direct_deps(*id) {
1894                        let dep_key = WorldKey::Interface(dep);
1895                        if world.exports.contains_key(&dep_key) {
1896                            continue;
1897                        }
1898                        self.foreach_interface_dep(dep, &mut |dep| {
1899                            let dep_key = WorldKey::Interface(dep);
1900                            assert!(
1901                                world.imports.contains_key(&dep_key),
1902                                "world should import {} (required by {})",
1903                                self.name_world_key(&dep_key),
1904                                self.name_world_key(key),
1905                            );
1906                            assert!(
1907                                !world.exports.contains_key(&dep_key),
1908                                "world should not export {} (required by {})",
1909                                self.name_world_key(&dep_key),
1910                                self.name_world_key(key),
1911                            );
1912                        });
1913                    }
1914                }
1915
1916                // exported types not allowed at this time
1917                WorldItem::Type { .. } => unreachable!(),
1918            }
1919        }
1920    }
1921
1922    fn assert_world_imports_type_deps(&self, world: &World, key: &WorldKey, ty: TypeId) {
1923        // If this is a `use` statement then the referred-to interface must be
1924        // imported into this world.
1925        let ty = &self.types[ty];
1926        if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
1927            if let TypeOwner::Interface(id) = self.types[other].owner {
1928                let key = WorldKey::Interface(id);
1929                assert!(world.imports.contains_key(&key));
1930                return;
1931            }
1932        }
1933
1934        // ... otherwise any named type that this type refers to, one level
1935        // deep, must be imported into this world under that name.
1936
1937        let mut visitor = MyVisit(self, Vec::new());
1938        visitor.visit_type_def(self, ty);
1939        for ty in visitor.1 {
1940            let ty = &self.types[ty];
1941            let Some(name) = ty.name.clone() else {
1942                continue;
1943            };
1944            let dep_key = WorldKey::Name(name);
1945            assert!(
1946                world.imports.contains_key(&dep_key),
1947                "world import `{}` should also force an import of `{}`",
1948                self.name_world_key(key),
1949                self.name_world_key(&dep_key),
1950            );
1951        }
1952
1953        struct MyVisit<'a>(&'a Resolve, Vec<TypeId>);
1954
1955        impl TypeIdVisitor for MyVisit<'_> {
1956            fn before_visit_type_id(&mut self, id: TypeId) -> bool {
1957                self.1.push(id);
1958                // recurse into unnamed types to look at all named types
1959                self.0.types[id].name.is_none()
1960            }
1961        }
1962    }
1963
1964    /// This asserts that all types referred to by `func` are imported into
1965    /// `world` under `WorldKey::Name`. Note that this is only applicable to
1966    /// named type
1967    fn assert_world_function_imports_types(&self, world: &World, key: &WorldKey, func: &Function) {
1968        for ty in func
1969            .parameter_and_result_types()
1970            .chain(func.kind.resource().map(Type::Id))
1971        {
1972            let Type::Id(id) = ty else {
1973                continue;
1974            };
1975            self.assert_world_imports_type_deps(world, key, id);
1976        }
1977    }
1978
1979    /// Returns whether the `stability` annotation contained within `pkg_id`
1980    /// should be included or not.
1981    ///
1982    /// The `span` provided here is an optional span pointing to the item that
1983    /// is annotated with `stability`.
1984    ///
1985    /// Returns `Ok(true)` if the item is included, or `Ok(false)` if the item
1986    /// is not.
1987    ///
1988    /// # Errors
1989    ///
1990    /// Returns an error if the `pkg_id` isn't annotated with sufficient version
1991    /// information to have a `stability` annotation. For example if `pkg_id`
1992    /// has no version listed then an error will be returned if `stability`
1993    /// mentions a version.
1994    fn include_stability(
1995        &self,
1996        stability: &Stability,
1997        pkg_id: &PackageId,
1998        span: Span,
1999    ) -> ResolveResult<bool> {
2000        Ok(match stability {
2001            Stability::Unknown => true,
2002            // NOTE: deprecations are intentionally omitted -- an existing
2003            // `@since` takes precedence over `@deprecated`
2004            Stability::Stable { since, .. } => {
2005                let Some(p) = self.packages.get(*pkg_id) else {
2006                    // We can't check much without a package (possibly dealing
2007                    // with an item in an `UnresolvedPackage`), @since version &
2008                    // deprecations can't be checked because there's no package
2009                    // version to compare to.
2010                    //
2011                    // Feature requirements on stabilized features are ignored
2012                    // in resolved packages, so we do the same here.
2013                    return Ok(true);
2014                };
2015
2016                // Use of feature gating with version specifiers inside a
2017                // package that is not versioned is not allowed
2018                let package_version = p.name.version.as_ref().ok_or_else(|| {
2019                    ResolveError::new_semantic(
2020                        span,
2021                        format!(
2022                            "package [{}] contains a feature gate with a version \
2023                         specifier, so it must have a version",
2024                            p.name
2025                        ),
2026                    )
2027                })?;
2028
2029                // If the version on the feature gate is:
2030                // - released, then we can include it
2031                // - unreleased, then we must check the feature (if present)
2032                if since > package_version {
2033                    return Err(ResolveError::new_semantic(
2034                        span,
2035                        format!(
2036                            "feature gate cannot reference unreleased version \
2037                        {since} of package [{}] (current version {package_version})",
2038                            p.name
2039                        ),
2040                    ));
2041                }
2042
2043                true
2044            }
2045            Stability::Unstable { feature, .. } => {
2046                self.features.contains(feature) || self.all_features
2047            }
2048        })
2049    }
2050
2051    /// Performs the "elaboration process" necessary for the `world_id`
2052    /// specified to ensure that all of its transitive imports are listed.
2053    ///
2054    /// This function will take the unordered lists of the specified world's
2055    /// imports and exports and "elaborate" them to ensure that they're
2056    /// topographically sorted where all transitively required interfaces by
2057    /// imports, or exports, are listed. This will additionally validate that
2058    /// the exports are all valid and present, specifically with the restriction
2059    /// noted on `elaborate_world_exports`.
2060    ///
2061    /// The world is mutated in-place in this `Resolve`.
2062    fn elaborate_world(&mut self, world_id: WorldId, span: Span) -> ResolveResult<()> {
2063        // First process all imports. This is easier than exports since the only
2064        // requirement here is that all interfaces need to be added with a
2065        // topological order between them.
2066        let mut new_imports = IndexMap::default();
2067        let world = &self.worlds[world_id];
2068
2069        // Sort the imports by "class" to ensure that this matches the order
2070        // that items are printed and that items are in topological order.
2071        //
2072        // When printing worlds in WIT:
2073        //
2074        // * interfaces come first
2075        // * types are next
2076        //   * type imports are first
2077        //   * type definitions are next
2078        //   * resource definitions have methods printed inline
2079        // * freestanding functions are last
2080        //
2081        // This reflects the topological order between items where types
2082        // can refer to imports and functions can refer to these types. Ordering
2083        // within a single class (e.g. imports depending on each other, types
2084        // referring to each other) is already preserved by other passes in this
2085        // file and general AST resolution. That means that a stable sort here
2086        // can be used to ensure that each class is in the right location
2087        // relative to the others.
2088        //
2089        // Overall this ensures that round-trips of WIT through wasm should
2090        // always produce the same result.
2091        let sort_key = |resolve: &Resolve, item: &WorldItem| match item {
2092            WorldItem::Interface { .. } => 0,
2093            WorldItem::Type { id, .. } => {
2094                let ty = &resolve.types[*id];
2095                match ty.kind {
2096                    TypeDefKind::Type(Type::Id(t)) if resolve.types[t].owner != ty.owner => 1,
2097                    _ => 2,
2098                }
2099            }
2100            WorldItem::Function(f) => {
2101                if f.kind.resource().is_none() {
2102                    3
2103                } else {
2104                    4
2105                }
2106            }
2107        };
2108
2109        // Sort world items when we start to elaborate the world to start with a
2110        // topological view of items.
2111        let mut world_imports = world.imports.iter().collect::<Vec<_>>();
2112        world_imports.sort_by_key(|(_name, import)| sort_key(self, import));
2113        for (name, item) in world_imports {
2114            match item {
2115                // Interfaces get their dependencies added first followed by the
2116                // interface itself.
2117                WorldItem::Interface {
2118                    id,
2119                    stability,
2120                    docs,
2121                    external_id,
2122                    ..
2123                } => {
2124                    self.elaborate_world_import(
2125                        &mut new_imports,
2126                        name.clone(),
2127                        *id,
2128                        &stability,
2129                        docs,
2130                        external_id.as_deref(),
2131                    );
2132                }
2133
2134                // Functions are added as-is since their dependence on types in
2135                // the world should already be satisfied.
2136                WorldItem::Function(_) => {
2137                    let prev = new_imports.insert(name.clone(), item.clone());
2138                    assert!(prev.is_none());
2139                }
2140
2141                // Types may depend on an interface, in which case a (possibly)
2142                // recursive addition of that interface happens here. Afterwards
2143                // the type itself can be added safely.
2144                WorldItem::Type { id, .. } => {
2145                    if let Some(dep) = self.type_interface_dep(*id) {
2146                        self.elaborate_world_import(
2147                            &mut new_imports,
2148                            WorldKey::Interface(dep),
2149                            dep,
2150                            &self.types[*id].stability,
2151                            &Docs::default(),
2152                            None,
2153                        );
2154                    }
2155                    let prev = new_imports.insert(name.clone(), item.clone());
2156                    assert!(prev.is_none());
2157                }
2158            }
2159        }
2160
2161        // Exports are trickier than imports, notably to uphold the invariant
2162        // required by `elaborate_world_exports`. To do this the exports are
2163        // partitioned into interfaces/functions. All functions are added to
2164        // the new exports list during this loop but interfaces are all deferred
2165        // to be handled in the `elaborate_world_exports` function.
2166        let mut new_exports = IndexMap::default();
2167        let mut export_interfaces = IndexMap::default();
2168        for (name, item) in world.exports.iter() {
2169            match item {
2170                WorldItem::Interface { .. } => {
2171                    let prev = export_interfaces.insert(name.clone(), item.clone());
2172                    assert!(prev.is_none());
2173                }
2174                WorldItem::Function(_) => {
2175                    let prev = new_exports.insert(name.clone(), item.clone());
2176                    assert!(prev.is_none());
2177                }
2178                WorldItem::Type { .. } => unreachable!(),
2179            }
2180        }
2181
2182        self.elaborate_world_exports(&export_interfaces, &mut new_imports, &mut new_exports, span)?;
2183
2184        // In addition to sorting at the start of elaboration also sort here at
2185        // the end of elaboration to handle types being interspersed with
2186        // interfaces as they're found.
2187        new_imports.sort_by_cached_key(|_name, import| sort_key(self, import));
2188
2189        // And with all that done the world is updated in-place with
2190        // imports/exports.
2191        log::trace!("imports = {new_imports:?}");
2192        log::trace!("exports = {new_exports:?}");
2193        let world = &mut self.worlds[world_id];
2194        world.imports = new_imports;
2195        world.exports = new_exports;
2196
2197        Ok(())
2198    }
2199
2200    fn elaborate_world_import(
2201        &self,
2202        imports: &mut IndexMap<WorldKey, WorldItem>,
2203        key: WorldKey,
2204        id: InterfaceId,
2205        stability: &Stability,
2206        docs: &Docs,
2207        external_id: Option<&str>,
2208    ) {
2209        if imports.contains_key(&key) {
2210            return;
2211        }
2212        // Synthesized dependency imports carry no statement-level docs of their
2213        // own.
2214        for dep in self.interface_direct_deps(id) {
2215            self.elaborate_world_import(
2216                imports,
2217                WorldKey::Interface(dep),
2218                dep,
2219                stability,
2220                &Docs::default(),
2221                None,
2222            );
2223        }
2224        let prev = imports.insert(
2225            key,
2226            WorldItem::Interface {
2227                id,
2228                stability: stability.clone(),
2229                docs: docs.clone(),
2230                span: Default::default(),
2231                external_id: external_id.map(|s| s.to_string()),
2232            },
2233        );
2234        assert!(prev.is_none());
2235    }
2236
2237    /// This function adds all of the interfaces in `export_interfaces` to the
2238    /// list of exports of the `world` specified.
2239    ///
2240    /// This method is more involved than adding imports because it is fallible.
2241    /// Chiefly what can happen is that the dependencies of all exports must be
2242    /// satisfied by other exports or imports, but not both. For example given a
2243    /// situation such as:
2244    ///
2245    /// ```wit
2246    /// interface a {
2247    ///     type t = u32
2248    /// }
2249    /// interface b {
2250    ///     use a.{t}
2251    /// }
2252    /// interface c {
2253    ///     use a.{t}
2254    ///     use b.{t as t2}
2255    /// }
2256    /// ```
2257    ///
2258    /// where `c` depends on `b` and `a` where `b` depends on `a`, then the
2259    /// purpose of this method is to reject this world:
2260    ///
2261    /// ```wit
2262    /// world foo {
2263    ///     export a
2264    ///     export c
2265    /// }
2266    /// ```
2267    ///
2268    /// The reasoning here is unfortunately subtle and is additionally the
2269    /// subject of WebAssembly/component-model#208. Effectively the `c`
2270    /// interface depends on `b`, but it's not listed explicitly as an import,
2271    /// so it's then implicitly added as an import. This then transitively
2272    /// depends on `a` so it's also added as an import. At this point though `c`
2273    /// also depends on `a`, and it's also exported, so naively it should depend
2274    /// on the export and not implicitly add an import. This means though that
2275    /// `c` has access to two copies of `a`, one imported and one exported. This
2276    /// is not valid, especially in the face of resource types.
2277    ///
2278    /// Overall this method is tasked with rejecting the above world by walking
2279    /// over all the exports and adding their dependencies. Each dependency is
2280    /// recorded with whether it's required to be imported, and then if an
2281    /// export is added for something that's required to be an error then the
2282    /// operation fails.
2283    fn elaborate_world_exports(
2284        &self,
2285        export_interfaces: &IndexMap<WorldKey, WorldItem>,
2286        imports: &mut IndexMap<WorldKey, WorldItem>,
2287        exports: &mut IndexMap<WorldKey, WorldItem>,
2288        span: Span,
2289    ) -> ResolveResult<()> {
2290        let mut required_imports = HashSet::new();
2291        for (key, item) in export_interfaces.iter() {
2292            let name = self.name_world_key(&key);
2293            let ok = add_world_export(
2294                self,
2295                imports,
2296                exports,
2297                &export_interfaces,
2298                &mut required_imports,
2299                key.clone(),
2300                item.clone(),
2301                true,
2302            );
2303            if !ok {
2304                // FIXME: this is not a great error message and basically no
2305                // one will know what to do when it gets printed. Improving
2306                // this error message, however, is a chunk of work that may
2307                // not be best spent doing this at this time, so I'm writing
2308                // this comment instead.
2309                //
2310                // More-or-less what should happen here is that a "path"
2311                // from this interface to the conflicting interface should
2312                // be printed. It should be explained why an import is being
2313                // injected, why that's conflicting with an export, and
2314                // ideally with a suggestion of "add this interface to the
2315                // export list to fix this error".
2316                //
2317                // That's a lot of info that's not easy to get at without
2318                // more refactoring, so it's left to a future date in the
2319                // hopes that most folks won't actually run into this for
2320                // the time being.
2321                return Err(ResolveError::from(
2322                    ResolveErrorKind::InvalidTransitiveDependency { name, span },
2323                ));
2324            }
2325        }
2326        return Ok(());
2327
2328        fn add_world_export(
2329            resolve: &Resolve,
2330            imports: &mut IndexMap<WorldKey, WorldItem>,
2331            exports: &mut IndexMap<WorldKey, WorldItem>,
2332            export_interfaces: &IndexMap<WorldKey, WorldItem>,
2333            required_imports: &mut HashSet<InterfaceId>,
2334            key: WorldKey,
2335            item: WorldItem,
2336            add_export: bool,
2337        ) -> bool {
2338            if exports.contains_key(&key) {
2339                if add_export {
2340                    return true;
2341                } else {
2342                    return false;
2343                }
2344            }
2345            let (id, stability, external_id) = match &item {
2346                WorldItem::Interface {
2347                    id,
2348                    stability,
2349                    external_id,
2350                    ..
2351                } => (*id, stability, external_id),
2352                _ => unreachable!(),
2353            };
2354            // If this is an import and it's already in the `imports` set then
2355            // we can skip it as we've already visited this interface.
2356            if !add_export && required_imports.contains(&id) {
2357                return true;
2358            }
2359            let ok = resolve.interface_direct_deps(id).all(|dep| {
2360                let item = WorldItem::Interface {
2361                    id: dep,
2362                    stability: stability.clone(),
2363                    docs: Default::default(),
2364                    span: Default::default(),
2365                    external_id: external_id.clone(),
2366                };
2367                let key = WorldKey::Interface(dep);
2368                let add_export = add_export && export_interfaces.contains_key(&key);
2369                add_world_export(
2370                    resolve,
2371                    imports,
2372                    exports,
2373                    export_interfaces,
2374                    required_imports,
2375                    key,
2376                    item,
2377                    add_export,
2378                )
2379            });
2380            if !ok {
2381                return false;
2382            }
2383            if add_export {
2384                if required_imports.contains(&id) {
2385                    return false;
2386                }
2387                let prev = exports.insert(key.clone(), item);
2388                assert!(prev.is_none());
2389            } else {
2390                required_imports.insert(id);
2391                if !imports.contains_key(&key) {
2392                    imports.insert(key.clone(), item);
2393                }
2394            }
2395            true
2396        }
2397    }
2398
2399    /// Remove duplicate imports from a world if they import from the same
2400    /// interface with semver-compatible versions.
2401    ///
2402    /// This will merge duplicate interfaces present at multiple versions in
2403    /// both a world by selecting the larger version of the two interfaces. This
2404    /// requires that the interfaces are indeed semver-compatible and it means
2405    /// that some imports might be removed and replaced. Note that this is only
2406    /// done within a single semver track, for example the world imports 0.2.0
2407    /// and 0.2.1 then the result afterwards will be that it imports
2408    /// 0.2.1. If, however, 0.3.0 where imported then the final result would
2409    /// import both 0.2.0 and 0.3.0.
2410    pub fn merge_world_imports_based_on_semver(&mut self, world_id: WorldId) -> anyhow::Result<()> {
2411        let world = &self.worlds[world_id];
2412
2413        // The first pass here is to build a map of "semver tracks" where they
2414        // key is per-interface and the value is the maximal version found in
2415        // that semver-compatible-track plus the interface which is the maximal
2416        // version.
2417        //
2418        // At the same time a `to_remove` set is maintained to remember what
2419        // interfaces are being removed from `from` and `into`. All of
2420        // `to_remove` are placed with a known other version.
2421        let mut semver_tracks = HashMap::new();
2422        let mut to_remove = HashSet::new();
2423        for (key, _) in world.imports.iter() {
2424            let iface_id = match key {
2425                WorldKey::Interface(id) => *id,
2426                WorldKey::Name(_) => continue,
2427            };
2428            let (track, version) = match self.semver_track(iface_id) {
2429                Some(track) => track,
2430                None => continue,
2431            };
2432            log::debug!(
2433                "{} is on track {}/{}",
2434                self.id_of(iface_id).unwrap(),
2435                track.0,
2436                track.1,
2437            );
2438            match semver_tracks.entry(track.clone()) {
2439                Entry::Vacant(e) => {
2440                    e.insert((version, iface_id));
2441                }
2442                Entry::Occupied(mut e) => match version.cmp(&e.get().0) {
2443                    Ordering::Greater => {
2444                        to_remove.insert(e.get().1);
2445                        e.insert((version, iface_id));
2446                    }
2447                    Ordering::Equal => {}
2448                    Ordering::Less => {
2449                        to_remove.insert(iface_id);
2450                    }
2451                },
2452            }
2453        }
2454
2455        // Build a map of "this interface is replaced with this interface" using
2456        // the results of the loop above.
2457        let mut replacements = HashMap::new();
2458        for id in to_remove {
2459            let (track, _) = self.semver_track(id).unwrap();
2460            let (_, latest) = semver_tracks[&track];
2461            let prev = replacements.insert(id, latest);
2462            assert!(prev.is_none());
2463        }
2464        // Explicit drop needed for hashbrown compatibility - hashbrown's HashMap
2465        // destructor may access stored references, extending the borrow.
2466        drop(semver_tracks);
2467
2468        // Validate that `merge_world_item` succeeds for merging all removed
2469        // interfaces with their replacement. This is a double-check that the
2470        // semver version is actually correct and all items present in the old
2471        // interface are in the new.
2472        for (to_replace, replace_with) in replacements.iter() {
2473            self.merge_world_item(
2474                &WorldItem::Interface {
2475                    id: *to_replace,
2476                    stability: Default::default(),
2477                    docs: Default::default(),
2478                    span: Default::default(),
2479                    external_id: Default::default(),
2480                },
2481                &WorldItem::Interface {
2482                    id: *replace_with,
2483                    stability: Default::default(),
2484                    docs: Default::default(),
2485                    span: Default::default(),
2486                    external_id: Default::default(),
2487                },
2488            )
2489            .with_context(|| {
2490                let old_name = self.id_of(*to_replace).unwrap();
2491                let new_name = self.id_of(*replace_with).unwrap();
2492                format!(
2493                    "failed to upgrade `{old_name}` to `{new_name}`, was \
2494                     this semver-compatible update not semver compatible?"
2495                )
2496            })?;
2497        }
2498
2499        for (to_replace, replace_with) in replacements.iter() {
2500            log::debug!(
2501                "REPLACE {} => {}",
2502                self.id_of(*to_replace).unwrap(),
2503                self.id_of(*replace_with).unwrap(),
2504            );
2505        }
2506
2507        // Finally perform the actual transformation of the imports/exports.
2508        // Here all imports are removed if they're replaced and otherwise all
2509        // imports have their dependencies updated, possibly transitively, to
2510        // point to the new interfaces in `replacements`.
2511        //
2512        // Afterwards exports are additionally updated, but only their
2513        // dependencies on imports which were remapped. Exports themselves are
2514        // not deduplicated and/or removed.
2515        for (key, item) in mem::take(&mut self.worlds[world_id].imports) {
2516            if let WorldItem::Interface { id, .. } = item {
2517                if replacements.contains_key(&id) {
2518                    continue;
2519                }
2520            }
2521
2522            self.update_interface_deps_of_world_item(&item, &replacements);
2523
2524            let prev = self.worlds[world_id].imports.insert(key, item);
2525            assert!(prev.is_none());
2526        }
2527        for (key, item) in mem::take(&mut self.worlds[world_id].exports) {
2528            self.update_interface_deps_of_world_item(&item, &replacements);
2529            let prev = self.worlds[world_id].exports.insert(key, item);
2530            assert!(prev.is_none());
2531        }
2532
2533        // Run through `elaborate_world` to reorder imports as appropriate and
2534        // fill anything back in if it's actually required by exports. For now
2535        // this doesn't tamper with exports at all. Also note that this is
2536        // applied to all worlds in this `Resolve` because interfaces were
2537        // modified directly.
2538        let ids = self.worlds.iter().map(|(id, _)| id).collect::<Vec<_>>();
2539        for world_id in ids {
2540            let world_span = self.worlds[world_id].span;
2541            self.elaborate_world(world_id, world_span)?;
2542        }
2543
2544        #[cfg(debug_assertions)]
2545        self.assert_valid();
2546
2547        Ok(())
2548    }
2549
2550    fn update_interface_deps_of_world_item(
2551        &mut self,
2552        item: &WorldItem,
2553        replacements: &HashMap<InterfaceId, InterfaceId>,
2554    ) {
2555        match *item {
2556            WorldItem::Type { id, .. } => self.update_interface_dep_of_type(id, &replacements),
2557            WorldItem::Interface { id, .. } => {
2558                let types = self.interfaces[id]
2559                    .types
2560                    .values()
2561                    .copied()
2562                    .collect::<Vec<_>>();
2563                for ty in types {
2564                    self.update_interface_dep_of_type(ty, &replacements);
2565                }
2566            }
2567            WorldItem::Function(_) => {}
2568        }
2569    }
2570
2571    /// Returns the "semver track" of an interface plus the interface's version.
2572    ///
2573    /// This function returns `None` if the interface `id` has a package without
2574    /// a version. If the version is present, however, the first element of the
2575    /// tuple returned is a "semver track" for the specific interface. The
2576    /// version listed in `PackageName` will be modified so all
2577    /// semver-compatible versions are listed the same way.
2578    ///
2579    /// The second element in the returned tuple is this interface's package's
2580    /// version.
2581    fn semver_track(&self, id: InterfaceId) -> Option<((PackageName, String), &Version)> {
2582        let iface = &self.interfaces[id];
2583        let pkg = &self.packages[iface.package?];
2584        let version = pkg.name.version.as_ref()?;
2585        let mut name = pkg.name.clone();
2586        name.version = Some(PackageName::version_compat_track(version));
2587        Some(((name, iface.name.clone()?), version))
2588    }
2589
2590    /// If `ty` is a definition where it's a `use` from another interface, then
2591    /// change what interface it's using from according to the pairs in the
2592    /// `replacements` map.
2593    fn update_interface_dep_of_type(
2594        &mut self,
2595        ty: TypeId,
2596        replacements: &HashMap<InterfaceId, InterfaceId>,
2597    ) {
2598        let to_replace = match self.type_interface_dep(ty) {
2599            Some(id) => id,
2600            None => return,
2601        };
2602        let replace_with = match replacements.get(&to_replace) {
2603            Some(id) => id,
2604            None => return,
2605        };
2606        let dep = match self.types[ty].kind {
2607            TypeDefKind::Type(Type::Id(id)) => id,
2608            _ => return,
2609        };
2610        let name = self.types[dep].name.as_ref().unwrap();
2611        // Note the infallible name indexing happening here. This should be
2612        // previously validated with `merge_world_item` to succeed.
2613        let replacement_id = self.interfaces[*replace_with].types[name];
2614        self.types[ty].kind = TypeDefKind::Type(Type::Id(replacement_id));
2615    }
2616
2617    /// Returns the core wasm module/field names for the specified `import`.
2618    ///
2619    /// This function will return the core wasm module/field that can be used to
2620    /// use `import` with the name `mangling` scheme specified as well. This can
2621    /// be useful for bindings generators, for example, and these names are
2622    /// recognized by `wit-component` and `wasm-tools component new`.
2623    pub fn wasm_import_name(
2624        &self,
2625        mangling: ManglingAndAbi,
2626        import: WasmImport<'_>,
2627    ) -> (String, String) {
2628        match mangling {
2629            ManglingAndAbi::Standard32 => match import {
2630                WasmImport::Func { interface, func } => {
2631                    let module = match interface {
2632                        Some(key) => format!("cm32p2|{}", self.name_canonicalized_world_key(key)),
2633                        None => format!("cm32p2"),
2634                    };
2635                    (module, func.name.clone())
2636                }
2637                WasmImport::ResourceIntrinsic {
2638                    interface,
2639                    resource,
2640                    intrinsic,
2641                } => {
2642                    let name = self.types[resource].name.as_ref().unwrap();
2643                    let (prefix, name) = match intrinsic {
2644                        ResourceIntrinsic::ImportedDrop => ("", format!("{name}_drop")),
2645                        ResourceIntrinsic::ExportedDrop => ("_ex_", format!("{name}_drop")),
2646                        ResourceIntrinsic::ExportedNew => ("_ex_", format!("{name}_new")),
2647                        ResourceIntrinsic::ExportedRep => ("_ex_", format!("{name}_rep")),
2648                    };
2649                    let module = match interface {
2650                        Some(key) => {
2651                            format!("cm32p2|{prefix}{}", self.name_canonicalized_world_key(key))
2652                        }
2653                        None => {
2654                            assert_eq!(prefix, "");
2655                            format!("cm32p2")
2656                        }
2657                    };
2658                    (module, name)
2659                }
2660                WasmImport::FutureIntrinsic { .. } | WasmImport::StreamIntrinsic { .. } => {
2661                    panic!(
2662                        "at the time of writing, standard32 name mangling only supports the \
2663                         synchronous ABI and does not define future/stream intrinsic imports; \
2664                         use legacy mangling for these imports"
2665                    )
2666                }
2667            },
2668            ManglingAndAbi::Legacy(abi) => match import {
2669                WasmImport::Func { interface, func } => {
2670                    let module = match interface {
2671                        Some(key) => self.name_world_key(key),
2672                        None => format!("$root"),
2673                    };
2674                    (module, format!("{}{}", abi.import_prefix(), func.name))
2675                }
2676                WasmImport::ResourceIntrinsic {
2677                    interface,
2678                    resource,
2679                    intrinsic,
2680                } => {
2681                    let name = self.types[resource].name.as_ref().unwrap();
2682                    let (prefix, name) = match intrinsic {
2683                        ResourceIntrinsic::ImportedDrop => ("", format!("[resource-drop]{name}")),
2684                        ResourceIntrinsic::ExportedDrop => {
2685                            ("[export]", format!("[resource-drop]{name}"))
2686                        }
2687                        ResourceIntrinsic::ExportedNew => {
2688                            ("[export]", format!("[resource-new]{name}"))
2689                        }
2690                        ResourceIntrinsic::ExportedRep => {
2691                            ("[export]", format!("[resource-rep]{name}"))
2692                        }
2693                    };
2694                    let module = match interface {
2695                        Some(key) => format!("{prefix}{}", self.name_world_key(key)),
2696                        None => {
2697                            assert_eq!(prefix, "");
2698                            format!("$root")
2699                        }
2700                    };
2701                    (module, format!("{}{name}", abi.import_prefix()))
2702                }
2703                WasmImport::FutureIntrinsic {
2704                    interface,
2705                    func,
2706                    ty,
2707                    intrinsic,
2708                    exported,
2709                    async_,
2710                } => {
2711                    let module_prefix = if exported { "[export]" } else { "" };
2712                    let module = match interface {
2713                        Some(key) => format!("{module_prefix}{}", self.name_world_key(key)),
2714                        None => format!("{module_prefix}$root"),
2715                    };
2716                    let type_index = match ty {
2717                        Some(ty) => func
2718                            .find_futures_and_streams(self)
2719                            .into_iter()
2720                            .position(|candidate| candidate == ty)
2721                            .unwrap_or_else(|| {
2722                                panic!(
2723                                    "future type {ty:?} not found in `find_futures_and_streams` for `{}`",
2724                                    func.name
2725                                )
2726                            })
2727                            .to_string(),
2728                        None => "unit".to_string(),
2729                    };
2730                    let (async_prefix, name) = match intrinsic {
2731                        FutureIntrinsic::New => {
2732                            assert!(!async_, "future.new cannot be async-lowered");
2733                            ("", "new")
2734                        }
2735                        FutureIntrinsic::Read => {
2736                            (if async_ { "[async-lower]" } else { "" }, "read")
2737                        }
2738                        FutureIntrinsic::Write => {
2739                            (if async_ { "[async-lower]" } else { "" }, "write")
2740                        }
2741                        FutureIntrinsic::CancelRead => {
2742                            (if async_ { "[async-lower]" } else { "" }, "cancel-read")
2743                        }
2744                        FutureIntrinsic::CancelWrite => {
2745                            (if async_ { "[async-lower]" } else { "" }, "cancel-write")
2746                        }
2747                        FutureIntrinsic::DropReadable => {
2748                            assert!(!async_, "future.drop-readable cannot be async-lowered");
2749                            ("", "drop-readable")
2750                        }
2751                        FutureIntrinsic::DropWritable => {
2752                            assert!(!async_, "future.drop-writable cannot be async-lowered");
2753                            ("", "drop-writable")
2754                        }
2755                    };
2756                    (
2757                        module,
2758                        format!("{async_prefix}[future-{name}-{type_index}]{}", func.name),
2759                    )
2760                }
2761                WasmImport::StreamIntrinsic {
2762                    interface,
2763                    func,
2764                    ty,
2765                    intrinsic,
2766                    exported,
2767                    async_,
2768                } => {
2769                    let module_prefix = if exported { "[export]" } else { "" };
2770                    let module = match interface {
2771                        Some(key) => format!("{module_prefix}{}", self.name_world_key(key)),
2772                        None => format!("{module_prefix}$root"),
2773                    };
2774                    let type_index = match ty {
2775                        Some(ty) => func
2776                            .find_futures_and_streams(self)
2777                            .into_iter()
2778                            .position(|candidate| candidate == ty)
2779                            .unwrap_or_else(|| {
2780                                panic!(
2781                                    "stream type {ty:?} not found in `find_futures_and_streams` for `{}`",
2782                                    func.name
2783                                )
2784                            })
2785                            .to_string(),
2786                        None => "unit".to_string(),
2787                    };
2788                    let (async_prefix, name) = match intrinsic {
2789                        StreamIntrinsic::New => {
2790                            assert!(!async_, "stream.new cannot be async-lowered");
2791                            ("", "new")
2792                        }
2793                        StreamIntrinsic::Read => {
2794                            (if async_ { "[async-lower]" } else { "" }, "read")
2795                        }
2796                        StreamIntrinsic::Write => {
2797                            (if async_ { "[async-lower]" } else { "" }, "write")
2798                        }
2799                        StreamIntrinsic::CancelRead => {
2800                            (if async_ { "[async-lower]" } else { "" }, "cancel-read")
2801                        }
2802                        StreamIntrinsic::CancelWrite => {
2803                            (if async_ { "[async-lower]" } else { "" }, "cancel-write")
2804                        }
2805                        StreamIntrinsic::DropReadable => {
2806                            assert!(!async_, "stream.drop-readable cannot be async-lowered");
2807                            ("", "drop-readable")
2808                        }
2809                        StreamIntrinsic::DropWritable => {
2810                            assert!(!async_, "stream.drop-writable cannot be async-lowered");
2811                            ("", "drop-writable")
2812                        }
2813                    };
2814                    (
2815                        module,
2816                        format!("{async_prefix}[stream-{name}-{type_index}]{}", func.name),
2817                    )
2818                }
2819            },
2820        }
2821    }
2822
2823    /// Returns the core wasm export name for the specified `export`.
2824    ///
2825    /// This is the same as [`Resolve::wasm_import_name`], except for exports.
2826    pub fn wasm_export_name(&self, mangling: ManglingAndAbi, export: WasmExport<'_>) -> String {
2827        match mangling {
2828            ManglingAndAbi::Standard32 => match export {
2829                WasmExport::Func {
2830                    interface,
2831                    func,
2832                    kind,
2833                } => {
2834                    let mut name = String::from("cm32p2|");
2835                    if let Some(interface) = interface {
2836                        let s = self.name_canonicalized_world_key(interface);
2837                        name.push_str(&s);
2838                    }
2839                    name.push_str("|");
2840                    name.push_str(&func.name);
2841                    match kind {
2842                        WasmExportKind::Normal => {}
2843                        WasmExportKind::PostReturn => name.push_str("_post"),
2844                        WasmExportKind::Callback => todo!(
2845                            "not yet supported: \
2846                             async callback functions using standard name mangling"
2847                        ),
2848                    }
2849                    name
2850                }
2851                WasmExport::ResourceDtor {
2852                    interface,
2853                    resource,
2854                } => {
2855                    let name = self.types[resource].name.as_ref().unwrap();
2856                    let interface = self.name_canonicalized_world_key(interface);
2857                    format!("cm32p2|{interface}|{name}_dtor")
2858                }
2859                WasmExport::Memory => "cm32p2_memory".to_string(),
2860                WasmExport::Initialize => "cm32p2_initialize".to_string(),
2861                WasmExport::Realloc => "cm32p2_realloc".to_string(),
2862            },
2863            ManglingAndAbi::Legacy(abi) => match export {
2864                WasmExport::Func {
2865                    interface,
2866                    func,
2867                    kind,
2868                } => {
2869                    let mut name = abi.export_prefix().to_string();
2870                    match kind {
2871                        WasmExportKind::Normal => {}
2872                        WasmExportKind::PostReturn => name.push_str("cabi_post_"),
2873                        WasmExportKind::Callback => {
2874                            assert!(matches!(abi, LiftLowerAbi::AsyncCallback));
2875                            name = format!("[callback]{name}")
2876                        }
2877                    }
2878                    if let Some(interface) = interface {
2879                        let s = self.name_world_key(interface);
2880                        name.push_str(&s);
2881                        name.push_str("#");
2882                    }
2883                    name.push_str(&func.name);
2884                    name
2885                }
2886                WasmExport::ResourceDtor {
2887                    interface,
2888                    resource,
2889                } => {
2890                    let name = self.types[resource].name.as_ref().unwrap();
2891                    let interface = self.name_world_key(interface);
2892                    format!("{}{interface}#[dtor]{name}", abi.export_prefix())
2893                }
2894                WasmExport::Memory => "memory".to_string(),
2895                WasmExport::Initialize => "_initialize".to_string(),
2896                WasmExport::Realloc => "cabi_realloc".to_string(),
2897            },
2898        }
2899    }
2900
2901    /// This method will rewrite the `world` provided to ensure that, where
2902    /// necessary, all types in interfaces referred to by the `world` have
2903    /// nominal type ids for bindings generation.
2904    ///
2905    /// The need for this method primarily arises from bindings generators
2906    /// generating types in a programming language. Bindings generators try to
2907    /// generate a type-per-WIT-type but this becomes problematic in situations
2908    /// such as when an `interface` is both imported and exported. For example:
2909    ///
2910    /// ```wit
2911    /// interface x {
2912    ///    resource r;
2913    /// }
2914    ///
2915    /// world foo {
2916    ///     import x;
2917    ///     export x;
2918    /// }
2919    /// ```
2920    ///
2921    /// Here the `r` resource, before this method, exists once within this
2922    /// [`Resolve`]. This is a problem for bindings generators because guest
2923    /// languages typically want to represent this world with two types: one
2924    /// for the import and one for the export. This matches component model
2925    /// semantics where `r` is a different type between the import and the
2926    /// export.
2927    ///
2928    /// The purpose of this method is to ensure that languages with nominal
2929    /// types, where type identity is unique based on definition not structure,
2930    /// will have an easier time generating bindings. This method will
2931    /// duplicate the interface `x`, for example, and everything it contains.
2932    /// This means that the `world foo` above will have a different
2933    /// `InterfaceId` for the import and the export of `x`, despite them using
2934    /// the same interface in WIT. This is intended to make bindings generators'
2935    /// jobs much easier because now Id-uniqueness matches the semantic meaning
2936    /// of the world as well.
2937    ///
2938    /// This function will rewrite imported/exported interfaces, as appropriate,
2939    /// to all have unique ids if they would otherwise overlap with the imports.
2940    pub fn generate_nominal_type_ids(&mut self, world_id: WorldId) {
2941        let mut seen = HashSet::new();
2942        let mut interface_keys_rewritten = HashSet::new();
2943        let mut maps = CloneMaps::default();
2944
2945        // Pull out the imports/exports from `self` to have simultaneous
2946        // borrows.
2947        let world = &mut self.worlds[world_id];
2948        let mut imports = mem::take(&mut world.imports);
2949        let mut exports = mem::take(&mut world.exports);
2950
2951        // Notably visit `imports` first as they always get priority in the
2952        // order of having things imported from them. After `imports` are
2953        // visited then process all `exports`.
2954        log::trace!("nominalizing world imports");
2955        self.nominalize_world_items(
2956            &mut maps,
2957            world_id,
2958            &mut imports,
2959            &mut seen,
2960            &mut interface_keys_rewritten,
2961        );
2962        log::trace!("nominalizing world exports");
2963        self.nominalize_world_items(
2964            &mut maps,
2965            world_id,
2966            &mut exports,
2967            &mut seen,
2968            &mut interface_keys_rewritten,
2969        );
2970
2971        // Put that thing back where it came from, or so help me!
2972        let world = &mut self.worlds[world_id];
2973        assert!(world.imports.is_empty());
2974        assert!(world.exports.is_empty());
2975        world.imports = imports;
2976        world.exports = exports;
2977
2978        #[cfg(debug_assertions)]
2979        self.assert_valid();
2980    }
2981
2982    /// Implementation of `generate_nominal_type_ids` which processes either a
2983    /// world's imports or exports as specified in `items`.
2984    ///
2985    /// The parameters here are:
2986    ///
2987    /// * `maps` - the set of types that have previously been cloned by the
2988    ///   previous stage, if any. This is used to update any dependencies of an
2989    ///   interface that is cloned.
2990    ///
2991    /// * `world` - the world that's being nominalized.
2992    ///
2993    /// * `items` - either `imports` or `exports` for the `world`. This is
2994    ///   mutated in-place to have keys/items rewritten as-needed.
2995    ///
2996    /// * `seen` - the set of interfaces that have been seen previously when
2997    ///   iterating over this world. All interfaces processed are added to this
2998    ///   set.
2999    ///
3000    /// * `interface_keys_rewritten` - a distinct set from `seen` which only
3001    ///   tracks rewritten interfaces which have `WorldKey::Interface`. This is
3002    ///   the set of interfaces which dependencies can pull types from, which
3003    ///   needs to be tracked separately to know when to rewrite.
3004    fn nominalize_world_items(
3005        &mut self,
3006        maps: &mut CloneMaps,
3007        world: WorldId,
3008        items: &mut IndexMap<WorldKey, WorldItem>,
3009        seen: &mut HashSet<InterfaceId>,
3010        interface_keys_rewritten: &mut HashSet<InterfaceId>,
3011    ) {
3012        // Overall the problem that this function is trying to solve is not an
3013        // easy one. The input is an AST-like structure and the goal of this
3014        // function is to effectively perform a name resolution pass. The end
3015        // result is that if a thing points to another thing (e.g. type-use or
3016        // interface id) then that represents the actual name resolution of what
3017        // it points to.
3018        //
3019        // Currently, though, this isn't really a full-blown name resolution
3020        // pass. This is a pretty simple "do things in the right order" and name
3021        // resolution pops out. The conventions of WIT and how it translates to
3022        // components is what falls out of this loop below.
3023        //
3024        // The first rule of WIT is that interfaces can only use types from
3025        // other interface imports/exports. This notably excludes named imports.
3026        // For example:
3027        //
3028        //      interface a {
3029        //          type t = u32;
3030        //      }
3031        //
3032        //      interface b {
3033        //          use a.{t};
3034        //      }
3035        //
3036        //      world w {
3037        //          import a;
3038        //          import b; // uses `import a`
3039        //          import c: b; // also uses `import a`
3040        //          import d: interface {
3041        //              use a.{t}; // uses `import a`
3042        //          }
3043        //      }
3044        //
3045        // The next rule is that exported interfaces will use types from
3046        // imports, unless the interface is also exported. For example:
3047        //
3048        //      interface a {
3049        //          type t = u32;
3050        //      }
3051        //
3052        //      interface b {
3053        //          use a.{t};
3054        //      }
3055        //
3056        //      world w1 {
3057        //          import a;
3058        //
3059        //          export b; // uses `import a`
3060        //          export c: b; // uses `import a`
3061        //          export d: interface {
3062        //              use a.{t}; // uses `import a`
3063        //          }
3064        //      }
3065        //
3066        //      world w2 {
3067        //          export a;
3068        //          export b; // uses `export a`
3069        //          export c: b; // uses `export a`
3070        //          export d: interface {
3071        //              use a.{t}; // uses `export a`
3072        //          }
3073        //      }
3074        //
3075        // Finally, named imports, such as `import a: b` and `import a:
3076        // interface { ... }` cannot be used by anything. They can only
3077        // reference types in other interface imports/exports.
3078        //
3079        // Overall this is a pretty simplistic system. It's "good enough" for
3080        // now but will almost certainly be expanded over time. The hope is that
3081        // expanding this involves making this function more complicated but
3082        // ideally nowhere else.
3083
3084        // Given all that intro, the first thing we need to prioritize is that
3085        // `WorldKey::Name`'d interfaces are visited after `WorldKey::Interface`
3086        // interfaces. This is a bit of a weird result of how this function is
3087        // implemented right now. This visit order is a bit of a hack and
3088        // probably won't live beyond making WIT more powerful.
3089        //
3090        // Anyway, the reason for this has to do with the `CloneMaps` down
3091        // below. Basically what we're doing here is cloning interfaces, but
3092        // when doing so we need to be able to rewrite references to
3093        // previously-cloned interfaces if need be. `CloneMaps` represents the
3094        // aggregate results of all previous clones. Due to named interfaces
3095        // never being importable-from it means that mutations to `CloneMaps`
3096        // are discarded when named interfaces are cloned. The trick here
3097        // happens where this unconditionally preserves all modifications to
3098        // `CloneMaps` for `WorldKey::Interface` clones. Behaivor then "falls
3099        // out" where references to cloned interfaces are naturally rewritten.
3100        //
3101        // This all falls down, however, if an import is cloned and recorded.
3102        // Interfaces can be both exported and imported, which would mean that
3103        // the import and export are both cloned, and both need to be preserved
3104        // in `CloneMaps`. Right now `CloneMaps` requires uniqueness when
3105        // cloning (e.g. can't clone the same thing twice).
3106        //
3107        // Long story short: it's a hack that sort order here is the way it is.
3108        // Sorry. Be prepared to delete this should WIT get more powerful.
3109        let mut order = items.iter().enumerate().collect::<Vec<_>>();
3110        order.sort_by_key(|(_, (key, item))| match (key, item) {
3111            (WorldKey::Name(_), WorldItem::Interface { .. }) => 1,
3112            _ => 0,
3113        });
3114        let mut to_rewrite = IndexMap::default();
3115        for (i, (key, item)) in order {
3116            let id = match item {
3117                WorldItem::Interface { id, .. } => *id,
3118
3119                // Functions/types aren't rewritten, they're all nominal at the
3120                // world-level anyway.
3121                WorldItem::Function(_) | WorldItem::Type { .. } => continue,
3122            };
3123
3124            // If this interface itself is being visited for the second time
3125            // (e.g. imported & exported, imported twice, exported twice, etc),
3126            // or if any dependency of this interface is rewritten, then the
3127            // interface itself needs to be rewritten. Otherwise continue
3128            // onwards.
3129            let duplicated = !seen.insert(id);
3130            let any_dep_rewritten = self
3131                .interface_direct_deps(id)
3132                .any(|dep| interface_keys_rewritten.contains(&dep));
3133            if !(duplicated || any_dep_rewritten) {
3134                log::trace!("{} already nominal", self.name_world_key(key));
3135                continue;
3136            }
3137            log::trace!("{} getting rewritten nominal", self.name_world_key(key));
3138
3139            // If this is `WorldKey::Interface` then register this in the
3140            // `interface_keys_rewritten` map, and also plumb this through to
3141            // the rewriting stage to know whether `maps` needs to be reset or
3142            // not.
3143            let is_name = matches!(key, WorldKey::Name(_));
3144            if !is_name {
3145                assert!(interface_keys_rewritten.insert(id));
3146            }
3147
3148            to_rewrite
3149                .entry(id)
3150                .or_insert(Vec::new())
3151                .push((i, is_name));
3152        }
3153
3154        // Now that we know what to rewrite, rewrite everything.
3155        //
3156        // The trickiest part here is deciding what to do with `maps`. As
3157        // interfaces are cloned they'll record all remappings of
3158        // types/interfaces/etc within `maps`. We don't want to persist
3159        // everything because if an interface is cloned twice then everything
3160        // will get overwritten/corrupted within the map. In theory what we want
3161        // is for `maps` to track, for any one interface, just the transitive
3162        // set of dependencies for that interface and how they've been cloned.
3163        // What's implemented here is an approximation of this that should work
3164        // for now.
3165        //
3166        // Notably `to_rewrite` is an ordered list keyed by `InterfaceId`. This
3167        // means that if we walk `to_rewrite` in order we're walking this in
3168        // topological order. Second we then additionally sort the `list` for
3169        // each `to_rewrite` entry to ensure that all `WorldKey::Name` items are
3170        // visited first. In doing so we also discard all mutations to `maps`
3171        // after visiting is done. In effect what this does is it discards all
3172        // modifications due to `WorldKey::Name`, because nothing can depend on
3173        // those interfaces, and then it preserves modifications for
3174        // `WorldKey::Interface`, which other interfaces can indeed depend on.
3175        // In the end this basically does a very careful walk over a very
3176        // careful organization of `to_rewrite`.
3177        //
3178        // This'll need massive refactoring if WIT gets the ability to express
3179        // arbitrary edges between interfaces. It's WIT-level restriction right
3180        // now of sorts. There's no current way to model a `import a: i;` where
3181        // `i`'s dependencies are pulled from `import b: dep`, for example.
3182        // Right now if `i` depends on `dep` then that just always results in
3183        // `import dep`.
3184        for (id, mut list) in to_rewrite {
3185            list.sort_by_key(|(_, is_name)| if *is_name { 0 } else { 1 });
3186            for (i, is_name) in list {
3187                let prev_maps = if is_name { Some(maps.clone()) } else { None };
3188
3189                let mut cloner = clone::Cloner::new(
3190                    self,
3191                    maps,
3192                    TypeOwner::World(world),
3193                    TypeOwner::World(world),
3194                );
3195
3196                let mut new_id = id;
3197                cloner.new_package = cloner.resolve.interfaces[id].package;
3198                cloner.interface(&mut new_id);
3199                let (key, prev) = items.get_index_mut(i).unwrap();
3200                match prev {
3201                    WorldItem::Interface { id, .. } => *id = new_id,
3202                    _ => unreachable!(),
3203                }
3204
3205                match key {
3206                    // If the key for this is an `Interface` then that means we
3207                    // need to update the key as well. Here that's replaced by-index
3208                    // in the `IndexMap` to preserve the same ordering as before,
3209                    // and this operation should always succeed since `new_id` is
3210                    // fresh, hence the `unwrap()`.
3211                    WorldKey::Interface(_) => {
3212                        items.replace_index(i, WorldKey::Interface(new_id)).unwrap();
3213                    }
3214
3215                    // Name-based keys don't need updating as they only contain a
3216                    // string, no ids.
3217                    WorldKey::Name(_) => {}
3218                }
3219
3220                if let Some(prev) = prev_maps {
3221                    *maps = prev;
3222                }
3223            }
3224        }
3225    }
3226}
3227
3228/// Possible imports that can be passed to [`Resolve::wasm_import_name`].
3229#[derive(Debug)]
3230pub enum WasmImport<'a> {
3231    /// A WIT function is being imported. Optionally from an interface.
3232    Func {
3233        /// The name of the interface that the function is being imported from.
3234        ///
3235        /// If the function is imported directly from the world then this is
3236        /// `None`.
3237        interface: Option<&'a WorldKey>,
3238
3239        /// The function being imported.
3240        func: &'a Function,
3241    },
3242
3243    /// A resource-related intrinsic is being imported.
3244    ResourceIntrinsic {
3245        /// The optional interface to import from, same as `WasmImport::Func`.
3246        interface: Option<&'a WorldKey>,
3247
3248        /// The resource that's being operated on.
3249        resource: TypeId,
3250
3251        /// The intrinsic that's being imported.
3252        intrinsic: ResourceIntrinsic,
3253    },
3254
3255    /// A future-related intrinsic is being imported.
3256    FutureIntrinsic {
3257        /// The optional interface to import from, same as `WasmImport::Func`.
3258        interface: Option<&'a WorldKey>,
3259
3260        /// The function whose signature this future type appears in.
3261        func: &'a Function,
3262
3263        /// The future type appearing in `func.find_futures_and_streams(resolve)`.
3264        ///
3265        /// Use `None` for the special `unit` payload case.
3266        ty: Option<TypeId>,
3267
3268        /// The intrinsic that's being imported.
3269        intrinsic: FutureIntrinsic,
3270
3271        /// Whether this import is for an exported WIT function.
3272        ///
3273        /// This controls whether the module name is prefixed with `[export]`.
3274        exported: bool,
3275
3276        /// Whether this intrinsic import is async-lowered.
3277        ///
3278        /// This is only valid for read/write/cancel intrinsics.
3279        async_: bool,
3280    },
3281
3282    /// A stream-related intrinsic is being imported.
3283    StreamIntrinsic {
3284        /// The optional interface to import from, same as `WasmImport::Func`.
3285        interface: Option<&'a WorldKey>,
3286
3287        /// The function whose signature this stream type appears in.
3288        func: &'a Function,
3289
3290        /// The stream type appearing in `func.find_futures_and_streams(resolve)`.
3291        ///
3292        /// Use `None` for the special `unit` payload case.
3293        ty: Option<TypeId>,
3294
3295        /// The intrinsic that's being imported.
3296        intrinsic: StreamIntrinsic,
3297
3298        /// Whether this import is for an exported WIT function.
3299        ///
3300        /// This controls whether the module name is prefixed with `[export]`.
3301        exported: bool,
3302
3303        /// Whether this intrinsic import is async-lowered.
3304        ///
3305        /// This is only valid for read/write/cancel intrinsics.
3306        async_: bool,
3307    },
3308}
3309
3310/// Intrinsic definitions to go with [`WasmImport::ResourceIntrinsic`] which
3311/// also goes with [`Resolve::wasm_import_name`].
3312#[derive(Debug)]
3313pub enum ResourceIntrinsic {
3314    ImportedDrop,
3315    ExportedDrop,
3316    ExportedNew,
3317    ExportedRep,
3318}
3319
3320/// Intrinsic definitions to go with [`WasmImport::FutureIntrinsic`] which
3321/// also goes with [`Resolve::wasm_import_name`].
3322#[derive(Debug)]
3323pub enum FutureIntrinsic {
3324    New,
3325    Read,
3326    Write,
3327    CancelRead,
3328    CancelWrite,
3329    DropReadable,
3330    DropWritable,
3331}
3332
3333/// Intrinsic definitions to go with [`WasmImport::StreamIntrinsic`] which
3334/// also goes with [`Resolve::wasm_import_name`].
3335#[derive(Debug)]
3336pub enum StreamIntrinsic {
3337    New,
3338    Read,
3339    Write,
3340    CancelRead,
3341    CancelWrite,
3342    DropReadable,
3343    DropWritable,
3344}
3345
3346/// Indicates whether a function export is a normal export, a post-return
3347/// function, or a callback function.
3348#[derive(Debug)]
3349pub enum WasmExportKind {
3350    /// Normal function export.
3351    Normal,
3352
3353    /// Post-return function.
3354    PostReturn,
3355
3356    /// Async callback function.
3357    Callback,
3358}
3359
3360/// Different kinds of exports that can be passed to
3361/// [`Resolve::wasm_export_name`] to export from core wasm modules.
3362#[derive(Debug)]
3363pub enum WasmExport<'a> {
3364    /// A WIT function is being exported, optionally from an interface.
3365    Func {
3366        /// An optional interface which owns `func`. Use `None` for top-level
3367        /// world function.
3368        interface: Option<&'a WorldKey>,
3369
3370        /// The function being exported.
3371        func: &'a Function,
3372
3373        /// Kind of function (normal, post-return, or callback) being exported.
3374        kind: WasmExportKind,
3375    },
3376
3377    /// A destructor for a resource exported from this module.
3378    ResourceDtor {
3379        /// The interface that owns the resource.
3380        interface: &'a WorldKey,
3381        /// The resource itself that the destructor is for.
3382        resource: TypeId,
3383    },
3384
3385    /// Linear memory, the one that the canonical ABI uses.
3386    Memory,
3387
3388    /// An initialization function (not the core wasm `start`).
3389    Initialize,
3390
3391    /// The general-purpose realloc hook.
3392    Realloc,
3393}
3394
3395/// Structure returned by [`Resolve::merge`] which contains mappings from
3396/// old-ids to new-ids after the merge.
3397#[derive(Default)]
3398pub struct Remap {
3399    pub types: Vec<Option<TypeId>>,
3400    pub interfaces: Vec<Option<InterfaceId>>,
3401    pub worlds: Vec<Option<WorldId>>,
3402    pub packages: Vec<PackageId>,
3403
3404    /// A cache of anonymous `own<T>` handles for resource types.
3405    ///
3406    /// The appending operation of `Remap` is the one responsible for
3407    /// translating references to `T` where `T` is a resource into `own<T>`
3408    /// instead. This map is used to deduplicate the `own<T>` types generated
3409    /// to generate as few as possible.
3410    ///
3411    /// The key of this map is the resource id `T` in the new resolve, and
3412    /// the value is the `own<T>` type pointing to `T`.
3413    own_handles: HashMap<TypeId, TypeId>,
3414
3415    type_has_borrow: Vec<Option<bool>>,
3416}
3417
3418fn apply_map<T>(map: &[Option<Id<T>>], id: Id<T>, desc: &str, span: Span) -> ResolveResult<Id<T>> {
3419    match map.get(id.index()) {
3420        Some(Some(id)) => Ok(*id),
3421        Some(None) => {
3422            let msg = format!(
3423                "found a reference to a {desc} which is excluded \
3424                 due to its feature not being activated"
3425            );
3426            Err(ResolveError::new_semantic(span, msg))
3427        }
3428        None => panic!("request to remap a {desc} that has not yet been registered"),
3429    }
3430}
3431
3432fn rename(original_name: &str, include_name: &IncludeName) -> Option<String> {
3433    if original_name == include_name.name {
3434        return Some(include_name.as_.to_string());
3435    }
3436    let (kind, rest) = original_name.split_once(']')?;
3437    match rest.split_once('.') {
3438        Some((name, rest)) if name == include_name.name => {
3439            Some(format!("{kind}]{}.{rest}", include_name.as_))
3440        }
3441        _ if rest == include_name.name => Some(format!("{kind}]{}", include_name.as_)),
3442        _ => None,
3443    }
3444}
3445
3446impl Remap {
3447    pub fn map_type(&self, id: TypeId, span: Span) -> ResolveResult<TypeId> {
3448        apply_map(&self.types, id, "type", span)
3449    }
3450
3451    pub fn map_interface(&self, id: InterfaceId, span: Span) -> ResolveResult<InterfaceId> {
3452        apply_map(&self.interfaces, id, "interface", span)
3453    }
3454
3455    pub fn map_world(&self, id: WorldId, span: Span) -> ResolveResult<WorldId> {
3456        apply_map(&self.worlds, id, "world", span)
3457    }
3458
3459    pub fn map_world_for_type(&self, id: WorldId, span: Span) -> ResolveResult<WorldId> {
3460        self.map_world(id, span).map_err(|e| {
3461            ResolveError::new_semantic(
3462                span,
3463                format!("{e}; this type is not gated by a feature but its world is"),
3464            )
3465        })
3466    }
3467
3468    pub fn map_interface_for_type(
3469        &self,
3470        id: InterfaceId,
3471        span: Span,
3472    ) -> ResolveResult<InterfaceId> {
3473        self.map_interface(id, span).map_err(|e| {
3474            ResolveError::new_semantic(
3475                span,
3476                format!("{e}; this type is not gated by a feature but its interface is"),
3477            )
3478        })
3479    }
3480
3481    fn append(
3482        &mut self,
3483        resolve: &mut Resolve,
3484        unresolved: UnresolvedPackage,
3485    ) -> ResolveResult<PackageId> {
3486        let pkgid = resolve.packages.alloc(Package {
3487            name: unresolved.name.clone(),
3488            docs: unresolved.docs.clone(),
3489            interfaces: Default::default(),
3490            worlds: Default::default(),
3491        });
3492        assert!(
3493            !resolve.package_names.contains_key(&unresolved.name),
3494            "attempting to re-add package `{}` when it's already present in this `Resolve`",
3495            unresolved.name,
3496        );
3497        resolve.package_names.insert(unresolved.name.clone(), pkgid);
3498        self.process_foreign_deps(resolve, pkgid, &unresolved)?;
3499
3500        let foreign_types = self.types.len();
3501        let foreign_interfaces = self.interfaces.len();
3502        let foreign_worlds = self.worlds.len();
3503
3504        // Copy over all types first, updating any intra-type references. Note
3505        // that types are sorted topologically which means this iteration
3506        // order should be sufficient. Also note though that the interface
3507        // owner of a type isn't updated here due to interfaces not being known
3508        // yet.
3509        for (id, mut ty) in unresolved.types.into_iter().skip(foreign_types) {
3510            let span = ty.span;
3511            if !resolve.include_stability(&ty.stability, &pkgid, span)? {
3512                self.types.push(None);
3513                continue;
3514            }
3515
3516            self.update_typedef(resolve, &mut ty, span)?;
3517            let new_id = resolve.types.alloc(ty);
3518            assert_eq!(self.types.len(), id.index());
3519
3520            let new_id = match resolve.types[new_id] {
3521                // If this is an `own<T>` handle then either replace it with a
3522                // preexisting `own<T>` handle which may have been generated in
3523                // `update_ty`. If that doesn't exist though then insert it into
3524                // the `own_handles` cache.
3525                TypeDef {
3526                    name: None,
3527                    owner: TypeOwner::None,
3528                    kind: TypeDefKind::Handle(Handle::Own(id)),
3529                    docs: _,
3530                    stability: _,
3531                    span: _,
3532                    external_id: _,
3533                } => *self.own_handles.entry(id).or_insert(new_id),
3534
3535                // Everything not-related to `own<T>` doesn't get its ID
3536                // modified.
3537                _ => new_id,
3538            };
3539            self.types.push(Some(new_id));
3540        }
3541
3542        // Next transfer all interfaces into `Resolve`, updating type ids
3543        // referenced along the way.
3544        for (id, mut iface) in unresolved.interfaces.into_iter().skip(foreign_interfaces) {
3545            let span = iface.span;
3546            if !resolve.include_stability(&iface.stability, &pkgid, span)? {
3547                self.interfaces.push(None);
3548                continue;
3549            }
3550            assert!(iface.package.is_none());
3551            iface.package = Some(pkgid);
3552            self.update_interface(resolve, &mut iface)?;
3553            let new_id = resolve.interfaces.alloc(iface);
3554            assert_eq!(self.interfaces.len(), id.index());
3555            self.interfaces.push(Some(new_id));
3556        }
3557
3558        // Now that interfaces are identified go back through the types and
3559        // update their interface owners.
3560        for id in self.types.iter().skip(foreign_types) {
3561            let id = match id {
3562                Some(id) => *id,
3563                None => continue,
3564            };
3565            let span = resolve.types[id].span;
3566            match &mut resolve.types[id].owner {
3567                TypeOwner::Interface(iface_id) => {
3568                    *iface_id = self.map_interface_for_type(*iface_id, span)?;
3569                }
3570                TypeOwner::World(_) | TypeOwner::None => {}
3571            }
3572        }
3573
3574        // Expand worlds. Note that this does NOT process `include` statements,
3575        // that's handled below. Instead this just handles world item updates
3576        // and resolves references to types/items within `Resolve`.
3577        //
3578        // This is done after types/interfaces are fully settled so the
3579        // transitive relation between interfaces, through types, is understood
3580        // here.
3581        for (id, mut world) in unresolved.worlds.into_iter().skip(foreign_worlds) {
3582            let world_span = world.span;
3583            if !resolve.include_stability(&world.stability, &pkgid, world_span)? {
3584                self.worlds.push(None);
3585                continue;
3586            }
3587            self.update_world(&mut world, resolve, &pkgid)?;
3588
3589            let new_id = resolve.worlds.alloc(world);
3590            assert_eq!(self.worlds.len(), id.index());
3591            self.worlds.push(Some(new_id));
3592        }
3593
3594        // As with interfaces, now update the ids of world-owned types.
3595        for id in self.types.iter().skip(foreign_types) {
3596            let id = match id {
3597                Some(id) => *id,
3598                None => continue,
3599            };
3600            let span = resolve.types[id].span;
3601            match &mut resolve.types[id].owner {
3602                TypeOwner::World(world_id) => {
3603                    *world_id = self.map_world_for_type(*world_id, span)?;
3604                }
3605                TypeOwner::Interface(_) | TypeOwner::None => {}
3606            }
3607        }
3608
3609        // After the above, process `include` statements for worlds and
3610        // additionally fully elaborate them. Processing of `include` is
3611        // deferred until after the steps above so the fully resolved state of
3612        // local types in this package are all available. This is required
3613        // because `include` may copy types between worlds when the type is
3614        // defined in the world itself.
3615        //
3616        // This step, after processing `include`, will also use
3617        // `elaborate_world` to fully expand the world in terms of
3618        // imports/exports and ensure that all necessary imports/exports are all
3619        // listed.
3620        //
3621        // Note that `self.worlds` is already sorted in topological order so if
3622        // one world refers to another via `include` then it's guaranteed that
3623        // the one we're referring to is already expanded and ready to be
3624        // included.
3625        for id in self.worlds.iter().skip(foreign_worlds) {
3626            let Some(id) = *id else {
3627                continue;
3628            };
3629            self.process_world_includes(id, resolve, &pkgid)?;
3630
3631            let world_span = resolve.worlds[id].span;
3632            resolve.elaborate_world(id, world_span)?;
3633        }
3634
3635        // Fixup "parent" ids now that everything has been identified
3636        for id in self.interfaces.iter().skip(foreign_interfaces) {
3637            let id = match id {
3638                Some(id) => *id,
3639                None => continue,
3640            };
3641            let iface = &mut resolve.interfaces[id];
3642            iface.package = Some(pkgid);
3643            if let Some(name) = &iface.name {
3644                let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), id);
3645                assert!(prev.is_none());
3646            }
3647        }
3648        for id in self.worlds.iter().skip(foreign_worlds) {
3649            let id = match id {
3650                Some(id) => *id,
3651                None => continue,
3652            };
3653            let world = &mut resolve.worlds[id];
3654            world.package = Some(pkgid);
3655            let prev = resolve.packages[pkgid]
3656                .worlds
3657                .insert(world.name.clone(), id);
3658            assert!(prev.is_none());
3659        }
3660        Ok(pkgid)
3661    }
3662
3663    fn process_foreign_deps(
3664        &mut self,
3665        resolve: &mut Resolve,
3666        pkgid: PackageId,
3667        unresolved: &UnresolvedPackage,
3668    ) -> ResolveResult<()> {
3669        // Invert the `foreign_deps` map to be keyed by world id to get
3670        // used in the loops below.
3671        let mut world_to_package = HashMap::new();
3672        let mut interface_to_package = HashMap::new();
3673        for (i, (pkg_name, worlds_or_ifaces)) in unresolved.foreign_deps.iter().enumerate() {
3674            for (name, (item, stabilities)) in worlds_or_ifaces {
3675                match item {
3676                    AstItem::Interface(unresolved_interface_id) => {
3677                        let prev = interface_to_package.insert(
3678                            *unresolved_interface_id,
3679                            (pkg_name, name, unresolved.foreign_dep_spans[i], stabilities),
3680                        );
3681                        assert!(prev.is_none());
3682                    }
3683                    AstItem::World(unresolved_world_id) => {
3684                        let prev = world_to_package.insert(
3685                            *unresolved_world_id,
3686                            (pkg_name, name, unresolved.foreign_dep_spans[i], stabilities),
3687                        );
3688                        assert!(prev.is_none());
3689                    }
3690                }
3691            }
3692        }
3693
3694        // Connect all interfaces referred to in `interface_to_package`, which
3695        // are at the front of `unresolved.interfaces`, to interfaces already
3696        // contained within `resolve`.
3697        self.process_foreign_interfaces(unresolved, &interface_to_package, resolve, &pkgid)?;
3698
3699        // Connect all worlds referred to in `world_to_package`, which
3700        // are at the front of `unresolved.worlds`, to worlds already
3701        // contained within `resolve`.
3702        self.process_foreign_worlds(unresolved, &world_to_package, resolve, &pkgid)?;
3703
3704        // Finally, iterate over all foreign-defined types and determine
3705        // what they map to.
3706        self.process_foreign_types(unresolved, pkgid, resolve)?;
3707
3708        for (id, span) in unresolved.required_resource_types.iter() {
3709            // Note that errors are ignored here because an error represents a
3710            // type that has been configured away. If a type is configured away
3711            // then any future use of it will generate an error so there's no
3712            // need to validate that it's a resource here.
3713            let Ok(mut id) = self.map_type(*id, *span) else {
3714                continue;
3715            };
3716            loop {
3717                match resolve.types[id].kind {
3718                    TypeDefKind::Type(Type::Id(i)) => id = i,
3719                    TypeDefKind::Resource => break,
3720                    _ => {
3721                        return Err(ResolveError::new_semantic(
3722                            *span,
3723                            "type used in a handle must be a resource",
3724                        ));
3725                    }
3726                }
3727            }
3728        }
3729
3730        #[cfg(debug_assertions)]
3731        resolve.assert_valid();
3732
3733        Ok(())
3734    }
3735
3736    fn process_foreign_interfaces(
3737        &mut self,
3738        unresolved: &UnresolvedPackage,
3739        interface_to_package: &HashMap<InterfaceId, (&PackageName, &String, Span, &Vec<Stability>)>,
3740        resolve: &mut Resolve,
3741        parent_pkg_id: &PackageId,
3742    ) -> ResolveResult<()> {
3743        for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() {
3744            let (pkg_name, interface, span, stabilities) =
3745                match interface_to_package.get(&unresolved_iface_id) {
3746                    Some(items) => *items,
3747                    // All foreign interfaces are defined first, so the first one
3748                    // which is defined in a non-foreign document means that all
3749                    // further interfaces will be non-foreign as well.
3750                    None => break,
3751                };
3752
3753            let pkgid = resolve
3754                .package_names
3755                .get(pkg_name)
3756                .copied()
3757                .ok_or_else(|| {
3758                    ResolveError::from(ResolveErrorKind::PackageNotFound {
3759                        span,
3760                        requested: pkg_name.clone(),
3761                        known: resolve.package_names.keys().cloned().collect(),
3762                    })
3763                })?;
3764
3765            // Functions can't be imported so this should be empty.
3766            assert!(unresolved_iface.functions.is_empty());
3767
3768            let pkg = &resolve.packages[pkgid];
3769            let iface_span = unresolved_iface.span;
3770
3771            let mut enabled = false;
3772            for stability in stabilities {
3773                if resolve.include_stability(stability, parent_pkg_id, iface_span)? {
3774                    enabled = true;
3775                    break;
3776                }
3777            }
3778
3779            if !enabled {
3780                self.interfaces.push(None);
3781                continue;
3782            }
3783
3784            let iface_id = pkg.interfaces.get(interface).copied().ok_or_else(|| {
3785                ResolveError::new_semantic(iface_span, "interface not found in package")
3786            })?;
3787            assert_eq!(self.interfaces.len(), unresolved_iface_id.index());
3788            self.interfaces.push(Some(iface_id));
3789        }
3790        for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) {
3791            assert!(
3792                interface_to_package.get(&id).is_none(),
3793                "found foreign interface after local interface"
3794            );
3795        }
3796        Ok(())
3797    }
3798
3799    fn process_foreign_worlds(
3800        &mut self,
3801        unresolved: &UnresolvedPackage,
3802        world_to_package: &HashMap<WorldId, (&PackageName, &String, Span, &Vec<Stability>)>,
3803        resolve: &mut Resolve,
3804        parent_pkg_id: &PackageId,
3805    ) -> ResolveResult<()> {
3806        for (unresolved_world_id, unresolved_world) in unresolved.worlds.iter() {
3807            let (pkg_name, world, span, stabilities) =
3808                match world_to_package.get(&unresolved_world_id) {
3809                    Some(items) => *items,
3810                    // Same as above, all worlds are foreign until we find a
3811                    // non-foreign one.
3812                    None => break,
3813                };
3814
3815            let pkgid = resolve
3816                .package_names
3817                .get(pkg_name)
3818                .copied()
3819                .ok_or_else(|| {
3820                    ResolveError::from(ResolveErrorKind::PackageNotFound {
3821                        span,
3822                        requested: pkg_name.clone(),
3823                        known: resolve.package_names.keys().cloned().collect(),
3824                    })
3825                })?;
3826            let pkg = &resolve.packages[pkgid];
3827            let world_span = unresolved_world.span;
3828
3829            let mut enabled = false;
3830            for stability in stabilities {
3831                if resolve.include_stability(stability, parent_pkg_id, world_span)? {
3832                    enabled = true;
3833                    break;
3834                }
3835            }
3836
3837            if !enabled {
3838                self.worlds.push(None);
3839                continue;
3840            }
3841
3842            let world_id = pkg.worlds.get(world).copied().ok_or_else(|| {
3843                ResolveError::new_semantic(world_span, "world not found in package")
3844            })?;
3845            assert_eq!(self.worlds.len(), unresolved_world_id.index());
3846            self.worlds.push(Some(world_id));
3847        }
3848        for (id, _) in unresolved.worlds.iter().skip(self.worlds.len()) {
3849            assert!(
3850                world_to_package.get(&id).is_none(),
3851                "found foreign world after local world"
3852            );
3853        }
3854        Ok(())
3855    }
3856
3857    fn process_foreign_types(
3858        &mut self,
3859        unresolved: &UnresolvedPackage,
3860        pkgid: PackageId,
3861        resolve: &mut Resolve,
3862    ) -> ResolveResult<()> {
3863        for (unresolved_type_id, unresolved_ty) in unresolved.types.iter() {
3864            // All "Unknown" types should appear first so once we're no longer
3865            // in unknown territory it's package-defined types so break out of
3866            // this loop.
3867            match unresolved_ty.kind {
3868                TypeDefKind::Unknown => {}
3869                _ => break,
3870            }
3871
3872            let span = unresolved_ty.span;
3873            if !resolve.include_stability(&unresolved_ty.stability, &pkgid, span)? {
3874                self.types.push(None);
3875                continue;
3876            }
3877
3878            let unresolved_iface_id = match unresolved_ty.owner {
3879                TypeOwner::Interface(id) => id,
3880                _ => unreachable!(),
3881            };
3882            let iface_id = self.map_interface(unresolved_iface_id, Default::default())?;
3883            let name = unresolved_ty.name.as_ref().unwrap();
3884            let span = unresolved.unknown_type_spans[unresolved_type_id.index()];
3885            let type_id = *resolve.interfaces[iface_id]
3886                .types
3887                .get(name)
3888                .ok_or_else(|| {
3889                    ResolveError::new_semantic(
3890                        span,
3891                        format!("type `{name}` not defined in interface"),
3892                    )
3893                })?;
3894            assert_eq!(self.types.len(), unresolved_type_id.index());
3895            self.types.push(Some(type_id));
3896        }
3897        for (_, ty) in unresolved.types.iter().skip(self.types.len()) {
3898            if let TypeDefKind::Unknown = ty.kind {
3899                panic!("unknown type after defined type");
3900            }
3901        }
3902        Ok(())
3903    }
3904
3905    fn update_typedef(
3906        &mut self,
3907        resolve: &mut Resolve,
3908        ty: &mut TypeDef,
3909        span: Span,
3910    ) -> ResolveResult<()> {
3911        // NB: note that `ty.owner` is not updated here since interfaces
3912        // haven't been mapped yet and that's done in a separate step.
3913        use crate::TypeDefKind::*;
3914        match &mut ty.kind {
3915            Handle(handle) => match handle {
3916                crate::Handle::Own(ty) | crate::Handle::Borrow(ty) => {
3917                    self.update_type_id(ty, span)?
3918                }
3919            },
3920            Resource => {}
3921            Record(r) => {
3922                for field in r.fields.iter_mut() {
3923                    self.update_ty(resolve, &mut field.ty, field.span)?
3924                }
3925            }
3926            Tuple(t) => {
3927                for ty in t.types.iter_mut() {
3928                    self.update_ty(resolve, ty, span)?;
3929                }
3930            }
3931            Variant(v) => {
3932                for case in v.cases.iter_mut() {
3933                    if let Some(t) = &mut case.ty {
3934                        self.update_ty(resolve, t, span)?;
3935                    }
3936                }
3937            }
3938            Option(t)
3939            | List(t, ..)
3940            | FixedLengthList(t, ..)
3941            | Future(Some(t))
3942            | Stream(Some(t)) => self.update_ty(resolve, t, span)?,
3943            Map(k, v) => {
3944                self.update_ty(resolve, k, span)?;
3945                self.update_ty(resolve, v, span)?;
3946            }
3947            Result(r) => {
3948                if let Some(ty) = &mut r.ok {
3949                    self.update_ty(resolve, ty, span)?;
3950                }
3951                if let Some(ty) = &mut r.err {
3952                    self.update_ty(resolve, ty, span)?;
3953                }
3954            }
3955
3956            // Note that `update_ty` is specifically not used here as typedefs
3957            // because for the `type a = b` form that doesn't force `a` to be a
3958            // handle type if `b` is a resource type, instead `a` is
3959            // simultaneously usable as a resource and a handle type
3960            Type(crate::Type::Id(id)) => self.update_type_id(id, span)?,
3961            Type(_) => {}
3962
3963            // nothing to do for these as they're just names or empty
3964            Flags(_) | Enum(_) | Future(None) | Stream(None) => {}
3965
3966            Unknown => unreachable!(),
3967        }
3968
3969        Ok(())
3970    }
3971
3972    fn update_ty(&mut self, resolve: &mut Resolve, ty: &mut Type, span: Span) -> ResolveResult<()> {
3973        let id = match ty {
3974            Type::Id(id) => id,
3975            _ => return Ok(()),
3976        };
3977        self.update_type_id(id, span)?;
3978
3979        // If `id` points to a `Resource` type then this means that what was
3980        // just discovered was a reference to what will implicitly become an
3981        // `own<T>` handle. This `own` handle is implicitly allocated here
3982        // and handled during the merging process.
3983        let mut cur = *id;
3984        let points_to_resource = loop {
3985            match resolve.types[cur].kind {
3986                TypeDefKind::Type(Type::Id(id)) => cur = id,
3987                TypeDefKind::Resource => break true,
3988                _ => break false,
3989            }
3990        };
3991
3992        if points_to_resource {
3993            *id = *self.own_handles.entry(*id).or_insert_with(|| {
3994                resolve.types.alloc(TypeDef {
3995                    name: None,
3996                    owner: TypeOwner::None,
3997                    kind: TypeDefKind::Handle(Handle::Own(*id)),
3998                    docs: Default::default(),
3999                    stability: Default::default(),
4000                    span: Default::default(),
4001                    external_id: None,
4002                })
4003            });
4004        }
4005        Ok(())
4006    }
4007
4008    fn update_type_id(&self, id: &mut TypeId, span: Span) -> ResolveResult<()> {
4009        *id = self.map_type(*id, span)?;
4010        Ok(())
4011    }
4012
4013    fn update_interface(
4014        &mut self,
4015        resolve: &mut Resolve,
4016        iface: &mut Interface,
4017    ) -> ResolveResult<()> {
4018        iface.types.retain(|_, ty| self.types[ty.index()].is_some());
4019        let iface_pkg_id = iface.package.as_ref().unwrap_or_else(|| {
4020            panic!(
4021                "unexpectedly missing package on interface [{}]",
4022                iface
4023                    .name
4024                    .as_ref()
4025                    .map(String::as_str)
4026                    .unwrap_or("<unknown>"),
4027            )
4028        });
4029
4030        // NB: note that `iface.doc` is not updated here since interfaces
4031        // haven't been mapped yet and that's done in a separate step.
4032        for (_name, ty) in iface.types.iter_mut() {
4033            self.update_type_id(ty, iface.span)?;
4034        }
4035        for (_, func) in iface.functions.iter_mut() {
4036            let span = func.span;
4037            if !resolve.include_stability(&func.stability, iface_pkg_id, span)? {
4038                continue;
4039            }
4040            self.update_function(resolve, func, span)?
4041        }
4042
4043        // Filter out all of the existing functions in interface which fail the
4044        // `include_stability()` check, as they shouldn't be available.
4045        for (name, func) in mem::take(&mut iface.functions) {
4046            if resolve.include_stability(&func.stability, iface_pkg_id, func.span)? {
4047                iface.functions.insert(name, func);
4048            }
4049        }
4050
4051        Ok(())
4052    }
4053
4054    fn update_function(
4055        &mut self,
4056        resolve: &mut Resolve,
4057        func: &mut Function,
4058        span: Span,
4059    ) -> ResolveResult<()> {
4060        if let Some(id) = func.kind.resource_mut() {
4061            self.update_type_id(id, span)?;
4062        }
4063        for param in func.params.iter_mut() {
4064            self.update_ty(resolve, &mut param.ty, span)?;
4065        }
4066        if let Some(ty) = &mut func.result {
4067            self.update_ty(resolve, ty, span)?;
4068        }
4069
4070        if let Some(ty) = &func.result {
4071            if self.type_has_borrow(resolve, ty) {
4072                return Err(ResolveError::new_semantic(
4073                    span,
4074                    format!(
4075                        "function `{}` returns a type which contains a `borrow<T>` which is not supported",
4076                        func.name,
4077                    ),
4078                ));
4079            }
4080        }
4081
4082        Ok(())
4083    }
4084
4085    fn update_world(
4086        &mut self,
4087        world: &mut World,
4088        resolve: &mut Resolve,
4089        pkg_id: &PackageId,
4090    ) -> ResolveResult<()> {
4091        // Rewrite imports/exports with their updated versions. Note that this
4092        // may involve updating the key of the imports/exports maps so this
4093        // starts by emptying them out and then everything is re-inserted.
4094        let imports = mem::take(&mut world.imports).into_iter().map(|p| (p, true));
4095        let exports = mem::take(&mut world.exports)
4096            .into_iter()
4097            .map(|p| (p, false));
4098        for ((mut name, mut item), import) in imports.chain(exports) {
4099            let span = item.span();
4100            // Update the `id` eagerly here so `item.stability(..)` below
4101            // works.
4102            if let WorldItem::Type { id, .. } = &mut item {
4103                *id = self.map_type(*id, span)?;
4104            }
4105            let stability = item.stability(resolve);
4106            if !resolve.include_stability(stability, pkg_id, span)? {
4107                continue;
4108            }
4109            self.update_world_key(&mut name, span)?;
4110            match &mut item {
4111                WorldItem::Interface { id, .. } => {
4112                    *id = self.map_interface(*id, span)?;
4113                }
4114                WorldItem::Function(f) => {
4115                    self.update_function(resolve, f, span)?;
4116                }
4117                WorldItem::Type { .. } => {
4118                    // already mapped above
4119                }
4120            }
4121
4122            let dst = if import {
4123                &mut world.imports
4124            } else {
4125                &mut world.exports
4126            };
4127            let prev = dst.insert(name, item);
4128            assert!(prev.is_none());
4129        }
4130
4131        Ok(())
4132    }
4133
4134    fn process_world_includes(
4135        &self,
4136        id: WorldId,
4137        resolve: &mut Resolve,
4138        pkg_id: &PackageId,
4139    ) -> ResolveResult<()> {
4140        let world = &mut resolve.worlds[id];
4141        // Resolve all `include` statements of the world which will add more
4142        // entries to the imports/exports list for this world.
4143        let includes = mem::take(&mut world.includes);
4144        for include in includes {
4145            if !resolve.include_stability(&include.stability, pkg_id, include.span)? {
4146                continue;
4147            }
4148            self.resolve_include(
4149                id,
4150                include.id,
4151                &include.names,
4152                include.span,
4153                pkg_id,
4154                resolve,
4155            )?;
4156        }
4157
4158        // Validate that there are no case-insensitive duplicate names in imports/exports
4159        Self::validate_world_case_insensitive_names(resolve, id)?;
4160
4161        Ok(())
4162    }
4163
4164    /// Validates that a world's imports and exports don't have case-insensitive
4165    /// duplicate names. Per the WIT specification, kebab-case identifiers are
4166    /// case-insensitive within the same scope.
4167    fn validate_world_case_insensitive_names(
4168        resolve: &Resolve,
4169        world_id: WorldId,
4170    ) -> ResolveResult<()> {
4171        let world = &resolve.worlds[world_id];
4172
4173        // Helper closure to check for case-insensitive duplicates in a map
4174        let validate_names =
4175            |items: &IndexMap<WorldKey, WorldItem>, item_type: &str| -> ResolveResult<()> {
4176                let mut seen_lowercase: HashMap<String, String> = HashMap::new();
4177
4178                for key in items.keys() {
4179                    // Only WorldKey::Name variants can have case-insensitive conflicts
4180                    if let WorldKey::Name(name) = key {
4181                        let lowercase_name = name.to_lowercase();
4182
4183                        if let Some(existing_name) = seen_lowercase.get(&lowercase_name) {
4184                            // Only error on case-insensitive duplicates (e.g., "foo" vs "FOO").
4185                            // Exact duplicates would have been caught earlier.
4186                            if existing_name != name {
4187                                // TODO: `WorldKey::Name` does not carry a `Span`, so we
4188                                // cannot point at the conflicting item. Add a span to
4189                                // `WorldKey::Name` to improve this error.
4190                                return Err(ResolveError::new_semantic(
4191                                    Span::default(),
4192                                    format!(
4193                                        "{item_type} `{name}` in world `{}` conflicts with \
4194                                     {item_type} `{existing_name}` \
4195                                     (kebab-case identifiers are case-insensitive)",
4196                                        world.name,
4197                                    ),
4198                                ));
4199                            }
4200                        }
4201
4202                        seen_lowercase.insert(lowercase_name, name.clone());
4203                    }
4204                }
4205
4206                Ok(())
4207            };
4208
4209        validate_names(&world.imports, "import")?;
4210        validate_names(&world.exports, "export")?;
4211
4212        Ok(())
4213    }
4214
4215    fn update_world_key(&self, key: &mut WorldKey, span: Span) -> ResolveResult<()> {
4216        match key {
4217            WorldKey::Name(_) => {}
4218            WorldKey::Interface(id) => {
4219                *id = self.map_interface(*id, span)?;
4220            }
4221        }
4222        Ok(())
4223    }
4224
4225    fn resolve_include(
4226        &self,
4227        id: WorldId,
4228        include_world_id_orig: WorldId,
4229        names: &[IncludeName],
4230        span: Span,
4231        pkg_id: &PackageId,
4232        resolve: &mut Resolve,
4233    ) -> ResolveResult<()> {
4234        let world = &resolve.worlds[id];
4235        let include_world_id = self.map_world(include_world_id_orig, span)?;
4236        let include_world = resolve.worlds[include_world_id].clone();
4237        let mut names_ = names.to_owned();
4238        let is_external_include = world.package != include_world.package;
4239
4240        // remove all imports and exports that match the names we're including
4241        for import in include_world.imports.iter() {
4242            self.remove_matching_name(import, &mut names_);
4243        }
4244        for export in include_world.exports.iter() {
4245            self.remove_matching_name(export, &mut names_);
4246        }
4247        if !names_.is_empty() {
4248            return Err(ResolveError::new_semantic(
4249                span,
4250                format!(
4251                    "no import or export kebab-name `{}`. Note that an ID does not support renaming",
4252                    names_[0].name
4253                ),
4254            ));
4255        }
4256
4257        let mut maps = Default::default();
4258        let mut cloner = clone::Cloner::new(
4259            resolve,
4260            &mut maps,
4261            TypeOwner::World(if is_external_include {
4262                include_world_id
4263            } else {
4264                include_world_id
4265                // include_world_id_orig
4266            }),
4267            TypeOwner::World(id),
4268        );
4269        cloner.new_package = Some(*pkg_id);
4270
4271        // copy the imports and exports from the included world into the current world
4272        for import in include_world.imports.iter() {
4273            self.resolve_include_item(
4274                &mut cloner,
4275                names,
4276                |resolve| &mut resolve.worlds[id].imports,
4277                import,
4278                span,
4279                "import",
4280                is_external_include,
4281            )?;
4282        }
4283
4284        for export in include_world.exports.iter() {
4285            self.resolve_include_item(
4286                &mut cloner,
4287                names,
4288                |resolve| &mut resolve.worlds[id].exports,
4289                export,
4290                span,
4291                "export",
4292                is_external_include,
4293            )?;
4294        }
4295        Ok(())
4296    }
4297
4298    fn resolve_include_item(
4299        &self,
4300        cloner: &mut clone::Cloner<'_>,
4301        names: &[IncludeName],
4302        get_items: impl Fn(&mut Resolve) -> &mut IndexMap<WorldKey, WorldItem>,
4303        item: (&WorldKey, &WorldItem),
4304        span: Span,
4305        item_type: &str,
4306        is_external_include: bool,
4307    ) -> ResolveResult<()> {
4308        match item.0 {
4309            WorldKey::Name(n) => {
4310                let n = names
4311                    .into_iter()
4312                    .find_map(|include_name| rename(n, include_name))
4313                    .unwrap_or(n.clone());
4314
4315                // When the `with` option to the `include` directive is
4316                // specified and is used to rename a function that means that
4317                // the function's own original name needs to be updated, so
4318                // reflect the change not only in the world key but additionally
4319                // in the function itself.
4320                let mut new_item = item.1.clone();
4321                let key = WorldKey::Name(n.clone());
4322                cloner.world_item(&key, &mut new_item);
4323                match &mut new_item {
4324                    WorldItem::Function(f) => f.name = n.clone(),
4325                    WorldItem::Type { id, .. } => cloner.resolve.types[*id].name = Some(n.clone()),
4326                    WorldItem::Interface { .. } => {}
4327                }
4328
4329                let prev = get_items(cloner.resolve).insert(key, new_item);
4330                if prev.is_some() {
4331                    return Err(ResolveError::from(ResolveErrorKind::ItemShadowing {
4332                        span,
4333                        item_type: item_type.to_owned(),
4334                        name: n,
4335                    }));
4336                }
4337            }
4338            key @ WorldKey::Interface(_) => {
4339                let prev = get_items(cloner.resolve)
4340                    .entry(key.clone())
4341                    .or_insert(item.1.clone());
4342                match (&item.1, prev) {
4343                    (
4344                        WorldItem::Interface {
4345                            id: aid,
4346                            stability: astability,
4347                            span: aspan,
4348                            ..
4349                        },
4350                        WorldItem::Interface {
4351                            id: bid,
4352                            stability: bstability,
4353                            ..
4354                        },
4355                    ) => {
4356                        assert_eq!(*aid, *bid);
4357                        merge_include_stability(
4358                            astability,
4359                            bstability,
4360                            is_external_include,
4361                            *aspan,
4362                        )?;
4363                    }
4364                    (WorldItem::Interface { .. }, _) => unreachable!(),
4365                    (WorldItem::Function(_), _) => unreachable!(),
4366                    (WorldItem::Type { .. }, _) => unreachable!(),
4367                }
4368            }
4369        };
4370
4371        Ok(())
4372    }
4373
4374    fn remove_matching_name(&self, item: (&WorldKey, &WorldItem), names: &mut Vec<IncludeName>) {
4375        match item.0 {
4376            WorldKey::Name(n) => {
4377                names.retain(|name| rename(n, name).is_none());
4378            }
4379            _ => {}
4380        }
4381    }
4382
4383    fn type_has_borrow(&mut self, resolve: &Resolve, ty: &Type) -> bool {
4384        let id = match ty {
4385            Type::Id(id) => *id,
4386            _ => return false,
4387        };
4388
4389        if let Some(Some(has_borrow)) = self.type_has_borrow.get(id.index()) {
4390            return *has_borrow;
4391        }
4392
4393        let result = self.typedef_has_borrow(resolve, &resolve.types[id]);
4394        if self.type_has_borrow.len() <= id.index() {
4395            self.type_has_borrow.resize(id.index() + 1, None);
4396        }
4397        self.type_has_borrow[id.index()] = Some(result);
4398        result
4399    }
4400
4401    fn typedef_has_borrow(&mut self, resolve: &Resolve, ty: &TypeDef) -> bool {
4402        match &ty.kind {
4403            TypeDefKind::Type(t) => self.type_has_borrow(resolve, t),
4404            TypeDefKind::Variant(v) => v
4405                .cases
4406                .iter()
4407                .filter_map(|case| case.ty.as_ref())
4408                .any(|ty| self.type_has_borrow(resolve, ty)),
4409            TypeDefKind::Handle(Handle::Borrow(_)) => true,
4410            TypeDefKind::Handle(Handle::Own(_)) => false,
4411            TypeDefKind::Resource => false,
4412            TypeDefKind::Record(r) => r
4413                .fields
4414                .iter()
4415                .any(|case| self.type_has_borrow(resolve, &case.ty)),
4416            TypeDefKind::Flags(_) => false,
4417            TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.type_has_borrow(resolve, t)),
4418            TypeDefKind::Enum(_) => false,
4419            TypeDefKind::List(ty)
4420            | TypeDefKind::FixedLengthList(ty, ..)
4421            | TypeDefKind::Future(Some(ty))
4422            | TypeDefKind::Stream(Some(ty))
4423            | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty),
4424            TypeDefKind::Map(k, v) => {
4425                self.type_has_borrow(resolve, k) || self.type_has_borrow(resolve, v)
4426            }
4427            TypeDefKind::Result(r) => [&r.ok, &r.err]
4428                .iter()
4429                .filter_map(|t| t.as_ref())
4430                .any(|t| self.type_has_borrow(resolve, t)),
4431            TypeDefKind::Future(None) | TypeDefKind::Stream(None) => false,
4432            TypeDefKind::Unknown => unreachable!(),
4433        }
4434    }
4435}
4436
4437struct MergeMap<'a> {
4438    /// A map of package ids in `from` to those in `into` for those that are
4439    /// found to be equivalent.
4440    package_map: HashMap<PackageId, PackageId>,
4441
4442    /// A map of interface ids in `from` to those in `into` for those that are
4443    /// found to be equivalent.
4444    interface_map: HashMap<InterfaceId, InterfaceId>,
4445
4446    /// A map of type ids in `from` to those in `into` for those that are
4447    /// found to be equivalent.
4448    type_map: HashMap<TypeId, TypeId>,
4449
4450    /// A map of world ids in `from` to those in `into` for those that are
4451    /// found to be equivalent.
4452    world_map: HashMap<WorldId, WorldId>,
4453
4454    /// A list of documents that need to be added to packages in `into`.
4455    ///
4456    /// The elements here are:
4457    ///
4458    /// * The name of the interface/world
4459    /// * The ID within `into` of the package being added to
4460    /// * The ID within `from` of the item being added.
4461    interfaces_to_add: Vec<(String, PackageId, InterfaceId)>,
4462    worlds_to_add: Vec<(String, PackageId, WorldId)>,
4463
4464    /// Which `Resolve` is being merged from.
4465    from: &'a Resolve,
4466
4467    /// Which `Resolve` is being merged into.
4468    into: &'a Resolve,
4469}
4470
4471impl<'a> MergeMap<'a> {
4472    fn new(from: &'a Resolve, into: &'a Resolve) -> MergeMap<'a> {
4473        MergeMap {
4474            package_map: Default::default(),
4475            interface_map: Default::default(),
4476            type_map: Default::default(),
4477            world_map: Default::default(),
4478            interfaces_to_add: Default::default(),
4479            worlds_to_add: Default::default(),
4480            from,
4481            into,
4482        }
4483    }
4484
4485    fn build(&mut self) -> anyhow::Result<()> {
4486        for from_id in self.from.topological_packages() {
4487            let from = &self.from.packages[from_id];
4488            let into_id = match self.into.package_names.get(&from.name) {
4489                Some(id) => *id,
4490
4491                // This package, according to its name and url, is not present
4492                // in `self` so it needs to get added below.
4493                None => {
4494                    log::trace!("adding unique package {}", from.name);
4495                    continue;
4496                }
4497            };
4498            log::trace!("merging duplicate package {}", from.name);
4499
4500            self.build_package(from_id, into_id).with_context(|| {
4501                format!("failed to merge package `{}` into existing copy", from.name)
4502            })?;
4503        }
4504
4505        Ok(())
4506    }
4507
4508    fn build_package(&mut self, from_id: PackageId, into_id: PackageId) -> anyhow::Result<()> {
4509        let prev = self.package_map.insert(from_id, into_id);
4510        assert!(prev.is_none());
4511
4512        let from = &self.from.packages[from_id];
4513        let into = &self.into.packages[into_id];
4514
4515        // If an interface is present in `from_id` but not present in `into_id`
4516        // then it can be copied over wholesale. That copy is scheduled to
4517        // happen within the `self.interfaces_to_add` list.
4518        for (name, from_interface_id) in from.interfaces.iter() {
4519            let into_interface_id = match into.interfaces.get(name) {
4520                Some(id) => *id,
4521                None => {
4522                    log::trace!("adding unique interface {name}");
4523                    self.interfaces_to_add
4524                        .push((name.clone(), into_id, *from_interface_id));
4525                    continue;
4526                }
4527            };
4528
4529            log::trace!("merging duplicate interfaces {name}");
4530            self.build_interface(*from_interface_id, into_interface_id)
4531                .with_context(|| format!("failed to merge interface `{name}`"))?;
4532        }
4533
4534        for (name, from_world_id) in from.worlds.iter() {
4535            let into_world_id = match into.worlds.get(name) {
4536                Some(id) => *id,
4537                None => {
4538                    log::trace!("adding unique world {name}");
4539                    self.worlds_to_add
4540                        .push((name.clone(), into_id, *from_world_id));
4541                    continue;
4542                }
4543            };
4544
4545            log::trace!("merging duplicate worlds {name}");
4546            self.build_world(*from_world_id, into_world_id)
4547                .with_context(|| format!("failed to merge world `{name}`"))?;
4548        }
4549
4550        Ok(())
4551    }
4552
4553    fn build_interface(
4554        &mut self,
4555        from_id: InterfaceId,
4556        into_id: InterfaceId,
4557    ) -> anyhow::Result<()> {
4558        let prev = self.interface_map.insert(from_id, into_id);
4559        assert!(prev.is_none());
4560
4561        let from_interface = &self.from.interfaces[from_id];
4562        let into_interface = &self.into.interfaces[into_id];
4563
4564        // When merging interfaces, types and functions that exist in both
4565        // `from` and `into` must match structurally. Either side is allowed
4566        // to have extra types or functions not present in the other, which
4567        // enables commutative merging of partial views of the same
4568        // interface. The only requirement is that the intersection of the
4569        // two interfaces is compatible.
4570
4571        for (name, from_type_id) in from_interface.types.iter() {
4572            let into_type_id = match into_interface.types.get(name) {
4573                Some(id) => *id,
4574                // Extra type in `from` not present in `into`; it will be
4575                // moved as a new type and added to the interface later.
4576                None => continue,
4577            };
4578            let prev = self.type_map.insert(*from_type_id, into_type_id);
4579            assert!(prev.is_none());
4580
4581            self.build_type_id(*from_type_id, into_type_id)
4582                .with_context(|| format!("mismatch in type `{name}`"))?;
4583        }
4584
4585        for (name, from_func) in from_interface.functions.iter() {
4586            let into_func = match into_interface.functions.get(name) {
4587                Some(func) => func,
4588                // Extra function in `from` not present in `into`; it will
4589                // be added to the interface during the merge phase.
4590                None => continue,
4591            };
4592            self.build_function(from_func, into_func)
4593                .with_context(|| format!("mismatch in function `{name}`"))?;
4594        }
4595
4596        Ok(())
4597    }
4598
4599    fn build_type_id(&mut self, from_id: TypeId, into_id: TypeId) -> anyhow::Result<()> {
4600        // FIXME: ideally the types should be "structurally
4601        // equal" but that's not trivial to do in the face of
4602        // resources.
4603        let _ = from_id;
4604        let _ = into_id;
4605        Ok(())
4606    }
4607
4608    fn build_type(&mut self, from_ty: &Type, into_ty: &Type) -> anyhow::Result<()> {
4609        match (from_ty, into_ty) {
4610            (Type::Id(from), Type::Id(into)) => {
4611                self.build_type_id(*from, *into)?;
4612            }
4613            (from, into) if from != into => bail!("different kinds of types"),
4614            _ => {}
4615        }
4616        Ok(())
4617    }
4618
4619    fn build_function(&mut self, from_func: &Function, into_func: &Function) -> anyhow::Result<()> {
4620        if from_func.name != into_func.name {
4621            bail!(
4622                "different function names `{}` and `{}`",
4623                from_func.name,
4624                into_func.name
4625            );
4626        }
4627        match (&from_func.kind, &into_func.kind) {
4628            (FunctionKind::Freestanding, FunctionKind::Freestanding) => {}
4629            (FunctionKind::AsyncFreestanding, FunctionKind::AsyncFreestanding) => {}
4630
4631            (FunctionKind::Method(from), FunctionKind::Method(into))
4632            | (FunctionKind::Static(from), FunctionKind::Static(into))
4633            | (FunctionKind::AsyncMethod(from), FunctionKind::AsyncMethod(into))
4634            | (FunctionKind::AsyncStatic(from), FunctionKind::AsyncStatic(into))
4635            | (FunctionKind::Constructor(from), FunctionKind::Constructor(into)) => {
4636                self.build_type_id(*from, *into)
4637                    .context("different function kind types")?;
4638            }
4639
4640            (FunctionKind::Method(_), _)
4641            | (FunctionKind::Constructor(_), _)
4642            | (FunctionKind::Static(_), _)
4643            | (FunctionKind::Freestanding, _)
4644            | (FunctionKind::AsyncFreestanding, _)
4645            | (FunctionKind::AsyncMethod(_), _)
4646            | (FunctionKind::AsyncStatic(_), _) => {
4647                bail!("different function kind types")
4648            }
4649        }
4650
4651        if from_func.params.len() != into_func.params.len() {
4652            bail!("different number of function parameters");
4653        }
4654        for (from_param, into_param) in from_func.params.iter().zip(&into_func.params) {
4655            if from_param.name != into_param.name {
4656                bail!(
4657                    "different function parameter names: {} != {}",
4658                    from_param.name,
4659                    into_param.name
4660                );
4661            }
4662            self.build_type(&from_param.ty, &into_param.ty)
4663                .with_context(|| {
4664                    format!(
4665                        "different function parameter types for `{}`",
4666                        from_param.name
4667                    )
4668                })?;
4669        }
4670        match (&from_func.result, &into_func.result) {
4671            (Some(from_ty), Some(into_ty)) => {
4672                self.build_type(from_ty, into_ty)
4673                    .context("different function result types")?;
4674            }
4675            (None, None) => {}
4676            (Some(_), None) | (None, Some(_)) => bail!("different number of function results"),
4677        }
4678        Ok(())
4679    }
4680
4681    fn build_world(&mut self, from_id: WorldId, into_id: WorldId) -> anyhow::Result<()> {
4682        let prev = self.world_map.insert(from_id, into_id);
4683        assert!(prev.is_none());
4684
4685        let from_world = &self.from.worlds[from_id];
4686        let into_world = &self.into.worlds[into_id];
4687
4688        // Same as interfaces worlds are expected to exactly match to avoid
4689        // unexpectedly changing a particular component's view of imports and
4690        // exports.
4691        //
4692        // FIXME: this should probably share functionality with
4693        // `Resolve::merge_worlds` to support adding imports but not changing
4694        // exports.
4695
4696        if from_world.imports.len() != into_world.imports.len() {
4697            bail!("world contains different number of imports than expected");
4698        }
4699        if from_world.exports.len() != into_world.exports.len() {
4700            bail!("world contains different number of exports than expected");
4701        }
4702
4703        for (from_name, from) in from_world.imports.iter() {
4704            let into_name = MergeMap::map_name(from_name, &self.interface_map);
4705            let name_str = self.from.name_world_key(from_name);
4706            let into = into_world
4707                .imports
4708                .get(&into_name)
4709                .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?;
4710            self.match_world_item(from, into)
4711                .with_context(|| format!("import `{name_str}` didn't match target world"))?;
4712        }
4713
4714        for (from_name, from) in from_world.exports.iter() {
4715            let into_name = MergeMap::map_name(from_name, &self.interface_map);
4716            let name_str = self.from.name_world_key(from_name);
4717            let into = into_world
4718                .exports
4719                .get(&into_name)
4720                .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?;
4721            self.match_world_item(from, into)
4722                .with_context(|| format!("export `{name_str}` didn't match target world"))?;
4723        }
4724
4725        Ok(())
4726    }
4727
4728    fn map_name(
4729        from_name: &WorldKey,
4730        interface_map: &HashMap<InterfaceId, InterfaceId>,
4731    ) -> WorldKey {
4732        match from_name {
4733            WorldKey::Name(s) => WorldKey::Name(s.clone()),
4734            WorldKey::Interface(id) => {
4735                WorldKey::Interface(interface_map.get(id).copied().unwrap_or(*id))
4736            }
4737        }
4738    }
4739
4740    fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> anyhow::Result<()> {
4741        match (from, into) {
4742            (WorldItem::Interface { id: from, .. }, WorldItem::Interface { id: into, .. }) => {
4743                match (
4744                    &self.from.interfaces[*from].name,
4745                    &self.into.interfaces[*into].name,
4746                ) {
4747                    // If one interface is unnamed then they must both be
4748                    // unnamed and they must both have the same structure for
4749                    // now.
4750                    (None, None) => self.build_interface(*from, *into)?,
4751
4752                    // Otherwise both interfaces must be named and they must
4753                    // have been previously found to be equivalent. Note that
4754                    // if either is unnamed it won't be present in
4755                    // `interface_map` so this'll return an error.
4756                    _ => {
4757                        if self.interface_map.get(from) != Some(into) {
4758                            bail!("interfaces are not the same");
4759                        }
4760                    }
4761                }
4762            }
4763            (WorldItem::Function(from), WorldItem::Function(into)) => {
4764                let _ = (from, into);
4765                // FIXME: should assert an check that `from` structurally
4766                // matches `into`
4767            }
4768            (WorldItem::Type { id: from, .. }, WorldItem::Type { id: into, .. }) => {
4769                // FIXME: should assert an check that `from` structurally
4770                // matches `into`
4771                let prev = self.type_map.insert(*from, *into);
4772                assert!(prev.is_none());
4773            }
4774
4775            (WorldItem::Interface { .. }, _)
4776            | (WorldItem::Function(_), _)
4777            | (WorldItem::Type { .. }, _) => {
4778                bail!("world items do not have the same type")
4779            }
4780        }
4781        Ok(())
4782    }
4783}
4784
4785/// Updates stability annotations when merging `from` into `into`.
4786///
4787/// This is done to keep up-to-date stability information if possible.
4788/// Components for example don't carry stability information but WIT does so
4789/// this tries to move from "unknown" to stable/unstable if possible.
4790fn update_stability(from: &Stability, into: &mut Stability, span: Span) -> ResolveResult<()> {
4791    // If `from` is unknown or the two stability annotations are equal then
4792    // there's nothing to do here.
4793    if from == into || from.is_unknown() {
4794        return Ok(());
4795    }
4796    // Otherwise if `into` is unknown then inherit the stability listed in
4797    // `from`.
4798    if into.is_unknown() {
4799        *into = from.clone();
4800        return Ok(());
4801    }
4802
4803    // Failing all that this means that the two attributes are different so
4804    // generate an error.
4805    Err(ResolveError::from(ResolveErrorKind::StabilityMismatch {
4806        span,
4807        from: from.clone(),
4808        into: into.clone(),
4809    }))
4810}
4811
4812fn merge_include_stability(
4813    from: &Stability,
4814    into: &mut Stability,
4815    is_external_include: bool,
4816    span: Span,
4817) -> ResolveResult<()> {
4818    if is_external_include && from.is_stable() {
4819        log::trace!("dropped stability from external package");
4820        *into = Stability::Unknown;
4821        return Ok(());
4822    }
4823
4824    update_stability(from, into, span)
4825}
4826
4827#[cfg(test)]
4828mod tests {
4829    use crate::alloc::format;
4830    use crate::alloc::string::{String, ToString};
4831    use crate::alloc::vec::Vec;
4832    use crate::{Resolve, SourceMap, WorldItem, WorldKey};
4833    use anyhow::Result;
4834
4835    #[test]
4836    fn select_world() -> Result<()> {
4837        let mut resolve = Resolve::default();
4838        resolve.push_str(
4839            "test.wit",
4840            r#"
4841                package foo:bar@0.1.0;
4842
4843                world foo {}
4844            "#,
4845        )?;
4846        resolve.push_str(
4847            "test.wit",
4848            r#"
4849                package foo:baz@0.1.0;
4850
4851                world foo {}
4852            "#,
4853        )?;
4854        resolve.push_str(
4855            "test.wit",
4856            r#"
4857                package foo:baz@0.2.0;
4858
4859                world foo {}
4860            "#,
4861        )?;
4862
4863        let dummy = resolve.push_str(
4864            "test.wit",
4865            r#"
4866                package foo:dummy;
4867
4868                world foo {}
4869            "#,
4870        )?;
4871
4872        assert!(resolve.select_world(&[dummy], None).is_ok());
4873        assert!(resolve.select_world(&[dummy], Some("xx")).is_err());
4874        assert!(resolve.select_world(&[dummy], Some("")).is_err());
4875        assert!(resolve.select_world(&[dummy], Some("foo:bar/foo")).is_ok());
4876        assert!(
4877            resolve
4878                .select_world(&[dummy], Some("foo:bar/foo@0.1.0"))
4879                .is_ok()
4880        );
4881        assert!(resolve.select_world(&[dummy], Some("foo:baz/foo")).is_err());
4882        assert!(
4883            resolve
4884                .select_world(&[dummy], Some("foo:baz/foo@0.1.0"))
4885                .is_ok()
4886        );
4887        assert!(
4888            resolve
4889                .select_world(&[dummy], Some("foo:baz/foo@0.2.0"))
4890                .is_ok()
4891        );
4892        Ok(())
4893    }
4894
4895    #[test]
4896    fn wasm_import_name_future_and_stream_intrinsics() -> Result<()> {
4897        use crate::{FutureIntrinsic, LiftLowerAbi, ManglingAndAbi, StreamIntrinsic, WasmImport};
4898
4899        let mut resolve = Resolve::default();
4900        let pkg = resolve.push_str(
4901            "test.wit",
4902            r#"
4903                package foo:bar;
4904
4905                interface iface {
4906                    iface-func: func(x: future<u32>) -> stream<u32>;
4907                }
4908
4909                world w {
4910                    import import-func: func(x: future<future<u32>>, y: u32) -> stream<string>;
4911                    export export-func: func(x: future, y: stream);
4912                    import iface;
4913                    export iface;
4914                }
4915            "#,
4916        )?;
4917        let world = resolve.packages[pkg].worlds["w"];
4918        let world = &resolve.worlds[world];
4919        let mangling = ManglingAndAbi::Legacy(LiftLowerAbi::AsyncStackful);
4920
4921        let WorldItem::Function(import_func) =
4922            &world.imports[&WorldKey::Name("import-func".to_string())]
4923        else {
4924            panic!("expected `import-func` to be a top-level world import");
4925        };
4926        let WorldItem::Function(export_func) =
4927            &world.exports[&WorldKey::Name("export-func".to_string())]
4928        else {
4929            panic!("expected `export-func` to be a top-level world export");
4930        };
4931        let import_types = import_func.find_futures_and_streams(&resolve);
4932        assert_eq!(import_types.len(), 3);
4933
4934        let (interface_key, interface_func) = world
4935            .imports
4936            .iter()
4937            .find_map(|(key, item)| match item {
4938                WorldItem::Interface { id, .. } => Some((
4939                    key.clone(),
4940                    &resolve.interfaces[*id].functions["iface-func"],
4941                )),
4942                _ => None,
4943            })
4944            .expect("expected interface import");
4945        let interface_types = interface_func.find_futures_and_streams(&resolve);
4946        assert_eq!(interface_types.len(), 2);
4947
4948        let (module, name) = resolve.wasm_import_name(
4949            mangling,
4950            WasmImport::FutureIntrinsic {
4951                interface: None,
4952                func: import_func,
4953                ty: Some(import_types[0]),
4954                intrinsic: FutureIntrinsic::New,
4955                exported: false,
4956                async_: false,
4957            },
4958        );
4959        assert_eq!(module, "$root");
4960        assert_eq!(name, "[future-new-0]import-func");
4961
4962        let (module, name) = resolve.wasm_import_name(
4963            mangling,
4964            WasmImport::FutureIntrinsic {
4965                interface: None,
4966                func: import_func,
4967                ty: Some(import_types[1]),
4968                intrinsic: FutureIntrinsic::Read,
4969                exported: false,
4970                async_: true,
4971            },
4972        );
4973        assert_eq!(module, "$root");
4974        assert_eq!(name, "[async-lower][future-read-1]import-func");
4975
4976        let (module, name) = resolve.wasm_import_name(
4977            mangling,
4978            WasmImport::StreamIntrinsic {
4979                interface: None,
4980                func: import_func,
4981                ty: Some(import_types[2]),
4982                intrinsic: StreamIntrinsic::CancelRead,
4983                exported: false,
4984                async_: true,
4985            },
4986        );
4987        assert_eq!(module, "$root");
4988        assert_eq!(name, "[async-lower][stream-cancel-read-2]import-func");
4989
4990        let (module, name) = resolve.wasm_import_name(
4991            mangling,
4992            WasmImport::FutureIntrinsic {
4993                interface: None,
4994                func: export_func,
4995                ty: None,
4996                intrinsic: FutureIntrinsic::DropReadable,
4997                exported: true,
4998                async_: false,
4999            },
5000        );
5001        assert_eq!(module, "[export]$root");
5002        assert_eq!(name, "[future-drop-readable-unit]export-func");
5003
5004        let (module, name) = resolve.wasm_import_name(
5005            mangling,
5006            WasmImport::StreamIntrinsic {
5007                interface: None,
5008                func: export_func,
5009                ty: None,
5010                intrinsic: StreamIntrinsic::Write,
5011                exported: true,
5012                async_: true,
5013            },
5014        );
5015        assert_eq!(module, "[export]$root");
5016        assert_eq!(name, "[async-lower][stream-write-unit]export-func");
5017
5018        let (module, name) = resolve.wasm_import_name(
5019            mangling,
5020            WasmImport::StreamIntrinsic {
5021                interface: Some(&interface_key),
5022                func: interface_func,
5023                ty: Some(interface_types[1]),
5024                intrinsic: StreamIntrinsic::Read,
5025                exported: true,
5026                async_: false,
5027            },
5028        );
5029        assert_eq!(
5030            module,
5031            format!("[export]{}", resolve.name_world_key(&interface_key))
5032        );
5033        assert_eq!(name, "[stream-read-1]iface-func");
5034
5035        Ok(())
5036    }
5037
5038    /// When there are multiple packages and there's no main package, don't
5039    /// pick a world just based on it being the only one that matches.
5040    #[test]
5041    fn select_world_multiple_packages() -> Result<()> {
5042        use wit_parser::Resolve;
5043
5044        let mut resolve = Resolve::default();
5045
5046        // Just one world in one package; we always succeed.
5047        let stuff = resolve.push_str(
5048            "./my-test.wit",
5049            r#"
5050                    package test:stuff;
5051
5052                    world foo {
5053                        // ...
5054                    }
5055                "#,
5056        )?;
5057        assert!(resolve.select_world(&[stuff], None).is_ok());
5058        assert!(resolve.select_world(&[stuff], Some("foo")).is_ok());
5059
5060        // Multiple packages, but still just one total world. Lookups
5061        // without a main package now fail.
5062        let empty = resolve.push_str(
5063            "./my-test.wit",
5064            r#"
5065                    package test:empty;
5066                "#,
5067        )?;
5068        assert!(resolve.select_world(&[stuff, empty], None).is_err());
5069        assert!(resolve.select_world(&[stuff, empty], Some("foo")).is_err());
5070        assert!(resolve.select_world(&[empty], None).is_err());
5071        assert!(resolve.select_world(&[empty], Some("foo")).is_err());
5072
5073        Ok(())
5074    }
5075
5076    /// Test selecting a world with multiple versions of a package name.
5077    #[test]
5078    fn select_world_versions() -> Result<()> {
5079        use wit_parser::Resolve;
5080
5081        let mut resolve = Resolve::default();
5082
5083        let _id = resolve.push_str(
5084            "./my-test.wit",
5085            r#"
5086                    package example:distraction;
5087                "#,
5088        )?;
5089
5090        // When selecting with a version it's ok to drop the version when
5091        // there's only a single copy of that package in `Resolve`.
5092        let versions_1 = resolve.push_str(
5093            "./my-test.wit",
5094            r#"
5095                    package example:versions@1.0.0;
5096
5097                    world foo { /* ... */ }
5098                "#,
5099        )?;
5100        assert!(resolve.select_world(&[versions_1], Some("foo")).is_ok());
5101        assert!(
5102            resolve
5103                .select_world(&[versions_1], Some("foo@1.0.0"))
5104                .is_err()
5105        );
5106        assert!(
5107            resolve
5108                .select_world(&[versions_1], Some("example:versions/foo"))
5109                .is_ok()
5110        );
5111        assert!(
5112            resolve
5113                .select_world(&[versions_1], Some("example:versions/foo@1.0.0"))
5114                .is_ok()
5115        );
5116
5117        // However when a single package has multiple versions in a resolve
5118        // it's required to specify the version to select which one.
5119        let versions_2 = resolve.push_str(
5120            "./my-test.wit",
5121            r#"
5122                    package example:versions@2.0.0;
5123
5124                    world foo { /* ... */ }
5125                "#,
5126        )?;
5127        assert!(
5128            resolve
5129                .select_world(&[versions_1, versions_2], Some("foo"))
5130                .is_err()
5131        );
5132        assert!(
5133            resolve
5134                .select_world(&[versions_1, versions_2], Some("foo@1.0.0"))
5135                .is_err()
5136        );
5137        assert!(
5138            resolve
5139                .select_world(&[versions_1, versions_2], Some("foo@2.0.0"))
5140                .is_err()
5141        );
5142        assert!(
5143            resolve
5144                .select_world(&[versions_1, versions_2], Some("example:versions/foo"))
5145                .is_err()
5146        );
5147        assert!(
5148            resolve
5149                .select_world(
5150                    &[versions_1, versions_2],
5151                    Some("example:versions/foo@1.0.0")
5152                )
5153                .is_ok()
5154        );
5155        assert!(
5156            resolve
5157                .select_world(
5158                    &[versions_1, versions_2],
5159                    Some("example:versions/foo@2.0.0")
5160                )
5161                .is_ok()
5162        );
5163
5164        Ok(())
5165    }
5166
5167    /// Test overriding a main package using name qualification
5168    #[test]
5169    fn select_world_override_qualification() -> Result<()> {
5170        use wit_parser::Resolve;
5171
5172        let mut resolve = Resolve::default();
5173
5174        let other = resolve.push_str(
5175            "./my-test.wit",
5176            r#"
5177                    package example:other;
5178
5179                    world foo { }
5180                "#,
5181        )?;
5182
5183        // A fully-qualified name overrides a main package.
5184        let fq = resolve.push_str(
5185            "./my-test.wit",
5186            r#"
5187                    package example:fq;
5188
5189                    world bar { }
5190                "#,
5191        )?;
5192        assert!(resolve.select_world(&[other, fq], Some("foo")).is_err());
5193        assert!(resolve.select_world(&[other, fq], Some("bar")).is_err());
5194        assert!(
5195            resolve
5196                .select_world(&[other, fq], Some("example:other/foo"))
5197                .is_ok()
5198        );
5199        assert!(
5200            resolve
5201                .select_world(&[other, fq], Some("example:fq/bar"))
5202                .is_ok()
5203        );
5204        assert!(
5205            resolve
5206                .select_world(&[other, fq], Some("example:other/bar"))
5207                .is_err()
5208        );
5209        assert!(
5210            resolve
5211                .select_world(&[other, fq], Some("example:fq/foo"))
5212                .is_err()
5213        );
5214
5215        Ok(())
5216    }
5217
5218    /// Test selecting with fully-qualified world names.
5219    #[test]
5220    fn select_world_fully_qualified() -> Result<()> {
5221        use wit_parser::Resolve;
5222
5223        let mut resolve = Resolve::default();
5224
5225        let distraction = resolve.push_str(
5226            "./my-test.wit",
5227            r#"
5228                    package example:distraction;
5229                "#,
5230        )?;
5231
5232        // If a package has multiple worlds, then we can't guess the world
5233        // even if we know the package.
5234        let multiworld = resolve.push_str(
5235            "./my-test.wit",
5236            r#"
5237                    package example:multiworld;
5238
5239                    world foo { /* ... */ }
5240
5241                    world bar { /* ... */ }
5242                "#,
5243        )?;
5244        assert!(
5245            resolve
5246                .select_world(&[distraction, multiworld], None)
5247                .is_err()
5248        );
5249        assert!(
5250            resolve
5251                .select_world(&[distraction, multiworld], Some("foo"))
5252                .is_err()
5253        );
5254        assert!(
5255            resolve
5256                .select_world(&[distraction, multiworld], Some("example:multiworld/foo"))
5257                .is_ok()
5258        );
5259        assert!(
5260            resolve
5261                .select_world(&[distraction, multiworld], Some("bar"))
5262                .is_err()
5263        );
5264        assert!(
5265            resolve
5266                .select_world(&[distraction, multiworld], Some("example:multiworld/bar"))
5267                .is_ok()
5268        );
5269
5270        Ok(())
5271    }
5272
5273    /// Test `select_world` with single and multiple packages.
5274    #[test]
5275    fn select_world_packages() -> Result<()> {
5276        use wit_parser::Resolve;
5277
5278        let mut resolve = Resolve::default();
5279
5280        // If there's a single package and only one world, that world is
5281        // the obvious choice.
5282        let wit1 = resolve.push_str(
5283            "./my-test.wit",
5284            r#"
5285                    package example:wit1;
5286
5287                    world foo {
5288                        // ...
5289                    }
5290                "#,
5291        )?;
5292        assert!(resolve.select_world(&[wit1], None).is_ok());
5293        assert!(resolve.select_world(&[wit1], Some("foo")).is_ok());
5294        assert!(
5295            resolve
5296                .select_world(&[wit1], Some("example:wit1/foo"))
5297                .is_ok()
5298        );
5299        assert!(resolve.select_world(&[wit1], Some("bar")).is_err());
5300        assert!(
5301            resolve
5302                .select_world(&[wit1], Some("example:wit2/foo"))
5303                .is_err()
5304        );
5305
5306        // If there are multiple packages, we need to be told which package
5307        // to use.
5308        let wit2 = resolve.push_str(
5309            "./my-test.wit",
5310            r#"
5311                    package example:wit2;
5312
5313                    world foo { /* ... */ }
5314                "#,
5315        )?;
5316        assert!(resolve.select_world(&[wit1, wit2], None).is_err());
5317        assert!(resolve.select_world(&[wit1, wit2], Some("foo")).is_err());
5318        assert!(
5319            resolve
5320                .select_world(&[wit1, wit2], Some("example:wit1/foo"))
5321                .is_ok()
5322        );
5323        assert!(resolve.select_world(&[wit2], None).is_ok());
5324        assert!(resolve.select_world(&[wit2], Some("foo")).is_ok());
5325        assert!(
5326            resolve
5327                .select_world(&[wit2], Some("example:wit1/foo"))
5328                .is_ok()
5329        );
5330        assert!(resolve.select_world(&[wit1, wit2], Some("bar")).is_err());
5331        assert!(
5332            resolve
5333                .select_world(&[wit1, wit2], Some("example:wit2/foo"))
5334                .is_ok()
5335        );
5336        assert!(resolve.select_world(&[wit2], Some("bar")).is_err());
5337        assert!(
5338            resolve
5339                .select_world(&[wit2], Some("example:wit2/foo"))
5340                .is_ok()
5341        );
5342
5343        Ok(())
5344    }
5345
5346    #[test]
5347    fn span_preservation() -> Result<()> {
5348        let mut resolve = Resolve::default();
5349        let pkg = resolve.push_str(
5350            "test.wit",
5351            r#"
5352                package foo:bar;
5353
5354                interface my-iface {
5355                    type my-type = u32;
5356                    my-func: func();
5357                }
5358
5359                world my-world {
5360                    export my-export: func();
5361                }
5362            "#,
5363        )?;
5364
5365        let iface_id = resolve.packages[pkg].interfaces["my-iface"];
5366        assert!(resolve.interfaces[iface_id].span.is_known());
5367
5368        let type_id = resolve.interfaces[iface_id].types["my-type"];
5369        assert!(resolve.types[type_id].span.is_known());
5370
5371        assert!(
5372            resolve.interfaces[iface_id].functions["my-func"]
5373                .span
5374                .is_known()
5375        );
5376
5377        let world_id = resolve.packages[pkg].worlds["my-world"];
5378        assert!(resolve.worlds[world_id].span.is_known());
5379
5380        let WorldItem::Function(f) =
5381            &resolve.worlds[world_id].exports[&WorldKey::Name("my-export".to_string())]
5382        else {
5383            panic!("expected function");
5384        };
5385        assert!(f.span.is_known());
5386
5387        Ok(())
5388    }
5389
5390    #[test]
5391    fn span_preservation_through_merge() -> Result<()> {
5392        let mut resolve1 = Resolve::default();
5393        resolve1.push_str(
5394            "test1.wit",
5395            r#"
5396                package foo:bar;
5397
5398                interface iface1 {
5399                    type type1 = u32;
5400                    func1: func();
5401                }
5402            "#,
5403        )?;
5404
5405        let mut resolve2 = Resolve::default();
5406        let pkg2 = resolve2.push_str(
5407            "test2.wit",
5408            r#"
5409                package foo:baz;
5410
5411                interface iface2 {
5412                    type type2 = string;
5413                    func2: func();
5414                }
5415            "#,
5416        )?;
5417
5418        let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5419        let remap = resolve1.merge(resolve2)?;
5420        let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
5421
5422        assert!(resolve1.interfaces[iface2_id].span.is_known());
5423
5424        let type2_id = resolve1.interfaces[iface2_id].types["type2"];
5425        assert!(resolve1.types[type2_id].span.is_known());
5426
5427        assert!(
5428            resolve1.interfaces[iface2_id].functions["func2"]
5429                .span
5430                .is_known()
5431        );
5432
5433        Ok(())
5434    }
5435
5436    #[test]
5437    fn span_preservation_through_include() -> Result<()> {
5438        let mut resolve = Resolve::default();
5439        let pkg = resolve.push_str(
5440            "test.wit",
5441            r#"
5442                package foo:bar;
5443
5444                world base {
5445                    export my-func: func();
5446                }
5447
5448                world extended {
5449                    include base;
5450                }
5451            "#,
5452        )?;
5453
5454        let base_id = resolve.packages[pkg].worlds["base"];
5455        let extended_id = resolve.packages[pkg].worlds["extended"];
5456
5457        let WorldItem::Function(base_func) =
5458            &resolve.worlds[base_id].exports[&WorldKey::Name("my-func".to_string())]
5459        else {
5460            panic!("expected function");
5461        };
5462        assert!(base_func.span.is_known());
5463
5464        let WorldItem::Function(extended_func) =
5465            &resolve.worlds[extended_id].exports[&WorldKey::Name("my-func".to_string())]
5466        else {
5467            panic!("expected function");
5468        };
5469        assert!(extended_func.span.is_known());
5470
5471        Ok(())
5472    }
5473
5474    #[test]
5475    fn span_preservation_through_include_with_rename() -> Result<()> {
5476        let mut resolve = Resolve::default();
5477        let pkg = resolve.push_str(
5478            "test.wit",
5479            r#"
5480                package foo:bar;
5481
5482                world base {
5483                    export original-name: func();
5484                }
5485
5486                world extended {
5487                    include base with { original-name as renamed-func }
5488                }
5489            "#,
5490        )?;
5491
5492        let extended_id = resolve.packages[pkg].worlds["extended"];
5493
5494        let WorldItem::Function(f) =
5495            &resolve.worlds[extended_id].exports[&WorldKey::Name("renamed-func".to_string())]
5496        else {
5497            panic!("expected function");
5498        };
5499        assert!(f.span.is_known());
5500
5501        assert!(
5502            !resolve.worlds[extended_id]
5503                .exports
5504                .contains_key(&WorldKey::Name("original-name".to_string()))
5505        );
5506
5507        Ok(())
5508    }
5509
5510    /// Test that spans work when included world is defined after the including world
5511    #[test]
5512    fn span_preservation_through_include_reverse_order() -> Result<()> {
5513        let mut resolve = Resolve::default();
5514        let pkg = resolve.push_str(
5515            "test.wit",
5516            r#"
5517                package foo:bar;
5518
5519                world extended {
5520                    include base;
5521                }
5522
5523                world base {
5524                    export my-func: func();
5525                }
5526            "#,
5527        )?;
5528
5529        let base_id = resolve.packages[pkg].worlds["base"];
5530        let extended_id = resolve.packages[pkg].worlds["extended"];
5531
5532        let WorldItem::Function(base_func) =
5533            &resolve.worlds[base_id].exports[&WorldKey::Name("my-func".to_string())]
5534        else {
5535            panic!("expected function");
5536        };
5537        assert!(base_func.span.is_known());
5538
5539        let WorldItem::Function(extended_func) =
5540            &resolve.worlds[extended_id].exports[&WorldKey::Name("my-func".to_string())]
5541        else {
5542            panic!("expected function");
5543        };
5544        assert!(extended_func.span.is_known());
5545
5546        Ok(())
5547    }
5548
5549    #[test]
5550    fn span_line_numbers() -> Result<()> {
5551        let mut resolve = Resolve::default();
5552        let pkg = resolve.push_source(
5553            "test.wit",
5554            "package foo:bar;
5555
5556interface my-iface {
5557    type my-type = u32;
5558    my-func: func();
5559}
5560
5561world my-world {
5562    export my-export: func();
5563}
5564",
5565        )?;
5566
5567        let iface_id = resolve.packages[pkg].interfaces["my-iface"];
5568        let iface_span = resolve.interfaces[iface_id].span;
5569        let iface_loc = resolve.render_location(iface_span);
5570        assert!(
5571            iface_loc.contains(":3:"),
5572            "interface location was {iface_loc}"
5573        );
5574
5575        let type_id = resolve.interfaces[iface_id].types["my-type"];
5576        let type_span = resolve.types[type_id].span;
5577        let type_loc = resolve.render_location(type_span);
5578        assert!(type_loc.contains(":4:"), "type location was {type_loc}");
5579
5580        let func_span = resolve.interfaces[iface_id].functions["my-func"].span;
5581        let func_loc = resolve.render_location(func_span);
5582        assert!(func_loc.contains(":5:"), "function location was {func_loc}");
5583
5584        let world_id = resolve.packages[pkg].worlds["my-world"];
5585        let world_span = resolve.worlds[world_id].span;
5586        let world_loc = resolve.render_location(world_span);
5587        assert!(world_loc.contains(":8:"), "world location was {world_loc}");
5588
5589        let WorldItem::Function(export_func) =
5590            &resolve.worlds[world_id].exports[&WorldKey::Name("my-export".to_string())]
5591        else {
5592            panic!("expected function");
5593        };
5594        let export_loc = resolve.render_location(export_func.span);
5595        assert!(
5596            export_loc.contains(":9:"),
5597            "export location was {export_loc}"
5598        );
5599
5600        Ok(())
5601    }
5602
5603    #[test]
5604    fn span_line_numbers_through_merge() -> Result<()> {
5605        let mut resolve1 = Resolve::default();
5606        resolve1.push_source(
5607            "first.wit",
5608            "package foo:first;
5609
5610interface iface1 {
5611    func1: func();
5612}
5613",
5614        )?;
5615
5616        let mut resolve2 = Resolve::default();
5617        let pkg2 = resolve2.push_source(
5618            "second.wit",
5619            "package foo:second;
5620
5621interface iface2 {
5622    func2: func();
5623}
5624",
5625        )?;
5626
5627        let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5628        let remap = resolve1.merge(resolve2)?;
5629        let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
5630
5631        let iface2_span = resolve1.interfaces[iface2_id].span;
5632        let iface2_loc = resolve1.render_location(iface2_span);
5633        assert!(
5634            iface2_loc.contains("second.wit"),
5635            "should reference second.wit, got {iface2_loc}"
5636        );
5637        assert!(
5638            iface2_loc.contains(":3:"),
5639            "interface should be on line 3, got {iface2_loc}"
5640        );
5641
5642        let func2_span = resolve1.interfaces[iface2_id].functions["func2"].span;
5643        let func2_loc = resolve1.render_location(func2_span);
5644        assert!(
5645            func2_loc.contains("second.wit"),
5646            "should reference second.wit, got {func2_loc}"
5647        );
5648        assert!(
5649            func2_loc.contains(":4:"),
5650            "function should be on line 4, got {func2_loc}"
5651        );
5652
5653        Ok(())
5654    }
5655
5656    #[test]
5657    fn span_line_numbers_multiple_sources() -> Result<()> {
5658        let mut resolve = Resolve::default();
5659
5660        let pkg1 = resolve.push_source(
5661            "first.wit",
5662            "package test:first;
5663
5664interface first-iface {
5665    first-func: func();
5666}
5667",
5668        )?;
5669
5670        let pkg2 = resolve.push_source(
5671            "second.wit",
5672            "package test:second;
5673
5674interface second-iface {
5675    second-func: func();
5676}
5677",
5678        )?;
5679
5680        let iface1_id = resolve.packages[pkg1].interfaces["first-iface"];
5681        let iface1_span = resolve.interfaces[iface1_id].span;
5682        let iface1_loc = resolve.render_location(iface1_span);
5683        assert!(
5684            iface1_loc.contains("first.wit"),
5685            "should reference first.wit, got {iface1_loc}"
5686        );
5687        assert!(
5688            iface1_loc.contains(":3:"),
5689            "interface should be on line 3, got {iface1_loc}"
5690        );
5691
5692        let func1_span = resolve.interfaces[iface1_id].functions["first-func"].span;
5693        let func1_loc = resolve.render_location(func1_span);
5694        assert!(
5695            func1_loc.contains("first.wit"),
5696            "should reference first.wit, got {func1_loc}"
5697        );
5698        assert!(
5699            func1_loc.contains(":4:"),
5700            "function should be on line 4, got {func1_loc}"
5701        );
5702
5703        let iface2_id = resolve.packages[pkg2].interfaces["second-iface"];
5704        let iface2_span = resolve.interfaces[iface2_id].span;
5705        let iface2_loc = resolve.render_location(iface2_span);
5706        assert!(
5707            iface2_loc.contains("second.wit"),
5708            "should reference second.wit, got {iface2_loc}"
5709        );
5710        assert!(
5711            iface2_loc.contains(":3:"),
5712            "interface should be on line 3, got {iface2_loc}"
5713        );
5714
5715        let func2_span = resolve.interfaces[iface2_id].functions["second-func"].span;
5716        let func2_loc = resolve.render_location(func2_span);
5717        assert!(
5718            func2_loc.contains("second.wit"),
5719            "should reference second.wit, got {func2_loc}"
5720        );
5721        assert!(
5722            func2_loc.contains(":4:"),
5723            "function should be on line 4, got {func2_loc}"
5724        );
5725
5726        Ok(())
5727    }
5728
5729    #[test]
5730    fn span_preservation_for_fields_and_cases() -> Result<()> {
5731        use crate::TypeDefKind;
5732
5733        let mut resolve = Resolve::default();
5734        let pkg = resolve.push_str(
5735            "test.wit",
5736            r#"
5737                package foo:bar;
5738
5739                interface my-iface {
5740                    record my-record {
5741                        field1: u32,
5742                        field2: string,
5743                    }
5744
5745                    flags my-flags {
5746                        flag1,
5747                        flag2,
5748                    }
5749
5750                    variant my-variant {
5751                        case1,
5752                        case2(u32),
5753                    }
5754
5755                    enum my-enum {
5756                        val1,
5757                        val2,
5758                    }
5759                }
5760            "#,
5761        )?;
5762
5763        let iface_id = resolve.packages[pkg].interfaces["my-iface"];
5764
5765        // Check record fields have spans
5766        let record_id = resolve.interfaces[iface_id].types["my-record"];
5767        let TypeDefKind::Record(record) = &resolve.types[record_id].kind else {
5768            panic!("expected record");
5769        };
5770        assert!(record.fields[0].span.is_known(), "field1 should have span");
5771        assert!(record.fields[1].span.is_known(), "field2 should have span");
5772
5773        // Check flags have spans
5774        let flags_id = resolve.interfaces[iface_id].types["my-flags"];
5775        let TypeDefKind::Flags(flags) = &resolve.types[flags_id].kind else {
5776            panic!("expected flags");
5777        };
5778        assert!(flags.flags[0].span.is_known(), "flag1 should have span");
5779        assert!(flags.flags[1].span.is_known(), "flag2 should have span");
5780
5781        // Check variant cases have spans
5782        let variant_id = resolve.interfaces[iface_id].types["my-variant"];
5783        let TypeDefKind::Variant(variant) = &resolve.types[variant_id].kind else {
5784            panic!("expected variant");
5785        };
5786        assert!(variant.cases[0].span.is_known(), "case1 should have span");
5787        assert!(variant.cases[1].span.is_known(), "case2 should have span");
5788
5789        // Check enum cases have spans
5790        let enum_id = resolve.interfaces[iface_id].types["my-enum"];
5791        let TypeDefKind::Enum(e) = &resolve.types[enum_id].kind else {
5792            panic!("expected enum");
5793        };
5794        assert!(e.cases[0].span.is_known(), "val1 should have span");
5795        assert!(e.cases[1].span.is_known(), "val2 should have span");
5796
5797        Ok(())
5798    }
5799
5800    #[test]
5801    fn span_preservation_for_fields_through_merge() -> Result<()> {
5802        use crate::TypeDefKind;
5803
5804        let mut resolve1 = Resolve::default();
5805        resolve1.push_str(
5806            "test1.wit",
5807            r#"
5808                package foo:bar;
5809
5810                interface iface1 {
5811                    record rec1 {
5812                        f1: u32,
5813                    }
5814                }
5815            "#,
5816        )?;
5817
5818        let mut resolve2 = Resolve::default();
5819        let pkg2 = resolve2.push_str(
5820            "test2.wit",
5821            r#"
5822                package foo:baz;
5823
5824                interface iface2 {
5825                    record rec2 {
5826                        f2: string,
5827                    }
5828
5829                    variant var2 {
5830                        c2,
5831                    }
5832                }
5833            "#,
5834        )?;
5835
5836        let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5837        let rec2_old_id = resolve2.interfaces[iface2_old_id].types["rec2"];
5838        let var2_old_id = resolve2.interfaces[iface2_old_id].types["var2"];
5839
5840        let remap = resolve1.merge(resolve2)?;
5841
5842        let rec2_id = remap.types[rec2_old_id.index()].unwrap();
5843        let TypeDefKind::Record(record) = &resolve1.types[rec2_id].kind else {
5844            panic!("expected record");
5845        };
5846        assert!(
5847            record.fields[0].span.is_known(),
5848            "field should have span after merge"
5849        );
5850
5851        let var2_id = remap.types[var2_old_id.index()].unwrap();
5852        let TypeDefKind::Variant(variant) = &resolve1.types[var2_id].kind else {
5853            panic!("expected variant");
5854        };
5855        assert!(
5856            variant.cases[0].span.is_known(),
5857            "case should have span after merge"
5858        );
5859
5860        Ok(())
5861    }
5862
5863    #[test]
5864    fn param_spans_point_to_names() -> Result<()> {
5865        let source = "\
5866package foo:bar;
5867
5868interface iface {
5869    my-func: func(a: u32, b: string);
5870}
5871";
5872        let mut resolve = Resolve::default();
5873        let pkg = resolve.push_str("test.wit", source)?;
5874
5875        let iface_id = resolve.packages[pkg].interfaces["iface"];
5876        let func = &resolve.interfaces[iface_id].functions["my-func"];
5877        assert_eq!(func.params.len(), 2);
5878        for param in &func.params {
5879            let start = param.span.start() as usize;
5880            let end = param.span.end() as usize;
5881            let snippet = &source[start..end];
5882            assert_eq!(
5883                snippet, param.name,
5884                "param `{}` span points to {:?}",
5885                param.name, snippet
5886            );
5887        }
5888
5889        Ok(())
5890    }
5891
5892    #[test]
5893    fn push_groups_resolves_dep_before_main() -> Result<()> {
5894        // push_groups must topologically sort main + deps internally and succeed
5895        // even when the dep is listed after main in the caller's mental model.
5896        let dep = {
5897            let mut map = SourceMap::default();
5898            map.push_str(
5899                "file:///dep.wit",
5900                "package foo:dep;\ninterface i { type t = u32; }",
5901            );
5902            map.parse().map_err(|(_, e)| e)?
5903        };
5904        let main = {
5905            let mut map = SourceMap::default();
5906            map.push_str(
5907                "file:///main.wit",
5908                "package foo:main;\ninterface j { use foo:dep/i.{t}; type u = t; }",
5909            );
5910            map.parse().map_err(|(_, e)| e)?
5911        };
5912        let mut resolve = Resolve::default();
5913        resolve.push_groups(main, Vec::from([dep]))?;
5914        assert_eq!(resolve.packages.len(), 2);
5915        Ok(())
5916    }
5917
5918    #[test]
5919    fn push_groups_cycle_error_contains_location() {
5920        // A cross-group cycle must produce an error message with a file URI and
5921        // line/col. This validates that source maps are merged into resolve.source_map
5922        // *before* toposort runs, so the span in the cycle error is resolvable.
5923        let a = {
5924            let mut map = SourceMap::default();
5925            map.push_str(
5926                "file:///a.wit",
5927                "package foo:a;\ninterface i { use foo:b/j.{}; }",
5928            );
5929            map.parse().unwrap()
5930        };
5931        let b = {
5932            let mut map = SourceMap::default();
5933            map.push_str(
5934                "file:///b.wit",
5935                "package foo:b;\ninterface j { use foo:a/i.{}; }",
5936            );
5937            map.parse().unwrap()
5938        };
5939        let mut resolve = Resolve::default();
5940        let err = resolve.push_groups(a, Vec::from([b])).unwrap_err();
5941        let msg = err.render(&resolve.source_map);
5942        assert!(
5943            msg.contains("file:///"),
5944            "cycle error should contain a file URI, got: {msg}"
5945        );
5946    }
5947
5948    #[test]
5949    fn param_spans_preserved_through_merge() -> Result<()> {
5950        let mut resolve1 = Resolve::default();
5951        resolve1.push_str(
5952            "test1.wit",
5953            r#"
5954                package foo:bar;
5955
5956                interface iface1 {
5957                    f1: func(x: u32);
5958                }
5959            "#,
5960        )?;
5961
5962        let mut resolve2 = Resolve::default();
5963        let pkg2 = resolve2.push_str(
5964            "test2.wit",
5965            r#"
5966                package foo:baz;
5967
5968                interface iface2 {
5969                    f2: func(y: string, z: bool);
5970                }
5971            "#,
5972        )?;
5973
5974        let iface2_old_id = resolve2.packages[pkg2].interfaces["iface2"];
5975
5976        let remap = resolve1.merge(resolve2)?;
5977
5978        let iface2_id = remap.interfaces[iface2_old_id.index()].unwrap();
5979        let func = &resolve1.interfaces[iface2_id].functions["f2"];
5980        for param in &func.params {
5981            assert!(
5982                param.span.is_known(),
5983                "param `{}` should have span after merge",
5984                param.name
5985            );
5986        }
5987
5988        Ok(())
5989    }
5990
5991    /// Demonstrates the round-trip property: starting from a world with only
5992    /// exports, `importize` turns them into imports, then `exportize` turns
5993    /// them back. The resulting world has the same set of exports (by key)
5994    /// as the original.
5995    #[test]
5996    fn exportize_importize_roundtrip() -> Result<()> {
5997        let mut resolve = Resolve::default();
5998        let pkg = resolve.push_str(
5999            "test.wit",
6000            r#"
6001                package foo:bar;
6002
6003                interface types {
6004                    type my-type = u32;
6005                }
6006
6007                interface api {
6008                    use types.{my-type};
6009                    do-something: func(a: my-type) -> my-type;
6010                }
6011
6012                world w {
6013                    export api;
6014                }
6015            "#,
6016        )?;
6017        let world_id = resolve.packages[pkg].worlds["w"];
6018
6019        // Snapshot original export keys.
6020        let original_export_keys: Vec<String> = resolve.worlds[world_id]
6021            .exports
6022            .keys()
6023            .map(|k| resolve.name_world_key(k))
6024            .collect();
6025        assert!(!original_export_keys.is_empty());
6026        assert!(resolve.worlds[world_id].imports.iter().all(|(_, item)| {
6027            // Before importize the only imports should be elaborated
6028            // interface deps (all interface items).
6029            matches!(item, WorldItem::Interface { .. })
6030        }));
6031
6032        // importize: exports -> imports, no exports remain.
6033        resolve.importize(world_id, Some("w-temp".to_string()))?;
6034        assert!(
6035            resolve.worlds[world_id].exports.is_empty(),
6036            "importize should leave no exports"
6037        );
6038        // The original exports should now appear as imports.
6039        for key in &original_export_keys {
6040            assert!(
6041                resolve.worlds[world_id]
6042                    .imports
6043                    .keys()
6044                    .any(|k| resolve.name_world_key(k) == *key),
6045                "expected `{key}` to be an import after importize"
6046            );
6047        }
6048
6049        // exportize: imports -> exports, round-tripping back.
6050        resolve.exportize(world_id, Some("w-final".to_string()), None)?;
6051        assert!(
6052            !resolve.worlds[world_id].exports.is_empty(),
6053            "exportize should produce exports"
6054        );
6055        // The original export keys should be present as exports again.
6056        let final_export_keys: Vec<String> = resolve.worlds[world_id]
6057            .exports
6058            .keys()
6059            .map(|k| resolve.name_world_key(k))
6060            .collect();
6061        for key in &original_export_keys {
6062            assert!(
6063                final_export_keys.contains(key),
6064                "expected `{key}` to be an export after round-trip, got exports: {final_export_keys:?}"
6065            );
6066        }
6067
6068        Ok(())
6069    }
6070}