summary refs log tree commit diff
path: root/library/core/src
AgeCommit message (Collapse)AuthorLines
2024-03-14Rollup merge of #122479 - GrigorenkoPV:duration_millis_float, r=scottmcmMatthias Krüger-0/+42
Implement `Duration::as_millis_{f64,f32}` Implementation of #122451. Linked const-unstability to #72440, so the post there should probably be updated to mentions the 2 new methods when/if this PR is merged.
2024-03-14Rollup merge of #122461 - the8472:fix-step-forward-unchecked, r=AmanieuMatthias Krüger-2/+28
fix unsoundness in Step::forward_unchecked for signed integers Fixes #122420 ```rust pub fn foo(a: i8, b: u8) -> i8 { unsafe { a.checked_add_unsigned(b).unwrap_unchecked() } } ``` still compiles down to a single arithmetic instruction ([godbolt](https://rust.godbolt.org/z/qsd3xYWfE)). But we may be losing some loop optimizations if llvm can no longer easily derive that it's a finite counted loop from the no-wrapping flags.
2024-03-14Rollup merge of #122421 - CAD97:step-trait-docs, r=jhprattMatthias Krüger-8/+7
Improve `Step` docs It [came up on urlo](https://users.rust-lang.org/t/implement-trait-step-in-1-76-0/108204?u=cad97) that the unstable reason string isn't helpful, so just remove it; there's nothing meaningful to add here. Also makes a couple drive-by improvements to the method docs -- removes incorrect references, changes `forward_checked`'s invariant formulation to match `backward_checked`'s, and adds a helpful corollary that `step_unchecked(a, 0)` is always safe.
2024-03-14Rollup merge of #104353 - clarfonthey:cstr-bytes-iter, r=cuviperMatthias Krüger-0/+91
Add CStr::bytes iterator See rust-lang/libs-team#135 for an ACP. Since rust-lang/libs-team#134 was also accepted, this type is now `core::ffi::c_str::Bytes` instead of `core::ffi::CStrBytes`.
2024-03-14fix unsoundness in Step::forward_unchecked for signed integersThe 8472-2/+28
2024-03-14Implement `Duration::as_millis_{f64,f32}`Pavel Grigorenko-0/+42
2024-03-13Improve Step docsChristopher Durham-8/+7
2024-03-12Reduce unsafe code, use more NonNull APIs per @cuviper reviewltdk-9/+11
2024-03-12Use `min_exhaustive_patterns` in core & stdNadrieril-1/+2
2024-03-11Rollup merge of #121840 - oli-obk:freeze, r=dtolnayJacob Pratt-2/+9
Expose the Freeze trait again (unstably) and forbid implementing it manually non-emoji version of https://github.com/rust-lang/rust/pull/121501 cc #60715 This trait is useful for generic constants (associated consts of generic traits). See the test (`tests/ui/associated-consts/freeze.rs`) added in this PR for a usage example. The builtin `Freeze` trait is the only way to do it, users cannot work around this issue. It's also a useful trait for building some very specific abstrations, as shown by the usage by the `zerocopy` crate: https://github.com/google/zerocopy/issues/941 cc ```@RalfJung``` T-lang signed off on reexposing this unstably: https://github.com/rust-lang/rust/pull/121501#issuecomment-1969827742
2024-03-11Rollup merge of #121148 - clarfonthey:try-range, r=dtolnayJacob Pratt-5/+56
Add slice::try_range This adds a fallible version of the unstable `slice::range` (tracking: #76393) which is highly requested in the tracking issue. Hoping this can slide by without an ACP (since the feature is already being tracked), but let me know otherwise.
2024-03-10Rollup merge of #122302 - ratmice:issue122234, r=cuviperMatthias Krüger-4/+4
docs: Correct ptr/ref verbiage in SliceIndex docs. Fixes #122234
2024-03-10Rollup merge of #122277 - RalfJung:BorrowedCursor, r=cuviperMatthias Krüger-2/+4
BorrowedCursor docs clarification If one reads the `BorrowedCursor` docs without having seen `BorrowedBuf` before, it is quite easy to assume that "unfilled" and "uninit" are synonyms.
2024-03-10Add CStr::bytes iteratorltdk-0/+89
2024-03-10docs: Correct ptr/ref verbiage in SliceIndex docs.matt rice-4/+4
Fixes #122234
2024-03-10Rollup merge of #122271 - pitaj:diag_items-legacy_numeric_constants, r=NilstriebMatthias Krüger-0/+2
Fix legacy numeric constant diag items - missed syms for usize/isize - missed diag items on unsigned integers For rust-lang/rust-clippy#12312 r? ```@Nilstrieb``` Follow-up to #121272, #121361, #121667 This should be the last one 🤞 Sorry!
2024-03-10Rollup merge of #122244 - tvallotton:local_waker_leak_fix, r=NilstriebMatthias Krüger-5/+16
fix: LocalWaker memory leak and some stability attributes fixes #122180.
2024-03-10Rollup merge of #112136 - clarfonthey:ffi-c_str, r=cuviperMatthias Krüger-7/+24
Add std::ffi::c_str module ACP: rust-lang/libs-team#134 `std::ffi` docs before change: ![Structs: VaList, VaListImpl, CStr, CString, FromBytesWithNulError, FromVecWithNulError, IntoStringError, NulError, OsStr, OsString](https://github.com/rust-lang/rust/assets/15850505/b2cf3534-30f9-4ef0-a655-bacdc3a19e17) `std::ffi` docs after change: ![Re-exports: self::c_str::{FromBytesWithNulError, FromBytesUntilNulError, FromVecWithNulError, NulError, IntoStringError} ; Modules: c_str ; Structs: VaList, VaListImpl, CStr, CString, OsStr, OsString](https://github.com/rust-lang/rust/assets/15850505/23aa6964-da7a-4942-bbf7-42bde2146f9e) (note: I'm omitting the `c_int`, etc. stuff from the screenshots since it's the same in both. this doesn't just delete those types)
2024-03-10BorrowedCursor docs clarificationRalf Jung-2/+4
2024-03-09fix legacy numeric constant diag itemsPeter Jaszkowiak-0/+2
- missed syms for usize/isize - missed diag items on unsigned integers
2024-03-10Auto merge of #121662 - saethlin:precondition-unification, r=RalfJungbors-202/+279
Distinguish between library and lang UB in assert_unsafe_precondition As described in https://github.com/rust-lang/rust/pull/121583#issuecomment-1963168186, `assert_unsafe_precondition` now explicitly distinguishes between language UB (conditions we explicitly optimize on) and library UB (things we document you shouldn't do, and maybe some library internals assume you don't do). `debug_assert_nounwind` was originally added to avoid the "only at runtime" aspect of `assert_unsafe_precondition`. Since then the difference between the macros has gotten muddied. This totally revamps the situation. Now _all_ preconditions shall be checked with `assert_unsafe_precondition`. If you have a precondition that's only checkable at runtime, do a `const_eval_select` hack, as done in this PR. r? RalfJung
2024-03-09Rollup merge of #121280 - ajwock:maybeuninit_fill, r=AmanieuGuillaume Boisseau-16/+186
Implement MaybeUninit::fill{,_with,_from} ACP: rust-lang/libs-team#156
2024-03-09Explain why we don't use intrinsics::is_nonoverlappingBen Kimock-0/+2
2024-03-09fix: remove memory leak due to missing drop implementation for local waker. ↵Tomás Vallotton-5/+16
Also, fix some of the stability attributes of LocalWaker's methods.
2024-03-09NonZero::from_mut_unchecked is library UBBen Kimock-1/+1
2024-03-09Improve docsBen Kimock-8/+10
2024-03-09Rollup merge of #122233 - RalfJung:custom-alloc-box, r=oli-obkMatthias Krüger-0/+13
miri: do not apply aliasing restrictions to Box with custom allocator This is the Miri side of https://github.com/rust-lang/rust/pull/122018. The "intrinsics with body" made this much more pleasant. :) Fixes https://github.com/rust-lang/miri/issues/3341. r? `@oli-obk`
2024-03-09Rollup merge of #122232 - RalfJung:misc, r=jhprattMatthias Krüger-6/+7
library/core: fix a comment, and a cfg(miri) warning Just two things I noticed while working on another PR.
2024-03-09Rollup merge of #121358 - GnomedDev:lower-align-typeid, r=Mark-SimulacrumMatthias Krüger-3/+8
Reduce alignment of TypeId to u64 alignment Closes #115620
2024-03-09miri: do not apply aliasing restrictions to Box with custom allocatorRalf Jung-0/+13
2024-03-09fn is_align_to: move some comments closer to the cast they refer toRalf Jung-6/+6
2024-03-09fix warning when building libcore for MiriRalf Jung-0/+1
2024-03-08Distinguish between library and lang UB in assert_unsafe_preconditionBen Kimock-202/+275
2024-03-08Rollup merge of #121201 - RalfJung:align_offset_contract, r=cuviperMatthias Krüger-16/+24
align_offset, align_to: no longer allow implementations to spuriously fail to align For a long time, we have allowed `align_offset` to fail to compute a properly aligned offset, and `align_to` to return a smaller-than-maximal "middle slice". This was done to cover the implementation of `align_offset` in const-eval and Miri. See https://github.com/rust-lang/rust/issues/62420 for more background. For about the same amount of time, this has caused confusion and surprise, where people didn't realize they have to write their code to be defensive against `align_offset` failures. Another way to put this is: the specification is effectively non-deterministic, and non-determinism is hard to test for -- in particular if the implementation everyone uses to test always produces the same reliable result, and nobody expects it to be non-deterministic to begin with. With https://github.com/rust-lang/rust/pull/117840, Miri has stopped making use of this liberty in the spec; it now always behaves like rustc. That only leaves const-eval as potential motivation for this behavior. I do not think this is sufficient motivation. Currently, none of the relevant functions are stably const: `align_offset` is unstably const, `align_to` is not const at all. I propose that if we ever want to make these const-stable, we just accept the fact that they can behave differently at compile-time vs at run-time. This is not the end of the world, and it seems to be much less surprising to programmers than unexpected non-determinism. (Related: https://github.com/rust-lang/rfcs/pull/3352.) `@thomcc` has repeatedly made it clear that they strongly dislike the non-determinism in align_offset, so I expect they will support this. `@oli-obk,` what do you think? Also, whom else should we involve? The primary team responsible is clearly libs-api, so I will nominate this for them. However, allowing const-evaluated code to behave different from run-time code is t-lang territory. The thing is, this is not stabilizing anything t-lang-worthy immediately, but it still does make a decision we will be bound to: if we accept this change, then - either `align_offset`/`align_to` can never be called in const fn, - or we allow compile-time behavior to differ from run-time behavior. So I will nominate for t-lang as well, with the question being: are you okay with accepting either of these outcomes (without committing to which one, just accepting that it has to be one of them)? This closes the door to "have `align_offset` and `align_to` at compile-time and also always have compile-time behavior match run-time behavior". Closes https://github.com/rust-lang/rust/issues/62420
2024-03-08align_offset, align_to: no longer allow implementations to spuriously fail ↵Ralf Jung-16/+24
to align
2024-03-08Rollup merge of #120608 - kornelski:slice-ptr-doc, r=cuviperMatthias Krüger-2/+26
Docs for std::ptr::slice_from_raw_parts
2024-03-08Auto merge of #122059 - nyurik:with-as-const-str, r=cuviperbors-10/+26
Optimize write with as_const_str for shorter code Following up on #121001 Apparently this code generates significant code block for each call to `write()` with non-simple formatting string - approx 100 lines of assembly code, possibly due to `dyn` (?). See generated assembly code [here](https://github.com/nyurik/rust-optimize-format-str/compare/before-changes..with-my-change#diff-6b404e954c692d8cdc8c452d819a216aa5dcf40522b5944639e9ad947279a477): <details><summary>Details</summary> <p> This is the inlining of `write!(buffer, "Iteration {value} was written")` ```asm core::fmt::Write::write_fmt: // /home/nyurik/dev/rust/rust/library/core/src/fmt/mod.rs : 194 fn write_fmt(&mut self, args: Arguments<'_>) -> Result { push r15 push r14 push r13 push r12 push rbx mov rdx, rsi // /home/nyurik/dev/rust/rust/library/core/src/fmt/mod.rs : 427 match (self.pieces, self.args) { mov rcx, qword ptr [rsi + 8] mov rax, qword ptr [rsi + 24] // /home/nyurik/dev/rust/rust/library/core/src/fmt/mod.rs : 428 ([], []) => Some(""), cmp rcx, 1 je .LBB0_8 test rcx, rcx jne .LBB0_9 test rax, rax jne .LBB0_9 // /home/nyurik/dev/rust/rust/library/alloc/src/vec/mod.rs : 911 self.buf.reserve(self.len, additional); lea r12, [rdi + 16] lea rsi, [rip + .L__unnamed_2] xor ebx, ebx .LBB0_6: mov r14, qword ptr [r12] jmp .LBB0_7 .LBB0_8: // /home/nyurik/dev/rust/rust/library/core/src/fmt/mod.rs : 429 ([s], []) => Some(s), test rax, rax je .LBB0_4 .LBB0_9: // /home/nyurik/dev/rust/rust/library/core/src/fmt/mod.rs : 1108 if let Some(s) = args.as_str() { output.write_str(s) } else { write_internal(output, args) } lea rsi, [rip + .L__unnamed_1] pop rbx pop r12 pop r13 pop r14 pop r15 jmp qword ptr [rip + core::fmt::write_internal@GOTPCREL] .LBB0_4: mov rax, qword ptr [rdx] // /home/nyurik/dev/rust/rust/library/core/src/fmt/mod.rs : 429 ([s], []) => Some(s), mov rsi, qword ptr [rax] mov rbx, qword ptr [rax + 8] // /home/nyurik/dev/rust/rust/library/alloc/src/raw_vec.rs : 248 if T::IS_ZST { usize::MAX } else { self.cap.0 } mov rax, qword ptr [rdi] // /home/nyurik/dev/rust/rust/library/alloc/src/vec/mod.rs : 911 self.buf.reserve(self.len, additional); mov r14, qword ptr [rdi + 16] // /home/nyurik/dev/rust/rust/library/core/src/num/mod.rs : 1281 uint_impl! { sub rax, r14 // /home/nyurik/dev/rust/rust/library/alloc/src/raw_vec.rs : 392 additional > self.capacity().wrapping_sub(len) cmp rax, rbx // /home/nyurik/dev/rust/rust/library/alloc/src/raw_vec.rs : 309 if self.needs_to_grow(len, additional) { jb .LBB0_5 .LBB0_7: mov rax, qword ptr [rdi + 8] // /home/nyurik/dev/rust/rust/library/core/src/ptr/mut_ptr.rs : 1046 unsafe { intrinsics::offset(self, count) } add rax, r14 mov r15, rdi // /home/nyurik/dev/rust/rust/library/core/src/intrinsics.rs : 2922 copy_nonoverlapping(src, dst, count) mov rdi, rax mov rdx, rbx call qword ptr [rip + memcpy@GOTPCREL] // /home/nyurik/dev/rust/rust/library/alloc/src/vec/mod.rs : 2040 self.len += count; add r14, rbx mov qword ptr [r15 + 16], r14 // /home/nyurik/dev/rust/rust/library/core/src/fmt/mod.rs : 216 } xor eax, eax pop rbx pop r12 pop r13 pop r14 pop r15 ret .LBB0_5: // /home/nyurik/dev/rust/rust/library/alloc/src/vec/mod.rs : 911 self.buf.reserve(self.len, additional); lea r12, [rdi + 16] mov r15, rdi mov r13, rsi // /home/nyurik/dev/rust/rust/library/alloc/src/raw_vec.rs : 310 do_reserve_and_handle(self, len, additional); mov rsi, r14 mov rdx, rbx call alloc::raw_vec::RawVec<T,A>::reserve::do_reserve_and_handle mov rsi, r13 mov rdi, r15 jmp .LBB0_6 ``` </p> </details> ```rust #[inline] pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { if let Some(s) = args.as_str() { output.write_str(s) } else { write_internal(output, args) } } ``` So, this brings back the older experiment - where I used `if core::intrinsics::is_val_statically_known(s.is_some()) { s } else { None }` helper function, and called it in multiple places that used `write`. This is not as optimal because now every user of `write` must do this logic, but at least it results in significantly smaller assembly code for the formatting case, and results in identical code as now for the "simple" (no formatting) case. See [assembly comparison](https://github.com/nyurik/rust-optimize-format-str/compare/with-my-change..with-as-const-str#diff-6b404e954c692d8cdc8c452d819a216aa5dcf40522b5944639e9ad947279a477) of what is now with what this change brings (focus only on `fmt/intel-lib.txt` and `str/intel-lib.txt` files). ```rust if let Some(s) = args.as_const_str() { self.write_str(s) } else { write(self, args) } ```
2024-03-07Rollup merge of #119888 - weiznich:stablize_diagnostic_namespace, ↵Guillaume Gomez-1/+1
r=compiler-errors Stabilize the `#[diagnostic]` namespace and `#[diagnostic::on_unimplemented]` attribute This PR stabilizes the `#[diagnostic]` attribute namespace and a minimal option of the `#[diagnostic::on_unimplemented]` attribute. The `#[diagnostic]` attribute namespace is meant to provide a home for attributes that allow users to influence error messages emitted by the compiler. The compiler is not guaranteed to use any of this hints, however it should accept any (non-)existing attribute in this namespace and potentially emit lint-warnings for unused attributes and options. This is meant to allow discarding certain attributes/options in the future to allow fundamental changes to the compiler without the need to keep then non-meaningful options working. The `#[diagnostic::on_unimplemented]` attribute is allowed to appear on a trait definition. This allows crate authors to hint the compiler to emit a specific error message if a certain trait is not implemented. For the `#[diagnostic::on_unimplemented]` attribute the following options are implemented: * `message` which provides the text for the top level error message * `label` which provides the text for the label shown inline in the broken code in the error message * `note` which provides additional notes. The `note` option can appear several times, which results in several note messages being emitted. If any of the other options appears several times the first occurrence of the relevant option specifies the actually used value. Any other occurrence generates an lint warning. For any other non-existing option a lint-warning is generated. All three options accept a text as argument. This text is allowed to contain format parameters referring to generic argument or `Self` by name via the `{Self}` or `{NameOfGenericArgument}` syntax. For any non-existing argument a lint warning is generated. This allows to have a trait definition like: ```rust #[diagnostic::on_unimplemented( message = "My Message for `ImportantTrait<{A}>` is not implemented for `{Self}`", label = "My Label", note = "Note 1", note = "Note 2" )] trait ImportantTrait<A> {} ``` which then generates for the following code ```rust fn use_my_trait(_: impl ImportantTrait<i32>) {} fn main() { use_my_trait(String::new()); } ``` this error message: ``` error[E0277]: My Message for `ImportantTrait<i32>` is not implemented for `String` --> src/main.rs:14:18 | 14 | use_my_trait(String::new()); | ------------ ^^^^^^^^^^^^^ My Label | | | required by a bound introduced by this call | = help: the trait `ImportantTrait<i32>` is not implemented for `String` = note: Note 1 = note: Note 2 ``` [Playground with the unstable feature](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=05133acce8e1d163d481e97631f17536) Fixes #111996
2024-03-07Rust is a proper name: rust → RustRalf Jung-8/+8
2024-03-07Auto merge of #122113 - matthiaskrgr:rollup-5d1jnwi, r=matthiaskrgrbors-0/+1
Rollup of 9 pull requests Successful merges: - #121958 (Fix redundant import errors for preload extern crate) - #121976 (Add an option to have an external download/bootstrap cache) - #122022 (loongarch: add frecipe and relax target feature) - #122026 (Do not try to format removed files) - #122027 (Uplift some feeding out of `associated_type_for_impl_trait_in_impl` and into queries) - #122063 (Make the lowering of `thir::ExprKind::If` easier to follow) - #122074 (Add missing PartialOrd trait implementation doc for array) - #122082 (remove outdated fixme comment) - #122091 (Note why we're using a new thread in `test_get_os_named_thread`) r? `@ghost` `@rustbot` modify labels: rollup
2024-03-06add missing PartialOrd impl doc for arrayKonrad Höffner-0/+1
2024-03-06Refer to "slice" instead of "vector" in Ord and PartialOrd trait impl of sliceKonrad Höffner-2/+2
2024-03-05Optimize write with as_const_str for shorter codeYuri Astrakhan-10/+26
2024-03-05Rollup merge of #121894 - RalfJung:const_eval_select, r=oli-obkMatthias Krüger-30/+73
const_eval_select: make it safe but be careful with what we expose on stable for now As this is all still nightly-only I think `````@rust-lang/wg-const-eval````` can do that without involving t-lang. r? `````@oli-obk````` Cc `````@Nilstrieb````` -- the updated version of your RFC would basically say that we can remove these comments about not making behavior differences visible in stable `const fn`
2024-03-05Rollup merge of #121065 - CAD97:display-i18n, r=cuviperMatthias Krüger-0/+17
Add basic i18n guidance for `Display` I've tried to be relatively noncommittal here. The part I think is most important is to mention the concept of "display adapters" *somewhere* in the `std::fmt` documentation that has some chance of being discovered when people go looking for ways to provide context when `Display`ing their type. Rendered: > ### Internationalization > > Because a type can only have one `Display` implementation, it is often preferable to only implement `Display` when there is a single most "obvious" way that values can be formatted as text. This could mean formatting according to the "invariant" culture and "undefined" locale, or it could mean that the type display is designed for a specific culture/locale, such as developer logs. > > If not all values have a justifiably canonical textual format or if you want to support alternative formats not covered by the standard set of possible [formatting traits], the most flexible approach is display adapters: methods like [`str::escape_default`] or [`Path::display`] which create a wrapper implementing `Display` to output the specific display format. > > [formatting traits]: https://doc.rust-lang.org/nightly/std/fmt/index.html#formatting-traits > [`str::escape_default`]: https://doc.rust-lang.org/nightly/std/primitive.str.html#method.escape_default > [`Path::display`]: https://doc.rust-lang.org/nightly/std/path/struct.Path.html#method.display The module docs do already have a [localization header](https://doc.rust-lang.org/nightly/std/fmt/index.html#localization), so maybe this header should be l10n instead of i18n, or maybe this information should live under that header? I'm not sure, but here on the `Display` trait at least isn't a *bad* spot to put it. The other side of this that comes up a lot is `FromStr` compatibility, but that's for a different PR.
2024-03-05Implement MaybeUninit::fill{,_with,_from}Andrew Wock-16/+186
ACP: rust-lang/libs-team#156 Signed-off-by: Andrew Wock <ajwock@gmail.com>
2024-03-05Auto merge of #121428 - okaneco:ipaddr_parse, r=cuviperbors-21/+51
net: Don't use checked arithmetic when parsing numbers with known max digits Add a branch to `Parser::read_number` that determines whether checked or regular arithmetic is used. - If `max_digits.is_some()`, then we know we are parsing a `u8` or `u16` because `read_number` is only called with `Some(3)` or `Some(4)`. Both types fit within a `u32` without risk of overflow. Thus, we can use plain arithmetic to avoid extra instructions from `checked_mul` and `checked_add`. Add benches for `IpAddr`, `Ipv4Addr`, `Ipv6Addr`, `SocketAddr`, `SocketAddrV4`, and `SocketAddrV6` parsing
2024-03-05Auto merge of #121138 - Swatinem:grapheme-extend-ascii, r=cuviperbors-1/+1
Add ASCII fast-path for `char::is_grapheme_extended` I discovered that `impl Debug for str` is quite slow because it ends up doing a `unicode_data::grapheme_extend::lookup` for each char, which ends up doing a binary search. This introduces a fast-path for ASCII chars which do not have this property. The `lookup` is thus completely gone from profiles. --- As a followup, maybe it’s worth implementing this fast path directly in `unicode_data` so that it can check for the lower bound directly before going to a potentially expensive binary search.
2024-03-05Auto merge of #122012 - matthiaskrgr:rollup-bzqjj2n, r=matthiaskrgrbors-35/+51
Rollup of 10 pull requests Successful merges: - #121213 (Add an example to demonstrate how Rc::into_inner works) - #121262 (Add vector time complexity) - #121287 (Clarify/add `must_use` message for Rc/Arc/Weak::into_raw.) - #121664 (Adjust error `yield`/`await` lowering) - #121826 (Use root obligation on E0277 for some cases) - #121838 (Use the correct logic for nested impl trait in assoc types) - #121913 (Don't panic when waiting on poisoned queries) - #121987 (pattern analysis: abort on arity mismatch) - #121993 (Avoid using unnecessary queries when printing the query stack in panics) - #121997 (interpret/cast: make more matches on FloatTy properly exhaustive) r? `@ghost` `@rustbot` modify labels: rollup
2024-03-05Rollup merge of #121826 - estebank:e0277-root-obligation-2, r=oli-obkMatthias Krüger-35/+51
Use root obligation on E0277 for some cases When encountering trait bound errors that satisfy some heuristics that tell us that the relevant trait for the user comes from the root obligation and not the current obligation, we use the root predicate for the main message. This allows to talk about "X doesn't implement Pattern<'_>" over the most specific case that just happened to fail, like "char doesn't implement Fn(&mut char)" in `tests/ui/traits/suggest-dereferences/root-obligation.rs` The heuristics are: - the type of the leaf predicate is (roughly) the same as the type from the root predicate, as a proxy for "we care about the root" - the leaf trait and the root trait are different, so as to avoid talking about `&mut T: Trait` and instead remain talking about `T: Trait` instead - the root trait is not `Unsize`, as to avoid talking about it in `tests/ui/coercion/coerce-issue-49593-box-never.rs`. ``` error[E0277]: the trait bound `&char: Pattern<'_>` is not satisfied --> $DIR/root-obligation.rs:6:38 | LL | .filter(|c| "aeiou".contains(c)) | -------- ^ the trait `Fn<(char,)>` is not implemented for `&char`, which is required by `&char: Pattern<'_>` | | | required by a bound introduced by this call | = note: required for `&char` to implement `FnOnce<(char,)>` = note: required for `&char` to implement `Pattern<'_>` note: required by a bound in `core::str::<impl str>::contains` --> $SRC_DIR/core/src/str/mod.rs:LL:COL help: consider dereferencing here | LL | .filter(|c| "aeiou".contains(*c)) | + ``` Fix #79359, fix #119983, fix #118779, cc #118415 (the suggestion needs to change), cc #121398 (doesn't fix the underlying issue).