Skip to content

Commit

Permalink
Auto merge of #26861 - steveklabnik:rollup, r=steveklabnik
Browse files Browse the repository at this point in the history
- Successful merges: #26742, #26852, #26853, #26854, #26855, #26857
- Failed merges: #26796
  • Loading branch information
bors committed Jul 7, 2015
2 parents 5d53921 + bead66b commit e6a9be1
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 23 deletions.
11 changes: 6 additions & 5 deletions src/doc/trpl/concurrency.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`

Expand Down
29 changes: 29 additions & 0 deletions src/doc/trpl/lifetimes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

You’ll also need explicit lifetimes when working with [`struct`][structs]s:

```rust
Expand Down Expand Up @@ -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

Let’s 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
Expand Down
43 changes: 28 additions & 15 deletions src/doc/trpl/unsafe.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ this, Rust has a keyword, `unsafe`. Code using `unsafe` has less restrictions
than normal code does.

Let’s go over the syntax, and then we’ll 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() {
Expand All @@ -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 {}
```

It’s 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 it’s somewhere
in the sections marked `unsafe`.

# What does ‘safe’ mean?

Safe, in the context of Rust, means “doesn’t do anything unsafe.” Easy!
Safe, in the context of Rust, means ‘doesn’t do anything unsafe’. It’s also
important to know that there are certain behaviors that are probably not
desirable in your code, but are expressly _not_ unsafe:

Okay, let’s try again: what is not safe to do? Here’s 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 aren’t great, but they don’t 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
Expand Down Expand Up @@ -64,18 +89,6 @@ Okay, let’s try again: what is not safe to do? Here’s a list:
[undef]: http://llvm.org/docs/LangRef.html#undefined-values
[aliasing]: http://llvm.org/docs/LangRef.html#pointer-aliasing-rules

Whew! That’s a bunch of stuff. It’s 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 aren’t great, but they don’t qualify as `unsafe`
specifically.

# Unsafe Superpowers

In both unsafe functions and unsafe blocks, Rust will let you do three things
Expand Down
84 changes: 81 additions & 3 deletions src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 `()`.
Expand All @@ -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
Expand Down Expand Up @@ -1467,6 +1547,7 @@ impl Foo for Bar {
// the impl
fn foo() {}
}
```
"##,

E0192: r##"
Expand Down Expand Up @@ -1978,11 +2059,8 @@ register_diagnostics! {
E0122,
E0123,
E0127,
E0128,
E0129,
E0130,
E0141,
E0159,
E0163,
E0164,
E0167,
Expand Down

0 comments on commit e6a9be1

Please sign in to comment.