Auto merge of #26861 - steveklabnik:rollup, r=steveklabnik

- Successful merges: #26742, #26852, #26853, #26854, #26855, #26857
- Failed merges: #26796
This commit is contained in:
bors 2015-07-07 21:28:54 +00:00
commit e6a9be10bc
4 changed files with 144 additions and 23 deletions

View File

@ -10,11 +10,12 @@ system is up to the task, and gives you powerful ways to reason about
concurrent code at compile time.
Before we talk about the concurrency features that come with Rust, it's important
to understand something: Rust is low-level enough that all of this is provided
by the standard library, not by the language. This means that if you don't like
some aspect of the way Rust handles concurrency, you can implement an alternative
way of doing things. [mio](https://github.com/carllerche/mio) is a real-world
example of this principle in action.
to understand something: Rust is low-level enough that the vast majority of
this is provided by the standard library, not by the language. This means that
if you don't like some aspect of the way Rust handles concurrency, you can
implement an alternative way of doing things.
[mio](https://github.com/carllerche/mio) is a real-world example of this
principle in action.
## Background: `Send` and `Sync`

View File

@ -101,6 +101,8 @@ the lifetime `'a` has snuck in between the `&` and the `mut i32`. We read `&mut
i32` as a mutable reference to an i32 and `&'a mut i32` as a mutable
reference to an `i32` with the lifetime `'a`.
# In `struct`s
Youll also need explicit lifetimes when working with [`struct`][structs]s:
```rust
@ -137,6 +139,33 @@ x: &'a i32,
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 `i32` it contains.
## `impl` blocks
Lets implement a method on `Foo`:
```rust
struct Foo<'a> {
x: &'a i32,
}
impl<'a> Foo<'a> {
fn x(&self) -> &'a i32 { self.x }
}
fn main() {
let y = &5; // this is the same as `let _y = 5; let y = &_y;`
let f = Foo { x: y };
println!("x is: {}", f.x());
}
```
As you can see, we need to declare a lifetime for `Foo` in the `impl` line. We repeat
`'a` twice, just like on functions: `impl<'a>` defines a lifetime `'a`, and `Foo<'a>`
uses it.
## Multiple lifetimes
If you have multiple references, you can use the same lifetime multiple times:
```rust

View File

@ -8,7 +8,7 @@ this, Rust has a keyword, `unsafe`. Code using `unsafe` has less restrictions
than normal code does.
Lets go over the syntax, and then well talk semantics. `unsafe` is used in
two contexts. The first one is to mark a function as unsafe:
four contexts. The first one is to mark a function as unsafe:
```rust
unsafe fn danger_will_robinson() {
@ -27,15 +27,40 @@ unsafe {
}
```
The third is for unsafe traits:
```rust
unsafe trait Scary { }
```
And the fourth is for `impl`ementing one of those traits:
```rust
# unsafe trait Scary { }
unsafe impl Scary for i32 {}
```
Its important to be able to explicitly delineate code that may have bugs that
cause big problems. If a Rust program segfaults, you can be sure its somewhere
in the sections marked `unsafe`.
# What does safe mean?
Safe, in the context of Rust, means “doesnt do anything unsafe.” Easy!
Safe, in the context of Rust, means doesnt do anything unsafe. Its also
important to know that there are certain behaviors that are probably not
desirable in your code, but are expressly _not_ unsafe:
Okay, lets try again: what is not safe to do? Heres a list:
* Deadlocks
* Leaks of memory or other resources
* Exiting without calling destructors
* Integer overflow
Rust cannot prevent all kinds of software problems. Buggy code can and will be
written in Rust. These things arent great, but they dont qualify as `unsafe`
specifically.
In addition, the following are all undefined behaviors in Rust, and must be
avoided, even when writing `unsafe` code:
* Data races
* Dereferencing a null/dangling raw pointer
@ -64,18 +89,6 @@ Okay, lets try again: what is not safe to do? Heres a list:
[undef]: http://llvm.org/docs/LangRef.html#undefined-values
[aliasing]: http://llvm.org/docs/LangRef.html#pointer-aliasing-rules
Whew! Thats a bunch of stuff. Its also important to notice all kinds of
behaviors that are certainly bad, but are expressly _not_ unsafe:
* Deadlocks
* Leaks of memory or other resources
* Exiting without calling destructors
* Integer overflow
Rust cannot prevent all kinds of software problems. Buggy code can and will be
written in Rust. These things arent great, but they dont qualify as `unsafe`
specifically.
# Unsafe Superpowers
In both unsafe functions and unsafe blocks, Rust will let you do three things

View File

@ -1368,6 +1368,62 @@ struct Foo {
```
"##,
E0128: r##"
Type parameter defaults can only use parameters that occur before them.
Erroneous code example:
```
pub struct Foo<T=U, U=()> {
field1: T,
filed2: U,
}
// error: type parameters with a default cannot use forward declared
// identifiers
```
Since type parameters are evaluated in-order, you may be able to fix this issue
by doing:
```
pub struct Foo<U=(), T=U> {
field1: T,
filed2: U,
}
```
Please also verify that this wasn't because of a name-clash and rename the type
parameter if so.
"##,
E0130: r##"
You declared a pattern as an argument in a foreign function declaration.
Erroneous code example:
```
extern {
fn foo((a, b): (u32, u32)); // error: patterns aren't allowed in foreign
// function declarations
}
```
Please replace the pattern argument with a regular one. Example:
```
struct SomeStruct {
a: u32,
b: u32,
}
extern {
fn foo(s: SomeStruct); // ok!
}
// or
extern {
fn foo(a: (u32, u32)); // ok!
}
```
"##,
E0131: r##"
It is not possible to define `main` with type parameters, or even with function
parameters. When `main` is present, it must take no arguments and return `()`.
@ -1382,6 +1438,30 @@ fn(isize, *const *const u8) -> isize
```
"##,
E0159: r##"
You tried to use a trait as a struct constructor. Erroneous code example:
```
trait TraitNotAStruct {}
TraitNotAStruct{ value: 0 }; // error: use of trait `TraitNotAStruct` as a
// struct constructor
```
Please verify you used the correct type name or please implement the trait
on a struct and use this struct constructor. Example:
```
trait TraitNotAStruct {}
struct Foo {
value: i32
}
Foo{ value: 0 }; // ok!
```
"##,
E0166: r##"
This error means that the compiler found a return expression in a function
marked as diverging. A function diverges if it has `!` in the place of the
@ -1467,6 +1547,7 @@ impl Foo for Bar {
// the impl
fn foo() {}
}
```
"##,
E0192: r##"
@ -1978,11 +2059,8 @@ register_diagnostics! {
E0122,
E0123,
E0127,
E0128,
E0129,
E0130,
E0141,
E0159,
E0163,
E0164,
E0167,