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:
commit
04ba50e823
2
.gitignore
vendored
2
.gitignore
vendored
@ -20,6 +20,8 @@ Session.vim
|
||||
.vscode
|
||||
.project
|
||||
.vim/
|
||||
.helix/
|
||||
.zed/
|
||||
.favorites.json
|
||||
.settings/
|
||||
.vs/
|
||||
|
@ -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>(
|
||||
|
@ -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,
|
||||
|
@ -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))
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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")]
|
||||
|
@ -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>(
|
||||
|
@ -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]
|
||||
|
@ -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>
|
||||
///
|
||||
|
@ -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)]
|
||||
|
@ -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 ")?;
|
||||
|
@ -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>\
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
26
tests/rustdoc/negative-impl-no-items.rs
Normal file
26
tests/rustdoc/negative-impl-no-items.rs
Normal 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
|
||||
}
|
||||
}
|
@ -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() {}
|
||||
|
@ -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 {
|
||||
|
@ -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() {}
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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 }
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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() {}
|
@ -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() {}
|
@ -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]
|
||||
|
@ -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>() {}
|
||||
|
Loading…
Reference in New Issue
Block a user