Skip to content

Commit

Permalink
Auto merge of rust-lang#128927 - GuillaumeGomez:rollup-ei2lr0f, r=Gui…
Browse files Browse the repository at this point in the history
…llaumeGomez

Rollup of 8 pull requests

Successful merges:

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

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Aug 10, 2024
2 parents 8291d68 + 893b9f3 commit 04ba50e
Show file tree
Hide file tree
Showing 52 changed files with 368 additions and 191 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Session.vim
.vscode
.project
.vim/
.helix/
.zed/
.favorites.json
.settings/
.vs/
Expand Down
14 changes: 3 additions & 11 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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))
);
Expand Down Expand Up @@ -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>(
Expand Down
21 changes: 15 additions & 6 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1924,14 +1924,13 @@ declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMEN
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)
Expand All @@ -1947,11 +1946,10 @@ impl ExplicitOutlivesRequirements {
}

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)
Expand Down Expand Up @@ -2094,7 +2092,11 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
(
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,
),
Expand All @@ -2116,7 +2118,14 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
};
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,
Expand Down
18 changes: 12 additions & 6 deletions compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_middle/src/ty/assoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ impl AssocItem {
}
}

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()
}
Expand Down
96 changes: 56 additions & 40 deletions library/alloc/src/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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")]
Expand All @@ -221,30 +234,19 @@ impl<T> [T] {
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 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`):
/// 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.
///
/// * 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
///
Expand All @@ -257,21 +259,24 @@ 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 `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")]
Expand All @@ -288,9 +293,10 @@ impl<T> [T] {
/// 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
///
Expand All @@ -303,18 +309,21 @@ impl<T> [T] {
/// 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")]
Expand All @@ -336,9 +345,10 @@ impl<T> [T] {
/// 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.
Expand All @@ -355,16 +365,22 @@ impl<T> [T] {
/// 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")]
Expand Down
Loading

0 comments on commit 04ba50e

Please sign in to comment.