Coverage Report

Created: 2026-09-14 07:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasm-tools/crates/wit-parser/src/ast/resolve.rs
Line
Count
Source
1
use super::{ParamList, WorldOrInterface};
2
use crate::alloc::borrow::ToOwned;
3
use crate::ast::error::{ParseError, ParseErrorKind};
4
use crate::ast::toposort::toposort;
5
use crate::*;
6
use alloc::string::{String, ToString};
7
use alloc::vec::Vec;
8
use alloc::{format, vec};
9
use core::mem;
10
11
#[derive(Default)]
12
pub struct Resolver<'a> {
13
    /// Current package name learned through the ASTs pushed onto this resolver.
14
    package_name: Option<(PackageName, Span)>,
15
16
    /// Package docs.
17
    package_docs: Docs,
18
19
    /// All non-`package` WIT decls are going to be resolved together.
20
    decl_lists: Vec<ast::DeclList<'a>>,
21
22
    // Arenas that get plumbed to the final `UnresolvedPackage`
23
    types: Arena<TypeDef>,
24
    interfaces: Arena<Interface>,
25
    worlds: Arena<World>,
26
27
    // Interning structure for types which-need-not-be-named such as
28
    // `list<string>` and such.
29
    anon_types: HashMap<Key, TypeId>,
30
31
    /// The index within `self.ast_items` that lookups should go through. This
32
    /// is updated as the ASTs are walked.
33
    cur_ast_index: usize,
34
35
    /// A map per `ast::DeclList` which keeps track of the file's top level
36
    /// names in scope. This maps each name onto either a world or an interface,
37
    /// handling things like `use` at the top level.
38
    ast_items: Vec<IndexMap<&'a str, AstItem>>,
39
40
    /// A map for the entire package being created of all names defined within,
41
    /// along with the ID they're mapping to.
42
    package_items: IndexMap<&'a str, AstItem>,
43
44
    /// A per-interface map of name to item-in-the-interface. This is the same
45
    /// length as `self.types` and is pushed to whenever `self.types` is pushed
46
    /// to.
47
    interface_types: Vec<IndexMap<&'a str, (TypeOrItem, Span)>>,
48
49
    /// Metadata about foreign dependencies which are not defined in this
50
    /// package. This map is keyed by the name of the package being imported
51
    /// from. The next level of key is the name of the interface being imported
52
    /// from, and the final value is a tuple containing the assigned ID of the
53
    /// dependency, and a Vector of the Stability attributes associated with each
54
    /// of its imports.
55
    foreign_deps: IndexMap<PackageName, IndexMap<&'a str, (AstItem, Vec<Stability>)>>,
56
57
    /// All interfaces that are present within `self.foreign_deps`.
58
    foreign_interfaces: HashSet<InterfaceId>,
59
60
    foreign_worlds: HashSet<WorldId>,
61
62
    /// The current type lookup scope which will eventually make its way into
63
    /// `self.interface_types`.
64
    type_lookup: IndexMap<&'a str, (TypeOrItem, Span)>,
65
66
    /// An assigned span for where all types inserted into `self.types` as
67
    /// imported from foreign interfaces. These types all show up first in the
68
    /// `self.types` arena and this span is used to generate an error message
69
    /// pointing to it if the item isn't actually defined.
70
    unknown_type_spans: Vec<Span>,
71
72
    /// Spans per entry in `self.foreign_deps` for where the dependency was
73
    /// introduced to print an error message if necessary.
74
    foreign_dep_spans: Vec<Span>,
75
76
    /// A list of `TypeDefKind::Unknown` types which are required to be
77
    /// resources when this package is resolved against its dependencies.
78
    required_resource_types: Vec<(TypeId, Span)>,
79
}
80
81
#[derive(PartialEq, Eq, Hash)]
82
enum Key {
83
    Variant(Vec<(String, Option<Type>)>),
84
    BorrowHandle(TypeId),
85
    Record(Vec<(String, Type)>),
86
    Flags(Vec<String>),
87
    Tuple(Vec<Type>),
88
    Enum(Vec<String>),
89
    List(Type),
90
    Map(Type, Type),
91
    FixedLengthList(Type, u32),
92
    Option(Type),
93
    Result(Option<Type>, Option<Type>),
94
    Future(Option<Type>),
95
    Stream(Option<Type>),
96
}
97
98
enum TypeItem<'a, 'b> {
99
    Use(&'b ast::Use<'a>),
100
    Def(&'b ast::TypeDef<'a>),
101
}
102
103
enum TypeOrItem {
104
    Type(TypeId),
105
    Item(&'static str),
106
}
107
108
impl<'a> Resolver<'a> {
109
24.6k
    pub(super) fn push(&mut self, file: ast::PackageFile<'a>) -> ParseResult<()> {
110
        // As each WIT file is pushed into this resolver keep track of the
111
        // current package name assigned. Only one file needs to mention it, but
112
        // if multiple mention it then they must all match.
113
24.6k
        if let Some(cur) = &file.package_id {
114
18.9k
            let cur_name = cur.package_name();
115
18.9k
            if let Some((prev, _)) = &self.package_name {
116
4.68k
                if cur_name != *prev {
117
0
                    return Err(ParseError::new_syntax(
118
0
                        cur.span,
119
0
                        format!(
120
0
                            "package identifier `{cur_name}` does not match \
121
0
                         previous package name of `{prev}`"
122
0
                        ),
123
0
                    ));
124
4.68k
                }
125
14.2k
            }
126
18.9k
            self.package_name = Some((cur_name, cur.span));
127
128
            // At most one 'package' item can have doc comments.
129
18.9k
            let docs = self.docs(&cur.docs);
130
18.9k
            if docs.contents.is_some() {
131
0
                if self.package_docs.contents.is_some() {
132
0
                    return Err(ParseError::new_syntax(
133
0
                        cur.docs.span,
134
0
                        "found doc comments on multiple 'package' items".to_owned(),
135
0
                    ));
136
0
                }
137
0
                self.package_docs = docs;
138
18.9k
            }
139
5.74k
        }
140
141
        // Ensure that there are no nested packages in `file`. Note that for
142
        // top level files nested packages are handled separately in `ast.rs`
143
        // with their own resolver.
144
81.1k
        for item in file.decl_list.items.iter() {
145
81.1k
            let span = match item {
146
0
                ast::AstItem::Package(pkg) => pkg.package_id.as_ref().unwrap().span,
147
81.1k
                _ => continue,
148
            };
149
0
            return Err(ParseError::new_syntax(
150
0
                span,
151
0
                "nested packages must be placed at the top-level".to_owned(),
152
0
            ));
153
        }
154
155
24.6k
        self.decl_lists.push(file.decl_list);
156
24.6k
        Ok(())
157
24.6k
    }
158
159
14.2k
    pub(crate) fn resolve(&mut self) -> ParseResult<UnresolvedPackage> {
160
        // At least one of the WIT files must have a `package` annotation.
161
14.2k
        let (name, package_name_span) = match &self.package_name {
162
14.2k
            Some(name) => name.clone(),
163
            None => {
164
0
                return Err(ParseError::new_syntax(
165
0
                    Span::default(),
166
0
                    "no `package` header was found in any WIT file for this package".to_owned(),
167
0
                ));
168
            }
169
        };
170
171
        // First populate information about foreign dependencies and the general
172
        // structure of the package. This should resolve the "base" of many
173
        // `use` statements and additionally generate a topological ordering of
174
        // all interfaces in the package to visit.
175
14.2k
        let decl_lists = mem::take(&mut self.decl_lists);
176
14.2k
        self.populate_foreign_deps(&decl_lists);
177
14.2k
        let (iface_order, world_order) = self.populate_ast_items(&decl_lists)?;
178
14.2k
        self.populate_foreign_types(&decl_lists)?;
179
180
        // Use the topological ordering of all interfaces to resolve all
181
        // interfaces in-order. Note that a reverse-mapping from ID to AST is
182
        // generated here to assist with this.
183
14.2k
        let mut iface_id_to_ast = IndexMap::default();
184
14.2k
        let mut world_id_to_ast = IndexMap::default();
185
24.6k
        for (i, decl_list) in decl_lists.iter().enumerate() {
186
81.1k
            for item in decl_list.items.iter() {
187
81.1k
                match item {
188
56.8k
                    ast::AstItem::Interface(iface) => {
189
56.8k
                        let id = match self.ast_items[i][iface.name.name] {
190
56.8k
                            AstItem::Interface(id) => id,
191
0
                            AstItem::World(_) => unreachable!(),
192
                        };
193
56.8k
                        iface_id_to_ast.insert(id, (iface, i));
194
                    }
195
20.5k
                    ast::AstItem::World(world) => {
196
20.5k
                        let id = match self.ast_items[i][world.name.name] {
197
20.5k
                            AstItem::World(id) => id,
198
0
                            AstItem::Interface(_) => unreachable!(),
199
                        };
200
20.5k
                        world_id_to_ast.insert(id, (world, i));
201
                    }
202
3.64k
                    ast::AstItem::Use(_) => {}
203
0
                    ast::AstItem::Package(_) => unreachable!(),
204
                }
205
            }
206
        }
207
208
56.8k
        for id in iface_order {
209
56.8k
            let (interface, i) = &iface_id_to_ast[&id];
210
56.8k
            self.cur_ast_index = *i;
211
56.8k
            self.resolve_interface(id, &interface.items, &interface.docs, &interface.attributes)?;
212
        }
213
214
20.5k
        for id in world_order {
215
20.5k
            let (world, i) = &world_id_to_ast[&id];
216
20.5k
            self.cur_ast_index = *i;
217
20.5k
            self.resolve_world(id, world)?;
218
        }
219
220
14.2k
        self.decl_lists = decl_lists;
221
        Ok(UnresolvedPackage {
222
14.2k
            package_name_span,
223
14.2k
            name,
224
14.2k
            docs: mem::take(&mut self.package_docs),
225
14.2k
            worlds: mem::take(&mut self.worlds),
226
14.2k
            types: mem::take(&mut self.types),
227
14.2k
            interfaces: mem::take(&mut self.interfaces),
228
14.2k
            foreign_deps: self
229
14.2k
                .foreign_deps
230
14.2k
                .iter()
231
14.2k
                .map(|(name, deps)| {
232
                    (
233
3.76k
                        name.clone(),
234
3.76k
                        deps.iter()
235
4.40k
                            .map(|(name, (id, stabilities))| {
236
4.40k
                                (name.to_string(), (*id, stabilities.clone()))
237
4.40k
                            })
238
3.76k
                            .collect(),
239
                    )
240
3.76k
                })
241
14.2k
                .collect(),
242
14.2k
            unknown_type_spans: mem::take(&mut self.unknown_type_spans),
243
14.2k
            foreign_dep_spans: mem::take(&mut self.foreign_dep_spans),
244
14.2k
            required_resource_types: mem::take(&mut self.required_resource_types),
245
        })
246
14.2k
    }
247
248
    /// Registers all foreign dependencies made within the ASTs provided.
249
    ///
250
    /// This will populate the `self.foreign_{deps,interfaces,worlds}` maps with all
251
    /// `UsePath::Package` entries.
252
14.2k
    fn populate_foreign_deps(&mut self, decl_lists: &[ast::DeclList<'a>]) {
253
14.2k
        let mut foreign_deps = mem::take(&mut self.foreign_deps);
254
14.2k
        let mut foreign_interfaces = mem::take(&mut self.foreign_interfaces);
255
14.2k
        let mut foreign_worlds = mem::take(&mut self.foreign_worlds);
256
24.6k
        for decl_list in decl_lists {
257
24.6k
            decl_list
258
61.7k
                .for_each_path(&mut |_, attrs, path, _names, world_or_iface| {
259
61.7k
                    let (id, name) = match path {
260
42.8k
                        ast::UsePath::Package { id, name } => (id, name),
261
18.8k
                        _ => return Ok(()),
262
                    };
263
264
42.8k
                    let stability = self.stability(attrs)?;
265
266
42.8k
                    let deps = foreign_deps.entry(id.package_name()).or_insert_with(|| {
267
3.76k
                        self.foreign_dep_spans.push(id.span);
268
3.76k
                        IndexMap::default()
269
3.76k
                    });
270
42.8k
                    let (id, stabilities) = deps.entry(name.name).or_insert_with(|| {
271
4.40k
                        let id = match world_or_iface {
272
                            WorldOrInterface::World => {
273
0
                                log::trace!(
274
                                    "creating a world for foreign dep: {}/{}",
275
0
                                    id.package_name(),
276
                                    name.name
277
                                );
278
0
                                AstItem::World(self.alloc_world(name.span))
279
                            }
280
                            WorldOrInterface::Interface | WorldOrInterface::Unknown => {
281
                                // Currently top-level `use` always assumes an interface, so the
282
                                // `Unknown` case is the same as `Interface`.
283
4.40k
                                log::trace!(
284
                                    "creating an interface for foreign dep: {}/{}",
285
0
                                    id.package_name(),
286
                                    name.name
287
                                );
288
4.40k
                                AstItem::Interface(self.alloc_interface(name.span))
289
                            }
290
                        };
291
4.40k
                        (id, Vec::new())
292
4.40k
                    });
293
294
42.8k
                    stabilities.push(stability);
295
296
42.8k
                    let _ = match *id {
297
42.8k
                        AstItem::Interface(id) => foreign_interfaces.insert(id),
298
0
                        AstItem::World(id) => foreign_worlds.insert(id),
299
                    };
300
301
42.8k
                    Ok(())
302
61.7k
                })
303
24.6k
                .unwrap();
304
        }
305
14.2k
        self.foreign_deps = foreign_deps;
306
14.2k
        self.foreign_interfaces = foreign_interfaces;
307
14.2k
        self.foreign_worlds = foreign_worlds;
308
14.2k
    }
309
310
63.6k
    fn alloc_interface(&mut self, span: Span) -> InterfaceId {
311
63.6k
        self.interface_types.push(IndexMap::default());
312
63.6k
        self.interfaces.alloc(Interface {
313
63.6k
            name: None,
314
63.6k
            types: IndexMap::default(),
315
63.6k
            docs: Docs::default(),
316
63.6k
            stability: Default::default(),
317
63.6k
            functions: IndexMap::default(),
318
63.6k
            package: None,
319
63.6k
            span,
320
63.6k
            clone_of: None,
321
63.6k
        })
322
63.6k
    }
323
324
20.5k
    fn alloc_world(&mut self, span: Span) -> WorldId {
325
20.5k
        self.worlds.alloc(World {
326
20.5k
            name: String::new(),
327
20.5k
            docs: Docs::default(),
328
20.5k
            exports: IndexMap::default(),
329
20.5k
            imports: IndexMap::default(),
330
20.5k
            package: None,
331
20.5k
            includes: Default::default(),
332
20.5k
            stability: Default::default(),
333
20.5k
            span,
334
20.5k
        })
335
20.5k
    }
336
337
    /// This method will create a `World` and an `Interface` for all items
338
    /// present in the specified set of ASTs. Additionally maps for each AST are
339
    /// generated for resolving use-paths later on.
340
14.2k
    fn populate_ast_items(
341
14.2k
        &mut self,
342
14.2k
        decl_lists: &[ast::DeclList<'a>],
343
14.2k
    ) -> ParseResult<(Vec<InterfaceId>, Vec<WorldId>)> {
344
14.2k
        let mut package_items = IndexMap::default();
345
346
        // Validate that all worlds and interfaces have unique names within this
347
        // package across all ASTs which make up the package.
348
14.2k
        let mut names = HashMap::new();
349
14.2k
        let mut decl_list_namespaces = Vec::new();
350
14.2k
        let mut order = IndexMap::default();
351
24.6k
        for decl_list in decl_lists {
352
24.6k
            let mut decl_list_ns = IndexMap::default();
353
81.1k
            for item in decl_list.items.iter() {
354
81.1k
                match item {
355
56.8k
                    ast::AstItem::Interface(i) => {
356
56.8k
                        if package_items.insert(i.name.name, i.name.span).is_some() {
357
0
                            return Err(ParseError::new_syntax(
358
0
                                i.name.span,
359
0
                                format!("duplicate item named `{}`", i.name.name),
360
0
                            ));
361
56.8k
                        }
362
56.8k
                        let prev = decl_list_ns.insert(i.name.name, ());
363
56.8k
                        assert!(prev.is_none());
364
56.8k
                        let prev = order.insert(i.name.name, Vec::new());
365
56.8k
                        assert!(prev.is_none());
366
56.8k
                        let prev = names.insert(i.name.name, item);
367
56.8k
                        assert!(prev.is_none());
368
                    }
369
20.5k
                    ast::AstItem::World(w) => {
370
20.5k
                        if package_items.insert(w.name.name, w.name.span).is_some() {
371
0
                            return Err(ParseError::new_syntax(
372
0
                                w.name.span,
373
0
                                format!("duplicate item named `{}`", w.name.name),
374
0
                            ));
375
20.5k
                        }
376
20.5k
                        let prev = decl_list_ns.insert(w.name.name, ());
377
20.5k
                        assert!(prev.is_none());
378
20.5k
                        let prev = order.insert(w.name.name, Vec::new());
379
20.5k
                        assert!(prev.is_none());
380
20.5k
                        let prev = names.insert(w.name.name, item);
381
20.5k
                        assert!(prev.is_none());
382
                    }
383
                    // These are processed down below.
384
3.64k
                    ast::AstItem::Use(_) => {}
385
386
0
                    ast::AstItem::Package(_) => unreachable!(),
387
                }
388
            }
389
24.6k
            decl_list_namespaces.push(decl_list_ns);
390
        }
391
392
        // Next record dependencies between interfaces as induced via `use`
393
        // paths. This step is used to perform a topological sort of all
394
        // interfaces to ensure there are no cycles and to generate an ordering
395
        // which we can resolve in.
396
        enum ItemSource<'a> {
397
            Foreign,
398
            Local(ast::Id<'a>),
399
        }
400
401
24.6k
        for decl_list in decl_lists {
402
            // Record, in the context of this file, what all names are defined
403
            // at the top level and whether they point to other items in this
404
            // package or foreign items. Foreign deps are ignored for
405
            // topological ordering.
406
24.6k
            let mut decl_list_ns = IndexMap::default();
407
81.1k
            for item in decl_list.items.iter() {
408
81.1k
                let (name, src) = match item {
409
3.64k
                    ast::AstItem::Use(u) => {
410
3.64k
                        let name = u.as_.as_ref().unwrap_or(u.item.name());
411
3.64k
                        let src = match &u.item {
412
1.30k
                            ast::UsePath::Id(id) => ItemSource::Local(id.clone()),
413
2.34k
                            ast::UsePath::Package { .. } => ItemSource::Foreign,
414
                        };
415
3.64k
                        (name, src)
416
                    }
417
56.8k
                    ast::AstItem::Interface(i) => (&i.name, ItemSource::Local(i.name.clone())),
418
20.5k
                    ast::AstItem::World(w) => (&w.name, ItemSource::Local(w.name.clone())),
419
0
                    ast::AstItem::Package(_) => unreachable!(),
420
                };
421
81.1k
                if decl_list_ns.insert(name.name, (name.span, src)).is_some() {
422
0
                    return Err(ParseError::new_syntax(
423
0
                        name.span,
424
0
                        format!("duplicate name `{}` in this file", name.name),
425
0
                    ));
426
81.1k
                }
427
            }
428
429
            // With this file's namespace information look at all `use` paths
430
            // and record dependencies between interfaces.
431
61.7k
            decl_list.for_each_path(&mut |iface, _attrs, path, _names, _| {
432
                // If this import isn't contained within an interface then it's
433
                // in a world and it doesn't need to participate in our
434
                // topo-sort.
435
61.7k
                let iface = match iface {
436
23.8k
                    Some(name) => name,
437
37.8k
                    None => return Ok(()),
438
                };
439
23.8k
                let used_name = match path {
440
5.59k
                    ast::UsePath::Id(id) => id,
441
18.2k
                    ast::UsePath::Package { .. } => return Ok(()),
442
                };
443
5.59k
                match decl_list_ns.get(used_name.name) {
444
24
                    Some((_, ItemSource::Foreign)) => return Ok(()),
445
2.92k
                    Some((_, ItemSource::Local(id))) => {
446
2.92k
                        order[iface.name].push(id.clone());
447
2.92k
                    }
448
2.64k
                    None => match package_items.get(used_name.name) {
449
2.64k
                        Some(_) => {
450
2.64k
                            order[iface.name].push(used_name.clone());
451
2.64k
                        }
452
                        None => {
453
0
                            return Err(ParseError::from(ParseErrorKind::ItemNotFound {
454
0
                                span: used_name.span,
455
0
                                name: used_name.name.to_string(),
456
0
                                kind: "interface or world".to_string(),
457
0
                                hint: None,
458
0
                            }));
459
                        }
460
                    },
461
                }
462
5.56k
                Ok(())
463
61.7k
            })?;
464
        }
465
466
14.2k
        let order = toposort("interface or world", &order)?;
467
14.2k
        log::debug!("toposort for interfaces and worlds in order: {order:?}");
468
469
        // Allocate interfaces in-order now that the ordering is defined. This
470
        // is then used to build up internal maps for each AST which are stored
471
        // in `self.ast_items`.
472
14.2k
        let mut ids = IndexMap::default();
473
14.2k
        let mut iface_id_order = Vec::new();
474
14.2k
        let mut world_id_order = Vec::new();
475
77.4k
        for name in order {
476
77.4k
            match names.get(name).unwrap() {
477
                ast::AstItem::Interface(_) => {
478
56.8k
                    let id = self.alloc_interface(package_items[name]);
479
56.8k
                    self.interfaces[id].name = Some(name.to_string());
480
56.8k
                    let prev = ids.insert(name, AstItem::Interface(id));
481
56.8k
                    assert!(prev.is_none());
482
56.8k
                    iface_id_order.push(id);
483
                }
484
                ast::AstItem::World(_) => {
485
20.5k
                    let id = self.alloc_world(package_items[name]);
486
20.5k
                    self.worlds[id].name = name.to_string();
487
20.5k
                    let prev = ids.insert(name, AstItem::World(id));
488
20.5k
                    assert!(prev.is_none());
489
20.5k
                    world_id_order.push(id);
490
                }
491
0
                ast::AstItem::Use(_) | ast::AstItem::Package(_) => unreachable!(),
492
            };
493
        }
494
24.6k
        for decl_list in decl_lists {
495
24.6k
            let mut items = IndexMap::default();
496
81.1k
            for item in decl_list.items.iter() {
497
81.1k
                let (name, ast_item) = match item {
498
3.64k
                    ast::AstItem::Use(u) => {
499
3.64k
                        if !u.attributes.is_empty() {
500
0
                            return Err(ParseError::new_syntax(
501
0
                                u.span,
502
0
                                format!("attributes not allowed on top-level use"),
503
0
                            ));
504
3.64k
                        }
505
3.64k
                        let name = u.as_.as_ref().unwrap_or(u.item.name());
506
3.64k
                        let item = match &u.item {
507
1.30k
                            ast::UsePath::Id(name) => *ids.get(name.name).ok_or_else(|| {
508
0
                                ParseError::from(ParseErrorKind::ItemNotFound {
509
0
                                    span: name.span,
510
0
                                    name: name.name.to_string(),
511
0
                                    kind: "interface or world".to_owned(),
512
0
                                    hint: None,
513
0
                                })
514
0
                            })?,
515
2.34k
                            ast::UsePath::Package { id, name } => {
516
2.34k
                                self.foreign_deps[&id.package_name()][name.name].0
517
                            }
518
                        };
519
3.64k
                        (name.name, item)
520
                    }
521
56.8k
                    ast::AstItem::Interface(i) => {
522
56.8k
                        let iface_item = ids[i.name.name];
523
56.8k
                        assert!(matches!(iface_item, AstItem::Interface(_)));
524
56.8k
                        (i.name.name, iface_item)
525
                    }
526
20.5k
                    ast::AstItem::World(w) => {
527
20.5k
                        let world_item = ids[w.name.name];
528
20.5k
                        assert!(matches!(world_item, AstItem::World(_)));
529
20.5k
                        (w.name.name, world_item)
530
                    }
531
0
                    ast::AstItem::Package(_) => unreachable!(),
532
                };
533
81.1k
                let prev = items.insert(name, ast_item);
534
81.1k
                assert!(prev.is_none());
535
536
                // Items defined via `use` don't go into the package namespace,
537
                // only the file namespace.
538
81.1k
                if !matches!(item, ast::AstItem::Use(_)) {
539
77.4k
                    let prev = self.package_items.insert(name, ast_item);
540
77.4k
                    assert!(prev.is_none());
541
3.64k
                }
542
            }
543
24.6k
            self.ast_items.push(items);
544
        }
545
14.2k
        Ok((iface_id_order, world_id_order))
546
14.2k
    }
547
548
    /// Generate a `Type::Unknown` entry for all types imported from foreign
549
    /// packages.
550
    ///
551
    /// This is done after all interfaces are generated so `self.resolve_path`
552
    /// can be used to determine if what's being imported from is a foreign
553
    /// interface or not.
554
14.2k
    fn populate_foreign_types(&mut self, decl_lists: &[ast::DeclList<'a>]) -> ParseResult<()> {
555
24.6k
        for (i, decl_list) in decl_lists.iter().enumerate() {
556
24.6k
            self.cur_ast_index = i;
557
61.7k
            decl_list.for_each_path(&mut |_, attrs, path, names, _| {
558
61.7k
                let names = match names {
559
25.8k
                    Some(names) => names,
560
35.8k
                    None => return Ok(()),
561
                };
562
25.8k
                let stability = self.stability(attrs)?;
563
25.8k
                let external_id = self.external_id(attrs)?;
564
25.8k
                let (item, name, span) = self.resolve_ast_item_path(path)?;
565
25.8k
                let iface = self.extract_iface_from_item(&item, &name, span)?;
566
25.8k
                if !self.foreign_interfaces.contains(&iface) {
567
6.68k
                    return Ok(());
568
19.2k
                }
569
570
19.2k
                let lookup = &mut self.interface_types[iface.index()];
571
22.9k
                for name in names {
572
                    // If this name has already been defined then use that prior
573
                    // definition, otherwise create a new type with an unknown
574
                    // representation and insert it into the various maps.
575
22.9k
                    if lookup.contains_key(name.name.name) {
576
19.1k
                        continue;
577
3.77k
                    }
578
3.77k
                    let id = self.types.alloc(TypeDef {
579
3.77k
                        docs: Docs::default(),
580
3.77k
                        stability: stability.clone(),
581
3.77k
                        kind: TypeDefKind::Unknown,
582
3.77k
                        name: Some(name.name.name.to_string()),
583
3.77k
                        owner: TypeOwner::Interface(iface),
584
3.77k
                        span: name.name.span,
585
3.77k
                        external_id: external_id.clone(),
586
3.77k
                    });
587
3.77k
                    self.unknown_type_spans.push(name.name.span);
588
3.77k
                    lookup.insert(name.name.name, (TypeOrItem::Type(id), name.name.span));
589
3.77k
                    self.interfaces[iface]
590
3.77k
                        .types
591
3.77k
                        .insert(name.name.name.to_string(), id);
592
                }
593
594
19.2k
                Ok(())
595
61.7k
            })?;
596
        }
597
14.2k
        Ok(())
598
14.2k
    }
599
600
20.5k
    fn resolve_world(&mut self, world_id: WorldId, world: &ast::World<'a>) -> ParseResult<WorldId> {
601
20.5k
        let docs = self.docs(&world.docs);
602
20.5k
        self.worlds[world_id].docs = docs;
603
20.5k
        let stability = self.stability(&world.attributes)?;
604
20.5k
        self.worlds[world_id].stability = stability;
605
606
20.5k
        self.resolve_types(
607
20.5k
            TypeOwner::World(world_id),
608
101k
            world.items.iter().filter_map(|i| match i {
609
2.29k
                ast::WorldItem::Use(u) => Some(TypeItem::Use(u)),
610
19.9k
                ast::WorldItem::Type(t) => Some(TypeItem::Def(t)),
611
79.0k
                ast::WorldItem::Import(_) | ast::WorldItem::Export(_) => None,
612
                // should be handled in `wit-parser::resolve`
613
0
                ast::WorldItem::Include(_) => None,
614
101k
            }),
615
0
        )?;
616
617
        // resolve include items
618
50.6k
        let items = world.items.iter().filter_map(|i| match i {
619
0
            ast::WorldItem::Include(i) => Some(i),
620
50.6k
            _ => None,
621
50.6k
        });
622
20.5k
        for include in items {
623
0
            self.resolve_include(world_id, include)?;
624
        }
625
626
20.5k
        for (name, (item, span)) in self.type_lookup.iter() {
627
11.2k
            match *item {
628
11.2k
                TypeOrItem::Type(id) => {
629
11.2k
                    let prev = self.worlds[world_id].imports.insert(
630
11.2k
                        WorldKey::Name(name.to_string()),
631
11.2k
                        WorldItem::Type { id, span: *span },
632
                    );
633
11.2k
                    if prev.is_some() {
634
0
                        return Err(ParseError::new_syntax(
635
0
                            *span,
636
0
                            format!("import `{name}` conflicts with prior import of same name"),
637
0
                        ));
638
11.2k
                    }
639
                }
640
0
                TypeOrItem::Item(_) => unreachable!(),
641
            }
642
        }
643
644
20.5k
        let mut imported_interfaces = HashSet::new();
645
20.5k
        let mut exported_interfaces = HashSet::new();
646
50.6k
        for item in world.items.iter() {
647
39.5k
            let (docs, attrs, kind, desc, interfaces) = match item {
648
6.99k
                ast::WorldItem::Import(import) => (
649
6.99k
                    &import.docs,
650
6.99k
                    &import.attributes,
651
6.99k
                    &import.kind,
652
6.99k
                    "import",
653
6.99k
                    &mut imported_interfaces,
654
6.99k
                ),
655
32.5k
                ast::WorldItem::Export(export) => (
656
32.5k
                    &export.docs,
657
32.5k
                    &export.attributes,
658
32.5k
                    &export.kind,
659
32.5k
                    "export",
660
32.5k
                    &mut exported_interfaces,
661
32.5k
                ),
662
663
                ast::WorldItem::Type(ast::TypeDef {
664
868
                    name,
665
868
                    ty: ast::Type::Resource(r),
666
                    ..
667
                }) => {
668
1.68k
                    for func in r.funcs.iter() {
669
1.68k
                        let func = self.resolve_resource_func(func, name)?;
670
1.68k
                        let prev = self.worlds[world_id]
671
1.68k
                            .imports
672
1.68k
                            .insert(WorldKey::Name(func.name.clone()), WorldItem::Function(func));
673
                        // Resource names themselves are unique, and methods are
674
                        // uniquely named, so this should be possible to assert
675
                        // at this point and never trip.
676
1.68k
                        assert!(prev.is_none());
677
                    }
678
868
                    continue;
679
                }
680
681
                // handled in `resolve_types`
682
                ast::WorldItem::Use(_) | ast::WorldItem::Type(_) | ast::WorldItem::Include(_) => {
683
10.2k
                    continue;
684
                }
685
            };
686
687
39.5k
            let world_item = self.resolve_world_item(docs, attrs, kind)?;
688
39.5k
            let key = match kind {
689
                // Interfaces are always named exactly as they are in the WIT.
690
2.42k
                ast::ExternKind::Interface(name, _) => WorldKey::Name(name.name.to_string()),
691
692
                // Functions, however, might get mangled (e.g. with async)
693
                // meaning that the item's name comes from the function, not
694
                // from the in-WIT name.
695
                ast::ExternKind::Func(..) => {
696
4.94k
                    let func = match &world_item {
697
4.94k
                        WorldItem::Function(f) => f,
698
0
                        _ => unreachable!(),
699
                    };
700
4.94k
                    WorldKey::Name(func.name.clone())
701
                }
702
703
1.65k
                ast::ExternKind::Path(path) => {
704
1.65k
                    let (item, name, span) = self.resolve_ast_item_path(path)?;
705
1.65k
                    let id = self.extract_iface_from_item(&item, &name, span)?;
706
1.65k
                    WorldKey::Interface(id)
707
                }
708
709
                // Named paths use the label as the key.
710
30.5k
                ast::ExternKind::NamedPath(name, _) => WorldKey::Name(name.name.to_string()),
711
            };
712
39.5k
            if let WorldKey::Interface(id) = key {
713
1.65k
                if !interfaces.insert(id) {
714
0
                    return Err(ParseError::new_syntax(
715
0
                        kind.span(),
716
0
                        format!("interface cannot be {desc}ed more than once"),
717
0
                    ));
718
1.65k
                }
719
37.8k
            }
720
39.5k
            let dst = if desc == "import" {
721
6.99k
                &mut self.worlds[world_id].imports
722
            } else {
723
32.5k
                &mut self.worlds[world_id].exports
724
            };
725
39.5k
            let prev = dst.insert(key.clone(), world_item);
726
39.5k
            if let Some(prev) = prev {
727
0
                let prev = match prev {
728
0
                    WorldItem::Interface { .. } => "interface",
729
0
                    WorldItem::Function(..) => "func",
730
0
                    WorldItem::Type { .. } => "type",
731
                };
732
0
                let name = match key {
733
0
                    WorldKey::Name(name) => name,
734
0
                    WorldKey::Interface(..) => unreachable!(),
735
                };
736
0
                return Err(ParseError::new_syntax(
737
0
                    kind.span(),
738
0
                    format!("{desc} `{name}` conflicts with prior {prev} of same name",),
739
0
                ));
740
39.5k
            }
741
        }
742
20.5k
        self.type_lookup.clear();
743
744
20.5k
        Ok(world_id)
745
20.5k
    }
746
747
39.5k
    fn resolve_world_item(
748
39.5k
        &mut self,
749
39.5k
        docs: &ast::Docs<'a>,
750
39.5k
        attrs: &[ast::Attribute<'a>],
751
39.5k
        kind: &ast::ExternKind<'a>,
752
39.5k
    ) -> ParseResult<WorldItem> {
753
39.5k
        match kind {
754
2.42k
            ast::ExternKind::Interface(name, items) => {
755
2.42k
                let prev = mem::take(&mut self.type_lookup);
756
2.42k
                let id = self.alloc_interface(name.span);
757
2.42k
                self.resolve_interface(id, items, docs, attrs)?;
758
2.42k
                self.type_lookup = prev;
759
2.42k
                let stability = self.interfaces[id].stability.clone();
760
2.42k
                let external_id = self.external_id(attrs)?;
761
2.42k
                Ok(WorldItem::Interface {
762
2.42k
                    id,
763
2.42k
                    stability,
764
2.42k
                    docs: Default::default(),
765
2.42k
                    span: name.span,
766
2.42k
                    external_id,
767
2.42k
                })
768
            }
769
1.65k
            ast::ExternKind::Path(path) => {
770
1.65k
                let stability = self.stability(attrs)?;
771
1.65k
                let external_id = self.external_id(attrs)?;
772
1.65k
                let docs = self.docs(docs);
773
1.65k
                let (item, name, item_span) = self.resolve_ast_item_path(path)?;
774
1.65k
                let id = self.extract_iface_from_item(&item, &name, item_span)?;
775
1.65k
                Ok(WorldItem::Interface {
776
1.65k
                    id,
777
1.65k
                    stability,
778
1.65k
                    external_id,
779
1.65k
                    docs,
780
1.65k
                    span: item_span,
781
1.65k
                })
782
            }
783
30.5k
            ast::ExternKind::NamedPath(name, path) => {
784
30.5k
                let stability = self.stability(attrs)?;
785
30.5k
                let external_id = self.external_id(attrs)?;
786
30.5k
                let docs = self.docs(docs);
787
30.5k
                let (item, iface_name, item_span) = self.resolve_ast_item_path(path)?;
788
30.5k
                let id = self.extract_iface_from_item(&item, &iface_name, item_span)?;
789
30.5k
                Ok(WorldItem::Interface {
790
30.5k
                    id,
791
30.5k
                    stability,
792
30.5k
                    external_id,
793
30.5k
                    docs,
794
30.5k
                    span: name.span,
795
30.5k
                })
796
            }
797
4.94k
            ast::ExternKind::Func(name, func) => {
798
4.94k
                let func = self.resolve_function(
799
4.94k
                    docs,
800
4.94k
                    attrs,
801
4.94k
                    &name.name,
802
4.94k
                    name.span,
803
4.94k
                    func,
804
4.94k
                    if func.async_ {
805
2.26k
                        FunctionKind::AsyncFreestanding
806
                    } else {
807
2.68k
                        FunctionKind::Freestanding
808
                    },
809
0
                )?;
810
4.94k
                Ok(WorldItem::Function(func))
811
            }
812
        }
813
39.5k
    }
814
815
59.2k
    fn resolve_interface(
816
59.2k
        &mut self,
817
59.2k
        interface_id: InterfaceId,
818
59.2k
        fields: &[ast::InterfaceItem<'a>],
819
59.2k
        docs: &ast::Docs<'a>,
820
59.2k
        attrs: &[ast::Attribute<'a>],
821
59.2k
    ) -> ParseResult<()> {
822
59.2k
        let docs = self.docs(docs);
823
59.2k
        self.interfaces[interface_id].docs = docs;
824
59.2k
        let stability = self.stability(attrs)?;
825
59.2k
        self.interfaces[interface_id].stability = stability;
826
827
59.2k
        self.resolve_types(
828
59.2k
            TypeOwner::Interface(interface_id),
829
149k
            fields.iter().filter_map(|i| match i {
830
49.4k
                ast::InterfaceItem::Use(u) => Some(TypeItem::Use(u)),
831
51.0k
                ast::InterfaceItem::TypeDef(t) => Some(TypeItem::Def(t)),
832
49.1k
                ast::InterfaceItem::Func(_) => None,
833
149k
            }),
834
0
        )?;
835
836
59.2k
        for (name, (ty, _)) in self.type_lookup.iter() {
837
55.4k
            match *ty {
838
55.4k
                TypeOrItem::Type(id) => {
839
55.4k
                    self.interfaces[interface_id]
840
55.4k
                        .types
841
55.4k
                        .insert(name.to_string(), id);
842
55.4k
                }
843
0
                TypeOrItem::Item(_) => unreachable!(),
844
            }
845
        }
846
847
        // Finally process all function definitions now that all types are
848
        // defined.
849
59.2k
        let mut funcs = Vec::new();
850
74.8k
        for field in fields {
851
25.5k
            match field {
852
24.5k
                ast::InterfaceItem::Func(f) => {
853
24.5k
                    self.define_interface_name(&f.name, TypeOrItem::Item("function"))?;
854
24.5k
                    funcs.push(self.resolve_function(
855
24.5k
                        &f.docs,
856
24.5k
                        &f.attributes,
857
24.5k
                        &f.name.name,
858
24.5k
                        f.name.span,
859
24.5k
                        &f.func,
860
24.5k
                        if f.func.async_ {
861
15.3k
                            FunctionKind::AsyncFreestanding
862
                        } else {
863
9.17k
                            FunctionKind::Freestanding
864
                        },
865
0
                    )?);
866
                }
867
24.7k
                ast::InterfaceItem::Use(_) => {}
868
                ast::InterfaceItem::TypeDef(ast::TypeDef {
869
2.14k
                    name,
870
2.14k
                    ty: ast::Type::Resource(r),
871
                    ..
872
                }) => {
873
4.95k
                    for func in r.funcs.iter() {
874
4.95k
                        funcs.push(self.resolve_resource_func(func, name)?);
875
                    }
876
                }
877
23.3k
                ast::InterfaceItem::TypeDef(_) => {}
878
            }
879
        }
880
59.2k
        for func in funcs {
881
29.5k
            let prev = self.interfaces[interface_id]
882
29.5k
                .functions
883
29.5k
                .insert(func.name.clone(), func);
884
29.5k
            assert!(prev.is_none());
885
        }
886
887
59.2k
        let lookup = mem::take(&mut self.type_lookup);
888
59.2k
        self.interface_types[interface_id.index()] = lookup;
889
890
59.2k
        Ok(())
891
59.2k
    }
892
893
79.8k
    fn resolve_types<'b>(
894
79.8k
        &mut self,
895
79.8k
        owner: TypeOwner,
896
79.8k
        fields: impl Iterator<Item = TypeItem<'a, 'b>> + Clone,
897
79.8k
    ) -> ParseResult<()>
898
79.8k
    where
899
79.8k
        'a: 'b,
900
    {
901
79.8k
        assert!(self.type_lookup.is_empty());
902
903
        // First, populate our namespace with `use` statements
904
79.8k
        for field in fields.clone() {
905
61.3k
            match field {
906
25.8k
                TypeItem::Use(u) => {
907
25.8k
                    self.resolve_use(owner, u)?;
908
                }
909
35.4k
                TypeItem::Def(_) => {}
910
            }
911
        }
912
913
        // Next determine dependencies between types, perform a topological
914
        // sort, and then define all types. This will define types in a
915
        // topological fashion, forbid cycles, and weed out references to
916
        // undefined types all in one go.
917
79.8k
        let mut type_deps = IndexMap::default();
918
79.8k
        let mut type_defs = IndexMap::default();
919
79.8k
        for field in fields {
920
61.3k
            match field {
921
35.4k
                TypeItem::Def(t) => {
922
35.4k
                    let prev = type_defs.insert(t.name.name, Some(t));
923
35.4k
                    if prev.is_some() {
924
0
                        return Err(ParseError::new_syntax(
925
0
                            t.name.span,
926
0
                            format!("name `{}` is defined more than once", t.name.name),
927
0
                        ));
928
35.4k
                    }
929
35.4k
                    let mut deps = Vec::new();
930
35.4k
                    collect_deps(&t.ty, &mut deps);
931
35.4k
                    type_deps.insert(t.name.name, deps);
932
                }
933
25.8k
                TypeItem::Use(u) => {
934
31.2k
                    for name in u.names.iter() {
935
31.2k
                        let name = name.as_.as_ref().unwrap_or(&name.name);
936
31.2k
                        type_deps.insert(name.name, Vec::new());
937
31.2k
                        type_defs.insert(name.name, None);
938
31.2k
                    }
939
                }
940
            }
941
        }
942
79.8k
        let order = toposort("type", &type_deps).map_err(attach_old_float_type_context)?;
943
79.8k
        for ty in order {
944
66.7k
            let def = match type_defs.swap_remove(&ty).unwrap() {
945
35.4k
                Some(def) => def,
946
31.2k
                None => continue,
947
            };
948
35.4k
            let docs = self.docs(&def.docs);
949
35.4k
            let stability = self.stability(&def.attributes)?;
950
35.4k
            let external_id = self.external_id(&def.attributes)?;
951
35.4k
            let kind = self.resolve_type_def(&def.ty, &stability)?;
952
35.4k
            let id = self.types.alloc(TypeDef {
953
35.4k
                docs,
954
35.4k
                stability,
955
35.4k
                kind,
956
35.4k
                name: Some(def.name.name.to_string()),
957
35.4k
                owner,
958
35.4k
                span: def.name.span,
959
35.4k
                external_id,
960
35.4k
            });
961
35.4k
            self.define_interface_name(&def.name, TypeOrItem::Type(id))?;
962
        }
963
79.8k
        return Ok(());
964
965
0
        fn attach_old_float_type_context(mut err: ParseError) -> ParseError {
966
0
            if let ParseErrorKind::ItemNotFound { name, hint, .. } = err.kind_mut() {
967
0
                let new = match name.as_str() {
968
0
                    "float32" => "f32",
969
0
                    "float64" => "f64",
970
0
                    _ => return err,
971
                };
972
0
                *hint = Some(format!(
973
0
                    "the `{name}` type has been renamed to `{new}` and is \
974
0
                     no longer accepted, but the `WIT_REQUIRE_F32_F64=0` \
975
0
                     environment variable can be used to temporarily \
976
0
                     disable this error"
977
0
                ));
978
0
            }
979
0
            err
980
0
        }
981
79.8k
    }
<wit_parser::ast::resolve::Resolver>::resolve_types::<core::iter::adapters::filter_map::FilterMap<core::slice::iter::Iter<wit_parser::ast::InterfaceItem>, <wit_parser::ast::resolve::Resolver>::resolve_interface::{closure#0}>>
Line
Count
Source
893
59.2k
    fn resolve_types<'b>(
894
59.2k
        &mut self,
895
59.2k
        owner: TypeOwner,
896
59.2k
        fields: impl Iterator<Item = TypeItem<'a, 'b>> + Clone,
897
59.2k
    ) -> ParseResult<()>
898
59.2k
    where
899
59.2k
        'a: 'b,
900
    {
901
59.2k
        assert!(self.type_lookup.is_empty());
902
903
        // First, populate our namespace with `use` statements
904
59.2k
        for field in fields.clone() {
905
50.2k
            match field {
906
24.7k
                TypeItem::Use(u) => {
907
24.7k
                    self.resolve_use(owner, u)?;
908
                }
909
25.5k
                TypeItem::Def(_) => {}
910
            }
911
        }
912
913
        // Next determine dependencies between types, perform a topological
914
        // sort, and then define all types. This will define types in a
915
        // topological fashion, forbid cycles, and weed out references to
916
        // undefined types all in one go.
917
59.2k
        let mut type_deps = IndexMap::default();
918
59.2k
        let mut type_defs = IndexMap::default();
919
59.2k
        for field in fields {
920
50.2k
            match field {
921
25.5k
                TypeItem::Def(t) => {
922
25.5k
                    let prev = type_defs.insert(t.name.name, Some(t));
923
25.5k
                    if prev.is_some() {
924
0
                        return Err(ParseError::new_syntax(
925
0
                            t.name.span,
926
0
                            format!("name `{}` is defined more than once", t.name.name),
927
0
                        ));
928
25.5k
                    }
929
25.5k
                    let mut deps = Vec::new();
930
25.5k
                    collect_deps(&t.ty, &mut deps);
931
25.5k
                    type_deps.insert(t.name.name, deps);
932
                }
933
24.7k
                TypeItem::Use(u) => {
934
29.9k
                    for name in u.names.iter() {
935
29.9k
                        let name = name.as_.as_ref().unwrap_or(&name.name);
936
29.9k
                        type_deps.insert(name.name, Vec::new());
937
29.9k
                        type_defs.insert(name.name, None);
938
29.9k
                    }
939
                }
940
            }
941
        }
942
59.2k
        let order = toposort("type", &type_deps).map_err(attach_old_float_type_context)?;
943
59.2k
        for ty in order {
944
55.4k
            let def = match type_defs.swap_remove(&ty).unwrap() {
945
25.5k
                Some(def) => def,
946
29.9k
                None => continue,
947
            };
948
25.5k
            let docs = self.docs(&def.docs);
949
25.5k
            let stability = self.stability(&def.attributes)?;
950
25.5k
            let external_id = self.external_id(&def.attributes)?;
951
25.5k
            let kind = self.resolve_type_def(&def.ty, &stability)?;
952
25.5k
            let id = self.types.alloc(TypeDef {
953
25.5k
                docs,
954
25.5k
                stability,
955
25.5k
                kind,
956
25.5k
                name: Some(def.name.name.to_string()),
957
25.5k
                owner,
958
25.5k
                span: def.name.span,
959
25.5k
                external_id,
960
25.5k
            });
961
25.5k
            self.define_interface_name(&def.name, TypeOrItem::Type(id))?;
962
        }
963
59.2k
        return Ok(());
964
965
        fn attach_old_float_type_context(mut err: ParseError) -> ParseError {
966
            if let ParseErrorKind::ItemNotFound { name, hint, .. } = err.kind_mut() {
967
                let new = match name.as_str() {
968
                    "float32" => "f32",
969
                    "float64" => "f64",
970
                    _ => return err,
971
                };
972
                *hint = Some(format!(
973
                    "the `{name}` type has been renamed to `{new}` and is \
974
                     no longer accepted, but the `WIT_REQUIRE_F32_F64=0` \
975
                     environment variable can be used to temporarily \
976
                     disable this error"
977
                ));
978
            }
979
            err
980
        }
981
59.2k
    }
<wit_parser::ast::resolve::Resolver>::resolve_types::<core::iter::adapters::filter_map::FilterMap<core::slice::iter::Iter<wit_parser::ast::WorldItem>, <wit_parser::ast::resolve::Resolver>::resolve_world::{closure#0}>>
Line
Count
Source
893
20.5k
    fn resolve_types<'b>(
894
20.5k
        &mut self,
895
20.5k
        owner: TypeOwner,
896
20.5k
        fields: impl Iterator<Item = TypeItem<'a, 'b>> + Clone,
897
20.5k
    ) -> ParseResult<()>
898
20.5k
    where
899
20.5k
        'a: 'b,
900
    {
901
20.5k
        assert!(self.type_lookup.is_empty());
902
903
        // First, populate our namespace with `use` statements
904
20.5k
        for field in fields.clone() {
905
11.1k
            match field {
906
1.14k
                TypeItem::Use(u) => {
907
1.14k
                    self.resolve_use(owner, u)?;
908
                }
909
9.95k
                TypeItem::Def(_) => {}
910
            }
911
        }
912
913
        // Next determine dependencies between types, perform a topological
914
        // sort, and then define all types. This will define types in a
915
        // topological fashion, forbid cycles, and weed out references to
916
        // undefined types all in one go.
917
20.5k
        let mut type_deps = IndexMap::default();
918
20.5k
        let mut type_defs = IndexMap::default();
919
20.5k
        for field in fields {
920
11.1k
            match field {
921
9.95k
                TypeItem::Def(t) => {
922
9.95k
                    let prev = type_defs.insert(t.name.name, Some(t));
923
9.95k
                    if prev.is_some() {
924
0
                        return Err(ParseError::new_syntax(
925
0
                            t.name.span,
926
0
                            format!("name `{}` is defined more than once", t.name.name),
927
0
                        ));
928
9.95k
                    }
929
9.95k
                    let mut deps = Vec::new();
930
9.95k
                    collect_deps(&t.ty, &mut deps);
931
9.95k
                    type_deps.insert(t.name.name, deps);
932
                }
933
1.14k
                TypeItem::Use(u) => {
934
1.31k
                    for name in u.names.iter() {
935
1.31k
                        let name = name.as_.as_ref().unwrap_or(&name.name);
936
1.31k
                        type_deps.insert(name.name, Vec::new());
937
1.31k
                        type_defs.insert(name.name, None);
938
1.31k
                    }
939
                }
940
            }
941
        }
942
20.5k
        let order = toposort("type", &type_deps).map_err(attach_old_float_type_context)?;
943
20.5k
        for ty in order {
944
11.2k
            let def = match type_defs.swap_remove(&ty).unwrap() {
945
9.95k
                Some(def) => def,
946
1.31k
                None => continue,
947
            };
948
9.95k
            let docs = self.docs(&def.docs);
949
9.95k
            let stability = self.stability(&def.attributes)?;
950
9.95k
            let external_id = self.external_id(&def.attributes)?;
951
9.95k
            let kind = self.resolve_type_def(&def.ty, &stability)?;
952
9.95k
            let id = self.types.alloc(TypeDef {
953
9.95k
                docs,
954
9.95k
                stability,
955
9.95k
                kind,
956
9.95k
                name: Some(def.name.name.to_string()),
957
9.95k
                owner,
958
9.95k
                span: def.name.span,
959
9.95k
                external_id,
960
9.95k
            });
961
9.95k
            self.define_interface_name(&def.name, TypeOrItem::Type(id))?;
962
        }
963
20.5k
        return Ok(());
964
965
        fn attach_old_float_type_context(mut err: ParseError) -> ParseError {
966
            if let ParseErrorKind::ItemNotFound { name, hint, .. } = err.kind_mut() {
967
                let new = match name.as_str() {
968
                    "float32" => "f32",
969
                    "float64" => "f64",
970
                    _ => return err,
971
                };
972
                *hint = Some(format!(
973
                    "the `{name}` type has been renamed to `{new}` and is \
974
                     no longer accepted, but the `WIT_REQUIRE_F32_F64=0` \
975
                     environment variable can be used to temporarily \
976
                     disable this error"
977
                ));
978
            }
979
            err
980
        }
981
20.5k
    }
982
983
25.8k
    fn resolve_use(&mut self, owner: TypeOwner, u: &ast::Use<'a>) -> ParseResult<()> {
984
25.8k
        let (item, name, span) = self.resolve_ast_item_path(&u.from)?;
985
25.8k
        let use_from = self.extract_iface_from_item(&item, &name, span)?;
986
25.8k
        let stability = self.stability(&u.attributes)?;
987
25.8k
        let external_id = self.external_id(&u.attributes)?;
988
989
31.2k
        for name in u.names.iter() {
990
31.2k
            let lookup = &self.interface_types[use_from.index()];
991
31.2k
            let id = match lookup.get(name.name.name) {
992
31.2k
                Some((TypeOrItem::Type(id), _)) => *id,
993
0
                Some((TypeOrItem::Item(s), _)) => {
994
0
                    return Err(ParseError::new_syntax(
995
0
                        name.name.span,
996
0
                        format!("cannot import {s} `{}`", name.name.name),
997
0
                    ));
998
                }
999
                None => {
1000
0
                    return Err(ParseError::from(ParseErrorKind::ItemNotFound {
1001
0
                        span: name.name.span,
1002
0
                        name: name.name.name.to_string(),
1003
0
                        kind: "name".to_string(),
1004
0
                        hint: None,
1005
0
                    }));
1006
                }
1007
            };
1008
31.2k
            let span = name.name.span;
1009
31.2k
            let name = name.as_.as_ref().unwrap_or(&name.name);
1010
31.2k
            let id = self.types.alloc(TypeDef {
1011
31.2k
                docs: Docs::default(),
1012
31.2k
                stability: stability.clone(),
1013
31.2k
                kind: TypeDefKind::Type(Type::Id(id)),
1014
31.2k
                name: Some(name.name.to_string()),
1015
31.2k
                owner,
1016
31.2k
                span,
1017
31.2k
                external_id: external_id.clone(),
1018
31.2k
            });
1019
31.2k
            self.define_interface_name(name, TypeOrItem::Type(id))?;
1020
        }
1021
25.8k
        Ok(())
1022
25.8k
    }
1023
1024
    /// For each name in the `include`, resolve the path of the include, add it to the self.includes
1025
0
    fn resolve_include(&mut self, world_id: WorldId, i: &ast::Include<'a>) -> ParseResult<()> {
1026
0
        let stability = self.stability(&i.attributes)?;
1027
0
        let (item, name, span) = self.resolve_ast_item_path(&i.from)?;
1028
0
        let include_from = self.extract_world_from_item(&item, &name, span)?;
1029
0
        self.worlds[world_id].includes.push(WorldInclude {
1030
0
            stability,
1031
0
            id: include_from,
1032
0
            names: i
1033
0
                .names
1034
0
                .iter()
1035
0
                .map(|n| IncludeName {
1036
0
                    name: n.name.name.to_string(),
1037
0
                    as_: n.as_.name.to_string(),
1038
0
                })
1039
0
                .collect(),
1040
0
            span,
1041
        });
1042
0
        Ok(())
1043
0
    }
1044
1045
6.63k
    fn resolve_resource_func(
1046
6.63k
        &mut self,
1047
6.63k
        func: &ast::ResourceFunc<'_>,
1048
6.63k
        resource: &ast::Id<'_>,
1049
6.63k
    ) -> ParseResult<Function> {
1050
6.63k
        let resource_id = match self.type_lookup.get(resource.name) {
1051
6.63k
            Some((TypeOrItem::Type(id), _)) => *id,
1052
0
            _ => panic!("type lookup for resource failed"),
1053
        };
1054
        let (name, kind);
1055
6.63k
        let named_func = func.named_func();
1056
6.63k
        let async_ = named_func.func.async_;
1057
6.63k
        match func {
1058
3.83k
            ast::ResourceFunc::Method(f) => {
1059
3.83k
                name = format!("[method]{}.{}", resource.name, f.name.name);
1060
3.83k
                kind = if async_ {
1061
2.82k
                    FunctionKind::AsyncMethod(resource_id)
1062
                } else {
1063
1.00k
                    FunctionKind::Method(resource_id)
1064
                };
1065
            }
1066
1.96k
            ast::ResourceFunc::Static(f) => {
1067
1.96k
                name = format!("[static]{}.{}", resource.name, f.name.name);
1068
1.96k
                kind = if async_ {
1069
1.41k
                    FunctionKind::AsyncStatic(resource_id)
1070
                } else {
1071
553
                    FunctionKind::Static(resource_id)
1072
                };
1073
            }
1074
            ast::ResourceFunc::Constructor(_) => {
1075
838
                assert!(!async_); // should not be possible to parse
1076
838
                name = format!("[constructor]{}", resource.name);
1077
838
                kind = FunctionKind::Constructor(resource_id);
1078
            }
1079
        }
1080
6.63k
        self.resolve_function(
1081
6.63k
            &named_func.docs,
1082
6.63k
            &named_func.attributes,
1083
6.63k
            &name,
1084
6.63k
            named_func.name.span,
1085
6.63k
            &named_func.func,
1086
6.63k
            kind,
1087
        )
1088
6.63k
    }
1089
1090
36.1k
    fn resolve_function(
1091
36.1k
        &mut self,
1092
36.1k
        docs: &ast::Docs<'_>,
1093
36.1k
        attrs: &[ast::Attribute<'_>],
1094
36.1k
        name: &str,
1095
36.1k
        name_span: Span,
1096
36.1k
        func: &ast::Func,
1097
36.1k
        kind: FunctionKind,
1098
36.1k
    ) -> ParseResult<Function> {
1099
36.1k
        let docs = self.docs(docs);
1100
36.1k
        let stability = self.stability(attrs)?;
1101
36.1k
        let external_id = self.external_id(attrs)?;
1102
36.1k
        let params = self.resolve_params(&func.params, &kind, func.span)?;
1103
36.1k
        let result = self.resolve_result(&func.result, &kind, func.span)?;
1104
36.1k
        Ok(Function {
1105
36.1k
            docs,
1106
36.1k
            stability,
1107
36.1k
            name: name.to_string(),
1108
36.1k
            kind,
1109
36.1k
            params,
1110
36.1k
            result,
1111
36.1k
            span: name_span,
1112
36.1k
            external_id,
1113
36.1k
        })
1114
36.1k
    }
1115
1116
85.6k
    fn resolve_ast_item_path(
1117
85.6k
        &self,
1118
85.6k
        path: &ast::UsePath<'a>,
1119
85.6k
    ) -> ParseResult<(AstItem, String, Span)> {
1120
85.6k
        match path {
1121
25.0k
            ast::UsePath::Id(id) => {
1122
25.0k
                let item = self.ast_items[self.cur_ast_index]
1123
25.0k
                    .get(id.name)
1124
25.0k
                    .or_else(|| self.package_items.get(id.name));
1125
25.0k
                match item {
1126
25.0k
                    Some(item) => Ok((*item, id.name.into(), id.span)),
1127
                    None => {
1128
0
                        return Err(ParseError::from(ParseErrorKind::ItemNotFound {
1129
0
                            span: id.span,
1130
0
                            name: id.name.to_string(),
1131
0
                            kind: "interface or world".to_owned(),
1132
0
                            hint: None,
1133
0
                        }));
1134
                    }
1135
                }
1136
            }
1137
60.5k
            ast::UsePath::Package { id, name } => Ok((
1138
60.5k
                self.foreign_deps[&id.package_name()][name.name].0,
1139
60.5k
                name.name.into(),
1140
60.5k
                name.span,
1141
60.5k
            )),
1142
        }
1143
85.6k
    }
1144
1145
85.6k
    fn extract_iface_from_item(
1146
85.6k
        &self,
1147
85.6k
        item: &AstItem,
1148
85.6k
        name: &str,
1149
85.6k
        span: Span,
1150
85.6k
    ) -> ParseResult<InterfaceId> {
1151
85.6k
        match item {
1152
85.6k
            AstItem::Interface(id) => Ok(*id),
1153
            AstItem::World(_) => {
1154
0
                return Err(ParseError::new_syntax(
1155
0
                    span,
1156
0
                    format!("name `{name}` is defined as a world, not an interface"),
1157
0
                ));
1158
            }
1159
        }
1160
85.6k
    }
1161
1162
0
    fn extract_world_from_item(
1163
0
        &self,
1164
0
        item: &AstItem,
1165
0
        name: &str,
1166
0
        span: Span,
1167
0
    ) -> ParseResult<WorldId> {
1168
0
        match item {
1169
0
            AstItem::World(id) => Ok(*id),
1170
            AstItem::Interface(_) => {
1171
0
                return Err(ParseError::new_syntax(
1172
0
                    span,
1173
0
                    format!("name `{name}` is defined as an interface, not a world"),
1174
0
                ));
1175
            }
1176
        }
1177
0
    }
1178
1179
91.2k
    fn define_interface_name(&mut self, name: &ast::Id<'a>, item: TypeOrItem) -> ParseResult<()> {
1180
91.2k
        let prev = self.type_lookup.insert(name.name, (item, name.span));
1181
91.2k
        if prev.is_some() {
1182
0
            return Err(ParseError::new_syntax(
1183
0
                name.span,
1184
0
                format!("name `{}` is defined more than once", name.name),
1185
0
            ));
1186
        } else {
1187
91.2k
            Ok(())
1188
        }
1189
91.2k
    }
1190
1191
607k
    fn resolve_type_def(
1192
607k
        &mut self,
1193
607k
        ty: &ast::Type<'_>,
1194
607k
        stability: &Stability,
1195
607k
    ) -> ParseResult<TypeDefKind> {
1196
607k
        Ok(match ty {
1197
160k
            ast::Type::Bool(_) => TypeDefKind::Type(Type::Bool),
1198
12.3k
            ast::Type::U8(_) => TypeDefKind::Type(Type::U8),
1199
3.99k
            ast::Type::U16(_) => TypeDefKind::Type(Type::U16),
1200
3.82k
            ast::Type::U32(_) => TypeDefKind::Type(Type::U32),
1201
3.73k
            ast::Type::U64(_) => TypeDefKind::Type(Type::U64),
1202
9.39k
            ast::Type::S8(_) => TypeDefKind::Type(Type::S8),
1203
3.25k
            ast::Type::S16(_) => TypeDefKind::Type(Type::S16),
1204
4.08k
            ast::Type::S32(_) => TypeDefKind::Type(Type::S32),
1205
12.2k
            ast::Type::S64(_) => TypeDefKind::Type(Type::S64),
1206
7.98k
            ast::Type::F32(_) => TypeDefKind::Type(Type::F32),
1207
10.2k
            ast::Type::F64(_) => TypeDefKind::Type(Type::F64),
1208
21.7k
            ast::Type::Char(_) => TypeDefKind::Type(Type::Char),
1209
2.93k
            ast::Type::String(_) => TypeDefKind::Type(Type::String),
1210
38.2k
            ast::Type::ErrorContext(_) => TypeDefKind::Type(Type::ErrorContext),
1211
2.90k
            ast::Type::Name(name) => {
1212
2.90k
                let id = self.resolve_type_name(name)?;
1213
2.90k
                TypeDefKind::Type(Type::Id(id))
1214
            }
1215
7.84k
            ast::Type::List(list) => {
1216
7.84k
                let ty = self.resolve_type(&list.ty, stability)?;
1217
7.84k
                TypeDefKind::List(ty)
1218
            }
1219
0
            ast::Type::Map(map) => {
1220
0
                let key_ty = self.resolve_type(&map.key, stability)?;
1221
0
                let value_ty = self.resolve_type(&map.value, stability)?;
1222
1223
0
                match key_ty {
1224
                    Type::Bool
1225
                    | Type::U8
1226
                    | Type::U16
1227
                    | Type::U32
1228
                    | Type::U64
1229
                    | Type::S8
1230
                    | Type::S16
1231
                    | Type::S32
1232
                    | Type::S64
1233
                    | Type::Char
1234
0
                    | Type::String => {}
1235
                    _ => {
1236
0
                        return Err(ParseError::new_syntax(map.span, "invalid map key type: map keys must be bool, u8, u16, u32, u64, s8, s16, s32, s64, char, or string".to_owned()));
1237
                    }
1238
                }
1239
1240
0
                TypeDefKind::Map(key_ty, value_ty)
1241
            }
1242
97.4k
            ast::Type::FixedLengthList(list) => {
1243
97.4k
                let ty = self.resolve_type(&list.ty, stability)?;
1244
97.4k
                TypeDefKind::FixedLengthList(ty, list.size)
1245
            }
1246
355
            ast::Type::Handle(handle) => TypeDefKind::Handle(match handle {
1247
355
                ast::Handle::Own { resource } => Handle::Own(self.validate_resource(resource)?),
1248
0
                ast::Handle::Borrow { resource } => {
1249
0
                    Handle::Borrow(self.validate_resource(resource)?)
1250
                }
1251
            }),
1252
3.01k
            ast::Type::Resource(resource) => {
1253
                // Validate here that the resource doesn't have any duplicate-ly
1254
                // named methods and that there's at most one constructor.
1255
3.01k
                let mut ctors = 0;
1256
3.01k
                let mut names = HashSet::new();
1257
6.63k
                for func in resource.funcs.iter() {
1258
6.63k
                    match func {
1259
3.83k
                        ast::ResourceFunc::Method(f) | ast::ResourceFunc::Static(f) => {
1260
5.79k
                            if !names.insert(&f.name.name) {
1261
0
                                return Err(ParseError::new_syntax(
1262
0
                                    f.name.span,
1263
0
                                    format!("duplicate function name `{}`", f.name.name),
1264
0
                                ));
1265
5.79k
                            }
1266
                        }
1267
838
                        ast::ResourceFunc::Constructor(f) => {
1268
838
                            ctors += 1;
1269
838
                            if ctors > 1 {
1270
0
                                return Err(ParseError::new_syntax(
1271
0
                                    f.name.span,
1272
0
                                    "duplicate constructors".to_owned(),
1273
0
                                ));
1274
838
                            }
1275
                        }
1276
                    }
1277
                }
1278
1279
3.01k
                TypeDefKind::Resource
1280
            }
1281
3.30k
            ast::Type::Record(record) => {
1282
3.30k
                let fields = record
1283
3.30k
                    .fields
1284
3.30k
                    .iter()
1285
10.6k
                    .map(|field| {
1286
                        Ok(Field {
1287
10.6k
                            docs: self.docs(&field.docs),
1288
10.6k
                            name: field.name.name.to_string(),
1289
10.6k
                            ty: self.resolve_type(&field.ty, stability)?,
1290
10.6k
                            span: field.name.span,
1291
                        })
1292
10.6k
                    })
1293
3.30k
                    .collect::<ParseResult<Vec<_>>>()?;
1294
3.30k
                TypeDefKind::Record(Record { fields })
1295
            }
1296
1.61k
            ast::Type::Flags(flags) => {
1297
1.61k
                let flags = flags
1298
1.61k
                    .flags
1299
1.61k
                    .iter()
1300
1.61k
                    .map(|flag| Flag {
1301
4.44k
                        docs: self.docs(&flag.docs),
1302
4.44k
                        name: flag.name.name.to_string(),
1303
4.44k
                        span: flag.name.span,
1304
4.44k
                    })
1305
1.61k
                    .collect::<Vec<_>>();
1306
1.61k
                TypeDefKind::Flags(Flags { flags })
1307
            }
1308
49.6k
            ast::Type::Tuple(t) => {
1309
49.6k
                let types = t
1310
49.6k
                    .types
1311
49.6k
                    .iter()
1312
182k
                    .map(|ty| self.resolve_type(ty, stability))
1313
49.6k
                    .collect::<ParseResult<Vec<_>>>()?;
1314
49.6k
                TypeDefKind::Tuple(Tuple { types })
1315
            }
1316
6.82k
            ast::Type::Variant(variant) => {
1317
6.82k
                if variant.cases.is_empty() {
1318
0
                    return Err(ParseError::new_syntax(
1319
0
                        variant.span,
1320
0
                        "empty variant".to_owned(),
1321
0
                    ));
1322
6.82k
                }
1323
6.82k
                let cases = variant
1324
6.82k
                    .cases
1325
6.82k
                    .iter()
1326
22.1k
                    .map(|case| {
1327
                        Ok(Case {
1328
22.1k
                            docs: self.docs(&case.docs),
1329
22.1k
                            name: case.name.name.to_string(),
1330
22.1k
                            ty: self.resolve_optional_type(case.ty.as_ref(), stability)?,
1331
22.1k
                            span: case.name.span,
1332
                        })
1333
22.1k
                    })
1334
6.82k
                    .collect::<ParseResult<Vec<_>>>()?;
1335
6.82k
                TypeDefKind::Variant(Variant { cases })
1336
            }
1337
16.8k
            ast::Type::Enum(e) => {
1338
16.8k
                if e.cases.is_empty() {
1339
0
                    return Err(ParseError::new_syntax(e.span, "empty enum".to_owned()));
1340
16.8k
                }
1341
16.8k
                let cases = e
1342
16.8k
                    .cases
1343
16.8k
                    .iter()
1344
85.0k
                    .map(|case| {
1345
85.0k
                        Ok(EnumCase {
1346
85.0k
                            docs: self.docs(&case.docs),
1347
85.0k
                            name: case.name.name.to_string(),
1348
85.0k
                            span: case.name.span,
1349
85.0k
                        })
1350
85.0k
                    })
1351
16.8k
                    .collect::<ParseResult<Vec<_>>>()?;
1352
16.8k
                TypeDefKind::Enum(Enum { cases })
1353
            }
1354
66.7k
            ast::Type::Option(ty) => TypeDefKind::Option(self.resolve_type(&ty.ty, stability)?),
1355
29.3k
            ast::Type::Result(r) => TypeDefKind::Result(Result_ {
1356
29.3k
                ok: self.resolve_optional_type(r.ok.as_deref(), stability)?,
1357
29.3k
                err: self.resolve_optional_type(r.err.as_deref(), stability)?,
1358
            }),
1359
19.1k
            ast::Type::Future(t) => {
1360
19.1k
                TypeDefKind::Future(self.resolve_optional_type(t.ty.as_deref(), stability)?)
1361
            }
1362
8.63k
            ast::Type::Stream(s) => {
1363
8.63k
                TypeDefKind::Stream(self.resolve_optional_type(s.ty.as_deref(), stability)?)
1364
            }
1365
        })
1366
607k
    }
1367
1368
3.25k
    fn resolve_type_name(&mut self, name: &ast::Id<'_>) -> ParseResult<TypeId> {
1369
3.25k
        match self.type_lookup.get(name.name) {
1370
3.25k
            Some((TypeOrItem::Type(id), _)) => Ok(*id),
1371
0
            Some((TypeOrItem::Item(s), _)) => {
1372
0
                return Err(ParseError::new_syntax(
1373
0
                    name.span,
1374
0
                    format!("cannot use {s} `{name}` as a type", name = name.name),
1375
0
                ));
1376
            }
1377
            None => {
1378
0
                return Err(ParseError::from(ParseErrorKind::ItemNotFound {
1379
0
                    span: name.span,
1380
0
                    name: name.name.to_string(),
1381
0
                    kind: "name".to_owned(),
1382
0
                    hint: None,
1383
0
                }));
1384
            }
1385
        }
1386
3.25k
    }
1387
1388
355
    fn validate_resource(&mut self, name: &ast::Id<'_>) -> ParseResult<TypeId> {
1389
355
        let id = self.resolve_type_name(name)?;
1390
355
        let mut cur = id;
1391
        loop {
1392
378
            match self.types[cur].kind {
1393
335
                TypeDefKind::Resource => break Ok(id),
1394
23
                TypeDefKind::Type(Type::Id(ty)) => cur = ty,
1395
                TypeDefKind::Unknown => {
1396
20
                    self.required_resource_types.push((cur, name.span));
1397
20
                    break Ok(id);
1398
                }
1399
                _ => {
1400
0
                    return Err(ParseError::new_syntax(
1401
0
                        name.span,
1402
0
                        format!("type `{}` used in a handle must be a resource", name.name),
1403
0
                    ));
1404
                }
1405
            }
1406
        }
1407
355
    }
1408
1409
    /// If `stability` is `Stability::Unknown`, recursively inspect the
1410
    /// specified `kind` until we either bottom out or find a type which has a
1411
    /// stability that's _not_ unknown.  If we find such a type, return a clone
1412
    /// of its stability; otherwise return `Stability::Unknown`.
1413
    ///
1414
    /// The idea here is that e.g. `option<T>` should inherit `T`'s stability.
1415
    /// This gets a little ambiguous in the case of e.g. `tuple<T, U, V>`; for
1416
    /// now, we just pick the first one has a known stability, if any.
1417
576k
    fn find_stability(&self, kind: &TypeDefKind, stability: &Stability) -> Stability {
1418
724k
        fn find_in_type(types: &Arena<TypeDef>, ty: Type) -> Option<&Stability> {
1419
724k
            if let Type::Id(id) = ty {
1420
264k
                let ty = &types[id];
1421
264k
                if !matches!(&ty.stability, Stability::Unknown) {
1422
342
                    Some(&ty.stability)
1423
                } else {
1424
                    // Note that this type isn't searched recursively since the
1425
                    // creation of `id` should already have searched its
1426
                    // recursive edges, so there's no need to search again.
1427
263k
                    None
1428
                }
1429
            } else {
1430
460k
                None
1431
            }
1432
724k
        }
1433
1434
573k
        fn find_in_kind<'a>(
1435
573k
            types: &'a Arena<TypeDef>,
1436
573k
            kind: &TypeDefKind,
1437
573k
        ) -> Option<&'a Stability> {
1438
4.18k
            match kind {
1439
293k
                TypeDefKind::Type(ty) => find_in_type(types, *ty),
1440
3.83k
                TypeDefKind::Handle(Handle::Borrow(id) | Handle::Own(id)) => {
1441
4.18k
                    find_in_type(types, Type::Id(*id))
1442
                }
1443
180k
                TypeDefKind::Tuple(t) => t.types.iter().find_map(|ty| find_in_type(types, *ty)),
1444
7.68k
                TypeDefKind::List(ty)
1445
97.3k
                | TypeDefKind::FixedLengthList(ty, _)
1446
170k
                | TypeDefKind::Option(ty) => find_in_type(types, *ty),
1447
0
                TypeDefKind::Map(k, v) => {
1448
0
                    find_in_type(types, *k).or_else(|| find_in_type(types, *v))
1449
                }
1450
19.0k
                TypeDefKind::Future(ty) | TypeDefKind::Stream(ty) => {
1451
27.6k
                    ty.as_ref().and_then(|ty| find_in_type(types, *ty))
1452
                }
1453
29.0k
                TypeDefKind::Result(r) => {
1454
29.0k
                    r.ok.as_ref()
1455
29.0k
                        .and_then(|ty| find_in_type(types, *ty))
1456
29.0k
                        .or_else(|| r.err.as_ref().and_then(|ty| find_in_type(types, *ty)))
1457
                }
1458
                // Assume these are named types which will be annotated with an
1459
                // explicit stability if applicable:
1460
                TypeDefKind::Resource
1461
                | TypeDefKind::Variant(_)
1462
                | TypeDefKind::Record(_)
1463
                | TypeDefKind::Flags(_)
1464
                | TypeDefKind::Enum(_)
1465
0
                | TypeDefKind::Unknown => None,
1466
            }
1467
573k
        }
1468
1469
576k
        if let Stability::Unknown = stability {
1470
573k
            find_in_kind(&self.types, kind)
1471
573k
                .cloned()
1472
573k
                .unwrap_or(Stability::Unknown)
1473
        } else {
1474
2.39k
            stability.clone()
1475
        }
1476
576k
    }
1477
1478
572k
    fn resolve_type(&mut self, ty: &super::Type<'_>, stability: &Stability) -> ParseResult<Type> {
1479
        // Resources must be declared at the top level to have their methods
1480
        // processed appropriately, but resources also shouldn't show up
1481
        // recursively so assert that's not happening here.
1482
572k
        match ty {
1483
0
            ast::Type::Resource(_) => unreachable!(),
1484
572k
            _ => {}
1485
        }
1486
572k
        let kind = self.resolve_type_def(ty, stability)?;
1487
572k
        let stability = self.find_stability(&kind, stability);
1488
572k
        Ok(self.anon_type_def(TypeDef {
1489
572k
            kind,
1490
572k
            name: None,
1491
572k
            docs: Docs::default(),
1492
572k
            stability,
1493
572k
            owner: TypeOwner::None,
1494
572k
            span: ty.span(),
1495
572k
            external_id: None,
1496
572k
        }))
1497
572k
    }
1498
1499
108k
    fn resolve_optional_type(
1500
108k
        &mut self,
1501
108k
        ty: Option<&super::Type<'_>>,
1502
108k
        stability: &Stability,
1503
108k
    ) -> ParseResult<Option<Type>> {
1504
108k
        match ty {
1505
95.8k
            Some(ty) => Ok(Some(self.resolve_type(ty, stability)?)),
1506
12.6k
            None => Ok(None),
1507
        }
1508
108k
    }
1509
1510
576k
    fn anon_type_def(&mut self, ty: TypeDef) -> Type {
1511
281k
        let key = match &ty.kind {
1512
294k
            TypeDefKind::Type(t) => return *t,
1513
0
            TypeDefKind::Variant(v) => Key::Variant(
1514
0
                v.cases
1515
0
                    .iter()
1516
0
                    .map(|case| (case.name.clone(), case.ty))
1517
0
                    .collect::<Vec<_>>(),
1518
            ),
1519
3.83k
            TypeDefKind::Handle(Handle::Borrow(h)) => Key::BorrowHandle(*h),
1520
            // An anonymous `own<T>` type is the same as a reference to the type
1521
            // `T`, so avoid creating anonymous type and return that here
1522
            // directly. Note that this additionally avoids creating distinct
1523
            // anonymous types for `list<T>` and `list<own<T>>` for example.
1524
355
            TypeDefKind::Handle(Handle::Own(id)) => return Type::Id(*id),
1525
0
            TypeDefKind::Resource => unreachable!("anonymous resources aren't supported"),
1526
0
            TypeDefKind::Record(r) => Key::Record(
1527
0
                r.fields
1528
0
                    .iter()
1529
0
                    .map(|case| (case.name.clone(), case.ty))
1530
0
                    .collect::<Vec<_>>(),
1531
            ),
1532
0
            TypeDefKind::Flags(r) => {
1533
0
                Key::Flags(r.flags.iter().map(|f| f.name.clone()).collect::<Vec<_>>())
1534
            }
1535
48.9k
            TypeDefKind::Tuple(t) => Key::Tuple(t.types.clone()),
1536
0
            TypeDefKind::Enum(r) => {
1537
0
                Key::Enum(r.cases.iter().map(|f| f.name.clone()).collect::<Vec<_>>())
1538
            }
1539
7.75k
            TypeDefKind::List(ty) => Key::List(*ty),
1540
0
            TypeDefKind::Map(k, v) => Key::Map(*k, *v),
1541
97.3k
            TypeDefKind::FixedLengthList(ty, size) => Key::FixedLengthList(*ty, *size),
1542
66.2k
            TypeDefKind::Option(t) => Key::Option(*t),
1543
29.1k
            TypeDefKind::Result(r) => Key::Result(r.ok, r.err),
1544
19.0k
            TypeDefKind::Future(ty) => Key::Future(*ty),
1545
8.60k
            TypeDefKind::Stream(ty) => Key::Stream(*ty),
1546
0
            TypeDefKind::Unknown => unreachable!(),
1547
        };
1548
281k
        let id = self
1549
281k
            .anon_types
1550
281k
            .entry(key)
1551
281k
            .or_insert_with(|| self.types.alloc(ty));
1552
281k
        Type::Id(*id)
1553
576k
    }
1554
1555
324k
    fn docs(&mut self, doc: &super::Docs<'_>) -> Docs {
1556
324k
        let mut docs = vec![];
1557
1558
324k
        for doc in doc.docs.iter() {
1559
0
            let contents = match doc.strip_prefix("/**") {
1560
0
                Some(doc) => doc.strip_suffix("*/").unwrap(),
1561
0
                None => doc.trim_start_matches('/'),
1562
            };
1563
1564
0
            docs.push(contents.trim_end());
1565
        }
1566
1567
        // Scan the (non-empty) doc lines to find the minimum amount of leading whitespace.
1568
        // This amount of whitespace will be removed from the start of all doc lines,
1569
        // normalizing the output while retaining intentional spacing added by the original authors.
1570
324k
        let min_leading_ws = docs
1571
324k
            .iter()
1572
324k
            .filter(|doc| !doc.is_empty())
1573
324k
            .map(|doc| doc.bytes().take_while(|c| c.is_ascii_whitespace()).count())
1574
324k
            .min()
1575
324k
            .unwrap_or(0);
1576
1577
324k
        if min_leading_ws > 0 {
1578
0
            let leading_ws_pattern = " ".repeat(min_leading_ws);
1579
0
            docs = docs
1580
0
                .iter()
1581
0
                .map(|doc| doc.strip_prefix(&leading_ws_pattern).unwrap_or(doc))
1582
0
                .collect();
1583
324k
        }
1584
1585
324k
        let contents = if docs.is_empty() {
1586
324k
            None
1587
        } else {
1588
            // NB: this notably, through the use of `lines`, normalizes `\r\n`
1589
            // to `\n`.
1590
0
            let mut contents = String::new();
1591
0
            for doc in docs {
1592
0
                if doc.is_empty() {
1593
0
                    contents.push_str("\n");
1594
0
                } else {
1595
0
                    for line in doc.lines() {
1596
0
                        contents.push_str(line);
1597
0
                        contents.push_str("\n");
1598
0
                    }
1599
                }
1600
            }
1601
0
            while contents.ends_with("\n") {
1602
0
                contents.pop();
1603
0
            }
1604
0
            Some(contents)
1605
        };
1606
324k
        Docs { contents }
1607
324k
    }
1608
1609
278k
    fn stability(&mut self, attrs: &[ast::Attribute<'_>]) -> ParseResult<Stability> {
1610
278k
        let mut since = None;
1611
278k
        let mut since_span = Span::default();
1612
278k
        let mut deprecated = None;
1613
278k
        let mut deprecated_span = Span::default();
1614
278k
        let mut unstable = None;
1615
278k
        for attr in attrs {
1616
180k
            match attr {
1617
4.32k
                ast::Attribute::Since { version, span } => {
1618
4.32k
                    if since.is_some() {
1619
0
                        return Err(ParseError::new_syntax(
1620
0
                            *span,
1621
0
                            "cannot specify @since twice".to_owned(),
1622
0
                        ));
1623
4.32k
                    }
1624
4.32k
                    since = Some(version.clone());
1625
4.32k
                    since_span = *span;
1626
                }
1627
1.66k
                ast::Attribute::Deprecated { version, span } => {
1628
1.66k
                    if deprecated.is_some() {
1629
0
                        return Err(ParseError::new_syntax(
1630
0
                            *span,
1631
0
                            "cannot specify @deprecated twice".to_owned(),
1632
0
                        ));
1633
1.66k
                    }
1634
1.66k
                    deprecated = Some(version.clone());
1635
1.66k
                    deprecated_span = *span;
1636
                }
1637
2.02k
                ast::Attribute::Unstable { feature, span } => {
1638
2.02k
                    if unstable.is_some() {
1639
0
                        return Err(ParseError::new_syntax(
1640
0
                            *span,
1641
0
                            "cannot specify @unstable twice".to_owned(),
1642
0
                        ));
1643
2.02k
                    }
1644
2.02k
                    unstable = Some(feature.name.to_string());
1645
                }
1646
172k
                _ => {}
1647
            }
1648
        }
1649
278k
        match (since, deprecated, unstable) {
1650
4.32k
            (Some(since), deprecated, None) => Ok(Stability::Stable { since, deprecated }),
1651
2.02k
            (None, deprecated, Some(feature)) => Ok(Stability::Unstable {
1652
2.02k
                feature,
1653
2.02k
                deprecated,
1654
2.02k
            }),
1655
0
            (Some(_), _deprecated, Some(_)) => {
1656
0
                return Err(ParseError::new_syntax(
1657
0
                    since_span,
1658
0
                    "cannot specify both @since and @unstable".to_owned(),
1659
0
                ));
1660
            }
1661
            (None, Some(_), None) => {
1662
0
                return Err(ParseError::new_syntax(
1663
0
                    deprecated_span,
1664
0
                    "cannot specify both @deprecated without @since or @unstable".to_owned(),
1665
0
                ));
1666
            }
1667
271k
            (None, None, None) => Ok(Stability::Unknown),
1668
        }
1669
278k
    }
1670
1671
157k
    fn external_id(&mut self, attrs: &[ast::Attribute<'_>]) -> ParseResult<Option<String>> {
1672
157k
        let mut external_id = None;
1673
157k
        for attr in attrs {
1674
141k
            match attr {
1675
134k
                ast::Attribute::ExternalId { span, id } => {
1676
134k
                    if external_id.is_some() {
1677
0
                        return Err(ParseError::new_syntax(
1678
0
                            *span,
1679
0
                            "cannot specify @external-id twice".to_owned(),
1680
0
                        ));
1681
134k
                    }
1682
134k
                    external_id = Some(id.clone())
1683
                }
1684
6.97k
                _ => {}
1685
            }
1686
        }
1687
157k
        Ok(external_id)
1688
157k
    }
1689
1690
36.1k
    fn resolve_params(
1691
36.1k
        &mut self,
1692
36.1k
        params: &ParamList<'_>,
1693
36.1k
        kind: &FunctionKind,
1694
36.1k
        span: Span,
1695
36.1k
    ) -> ParseResult<Vec<Param>> {
1696
36.1k
        let mut ret = Vec::new();
1697
36.1k
        match *kind {
1698
            // These kinds of methods don't have any adjustments to the
1699
            // parameters, so do nothing here.
1700
            FunctionKind::Freestanding
1701
            | FunctionKind::AsyncFreestanding
1702
            | FunctionKind::Constructor(_)
1703
            | FunctionKind::Static(_)
1704
32.2k
            | FunctionKind::AsyncStatic(_) => {}
1705
1706
            // Methods automatically get a `self` initial argument so insert
1707
            // that here before processing the normal parameters.
1708
3.83k
            FunctionKind::Method(id) | FunctionKind::AsyncMethod(id) => {
1709
3.83k
                let kind = TypeDefKind::Handle(Handle::Borrow(id));
1710
3.83k
                let stability = self.find_stability(&kind, &Stability::Unknown);
1711
3.83k
                let shared = self.anon_type_def(TypeDef {
1712
3.83k
                    docs: Docs::default(),
1713
3.83k
                    stability,
1714
3.83k
                    kind,
1715
3.83k
                    name: None,
1716
3.83k
                    owner: TypeOwner::None,
1717
3.83k
                    span,
1718
3.83k
                    external_id: None,
1719
3.83k
                });
1720
3.83k
                ret.push(Param {
1721
3.83k
                    name: "self".to_string(),
1722
3.83k
                    ty: shared,
1723
3.83k
                    span,
1724
3.83k
                });
1725
3.83k
            }
1726
        }
1727
83.6k
        for (name, ty) in params {
1728
158k
            if ret.iter().any(|p| p.name == name.name) {
1729
0
                return Err(ParseError::new_syntax(
1730
0
                    name.span,
1731
0
                    format!("param `{}` is defined more than once", name.name),
1732
0
                ));
1733
83.6k
            }
1734
83.6k
            ret.push(Param {
1735
83.6k
                name: name.name.to_string(),
1736
83.6k
                ty: self.resolve_type(ty, &Stability::Unknown)?,
1737
83.6k
                span: name.span,
1738
            });
1739
        }
1740
36.1k
        Ok(ret)
1741
36.1k
    }
1742
1743
36.1k
    fn resolve_result(
1744
36.1k
        &mut self,
1745
36.1k
        result: &Option<ast::Type<'_>>,
1746
36.1k
        kind: &FunctionKind,
1747
36.1k
        _span: Span,
1748
36.1k
    ) -> ParseResult<Option<Type>> {
1749
36.1k
        match *kind {
1750
            // These kinds of methods don't have any adjustments to the return
1751
            // values, so plumb them through as-is.
1752
            FunctionKind::Freestanding
1753
            | FunctionKind::AsyncFreestanding
1754
            | FunctionKind::Method(_)
1755
            | FunctionKind::AsyncMethod(_)
1756
            | FunctionKind::Static(_)
1757
35.2k
            | FunctionKind::AsyncStatic(_) => match result {
1758
27.4k
                Some(ty) => Ok(Some(self.resolve_type(ty, &Stability::Unknown)?)),
1759
7.79k
                None => Ok(None),
1760
            },
1761
1762
838
            FunctionKind::Constructor(id) => match result {
1763
                // When constructors don't define a return type, they're
1764
                // implicitly assumed to return an owned handle to the type
1765
                // they construct.
1766
838
                None => Ok(Some(Type::Id(id))),
1767
1768
                // If a constructor does define a return type, it must be in the
1769
                // form of `-> result<R, E?>` where `R` is the resource being
1770
                // constructed and `E` is an optional error type.
1771
0
                Some(ty) => Ok(Some(self.resolve_constructor_result(id, ty)?)),
1772
            },
1773
        }
1774
36.1k
    }
1775
1776
0
    fn resolve_constructor_result(
1777
0
        &mut self,
1778
0
        resource_id: TypeId,
1779
0
        result_ast: &ast::Type<'_>,
1780
0
    ) -> ParseResult<Type> {
1781
0
        let result = self.resolve_type(result_ast, &Stability::Unknown)?;
1782
0
        let ok_type = match result {
1783
0
            Type::Id(id) => match &self.types[id].kind {
1784
0
                TypeDefKind::Result(r) => Some(r.ok),
1785
0
                _ => None,
1786
            },
1787
0
            _ => None,
1788
        };
1789
0
        let Some(ok_type) = ok_type else {
1790
0
            return Err(ParseError::new_syntax(
1791
0
                result_ast.span(),
1792
0
                "if a constructor return type is declared it must be a `result`".to_owned(),
1793
0
            ));
1794
        };
1795
0
        match ok_type {
1796
0
            Some(Type::Id(ok_id)) if resource_id == ok_id => Ok(result),
1797
            _ => {
1798
0
                let ok_span =
1799
0
                    if let ast::Type::Result(ast::Result_ { ok: Some(ok), .. }) = result_ast {
1800
0
                        ok.span()
1801
                    } else {
1802
0
                        result_ast.span()
1803
                    };
1804
0
                return Err(ParseError::new_syntax(
1805
0
                    ok_span,
1806
0
                    "the `ok` type must be the resource being constructed".to_owned(),
1807
0
                ));
1808
            }
1809
        }
1810
0
    }
1811
}
1812
1813
146k
fn collect_deps<'a>(ty: &ast::Type<'a>, deps: &mut Vec<ast::Id<'a>>) {
1814
146k
    match ty {
1815
        ast::Type::Bool(_)
1816
        | ast::Type::U8(_)
1817
        | ast::Type::U16(_)
1818
        | ast::Type::U32(_)
1819
        | ast::Type::U64(_)
1820
        | ast::Type::S8(_)
1821
        | ast::Type::S16(_)
1822
        | ast::Type::S32(_)
1823
        | ast::Type::S64(_)
1824
        | ast::Type::F32(_)
1825
        | ast::Type::F64(_)
1826
        | ast::Type::Char(_)
1827
        | ast::Type::String(_)
1828
        | ast::Type::Flags(_)
1829
        | ast::Type::Enum(_)
1830
103k
        | ast::Type::ErrorContext(_) => {}
1831
1.20k
        ast::Type::Name(name) => deps.push(name.clone()),
1832
14
        ast::Type::Handle(handle) => match handle {
1833
14
            ast::Handle::Own { resource } => deps.push(resource.clone()),
1834
0
            ast::Handle::Borrow { resource } => deps.push(resource.clone()),
1835
        },
1836
3.01k
        ast::Type::Resource(_) => {}
1837
3.30k
        ast::Type::Record(record) => {
1838
10.6k
            for field in record.fields.iter() {
1839
10.6k
                collect_deps(&field.ty, deps);
1840
10.6k
            }
1841
        }
1842
14.7k
        ast::Type::Tuple(t) => {
1843
64.9k
            for ty in t.types.iter() {
1844
64.9k
                collect_deps(ty, deps);
1845
64.9k
            }
1846
        }
1847
6.82k
        ast::Type::Variant(variant) => {
1848
22.1k
            for case in variant.cases.iter() {
1849
22.1k
                if let Some(ty) = &case.ty {
1850
19.8k
                    collect_deps(ty, deps);
1851
19.8k
                }
1852
            }
1853
        }
1854
7.87k
        ast::Type::Option(ast::Option_ { ty, .. })
1855
1.42k
        | ast::Type::List(ast::List { ty, .. })
1856
9.57k
        | ast::Type::FixedLengthList(ast::FixedLengthList { ty, .. }) => collect_deps(ty, deps),
1857
0
        ast::Type::Map(ast::Map { key, value, .. }) => {
1858
0
            collect_deps(key, deps);
1859
0
            collect_deps(value, deps);
1860
0
        }
1861
3.04k
        ast::Type::Result(r) => {
1862
3.04k
            if let Some(ty) = &r.ok {
1863
2.39k
                collect_deps(ty, deps);
1864
2.39k
            }
1865
3.04k
            if let Some(ty) = &r.err {
1866
2.52k
                collect_deps(ty, deps);
1867
2.52k
            }
1868
        }
1869
532
        ast::Type::Future(t) => {
1870
532
            if let Some(t) = &t.ty {
1871
367
                collect_deps(t, deps)
1872
165
            }
1873
        }
1874
741
        ast::Type::Stream(s) => {
1875
741
            if let Some(t) = &s.ty {
1876
741
                collect_deps(t, deps)
1877
0
            }
1878
        }
1879
    }
1880
146k
}