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