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