Skip to content

Commit deffc58

Browse files
authored
Replace From<SizeType> for usize with TryFrom. (#234)
SizeType wraps tsk_size_t, a.k.a. u64. The From conversion was fallible on 32-bit systems.
1 parent a7c0421 commit deffc58

File tree

7 files changed

+34
-51
lines changed

7 files changed

+34
-51
lines changed

src/lib.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,19 @@ impl From<SizeType> for tsk_size_t {
274274
}
275275
}
276276

277-
impl From<SizeType> for usize {
278-
fn from(value: SizeType) -> Self {
279-
crate::util::handle_u64_to_usize(value.0)
277+
// SizeType is u64, so converstion
278+
// can fail on systems with smaller pointer widths.
279+
impl TryFrom<SizeType> for usize {
280+
type Error = TskitError;
281+
282+
fn try_from(value: SizeType) -> Result<Self, Self::Error> {
283+
match usize::try_from(value.0) {
284+
Ok(x) => Ok(x),
285+
Err(_) => Err(TskitError::RangeError(format!(
286+
"could not convert {} to usize",
287+
value
288+
))),
289+
}
280290
}
281291
}
282292

src/metadata.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ mod tests {
369369
let enc = EncodedMetadata::new(&f).unwrap();
370370
let p = enc.as_ptr();
371371
let mut d = vec![];
372-
for i in 0..usize::from(enc.len()) {
372+
for i in 0..usize::try_from(enc.len()).unwrap() {
373373
d.push(unsafe { *p.add(i) as u8 });
374374
}
375375
let df = F::decode(&d).unwrap();
@@ -403,7 +403,7 @@ mod test_serde {
403403
let enc = EncodedMetadata::new(&f).unwrap();
404404
let p = enc.as_ptr();
405405
let mut d = vec![];
406-
for i in 0..usize::from(enc.len()) {
406+
for i in 0..usize::try_from(enc.len()).unwrap() {
407407
d.push(unsafe { *p.add(i) as u8 });
408408
}
409409
let df = F::decode(&d).unwrap();

src/node_table.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ impl<'a> NodeTable<'a> {
119119
unsafe {
120120
std::slice::from_raw_parts_mut(
121121
self.table_.flags.cast::<NodeFlags>(),
122-
crate::util::handle_u64_to_usize(self.table_.num_rows),
122+
usize::try_from(self.table_.num_rows).unwrap(),
123123
)
124124
}
125125
}
@@ -129,7 +129,7 @@ impl<'a> NodeTable<'a> {
129129
unsafe {
130130
std::slice::from_raw_parts_mut(
131131
self.table_.time.cast::<Time>(),
132-
crate::util::handle_u64_to_usize(self.table_.num_rows),
132+
usize::try_from(self.table_.num_rows).unwrap(),
133133
)
134134
}
135135
}

src/provenance.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,10 @@ mod test_provenances {
212212
assert!(row_id == ProvenanceId(i as crate::tsk_id_t));
213213
assert_eq!(tables.provenances().record(row_id).unwrap(), *r);
214214
}
215-
assert_eq!(usize::from(tables.provenances().num_rows()), records.len());
215+
assert_eq!(
216+
usize::try_from(tables.provenances().num_rows()).unwrap(),
217+
records.len()
218+
);
216219
for (i, row) in tables.provenances_iter().enumerate() {
217220
assert_eq!(records[i], row.record);
218221
}

src/table_collection.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ impl TableCollection {
583583
Some(unsafe {
584584
std::slice::from_raw_parts(
585585
(*self.as_ptr()).indexes.edge_insertion_order as *const EdgeId,
586-
crate::util::handle_u64_to_usize((*self.as_ptr()).indexes.num_edges),
586+
usize::try_from((*self.as_ptr()).indexes.num_edges).unwrap(),
587587
)
588588
})
589589
} else {
@@ -599,7 +599,7 @@ impl TableCollection {
599599
Some(unsafe {
600600
std::slice::from_raw_parts(
601601
(*self.as_ptr()).indexes.edge_removal_order as *const EdgeId,
602-
crate::util::handle_u64_to_usize((*self.as_ptr()).indexes.num_edges),
602+
usize::try_from((*self.as_ptr()).indexes.num_edges).unwrap(),
603603
)
604604
})
605605
} else {
@@ -798,7 +798,7 @@ impl TableCollection {
798798
) -> Result<Option<Vec<NodeId>>, TskitError> {
799799
let mut output_node_map: Vec<NodeId> = vec![];
800800
if idmap {
801-
output_node_map.resize(usize::from(self.nodes().num_rows()), NodeId::NULL);
801+
output_node_map.resize(usize::try_from(self.nodes().num_rows())?, NodeId::NULL);
802802
}
803803
let rv = unsafe {
804804
ll_bindings::tsk_table_collection_simplify(
@@ -1105,11 +1105,11 @@ mod test {
11051105
assert!(tables.is_indexed());
11061106
assert_eq!(
11071107
tables.edge_insertion_order().unwrap().len(),
1108-
tables.edges().num_rows().into()
1108+
tables.edges().num_rows().try_into().unwrap()
11091109
);
11101110
assert_eq!(
11111111
tables.edge_removal_order().unwrap().len(),
1112-
tables.edges().num_rows().into()
1112+
tables.edges().num_rows().try_into().unwrap()
11131113
);
11141114

11151115
for i in tables.edge_insertion_order().unwrap() {
@@ -1362,7 +1362,7 @@ mod test {
13621362

13631363
let mut num_with_metadata = 0;
13641364
let mut num_without_metadata = 0;
1365-
for i in 0..usize::from(tables.mutations().num_rows()) {
1365+
for i in 0..usize::try_from(tables.mutations().num_rows()).unwrap() {
13661366
match tables
13671367
.mutations()
13681368
.metadata::<F>((i as tsk_id_t).into())
@@ -1837,7 +1837,7 @@ mod test_adding_site {
18371837
Some(metadata[mi])
18381838
);
18391839
}
1840-
for i in 0..usize::from(tables.sites().num_rows()) {
1840+
for i in 0..usize::try_from(tables.sites().num_rows()).unwrap() {
18411841
assert!(
18421842
tables.sites().row(SiteId::from(i as tsk_id_t)).unwrap()
18431843
== tables.sites().row(SiteId::from(i as tsk_id_t)).unwrap()

src/trees.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -714,9 +714,9 @@ impl<'a> PostorderNodeIterator<'a> {
714714
let mut nodes = vec![
715715
NodeId::NULL;
716716
// NOTE: this fn does not return error codes
717-
crate::util::handle_u64_to_usize(unsafe {
717+
usize::try_from(unsafe {
718718
ll_bindings::tsk_tree_get_size_bound(tree.as_ptr())
719-
})
719+
}).unwrap()
720720
];
721721

722722
let rv = unsafe {
@@ -738,7 +738,7 @@ impl<'a> PostorderNodeIterator<'a> {
738738
Self {
739739
nodes,
740740
current_node_index: 0,
741-
num_nodes_current_tree: crate::util::handle_u64_to_usize(num_nodes_current_tree),
741+
num_nodes_current_tree: usize::try_from(num_nodes_current_tree).unwrap(),
742742
tree: std::marker::PhantomData,
743743
}
744744
}
@@ -1187,7 +1187,7 @@ impl TreeSequence {
11871187
let mut ts = tables.tree_sequence(TreeSequenceFlags::default())?;
11881188
let mut output_node_map: Vec<NodeId> = vec![];
11891189
if idmap {
1190-
output_node_map.resize(usize::from(self.nodes().num_rows()), NodeId::NULL);
1190+
output_node_map.resize(usize::try_from(self.nodes().num_rows())?, NodeId::NULL);
11911191
}
11921192
let rv = unsafe {
11931193
ll_bindings::tsk_treeseq_simplify(
@@ -1430,7 +1430,7 @@ pub(crate) mod test_trees {
14301430
assert_eq!(s.len(), 2);
14311431
assert_eq!(
14321432
s.len(),
1433-
usize::from(tree.num_tracked_samples(0.into()).unwrap())
1433+
usize::try_from(tree.num_tracked_samples(0.into()).unwrap()).unwrap()
14341434
);
14351435
assert_eq!(s[0], 1);
14361436
assert_eq!(s[1], 2);
@@ -1444,7 +1444,7 @@ pub(crate) mod test_trees {
14441444
assert_eq!(s[0], u);
14451445
assert_eq!(
14461446
s.len(),
1447-
usize::from(tree.num_tracked_samples(u.into()).unwrap())
1447+
usize::try_from(tree.num_tracked_samples(u.into()).unwrap()).unwrap()
14481448
);
14491449
}
14501450
} else {

src/util.rs

-30
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,3 @@
11
pub(crate) fn partial_cmp_equal<T: PartialOrd>(lhs: &T, rhs: &T) -> bool {
22
matches!(lhs.partial_cmp(rhs), Some(std::cmp::Ordering::Equal))
33
}
4-
5-
// If the system is not 16 or 32 bit, then u64 fits safely in the native
6-
// pointer width, so we can suppress the clippy pedantic lints
7-
//
8-
// To test 32 bit builds:
9-
//
10-
// 1. sudo apt install gcc-multilib
11-
// 2. rustup target install i686-unknown-linux-gnu
12-
// 3. cargo clean
13-
// 4. cargo test --target=i686-unknown-linux-gnu
14-
15-
#[inline]
16-
#[cfg(not(any(target_pointer_width = "16", target_pointer_width = "32")))]
17-
#[allow(clippy::cast_possible_truncation)]
18-
/// Safely handle u64 -> usize on 16/32 vs 64 bit systems.
19-
/// On 16/32-bit systems, panic! if the conversion cannot happen.
20-
pub(crate) fn handle_u64_to_usize(v: u64) -> usize {
21-
v as usize
22-
}
23-
24-
#[inline]
25-
#[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
26-
/// Safely handle u64 -> usize on 16/32 vs 64 bit systems.
27-
/// On 16/32-bit systems, panic! if the conversion cannot happen.
28-
pub(crate) fn handle_u64_to_usize(v: u64) -> usize {
29-
match usize::try_from(v) {
30-
Ok(u) => u,
31-
Err(_) => panic!("could not convert {} to usize", v),
32-
}
33-
}

0 commit comments

Comments
 (0)