@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.
Vec::set_len is a good example.
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
.
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.
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.