@@ -15,6 +15,8 @@ for example:
1515  or an invalid enum discriminant)
1616*  ** Experimental** : Violations of the [ Stacked Borrows]  rules governing aliasing
1717  for reference types
18+ *  ** Experimental** : Violations of the Tree Borrows aliasing rules, as an optional
19+   alternative to [ Stacked Borrows] 
1820*  ** Experimental** : Data races
1921
2022On top of that, Miri will also tell you about memory leaks: when there is memory
@@ -225,6 +227,26 @@ degree documented below):
225227  reduced feature set. We might ship Miri with a nightly even when some features 
226228  on these targets regress. 
227229
230+ # ## Running tests in parallel
231+ 
232+ Though it implements Rust threading, Miri itself is a single-threaded interpreter. 
233+ This means that when running `cargo miri test`, you will probably see a dramatic 
234+ increase in the amount of time it takes to run your whole test suite due to the 
235+ inherent interpreter slowdown and a loss of parallelism. 
236+ 
237+ You can get your test suite's parallelism back by running `cargo miri nextest run -jN` 
238+ (note that you will need [`cargo-nextest`](https://nexte.st) installed). 
239+ This works because `cargo-nextest` collects a list of all tests then launches a 
240+ separate `cargo miri run` for each test. You will need to specify a `-j` or `--test-threads`; 
241+ by default `cargo miri nextest run` runs one test at a time. For more details, see the 
242+ [`cargo-nextest` Miri documentation](https://nexte.st/book/miri.html). 
243+ 
244+ Note : This one-test-per-process model means that `cargo miri test` is able to detect data 
245+ races where two tests race on a shared resource, but `cargo miri nextest run` will not detect 
246+ such races. 
247+ 
248+ Note : ` cargo-nextest` does not support doctests, see https://github.com/nextest-rs/nextest/issues/16 
249+ 
228250# ## Common Problems
229251
230252When using the above instructions, you may encounter a number of confusing compiler 
@@ -337,9 +359,11 @@ to Miri failing to detect cases of undefined behavior in a program.
337359* `-Zmiri-disable-data-race-detector` disables checking for data races.  Using 
338360  this flag is **unsound**. This implies `-Zmiri-disable-weak-memory-emulation`. 
339361* `-Zmiri-disable-stacked-borrows` disables checking the experimental 
340-   [Stacked Borrows] aliasing rules.  This can make Miri run faster, but it also 
341-   means no aliasing violations will be detected.  Using this flag is **unsound** 
342-   (but the affected soundness rules are experimental). 
362+   aliasing rules to track borrows ([Stacked Borrows] and Tree Borrows). 
363+   This can make Miri run faster, but it also means no aliasing violations will 
364+   be detected. Using this flag is **unsound** (but the affected soundness rules 
365+   are experimental). Later flags take precedence : borrow tracking can be reactivated 
366+   by `-Zmiri-tree-borrows`. 
343367* `-Zmiri-disable-validation` disables enforcing validity invariants, which are 
344368  enforced by default.  This is mostly useful to focus on other failures (such 
345369  as out-of-bounds accesses) first.  Setting this flag means Miri can miss bugs 
@@ -401,6 +425,9 @@ to Miri failing to detect cases of undefined behavior in a program.
401425* `-Zmiri-track-weak-memory-loads` shows a backtrace when weak memory emulation returns an outdated 
402426  value from a load. This can help diagnose problems that disappear under 
403427  ` -Zmiri-disable-weak-memory-emulation` . 
428+ * `-Zmiri-tree-borrows` replaces [Stacked Borrows] with the Tree Borrows rules. 
429+   The soundness rules are already experimental without this flag, but even more 
430+   so with this flag. 
404431* `-Zmiri-force-page-size=<num>` overrides the default page size for an architecture, in multiples of 1k. 
405432  ` 4` is default for most targets. This value should always be a power of 2 and nonzero. 
406433
@@ -415,7 +442,7 @@ Some native rustc `-Z` flags are also very relevant for Miri:
415442  functions.  This is needed so that Miri can execute such functions, so Miri 
416443  sets this flag per default. 
417444* `-Zmir-emit-retag` controls whether `Retag` statements are emitted. Miri 
418-   enables this per default because it is needed for [Stacked Borrows]. 
445+   enables this per default because it is needed for [Stacked Borrows] and Tree Borrows . 
419446
420447Moreover, Miri recognizes some environment variables :
421448
@@ -481,120 +508,8 @@ binaries, and as such worth documenting:
481508# # Miri `extern` functions
482509
483510Miri provides some `extern` functions that programs can import to access 
484- Miri-specific functionality :
485- 
486- ` ` ` rust
487- #[cfg(miri)] 
488- extern "Rust" { 
489-     /// Miri-provided extern function to mark the block `  ptr` points to as a "root" 
490-     /// for some static memory. This memory and everything reachable by it is not 
491-     /// considered leaking even if it still exists when the program terminates. 
492-     /// 
493-     /// `ptr` has to point to the beginning of an allocated block. 
494-     fn miri_static_root(ptr : *const u8); 
495- 
496-     // Miri-provided extern function to get the amount of frames in the current backtrace. 
497-     // The `flags` argument must be `0`. 
498-     fn miri_backtrace_size(flags : u64) -> usize; 
499- 
500-     /// Miri-provided extern function to obtain a backtrace of the current call stack. 
501-     /// This writes a slice of pointers into `buf` - each pointer is an opaque value 
502-     /// that is only useful when passed to `miri_resolve_frame`. 
503-     /// `buf` must have `miri_backtrace_size(0) * pointer_size` bytes of space. 
504-     /// The `flags` argument must be `1`. 
505-     fn miri_get_backtrace(flags : u64, buf: *mut *mut ()); 
506- 
507-     /// Miri-provided extern function to resolve a frame pointer obtained 
508-     /// from `miri_get_backtrace`. The `flags` argument must be `1`, 
509-     /// and `MiriFrame` should be declared as follows :
510-     /// 
511-     /// ```rust 
512-     ///  # [repr(C)]
513-     /// struct MiriFrame { 
514-     ///     // The size of the name of the function being executed, encoded in UTF-8 
515-     ///     name_len : usize, 
516-     ///     // The size of filename of the function being executed, encoded in UTF-8 
517-     ///     filename_len : usize, 
518-     ///     // The line number currently being executed in `filename`, starting from '1'. 
519-     ///     lineno : u32, 
520-     ///     // The column number currently being executed in `filename`, starting from '1'. 
521-     ///     colno : u32, 
522-     ///     // The function pointer to the function currently being executed. 
523-     ///     // This can be compared against function pointers obtained by 
524-     ///     // casting a function (e.g. `my_fn as *mut ()`) 
525-     ///     fn_ptr : *mut () 
526-     /// } 
527-     /// ``` 
528-     /// 
529-     /// The fields must be declared in exactly the same order as they appear in `MiriFrame` above. 
530-     /// This function can be called on any thread (not just the one which obtained `frame`). 
531-     fn miri_resolve_frame(frame : *mut (), flags: u64) -> MiriFrame; 
532- 
533-     /// Miri-provided extern function to get the name and filename of the frame provided by `miri_resolve_frame`. 
534-     /// `name_buf` and `filename_buf` should be allocated with the `name_len` and `filename_len` fields of `MiriFrame`. 
535-     /// The flags argument must be `0`. 
536-     fn miri_resolve_frame_names(ptr : *mut (), flags: u64, name_buf: *mut u8, filename_buf: *mut u8); 
537- 
538-     /// Miri-provided extern function to begin unwinding with the given payload. 
539-     /// 
540-     /// This is internal and unstable and should not be used; we give it here 
541-     /// just to be complete. 
542-     fn miri_start_panic(payload : *mut u8) -> !; 
543- 
544-     /// Miri-provided extern function to get the internal unique identifier for the allocation that a pointer 
545-     /// points to. If this pointer is invalid (not pointing to an allocation), interpretation will abort. 
546-     /// 
547-     /// This is only useful as an input to `miri_print_borrow_stacks`, and it is a separate call because 
548-     /// getting a pointer to an allocation at runtime can change the borrow stacks in the allocation. 
549-     /// This function should be considered unstable. It exists only to support `miri_print_borrow_stacks` and so 
550-     /// inherits all of its instability. 
551-     fn miri_get_alloc_id(ptr : *const ()) -> u64; 
552- 
553-     /// Miri-provided extern function to print (from the interpreter, not the program) the contents of all 
554-     /// borrow stacks in an allocation. The leftmost tag is the bottom of the stack. 
555-     /// The format of what this emits is unstable and may change at any time. In particular, users should be 
556-     /// aware that Miri will periodically attempt to garbage collect the contents of all stacks. Callers of 
557-     /// this function may wish to pass `-Zmiri-tag-gc=0` to disable the GC. 
558-     /// 
559-     /// This function is extremely unstable. At any time the format of its output may change, its signature may 
560-     /// change, or it may be removed entirely. 
561-     fn miri_print_borrow_stacks(alloc_id : u64); 
562- 
563-     /// Miri-provided extern function to print (from the interpreter, not the 
564-     /// program) the contents of a section of program memory, as bytes. Bytes 
565-     /// written using this function will emerge from the interpreter's stdout. 
566-     fn miri_write_to_stdout(bytes : &[u8]); 
567- 
568-     /// Miri-provided extern function to print (from the interpreter, not the 
569-     /// program) the contents of a section of program memory, as bytes. Bytes 
570-     /// written using this function will emerge from the interpreter's stderr. 
571-     fn miri_write_to_stderr(bytes : &[u8]); 
572- 
573-     /// Miri-provided extern function to allocate memory from the interpreter. 
574-     ///  
575-     /// This is useful when no fundamental way of allocating memory is 
576-     /// available, e.g. when using `no_std` + `alloc`. 
577-     fn miri_alloc(size : usize, align: usize) -> *mut u8; 
578- 
579-     /// Miri-provided extern function to deallocate memory. 
580-     fn miri_dealloc(ptr : *mut u8, size: usize, align: usize); 
581- 
582-     /// Convert a path from the host Miri runs on to the target Miri interprets. 
583-     /// Performs conversion of path separators as needed. 
584-     /// 
585-     /// Usually Miri performs this kind of conversion automatically. However, manual conversion 
586-     /// might be necessary when reading an environment variable that was set on the host 
587-     /// (such as TMPDIR) and using it as a target path. 
588-     /// 
589-     /// Only works with isolation disabled. 
590-     /// 
591-     /// `in` must point to a null-terminated string, and will be read as the input host path. 
592-     /// `out` must point to at least `out_size` many bytes, and the result will be stored there 
593-     /// with a null terminator. 
594-     /// Returns 0 if the `out` buffer was large enough, and the required size otherwise. 
595-     fn miri_host_to_target_path(path : *const std::ffi::c_char, out: *mut std::ffi::c_char, out_size: usize) -> usize; 
596- } 
597- ``` 
511+ Miri-specific functionality. They are declared in 
512+ [/tests/utils/miri\_extern.rs](/tests/utils/miri_extern.rs). 
598513
599514# # Contributing and getting help
600515
0 commit comments