diff options
Diffstat (limited to 'vendor/windows-bindgen/src/winmd')
-rw-r--r-- | vendor/windows-bindgen/src/winmd/from_reader.rs | 74 | ||||
-rw-r--r-- | vendor/windows-bindgen/src/winmd/verify.rs | 33 | ||||
-rw-r--r-- | vendor/windows-bindgen/src/winmd/writer/file.rs | 2 | ||||
-rw-r--r-- | vendor/windows-bindgen/src/winmd/writer/mod.rs | 173 | ||||
-rw-r--r-- | vendor/windows-bindgen/src/winmd/writer/tables.rs | 2 | ||||
-rw-r--r-- | vendor/windows-bindgen/src/winmd/writer/type.rs | 4 |
6 files changed, 146 insertions, 142 deletions
diff --git a/vendor/windows-bindgen/src/winmd/from_reader.rs b/vendor/windows-bindgen/src/winmd/from_reader.rs index b535caed0..ed5f4d178 100644 --- a/vendor/windows-bindgen/src/winmd/from_reader.rs +++ b/vendor/windows-bindgen/src/winmd/from_reader.rs @@ -1,8 +1,7 @@ use super::*; use crate::winmd::{self, writer}; -use metadata::RowReader; -pub fn from_reader(reader: &metadata::Reader, filter: &metadata::Filter, config: std::collections::BTreeMap<&str, &str>, output: &str) -> crate::Result<()> { +pub fn from_reader(reader: &metadata::Reader, config: std::collections::BTreeMap<&str, &str>, output: &str) -> crate::Result<()> { let mut writer = winmd::Writer::new(output); // TODO: do we need any configuration values for winmd generation? @@ -16,37 +15,36 @@ pub fn from_reader(reader: &metadata::Reader, filter: &metadata::Filter, config: // TODO: just use the reader directly since we now have everything in the reader, there's no need to abstract // away the source format. Few reprs is always better. - for item in reader.items(filter) { + for item in reader.items() { // TODO: cover all variants let metadata::Item::Type(def) = item else { continue; }; - let generics = &metadata::type_def_generics(reader, def); + let generics = &metadata::type_def_generics(def); - let extends = if let Some(extends) = reader.type_def_extends(def) { writer.insert_type_ref(extends.namespace, extends.name) } else { 0 }; + let extends = if let Some(extends) = def.extends() { writer.insert_type_ref(extends.namespace, extends.name) } else { 0 }; writer.tables.TypeDef.push(writer::TypeDef { Extends: extends, FieldList: writer.tables.Field.len() as u32, - Flags: reader.type_def_flags(def).0, + Flags: def.flags().0, MethodList: writer.tables.MethodDef.len() as u32, - TypeName: writer.strings.insert(reader.type_def_name(def)), - TypeNamespace: writer.strings.insert(reader.type_def_namespace(def)), + TypeName: writer.strings.insert(def.name()), + TypeNamespace: writer.strings.insert(def.namespace()), }); - for generic in reader.type_def_generics(def) { + for generic in def.generics() { writer.tables.GenericParam.push(writer::GenericParam { - Number: reader.generic_param_number(generic), + Number: generic.number(), // TODO: isn't this just going to be incremental? Flags: 0, Owner: writer::TypeOrMethodDef::TypeDef(writer.tables.TypeDef.len() as u32 - 1).encode(), - Name: writer.strings.insert(reader.generic_param_name(generic)), + Name: writer.strings.insert(generic.name()), }); } - for imp in reader.type_def_interface_impls(def) { - let ty = reader.interface_impl_type(imp, generics); - let ty = winmd_type(reader, &ty); + for interface in metadata::type_def_interfaces(def, generics) { + let ty = winmd_type(&interface.ty); let reference = match &ty { winmd::Type::TypeRef(type_name) if type_name.generics.is_empty() => writer.insert_type_ref(&type_name.namespace, &type_name.name), @@ -61,31 +59,31 @@ pub fn from_reader(reader: &metadata::Reader, filter: &metadata::Filter, config: // TODO: if the class is "Apis" then should we sort the fields (constants) and methods (functions) for stability - for field in reader.type_def_fields(def) { - let ty = winmd_type(reader, &reader.field_type(field, Some(def))); + for field in def.fields() { + let ty = winmd_type(&field.ty(Some(def))); let signature = writer.insert_field_sig(&ty); - writer.tables.Field.push(writer::Field { Flags: reader.field_flags(field).0, Name: writer.strings.insert(reader.field_name(field)), Signature: signature }); + writer.tables.Field.push(writer::Field { Flags: field.flags().0, Name: writer.strings.insert(field.name()), Signature: signature }); } - for method in reader.type_def_methods(def) { - let signature = reader.method_def_signature(method, generics); - let return_type = winmd_type(reader, &signature.return_type); - let param_types: Vec<Type> = signature.params.iter().map(|param| winmd_type(reader, param)).collect(); + for method in def.methods() { + let signature = method.signature(generics); + let return_type = winmd_type(&signature.return_type); + let param_types: Vec<Type> = signature.params.iter().map(winmd_type).collect(); let signature = writer.insert_method_sig(signature.call_flags, &return_type, ¶m_types); writer.tables.MethodDef.push(winmd::MethodDef { RVA: 0, - ImplFlags: reader.method_def_impl_flags(method).0, - Flags: reader.method_def_flags(method).0, - Name: writer.strings.insert(reader.method_def_name(method)), + ImplFlags: method.impl_flags().0, + Flags: method.flags().0, + Name: writer.strings.insert(method.name()), Signature: signature, ParamList: writer.tables.Param.len() as u32, }); - for param in reader.method_def_params(method) { - writer.tables.Param.push(writer::Param { Flags: reader.param_flags(param).0, Sequence: reader.param_sequence(param), Name: writer.strings.insert(reader.param_name(param)) }); + for param in method.params() { + writer.tables.Param.push(writer::Param { Flags: param.flags().0, Sequence: param.sequence(), Name: writer.strings.insert(param.name()) }); } } } @@ -96,7 +94,7 @@ pub fn from_reader(reader: &metadata::Reader, filter: &metadata::Filter, config: } // TODO: keep the basic type conversion -fn winmd_type(reader: &metadata::Reader, ty: &metadata::Type) -> winmd::Type { +fn winmd_type(ty: &metadata::Type) -> winmd::Type { match ty { metadata::Type::Void => winmd::Type::Void, metadata::Type::Bool => winmd::Type::Bool, @@ -123,19 +121,15 @@ fn winmd_type(reader: &metadata::Reader, ty: &metadata::Type) -> winmd::Type { metadata::Type::PCSTR => winmd::Type::PCSTR, metadata::Type::PCWSTR => winmd::Type::PCWSTR, metadata::Type::BSTR => winmd::Type::BSTR, - metadata::Type::TypeName => winmd::Type::TypeName, - metadata::Type::TypeDef(def, generics) => winmd::Type::TypeRef(winmd::TypeName { - namespace: reader.type_def_namespace(*def).to_string(), - name: reader.type_def_name(*def).to_string(), - generics: generics.iter().map(|ty| winmd_type(reader, ty)).collect(), - }), - metadata::Type::GenericParam(generic) => winmd::Type::GenericParam(reader.generic_param_number(*generic)), - metadata::Type::ConstRef(ty) => winmd::Type::ConstRef(Box::new(winmd_type(reader, ty))), - metadata::Type::WinrtArrayRef(ty) => winmd::Type::WinrtArrayRef(Box::new(winmd_type(reader, ty))), - metadata::Type::WinrtArray(ty) => winmd::Type::WinrtArray(Box::new(winmd_type(reader, ty))), - metadata::Type::MutPtr(ty, pointers) => winmd::Type::MutPtr(Box::new(winmd_type(reader, ty)), *pointers), - metadata::Type::ConstPtr(ty, pointers) => winmd::Type::ConstPtr(Box::new(winmd_type(reader, ty)), *pointers), - metadata::Type::Win32Array(ty, len) => winmd::Type::Win32Array(Box::new(winmd_type(reader, ty)), *len), + metadata::Type::Type => winmd::Type::Type, + metadata::Type::TypeDef(def, generics) => winmd::Type::TypeRef(winmd::TypeName { namespace: def.namespace().to_string(), name: def.name().to_string(), generics: generics.iter().map(winmd_type).collect() }), + metadata::Type::GenericParam(generic) => winmd::Type::GenericParam(generic.number()), + metadata::Type::ConstRef(ty) => winmd::Type::ConstRef(Box::new(winmd_type(ty))), + metadata::Type::WinrtArrayRef(ty) => winmd::Type::WinrtArrayRef(Box::new(winmd_type(ty))), + metadata::Type::WinrtArray(ty) => winmd::Type::WinrtArray(Box::new(winmd_type(ty))), + metadata::Type::MutPtr(ty, pointers) => winmd::Type::MutPtr(Box::new(winmd_type(ty)), *pointers), + metadata::Type::ConstPtr(ty, pointers) => winmd::Type::ConstPtr(Box::new(winmd_type(ty)), *pointers), + metadata::Type::Win32Array(ty, len) => winmd::Type::Win32Array(Box::new(winmd_type(ty)), *len), rest => unimplemented!("{rest:?}"), } } diff --git a/vendor/windows-bindgen/src/winmd/verify.rs b/vendor/windows-bindgen/src/winmd/verify.rs index f10bd6524..c376d9d19 100644 --- a/vendor/windows-bindgen/src/winmd/verify.rs +++ b/vendor/windows-bindgen/src/winmd/verify.rs @@ -1,31 +1,42 @@ use super::*; -use metadata::RowReader; -pub fn verify(reader: &metadata::Reader, filter: &metadata::Filter) -> crate::Result<()> { - for item in reader.items(filter) { +pub fn verify(reader: &metadata::Reader) -> crate::Result<()> { + let unused: Vec<&str> = reader.unused().collect(); + + if !unused.is_empty() { + let mut message = "unused filters".to_string(); + + for unused in unused { + message.push_str(&format!("\n {unused}")); + } + + return Err(crate::Error::new(&message)); + } + + for item in reader.items() { // TODO: cover all variants let metadata::Item::Type(def) = item else { continue; }; - let generics = &metadata::type_def_generics(reader, def); + let generics = &metadata::type_def_generics(def); - reader.type_def_fields(def).try_for_each(|field| not_type_ref(reader, &reader.field_type(field, Some(def))))?; + def.fields().try_for_each(|field| not_type_ref(&field.ty(Some(def))))?; - reader.type_def_methods(def).try_for_each(|method| { - let sig = reader.method_def_signature(method, generics); - not_type_ref(reader, &sig.return_type)?; + def.methods().try_for_each(|method| { + let sig = method.signature(generics); + not_type_ref(&sig.return_type)?; - sig.params.iter().try_for_each(|param| not_type_ref(reader, param)) + sig.params.iter().try_for_each(not_type_ref) })?; } Ok(()) } -fn not_type_ref(reader: &metadata::Reader, ty: &metadata::Type) -> crate::Result<()> { +fn not_type_ref(ty: &metadata::Type) -> crate::Result<()> { if let metadata::Type::TypeRef(ty) = ty { - return Err(crate::Error::new(&format!("missing type definition `{}`", reader.type_def_or_ref(*ty)))); + return Err(crate::Error::new(&format!("missing type definition `{}`", ty))); } Ok(()) } diff --git a/vendor/windows-bindgen/src/winmd/writer/file.rs b/vendor/windows-bindgen/src/winmd/writer/file.rs index b452ba559..204358d94 100644 --- a/vendor/windows-bindgen/src/winmd/writer/file.rs +++ b/vendor/windows-bindgen/src/winmd/writer/file.rs @@ -1,5 +1,5 @@ use super::*; -use metadata::imp::*; +use metadata::*; use std::mem::*; pub fn write(mut tables: Vec<u8>, mut strings: Vec<u8>, mut blobs: Vec<u8>) -> Vec<u8> { diff --git a/vendor/windows-bindgen/src/winmd/writer/mod.rs b/vendor/windows-bindgen/src/winmd/writer/mod.rs index af49ecfeb..7ac4a08d6 100644 --- a/vendor/windows-bindgen/src/winmd/writer/mod.rs +++ b/vendor/windows-bindgen/src/winmd/writer/mod.rs @@ -9,7 +9,6 @@ mod r#type; use super::*; use blobs::Blobs; pub use codes::*; -use metadata::imp::*; pub use r#type::*; use std::collections::HashMap; use strings::Strings; @@ -150,39 +149,39 @@ impl Writer { fn type_blob(&mut self, ty: &Type, blob: &mut Vec<u8>) { match ty { - Type::Void => blob.push(ELEMENT_TYPE_VOID), - Type::Bool => blob.push(ELEMENT_TYPE_BOOLEAN), - Type::Char => blob.push(ELEMENT_TYPE_CHAR), - Type::I8 => blob.push(ELEMENT_TYPE_I1), - Type::U8 => blob.push(ELEMENT_TYPE_U1), - Type::I16 => blob.push(ELEMENT_TYPE_I2), - Type::U16 => blob.push(ELEMENT_TYPE_U2), - Type::I32 => blob.push(ELEMENT_TYPE_I4), - Type::U32 => blob.push(ELEMENT_TYPE_U4), - Type::I64 => blob.push(ELEMENT_TYPE_I8), - Type::U64 => blob.push(ELEMENT_TYPE_U8), - Type::F32 => blob.push(ELEMENT_TYPE_R4), - Type::F64 => blob.push(ELEMENT_TYPE_R8), - Type::ISize => blob.push(ELEMENT_TYPE_I), - Type::USize => blob.push(ELEMENT_TYPE_U), - Type::String => blob.push(ELEMENT_TYPE_STRING), - Type::IInspectable => blob.push(ELEMENT_TYPE_OBJECT), + Type::Void => blob.push(metadata::ELEMENT_TYPE_VOID), + Type::Bool => blob.push(metadata::ELEMENT_TYPE_BOOLEAN), + Type::Char => blob.push(metadata::ELEMENT_TYPE_CHAR), + Type::I8 => blob.push(metadata::ELEMENT_TYPE_I1), + Type::U8 => blob.push(metadata::ELEMENT_TYPE_U1), + Type::I16 => blob.push(metadata::ELEMENT_TYPE_I2), + Type::U16 => blob.push(metadata::ELEMENT_TYPE_U2), + Type::I32 => blob.push(metadata::ELEMENT_TYPE_I4), + Type::U32 => blob.push(metadata::ELEMENT_TYPE_U4), + Type::I64 => blob.push(metadata::ELEMENT_TYPE_I8), + Type::U64 => blob.push(metadata::ELEMENT_TYPE_U8), + Type::F32 => blob.push(metadata::ELEMENT_TYPE_R4), + Type::F64 => blob.push(metadata::ELEMENT_TYPE_R8), + Type::ISize => blob.push(metadata::ELEMENT_TYPE_I), + Type::USize => blob.push(metadata::ELEMENT_TYPE_U), + Type::String => blob.push(metadata::ELEMENT_TYPE_STRING), + Type::IInspectable => blob.push(metadata::ELEMENT_TYPE_OBJECT), Type::GUID => { let code = self.insert_type_ref("System", "Guid"); - blob.push(ELEMENT_TYPE_VALUETYPE); + blob.push(metadata::ELEMENT_TYPE_VALUETYPE); usize_blob(code as usize, blob); } Type::HRESULT => { let code = self.insert_type_ref("Windows.Foundation", "HResult"); - blob.push(ELEMENT_TYPE_VALUETYPE); + blob.push(metadata::ELEMENT_TYPE_VALUETYPE); usize_blob(code as usize, blob); } Type::TypeRef(ty) => { if !ty.generics.is_empty() { - blob.push(ELEMENT_TYPE_GENERICINST); + blob.push(metadata::ELEMENT_TYPE_GENERICINST); } let code = self.insert_type_ref(&ty.namespace, &ty.name); - blob.push(ELEMENT_TYPE_VALUETYPE); + blob.push(metadata::ELEMENT_TYPE_VALUETYPE); usize_blob(code as usize, blob); if !ty.generics.is_empty() { @@ -195,59 +194,59 @@ impl Writer { } Type::BSTR => { let code = self.insert_type_ref("Windows.Win32.Foundation", "BSTR"); - blob.push(ELEMENT_TYPE_VALUETYPE); + blob.push(metadata::ELEMENT_TYPE_VALUETYPE); usize_blob(code as usize, blob); } Type::IUnknown => { let code = self.insert_type_ref("Windows.Win32.Foundation", "IUnknown"); - blob.push(ELEMENT_TYPE_VALUETYPE); + blob.push(metadata::ELEMENT_TYPE_VALUETYPE); usize_blob(code as usize, blob); } Type::PCWSTR | Type::PWSTR => { let code = self.insert_type_ref("Windows.Win32.Foundation", "PWSTR"); - blob.push(ELEMENT_TYPE_VALUETYPE); + blob.push(metadata::ELEMENT_TYPE_VALUETYPE); usize_blob(code as usize, blob); } Type::PCSTR | Type::PSTR => { let code = self.insert_type_ref("Windows.Win32.Foundation", "PSTR"); - blob.push(ELEMENT_TYPE_VALUETYPE); + blob.push(metadata::ELEMENT_TYPE_VALUETYPE); usize_blob(code as usize, blob); } Type::ConstRef(ty) => { - usize_blob(ELEMENT_TYPE_CMOD_OPT as usize, blob); + usize_blob(metadata::ELEMENT_TYPE_CMOD_OPT as usize, blob); usize_blob(self.insert_type_ref("System.Runtime.CompilerServices", "IsConst") as usize, blob); - usize_blob(ELEMENT_TYPE_BYREF as usize, blob); + usize_blob(metadata::ELEMENT_TYPE_BYREF as usize, blob); self.type_blob(ty, blob); } Type::WinrtArrayRef(ty) => { - usize_blob(ELEMENT_TYPE_BYREF as usize, blob); - usize_blob(ELEMENT_TYPE_SZARRAY as usize, blob); + usize_blob(metadata::ELEMENT_TYPE_BYREF as usize, blob); + usize_blob(metadata::ELEMENT_TYPE_SZARRAY as usize, blob); self.type_blob(ty, blob); } Type::WinrtArray(ty) => { - usize_blob(ELEMENT_TYPE_SZARRAY as usize, blob); + usize_blob(metadata::ELEMENT_TYPE_SZARRAY as usize, blob); self.type_blob(ty, blob); } Type::Win32Array(ty, bounds) => { - usize_blob(ELEMENT_TYPE_ARRAY as usize, blob); + usize_blob(metadata::ELEMENT_TYPE_ARRAY as usize, blob); self.type_blob(ty, blob); usize_blob(1, blob); // rank usize_blob(1, blob); // count usize_blob(*bounds, blob); } - Type::TypeName => { + Type::Type => { let code = self.insert_type_ref("System", "Type"); - blob.push(ELEMENT_TYPE_CLASS); + blob.push(metadata::ELEMENT_TYPE_CLASS); usize_blob(code as usize, blob); } Type::MutPtr(ty, pointers) | Type::ConstPtr(ty, pointers) => { for _ in 0..*pointers { - usize_blob(ELEMENT_TYPE_PTR as usize, blob); + usize_blob(metadata::ELEMENT_TYPE_PTR as usize, blob); } self.type_blob(ty, blob); } Type::GenericParam(index) => { - blob.push(ELEMENT_TYPE_VAR); + blob.push(metadata::ELEMENT_TYPE_VAR); usize_blob(*index as usize, blob); } } @@ -276,54 +275,54 @@ fn usize_blob(value: usize, blob: &mut Vec<u8>) { } } -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_usize_blob() { - let mut blob = vec![]; - usize_blob(0, &mut blob); - usize_blob(1, &mut blob); - usize_blob(2, &mut blob); - - usize_blob(0x80 - 2, &mut blob); - usize_blob(0x80 - 1, &mut blob); - usize_blob(0x80, &mut blob); - usize_blob(0x80 + 1, &mut blob); - usize_blob(0x80 + 2, &mut blob); - - usize_blob(0x4000 - 2, &mut blob); - usize_blob(0x4000 - 1, &mut blob); - usize_blob(0x4000, &mut blob); - usize_blob(0x4000 + 1, &mut blob); - usize_blob(0x4000 + 2, &mut blob); - - usize_blob(0x20000000 - 3, &mut blob); - usize_blob(0x20000000 - 2, &mut blob); - usize_blob(0x20000000 - 1, &mut blob); - - let mut blob = metadata::Blob::new(0, &blob); - assert_eq!(blob.read_usize(), 0); - assert_eq!(blob.read_usize(), 1); - assert_eq!(blob.read_usize(), 2); - - assert_eq!(blob.read_usize(), 0x80 - 2); - assert_eq!(blob.read_usize(), 0x80 - 1); - assert_eq!(blob.read_usize(), 0x80); - assert_eq!(blob.read_usize(), 0x80 + 1); - assert_eq!(blob.read_usize(), 0x80 + 2); - - assert_eq!(blob.read_usize(), 0x4000 - 2); - assert_eq!(blob.read_usize(), 0x4000 - 1); - assert_eq!(blob.read_usize(), 0x4000); - assert_eq!(blob.read_usize(), 0x4000 + 1); - assert_eq!(blob.read_usize(), 0x4000 + 2); - - assert_eq!(blob.read_usize(), 0x20000000 - 3); - assert_eq!(blob.read_usize(), 0x20000000 - 2); - assert_eq!(blob.read_usize(), 0x20000000 - 1); - - assert_eq!(blob.slice.len(), 0); - } -} +// #[cfg(test)] +// mod tests { +// use super::*; + +// #[test] +// fn test_usize_blob() { +// let mut blob = vec![]; +// usize_blob(0, &mut blob); +// usize_blob(1, &mut blob); +// usize_blob(2, &mut blob); + +// usize_blob(0x80 - 2, &mut blob); +// usize_blob(0x80 - 1, &mut blob); +// usize_blob(0x80, &mut blob); +// usize_blob(0x80 + 1, &mut blob); +// usize_blob(0x80 + 2, &mut blob); + +// usize_blob(0x4000 - 2, &mut blob); +// usize_blob(0x4000 - 1, &mut blob); +// usize_blob(0x4000, &mut blob); +// usize_blob(0x4000 + 1, &mut blob); +// usize_blob(0x4000 + 2, &mut blob); + +// usize_blob(0x20000000 - 3, &mut blob); +// usize_blob(0x20000000 - 2, &mut blob); +// usize_blob(0x20000000 - 1, &mut blob); + +// let mut blob = metadata::Blob::new(0, &blob); +// assert_eq!(blob.read_usize(), 0); +// assert_eq!(blob.read_usize(), 1); +// assert_eq!(blob.read_usize(), 2); + +// assert_eq!(blob.read_usize(), 0x80 - 2); +// assert_eq!(blob.read_usize(), 0x80 - 1); +// assert_eq!(blob.read_usize(), 0x80); +// assert_eq!(blob.read_usize(), 0x80 + 1); +// assert_eq!(blob.read_usize(), 0x80 + 2); + +// assert_eq!(blob.read_usize(), 0x4000 - 2); +// assert_eq!(blob.read_usize(), 0x4000 - 1); +// assert_eq!(blob.read_usize(), 0x4000); +// assert_eq!(blob.read_usize(), 0x4000 + 1); +// assert_eq!(blob.read_usize(), 0x4000 + 2); + +// assert_eq!(blob.read_usize(), 0x20000000 - 3); +// assert_eq!(blob.read_usize(), 0x20000000 - 2); +// assert_eq!(blob.read_usize(), 0x20000000 - 1); + +// assert_eq!(blob.slice.len(), 0); +// } +// } diff --git a/vendor/windows-bindgen/src/winmd/writer/tables.rs b/vendor/windows-bindgen/src/winmd/writer/tables.rs index 4d4b8e354..a18aceae8 100644 --- a/vendor/windows-bindgen/src/winmd/writer/tables.rs +++ b/vendor/windows-bindgen/src/winmd/writer/tables.rs @@ -2,7 +2,7 @@ use super::Write; use super::*; -use metadata::imp::coded_index_size; +use metadata::*; #[derive(Default)] pub struct Tables { diff --git a/vendor/windows-bindgen/src/winmd/writer/type.rs b/vendor/windows-bindgen/src/winmd/writer/type.rs index 3f0178654..f04f86636 100644 --- a/vendor/windows-bindgen/src/winmd/writer/type.rs +++ b/vendor/windows-bindgen/src/winmd/writer/type.rs @@ -1,4 +1,4 @@ -#![allow(dead_code, clippy::upper_case_acronyms)] +#![allow(dead_code, clippy::upper_case_acronyms, clippy::enum_variant_names)] #[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct TypeName { @@ -34,7 +34,7 @@ pub enum Type { PCSTR, PCWSTR, BSTR, - TypeName, + Type, TypeRef(TypeName), GenericParam(u16), MutPtr(Box<Self>, usize), |