Auto merge of #128927 - GuillaumeGomez:rollup-ei2lr0f, r=GuillaumeGomez

Rollup of 8 pull requests

Successful merges:

 - #128273 (Improve `Ord` violation help)
 - #128807 (run-make: explaing why fmt-write-bloat is ignore-windows)
 - #128903 (rustdoc-json-types `Discriminant`: fix typo)
 - #128905 (gitignore: Add Zed and Helix editors)
 - #128908 (diagnostics: do not warn when a lifetime bound infers itself)
 - #128909 (Fix dump-ice-to-disk for RUSTC_ICE=0 users)
 - #128910 (Differentiate between methods and associated functions in diagnostics)
 - #128923 ([rustdoc] Stop showing impl items for negative impls)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-08-10 15:13:38 +00:00
commit 04ba50e823
52 changed files with 368 additions and 191 deletions

2
.gitignore vendored
View File

@ -20,6 +20,8 @@ Session.vim
.vscode
.project
.vim/
.helix/
.zed/
.favorites.json
.settings/
.vs/

View File

@ -1117,7 +1117,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
.dcx()
.create_err(LifetimesOrBoundsMismatchOnTrait {
span,
item_kind: assoc_item_kind_str(&impl_m),
item_kind: impl_m.descr(),
ident: impl_m.ident(tcx),
generics_span,
bounds_span,
@ -1294,7 +1294,7 @@ fn compare_number_of_generics<'tcx>(
("const", trait_own_counts.consts, impl_own_counts.consts),
];
let item_kind = assoc_item_kind_str(&impl_);
let item_kind = impl_.descr();
let mut err_occurred = None;
for (kind, trait_count, impl_count) in matchings {
@ -1676,7 +1676,7 @@ fn compare_generic_param_kinds<'tcx>(
param_impl_span,
E0053,
"{} `{}` has an incompatible generic parameter for trait `{}`",
assoc_item_kind_str(&impl_item),
impl_item.descr(),
trait_item.name,
&tcx.def_path_str(tcx.parent(trait_item.def_id))
);
@ -2249,14 +2249,6 @@ fn param_env_with_gat_bounds<'tcx>(
ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing)
}
fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str {
match impl_item.kind {
ty::AssocKind::Const => "const",
ty::AssocKind::Fn => "method",
ty::AssocKind::Type => "type",
}
}
/// Manually check here that `async fn foo()` wasn't matched against `fn foo()`,
/// and extract a better error if so.
fn try_report_async_mismatch<'tcx>(

View File

@ -1924,14 +1924,13 @@ fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
impl ExplicitOutlivesRequirements {
fn lifetimes_outliving_lifetime<'tcx>(
tcx: TyCtxt<'tcx>,
inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)],
inferred_outlives: impl Iterator<Item = &'tcx (ty::Clause<'tcx>, Span)>,
item: DefId,
lifetime: DefId,
) -> Vec<ty::Region<'tcx>> {
let item_generics = tcx.generics_of(item);
inferred_outlives
.iter()
.filter_map(|(clause, _)| match clause.kind().skip_binder() {
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a {
ty::ReEarlyParam(ebr)
@ -1947,11 +1946,10 @@ fn lifetimes_outliving_lifetime<'tcx>(
}
fn lifetimes_outliving_type<'tcx>(
inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)],
inferred_outlives: impl Iterator<Item = &'tcx (ty::Clause<'tcx>, Span)>,
index: u32,
) -> Vec<ty::Region<'tcx>> {
inferred_outlives
.iter()
.filter_map(|(clause, _)| match clause.kind().skip_binder() {
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => {
a.is_param(index).then_some(b)
@ -2094,7 +2092,11 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
(
Self::lifetimes_outliving_lifetime(
cx.tcx,
inferred_outlives,
// don't warn if the inferred span actually came from the predicate we're looking at
// this happens if the type is recursively defined
inferred_outlives
.iter()
.filter(|(_, span)| !predicate.span.contains(*span)),
item.owner_id.to_def_id(),
region_def_id,
),
@ -2116,7 +2118,14 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
};
let index = ty_generics.param_def_id_to_index[&def_id];
(
Self::lifetimes_outliving_type(inferred_outlives, index),
Self::lifetimes_outliving_type(
// don't warn if the inferred span actually came from the predicate we're looking at
// this happens if the type is recursively defined
inferred_outlives.iter().filter(|(_, span)| {
!predicate.span.contains(*span)
}),
index,
),
&predicate.bounds,
predicate.span,
predicate.origin == PredicateOrigin::WhereClause,

View File

@ -1165,17 +1165,23 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
}
Node::ImplItem(ii) => {
let kind = match ii.kind {
ImplItemKind::Const(..) => "assoc const",
ImplItemKind::Fn(..) => "method",
ImplItemKind::Type(_) => "assoc type",
ImplItemKind::Const(..) => "associated constant",
ImplItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self {
ImplicitSelfKind::None => "associated function",
_ => "method",
},
ImplItemKind::Type(_) => "associated type",
};
format!("{id} ({kind} `{}` in {})", ii.ident, path_str(ii.owner_id.def_id))
}
Node::TraitItem(ti) => {
let kind = match ti.kind {
TraitItemKind::Const(..) => "assoc constant",
TraitItemKind::Fn(..) => "trait method",
TraitItemKind::Type(..) => "assoc type",
TraitItemKind::Const(..) => "associated constant",
TraitItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self {
ImplicitSelfKind::None => "associated function",
_ => "trait method",
},
TraitItemKind::Type(..) => "associated type",
};
format!("{id} ({kind} `{}` in {})", ti.ident, path_str(ti.owner_id.def_id))

View File

@ -98,6 +98,15 @@ pub fn signature(&self, tcx: TyCtxt<'_>) -> String {
}
}
pub fn descr(&self) -> &'static str {
match self.kind {
ty::AssocKind::Const => "const",
ty::AssocKind::Fn if self.fn_has_self_parameter => "method",
ty::AssocKind::Fn => "associated function",
ty::AssocKind::Type => "type",
}
}
pub fn is_impl_trait_in_trait(&self) -> bool {
self.opt_rpitit_info.is_some()
}

View File

@ -178,15 +178,25 @@ impl<T> [T] {
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*))
/// worst-case.
///
/// If `T: Ord` does not implement a total order the resulting order is unspecified. All
/// original elements will remain in the slice and any possible modifications via interior
/// mutability are observed in the input. Same is true if `T: Ord` panics.
/// If the implementation of [`Ord`] for `T` does not implement a [total order] the resulting
/// order of elements in the slice is unspecified. All original elements will remain in the
/// slice and any possible modifications via interior mutability are observed in the input. Same
/// is true if the implementation of [`Ord`] for `T` panics.
///
/// When applicable, unstable sorting is preferred because it is generally faster than stable
/// sorting and it doesn't allocate auxiliary memory. See
/// [`sort_unstable`](slice::sort_unstable). The exception are partially sorted slices, which
/// may be better served with `slice::sort`.
///
/// Sorting types that only implement [`PartialOrd`] such as [`f32`] and [`f64`] require
/// additional precautions. For example, `f32::NAN != f32::NAN`, which doesn't fulfill the
/// reflexivity requirement of [`Ord`]. By using an alternative comparison function with
/// `slice::sort_by` such as [`f32::total_cmp`] or [`f64::total_cmp`] that defines a [total
/// order] users can sort slices containing floating-point values. Alternatively, if all values
/// in the slice are guaranteed to be in a subset for which [`PartialOrd::partial_cmp`] forms a
/// [total order], it's possible to sort the slice with `sort_by(|a, b|
/// a.partial_cmp(b).unwrap())`.
///
/// # Current implementation
///
/// The current implementation is based on [driftsort] by Orson Peters and Lukas Bergdoll, which
@ -198,18 +208,21 @@ impl<T> [T] {
/// handled without allocation, medium sized slices allocate `self.len()` and beyond that it
/// clamps at `self.len() / 2`.
///
/// If `T: Ord` does not implement a total order, the implementation may panic.
/// # Panics
///
/// May panic if the implementation of [`Ord`] for `T` does not implement a [total order].
///
/// # Examples
///
/// ```
/// let mut v = [-5, 4, 1, -3, 2];
/// let mut v = [4, -5, 1, -3, 2];
///
/// v.sort();
/// assert!(v == [-5, -3, 1, 2, 4]);
/// assert_eq!(v, [-5, -3, 1, 2, 4]);
/// ```
///
/// [driftsort]: https://github.com/Voultapher/driftsort
/// [total order]: https://en.wikipedia.org/wiki/Total_order
#[cfg(not(no_global_oom_handling))]
#[rustc_allow_incoherent_impl]
#[stable(feature = "rust1", since = "1.0.0")]
@ -221,30 +234,19 @@ pub fn sort(&mut self)
stable_sort(self, T::lt);
}
/// Sorts the slice with a comparator function, preserving initial order of equal elements.
/// Sorts the slice with a comparison function, preserving initial order of equal elements.
///
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*))
/// worst-case.
///
/// The comparator function should define a total ordering for the elements in the slice. If the
/// ordering is not total, the order of the elements is unspecified.
/// If the comparison function `compare` does not implement a [total order] the resulting order
/// of elements in the slice is unspecified. All original elements will remain in the slice and
/// any possible modifications via interior mutability are observed in the input. Same is true
/// if `compare` panics.
///
/// If the comparator function does not implement a total order the resulting order is
/// unspecified. All original elements will remain in the slice and any possible modifications
/// via interior mutability are observed in the input. Same is true if the comparator function
/// panics. A total order (for all `a`, `b` and `c`):
///
/// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and
/// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
///
/// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use
/// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`.
///
/// ```
/// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
/// floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
/// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
/// ```
/// For example `|a, b| (a - b).cmp(a)` is a comparison function that is neither transitive nor
/// reflexive nor total, `a < b < c < a` with `a = 1, b = 2, c = 3`. For more information and
/// examples see the [`Ord`] documentation.
///
/// # Current implementation
///
@ -257,21 +259,24 @@ pub fn sort(&mut self)
/// handled without allocation, medium sized slices allocate `self.len()` and beyond that it
/// clamps at `self.len() / 2`.
///
/// If `T: Ord` does not implement a total order, the implementation may panic.
/// # Panics
///
/// May panic if `compare` does not implement a [total order].
///
/// # Examples
///
/// ```
/// let mut v = [5, 4, 1, 3, 2];
/// let mut v = [4, -5, 1, -3, 2];
/// v.sort_by(|a, b| a.cmp(b));
/// assert!(v == [1, 2, 3, 4, 5]);
/// assert_eq!(v, [-5, -3, 1, 2, 4]);
///
/// // reverse sorting
/// v.sort_by(|a, b| b.cmp(a));
/// assert!(v == [5, 4, 3, 2, 1]);
/// assert_eq!(v, [4, 2, 1, -3, -5]);
/// ```
///
/// [driftsort]: https://github.com/Voultapher/driftsort
/// [total order]: https://en.wikipedia.org/wiki/Total_order
#[cfg(not(no_global_oom_handling))]
#[rustc_allow_incoherent_impl]
#[stable(feature = "rust1", since = "1.0.0")]
@ -288,9 +293,10 @@ pub fn sort_by<F>(&mut self, mut compare: F)
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* \* log(*n*))
/// worst-case, where the key function is *O*(*m*).
///
/// If `K: Ord` does not implement a total order the resulting order is unspecified.
/// All original elements will remain in the slice and any possible modifications via interior
/// mutability are observed in the input. Same is true if `K: Ord` panics.
/// If the implementation of [`Ord`] for `K` does not implement a [total order] the resulting
/// order of elements in the slice is unspecified. All original elements will remain in the
/// slice and any possible modifications via interior mutability are observed in the input. Same
/// is true if the implementation of [`Ord`] for `K` panics.
///
/// # Current implementation
///
@ -303,18 +309,21 @@ pub fn sort_by<F>(&mut self, mut compare: F)
/// handled without allocation, medium sized slices allocate `self.len()` and beyond that it
/// clamps at `self.len() / 2`.
///
/// If `K: Ord` does not implement a total order, the implementation may panic.
/// # Panics
///
/// May panic if the implementation of [`Ord`] for `K` does not implement a [total order].
///
/// # Examples
///
/// ```
/// let mut v = [-5i32, 4, 1, -3, 2];
/// let mut v = [4i32, -5, 1, -3, 2];
///
/// v.sort_by_key(|k| k.abs());
/// assert!(v == [1, 2, -3, 4, -5]);
/// assert_eq!(v, [1, 2, -3, 4, -5]);
/// ```
///
/// [driftsort]: https://github.com/Voultapher/driftsort
/// [total order]: https://en.wikipedia.org/wiki/Total_order
#[cfg(not(no_global_oom_handling))]
#[rustc_allow_incoherent_impl]
#[stable(feature = "slice_sort_by_key", since = "1.7.0")]
@ -336,9 +345,10 @@ pub fn sort_by_key<K, F>(&mut self, mut f: F)
/// storage to remember the results of key evaluation. The order of calls to the key function is
/// unspecified and may change in future versions of the standard library.
///
/// If `K: Ord` does not implement a total order the resulting order is unspecified.
/// All original elements will remain in the slice and any possible modifications via interior
/// mutability are observed in the input. Same is true if `K: Ord` panics.
/// If the implementation of [`Ord`] for `K` does not implement a [total order] the resulting
/// order of elements in the slice is unspecified. All original elements will remain in the
/// slice and any possible modifications via interior mutability are observed in the input. Same
/// is true if the implementation of [`Ord`] for `K` panics.
///
/// For simple key functions (e.g., functions that are property accesses or basic operations),
/// [`sort_by_key`](slice::sort_by_key) is likely to be faster.
@ -355,16 +365,22 @@ pub fn sort_by_key<K, F>(&mut self, mut f: F)
/// In the worst case, the algorithm allocates temporary storage in a `Vec<(K, usize)>` the
/// length of the slice.
///
/// # Panics
///
/// May panic if the implementation of [`Ord`] for `K` does not implement a [total order].
///
/// # Examples
///
/// ```
/// let mut v = [-5i32, 4, 32, -3, 2];
/// let mut v = [4i32, -5, 1, -3, 2, 10];
///
/// // Strings are sorted by lexicographical order.
/// v.sort_by_cached_key(|k| k.to_string());
/// assert!(v == [-3, -5, 2, 32, 4]);
/// assert_eq!(v, [-3, -5, 1, 10, 2, 4]);
/// ```
///
/// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
/// [total order]: https://en.wikipedia.org/wiki/Total_order
#[cfg(not(no_global_oom_handling))]
#[rustc_allow_incoherent_impl]
#[stable(feature = "slice_sort_by_cached_key", since = "1.34.0")]

View File

@ -28,6 +28,7 @@
issue = "none",
reason = "exposed from core to be reused in std;"
)]
#[doc(hidden)]
pub mod sort;
mod ascii;
@ -2880,9 +2881,19 @@ pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize
/// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not
/// allocate), and *O*(*n* \* log(*n*)) worst-case.
///
/// If `T: Ord` does not implement a total order the resulting order is unspecified. All
/// original elements will remain in the slice and any possible modifications via interior
/// mutability are observed in the input. Same is true if `T: Ord` panics.
/// If the implementation of [`Ord`] for `T` does not implement a [total order] the resulting
/// order of elements in the slice is unspecified. All original elements will remain in the
/// slice and any possible modifications via interior mutability are observed in the input. Same
/// is true if the implementation of [`Ord`] for `T` panics.
///
/// Sorting types that only implement [`PartialOrd`] such as [`f32`] and [`f64`] require
/// additional precautions. For example, `f32::NAN != f32::NAN`, which doesn't fulfill the
/// reflexivity requirement of [`Ord`]. By using an alternative comparison function with
/// `slice::sort_unstable_by` such as [`f32::total_cmp`] or [`f64::total_cmp`] that defines a
/// [total order] users can sort slices containing floating-point values. Alternatively, if all
/// values in the slice are guaranteed to be in a subset for which [`PartialOrd::partial_cmp`]
/// forms a [total order], it's possible to sort the slice with `sort_unstable_by(|a, b|
/// a.partial_cmp(b).unwrap())`.
///
/// # Current implementation
///
@ -2894,18 +2905,21 @@ pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize
/// It is typically faster than stable sorting, except in a few special cases, e.g., when the
/// slice is partially sorted.
///
/// If `T: Ord` does not implement a total order, the implementation may panic.
/// # Panics
///
/// May panic if the implementation of [`Ord`] for `T` does not implement a [total order].
///
/// # Examples
///
/// ```
/// let mut v = [-5, 4, 1, -3, 2];
/// let mut v = [4, -5, 1, -3, 2];
///
/// v.sort_unstable();
/// assert!(v == [-5, -3, 1, 2, 4]);
/// assert_eq!(v, [-5, -3, 1, 2, 4]);
/// ```
///
/// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
/// [total order]: https://en.wikipedia.org/wiki/Total_order
#[stable(feature = "sort_unstable", since = "1.20.0")]
#[inline]
pub fn sort_unstable(&mut self)
@ -2915,31 +2929,20 @@ pub fn sort_unstable(&mut self)
sort::unstable::sort(self, &mut T::lt);
}
/// Sorts the slice with a comparator function, **without** preserving the initial order of
/// Sorts the slice with a comparison function, **without** preserving the initial order of
/// equal elements.
///
/// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not
/// allocate), and *O*(*n* \* log(*n*)) worst-case.
///
/// The comparator function should define a total ordering for the elements in the slice. If the
/// ordering is not total, the order of the elements is unspecified.
/// If the comparison function `compare` does not implement a [total order] the resulting order
/// of elements in the slice is unspecified. All original elements will remain in the slice and
/// any possible modifications via interior mutability are observed in the input. Same is true
/// if `compare` panics.
///
/// If the comparator function does not implement a total order the resulting order is
/// unspecified. All original elements will remain in the slice and any possible modifications
/// via interior mutability are observed in the input. Same is true if the comparator function
/// panics. A total order (for all `a`, `b` and `c`):
///
/// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and
/// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
///
/// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use
/// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`.
///
/// ```
/// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
/// floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
/// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
/// ```
/// For example `|a, b| (a - b).cmp(a)` is a comparison function that is neither transitive nor
/// reflexive nor total, `a < b < c < a` with `a = 1, b = 2, c = 3`. For more information and
/// examples see the [`Ord`] documentation.
///
/// # Current implementation
///
@ -2951,21 +2954,24 @@ pub fn sort_unstable(&mut self)
/// It is typically faster than stable sorting, except in a few special cases, e.g., when the
/// slice is partially sorted.
///
/// If `T: Ord` does not implement a total order, the implementation may panic.
/// # Panics
///
/// May panic if `compare` does not implement a [total order].
///
/// # Examples
///
/// ```
/// let mut v = [5, 4, 1, 3, 2];
/// let mut v = [4, -5, 1, -3, 2];
/// v.sort_unstable_by(|a, b| a.cmp(b));
/// assert!(v == [1, 2, 3, 4, 5]);
/// assert_eq!(v, [-5, -3, 1, 2, 4]);
///
/// // reverse sorting
/// v.sort_unstable_by(|a, b| b.cmp(a));
/// assert!(v == [5, 4, 3, 2, 1]);
/// assert_eq!(v, [4, 2, 1, -3, -5]);
/// ```
///
/// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
/// [total order]: https://en.wikipedia.org/wiki/Total_order
#[stable(feature = "sort_unstable", since = "1.20.0")]
#[inline]
pub fn sort_unstable_by<F>(&mut self, mut compare: F)
@ -2981,9 +2987,10 @@ pub fn sort_unstable_by<F>(&mut self, mut compare: F)
/// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not
/// allocate), and *O*(*n* \* log(*n*)) worst-case.
///
/// If `K: Ord` does not implement a total order the resulting order is unspecified.
/// All original elements will remain in the slice and any possible modifications via interior
/// mutability are observed in the input. Same is true if `K: Ord` panics.
/// If the implementation of [`Ord`] for `K` does not implement a [total order] the resulting
/// order of elements in the slice is unspecified. All original elements will remain in the
/// slice and any possible modifications via interior mutability are observed in the input. Same
/// is true if the implementation of [`Ord`] for `K` panics.
///
/// # Current implementation
///
@ -2995,18 +3002,21 @@ pub fn sort_unstable_by<F>(&mut self, mut compare: F)
/// It is typically faster than stable sorting, except in a few special cases, e.g., when the
/// slice is partially sorted.
///
/// If `K: Ord` does not implement a total order, the implementation may panic.
/// # Panics
///
/// May panic if the implementation of [`Ord`] for `K` does not implement a [total order].
///
/// # Examples
///
/// ```
/// let mut v = [-5i32, 4, 1, -3, 2];
/// let mut v = [4i32, -5, 1, -3, 2];
///
/// v.sort_unstable_by_key(|k| k.abs());
/// assert!(v == [1, 2, -3, 4, -5]);
/// assert_eq!(v, [1, 2, -3, 4, -5]);
/// ```
///
/// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
/// [total order]: https://en.wikipedia.org/wiki/Total_order
#[stable(feature = "sort_unstable", since = "1.20.0")]
#[inline]
pub fn sort_unstable_by_key<K, F>(&mut self, mut f: F)
@ -3038,15 +3048,14 @@ pub fn sort_unstable_by_key<K, F>(&mut self, mut f: F)
/// Median of Medians using Tukey's Ninther for pivot selection, which guarantees linear runtime
/// for all inputs.
///
/// It is typically faster than stable sorting, except in a few special cases, e.g., when the
/// slice is nearly fully sorted, where `slice::sort` may be faster.
///
/// [`sort_unstable`]: slice::sort_unstable
///
/// # Panics
///
/// Panics when `index >= len()`, meaning it always panics on empty slices.
///
/// May panic if the implementation of [`Ord`] for `T` does not implement a [total order].
///
/// # Examples
///
/// ```
@ -3069,6 +3078,7 @@ pub fn sort_unstable_by_key<K, F>(&mut self, mut f: F)
/// ```
///
/// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
/// [total order]: https://en.wikipedia.org/wiki/Total_order
#[stable(feature = "slice_select_nth_unstable", since = "1.49.0")]
#[inline]
pub fn select_nth_unstable(&mut self, index: usize) -> (&mut [T], &mut T, &mut [T])
@ -3099,15 +3109,14 @@ pub fn select_nth_unstable(&mut self, index: usize) -> (&mut [T], &mut T, &mut [
/// Median of Medians using Tukey's Ninther for pivot selection, which guarantees linear runtime
/// for all inputs.
///
/// It is typically faster than stable sorting, except in a few special cases, e.g., when the
/// slice is nearly fully sorted, where `slice::sort` may be faster.
///
/// [`sort_unstable`]: slice::sort_unstable
///
/// # Panics
///
/// Panics when `index >= len()`, meaning it always panics on empty slices.
///
/// May panic if `compare` does not implement a [total order].
///
/// # Examples
///
/// ```
@ -3130,6 +3139,7 @@ pub fn select_nth_unstable(&mut self, index: usize) -> (&mut [T], &mut T, &mut [
/// ```
///
/// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
/// [total order]: https://en.wikipedia.org/wiki/Total_order
#[stable(feature = "slice_select_nth_unstable", since = "1.49.0")]
#[inline]
pub fn select_nth_unstable_by<F>(
@ -3164,15 +3174,14 @@ pub fn select_nth_unstable_by<F>(
/// Median of Medians using Tukey's Ninther for pivot selection, which guarantees linear runtime
/// for all inputs.
///
/// It is typically faster than stable sorting, except in a few special cases, e.g., when the
/// slice is nearly fully sorted, where `slice::sort` may be faster.
///
/// [`sort_unstable`]: slice::sort_unstable
///
/// # Panics
///
/// Panics when `index >= len()`, meaning it always panics on empty slices.
///
/// May panic if `K: Ord` does not implement a total order.
///
/// # Examples
///
/// ```
@ -3195,6 +3204,7 @@ pub fn select_nth_unstable_by<F>(
/// ```
///
/// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
/// [total order]: https://en.wikipedia.org/wiki/Total_order
#[stable(feature = "slice_select_nth_unstable", since = "1.49.0")]
#[inline]
pub fn select_nth_unstable_by_key<K, F>(

View File

@ -831,9 +831,9 @@ unsafe fn bidirectional_merge<T: FreezeMarker, F: FnMut(&T, &T) -> bool>(
right = right.add((!left_nonempty) as usize);
}
// We now should have consumed the full input exactly once. This can
// only fail if the comparison operator fails to be Ord, in which case
// we will panic and never access the inconsistent state in dst.
// We now should have consumed the full input exactly once. This can only fail if the
// user-provided comparison function fails to implement a strict weak ordering. In that case
// we panic and never access the inconsistent state in dst.
if left != left_end || right != right_end {
panic_on_ord_violation();
}
@ -842,7 +842,21 @@ unsafe fn bidirectional_merge<T: FreezeMarker, F: FnMut(&T, &T) -> bool>(
#[inline(never)]
fn panic_on_ord_violation() -> ! {
panic!("Ord violation");
// This is indicative of a logic bug in the user-provided comparison function or Ord
// implementation. They are expected to implement a total order as explained in the Ord
// documentation.
//
// By panicking we inform the user, that they have a logic bug in their program. If a strict
// weak ordering is not given, the concept of comparison based sorting cannot yield a sorted
// result. E.g.: a < b < c < a
//
// The Ord documentation requires users to implement a total order. Arguably that's
// unnecessarily strict in the context of sorting. Issues only arise if the weaker requirement
// of a strict weak ordering is violated.
//
// The panic message talks about a total order because that's what the Ord documentation talks
// about and requires, so as to not confuse users.
panic!("user-provided comparison function does not correctly implement a total order");
}
#[must_use]

View File

@ -8,7 +8,7 @@
pub(crate) mod heapsort;
pub(crate) mod quicksort;
/// Unstable sort called ipnsort by Lukas Bergdoll.
/// Unstable sort called ipnsort by Lukas Bergdoll and Orson Peters.
/// Design document:
/// <https://github.com/Voultapher/sort-research-rs/blob/main/writeup/ipnsort_introduction/text.md>
///

View File

@ -2446,6 +2446,10 @@ pub(crate) fn provided_trait_methods(&self, tcx: TyCtxt<'_>) -> FxHashSet<Symbol
.map(|did| tcx.provided_trait_methods(did).map(|meth| meth.name).collect())
.unwrap_or_default()
}
pub(crate) fn is_negative_trait_impl(&self) -> bool {
matches!(self.polarity, ty::ImplPolarity::Negative)
}
}
#[derive(Clone, Debug)]

View File

@ -1285,9 +1285,8 @@ pub(crate) fn print<'a, 'tcx: 'a>(
f.write_str(" ")?;
if let Some(ref ty) = self.trait_ {
match self.polarity {
ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => {}
ty::ImplPolarity::Negative => write!(f, "!")?,
if self.is_negative_trait_impl() {
write!(f, "!")?;
}
ty.print(cx).fmt(f)?;
write!(f, " for ")?;

View File

@ -1780,20 +1780,23 @@ fn doc_impl_item(
let mut impl_items = Buffer::empty_from(w);
let mut default_impl_items = Buffer::empty_from(w);
let impl_ = i.inner_impl();
for trait_item in &i.inner_impl().items {
doc_impl_item(
&mut default_impl_items,
&mut impl_items,
cx,
trait_item,
if trait_.is_some() { &i.impl_item } else { parent },
link,
render_mode,
false,
trait_,
rendering_params,
);
if !impl_.is_negative_trait_impl() {
for trait_item in &impl_.items {
doc_impl_item(
&mut default_impl_items,
&mut impl_items,
cx,
trait_item,
if trait_.is_some() { &i.impl_item } else { parent },
link,
render_mode,
false,
trait_,
rendering_params,
);
}
}
fn render_default_items(
@ -1844,13 +1847,15 @@ fn render_default_items(
// We don't emit documentation for default items if they appear in the
// Implementations on Foreign Types or Implementors sections.
if rendering_params.show_default_items {
if let Some(t) = trait_ {
if let Some(t) = trait_
&& !impl_.is_negative_trait_impl()
{
render_default_items(
&mut default_impl_items,
&mut impl_items,
cx,
t,
i.inner_impl(),
impl_,
&i.impl_item,
render_mode,
rendering_params,
@ -1882,7 +1887,7 @@ fn render_default_items(
}
if let Some(ref dox) = i.impl_item.opt_doc_value() {
if trait_.is_none() && i.inner_impl().items.is_empty() {
if trait_.is_none() && impl_.items.is_empty() {
w.write_str(
"<div class=\"item-info\">\
<div class=\"stab empty-impl\">This impl block contains no items.</div>\

View File

@ -634,7 +634,7 @@ pub struct Discriminant {
/// hexadecimal, and underscores), making it unsuitable to be machine
/// interpreted.
///
/// In some cases, when the value is to complex, this may be `"{ _ }"`.
/// In some cases, when the value is too complex, this may be `"{ _ }"`.
/// When this occurs is unstable, and may change without notice.
pub expr: String,
/// The numerical value of the discriminant. Stored as a string due to

View File

@ -13,7 +13,7 @@
use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_files};
fn main() {
rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
rustc().env("RUSTC_ICE", cwd()).input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
let default = get_text_from_ice(".").lines().count();
clear_ice_files();

View File

@ -5,7 +5,7 @@
use core::fmt;
use core::fmt::Write;
#[link(name = "c")]
#[cfg_attr(not(windows), link(name = "c"))]
extern "C" {}
struct Dummy;

View File

@ -15,9 +15,12 @@
//! `NO_DEBUG_ASSERTIONS=1`). If debug assertions are disabled, then we can check for the absence of
//! additional `usize` formatting and padding related symbols.
// Reason: This test is `ignore-windows` because the `no_std` test (using `#[link(name = "c")])`
// doesn't link on windows.
//@ ignore-windows
// Reason:
// - MSVC targets really need to parse the .pdb file (aka the debug information).
// On Windows there's an API for that (dbghelp) which maybe we can use
// - MinGW targets have a lot of symbols included in their runtime which we can't avoid.
// We would need to make the symbols we're looking for more specific for this test to work.
//@ ignore-cross-compile
use run_make_support::env::no_debug_assertions;

View File

@ -0,0 +1,26 @@
// This test ensures that negative impls don't have items listed inside them.
#![feature(negative_impls)]
#![crate_name = "foo"]
pub struct Thing;
//@ has 'foo/struct.Thing.html'
// We check the full path to ensure there is no `<details>` element.
//@ has - '//div[@id="trait-implementations-list"]/section[@id="impl-Iterator-for-Thing"]/h3' \
// 'impl !Iterator for Thing'
impl !Iterator for Thing {}
// This struct will allow us to compare both paths.
pub struct Witness;
//@ has 'foo/struct.Witness.html'
//@ has - '//div[@id="trait-implementations-list"]/details//section[@id="impl-Iterator-for-Witness"]/h3' \
// 'impl Iterator for Witness'
impl Iterator for Witness {
type Item = u8;
fn next(&mut self) -> Option<Self::Item> {
None
}
}

View File

@ -6,7 +6,7 @@ trait Foo {
impl Foo for () {
async fn foo<const N: usize>() {}
//~^ ERROR: method `foo` has an incompatible generic parameter for trait `Foo` [E0053]
//~^ ERROR: associated function `foo` has an incompatible generic parameter for trait `Foo` [E0053]
}
fn main() {}

View File

@ -1,4 +1,4 @@
error[E0053]: method `foo` has an incompatible generic parameter for trait `Foo`
error[E0053]: associated function `foo` has an incompatible generic parameter for trait `Foo`
--> $DIR/generics-mismatch.rs:8:18
|
LL | trait Foo {

View File

@ -3,7 +3,7 @@ fn foo<U>() {}
}
impl Trait for () {
fn foo<const M: u64>() {}
//~^ error: method `foo` has an incompatible generic parameter for trait
//~^ error: associated function `foo` has an incompatible generic parameter for trait
}
trait Other {
@ -11,7 +11,7 @@ fn bar<const M: u8>() {}
}
impl Other for () {
fn bar<T>() {}
//~^ error: method `bar` has an incompatible generic parameter for trait
//~^ error: associated function `bar` has an incompatible generic parameter for trait
}
trait Uwu {
@ -19,7 +19,7 @@ fn baz<const N: u32>() {}
}
impl Uwu for () {
fn baz<const N: i32>() {}
//~^ error: method `baz` has an incompatible generic parameter for trait
//~^ error: associated function `baz` has an incompatible generic parameter for trait
}
trait Aaaaaa {
@ -27,7 +27,7 @@ fn bbbb<const N: u32, T>() {}
}
impl Aaaaaa for () {
fn bbbb<T, const N: u32>() {}
//~^ error: method `bbbb` has an incompatible generic parameter for trait
//~^ error: associated function `bbbb` has an incompatible generic parameter for trait
}
trait Names {
@ -35,7 +35,7 @@ fn abcd<T, const N: u32>() {}
}
impl Names for () {
fn abcd<const N: u32, T>() {}
//~^ error: method `abcd` has an incompatible generic parameter for trait
//~^ error: associated function `abcd` has an incompatible generic parameter for trait
}
fn main() {}

View File

@ -1,4 +1,4 @@
error[E0053]: method `foo` has an incompatible generic parameter for trait `Trait`
error[E0053]: associated function `foo` has an incompatible generic parameter for trait `Trait`
--> $DIR/mismatched_ty_const_in_trait_impl.rs:5:12
|
LL | trait Trait {
@ -11,7 +11,7 @@ LL | impl Trait for () {
LL | fn foo<const M: u64>() {}
| ^^^^^^^^^^^^ found const parameter of type `u64`
error[E0053]: method `bar` has an incompatible generic parameter for trait `Other`
error[E0053]: associated function `bar` has an incompatible generic parameter for trait `Other`
--> $DIR/mismatched_ty_const_in_trait_impl.rs:13:12
|
LL | trait Other {
@ -24,7 +24,7 @@ LL | impl Other for () {
LL | fn bar<T>() {}
| ^ found type parameter
error[E0053]: method `baz` has an incompatible generic parameter for trait `Uwu`
error[E0053]: associated function `baz` has an incompatible generic parameter for trait `Uwu`
--> $DIR/mismatched_ty_const_in_trait_impl.rs:21:12
|
LL | trait Uwu {
@ -37,7 +37,7 @@ LL | impl Uwu for () {
LL | fn baz<const N: i32>() {}
| ^^^^^^^^^^^^ found const parameter of type `i32`
error[E0053]: method `bbbb` has an incompatible generic parameter for trait `Aaaaaa`
error[E0053]: associated function `bbbb` has an incompatible generic parameter for trait `Aaaaaa`
--> $DIR/mismatched_ty_const_in_trait_impl.rs:29:13
|
LL | trait Aaaaaa {
@ -50,7 +50,7 @@ LL | impl Aaaaaa for () {
LL | fn bbbb<T, const N: u32>() {}
| ^ found type parameter
error[E0053]: method `abcd` has an incompatible generic parameter for trait `Names`
error[E0053]: associated function `abcd` has an incompatible generic parameter for trait `Names`
--> $DIR/mismatched_ty_const_in_trait_impl.rs:37:13
|
LL | trait Names {

View File

@ -53,7 +53,7 @@ impl Trait for S {
//~| ERROR method `foo2` has 0 type parameters but its trait declaration has 1 type parameter
reuse <F as Trait>::foo3;
//~^ ERROR early bound generics are not supported for associated delegation items
//~| ERROR lifetime parameters or bounds on method `foo3` do not match the trait declaration
//~| ERROR lifetime parameters or bounds on associated function `foo3` do not match the trait declaration
}
struct GenericS<T>(T);

View File

@ -84,14 +84,14 @@ LL | fn foo3<'a: 'a>(_: &'a u32) {}
LL | reuse <F as Trait>::foo3;
| ^^^^
error[E0195]: lifetime parameters or bounds on method `foo3` do not match the trait declaration
error[E0195]: lifetime parameters or bounds on associated function `foo3` do not match the trait declaration
--> $DIR/not-supported.rs:54:29
|
LL | fn foo3<'a: 'a>(_: &'a u32) {}
| -------- lifetimes in impl do not match this method in trait
| -------- lifetimes in impl do not match this associated function in trait
...
LL | reuse <F as Trait>::foo3;
| ^^^^ lifetimes do not match method in trait
| ^^^^ lifetimes do not match associated function in trait
error: delegation to a function with effect parameter is not supported yet
--> $DIR/not-supported.rs:112:18

View File

@ -1,4 +1,4 @@
error[E0049]: method `foo` has 0 type parameters but its trait declaration has 1 type parameter
error[E0049]: associated function `foo` has 0 type parameters but its trait declaration has 1 type parameter
--> $DIR/E0049.rs:8:11
|
LL | fn foo<T: Default>(x: T) -> Self;
@ -7,7 +7,7 @@ LL | fn foo<T: Default>(x: T) -> Self;
LL | fn foo(x: bool) -> Self { Bar }
| ^ found 0 type parameters
error[E0049]: method `fuzz` has 0 type parameters but its trait declaration has 2 type parameters
error[E0049]: associated function `fuzz` has 0 type parameters but its trait declaration has 2 type parameters
--> $DIR/E0049.rs:18:12
|
LL | fn fuzz<A: Default, B>(x: A, y: B) -> Self;

View File

@ -1,13 +1,13 @@
trait Trait {
fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
//~^ NOTE lifetimes in impl do not match this method in trait
//~^ NOTE lifetimes in impl do not match this associated function in trait
}
struct Foo;
impl Trait for Foo {
fn bar<'a,'b>(x: &'a str, y: &'b str) { //~ ERROR E0195
//~^ NOTE lifetimes do not match method in trait
//~^ NOTE lifetimes do not match associated function in trait
}
}

View File

@ -1,11 +1,11 @@
error[E0195]: lifetime parameters or bounds on method `bar` do not match the trait declaration
error[E0195]: lifetime parameters or bounds on associated function `bar` do not match the trait declaration
--> $DIR/E0195.rs:9:11
|
LL | fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
| ---------- lifetimes in impl do not match this method in trait
| ---------- lifetimes in impl do not match this associated function in trait
...
LL | fn bar<'a,'b>(x: &'a str, y: &'b str) {
| ^^^^^^^ lifetimes do not match method in trait
| ^^^^^^^ lifetimes do not match associated function in trait
error: aborting due to 1 previous error

View File

@ -8,7 +8,7 @@ impl<T> X for T { //~ ERROR: not all trait items implemented
fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
//~^ ERROR missing generics for associated type
//~^^ ERROR missing generics for associated type
//~| ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters
//~| ERROR associated function `foo` has 1 type parameter but its trait declaration has 0 type parameters
t
}
}

View File

@ -1,4 +1,4 @@
error[E0049]: method `foo` has 1 type parameter but its trait declaration has 0 type parameters
error[E0049]: associated function `foo` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/gat-trait-path-missing-lifetime.rs:8:10
|
LL | fn foo<'a>(t : Self::Y<'a>) -> Self::Y<'a> { t }

View File

@ -6,7 +6,7 @@ trait Foo {
impl Foo for S {
fn bar() -> impl Sized {}
//~^ ERROR method `bar` has 0 type parameters but its trait declaration has 1 type parameter
//~^ ERROR associated function `bar` has 0 type parameters but its trait declaration has 1 type parameter
}
fn main() {

View File

@ -1,4 +1,4 @@
error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter
error[E0049]: associated function `bar` has 0 type parameters but its trait declaration has 1 type parameter
--> $DIR/trait-more-generics-than-impl.rs:8:11
|
LL | fn bar<T>() -> impl Sized;

View File

@ -40,7 +40,7 @@ error: `~const` can only be applied to `#[const_trait]` traits
LL | const fn a<T: ~const Destruct>(_: T) {}
| ^^^^^^^^
error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/const-drop.rs:54:5
|
LL | #[const_trait]
@ -49,7 +49,7 @@ LL | pub trait SomeTrait {
LL | fn foo();
| - expected 0 const parameters
error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/const-drop.rs:54:5
|
LL | #[const_trait]

View File

@ -40,7 +40,7 @@ error: `~const` can only be applied to `#[const_trait]` traits
LL | const fn a<T: ~const Destruct>(_: T) {}
| ^^^^^^^^
error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/const-drop.rs:54:5
|
LL | #[const_trait]
@ -49,7 +49,7 @@ LL | pub trait SomeTrait {
LL | fn foo();
| - expected 0 const parameters
error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/const-drop.rs:54:5
|
LL | #[const_trait]

View File

@ -1,4 +1,4 @@
error[E0049]: method `bar` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/const-default-bound-non-const-specialized-bound.rs:16:1
|
LL | #[const_trait]
@ -16,7 +16,7 @@ LL | | T: Foo, //FIXME ~ ERROR missing `~const` qualifier
LL | | T: Specialize,
| |__________________^
error[E0049]: method `baz` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/const-default-bound-non-const-specialized-bound.rs:36:1
|
LL | #[const_trait]
@ -25,7 +25,7 @@ LL | trait Baz {
LL | fn baz();
| - expected 0 const parameters
error[E0049]: method `baz` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/const-default-bound-non-const-specialized-bound.rs:36:1
|
LL | #[const_trait]

View File

@ -1,4 +1,4 @@
error[E0049]: method `value` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/const-default-const-specialized.rs:10:1
|
LL | #[const_trait]
@ -7,7 +7,7 @@ LL | trait Value {
LL | fn value() -> u32;
| - expected 0 const parameters
error[E0049]: method `value` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/const-default-const-specialized.rs:10:1
|
LL | #[const_trait]

View File

@ -1,4 +1,4 @@
error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/default-keyword.rs:7:1
|
LL | #[const_trait]

View File

@ -1,4 +1,4 @@
error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/issue-95186-specialize-on-tilde-const.rs:14:1
|
LL | #[const_trait]
@ -7,7 +7,7 @@ LL | trait Foo {
LL | fn foo();
| - expected 0 const parameters
error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/issue-95186-specialize-on-tilde-const.rs:14:1
|
LL | #[const_trait]
@ -18,7 +18,7 @@ LL | fn foo();
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0049]: method `bar` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/issue-95186-specialize-on-tilde-const.rs:30:1
|
LL | #[const_trait]
@ -27,7 +27,7 @@ LL | trait Bar {
LL | fn bar() {}
| - expected 0 const parameters
error[E0049]: method `bar` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/issue-95186-specialize-on-tilde-const.rs:30:1
|
LL | #[const_trait]

View File

@ -1,4 +1,4 @@
error[E0049]: method `bar` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/issue-95187-same-trait-bound-different-constness.rs:18:1
|
LL | #[const_trait]
@ -7,7 +7,7 @@ LL | trait Bar {
LL | fn bar();
| - expected 0 const parameters
error[E0049]: method `bar` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/issue-95187-same-trait-bound-different-constness.rs:18:1
|
LL | #[const_trait]
@ -18,7 +18,7 @@ LL | fn bar();
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0049]: method `baz` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/issue-95187-same-trait-bound-different-constness.rs:38:1
|
LL | #[const_trait]
@ -27,7 +27,7 @@ LL | trait Baz {
LL | fn baz();
| - expected 0 const parameters
error[E0049]: method `baz` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/issue-95187-same-trait-bound-different-constness.rs:38:1
|
LL | #[const_trait]

View File

@ -1,4 +1,4 @@
error[E0049]: method `value` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/non-const-default-const-specialized.rs:9:1
|
LL | #[const_trait]
@ -7,7 +7,7 @@ LL | trait Value {
LL | fn value() -> u32;
| - expected 0 const parameters
error[E0049]: method `value` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/non-const-default-const-specialized.rs:9:1
|
LL | #[const_trait]

View File

@ -1,4 +1,4 @@
error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/specializing-constness-2.rs:9:1
|
LL | #[const_trait]
@ -7,7 +7,7 @@ LL | pub trait A {
LL | fn a() -> u32;
| - expected 0 const parameters
error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/specializing-constness-2.rs:9:1
|
LL | #[const_trait]

View File

@ -0,0 +1,41 @@
//@ run-rustfix
//@ check-pass
#![deny(explicit_outlives_requirements)]
pub trait TypeCx {
type Ty;
}
pub struct Pat<Cx: TypeCx> {
pub ty: Cx::Ty,
}
// Simple recursive case: no warning
pub struct MyTypeContextSimpleRecursive<'thir, 'tcx: 'thir> {
pub pat: Pat<MyTypeContextSimpleRecursive<'thir, 'tcx>>,
}
impl<'thir, 'tcx: 'thir> TypeCx for MyTypeContextSimpleRecursive<'thir, 'tcx> {
type Ty = ();
}
// Non-recursive case: we want a warning
pub struct MyTypeContextNotRecursive<'thir, 'tcx: 'thir> {
pub tcx: &'tcx (),
pub thir: &'thir (),
}
impl<'thir, 'tcx: 'thir> TypeCx for MyTypeContextNotRecursive<'thir, 'tcx> {
type Ty = ();
}
// Mixed-recursive case: we want a warning
pub struct MyTypeContextMixedRecursive<'thir, 'tcx: 'thir> {
pub pat: Pat<MyTypeContextMixedRecursive<'thir, 'tcx>>,
pub tcx: &'tcx (),
pub thir: &'thir (),
}
impl<'thir, 'tcx: 'thir> TypeCx for MyTypeContextMixedRecursive<'thir, 'tcx> {
type Ty = ();
}
fn main() {}

View File

@ -0,0 +1,41 @@
//@ run-rustfix
//@ check-pass
#![deny(explicit_outlives_requirements)]
pub trait TypeCx {
type Ty;
}
pub struct Pat<Cx: TypeCx> {
pub ty: Cx::Ty,
}
// Simple recursive case: no warning
pub struct MyTypeContextSimpleRecursive<'thir, 'tcx: 'thir> {
pub pat: Pat<MyTypeContextSimpleRecursive<'thir, 'tcx>>,
}
impl<'thir, 'tcx: 'thir> TypeCx for MyTypeContextSimpleRecursive<'thir, 'tcx> {
type Ty = ();
}
// Non-recursive case: we want a warning
pub struct MyTypeContextNotRecursive<'thir, 'tcx: 'thir> {
pub tcx: &'tcx (),
pub thir: &'thir (),
}
impl<'thir, 'tcx: 'thir> TypeCx for MyTypeContextNotRecursive<'thir, 'tcx> {
type Ty = ();
}
// Mixed-recursive case: we want a warning
pub struct MyTypeContextMixedRecursive<'thir, 'tcx: 'thir> {
pub pat: Pat<MyTypeContextMixedRecursive<'thir, 'tcx>>,
pub tcx: &'tcx (),
pub thir: &'thir (),
}
impl<'thir, 'tcx: 'thir> TypeCx for MyTypeContextMixedRecursive<'thir, 'tcx> {
type Ty = ();
}
fn main() {}

View File

@ -1,4 +1,4 @@
error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/const_trait_impl.rs:6:1
|
LL | #[const_trait]
@ -7,7 +7,7 @@ LL | pub unsafe trait Sup {
LL | fn foo() -> u32;
| - expected 0 const parameters
error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/const_trait_impl.rs:6:1
|
LL | #[const_trait]
@ -36,7 +36,7 @@ error: `~const` can only be applied to `#[const_trait]` traits
LL | impl<T: ~const Default + ~const Sub> const A for T {
| ^^^^^^^
error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/const_trait_impl.rs:29:1
|
LL | #[const_trait]
@ -45,7 +45,7 @@ LL | pub trait A {
LL | fn a() -> u32;
| - expected 0 const parameters
error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/const_trait_impl.rs:29:1
|
LL | #[const_trait]
@ -56,7 +56,7 @@ LL | fn a() -> u32;
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters
error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
--> $DIR/const_trait_impl.rs:29:1
|
LL | #[const_trait]

View File

@ -1,4 +1,4 @@
error[E0049]: method `foo` has 1 type parameter but its trait declaration has 0 type parameters
error[E0049]: associated function `foo` has 1 type parameter but its trait declaration has 0 type parameters
--> $DIR/issue-36708.rs:8:12
|
LL | fn foo<T>() {}