mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Auto merge of #26861 - steveklabnik:rollup, r=steveklabnik
- Successful merges: #26742, #26852, #26853, #26854, #26855, #26857 - Failed merges: #26796
This commit is contained in:
commit
e6a9be10bc
@ -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`
|
||||
|
||||
|
@ -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
|
||||
@ -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
|
||||
|
@ -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() {
|
||||
@ -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
|
||||
@ -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
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user