Skip to content

Commit

Permalink
Auto merge of #35332 - GuillaumeGomez:rollup, r=GuillaumeGomez
Browse files Browse the repository at this point in the history
Rollup of 30 pull requests

- Successful merges: #34319, #34894, #35041, #35042, #35076, #35109, #35137, #35175, #35181, #35182, #35189, #35239, #35264, #35266, #35281, #35285, #35289, #35291, #35294, #35296, #35297, #35298, #35299, #35318, #35319, #35324, #35326, #35328, #35331
- Failed merges:
  • Loading branch information
bors committed Aug 5, 2016
2 parents 41fe4b7 + 854532a commit 5101d6e
Show file tree
Hide file tree
Showing 55 changed files with 701 additions and 74 deletions.
2 changes: 1 addition & 1 deletion src/doc/book/guessing-game.md
Expand Up @@ -365,7 +365,7 @@ numbers. A bare number like above is actually shorthand for `^0.3.0`,
meaning "anything compatible with 0.3.0".
If we wanted to use only `0.3.0` exactly, we could say `rand="=0.3.0"`
(note the two equal signs).
And if we wanted to use the latest version we could use `*`.
And if we wanted to use the latest version we could use `rand="*"`.
We could also use a range of versions.
[Cargo’s documentation][cargodoc] contains more details.

Expand Down
2 changes: 2 additions & 0 deletions src/doc/book/the-stack-and-the-heap.md
Expand Up @@ -26,6 +26,8 @@ The stack is very fast, and is where memory is allocated in Rust by default.
But the allocation is local to a function call, and is limited in size. The
heap, on the other hand, is slower, and is explicitly allocated by your
program. But it’s effectively unlimited in size, and is globally accessible.
Note this meaning of heap, which allocates arbitrary-sized blocks of memory in arbitrary
order, is quite different from the heap data structure.

# The Stack

Expand Down
3 changes: 2 additions & 1 deletion src/doc/reference.md
Expand Up @@ -3049,7 +3049,8 @@ as
== != < > <= >=
&&
||
= ..
.. ...
=
```

Operators at the same precedence level are evaluated left-to-right. [Unary
Expand Down
32 changes: 32 additions & 0 deletions src/libcollections/range.rs
Expand Up @@ -23,13 +23,45 @@ pub trait RangeArgument<T> {
/// Start index (inclusive)
///
/// Return start value if present, else `None`.
///
/// # Examples
///
/// ```
/// #![feature(collections)]
/// #![feature(collections_range)]
///
/// extern crate collections;
///
/// # fn main() {
/// use collections::range::RangeArgument;
///
/// assert_eq!((..10).start(), None);
/// assert_eq!((3..10).start(), Some(&3));
/// # }
/// ```
fn start(&self) -> Option<&T> {
None
}

/// End index (exclusive)
///
/// Return end value if present, else `None`.
///
/// # Examples
///
/// ```
/// #![feature(collections)]
/// #![feature(collections_range)]
///
/// extern crate collections;
///
/// # fn main() {
/// use collections::range::RangeArgument;
///
/// assert_eq!((3..).end(), None);
/// assert_eq!((3..10).end(), Some(&10));
/// # }
/// ```
fn end(&self) -> Option<&T> {
None
}
Expand Down
19 changes: 19 additions & 0 deletions src/libcollections/vec.rs
Expand Up @@ -476,6 +476,25 @@ impl<T> Vec<T> {
/// 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()`.
///
/// # Examples
///
/// ```
/// let v = vec![1, 2, 3];
///
/// let slice = v.into_boxed_slice();
/// ```
///
/// Any excess capacity is removed:
///
/// ```
/// let mut vec = Vec::with_capacity(10);
/// vec.extend([1, 2, 3].iter().cloned());
///
/// assert_eq!(vec.capacity(), 10);
/// let slice = vec.into_boxed_slice();
/// assert_eq!(slice.into_vec().capacity(), 3);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_boxed_slice(mut self) -> Box<[T]> {
unsafe {
Expand Down
6 changes: 6 additions & 0 deletions src/libcore/marker.rs
Expand Up @@ -144,6 +144,12 @@ pub trait Unsize<T: ?Sized> {
/// Generalizing the latter case, any type implementing `Drop` can't be `Copy`, because it's
/// managing some resource besides its own `size_of::<T>()` bytes.
///
/// ## What if I derive `Copy` on a type that can't?
///
/// If you try to derive `Copy` on a struct or enum, you will get a compile-time error.
/// Specifically, with structs you'll get [E0204](https://doc.rust-lang.org/error-index.html#E0204)
/// and with enums you'll get [E0205](https://doc.rust-lang.org/error-index.html#E0205).
///
/// ## When should my type be `Copy`?
///
/// Generally speaking, if your type _can_ implement `Copy`, it should. There's one important thing
Expand Down
16 changes: 8 additions & 8 deletions src/libcore/raw.rs
Expand Up @@ -34,12 +34,13 @@
/// only designed to be used by unsafe code that needs to manipulate
/// the low-level details.
///
/// There is no `Repr` implementation for `TraitObject` because there
/// is no way to refer to all trait objects generically, so the only
/// There is no way to refer to all trait objects generically, so the only
/// way to create values of this type is with functions like
/// `std::mem::transmute`. Similarly, the only way to create a true
/// [`std::mem::transmute`][transmute]. Similarly, the only way to create a true
/// trait object from a `TraitObject` value is with `transmute`.
///
/// [transmute]: ../mem/fn.transmute.html
///
/// Synthesizing a trait object with mismatched types—one where the
/// vtable does not correspond to the type of the value to which the
/// data pointer points—is highly likely to lead to undefined
Expand All @@ -50,13 +51,13 @@
/// ```
/// #![feature(raw)]
///
/// use std::mem;
/// use std::raw;
/// use std::{mem, raw};
///
/// // an example trait
/// trait Foo {
/// fn bar(&self) -> i32;
/// }
///
/// impl Foo for i32 {
/// fn bar(&self) -> i32 {
/// *self + 1
Expand All @@ -74,19 +75,18 @@
/// // the data pointer is the address of `value`
/// assert_eq!(raw_object.data as *const i32, &value as *const _);
///
///
/// let other_value: i32 = 456;
///
/// // construct a new object, pointing to a different `i32`, being
/// // careful to use the `i32` vtable from `object`
/// let synthesized: &Foo = unsafe {
/// mem::transmute(raw::TraitObject {
/// data: &other_value as *const _ as *mut (),
/// vtable: raw_object.vtable
/// vtable: raw_object.vtable,
/// })
/// };
///
/// // it should work just like we constructed a trait object out of
/// // it should work just as if we had constructed a trait object out of
/// // `other_value` directly
/// assert_eq!(synthesized.bar(), 457);
/// ```
Expand Down
34 changes: 33 additions & 1 deletion src/librustc/hir/mod.rs
Expand Up @@ -36,7 +36,7 @@ use hir::def::Def;
use hir::def_id::DefId;
use util::nodemap::{NodeMap, FnvHashSet};

use syntax_pos::{mk_sp, Span, ExpnId};
use syntax_pos::{BytePos, mk_sp, Span, ExpnId};
use syntax::codemap::{self, respan, Spanned};
use syntax::abi::Abi;
use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, AsmDialect};
Expand Down Expand Up @@ -326,6 +326,38 @@ impl Generics {
pub fn is_parameterized(&self) -> bool {
self.is_lt_parameterized() || self.is_type_parameterized()
}

// Does return a span which includes lifetimes and type parameters,
// not where clause.
pub fn span(&self) -> Option<Span> {
if !self.is_parameterized() {
None
} else {
let mut span: Option<Span> = None;
for lifetime in self.lifetimes.iter() {
if let Some(ref mut span) = span {
let life_span = lifetime.lifetime.span;
span.hi = if span.hi > life_span.hi { span.hi } else { life_span.hi };
span.lo = if span.lo < life_span.lo { span.lo } else { life_span.lo };
} else {
span = Some(lifetime.lifetime.span.clone());
}
}
for ty_param in self.ty_params.iter() {
if let Some(ref mut span) = span {
span.lo = if span.lo < ty_param.span.lo { span.lo } else { ty_param.span.lo };
span.hi = if span.hi > ty_param.span.hi { span.hi } else { ty_param.span.hi };
} else {
span = Some(ty_param.span.clone());
}
}
if let Some(ref mut span) = span {
span.lo = span.lo - BytePos(1);
span.hi = span.hi + BytePos(1);
}
span
}
}
}

/// A `where` clause in a definition
Expand Down
13 changes: 9 additions & 4 deletions src/librustc/middle/astconv_util.rs
Expand Up @@ -24,13 +24,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn prohibit_type_params(self, segments: &[ast::PathSegment]) {
for segment in segments {
for typ in segment.parameters.types() {
span_err!(self.sess, typ.span, E0109,
"type parameters are not allowed on this type");
struct_span_err!(self.sess, typ.span, E0109,
"type parameters are not allowed on this type")
.span_label(typ.span, &format!("type parameter not allowed"))
.emit();
break;
}
for lifetime in segment.parameters.lifetimes() {
span_err!(self.sess, lifetime.span, E0110,
"lifetime parameters are not allowed on this type");
struct_span_err!(self.sess, lifetime.span, E0110,
"lifetime parameters are not allowed on this type")
.span_label(lifetime.span,
&format!("lifetime parameter not allowed on this type"))
.emit();
break;
}
for binding in segment.parameters.bindings() {
Expand Down
7 changes: 5 additions & 2 deletions src/librustc/middle/entry.rs
Expand Up @@ -121,8 +121,11 @@ fn find_item(item: &Item, ctxt: &mut EntryContext, at_root: bool) {
if ctxt.attr_main_fn.is_none() {
ctxt.attr_main_fn = Some((item.id, item.span));
} else {
span_err!(ctxt.session, item.span, E0137,
"multiple functions with a #[main] attribute");
struct_span_err!(ctxt.session, item.span, E0137,
"multiple functions with a #[main] attribute")
.span_label(item.span, &format!("additional #[main] function"))
.span_label(ctxt.attr_main_fn.unwrap().1, &format!("first #[main] function"))
.emit();
}
},
EntryPointType::Start => {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_const_eval/check_match.rs
Expand Up @@ -335,6 +335,7 @@ fn check_arms(cx: &MatchCheckCtxt,
hir::MatchSource::Normal => {
let mut err = struct_span_err!(cx.tcx.sess, pat.span, E0001,
"unreachable pattern");
err.span_label(pat.span, &format!("this is an unreachable pattern"));
// if we had a catchall pattern, hint at that
for row in &seen.0 {
if pat_is_catchall(&cx.tcx.def_map.borrow(), row[0].0) {
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_passes/ast_validation.rs
Expand Up @@ -169,6 +169,8 @@ impl<'a> Visitor for AstValidator<'a> {
self.check_decl_no_pat(decl, |span, is_recent| {
let mut err = struct_span_err!(self.session, span, E0130,
"patterns aren't allowed in foreign function declarations");
err.span_label(span, &format!("pattern not allowed in foreign function"));

if is_recent {
err.span_note(span, "this is a recent error, see \
issue #35203 for more details");
Expand Down
7 changes: 5 additions & 2 deletions src/librustc_typeck/astconv.rs
Expand Up @@ -1075,8 +1075,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
Ok((trait_ref, projection_bounds))
}
_ => {
span_err!(self.tcx().sess, ty.span, E0172,
"expected a reference to a trait");
struct_span_err!(self.tcx().sess, ty.span, E0172,
"expected a reference to a trait")
.span_label(ty.span, &format!("expected a trait"))
.emit();
Err(ErrorReported)
}
}
Expand All @@ -1086,6 +1088,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
"expected a path on the left-hand side \
of `+`, not `{}`",
pprust::ty_to_string(ty));
err.span_label(ty.span, &format!("expected a path"));
let hi = bounds.iter().map(|x| match *x {
hir::TraitTyParamBound(ref tr, _) => tr.span.hi,
hir::RegionTyParamBound(ref r) => r.span.hi,
Expand Down
6 changes: 4 additions & 2 deletions src/librustc_typeck/check/autoderef.rs
Expand Up @@ -54,9 +54,11 @@ impl<'a, 'gcx, 'tcx> Iterator for Autoderef<'a, 'gcx, 'tcx> {

if self.steps.len() == tcx.sess.recursion_limit.get() {
// We've reached the recursion limit, error gracefully.
span_err!(tcx.sess, self.span, E0055,
struct_span_err!(tcx.sess, self.span, E0055,
"reached the recursion limit while auto-dereferencing {:?}",
self.cur_ty);
self.cur_ty)
.span_label(self.span, &format!("deref recursion limit reached"))
.emit();
return None;
}

Expand Down
35 changes: 29 additions & 6 deletions src/librustc_typeck/check/mod.rs
Expand Up @@ -2384,6 +2384,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
arg_count,
if arg_count == 1 {" was"} else {"s were"}),
error_code);

err.span_label(sp, &format!("expected {}{} parameter{}",
if variadic {"at least "} else {""},
expected_count,
if expected_count == 1 {""} else {"s"}));

let input_types = fn_inputs.iter().map(|i| format!("{:?}", i)).collect::<Vec<String>>();
if input_types.len() > 0 {
err.note(&format!("the following parameter type{} expected: {}",
Expand Down Expand Up @@ -3063,6 +3069,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
remaining_fields.insert(field.name, field);
}

let mut seen_fields = FnvHashMap();

let mut error_happened = false;

// Typecheck each field.
Expand All @@ -3071,13 +3079,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {

if let Some(v_field) = remaining_fields.remove(&field.name.node) {
expected_field_type = self.field_ty(field.span, v_field, substs);

seen_fields.insert(field.name.node, field.span);
} else {
error_happened = true;
expected_field_type = tcx.types.err;
if let Some(_) = variant.find_field_named(field.name.node) {
span_err!(self.tcx.sess, field.name.span, E0062,
"field `{}` specified more than once",
field.name.node);
let mut err = struct_span_err!(self.tcx.sess,
field.name.span,
E0062,
"field `{}` specified more than once",
field.name.node);

err.span_label(field.name.span, &format!("used more than once"));

if let Some(prev_span) = seen_fields.get(&field.name.node) {
err.span_label(*prev_span, &format!("first use of `{}`", field.name.node));
}

err.emit();
} else {
self.report_unknown_field(adt_ty, variant, field, ast_fields);
}
Expand Down Expand Up @@ -3147,9 +3167,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
};
if variant.is_none() || variant.unwrap().kind == ty::VariantKind::Tuple {
// Reject tuple structs for now, braced and unit structs are allowed.
span_err!(self.tcx.sess, span, E0071,
"`{}` does not name a struct or a struct variant",
pprust::path_to_string(path));
struct_span_err!(self.tcx.sess, path.span, E0071,
"`{}` does not name a struct or a struct variant",
pprust::path_to_string(path))
.span_label(path.span, &format!("not a struct"))
.emit();

return None;
}

Expand Down

0 comments on commit 5101d6e

Please sign in to comment.