Unsafe functions with no unsafe inside

@chrefr could you give an example of this? I can sort of understand what you're getting at but I don't have a concrete situation in mind.

This isn't actually the case, but imagine you could construct str from a sequence of bytes — by itself this would be safe. But other methods assume valid UTF-8 and could have undefined behavior if it's not. The transientness means that the constructor has to be unsafe if you want the other methods to be safe.

2 Likes

Vec::set_len is a good example.

Or NotNan::new_unchecked.

7 Likes

Send and Sync are an interesting example (in fact, this generalizes to all unsafe traits) you cannot cause UB just by implementing them, but if they were safe (which equals to not exist, in this case), any function that spawns a thread was need to be unsafe.

1 Like

The simplest example is something like struct I32NeverMin(i32);.

Suppose you want to have this method:

impl I32NeverMin {
    fn abs(self) -> Self {
        // SAFETY: Can't overflow because the invariant is that it's never MIN
        unsafe {
            Self(intrinsics::nowrap_sub(0, self.0))
        }
    }
}

That means that a constructor like this one:

impl I32NeverMin {
    /// # Safety
    /// - `x` must not be `i32::MIN`
    unsafe fn new_unchecked(x: i32) -> Self {
        Self(x)
    }
}

Must be unsafe to call, despite not doing anything scary in that method, because other unsafe blocks are relying on the invariant.

5 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.