From aa725606db531e3d2c531454ca6a244fd09867ad Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sat, 7 Nov 2020 16:58:14 +0100 Subject: [PATCH 01/12] Advance ptr, even when 'None' --- crates/storage/src/traits/impls/prims.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/storage/src/traits/impls/prims.rs b/crates/storage/src/traits/impls/prims.rs index b1dfa3a11ad..387afcc1e3b 100644 --- a/crates/storage/src/traits/impls/prims.rs +++ b/crates/storage/src/traits/impls/prims.rs @@ -66,6 +66,8 @@ where ::push_spread(&(self.is_some() as u8), ptr); if let Some(value) = self { ::push_spread(value, ptr); + } else { + ptr.advance_by(::FOOTPRINT); } } @@ -76,12 +78,17 @@ where ::clear_spread(&0, ptr); if let Some(value) = self { ::clear_spread(value, ptr) + } else { + ptr.advance_by(::FOOTPRINT); } } fn pull_spread(ptr: &mut KeyPtr) -> Self { match ::pull_spread(ptr) { - 0u8 => None, + 0u8 => { + ptr.advance_by(::FOOTPRINT); + None + } 1u8 => Some(::pull_spread(ptr)), _ => unreachable!("invalid Option discriminant"), } From 69cd40e28de5e8ced4c2b08a3bd9524ada97b2c1 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sat, 7 Nov 2020 16:58:39 +0100 Subject: [PATCH 02/12] Revert me: Add minimal contract which reproduces bug --- examples/bug/.gitignore | 9 ++++++++ examples/bug/Cargo.toml | 37 ++++++++++++++++++++++++++++++ examples/bug/lib.rs | 51 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 examples/bug/.gitignore create mode 100644 examples/bug/Cargo.toml create mode 100644 examples/bug/lib.rs diff --git a/examples/bug/.gitignore b/examples/bug/.gitignore new file mode 100644 index 00000000000..bf910de10af --- /dev/null +++ b/examples/bug/.gitignore @@ -0,0 +1,9 @@ +# Ignore build artifacts from the local tests sub-crate. +/target/ + +# Ignore backup files creates by cargo fmt. +**/*.rs.bk + +# Remove Cargo.lock when creating an executable, leave it for libraries +# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock +Cargo.lock \ No newline at end of file diff --git a/examples/bug/Cargo.toml b/examples/bug/Cargo.toml new file mode 100644 index 00000000000..71d129514b2 --- /dev/null +++ b/examples/bug/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "bug" +version = "3.0.0-rc2" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +ink_primitives = { version = "3.0.0-rc2", path = "../../crates/primitives", default-features = false } +ink_metadata = { version = "3.0.0-rc2", path = "../../crates/metadata", default-features = false, features = ["derive"], optional = true } +ink_env = { version = "3.0.0-rc2", path = "../../crates/env", default-features = false } +ink_storage = { version = "3.0.0-rc2", path = "../../crates/storage", default-features = false } +ink_lang = { version = "3.0.0-rc2", path = "../../crates/lang", default-features = false } + +scale = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive"] } +scale-info = { version = "0.4", default-features = false, features = ["derive"], optional = true } +generic-array = "0.14.1" + + +[lib] +name = "bug" +path = "lib.rs" +crate-type = ["cdylib"] + +[features] +default = ["std"] +std = [ + "ink_primitives/std", + "ink_metadata", + "ink_metadata/std", + "ink_env/std", + "ink_storage/std", + "ink_lang/std", + "scale/std", + "scale-info", + "scale-info/std", +] +ink-as-dependency = [] diff --git a/examples/bug/lib.rs b/examples/bug/lib.rs new file mode 100644 index 00000000000..4375993f6bf --- /dev/null +++ b/examples/bug/lib.rs @@ -0,0 +1,51 @@ +// Copyright 2018-2020 Parity Technologies (UK) Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg_attr(not(feature = "std"), no_std)] +#![allow(clippy::new_without_default)] + +use ink_lang as ink; + +#[ink::contract] +mod bug { + use ink_storage::Lazy; + + #[ink(storage)] + pub struct Bug { + opt: Option, + some_val: Lazy, + } + + impl Bug { + #[ink(constructor)] + pub fn new() -> Self { + Self { + opt: None, + some_val: Lazy::new(27), + } + } + + #[ink(message)] + pub fn bug(&mut self) -> Result<(), ()> { + ink_env::debug_println("get some_val"); + let _ = *self.some_val; + + ink_env::debug_println("set opt"); + self.opt = Some(13); + + ink_env::debug_println("end"); + Ok(()) + } + } +} From be8f3afdf1b799c051840cf4957269f8311b2f30 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 9 Nov 2020 10:42:37 +0100 Subject: [PATCH 03/12] =?UTF-8?q?Fix=20typo:=20explicitely=20=E2=9E=9C=20e?= =?UTF-8?q?xplicitly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/storage/src/lazy/lazy_cell.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/storage/src/lazy/lazy_cell.rs b/crates/storage/src/lazy/lazy_cell.rs index a09c4afea70..d407465d6cf 100644 --- a/crates/storage/src/lazy/lazy_cell.rs +++ b/crates/storage/src/lazy/lazy_cell.rs @@ -523,7 +523,7 @@ mod tests { // We prevent the intermediate instance from clearing the storage preemtively by wrapping // it inside `ManuallyDrop`. The third step will clean up the same storage region afterwards. // - // We explicitely do not touch or assert the value of `pulled_pair.0` in order to trigger + // We explicitly do not touch or assert the value of `pulled_pair.0` in order to trigger // the bug. let pulled_pair: (LazyCell, i32) = SpreadLayout::pull_spread(&mut KeyPtr::from(root_key)); From 37ed1fce6f5d853a8659d62b72e2c16506232e09 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 9 Nov 2020 10:41:28 +0100 Subject: [PATCH 04/12] Add regression test --- crates/storage/src/lazy/lazy_cell.rs | 59 ++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/crates/storage/src/lazy/lazy_cell.rs b/crates/storage/src/lazy/lazy_cell.rs index d407465d6cf..f2f3629f0ed 100644 --- a/crates/storage/src/lazy/lazy_cell.rs +++ b/crates/storage/src/lazy/lazy_cell.rs @@ -545,4 +545,63 @@ mod tests { Ok(()) }) } + + #[test] + fn regression_test_for_issue_570() -> ink_env::Result<()> { + type V1 = Option; + type V2 = u32; + + run_test::(|_| { + let root_key = Key::from([0x00; 32]); + { + // Step 1: Push two valid values one after the other to contract storage. + // The first value needs to be an Option, since the bug was messing up + // following pointers for an Option. + let v1: V1 = None; + let v2: V2 = 13; + + let v1_cell = v1; + let mut ptr = KeyPtr::from(root_key); + SpreadLayout::push_spread(&v1_cell, &mut ptr); + + let v2_cell = v2; + SpreadLayout::push_spread(&v2_cell, &mut ptr); + } + { + // Step 2: Pull the values from the step before. + // + // 1. Change the first values `None` to `Some(...)`. + // 2. Push the first value again to contract storage. + // + // We prevent the intermediate instance from clearing the storage preemptively + // by wrapping it inside `ManuallyDrop`. The third step will clean up the same + // storage region afterwards. + let mut ptr = KeyPtr::from(root_key); + let pulled_v1: V1 = SpreadLayout::pull_spread(&mut ptr); + let mut pulled_v1 = core::mem::ManuallyDrop::new(pulled_v1); + + let pulled_v2: V2 = SpreadLayout::pull_spread(&mut ptr); + let pulled_v2 = core::mem::ManuallyDrop::new(pulled_v2); + + assert_eq!(*pulled_v1, None); + assert_eq!(*pulled_v2, 13); + + *pulled_v1 = Some(99u32); + SpreadLayout::push_spread(&*pulled_v1, &mut KeyPtr::from(root_key)); + } + { + // Step 3: Pull the values again from the storage. + // + // If the bug with `Option` has been fixed in PR #520 we must be able to inspect + // the correct values for both entries. + let mut ptr = KeyPtr::from(root_key); + let pulled_v1: V1 = SpreadLayout::pull_spread(&mut ptr); + let pulled_v2: V2 = SpreadLayout::pull_spread(&mut ptr); + + assert_eq!(pulled_v1, Some(99)); + assert_eq!(pulled_v2, 13); + } + Ok(()) + }) + } } From 403439f83cbf693673c5f597f79ca21da32a7999 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 9 Nov 2020 10:43:26 +0100 Subject: [PATCH 05/12] Improve structure --- crates/storage/src/lazy/lazy_cell.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/storage/src/lazy/lazy_cell.rs b/crates/storage/src/lazy/lazy_cell.rs index f2f3629f0ed..adc2ac18a62 100644 --- a/crates/storage/src/lazy/lazy_cell.rs +++ b/crates/storage/src/lazy/lazy_cell.rs @@ -559,9 +559,9 @@ mod tests { // following pointers for an Option. let v1: V1 = None; let v2: V2 = 13; + let mut ptr = KeyPtr::from(root_key); let v1_cell = v1; - let mut ptr = KeyPtr::from(root_key); SpreadLayout::push_spread(&v1_cell, &mut ptr); let v2_cell = v2; From e957478bf64a1fdc3f0d642b855d984f912483de Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 9 Nov 2020 10:43:58 +0100 Subject: [PATCH 06/12] Revert "Revert me: Add minimal contract which reproduces bug" This reverts commit 69cd40e28de5e8ced4c2b08a3bd9524ada97b2c1. --- examples/bug/.gitignore | 9 -------- examples/bug/Cargo.toml | 37 ------------------------------ examples/bug/lib.rs | 51 ----------------------------------------- 3 files changed, 97 deletions(-) delete mode 100644 examples/bug/.gitignore delete mode 100644 examples/bug/Cargo.toml delete mode 100644 examples/bug/lib.rs diff --git a/examples/bug/.gitignore b/examples/bug/.gitignore deleted file mode 100644 index bf910de10af..00000000000 --- a/examples/bug/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# Ignore build artifacts from the local tests sub-crate. -/target/ - -# Ignore backup files creates by cargo fmt. -**/*.rs.bk - -# Remove Cargo.lock when creating an executable, leave it for libraries -# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock -Cargo.lock \ No newline at end of file diff --git a/examples/bug/Cargo.toml b/examples/bug/Cargo.toml deleted file mode 100644 index 71d129514b2..00000000000 --- a/examples/bug/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "bug" -version = "3.0.0-rc2" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -ink_primitives = { version = "3.0.0-rc2", path = "../../crates/primitives", default-features = false } -ink_metadata = { version = "3.0.0-rc2", path = "../../crates/metadata", default-features = false, features = ["derive"], optional = true } -ink_env = { version = "3.0.0-rc2", path = "../../crates/env", default-features = false } -ink_storage = { version = "3.0.0-rc2", path = "../../crates/storage", default-features = false } -ink_lang = { version = "3.0.0-rc2", path = "../../crates/lang", default-features = false } - -scale = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive"] } -scale-info = { version = "0.4", default-features = false, features = ["derive"], optional = true } -generic-array = "0.14.1" - - -[lib] -name = "bug" -path = "lib.rs" -crate-type = ["cdylib"] - -[features] -default = ["std"] -std = [ - "ink_primitives/std", - "ink_metadata", - "ink_metadata/std", - "ink_env/std", - "ink_storage/std", - "ink_lang/std", - "scale/std", - "scale-info", - "scale-info/std", -] -ink-as-dependency = [] diff --git a/examples/bug/lib.rs b/examples/bug/lib.rs deleted file mode 100644 index 4375993f6bf..00000000000 --- a/examples/bug/lib.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#![cfg_attr(not(feature = "std"), no_std)] -#![allow(clippy::new_without_default)] - -use ink_lang as ink; - -#[ink::contract] -mod bug { - use ink_storage::Lazy; - - #[ink(storage)] - pub struct Bug { - opt: Option, - some_val: Lazy, - } - - impl Bug { - #[ink(constructor)] - pub fn new() -> Self { - Self { - opt: None, - some_val: Lazy::new(27), - } - } - - #[ink(message)] - pub fn bug(&mut self) -> Result<(), ()> { - ink_env::debug_println("get some_val"); - let _ = *self.some_val; - - ink_env::debug_println("set opt"); - self.opt = Some(13); - - ink_env::debug_println("end"); - Ok(()) - } - } -} From 69112ae46cab0a6e91f0083ceff3536b8a922a6d Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 9 Nov 2020 11:27:06 +0100 Subject: [PATCH 07/12] Fix clippy error 'result_unit_err' --- examples/multisig_plain/lib.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/multisig_plain/lib.rs b/examples/multisig_plain/lib.rs index f80a5243b53..78db1bc5a80 100755 --- a/examples/multisig_plain/lib.rs +++ b/examples/multisig_plain/lib.rs @@ -155,6 +155,9 @@ mod multisig_plain { pub gas_limit: u64, } + /// Type alias for the contract's result type. + pub type Result = core::result::Result; + #[ink(storage)] pub struct MultisigPlain { /// Every entry in this map represents the confirmation of an owner for a @@ -227,7 +230,7 @@ mod multisig_plain { /// the output in bytes. The Option is `None` when the transaction was executed through /// `invoke_transaction` rather than `evaluate_transaction`. #[ink(topic)] - result: Result>, ()>, + result: Result>>, } /// Emitted when an owner is added to the wallet. @@ -479,7 +482,7 @@ mod multisig_plain { /// Its return value indicates whether the called transaction was successful. /// This can be called by anyone. #[ink(message)] - pub fn invoke_transaction(&mut self, trans_id: TransactionId) -> Result<(), ()> { + pub fn invoke_transaction(&mut self, trans_id: TransactionId) -> Result<()> { self.ensure_confirmed(trans_id); let t = self.take_transaction(trans_id).expect(WRONG_TRANSACTION_ID); let result = build_call::<::Env>() @@ -508,7 +511,7 @@ mod multisig_plain { pub fn eval_transaction( &mut self, trans_id: TransactionId, - ) -> Result, ()> { + ) -> Result> { self.ensure_confirmed(trans_id); let t = self.take_transaction(trans_id).expect(WRONG_TRANSACTION_ID); let result = build_call::<::Env>() From ab25124b912419b2056527cdc8edb055f005d4f2 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 9 Nov 2020 11:46:17 +0100 Subject: [PATCH 08/12] Fix clippy error 'result_unit_err' --- examples/multisig_plain/lib.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/examples/multisig_plain/lib.rs b/examples/multisig_plain/lib.rs index 78db1bc5a80..43db74ff6f9 100755 --- a/examples/multisig_plain/lib.rs +++ b/examples/multisig_plain/lib.rs @@ -155,8 +155,13 @@ mod multisig_plain { pub gas_limit: u64, } - /// Type alias for the contract's result type. - pub type Result = core::result::Result; + /// Errors that can occur upon calling this contract. + #[derive(Copy, Clone, Debug, PartialEq, Eq, scale::Encode, scale::Decode)] + #[cfg_attr(feature = "std", derive(::scale_info::TypeInfo))] + pub enum Error { + /// Returned if the call failed. + TransactionFailed, + } #[ink(storage)] pub struct MultisigPlain { @@ -230,7 +235,7 @@ mod multisig_plain { /// the output in bytes. The Option is `None` when the transaction was executed through /// `invoke_transaction` rather than `evaluate_transaction`. #[ink(topic)] - result: Result>>, + result: Result>, Error>, } /// Emitted when an owner is added to the wallet. @@ -482,7 +487,10 @@ mod multisig_plain { /// Its return value indicates whether the called transaction was successful. /// This can be called by anyone. #[ink(message)] - pub fn invoke_transaction(&mut self, trans_id: TransactionId) -> Result<()> { + pub fn invoke_transaction( + &mut self, + trans_id: TransactionId, + ) -> Result<(), Error> { self.ensure_confirmed(trans_id); let t = self.take_transaction(trans_id).expect(WRONG_TRANSACTION_ID); let result = build_call::<::Env>() @@ -494,7 +502,7 @@ mod multisig_plain { ) .returns::<()>() .fire() - .map_err(|_| ()); + .map_err(|_| Error::TransactionFailed); self.env().emit_event(Execution { transaction: trans_id, result: result.map(|_| None), @@ -511,7 +519,7 @@ mod multisig_plain { pub fn eval_transaction( &mut self, trans_id: TransactionId, - ) -> Result> { + ) -> Result, Error> { self.ensure_confirmed(trans_id); let t = self.take_transaction(trans_id).expect(WRONG_TRANSACTION_ID); let result = build_call::<::Env>() @@ -523,7 +531,7 @@ mod multisig_plain { ) .returns::>>() .fire() - .map_err(|_| ()); + .map_err(|_| Error::TransactionFailed); self.env().emit_event(Execution { transaction: trans_id, result: result.clone().map(Some), From 9e2828aad93e72dc990f9cb081cd95a29a67b866 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 9 Nov 2020 11:47:12 +0100 Subject: [PATCH 09/12] =?UTF-8?q?Fix=20typo:=20sucesful=20=E2=9E=9C=20succ?= =?UTF-8?q?essful?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/multisig_plain/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/multisig_plain/lib.rs b/examples/multisig_plain/lib.rs index 43db74ff6f9..3389fa368af 100755 --- a/examples/multisig_plain/lib.rs +++ b/examples/multisig_plain/lib.rs @@ -513,7 +513,7 @@ mod multisig_plain { /// Evaluate a confirmed execution and return its output as bytes. /// /// Its return value indicates whether the called transaction was successful and contains - /// its output when sucesful. + /// its output when successful. /// This can be called by anyone. #[ink(message)] pub fn eval_transaction( From 4d52e85e0c3efc5be3d431c6ba9db30dfe16d883 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 10 Nov 2020 07:25:58 +0100 Subject: [PATCH 10/12] Improve comment --- crates/storage/src/lazy/lazy_cell.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/storage/src/lazy/lazy_cell.rs b/crates/storage/src/lazy/lazy_cell.rs index adc2ac18a62..bd0143f5720 100644 --- a/crates/storage/src/lazy/lazy_cell.rs +++ b/crates/storage/src/lazy/lazy_cell.rs @@ -555,8 +555,8 @@ mod tests { let root_key = Key::from([0x00; 32]); { // Step 1: Push two valid values one after the other to contract storage. - // The first value needs to be an Option, since the bug was messing up - // following pointers for an Option. + // The first value needs to be an `Option::None` value, since the bug was + // then messing up following pointers. let v1: V1 = None; let v2: V2 = 13; let mut ptr = KeyPtr::from(root_key); From 15412a7255796903ed7f7529ef5d45ab604c3499 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 10 Nov 2020 07:26:55 +0100 Subject: [PATCH 11/12] Remove no-op --- crates/storage/src/lazy/lazy_cell.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/storage/src/lazy/lazy_cell.rs b/crates/storage/src/lazy/lazy_cell.rs index bd0143f5720..d45bb0fae85 100644 --- a/crates/storage/src/lazy/lazy_cell.rs +++ b/crates/storage/src/lazy/lazy_cell.rs @@ -561,11 +561,8 @@ mod tests { let v2: V2 = 13; let mut ptr = KeyPtr::from(root_key); - let v1_cell = v1; - SpreadLayout::push_spread(&v1_cell, &mut ptr); - - let v2_cell = v2; - SpreadLayout::push_spread(&v2_cell, &mut ptr); + SpreadLayout::push_spread(&v1, &mut ptr); + SpreadLayout::push_spread(&v2, &mut ptr); } { // Step 2: Pull the values from the step before. From 3bc442ef7a21bdef7c2daa40310c7e3a37eae22a Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 10 Nov 2020 09:39:14 +0100 Subject: [PATCH 12/12] Remove type aliases for V1/V2 --- crates/storage/src/lazy/lazy_cell.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/crates/storage/src/lazy/lazy_cell.rs b/crates/storage/src/lazy/lazy_cell.rs index d45bb0fae85..ea6ef5909c0 100644 --- a/crates/storage/src/lazy/lazy_cell.rs +++ b/crates/storage/src/lazy/lazy_cell.rs @@ -548,17 +548,14 @@ mod tests { #[test] fn regression_test_for_issue_570() -> ink_env::Result<()> { - type V1 = Option; - type V2 = u32; - run_test::(|_| { let root_key = Key::from([0x00; 32]); { // Step 1: Push two valid values one after the other to contract storage. // The first value needs to be an `Option::None` value, since the bug was // then messing up following pointers. - let v1: V1 = None; - let v2: V2 = 13; + let v1: Option = None; + let v2: u32 = 13; let mut ptr = KeyPtr::from(root_key); SpreadLayout::push_spread(&v1, &mut ptr); @@ -574,10 +571,10 @@ mod tests { // by wrapping it inside `ManuallyDrop`. The third step will clean up the same // storage region afterwards. let mut ptr = KeyPtr::from(root_key); - let pulled_v1: V1 = SpreadLayout::pull_spread(&mut ptr); + let pulled_v1: Option = SpreadLayout::pull_spread(&mut ptr); let mut pulled_v1 = core::mem::ManuallyDrop::new(pulled_v1); - let pulled_v2: V2 = SpreadLayout::pull_spread(&mut ptr); + let pulled_v2: u32 = SpreadLayout::pull_spread(&mut ptr); let pulled_v2 = core::mem::ManuallyDrop::new(pulled_v2); assert_eq!(*pulled_v1, None); @@ -592,8 +589,8 @@ mod tests { // If the bug with `Option` has been fixed in PR #520 we must be able to inspect // the correct values for both entries. let mut ptr = KeyPtr::from(root_key); - let pulled_v1: V1 = SpreadLayout::pull_spread(&mut ptr); - let pulled_v2: V2 = SpreadLayout::pull_spread(&mut ptr); + let pulled_v1: Option = SpreadLayout::pull_spread(&mut ptr); + let pulled_v2: u32 = SpreadLayout::pull_spread(&mut ptr); assert_eq!(pulled_v1, Some(99)); assert_eq!(pulled_v2, 13);