Auto merge of #37419 - GuillaumeGomez:rollup, r=GuillaumeGomez
Rollup of 7 pull requests - Successful merges: #36206, #37144, #37391, #37394, #37396, #37398, #37414 - Failed merges:
This commit is contained in:
commit
c59cb71d97
@ -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:
|
||||
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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`
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() { }
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user