Skip to content

Commit

Permalink
Auto merge of #27453 - Manishearth:rollup, r=Manishearth
Browse files Browse the repository at this point in the history
- Successful merges: #26982, #27305, #27419, #27423, #27426
- Failed merges:
  • Loading branch information
bors committed Aug 1, 2015
2 parents f50518e + ead9a6d commit 832e5a0
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 28 deletions.
22 changes: 15 additions & 7 deletions src/doc/tarpl/borrow-splitting.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,27 @@ However borrowck doesn't understand arrays or slices in any way, so this doesn't
work:

```rust,ignore
let x = [1, 2, 3];
let mut x = [1, 2, 3];
let a = &mut x[0];
let b = &mut x[1];
println!("{} {}", a, b);
```

```text
<anon>:3:18: 3:22 error: cannot borrow immutable indexed content `x[..]` as mutable
<anon>:3 let a = &mut x[0];
^~~~
<anon>:4:18: 4:22 error: cannot borrow immutable indexed content `x[..]` as mutable
<anon>:4 let b = &mut x[1];
^~~~
<anon>:4:14: 4:18 error: cannot borrow `x[..]` as mutable more than once at a time
<anon>:4 let b = &mut x[1];
^~~~
<anon>:3:14: 3:18 note: previous borrow of `x[..]` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `x[..]` until the borrow ends
<anon>:3 let a = &mut x[0];
^~~~
<anon>:6:2: 6:2 note: previous borrow ends here
<anon>:1 fn main() {
<anon>:2 let mut x = [1, 2, 3];
<anon>:3 let a = &mut x[0];
<anon>:4 let b = &mut x[1];
<anon>:5 println!("{} {}", a, b);
<anon>:6 }
^
error: aborting due to 2 previous errors
```

Expand Down
12 changes: 6 additions & 6 deletions src/doc/tarpl/send-and-sync.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ multiply alias a location in memory while mutating it. Unless these types use
synchronization to manage this access, they are absolutely not thread safe. Rust
captures this with through the `Send` and `Sync` traits.

* A type is Send if it is safe to send it to another thread. A type is Sync if
* it is safe to share between threads (`&T` is Send).
* A type is Send if it is safe to send it to another thread.
* A type is Sync if it is safe to share between threads (`&T` is Send).

Send and Sync are fundamental to Rust's concurrency story. As such, a
substantial amount of special tooling exists to make them work right. First and
Expand All @@ -24,9 +24,9 @@ pretty much all types you'll ever interact with are Send and Sync.

Major exceptions include:

* raw pointers are neither Send nor Sync (because they have no safety guards)
* `UnsafeCell` isn't Sync (and therefore `Cell` and `RefCell` aren't) `Rc` isn't
* Send or Sync (because the refcount is shared and unsynchronized)
* raw pointers are neither Send nor Sync (because they have no safety guards).
* `UnsafeCell` isn't Sync (and therefore `Cell` and `RefCell` aren't).
* `Rc` isn't Send or Sync (because the refcount is shared and unsynchronized).

`Rc` and `UnsafeCell` are very fundamentally not thread-safe: they enable
unsynchronized shared mutable state. However raw pointers are, strictly
Expand Down Expand Up @@ -70,7 +70,7 @@ possible cause trouble by being incorrectly Send or Sync.
Most uses of raw pointers should be encapsulated behind a sufficient abstraction
that Send and Sync can be derived. For instance all of Rust's standard
collections are Send and Sync (when they contain Send and Sync types) in spite
of their pervasive use raw pointers to manage allocations and complex ownership.
of their pervasive use of raw pointers to manage allocations and complex ownership.
Similarly, most iterators into these collections are Send and Sync because they
largely behave like an `&` or `&mut` into the collection.

Expand Down
106 changes: 92 additions & 14 deletions src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1227,16 +1227,22 @@ impl Bytes { ... } // error, same as above
"##,

E0117: r##"
You got this error because because you tried to implement a foreign
trait for a foreign type (with maybe a foreign type parameter). Erroneous
code example:
This error indicates a violation of one of Rust's orphan rules for trait
implementations. The rule prohibits any implementation of a foreign trait (a
trait defined in another crate) where
- the type that is implementing the trait is foreign
- all of the parameters being passed to the trait (if there are any) are also
foreign.
Here's one example of this error:
```
impl Drop for u32 {}
```
The type, trait or the type parameter (or all of them) has to be defined
in your crate. Example:
To avoid this kind of error, ensure that at least one local type is referenced
by the `impl`:
```
pub struct Foo; // you define your type in your crate
Expand All @@ -1245,21 +1251,29 @@ impl Drop for Foo { // and you can implement the trait on it!
// code of trait implementation here
}
trait Bar { // or define your trait in your crate
fn get(&self) -> usize;
}
impl Bar for u32 { // and then you implement it on a foreign type
fn get(&self) -> usize { 0 }
}
impl From<Foo> for i32 { // or you use a type from your crate as
// a type parameter
fn from(i: Foo) -> i32 {
0
}
}
```
Alternatively, define a trait locally and implement that instead:
```
trait Bar {
fn get(&self) -> usize;
}
impl Bar for u32 {
fn get(&self) -> usize { 0 }
}
```
For information on the design of the orphan rules, see [RFC 1023].
[RFC 1023]: https://github.com/rust-lang/rfcs/pull/1023
"##,

E0119: r##"
Expand Down Expand Up @@ -1889,6 +1903,71 @@ impl MyTrait for Foo {
```
"##,

E0210: r##"
This error indicates a violation of one of Rust's orphan rules for trait
implementations. The rule concerns the use of type parameters in an
implementation of a foreign trait (a trait defined in another crate), and
states that type parameters must be "covered" by a local type. To understand
what this means, it is perhaps easiest to consider a few examples.
If `ForeignTrait` is a trait defined in some external crate `foo`, then the
following trait `impl` is an error:
```
extern crate foo;
use foo::ForeignTrait;
impl<T> ForeignTrait for T { ... } // error
```
To work around this, it can be covered with a local type, `MyType`:
```
struct MyType<T>(T);
impl<T> ForeignTrait for MyType<T> { ... } // Ok
```
For another example of an error, suppose there's another trait defined in `foo`
named `ForeignTrait2` that takes two type parameters. Then this `impl` results
in the same rule violation:
```
struct MyType2;
impl<T> ForeignTrait2<T, MyType<T>> for MyType2 { ... } // error
```
The reason for this is that there are two appearances of type parameter `T` in
the `impl` header, both as parameters for `ForeignTrait2`. The first appearance
is uncovered, and so runs afoul of the orphan rule.
Consider one more example:
```
impl<T> ForeignTrait2<MyType<T>, T> for MyType2 { ... } // Ok
```
This only differs from the previous `impl` in that the parameters `T` and
`MyType<T>` for `ForeignTrait2` have been swapped. This example does *not*
violate the orphan rule; it is permitted.
To see why that last example was allowed, you need to understand the general
rule. Unfortunately this rule is a bit tricky to state. Consider an `impl`:
```
impl<P1, ..., Pm> ForeignTrait<T1, ..., Tn> for T0 { ... }
```
where `P1, ..., Pm` are the type parameters of the `impl` and `T0, ..., Tn`
are types. One of the types `T0, ..., Tn` must be a local type (this is another
orphan rule, see the explanation for E0117). Let `i` be the smallest integer
such that `Ti` is a local type. Then no type parameter can appear in any of the
`Tj` for `j < i`.
For information on the design of the orphan rules, see [RFC 1023].
[RFC 1023]: https://github.com/rust-lang/rfcs/pull/1023
"##,

E0211: r##"
You used an intrinsic function which doesn't correspond to its
definition. Erroneous code example:
Expand Down Expand Up @@ -2335,7 +2414,6 @@ register_diagnostics! {
// and only one is supported
E0208,
E0209, // builtin traits can only be implemented on structs or enums
E0210, // type parameter is not constrained by any local type
E0212, // cannot extract an associated type from a higher-ranked trait bound
E0213, // associated types are not accepted in this context
E0214, // parenthesized parameters may only be used with a trait
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
//! for the [broader Rust ecosystem](https://crates.io). It offers
//! core types (e.g. [`Vec`](vec/index.html)
//! and [`Option`](option/index.html)), library-defined [operations on
//! language primitives](#primitive) (e.g. [`u32`](u32/index.html) and
//! language primitives](#primitives) (e.g. [`u32`](u32/index.html) and
//! [`str`](str/index.html)), [standard macros](#macros),
//! [I/O](io/index.html) and [multithreading](thread/index.html), among
//! [many other lovely
Expand Down

0 comments on commit 832e5a0

Please sign in to comment.