fxrazen/semantics/
thingy_factory.rs

1use crate::ns::*;
2
3pub struct ThingyFactory<'a>(pub(crate) &'a SemanticHost);
4
5impl<'a> ThingyFactory<'a> {
6    pub fn create_public_ns(&self, parent: Option<Thingy>) -> Thingy {
7        SystemNamespace::new(&self.0.arena, SystemNamespaceKind::Public, parent).into()
8    }
9
10    pub fn create_private_ns(&self, parent: Option<Thingy>) -> Thingy {
11        SystemNamespace::new(&self.0.arena, SystemNamespaceKind::Private, parent).into()
12    }
13
14    pub fn create_protected_ns(&self, parent: Option<Thingy>) -> Thingy {
15        SystemNamespace::new(&self.0.arena, SystemNamespaceKind::Protected, parent).into()
16    }
17
18    pub fn create_static_protected_ns(&self, parent: Option<Thingy>) -> Thingy {
19        SystemNamespace::new(&self.0.arena, SystemNamespaceKind::StaticProtected, parent).into()
20    }
21
22    pub fn create_internal_ns(&self, parent: Option<Thingy>) -> Thingy {
23        SystemNamespace::new(&self.0.arena, SystemNamespaceKind::Internal, parent).into()
24    }
25
26    pub fn create_explicit_ns(&self, uri: String) -> Thingy {
27        let mut mappings = self.0.explicit_namespaces.borrow_mut();
28        if let Some(ns) = mappings.get(&uri) {
29            return ns.clone();
30        }
31        let ns: Thingy = ExplicitNamespace::new(&self.0.arena, uri.clone()).into();
32        mappings.insert(uri, ns.clone());
33        ns
34    }
35
36    pub fn create_user_ns(&self, uri: String) -> Thingy {
37        let mut mappings = self.0.user_namespaces.borrow_mut();
38        if let Some(ns) = mappings.get(&uri) {
39            return ns.clone();
40        }
41        let ns: Thingy = UserNamespace::new(&self.0.arena, uri.clone()).into();
42        mappings.insert(uri, ns.clone());
43        ns
44    }
45
46    pub fn create_qname(&self, namespace: &Thingy, local_name: String) -> QName {
47        let mut ns_mappings = self.0.qnames.borrow_mut();
48        if let Some(qn_mappings) = ns_mappings.get_mut(namespace) {
49            if let Some(qn) = qn_mappings.get(&local_name) {
50                return qn.clone();
51            }
52            let qn = QName(Rc::new(QName1 {
53                m_namespace: namespace.clone(),
54                m_local_name: local_name.clone(),
55            }));
56            qn_mappings.insert(local_name, qn.clone());
57            return qn;
58        }
59        let qn = QName(Rc::new(QName1 {
60            m_namespace: namespace.clone(),
61            m_local_name: local_name.clone(),
62        }));
63        let mut qn_mappings = HashMap::new();
64        qn_mappings.insert(local_name, qn.clone());
65        ns_mappings.insert(namespace.clone(), qn_mappings);
66        qn
67    }
68
69    /// Interns a package from a fully qualified name.
70    ///
71    /// # Example
72    ///
73    /// ```ignore
74    /// assert_eq!(host.factory().create_package(["foo", "bar"]).fully_qualified_name(), "foo.bar");
75    /// ```
76    pub fn create_package<'b>(&self, name: impl IntoIterator<Item = &'b str>) -> Thingy {
77        self.create_package_1(&name.into_iter().collect())
78    }
79
80    fn create_package_1(&self, name: &Vec<&str>) -> Thingy {
81        let mut result: Thingy = self.0.top_level_package.clone();
82        for name_1 in name {
83            let name_1 = (*name_1).to_owned();
84            let result_1 = result.subpackages().get(&name_1);
85            if let Some(result_1) = result_1 {
86                result = result_1;
87            } else {
88                let result_1 = Package::new(&self.0.arena, name_1.clone());
89                result_1.set_parent(Some(result.clone().into()));
90
91                // Assign namespaces
92                result_1.set_public_ns(Some(self.create_public_ns(Some(result_1.clone().into()))));
93                result_1.set_internal_ns(Some(self.create_internal_ns(Some(result_1.clone().into()))));
94
95                result.subpackages().set(name_1, result_1.clone().into());
96                result = result_1.into();
97            }
98        }
99        result
100    }
101
102    pub fn create_alias(&self, name: QName, alias_of: Thingy) -> Thingy {
103        Alias::new(&self.0.arena, name, alias_of).into()
104    }
105
106    /// # Parameters
107    /// 
108    /// - `ns_for_prototype`: The namespace used for the `prototype` property. Either
109    ///   `public` or `internal`.
110    pub fn create_class_type(&self, name: QName, ns_for_prototype: &Thingy) -> Thingy {
111        let r = ClassType::new(&self.0.arena, name);
112        r.set_private_ns(Some(self.create_private_ns(Some(r.clone().into()))));
113        r.set_protected_ns(Some(self.create_protected_ns(Some(r.clone().into()))));
114        r.set_static_protected_ns(Some(self.create_static_protected_ns(Some(r.clone().into()))));
115
116        // "static const prototype: *;"
117        let prototype_name = self.create_qname(&ns_for_prototype, "prototype".into());
118        let prototype_slot = self.create_variable_slot(&prototype_name, true, &self.0.any_type());
119        prototype_slot.set_is_external(true);
120        r.properties(self.0).set(prototype_name.clone(), prototype_slot);
121
122        r.into()
123    }
124
125    pub fn create_enum_type(&self, name: QName, ns_for_prototype: &Thingy) -> Thingy {
126        let r = EnumType::new(&self.0.arena, name);
127        r.set_private_ns(Some(self.create_private_ns(Some(r.clone().into()))));
128
129        // "static const prototype: *;"
130        let prototype_name = self.create_qname(&ns_for_prototype, "prototype".into());
131        let prototype_slot = self.create_variable_slot(&prototype_name, true, &self.0.any_type());
132        prototype_slot.set_is_external(true);
133        r.properties(self.0).set(prototype_name.clone(), prototype_slot);
134
135        r.into()
136    }
137
138    pub fn create_interface_type(&self, name: QName) -> Thingy {
139        let r = InterfaceType::new(&self.0.arena, name);
140        r.into()
141    }
142
143    /// Interns type after substitution.
144    pub fn create_type_after_substitution(&self, origin: &Thingy, substitute_types: &SharedArray<Thingy>) -> Thingy {
145        // Verify parameter count
146        let params = origin.type_params().unwrap();
147        let param_count = params.length();
148        assert_eq!(substitute_types.length(), param_count);
149
150        let mut tas_list = self.0.types_after_sub.borrow_mut();
151
152        let mut list = tas_list.get(&origin);
153        let empty_list = vec![];
154        if list.is_none() {
155            list = Some(&empty_list);
156            tas_list.insert(origin.clone(), vec![]);
157        }
158        'tas: for tas in list.unwrap() {
159            let mut substitute_types_1 = substitute_types.iter();
160            let substitute_types_2 = tas.substitute_types();
161            let mut substitute_types_2 = substitute_types_2.iter();
162            while let Some(substitute_type_1) = substitute_types_1.next() {
163                let substitute_type_2 = substitute_types_2.next().unwrap();
164                if substitute_type_1 != substitute_type_2 {
165                    continue 'tas;
166                }
167            }
168            return tas.clone();
169        }
170
171        let tas = TypeAfterSubstitution::new(&self.0.arena, origin.clone(), substitute_types.clone());
172        let list = tas_list.get_mut(&origin).unwrap();
173        list.push(tas.clone().into());
174
175        tas.into()
176    }
177
178    /// Interns a tuple type.
179    pub fn create_tuple_type(&self, element_types: Vec<Thingy>) -> Thingy {
180        let element_count = element_types.len();
181        let mut tuple_types = self.0.tuple_types.borrow_mut();
182        let mut collection = tuple_types.get_mut(&element_count);
183        let mut empty_collection = vec![];
184        if collection.is_none() {
185            collection = Some(&mut empty_collection);
186            tuple_types.insert(element_count, vec![]);
187        }
188        'tt: for tt in collection.unwrap() {
189            let mut element_types_1 = element_types.iter();
190            let element_types_2 = tt.element_types();
191            let mut element_types_2 = element_types_2.iter();
192            while let Some(e_1) = element_types_1.next() {
193                let e_2 = element_types_2.next().unwrap();
194                if e_1 != &e_2 {
195                    continue 'tt;
196                }
197            }
198            return tt.clone();
199        }
200        let tt = TupleType::new(&self.0.arena, SharedArray::from(element_types));
201
202        let collection = tuple_types.get_mut(&element_count);
203        collection.unwrap().push(tt.clone().into());
204
205        tt.into()
206    }
207
208    /// Interns a function type.
209    pub fn create_function_type(&self, params: Vec<Rc<SemanticFunctionTypeParameter>>, result_type: Thingy) -> Thingy {
210        let param_count = params.len();
211        let mut function_types = self.0.function_types.borrow_mut();
212        let mut collection = function_types.get_mut(&param_count);
213        let mut empty_collection = vec![];
214        if collection.is_none() {
215            collection = Some(&mut empty_collection);
216            function_types.insert(params.len(), vec![]);
217        }
218        'ft: for ft in collection.unwrap() {
219            if result_type != ft.result_type() {
220                continue 'ft;
221            }
222            let mut params_1 = params.iter();
223            let params_2 = ft.params();
224            let mut params_2 = params_2.iter();
225            while let Some(param_1) = params_1.next() {
226                let param_2 = params_2.next().unwrap();
227                if !(param_1.kind == param_2.kind && && param_1.static_type == &&param_2.static_type) {
228                    continue 'ft;
229                }
230            }
231            return ft.clone();
232        }
233        let ft = FunctionType::new(&self.0.arena, SharedArray::from(params), result_type);
234
235        let collection = function_types.get_mut(&param_count);
236        collection.unwrap().push(ft.clone().into());
237
238        ft.into()
239    }
240
241    /// Interns a nullable type.
242    pub fn create_nullable_type(&self, base: &Thingy) -> Thingy {
243        if base == &self.0.any_type() || base.is::<NullableType>() {
244            return base.clone();
245        }
246        if base.is::<NonNullableType>() {
247            return base.base();
248        }
249        let mut m = self.0.nullable_types.borrow_mut();
250        let nt = m.get(base);
251        if let Some(nt) = nt {
252            return nt.clone();
253        }
254        let nt = NullableType::new(&self.0.arena, base.clone());
255        m.insert(base.clone(), nt.clone().into());
256        nt.into()
257    }
258
259    /// Interns a non nullable type.
260    pub fn create_non_nullable_type(&self, base: &Thingy) -> Thingy {
261        if base == &self.0.any_type() || base.is::<NonNullableType>() {
262            return base.clone();
263        }
264        let mut m = self.0.non_nullable_types.borrow_mut();
265        let nt = m.get(base);
266        if let Some(nt) = nt {
267            return nt.clone();
268        }
269        let nt = NonNullableType::new(&self.0.arena, base.clone());
270        m.insert(base.clone(), nt.clone().into());
271        nt.into()
272    }
273
274    pub fn create_type_parameter_type(&self, name: &QName) -> Thingy {
275        TypeParameterType::new(&self.0.arena, name.clone()).into()
276    }
277
278    pub fn create_variable_slot(&self, name: &QName, read_only: bool, static_type: &Thingy) -> Thingy {
279        OriginalVariableSlot::new(&self.0.arena, name, read_only, static_type).into()
280    }
281
282    /// Interns a variable slot after indirect substitution.
283    pub fn create_variable_slot_after_substitution(&self, origin: &Thingy, indirect_type_params: &SharedArray<Thingy>, indirect_substitute_types: &SharedArray<Thingy>) -> Thingy {
284        // Verify parameter count
285        assert_eq!(indirect_type_params.length(), indirect_substitute_types.length());
286
287        let mut vasub_list = self.0.vasub.borrow_mut();
288
289        let mut base_list = vasub_list.get_mut(origin);
290        let mut empty_base_list = HashMap::<SharedArray<Thingy>, Vec<Thingy>>::new();
291        if base_list.is_none() {
292            base_list = Some(&mut empty_base_list);
293            vasub_list.insert(origin.clone(), HashMap::new());
294        }
295        let base_list = base_list.unwrap();
296
297        let mut list = base_list.get(indirect_type_params);
298        let empty_list = vec![];
299        if list.is_none() {
300            list = Some(&empty_list);
301            base_list.insert(indirect_type_params.clone(), vec![]);
302        }
303        'vasub: for vasub in list.unwrap() {
304            let mut substitute_types_1 = indirect_substitute_types.iter();
305            let substitute_types_2 = vasub.indirect_substitute_types();
306            let mut substitute_types_2 = substitute_types_2.iter();
307            while let Some(substitute_type_1) = substitute_types_1.next() {
308                let substitute_type_2 = substitute_types_2.next().unwrap();
309                if substitute_type_1 != substitute_type_2 {
310                    continue 'vasub;
311                }
312            }
313            return vasub.clone();
314        }
315
316        let vasub = VariableSlotAfterSubstitution::new(
317            &self.0.arena,
318            &origin,
319            &indirect_type_params,
320            &indirect_substitute_types.clone());
321
322        let list = vasub_list.get_mut(origin).unwrap().get_mut(&indirect_type_params).unwrap();
323        list.push(vasub.clone().into());
324
325        vasub.into()
326    }
327
328    pub fn create_virtual_slot(&self, name: &QName) -> Thingy {
329        OriginalVirtualSlot::new(&self.0.arena, name).into()
330    }
331
332    /// Interns a virtual slot after indirect substitution.
333    pub fn create_virtual_slot_after_substitution(&self, origin: &Thingy, indirect_type_params: &SharedArray<Thingy>, indirect_substitute_types: &SharedArray<Thingy>) -> Thingy {
334        // Verify parameter count
335        assert_eq!(indirect_type_params.length(), indirect_substitute_types.length());
336
337        let mut visub_list = self.0.visub.borrow_mut();
338
339        let mut base_list = visub_list.get_mut(origin);
340        let mut empty_base_list = HashMap::<SharedArray<Thingy>, Vec<Thingy>>::new();
341        if base_list.is_none() {
342            base_list = Some(&mut empty_base_list);
343            visub_list.insert(origin.clone(), HashMap::new());
344        }
345        let base_list = base_list.unwrap();
346
347        let mut list = base_list.get(indirect_type_params);
348        let empty_list = vec![];
349        if list.is_none() {
350            list = Some(&empty_list);
351            base_list.insert(indirect_type_params.clone(), vec![]);
352        }
353        'visub: for visub in list.unwrap() {
354            let mut substitute_types_1 = indirect_substitute_types.iter();
355            let substitute_types_2 = visub.indirect_substitute_types();
356            let mut substitute_types_2 = substitute_types_2.iter();
357            while let Some(substitute_type_1) = substitute_types_1.next() {
358                let substitute_type_2 = substitute_types_2.next().unwrap();
359                if substitute_type_1 != substitute_type_2 {
360                    continue 'visub;
361                }
362            }
363            return visub.clone();
364        }
365
366        let visub = VirtualSlotAfterSubstitution::new(
367            &self.0.arena,
368            &origin,
369            &indirect_type_params,
370            &indirect_substitute_types.clone());
371
372        let list = visub_list.get_mut(origin).unwrap().get_mut(&indirect_type_params).unwrap();
373        list.push(visub.clone().into());
374
375        visub.into()
376    }
377
378    pub fn create_method_slot(&self, name: &QName, signature: &Thingy) -> Thingy {
379        OriginalMethodSlot::new(&self.0.arena, name, signature).into()
380    }
381
382    /// Interns a method slot after indirect substitution.
383    pub fn create_method_slot_after_substitution(&self, origin: &Thingy, indirect_type_params: &SharedArray<Thingy>, indirect_substitute_types: &SharedArray<Thingy>) -> Thingy {
384        // Verify parameter count
385        assert_eq!(indirect_type_params.length(), indirect_substitute_types.length());
386
387        let mut mssub_list = self.0.mssub.borrow_mut();
388
389        let mut base_list = mssub_list.get_mut(origin);
390        let mut empty_base_list = HashMap::<SharedArray<Thingy>, Vec<Thingy>>::new();
391        if base_list.is_none() {
392            base_list = Some(&mut empty_base_list);
393            mssub_list.insert(origin.clone(), HashMap::new());
394        }
395        let base_list = base_list.unwrap();
396
397        let mut list = base_list.get(indirect_type_params);
398        let empty_list = vec![];
399        if list.is_none() {
400            list = Some(&empty_list);
401            base_list.insert(indirect_type_params.clone(), vec![]);
402        }
403        'mssub: for mssub in list.unwrap() {
404            let mut substitute_types_1 = indirect_substitute_types.iter();
405            let substitute_types_2 = mssub.indirect_substitute_types();
406            let mut substitute_types_2 = substitute_types_2.iter();
407            while let Some(substitute_type_1) = substitute_types_1.next() {
408                let substitute_type_2 = substitute_types_2.next().unwrap();
409                if substitute_type_1 != substitute_type_2 {
410                    continue 'mssub;
411                }
412            }
413            return mssub.clone();
414        }
415
416        let mssub = MethodSlotAfterSubstitution::new(
417            &self.0.arena,
418            &origin,
419            &indirect_type_params,
420            &indirect_substitute_types.clone());
421
422        let list = mssub_list.get_mut(origin).unwrap().get_mut(&indirect_type_params).unwrap();
423        list.push(mssub.clone().into());
424
425        mssub.into()
426    }
427
428    pub fn create_scope(&self) -> Thingy {
429        Scope::new(&self.0.arena).into()
430    }
431
432    pub fn create_with_scope(&self, object: &Thingy) -> Thingy {
433        WithScope::new(&self.0.arena, object).into()
434    }
435
436    pub fn create_filter_scope(&self, base: &Thingy) -> Thingy {
437        FilterScope::new(&self.0.arena, base).into()
438    }
439
440    pub fn create_activation(&self, of_method: &Thingy) -> Thingy {
441        Activation::new(&self.0.arena, of_method).into()
442    }
443
444    pub fn create_class_scope(&self, class: &Thingy) -> Thingy {
445        ClassScope::new(&self.0.arena, class).into()
446    }
447
448    pub fn create_enum_scope(&self, class: &Thingy) -> Thingy {
449        EnumScope::new(&self.0.arena, class).into()
450    }
451
452    pub fn create_interface_scope(&self, itrfc: &Thingy) -> Thingy {
453        InterfaceScope::new(&self.0.arena, itrfc).into()
454    }
455
456    pub fn create_package_scope(&self, pckg: &Thingy) -> Thingy {
457        PackageScope::new(&self.0.arena, pckg).into()
458    }
459
460    pub fn create_value(&self, static_type: &Thingy) -> Thingy {
461        Value::new(&self.0.arena, static_type).into()
462    }
463
464    pub fn create_package_property_import(&self, property: &Thingy, location: Option<Location>) -> Thingy {
465        PackagePropertyImport::new(&self.0.arena, property, location, &self.0.any_type()).into()
466    }
467
468    pub fn create_package_wildcard_import(&self, package: &Thingy, location: Option<Location>) -> Thingy {
469        PackageWildcardImport::new(&self.0.arena, package, location, &self.0.any_type()).into()
470    }
471
472    pub fn create_package_recursive_import(&self, package: &Thingy, location: Option<Location>) -> Thingy {
473        PackageRecursiveImport::new(&self.0.arena, package, location, &self.0.any_type()).into()
474    }
475
476    pub fn create_undefined_constant(&self, static_type: &Thingy) -> Thingy {
477        UndefinedConstant::new(&self.0.arena, static_type).into()
478    }
479
480    pub fn create_null_constant(&self, static_type: &Thingy) -> Thingy {
481        NullConstant::new(&self.0.arena, static_type).into()
482    }
483
484    pub fn create_number_constant(&self, value: NumberVariant, static_type: &Thingy) -> Thingy {
485        NumberConstant::new(&self.0.arena, value, static_type).into()
486    }
487
488    pub fn create_string_constant(&self, value: String, static_type: &Thingy) -> Thingy {
489        StringConstant::new(&self.0.arena, value, static_type).into()
490    }
491
492    pub fn create_boolean_constant(&self, value: bool, static_type: &Thingy) -> Thingy {
493        BooleanConstant::new(&self.0.arena, value, static_type).into()
494    }
495
496    pub fn create_this_object(&self, static_type: &Thingy) -> Thingy {
497        ThisObject::new(&self.0.arena, static_type).into()
498    }
499
500    pub fn create_type_as_reference_value(&self, referenced_type: &Thingy) -> Result<Thingy, DeferError> {
501        Ok(TypeAsReferenceValue::new(&self.0.arena, referenced_type, &self.0.class_type().defer()?).into())
502    }
503
504    pub fn create_namespace_as_reference_value(&self, referenced_ns: &Thingy) -> Result<Thingy, DeferError> {
505        Ok(NamespaceAsReferenceValue::new(&self.0.arena, referenced_ns, &self.0.namespace_type().defer()?).into())
506    }
507
508    pub fn create_xml_reference_value(&self, base: &Thingy, qualifier: Option<Thingy>, key: &Thingy) -> Thingy {
509        XmlReferenceValue::new(&self.0.arena, base, qualifier, key, &self.0.any_type()).into()
510    }
511
512    pub fn create_dynamic_reference_value(&self, base: &Thingy, qualifier: Option<Thingy>, key: &Thingy) -> Thingy {
513        DynamicReferenceValue::new(&self.0.arena, base, qualifier, key, &self.0.any_type()).into()
514    }
515
516    pub fn create_array_element_reference_value(&self, base: &Thingy, key: &Thingy) -> Result<Thingy, DeferError> {
517        let st = base.static_type(self.0).defer()?.escape_of_non_nullable().array_element_type(self.0)?.unwrap();
518        Ok(ArrayElementReferenceValue::new(&self.0.arena, base, key, &st).into())
519    }
520
521    pub fn create_vector_element_reference_value(&self, base: &Thingy, key: &Thingy) -> Result<Thingy, DeferError> {
522        let st = base.static_type(self.0).defer()?.escape_of_non_nullable().vector_element_type(self.0)?.unwrap();
523        Ok(VectorElementReferenceValue::new(&self.0.arena, base, key, &st).into())
524    }
525
526    pub fn create_static_reference_value(&self, base: &Thingy, property: &Thingy) -> Result<Thingy, DeferError> {
527        Ok(StaticReferenceValue::new(&self.0.arena, base, property, &property.property_static_type(self.0).defer()?).into())
528    }
529
530    pub fn create_static_dynamic_reference_value(&self, base: &Thingy, qualifier: Option<Thingy>, key: &Thingy) -> Thingy {
531        StaticDynamicReferenceValue::new(&self.0.arena, base, qualifier, key, &self.0.any_type()).into()
532    }
533
534    pub fn create_instance_reference_value(&self, base: &Thingy, property: &Thingy) -> Result<Thingy, DeferError> {
535        Ok(InstanceReferenceValue::new(&self.0.arena, base, property, &property.property_static_type(self.0).defer()?).into())
536    }
537
538    pub fn create_tuple_reference_value(&self, base: &Thingy, index: usize) -> Thingy {
539        let st = base.static_type(self.0).element_types().get(index).unwrap();
540        TupleReferenceValue::new(&self.0.arena, base, index, &st).into()
541    }
542
543    pub fn create_scope_reference_value(&self, base: &Thingy, property: &Thingy) -> Result<Thingy, DeferError> {
544        Ok(ScopeReferenceValue::new(&self.0.arena, base, property, &property.property_static_type(self.0).defer()?).into())
545    }
546
547    pub fn create_dynamic_scope_reference_value(&self, base: &Thingy, qualifier: Option<Thingy>, key: &Thingy) -> Thingy {
548        DynamicScopeReferenceValue::new(&self.0.arena, base, qualifier, key, &self.0.any_type()).into()
549    }
550
551    pub fn create_package_reference_value(&self, base: &Thingy, property: &Thingy) -> Result<Thingy, DeferError> {
552        Ok(PackageReferenceValue::new(&self.0.arena, base, property, &property.property_static_type(self.0).defer()?).into())
553    }
554
555    pub fn create_conversion_value(&self, base: &Thingy, variant: TypeConversionVariant, opt: bool, target: &Thingy) -> Result<Thingy, DeferError> {
556        let mut st = if opt && !target.includes_null(self.0)? {
557            if target.is::<NonNullableType>() {
558                target.base()
559            } else {
560                self.create_nullable_type(target)
561            }
562        } else { target.clone() };
563        if opt && !st.includes_null(self.0)? {
564            st = self.create_nullable_type(target);
565        }
566        Ok(ConversionValue::new(&self.0.arena, base, variant, opt, target, &st).into())
567    }
568
569    pub fn create_lambda_object(&self, activation: &Thingy) -> Result<Thingy, DeferError> {
570        Ok(LambdaObject::new(&self.0.arena, activation, &self.0.function_type().defer()?).into())
571    }
572}