From 56600e68eb30252b9e553e36f76d14ed47ff9591 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 7 May 2021 10:36:48 +0100 Subject: [PATCH 1/6] Replace NonZeroU32 type ids with u32 --- src/interner.rs | 57 ++++++---------- src/registry.rs | 15 ++--- test_suite/tests/codec.rs | 4 +- test_suite/tests/json.rs | 132 +++++++++++++++++++------------------- 4 files changed, 93 insertions(+), 115 deletions(-) diff --git a/src/interner.rs b/src/interner.rs index 5fc7b55c..e6343b9b 100644 --- a/src/interner.rs +++ b/src/interner.rs @@ -28,7 +28,6 @@ use crate::prelude::{ Entry, }, marker::PhantomData, - num::NonZeroU32, vec::Vec, }; @@ -42,39 +41,19 @@ use serde::{ /// /// This can be used by self-referential types but /// can no longer be used to resolve instances. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, scale::Encode, scale::Decode)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(transparent))] pub struct UntrackedSymbol { /// The index to the symbol in the interner table. - id: NonZeroU32, + id: u32, #[cfg_attr(feature = "serde", serde(skip))] marker: PhantomData T>, } -impl scale::Encode for UntrackedSymbol { - fn encode_to(&self, dest: &mut W) { - self.id.get().encode_to(dest) - } -} - -impl scale::Decode for UntrackedSymbol { - fn decode(value: &mut I) -> Result { - let id = ::decode(value)?; - if id < 1 { - return Err("UntrackedSymbol::id should be a non-zero unsigned integer".into()) - } - let id = NonZeroU32::new(id).expect("ID is non zero"); - Ok(UntrackedSymbol { - id, - marker: Default::default(), - }) - } -} - impl UntrackedSymbol { /// Returns the index to the symbol in the interner table. - pub fn id(&self) -> NonZeroU32 { + pub fn id(&self) -> u32 { self.id } } @@ -86,7 +65,7 @@ impl UntrackedSymbol { #[cfg_attr(feature = "serde", derive(Serialize))] #[cfg_attr(feature = "serde", serde(transparent))] pub struct Symbol<'a, T> { - id: NonZeroU32, + id: u32, #[cfg_attr(feature = "serde", serde(skip))] marker: PhantomData &'a T>, } @@ -181,7 +160,7 @@ where ( inserted, Symbol { - id: NonZeroU32::new((sym_id + 1) as u32).unwrap(), + id: sym_id as u32, marker: PhantomData, }, ) @@ -192,7 +171,7 @@ where pub fn get(&self, s: &T) -> Option> { self.map.get(s).map(|&id| { Symbol { - id: NonZeroU32::new(id as u32).unwrap(), + id: id as u32, marker: PhantomData, } }) @@ -201,7 +180,7 @@ where /// Resolves the original element given its associated symbol or /// returns `None` if it has not been interned yet. pub fn resolve(&self, sym: Symbol) -> Option<&T> { - let idx = (sym.id.get() - 1) as usize; + let idx = sym.id as usize; if idx >= self.vec.len() { return None } @@ -220,7 +199,7 @@ mod tests { new_symbol: &'static str, expected_id: u32, ) { - let actual_id = interner.intern_or_get(new_symbol).1.id.get(); + let actual_id = interner.intern_or_get(new_symbol).1.id; assert_eq!(actual_id, expected_id,); } @@ -229,7 +208,7 @@ mod tests { E: Into>, { let actual_str = interner.resolve(Symbol { - id: NonZeroU32::new(symbol_id).unwrap(), + id: symbol_id, marker: PhantomData, }); assert_eq!(actual_str.cloned(), expected_str.into(),); @@ -238,14 +217,14 @@ mod tests { #[test] fn simple() { let mut interner = StringInterner::new(); - assert_id(&mut interner, "Hello", 1); - assert_id(&mut interner, ", World!", 2); - assert_id(&mut interner, "1 2 3", 3); - assert_id(&mut interner, "Hello", 1); - - assert_resolve(&mut interner, 1, "Hello"); - assert_resolve(&mut interner, 2, ", World!"); - assert_resolve(&mut interner, 3, "1 2 3"); - assert_resolve(&mut interner, 4, None); + assert_id(&mut interner, "Hello", 0); + assert_id(&mut interner, ", World!", 1); + assert_id(&mut interner, "1 2 3", 2); + assert_id(&mut interner, "Hello", 0); + + assert_resolve(&mut interner, 0, "Hello"); + assert_resolve(&mut interner, 1, ", World!"); + assert_resolve(&mut interner, 2, "1 2 3"); + assert_resolve(&mut interner, 3, None); } } diff --git a/src/registry.rs b/src/registry.rs index 5678d121..7655a865 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -27,7 +27,6 @@ use crate::prelude::{ any::TypeId, collections::BTreeMap, fmt::Debug, - num::NonZeroU32, vec::Vec, }; @@ -178,14 +177,14 @@ impl From for PortableRegistry { impl PortableRegistry { /// Returns the type definition for the given identifier, `None` if no type found for that ID. - pub fn resolve(&self, id: NonZeroU32) -> Option<&Type> { - self.types.get((id.get() - 1) as usize) + pub fn resolve(&self, id: u32) -> Option<&Type> { + self.types.get(id as usize) } - /// Returns an iterator for all types paired with their associated NonZeroU32 identifier. - pub fn enumerate(&self) -> impl Iterator)> { + /// Returns an iterator for all types paired with their associated u32 identifier. + pub fn enumerate(&self) -> impl Iterator)> { self.types.iter().enumerate().map(|(i, ty)| { - let id = NonZeroU32::new(i as u32 + 1).expect("i + 1 > 0; qed"); + let id = i as u32; (id, ty) }) } @@ -213,9 +212,9 @@ mod tests { assert_eq!(4, readonly.enumerate().count()); - let mut expected = 1; + let mut expected = 0; for (i, _) in readonly.enumerate() { - assert_eq!(NonZeroU32::new(expected).unwrap(), i); + assert_eq!(expected, i); expected += 1; } } diff --git a/test_suite/tests/codec.rs b/test_suite/tests/codec.rs index cfe41a97..f80ebbb2 100644 --- a/test_suite/tests/codec.rs +++ b/test_suite/tests/codec.rs @@ -64,7 +64,7 @@ fn scale_encode_then_decode_to_readonly() { let readonly_decoded = PortableRegistry::decode(&mut &encoded[..]).unwrap(); assert!(readonly_decoded - .resolve(NonZeroU32::new(1).unwrap()) + .resolve(0) .is_some()); let decoded_serialized = serde_json::to_value(readonly_decoded).unwrap(); @@ -82,7 +82,7 @@ fn json_serialize_then_deserialize_to_readonly() { let readonly_deserialized: PortableRegistry = serde_json::from_value(original_serialized.clone()).unwrap(); assert!(readonly_deserialized - .resolve(NonZeroU32::new(1).unwrap()) + .resolve(0) .is_some()); let readonly_serialized = serde_json::to_value(readonly_deserialized).unwrap(); diff --git a/test_suite/tests/json.rs b/test_suite/tests/json.rs index 9ece5fc3..a1951540 100644 --- a/test_suite/tests/json.rs +++ b/test_suite/tests/json.rs @@ -69,32 +69,32 @@ fn test_primitives() { fn test_builtins() { // arrays assert_json_for_type::<[u8; 2]>( - json!({ "def": { "array": { "len": 2, "type": 1 } } }), + json!({ "def": { "array": { "len": 2, "type": 0 } } }), ); assert_json_for_type::<[bool; 4]>( - json!({ "def": { "array": { "len": 4, "type": 1 } } }), + json!({ "def": { "array": { "len": 4, "type": 0 } } }), ); assert_json_for_type::<[char; 8]>( - json!({ "def": { "array": { "len": 8, "type": 1 } } }), + json!({ "def": { "array": { "len": 8, "type": 0 } } }), ); // tuples - assert_json_for_type::<(u8, bool)>(json!({ "def": { "tuple": [ 1, 2 ] } })); + assert_json_for_type::<(u8, bool)>(json!({ "def": { "tuple": [ 0, 1 ] } })); assert_json_for_type::<(u8, bool, char, u128)>( - json!({ "def": { "tuple": [ 1, 2, 3, 4 ] } }), + json!({ "def": { "tuple": [ 0, 1, 2, 3 ] } }), ); assert_json_for_type::<(u8, bool, char, u128, i32, u32)>(json!({ "def": { - "tuple": [ 1, 2, 3, 4, 5, 6 ] + "tuple": [ 0, 1, 2, 3, 4, 5 ] } })); // sequences - assert_json_for_type::<[bool]>(json!({ "def": { "sequence": { "type": 1 } } })); - assert_json_for_type::<&[bool]>(json!({ "def": { "sequence": { "type": 1 } } })); - assert_json_for_type::>(json!({ "def": { "sequence": { "type": 1 } } })); + assert_json_for_type::<[bool]>(json!({ "def": { "sequence": { "type": 0 } } })); + assert_json_for_type::<&[bool]>(json!({ "def": { "sequence": { "type": 0 } } })); + assert_json_for_type::>(json!({ "def": { "sequence": { "type": 0 } } })); // complex types assert_json_for_type::>(json!({ "path": ["Option"], - "params": [1], + "params": [0], "def": { "variant": { "variants": [ @@ -103,7 +103,7 @@ fn test_builtins() { }, { "name": "Some", - "fields": [ { "type": 1, "typeName": "T" } ] + "fields": [ { "type": 0, "typeName": "T" } ] }, ] } @@ -111,17 +111,17 @@ fn test_builtins() { })); assert_json_for_type::>(json!({ "path": ["Result"], - "params": [1, 2], + "params": [0, 1], "def": { "variant": { "variants": [ { "name": "Ok", - "fields": [ { "type": 1, "typeName": "T" } ] + "fields": [ { "type": 0, "typeName": "T" } ] }, { "name": "Err", - "fields": [ { "type": 2, "typeName": "E" } ] + "fields": [ { "type": 1, "typeName": "E" } ] } ] } @@ -136,7 +136,7 @@ fn test_builtins() { assert_json_for_type::(json!({ "def": { "primitive": "str" } })); // PhantomData assert_json_for_type::>( - json!({ "def": { "phantom": { "type": 1 } }, }), + json!({ "def": { "phantom": { "type": 0 } }, }), ) } @@ -163,9 +163,9 @@ fn test_tuplestruct() { "def": { "composite": { "fields": [ - { "type": 1, "typeName": "i32" }, - { "type": 2, "typeName": "[u8; 32]" }, - { "type": 4, "typeName": "bool" }, + { "type": 0, "typeName": "i32" }, + { "type": 1, "typeName": "[u8; 32]" }, + { "type": 3, "typeName": "bool" }, ], }, } @@ -186,9 +186,9 @@ fn test_struct() { "def": { "composite": { "fields": [ - { "name": "a", "type": 1, "typeName": "i32" }, - { "name": "b", "type": 2, "typeName": "[u8; 32]" }, - { "name": "c", "type": 4, "typeName": "bool" }, + { "name": "a", "type": 0, "typeName": "i32" }, + { "name": "b", "type": 1, "typeName": "[u8; 32]" }, + { "name": "c", "type": 3, "typeName": "bool" }, ], }, } @@ -233,10 +233,10 @@ fn test_struct_with_some_fields_marked_as_compact() { "def": { "composite": { "fields": [ - { "name": "a", "type": 1, "typeName": "u128" }, - { "name": "a_not_compact", "type": 2, "typeName": "u128" }, - { "name": "b", "type": 3, "typeName": "[u8; 32]" }, - { "name": "c", "type": 5, "typeName": "u64" }, + { "name": "a", "type": 0, "typeName": "u128" }, + { "name": "a_not_compact", "type": 1, "typeName": "u128" }, + { "name": "b", "type": 2, "typeName": "[u8; 32]" }, + { "name": "c", "type": 4, "typeName": "u64" }, ], }, } @@ -254,13 +254,13 @@ fn test_struct_with_phantom() { assert_json_for_type::>(json!({ "path": ["json", "Struct"], - "params": [1], + "params": [0], "def": { "composite": { "fields": [ - { "name": "a", "type": 2, "typeName": "i32" }, + { "name": "a", "type": 1, "typeName": "i32" }, // type 1 is the `u8` in the `PhantomData` - { "name": "b", "type": 3, "typeName": "PhantomData" }, + { "name": "b", "type": 2, "typeName": "PhantomData" }, ], }, } @@ -308,16 +308,16 @@ fn test_enum() { { "name": "TupleStructVariant", "fields": [ - { "type": 1, "typeName": "u32" }, - { "type": 2, "typeName": "bool" }, + { "type": 0, "typeName": "u32" }, + { "type": 1, "typeName": "bool" }, ], }, { "name": "StructVariant", "fields": [ - { "name": "a", "type": 1, "typeName": "u32" }, - { "name": "b", "type": 3, "typeName": "[u8; 32]" }, - { "name": "c", "type": 5, "typeName": "char" }, + { "name": "a", "type": 0, "typeName": "u32" }, + { "name": "b", "type": 2, "typeName": "[u8; 32]" }, + { "name": "c", "type": 4, "typeName": "char" }, ], } ], @@ -347,14 +347,14 @@ fn test_recursive_type_with_box() { { "name": "Leaf", "fields": [ - { "name": "value", "type": 2, "typeName": "i32" }, + { "name": "value", "type": 1, "typeName": "i32" }, ], }, { "name": "Node", "fields": [ - { "name": "right", "type": 1, "typeName": "Box" }, - { "name": "left", "type": 1, "typeName": "Box" }, + { "name": "right", "type": 0, "typeName": "Box" }, + { "name": "left", "type": 0, "typeName": "Box" }, ], } ], @@ -393,28 +393,28 @@ fn registry_knows_about_compact_types() { "def": { "composite": { "fields": [ - { "name": "a", "type": 2, "typeName": "u128" }, - { "name": "a_not_compact", "type": 3, "typeName": "u128" }, - { "name": "b", "type": 4, "typeName": "[u8; 32]" }, - { "name": "c", "type": 6, "typeName": "u64" } + { "name": "a", "type": 1, "typeName": "u128" }, + { "name": "a_not_compact", "type": 2, "typeName": "u128" }, + { "name": "b", "type": 3, "typeName": "[u8; 32]" }, + { "name": "c", "type": 5, "typeName": "u64" } ] } } }, { // type 2, the `Compact` of field `a`. - "def": { "compact": { "type": 3 } }, + "def": { "compact": { "type": 2 } }, }, { // type 3, the `u128` used by type 2 and field `a_not_compact`. "def": { "primitive": "u128" } }, { // type 4, the `[u8; 32]` of field `b`. - "def": { "array": { "len": 32, "type": 5 }} + "def": { "array": { "len": 32, "type": 4 }} }, { // type 5, the `u8` in `[u8; 32]` "def": { "primitive": "u8" } }, { // type 6, the `Compact` of field `c` - "def": { "compact": { "type": 7 } }, + "def": { "compact": { "type": 6 } }, }, { // type 7, the `u64` in `Compact` of field `c` "def": { "primitive": "u64" } @@ -466,7 +466,7 @@ fn test_registry() { let expected_json = json!({ "types": [ - { // type 1 + { // type 0 "path": [ "json", "UnitStruct", @@ -475,7 +475,7 @@ fn test_registry() { "composite": {}, } }, - { // type 2 + { // type 1 "path": [ "json", "TupleStruct", @@ -483,19 +483,19 @@ fn test_registry() { "def": { "composite": { "fields": [ - { "type": 3, "typeName": "u8" }, - { "type": 4, "typeName": "u32" }, + { "type": 2, "typeName": "u8" }, + { "type": 3, "typeName": "u32" }, ], }, } }, - { // type 3 + { // type 2 "def": { "primitive": "u8" }, }, - { // type 4 + { // type 3 "def": { "primitive": "u32" }, }, - { // type 5 + { // type 4 "path": [ "json", "Struct", @@ -505,32 +505,32 @@ fn test_registry() { "fields": [ { "name": "a", - "type": 3, + "type": 2, "typeName": "u8" }, { "name": "b", - "type": 4, + "type": 3, "typeName": "u32" }, { "name": "c", - "type": 6, + "type": 5, "typeName": "[u8; 32]" } ] }, } }, - { // type 6 + { // type 5 "def": { "array": { "len": 32, - "type": 3, // u8 + "type": 2, // u8 }, } }, - { // type 7 + { // type 6 "path": [ "json", "RecursiveStruct", @@ -540,21 +540,21 @@ fn test_registry() { "fields": [ { "name": "rec", - "type": 8, + "type": 7, "typeName": "Vec" } ] }, } }, - { // type 8 + { // type 7 "def": { "sequence": { - "type": 7, // RecursiveStruct + "type": 6, // RecursiveStruct }, } }, - { // type 9 + { // type 8 "path": [ "json", "ClikeEnum", @@ -578,7 +578,7 @@ fn test_registry() { } } }, - { // type 10 + { // type 9 "path": [ "json", "RustEnum" @@ -592,8 +592,8 @@ fn test_registry() { { "name": "B", "fields": [ - { "type": 3, "typeName": "u8" }, // u8 - { "type": 4, "typeName": "u32" }, // u32 + { "type": 2, "typeName": "u8" }, // u8 + { "type": 3, "typeName": "u32" }, // u32 ] }, { @@ -601,17 +601,17 @@ fn test_registry() { "fields": [ { "name": "a", - "type": 3, // u8 + "type": 2, // u8 "typeName": "u8" }, { "name": "b", - "type": 4, // u32 + "type": 3, // u32 "typeName": "u32" }, { "name": "c", - "type": 6, + "type": 5, "typeName": "[u8; 32]" } ] From 99df03cca30aa2552b3e3d61d30fbd64de667b3c Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 7 May 2021 10:41:17 +0100 Subject: [PATCH 2/6] Add UntrackedSymbol constructor --- src/interner.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/interner.rs b/src/interner.rs index e6343b9b..41bf5700 100644 --- a/src/interner.rs +++ b/src/interner.rs @@ -51,7 +51,18 @@ pub struct UntrackedSymbol { marker: PhantomData T>, } +impl From for UntrackedSymbol { + fn from(id: u32) -> Self { + Self::new(id) + } +} + impl UntrackedSymbol { + /// Construct a new [`UntrackedSymbol`]. + pub fn new(id: u32) -> Self { + Self { id, marker: PhantomData } + } + /// Returns the index to the symbol in the interner table. pub fn id(&self) -> u32 { self.id @@ -87,10 +98,7 @@ impl Symbol<'_, T> { /// considered to be safe since untracked symbols can no longer be /// used to resolve their associated instance from the interner. pub fn into_untracked(self) -> UntrackedSymbol { - UntrackedSymbol { - id: self.id, - marker: PhantomData, - } + UntrackedSymbol::new(self.id) } } From 04946a3276de95d318dd8136fb6985ec3db4d4af Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 7 May 2021 10:42:27 +0100 Subject: [PATCH 3/6] Fmt --- src/interner.rs | 9 +++++++-- test_suite/tests/codec.rs | 8 ++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/interner.rs b/src/interner.rs index 41bf5700..66ce7d04 100644 --- a/src/interner.rs +++ b/src/interner.rs @@ -41,7 +41,9 @@ use serde::{ /// /// This can be used by self-referential types but /// can no longer be used to resolve instances. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, scale::Encode, scale::Decode)] +#[derive( + Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, scale::Encode, scale::Decode, +)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(transparent))] pub struct UntrackedSymbol { @@ -60,7 +62,10 @@ impl From for UntrackedSymbol { impl UntrackedSymbol { /// Construct a new [`UntrackedSymbol`]. pub fn new(id: u32) -> Self { - Self { id, marker: PhantomData } + Self { + id, + marker: PhantomData, + } } /// Returns the index to the symbol in the interner table. diff --git a/test_suite/tests/codec.rs b/test_suite/tests/codec.rs index f80ebbb2..e72b848f 100644 --- a/test_suite/tests/codec.rs +++ b/test_suite/tests/codec.rs @@ -63,9 +63,7 @@ fn scale_encode_then_decode_to_readonly() { let original_serialized = serde_json::to_value(registry).unwrap(); let readonly_decoded = PortableRegistry::decode(&mut &encoded[..]).unwrap(); - assert!(readonly_decoded - .resolve(0) - .is_some()); + assert!(readonly_decoded.resolve(0).is_some()); let decoded_serialized = serde_json::to_value(readonly_decoded).unwrap(); assert_eq!(decoded_serialized, original_serialized); @@ -81,9 +79,7 @@ fn json_serialize_then_deserialize_to_readonly() { // assert_eq!(original_serialized, serde_json::Value::Null); let readonly_deserialized: PortableRegistry = serde_json::from_value(original_serialized.clone()).unwrap(); - assert!(readonly_deserialized - .resolve(0) - .is_some()); + assert!(readonly_deserialized.resolve(0).is_some()); let readonly_serialized = serde_json::to_value(readonly_deserialized).unwrap(); assert_eq!(readonly_serialized, original_serialized); From 893131210dfbc057b28dc1f620e5aefcf5c2722d Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 7 May 2021 10:50:23 +0100 Subject: [PATCH 4/6] Remove UntrackedSymbol constructor --- src/interner.rs | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/interner.rs b/src/interner.rs index 66ce7d04..539cc95b 100644 --- a/src/interner.rs +++ b/src/interner.rs @@ -53,21 +53,7 @@ pub struct UntrackedSymbol { marker: PhantomData T>, } -impl From for UntrackedSymbol { - fn from(id: u32) -> Self { - Self::new(id) - } -} - impl UntrackedSymbol { - /// Construct a new [`UntrackedSymbol`]. - pub fn new(id: u32) -> Self { - Self { - id, - marker: PhantomData, - } - } - /// Returns the index to the symbol in the interner table. pub fn id(&self) -> u32 { self.id @@ -103,7 +89,10 @@ impl Symbol<'_, T> { /// considered to be safe since untracked symbols can no longer be /// used to resolve their associated instance from the interner. pub fn into_untracked(self) -> UntrackedSymbol { - UntrackedSymbol::new(self.id) + UntrackedSymbol { + id: self.id, + marker: PhantomData, + } } } From 4079de75f262e7c2b04d6731636441186c4da4e6 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 10 May 2021 10:19:52 +0100 Subject: [PATCH 5/6] Update src/interner.rs Co-authored-by: David --- src/interner.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interner.rs b/src/interner.rs index 539cc95b..940bc7ba 100644 --- a/src/interner.rs +++ b/src/interner.rs @@ -170,7 +170,7 @@ where /// Returns the symbol of the given element or `None` if it hasn't been /// interned already. - pub fn get(&self, s: &T) -> Option> { + pub fn get(&self, sym: &T) -> Option> { self.map.get(s).map(|&id| { Symbol { id: id as u32, From a3e647759e7e1ccdb7d586e303a3221aa0cce5c4 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 10 May 2021 10:19:58 +0100 Subject: [PATCH 6/6] Update src/interner.rs Co-authored-by: David --- src/interner.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interner.rs b/src/interner.rs index 940bc7ba..c002e2f9 100644 --- a/src/interner.rs +++ b/src/interner.rs @@ -171,7 +171,7 @@ where /// Returns the symbol of the given element or `None` if it hasn't been /// interned already. pub fn get(&self, sym: &T) -> Option> { - self.map.get(s).map(|&id| { + self.map.get(sym).map(|&id| { Symbol { id: id as u32, marker: PhantomData,