Coverage Report

Created: 2026-10-24 07:23

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