Skip to content

Commit 8c72d46

Browse files
committed
Merge rust-bitcoin#5006: Remove the implicit lifetime name requirement in the encoder_newtype macro
cf99839 consensus_encoding: API updates (Nick Johnson) 9547fe3 consensus_encoding: remove implicit lifetime name (Nick Johnson) Pull request description: Inspired by rust-bitcoin#5003 (which I believe is the [elidable_lifetime_names](https://rust-lang.github.io/rust-clippy/master/index.html#elidable_lifetime_names) clippy rule) I experimented with some lifetime elision in the encoder_newtype macro. This drops the implicit requirement that the encoder struct's lifetime be called `'e` to match the internal macro's usage. This might be a subtle change in the requirements themselves since they are no longer explicitly tied together, however, I haven't been able to come up with a unit test to break that in any way. ACKs for top commit: apoelstra: ACK cf99839; successfully ran local tests; neat! Tree-SHA512: 5ce2a32017bf66e21bce95b38aeb6c4e4e317a68c5adc48c03cd815bc3efb67638d04eb4e42980231656761be91b21e0750efe293ea6c506cf3c1631be0f983f
2 parents ee701e4 + cf99839 commit 8c72d46

File tree

4 files changed

+37
-27
lines changed

4 files changed

+37
-27
lines changed

api/units/all-features.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ impl consensus_encoding::encode::Encodable for bitcoin_units::BlockTime
6262
impl consensus_encoding::encode::Encodable for bitcoin_units::block::BlockHeight
6363
impl consensus_encoding::encode::Encodable for bitcoin_units::locktime::absolute::LockTime
6464
impl consensus_encoding::encode::Encodable for bitcoin_units::sequence::Sequence
65+
impl consensus_encoding::encode::Encoder for bitcoin_units::block::BlockHeightEncoder
66+
impl consensus_encoding::encode::Encoder for bitcoin_units::locktime::absolute::LockTimeEncoder
67+
impl consensus_encoding::encode::Encoder for bitcoin_units::sequence::SequenceEncoder
68+
impl consensus_encoding::encode::Encoder for bitcoin_units::time::BlockTimeEncoder
6569
impl core::clone::Clone for bitcoin_units::Amount
6670
impl core::clone::Clone for bitcoin_units::BlockTime
6771
impl core::clone::Clone for bitcoin_units::FeeRate
@@ -1242,10 +1246,6 @@ impl<'de> serde::de::Deserialize<'de> for bitcoin_units::block::BlockMtpInterval
12421246
impl<'de> serde::de::Deserialize<'de> for bitcoin_units::locktime::absolute::LockTime
12431247
impl<'de> serde::de::Deserialize<'de> for bitcoin_units::locktime::relative::LockTime
12441248
impl<'de> serde::de::Deserialize<'de> for bitcoin_units::sequence::Sequence
1245-
impl<'e> consensus_encoding::encode::Encoder<'e> for bitcoin_units::block::BlockHeightEncoder
1246-
impl<'e> consensus_encoding::encode::Encoder<'e> for bitcoin_units::locktime::absolute::LockTimeEncoder
1247-
impl<'e> consensus_encoding::encode::Encoder<'e> for bitcoin_units::sequence::SequenceEncoder
1248-
impl<'e> consensus_encoding::encode::Encoder<'e> for bitcoin_units::time::BlockTimeEncoder
12491249
impl<T: core::clone::Clone> core::clone::Clone for bitcoin_units::result::NumOpResult<T>
12501250
impl<T: core::cmp::Eq> core::cmp::Eq for bitcoin_units::result::NumOpResult<T>
12511251
impl<T: core::cmp::PartialEq> core::cmp::PartialEq for bitcoin_units::result::NumOpResult<T>

consensus_encoding/src/encode/encoders.rs

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ impl<'sl> BytesEncoder<'sl> {
3737
}
3838
}
3939

40-
impl Encoder<'_> for BytesEncoder<'_> {
40+
impl Encoder for BytesEncoder<'_> {
4141
fn current_chunk(&self) -> Option<&[u8]> {
4242
if let Some(compact_size) = self.compact_size.as_ref() {
4343
Some(compact_size)
@@ -67,7 +67,7 @@ impl<const N: usize> ArrayEncoder<N> {
6767
pub fn without_length_prefix(arr: [u8; N]) -> Self { Self { arr: Some(arr) } }
6868
}
6969

70-
impl<const N: usize> Encoder<'_> for ArrayEncoder<N> {
70+
impl<const N: usize> Encoder for ArrayEncoder<N> {
7171
fn current_chunk(&self) -> Option<&[u8]> { self.arr.as_ref().map(|x| &x[..]) }
7272

7373
fn advance(&mut self) -> bool {
@@ -104,7 +104,7 @@ impl<'e, T: Encodable> SliceEncoder<'e, T> {
104104
}
105105
}
106106

107-
impl<'e, T: Encodable> Encoder<'e> for SliceEncoder<'e, T> {
107+
impl<'e, T: Encodable> Encoder for SliceEncoder<'e, T> {
108108
fn current_chunk(&self) -> Option<&[u8]> {
109109
if let Some(compact_size) = self.compact_size.as_ref() {
110110
return Some(compact_size);
@@ -160,7 +160,7 @@ impl<A, B> Encoder2<A, B> {
160160
pub fn new(enc_1: A, enc_2: B) -> Self { Self { enc_idx: 0, enc_1, enc_2 } }
161161
}
162162

163-
impl<'e, A: Encoder<'e>, B: Encoder<'e>> Encoder<'e> for Encoder2<A, B> {
163+
impl<A: Encoder, B: Encoder> Encoder for Encoder2<A, B> {
164164
fn current_chunk(&self) -> Option<&[u8]> {
165165
if self.enc_idx == 0 {
166166
self.enc_1.current_chunk()
@@ -198,7 +198,7 @@ impl<A, B, C> Encoder3<A, B, C> {
198198
}
199199
}
200200

201-
impl<'e, A: Encoder<'e>, B: Encoder<'e>, C: Encoder<'e>> Encoder<'e> for Encoder3<A, B, C> {
201+
impl<A: Encoder, B: Encoder, C: Encoder> Encoder for Encoder3<A, B, C> {
202202
fn current_chunk(&self) -> Option<&[u8]> { self.inner.current_chunk() }
203203
fn advance(&mut self) -> bool { self.inner.advance() }
204204
}
@@ -215,9 +215,7 @@ impl<A, B, C, D> Encoder4<A, B, C, D> {
215215
}
216216
}
217217

218-
impl<'e, A: Encoder<'e>, B: Encoder<'e>, C: Encoder<'e>, D: Encoder<'e>> Encoder<'e>
219-
for Encoder4<A, B, C, D>
220-
{
218+
impl<A: Encoder, B: Encoder, C: Encoder, D: Encoder> Encoder for Encoder4<A, B, C, D> {
221219
fn current_chunk(&self) -> Option<&[u8]> { self.inner.current_chunk() }
222220
fn advance(&mut self) -> bool { self.inner.advance() }
223221
}
@@ -239,15 +237,8 @@ impl<A, B, C, D, E, F> Encoder6<A, B, C, D, E, F> {
239237
}
240238
}
241239

242-
impl<
243-
'e,
244-
A: Encoder<'e>,
245-
B: Encoder<'e>,
246-
C: Encoder<'e>,
247-
D: Encoder<'e>,
248-
E: Encoder<'e>,
249-
F: Encoder<'e>,
250-
> Encoder<'e> for Encoder6<A, B, C, D, E, F>
240+
impl<A: Encoder, B: Encoder, C: Encoder, D: Encoder, E: Encoder, F: Encoder> Encoder
241+
for Encoder6<A, B, C, D, E, F>
251242
{
252243
fn current_chunk(&self) -> Option<&[u8]> { self.inner.current_chunk() }
253244
fn advance(&mut self) -> bool { self.inner.advance() }
@@ -261,7 +252,7 @@ mod tests {
261252
use super::*;
262253

263254
// Run the encoder i.e., use it to encode into a vector.
264-
fn run_encoder<'e>(mut encoder: impl Encoder<'e>) -> Vec<u8> {
255+
fn run_encoder(mut encoder: impl Encoder) -> Vec<u8> {
265256
let mut vec = Vec::new();
266257
while let Some(chunk) = encoder.current_chunk() {
267258
vec.extend_from_slice(chunk);
@@ -311,4 +302,4 @@ mod tests {
311302
let want = [0u8];
312303
assert_eq!(got, want);
313304
}
314-
}
305+
}

consensus_encoding/src/encode/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub mod encoders;
1515
pub trait Encodable {
1616
/// The encoder associated with this type. Conceptually, the encoder is like
1717
/// an iterator which yields byte slices.
18-
type Encoder<'s>: Encoder<'s>
18+
type Encoder<'s>: Encoder
1919
where
2020
Self: 's;
2121

@@ -24,7 +24,7 @@ pub trait Encodable {
2424
}
2525

2626
/// An encoder for a consensus-encodable object.
27-
pub trait Encoder<'e> {
27+
pub trait Encoder {
2828
/// Yields the current encoded byteslice.
2929
///
3030
/// Will always return the same value until [`Self::advance`] is called.
@@ -55,7 +55,7 @@ macro_rules! encoder_newtype{
5555
$(#[$($struct_attr)*])*
5656
pub struct $name$(<$lt>)?($encoder);
5757

58-
impl<'e> $crate::Encoder<'e> for $name$(<$lt>)? {
58+
impl$(<$lt>)? $crate::Encoder for $name$(<$lt>)? {
5959
#[inline]
6060
fn current_chunk(&self) -> Option<&[u8]> { self.0.current_chunk() }
6161

consensus_encoding/tests/encode.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#[cfg(feature = "std")]
66
use std::io::{Cursor, Write};
77

8-
use consensus_encoding::{ArrayEncoder, Encodable};
8+
use consensus_encoding::{ArrayEncoder, BytesEncoder, Encodable, Encoder};
99

1010
// Simple test type that implements Encodable.
1111
struct TestData(u32);
@@ -94,3 +94,22 @@ fn encode_std_writer_io_error() {
9494
assert!(result.is_err());
9595
assert_eq!(result.unwrap_err().kind(), std::io::ErrorKind::Other);
9696
}
97+
98+
#[test]
99+
fn encode_newtype_lifetime_flexibility() {
100+
// Test that the encoder_newtype macro allows different lifetime names.
101+
102+
consensus_encoding::encoder_newtype! {
103+
pub struct CustomEncoder<'data>(BytesEncoder<'data>);
104+
}
105+
consensus_encoding::encoder_newtype! {
106+
pub struct NoLifetimeEncoder(ArrayEncoder<4>);
107+
}
108+
109+
let test_data = b"hello world";
110+
let custom_encoder = CustomEncoder(BytesEncoder::without_length_prefix(test_data));
111+
let no_lifetime_encoder = NoLifetimeEncoder(ArrayEncoder::without_length_prefix([1, 2, 3, 4]));
112+
113+
assert_eq!(custom_encoder.current_chunk(), Some(test_data.as_slice()));
114+
assert_eq!(no_lifetime_encoder.current_chunk(), Some(&[1, 2, 3, 4][..]));
115+
}

0 commit comments

Comments
 (0)