diff --git a/.gitignore b/.gitignore index 5e8c40d03fbef..6de43f471d886 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ __pycache__/ .project .settings/ .valgrindrc +.vscode/ /*-*-*-*/ /*-*-*/ /Makefile diff --git a/src/doc/book/crates-and-modules.md b/src/doc/book/crates-and-modules.md index 67fe8ba2c11a4..fcb7e0bc7eacd 100644 --- a/src/doc/book/crates-and-modules.md +++ b/src/doc/book/crates-and-modules.md @@ -22,6 +22,7 @@ As an example, let’s make a *phrases* crate, which will give us various phrase in different languages. To keep things simple, we’ll stick to ‘greetings’ and ‘farewells’ as two kinds of phrases, and use English and Japanese (日本語) as two languages for those phrases to be in. We’ll use this module layout: + ```text +-----------+ +---| greetings | diff --git a/src/doc/book/patterns.md b/src/doc/book/patterns.md index a0245d4c7b163..910b13754767f 100644 --- a/src/doc/book/patterns.md +++ b/src/doc/book/patterns.md @@ -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]. diff --git a/src/doc/reference.md b/src/doc/reference.md index f4ffe5774d27c..f0ab1488d4015 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -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 && || .. ... +<- = ``` diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 70b514afd035f..c06bde6222ac8 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -1180,7 +1180,7 @@ impl String { #[inline] #[unstable(feature = "insert_str", reason = "recent addition", - issue = "0")] + issue = "35553")] pub fn insert_str(&mut self, idx: usize, string: &str) { let len = self.len(); assert!(idx <= len); diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index b0c79a3a88547..c916ad930ff10 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -229,14 +229,28 @@ macro_rules! try { }) } -/// Use the `format!` syntax to write data into a buffer. +/// Write formatted data into a buffer /// -/// This macro is typically used with a buffer of `&mut `[`Write`][write]. +/// This macro accepts any value with `write_fmt` method as a writer, a format string, and a list +/// of arguments to format. +/// +/// `write_fmt` method usually comes from an implementation of [`std::fmt::Write`][fmt_write] or +/// [`std::io::Write`][io_write] traits. These are sometimes called 'writers'. +/// +/// Passed arguments will be formatted according to the specified format string and the resulting +/// string will be passed to the writer. /// /// See [`std::fmt`][fmt] for more information on format syntax. /// +/// Return value is completely dependent on the 'write_fmt' method. +/// +/// Common return values are: [`Result`][enum_result], [`io::Result`][type_result] +/// /// [fmt]: ../std/fmt/index.html -/// [write]: ../std/io/trait.Write.html +/// [fmt_write]: ../std/fmt/trait.Write.html +/// [io_write]: ../std/io/trait.Write.html +/// [enum_result]: ../std/result/enum.Result.html +/// [type_result]: ../std/io/type.Result.html /// /// # Examples /// @@ -255,16 +269,31 @@ macro_rules! write { ($dst:expr, $($arg:tt)*) => ($dst.write_fmt(format_args!($($arg)*))) } -/// Use the `format!` syntax to write data into a buffer, appending a newline. -/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) -/// alone (no additional CARRIAGE RETURN (`\r`/`U+000D`). +/// Write formatted data into a buffer, with appending a newline. +/// +/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone +/// (no additional CARRIAGE RETURN (`\r`/`U+000D`). /// -/// This macro is typically used with a buffer of `&mut `[`Write`][write]. +/// This macro accepts any value with `write_fmt` method as a writer, a format string, and a list +/// of arguments to format. +/// +/// `write_fmt` method usually comes from an implementation of [`std::fmt::Write`][fmt_write] or +/// [`std::io::Write`][io_write] traits. These are sometimes called 'writers'. +/// +/// Passed arguments will be formatted according to the specified format string and the resulting +/// string will be passed to the writer. /// /// See [`std::fmt`][fmt] for more information on format syntax. /// +/// Return value is completely dependent on the 'write_fmt' method. +/// +/// Common return values are: [`Result`][enum_result], [`io::Result`][type_result] +/// /// [fmt]: ../std/fmt/index.html -/// [write]: ../std/io/trait.Write.html +/// [fmt_write]: ../std/fmt/trait.Write.html +/// [io_write]: ../std/io/trait.Write.html +/// [enum_result]: ../std/result/enum.Result.html +/// [type_result]: ../std/io/type.Result.html /// /// # Examples /// diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 94c6c636ce8fc..c7ca70fc1622d 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -402,8 +402,8 @@ impl Result { /// ``` /// fn mutate(r: &mut Result) { /// match r.as_mut() { - /// Ok(&mut ref mut v) => *v = 42, - /// Err(&mut ref mut e) => *e = 0, + /// Ok(v) => *v = 42, + /// Err(e) => *e = 0, /// } /// } /// diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 7f6614a959c89..aa74fb2e02fa0 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -718,10 +718,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let lifetime_j = &lifetimes[j]; if lifetime_i.lifetime.name == lifetime_j.lifetime.name { - span_err!(self.sess, lifetime_j.lifetime.span, E0263, - "lifetime name `{}` declared twice in \ - the same scope", - lifetime_j.lifetime.name); + struct_span_err!(self.sess, lifetime_j.lifetime.span, E0263, + "lifetime name `{}` declared twice in the same scope", + lifetime_j.lifetime.name) + .span_label(lifetime_j.lifetime.span, + &format!("declared twice")) + .span_label(lifetime_i.lifetime.span, + &format!("previous declaration here")) + .emit(); } } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 9950560b13a5a..4725272d2b69a 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -670,10 +670,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let mut err = match warning_node_id { Some(_) => None, None => { - Some(struct_span_err!( - self.sess, span, E0038, - "the trait `{}` cannot be made into an object", - self.item_path_str(trait_def_id))) + let trait_str = self.item_path_str(trait_def_id); + let mut db = struct_span_err!( + self.sess, span, E0038, + "the trait `{}` cannot be made into an object", + trait_str); + db.span_label(span, + &format!("the trait `{}` cannot be made \ + into an object", trait_str)); + Some(db) } }; diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 904cffac6b3cd..e0cbd972bd37f 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -760,12 +760,16 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { lp: &LoanPath<'tcx>, assign: &move_data::Assignment) { - struct_span_err!( + let mut err = struct_span_err!( self.tcx.sess, span, E0384, "re-assignment of immutable variable `{}`", - self.loan_path_to_string(lp)) - .span_note(assign.span, "prior assignment occurs here") - .emit(); + self.loan_path_to_string(lp)); + err.span_label(span, &format!("re-assignment of immutable variable")); + if span != assign.span { + err.span_label(assign.span, &format!("first assignment to `{}`", + self.loan_path_to_string(lp))); + } + err.emit(); } pub fn span_err(&self, s: Span, m: &str) { diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 599e3ec871a83..5fe4830c365ef 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -235,12 +235,7 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &hir::Expr) { .flat_map(|arm| &arm.0) .map(|pat| vec![wrap_pat(cx, &pat)]) .collect(); - let match_span = Span { - lo: ex.span.lo, - hi: scrut.span.hi, - expn_id: ex.span.expn_id - }; - check_exhaustive(cx, match_span, &matrix, source); + check_exhaustive(cx, scrut.span, &matrix, source); }, _ => () } @@ -316,7 +311,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; } }, @@ -1112,9 +1110,15 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt, // x @ Foo(..) is legal, but x @ Foo(y) isn't. if sub.map_or(false, |p| pat_contains_bindings(&p)) { - span_err!(cx.tcx.sess, p.span, E0007, "cannot bind by-move with sub-bindings"); + struct_span_err!(cx.tcx.sess, p.span, E0007, + "cannot bind by-move with sub-bindings") + .span_label(p.span, &format!("binds an already bound by-move value by moving it")) + .emit(); } else if has_guard { - span_err!(cx.tcx.sess, p.span, E0008, "cannot bind by-move into a pattern guard"); + struct_span_err!(cx.tcx.sess, p.span, E0008, + "cannot bind by-move into a pattern guard") + .span_label(p.span, &format!("moves value into pattern guard")) + .emit(); } else if by_ref_span.is_some() { let mut err = struct_span_err!(cx.tcx.sess, p.span, E0009, "cannot bind by-move and by-ref in the same pattern"); diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index b16ee9577463b..132234c8c6b23 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -617,9 +617,12 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { if !allow { self.add(Qualif::NOT_CONST); if self.mode != Mode::Fn { - span_err!(self.tcx.sess, self.span, E0017, - "references in {}s may only refer \ - to immutable values", self.mode); + struct_span_err!(self.tcx.sess, self.span, E0017, + "references in {}s may only refer \ + to immutable values", self.mode) + .span_label(self.span, &format!("{}s require immutable values", + self.mode)) + .emit(); } } } else { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 860e569ba7e5e..a7a503f6f2f1e 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -412,7 +412,9 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, struct_span_err!(resolver.session, span, E0432, "{}", msg) } ResolutionError::FailedToResolve(msg) => { - struct_span_err!(resolver.session, span, E0433, "failed to resolve. {}", msg) + let mut err = struct_span_err!(resolver.session, span, E0433, "failed to resolve. {}", msg); + err.span_label(span, &msg); + err } ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => { struct_span_err!(resolver.session, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index b4e9fb5c65bb3..d6b781054ca11 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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, diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index fe68690d4e974..db161379920e3 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -347,9 +347,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let ty::TyTrait(..) = mt.ty.sty { // This is "x = SomeTrait" being reduced from // "let &x = &SomeTrait" or "let box x = Box", an error. - span_err!(self.tcx.sess, span, E0033, - "type `{}` cannot be dereferenced", - self.ty_to_string(expected)); + let type_str = self.ty_to_string(expected); + struct_span_err!(self.tcx.sess, span, E0033, + "type `{}` cannot be dereferenced", type_str) + .span_label(span, &format!("type `{}` cannot be dereferenced", type_str)) + .emit(); return false } } @@ -633,10 +635,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 +697,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 }) } diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 8a53c59b4c7fa..9051b1c8069bd 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -97,8 +97,10 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) { (0, Vec::new(), tcx.mk_nil()) } op => { - span_err!(tcx.sess, it.span, E0092, - "unrecognized atomic operation function: `{}`", op); + struct_span_err!(tcx.sess, it.span, E0092, + "unrecognized atomic operation function: `{}`", op) + .span_label(it.span, &format!("unrecognized atomic operation")) + .emit(); return; } }; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4bb36aa639c54..36fdba3706109 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1272,13 +1272,21 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, // Check for duplicate discriminant values if let Some(i) = disr_vals.iter().position(|&x| x == current_disr_val) { - let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0081, - "discriminant value `{}` already exists", disr_vals[i]); let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap(); - err.span_label(ccx.tcx.map.span(variant_i_node_id), - &format!("first use of `{}`", disr_vals[i])); - err.span_label(v.span , &format!("enum already has `{}`", disr_vals[i])); - err.emit(); + let variant_i = ccx.tcx.map.expect_variant(variant_i_node_id); + let i_span = match variant_i.node.disr_expr { + Some(ref expr) => expr.span, + None => ccx.tcx.map.span(variant_i_node_id) + }; + let span = match v.node.disr_expr { + Some(ref expr) => expr.span, + None => v.span + }; + struct_span_err!(ccx.tcx.sess, span, E0081, + "discriminant value `{}` already exists", disr_vals[i]) + .span_label(i_span, &format!("first use of `{}`", disr_vals[i])) + .span_label(span , &format!("enum already has `{}`", disr_vals[i])) + .emit(); } disr_vals.push(current_disr_val); } @@ -4372,14 +4380,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; } @@ -4637,9 +4648,11 @@ pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, for (i, b) in tps_used.iter().enumerate() { if !*b { - span_err!(ccx.tcx.sess, tps[i].span, E0091, + struct_span_err!(ccx.tcx.sess, tps[i].span, E0091, "type parameter `{}` is unused", - tps[i].name); + tps[i].name) + .span_label(tps[i].span, &format!("unused type parameter")) + .emit(); } } } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index cdf2ca14d4c78..7a923cd29d0fb 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -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); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index f0ce4f6d2ec42..f68d902ef36ab 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1903,9 +1903,12 @@ fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, for leaf_ty in ty.walk() { if let ty::TyParam(p) = leaf_ty.sty { if p.space == space && p.idx >= index { - span_err!(ccx.tcx.sess, path.span, E0128, - "type parameters with a default cannot use \ - forward declared identifiers"); + struct_span_err!(ccx.tcx.sess, path.span, E0128, + "type parameters with a default cannot use \ + forward declared identifiers") + .span_label(path.span, &format!("defaulted type parameters \ + cannot be forward declared")) + .emit(); return ccx.tcx.types.err } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index eac26487ea3af..a31961a157b35 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -178,8 +178,10 @@ fn require_c_abi_if_variadic(tcx: TyCtxt, abi: Abi, span: Span) { if decl.variadic && abi != Abi::C { - span_err!(tcx.sess, span, E0045, + let mut err = struct_span_err!(tcx.sess, span, E0045, "variadic function must have C calling convention"); + err.span_label(span, &("variadics require C calling conventions").to_string()) + .emit(); } } @@ -262,9 +264,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; diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index fd7b0a2e6bbf6..8039421ae7730 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -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)]`. diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index e0501f9cc61d2..77b90c0846bbe 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -99,11 +99,9 @@ pub struct CString { /// /// extern { fn my_string() -> *const c_char; } /// -/// fn main() { -/// unsafe { -/// let slice = CStr::from_ptr(my_string()); -/// println!("string length: {}", slice.to_bytes().len()); -/// } +/// unsafe { +/// let slice = CStr::from_ptr(my_string()); +/// println!("string length: {}", slice.to_bytes().len()); /// } /// ``` /// @@ -119,10 +117,8 @@ pub struct CString { /// unsafe { work_with(data.as_ptr()) } /// } /// -/// fn main() { -/// let s = CString::new("data data data data").unwrap(); -/// work(&s); -/// } +/// let s = CString::new("data data data data").unwrap(); +/// work(&s); /// ``` /// /// Converting a foreign C string into a Rust `String` @@ -139,9 +135,7 @@ pub struct CString { /// } /// } /// -/// fn main() { -/// println!("string: {}", my_string_safe()); -/// } +/// println!("string: {}", my_string_safe()); /// ``` #[derive(Hash)] #[stable(feature = "rust1", since = "1.0.0")] @@ -188,11 +182,9 @@ impl CString { /// /// extern { fn puts(s: *const c_char); } /// - /// fn main() { - /// let to_print = CString::new("Hello!").unwrap(); - /// unsafe { - /// puts(to_print.as_ptr()); - /// } + /// let to_print = CString::new("Hello!").unwrap(); + /// unsafe { + /// puts(to_print.as_ptr()); /// } /// ``` /// diff --git a/src/test/compile-fail/E0007.rs b/src/test/compile-fail/E0007.rs index bfc0f1afe3ad3..4be115b8afdac 100644 --- a/src/test/compile-fail/E0007.rs +++ b/src/test/compile-fail/E0007.rs @@ -11,8 +11,10 @@ fn main() { let x = Some("s".to_string()); match x { - op_string @ Some(s) => {}, //~ ERROR E0007 - //~| ERROR E0303 + op_string @ Some(s) => {}, + //~^ ERROR E0007 + //~| NOTE binds an already bound by-move value by moving it + //~| ERROR E0303 None => {}, } } diff --git a/src/test/compile-fail/E0008.rs b/src/test/compile-fail/E0008.rs index 97dd0f368bd12..20cc1cbd2232d 100644 --- a/src/test/compile-fail/E0008.rs +++ b/src/test/compile-fail/E0008.rs @@ -10,7 +10,9 @@ fn main() { match Some("hi".to_string()) { - Some(s) if s.len() == 0 => {}, //~ ERROR E0008 + Some(s) if s.len() == 0 => {}, + //~^ ERROR E0008 + //~| NOTE moves value into pattern guard _ => {}, } } diff --git a/src/test/compile-fail/E0017.rs b/src/test/compile-fail/E0017.rs index 13f2c23d8c4a9..1223a01cbcb6f 100644 --- a/src/test/compile-fail/E0017.rs +++ b/src/test/compile-fail/E0017.rs @@ -12,11 +12,16 @@ static X: i32 = 1; const C: i32 = 2; const CR: &'static mut i32 = &mut C; //~ ERROR E0017 + //~| NOTE constants require immutable values //~| ERROR E0017 + //~| NOTE constants require immutable values static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017 + //~| NOTE statics require immutable values //~| ERROR E0017 + //~| NOTE statics require immutable values //~| ERROR E0388 static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017 + //~| NOTE statics require immutable values //~| ERROR E0017 - + //~| NOTE statics require immutable values fn main() {} diff --git a/src/test/compile-fail/E0023.rs b/src/test/compile-fail/E0023.rs index 05f126baf9a70..c3623e3177b56 100644 --- a/src/test/compile-fail/E0023.rs +++ b/src/test/compile-fail/E0023.rs @@ -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 } } diff --git a/src/test/compile-fail/E0026.rs b/src/test/compile-fail/E0026.rs index 359c2a822a243..ac609da4cbdde 100644 --- a/src/test/compile-fail/E0026.rs +++ b/src/test/compile-fail/E0026.rs @@ -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` } } diff --git a/src/test/compile-fail/E0033.rs b/src/test/compile-fail/E0033.rs index 946600013f33d..fe75b6b1f0f1b 100644 --- a/src/test/compile-fail/E0033.rs +++ b/src/test/compile-fail/E0033.rs @@ -15,5 +15,9 @@ trait SomeTrait { fn main() { let trait_obj: &SomeTrait = SomeTrait; //~ ERROR E0425 //~^ ERROR E0038 - let &invalid = trait_obj; //~ ERROR E0033 + //~| method `foo` has no receiver + + let &invalid = trait_obj; + //~^ ERROR E0033 + //~| NOTE type `&SomeTrait` cannot be dereferenced } diff --git a/src/test/compile-fail/E0038.rs b/src/test/compile-fail/E0038.rs index 26d2f339763aa..6cf3f1ebf19e4 100644 --- a/src/test/compile-fail/E0038.rs +++ b/src/test/compile-fail/E0038.rs @@ -12,7 +12,10 @@ trait Trait { fn foo(&self) -> Self; } -fn call_foo(x: Box) { //~ ERROR E0038 +fn call_foo(x: Box) { + //~^ ERROR E0038 + //~| NOTE the trait `Trait` cannot be made into an object + //~| NOTE method `foo` references the `Self` type in its arguments or return type let y = x.foo(); } diff --git a/src/test/compile-fail/E0045.rs b/src/test/compile-fail/E0045.rs index 2a731596b4be8..a3fea8e0db299 100644 --- a/src/test/compile-fail/E0045.rs +++ b/src/test/compile-fail/E0045.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern "Rust" { fn foo(x: u8, ...); } //~ ERROR E0045 +extern "Rust" { fn foo(x: u8, ...); } //~ ERROR E0045 + //~| NOTE variadics require C calling conventions fn main() { } diff --git a/src/test/compile-fail/E0081.rs b/src/test/compile-fail/E0081.rs index b63265564b334..9911e093a8980 100644 --- a/src/test/compile-fail/E0081.rs +++ b/src/test/compile-fail/E0081.rs @@ -9,8 +9,10 @@ // except according to those terms. enum Enum { - P = 3, - X = 3, //~ ERROR E0081 + P = 3, //~ NOTE first use of `3isize` + X = 3, + //~^ ERROR discriminant value `3isize` already exists + //~| NOTE enum already has `3isize` Y = 5 } diff --git a/src/test/compile-fail/E0087.rs b/src/test/compile-fail/E0087.rs index ec559fc8389d2..63115f093c386 100644 --- a/src/test/compile-fail/E0087.rs +++ b/src/test/compile-fail/E0087.rs @@ -12,4 +12,5 @@ fn foo() {} fn main() { foo::(); //~ ERROR E0087 + //~^ NOTE expected } diff --git a/src/test/compile-fail/E0091.rs b/src/test/compile-fail/E0091.rs index da988dbf819ac..0d6c246de2a0e 100644 --- a/src/test/compile-fail/E0091.rs +++ b/src/test/compile-fail/E0091.rs @@ -9,7 +9,9 @@ // except according to those terms. type Foo = u32; //~ ERROR E0091 + //~| NOTE unused type parameter type Foo2 = Box; //~ ERROR E0091 + //~| NOTE unused type parameter fn main() { } diff --git a/src/test/compile-fail/E0092.rs b/src/test/compile-fail/E0092.rs index b08164ac06d42..c8bb31a7857ee 100644 --- a/src/test/compile-fail/E0092.rs +++ b/src/test/compile-fail/E0092.rs @@ -11,7 +11,7 @@ #![feature(intrinsics)] extern "rust-intrinsic" { fn atomic_foo(); //~ ERROR E0092 -} +} //~| NOTE unrecognized atomic operation fn main() { } diff --git a/src/test/compile-fail/E0128.rs b/src/test/compile-fail/E0128.rs index 37071012825ec..f5829b9385941 100644 --- a/src/test/compile-fail/E0128.rs +++ b/src/test/compile-fail/E0128.rs @@ -9,6 +9,7 @@ // except according to those terms. struct Foo { //~ ERROR E0128 + //~| NOTE defaulted type parameters cannot be forward declared field1: T, field2: U, } diff --git a/src/test/compile-fail/E0162.rs b/src/test/compile-fail/E0162.rs index e13b0af6f7977..0b63d7c3f85c7 100644 --- a/src/test/compile-fail/E0162.rs +++ b/src/test/compile-fail/E0162.rs @@ -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); } } diff --git a/src/test/compile-fail/E0191.rs b/src/test/compile-fail/E0191.rs index 489ebb033f84e..dcfe441ab0d00 100644 --- a/src/test/compile-fail/E0191.rs +++ b/src/test/compile-fail/E0191.rs @@ -13,6 +13,7 @@ trait Trait { } type Foo = Trait; //~ ERROR E0191 + //~| NOTE missing associated type `Bar` value fn main() { } diff --git a/src/test/compile-fail/E0205.rs b/src/test/compile-fail/E0205.rs index 37ac57af524a6..c73e753430105 100644 --- a/src/test/compile-fail/E0205.rs +++ b/src/test/compile-fail/E0205.rs @@ -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> { diff --git a/src/test/compile-fail/E0214.rs b/src/test/compile-fail/E0214.rs index 59609345ee523..e9c3cb72c11b0 100644 --- a/src/test/compile-fail/E0214.rs +++ b/src/test/compile-fail/E0214.rs @@ -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 } diff --git a/src/test/compile-fail/E0263.rs b/src/test/compile-fail/E0263.rs index 09f654c368c62..11a8ff443a845 100644 --- a/src/test/compile-fail/E0263.rs +++ b/src/test/compile-fail/E0263.rs @@ -8,6 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { } //~ ERROR E0263 +fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { + //~^ ERROR E0263 + //~| NOTE declared twice + //~| NOTE previous declaration here +} fn main() {} diff --git a/src/test/compile-fail/asm-out-assign-imm.rs b/src/test/compile-fail/asm-out-assign-imm.rs index c1c72a5519bf1..0541faa021356 100644 --- a/src/test/compile-fail/asm-out-assign-imm.rs +++ b/src/test/compile-fail/asm-out-assign-imm.rs @@ -18,11 +18,12 @@ fn foo(x: isize) { println!("{}", x); } target_arch = "aarch64"))] pub fn main() { let x: isize; - x = 1; //~ NOTE prior assignment occurs here + x = 1; //~ NOTE first assignment foo(x); unsafe { asm!("mov $1, $0" : "=r"(x) : "r"(5)); //~^ ERROR re-assignment of immutable variable `x` + //~| NOTE re-assignment of immutable //~| NOTE in this expansion of asm! } foo(x); diff --git a/src/test/compile-fail/assign-imm-local-twice.rs b/src/test/compile-fail/assign-imm-local-twice.rs index 540272a8e2c58..9a5d6289b589e 100644 --- a/src/test/compile-fail/assign-imm-local-twice.rs +++ b/src/test/compile-fail/assign-imm-local-twice.rs @@ -10,9 +10,10 @@ fn test() { let v: isize; - v = 1; //~ NOTE prior assignment occurs here + v = 1; //~ NOTE first assignment println!("v={}", v); v = 2; //~ ERROR re-assignment of immutable variable + //~| NOTE re-assignment of immutable println!("v={}", v); } 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 2b34fcab24c04..a2a11c62bb832 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 @@ -28,6 +28,7 @@ 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` } @@ -35,12 +36,15 @@ fn dent(c: C, color: C::Color) { 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` } diff --git a/src/test/compile-fail/derived-errors/issue-31997-1.rs b/src/test/compile-fail/derived-errors/issue-31997-1.rs index 7d79c48c06ae2..6a9d8db9654ac 100644 --- a/src/test/compile-fail/derived-errors/issue-31997-1.rs +++ b/src/test/compile-fail/derived-errors/issue-31997-1.rs @@ -29,6 +29,7 @@ fn main() { let mut map = HashMap::new(); //~^ ERROR E0433 + //~| NOTE Use of undeclared type or module `HashMap` for line in input.lines() { let line = line.unwrap(); diff --git a/src/test/compile-fail/issue-15524.rs b/src/test/compile-fail/issue-15524.rs index 3d6f224c24904..658a0c1546b9f 100644 --- a/src/test/compile-fail/issue-15524.rs +++ b/src/test/compile-fail/issue-15524.rs @@ -12,17 +12,20 @@ const N: isize = 1; enum Foo { A = 1, - //~^ NOTE first use - //~| NOTE first use - //~| NOTE first use - B = 1, //~ ERROR discriminant value - //~^ NOTE enum already + //~^ NOTE first use of `1isize` + //~| NOTE first use of `1isize` + //~| NOTE first use of `1isize` + B = 1, + //~^ ERROR discriminant value `1isize` already exists + //~| NOTE enum already has `1isize` C = 0, - D, //~ ERROR discriminant value - //~^ NOTE enum already + D, + //~^ ERROR discriminant value `1isize` already exists + //~| NOTE enum already has `1isize` - E = N, //~ ERROR discriminant value - //~^ NOTE enum already + E = N, + //~^ ERROR discriminant value `1isize` already exists + //~| NOTE enum already has `1isize` } diff --git a/src/test/compile-fail/issue-18183.rs b/src/test/compile-fail/issue-18183.rs index e6f3a2bdd33ad..b3fc3aea148ee 100644 --- a/src/test/compile-fail/issue-18183.rs +++ b/src/test/compile-fail/issue-18183.rs @@ -9,5 +9,6 @@ // except according to those terms. pub struct Foo; //~ ERROR E0128 + //~| NOTE defaulted type parameters cannot be forward declared pub struct Baz(Foo); fn main() {} diff --git a/src/test/compile-fail/issue-20692.rs b/src/test/compile-fail/issue-20692.rs index 1c9e588cb2cd1..3e44053875552 100644 --- a/src/test/compile-fail/issue-20692.rs +++ b/src/test/compile-fail/issue-20692.rs @@ -15,10 +15,12 @@ fn f(x: &T) { //~^ ERROR `Array` cannot be made into an object //~| NOTE the trait cannot require that `Self : Sized` //~| NOTE requirements on the impl of `std::ops::CoerceUnsized<&Array>` + //~| NOTE the trait `Array` cannot be made into an object as &Array; //~^ ERROR `Array` cannot be made into an object //~| NOTE the trait cannot require that `Self : Sized` + //~| NOTE the trait `Array` cannot be made into an object } fn main() {} diff --git a/src/test/compile-fail/issue-26056.rs b/src/test/compile-fail/issue-26056.rs index 4e9cbc4f283b4..ded685152d49b 100644 --- a/src/test/compile-fail/issue-26056.rs +++ b/src/test/compile-fail/issue-26056.rs @@ -28,6 +28,7 @@ impl Map for K { fn main() { let _ = &() as &Map; - //~^ ERROR the trait `Map` cannot be made into an object + //~^ ERROR E0038 //~| NOTE the trait cannot use `Self` as a type parameter + //~| NOTE the trait `Map` cannot be made into an object } diff --git a/src/test/compile-fail/liveness-assign-imm-local-in-loop.rs b/src/test/compile-fail/liveness-assign-imm-local-in-loop.rs index f50a934510697..9d246f8ea5e0e 100644 --- a/src/test/compile-fail/liveness-assign-imm-local-in-loop.rs +++ b/src/test/compile-fail/liveness-assign-imm-local-in-loop.rs @@ -12,7 +12,7 @@ fn test() { let v: isize; loop { v = 1; //~ ERROR re-assignment of immutable variable - //~^ NOTE prior assignment occurs here + //~^ NOTE re-assignment of immutable variable v.clone(); // just to prevent liveness warnings } } diff --git a/src/test/compile-fail/liveness-assign-imm-local-in-op-eq.rs b/src/test/compile-fail/liveness-assign-imm-local-in-op-eq.rs index df57bb9e4417e..e1eb3246137d2 100644 --- a/src/test/compile-fail/liveness-assign-imm-local-in-op-eq.rs +++ b/src/test/compile-fail/liveness-assign-imm-local-in-op-eq.rs @@ -10,8 +10,9 @@ fn test() { let v: isize; - v = 2; //~ NOTE prior assignment occurs here + v = 2; //~ NOTE first assignment v += 1; //~ ERROR re-assignment of immutable variable + //~| NOTE re-assignment of immutable v.clone(); } diff --git a/src/test/compile-fail/liveness-assign-imm-local-with-init.rs b/src/test/compile-fail/liveness-assign-imm-local-with-init.rs index 28218bff60d68..2468c91f34bbd 100644 --- a/src/test/compile-fail/liveness-assign-imm-local-with-init.rs +++ b/src/test/compile-fail/liveness-assign-imm-local-with-init.rs @@ -9,9 +9,10 @@ // except according to those terms. fn test() { - let v: isize = 1; //~ NOTE prior assignment occurs here + let v: isize = 1; //~ NOTE first assignment v.clone(); v = 2; //~ ERROR re-assignment of immutable variable + //~| NOTE re-assignment of immutable v.clone(); } diff --git a/src/test/compile-fail/object-safety-generics.rs b/src/test/compile-fail/object-safety-generics.rs index 5097e3d7b10d4..6174d45b898d6 100644 --- a/src/test/compile-fail/object-safety-generics.rs +++ b/src/test/compile-fail/object-safety-generics.rs @@ -24,12 +24,14 @@ trait Quux { fn make_bar(t: &T) -> &Bar { //~^ ERROR E0038 //~| NOTE method `bar` has generic type parameters + //~| NOTE the trait `Bar` cannot be made into an object t } fn make_bar_explicit(t: &T) -> &Bar { //~^ ERROR E0038 - //~^^ NOTE method `bar` has generic type parameters + //~| NOTE method `bar` has generic type parameters + //~| NOTE the trait `Bar` cannot be made into an object t as &Bar } diff --git a/src/test/compile-fail/object-safety-mentions-Self.rs b/src/test/compile-fail/object-safety-mentions-Self.rs index edd31c1f79649..d85614fa5b538 100644 --- a/src/test/compile-fail/object-safety-mentions-Self.rs +++ b/src/test/compile-fail/object-safety-mentions-Self.rs @@ -27,12 +27,14 @@ trait Quux { fn make_bar(t: &T) -> &Bar { //~^ ERROR E0038 //~| NOTE method `bar` references the `Self` type in its arguments or return type + //~| NOTE the trait `Bar` cannot be made into an object loop { } } fn make_baz(t: &T) -> &Baz { //~^ ERROR E0038 //~| NOTE method `bar` references the `Self` type in its arguments or return type + //~| NOTE the trait `Baz` cannot be made into an object t } diff --git a/src/test/compile-fail/object-safety-sized.rs b/src/test/compile-fail/object-safety-sized.rs index 501d61d20fed1..accd7fa87ac29 100644 --- a/src/test/compile-fail/object-safety-sized.rs +++ b/src/test/compile-fail/object-safety-sized.rs @@ -18,6 +18,7 @@ trait Bar : Sized { fn make_bar(t: &T) -> &Bar { //~^ ERROR E0038 //~| NOTE the trait cannot require that `Self : Sized` + //~| NOTE the trait `Bar` cannot be made into an object t } diff --git a/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs b/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs index 0a79ec30e4b94..74d1ad62f14c3 100644 --- a/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs +++ b/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs @@ -25,6 +25,7 @@ fn make_bar>(t: &T) -> &Bar { fn make_baz(t: &T) -> &Baz { //~^ ERROR E0038 //~| NOTE the trait cannot use `Self` as a type parameter in the supertrait listing + //~| NOTE the trait `Baz` cannot be made into an object t } diff --git a/src/test/run-pass/issue-29053.rs b/src/test/run-pass/issue-29053.rs new file mode 100644 index 0000000000000..72655071e4135 --- /dev/null +++ b/src/test/run-pass/issue-29053.rs @@ -0,0 +1,21 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let x: &'static str = "x"; + + { + let y = "y".to_string(); + let ref mut x = &*x; + *x = &*y; + } + + assert_eq!(x, "x"); +} diff --git a/src/test/run-pass/issue-33498.rs b/src/test/run-pass/issue-33498.rs new file mode 100644 index 0000000000000..9b4e1918baea1 --- /dev/null +++ b/src/test/run-pass/issue-33498.rs @@ -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 or the MIT license +// , 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) => {} + _ => (), + } +} diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 2a35fab9676a7..6090cb4f52725 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -36,22 +36,22 @@ impl FromStr for Mode { type Err = (); fn from_str(s: &str) -> Result { match s { - "compile-fail" => Ok(CompileFail), - "parse-fail" => Ok(ParseFail), - "run-fail" => Ok(RunFail), - "run-pass" => Ok(RunPass), - "run-pass-valgrind" => Ok(RunPassValgrind), - "pretty" => Ok(Pretty), - "debuginfo-lldb" => Ok(DebugInfoLldb), - "debuginfo-gdb" => Ok(DebugInfoGdb), - "codegen" => Ok(Codegen), - "rustdoc" => Ok(Rustdoc), - "codegen-units" => Ok(CodegenUnits), - "incremental" => Ok(Incremental), - "run-make" => Ok(RunMake), - "ui" => Ok(Ui), - "mir-opt" => Ok(MirOpt), - _ => Err(()), + "compile-fail" => Ok(CompileFail), + "parse-fail" => Ok(ParseFail), + "run-fail" => Ok(RunFail), + "run-pass" => Ok(RunPass), + "run-pass-valgrind" => Ok(RunPassValgrind), + "pretty" => Ok(Pretty), + "debuginfo-lldb" => Ok(DebugInfoLldb), + "debuginfo-gdb" => Ok(DebugInfoGdb), + "codegen" => Ok(Codegen), + "rustdoc" => Ok(Rustdoc), + "codegen-units" => Ok(CodegenUnits), + "incremental" => Ok(Incremental), + "run-make" => Ok(RunMake), + "ui" => Ok(Ui), + "mir-opt" => Ok(MirOpt), + _ => Err(()), } } } @@ -59,22 +59,23 @@ impl FromStr for Mode { impl fmt::Display for Mode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(match *self { - CompileFail => "compile-fail", - ParseFail => "parse-fail", - RunFail => "run-fail", - RunPass => "run-pass", - RunPassValgrind => "run-pass-valgrind", - Pretty => "pretty", - DebugInfoGdb => "debuginfo-gdb", - DebugInfoLldb => "debuginfo-lldb", - Codegen => "codegen", - Rustdoc => "rustdoc", - CodegenUnits => "codegen-units", - Incremental => "incremental", - RunMake => "run-make", - Ui => "ui", - MirOpt => "mir-opt", - }, f) + CompileFail => "compile-fail", + ParseFail => "parse-fail", + RunFail => "run-fail", + RunPass => "run-pass", + RunPassValgrind => "run-pass-valgrind", + Pretty => "pretty", + DebugInfoGdb => "debuginfo-gdb", + DebugInfoLldb => "debuginfo-lldb", + Codegen => "codegen", + Rustdoc => "rustdoc", + CodegenUnits => "codegen-units", + Incremental => "incremental", + RunMake => "run-make", + Ui => "ui", + MirOpt => "mir-opt", + }, + f) } } diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs index c3da891933f6d..29ca54fda8db9 100644 --- a/src/tools/compiletest/src/errors.rs +++ b/src/tools/compiletest/src/errors.rs @@ -64,7 +64,11 @@ pub struct Error { } #[derive(PartialEq, Debug)] -enum WhichLine { ThisLine, FollowPrevious(usize), AdjustBackward(usize) } +enum WhichLine { + ThisLine, + FollowPrevious(usize), + AdjustBackward(usize), +} /// Looks for either "//~| KIND MESSAGE" or "//~^^... KIND MESSAGE" /// The former is a "follow" that inherits its target from the preceding line; @@ -91,25 +95,22 @@ pub fn load_errors(testfile: &Path, cfg: Option<&str>) -> Vec { let tag = match cfg { Some(rev) => format!("//[{}]~", rev), - None => format!("//~") + None => format!("//~"), }; rdr.lines() - .enumerate() - .filter_map(|(line_num, line)| { - parse_expected(last_nonfollow_error, - line_num + 1, - &line.unwrap(), - &tag) - .map(|(which, error)| { - match which { - FollowPrevious(_) => {} - _ => last_nonfollow_error = Some(error.line_num), - } - error - }) - }) - .collect() + .enumerate() + .filter_map(|(line_num, line)| { + parse_expected(last_nonfollow_error, line_num + 1, &line.unwrap(), &tag) + .map(|(which, error)| { + match which { + FollowPrevious(_) => {} + _ => last_nonfollow_error = Some(error.line_num), + } + error + }) + }) + .collect() } fn parse_expected(last_nonfollow_error: Option, @@ -117,7 +118,10 @@ fn parse_expected(last_nonfollow_error: Option, line: &str, tag: &str) -> Option<(WhichLine, Error)> { - let start = match line.find(tag) { Some(i) => i, None => return None }; + let start = match line.find(tag) { + Some(i) => i, + None => return None, + }; let (follow, adjusts) = if line[start + tag.len()..].chars().next().unwrap() == '|' { (true, 0) } else { @@ -125,26 +129,25 @@ fn parse_expected(last_nonfollow_error: Option, }; let kind_start = start + tag.len() + adjusts + (follow as usize); let (kind, msg); - match - line[kind_start..].split_whitespace() - .next() - .expect("Encountered unexpected empty comment") - .parse::() - { + match line[kind_start..] + .split_whitespace() + .next() + .expect("Encountered unexpected empty comment") + .parse::() { Ok(k) => { // If we find `//~ ERROR foo` or something like that: kind = Some(k); let letters = line[kind_start..].chars(); msg = letters.skip_while(|c| c.is_whitespace()) - .skip_while(|c| !c.is_whitespace()) - .collect::(); + .skip_while(|c| !c.is_whitespace()) + .collect::(); } Err(_) => { // Otherwise we found `//~ foo`: kind = None; let letters = line[kind_start..].chars(); msg = letters.skip_while(|c| c.is_whitespace()) - .collect::(); + .collect::(); } } let msg = msg.trim().to_owned(); @@ -155,15 +158,25 @@ fn parse_expected(last_nonfollow_error: Option, preceding //~^ line."); (FollowPrevious(line_num), line_num) } else { - let which = - if adjusts > 0 { AdjustBackward(adjusts) } else { ThisLine }; + let which = if adjusts > 0 { + AdjustBackward(adjusts) + } else { + ThisLine + }; let line_num = line_num - adjusts; (which, line_num) }; debug!("line={} tag={:?} which={:?} kind={:?} msg={:?}", - line_num, tag, which, kind, msg); - Some((which, Error { line_num: line_num, - kind: kind, - msg: msg, })) + line_num, + tag, + which, + kind, + msg); + Some((which, + Error { + line_num: line_num, + kind: kind, + msg: msg, + })) } diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 7593033ffe399..af33d76be1b0d 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -32,24 +32,21 @@ impl EarlyProps { should_fail: false, }; - iter_header(testfile, None, &mut |ln| { + iter_header(testfile, + None, + &mut |ln| { props.ignore = - props.ignore || - parse_name_directive(ln, "ignore-test") || + props.ignore || parse_name_directive(ln, "ignore-test") || parse_name_directive(ln, &ignore_target(config)) || parse_name_directive(ln, &ignore_architecture(config)) || parse_name_directive(ln, &ignore_stage(config)) || parse_name_directive(ln, &ignore_env(config)) || - (config.mode == common::Pretty && - parse_name_directive(ln, "ignore-pretty")) || + (config.mode == common::Pretty && parse_name_directive(ln, "ignore-pretty")) || (config.target != config.host && parse_name_directive(ln, "ignore-cross-compile")) || - ignore_gdb(config, ln) || - ignore_lldb(config, ln); + ignore_gdb(config, ln) || ignore_lldb(config, ln); - props.should_fail = - props.should_fail || - parse_name_directive(ln, "should-fail"); + props.should_fail = props.should_fail || parse_name_directive(ln, "should-fail"); }); return props; @@ -61,11 +58,11 @@ impl EarlyProps { format!("ignore-{}", util::get_arch(&config.target)) } fn ignore_stage(config: &Config) -> String { - format!("ignore-{}", - config.stage_id.split('-').next().unwrap()) + format!("ignore-{}", config.stage_id.split('-').next().unwrap()) } fn ignore_env(config: &Config) -> String { - format!("ignore-{}", util::get_env(&config.target).unwrap_or("")) + format!("ignore-{}", + util::get_env(&config.target).unwrap_or("")) } fn ignore_gdb(config: &Config, line: &str) -> bool { if config.mode != common::DebugInfoGdb { @@ -79,13 +76,12 @@ impl EarlyProps { if let Some(ref actual_version) = config.gdb_version { if line.contains("min-gdb-version") { let min_version = line.trim() - .split(' ') - .last() - .expect("Malformed GDB version directive"); + .split(' ') + .last() + .expect("Malformed GDB version directive"); // Ignore if actual version is smaller the minimum required // version - gdb_version_to_int(actual_version) < - gdb_version_to_int(min_version) + gdb_version_to_int(actual_version) < gdb_version_to_int(min_version) } else { false } @@ -106,13 +102,12 @@ impl EarlyProps { if let Some(ref actual_version) = config.lldb_version { if line.contains("min-lldb-version") { let min_version = line.trim() - .split(' ') - .last() - .expect("Malformed lldb version directive"); + .split(' ') + .last() + .expect("Malformed lldb version directive"); // Ignore if actual version is smaller the minimum required // version - lldb_version_to_int(actual_version) < - lldb_version_to_int(min_version) + lldb_version_to_int(actual_version) < lldb_version_to_int(min_version) } else { false } @@ -126,7 +121,7 @@ impl EarlyProps { #[derive(Clone, Debug)] pub struct TestProps { // Lines that should be expected, in order, on standard out - pub error_patterns: Vec , + pub error_patterns: Vec, // Extra flags to pass to the compiler pub compile_flags: Vec, // Extra flags to pass when the compiled code is run (such as --bench) @@ -137,13 +132,13 @@ pub struct TestProps { // Other crates that should be compiled (typically from the same // directory as the test, but for backwards compatibility reasons // we also check the auxiliary directory) - pub aux_builds: Vec , + pub aux_builds: Vec, // Environment settings to use for compiling - pub rustc_env: Vec<(String,String)> , + pub rustc_env: Vec<(String, String)>, // Environment settings to use during execution - pub exec_env: Vec<(String,String)> , + pub exec_env: Vec<(String, String)>, // Lines to check if they appear in the expected debugger output - pub check_lines: Vec , + pub check_lines: Vec, // Build documentation for all specified aux-builds as well pub build_aux_docs: bool, // Flag to force a crate to be built with the host architecture @@ -226,17 +221,17 @@ impl TestProps { /// tied to a particular revision `foo` (indicated by writing /// `//[foo]`), then the property is ignored unless `cfg` is /// `Some("foo")`. - pub fn load_from(&mut self, testfile: &Path, cfg: Option<&str>) { - iter_header(testfile, cfg, &mut |ln| { + pub fn load_from(&mut self, testfile: &Path, cfg: Option<&str>) { + iter_header(testfile, + cfg, + &mut |ln| { if let Some(ep) = parse_error_pattern(ln) { self.error_patterns.push(ep); } if let Some(flags) = parse_compile_flags(ln) { - self.compile_flags.extend( - flags - .split_whitespace() - .map(|s| s.to_owned())); + self.compile_flags.extend(flags.split_whitespace() + .map(|s| s.to_owned())); } if let Some(r) = parse_revisions(ln) { @@ -279,7 +274,7 @@ impl TestProps { self.pretty_compare_only = parse_pretty_compare_only(ln); } - if let Some(ab) = parse_aux_build(ln) { + if let Some(ab) = parse_aux_build(ln) { self.aux_builds.push(ab); } @@ -291,7 +286,7 @@ impl TestProps { self.rustc_env.push(ee); } - if let Some(cl) = parse_check_line(ln) { + if let Some(cl) = parse_check_line(ln) { self.check_lines.push(cl); } @@ -302,21 +297,20 @@ impl TestProps { for key in vec!["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] { match env::var(key) { - Ok(val) => + Ok(val) => { if self.exec_env.iter().find(|&&(ref x, _)| *x == key).is_none() { self.exec_env.push((key.to_owned(), val)) - }, + } + } Err(..) => {} } } } } -fn iter_header(testfile: &Path, - cfg: Option<&str>, - it: &mut FnMut(&str)) { +fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut FnMut(&str)) { if testfile.is_dir() { - return + return; } let rdr = BufReader::new(File::open(testfile).unwrap()); for ln in rdr.lines() { @@ -336,7 +330,7 @@ fn iter_header(testfile: &Path, None => false, }; if matches { - it(&ln[close_brace+1..]); + it(&ln[close_brace + 1..]); } } else { panic!("malformed condition directive: expected `//[foo]`, found `{}`", @@ -409,18 +403,17 @@ fn parse_pretty_compare_only(line: &str) -> bool { fn parse_env(line: &str, name: &str) -> Option<(String, String)> { parse_name_value_directive(line, name).map(|nv| { // nv is either FOO or FOO=BAR - let mut strs: Vec = nv - .splitn(2, '=') - .map(str::to_owned) - .collect(); + let mut strs: Vec = nv.splitn(2, '=') + .map(str::to_owned) + .collect(); match strs.len() { - 1 => (strs.pop().unwrap(), "".to_owned()), - 2 => { - let end = strs.pop().unwrap(); - (strs.pop().unwrap(), end) - } - n => panic!("Expected 1 or 2 strings, not {}", n) + 1 => (strs.pop().unwrap(), "".to_owned()), + 2 => { + let end = strs.pop().unwrap(); + (strs.pop().unwrap(), end) + } + n => panic!("Expected 1 or 2 strings, not {}", n), } }) } @@ -442,11 +435,10 @@ fn parse_name_directive(line: &str, directive: &str) -> bool { line.contains(directive) && !line.contains(&("no-".to_owned() + directive)) } -pub fn parse_name_value_directive(line: &str, directive: &str) - -> Option { +pub fn parse_name_value_directive(line: &str, directive: &str) -> Option { let keycolon = format!("{}:", directive); if let Some(colon) = line.find(&keycolon) { - let value = line[(colon + keycolon.len()) .. line.len()].to_owned(); + let value = line[(colon + keycolon.len())..line.len()].to_owned(); debug!("{}: {}", directive, value); Some(value) } else { @@ -455,9 +447,8 @@ pub fn parse_name_value_directive(line: &str, directive: &str) } pub fn gdb_version_to_int(version_string: &str) -> isize { - let error_string = format!( - "Encountered GDB version string with unexpected format: {}", - version_string); + let error_string = format!("Encountered GDB version string with unexpected format: {}", + version_string); let error_string = error_string; let components: Vec<&str> = version_string.trim().split('.').collect(); @@ -473,9 +464,8 @@ pub fn gdb_version_to_int(version_string: &str) -> isize { } pub fn lldb_version_to_int(version_string: &str) -> isize { - let error_string = format!( - "Encountered LLDB version string with unexpected format: {}", - version_string); + let error_string = format!("Encountered LLDB version string with unexpected format: {}", + version_string); let error_string = error_string; let major: isize = version_string.parse().ok().expect(&error_string); return major; diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs index e5b628bb00295..d9da1bdc34858 100644 --- a/src/tools/compiletest/src/json.rs +++ b/src/tools/compiletest/src/json.rs @@ -12,7 +12,7 @@ use errors::{Error, ErrorKind}; use rustc_serialize::json; use std::str::FromStr; use std::path::Path; -use runtest::{ProcRes}; +use runtest::ProcRes; // These structs are a subset of the ones found in // `syntax::json`. @@ -58,8 +58,8 @@ struct DiagnosticCode { pub fn parse_output(file_name: &str, output: &str, proc_res: &ProcRes) -> Vec { output.lines() - .flat_map(|line| parse_line(file_name, line, output, proc_res)) - .collect() + .flat_map(|line| parse_line(file_name, line, output, proc_res)) + .collect() } fn parse_line(file_name: &str, line: &str, output: &str, proc_res: &ProcRes) -> Vec { @@ -73,9 +73,11 @@ fn parse_line(file_name: &str, line: &str, output: &str, proc_res: &ProcRes) -> expected_errors } Err(error) => { - proc_res.fatal(Some(&format!( - "failed to decode compiler output as json: `{}`\noutput: {}\nline: {}", - error, line, output))); + proc_res.fatal(Some(&format!("failed to decode compiler output as json: \ + `{}`\noutput: {}\nline: {}", + error, + line, + output))); } } } else { @@ -87,16 +89,15 @@ fn push_expected_errors(expected_errors: &mut Vec, diagnostic: &Diagnostic, default_spans: &[&DiagnosticSpan], file_name: &str) { - let spans_in_this_file: Vec<_> = - diagnostic.spans.iter() - .filter(|span| Path::new(&span.file_name) == Path::new(&file_name)) - .collect(); - - let primary_spans: Vec<_> = - spans_in_this_file.iter() - .cloned() - .filter(|span| span.is_primary) - .collect(); + let spans_in_this_file: Vec<_> = diagnostic.spans + .iter() + .filter(|span| Path::new(&span.file_name) == Path::new(&file_name)) + .collect(); + + let primary_spans: Vec<_> = spans_in_this_file.iter() + .cloned() + .filter(|span| span.is_primary) + .collect(); let primary_spans = if primary_spans.is_empty() { // subdiagnostics often don't have a span of their own; // inherit the span from the parent in that case @@ -144,24 +145,20 @@ fn push_expected_errors(expected_errors: &mut Vec, for span in primary_spans { let msg = with_code(span, first_line); let kind = ErrorKind::from_str(&diagnostic.level).ok(); - expected_errors.push( - Error { - line_num: span.line_start, - kind: kind, - msg: msg, - } - ); + expected_errors.push(Error { + line_num: span.line_start, + kind: kind, + msg: msg, + }); } } for next_line in message_lines { for span in primary_spans { - expected_errors.push( - Error { - line_num: span.line_start, - kind: None, - msg: with_code(span, next_line), - } - ); + expected_errors.push(Error { + line_num: span.line_start, + kind: None, + msg: with_code(span, next_line), + }); } } @@ -170,33 +167,28 @@ fn push_expected_errors(expected_errors: &mut Vec, let start_line = primary_spans.iter().map(|s| s.line_start).min().expect("\ every suggestion should have at least one span"); for (index, line) in rendered.lines().enumerate() { - expected_errors.push( - Error { - line_num: start_line + index, - kind: Some(ErrorKind::Suggestion), - msg: line.to_string() - } - ); + expected_errors.push(Error { + line_num: start_line + index, + kind: Some(ErrorKind::Suggestion), + msg: line.to_string(), + }); } } // Add notes for the backtrace for span in primary_spans { for frame in &span.expansion { - push_backtrace(expected_errors, - frame, - file_name); + push_backtrace(expected_errors, frame, file_name); } } // Add notes for any labels that appear in the message. for span in spans_in_this_file.iter() - .filter(|span| span.label.is_some()) - { + .filter(|span| span.label.is_some()) { expected_errors.push(Error { line_num: span.line_start, kind: Some(ErrorKind::Note), - msg: span.label.clone().unwrap() + msg: span.label.clone().unwrap(), }); } @@ -210,13 +202,11 @@ fn push_backtrace(expected_errors: &mut Vec, expansion: &DiagnosticSpanMacroExpansion, file_name: &str) { if Path::new(&expansion.span.file_name) == Path::new(&file_name) { - expected_errors.push( - Error { - line_num: expansion.span.line_start, - kind: Some(ErrorKind::Note), - msg: format!("in this expansion of {}", expansion.macro_decl_name), - } - ); + expected_errors.push(Error { + line_num: expansion.span.line_start, + kind: Some(ErrorKind::Note), + msg: format!("in this expansion of {}", expansion.macro_decl_name), + }); } for previous_expansion in &expansion.span.expansion { diff --git a/src/tools/compiletest/src/procsrv.rs b/src/tools/compiletest/src/procsrv.rs index 53b7cd059be27..ed690c08a1ed2 100644 --- a/src/tools/compiletest/src/procsrv.rs +++ b/src/tools/compiletest/src/procsrv.rs @@ -12,7 +12,7 @@ use std::env; use std::ffi::OsString; use std::io::prelude::*; use std::path::PathBuf; -use std::process::{ExitStatus, Command, Child, Output, Stdio}; +use std::process::{Child, Command, ExitStatus, Output, Stdio}; pub fn dylib_env_var() -> &'static str { if cfg!(windows) { @@ -29,7 +29,7 @@ fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) { // search path for the child. let var = dylib_env_var(); let mut path = env::split_paths(&env::var_os(var).unwrap_or(OsString::new())) - .collect::>(); + .collect::>(); if let Some(p) = aux_path { path.insert(0, PathBuf::from(p)) } @@ -40,20 +40,25 @@ fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) { cmd.env(var, newpath); } -pub struct Result {pub status: ExitStatus, pub out: String, pub err: String} +pub struct Result { + pub status: ExitStatus, + pub out: String, + pub err: String, +} pub fn run(lib_path: &str, prog: &str, aux_path: Option<&str>, args: &[String], - env: Vec<(String, String)> , - input: Option) -> Option { + env: Vec<(String, String)>, + input: Option) + -> Option { let mut cmd = Command::new(prog); cmd.args(args) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()); + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()); add_target_env(&mut cmd, lib_path, aux_path); for (key, val) in env { cmd.env(&key, &val); @@ -64,31 +69,31 @@ pub fn run(lib_path: &str, if let Some(input) = input { process.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap(); } - let Output { status, stdout, stderr } = - process.wait_with_output().unwrap(); + let Output { status, stdout, stderr } = process.wait_with_output().unwrap(); Some(Result { status: status, out: String::from_utf8(stdout).unwrap(), - err: String::from_utf8(stderr).unwrap() + err: String::from_utf8(stderr).unwrap(), }) - }, - Err(..) => None + } + Err(..) => None, } } pub fn run_background(lib_path: &str, - prog: &str, - aux_path: Option<&str>, - args: &[String], - env: Vec<(String, String)> , - input: Option) -> Option { + prog: &str, + aux_path: Option<&str>, + args: &[String], + env: Vec<(String, String)>, + input: Option) + -> Option { let mut cmd = Command::new(prog); cmd.args(args) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()); + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()); add_target_env(&mut cmd, lib_path, aux_path); for (key, val) in env { cmd.env(&key, &val); @@ -101,7 +106,7 @@ pub fn run_background(lib_path: &str, } Some(process) - }, - Err(..) => None + } + Err(..) => None, } } diff --git a/src/tools/compiletest/src/raise_fd_limit.rs b/src/tools/compiletest/src/raise_fd_limit.rs index 0cf90ec95f38e..e2629ffd8f54a 100644 --- a/src/tools/compiletest/src/raise_fd_limit.rs +++ b/src/tools/compiletest/src/raise_fd_limit.rs @@ -34,14 +34,21 @@ pub unsafe fn raise_fd_limit() { let mut mib: [libc::c_int; 2] = [CTL_KERN, KERN_MAXFILESPERPROC]; let mut maxfiles: libc::c_int = 0; let mut size: libc::size_t = size_of_val(&maxfiles) as libc::size_t; - if libc::sysctl(&mut mib[0], 2, &mut maxfiles as *mut _ as *mut _, &mut size, - null_mut(), 0) != 0 { + if libc::sysctl(&mut mib[0], + 2, + &mut maxfiles as *mut _ as *mut _, + &mut size, + null_mut(), + 0) != 0 { let err = io::Error::last_os_error(); panic!("raise_fd_limit: error calling sysctl: {}", err); } // Fetch the current resource limits - let mut rlim = libc::rlimit{rlim_cur: 0, rlim_max: 0}; + let mut rlim = libc::rlimit { + rlim_cur: 0, + rlim_max: 0, + }; if libc::getrlimit(libc::RLIMIT_NOFILE, &mut rlim) != 0 { let err = io::Error::last_os_error(); panic!("raise_fd_limit: error calling getrlimit: {}", err); diff --git a/src/tools/compiletest/src/uidiff.rs b/src/tools/compiletest/src/uidiff.rs index 66573393971c4..fca01029c4465 100644 --- a/src/tools/compiletest/src/uidiff.rs +++ b/src/tools/compiletest/src/uidiff.rs @@ -13,24 +13,23 @@ pub fn diff_lines(actual: &str, expected: &str) -> Vec { // mega simplistic diff algorithm that just prints the things added/removed - zip_all(actual.lines(), expected.lines()).enumerate().filter_map(|(i, (a,e))| { - match (a, e) { - (Some(a), Some(e)) => { - if lines_match(e, a) { - None - } else { - Some(format!("{:3} - |{}|\n + |{}|\n", i, e, a)) + zip_all(actual.lines(), expected.lines()) + .enumerate() + .filter_map(|(i, (a, e))| { + match (a, e) { + (Some(a), Some(e)) => { + if lines_match(e, a) { + None + } else { + Some(format!("{:3} - |{}|\n + |{}|\n", i, e, a)) + } } - }, - (Some(a), None) => { - Some(format!("{:3} -\n + |{}|\n", i, a)) - }, - (None, Some(e)) => { - Some(format!("{:3} - |{}|\n +\n", i, e)) - }, - (None, None) => panic!("Cannot get here") - } - }).collect() + (Some(a), None) => Some(format!("{:3} -\n + |{}|\n", i, a)), + (None, Some(e)) => Some(format!("{:3} - |{}|\n +\n", i, e)), + (None, None) => panic!("Cannot get here"), + } + }) + .collect() } fn lines_match(expected: &str, mut actual: &str) -> bool { @@ -38,13 +37,11 @@ fn lines_match(expected: &str, mut actual: &str) -> bool { match actual.find(part) { Some(j) => { if i == 0 && j != 0 { - return false + return false; } actual = &actual[j + part.len()..]; } - None => { - return false - } + None => return false, } } actual.is_empty() || expected.ends_with("[..]") @@ -55,7 +52,7 @@ struct ZipAll { second: I2, } -impl, I2: Iterator> Iterator for ZipAll { +impl, I2: Iterator> Iterator for ZipAll { type Item = (Option, Option); fn next(&mut self) -> Option<(Option, Option)> { let first = self.first.next(); @@ -63,12 +60,12 @@ impl, I2: Iterator> Iterator for ZipAll match (first, second) { (None, None) => None, - (a, b) => Some((a, b)) + (a, b) => Some((a, b)), } } } -fn zip_all, I2: Iterator>(a: I1, b: I2) -> ZipAll { +fn zip_all, I2: Iterator>(a: I1, b: I2) -> ZipAll { ZipAll { first: a, second: b, diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 69b839c5b7d9d..d2872a0a2b7ca 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -12,46 +12,42 @@ use std::env; use common::Config; /// Conversion table from triple OS name to Rust SYSNAME -const OS_TABLE: &'static [(&'static str, &'static str)] = &[ - ("android", "android"), - ("bitrig", "bitrig"), - ("darwin", "macos"), - ("dragonfly", "dragonfly"), - ("freebsd", "freebsd"), - ("ios", "ios"), - ("linux", "linux"), - ("mingw32", "windows"), - ("netbsd", "netbsd"), - ("openbsd", "openbsd"), - ("win32", "windows"), - ("windows", "windows"), - ("solaris", "solaris"), - ("emscripten", "emscripten"), -]; +const OS_TABLE: &'static [(&'static str, &'static str)] = &[("android", "android"), + ("bitrig", "bitrig"), + ("darwin", "macos"), + ("dragonfly", "dragonfly"), + ("freebsd", "freebsd"), + ("ios", "ios"), + ("linux", "linux"), + ("mingw32", "windows"), + ("netbsd", "netbsd"), + ("openbsd", "openbsd"), + ("win32", "windows"), + ("windows", "windows"), + ("solaris", "solaris"), + ("emscripten", "emscripten")]; -const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ - ("aarch64", "aarch64"), - ("amd64", "x86_64"), - ("arm", "arm"), - ("arm64", "aarch64"), - ("hexagon", "hexagon"), - ("i386", "x86"), - ("i686", "x86"), - ("mips", "mips"), - ("msp430", "msp430"), - ("powerpc", "powerpc"), - ("powerpc64", "powerpc64"), - ("s390x", "systemz"), - ("sparc", "sparc"), - ("x86_64", "x86_64"), - ("xcore", "xcore"), - ("asmjs", "asmjs"), -]; +const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[("aarch64", "aarch64"), + ("amd64", "x86_64"), + ("arm", "arm"), + ("arm64", "aarch64"), + ("hexagon", "hexagon"), + ("i386", "x86"), + ("i686", "x86"), + ("mips", "mips"), + ("msp430", "msp430"), + ("powerpc", "powerpc"), + ("powerpc64", "powerpc64"), + ("s390x", "systemz"), + ("sparc", "sparc"), + ("x86_64", "x86_64"), + ("xcore", "xcore"), + ("asmjs", "asmjs")]; pub fn get_os(triple: &str) -> &'static str { for &(triple_os, os) in OS_TABLE { if triple.contains(triple_os) { - return os + return os; } } panic!("Cannot determine OS from triple"); @@ -59,7 +55,7 @@ pub fn get_os(triple: &str) -> &'static str { pub fn get_arch(triple: &str) -> &'static str { for &(triple_arch, arch) in ARCH_TABLE { if triple.contains(triple_arch) { - return arch + return arch; } } panic!("Cannot determine Architecture from triple"); @@ -74,17 +70,21 @@ pub fn make_new_path(path: &str) -> String { // Windows just uses PATH as the library search path, so we have to // maintain the current value while adding our own match env::var(lib_path_env_var()) { - Ok(curr) => { - format!("{}{}{}", path, path_div(), curr) - } - Err(..) => path.to_owned() + Ok(curr) => format!("{}{}{}", path, path_div(), curr), + Err(..) => path.to_owned(), } } -pub fn lib_path_env_var() -> &'static str { "PATH" } -fn path_div() -> &'static str { ";" } +pub fn lib_path_env_var() -> &'static str { + "PATH" +} +fn path_div() -> &'static str { + ";" +} pub fn logv(config: &Config, s: String) { debug!("{}", s); - if config.verbose { println!("{}", s); } + if config.verbose { + println!("{}", s); + } }