[RFC] externally implementable functions by m-ou-se · Pull Request #3632 · rust-lang/rfcs (original) (raw)
Move extern impls to blocks
My proposal is to move both the declarations and implementations into blocks. That would let us differentiate between functions that are unsafe to implement and functions that are unsafe to call. It would look something like this:1
// alloc::global:
extern unsafe impl { fn allocate(layout: Layout) -> Result<NonNull<[u8]>, AllocError>; unsafe fn deallocate(ptr: NonNull, layout: Layout); }
// user:
// Note the use of a path here – already allowed, except it's a module not a type! // This means we won't have to add a new case to the syntax, and keeps things nicely grouped together. unsafe impl alloc::global { fn allocate(layout: Layout) -> Result<NonNull<[u8]>, AllocError> { todo!() }
unsafe fn deallocate(ptr: NonNull<u8>, layout: Layout) {
todo!()
}
}
From here we can, optionally, do the following:
Unify declarations with extern "Rust" {}
blocks
We can make extern "Rust" {}
work exactly like extern impl
above. This includes preserving namespacing of function names, unlike the "C"
ABI.
If we do this we should transition the default ABI inside extern {}
blocks to be "Rust"
. This can be done over an edition.
Also as a delta to #3484, extern "Rust" {}
blocks would not need unsafe
. In fact, it wouldn't make sense to mark them as such, because the compiler checks the signatures for you. We would not want to use unsafe extern
to mean "unsafe to override"; instead, we should keep the extern unsafe impl {}
syntax.
The first proposal is forward-compatible with this one.
Footnotes
- As I prepare to post this I see that it's quite close to a proposal for extern mod in the other thread, though it isn't clear where to hang the
unsafe
for impls in that proposal. ↩