about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-08-01 08:36:59 +0000
committerbors <bors@rust-lang.org>2015-08-01 08:36:59 +0000
commit832e5a02cd41b3a20d1142b47867da4aa5033f03 (patch)
tree46e2aae3d859a544acbdc5b44d7bc1eb52f8ad2c
parentf50518e05ab1fd7632b83c0c6675ec072d1685ea (diff)
parentead9a6dacf88f252b700a3d342cf332ae522eef7 (diff)
downloadrust-832e5a02cd41b3a20d1142b47867da4aa5033f03.tar.gz
rust-832e5a02cd41b3a20d1142b47867da4aa5033f03.zip
Auto merge of #27453 - Manishearth:rollup, r=Manishearth
- Successful merges: #26982, #27305, #27419, #27423, #27426
- Failed merges: 
-rw-r--r--src/doc/tarpl/borrow-splitting.md22
-rw-r--r--src/doc/tarpl/send-and-sync.md12
-rw-r--r--src/librustc_typeck/diagnostics.rs106
-rw-r--r--src/libstd/lib.rs2
4 files changed, 114 insertions, 28 deletions
diff --git a/src/doc/tarpl/borrow-splitting.md b/src/doc/tarpl/borrow-splitting.md
index da484385788..cc5bc8a602d 100644
--- a/src/doc/tarpl/borrow-splitting.md
+++ b/src/doc/tarpl/borrow-splitting.md
@@ -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
 ```
 
diff --git a/src/doc/tarpl/send-and-sync.md b/src/doc/tarpl/send-and-sync.md
index af8fb43f2e9..334d5c9dd55 100644
--- a/src/doc/tarpl/send-and-sync.md
+++ b/src/doc/tarpl/send-and-sync.md
@@ -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
@@ -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
@@ -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.
 
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index d94870c68bd..77256d5b34e 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -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
@@ -1245,14 +1251,6 @@ 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 {
@@ -1260,6 +1258,22 @@ impl From<Foo> for i32 { // or you use a type from your crate as
     }
 }
 ```
+
+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##"
@@ -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:
@@ -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
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 61de7eafbb5..010e2cc7bb2 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -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