about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-10-26 14:58:16 -0700
committerGitHub <noreply@github.com>2016-10-26 14:58:16 -0700
commitc59cb71d976ceabf00c7da0224a795fab530601e (patch)
tree7b07c6b19df2843426f2ee453317a2a4d9fd44b3
parent3a25b65c1fbdd6101b77e8a8b06a5e42d775dc3f (diff)
parent48b022838b28d046e127d24caa6a9dee5460fa08 (diff)
downloadrust-c59cb71d976ceabf00c7da0224a795fab530601e.tar.gz
rust-c59cb71d976ceabf00c7da0224a795fab530601e.zip
Auto merge of #37419 - GuillaumeGomez:rollup, r=GuillaumeGomez
Rollup of 7 pull requests

- Successful merges: #36206, #37144, #37391, #37394, #37396, #37398, #37414
- Failed merges:
-rw-r--r--src/doc/book/references-and-borrowing.md2
-rw-r--r--src/libcollections/vec.rs44
-rw-r--r--src/librustc_resolve/check_unused.rs10
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs4
-rw-r--r--src/librustc_typeck/astconv.rs28
-rw-r--r--src/librustc_typeck/check_unused.rs11
-rw-r--r--src/libsyntax/feature_gate.rs2
-rw-r--r--src/test/compile-fail/E0221.rs18
-rw-r--r--src/test/compile-fail/associated-type-projection-from-multiple-supertraits.rs14
-rw-r--r--src/test/compile-fail/lint-unused-imports.rs16
10 files changed, 90 insertions, 59 deletions
diff --git a/src/doc/book/references-and-borrowing.md b/src/doc/book/references-and-borrowing.md
index d845ad6feb0..1e2f061b067 100644
--- a/src/doc/book/references-and-borrowing.md
+++ b/src/doc/book/references-and-borrowing.md
@@ -240,7 +240,7 @@ fn main() {
 
 In other words, the mutable borrow is held through the rest of our example. What
 we want is for the mutable borrow by `y` to end so that the resource can be
-returned to the owner, `x`. `x` can then provide a immutable borrow to `println!`.
+returned to the owner, `x`. `x` can then provide an immutable borrow to `println!`.
 In Rust, borrowing is tied to the scope that the borrow is valid for. And our
 scopes look like this:
 
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index df76140f687..7fdf7e903d5 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -166,7 +166,7 @@ use super::range::RangeArgument;
 /// # Slicing
 ///
 /// A `Vec` can be mutable. Slices, on the other hand, are read-only objects.
-/// To get a slice, use "&". Example:
+/// To get a slice, use `&`. Example:
 ///
 /// ```
 /// fn read_slice(slice: &[usize]) {
@@ -203,33 +203,33 @@ use super::range::RangeArgument;
 ///
 /// # Guarantees
 ///
-/// Due to its incredibly fundamental nature, Vec makes a lot of guarantees
+/// Due to its incredibly fundamental nature, `Vec` makes a lot of guarantees
 /// about its design. This ensures that it's as low-overhead as possible in
 /// the general case, and can be correctly manipulated in primitive ways
 /// by unsafe code. Note that these guarantees refer to an unqualified `Vec<T>`.
 /// If additional type parameters are added (e.g. to support custom allocators),
 /// overriding their defaults may change the behavior.
 ///
-/// Most fundamentally, Vec is and always will be a (pointer, capacity, length)
+/// Most fundamentally, `Vec` is and always will be a (pointer, capacity, length)
 /// triplet. No more, no less. The order of these fields is completely
 /// unspecified, and you should use the appropriate methods to modify these.
 /// The pointer will never be null, so this type is null-pointer-optimized.
 ///
 /// However, the pointer may not actually point to allocated memory. In particular,
-/// if you construct a Vec with capacity 0 via [`Vec::new()`], [`vec![]`][`vec!`],
+/// if you construct a `Vec` with capacity 0 via [`Vec::new()`], [`vec![]`][`vec!`],
 /// [`Vec::with_capacity(0)`][`Vec::with_capacity`], or by calling [`shrink_to_fit()`]
 /// on an empty Vec, it will not allocate memory. Similarly, if you store zero-sized
 /// types inside a `Vec`, it will not allocate space for them. *Note that in this case
-/// the `Vec` may not report a [`capacity()`] of 0*. Vec will allocate if and only
+/// the `Vec` may not report a [`capacity()`] of 0*. `Vec` will allocate if and only
 /// if [`mem::size_of::<T>()`]` * capacity() > 0`. In general, `Vec`'s allocation
 /// details are subtle enough that it is strongly recommended that you only
-/// free memory allocated by a Vec by creating a new Vec and dropping it.
+/// free memory allocated by a `Vec` by creating a new `Vec` and dropping it.
 ///
 /// If a `Vec` *has* allocated memory, then the memory it points to is on the heap
 /// (as defined by the allocator Rust is configured to use by default), and its
 /// pointer points to [`len()`] initialized elements in order (what you would see
-/// if you coerced it to a slice), followed by `[capacity()][`capacity()`] -
-/// [len()][`len()`]` logically uninitialized elements.
+/// if you coerced it to a slice), followed by [`capacity()`]` - `[`len()`]
+/// logically uninitialized elements.
 ///
 /// `Vec` will never perform a "small optimization" where elements are actually
 /// stored on the stack for two reasons:
@@ -249,8 +249,8 @@ use super::range::RangeArgument;
 /// [`shrink_to_fit`][`shrink_to_fit()`].
 ///
 /// [`push`] and [`insert`] will never (re)allocate if the reported capacity is
-/// sufficient. [`push`] and [`insert`] *will* (re)allocate if `[len()][`len()`]
-/// == [capacity()][`capacity()`]`. That is, the reported capacity is completely
+/// sufficient. [`push`] and [`insert`] *will* (re)allocate if
+/// [`len()`]` == `[`capacity()`]. That is, the reported capacity is completely
 /// accurate, and can be relied on. It can even be used to manually free the memory
 /// allocated by a `Vec` if desired. Bulk insertion methods *may* reallocate, even
 /// when not necessary.
@@ -261,11 +261,10 @@ use super::range::RangeArgument;
 /// strategy is used will of course guarantee `O(1)` amortized [`push`].
 ///
 /// `vec![x; n]`, `vec![a, b, c, d]`, and
-/// [`Vec::with_capacity(n)`][`Vec::with_capacity`], will all
-/// produce a `Vec` with exactly the requested capacity. If `[len()][`len()`] ==
-/// [capacity()][`capacity()`]`, (as is the case for the [`vec!`] macro), then a
-/// `Vec<T>` can be converted to and from a [`Box<[T]>`] without reallocating or
-/// moving the elements.
+/// [`Vec::with_capacity(n)`][`Vec::with_capacity`], will all produce a `Vec`
+/// with exactly the requested capacity. If [`len()`]` == `[`capacity()`],
+/// (as is the case for the [`vec!`] macro), then a `Vec<T>` can be converted to
+/// and from a [`Box<[T]>`][owned slice] without reallocating or moving the elements.
 ///
 /// `Vec` will not specifically overwrite any data that is removed from it,
 /// but also won't specifically preserve it. Its uninitialized memory is
@@ -292,7 +291,7 @@ use super::range::RangeArgument;
 /// [`push`]: ../../std/vec/struct.Vec.html#method.push
 /// [`insert`]: ../../std/vec/struct.Vec.html#method.insert
 /// [`reserve`]: ../../std/vec/struct.Vec.html#method.reserve
-/// [`Box<[T]>`]: ../../std/boxed/struct.Box.html
+/// [owned slice]: ../../std/boxed/struct.Box.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Vec<T> {
     buf: RawVec<T>,
@@ -329,9 +328,10 @@ impl<T> Vec<T> {
     /// reallocating. If `capacity` is 0, the vector will not allocate.
     ///
     /// It is important to note that this function does not specify the *length*
-    /// of the returned vector, but only the *capacity*. (For an explanation of
-    /// the difference between length and capacity, see the main `Vec<T>` docs
-    /// above, 'Capacity and reallocation'.)
+    /// of the returned vector, but only the *capacity*. For an explanation of
+    /// the difference between length and capacity, see *[Capacity and reallocation]*.
+    ///
+    /// [Capacity and reallocation]: #capacity-and-reallocation
     ///
     /// # Examples
     ///
@@ -497,13 +497,13 @@ impl<T> Vec<T> {
         self.buf.shrink_to_fit(self.len);
     }
 
-    /// Converts the vector into [`Box<[T]>`].
+    /// Converts the vector into [`Box<[T]>`][owned slice].
     ///
     /// Note that this will drop any excess capacity. Calling this and
     /// converting back to a vector with [`into_vec()`] is equivalent to calling
     /// [`shrink_to_fit()`].
     ///
-    /// [`Box<[T]>`]: ../../std/boxed/struct.Box.html
+    /// [owned slice]: ../../std/boxed/struct.Box.html
     /// [`into_vec()`]: ../../std/primitive.slice.html#method.into_vec
     /// [`shrink_to_fit()`]: #method.shrink_to_fit
     ///
@@ -779,7 +779,7 @@ impl<T> Vec<T> {
 
     /// Retains only the elements specified by the predicate.
     ///
-    /// In other words, remove all elements `e` such that `f(&e)` returns false.
+    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
     /// This method operates in place and preserves the order of the retained
     /// elements.
     ///
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
index 93abe07128f..e1ea40809da 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/src/librustc_resolve/check_unused.rs
@@ -59,10 +59,12 @@ impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> {
                 // Check later.
                 return;
             }
-            self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
-                                  id,
-                                  span,
-                                  "unused import".to_string());
+            let msg = if let Ok(snippet) = self.session.codemap().span_to_snippet(span) {
+                format!("unused import: `{}`", snippet)
+            } else {
+                "unused import".to_string()
+            };
+            self.session.add_lint(lint::builtin::UNUSED_IMPORTS, id, span, msg);
         } else {
             // This trait import is definitely used, in a way other than
             // method resolution.
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 6d9cd88afb1..1c60ccb9765 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -854,9 +854,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
         let path_data = match path_data {
             Some(pd) => pd,
             None => {
-                span_bug!(path.span,
-                          "Unexpected def kind while looking up path in `{}`",
-                          self.span.snippet(path.span))
+                return;
             }
         };
 
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index aa3c9a711fa..c137fca58af 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1261,6 +1261,18 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
         }
 
         if bounds.len() > 1 {
+            let spans = bounds.iter().map(|b| {
+                self.tcx().impl_or_trait_items(b.def_id()).iter()
+                .find(|&&def_id| {
+                    match self.tcx().impl_or_trait_item(def_id) {
+                        ty::TypeTraitItem(ref item) => item.name.as_str() == assoc_name,
+                        _ => false
+                    }
+                })
+                .and_then(|&def_id| self.tcx().map.as_local_node_id(def_id))
+                .and_then(|node_id| self.tcx().map.opt_span(node_id))
+            });
+
             let mut err = struct_span_err!(
                 self.tcx().sess, span, E0221,
                 "ambiguous associated type `{}` in bounds of `{}`",
@@ -1268,11 +1280,17 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                 ty_param_name);
             err.span_label(span, &format!("ambiguous associated type `{}`", assoc_name));
 
-            for bound in &bounds {
-                span_note!(&mut err, span,
-                           "associated type `{}` could derive from `{}`",
-                           ty_param_name,
-                           bound);
+            for span_and_bound in spans.zip(&bounds) {
+                if let Some(span) = span_and_bound.0 {
+                    err.span_label(span, &format!("ambiguous `{}` from `{}`",
+                                                  assoc_name,
+                                                  span_and_bound.1));
+                } else {
+                    span_note!(&mut err, span,
+                               "associated type `{}` could derive from `{}`",
+                               ty_param_name,
+                               span_and_bound.1);
+                }
             }
             err.emit();
         }
diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs
index f66f15b238e..7e41a672bf3 100644
--- a/src/librustc_typeck/check_unused.rs
+++ b/src/librustc_typeck/check_unused.rs
@@ -30,10 +30,13 @@ impl<'a, 'tcx> UnusedTraitImportVisitor<'a, 'tcx> {
         if self.tcx.used_trait_imports.borrow().contains(&id) {
             return;
         }
-        self.tcx.sess.add_lint(lint::builtin::UNUSED_IMPORTS,
-                               id,
-                               span,
-                               "unused import".to_string());
+
+        let msg = if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(span) {
+            format!("unused import: `{}`", snippet)
+        } else {
+            "unused import".to_string()
+        };
+        self.tcx.sess.add_lint(lint::builtin::UNUSED_IMPORTS, id, span, msg);
     }
 }
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 954fe330b54..7143a26d133 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -1317,7 +1317,7 @@ pub enum UnstableFeatures {
     /// Hard errors for unstable features are active, as on
     /// beta/stable channels.
     Disallow,
-    /// Allow features to me activated, as on nightly.
+    /// Allow features to be activated, as on nightly.
     Allow,
     /// Errors are bypassed for bootstrapping. This is required any time
     /// during the build that feature-related lints are set to warn or above
diff --git a/src/test/compile-fail/E0221.rs b/src/test/compile-fail/E0221.rs
index 65105458040..aed2b4084e8 100644
--- a/src/test/compile-fail/E0221.rs
+++ b/src/test/compile-fail/E0221.rs
@@ -12,17 +12,27 @@ trait T1 {}
 trait T2 {}
 
 trait Foo {
-    type A: T1;
+    type A: T1; //~ NOTE: ambiguous `A` from `Foo`
 }
 
 trait Bar : Foo {
-    type A: T2;
+    type A: T2; //~ NOTE: ambiguous `A` from `Bar`
     fn do_something() {
         let _: Self::A;
         //~^ ERROR E0221
         //~| NOTE ambiguous associated type `A`
-        //~| NOTE associated type `Self` could derive from `Foo`
-        //~| NOTE associated type `Self` could derive from `Bar`
+    }
+}
+
+trait T3 {}
+
+trait My : std::str::FromStr {
+    type Err: T3; //~ NOTE: ambiguous `Err` from `My`
+    fn test() {
+        let _: Self::Err;
+        //~^ ERROR E0221
+        //~| NOTE ambiguous associated type `Err`
+        //~| NOTE associated type `Self` could derive from `std::str::FromStr`
     }
 }
 
diff --git a/src/test/compile-fail/associated-type-projection-from-multiple-supertraits.rs b/src/test/compile-fail/associated-type-projection-from-multiple-supertraits.rs
index a2a11c62bb8..b33bbfd8425 100644
--- a/src/test/compile-fail/associated-type-projection-from-multiple-supertraits.rs
+++ b/src/test/compile-fail/associated-type-projection-from-multiple-supertraits.rs
@@ -13,13 +13,19 @@
 
 pub trait Vehicle {
     type Color;
+    //~^ NOTE ambiguous `Color` from `Vehicle`
+    //~| NOTE ambiguous `Color` from `Vehicle`
+    //~| NOTE ambiguous `Color` from `Vehicle`
 
     fn go(&self) {  }
 }
 
 pub trait Box {
     type Color;
-
+    //~^ NOTE ambiguous `Color` from `Box`
+    //~| NOTE ambiguous `Color` from `Box`
+    //~| NOTE ambiguous `Color` from `Box`
+    //
     fn mail(&self) {  }
 }
 
@@ -29,24 +35,18 @@ pub trait BoxCar : Box + Vehicle {
 fn dent<C:BoxCar>(c: C, color: C::Color) {
     //~^ ERROR ambiguous associated type `Color` in bounds of `C`
     //~| NOTE ambiguous associated type `Color`
-    //~| NOTE could derive from `Vehicle`
-    //~| NOTE could derive from `Box`
 }
 
 fn dent_object<COLOR>(c: BoxCar<Color=COLOR>) {
     //~^ ERROR ambiguous associated type
     //~| ERROR the value of the associated type `Color` (from the trait `Vehicle`) must be specified
     //~| NOTE ambiguous associated type `Color`
-    //~| NOTE could derive from `Vehicle`
-    //~| NOTE could derive from `Box`
     //~| NOTE missing associated type `Color` value
 }
 
 fn paint<C:BoxCar>(c: C, d: C::Color) {
     //~^ ERROR ambiguous associated type `Color` in bounds of `C`
     //~| NOTE ambiguous associated type `Color`
-    //~| NOTE could derive from `Vehicle`
-    //~| NOTE could derive from `Box`
 }
 
 pub fn main() { }
diff --git a/src/test/compile-fail/lint-unused-imports.rs b/src/test/compile-fail/lint-unused-imports.rs
index 239f380e6c4..3f91c3e1e5c 100644
--- a/src/test/compile-fail/lint-unused-imports.rs
+++ b/src/test/compile-fail/lint-unused-imports.rs
@@ -17,19 +17,19 @@ use std::mem::*;            // shouldn't get errors for not using
                             // everything imported
 
 // Should get errors for both 'Some' and 'None'
-use std::option::Option::{Some, None}; //~ ERROR unused import
-                                     //~^ ERROR unused import
+use std::option::Option::{Some, None}; //~ ERROR unused import: `Some`
+                                    //~^ ERROR unused import: `None`
 
-use test::A;       //~ ERROR unused import
+use test::A;       //~ ERROR unused import: `test::A`
 // Be sure that if we just bring some methods into scope that they're also
 // counted as being used.
 use test::B;
 // But only when actually used: do not get confused by the method with the same name.
-use test::B2; //~ ERROR unused import
+use test::B2; //~ ERROR unused import: `test::B2`
 
 // Make sure this import is warned about when at least one of its imported names
 // is unused
-use test2::{foo, bar}; //~ ERROR unused import
+use test2::{foo, bar}; //~ ERROR unused import: `bar`
 
 mod test2 {
     pub fn foo() {}
@@ -57,7 +57,7 @@ mod bar {
 
     pub mod c {
         use foo::Point;
-        use foo::Square; //~ ERROR unused import
+        use foo::Square; //~ ERROR unused import: `foo::Square`
         pub fn cc(_p: Point) -> super::Square {
             fn f() -> super::Square {
                 super::Square
@@ -73,7 +73,7 @@ mod bar {
 }
 
 fn g() {
-    use self::g; //~ ERROR unused import
+    use self::g; //~ ERROR unused import: `self::g`
     fn f() {
         self::g();
     }
@@ -82,7 +82,7 @@ fn g() {
 // c.f. issue #35135
 #[allow(unused_variables)]
 fn h() {
-    use test2::foo; //~ ERROR unused import
+    use test2::foo; //~ ERROR unused import: `test2::foo`
     let foo = 0;
 }