diff --git a/src/doc/trpl/crates-and-modules.md b/src/doc/trpl/crates-and-modules.md index c179a263b35ed..737300c46643b 100644 --- a/src/doc/trpl/crates-and-modules.md +++ b/src/doc/trpl/crates-and-modules.md @@ -6,7 +6,7 @@ fit them together. It's also important to have a well-defined interface, so that some of your functionality is private, and some is public. To facilitate these kinds of things, Rust has a module system. -# Basic terminology: Crates and Modules +## Basic terminology: Crates and Modules Rust has two distinct terms that relate to the module system: *crate* and *module*. A crate is synonymous with a *library* or *package* in other @@ -70,7 +70,7 @@ $ tree . `src/lib.rs` is our crate root, corresponding to the `phrases` in our diagram above. -# Defining Modules +## Defining Modules To define each of our modules, we use the `mod` keyword. Let's make our `src/lib.rs` look like this: @@ -124,7 +124,7 @@ deps libphrases-a7448e02a0468eaa.rlib native `libphrase-hash.rlib` is the compiled crate. Before we see how to use this crate from another crate, let's break it up into multiple files. -# Multiple file crates +## Multiple file crates If each crate were just one file, these files would get very large. It's often easier to split up crates into multiple files, and Rust supports this in two @@ -261,7 +261,7 @@ fn goodbye() -> String { Now that we have our some functionality in our crate, let's try to use it from another crate. -# Importing External Crates +## Importing External Crates We have a library crate. Let's make an executable crate that imports and uses our library. @@ -314,7 +314,7 @@ note: in expansion of format_args! By default, everything is private in Rust. Let's talk about this in some more depth. -# Exporting a Public Interface +## Exporting a Public Interface Rust allows you to precisely control which aspects of your interface are public, and so private is the default. To make things public, you use the `pub` @@ -396,7 +396,7 @@ Now that our functions are public, we can use them. Great! However, typing out another keyword for importing names into the current scope, so that you can refer to them with shorter names. Let's talk about `use`. -# Importing Modules with `use` +## Importing Modules with `use` Rust has a `use` keyword, which allows us to import names into our local scope. Let's change our `src/main.rs` to look like this: @@ -477,7 +477,7 @@ use phrases::english::{greetings, farewells}; These two declarations are equivalent, but the second is a lot less typing. -## Re-exporting with `pub use` +### Re-exporting with `pub use` You don't just use `use` to shorten identifiers. You can also use it inside of your crate to re-export a function inside another module. This allows you to present an external diff --git a/src/doc/trpl/error-handling.md b/src/doc/trpl/error-handling.md index 6c444b741c5de..b21c5e1b05c42 100644 --- a/src/doc/trpl/error-handling.md +++ b/src/doc/trpl/error-handling.md @@ -13,7 +13,7 @@ There are two main kinds of errors that can occur in your programs: failures, and panics. Let's talk about the difference between the two, and then discuss how to handle each. Then, we'll discuss upgrading failures to panics. -# Failure vs. Panic +## Failure vs. Panic Rust uses two terms to differentiate between two forms of error: failure, and panic. A *failure* is an error that can be recovered from in some way. A @@ -116,7 +116,7 @@ We shouldn't ever hit the `_` case, so we use the `unreachable!()` macro to indicate this. `unreachable!()` gives a different kind of error than `Result`. Rust calls these sorts of errors *panics*. -# Handling errors with `Option` and `Result` +## Handling errors with `Option` and `Result` The simplest way to indicate that a function may fail is to use the `Option` type. Remember our `from_str()` example? Here's its type signature: @@ -178,7 +178,7 @@ match version { This function makes use of an enum, `ParseError`, to enumerate the various errors that can occur. -# Non-recoverable errors with `panic!` +## Non-recoverable errors with `panic!` In the case of an error that is unexpected and not recoverable, the `panic!` macro will induce a panic. This will crash the current task, and give an error: @@ -197,7 +197,7 @@ when you run it. Because these kinds of situations are relatively rare, use panics sparingly. -# Upgrading failures to panics +## Upgrading failures to panics In certain circumstances, even though a function may fail, we may want to treat it as a panic instead. For example, `io::stdin().read_line()` returns an diff --git a/src/doc/trpl/ffi.md b/src/doc/trpl/ffi.md index a65325af7be3d..08f264cfc03ab 100644 --- a/src/doc/trpl/ffi.md +++ b/src/doc/trpl/ffi.md @@ -1,6 +1,6 @@ % The Rust Foreign Function Interface Guide -# Introduction +## Introduction This guide will use the [snappy](https://github.com/google/snappy) compression/decompression library as an introduction to writing bindings for @@ -68,7 +68,7 @@ extern { # fn main() {} ~~~~ -# Creating a safe interface +## Creating a safe interface The raw C API needs to be wrapped to provide memory safety and make use of higher-level concepts like vectors. A library can choose to expose only the safe, high-level interface and hide the unsafe @@ -164,7 +164,7 @@ pub fn uncompress(src: &[u8]) -> Option> { For reference, the examples used here are also available as an [library on GitHub](https://github.com/thestinger/rust-snappy). -# Stack management +## Stack management Rust tasks by default run on a *large stack*. This is actually implemented as a reserving a large segment of the address space and then lazily mapping in pages @@ -187,13 +187,13 @@ interoperate. If, however, it is determined that a larger stack is necessary, there are appropriate functions in the task spawning API to control the size of the stack of the task which is spawned. -# Destructors +## Destructors Foreign libraries often hand off ownership of resources to the calling code. When this occurs, we must use Rust's destructors to provide safety and guarantee the release of these resources (especially in the case of panic). -# Callbacks from C code to Rust functions +## Callbacks from C code to Rust functions Some external libraries require the usage of callbacks to report back their current state or intermediate data to the caller. @@ -247,7 +247,7 @@ In this example Rust's `main()` will call `trigger_callback()` in C, which would, in turn, call back to `callback()` in Rust. -## Targeting callbacks to Rust objects +### Targeting callbacks to Rust objects The former example showed how a global function can be called from C code. However it is often desired that the callback is targeted to a special @@ -314,7 +314,7 @@ void trigger_callback() { } ~~~~ -## Asynchronous callbacks +### Asynchronous callbacks In the previously given examples the callbacks are invoked as a direct reaction to a function call to the external C library. @@ -338,7 +338,7 @@ This can be achieved by unregistering the callback in the object's destructor and designing the library in a way that guarantees that no callback will be performed after deregistration. -# Linking +## Linking The `link` attribute on `extern` blocks provides the basic building block for instructing rustc how it will link to native libraries. There are two accepted @@ -385,7 +385,7 @@ A few examples of how this model can be used are: On OSX, frameworks behave with the same semantics as a dynamic library. -## The `link_args` attribute +### The `link_args` attribute There is one other way to tell rustc how to customize linking, and that is via the `link_args` attribute. This attribute is applied to `extern` blocks and @@ -410,7 +410,7 @@ meaning. It is highly recommended to *not* use this attribute, and rather use the more formal `#[link(...)]` attribute on `extern` blocks instead. -# Unsafe blocks +## Unsafe blocks Some operations, like dereferencing unsafe pointers or calling functions that have been marked unsafe are only allowed inside unsafe blocks. Unsafe blocks isolate unsafety and are a promise to @@ -425,7 +425,7 @@ unsafe fn kaboom(ptr: *const int) -> int { *ptr } This function can only be called from an `unsafe` block or another `unsafe` function. -# Accessing foreign globals +## Accessing foreign globals Foreign APIs often export a global variable which could do something like track global state. In order to access these variables, you declare them in `extern` @@ -468,7 +468,7 @@ fn main() { } ~~~ -# Foreign calling conventions +## Foreign calling conventions Most foreign code exposes a C ABI, and Rust uses the platform's C calling convention by default when calling foreign functions. Some foreign functions, most notably the Windows API, use other calling @@ -507,7 +507,7 @@ however, windows uses the `C` calling convention, so `C` would be used. This means that in our previous example, we could have used `extern "system" { ... }` to define a block for all windows systems, not just x86 ones. -# Interoperability with foreign code +## Interoperability with foreign code Rust guarantees that the layout of a `struct` is compatible with the platform's representation in C only if the `#[repr(C)]` attribute is applied to it. @@ -532,7 +532,7 @@ The standard library includes type aliases and function definitions for the C standard library in the `libc` module, and Rust links against `libc` and `libm` by default. -# The "nullable pointer optimization" +## The "nullable pointer optimization" Certain types are defined to not be `null`. This includes references (`&T`, `&mut T`), boxes (`Box`), and function pointers (`extern "abi" fn()`). diff --git a/src/doc/trpl/macros.md b/src/doc/trpl/macros.md index c73fbefb2a401..af334511b21d5 100644 --- a/src/doc/trpl/macros.md +++ b/src/doc/trpl/macros.md @@ -1,6 +1,6 @@ % The Rust Macros Guide -# Introduction +## Introduction Functions are the primary tool that programmers can use to build abstractions. Sometimes, however, programmers want to abstract over compile-time syntax @@ -64,7 +64,7 @@ Macros are defined in pattern-matching style: in the above example, the text macro. The text on the right-hand side of the `=>`, beginning with `match $inp`, is the *macro transcription syntax*: what the macro expands to. -# Invocation syntax +## Invocation syntax The macro invocation syntax specifies the syntax for the arguments to the macro. It appears on the left-hand side of the `=>` in a macro definition. It @@ -97,7 +97,7 @@ rules of tokenization apply, So `($x:ident -> (($e:expr)))`, though excessively fancy, would designate a macro that could be invoked like: `my_macro!(i->(( 2+2 )))`. -## Invocation location +### Invocation location A macro invocation may take the place of (and therefore expand to) an expression, item, statement, or pattern. The Rust parser will parse the macro @@ -112,7 +112,7 @@ location). Although this behavior sounds excessively dynamic, it is known to be useful under some circumstances. -# Transcription syntax +## Transcription syntax The right-hand side of the `=>` follows the same rules as the left-hand side, except that a `$` need only be followed by the name of the syntactic fragment @@ -132,15 +132,15 @@ are permitted in expression, statement, and item locations. However, nothing else about the code is examined or executed by the macro system; execution still has to wait until run-time. -## Interpolation location +### Interpolation location The interpolation `$argument_name` may appear in any location consistent with its fragment specifier (i.e., if it is specified as `ident`, it may be used anywhere an identifier is permitted). -# Multiplicity +## Multiplicity -## Invocation +### Invocation Going back to the motivating example, recall that `early_return` expanded into a `match` that would `return` if the `match`'s scrutinee matched the @@ -179,7 +179,7 @@ early_return!(input_2, [T::SpecialB]); # fn main() {} ~~~~ -### Transcription +#### Transcription As the above example demonstrates, `$(...)*` is also valid on the right-hand side of a macro definition. The behavior of `*` in transcription, @@ -191,7 +191,7 @@ of repetitions for all of the `$name`s it contains in lockstep, and (2) each `$name` must be under at least as many `$(...)*`s as it was matched against. If it is under more, it'll be repeated, as appropriate. -## Parsing limitations +### Parsing limitations For technical reasons, there are two limitations to the treatment of syntax @@ -210,9 +210,9 @@ parsing `e`. Changing the invocation syntax to require a distinctive token in front can solve the problem. In the above example, `$(T $t:ty)* E $e:exp` solves the problem. -# Macro argument pattern matching +## Macro argument pattern matching -## Motivation +### Motivation Now consider code like the following: @@ -295,7 +295,7 @@ pattern we want is clear: However, it's not possible to directly expand to nested match statements. But there is a solution. -## The recursive approach to macro writing +### The recursive approach to macro writing A macro may accept multiple different input grammars. The first one to successfully match the actual argument to a macro invocation is the one that @@ -408,7 +408,7 @@ position (in particular, not as an argument to yet another macro invocation), the expander will then proceed to evaluate `m2!()` (along with any other macro invocations `m1!(m2!())` produced). -# Hygiene +## Hygiene To prevent clashes, rust implements [hygienic macros](http://en.wikipedia.org/wiki/Hygienic_macro). @@ -438,7 +438,7 @@ fn main() { The two `'x` names did not clash, which would have caused the loop to print "I am never printed" and to run forever. -# Scoping and macro import/export +## Scoping and macro import/export Macros are expanded at an early stage in compilation, before name resolution. One downside is that scoping works differently for macros, compared to other @@ -513,7 +513,7 @@ be imported. The Rust Reference has a [listing of macro-related attributes](../reference.html#macro--and-plugin-related-attributes). -# The variable `$crate` +## The variable `$crate` A further difficulty occurs when a macro is used in multiple crates. Say that `mylib` defines @@ -560,7 +560,7 @@ To keep this system simple and correct, `#[macro_use] extern crate ...` may only appear at the root of your crate, not inside `mod`. This ensures that `$crate` is a single identifier. -# A final note +## A final note Macros, as currently implemented, are not for the faint of heart. Even ordinary syntax errors can be more difficult to debug when they occur inside a diff --git a/src/doc/trpl/ownership.md b/src/doc/trpl/ownership.md index 4febec941350b..b8c57af6f8883 100644 --- a/src/doc/trpl/ownership.md +++ b/src/doc/trpl/ownership.md @@ -6,7 +6,7 @@ acquainted. Ownership is how Rust achieves its largest goal, memory safety. The ownership system has a few distinct concepts: *ownership*, *borrowing*, and *lifetimes*. We'll talk about each one in turn. -# Meta +## Meta Before we get to the details, two important notes about the ownership system. @@ -29,7 +29,7 @@ checker less and less. With that in mind, let's learn about ownership. -# Ownership +## Ownership At its core, ownership is about *resources*. For the purposes of the vast majority of this guide, we will talk about a specific resource: memory. The @@ -174,7 +174,7 @@ and so Rust introduces a concept to describe a handle which temporarily refers to something another handle owns. It's called *borrowing*, and it's done with *references*, designated by the `&` symbol. -# Borrowing +## Borrowing Here's the current state of our `add_one` function: @@ -207,7 +207,7 @@ fn add_one(num: &mut int) { This function borrows an `int` from its caller, and then increments it. When the function is over, and `num` goes out of scope, the borrow is over. -# Lifetimes +## Lifetimes Lending out a reference to a resource that someone else owns can be complicated, however. For example, imagine this set of operations: @@ -303,7 +303,7 @@ x: &'a int, uses it. So why do we need a lifetime here? We need to ensure that any reference to a `Foo` cannot outlive the reference to an `int` it contains. -## Thinking in scopes +### Thinking in scopes A way to think about lifetimes is to visualize the scope that a reference is valid for. For example: @@ -360,7 +360,7 @@ about to go out of scope. Named lifetimes are a way of giving these scopes a name. Giving something a name is the first step towards being able to talk about it. -## 'static +### 'static The lifetime named *static* is a special lifetime. It signals that something has the lifetime of the entire program. Most Rust programmers first come across @@ -382,7 +382,7 @@ let x: &'static int = &FOO; This adds an `int` to the data segment of the binary, and FOO is a reference to it. -# Shared Ownership +## Shared Ownership In all the examples we've considered so far, we've assumed that each handle has a singular owner. But sometimes, this doesn't work. Consider a car. Cars have @@ -454,7 +454,7 @@ This is the simplest kind of multiple ownership possible. For example, there's also `Arc`, which uses more expensive atomic instructions to be the thread-safe counterpart of `Rc`. -## Lifetime Elision +### Lifetime Elision Earlier, we mentioned *lifetime elision*, a feature of Rust which allows you to not write lifetime annotations in certain circumstances. All references have a @@ -495,7 +495,7 @@ Here are the three rules: Otherwise, it is an error to elide an output lifetime. -### Examples +#### Examples Here are some examples of functions with elided lifetimes, and the version of what the elided lifetimes are expand to: @@ -528,6 +528,6 @@ fn new(buf: &mut [u8]) -> BufWriter; // elided fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> // expanded ``` -# Related Resources +## Related Resources Coming Soon. diff --git a/src/doc/trpl/plugins.md b/src/doc/trpl/plugins.md index 2fc361ca1b284..09392b9f31943 100644 --- a/src/doc/trpl/plugins.md +++ b/src/doc/trpl/plugins.md @@ -24,7 +24,7 @@ information. -# Introduction +## Introduction `rustc` can load compiler plugins, which are user-provided libraries that extend the compiler's behavior with new syntax extensions, lint checks, etc. @@ -39,7 +39,7 @@ Arguments passed as `#[plugin=...]` or `#[plugin(...)]` are not interpreted by rustc itself. They are provided to the plugin through the `Registry`'s [`args` method](../rustc/plugin/registry/struct.Registry.html#method.args). -# Syntax extensions +## Syntax extensions Plugins can extend Rust's syntax in various ways. One kind of syntax extension is the procedural macro. These are invoked the same way as [ordinary @@ -135,7 +135,7 @@ a more involved macro example, see [`regex_macros`](https://github.com/rust-lang/regex/blob/master/regex_macros/src/lib.rs). -## Tips and tricks +### Tips and tricks To see the results of expanding syntax extensions, run `rustc --pretty expanded`. The output represents a whole crate, so you @@ -183,7 +183,7 @@ very rough around the edges. However, the implementation may be a good starting point for an improved quasiquote as an ordinary plugin library. -# Lint plugins +## Lint plugins Plugins can extend [Rust's lint infrastructure](../reference.html#lint-check-attributes) with additional checks for diff --git a/src/doc/trpl/pointers.md b/src/doc/trpl/pointers.md index 63c16ef191e06..718ab97b51cd2 100644 --- a/src/doc/trpl/pointers.md +++ b/src/doc/trpl/pointers.md @@ -13,13 +13,13 @@ unless you're in one of those specific situations. You may be interested in the [cheat sheet](#cheat-sheet), which gives a quick overview of the types, names, and purpose of the various pointers. -# An introduction +## An introduction If you aren't familiar with the concept of pointers, here's a short introduction. Pointers are a very fundamental concept in systems programming languages, so it's important to understand them. -## Pointer Basics +### Pointer Basics When you create a new variable binding, you're giving a name to a value that's stored at a particular location on the stack. (If you're not familiar with the @@ -108,7 +108,7 @@ That's it! That's all pointers are: they point to some memory location. Not much else to them. Now that we've discussed the *what* of pointers, let's talk about the *why*. -## Pointer uses +### Pointer uses Rust's pointers are quite useful, but in different ways than in other systems languages. We'll talk about best practices for Rust pointers later in @@ -170,7 +170,7 @@ but because it points at a memory location, which we then assign to, the original value is still changed. This pattern is called *pass-reference-by-value*. Tricky! -## Common pointer problems +### Common pointer problems We've talked about pointers, and we've sung their praises. So what's the downside? Well, Rust attempts to mitigate each of these kinds of problems, @@ -238,7 +238,7 @@ first, and therefore, the value of `x` is actually non-deterministic. Worse, what if one of them had invalidated the memory location they pointed to? We'd have the same problem as before, where we'd be setting an invalid location. -## Conclusion +### Conclusion That's a basic overview of pointers as a general concept. As we alluded to before, Rust has different kinds of pointers, rather than just one, and @@ -246,7 +246,7 @@ mitigates all of the problems that we talked about, too. This does mean that Rust pointers are slightly more complicated than in other languages, but it's worth it to not have the problems that simple pointers have. -# References +## References The most basic type of pointer that Rust has is called a *reference*. Rust references look like this: @@ -412,7 +412,7 @@ hard for a computer, too! There is an entire [guide devoted to references, owner and lifetimes](ownership.html) that goes into this topic in great detail, so if you want the full details, check that out. -## Best practices +### Best practices In general, prefer stack allocation over heap allocation. Using references to stack allocated information is preferred whenever possible. Therefore, @@ -472,7 +472,7 @@ succ(&*rc_x); The initial `*` dereferences the pointer, and then `&` takes a reference to those contents. -# Boxes +## Boxes `Box` is Rust's *boxed pointer* type. Boxes provide the simplest form of heap allocation in Rust. Creating a box looks like this: @@ -598,12 +598,12 @@ fn main() { Notice we changed the signature of `add_one()` to request a mutable reference. -## Best practices +### Best practices Boxes are appropriate to use in two situations: Recursive data structures, and occasionally, when returning data. -### Recursive data structures +#### Recursive data structures Sometimes, you need a recursive data structure. The simplest is known as a *cons list*: @@ -636,7 +636,7 @@ we don't know the size, and therefore, we need to heap allocate our list. Working with recursive or other unknown-sized data structures is the primary use-case for boxes. -### Returning data +#### Returning data This is important enough to have its own section entirely. The TL;DR is this: you don't generally want to return pointers, even when you might in a language @@ -644,23 +644,23 @@ like C or C++. See [Returning Pointers](#returning-pointers) below for more. -# Rc and Arc +## Rc and Arc This part is coming soon. -## Best practices +### Best practices This part is coming soon. -# Raw Pointers +## Raw Pointers This part is coming soon. -## Best practices +### Best practices This part is coming soon. -# Returning Pointers +## Returning Pointers In many languages with pointers, you'd return a pointer from a function so as to avoid copying a large data structure. For example: @@ -731,15 +731,15 @@ This is important enough that it bears repeating: pointers are not for optimizing returning values from your code. Allow the caller to choose how they want to use your output. -# Creating your own Pointers +## Creating your own Pointers This part is coming soon. -## Best practices +### Best practices This part is coming soon. -# Patterns and `ref` +## Patterns and `ref` When you're trying to match something that's stored in a pointer, there may be a situation where matching directly isn't the best option available. Let's see @@ -764,7 +764,7 @@ The `ref s` here means that `s` will be of type `&String`, rather than type This is important when the type you're trying to get access to has a destructor and you don't want to move it, you just want a reference to it. -# Cheat Sheet +## Cheat Sheet Here's a quick rundown of Rust's pointer types: @@ -778,7 +778,7 @@ Here's a quick rundown of Rust's pointer types: | `*const T` | Raw pointer | Unsafe read access to `T` | | `*mut T` | Mutable raw pointer | Unsafe read and write access to `T` | -# Related resources +## Related resources * [API documentation for Box](../std/boxed/index.html) * [Ownership guide](ownership.html) diff --git a/src/doc/trpl/tasks.md b/src/doc/trpl/tasks.md index 4c6a7f1323fb1..16e188491b34f 100644 --- a/src/doc/trpl/tasks.md +++ b/src/doc/trpl/tasks.md @@ -2,7 +2,7 @@ **NOTE** This guide is badly out of date and needs to be rewritten. -# Introduction +## Introduction Rust provides safe concurrent abstractions through a number of core library primitives. This guide will describe the concurrency model in Rust, how it @@ -19,7 +19,7 @@ Threads use Rust's type system to provide strong memory safety guarantees. In particular, the type system guarantees that threads cannot induce a data race from shared mutable state. -# Basics +## Basics At its simplest, creating a thread is a matter of calling the `spawn` function with a closure argument. `spawn` executes the closure in the new thread. @@ -66,7 +66,7 @@ spawn(move || { }); ``` -## Communication +### Communication Now that we have spawned a new thread, it would be nice if we could communicate with it. For this, we use *channels*. A channel is simply a pair of endpoints: @@ -198,7 +198,7 @@ let result = rxs.iter().fold(0, |accum, rx| accum + rx.recv() ); # fn some_expensive_computation(_i: uint) -> int { 42 } ``` -## Backgrounding computations: Futures +### Backgrounding computations: Futures With `sync::Future`, rust has a mechanism for requesting a computation and getting the result later. @@ -256,7 +256,7 @@ fn main() { } ``` -## Sharing without copying: Arc +### Sharing without copying: Arc To share data between threads, a first approach would be to only use channel as we have seen previously. A copy of the data to share would then be made for @@ -329,7 +329,7 @@ spawn(move || { # } ``` -# Handling thread panics +## Handling thread panics Rust has a built-in mechanism for raising exceptions. The `panic!()` macro (which can also be written with an error string as an argument: `panic!( diff --git a/src/doc/trpl/testing.md b/src/doc/trpl/testing.md index 791a90bdf9b82..1b6b738c15cd9 100644 --- a/src/doc/trpl/testing.md +++ b/src/doc/trpl/testing.md @@ -10,7 +10,7 @@ the right way to test Rust code. There are many schools of thought regarding the right and wrong way to write tests. All of these approaches use the same basic tools, and so we'll show you the syntax for using them. -# The `test` attribute +## The `test` attribute At its simplest, a test in Rust is a function that's annotated with the `test` attribute. Let's make a new project with Cargo called `adder`: @@ -219,7 +219,7 @@ fn it_works() { This is a very common use of `assert_eq!`: call some function with some known arguments and compare it to the expected output. -# The `test` module +## The `test` module There is one way in which our existing example is not idiomatic: it's missing the test module. The idiomatic way of writing our example @@ -299,7 +299,7 @@ tests. Anything that just tests one small bit of functionality makes sense to go here. But what about "integration-style" tests instead? For that, we have the `tests` directory -# The `tests` directory +## The `tests` directory To write an integration test, let's make a `tests` directory, and put a `tests/lib.rs` file inside, with this as its contents: @@ -353,7 +353,7 @@ here, since the whole thing is focused on tests. Let's finally check out that third section: documentation tests. -# Documentation tests +## Documentation tests Nothing is better than documentation with examples. Nothing is worse than examples that don't actually work, because the code has changed since the @@ -434,7 +434,7 @@ documentation tests: the `_0` is generated for the module test, and `add_two_0` for the function test. These will auto increment with names like `add_two_1` as you add more examples. -# Benchmark tests +## Benchmark tests Rust also supports benchmark tests, which can test the performance of your code. Let's make our `src/lib.rs` look like this (comments elided): @@ -503,7 +503,7 @@ Advice on writing benchmarks: * Make the code in the `iter` loop do something simple, to assist in pinpointing performance improvements (or regressions) -## Gotcha: optimizations +### Gotcha: optimizations There's another tricky part to writing benchmarks: benchmarks compiled with optimizations activated can be dramatically changed by the optimizer so that diff --git a/src/doc/trpl/unsafe.md b/src/doc/trpl/unsafe.md index 38427875a6230..84146a0403f74 100644 --- a/src/doc/trpl/unsafe.md +++ b/src/doc/trpl/unsafe.md @@ -1,6 +1,6 @@ % Writing Unsafe and Low-Level Code in Rust -# Introduction +## Introduction Rust aims to provide safe abstractions over the low-level details of the CPU and operating system, but sometimes one needs to drop down and @@ -32,9 +32,9 @@ build safe interfaces. > compilation errors, but do cause semantic changes (such as invoking > undefined behaviour). As such, extreme care is required. -# Pointers +## Pointers -## References +### References One of Rust's biggest features is memory safety. This is achieved in part via [the ownership system](ownership.html), which is how the @@ -76,7 +76,7 @@ let ref_2: &mut u8 = unsafe { mem::transmute(&mut *ref_1) }; *ref_2 = 20; ``` -## Raw pointers +### Raw pointers Rust offers two additional pointer types (*raw pointers*), written as `*const T` and `*mut T`. They're an approximation of C's `const T*` and `T*` @@ -127,7 +127,7 @@ The latter assumption allows the compiler to optimize more effectively. As can be seen, actually *creating* a raw pointer is not unsafe, and neither is converting to an integer. -### References and raw pointers +#### References and raw pointers At runtime, a raw pointer `*` and a reference pointing to the same piece of data have an identical representation. In fact, an `&T` @@ -167,7 +167,7 @@ requires that `x` is a pointer (unlike `transmute`). -## Making the unsafe safe(r) +### Making the unsafe safe(r) There are various ways to expose a safe interface around some unsafe code: @@ -284,7 +284,7 @@ because the compiler statically guarantees that objects are never used before creation or after destruction (unless you use some `unsafe` code...). -# Inline assembly +## Inline assembly For extremely low-level manipulations and performance reasons, one might wish to control the CPU directly. Rust supports using inline @@ -306,7 +306,7 @@ crate to allow) and of course requires an `unsafe` block. > **Note**: the examples here are given in x86/x86-64 assembly, but > all platforms are supported. -## Assembly template +### Assembly template The `assembly template` is the only required parameter and must be a literal string (i.e `""`) @@ -359,7 +359,7 @@ asm!("xor %eax, %eax" ::: "eax"); # } } ``` -## Operands +### Operands Input and output operands follow the same format: `: "constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand @@ -386,7 +386,7 @@ fn main() { } ``` -## Clobbers +### Clobbers Some instructions modify registers which might otherwise have held different values so we use the clobbers list to indicate to the @@ -410,7 +410,7 @@ If the assembly changes the condition code register `cc` should be specified as one of the clobbers. Similarly, if the assembly modifies memory, `memory` should also be specified. -## Options +### Options The last section, `options` is specific to Rust. The format is comma separated literal strings (i.e `:"foo", "bar", "baz"`). It's used to @@ -425,7 +425,7 @@ Current valid options are: the compiler to insert its usual stack alignment code 3. *intel* - use intel syntax instead of the default AT&T. -# Avoiding the standard library +## Avoiding the standard library By default, `std` is linked to every Rust crate. In some contexts, this is undesirable, and can be avoided with the `#![no_std]` @@ -510,7 +510,7 @@ information), but crates which do not trigger a panic can be assured that this function is never called. The final function, `panic_fmt`, is also used by the failure mechanisms of the compiler. -## Using libcore +### Using libcore > **Note**: the core library's structure is unstable, and it is recommended to > use the standard library instead wherever possible. @@ -592,7 +592,7 @@ libraries, such as liballoc, add functionality to libcore which make other platform-specific assumptions, but continue to be more portable than the standard library itself. -# Interacting with the compiler internals +## Interacting with the compiler internals > **Note**: this section is specific to the `rustc` compiler; these > parts of the language may never be fully specified and so details may @@ -611,7 +611,7 @@ libraries to interact directly with the compiler and vice versa: - lang-items, special functions, types and traits in libraries marked with specific `#[lang]` attributes -## Intrinsics +### Intrinsics > **Note**: intrinsics will forever have an unstable interface, it is > recommended to use the stable interfaces of libcore rather than intrinsics @@ -636,7 +636,7 @@ extern "rust-intrinsic" { As with any other FFI functions, these are always `unsafe` to call. -## Lang items +### Lang items > **Note**: lang items are often provided by crates in the Rust distribution, > and lang items themselves have an unstable interface. It is recommended to use