7

This code is throwing an error about returning a reference from the function:

fn sha512_256_digest(str: &[u8]) -> &[u8] {
    let x = digest::digest(&digest::SHA512_256, str);
    x.as_ref()
}

What would be the correct way to return the as_ref() value of x here?

pretzelhammer
  • 13,874
  • 15
  • 47
  • 98
themonkey
  • 377
  • 1
  • 3
  • 9
  • 3
    "_I get why the error is being returned_" Could you quote it in your post? That could help future users find this. – underscore_d Nov 14 '19 at 17:00

3 Answers3

7

Short answer: You can't. That's because digest() returns an owned value and as_ref() (by definition) borrows from it. When the function returns, the memory owned by the return value of digest() is destroyed and the referenced returned by as_ref() becomes invalid.

I guess your goal is to hide the implementation detail that digest() returns a GenericArray, while you only need a &[u8]. You can get something similar by hiding the concrete type:

fn sha512_256_digest(str: &[u8]) -> impl AsRef<[u8]> {
    digest::digest(&digest::SHA512_256, str)
}

... should work. The function signature says that the return value will be some anonymous type which the caller can only ever know about that it can be referenced as if it was a &[u8]. The caller can do

// `d` is of some anonymous type
let d = sha512_256_digest(...);

// `db` is a &[u8]
let db = d.as_ref();

However, I'd recommend not to hide types in such a way.

user2722968
  • 13,636
  • 2
  • 46
  • 67
6

Since the value you're returning is created in (and thus owned by) the function, a reference to it cannot be returned as it won't exist once the function finishes.

You must either change the function to return an owned value or make its argument a mutable reference &mut [u8] and remove the return - so your options for function signatures would probably be one of the following:

fn sha512_256_digest(str: &mut [u8])

or

fn sha512_256_digest(str: &[u8]) -> Vec<u8>

A complete example with the former would be:

let mut x = <insert your byte array here>;
sha512_256_digest(&mut x);
<use x here>

A complete example with the latter would be:

let x = <insert your byte array here>;
let y = sha512_256_digest(&x);
<use y here>
notquiteamonad
  • 1,159
  • 2
  • 12
  • 28
0

I'm not sure which hashing library you are using, but there should be a way to get the actual hash data (instead of a reference to it). Looking at your code, this will probably be a value of type [u8; 32]. This is the value you want to return from your function.

z2oh
  • 93
  • 2
  • 9