You can also implement BumpUp() with only two conditionals and no overflow like this (in C, because I don't know Rust, but the logic is identical):
size_t alignment_needed = align - (ptr & (align - 1));
if (alignment_needed > SIZE_MAX - size) return nullptr;
size_t space_needed = size + alignment_needed;
size_t space_remaining = end - ptr;
if (space_needed > space_remaining) return nullptr;
char *result = ptr + alignment_needed;
ptr += space_needed;
return result;