diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index b5b68471b9d16..0dbe64c3ea7f7 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -981,7 +981,7 @@ fn report_trait_method_mismatch<'tcx>( .next() .unwrap_or(impl_err_span); - diag.span_suggestion( + diag.span_suggestion_verbose( span, "change the self-receiver type to match the trait", sugg, @@ -1005,12 +1005,12 @@ fn report_trait_method_mismatch<'tcx>( } hir::FnRetTy::Return(hir_ty) => { let sugg = trait_sig.output(); - diag.span_suggestion(hir_ty.span, msg, sugg, ap); + diag.span_suggestion_verbose(hir_ty.span, msg, sugg, ap); } }; }; } else if let Some(trait_ty) = trait_sig.inputs().get(*i) { - diag.span_suggestion( + diag.span_suggestion_verbose( impl_err_span, "change the parameter type to match the trait", trait_ty, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 56dff0808676b..047d0850d4ca1 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1384,7 +1384,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(format!("provide the argument{}", if plural { "s" } else { "" })) } SuggestionText::Remove(plural) => { - err.multipart_suggestion( + err.multipart_suggestion_verbose( format!("remove the extra argument{}", if plural { "s" } else { "" }), suggestions, Applicability::HasPlaceholders, diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index c8db4b97bae0d..5e0f37ed792ab 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2217,7 +2217,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("check_pat_ref: expected={:?}", expected); match *expected.kind() { ty::Ref(_, r_ty, r_mutbl) - if (new_match_ergonomics && r_mutbl >= pat_mutbl) + if (no_ref_mut_behind_and && r_mutbl >= pat_mutbl) || r_mutbl == pat_mutbl => { if no_ref_mut_behind_and && r_mutbl == Mutability::Not { diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index c5a1fca667bc3..0f82f01e57a71 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -395,6 +395,8 @@ pub mod panicking; #[unstable(feature = "core_pattern_types", issue = "none")] pub mod pat; pub mod pin; +#[unstable(feature = "new_range_api", issue = "125687")] +pub mod range; pub mod result; pub mod sync; diff --git a/library/core/src/range.rs b/library/core/src/range.rs new file mode 100644 index 0000000000000..bfbbf123b1ca5 --- /dev/null +++ b/library/core/src/range.rs @@ -0,0 +1,494 @@ +//! # Experimental replacement range types +//! +//! The types within this module are meant to replace the existing +//! `Range`, `RangeInclusive`, and `RangeFrom` types in a future edition. +//! +//! ``` +//! #![feature(new_range_api)] +//! use core::range::{Range, RangeFrom, RangeInclusive}; +//! +//! let arr = [0, 1, 2, 3, 4]; +//! assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]); +//! assert_eq!(arr[ .. 3 ], [0, 1, 2 ]); +//! assert_eq!(arr[ ..=3 ], [0, 1, 2, 3 ]); +//! assert_eq!(arr[ RangeFrom::from(1.. )], [ 1, 2, 3, 4]); +//! assert_eq!(arr[ Range::from(1..3 )], [ 1, 2 ]); +//! assert_eq!(arr[RangeInclusive::from(1..=3)], [ 1, 2, 3 ]); +//! ``` + +use crate::fmt; +use crate::hash::Hash; + +mod iter; + +#[unstable(feature = "new_range_api", issue = "125687")] +pub mod legacy; + +#[doc(inline)] +pub use crate::ops::{Bound, OneSidedRange, RangeBounds, RangeFull, RangeTo, RangeToInclusive}; + +use Bound::{Excluded, Included, Unbounded}; + +#[doc(inline)] +pub use crate::iter::Step; + +#[doc(inline)] +pub use iter::{IterRange, IterRangeFrom, IterRangeInclusive}; + +/// A (half-open) range bounded inclusively below and exclusively above +/// (`start..end` in a future edition). +/// +/// The range `start..end` contains all values with `start <= x < end`. +/// It is empty if `start >= end`. +/// +/// # Examples +/// +/// ``` +/// #![feature(new_range_api)] +/// use core::range::Range; +/// +/// assert_eq!(Range::from(3..5), Range { start: 3, end: 5 }); +/// assert_eq!(3 + 4 + 5, Range::from(3..6).into_iter().sum()); +/// ``` +#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)] +#[unstable(feature = "new_range_api", issue = "125687")] +pub struct Range { + /// The lower bound of the range (inclusive). + #[unstable(feature = "new_range_api", issue = "125687")] + pub start: Idx, + /// The upper bound of the range (exclusive). + #[unstable(feature = "new_range_api", issue = "125687")] + pub end: Idx, +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl fmt::Debug for Range { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + self.start.fmt(fmt)?; + write!(fmt, "..")?; + self.end.fmt(fmt)?; + Ok(()) + } +} + +impl Range { + /// Create an iterator over the elements within this range. + /// + /// Shorthand for `.clone().into_iter()` + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::Range; + /// + /// let mut i = Range::from(3..9).iter().map(|n| n*n); + /// assert_eq!(i.next(), Some(9)); + /// assert_eq!(i.next(), Some(16)); + /// assert_eq!(i.next(), Some(25)); + /// ``` + #[unstable(feature = "new_range_api", issue = "125687")] + #[inline] + pub fn iter(&self) -> IterRange { + self.clone().into_iter() + } +} + +impl> Range { + /// Returns `true` if `item` is contained in the range. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::Range; + /// + /// assert!(!Range::from(3..5).contains(&2)); + /// assert!( Range::from(3..5).contains(&3)); + /// assert!( Range::from(3..5).contains(&4)); + /// assert!(!Range::from(3..5).contains(&5)); + /// + /// assert!(!Range::from(3..3).contains(&3)); + /// assert!(!Range::from(3..2).contains(&3)); + /// + /// assert!( Range::from(0.0..1.0).contains(&0.5)); + /// assert!(!Range::from(0.0..1.0).contains(&f32::NAN)); + /// assert!(!Range::from(0.0..f32::NAN).contains(&0.5)); + /// assert!(!Range::from(f32::NAN..1.0).contains(&0.5)); + /// ``` + #[inline] + #[unstable(feature = "new_range_api", issue = "125687")] + pub fn contains(&self, item: &U) -> bool + where + Idx: PartialOrd, + U: ?Sized + PartialOrd, + { + >::contains(self, item) + } + + /// Returns `true` if the range contains no items. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::Range; + /// + /// assert!(!Range::from(3..5).is_empty()); + /// assert!( Range::from(3..3).is_empty()); + /// assert!( Range::from(3..2).is_empty()); + /// ``` + /// + /// The range is empty if either side is incomparable: + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::Range; + /// + /// assert!(!Range::from(3.0..5.0).is_empty()); + /// assert!( Range::from(3.0..f32::NAN).is_empty()); + /// assert!( Range::from(f32::NAN..5.0).is_empty()); + /// ``` + #[inline] + #[unstable(feature = "new_range_api", issue = "125687")] + pub fn is_empty(&self) -> bool { + !(self.start < self.end) + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl RangeBounds for Range { + fn start_bound(&self) -> Bound<&T> { + Included(&self.start) + } + fn end_bound(&self) -> Bound<&T> { + Excluded(&self.end) + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl RangeBounds for Range<&T> { + fn start_bound(&self) -> Bound<&T> { + Included(self.start) + } + fn end_bound(&self) -> Bound<&T> { + Excluded(self.end) + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl From> for legacy::Range { + #[inline] + fn from(value: Range) -> Self { + Self { start: value.start, end: value.end } + } +} +#[unstable(feature = "new_range_api", issue = "125687")] +impl From> for Range { + #[inline] + fn from(value: legacy::Range) -> Self { + Self { start: value.start, end: value.end } + } +} + +/// A range bounded inclusively below and above (`start..=end`). +/// +/// The `RangeInclusive` `start..=end` contains all values with `x >= start` +/// and `x <= end`. It is empty unless `start <= end`. +/// +/// # Examples +/// +/// The `start..=end` syntax is a `RangeInclusive`: +/// +/// ``` +/// #![feature(new_range_api)] +/// use core::range::RangeInclusive; +/// +/// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, end: 5 }); +/// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum()); +/// ``` +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +#[unstable(feature = "new_range_api", issue = "125687")] +pub struct RangeInclusive { + /// The lower bound of the range (inclusive). + #[unstable(feature = "new_range_api", issue = "125687")] + pub start: Idx, + /// The upper bound of the range (inclusive). + #[unstable(feature = "new_range_api", issue = "125687")] + pub end: Idx, +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl fmt::Debug for RangeInclusive { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + self.start.fmt(fmt)?; + write!(fmt, "..=")?; + self.end.fmt(fmt)?; + Ok(()) + } +} + +impl> RangeInclusive { + /// Returns `true` if `item` is contained in the range. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::RangeInclusive; + /// + /// assert!(!RangeInclusive::from(3..=5).contains(&2)); + /// assert!( RangeInclusive::from(3..=5).contains(&3)); + /// assert!( RangeInclusive::from(3..=5).contains(&4)); + /// assert!( RangeInclusive::from(3..=5).contains(&5)); + /// assert!(!RangeInclusive::from(3..=5).contains(&6)); + /// + /// assert!( RangeInclusive::from(3..=3).contains(&3)); + /// assert!(!RangeInclusive::from(3..=2).contains(&3)); + /// + /// assert!( RangeInclusive::from(0.0..=1.0).contains(&1.0)); + /// assert!(!RangeInclusive::from(0.0..=1.0).contains(&f32::NAN)); + /// assert!(!RangeInclusive::from(0.0..=f32::NAN).contains(&0.0)); + /// assert!(!RangeInclusive::from(f32::NAN..=1.0).contains(&1.0)); + /// ``` + #[inline] + #[unstable(feature = "new_range_api", issue = "125687")] + pub fn contains(&self, item: &U) -> bool + where + Idx: PartialOrd, + U: ?Sized + PartialOrd, + { + >::contains(self, item) + } + + /// Returns `true` if the range contains no items. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::RangeInclusive; + /// + /// assert!(!RangeInclusive::from(3..=5).is_empty()); + /// assert!(!RangeInclusive::from(3..=3).is_empty()); + /// assert!( RangeInclusive::from(3..=2).is_empty()); + /// ``` + /// + /// The range is empty if either side is incomparable: + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::RangeInclusive; + /// + /// assert!(!RangeInclusive::from(3.0..=5.0).is_empty()); + /// assert!( RangeInclusive::from(3.0..=f32::NAN).is_empty()); + /// assert!( RangeInclusive::from(f32::NAN..=5.0).is_empty()); + /// ``` + #[unstable(feature = "new_range_api", issue = "125687")] + #[inline] + pub fn is_empty(&self) -> bool { + !(self.start <= self.end) + } +} + +impl RangeInclusive { + /// Create an iterator over the elements within this range. + /// + /// Shorthand for `.clone().into_iter()` + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::RangeInclusive; + /// + /// let mut i = RangeInclusive::from(3..=8).iter().map(|n| n*n); + /// assert_eq!(i.next(), Some(9)); + /// assert_eq!(i.next(), Some(16)); + /// assert_eq!(i.next(), Some(25)); + /// ``` + #[unstable(feature = "new_range_api", issue = "125687")] + #[inline] + pub fn iter(&self) -> IterRangeInclusive { + self.clone().into_iter() + } +} + +impl RangeInclusive { + /// Converts to an exclusive `Range` for `SliceIndex` implementations. + /// The caller is responsible for dealing with `end == usize::MAX`. + #[inline] + pub(crate) const fn into_slice_range(self) -> Range { + Range { start: self.start, end: self.end + 1 } + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl RangeBounds for RangeInclusive { + fn start_bound(&self) -> Bound<&T> { + Included(&self.start) + } + fn end_bound(&self) -> Bound<&T> { + Included(&self.end) + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl RangeBounds for RangeInclusive<&T> { + fn start_bound(&self) -> Bound<&T> { + Included(self.start) + } + fn end_bound(&self) -> Bound<&T> { + Included(self.end) + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl From> for legacy::RangeInclusive { + #[inline] + fn from(value: RangeInclusive) -> Self { + Self::new(value.start, value.end) + } +} +#[unstable(feature = "new_range_api", issue = "125687")] +impl From> for RangeInclusive { + #[inline] + fn from(value: legacy::RangeInclusive) -> Self { + assert!( + !value.exhausted, + "attempted to convert from an exhausted `legacy::RangeInclusive` (unspecified behavior)" + ); + + let (start, end) = value.into_inner(); + RangeInclusive { start, end } + } +} + +/// A range only bounded inclusively below (`start..`). +/// +/// The `RangeFrom` `start..` contains all values with `x >= start`. +/// +/// *Note*: Overflow in the [`Iterator`] implementation (when the contained +/// data type reaches its numerical limit) is allowed to panic, wrap, or +/// saturate. This behavior is defined by the implementation of the [`Step`] +/// trait. For primitive integers, this follows the normal rules, and respects +/// the overflow checks profile (panic in debug, wrap in release). Note also +/// that overflow happens earlier than you might assume: the overflow happens +/// in the call to `next` that yields the maximum value, as the range must be +/// set to a state to yield the next value. +/// +/// [`Step`]: crate::iter::Step +/// +/// # Examples +/// +/// The `start..` syntax is a `RangeFrom`: +/// +/// ``` +/// #![feature(new_range_api)] +/// use core::range::RangeFrom; +/// +/// assert_eq!(RangeFrom::from(2..), core::range::RangeFrom { start: 2 }); +/// assert_eq!(2 + 3 + 4, RangeFrom::from(2..).into_iter().take(3).sum()); +/// ``` +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +#[unstable(feature = "new_range_api", issue = "125687")] +pub struct RangeFrom { + /// The lower bound of the range (inclusive). + #[unstable(feature = "new_range_api", issue = "125687")] + pub start: Idx, +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl fmt::Debug for RangeFrom { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + self.start.fmt(fmt)?; + write!(fmt, "..")?; + Ok(()) + } +} + +impl RangeFrom { + /// Create an iterator over the elements within this range. + /// + /// Shorthand for `.clone().into_iter()` + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::RangeFrom; + /// + /// let mut i = RangeFrom::from(3..).iter().map(|n| n*n); + /// assert_eq!(i.next(), Some(9)); + /// assert_eq!(i.next(), Some(16)); + /// assert_eq!(i.next(), Some(25)); + /// ``` + #[unstable(feature = "new_range_api", issue = "125687")] + #[inline] + pub fn iter(&self) -> IterRangeFrom { + self.clone().into_iter() + } +} + +impl> RangeFrom { + /// Returns `true` if `item` is contained in the range. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::RangeFrom; + /// + /// assert!(!RangeFrom::from(3..).contains(&2)); + /// assert!( RangeFrom::from(3..).contains(&3)); + /// assert!( RangeFrom::from(3..).contains(&1_000_000_000)); + /// + /// assert!( RangeFrom::from(0.0..).contains(&0.5)); + /// assert!(!RangeFrom::from(0.0..).contains(&f32::NAN)); + /// assert!(!RangeFrom::from(f32::NAN..).contains(&0.5)); + /// ``` + #[inline] + #[unstable(feature = "new_range_api", issue = "125687")] + pub fn contains(&self, item: &U) -> bool + where + Idx: PartialOrd, + U: ?Sized + PartialOrd, + { + >::contains(self, item) + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl RangeBounds for RangeFrom { + fn start_bound(&self) -> Bound<&T> { + Included(&self.start) + } + fn end_bound(&self) -> Bound<&T> { + Unbounded + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl RangeBounds for RangeFrom<&T> { + fn start_bound(&self) -> Bound<&T> { + Included(self.start) + } + fn end_bound(&self) -> Bound<&T> { + Unbounded + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl From> for legacy::RangeFrom { + #[inline] + fn from(value: RangeFrom) -> Self { + Self { start: value.start } + } +} +#[unstable(feature = "new_range_api", issue = "125687")] +impl From> for RangeFrom { + #[inline] + fn from(value: legacy::RangeFrom) -> Self { + Self { start: value.start } + } +} diff --git a/library/core/src/range/iter.rs b/library/core/src/range/iter.rs new file mode 100644 index 0000000000000..2b7db475ffb2c --- /dev/null +++ b/library/core/src/range/iter.rs @@ -0,0 +1,340 @@ +use crate::num::NonZero; +use crate::range::{legacy, Range, RangeFrom, RangeInclusive}; + +use crate::iter::{ + FusedIterator, Step, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, TrustedStep, +}; + +/// By-value [`Range`] iterator. +#[unstable(feature = "new_range_api", issue = "125687")] +#[derive(Debug, Clone)] +pub struct IterRange(legacy::Range); + +impl IterRange { + /// Returns the remainder of the range being iterated over. + pub fn remainder(self) -> Range { + Range { start: self.0.start, end: self.0.end } + } +} + +/// Safety: This macro must only be used on types that are `Copy` and result in ranges +/// which have an exact `size_hint()` where the upper bound must not be `None`. +macro_rules! unsafe_range_trusted_random_access_impl { + ($($t:ty)*) => ($( + #[doc(hidden)] + #[unstable(feature = "trusted_random_access", issue = "none")] + unsafe impl TrustedRandomAccess for IterRange<$t> {} + + #[doc(hidden)] + #[unstable(feature = "trusted_random_access", issue = "none")] + unsafe impl TrustedRandomAccessNoCoerce for IterRange<$t> { + const MAY_HAVE_SIDE_EFFECT: bool = false; + } + )*) +} + +unsafe_range_trusted_random_access_impl! { + usize u8 u16 + isize i8 i16 +} + +#[cfg(target_pointer_width = "32")] +unsafe_range_trusted_random_access_impl! { + u32 i32 +} + +#[cfg(target_pointer_width = "64")] +unsafe_range_trusted_random_access_impl! { + u32 i32 + u64 i64 +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl Iterator for IterRange { + type Item = A; + + #[inline] + fn next(&mut self) -> Option { + self.0.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } + + #[inline] + fn count(self) -> usize { + self.0.count() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + self.0.nth(n) + } + + #[inline] + fn last(self) -> Option { + self.0.last() + } + + #[inline] + fn min(self) -> Option + where + A: Ord, + { + self.0.min() + } + + #[inline] + fn max(self) -> Option + where + A: Ord, + { + self.0.max() + } + + #[inline] + fn is_sorted(self) -> bool { + true + } + + #[inline] + fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { + self.0.advance_by(n) + } + + #[inline] + unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item + where + Self: TrustedRandomAccessNoCoerce, + { + // SAFETY: The TrustedRandomAccess contract requires that callers only pass an index + // that is in bounds. + // Additionally Self: TrustedRandomAccess is only implemented for Copy types + // which means even repeated reads of the same index would be safe. + unsafe { Step::forward_unchecked(self.0.start.clone(), idx) } + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl DoubleEndedIterator for IterRange { + #[inline] + fn next_back(&mut self) -> Option { + self.0.next_back() + } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option { + self.0.nth_back(n) + } + + #[inline] + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { + self.0.advance_back_by(n) + } +} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for IterRange {} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl FusedIterator for IterRange {} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl IntoIterator for Range { + type Item = A; + type IntoIter = IterRange; + + fn into_iter(self) -> Self::IntoIter { + IterRange(self.into()) + } +} + +/// By-value [`RangeInclusive`] iterator. +#[unstable(feature = "new_range_api", issue = "125687")] +#[derive(Debug, Clone)] +pub struct IterRangeInclusive(legacy::RangeInclusive); + +impl IterRangeInclusive { + /// Returns the remainder of the range being iterated over. + /// + /// If the iterator is exhausted or empty, returns `None`. + pub fn remainder(self) -> Option> { + if self.0.is_empty() { + return None; + } + + Some(RangeInclusive { start: self.0.start, end: self.0.end }) + } +} + +#[unstable(feature = "trusted_random_access", issue = "none")] +impl Iterator for IterRangeInclusive { + type Item = A; + + #[inline] + fn next(&mut self) -> Option { + self.0.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } + + #[inline] + fn count(self) -> usize { + self.0.count() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + self.0.nth(n) + } + + #[inline] + fn last(self) -> Option { + self.0.last() + } + + #[inline] + fn min(self) -> Option + where + A: Ord, + { + self.0.min() + } + + #[inline] + fn max(self) -> Option + where + A: Ord, + { + self.0.max() + } + + #[inline] + fn is_sorted(self) -> bool { + true + } + + #[inline] + fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { + self.0.advance_by(n) + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl DoubleEndedIterator for IterRangeInclusive { + #[inline] + fn next_back(&mut self) -> Option { + self.0.next_back() + } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option { + self.0.nth_back(n) + } + + #[inline] + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { + self.0.advance_back_by(n) + } +} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for IterRangeInclusive {} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl FusedIterator for IterRangeInclusive {} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl IntoIterator for RangeInclusive { + type Item = A; + type IntoIter = IterRangeInclusive; + + fn into_iter(self) -> Self::IntoIter { + IterRangeInclusive(self.into()) + } +} + +// These macros generate `ExactSizeIterator` impls for various range types. +// +// * `ExactSizeIterator::len` is required to always return an exact `usize`, +// so no range can be longer than `usize::MAX`. +// * For integer types in `Range<_>` this is the case for types narrower than or as wide as `usize`. +// For integer types in `RangeInclusive<_>` +// this is the case for types *strictly narrower* than `usize` +// since e.g. `(0..=u64::MAX).len()` would be `u64::MAX + 1`. +macro_rules! range_exact_iter_impl { + ($($t:ty)*) => ($( + #[unstable(feature = "new_range_api", issue = "125687")] + impl ExactSizeIterator for IterRange<$t> { } + )*) +} + +macro_rules! range_incl_exact_iter_impl { + ($($t:ty)*) => ($( + #[unstable(feature = "new_range_api", issue = "125687")] + impl ExactSizeIterator for IterRangeInclusive<$t> { } + )*) +} + +range_exact_iter_impl! { + usize u8 u16 + isize i8 i16 +} + +range_incl_exact_iter_impl! { + u8 + i8 +} + +/// By-value [`RangeFrom`] iterator. +#[unstable(feature = "new_range_api", issue = "125687")] +#[derive(Debug, Clone)] +pub struct IterRangeFrom(legacy::RangeFrom); + +impl IterRangeFrom { + /// Returns the remainder of the range being iterated over. + pub fn remainder(self) -> RangeFrom { + RangeFrom { start: self.0.start } + } +} + +#[unstable(feature = "trusted_random_access", issue = "none")] +impl Iterator for IterRangeFrom { + type Item = A; + + #[inline] + fn next(&mut self) -> Option { + self.0.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + self.0.nth(n) + } +} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for IterRangeFrom {} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl FusedIterator for IterRangeFrom {} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl IntoIterator for RangeFrom { + type Item = A; + type IntoIter = IterRangeFrom; + + fn into_iter(self) -> Self::IntoIter { + IterRangeFrom(self.into()) + } +} diff --git a/library/core/src/range/legacy.rs b/library/core/src/range/legacy.rs new file mode 100644 index 0000000000000..6723c4903f756 --- /dev/null +++ b/library/core/src/range/legacy.rs @@ -0,0 +1,10 @@ +//! # Legacy range types +//! +//! The types within this module will be replaced by the types +//! [`Range`], [`RangeInclusive`], and [`RangeFrom`] in the parent +//! module, [`core::range`]. +//! +//! The types here are equivalent to those in [`core::ops`]. + +#[doc(inline)] +pub use crate::ops::{Range, RangeFrom, RangeInclusive}; diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 143dbd8a496d0..2624a44bb4bcb 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -2,6 +2,7 @@ use crate::intrinsics::const_eval_select; use crate::ops; +use crate::range; use crate::ub_checks::assert_unsafe_precondition; #[stable(feature = "rust1", since = "1.0.0")] @@ -147,7 +148,8 @@ const unsafe fn get_offset_len_mut_noubcheck( } mod private_slice_index { - use super::ops; + use super::{ops, range}; + #[stable(feature = "slice_get_slice", since = "1.28.0")] pub trait Sealed {} @@ -168,6 +170,13 @@ mod private_slice_index { #[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")] impl Sealed for (ops::Bound, ops::Bound) {} + #[unstable(feature = "new_range_api", issue = "125687")] + impl Sealed for range::Range {} + #[unstable(feature = "new_range_api", issue = "125687")] + impl Sealed for range::RangeInclusive {} + #[unstable(feature = "new_range_api", issue = "125687")] + impl Sealed for range::RangeFrom {} + impl Sealed for ops::IndexRange {} } @@ -473,6 +482,43 @@ unsafe impl SliceIndex<[T]> for ops::Range { } } +#[unstable(feature = "new_range_api", issue = "125687")] +unsafe impl SliceIndex<[T]> for range::Range { + type Output = [T]; + + #[inline] + fn get(self, slice: &[T]) -> Option<&[T]> { + ops::Range::from(self).get(slice) + } + + #[inline] + fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { + ops::Range::from(self).get_mut(slice) + } + + #[inline] + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. + unsafe { ops::Range::from(self).get_unchecked(slice) } + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. + unsafe { ops::Range::from(self).get_unchecked_mut(slice) } + } + + #[inline(always)] + fn index(self, slice: &[T]) -> &[T] { + ops::Range::from(self).index(slice) + } + + #[inline] + fn index_mut(self, slice: &mut [T]) -> &mut [T] { + ops::Range::from(self).index_mut(slice) + } +} + /// The methods `index` and `index_mut` panic if the end of the range is out of bounds. #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] @@ -559,6 +605,43 @@ unsafe impl SliceIndex<[T]> for ops::RangeFrom { } } +#[unstable(feature = "new_range_api", issue = "125687")] +unsafe impl SliceIndex<[T]> for range::RangeFrom { + type Output = [T]; + + #[inline] + fn get(self, slice: &[T]) -> Option<&[T]> { + ops::RangeFrom::from(self).get(slice) + } + + #[inline] + fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { + ops::RangeFrom::from(self).get_mut(slice) + } + + #[inline] + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. + unsafe { ops::RangeFrom::from(self).get_unchecked(slice) } + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. + unsafe { ops::RangeFrom::from(self).get_unchecked_mut(slice) } + } + + #[inline] + fn index(self, slice: &[T]) -> &[T] { + ops::RangeFrom::from(self).index(slice) + } + + #[inline] + fn index_mut(self, slice: &mut [T]) -> &mut [T] { + ops::RangeFrom::from(self).index_mut(slice) + } +} + #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] unsafe impl SliceIndex<[T]> for ops::RangeFull { @@ -643,6 +726,43 @@ unsafe impl SliceIndex<[T]> for ops::RangeInclusive { } } +#[unstable(feature = "new_range_api", issue = "125687")] +unsafe impl SliceIndex<[T]> for range::RangeInclusive { + type Output = [T]; + + #[inline] + fn get(self, slice: &[T]) -> Option<&[T]> { + ops::RangeInclusive::from(self).get(slice) + } + + #[inline] + fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { + ops::RangeInclusive::from(self).get_mut(slice) + } + + #[inline] + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. + unsafe { ops::RangeInclusive::from(self).get_unchecked(slice) } + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. + unsafe { ops::RangeInclusive::from(self).get_unchecked_mut(slice) } + } + + #[inline] + fn index(self, slice: &[T]) -> &[T] { + ops::RangeInclusive::from(self).index(slice) + } + + #[inline] + fn index_mut(self, slice: &mut [T]) -> &mut [T] { + ops::RangeInclusive::from(self).index_mut(slice) + } +} + /// The methods `index` and `index_mut` panic if the end of the range is out of bounds. #[stable(feature = "inclusive_range", since = "1.26.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] @@ -780,7 +900,7 @@ where /// Performs bounds-checking of a range without panicking. /// -/// This is a version of [`range`] that returns [`None`] instead of panicking. +/// This is a version of [`range()`] that returns [`None`] instead of panicking. /// /// # Examples /// diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index ba2d6f644962e..3de5546c4d4e3 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -4,6 +4,7 @@ use crate::cmp::Ordering; use crate::intrinsics::unchecked_sub; use crate::ops; use crate::ptr; +use crate::range; use crate::slice::SliceIndex; use crate::ub_checks::assert_unsafe_precondition; @@ -261,6 +262,108 @@ unsafe impl SliceIndex for ops::Range { } } +#[unstable(feature = "new_range_api", issue = "125687")] +unsafe impl SliceIndex for range::Range { + type Output = str; + #[inline] + fn get(self, slice: &str) -> Option<&Self::Output> { + if self.start <= self.end + && slice.is_char_boundary(self.start) + && slice.is_char_boundary(self.end) + { + // SAFETY: just checked that `start` and `end` are on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + // We also checked char boundaries, so this is valid UTF-8. + Some(unsafe { &*self.get_unchecked(slice) }) + } else { + None + } + } + #[inline] + fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { + if self.start <= self.end + && slice.is_char_boundary(self.start) + && slice.is_char_boundary(self.end) + { + // SAFETY: just checked that `start` and `end` are on a char boundary. + // We know the pointer is unique because we got it from `slice`. + Some(unsafe { &mut *self.get_unchecked_mut(slice) }) + } else { + None + } + } + #[inline] + unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { + let slice = slice as *const [u8]; + + assert_unsafe_precondition!( + // We'd like to check that the bounds are on char boundaries, + // but there's not really a way to do so without reading + // behind the pointer, which has aliasing implications. + // It's also not possible to move this check up to + // `str::get_unchecked` without adding a special function + // to `SliceIndex` just for this. + check_library_ub, + "str::get_unchecked requires that the range is within the string slice", + ( + start: usize = self.start, + end: usize = self.end, + len: usize = slice.len() + ) => end >= start && end <= len, + ); + + // SAFETY: the caller guarantees that `self` is in bounds of `slice` + // which satisfies all the conditions for `add`. + unsafe { + let new_len = unchecked_sub(self.end, self.start); + ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) as *const str + } + } + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { + let slice = slice as *mut [u8]; + + assert_unsafe_precondition!( + check_library_ub, + "str::get_unchecked_mut requires that the range is within the string slice", + ( + start: usize = self.start, + end: usize = self.end, + len: usize = slice.len() + ) => end >= start && end <= len, + ); + + // SAFETY: see comments for `get_unchecked`. + unsafe { + let new_len = unchecked_sub(self.end, self.start); + ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len) as *mut str + } + } + #[inline] + fn index(self, slice: &str) -> &Self::Output { + let (start, end) = (self.start, self.end); + match self.get(slice) { + Some(s) => s, + None => super::slice_error_fail(slice, start, end), + } + } + #[inline] + fn index_mut(self, slice: &mut str) -> &mut Self::Output { + // is_char_boundary checks that the index is in [0, .len()] + // cannot reuse `get` as above, because of NLL trouble + if self.start <= self.end + && slice.is_char_boundary(self.start) + && slice.is_char_boundary(self.end) + { + // SAFETY: just checked that `start` and `end` are on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + unsafe { &mut *self.get_unchecked_mut(slice) } + } else { + super::slice_error_fail(slice, self.start, self.end) + } + } +} + /// Implements substring slicing for arbitrary bounds. /// /// Returns a slice of the given string bounded by the byte indices @@ -453,6 +556,61 @@ unsafe impl SliceIndex for ops::RangeFrom { } } +#[unstable(feature = "new_range_api", issue = "125687")] +unsafe impl SliceIndex for range::RangeFrom { + type Output = str; + #[inline] + fn get(self, slice: &str) -> Option<&Self::Output> { + if slice.is_char_boundary(self.start) { + // SAFETY: just checked that `start` is on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + Some(unsafe { &*self.get_unchecked(slice) }) + } else { + None + } + } + #[inline] + fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { + if slice.is_char_boundary(self.start) { + // SAFETY: just checked that `start` is on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + Some(unsafe { &mut *self.get_unchecked_mut(slice) }) + } else { + None + } + } + #[inline] + unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { + let len = (slice as *const [u8]).len(); + // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. + unsafe { (self.start..len).get_unchecked(slice) } + } + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { + let len = (slice as *mut [u8]).len(); + // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. + unsafe { (self.start..len).get_unchecked_mut(slice) } + } + #[inline] + fn index(self, slice: &str) -> &Self::Output { + let (start, end) = (self.start, slice.len()); + match self.get(slice) { + Some(s) => s, + None => super::slice_error_fail(slice, start, end), + } + } + #[inline] + fn index_mut(self, slice: &mut str) -> &mut Self::Output { + if slice.is_char_boundary(self.start) { + // SAFETY: just checked that `start` is on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + unsafe { &mut *self.get_unchecked_mut(slice) } + } else { + super::slice_error_fail(slice, self.start, slice.len()) + } + } +} + /// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut /// self[begin ..= end]`. /// @@ -507,6 +665,43 @@ unsafe impl SliceIndex for ops::RangeInclusive { } } +#[unstable(feature = "new_range_api", issue = "125687")] +unsafe impl SliceIndex for range::RangeInclusive { + type Output = str; + #[inline] + fn get(self, slice: &str) -> Option<&Self::Output> { + if self.end == usize::MAX { None } else { self.into_slice_range().get(slice) } + } + #[inline] + fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { + if self.end == usize::MAX { None } else { self.into_slice_range().get_mut(slice) } + } + #[inline] + unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { + // SAFETY: the caller must uphold the safety contract for `get_unchecked`. + unsafe { self.into_slice_range().get_unchecked(slice) } + } + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { + // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`. + unsafe { self.into_slice_range().get_unchecked_mut(slice) } + } + #[inline] + fn index(self, slice: &str) -> &Self::Output { + if self.end == usize::MAX { + str_index_overflow_fail(); + } + self.into_slice_range().index(slice) + } + #[inline] + fn index_mut(self, slice: &mut str) -> &mut Self::Output { + if self.end == usize::MAX { + str_index_overflow_fail(); + } + self.into_slice_range().index_mut(slice) + } +} + /// Implements substring slicing with syntax `&self[..= end]` or `&mut /// self[..= end]`. /// diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 7321bd1bb52f2..72ae3ed26e89f 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -59,6 +59,8 @@ const INTRA_DOC_LINK_EXCEPTIONS: &[(&str, &[&str])] = &[ // This is being used in the sense of 'inclusive range', not a markdown link ("core/ops/struct.RangeInclusive.html", &["begin, end"]), ("std/ops/struct.RangeInclusive.html", &["begin, end"]), + ("core/range/legacy/struct.RangeInclusive.html", &["begin, end"]), + ("std/range/legacy/struct.RangeInclusive.html", &["begin, end"]), ("core/slice/trait.SliceIndex.html", &["begin, end"]), ("alloc/slice/trait.SliceIndex.html", &["begin, end"]), ("std/slice/trait.SliceIndex.html", &["begin, end"]), diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index af5ae6a8e608c..7bb89106de1b9 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -266,14 +266,14 @@ pub fn test_while_readonly, F: FnOnce() + std::panic::UnwindSafe> #[track_caller] pub fn shallow_find_files, F: Fn(&PathBuf) -> bool>( path: P, - closure: F, + filter: F, ) -> Vec { let mut matching_files = Vec::new(); for entry in fs_wrapper::read_dir(path) { let entry = entry.expect("failed to read directory entry."); let path = entry.path(); - if path.is_file() && closure(&path) { + if path.is_file() && filter(&path) { matching_files.push(path); } } @@ -295,6 +295,13 @@ pub fn not_contains>(path: P, expected: &str) -> bool { !path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected)) } +/// Returns true if the filename at `path` is not in `expected`. +pub fn filename_not_in_denylist>(path: P, expected: &[String]) -> bool { + path.as_ref() + .file_name() + .is_some_and(|name| !expected.contains(&name.to_str().unwrap().to_owned())) +} + /// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is /// available on the platform! #[track_caller] diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 0cb3275d7e934..ff98bd538db1f 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -100,7 +100,6 @@ run-make/no-alloc-shim/Makefile run-make/no-builtins-attribute/Makefile run-make/no-duplicate-libs/Makefile run-make/obey-crate-type-flag/Makefile -run-make/output-type-permutations/Makefile run-make/panic-abort-eh_frame/Makefile run-make/pass-linker-flags-flavor/Makefile run-make/pass-linker-flags-from-dep/Makefile diff --git a/tests/run-make/output-type-permutations/Makefile b/tests/run-make/output-type-permutations/Makefile deleted file mode 100644 index 035033b9fddd3..0000000000000 --- a/tests/run-make/output-type-permutations/Makefile +++ /dev/null @@ -1,147 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) foo.rs --crate-type=rlib,dylib,staticlib - $(call REMOVE_RLIBS,bar) - $(call REMOVE_DYLIBS,bar) - rm $(call STATICLIB,bar) - rm -f $(TMPDIR)/{lib,}bar.{dll.exp,dll.lib,pdb,dll.a} - # Check that $(TMPDIR) is empty. - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --crate-type=bin - rm $(TMPDIR)/$(call BIN,bar) - rm -f $(TMPDIR)/bar.pdb - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit=asm,llvm-ir,llvm-bc,obj,link - rm $(TMPDIR)/bar.ll - rm $(TMPDIR)/bar.bc - rm $(TMPDIR)/bar.s - rm $(TMPDIR)/bar.o - rm $(TMPDIR)/$(call BIN,bar) - rm -f $(TMPDIR)/bar.pdb - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit asm -o $(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit asm=$(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit=asm=$(TMPDIR)/foo - rm $(TMPDIR)/foo - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit llvm-bc -o $(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit llvm-bc=$(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit=llvm-bc=$(TMPDIR)/foo - rm $(TMPDIR)/foo - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit llvm-ir -o $(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit llvm-ir=$(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit=llvm-ir=$(TMPDIR)/foo - rm $(TMPDIR)/foo - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit obj -o $(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit obj=$(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit=obj=$(TMPDIR)/foo - rm $(TMPDIR)/foo - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit link -o $(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - $(RUSTC) foo.rs --emit link=$(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - $(RUSTC) foo.rs --emit=link=$(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - rm -f $(TMPDIR)/foo.pdb - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --crate-type=rlib -o $(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --crate-type=rlib --emit link=$(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --crate-type=rlib --emit=link=$(TMPDIR)/foo - rm $(TMPDIR)/foo - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --crate-type=dylib -o $(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - $(RUSTC) foo.rs --crate-type=dylib --emit link=$(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - $(RUSTC) foo.rs --crate-type=dylib --emit=link=$(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - rm -f $(TMPDIR)/{lib,}foo.{dll.exp,dll.lib,pdb,dll.a,exe.a} - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] || (ls -1 $(TMPDIR) && exit 1) - - $(RUSTC) foo.rs --crate-type=staticlib -o $(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --crate-type=staticlib --emit link=$(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --crate-type=staticlib --emit=link=$(TMPDIR)/foo - rm $(TMPDIR)/foo - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --crate-type=bin -o $(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - $(RUSTC) foo.rs --crate-type=bin --emit link=$(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - $(RUSTC) foo.rs --crate-type=bin --emit=link=$(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - rm -f $(TMPDIR)/foo.pdb - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit llvm-ir=$(TMPDIR)/ir \ - --emit link \ - --crate-type=rlib - rm $(TMPDIR)/ir - rm $(TMPDIR)/libbar.rlib - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit asm=$(TMPDIR)/asm \ - --emit llvm-ir=$(TMPDIR)/ir \ - --emit llvm-bc=$(TMPDIR)/bc \ - --emit obj=$(TMPDIR)/obj \ - --emit link=$(TMPDIR)/link \ - --crate-type=staticlib - rm $(TMPDIR)/asm - rm $(TMPDIR)/ir - rm $(TMPDIR)/bc - rm $(TMPDIR)/obj - rm $(TMPDIR)/link - $(RUSTC) foo.rs --emit=asm=$(TMPDIR)/asm \ - --emit llvm-ir=$(TMPDIR)/ir \ - --emit=llvm-bc=$(TMPDIR)/bc \ - --emit obj=$(TMPDIR)/obj \ - --emit=link=$(TMPDIR)/link \ - --crate-type=staticlib - rm $(TMPDIR)/asm - rm $(TMPDIR)/ir - rm $(TMPDIR)/bc - rm $(TMPDIR)/obj - rm $(TMPDIR)/link - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit=asm,llvm-ir,llvm-bc,obj,link --crate-type=staticlib - rm $(TMPDIR)/bar.ll - rm $(TMPDIR)/bar.s - rm $(TMPDIR)/bar.o - rm $(call STATICLIB,bar) - mv $(TMPDIR)/bar.bc $(TMPDIR)/foo.bc - # Don't check that the $(TMPDIR) is empty - we left `foo.bc` for later - # comparison. - - $(RUSTC) foo.rs --emit=llvm-bc,link --crate-type=rlib - cmp $(TMPDIR)/foo.bc $(TMPDIR)/bar.bc - rm $(TMPDIR)/bar.bc - rm $(TMPDIR)/foo.bc - $(call REMOVE_RLIBS,bar) - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] diff --git a/tests/run-make/output-type-permutations/rmake.rs b/tests/run-make/output-type-permutations/rmake.rs new file mode 100644 index 0000000000000..30036dc7eeacd --- /dev/null +++ b/tests/run-make/output-type-permutations/rmake.rs @@ -0,0 +1,543 @@ +// In 2014, rustc's output flags were reworked to be a lot more modular. +// This test uses these output flags in an expansive variety of combinations +// and syntax styles, checking that compilation is successful and that output +// files are exactly what is expected, no more, no less. +// See https://github.com/rust-lang/rust/pull/12020 + +use run_make_support::{ + bin_name, dynamic_lib_name, filename_not_in_denylist, fs_wrapper, rust_lib_name, rustc, + shallow_find_files, static_lib_name, +}; +use std::path::PathBuf; + +// Each test takes 4 arguments: +// `must_exist`: output files which must be found - if any are absent, the test fails +// `can_exist`: optional output files which will not trigger a failure +// `dir`: the name of the directory where the test happens +// `rustc_invocation`: the rustc command being tested +// Any unexpected output files not listed in `must_exist` or `can_exist` will cause a failure. +fn assert_expected_output_files(expectations: Expectations, rustc_invocation: impl Fn()) { + let must_exist = expectations.expected_files; + let can_exist = expectations.allowed_files; + let dir = expectations.test_dir; + + fs_wrapper::create_dir(&dir); + rustc_invocation(); + for file in must_exist { + fs_wrapper::remove_file(PathBuf::from(&dir).join(&file)); + } + let actual_output_files = + shallow_find_files(dir, |path| filename_not_in_denylist(path, &can_exist)); + if !&actual_output_files.is_empty() { + dbg!(&actual_output_files); + panic!("unexpected output artifacts detected"); + } +} + +struct Expectations { + /// Output files which must be found. The test fails if any are absent. + expected_files: Vec, + /// Allowed output files which will not trigger a failure. + allowed_files: Vec, + /// Name of the directory where the test happens. + test_dir: String, +} + +macro_rules! s { + ( $( $x:expr ),* ) => { + { + let mut temp_vec = Vec::new(); + $( + temp_vec.push($x.to_string()); + )* + temp_vec + } + }; +} + +fn main() { + let bin_foo = bin_name("foo"); + + assert_expected_output_files( + Expectations { + expected_files: s![ + static_lib_name("bar"), + dynamic_lib_name("bar"), + rust_lib_name("bar") + ], + allowed_files: s![ + "libbar.dll.exp", + "libbar.dll.lib", + "libbar.pdb", + "libbar.dll.a", + "libbar.exe.a", + "bar.dll.exp", + "bar.dll.lib", + "bar.pdb", + "bar.dll.a", + "bar.exe.a" + ], + test_dir: "three-crates".to_string(), + }, + || { + rustc() + .input("foo.rs") + .out_dir("three-crates") + .crate_type("rlib,dylib,staticlib") + .run(); + }, + ); + + assert_expected_output_files( + Expectations { + expected_files: s![bin_name("bar")], + allowed_files: s!["bar.pdb"], + test_dir: "bin-crate".to_string(), + }, + || { + rustc().input("foo.rs").crate_type("bin").out_dir("bin-crate").run(); + }, + ); + + assert_expected_output_files( + Expectations { + expected_files: s!["bar.ll", "bar.bc", "bar.s", "bar.o", bin_name("bar")], + allowed_files: s!["bar.pdb"], + test_dir: "all-emit".to_string(), + }, + || { + rustc().input("foo.rs").emit("asm,llvm-ir,llvm-bc,obj,link").out_dir("all-emit").run(); + }, + ); + + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "asm-emit".to_string(), + }, + || { + rustc().input("foo.rs").emit("asm").output("asm-emit/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "asm-emit2".to_string(), + }, + || { + rustc().input("foo.rs").emit("asm=asm-emit2/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "asm-emit3".to_string(), + }, + || { + rustc().input("foo.rs").arg("--emit=asm=asm-emit3/foo").run(); + }, + ); + + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "llvm-ir-emit".to_string(), + }, + || { + rustc().input("foo.rs").emit("llvm-ir").output("llvm-ir-emit/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "llvm-ir-emit2".to_string(), + }, + || { + rustc().input("foo.rs").emit("llvm-ir=llvm-ir-emit2/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "llvm-ir-emit3".to_string(), + }, + || { + rustc().input("foo.rs").arg("--emit=llvm-ir=llvm-ir-emit3/foo").run(); + }, + ); + + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "llvm-bc-emit".to_string(), + }, + || { + rustc().input("foo.rs").emit("llvm-bc").output("llvm-bc-emit/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "llvm-bc-emit2".to_string(), + }, + || { + rustc().input("foo.rs").emit("llvm-bc=llvm-bc-emit2/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "llvm-bc-emit3".to_string(), + }, + || { + rustc().input("foo.rs").arg("--emit=llvm-bc=llvm-bc-emit3/foo").run(); + }, + ); + + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "obj-emit".to_string(), + }, + || { + rustc().input("foo.rs").emit("obj").output("obj-emit/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "obj-emit2".to_string(), + }, + || { + rustc().input("foo.rs").emit("obj=obj-emit2/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "obj-emit3".to_string(), + }, + || { + rustc().input("foo.rs").arg("--emit=obj=obj-emit3/foo").run(); + }, + ); + + assert_expected_output_files( + Expectations { + expected_files: s![&bin_foo], + allowed_files: s!["foo.pdb"], + test_dir: "link-emit".to_string(), + }, + || { + rustc().input("foo.rs").emit("link").output("link-emit/".to_owned() + &bin_foo).run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s![&bin_foo], + allowed_files: s!["foo.pdb"], + test_dir: "link-emit2".to_string(), + }, + || { + rustc().input("foo.rs").emit(&format!("link=link-emit2/{bin_foo}")).run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s![&bin_foo], + allowed_files: s!["foo.pdb"], + test_dir: "link-emit3".to_string(), + }, + || { + rustc().input("foo.rs").arg(&format!("--emit=link=link-emit3/{bin_foo}")).run(); + }, + ); + + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "rlib".to_string(), + }, + || { + rustc().crate_type("rlib").input("foo.rs").output("rlib/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "rlib2".to_string(), + }, + || { + rustc().crate_type("rlib").input("foo.rs").emit("link=rlib2/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "rlib3".to_string(), + }, + || { + rustc().crate_type("rlib").input("foo.rs").arg("--emit=link=rlib3/foo").run(); + }, + ); + + assert_expected_output_files( + Expectations { + expected_files: s![bin_foo], + allowed_files: s![ + "libfoo.dll.exp", + "libfoo.dll.lib", + "libfoo.pdb", + "libfoo.dll.a", + "libfoo.exe.a", + "foo.dll.exp", + "foo.dll.lib", + "foo.pdb", + "foo.dll.a", + "foo.exe.a" + ], + test_dir: "dylib".to_string(), + }, + || { + rustc() + .crate_type("dylib") + .input("foo.rs") + .output("dylib/".to_owned() + &bin_foo) + .run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s![bin_foo], + allowed_files: s![ + "libfoo.dll.exp", + "libfoo.dll.lib", + "libfoo.pdb", + "libfoo.dll.a", + "libfoo.exe.a", + "foo.dll.exp", + "foo.dll.lib", + "foo.pdb", + "foo.dll.a", + "foo.exe.a" + ], + test_dir: "dylib2".to_string(), + }, + || { + rustc() + .crate_type("dylib") + .input("foo.rs") + .emit(&format!("link=dylib2/{bin_foo}")) + .run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s![bin_foo], + allowed_files: s![ + "libfoo.dll.exp", + "libfoo.dll.lib", + "libfoo.pdb", + "libfoo.dll.a", + "libfoo.exe.a", + "foo.dll.exp", + "foo.dll.lib", + "foo.pdb", + "foo.dll.a", + "foo.exe.a" + ], + test_dir: "dylib3".to_string(), + }, + || { + rustc() + .crate_type("dylib") + .input("foo.rs") + .arg(&format!("--emit=link=dylib3/{bin_foo}")) + .run(); + }, + ); + + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "staticlib".to_string(), + }, + || { + rustc().crate_type("staticlib").input("foo.rs").output("staticlib/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "staticlib2".to_string(), + }, + || { + rustc().crate_type("staticlib").input("foo.rs").emit("link=staticlib2/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "staticlib3".to_string(), + }, + || { + rustc().crate_type("staticlib").input("foo.rs").arg("--emit=link=staticlib3/foo").run(); + }, + ); + + assert_expected_output_files( + Expectations { + expected_files: s![bin_foo], + allowed_files: s!["foo.pdb"], + test_dir: "bincrate".to_string(), + }, + || { + rustc() + .crate_type("bin") + .input("foo.rs") + .output("bincrate/".to_owned() + &bin_foo) + .run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s![bin_foo], + allowed_files: s!["foo.pdb"], + test_dir: "bincrate2".to_string(), + }, + || { + rustc() + .crate_type("bin") + .input("foo.rs") + .emit(&format!("link=bincrate2/{bin_foo}")) + .run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s![bin_foo], + allowed_files: s!["foo.pdb"], + test_dir: "bincrate3".to_string(), + }, + || { + rustc() + .crate_type("bin") + .input("foo.rs") + .arg(&format!("--emit=link=bincrate3/{bin_foo}")) + .run(); + }, + ); + + assert_expected_output_files( + Expectations { + expected_files: s!["ir", rust_lib_name("bar")], + allowed_files: s![], + test_dir: "rlib-ir".to_string(), + }, + || { + rustc() + .input("foo.rs") + .emit("llvm-ir=rlib-ir/ir") + .emit("link") + .crate_type("rlib") + .out_dir("rlib-ir") + .run(); + }, + ); + + assert_expected_output_files( + Expectations { + expected_files: s!["ir", "asm", "bc", "obj", "link"], + allowed_files: s![], + test_dir: "staticlib-all".to_string(), + }, + || { + rustc() + .input("foo.rs") + .emit("asm=staticlib-all/asm") + .emit("llvm-ir=staticlib-all/ir") + .emit("llvm-bc=staticlib-all/bc") + .emit("obj=staticlib-all/obj") + .emit("link=staticlib-all/link") + .crate_type("staticlib") + .run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["ir", "asm", "bc", "obj", "link"], + allowed_files: s![], + test_dir: "staticlib-all2".to_string(), + }, + || { + rustc() + .input("foo.rs") + .arg("--emit=asm=staticlib-all2/asm") + .arg("--emit") + .arg("llvm-ir=staticlib-all2/ir") + .arg("--emit=llvm-bc=staticlib-all2/bc") + .arg("--emit") + .arg("obj=staticlib-all2/obj") + .arg("--emit=link=staticlib-all2/link") + .crate_type("staticlib") + .run(); + }, + ); + + assert_expected_output_files( + Expectations { + expected_files: s!["bar.ll", "bar.s", "bar.o", static_lib_name("bar")], + allowed_files: s!["bar.bc"], // keep this one for the next test + test_dir: "staticlib-all3".to_string(), + }, + || { + rustc() + .input("foo.rs") + .emit("asm,llvm-ir,llvm-bc,obj,link") + .crate_type("staticlib") + .out_dir("staticlib-all3") + .run(); + }, + ); + + // the .bc file from the previous test should be equivalent to this one, despite the difference + // in crate type + assert_expected_output_files( + Expectations { + expected_files: s!["bar.bc", rust_lib_name("bar"), "foo.bc"], + allowed_files: s![], + test_dir: "rlib-emits".to_string(), + }, + || { + fs_wrapper::rename("staticlib-all3/bar.bc", "rlib-emits/foo.bc"); + rustc() + .input("foo.rs") + .emit("llvm-bc,link") + .crate_type("rlib") + .out_dir("rlib-emits") + .run(); + assert_eq!( + fs_wrapper::read("rlib-emits/foo.bc"), + fs_wrapper::read("rlib-emits/bar.bc") + ); + }, + ); +} diff --git a/tests/ui/argument-suggestions/basic.stderr b/tests/ui/argument-suggestions/basic.stderr index c74186285f9f0..ea58ca97cfaf8 100644 --- a/tests/ui/argument-suggestions/basic.stderr +++ b/tests/ui/argument-suggestions/basic.stderr @@ -16,16 +16,18 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/basic.rs:21:5 | LL | extra(""); - | ^^^^^ -- - | | - | unexpected argument of type `&'static str` - | help: remove the extra argument + | ^^^^^ -- unexpected argument of type `&'static str` | note: function defined here --> $DIR/basic.rs:14:4 | LL | fn extra() {} | ^^^^^ +help: remove the extra argument + | +LL - extra(""); +LL + extra(); + | error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/basic.rs:22:5 diff --git a/tests/ui/argument-suggestions/exotic-calls.stderr b/tests/ui/argument-suggestions/exotic-calls.stderr index ff795b507f218..aca3b8a343343 100644 --- a/tests/ui/argument-suggestions/exotic-calls.stderr +++ b/tests/ui/argument-suggestions/exotic-calls.stderr @@ -2,61 +2,69 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/exotic-calls.rs:2:5 | LL | t(1i32); - | ^ ---- - | | - | unexpected argument of type `i32` - | help: remove the extra argument + | ^ ---- unexpected argument of type `i32` | note: callable defined here --> $DIR/exotic-calls.rs:1:11 | LL | fn foo(t: T) { | ^^^^ +help: remove the extra argument + | +LL - t(1i32); +LL + t(); + | error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/exotic-calls.rs:7:5 | LL | t(1i32); - | ^ ---- - | | - | unexpected argument of type `i32` - | help: remove the extra argument + | ^ ---- unexpected argument of type `i32` | note: type parameter defined here --> $DIR/exotic-calls.rs:6:11 | LL | fn bar(t: impl Fn()) { | ^^^^^^^^^ +help: remove the extra argument + | +LL - t(1i32); +LL + t(); + | error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/exotic-calls.rs:16:5 | LL | baz()(1i32) - | ^^^^^ ---- - | | - | unexpected argument of type `i32` - | help: remove the extra argument + | ^^^^^ ---- unexpected argument of type `i32` | note: opaque type defined here --> $DIR/exotic-calls.rs:11:13 | LL | fn baz() -> impl Fn() { | ^^^^^^^^^ +help: remove the extra argument + | +LL - baz()(1i32) +LL + baz()() + | error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/exotic-calls.rs:22:5 | LL | x(1i32); - | ^ ---- - | | - | unexpected argument of type `i32` - | help: remove the extra argument + | ^ ---- unexpected argument of type `i32` | note: closure defined here --> $DIR/exotic-calls.rs:21:13 | LL | let x = || {}; | ^^ +help: remove the extra argument + | +LL - x(1i32); +LL + x(); + | error: aborting due to 4 previous errors diff --git a/tests/ui/argument-suggestions/extra_arguments.stderr b/tests/ui/argument-suggestions/extra_arguments.stderr index 5ad8e35920a10..dec3da7518658 100644 --- a/tests/ui/argument-suggestions/extra_arguments.stderr +++ b/tests/ui/argument-suggestions/extra_arguments.stderr @@ -2,16 +2,18 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/extra_arguments.rs:19:3 | LL | empty(""); - | ^^^^^ -- - | | - | unexpected argument of type `&'static str` - | help: remove the extra argument + | ^^^^^ -- unexpected argument of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:1:4 | LL | fn empty() {} | ^^^^^ +help: remove the extra argument + | +LL - empty(""); +LL + empty(); + | error[E0061]: this function takes 0 arguments but 2 arguments were supplied --> $DIR/extra_arguments.rs:20:3 @@ -36,31 +38,35 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:22:3 | LL | one_arg(1, 1); - | ^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:2:4 | LL | fn one_arg(_a: T) {} | ^^^^^^^ ----- +help: remove the extra argument + | +LL - one_arg(1, 1); +LL + one_arg(1); + | error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:23:3 | LL | one_arg(1, ""); - | ^^^^^^^ ---- - | | | - | | unexpected argument of type `&'static str` - | help: remove the extra argument + | ^^^^^^^ -- unexpected argument of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:2:4 | LL | fn one_arg(_a: T) {} | ^^^^^^^ ----- +help: remove the extra argument + | +LL - one_arg(1, ""); +LL + one_arg(1); + | error[E0061]: this function takes 1 argument but 3 arguments were supplied --> $DIR/extra_arguments.rs:24:3 @@ -85,61 +91,69 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:26:3 | LL | two_arg_same(1, 1, 1); - | ^^^^^^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:3:4 | LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- +help: remove the extra argument + | +LL - two_arg_same(1, 1, 1); +LL + two_arg_same(1, 1); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:27:3 | LL | two_arg_same(1, 1, 1.0); - | ^^^^^^^^^^^^ ----- - | | | - | | unexpected argument of type `{float}` - | help: remove the extra argument + | ^^^^^^^^^^^^ --- unexpected argument of type `{float}` | note: function defined here --> $DIR/extra_arguments.rs:3:4 | LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- +help: remove the extra argument + | +LL - two_arg_same(1, 1, 1.0); +LL + two_arg_same(1, 1); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:29:3 | LL | two_arg_diff(1, 1, ""); - | ^^^^^^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:4:4 | LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- +help: remove the extra argument + | +LL - two_arg_diff(1, 1, ""); +LL + two_arg_diff(1, ""); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:30:3 | LL | two_arg_diff(1, "", ""); - | ^^^^^^^^^^^^ ---- - | | | - | | unexpected argument of type `&'static str` - | help: remove the extra argument + | ^^^^^^^^^^^^ -- unexpected argument of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:4:4 | LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- +help: remove the extra argument + | +LL - two_arg_diff(1, "", ""); +LL + two_arg_diff(1, ""); + | error[E0061]: this function takes 2 arguments but 4 arguments were supplied --> $DIR/extra_arguments.rs:31:3 @@ -183,70 +197,75 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:35:3 | LL | two_arg_same(1, 1, ""); - | ^^^^^^^^^^^^ -------- - | | | - | | unexpected argument of type `&'static str` - | help: remove the extra argument + | ^^^^^^^^^^^^ -- unexpected argument of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:3:4 | LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- +help: remove the extra argument + | +LL - two_arg_same(1, 1, ""); +LL + two_arg_same(1, 1); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:36:3 | LL | two_arg_diff(1, 1, ""); - | ^^^^^^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:4:4 | LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- +help: remove the extra argument + | +LL - two_arg_diff(1, 1, ""); +LL + two_arg_diff(1, ""); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:37:3 | -LL | two_arg_same( - | ^^^^^^^^^^^^ -LL | 1, -LL | 1, - | ______- -LL | | "" - | | -- - | |_____|| - | |help: remove the extra argument - | unexpected argument of type `&'static str` +LL | two_arg_same( + | ^^^^^^^^^^^^ +... +LL | "" + | -- unexpected argument of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:3:4 | LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- +help: remove the extra argument + | +LL - 1, +LL - "" +LL + 1 + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:43:3 | -LL | two_arg_diff( - | ^^^^^^^^^^^^ -LL | 1, - | ______- -LL | | 1, - | | - - | | | - | |_____unexpected argument of type `{integer}` - | help: remove the extra argument +LL | two_arg_diff( + | ^^^^^^^^^^^^ +LL | 1, +LL | 1, + | - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:4:4 | LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- +help: remove the extra argument + | +LL - 1, + | error[E0061]: this function takes 0 arguments but 2 arguments were supplied --> $DIR/extra_arguments.rs:8:9 @@ -310,61 +329,69 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:53:3 | LL | one_arg(1, panic!()); - | ^^^^^^^ ---------- - | | | - | | unexpected argument - | help: remove the extra argument + | ^^^^^^^ -------- unexpected argument | note: function defined here --> $DIR/extra_arguments.rs:2:4 | LL | fn one_arg(_a: T) {} | ^^^^^^^ ----- +help: remove the extra argument + | +LL - one_arg(1, panic!()); +LL + one_arg(1); + | error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:54:3 | LL | one_arg(panic!(), 1); - | ^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:2:4 | LL | fn one_arg(_a: T) {} | ^^^^^^^ ----- +help: remove the extra argument + | +LL - one_arg(panic!(), 1); +LL + one_arg(panic!()); + | error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:55:3 | LL | one_arg(stringify!($e), 1); - | ^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:2:4 | LL | fn one_arg(_a: T) {} | ^^^^^^^ ----- +help: remove the extra argument + | +LL - one_arg(stringify!($e), 1); +LL + one_arg(stringify!($e)); + | error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:60:3 | LL | one_arg(for _ in 1.. {}, 1); - | ^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:2:4 | LL | fn one_arg(_a: T) {} | ^^^^^^^ ----- +help: remove the extra argument + | +LL - one_arg(for _ in 1.. {}, 1); +LL + one_arg(for _ in 1.. {}); + | error: aborting due to 22 previous errors diff --git a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr index 7c4daa3ffe95b..dc293945eb600 100644 --- a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr +++ b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr @@ -32,91 +32,103 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:10:5 | LL | add_one(2, 2); - | ^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:1:4 | LL | fn add_one(x: i32) -> i32 { | ^^^^^^^ ------ +help: remove the extra argument + | +LL - add_one(2, 2); +LL + add_one(2); + | error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:11:5 | LL | add_one(no_such_local, 10); - | ^^^^^^^ --------------- - | | - | unexpected argument - | help: remove the extra argument + | ^^^^^^^ ------------- unexpected argument | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:1:4 | LL | fn add_one(x: i32) -> i32 { | ^^^^^^^ ------ +help: remove the extra argument + | +LL - add_one(no_such_local, 10); +LL + add_one(10); + | error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:13:5 | LL | add_one(10, no_such_local); - | ^^^^^^^ --------------- - | | | - | | unexpected argument - | help: remove the extra argument + | ^^^^^^^ ------------- unexpected argument | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:1:4 | LL | fn add_one(x: i32) -> i32 { | ^^^^^^^ ------ +help: remove the extra argument + | +LL - add_one(10, no_such_local); +LL + add_one(10); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:15:5 | LL | add_two(10, no_such_local, 10); - | ^^^^^^^ --------------- - | | | - | | unexpected argument - | help: remove the extra argument + | ^^^^^^^ ------------- unexpected argument | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:5:4 | LL | fn add_two(x: i32, y: i32) -> i32 { | ^^^^^^^ ------ ------ +help: remove the extra argument + | +LL - add_two(10, no_such_local, 10); +LL + add_two(10, 10); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:17:5 | LL | add_two(no_such_local, 10, 10); - | ^^^^^^^ --------------- - | | - | unexpected argument - | help: remove the extra argument + | ^^^^^^^ ------------- unexpected argument | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:5:4 | LL | fn add_two(x: i32, y: i32) -> i32 { | ^^^^^^^ ------ ------ +help: remove the extra argument + | +LL - add_two(no_such_local, 10, 10); +LL + add_two(10, 10); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:19:5 | LL | add_two(10, 10, no_such_local); - | ^^^^^^^ --------------- - | | | - | | unexpected argument - | help: remove the extra argument + | ^^^^^^^ ------------- unexpected argument | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:5:4 | LL | fn add_two(x: i32, y: i32) -> i32 { | ^^^^^^^ ------ ------ +help: remove the extra argument + | +LL - add_two(10, 10, no_such_local); +LL + add_two(10, 10); + | error: aborting due to 11 previous errors diff --git a/tests/ui/associated-types/defaults-specialization.stderr b/tests/ui/associated-types/defaults-specialization.stderr index 7ef433d859fa4..b4ed99f36f44a 100644 --- a/tests/ui/associated-types/defaults-specialization.stderr +++ b/tests/ui/associated-types/defaults-specialization.stderr @@ -12,10 +12,7 @@ error[E0053]: method `make` has an incompatible type for trait --> $DIR/defaults-specialization.rs:19:18 | LL | fn make() -> u8 { 0 } - | ^^ - | | - | expected associated type, found `u8` - | help: change the output type to match the trait: ` as Tr>::Ty` + | ^^ expected associated type, found `u8` | note: type in trait --> $DIR/defaults-specialization.rs:9:18 @@ -24,6 +21,10 @@ LL | fn make() -> Self::Ty { | ^^^^^^^^ = note: expected signature `fn() -> as Tr>::Ty` found signature `fn() -> u8` +help: change the output type to match the trait + | +LL | fn make() -> as Tr>::Ty { 0 } + | ~~~~~~~~~~~~~~~~ error[E0053]: method `make` has an incompatible type for trait --> $DIR/defaults-specialization.rs:35:18 @@ -32,10 +33,7 @@ LL | default type Ty = bool; | ----------------------- associated type is `default` and may be overridden LL | LL | fn make() -> bool { true } - | ^^^^ - | | - | expected associated type, found `bool` - | help: change the output type to match the trait: ` as Tr>::Ty` + | ^^^^ expected associated type, found `bool` | note: type in trait --> $DIR/defaults-specialization.rs:9:18 @@ -44,6 +42,10 @@ LL | fn make() -> Self::Ty { | ^^^^^^^^ = note: expected signature `fn() -> as Tr>::Ty` found signature `fn() -> bool` +help: change the output type to match the trait + | +LL | fn make() -> as Tr>::Ty { true } + | ~~~~~~~~~~~~~~~~ error[E0308]: mismatched types --> $DIR/defaults-specialization.rs:10:9 diff --git a/tests/ui/compare-method/bad-self-type.stderr b/tests/ui/compare-method/bad-self-type.stderr index a87b713c2b4bd..29ebbc5dffb11 100644 --- a/tests/ui/compare-method/bad-self-type.stderr +++ b/tests/ui/compare-method/bad-self-type.stderr @@ -2,22 +2,20 @@ error[E0053]: method `poll` has an incompatible type for trait --> $DIR/bad-self-type.rs:10:13 | LL | fn poll(self, _: &mut Context<'_>) -> Poll<()> { - | ^^^^ - | | - | expected `Pin<&mut MyFuture>`, found `MyFuture` - | help: change the self-receiver type to match the trait: `self: Pin<&mut MyFuture>` + | ^^^^ expected `Pin<&mut MyFuture>`, found `MyFuture` | = note: expected signature `fn(Pin<&mut MyFuture>, &mut Context<'_>) -> Poll<_>` found signature `fn(MyFuture, &mut Context<'_>) -> Poll<_>` +help: change the self-receiver type to match the trait + | +LL | fn poll(self: Pin<&mut MyFuture>, _: &mut Context<'_>) -> Poll<()> { + | ~~~~~~~~~~~~~~~~~~~~~~~~ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/bad-self-type.rs:22:18 | LL | fn foo(self: Box) {} - | ------^^^^^^^^^ - | | | - | | expected `MyFuture`, found `Box` - | help: change the self-receiver type to match the trait: `self` + | ^^^^^^^^^ expected `MyFuture`, found `Box` | note: type in trait --> $DIR/bad-self-type.rs:17:12 @@ -26,6 +24,10 @@ LL | fn foo(self); | ^^^^ = note: expected signature `fn(MyFuture)` found signature `fn(Box)` +help: change the self-receiver type to match the trait + | +LL | fn foo(self) {} + | ~~~~ error[E0053]: method `bar` has an incompatible type for trait --> $DIR/bad-self-type.rs:24:17 diff --git a/tests/ui/compare-method/issue-90444.stderr b/tests/ui/compare-method/issue-90444.stderr index 52e23d03b148b..f05c9939c0096 100644 --- a/tests/ui/compare-method/issue-90444.stderr +++ b/tests/ui/compare-method/issue-90444.stderr @@ -2,25 +2,27 @@ error[E0053]: method `from` has an incompatible type for trait --> $DIR/issue-90444.rs:3:16 | LL | fn from(_: fn((), (), &mut ())) -> Self { - | ^^^^^^^^^^^^^^^^^^^ - | | - | types differ in mutability - | help: change the parameter type to match the trait: `for<'a> fn((), (), &'a ())` + | ^^^^^^^^^^^^^^^^^^^ types differ in mutability | = note: expected signature `fn(for<'a> fn((), (), &'a ())) -> A` found signature `fn(for<'a> fn((), (), &'a mut ())) -> A` +help: change the parameter type to match the trait + | +LL | fn from(_: for<'a> fn((), (), &'a ())) -> Self { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0053]: method `from` has an incompatible type for trait --> $DIR/issue-90444.rs:11:16 | LL | fn from(_: fn((), (), u64)) -> Self { - | ^^^^^^^^^^^^^^^ - | | - | expected `u32`, found `u64` - | help: change the parameter type to match the trait: `fn((), (), u32)` + | ^^^^^^^^^^^^^^^ expected `u32`, found `u64` | = note: expected signature `fn(fn((), (), u32)) -> B` found signature `fn(fn((), (), u64)) -> B` +help: change the parameter type to match the trait + | +LL | fn from(_: fn((), (), u32)) -> Self { + | ~~~~~~~~~~~~~~~ error: aborting due to 2 previous errors diff --git a/tests/ui/compare-method/reordered-type-param.stderr b/tests/ui/compare-method/reordered-type-param.stderr index 8a439acee13de..1e8266e213d7f 100644 --- a/tests/ui/compare-method/reordered-type-param.stderr +++ b/tests/ui/compare-method/reordered-type-param.stderr @@ -2,10 +2,8 @@ error[E0053]: method `b` has an incompatible type for trait --> $DIR/reordered-type-param.rs:16:30 | LL | fn b(&self, _x: G) -> G { panic!() } - | - - ^ - | | | | - | | | expected type parameter `F`, found type parameter `G` - | | | help: change the parameter type to match the trait: `F` + | - - ^ expected type parameter `F`, found type parameter `G` + | | | | | found type parameter | expected type parameter | @@ -18,6 +16,10 @@ LL | fn b(&self, x: C) -> C; found signature `fn(&E, G) -> G` = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters +help: change the parameter type to match the trait + | +LL | fn b(&self, _x: F) -> G { panic!() } + | ~ error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0057.stderr b/tests/ui/error-codes/E0057.stderr index 9b0cf069824a6..efd2af6d609bd 100644 --- a/tests/ui/error-codes/E0057.stderr +++ b/tests/ui/error-codes/E0057.stderr @@ -18,16 +18,18 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied --> $DIR/E0057.rs:5:13 | LL | let c = f(2, 3); - | ^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^ - unexpected argument of type `{integer}` | note: closure defined here --> $DIR/E0057.rs:2:13 | LL | let f = |x| x * 3; | ^^^ +help: remove the extra argument + | +LL - let c = f(2, 3); +LL + let c = f(2); + | error: aborting due to 2 previous errors diff --git a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr index 1b9febd431d6f..06a606b09dc97 100644 --- a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr +++ b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr @@ -89,13 +89,14 @@ error[E0053]: method `call` has an incompatible type for trait --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:13:32 | LL | extern "rust-call" fn call(self, args: ()) -> () {} - | ^^^^ - | | - | expected `&Foo`, found `Foo` - | help: change the self-receiver type to match the trait: `&self` + | ^^^^ expected `&Foo`, found `Foo` | = note: expected signature `extern "rust-call" fn(&Foo, ()) -> _` found signature `extern "rust-call" fn(Foo, ())` +help: change the self-receiver type to match the trait + | +LL | extern "rust-call" fn call(&self, args: ()) -> () {} + | ~~~~~ error[E0183]: manual implementations of `FnOnce` are experimental --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6 @@ -158,13 +159,14 @@ error[E0053]: method `call_mut` has an incompatible type for trait --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:30:36 | LL | extern "rust-call" fn call_mut(&self, args: ()) -> () {} - | ^^^^^ - | | - | types differ in mutability - | help: change the self-receiver type to match the trait: `&mut self` + | ^^^^^ types differ in mutability | = note: expected signature `extern "rust-call" fn(&mut Bar, ()) -> _` found signature `extern "rust-call" fn(&Bar, ())` +help: change the self-receiver type to match the trait + | +LL | extern "rust-call" fn call_mut(&mut self, args: ()) -> () {} + | ~~~~~~~~~ error[E0046]: not all trait items implemented, missing: `Output` --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:35:1 diff --git a/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr b/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr index 7046e729e1834..90c31c9e3fc19 100644 --- a/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr +++ b/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr @@ -2,10 +2,8 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/impl-generic-mismatch-ab.rs:8:32 | LL | fn foo(&self, a: &impl Debug, b: &B) { } - | - ^^^^^^^^^^^ - | | | - | | expected type parameter `B`, found type parameter `impl Debug` - | | help: change the parameter type to match the trait: `&B` + | - ^^^^^^^^^^^ expected type parameter `B`, found type parameter `impl Debug` + | | | expected type parameter | note: type in trait @@ -17,6 +15,10 @@ LL | fn foo(&self, a: &A, b: &impl Debug); found signature `fn(&(), &impl Debug, &B)` = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters +help: change the parameter type to match the trait + | +LL | fn foo(&self, a: &B, b: &B) { } + | ~~ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr index 8e61a65abe4be..e32c59a75c699 100644 --- a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr +++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr @@ -27,10 +27,7 @@ LL | type Ty = impl Sized; | ---------- the expected opaque type LL | LL | fn method() -> () {} - | ^^ - | | - | expected opaque type, found `()` - | help: change the output type to match the trait: `<() as compare_method::Trait>::Ty` + | ^^ expected opaque type, found `()` | note: type in trait --> $DIR/in-assoc-type-unconstrained.rs:17:24 @@ -44,6 +41,10 @@ note: this item must have the opaque type in its signature in order to be able t | LL | fn method() -> () {} | ^^^^^^ +help: change the output type to match the trait + | +LL | fn method() -> <() as compare_method::Trait>::Ty {} + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unconstrained opaque type --> $DIR/in-assoc-type-unconstrained.rs:20:19 diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr index 2231205327cb0..6f6b787b6fe1b 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr @@ -2,10 +2,8 @@ error[E0053]: method `early` has an incompatible type for trait --> $DIR/method-signature-matches.rs:55:27 | LL | fn early<'late, T>(_: &'late ()) {} - | - ^^^^^^^^^ - | | | - | | expected type parameter `T`, found `()` - | | help: change the parameter type to match the trait: `&T` + | - ^^^^^^^^^ expected type parameter `T`, found `()` + | | | expected this type parameter | note: type in trait @@ -15,6 +13,10 @@ LL | fn early<'early, T>(x: &'early T) -> impl Sized; | ^^^^^^^^^ = note: expected signature `fn(&T)` found signature `fn(&'late ())` +help: change the parameter type to match the trait + | +LL | fn early<'late, T>(_: &T) {} + | ~~ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr index ec2a126865d5c..9e18517e48c55 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr @@ -2,10 +2,7 @@ error[E0053]: method `owo` has an incompatible type for trait --> $DIR/method-signature-matches.rs:11:15 | LL | fn owo(_: u8) {} - | ^^ - | | - | expected `()`, found `u8` - | help: change the parameter type to match the trait: `()` + | ^^ expected `()`, found `u8` | note: type in trait --> $DIR/method-signature-matches.rs:6:15 @@ -14,6 +11,10 @@ LL | fn owo(x: ()) -> impl Sized; | ^^ = note: expected signature `fn(())` found signature `fn(u8)` +help: change the parameter type to match the trait + | +LL | fn owo(_: ()) {} + | ~~ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr index 4d3e64e8050f9..c01d7322d117e 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr @@ -2,10 +2,7 @@ error[E0053]: method `owo` has an incompatible type for trait --> $DIR/method-signature-matches.rs:22:21 | LL | async fn owo(_: u8) {} - | ^^ - | | - | expected `()`, found `u8` - | help: change the parameter type to match the trait: `()` + | ^^ expected `()`, found `u8` | note: type in trait --> $DIR/method-signature-matches.rs:17:21 @@ -14,6 +11,10 @@ LL | async fn owo(x: ()) {} | ^^ = note: expected signature `fn(()) -> _` found signature `fn(u8) -> _` +help: change the parameter type to match the trait + | +LL | async fn owo(_: ()) {} + | ~~ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr index d7fc40fa3426f..1f8a0d5edd781 100644 --- a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr +++ b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr @@ -75,10 +75,7 @@ error[E0053]: method `bar` has an incompatible type for trait --> $DIR/opaque-and-lifetime-mismatch.rs:10:17 | LL | fn bar() -> i32 { - | ^^^ - | | - | expected `Wrapper<'static>`, found `i32` - | help: change the output type to match the trait: `Wrapper<'static>` + | ^^^ expected `Wrapper<'static>`, found `i32` | note: type in trait --> $DIR/opaque-and-lifetime-mismatch.rs:4:17 @@ -87,6 +84,10 @@ LL | fn bar() -> Wrapper; | ^^^^^^^^^^^^^^^^^^^ = note: expected signature `fn() -> Wrapper<'static>` found signature `fn() -> i32` +help: change the output type to match the trait + | +LL | fn bar() -> Wrapper<'static> { + | ~~~~~~~~~~~~~~~~ error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied --> $DIR/opaque-and-lifetime-mismatch.rs:24:17 diff --git a/tests/ui/impl-trait/in-trait/specialization-broken.stderr b/tests/ui/impl-trait/in-trait/specialization-broken.stderr index b8a8e2401b229..8c9f265601540 100644 --- a/tests/ui/impl-trait/in-trait/specialization-broken.stderr +++ b/tests/ui/impl-trait/in-trait/specialization-broken.stderr @@ -5,10 +5,7 @@ LL | default impl Foo for U | - found this type parameter ... LL | fn bar(&self) -> U { - | ^ - | | - | expected associated type, found type parameter `U` - | help: change the output type to match the trait: `impl Sized` + | ^ expected associated type, found type parameter `U` | note: type in trait --> $DIR/specialization-broken.rs:8:22 @@ -17,6 +14,10 @@ LL | fn bar(&self) -> impl Sized; | ^^^^^^^^^^ = note: expected signature `fn(&_) -> impl Sized` found signature `fn(&_) -> U` +help: change the output type to match the trait + | +LL | fn bar(&self) -> impl Sized { + | ~~~~~~~~~~ error: method with return-position `impl Trait` in trait cannot be specialized --> $DIR/specialization-broken.rs:15:5 diff --git a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr index 6d41748853332..caaac5434c56a 100644 --- a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr +++ b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr @@ -57,31 +57,35 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/opaque-used-in-extraneous-argument.rs:17:20 | LL | let old_path = frob("hello"); - | ^^^^ ------- - | | - | unexpected argument of type `&'static str` - | help: remove the extra argument + | ^^^^ ------- unexpected argument of type `&'static str` | note: function defined here --> $DIR/opaque-used-in-extraneous-argument.rs:5:4 | LL | fn frob() -> impl Fn + '_ {} | ^^^^ +help: remove the extra argument + | +LL - let old_path = frob("hello"); +LL + let old_path = frob(); + | error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/opaque-used-in-extraneous-argument.rs:20:5 | LL | open_parent(&old_path) - | ^^^^^^^^^^^ --------- - | | - | unexpected argument of type `&impl FnOnce<{type error}, Output = {type error}> + Fn<{type error}> + 'static` - | help: remove the extra argument + | ^^^^^^^^^^^ --------- unexpected argument of type `&impl FnOnce<{type error}, Output = {type error}> + Fn<{type error}> + 'static` | note: function defined here --> $DIR/opaque-used-in-extraneous-argument.rs:12:4 | LL | fn open_parent<'path>() { | ^^^^^^^^^^^ +help: remove the extra argument + | +LL - open_parent(&old_path) +LL + open_parent() + | error: aborting due to 7 previous errors diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr index 4352af1c0df76..3692cc77b0fb4 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr @@ -26,13 +26,14 @@ LL | type Foo = impl PartialEq<(Foo, i32)>; | -------------------------- the found opaque type ... LL | fn eq(&self, _other: &(Foo, i32)) -> bool { - | ^^^^^^^^^^^ - | | - | expected `a::Bar`, found opaque type - | help: change the parameter type to match the trait: `&(a::Bar, i32)` + | ^^^^^^^^^^^ expected `a::Bar`, found opaque type | = note: expected signature `fn(&a::Bar, &(a::Bar, _)) -> _` found signature `fn(&a::Bar, &(a::Foo, _)) -> _` +help: change the parameter type to match the trait + | +LL | fn eq(&self, _other: &(a::Bar, i32)) -> bool { + | ~~~~~~~~~~~~~~ error: unconstrained opaque type --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16 @@ -49,10 +50,7 @@ LL | type Foo = impl PartialEq<(Foo, i32)>; | -------------------------- the expected opaque type ... LL | fn eq(&self, _other: &(Bar, i32)) -> bool { - | ^^^^^^^^^^^ - | | - | expected opaque type, found `b::Bar` - | help: change the parameter type to match the trait: `&(b::Foo, i32)` + | ^^^^^^^^^^^ expected opaque type, found `b::Bar` | = note: expected signature `fn(&b::Bar, &(b::Foo, _)) -> _` found signature `fn(&b::Bar, &(b::Bar, _)) -> _` @@ -61,6 +59,10 @@ note: this item must have the opaque type in its signature in order to be able t | LL | fn eq(&self, _other: &(Bar, i32)) -> bool { | ^^ +help: change the parameter type to match the trait + | +LL | fn eq(&self, _other: &(b::Foo, i32)) -> bool { + | ~~~~~~~~~~~~~~ error: aborting due to 5 previous errors diff --git a/tests/ui/impl-trait/trait_type.stderr b/tests/ui/impl-trait/trait_type.stderr index 81e4c933e53f4..0eb132c7a1901 100644 --- a/tests/ui/impl-trait/trait_type.stderr +++ b/tests/ui/impl-trait/trait_type.stderr @@ -2,13 +2,14 @@ error[E0053]: method `fmt` has an incompatible type for trait --> $DIR/trait_type.rs:7:21 | LL | fn fmt(&self, x: &str) -> () { } - | ^^^^ - | | - | types differ in mutability - | help: change the parameter type to match the trait: `&mut Formatter<'_>` + | ^^^^ types differ in mutability | = note: expected signature `fn(&MyType, &mut Formatter<'_>) -> Result<(), std::fmt::Error>` found signature `fn(&MyType, &str)` +help: change the parameter type to match the trait + | +LL | fn fmt(&self, x: &mut Formatter<'_>) -> () { } + | ~~~~~~~~~~~~~~~~~~ error[E0050]: method `fmt` has 1 parameter but the declaration in trait `std::fmt::Display::fmt` has 2 --> $DIR/trait_type.rs:12:11 diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index bffe0447f8bb4..f0d259d01de94 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -397,10 +397,7 @@ LL | type Out = impl Debug; | ---------- the expected opaque type ... LL | fn in_trait_impl_return() -> impl Debug { () } - | ^^^^^^^^^^ - | | - | expected opaque type, found a different opaque type - | help: change the output type to match the trait: `<() as DummyTrait>::Out` + | ^^^^^^^^^^ expected opaque type, found a different opaque type | note: type in trait --> $DIR/where-allowed.rs:119:34 @@ -410,6 +407,10 @@ LL | fn in_trait_impl_return() -> Self::Out; = note: expected signature `fn() -> <() as DummyTrait>::Out` found signature `fn() -> impl Debug` = note: distinct uses of `impl Trait` result in different opaque types +help: change the output type to match the trait + | +LL | fn in_trait_impl_return() -> <() as DummyTrait>::Out { () } + | ~~~~~~~~~~~~~~~~~~~~~~~ error: unconstrained opaque type --> $DIR/where-allowed.rs:122:16 diff --git a/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr b/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr index e2ddf474c4a97..a5cd057e28421 100644 --- a/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr +++ b/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr @@ -55,16 +55,18 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/ice-ifer-var-leaked-out-of-rollback-122098.rs:21:31 | LL | LendingIterator::for_each(Query::new(&data), Box::new); - | ^^^^^^^^^^ ----- - | | - | unexpected argument of type `&fn() {data}` - | help: remove the extra argument + | ^^^^^^^^^^ ----- unexpected argument of type `&fn() {data}` | note: associated function defined here --> $DIR/ice-ifer-var-leaked-out-of-rollback-122098.rs:17:12 | LL | pub fn new() -> Self {} | ^^^ +help: remove the extra argument + | +LL - LendingIterator::for_each(Query::new(&data), Box::new); +LL + LendingIterator::for_each(Query::new(), Box::new); + | error: aborting due to 6 previous errors diff --git a/tests/ui/issues/issue-16939.stderr b/tests/ui/issues/issue-16939.stderr index 229ff9f181773..6e0889b89635b 100644 --- a/tests/ui/issues/issue-16939.stderr +++ b/tests/ui/issues/issue-16939.stderr @@ -2,16 +2,18 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/issue-16939.rs:5:9 | LL | |t| f(t); - | ^ - - | | - | unexpected argument - | help: remove the extra argument + | ^ - unexpected argument | note: callable defined here --> $DIR/issue-16939.rs:4:12 | LL | fn _foo (f: F) { | ^^^^ +help: remove the extra argument + | +LL - |t| f(t); +LL + |t| f(); + | error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-20225.stderr b/tests/ui/issues/issue-20225.stderr index 2d24a5bbd50ab..7d6b09cf7f893 100644 --- a/tests/ui/issues/issue-20225.stderr +++ b/tests/ui/issues/issue-20225.stderr @@ -4,13 +4,14 @@ error[E0053]: method `call` has an incompatible type for trait LL | impl<'a, T> Fn<(&'a T,)> for Foo { | - found this type parameter LL | extern "rust-call" fn call(&self, (_,): (T,)) {} - | ^^^^ - | | - | expected `&'a T`, found type parameter `T` - | help: change the parameter type to match the trait: `(&'a T,)` + | ^^^^ expected `&'a T`, found type parameter `T` | = note: expected signature `extern "rust-call" fn(&Foo, (&'a _,))` found signature `extern "rust-call" fn(&Foo, (_,))` +help: change the parameter type to match the trait + | +LL | extern "rust-call" fn call(&self, (_,): (&'a T,)) {} + | ~~~~~~~~ error[E0053]: method `call_mut` has an incompatible type for trait --> $DIR/issue-20225.rs:11:51 @@ -18,13 +19,14 @@ error[E0053]: method `call_mut` has an incompatible type for trait LL | impl<'a, T> FnMut<(&'a T,)> for Foo { | - found this type parameter LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {} - | ^^^^ - | | - | expected `&'a T`, found type parameter `T` - | help: change the parameter type to match the trait: `(&'a T,)` + | ^^^^ expected `&'a T`, found type parameter `T` | = note: expected signature `extern "rust-call" fn(&mut Foo, (&'a _,))` found signature `extern "rust-call" fn(&mut Foo, (_,))` +help: change the parameter type to match the trait + | +LL | extern "rust-call" fn call_mut(&mut self, (_,): (&'a T,)) {} + | ~~~~~~~~ error[E0053]: method `call_once` has an incompatible type for trait --> $DIR/issue-20225.rs:18:47 @@ -33,13 +35,14 @@ LL | impl<'a, T> FnOnce<(&'a T,)> for Foo { | - found this type parameter ... LL | extern "rust-call" fn call_once(self, (_,): (T,)) {} - | ^^^^ - | | - | expected `&'a T`, found type parameter `T` - | help: change the parameter type to match the trait: `(&'a T,)` + | ^^^^ expected `&'a T`, found type parameter `T` | = note: expected signature `extern "rust-call" fn(Foo, (&'a _,))` found signature `extern "rust-call" fn(Foo, (_,))` +help: change the parameter type to match the trait + | +LL | extern "rust-call" fn call_once(self, (_,): (&'a T,)) {} + | ~~~~~~~~ error: aborting due to 3 previous errors diff --git a/tests/ui/issues/issue-21332.stderr b/tests/ui/issues/issue-21332.stderr index 96e0f5fdb31db..7c960f7646db7 100644 --- a/tests/ui/issues/issue-21332.stderr +++ b/tests/ui/issues/issue-21332.stderr @@ -2,13 +2,14 @@ error[E0053]: method `next` has an incompatible type for trait --> $DIR/issue-21332.rs:5:27 | LL | fn next(&mut self) -> Result { Ok(7) } - | ^^^^^^^^^^^^^^^^ - | | - | expected `Option`, found `Result` - | help: change the output type to match the trait: `Option` + | ^^^^^^^^^^^^^^^^ expected `Option`, found `Result` | = note: expected signature `fn(&mut S) -> Option` found signature `fn(&mut S) -> Result` +help: change the output type to match the trait + | +LL | fn next(&mut self) -> Option { Ok(7) } + | ~~~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-4935.stderr b/tests/ui/issues/issue-4935.stderr index 25f299ae5f3bb..f18cf66f14d08 100644 --- a/tests/ui/issues/issue-4935.stderr +++ b/tests/ui/issues/issue-4935.stderr @@ -2,16 +2,18 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/issue-4935.rs:5:13 | LL | fn main() { foo(5, 6) } - | ^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/issue-4935.rs:3:4 | LL | fn foo(a: usize) {} | ^^^ -------- +help: remove the extra argument + | +LL - fn main() { foo(5, 6) } +LL + fn main() { foo(5) } + | error: aborting due to 1 previous error diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs index d28567f2859a3..afea249ffef0b 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs @@ -1,37 +1,15 @@ +//@ run-pass //@ edition: 2021 +//@ revisions: classic structural both #![allow(incomplete_features)] -#![feature(ref_pat_eat_one_layer_2024)] +#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))] + pub fn main() { - if let Some(Some(&x)) = &Some(&Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(Some(&x)) = &Some(Some(&0)) { + if let &Some(Some(x)) = &Some(&mut Some(0)) { let _: &u32 = x; - //~^ ERROR: mismatched types - } - if let Some(Some(&&x)) = &Some(Some(&0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(&Some(x)) = &Some(Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(Some(&x)) = &Some(&Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; } - if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { - //~^ ERROR: mismatched types + if let Some(&x) = Some(&mut 0) { let _: u32 = x; } } diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs new file mode 100644 index 0000000000000..d28567f2859a3 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs @@ -0,0 +1,37 @@ +//@ edition: 2021 +#![allow(incomplete_features)] +#![feature(ref_pat_eat_one_layer_2024)] +pub fn main() { + if let Some(Some(&x)) = &Some(&Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&x)) = &Some(Some(&0)) { + let _: &u32 = x; + //~^ ERROR: mismatched types + } + if let Some(Some(&&x)) = &Some(Some(&0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(&Some(x)) = &Some(Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&x)) = &Some(&Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } +} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr similarity index 88% rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr rename to tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr index 28706f89c066b..1a921234ea069 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:5:22 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:5:22 | LL | if let Some(Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -14,7 +14,7 @@ LL | if let Some(Some(x)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:10:23 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:10:23 | LL | let _: &u32 = x; | ---- ^ expected `&u32`, found integer @@ -27,7 +27,7 @@ LL | let _: &u32 = &x; | + error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:13:23 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:13:23 | LL | if let Some(Some(&&x)) = &Some(Some(&0)) { | ^^ --------------- this expression has type `&Option>` @@ -43,7 +43,7 @@ LL + if let Some(Some(&x)) = &Some(Some(&0)) { | error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:17:17 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:17:17 | LL | if let Some(&Some(x)) = &Some(Some(0)) { | ^^^^^^^^ -------------- this expression has type `&Option>` @@ -54,7 +54,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:21:22 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:21:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` @@ -64,7 +64,7 @@ LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/ref_pat_eat_one_layer_2021.rs:21:22 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:21:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ @@ -74,7 +74,7 @@ LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:25:22 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:25:22 | LL | if let Some(Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -89,7 +89,7 @@ LL | if let Some(Some(x)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:29:27 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:29:27 | LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -104,7 +104,7 @@ LL | if let Some(&mut Some(x)) = &Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:33:23 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:33:23 | LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -114,7 +114,7 @@ LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/ref_pat_eat_one_layer_2021.rs:33:23 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:33:23 | LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { | ^^^^^^ diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs index 0130189b874c6..c6a699d2ff8a9 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs @@ -63,4 +63,27 @@ pub fn main() { if let Some(&mut x) = &Some(&mut 0) { let _: &u32 = x; } + + fn generic() -> (R, bool) { + R::meow() + } + + trait Ref: Sized { + fn meow() -> (Self, bool); + } + + impl Ref for &'static [(); 0] { + fn meow() -> (Self, bool) { + (&[], false) + } + } + + impl Ref for &'static mut [(); 0] { + fn meow() -> (Self, bool) { + (&mut [], true) + } + } + + let (&_, b) = generic(); + assert!(!b); } diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr index f8931403774a3..0215df98ea16b 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr @@ -150,7 +150,20 @@ LL | let Foo(mut a) = &mut Foo(0); = help: add `#![feature(mut_ref)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 14 previous errors +error[E0277]: the trait bound `&_: main::Ref` is not satisfied + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:83:14 + | +LL | let &_ = generic(); + | ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_` + | + = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]` +note: required by a bound in `generic` + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:69:19 + | +LL | fn generic() -> R { + | ^^^ required by this bound in `generic` + +error: aborting due to 15 previous errors -Some errors have detailed explanations: E0308, E0658. -For more information about an error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0277, E0308, E0658. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr index 0010a612c30f1..9428b32c4affd 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr @@ -180,7 +180,20 @@ LL | let Foo(mut a) = &mut Foo(0); = help: add `#![feature(mut_ref)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 16 previous errors +error[E0277]: the trait bound `&_: main::Ref` is not satisfied + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:83:14 + | +LL | let &_ = generic(); + | ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_` + | + = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]` +note: required by a bound in `generic` + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:69:19 + | +LL | fn generic() -> R { + | ^^^ required by this bound in `generic` + +error: aborting due to 17 previous errors -Some errors have detailed explanations: E0308, E0658. -For more information about an error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0277, E0308, E0658. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs index 4a40060b2ea40..d23e9c8083d9f 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs @@ -65,4 +65,20 @@ pub fn main() { let Foo(mut a) = &mut Foo(0); //~^ ERROR: binding cannot be both mutable and by-reference a = &mut 42; + + fn generic() -> R { + R::meow() + } + + trait Ref: Sized { + fn meow() -> Self; + } + + impl Ref for &'static mut [(); 0] { + fn meow() -> Self { + &mut [] + } + } + + let &_ = generic(); //~ERROR: the trait bound `&_: main::Ref` is not satisfied [E0277] } diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr index 379bb6f4eaab3..56dad6050305b 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr @@ -161,7 +161,20 @@ LL | let Foo(mut a) = &mut Foo(0); = help: add `#![feature(mut_ref)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 15 previous errors +error[E0277]: the trait bound `&_: main::Ref` is not satisfied + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:83:14 + | +LL | let &_ = generic(); + | ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_` + | + = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]` +note: required by a bound in `generic` + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:69:19 + | +LL | fn generic() -> R { + | ^^^ required by this bound in `generic` + +error: aborting due to 16 previous errors -Some errors have detailed explanations: E0308, E0658. -For more information about an error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0277, E0308, E0658. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr index 5a76449e9f95b..0855a17b33394 100644 --- a/tests/ui/methods/method-call-err-msg.stderr +++ b/tests/ui/methods/method-call-err-msg.stderr @@ -2,16 +2,18 @@ error[E0061]: this method takes 0 arguments but 1 argument was supplied --> $DIR/method-call-err-msg.rs:13:7 | LL | x.zero(0) - | ^^^^ - - | | - | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^ - unexpected argument of type `{integer}` | note: method defined here --> $DIR/method-call-err-msg.rs:5:8 | LL | fn zero(self) -> Foo { self } | ^^^^ +help: remove the extra argument + | +LL - x.zero(0) +LL + x.zero() + | error[E0061]: this method takes 1 argument but 0 arguments were supplied --> $DIR/method-call-err-msg.rs:14:7 diff --git a/tests/ui/mismatched_types/E0053.stderr b/tests/ui/mismatched_types/E0053.stderr index d0bd5b46cf59f..2559d4487491e 100644 --- a/tests/ui/mismatched_types/E0053.stderr +++ b/tests/ui/mismatched_types/E0053.stderr @@ -2,10 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/E0053.rs:9:15 | LL | fn foo(x: i16) { } - | ^^^ - | | - | expected `u16`, found `i16` - | help: change the parameter type to match the trait: `u16` + | ^^^ expected `u16`, found `i16` | note: type in trait --> $DIR/E0053.rs:2:15 @@ -14,15 +11,16 @@ LL | fn foo(x: u16); | ^^^ = note: expected signature `fn(u16)` found signature `fn(i16)` +help: change the parameter type to match the trait + | +LL | fn foo(x: u16) { } + | ~~~ error[E0053]: method `bar` has an incompatible type for trait --> $DIR/E0053.rs:11:12 | LL | fn bar(&mut self) { } - | ^^^^^^^^^ - | | - | types differ in mutability - | help: change the self-receiver type to match the trait: `&self` + | ^^^^^^^^^ types differ in mutability | note: type in trait --> $DIR/E0053.rs:3:12 @@ -31,6 +29,10 @@ LL | fn bar(&self); | ^^^^^ = note: expected signature `fn(&Bar)` found signature `fn(&mut Bar)` +help: change the self-receiver type to match the trait + | +LL | fn bar(&self) { } + | ~~~~~ error: aborting due to 2 previous errors diff --git a/tests/ui/mismatched_types/issue-112036.stderr b/tests/ui/mismatched_types/issue-112036.stderr index b93ce4a8674c2..bd446b3d78cb2 100644 --- a/tests/ui/mismatched_types/issue-112036.stderr +++ b/tests/ui/mismatched_types/issue-112036.stderr @@ -2,13 +2,14 @@ error[E0053]: method `drop` has an incompatible type for trait --> $DIR/issue-112036.rs:4:13 | LL | fn drop(self) {} - | ^^^^ - | | - | expected `&mut Foo`, found `Foo` - | help: change the self-receiver type to match the trait: `&mut self` + | ^^^^ expected `&mut Foo`, found `Foo` | = note: expected signature `fn(&mut Foo)` found signature `fn(Foo)` +help: change the self-receiver type to match the trait + | +LL | fn drop(&mut self) {} + | ~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/mismatched_types/issue-13033.stderr b/tests/ui/mismatched_types/issue-13033.stderr index 4886fa30e89b1..2a266d40e7717 100644 --- a/tests/ui/mismatched_types/issue-13033.stderr +++ b/tests/ui/mismatched_types/issue-13033.stderr @@ -2,10 +2,7 @@ error[E0053]: method `bar` has an incompatible type for trait --> $DIR/issue-13033.rs:8:30 | LL | fn bar(&mut self, other: &dyn Foo) {} - | ^^^^^^^^ - | | - | types differ in mutability - | help: change the parameter type to match the trait: `&mut dyn Foo` + | ^^^^^^^^ types differ in mutability | note: type in trait --> $DIR/issue-13033.rs:2:30 @@ -14,6 +11,10 @@ LL | fn bar(&mut self, other: &mut dyn Foo); | ^^^^^^^^^^^^ = note: expected signature `fn(&mut Baz, &mut dyn Foo)` found signature `fn(&mut Baz, &dyn Foo)` +help: change the parameter type to match the trait + | +LL | fn bar(&mut self, other: &mut dyn Foo) {} + | ~~~~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr index 6e7bf5eb46d92..2e544a62223a0 100644 --- a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr +++ b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr @@ -2,10 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/trait-impl-fn-incompatibility.rs:9:15 | LL | fn foo(x: i16) { } - | ^^^ - | | - | expected `u16`, found `i16` - | help: change the parameter type to match the trait: `u16` + | ^^^ expected `u16`, found `i16` | note: type in trait --> $DIR/trait-impl-fn-incompatibility.rs:2:15 @@ -14,15 +11,16 @@ LL | fn foo(x: u16); | ^^^ = note: expected signature `fn(u16)` found signature `fn(i16)` +help: change the parameter type to match the trait + | +LL | fn foo(x: u16) { } + | ~~~ error[E0053]: method `bar` has an incompatible type for trait --> $DIR/trait-impl-fn-incompatibility.rs:10:28 | LL | fn bar(&mut self, bar: &Bar) { } - | ^^^^ - | | - | types differ in mutability - | help: change the parameter type to match the trait: `&mut Bar` + | ^^^^ types differ in mutability | note: type in trait --> $DIR/trait-impl-fn-incompatibility.rs:3:28 @@ -31,6 +29,10 @@ LL | fn bar(&mut self, bar: &mut Bar); | ^^^^^^^^ = note: expected signature `fn(&mut Bar, &mut Bar)` found signature `fn(&mut Bar, &Bar)` +help: change the parameter type to match the trait + | +LL | fn bar(&mut self, bar: &mut Bar) { } + | ~~~~~~~~ error: aborting due to 2 previous errors diff --git a/tests/ui/range/issue-54505-no-std.stderr b/tests/ui/range/issue-54505-no-std.stderr index 1694d514f4251..f15a0ae61389a 100644 --- a/tests/ui/range/issue-54505-no-std.stderr +++ b/tests/ui/range/issue-54505-no-std.stderr @@ -7,7 +7,7 @@ LL | take_range(0..1); | arguments to this function are incorrect | = note: expected reference `&_` - found struct `Range<{integer}>` + found struct `core::ops::Range<{integer}>` note: function defined here --> $DIR/issue-54505-no-std.rs:25:4 | @@ -27,7 +27,7 @@ LL | take_range(1..); | arguments to this function are incorrect | = note: expected reference `&_` - found struct `RangeFrom<{integer}>` + found struct `core::ops::RangeFrom<{integer}>` note: function defined here --> $DIR/issue-54505-no-std.rs:25:4 | @@ -67,7 +67,7 @@ LL | take_range(0..=1); | arguments to this function are incorrect | = note: expected reference `&_` - found struct `RangeInclusive<{integer}>` + found struct `core::ops::RangeInclusive<{integer}>` note: function defined here --> $DIR/issue-54505-no-std.rs:25:4 | diff --git a/tests/ui/resolve/resolve-primitive-fallback.stderr b/tests/ui/resolve/resolve-primitive-fallback.stderr index e3a5d4edcf102..d0583966459be 100644 --- a/tests/ui/resolve/resolve-primitive-fallback.stderr +++ b/tests/ui/resolve/resolve-primitive-fallback.stderr @@ -24,13 +24,15 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/resolve-primitive-fallback.rs:3:5 | LL | std::mem::size_of(u16); - | ^^^^^^^^^^^^^^^^^ --- - | | - | unexpected argument - | help: remove the extra argument + | ^^^^^^^^^^^^^^^^^ --- unexpected argument | note: function defined here --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +help: remove the extra argument + | +LL - std::mem::size_of(u16); +LL + std::mem::size_of(); + | error: aborting due to 3 previous errors diff --git a/tests/ui/span/issue-34264.stderr b/tests/ui/span/issue-34264.stderr index f0dea66f6128d..89c67719b5ae2 100644 --- a/tests/ui/span/issue-34264.stderr +++ b/tests/ui/span/issue-34264.stderr @@ -54,16 +54,18 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/issue-34264.rs:7:5 | LL | foo(Some(42), 2, ""); - | ^^^ ---- - | | | - | | unexpected argument of type `&'static str` - | help: remove the extra argument + | ^^^ -- unexpected argument of type `&'static str` | note: function defined here --> $DIR/issue-34264.rs:1:4 | LL | fn foo(Option, String) {} | ^^^ ----------- ------ +help: remove the extra argument + | +LL - foo(Some(42), 2, ""); +LL + foo(Some(42), 2); + | error[E0308]: mismatched types --> $DIR/issue-34264.rs:8:13 @@ -83,16 +85,18 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/issue-34264.rs:10:5 | LL | bar(1, 2, 3); - | ^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/issue-34264.rs:3:4 | LL | fn bar(x, y: usize) {} | ^^^ - -------- +help: remove the extra argument + | +LL - bar(1, 2, 3); +LL + bar(1, 2); + | error: aborting due to 6 previous errors diff --git a/tests/ui/traits/issue-35869.stderr b/tests/ui/traits/issue-35869.stderr index 6d985bdeaf859..503f9cee246e9 100644 --- a/tests/ui/traits/issue-35869.stderr +++ b/tests/ui/traits/issue-35869.stderr @@ -2,10 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/issue-35869.rs:11:15 | LL | fn foo(_: fn(u16) -> ()) {} - | ^^^^^^^^^^^^^ - | | - | expected `u8`, found `u16` - | help: change the parameter type to match the trait: `fn(u8)` + | ^^^^^^^^^^^^^ expected `u8`, found `u16` | note: type in trait --> $DIR/issue-35869.rs:2:15 @@ -14,15 +11,16 @@ LL | fn foo(_: fn(u8) -> ()); | ^^^^^^^^^^^^ = note: expected signature `fn(fn(u8))` found signature `fn(fn(u16))` +help: change the parameter type to match the trait + | +LL | fn foo(_: fn(u8)) {} + | ~~~~~~ error[E0053]: method `bar` has an incompatible type for trait --> $DIR/issue-35869.rs:13:15 | LL | fn bar(_: Option) {} - | ^^^^^^^^^^^ - | | - | expected `u8`, found `u16` - | help: change the parameter type to match the trait: `Option` + | ^^^^^^^^^^^ expected `u8`, found `u16` | note: type in trait --> $DIR/issue-35869.rs:3:15 @@ -31,15 +29,16 @@ LL | fn bar(_: Option); | ^^^^^^^^^^ = note: expected signature `fn(Option)` found signature `fn(Option)` +help: change the parameter type to match the trait + | +LL | fn bar(_: Option) {} + | ~~~~~~~~~~ error[E0053]: method `baz` has an incompatible type for trait --> $DIR/issue-35869.rs:15:15 | LL | fn baz(_: (u16, u16)) {} - | ^^^^^^^^^^ - | | - | expected `u8`, found `u16` - | help: change the parameter type to match the trait: `(u8, u16)` + | ^^^^^^^^^^ expected `u8`, found `u16` | note: type in trait --> $DIR/issue-35869.rs:4:15 @@ -48,15 +47,16 @@ LL | fn baz(_: (u8, u16)); | ^^^^^^^^^ = note: expected signature `fn((u8, _))` found signature `fn((u16, _))` +help: change the parameter type to match the trait + | +LL | fn baz(_: (u8, u16)) {} + | ~~~~~~~~~ error[E0053]: method `qux` has an incompatible type for trait --> $DIR/issue-35869.rs:17:17 | LL | fn qux() -> u16 { 5u16 } - | ^^^ - | | - | expected `u8`, found `u16` - | help: change the output type to match the trait: `u8` + | ^^^ expected `u8`, found `u16` | note: type in trait --> $DIR/issue-35869.rs:5:17 @@ -65,6 +65,10 @@ LL | fn qux() -> u8; | ^^ = note: expected signature `fn() -> u8` found signature `fn() -> u16` +help: change the output type to match the trait + | +LL | fn qux() -> u8 { 5u16 } + | ~~ error: aborting due to 4 previous errors diff --git a/tests/ui/traits/wrong-mul-method-signature.stderr b/tests/ui/traits/wrong-mul-method-signature.stderr index 91162cbc1231f..e30b61622ae01 100644 --- a/tests/ui/traits/wrong-mul-method-signature.stderr +++ b/tests/ui/traits/wrong-mul-method-signature.stderr @@ -2,37 +2,40 @@ error[E0053]: method `mul` has an incompatible type for trait --> $DIR/wrong-mul-method-signature.rs:16:21 | LL | fn mul(self, s: &f64) -> Vec1 { - | ^^^^ - | | - | expected `f64`, found `&f64` - | help: change the parameter type to match the trait: `f64` + | ^^^^ expected `f64`, found `&f64` | = note: expected signature `fn(Vec1, _) -> Vec1` found signature `fn(Vec1, &_) -> Vec1` +help: change the parameter type to match the trait + | +LL | fn mul(self, s: f64) -> Vec1 { + | ~~~ error[E0053]: method `mul` has an incompatible type for trait --> $DIR/wrong-mul-method-signature.rs:33:21 | LL | fn mul(self, s: f64) -> Vec2 { - | ^^^ - | | - | expected `Vec2`, found `f64` - | help: change the parameter type to match the trait: `Vec2` + | ^^^ expected `Vec2`, found `f64` | = note: expected signature `fn(Vec2, Vec2) -> f64` found signature `fn(Vec2, f64) -> Vec2` +help: change the parameter type to match the trait + | +LL | fn mul(self, s: Vec2) -> Vec2 { + | ~~~~ error[E0053]: method `mul` has an incompatible type for trait --> $DIR/wrong-mul-method-signature.rs:52:29 | LL | fn mul(self, s: f64) -> f64 { - | ^^^ - | | - | expected `i32`, found `f64` - | help: change the output type to match the trait: `i32` + | ^^^ expected `i32`, found `f64` | = note: expected signature `fn(Vec3, _) -> i32` found signature `fn(Vec3, _) -> f64` +help: change the output type to match the trait + | +LL | fn mul(self, s: f64) -> i32 { + | ~~~ error[E0308]: mismatched types --> $DIR/wrong-mul-method-signature.rs:63:45 diff --git a/tests/ui/tuple/wrong_argument_ice-4.stderr b/tests/ui/tuple/wrong_argument_ice-4.stderr index 3c7d6699be2b5..10191faf7bf03 100644 --- a/tests/ui/tuple/wrong_argument_ice-4.stderr +++ b/tests/ui/tuple/wrong_argument_ice-4.stderr @@ -6,16 +6,21 @@ LL | (|| {})(|| { LL | | LL | | let b = 1; LL | | }); - | | - - | | | - | |_____unexpected argument of type `{closure@$DIR/wrong_argument_ice-4.rs:2:13: 2:15}` - | help: remove the extra argument + | |_____- unexpected argument of type `{closure@$DIR/wrong_argument_ice-4.rs:2:13: 2:15}` | note: closure defined here --> $DIR/wrong_argument_ice-4.rs:2:6 | LL | (|| {})(|| { | ^^ +help: remove the extra argument + | +LL - (|| {})(|| { +LL - +LL - let b = 1; +LL - }); +LL + (|| {})(); + | error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.stderr b/tests/ui/type-alias-impl-trait/unnameable_type.stderr index f567b01d29a1b..5b331c5660d9c 100644 --- a/tests/ui/type-alias-impl-trait/unnameable_type.stderr +++ b/tests/ui/type-alias-impl-trait/unnameable_type.stderr @@ -5,10 +5,7 @@ LL | type MyPrivate = impl Sized; | ---------- the found opaque type LL | impl Trait for u32 { LL | fn dont_define_this(private: MyPrivate) { - | ^^^^^^^^^ - | | - | expected `Private`, found opaque type - | help: change the parameter type to match the trait: `Private` + | ^^^^^^^^^ expected `Private`, found opaque type | note: type in trait --> $DIR/unnameable_type.rs:10:39 @@ -17,6 +14,10 @@ LL | fn dont_define_this(_private: Private) {} | ^^^^^^^ = note: expected signature `fn(Private)` found signature `fn(MyPrivate)` +help: change the parameter type to match the trait + | +LL | fn dont_define_this(private: Private) { + | ~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/type/type-ascription-instead-of-initializer.stderr b/tests/ui/type/type-ascription-instead-of-initializer.stderr index efa917334bf0c..224ff6e740486 100644 --- a/tests/ui/type/type-ascription-instead-of-initializer.stderr +++ b/tests/ui/type/type-ascription-instead-of-initializer.stderr @@ -11,13 +11,15 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/type-ascription-instead-of-initializer.rs:2:12 | LL | let x: Vec::with_capacity(10, 20); - | ^^^^^^^^^^^^^^^^^^ ---- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^^^^^^^^^^^^ -- unexpected argument of type `{integer}` | note: associated function defined here --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL +help: remove the extra argument + | +LL - let x: Vec::with_capacity(10, 20); +LL + let x: Vec::with_capacity(10); + | error: aborting due to 2 previous errors diff --git a/tests/ui/typeck/mismatched-map-under-self.stderr b/tests/ui/typeck/mismatched-map-under-self.stderr index 322bf349f92fc..59de00a58bbea 100644 --- a/tests/ui/typeck/mismatched-map-under-self.stderr +++ b/tests/ui/typeck/mismatched-map-under-self.stderr @@ -2,10 +2,7 @@ error[E0053]: method `values` has an incompatible type for trait --> $DIR/mismatched-map-under-self.rs:10:15 | LL | fn values(self) -> Self::Values { - | ^^^^ - | | - | expected `&Option`, found `Option` - | help: change the self-receiver type to match the trait: `&self` + | ^^^^ expected `&Option`, found `Option` | note: type in trait --> $DIR/mismatched-map-under-self.rs:4:15 @@ -14,6 +11,10 @@ LL | fn values(&self) -> Self::Values; | ^^^^^ = note: expected signature `fn(&Option<_>)` found signature `fn(Option<_>)` +help: change the self-receiver type to match the trait + | +LL | fn values(&self) -> Self::Values { + | ~~~~~ error[E0631]: type mismatch in function arguments --> $DIR/mismatched-map-under-self.rs:12:18 diff --git a/tests/ui/typeck/remove-extra-argument.stderr b/tests/ui/typeck/remove-extra-argument.stderr index 9557c41457dcd..4bab2959651b7 100644 --- a/tests/ui/typeck/remove-extra-argument.stderr +++ b/tests/ui/typeck/remove-extra-argument.stderr @@ -2,16 +2,18 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/remove-extra-argument.rs:6:5 | LL | l(vec![], vec![]) - | ^ -------- - | | | - | | unexpected argument of type `Vec<_>` - | help: remove the extra argument + | ^ ------ unexpected argument of type `Vec<_>` | note: function defined here --> $DIR/remove-extra-argument.rs:3:4 | LL | fn l(_a: Vec) {} | ^ ----------- +help: remove the extra argument + | +LL - l(vec![], vec![]) +LL + l(vec![]) + | error: aborting due to 1 previous error diff --git a/tests/ui/typeck/struct-enum-wrong-args.stderr b/tests/ui/typeck/struct-enum-wrong-args.stderr index 57cbd1d2005c3..d005eca841ecb 100644 --- a/tests/ui/typeck/struct-enum-wrong-args.stderr +++ b/tests/ui/typeck/struct-enum-wrong-args.stderr @@ -2,13 +2,15 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:6:13 | LL | let _ = Some(3, 2); - | ^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^ - unexpected argument of type `{integer}` | note: tuple variant defined here --> $SRC_DIR/core/src/option.rs:LL:COL +help: remove the extra argument + | +LL - let _ = Some(3, 2); +LL + let _ = Some(3); + | error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:7:13 @@ -59,16 +61,18 @@ error[E0061]: this struct takes 1 argument but 2 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:10:13 | LL | let _ = Wrapper(5, 2); - | ^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^ - unexpected argument of type `{integer}` | note: tuple struct defined here --> $DIR/struct-enum-wrong-args.rs:2:8 | LL | struct Wrapper(i32); | ^^^^^^^ +help: remove the extra argument + | +LL - let _ = Wrapper(5, 2); +LL + let _ = Wrapper(5); + | error[E0061]: this struct takes 2 arguments but 0 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:11:13 @@ -106,16 +110,18 @@ error[E0061]: this struct takes 2 arguments but 3 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:13:13 | LL | let _ = DoubleWrapper(5, 2, 7); - | ^^^^^^^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^^^^^^^ - unexpected argument of type `{integer}` | note: tuple struct defined here --> $DIR/struct-enum-wrong-args.rs:3:8 | LL | struct DoubleWrapper(i32, i32); | ^^^^^^^^^^^^^ +help: remove the extra argument + | +LL - let _ = DoubleWrapper(5, 2, 7); +LL + let _ = DoubleWrapper(5, 2); + | error: aborting due to 8 previous errors diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr index c48d094daea20..2a8c4edbdb5f3 100644 --- a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr +++ b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr @@ -2,10 +2,7 @@ error[E0053]: method `dummy2` has an incompatible type for trait --> $DIR/ufcs-explicit-self-bad.rs:37:21 | LL | fn dummy2(self: &Bar) {} - | ------^^^^^^^ - | | | - | | expected `&'a Bar`, found `Bar` - | help: change the self-receiver type to match the trait: `&self` + | ^^^^^^^ expected `&'a Bar`, found `Bar` | note: type in trait --> $DIR/ufcs-explicit-self-bad.rs:31:15 @@ -14,6 +11,10 @@ LL | fn dummy2(&self); | ^^^^^ = note: expected signature `fn(&&'a Bar<_>)` found signature `fn(&Bar<_>)` +help: change the self-receiver type to match the trait + | +LL | fn dummy2(&self) {} + | ~~~~~ error[E0307]: invalid `self` parameter type: `isize` --> $DIR/ufcs-explicit-self-bad.rs:8:18