From 88b031e6efa417bb8cc0eecb18db13bfa93be19b Mon Sep 17 00:00:00 2001 From: Andrea Pretto Date: Thu, 13 Oct 2016 17:40:58 +0200 Subject: [PATCH 1/6] save-analysis: dump data only if get_path_data doesn't fail to resolve a path. Fixes #37126. --- src/librustc_save_analysis/dump_visitor.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 6d9cd88afb17b..1c60ccb976588 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; } }; From 585f835b8e53d48c5ee41275d728e931f4c62a00 Mon Sep 17 00:00:00 2001 From: Mikhail Modin Date: Sun, 23 Oct 2016 21:53:31 +0300 Subject: [PATCH 2/6] Make error E0221 more helpful --- src/librustc_typeck/astconv.rs | 28 +++++++++++++++---- src/test/compile-fail/E0221.rs | 18 +++++++++--- ...pe-projection-from-multiple-supertraits.rs | 14 +++++----- 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 4fbb31cf0a534..dcb94bfa4aaac 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/test/compile-fail/E0221.rs b/src/test/compile-fail/E0221.rs index 651054580408d..aed2b4084e810 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 a2a11c62bb832..b33bbfd84258f 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: 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(c: BoxCar) { //~^ 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: 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() { } From 22ce98d0e7aa573c5418bdf62d46c0444c60e2ab Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Tue, 25 Oct 2016 10:03:55 -0400 Subject: [PATCH 3/6] Fix typo --- src/doc/book/references-and-borrowing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/book/references-and-borrowing.md b/src/doc/book/references-and-borrowing.md index d845ad6feb001..1e2f061b06745 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: From 2bd94188f79b3aed99f148d05ce300621ad41209 Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Mon, 24 Oct 2016 22:57:33 -0700 Subject: [PATCH 4/6] Add identifier to unused import warnings --- src/librustc_resolve/check_unused.rs | 10 ++++++---- src/librustc_typeck/check_unused.rs | 11 +++++++---- src/test/compile-fail/lint-unused-imports.rs | 16 ++++++++-------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 93abe07128fa1..e1ea40809da07 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_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index f66f15b238e73..7e41a672bf325 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/test/compile-fail/lint-unused-imports.rs b/src/test/compile-fail/lint-unused-imports.rs index 239f380e6c4ab..3f91c3e1e5c79 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; } From 09227b17f4daf86afb269669671f197b4d481717 Mon Sep 17 00:00:00 2001 From: Duncan Date: Tue, 25 Oct 2016 14:22:54 +1300 Subject: [PATCH 5/6] Vec docs: fix broken links and make quoting consistent --- src/libcollections/vec.rs | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index df76140f687a7..7fdf7e903d5ca 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`. /// 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::()`]` * 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` 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` 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 { buf: RawVec, @@ -329,9 +328,10 @@ impl Vec { /// 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` 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 Vec { 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 Vec { /// 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. /// From d68fb5f20a3371c4057cc7ac940a9079f8c25416 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Wed, 26 Oct 2016 11:14:46 +0800 Subject: [PATCH 6/6] Fix typo, it bothered me --- src/libsyntax/feature_gate.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 954fe330b54ca..7143a26d1339e 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