Skip to content

Commit f1dfe41

Browse files
authored
ctutils: add missing #[must_use] attributes (#1382)
I ran into a bug `#[must_use]` would've caught and noticed we could use it all over the place. Fortunately, it can be detected and applied automatically with clippy.
1 parent a7fc367 commit f1dfe41

File tree

12 files changed

+47
-2
lines changed

12 files changed

+47
-2
lines changed

ctutils/src/array.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ where
2323
/// Generic implementation of constant-time equality testing for arrays which works with any type
2424
/// which impls `CtEq`. Useful in the event there isn't a `CtEq` impl for `[T; N]`.
2525
#[inline]
26+
#[must_use]
2627
pub fn ct_eq<T, const N: usize>(a: &[T; N], b: &[T; N]) -> Choice
2728
where
2829
T: CtEq,
@@ -42,6 +43,7 @@ where
4243
/// Unfortunately we can't provide this as a trait impl without specialization, since it would
4344
/// overlap with the optimized type-specific impls we provide.
4445
#[inline]
46+
#[must_use]
4547
pub fn ct_select<T, const N: usize>(a: &[T; N], b: &[T; N], choice: Choice) -> [T; N]
4648
where
4749
T: CtSelect,

ctutils/src/choice.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,24 +51,28 @@ impl Choice {
5151

5252
/// Apply an `and` conditional to the given [`Choice`]s.
5353
#[inline]
54+
#[must_use]
5455
pub const fn and(self, rhs: Choice) -> Choice {
5556
Self(self.0 & rhs.0)
5657
}
5758

5859
/// Apply an `or` conditional to the given [`Choice`]s.
5960
#[inline]
61+
#[must_use]
6062
pub const fn or(self, rhs: Choice) -> Choice {
6163
Self(self.0 | rhs.0)
6264
}
6365

6466
/// Apply an `xor` conditional to the given [`Choice`]s.
6567
#[inline]
68+
#[must_use]
6669
pub const fn xor(self, rhs: Choice) -> Choice {
6770
Self(self.0 ^ rhs.0)
6871
}
6972

7073
/// Compute the boolean inverse of `self`.
7174
#[inline]
75+
#[must_use]
7276
pub const fn not(self) -> Choice {
7377
// NOTE: assumes self.0 is `0` or `1` as checked in constructor
7478
Self(self.0 ^ 1)
@@ -80,12 +84,14 @@ impl Choice {
8084

8185
/// `const fn` equality operation.
8286
#[inline]
87+
#[must_use]
8388
pub const fn eq(self, other: Self) -> Self {
8489
Self::ne(self, other).not()
8590
}
8691

8792
/// `const fn` not equal operation.
8893
#[inline]
94+
#[must_use]
8995
pub const fn ne(self, other: Self) -> Self {
9096
Self::xor(self, other)
9197
}

ctutils/src/ct_option.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,22 @@ impl<T> CtOption<T> {
4949
/// Construct a new [`CtOption`], with a [`Choice`] parameter `is_some` as a stand-in for
5050
/// `Some` or `None` enum variants of a typical [`Option`] type.
5151
#[inline]
52+
#[must_use]
5253
pub const fn new(value: T, is_some: Choice) -> CtOption<T> {
5354
Self { value, is_some }
5455
}
5556

5657
/// Construct a new [`CtOption`] where `self.is_some()` is [`Choice::TRUE`].
5758
#[inline]
59+
#[must_use]
5860
pub const fn some(value: T) -> CtOption<T> {
5961
Self::new(value, Choice::TRUE)
6062
}
6163

6264
/// Construct a new [`CtOption`] with the [`Default`] value, and where `self.is_some()` is
6365
/// [`Choice::FALSE`].
66+
#[inline]
67+
#[must_use]
6468
pub fn none() -> CtOption<T>
6569
where
6670
T: Default,
@@ -70,6 +74,7 @@ impl<T> CtOption<T> {
7074

7175
/// Convert from a `&mut CtOption<T>` to `CtOption<&mut T>`.
7276
#[inline]
77+
#[must_use]
7378
pub const fn as_mut(&mut self) -> CtOption<&mut T> {
7479
CtOption {
7580
value: &mut self.value,
@@ -79,6 +84,7 @@ impl<T> CtOption<T> {
7984

8085
/// Convert from a `&CtOption<T>` to `CtOption<&T>`.
8186
#[inline]
87+
#[must_use]
8288
pub const fn as_ref(&self) -> CtOption<&T> {
8389
CtOption {
8490
value: &self.value,
@@ -88,6 +94,8 @@ impl<T> CtOption<T> {
8894

8995
/// Convert from `CtOption<T>` (or `&CtOption<T>`) to `CtOption<&T::Target>`, for types which
9096
/// impl the [`Deref`] trait.
97+
#[inline]
98+
#[must_use]
9199
pub fn as_deref(&self) -> CtOption<&T::Target>
92100
where
93101
T: Deref,
@@ -97,6 +105,8 @@ impl<T> CtOption<T> {
97105

98106
/// Convert from `CtOption<T>` (or `&mut CtOption<T>`) to `CtOption<&mut T::Target>`, for types
99107
/// which impl the [`DerefMut`] trait.
108+
#[inline]
109+
#[must_use]
100110
pub fn as_deref_mut(&mut self) -> CtOption<&mut T::Target>
101111
where
102112
T: DerefMut,
@@ -110,6 +120,7 @@ impl<T> CtOption<T> {
110120
/// In the event `self.is_some()` is [`Choice::FALSE`], panics with a custom panic message
111121
/// provided as the `msg` argument.
112122
#[inline]
123+
#[must_use]
113124
#[track_caller]
114125
pub fn expect(self, msg: &str) -> T {
115126
assert!(self.is_some().to_bool(), "{}", msg);
@@ -127,6 +138,7 @@ impl<T> CtOption<T> {
127138
// TODO(tarcieri): get rid of this when we can make `expect` a `const fn`
128139
// (needs `const_precise_live_drops`)
129140
#[inline]
141+
#[must_use]
130142
#[track_caller]
131143
pub const fn expect_copied(self, msg: &str) -> T
132144
where
@@ -143,6 +155,7 @@ impl<T> CtOption<T> {
143155
// TODO(tarcieri): get rid of this when we can make `expect` a `const fn`
144156
// (needs `const_precise_live_drops`)
145157
#[inline]
158+
#[must_use]
146159
#[track_caller]
147160
pub const fn expect_ref(&self, msg: &str) -> &T {
148161
// TODO(tarcieri): use `self.is_some().to_bool()` when MSRV is 1.86
@@ -234,6 +247,7 @@ impl<T> CtOption<T> {
234247
/// Returns `optb` if `self.is_some()` is [`Choice::TRUE`], otherwise returns a [`CtOption`]
235248
/// where `self.is_some()` is [`Choice::FALSE`].
236249
#[inline]
250+
#[must_use]
237251
pub fn and<U>(self, mut optb: CtOption<U>) -> CtOption<U> {
238252
optb.is_some &= self.is_some;
239253
optb
@@ -248,6 +262,7 @@ impl<T> CtOption<T> {
248262
/// (e.g. if the [`CtOption`] was constructed with a supplied placeholder value and
249263
/// [`Choice::FALSE`], the placeholder value will be provided).
250264
#[inline]
265+
#[must_use]
251266
pub fn and_then<U, F>(self, f: F) -> CtOption<U>
252267
where
253268
F: FnOnce(T) -> CtOption<U>,
@@ -271,6 +286,7 @@ impl<T> CtOption<T> {
271286
/// take great care to ensure that `self.is_some()` is checked elsewhere.
272287
/// </div>
273288
#[inline]
289+
#[must_use]
274290
pub const fn as_inner_unchecked(&self) -> &T {
275291
&self.value
276292
}
@@ -281,6 +297,7 @@ impl<T> CtOption<T> {
281297
/// It updates it to be [`Choice::FALSE`] in the event the returned choice is also false.
282298
/// If it was [`Choice::FALSE`] to begin with, it will unconditionally remain that way.
283299
#[inline]
300+
#[must_use]
284301
pub fn filter<P>(mut self, predicate: P) -> Self
285302
where
286303
P: FnOnce(&T) -> Choice,
@@ -291,6 +308,7 @@ impl<T> CtOption<T> {
291308

292309
/// Apply an additional [`Choice`] requirement to `is_some`.
293310
#[inline]
311+
#[must_use]
294312
pub const fn filter_by(mut self, is_some: Choice) -> Self {
295313
self.is_some = self.is_some.and(is_some);
296314
self
@@ -299,6 +317,7 @@ impl<T> CtOption<T> {
299317
/// Maps a `CtOption<T>` to a `CtOption<U>` by unconditionally applying a function to the
300318
/// contained `value`, but returning a new option value which inherits `self.is_some()`.
301319
#[inline]
320+
#[must_use]
302321
pub fn map<U, F>(self, f: F) -> CtOption<U>
303322
where
304323
F: FnOnce(T) -> U,
@@ -322,6 +341,7 @@ impl<T> CtOption<T> {
322341
/// `U::default()` using the [`Default`] trait, and returning it in the event `self.is_some()`
323342
/// is [`Choice::FALSE`].
324343
#[inline]
344+
#[must_use]
325345
pub fn map_or_default<U, F>(self, f: F) -> U
326346
where
327347
U: CtSelect + Default,
@@ -364,6 +384,7 @@ impl<T> CtOption<T> {
364384

365385
/// Returns `self` if `self.is_some()` is [`Choice::TRUE`], otherwise returns `optb`.
366386
#[inline]
387+
#[must_use]
367388
pub fn or(self, optb: CtOption<T>) -> CtOption<T>
368389
where
369390
T: CtSelect,
@@ -388,6 +409,7 @@ impl<T> CtOption<T> {
388409
/// take great care to ensure that `self.is_some()` is checked elsewhere.
389410
/// </div>
390411
#[inline]
412+
#[must_use]
391413
pub const fn to_inner_unchecked(self) -> T
392414
where
393415
T: Copy,
@@ -410,6 +432,8 @@ impl<T> CtOption<T> {
410432
/// # Panics
411433
/// In the event `self.is_some()` is [`Choice::FALSE`].
412434
#[inline]
435+
#[must_use]
436+
#[track_caller]
413437
pub fn unwrap(self) -> T {
414438
assert!(
415439
self.is_some.to_bool(),
@@ -421,6 +445,7 @@ impl<T> CtOption<T> {
421445
/// Return the contained value in the event `self.is_some()` is [`Choice::TRUE`], or if not,
422446
/// uses a provided default.
423447
#[inline]
448+
#[must_use]
424449
pub fn unwrap_or(self, default: T) -> T
425450
where
426451
T: CtSelect,
@@ -432,6 +457,7 @@ impl<T> CtOption<T> {
432457
/// the contained value if `self.is_some()` is [`Choice::TRUE`], or if it's [`Choice::FALSE`]
433458
/// returns the previously computed default.
434459
#[inline]
460+
#[must_use]
435461
pub fn unwrap_or_default(self) -> T
436462
where
437463
T: CtSelect + Default,
@@ -443,6 +469,7 @@ impl<T> CtOption<T> {
443469
/// the event exactly one of them has `self.is_some()` set to [`Choice::TRUE`], or else returns
444470
/// a [`CtOption`] with `self.is_some()` set to [`Choice::FALSE`].
445471
#[inline]
472+
#[must_use]
446473
pub fn xor(self, optb: CtOption<T>) -> CtOption<T>
447474
where
448475
T: CtSelect,
@@ -694,7 +721,7 @@ mod tests {
694721
#[test]
695722
#[should_panic]
696723
fn expect_none() {
697-
NONE.expect("should panic");
724+
let _ = NONE.expect("should panic");
698725
}
699726

700727
#[test]
@@ -834,7 +861,7 @@ mod tests {
834861
#[test]
835862
#[should_panic]
836863
fn unwrap_none() {
837-
NONE.unwrap();
864+
let _ = NONE.unwrap();
838865
}
839866

840867
#[test]

ctutils/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
clippy::mod_module_files,
1616
clippy::panic,
1717
clippy::panic_in_result_fn,
18+
clippy::return_self_not_must_use,
1819
clippy::std_instead_of_alloc,
1920
clippy::std_instead_of_core,
2021
clippy::undocumented_unsafe_blocks,

ctutils/src/slice.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ where
4343
target_pointer_width = "64"
4444
))]
4545
#[inline]
46+
#[must_use]
4647
pub fn ct_eq<T>(a: &[T], b: &[T]) -> Choice
4748
where
4849
T: CtEq,

ctutils/src/traits/ct_eq.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ where
2222
Rhs: ?Sized,
2323
{
2424
/// Determine if `self` is equal to `other` in constant-time.
25+
#[must_use]
2526
fn ct_eq(&self, other: &Rhs) -> Choice;
2627

2728
/// Determine if `self` is NOT equal to `other` in constant-time.
29+
#[must_use]
2830
fn ct_ne(&self, other: &Rhs) -> Choice {
2931
!self.ct_eq(other)
3032
}

ctutils/src/traits/ct_find.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub trait CtFind<T: CtAssign> {
1515
///
1616
/// The first item where `predicate` returns [`Choice::TRUE`] is selected, or the [`CtOption`]
1717
/// equivalent of `None` is returned if the `predicate` returns [`Choice::FALSE`] for all items.
18+
#[must_use]
1819
fn ct_find<P>(&self, predicate: P) -> CtOption<T>
1920
where
2021
P: Fn(&T) -> Choice;

ctutils/src/traits/ct_gt.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use core::{
77
/// Constant time greater than.
88
pub trait CtGt {
99
/// Compute whether `self > other` in constant time.
10+
#[must_use]
1011
fn ct_gt(&self, other: &Self) -> Choice;
1112
}
1213

ctutils/src/traits/ct_lookup.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub trait CtLookup<Idx> {
1515

1616
/// Attempt to retrieve the item at the given `index`, either returning it or the [`CtOption`]
1717
/// equivalent of [`None`] if the `index` was out-of-bounds.
18+
#[must_use]
1819
fn ct_lookup(&self, index: Idx) -> CtOption<Self::Output>;
1920
}
2021

ctutils/src/traits/ct_lt.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use core::{
77
/// Constant time less than.
88
pub trait CtLt {
99
/// Compute whether `self < other` in constant time.
10+
#[must_use]
1011
fn ct_lt(&self, other: &Self) -> Choice;
1112
}
1213

0 commit comments

Comments
 (0)