https://github.com/ClickHouse/ClickHouse/blob/9a48cf0da8badfc5f3da08611eb44961aa28e3f6/src/Functions/FunctionsHashing.h#L669-L671

There's a call to `blake3_free_char_pointer` that passes ownership of the pointer back to Rust (which then frees the memory), then there's a call to `std::string`'s constructor that accepts that now-freed pointer.
{
        const IDataType * nested_type = typeid_cast<const DataTypeArray *>(type)->getNestedType().get();
        if (const ColumnArray * col_from = checkAndGetColumn<ColumnArray>(column))
        {
            const IColumn * nested_column = &col_from->getData();
            const ColumnArray::Offsets & offsets = col_from->getOffsets();
            const size_t nested_size = nested_column->size();
            typename ColumnVector<ToType>::Container vec_temp(nested_size);
            bool nested_is_first = true;
            executeForArgument(nested_type, nested_column, vec_temp, nested_is_first);
            const size_t size = offsets.size();
            ColumnArray::Offset current_offset = 0;
            for (size_t i = 0; i < size; ++i)
            {
                ColumnArray::Offset next_offset = offsets[i];