You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Borrow<T> for Self implies that trait implementations on Self and T behave identically, in notable particular Eq, Ord, and Hash. The Hash implementation for Matrix is different from the one for arrays, resulting in e.g. the hash of Matrix3<i32> differing from that of the same matrix Borrow::borrowed as [[i32; 3]; 3]. [playground]
use nalgebra;// 0.32.3use std::borrow::Borrow;use std::hash::{BuildHasher,Hash};use std::collections::hash_map::RandomState;fnmain(){let s = RandomState::new();let v = nalgebra::matrix![3, 1, 4; 1, 5, 9; 2, 6, 5];assert_eq!(s.hash_one(&v), s.hash_one(<_ asBorrow<[_; 3]>>::borrow(&v)));// fails, should pass}
Either the Borrow implementation should be removed or the Hash implementation should be changed to try to match the array Hash implementation. I think the only way to do so properly1 would be to hash the data field directly; ArrayStorage has the properly equivalent Hash implementation, so it's a matter of requiring all impl RawStorage to provide a Hash impl. I think the way to do so in a non-API-breaking manner would be to add a copy of the Hash::hash method into the RawStorage trait and use that, as a default of the current behavior can be kept which ArrayStorage uses its derived Hash implementation. (This will result in hashing slightly more data, since R gets prefixed to each column individually, but that should be marginal for ArrayStorage-backed Matrix.)
Footnotes
The presence of Hash::hash_slice as a customization point means any and all attempts to mirror the Hash behavior will fail in an edge case, short of constructing &[[T; R]] or &[&[T]] (which would require allocation in the general case). ↩
The text was updated successfully, but these errors were encountered:
Borrow<T> for Self
implies that trait implementations onSelf
andT
behave identically, in notable particularEq
,Ord
, andHash
. TheHash
implementation forMatrix
is different from the one for arrays, resulting in e.g. the hash ofMatrix3<i32>
differing from that of the same matrixBorrow::borrow
ed as[[i32; 3]; 3]
. [playground]Either the
Borrow
implementation should be removed or theHash
implementation should be changed to try to match the arrayHash
implementation. I think the only way to do so properly1 would be to hash thedata
field directly;ArrayStorage
has the properly equivalentHash
implementation, so it's a matter of requiring allimpl RawStorage
to provide aHash
impl. I think the way to do so in a non-API-breaking manner would be to add a copy of theHash::hash
method into theRawStorage
trait and use that, as a default of the current behavior can be kept whichArrayStorage
uses its derivedHash
implementation. (This will result in hashing slightly more data, since R gets prefixed to each column individually, but that should be marginal forArrayStorage
-backedMatrix
.)Footnotes
The presence of
Hash::hash_slice
as a customization point means any and all attempts to mirror theHash
behavior will fail in an edge case, short of constructing&[[T; R]]
or&[&[T]]
(which would require allocation in the general case). ↩The text was updated successfully, but these errors were encountered: