diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 2f57c53a6d834..1bb2bed463b09 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1212,8 +1212,9 @@ impl Vec { /// difference, with each additional slot filled with `value`. /// If `new_len` is less than `len`, the `Vec` is simply truncated. /// - /// This method requires `Clone` to clone the passed value. If you'd - /// rather create a value with `Default` instead, see [`resize_default`]. + /// This method requires [`Clone`] to be able clone the passed value. If + /// you'd rather create a value with [`Default`] instead, see + /// [`resize_default`]. /// /// # Examples /// @@ -1227,6 +1228,8 @@ impl Vec { /// assert_eq!(vec, [1, 2]); /// ``` /// + /// [`Clone`]: ../../std/clone/trait.Clone.html + /// [`Default`]: ../../std/default/trait.Default.html /// [`resize_default`]: #method.resize_default #[stable(feature = "vec_resize", since = "1.5.0")] pub fn resize(&mut self, new_len: usize, value: T) { @@ -1244,7 +1247,7 @@ impl Vec { /// Iterates over the slice `other`, clones each element, and then appends /// it to this `Vec`. The `other` vector is traversed in-order. /// - /// Note that this function is same as `extend` except that it is + /// Note that this function is same as [`extend`] except that it is /// specialized to work with slices instead. If and when Rust gets /// specialization this function will likely be deprecated (but still /// available). @@ -1256,6 +1259,8 @@ impl Vec { /// vec.extend_from_slice(&[2, 3, 4]); /// assert_eq!(vec, [1, 2, 3, 4]); /// ``` + /// + /// [`extend`]: #method.extend #[stable(feature = "vec_extend_from_slice", since = "1.6.0")] pub fn extend_from_slice(&mut self, other: &[T]) { self.spec_extend(other.iter()) @@ -1266,12 +1271,11 @@ impl Vec { /// Resizes the `Vec` in-place so that `len` is equal to `new_len`. /// /// If `new_len` is greater than `len`, the `Vec` is extended by the - /// difference, with each additional slot filled with `Default::default()`. + /// difference, with each additional slot filled with [`Default::default()`]. /// If `new_len` is less than `len`, the `Vec` is simply truncated. /// - /// This method uses `Default` to create new values on every push. If - /// you'd rather `Clone` a given value, use [`resize`]. - /// + /// This method uses [`Default`] to create new values on every push. If + /// you'd rather [`Clone`] a given value, use [`resize`]. /// /// # Examples /// @@ -1288,6 +1292,9 @@ impl Vec { /// ``` /// /// [`resize`]: #method.resize + /// [`Default::default()`]: ../../std/default/trait.Default.html#tymethod.default + /// [`Default`]: ../../std/default/trait.Default.html + /// [`Clone`]: ../../std/clone/trait.Clone.html #[unstable(feature = "vec_resize_default", issue = "41758")] pub fn resize_default(&mut self, new_len: usize) { let len = self.len(); diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 1efd605112dc2..448e49ffebda8 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -74,7 +74,9 @@ #![feature(concat_idents)] #![feature(const_fn)] #![feature(custom_attribute)] +#![feature(doc_cfg)] #![feature(doc_spotlight)] +#![feature(fn_must_use)] #![feature(fundamental)] #![feature(i128_type)] #![feature(inclusive_range_syntax)] diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs index ae1b0b3ce11b2..826883fdc3f01 100644 --- a/src/libcore/num/wrapping.rs +++ b/src/libcore/num/wrapping.rs @@ -317,11 +317,320 @@ macro_rules! wrapping_impl { } forward_ref_unop! { impl Neg, neg for Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } + )*) } wrapping_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } +macro_rules! wrapping_int_impl { + ($($t:ty)*) => ($( + impl Wrapping<$t> { + /// Returns the number of ones in the binary representation of + /// `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(-0b1000_0000); + /// + /// assert_eq!(n.count_ones(), 1); + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn count_ones(self) -> u32 { + self.0.count_ones() + } + + /// Returns the number of zeros in the binary representation of + /// `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(-0b1000_0000); + /// + /// assert_eq!(n.count_zeros(), 7); + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn count_zeros(self) -> u32 { + self.0.count_zeros() + } + + /// Returns the number of leading zeros in the binary representation + /// of `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(-1); + /// + /// assert_eq!(n.leading_zeros(), 0); + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn leading_zeros(self) -> u32 { + self.0.leading_zeros() + } + + /// Returns the number of trailing zeros in the binary representation + /// of `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(-4); + /// + /// assert_eq!(n.trailing_zeros(), 2); + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn trailing_zeros(self) -> u32 { + self.0.trailing_zeros() + } + + /// Shifts the bits to the left by a specified amount, `n`, + /// wrapping the truncated bits to the end of the resulting + /// integer. + /// + /// Please note this isn't the same operation as `>>`! + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(0x0123456789ABCDEF); + /// let m: Wrapping = Wrapping(-0x76543210FEDCBA99); + /// + /// assert_eq!(n.rotate_left(32), m); + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn rotate_left(self, n: u32) -> Self { + Wrapping(self.0.rotate_left(n)) + } + + /// Shifts the bits to the right by a specified amount, `n`, + /// wrapping the truncated bits to the beginning of the resulting + /// integer. + /// + /// Please note this isn't the same operation as `<<`! + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(0x0123456789ABCDEF); + /// let m: Wrapping = Wrapping(-0xFEDCBA987654322); + /// + /// assert_eq!(n.rotate_right(4), m); + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn rotate_right(self, n: u32) -> Self { + Wrapping(self.0.rotate_right(n)) + } + + /// Reverses the byte order of the integer. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(0b0000000_01010101); + /// assert_eq!(n, Wrapping(85)); + /// + /// let m = n.swap_bytes(); + /// + /// assert_eq!(m, Wrapping(0b01010101_00000000)); + /// assert_eq!(m, Wrapping(21760)); + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn swap_bytes(self) -> Self { + Wrapping(self.0.swap_bytes()) + } + + /// Converts an integer from big endian to the target's endianness. + /// + /// On big endian this is a no-op. On little endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(0x0123456789ABCDEF); + /// + /// if cfg!(target_endian = "big") { + /// assert_eq!(Wrapping::::from_be(n), n); + /// } else { + /// assert_eq!(Wrapping::::from_be(n), n.swap_bytes()); + /// } + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn from_be(x: Self) -> Self { + Wrapping(<$t>::from_be(x.0)) + } + + /// Converts an integer from little endian to the target's endianness. + /// + /// On little endian this is a no-op. On big endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(0x0123456789ABCDEF); + /// + /// if cfg!(target_endian = "little") { + /// assert_eq!(Wrapping::::from_le(n), n); + /// } else { + /// assert_eq!(Wrapping::::from_le(n), n.swap_bytes()); + /// } + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn from_le(x: Self) -> Self { + Wrapping(<$t>::from_le(x.0)) + } + + /// Converts `self` to big endian from the target's endianness. + /// + /// On big endian this is a no-op. On little endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(0x0123456789ABCDEF); + /// + /// if cfg!(target_endian = "big") { + /// assert_eq!(n.to_be(), n); + /// } else { + /// assert_eq!(n.to_be(), n.swap_bytes()); + /// } + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn to_be(self) -> Self { + Wrapping(self.0.to_be()) + } + + /// Converts `self` to little endian from the target's endianness. + /// + /// On little endian this is a no-op. On big endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(0x0123456789ABCDEF); + /// + /// if cfg!(target_endian = "little") { + /// assert_eq!(n.to_le(), n); + /// } else { + /// assert_eq!(n.to_le(), n.swap_bytes()); + /// } + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn to_le(self) -> Self { + Wrapping(self.0.to_le()) + } + + /// Raises self to the power of `exp`, using exponentiation by + /// squaring. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let x: Wrapping = Wrapping(2); // or any other integer type + /// + /// assert_eq!(x.pow(4), Wrapping(16)); + /// ``` + /// + /// Results that are too large are wrapped: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// // 5 ^ 4 = 625, which is too big for a u8 + /// let x: Wrapping = Wrapping(5); + /// + /// assert_eq!(x.pow(4).0, 113); + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn pow(self, exp: u32) -> Self { + Wrapping(self.0.wrapping_pow(exp)) + } + } + )*) +} + +wrapping_int_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } + + mod shift_max { #![allow(non_upper_case_globals)] diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index bb198adea4a6a..93d6247eeae47 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -253,28 +253,28 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> { used_mut_nodes: RefCell>, } -impl<'b, 'tcx: 'b> BorrowckErrors for BorrowckCtxt<'b, 'tcx> { - fn struct_span_err_with_code<'a, S: Into>(&'a self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'a> +impl<'a, 'b, 'tcx: 'b> BorrowckErrors<'a> for &'a BorrowckCtxt<'b, 'tcx> { + fn struct_span_err_with_code>(self, + sp: S, + msg: &str, + code: DiagnosticId) + -> DiagnosticBuilder<'a> { self.tcx.sess.struct_span_err_with_code(sp, msg, code) } - fn struct_span_err<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> + fn struct_span_err>(self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'a> { self.tcx.sess.struct_span_err(sp, msg) } - fn cancel_if_wrong_origin<'a>(&'a self, - mut diag: DiagnosticBuilder<'a>, - o: Origin) - -> DiagnosticBuilder<'a> + fn cancel_if_wrong_origin(self, + mut diag: DiagnosticBuilder<'a>, + o: Origin) + -> DiagnosticBuilder<'a> { if !o.should_emit_errors(self.tcx.borrowck_mode()) { self.tcx.sess.diagnostic().cancel(&mut diag); diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs index 89242ca32bcbf..bcd7a3e7cd347 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/src/librustc_mir/util/borrowck_errors.rs @@ -52,30 +52,34 @@ impl Origin { } } -pub trait BorrowckErrors { - fn struct_span_err_with_code<'a, S: Into>(&'a self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'a>; - - fn struct_span_err<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a>; +pub trait BorrowckErrors<'cx> { + fn struct_span_err_with_code>(self, + sp: S, + msg: &str, + code: DiagnosticId) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy; + + fn struct_span_err>(self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy; /// Cancels the given error if we shouldn't emit errors for a given /// origin in the current mode. /// /// Always make sure that the error gets passed through this function /// before you return it. - fn cancel_if_wrong_origin<'a>(&'a self, - diag: DiagnosticBuilder<'a>, - o: Origin) - -> DiagnosticBuilder<'a>; - - fn cannot_move_when_borrowed(&self, span: Span, desc: &str, o: Origin) - -> DiagnosticBuilder<'_> + fn cancel_if_wrong_origin(self, + diag: DiagnosticBuilder<'cx>, + o: Origin) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy; + + fn cannot_move_when_borrowed(self, span: Span, desc: &str, o: Origin) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0505, "cannot move out of `{}` because it is borrowed{OGN}", @@ -83,13 +87,14 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_use_when_mutably_borrowed(&self, + fn cannot_use_when_mutably_borrowed(self, span: Span, desc: &str, borrow_span: Span, borrow_desc: &str, o: Origin) - -> DiagnosticBuilder<'_> + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, span, E0503, "cannot use `{}` because it was mutably borrowed{OGN}", @@ -101,12 +106,13 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_act_on_uninitialized_variable(&self, + fn cannot_act_on_uninitialized_variable(self, span: Span, verb: &str, desc: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0381, "{} of possibly uninitialized variable: `{}`{OGN}", @@ -114,7 +120,7 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_mutably_borrow_multiply(&self, + fn cannot_mutably_borrow_multiply(self, new_loan_span: Span, desc: &str, opt_via: &str, @@ -122,7 +128,8 @@ pub trait BorrowckErrors { old_opt_via: &str, old_load_end_span: Option, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, new_loan_span, E0499, "cannot borrow `{}`{} as mutable more than once at a time{OGN}", @@ -148,13 +155,14 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_uniquely_borrow_by_two_closures(&self, + fn cannot_uniquely_borrow_by_two_closures(self, new_loan_span: Span, desc: &str, old_loan_span: Span, old_load_end_span: Option, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, new_loan_span, E0524, "two closures require unique access to `{}` at the same time{OGN}", @@ -173,7 +181,7 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_uniquely_borrow_by_one_closure(&self, + fn cannot_uniquely_borrow_by_one_closure(self, new_loan_span: Span, desc_new: &str, opt_via: &str, @@ -182,7 +190,8 @@ pub trait BorrowckErrors { old_opt_via: &str, previous_end_span: Option, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, new_loan_span, E0500, "closure requires unique access to `{}` but {} is already borrowed{}{OGN}", @@ -197,7 +206,7 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_reborrow_already_uniquely_borrowed(&self, + fn cannot_reborrow_already_uniquely_borrowed(self, new_loan_span: Span, desc_new: &str, opt_via: &str, @@ -206,7 +215,8 @@ pub trait BorrowckErrors { old_opt_via: &str, previous_end_span: Option, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, new_loan_span, E0501, "cannot borrow `{}`{} as {} because previous closure \ @@ -222,7 +232,7 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_reborrow_already_borrowed(&self, + fn cannot_reborrow_already_borrowed(self, span: Span, desc_new: &str, msg_new: &str, @@ -233,7 +243,8 @@ pub trait BorrowckErrors { msg_old: &str, old_load_end_span: Option, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, span, E0502, "cannot borrow `{}`{} as {} because {} is also borrowed as {}{}{OGN}", @@ -246,8 +257,9 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_assign_to_borrowed(&self, span: Span, borrow_span: Span, desc: &str, o: Origin) - -> DiagnosticBuilder + fn cannot_assign_to_borrowed(self, span: Span, borrow_span: Span, desc: &str, o: Origin) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, span, E0506, "cannot assign to `{}` because it is borrowed{OGN}", @@ -259,8 +271,9 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_move_into_closure(&self, span: Span, desc: &str, o: Origin) - -> DiagnosticBuilder + fn cannot_move_into_closure(self, span: Span, desc: &str, o: Origin) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0504, "cannot move `{}` into closure because it is borrowed{OGN}", @@ -269,8 +282,9 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_reassign_immutable(&self, span: Span, desc: &str, is_arg: bool, o: Origin) - -> DiagnosticBuilder + fn cannot_reassign_immutable(self, span: Span, desc: &str, is_arg: bool, o: Origin) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let msg = if is_arg { "to immutable argument" @@ -284,7 +298,8 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_assign(&self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder + fn cannot_assign(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0594, "cannot assign to {}{OGN}", @@ -292,14 +307,16 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_assign_static(&self, span: Span, desc: &str, o: Origin) - -> DiagnosticBuilder + fn cannot_assign_static(self, span: Span, desc: &str, o: Origin) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { self.cannot_assign(span, &format!("immutable static item `{}`", desc), o) } - fn cannot_move_out_of(&self, move_from_span: Span, move_from_desc: &str, o: Origin) - -> DiagnosticBuilder + fn cannot_move_out_of(self, move_from_span: Span, move_from_desc: &str, o: Origin) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, move_from_span, E0507, "cannot move out of {}{OGN}", @@ -311,12 +328,13 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_move_out_of_interior_noncopy(&self, + fn cannot_move_out_of_interior_noncopy(self, move_from_span: Span, ty: ty::Ty, is_index: bool, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let type_name = match (&ty.sty, is_index) { (&ty::TyArray(_, _), true) => "array", @@ -332,11 +350,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_move_out_of_interior_of_drop(&self, + fn cannot_move_out_of_interior_of_drop(self, move_from_span: Span, container_ty: ty::Ty, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, move_from_span, E0509, "cannot move out of type `{}`, \ @@ -347,13 +366,14 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_act_on_moved_value(&self, + fn cannot_act_on_moved_value(self, use_span: Span, verb: &str, optional_adverb_for_moved: &str, moved_path: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, use_span, E0382, "{} of {}moved value: `{}`{OGN}", @@ -362,11 +382,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_partially_reinit_an_uninit_struct(&self, + fn cannot_partially_reinit_an_uninit_struct(self, span: Span, uninit_path: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, @@ -377,11 +398,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn closure_cannot_assign_to_borrowed(&self, + fn closure_cannot_assign_to_borrowed(self, span: Span, descr: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0595, "closure cannot assign to {}{OGN}", descr, OGN=o); @@ -389,11 +411,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_borrow_path_as_mutable(&self, + fn cannot_borrow_path_as_mutable(self, span: Span, path: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{OGN}", path, OGN=o); @@ -401,11 +424,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_borrow_across_generator_yield(&self, + fn cannot_borrow_across_generator_yield(self, span: Span, yield_span: Span, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, span, @@ -417,11 +441,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn path_does_not_live_long_enough(&self, + fn path_does_not_live_long_enough(self, span: Span, path: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0597, "{} does not live long enough{OGN}", path, OGN=o); @@ -429,11 +454,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn lifetime_too_short_for_reborrow(&self, + fn lifetime_too_short_for_reborrow(self, span: Span, path: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0598, "lifetime of {} is too short to guarantee \ @@ -443,12 +469,13 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_act_on_capture_in_sharable_fn(&self, + fn cannot_act_on_capture_in_sharable_fn(self, span: Span, bad_thing: &str, help: (Span, &str), o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let (help_span, help_msg) = help; let mut err = struct_span_err!(self, span, E0387, @@ -459,11 +486,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_assign_into_immutable_reference(&self, + fn cannot_assign_into_immutable_reference(self, span: Span, bad_thing: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, span, E0389, "{} in a `&` reference{OGN}", bad_thing, OGN=o); @@ -472,12 +500,13 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_capture_in_long_lived_closure(&self, + fn cannot_capture_in_long_lived_closure(self, closure_span: Span, borrowed_path: &str, capture_span: Span, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, closure_span, E0373, "closure may outlive the current function, \ @@ -491,28 +520,31 @@ pub trait BorrowckErrors { } } -impl<'b, 'gcx, 'tcx> BorrowckErrors for TyCtxt<'b, 'gcx, 'tcx> { - fn struct_span_err_with_code<'a, S: Into>(&'a self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'a> +impl<'cx, 'gcx, 'tcx> BorrowckErrors<'cx> for TyCtxt<'cx, 'gcx, 'tcx> { + fn struct_span_err_with_code>(self, + sp: S, + msg: &str, + code: DiagnosticId) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { self.sess.struct_span_err_with_code(sp, msg, code) } - fn struct_span_err<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> + fn struct_span_err>(self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { self.sess.struct_span_err(sp, msg) } - fn cancel_if_wrong_origin<'a>(&'a self, - mut diag: DiagnosticBuilder<'a>, - o: Origin) - -> DiagnosticBuilder<'a> + fn cancel_if_wrong_origin(self, + mut diag: DiagnosticBuilder<'cx>, + o: Origin) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { if !o.should_emit_errors(self.borrowck_mode()) { self.sess.diagnostic().cancel(&mut diag); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 19085ff039ec5..1ea1ff1fae24d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3096,10 +3096,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; } ty::TyRawPtr(..) => { - err.note(&format!("`{0}` is a native pointer; perhaps you need to deref \ - with `(*{0}).{1}`", - self.tcx.hir.node_to_pretty_string(base.id), - field.node)); + let base = self.tcx.hir.node_to_pretty_string(base.id); + let msg = format!("`{}` is a native pointer; try dereferencing it", base); + let suggestion = format!("(*{}).{}", base, field.node); + err.span_suggestion(field.span, &msg, suggestion); } _ => {} } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f5aa01fb03459..bd0ca0e670487 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2831,9 +2831,10 @@ impl<'a> Parser<'a> { let (span, e) = self.interpolated_or_expr_span(e)?; let span_of_tilde = lo; let mut err = self.diagnostic().struct_span_err(span_of_tilde, - "`~` can not be used as a unary operator"); - err.span_label(span_of_tilde, "did you mean `!`?"); - err.help("use `!` instead of `~` if you meant to perform bitwise negation"); + "`~` cannot be used as a unary operator"); + err.span_suggestion_short(span_of_tilde, + "use `!` to perform bitwise negation", + "!".to_owned()); err.emit(); (lo.to(span), self.mk_unary(UnOp::Not, e)) } @@ -3389,7 +3390,7 @@ impl<'a> Parser<'a> { None)?; if let Err(mut e) = self.expect(&token::OpenDelim(token::Brace)) { if self.token == token::Token::Semi { - e.span_note(match_span, "did you mean to remove this `match` keyword?"); + e.span_suggestion_short(match_span, "try removing this `match`", "".to_owned()); } return Err(e) } @@ -5361,7 +5362,9 @@ impl<'a> Parser<'a> { if is_macro_rules { let mut err = self.diagnostic() .struct_span_err(sp, "can't qualify macro_rules invocation with `pub`"); - err.help("did you mean #[macro_export]?"); + err.span_suggestion(sp, + "try exporting the macro", + "#[macro_export]".to_owned()); Err(err) } else { let mut err = self.diagnostic() diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs index 82fc09fca69af..7b23de582a79a 100644 --- a/src/libsyntax_ext/deriving/debug.rs +++ b/src/libsyntax_ext/deriving/debug.rs @@ -70,7 +70,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[derive(Debug)] +struct builder; + +fn main() { + +} + diff --git a/src/test/ui/did_you_mean/issue-41679.rs b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs similarity index 88% rename from src/test/ui/did_you_mean/issue-41679.rs rename to src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs index 98c909e212fdd..e8fd248011cb8 100644 --- a/src/test/ui/did_you_mean/issue-41679.rs +++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - let x = ~1; //~ ERROR can not be used as a unary operator + let x = ~1; //~ ERROR cannot be used as a unary operator } diff --git a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr new file mode 100644 index 0000000000000..f13f15f63771d --- /dev/null +++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr @@ -0,0 +1,8 @@ +error: `~` cannot be used as a unary operator + --> $DIR/issue-41679-tilde-bitwise-negation-attempt.rs:12:13 + | +LL | let x = ~1; //~ ERROR cannot be used as a unary operator + | ^ help: use `!` to perform bitwise negation + +error: aborting due to previous error + diff --git a/src/test/ui/did_you_mean/issue-41679.stderr b/src/test/ui/did_you_mean/issue-41679.stderr deleted file mode 100644 index c17812fc0cb9d..0000000000000 --- a/src/test/ui/did_you_mean/issue-41679.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: `~` can not be used as a unary operator - --> $DIR/issue-41679.rs:12:13 - | -LL | let x = ~1; //~ ERROR can not be used as a unary operator - | ^ did you mean `!`? - | - = help: use `!` instead of `~` if you meant to perform bitwise negation - -error: aborting due to previous error - diff --git a/src/test/parse-fail/match-refactor-to-expr.rs b/src/test/ui/did_you_mean/match-refactor-to-expr.rs similarity index 91% rename from src/test/parse-fail/match-refactor-to-expr.rs rename to src/test/ui/did_you_mean/match-refactor-to-expr.rs index e2fee1d189591..3c88608697aad 100644 --- a/src/test/parse-fail/match-refactor-to-expr.rs +++ b/src/test/ui/did_you_mean/match-refactor-to-expr.rs @@ -12,7 +12,7 @@ fn main() { let foo = - match //~ NOTE did you mean to remove this `match` keyword? + match Some(4).unwrap_or_else(5) //~^ NOTE expected one of `.`, `?`, `{`, or an operator here ; //~ NOTE unexpected token diff --git a/src/test/ui/did_you_mean/match-refactor-to-expr.stderr b/src/test/ui/did_you_mean/match-refactor-to-expr.stderr new file mode 100644 index 0000000000000..ecca781684cec --- /dev/null +++ b/src/test/ui/did_you_mean/match-refactor-to-expr.stderr @@ -0,0 +1,13 @@ +error: expected one of `.`, `?`, `{`, or an operator, found `;` + --> $DIR/match-refactor-to-expr.rs:18:9 + | +LL | match + | ----- help: try removing this `match` +LL | Some(4).unwrap_or_else(5) + | - expected one of `.`, `?`, `{`, or an operator here +LL | //~^ NOTE expected one of `.`, `?`, `{`, or an operator here +LL | ; //~ NOTE unexpected token + | ^ unexpected token + +error: aborting due to previous error + diff --git a/src/test/parse-fail/pub-macro-rules.rs b/src/test/ui/did_you_mean/pub-macro-rules.rs similarity index 91% rename from src/test/parse-fail/pub-macro-rules.rs rename to src/test/ui/did_you_mean/pub-macro-rules.rs index 93b992f2f8af2..65a0d642cd7d1 100644 --- a/src/test/parse-fail/pub-macro-rules.rs +++ b/src/test/ui/did_you_mean/pub-macro-rules.rs @@ -9,8 +9,7 @@ // except according to those terms. #[macro_use] mod bleh { - pub macro_rules! foo { //~ ERROR can't qualify macro_rules invocation with `pub` - //~^ HELP did you mean #[macro_export]? + pub macro_rules! foo { //~ ERROR can't qualify macro_rules invocation ($n:ident) => ( fn $n () -> i32 { 1 diff --git a/src/test/ui/did_you_mean/pub-macro-rules.stderr b/src/test/ui/did_you_mean/pub-macro-rules.stderr new file mode 100644 index 0000000000000..dfeab75525ba3 --- /dev/null +++ b/src/test/ui/did_you_mean/pub-macro-rules.stderr @@ -0,0 +1,8 @@ +error: can't qualify macro_rules invocation with `pub` + --> $DIR/pub-macro-rules.rs:12:5 + | +LL | pub macro_rules! foo { //~ ERROR can't qualify macro_rules invocation + | ^^^ help: try exporting the macro: `#[macro_export]` + +error: aborting due to previous error + diff --git a/src/test/ui/issue-11004.stderr b/src/test/ui/issue-11004.stderr index 4cfc7d23bd0b9..268c3cd6d2afd 100644 --- a/src/test/ui/issue-11004.stderr +++ b/src/test/ui/issue-11004.stderr @@ -2,17 +2,13 @@ error[E0609]: no field `x` on type `*mut A` --> $DIR/issue-11004.rs:17:21 | LL | let x : i32 = n.x; //~ no field `x` on type `*mut A` - | ^ - | - = note: `n` is a native pointer; perhaps you need to deref with `(*n).x` + | ^ help: `n` is a native pointer; try dereferencing it: `(*n).x` error[E0609]: no field `y` on type `*mut A` --> $DIR/issue-11004.rs:18:21 | LL | let y : f64 = n.y; //~ no field `y` on type `*mut A` - | ^ - | - = note: `n` is a native pointer; perhaps you need to deref with `(*n).y` + | ^ help: `n` is a native pointer; try dereferencing it: `(*n).y` error: aborting due to 2 previous errors diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-4.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-4.stderr deleted file mode 100644 index 19339800a7a98..0000000000000 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-4.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0623]: lifetime mismatch - --> $DIR/ex3-both-anon-regions-4.rs:12:13 - | -11 | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { - | --- --- these references are declared with different lifetimes... -12 | z.push((x,y)); - | ^ ...but data flows into `z` here - -error[E0623]: lifetime mismatch - --> $DIR/ex3-both-anon-regions-4.rs:12:15 - | -11 | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { - | --- --- these references are declared with different lifetimes... -12 | z.push((x,y)); - | ^ ...but data flows into `z` here - -error: aborting due to 2 previous errors - -If you want more information on this error, try using "rustc --explain E0623" diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr deleted file mode 100644 index 502b344c89e44..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr +++ /dev/null @@ -1,45 +0,0 @@ -warning: not reporting region error due to -Znll - --> $DIR/propagate-approximated-to-empty.rs:41:9 - | -41 | demand_y(x, y, x.get()) - | ^^^^^^^^^^^^^^^^^^^^^^^ - -error: free region `'_#6r` does not outlive free region `'_#4r` - --> $DIR/propagate-approximated-to-empty.rs:41:18 - | -41 | demand_y(x, y, x.get()) - | ^ - -note: No external requirements - --> $DIR/propagate-approximated-to-empty.rs:39:47 - | -39 | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { - | _______________________________________________^ -40 | | // Only works if 'x: 'y: -41 | | demand_y(x, y, x.get()) -42 | | //~^ WARN not reporting region error due to -Znll -43 | | //~| ERROR free region `'_#6r` does not outlive free region `'_#4r` -44 | | }); - | |_____^ - | - = note: defining type: DefId(0/1:18 ~ propagate_approximated_to_empty[317d]::supply[0]::{{closure}}[0]) with closure substs [ - i16, - for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1)) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>)) - ] - -note: No external requirements - --> $DIR/propagate-approximated-to-empty.rs:38:1 - | -38 | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { -39 | | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { -40 | | // Only works if 'x: 'y: -41 | | demand_y(x, y, x.get()) -... | -44 | | }); -45 | | } - | |_^ - | - = note: defining type: DefId(0/0:6 ~ propagate_approximated_to_empty[317d]::supply[0]) with substs [] - -error: aborting due to previous error - diff --git a/src/test/ui/resolve-error.stderr b/src/test/ui/resolve-error.stderr deleted file mode 100644 index 27f93939246c0..0000000000000 --- a/src/test/ui/resolve-error.stderr +++ /dev/null @@ -1,62 +0,0 @@ -error: cannot find derive macro `FooWithLongNan` in this scope - --> $DIR/resolve-error.rs:37:10 - | -37 | #[derive(FooWithLongNan)] - | ^^^^^^^^^^^^^^ help: try: `FooWithLongName` - -error: cannot find attribute macro `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:40:3 - | -40 | #[attr_proc_macra] - | ^^^^^^^^^^^^^^^ help: try: `attr_proc_macro` - -error: cannot find attribute macro `FooWithLongNan` in this scope - --> $DIR/resolve-error.rs:43:3 - | -43 | #[FooWithLongNan] - | ^^^^^^^^^^^^^^ - -error: cannot find derive macro `Dlone` in this scope - --> $DIR/resolve-error.rs:46:10 - | -46 | #[derive(Dlone)] - | ^^^^^ help: try: `Clone` - -error: cannot find derive macro `Dlona` in this scope - --> $DIR/resolve-error.rs:49:10 - | -49 | #[derive(Dlona)] - | ^^^^^ help: try: `Clona` - -error: cannot find derive macro `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:52:10 - | -52 | #[derive(attr_proc_macra)] - | ^^^^^^^^^^^^^^^ - -error: cannot find macro `FooWithLongNama!` in this scope - --> $DIR/resolve-error.rs:56:5 - | -56 | FooWithLongNama!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `FooWithLongNam!` - -error: cannot find macro `attr_proc_macra!` in this scope - --> $DIR/resolve-error.rs:58:5 - | -58 | attr_proc_macra!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `attr_proc_mac!` - -error: cannot find macro `Dlona!` in this scope - --> $DIR/resolve-error.rs:60:5 - | -60 | Dlona!(); - | ^^^^^ - -error: cannot find macro `bang_proc_macrp!` in this scope - --> $DIR/resolve-error.rs:62:5 - | -62 | bang_proc_macrp!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `bang_proc_macro!` - -error: aborting due to previous error(s) - diff --git a/src/test/ui/span/loan-extend.stderr b/src/test/ui/span/loan-extend.stderr deleted file mode 100644 index af498129fc440..0000000000000 --- a/src/test/ui/span/loan-extend.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0597]: `short` does not live long enough - --> $DIR/loan-extend.rs:21:1 - | -19 | long = borrow(&mut short); - | ----- borrow occurs here -20 | -21 | } - | ^ `short` dropped here while still borrowed - | - = note: values in a scope are dropped in the opposite order they are created - -error: aborting due to previous error - -If you want more information on this error, try using "rustc --explain E0597" diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index d3f571dd8aeb4..6619838cce07a 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2412,7 +2412,14 @@ impl<'test> TestCx<'test> { .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path)) .env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path)) .env("LLVM_COMPONENTS", &self.config.llvm_components) - .env("LLVM_CXXFLAGS", &self.config.llvm_cxxflags); + .env("LLVM_CXXFLAGS", &self.config.llvm_cxxflags) + + // We for sure don't want these tests to run in parallel, so make + // sure they don't have access to these vars if we we run via `make` + // at the top level + .env_remove("MAKEFLAGS") + .env_remove("MFLAGS") + .env_remove("CARGO_MAKEFLAGS"); if let Some(ref linker) = self.config.linker { cmd.env("RUSTC_LINKER", linker); diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index c927ff19b279b..06eb055f68e06 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -51,6 +51,7 @@ pub mod features; pub mod cargo; pub mod pal; pub mod deps; +pub mod ui_tests; pub mod unstable_book; fn filter_dirs(path: &Path) -> bool { diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index afa3ebd198319..2497419279560 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -45,6 +45,7 @@ fn main() { deps::check(&path, &mut bad); } deps::check_whitelist(&path, &cargo, &mut bad); + ui_tests::check(&path, &mut bad); if bad { eprintln!("some tidy checks failed"); diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs new file mode 100644 index 0000000000000..f7fec2e667ab9 --- /dev/null +++ b/src/tools/tidy/src/ui_tests.rs @@ -0,0 +1,26 @@ +// Copyright 2018 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. + +//! Tidy check to ensure that there are no stray `.stderr` files in UI test directories. + +use std::path::Path; + +pub fn check(path: &Path, bad: &mut bool) { + super::walk_many(&[&path.join("test/ui"), &path.join("test/ui-fulldeps")], + &mut |_| false, + &mut |file_path| { + if let Some(ext) = file_path.extension() { + if (ext == "stderr" || ext == "stdout") && !file_path.with_extension("rs").exists() { + println!("Stray file with UI testing output: {:?}", file_path); + *bad = true; + } + } + }); +}