Auto merge of #35525 - jonathandturner:rollup, r=jonathandturner

Rollup of 15 pull requests

- Successful merges: #35371, #35396, #35446, #35449, #35452, #35458, #35465, #35466, #35470, #35475, #35477, #35484, #35504, #35507, #35524
- Failed merges: #35395, #35415
This commit is contained in:
bors 2016-08-10 10:03:08 -07:00 committed by GitHub
commit 1f2ae3849c
20 changed files with 133 additions and 56 deletions

View File

@ -22,6 +22,7 @@ As an example, lets make a *phrases* crate, which will give us various phrase
in different languages. To keep things simple, well stick to greetings and
farewells as two kinds of phrases, and use English and Japanese (日本語) as
two languages for those phrases to be in. Well use this module layout:
```text
+-----------+
+---| greetings |

View File

@ -109,14 +109,14 @@ struct Point {
y: i32,
}
let origin = Point { x: 0, y: 0 };
let point = Point { x: 2, y: 3 };
match origin {
match point {
Point { x, .. } => println!("x is {}", x),
}
```
This prints `x is 0`.
This prints `x is 2`.
You can do this kind of match on any member, not only the first:
@ -126,14 +126,14 @@ struct Point {
y: i32,
}
let origin = Point { x: 0, y: 0 };
let point = Point { x: 2, y: 3 };
match origin {
match point {
Point { y, .. } => println!("y is {}", y),
}
```
This prints `y is 0`.
This prints `y is 3`.
This destructuring behavior works on any compound data type, like
[tuples][tuples] or [enums][enums].

View File

@ -3039,7 +3039,7 @@ The precedence of Rust binary operators is ordered as follows, going from
strong to weak:
```{.text .precedence}
as
as :
* / %
+ -
<< >>
@ -3050,6 +3050,7 @@ as
&&
||
.. ...
<-
=
```

View File

@ -316,7 +316,10 @@ fn check_arms(cx: &MatchCheckCtxt,
let &(ref first_arm_pats, _) = &arms[0];
let first_pat = &first_arm_pats[0];
let span = first_pat.span;
span_err!(cx.tcx.sess, span, E0162, "irrefutable if-let pattern");
struct_span_err!(cx.tcx.sess, span, E0162,
"irrefutable if-let pattern")
.span_label(span, &format!("irrefutable pattern"))
.emit();
printed_if_let_err = true;
}
},

View File

@ -360,8 +360,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
self.convert_angle_bracketed_parameters(rscope, span, decl_generics, data)
}
hir::ParenthesizedParameters(..) => {
span_err!(tcx.sess, span, E0214,
"parenthesized parameters may only be used with a trait");
struct_span_err!(tcx.sess, span, E0214,
"parenthesized parameters may only be used with a trait")
.span_label(span, &format!("only traits may use parentheses"))
.emit();
let ty_param_defs = decl_generics.types.get_slice(TypeSpace);
(Substs::empty(),
ty_param_defs.iter().map(|_| tcx.types.err).collect(),
@ -1201,10 +1204,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
}
for (trait_def_id, name) in associated_types {
span_err!(tcx.sess, span, E0191,
struct_span_err!(tcx.sess, span, E0191,
"the value of the associated type `{}` (from the trait `{}`) must be specified",
name,
tcx.item_path_str(trait_def_id));
tcx.item_path_str(trait_def_id))
.span_label(span, &format!(
"missing associated type `{}` value", name))
.emit();
}
tcx.mk_trait(object.principal, object.bounds)
@ -1281,10 +1287,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
}
if bounds.len() > 1 {
let mut err = struct_span_err!(self.tcx().sess, span, E0221,
"ambiguous associated type `{}` in bounds of `{}`",
assoc_name,
ty_param_name);
let mut err = struct_span_err!(
self.tcx().sess, span, E0221,
"ambiguous associated type `{}` in bounds of `{}`",
assoc_name,
ty_param_name);
err.span_label(span, &format!("ambiguous associated type `{}`", assoc_name));
for bound in &bounds {
span_note!(&mut err, span,
@ -1584,9 +1592,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
return self.tcx().types.err;
}
_ => {
span_err!(tcx.sess, span, E0248,
"found value `{}` used as a type",
tcx.item_path_str(def.def_id()));
struct_span_err!(tcx.sess, span, E0248,
"found value `{}` used as a type",
tcx.item_path_str(def.def_id()))
.span_label(span, &format!("value used as a type"))
.emit();
return self.tcx().types.err;
}
}

View File

@ -633,10 +633,23 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.check_pat(&subpat, field_ty);
}
} else {
span_err!(tcx.sess, pat.span, E0023,
"this pattern has {} field{s}, but the corresponding {} has {} field{s}",
subpats.len(), def.kind_name(), variant.fields.len(),
s = if variant.fields.len() == 1 {""} else {"s"});
let subpats_ending = if subpats.len() == 1 {
""
} else {
"s"
};
let fields_ending = if variant.fields.len() == 1 {
""
} else {
"s"
};
struct_span_err!(tcx.sess, pat.span, E0023,
"this pattern has {} field{}, but the corresponding {} has {} field{}",
subpats.len(), subpats_ending, def.kind_name(),
variant.fields.len(), fields_ending)
.span_label(pat.span, &format!("expected {} field{}, found {}",
variant.fields.len(), fields_ending, subpats.len()))
.emit();
on_error();
}
}
@ -682,10 +695,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
field_map.get(&field.name)
.map(|f| self.field_ty(span, f, substs))
.unwrap_or_else(|| {
span_err!(tcx.sess, span, E0026,
"struct `{}` does not have a field named `{}`",
tcx.item_path_str(variant.did),
field.name);
struct_span_err!(tcx.sess, span, E0026,
"struct `{}` does not have a field named `{}`",
tcx.item_path_str(variant.did),
field.name)
.span_label(span,
&format!("struct `{}` does not have field `{}`",
tcx.item_path_str(variant.did),
field.name))
.emit();
tcx.types.err
})
}

View File

@ -4372,14 +4372,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
if i < type_count {
substs.types.push(space, t);
} else if i == type_count {
span_err!(self.tcx.sess, typ.span, E0087,
"too many type parameters provided: \
expected at most {} parameter{}, \
found {} parameter{}",
type_count,
if type_count == 1 {""} else {"s"},
data.types.len(),
if data.types.len() == 1 {""} else {"s"});
struct_span_err!(self.tcx.sess, typ.span, E0087,
"too many type parameters provided: \
expected at most {} parameter{}, \
found {} parameter{}",
type_count,
if type_count == 1 {""} else {"s"},
data.types.len(),
if data.types.len() == 1 {""} else {"s"})
.span_label(typ.span , &format!("expected {} parameter{}",
type_count,
if type_count == 1 {""} else {"s"})).emit();
substs.types.truncate(space, 0);
break;
}

View File

@ -321,13 +321,18 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
}
Err(CopyImplementationError::InfrigingVariant(name)) => {
struct_span_err!(tcx.sess, span, E0205,
"the trait `Copy` may not be \
implemented for this type")
.span_label(span, &format!("variant \
`{}` does not implement `Copy`",
name))
.emit()
let item = tcx.map.expect_item(impl_node_id);
let span = if let ItemImpl(_, _, _, Some(ref tr), _, _) = item.node {
tr.path.span
} else {
span
};
struct_span_err!(tcx.sess, span, E0205,
"the trait `Copy` may not be implemented for this type")
.span_label(span, &format!("variant `{}` does not implement `Copy`",
name))
.emit()
}
Err(CopyImplementationError::NotAnAdt) => {
let item = tcx.map.expect_item(impl_node_id);

View File

@ -262,9 +262,10 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
match it.node {
hir::ItemFn(_,_,_,_,ref ps,_)
if ps.is_parameterized() => {
struct_span_err!(tcx.sess, start_span, E0132,
let sp = if let Some(sp) = ps.span() { sp } else { start_span };
struct_span_err!(tcx.sess, sp, E0132,
"start function is not allowed to have type parameters")
.span_label(ps.span().unwrap(),
.span_label(sp,
&format!("start function cannot have type parameters"))
.emit();
return;

View File

@ -199,13 +199,12 @@ fn test_resize_policy() {
/// A hash map implementation which uses linear probing with Robin
/// Hood bucket stealing.
///
/// The hashes are all keyed by the thread-local random number generator
/// on creation by default. This means that the ordering of the keys is
/// randomized, but makes the tables more resistant to
/// denial-of-service attacks (Hash DoS). No guarantees are made to the
/// quality of the random data. The implementation uses the best available
/// random data from your platform at the time of creation. This behavior
/// can be overridden with one of the constructors.
/// By default, HashMap uses a somewhat slow hashing algorithm which can provide resistance
/// to DoS attacks. Rust makes a best attempt at acquiring random numbers without IO
/// blocking from your system. Because of this HashMap is not guaranteed to provide
/// DoS resistance since the numbers generated might not be truly random. If you do
/// require this behavior you can create your own hashing function using
/// [BuildHasherDefault](../hash/struct.BuildHasherDefault.html).
///
/// It is required that the keys implement the `Eq` and `Hash` traits, although
/// this can frequently be achieved by using `#[derive(PartialEq, Eq, Hash)]`.

View File

@ -13,10 +13,15 @@ enum Fruit {
Pear(u32),
}
fn main() {
let x = Fruit::Apple(String::new(), String::new());
match x {
Fruit::Apple(a) => {}, //~ ERROR E0023
//~| NOTE expected 2 fields, found 1
Fruit::Apple(a, b, c) => {}, //~ ERROR E0023
//~| NOTE expected 2 fields, found 3
Fruit::Pear(1, 2) => {}, //~ ERROR E0023
//~| NOTE expected 1 field, found 2
}
}

View File

@ -16,6 +16,8 @@ struct Thing {
fn main() {
let thing = Thing { x: 0, y: 0 };
match thing {
Thing { x, y, z } => {} //~ ERROR E0026
Thing { x, y, z } => {}
//~^ ERROR struct `Thing` does not have a field named `z` [E0026]
//~| NOTE struct `Thing` does not have field `z`
}
}

View File

@ -12,4 +12,5 @@ fn foo<T>() {}
fn main() {
foo::<f64, bool>(); //~ ERROR E0087
//~^ NOTE expected
}

View File

@ -13,6 +13,7 @@ struct Irrefutable(i32);
fn main() {
let irr = Irrefutable(0);
if let Irrefutable(x) = irr { //~ ERROR E0162
//~| NOTE irrefutable pattern
println!("{}", x);
}
}

View File

@ -13,6 +13,7 @@ trait Trait {
}
type Foo = Trait; //~ ERROR E0191
//~| NOTE missing associated type `Bar` value
fn main() {
}

View File

@ -14,11 +14,11 @@ enum Foo {
}
impl Copy for Foo { }
//~^ ERROR E0205
//~^ ERROR the trait `Copy` may not be implemented for this type
//~| NOTE variant `Bar` does not implement `Copy`
#[derive(Copy)]
//~^ ERROR E0205
//~^ ERROR the trait `Copy` may not be implemented for this type
//~| NOTE variant `Bar` does not implement `Copy`
//~| NOTE in this expansion of #[derive(Copy)]
enum Foo2<'a> {

View File

@ -9,5 +9,7 @@
// except according to those terms.
fn main() {
let v: Vec(&str) = vec!["foo"]; //~ ERROR E0214
let v: Vec(&str) = vec!["foo"];
//~^ ERROR E0214
//~| NOTE only traits may use parentheses
}

View File

@ -13,6 +13,6 @@ enum Foo {
}
fn do_something(x: Foo::Bar) { } //~ ERROR E0248
//~| NOTE value used as a type
fn main() {
}

View File

@ -28,6 +28,7 @@ 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`
}
@ -35,12 +36,15 @@ fn dent<C:BoxCar>(c: C, color: C::Color) {
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`
}

View File

@ -0,0 +1,19 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub fn main() {
let x = (0, 2);
match x {
(0, ref y) => {}
(y, 0) => {}
_ => (),
}
}