docs: Add notes on behaviours which Rust considers undefined.
This commit is contained in:
parent
12cf04646c
commit
1645c5503d
|
@ -44,8 +44,8 @@ If your Rust code must call out to parts of Tor's C code, you must
|
|||
declare the functions you are calling in the `external` crate, located
|
||||
at `.../src/rust/external`.
|
||||
|
||||
XXX get better examples of how to declare these externs, when/how they
|
||||
XXX are unsafe, what they are expected to do —isis
|
||||
<!-- XXX get better examples of how to declare these externs, when/how they -->
|
||||
<!-- XXX are unsafe, what they are expected to do —isis -->
|
||||
|
||||
Modules should strive to be below 500 lines (tests excluded). Single
|
||||
responsibility and limited dependencies should be a guiding standard.
|
||||
|
@ -170,6 +170,45 @@ before attempting to write FFI or any other unsafe code.
|
|||
|
||||
Here are some additional bits of advice and rules:
|
||||
|
||||
0. Any behaviours which Rust considers to be undefined are forbidden
|
||||
|
||||
From https://doc.rust-lang.org/reference/behavior-considered-undefined.html:
|
||||
|
||||
> Behavior considered undefined
|
||||
>
|
||||
> The following is a list of behavior which is forbidden in all Rust code,
|
||||
> including within unsafe blocks and unsafe functions. Type checking provides the
|
||||
> guarantee that these issues are never caused by safe code.
|
||||
>
|
||||
> * Data races
|
||||
> * Dereferencing a null/dangling raw pointer
|
||||
> * Reads of [undef](http://llvm.org/docs/LangRef.html#undefined-values)
|
||||
> (uninitialized) memory
|
||||
> * Breaking the
|
||||
> [pointer aliasing rules](http://llvm.org/docs/LangRef.html#pointer-aliasing-rules)
|
||||
> with raw pointers (a subset of the rules used by C)
|
||||
> * `&mut T` and `&T` follow LLVM’s scoped noalias model, except if the `&T`
|
||||
> contains an `UnsafeCell<U>`. Unsafe code must not violate these aliasing
|
||||
> guarantees.
|
||||
> * Mutating non-mutable data (that is, data reached through a shared
|
||||
> reference or data owned by a `let` binding), unless that data is
|
||||
> contained within an `UnsafeCell<U>`.
|
||||
> * Invoking undefined behavior via compiler intrinsics:
|
||||
> - Indexing outside of the bounds of an object with
|
||||
> `std::ptr::offset` (`offset` intrinsic), with the exception of
|
||||
> one byte past the end which is permitted.
|
||||
> - Using `std::ptr::copy_nonoverlapping_memory` (`memcpy32`/`memcpy64`
|
||||
> intrinsics) on overlapping buffers
|
||||
> * Invalid values in primitive types, even in private fields/locals:
|
||||
> - Dangling/null references or boxes
|
||||
> - A value other than `false` (0) or `true` (1) in a `bool`
|
||||
> - A discriminant in an `enum` not included in the type definition
|
||||
> - A value in a `char` which is a surrogate or above `char::MAX`
|
||||
> - Non-UTF-8 byte sequences in a `str`
|
||||
> * Unwinding into Rust from foreign code or unwinding from Rust into foreign
|
||||
> code. Rust's failure system is not compatible with exception handling in other
|
||||
> languages. Unwinding must be caught and handled at FFI boundaries.
|
||||
|
||||
1. `unwrap()`
|
||||
|
||||
If you call `unwrap()`, anywhere, even in a test, you MUST include
|
||||
|
|
Loading…
Reference in New Issue