Skip to main content

wit_parser/resolve/
mod.rs

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