1use wasmparser::{
14 ComponentAlias, ComponentDefinedType, ComponentExternName, ComponentFuncType,
15 ComponentOuterAliasKind, ComponentType, ComponentTypeDeclaration, ComponentTypeRef,
16 ComponentValType, CompositeInnerType, CoreType, InstanceTypeDeclaration, ModuleTypeDeclaration,
17 OuterAliasKind, PrimitiveValType, TypeBounds, TypeRef,
18};
19
20use crate::etypes::{
21 BoundedTyvar, Component, CoreDefined, CoreExportDecl, CoreExternDesc, CoreModule,
22 CoreOrComponentExternDesc, Ctx, Defined, ExternDecl, ExternDesc, FloatWidth, Func, Handleable,
23 Instance, IntWidth, Name, Param, QualifiedInstance, RecordField, Resource, ResourceId,
24 TypeBound, Tyvar, Value, VariantCase,
25};
26use crate::substitute::{self, Substitution, Unvoidable};
27use crate::tv::ResolvedTyvar;
28use crate::wf;
29
30mod basic_conversions {
31 use wasmparser::{ComponentExternalKind, ExternalKind};
35
36 use crate::etypes::{CoreExternDesc, ExternDesc};
37 use crate::structure::{CoreSort, Sort};
38
39 pub(super) fn sort_matches_core_ed(sort: Sort, ed: &CoreExternDesc) {
40 match (sort, ed) {
41 (Sort::Core(CoreSort::Func), CoreExternDesc::Func(_)) => (),
42 (Sort::Core(CoreSort::Table), CoreExternDesc::Table(_)) => (),
43 (Sort::Core(CoreSort::Memory), CoreExternDesc::Memory(_)) => (),
44 (Sort::Core(CoreSort::Global), CoreExternDesc::Global(_)) => (),
45 _ => panic!("sort does not match core extern descriptor"),
46 }
47 }
48
49 pub(super) fn external_kind(k: ExternalKind) -> Sort {
50 match k {
51 ExternalKind::Func => Sort::Core(CoreSort::Func),
52 ExternalKind::Table => Sort::Core(CoreSort::Table),
53 ExternalKind::Memory => Sort::Core(CoreSort::Memory),
54 ExternalKind::Global => Sort::Core(CoreSort::Global),
55 ExternalKind::Tag => panic!("core type tags are not supported"),
56 ExternalKind::FuncExact => panic!("core type exact functions are not supported"),
57 }
58 }
59
60 pub(super) fn sort_matches_ed<'a>(sort: Sort, ed: &ExternDesc<'a>) {
61 match (sort, ed) {
62 (Sort::Core(CoreSort::Module), ExternDesc::CoreModule(_)) => (),
63 (Sort::Func, ExternDesc::Func(_)) => (),
64 (Sort::Type, ExternDesc::Type(_)) => (),
65 (Sort::Instance, ExternDesc::Instance(_)) => (),
66 (Sort::Component, ExternDesc::Component(_)) => (),
67 _ => panic!("sort does not match extern descriptor"),
68 }
69 }
70
71 pub(super) fn component_external_kind(k: ComponentExternalKind) -> Sort {
72 match k {
73 ComponentExternalKind::Module => Sort::Core(CoreSort::Module),
74 ComponentExternalKind::Func => Sort::Func,
75 ComponentExternalKind::Value => Sort::Value,
76 ComponentExternalKind::Type => Sort::Type,
77 ComponentExternalKind::Instance => Sort::Instance,
78 ComponentExternalKind::Component => Sort::Component,
79 }
80 }
81}
82use basic_conversions::*;
83
84#[derive(Debug)]
85#[allow(dead_code)]
86pub enum Error<'a> {
88 InvalidOuterAlias(substitute::InnerizeError),
91 IllFormedOuterAlias(wf::Error<'a>),
95 ResourceInDeclarator,
100 HandleToNonResource,
105 ValTypeRefToNonVal(Defined<'a>),
111 ClosingError(substitute::ClosingError),
117 IllFormed(wf::Error<'a>),
119}
120impl<'a> From<substitute::ClosingError> for Error<'a> {
121 fn from(e: substitute::ClosingError) -> Error<'a> {
122 Error::ClosingError(e)
123 }
124}
125
126impl<'p, 'a> Ctx<'p, 'a> {
131 pub fn elab_component<'c>(
132 &'c mut self,
133 decls: &[ComponentTypeDeclaration<'a>],
134 ) -> Result<Component<'a>, Error<'a>> {
135 let mut ctx = Ctx::new(Some(self), false);
136 let mut imports = Vec::new();
137 let mut exports = Vec::new();
138 for decl in decls {
139 let (import, export) = ctx.elab_component_decl(decl)?;
140 if let Some(import) = import {
141 imports.push(import);
142 }
143 if let Some(export) = export {
144 exports.push(export);
145 }
146 }
147 ctx.finish_component(&imports, &exports)
148 }
149
150 fn elab_core_module_decl<'c>(
151 &'c mut self,
152 decl: &ModuleTypeDeclaration<'a>,
153 ) -> (Option<wasmparser::Import<'a>>, Option<CoreExportDecl<'a>>) {
154 match decl {
155 ModuleTypeDeclaration::Import(i) => (Some(*i), None),
156 ModuleTypeDeclaration::Type(rg) => {
157 let ct = self.elab_core_type_rec(rg);
158 self.core.types.push(ct);
159 (None, None)
160 }
161 ModuleTypeDeclaration::OuterAlias {
162 kind: OuterAliasKind::Type,
163 count,
164 index,
165 } => {
166 let ct = self.parents().nth(*count as usize).unwrap().core.types[*index as usize]
167 .clone();
168 self.core.types.push(ct);
169 (None, None)
170 }
171 ModuleTypeDeclaration::Export { name, ty } => (
172 None,
173 Some(CoreExportDecl {
174 name: Name { name },
175 desc: match ty {
176 TypeRef::Func(n) => match &self.core.types[*n as usize] {
177 CoreDefined::Func(ft) => CoreExternDesc::Func(ft.clone()),
178 _ => panic!(
179 "internal invariant violation: WasmParser function TypeRef refers to non-function"
180 ),
181 },
182 TypeRef::Table(tt) => CoreExternDesc::Table(*tt),
183 TypeRef::Memory(mt) => CoreExternDesc::Memory(*mt),
184 TypeRef::Global(gt) => CoreExternDesc::Global(*gt),
185 TypeRef::Tag(_) => panic!("core type tags are not supported"),
186 TypeRef::FuncExact(_) => {
187 panic!("core type exact functions are not supported")
188 }
189 },
190 }),
191 ),
192 }
193 }
194
195 fn elab_core_module<'c>(&'c mut self, decls: &[ModuleTypeDeclaration<'a>]) -> CoreModule<'a> {
196 let mut ctx = Ctx::new(Some(self), false);
197 let mut imports = Vec::new();
198 let mut exports = Vec::new();
199 for decl in decls {
200 let (import, export) = ctx.elab_core_module_decl(decl);
201 if let Some(import) = import {
202 imports.push(import)
203 }
204 if let Some(export) = export {
205 exports.push(export)
206 }
207 }
208 CoreModule {
209 _imports: imports,
210 _exports: exports,
211 }
212 }
213
214 fn elab_core_type_rec<'c>(&'c mut self, rg: &wasmparser::RecGroup) -> CoreDefined<'a> {
215 match &rg.types().nth(0).unwrap().composite_type.inner {
216 CompositeInnerType::Func(ft) => CoreDefined::Func(ft.clone()),
217 _ => panic!("GC core types are not presently supported"),
218 }
219 }
220
221 fn elab_core_type<'c>(&'c mut self, ct: &wasmparser::CoreType<'a>) -> CoreDefined<'a> {
222 match ct {
223 CoreType::Rec(rg) => self.elab_core_type_rec(rg),
224 CoreType::Module(ds) => CoreDefined::Module(self.elab_core_module(ds)),
225 }
226 }
227
228 fn resolve_alias<'c>(
234 &'c mut self,
235 alias: &ComponentAlias<'a>,
236 ) -> Result<CoreOrComponentExternDesc<'a>, Error<'a>> {
237 match alias {
238 ComponentAlias::InstanceExport {
239 kind,
240 instance_index,
241 name,
242 } => {
243 let it = &self.instances[*instance_index as usize];
244 let ed = &it
245 .exports
246 .iter()
247 .find(|e| e.kebab_name == *name)
248 .unwrap()
249 .desc;
250 let sort = component_external_kind(*kind);
251 sort_matches_ed(sort, ed);
252 Ok(CoreOrComponentExternDesc::Component(ed.clone()))
253 }
254 ComponentAlias::CoreInstanceExport {
255 kind,
256 instance_index,
257 name,
258 } => {
259 let it = &self.core.instances[*instance_index as usize];
260 let ed = &it
261 .exports
262 .iter()
263 .find(|e| e.name.name == *name)
264 .unwrap()
265 .desc;
266 let sort = external_kind(*kind);
267 sort_matches_core_ed(sort, ed);
268 Ok(CoreOrComponentExternDesc::Core(ed.clone()))
269 }
270 ComponentAlias::Outer { kind, count, index } => {
271 if *kind != ComponentOuterAliasKind::Type {
272 panic!("In types, only outer type aliases are allowed");
273 }
274 let mut ctxs = self.parents().take(*count as usize + 1).collect::<Vec<_>>();
277 ctxs.reverse();
278 let mut target_type = ctxs[0].types[*index as usize].clone();
279 let mut ob_crossed = false;
280 for ctxs_ in ctxs.windows(2) {
281 ob_crossed |= ctxs_[1].outer_boundary;
282 let sub = substitute::Innerize::new(ctxs_[0], ctxs_[1].outer_boundary);
283 target_type = sub
284 .defined(&target_type)
285 .map_err(Error::InvalidOuterAlias)?;
286 }
287 if ob_crossed {
288 self.wf_defined(wf::DefinedTypePosition::export(), &target_type)
289 .map_err(Error::IllFormedOuterAlias)?;
290 }
291 Ok(CoreOrComponentExternDesc::Component(ExternDesc::Type(
292 target_type,
293 )))
294 }
295 }
296 }
297
298 fn add_core_ed<'c>(&'c mut self, ed: CoreExternDesc) {
301 match ed {
302 CoreExternDesc::Func(ft) => self.core.funcs.push(ft),
303 CoreExternDesc::Table(tt) => self.core.tables.push(tt),
304 CoreExternDesc::Memory(mt) => self.core.mems.push(mt),
305 CoreExternDesc::Global(gt) => self.core.globals.push(gt),
306 }
307 }
308
309 fn add_ed<'c>(&'c mut self, ed: &ExternDesc<'a>) {
318 match ed {
319 ExternDesc::CoreModule(cmd) => self.core.modules.push(cmd.clone()),
320 ExternDesc::Func(ft) => self.funcs.push(ft.clone()),
321 ExternDesc::Type(dt) => self.types.push(dt.clone()),
322 ExternDesc::Instance(it) => self.instances.push(it.clone()),
323 ExternDesc::Component(ct) => self.components.push(ct.clone()),
324 }
325 }
326
327 fn add_core_or_component_ed<'c>(&'c mut self, ed: CoreOrComponentExternDesc<'a>) {
328 match ed {
329 CoreOrComponentExternDesc::Core(ced) => self.add_core_ed(ced),
330 CoreOrComponentExternDesc::Component(ed) => self.add_ed(&ed),
331 }
332 }
333
334 fn elab_value<'c>(&'c mut self, ctr: &ComponentValType) -> Result<Value<'a>, Error<'a>> {
335 match ctr {
336 ComponentValType::Type(n) => match &self.types[*n as usize] {
337 Defined::Value(vt) => Ok(vt.clone()),
338 dt @ Defined::Handleable(Handleable::Var(tv)) => match self.resolve_tyvar(tv) {
339 ResolvedTyvar::Definite(Defined::Value(vt)) => {
340 Ok(Value::Var(Some(tv.clone()), Box::new(vt)))
341 }
342 _ => Err(Error::ValTypeRefToNonVal(dt.clone())),
343 },
344 dt => Err(Error::ValTypeRefToNonVal(dt.clone())),
345 },
346 ComponentValType::Primitive(pt) => Ok(match pt {
347 PrimitiveValType::Bool => Value::Bool,
348 PrimitiveValType::S8 => Value::S(IntWidth::I8),
349 PrimitiveValType::U8 => Value::U(IntWidth::I8),
350 PrimitiveValType::S16 => Value::S(IntWidth::I16),
351 PrimitiveValType::U16 => Value::U(IntWidth::I16),
352 PrimitiveValType::S32 => Value::S(IntWidth::I32),
353 PrimitiveValType::U32 => Value::U(IntWidth::I32),
354 PrimitiveValType::S64 => Value::S(IntWidth::I64),
355 PrimitiveValType::U64 => Value::U(IntWidth::I64),
356 PrimitiveValType::F32 => Value::F(FloatWidth::F32),
357 PrimitiveValType::F64 => Value::F(FloatWidth::F64),
358 PrimitiveValType::Char => Value::Char,
359 PrimitiveValType::String => Value::String,
360 PrimitiveValType::ErrorContext => panic!("async not yet supported"),
361 }),
362 }
363 }
364
365 fn elab_defined_value<'c>(
366 &'c mut self,
367 vt: &ComponentDefinedType<'a>,
368 ) -> Result<Value<'a>, Error<'a>> {
369 match vt {
370 ComponentDefinedType::Primitive(pvt) => {
371 self.elab_value(&ComponentValType::Primitive(*pvt))
372 }
373 ComponentDefinedType::Record(rfs) => {
374 let rfs = rfs
375 .iter()
376 .map(|(name, ty)| {
377 Ok::<_, Error<'a>>(RecordField {
378 name: Name { name },
379 ty: self.elab_value(ty)?,
380 })
381 })
382 .collect::<Result<Vec<_>, Error<'a>>>()?;
383 Ok(Value::Record(rfs))
384 }
385 ComponentDefinedType::Variant(vcs) => {
386 let vcs = vcs
387 .iter()
388 .map(|vc| {
389 Ok(VariantCase {
390 name: Name { name: vc.name },
391 ty: vc.ty.as_ref().map(|ty| self.elab_value(ty)).transpose()?,
392 })
393 })
394 .collect::<Result<Vec<_>, Error<'a>>>()?;
395 Ok(Value::Variant(vcs))
396 }
397 ComponentDefinedType::List(vt) => Ok(Value::List(Box::new(self.elab_value(vt)?))),
398 ComponentDefinedType::Tuple(vts) => Ok(Value::Tuple(
399 vts.iter()
400 .map(|vt| self.elab_value(vt))
401 .collect::<Result<Vec<_>, Error<'a>>>()?,
402 )),
403 ComponentDefinedType::Flags(ns) => {
404 Ok(Value::Flags(ns.iter().map(|n| Name { name: n }).collect()))
405 }
406 ComponentDefinedType::Enum(ns) => {
407 Ok(Value::Enum(ns.iter().map(|n| Name { name: n }).collect()))
408 }
409 ComponentDefinedType::Option(vt) => Ok(Value::Option(Box::new(self.elab_value(vt)?))),
410 ComponentDefinedType::Result { ok, err } => Ok(Value::Result(
411 Box::new(ok.map(|ok| self.elab_value(&ok)).transpose()?),
412 Box::new(err.map(|err| self.elab_value(&err)).transpose()?),
413 )),
414 ComponentDefinedType::Own(n) => match &self.types[*n as usize] {
415 Defined::Handleable(h) => Ok(Value::Own(h.clone())),
416 _ => Err(Error::HandleToNonResource),
417 },
418 ComponentDefinedType::Borrow(n) => match &self.types[*n as usize] {
419 Defined::Handleable(h) => Ok(Value::Borrow(h.clone())),
420 _ => Err(Error::HandleToNonResource),
421 },
422 ComponentDefinedType::FixedLengthList(vt, size) => {
423 Ok(Value::FixList(Box::new(self.elab_value(vt)?), *size))
424 }
425 ComponentDefinedType::Future(_) | ComponentDefinedType::Stream(_) => {
426 panic!("async not yet supported")
427 }
428 ComponentDefinedType::Map(_, _) => {
429 panic!("map type not yet supported")
430 }
431 }
432 }
433
434 fn elab_func<'c>(&'c mut self, ft: &ComponentFuncType<'a>) -> Result<Func<'a>, Error<'a>> {
435 if ft.async_ {
436 panic!("async not yet supported")
437 }
438 Ok(Func {
439 params: ft
440 .params
441 .iter()
442 .map(|(n, vt)| {
443 Ok(Param {
444 name: Name { name: n },
445 ty: self.elab_value(vt)?,
446 })
447 })
448 .collect::<Result<Vec<_>, Error<'a>>>()?,
449 result: ft
450 .result
451 .as_ref()
452 .map(|vt| self.elab_value(vt))
453 .transpose()?,
454 })
455 }
456
457 fn elab_extern_desc<'c>(
462 &'c mut self,
463 ed: &ComponentTypeRef,
464 ) -> Result<(Vec<BoundedTyvar<'a>>, ExternDesc<'a>), Error<'a>> {
465 match ed {
466 ComponentTypeRef::Module(i) => match &self.core.types[*i as usize] {
467 CoreDefined::Module(mt) => Ok((vec![], ExternDesc::CoreModule(mt.clone()))),
468 _ => {
469 panic!("internal invariant violation: bad sort for ComponentTypeRef to Module")
470 }
471 },
472 ComponentTypeRef::Func(i) => match &self.types[*i as usize] {
473 Defined::Func(ft) => Ok((vec![], ExternDesc::Func(ft.clone()))),
474 _ => panic!("internal invariant violation: bad sort for ComponentTypeRef to Func"),
475 },
476 ComponentTypeRef::Value(_) => panic!("First-class values are not yet supported"),
477 ComponentTypeRef::Type(tb) => {
478 let bound = match tb {
479 TypeBounds::Eq(i) => TypeBound::Eq(self.types[*i as usize].clone()),
480 TypeBounds::SubResource => TypeBound::SubResource,
481 };
482 let dt = Defined::Handleable(Handleable::Var(Tyvar::Bound(0)));
483 Ok((vec![BoundedTyvar::new(bound)], ExternDesc::Type(dt)))
484 }
485 ComponentTypeRef::Instance(i) => match &self.types[*i as usize] {
486 Defined::Instance(qit) => Ok((
487 qit.evars.clone(),
488 ExternDesc::Instance(qit.unqualified.clone()),
489 )),
490 _ => panic!(
491 "internal invariant violation: bad sort for ComponentTypeRef to Instance"
492 ),
493 },
494 ComponentTypeRef::Component(i) => match &self.types[*i as usize] {
495 Defined::Component(ct) => Ok((vec![], ExternDesc::Component(ct.clone()))),
496 _ => panic!(
497 "internal invariant violation: bad sort for ComponentTypeRef to Component"
498 ),
499 },
500 }
501 }
502
503 fn elab_instance_decl<'c>(
504 &'c mut self,
505 decl: &InstanceTypeDeclaration<'a>,
506 ) -> Result<Option<ExternDecl<'a>>, Error<'a>> {
507 match decl {
508 InstanceTypeDeclaration::CoreType(ct) => {
509 let ct = self.elab_core_type(ct);
510 self.core.types.push(ct);
511 Ok(None)
512 }
513 InstanceTypeDeclaration::Type(t) => {
514 let t = self.elab_defined(t)?;
515 if let Defined::Handleable(_) = t {
516 return Err(Error::ResourceInDeclarator);
517 }
518 self.types.push(t);
519 Ok(None)
520 }
521 InstanceTypeDeclaration::Alias(a) => {
522 let ed = self.resolve_alias(a)?;
523 self.add_core_or_component_ed(ed);
524 Ok(None)
525 }
526 InstanceTypeDeclaration::Export {
527 name: export_name,
528 ty,
529 } => {
530 let ComponentExternName {
531 name: kebab_name, ..
532 } = *export_name;
533 let (vs, ed) = self.elab_extern_desc(ty)?;
534 let sub = self.bound_to_evars(Some(kebab_name), &vs);
535 let ed = sub.extern_desc(&ed).not_void();
536 self.add_ed(&ed);
537 Ok(Some(ExternDecl {
538 kebab_name,
539 desc: ed,
540 }))
541 }
542 }
543 }
544
545 fn elab_instance<'c>(
546 &'c mut self,
547 decls: &[InstanceTypeDeclaration<'a>],
548 ) -> Result<QualifiedInstance<'a>, Error<'a>> {
549 let mut ctx = Ctx::new(Some(self), false);
550 let mut exports = Vec::new();
551 for decl in decls {
552 let export = ctx.elab_instance_decl(decl)?;
553 if let Some(export) = export {
554 exports.push(export);
555 }
556 }
557 ctx.finish_instance(&exports)
558 }
559
560 fn finish_instance_evars(
566 self,
567 exports: &[ExternDecl<'a>],
568 ) -> Result<QualifiedInstance<'a>, Error<'a>> {
569 let mut evars = Vec::new();
570 let mut sub = substitute::Closing::new(false);
571 for (bound, _) in self.evars {
572 let bound = sub.bounded_tyvar(&bound)?;
573 evars.push(bound);
574 sub.next_e();
575 }
576 let unqualified = sub.instance(&Instance {
577 exports: exports.to_vec(),
578 })?;
579 Ok(QualifiedInstance { evars, unqualified })
580 }
581
582 fn finish_instance(
589 self,
590 exports: &[ExternDecl<'a>],
591 ) -> Result<QualifiedInstance<'a>, Error<'a>> {
592 let fallback_parent = Ctx::new(None, false);
596 let parent_ctx = self.parent.unwrap_or(&fallback_parent);
597
598 let qi = self.finish_instance_evars(exports)?;
599 let raise_u_sub = substitute::Closing::new(true);
600 let it = raise_u_sub.qualified_instance(&qi)?;
601 parent_ctx
602 .wf_qualified_instance(wf::DefinedTypePosition::internal(), &it)
603 .map_err(Error::IllFormed)?;
604 Ok(it)
605 }
606
607 fn elab_component_decl<'c>(
608 &'c mut self,
609 decl: &ComponentTypeDeclaration<'a>,
610 ) -> Result<(Option<ExternDecl<'a>>, Option<ExternDecl<'a>>), Error<'a>> {
611 match decl {
612 ComponentTypeDeclaration::CoreType(ct) => {
613 let ct = self.elab_core_type(ct);
614 self.core.types.push(ct);
615 Ok((None, None))
616 }
617 ComponentTypeDeclaration::Type(t) => {
618 let t = self.elab_defined(t)?;
619 if let Defined::Handleable(_) = t {
620 return Err(Error::ResourceInDeclarator);
621 }
622 self.types.push(t);
623 Ok((None, None))
624 }
625 ComponentTypeDeclaration::Alias(a) => {
626 let ed = self.resolve_alias(a)?;
627 self.add_core_or_component_ed(ed);
628 Ok((None, None))
629 }
630 ComponentTypeDeclaration::Export {
631 name: export_name,
632 ty,
633 ..
634 } => {
635 let ComponentExternName {
636 name: kebab_name, ..
637 } = *export_name;
638 let (vs, ed) = self.elab_extern_desc(ty)?;
639 let sub = self.bound_to_evars(Some(kebab_name), &vs);
640 let ed = sub.extern_desc(&ed).not_void();
641 self.add_ed(&ed);
642 Ok((
643 None,
644 Some(ExternDecl {
645 kebab_name,
646 desc: ed,
647 }),
648 ))
649 }
650 ComponentTypeDeclaration::Import(i) => {
651 let ComponentExternName {
652 name: kebab_name, ..
653 } = i.name;
654 let (vs, ed) = self.elab_extern_desc(&i.ty)?;
655 let sub = self.bound_to_uvars(Some(kebab_name), &vs, true);
656 let ed = sub.extern_desc(&ed).not_void();
657 self.add_ed(&ed);
658 Ok((
659 Some(ExternDecl {
660 kebab_name,
661 desc: ed,
662 }),
663 None,
664 ))
665 }
666 }
667 }
668
669 fn finish_component(
672 self,
673 imports: &[ExternDecl<'a>],
674 exports: &[ExternDecl<'a>],
675 ) -> Result<Component<'a>, Error<'a>> {
676 let fallback_parent = Ctx::new(None, false);
680 let parent_ctx = self.parent.unwrap_or(&fallback_parent);
681
682 let mut uvars = Vec::new();
683 let mut sub = substitute::Closing::new(true);
684 for (bound, imported) in &self.uvars {
685 let bound = sub.bounded_tyvar(bound)?;
686 uvars.push(bound);
687 sub.next_u(*imported);
688 }
689 let imports = imports
690 .iter()
691 .map(|ed| sub.extern_decl(ed).map_err(Into::into))
692 .collect::<Result<Vec<ExternDecl<'a>>, Error<'a>>>()?;
693 let instance = sub.qualified_instance(&self.finish_instance_evars(exports)?)?;
694 let ct = Component {
695 uvars,
696 imports,
697 instance,
698 };
699 parent_ctx
700 .wf_component(wf::DefinedTypePosition::internal(), &ct)
701 .map_err(Error::IllFormed)?;
702 Ok(ct)
703 }
704
705 fn elab_defined<'c>(&'c mut self, dt: &ComponentType<'a>) -> Result<Defined<'a>, Error<'a>> {
706 match dt {
707 ComponentType::Defined(vt) => Ok(Defined::Value(self.elab_defined_value(vt)?)),
708 ComponentType::Func(ft) => Ok(Defined::Func(self.elab_func(ft)?)),
709 ComponentType::Component(cds) => Ok(Defined::Component(self.elab_component(cds)?)),
710 ComponentType::Instance(ids) => Ok(Defined::Instance(self.elab_instance(ids)?)),
711 ComponentType::Resource { dtor, .. } => {
712 let rid = ResourceId {
713 id: self.rtypes.len() as u32,
714 };
715 self.rtypes.push(Resource { _dtor: *dtor });
716 Ok(Defined::Handleable(Handleable::Resource(rid)))
717 }
718 }
719 }
720}