diff --git a/Cargo.lock b/Cargo.lock index 7ea3a6fd9c3d7..aaa709e50f60d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2143,6 +2143,20 @@ dependencies = [ "smallvec", ] +[[package]] +name = "measureme" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd460fad6e55ca82fa0cd9dab0d315294188fd9ec6efbf4105e5635d4872ef9c" +dependencies = [ + "log", + "memmap2", + "parking_lot", + "perf-event-open-sys", + "rustc-hash", + "smallvec", +] + [[package]] name = "memchr" version = "2.4.1" @@ -2247,7 +2261,7 @@ dependencies = [ "hex 0.4.2", "libc", "log", - "measureme", + "measureme 9.1.2", "rand 0.8.4", "rustc-workspace-hack", "rustc_version 0.4.0", @@ -3235,7 +3249,7 @@ dependencies = [ "indexmap", "jobserver", "libc", - "measureme", + "measureme 9.1.2", "memmap2", "parking_lot", "rustc-ap-rustc_graphviz", @@ -3674,7 +3688,7 @@ dependencies = [ "bitflags", "cstr", "libc", - "measureme", + "measureme 10.0.0", "rustc-demangle", "rustc_arena", "rustc_ast", @@ -3767,7 +3781,7 @@ dependencies = [ "indexmap", "jobserver", "libc", - "measureme", + "measureme 10.0.0", "memmap2", "parking_lot", "rustc-hash", @@ -4292,7 +4306,7 @@ dependencies = [ name = "rustc_query_impl" version = "0.0.0" dependencies = [ - "measureme", + "measureme 10.0.0", "rustc-rayon-core", "rustc_ast", "rustc_data_structures", diff --git a/RELEASES.md b/RELEASES.md index 52d823d8acac4..f1584224656ae 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -77,7 +77,7 @@ Cargo - [Cargo supports specifying a minimum supported Rust version in Cargo.toml.][`rust-version`] This has no effect at present on dependency version selection. We encourage crates to specify their minimum supported Rust version, and we encourage CI systems - that support Rust code to include a crate's specified minimum version in the text matrix for that + that support Rust code to include a crate's specified minimum version in the test matrix for that crate by default. Compatibility notes diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index a6a553b31a326..5f3f533447532 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -11,7 +11,7 @@ doctest = false bitflags = "1.0" cstr = "0.2" libc = "0.2" -measureme = "9.1.0" +measureme = "10.0.0" snap = "1" tracing = "0.1" rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 202c9cad8eb53..8efe3eb868b94 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -72,9 +72,7 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> { let span = self.find_closest_untracked_caller_location(); let (file, line, col) = self.location_triple_for_span(span); return Err(ConstEvalErrKind::Panic { msg, file, line, col }.into()); - } else if Some(def_id) == self.tcx.lang_items().panic_fmt() - || Some(def_id) == self.tcx.lang_items().begin_panic_fmt() - { + } else if Some(def_id) == self.tcx.lang_items().panic_fmt() { // For panic_fmt, call const_panic_fmt instead. if let Some(const_panic_fmt) = self.tcx.lang_items().const_panic_fmt() { return Ok(Some( diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index 0a852282f8f26..58d0f1a3ad88e 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -79,7 +79,6 @@ pub fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { || Some(def_id) == tcx.lang_items().panic_display() || Some(def_id) == tcx.lang_items().begin_panic_fn() || Some(def_id) == tcx.lang_items().panic_fmt() - || Some(def_id) == tcx.lang_items().begin_panic_fmt() } /// Returns `true` if this `DefId` points to one of the lang items that will be handled differently diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 4996257012970..e3395df35908c 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -23,7 +23,7 @@ rustc-hash = "1.1.0" smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } rustc_index = { path = "../rustc_index", package = "rustc_index" } bitflags = "1.2.1" -measureme = "9.1.0" +measureme = "10.0.0" libc = "0.2" stacker = "0.1.14" tempfile = "3.2" diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 0bbd0eda0c6e1..c21939209fc3b 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -110,12 +110,14 @@ bitflags::bitflags! { const FUNCTION_ARGS = 1 << 6; const LLVM = 1 << 7; const INCR_RESULT_HASHING = 1 << 8; + const ARTIFACT_SIZES = 1 << 9; const DEFAULT = Self::GENERIC_ACTIVITIES.bits | Self::QUERY_PROVIDERS.bits | Self::QUERY_BLOCKED.bits | Self::INCR_CACHE_LOADS.bits | - Self::INCR_RESULT_HASHING.bits; + Self::INCR_RESULT_HASHING.bits | + Self::ARTIFACT_SIZES.bits; const ARGS = Self::QUERY_KEYS.bits | Self::FUNCTION_ARGS.bits; } @@ -136,6 +138,7 @@ const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[ ("args", EventFilter::ARGS), ("llvm", EventFilter::LLVM), ("incr-result-hashing", EventFilter::INCR_RESULT_HASHING), + ("artifact-sizes", EventFilter::ARTIFACT_SIZES), ]; /// Something that uniquely identifies a query invocation. @@ -285,6 +288,33 @@ impl SelfProfilerRef { }) } + /// Record the size of an artifact that the compiler produces + /// + /// `artifact_kind` is the class of artifact (e.g., query_cache, object_file, etc.) + /// `artifact_name` is an identifier to the specific artifact being stored (usually a filename) + #[inline(always)] + pub fn artifact_size(&self, artifact_kind: &str, artifact_name: A, size: u64) + where + A: Borrow + Into, + { + drop(self.exec(EventFilter::ARTIFACT_SIZES, |profiler| { + let builder = EventIdBuilder::new(&profiler.profiler); + let event_label = profiler.get_or_alloc_cached_string(artifact_kind); + let event_arg = profiler.get_or_alloc_cached_string(artifact_name); + let event_id = builder.from_label_and_arg(event_label, event_arg); + let thread_id = get_thread_id(); + + profiler.profiler.record_integer_event( + profiler.artifact_size_event_kind, + event_id, + thread_id, + size, + ); + + TimingGuard::none() + })) + } + #[inline(always)] pub fn generic_activity_with_args( &self, @@ -372,7 +402,7 @@ impl SelfProfilerRef { ) { drop(self.exec(event_filter, |profiler| { let event_id = StringId::new_virtual(query_invocation_id.0); - let thread_id = std::thread::current().id().as_u64().get() as u32; + let thread_id = get_thread_id(); profiler.profiler.record_instant_event( event_kind(profiler), @@ -425,6 +455,7 @@ pub struct SelfProfiler { incremental_result_hashing_event_kind: StringId, query_blocked_event_kind: StringId, query_cache_hit_event_kind: StringId, + artifact_size_event_kind: StringId, } impl SelfProfiler { @@ -447,6 +478,7 @@ impl SelfProfiler { profiler.alloc_string("IncrementalResultHashing"); let query_blocked_event_kind = profiler.alloc_string("QueryBlocked"); let query_cache_hit_event_kind = profiler.alloc_string("QueryCacheHit"); + let artifact_size_event_kind = profiler.alloc_string("ArtifactSize"); let mut event_filter_mask = EventFilter::empty(); @@ -491,6 +523,7 @@ impl SelfProfiler { incremental_result_hashing_event_kind, query_blocked_event_kind, query_cache_hit_event_kind, + artifact_size_event_kind, }) } @@ -561,7 +594,7 @@ impl<'a> TimingGuard<'a> { event_kind: StringId, event_id: EventId, ) -> TimingGuard<'a> { - let thread_id = std::thread::current().id().as_u64().get() as u32; + let thread_id = get_thread_id(); let raw_profiler = &profiler.profiler; let timing_guard = raw_profiler.start_recording_interval_event(event_kind, event_id, thread_id); @@ -655,6 +688,10 @@ pub fn duration_to_secs_str(dur: std::time::Duration) -> String { format!("{:.3}", dur.as_secs_f64()) } +fn get_thread_id() -> u32 { + std::thread::current().id().as_u64().get() as u32 +} + // Memory reporting cfg_if! { if #[cfg(windows)] { diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index f35353dbfb581..97d4123138e8f 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -292,7 +292,6 @@ language_item_table! { PanicImpl, sym::panic_impl, panic_impl, Target::Fn, GenericRequirement::None; /// libstd panic entry point. Necessary for const eval to be able to catch it BeginPanic, sym::begin_panic, begin_panic_fn, Target::Fn, GenericRequirement::None; - BeginPanicFmt, sym::begin_panic_fmt, begin_panic_fmt, Target::Fn, GenericRequirement::None; ExchangeMalloc, sym::exchange_malloc, exchange_malloc_fn, Target::Fn, GenericRequirement::None; BoxFree, sym::box_free, box_free_fn, Target::Fn, GenericRequirement::Minimum(1); diff --git a/compiler/rustc_incremental/src/persist/file_format.rs b/compiler/rustc_incremental/src/persist/file_format.rs index 572a4fc697173..392c5bdc15ad2 100644 --- a/compiler/rustc_incremental/src/persist/file_format.rs +++ b/compiler/rustc_incremental/src/persist/file_format.rs @@ -95,6 +95,12 @@ where return; } + sess.prof.artifact_size( + &name.replace(' ', "_"), + path_buf.file_name().unwrap().to_string_lossy(), + encoder.position() as u64, + ); + debug!("save: data written to disk successfully"); } diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index 89df3d4674b6b..814581563896e 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" doctest = false [dependencies] -measureme = "9.0.0" +measureme = "10.0.0" rustc-rayon-core = "0.3.1" tracing = "0.1" rustc_ast = { path = "../rustc_ast" } diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index f5f67fcd0a08c..47197a1e492a3 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -222,7 +222,7 @@ impl EncoderState { index } - fn finish(self) -> FileEncodeResult { + fn finish(self, profiler: &SelfProfilerRef) -> FileEncodeResult { let Self { mut encoder, total_node_count, total_edge_count, result, stats: _ } = self; let () = result?; @@ -235,7 +235,11 @@ impl EncoderState { IntEncodedWithFixedSize(edge_count).encode(&mut encoder)?; debug!("position: {:?}", encoder.position()); // Drop the encoder so that nothing is written after the counts. - encoder.flush() + let result = encoder.flush(); + // FIXME(rylev): we hardcode the dep graph file name so we don't need a dependency on + // rustc_incremental just for that. + profiler.artifact_size("dep_graph", "dep-graph.bin", encoder.position() as u64); + result } } @@ -332,6 +336,6 @@ impl> GraphEncoder { pub fn finish(self, profiler: &SelfProfilerRef) -> FileEncodeResult { let _prof_timer = profiler.generic_activity("incr_comp_encode_dep_graph"); - self.status.into_inner().finish() + self.status.into_inner().finish(profiler) } } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index b3d36b396c51c..059b5dc51756e 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1283,7 +1283,7 @@ options! { "specify the events recorded by the self profiler; for example: `-Z self-profile-events=default,query-keys` all options: none, all, default, generic-activity, query-provider, query-cache-hit - query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm"), + query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes"), share_generics: Option = (None, parse_opt_bool, [TRACKED], "make the current crate share its generic instantiations"), show_span: Option = (None, parse_opt_string, [TRACKED], diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index ae148624a9068..c25bd9bfa80df 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -355,7 +355,6 @@ symbols! { await_macro, bang, begin_panic, - begin_panic_fmt, bench, bin, bind_by_move_pattern_guards, diff --git a/compiler/rustc_typeck/src/bounds.rs b/compiler/rustc_typeck/src/bounds.rs index ff04e07acc4f6..24474e163b9da 100644 --- a/compiler/rustc_typeck/src/bounds.rs +++ b/compiler/rustc_typeck/src/bounds.rs @@ -64,16 +64,16 @@ impl<'tcx> Bounds<'tcx> { }) }); - self.region_bounds - .iter() - .map(|&(region_bound, span)| { + sized_predicate + .into_iter() + .chain(self.region_bounds.iter().map(|&(region_bound, span)| { ( region_bound .map_bound(|region_bound| ty::OutlivesPredicate(param_ty, region_bound)) .to_predicate(tcx), span, ) - }) + })) .chain(self.trait_bounds.iter().map(|&(bound_trait_ref, span, constness)| { let predicate = bound_trait_ref.with_constness(constness).to_predicate(tcx); (predicate, span) @@ -83,7 +83,6 @@ impl<'tcx> Bounds<'tcx> { .iter() .map(|&(projection, span)| (projection.to_predicate(tcx), span)), ) - .chain(sized_predicate.into_iter()) .collect() } } diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 635708fd4cf6e..285d7755c0689 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -80,87 +80,90 @@ )] #![no_std] #![needs_allocator] +// +// Lints: +#![deny(unsafe_op_in_unsafe_fn)] #![warn(deprecated_in_future)] -#![warn(missing_docs)] #![warn(missing_debug_implementations)] +#![warn(missing_docs)] #![allow(explicit_outlives_requirements)] -#![deny(unsafe_op_in_unsafe_fn)] -#![feature(rustc_allow_const_fn_unstable)] -#![cfg_attr(not(test), feature(generator_trait))] -#![cfg_attr(test, feature(test))] -#![cfg_attr(test, feature(new_uninit))] +// +// Library features: +#![feature(alloc_layout_extra)] #![feature(allocator_api)] #![feature(array_chunks)] #![feature(array_methods)] #![feature(array_windows)] -#![feature(allow_internal_unstable)] -#![feature(arbitrary_self_types)] #![feature(async_stream)] -#![feature(box_patterns)] -#![feature(box_syntax)] -#![feature(cfg_sanitize)] -#![feature(cfg_target_has_atomic)] #![feature(coerce_unsized)] #![cfg_attr(not(no_global_oom_handling), feature(const_btree_new))] -#![feature(const_fn_trait_bound)] -#![feature(cow_is_borrowed)] #![feature(const_cow_is_borrowed)] -#![feature(const_trait_impl)] -#![feature(destructuring_assignment)] -#![feature(dispatch_from_dyn)] #![feature(core_intrinsics)] -#![feature(dropck_eyepatch)] +#![feature(dispatch_from_dyn)] #![feature(exact_size_is_empty)] -#![feature(exclusive_range_pattern)] #![feature(extend_one)] #![feature(fmt_internals)] #![feature(fn_traits)] -#![feature(fundamental)] #![feature(inplace_iteration)] -// Technically, this is a bug in rustdoc: rustdoc sees the documentation on `#[lang = slice_alloc]` -// blocks is for `&[T]`, which also has documentation using this feature in `core`, and gets mad -// that the feature-gate isn't enabled. Ideally, it wouldn't check for the feature gate for docs -// from other crates, but since this can only appear for lang items, it doesn't seem worth fixing. -#![feature(intra_doc_pointers)] #![feature(iter_advance_by)] #![feature(iter_zip)] -#![feature(lang_items)] #![feature(layout_for_ptr)] -#![feature(negative_impls)] -#![feature(never_type)] -#![feature(nll)] +#![feature(maybe_uninit_extra)] +#![feature(maybe_uninit_slice)] +#![cfg_attr(test, feature(new_uninit))] #![feature(nonnull_slice_from_raw_parts)] -#![feature(auto_traits)] #![feature(option_result_unwrap_unchecked)] #![feature(pattern)] #![feature(ptr_internals)] -#![feature(rustc_attrs)] #![feature(receiver_trait)] -#![feature(min_specialization)] #![feature(set_ptr_value)] +#![feature(slice_group_by)] #![feature(slice_ptr_get)] #![feature(slice_ptr_len)] #![feature(slice_range)] -#![feature(staged_api)] #![feature(str_internals)] #![feature(trusted_len)] -#![feature(unboxed_closures)] +#![feature(trusted_random_access)] +#![feature(try_trait_v2)] #![feature(unicode_internals)] #![feature(unsize)] -#![feature(unsized_fn_params)] +// +// Language features: #![feature(allocator_internals)] -#![feature(slice_partition_dedup)] -#![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_uninit_array)] -#![feature(alloc_layout_extra)] -#![feature(trusted_random_access)] -#![feature(try_trait_v2)] +#![feature(allow_internal_unstable)] #![feature(associated_type_bounds)] -#![feature(slice_group_by)] -#![feature(decl_macro)] +#![feature(box_syntax)] +#![feature(cfg_sanitize)] +#![feature(cfg_target_has_atomic)] +#![feature(const_fn_trait_bound)] +#![feature(const_trait_impl)] +#![feature(destructuring_assignment)] +#![feature(dropck_eyepatch)] +#![feature(exclusive_range_pattern)] +#![feature(fundamental)] +#![cfg_attr(not(test), feature(generator_trait))] +#![feature(lang_items)] +#![feature(min_specialization)] +#![feature(negative_impls)] +#![feature(never_type)] +#![feature(nll)] // Not necessary, but here to test the `nll` feature. +#![feature(rustc_allow_const_fn_unstable)] +#![feature(rustc_attrs)] +#![feature(staged_api)] +#![cfg_attr(test, feature(test))] +#![feature(unboxed_closures)] +#![feature(unsized_fn_params)] +// +// Rustdoc features: #![feature(doc_cfg)] #![cfg_attr(not(bootstrap), feature(doc_cfg_hide))] -// Allow testing this library +// Technically, this is a bug in rustdoc: rustdoc sees the documentation on `#[lang = slice_alloc]` +// blocks is for `&[T]`, which also has documentation using this feature in `core`, and gets mad +// that the feature-gate isn't enabled. Ideally, it wouldn't check for the feature gate for docs +// from other crates, but since this can only appear for lang items, it doesn't seem worth fixing. +#![feature(intra_doc_pointers)] +// Allow testing this library #[cfg(test)] #[macro_use] extern crate std; diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 8d5c0510404fb..b27c36baf37c5 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -125,7 +125,8 @@ impl TryFromSliceError { } #[stable(feature = "try_from_slice_error", since = "1.36.0")] -impl From for TryFromSliceError { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for TryFromSliceError { fn from(x: Infallible) -> TryFromSliceError { match x {} } diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 2ca077a98f8dc..ed464700cd357 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -308,7 +308,8 @@ impl Ord for Cell { } #[stable(feature = "cell_from", since = "1.12.0")] -impl From for Cell { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for Cell { fn from(t: T) -> Cell { Cell::new(t) } @@ -1236,7 +1237,8 @@ impl Ord for RefCell { } #[stable(feature = "cell_from", since = "1.12.0")] -impl From for RefCell { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for RefCell { fn from(t: T) -> RefCell { RefCell::new(t) } @@ -1976,7 +1978,8 @@ impl Default for UnsafeCell { } #[stable(feature = "cell_from", since = "1.12.0")] -impl From for UnsafeCell { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for UnsafeCell { fn from(t: T) -> UnsafeCell { UnsafeCell::new(t) } diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index 72921414fb3f2..8fc6b1af92452 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -97,7 +97,8 @@ pub unsafe fn from_u32_unchecked(i: u32) -> char { } #[stable(feature = "char_convert", since = "1.13.0")] -impl From for u32 { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for u32 { /// Converts a [`char`] into a [`u32`]. /// /// # Examples @@ -116,7 +117,8 @@ impl From for u32 { } #[stable(feature = "more_char_conversions", since = "1.51.0")] -impl From for u64 { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for u64 { /// Converts a [`char`] into a [`u64`]. /// /// # Examples @@ -137,7 +139,8 @@ impl From for u64 { } #[stable(feature = "more_char_conversions", since = "1.51.0")] -impl From for u128 { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for u128 { /// Converts a [`char`] into a [`u128`]. /// /// # Examples @@ -176,7 +179,8 @@ impl From for u128 { /// for a superset of Windows-1252 that fills the remaining blanks with corresponding /// C0 and C1 control codes. #[stable(feature = "char_convert", since = "1.13.0")] -impl From for char { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for char { /// Converts a [`u8`] into a [`char`]. /// /// # Examples diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index fb8305273a83c..5aa53deee343d 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -545,7 +545,8 @@ where // From (and thus Into) is reflexive #[stable(feature = "rust1", since = "1.0.0")] -impl From for T { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for T { fn from(t: T) -> T { t } @@ -560,7 +561,8 @@ impl From for T { #[allow(unused_attributes)] // FIXME(#58633): do a principled fix instead. #[rustc_reservation_impl = "permitting this impl would forbid us from adding \ `impl From for T` later; see rust-lang/rust#64715 for details"] -impl From for T { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for T { fn from(t: !) -> T { t } @@ -726,7 +728,8 @@ impl Ord for Infallible { } #[stable(feature = "convert_infallible", since = "1.34.0")] -impl From for Infallible { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for Infallible { fn from(x: !) -> Self { x } diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs index ba65f0fadbd9d..89d5fac30d357 100644 --- a/library/core/src/fmt/float.rs +++ b/library/core/src/fmt/float.rs @@ -3,6 +3,26 @@ use crate::mem::MaybeUninit; use crate::num::flt2dec; use crate::num::fmt as numfmt; +#[doc(hidden)] +trait GeneralFormat: PartialOrd { + /// Determines if a value should use exponential based on its magnitude, given the precondition + /// that it will not be rounded any further before it is displayed. + fn already_rounded_value_should_use_exponential(&self) -> bool; +} + +macro_rules! impl_general_format { + ($($t:ident)*) => { + $(impl GeneralFormat for $t { + fn already_rounded_value_should_use_exponential(&self) -> bool { + let abs = $t::abs_private(*self); + (abs != 0.0 && abs < 1e-4) || abs >= 1e+16 + } + })* + } +} + +impl_general_format! { f32 f64 } + // Don't inline this so callers don't use the stack space this function // requires unless they have to. #[inline(never)] @@ -54,8 +74,7 @@ where fmt.pad_formatted_parts(&formatted) } -// Common code of floating point Debug and Display. -fn float_to_decimal_common(fmt: &mut Formatter<'_>, num: &T, min_precision: usize) -> Result +fn float_to_decimal_display(fmt: &mut Formatter<'_>, num: &T) -> Result where T: flt2dec::DecodableFloat, { @@ -68,6 +87,7 @@ where if let Some(precision) = fmt.precision { float_to_decimal_common_exact(fmt, num, sign, precision) } else { + let min_precision = 0; float_to_decimal_common_shortest(fmt, num, sign, min_precision) } } @@ -145,19 +165,44 @@ where } } +fn float_to_general_debug(fmt: &mut Formatter<'_>, num: &T) -> Result +where + T: flt2dec::DecodableFloat + GeneralFormat, +{ + let force_sign = fmt.sign_plus(); + let sign = match force_sign { + false => flt2dec::Sign::Minus, + true => flt2dec::Sign::MinusPlus, + }; + + if let Some(precision) = fmt.precision { + // this behavior of {:.PREC?} predates exponential formatting for {:?} + float_to_decimal_common_exact(fmt, num, sign, precision) + } else { + // since there is no precision, there will be no rounding + if num.already_rounded_value_should_use_exponential() { + let upper = false; + float_to_exponential_common_shortest(fmt, num, sign, upper) + } else { + let min_precision = 1; + float_to_decimal_common_shortest(fmt, num, sign, min_precision) + } + } +} + macro_rules! floating { ($ty:ident) => { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for $ty { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { - float_to_decimal_common(fmt, self, 1) + float_to_general_debug(fmt, self) } } #[stable(feature = "rust1", since = "1.0.0")] impl Display for $ty { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { - float_to_decimal_common(fmt, self, 0) + float_to_decimal_display(fmt, self) } } diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs index 2b7287a413376..4b89bc363268d 100644 --- a/library/core/src/iter/adapters/zip.rs +++ b/library/core/src/iter/adapters/zip.rs @@ -427,13 +427,9 @@ where } } +// Since SourceIter forwards the left hand side we do the same here #[unstable(issue = "none", feature = "inplace_iteration")] -// Limited to Item: Copy since interaction between Zip's use of TrustedRandomAccess -// and Drop implementation of the source is unclear. -// -// An additional method returning the number of times the source has been logically advanced -// (without calling next()) would be needed to properly drop the remainder of the source. -unsafe impl InPlaceIterable for Zip where A::Item: Copy {} +unsafe impl InPlaceIterable for Zip {} #[stable(feature = "rust1", since = "1.0.0")] impl Debug for Zip { diff --git a/library/core/src/lazy.rs b/library/core/src/lazy.rs index d109141216aef..2b8a5f3cbf345 100644 --- a/library/core/src/lazy.rs +++ b/library/core/src/lazy.rs @@ -74,7 +74,7 @@ impl PartialEq for OnceCell { impl Eq for OnceCell {} #[unstable(feature = "once_cell", issue = "74465")] -impl From for OnceCell { +impl const From for OnceCell { fn from(value: T) -> Self { OnceCell { inner: UnsafeCell::new(Some(value)) } } diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index cdeba9c079273..2af61a0748236 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -29,14 +29,15 @@ impl fmt::Display for TryFromIntError { } #[stable(feature = "try_from", since = "1.34.0")] -impl From for TryFromIntError { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for TryFromIntError { fn from(x: Infallible) -> TryFromIntError { match x {} } } #[unstable(feature = "never_type", issue = "35121")] -impl From for TryFromIntError { +impl const From for TryFromIntError { fn from(never: !) -> TryFromIntError { // Match rather than coerce to make sure that code like // `From for TryFromIntError` above will keep working diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index ad8106df198da..83a922ae34891 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -449,7 +449,7 @@ impl f32 { // private use internally. #[inline] #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] - const fn abs_private(self) -> f32 { + pub(crate) const fn abs_private(self) -> f32 { f32::from_bits(self.to_bits() & 0x7fff_ffff) } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 6a48101e04fda..4267260eea38c 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -448,7 +448,7 @@ impl f64 { // private use internally. #[inline] #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] - const fn abs_private(self) -> f64 { + pub(crate) const fn abs_private(self) -> f64 { f64::from_bits(self.to_bits() & 0x7fff_ffff_ffff_ffff) } diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 89fd9fbaf455d..d28474c29232c 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -82,7 +82,8 @@ macro_rules! nonzero_integers { } #[stable(feature = "from_nonzero", since = "1.31.0")] - impl From<$Ty> for $Int { + #[rustc_const_unstable(feature = "const_convert", issue = "88674")] + impl const From<$Ty> for $Int { #[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")] #[inline] fn from(nonzero: $Ty) -> Self { diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 885058321589c..f4ce7d1dfb334 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1723,7 +1723,8 @@ impl<'a, T> IntoIterator for &'a mut Option { } #[stable(since = "1.12.0", feature = "option_from")] -impl From for Option { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for Option { /// Moves `val` into a new [`Some`]. /// /// # Examples @@ -1739,7 +1740,8 @@ impl From for Option { } #[stable(feature = "option_ref_from_ref_option", since = "1.30.0")] -impl<'a, T> From<&'a Option> for Option<&'a T> { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl<'a, T> const From<&'a Option> for Option<&'a T> { /// Converts from `&Option` to `Option<&T>`. /// /// # Examples @@ -1766,7 +1768,8 @@ impl<'a, T> From<&'a Option> for Option<&'a T> { } #[stable(feature = "option_ref_from_ref_option", since = "1.30.0")] -impl<'a, T> From<&'a mut Option> for Option<&'a mut T> { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl<'a, T> const From<&'a mut Option> for Option<&'a mut T> { /// Converts from `&mut Option` to `Option<&mut T>` /// /// # Examples @@ -2052,7 +2055,7 @@ impl ops::Try for Option { } #[unstable(feature = "try_trait_v2", issue = "84277")] -impl ops::FromResidual for Option { +impl const ops::FromResidual for Option { #[inline] fn from_residual(residual: Option) -> Self { match residual { diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index a52a0022e5d2b..649bc3e44ad21 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -121,7 +121,7 @@ impl<'a> PanicInfo<'a> { #[stable(feature = "panic_hooks", since = "1.10.0")] pub fn location(&self) -> Option<&Location<'_>> { // NOTE: If this is changed to sometimes return None, - // deal with that case in std::panicking::default_hook and std::panicking::begin_panic_fmt. + // deal with that case in std::panicking::default_hook and core::panicking::panic_fmt. Some(&self.location) } } diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 6d3ec6ae8612a..a12447acf7ec3 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -76,8 +76,15 @@ fn panic_bounds_check(index: usize, len: usize) -> ! { panic!("index out of bounds: the len is {} but the index is {}", len, index) } -/// The underlying implementation of libcore's `panic!` macro when formatting is used. +/// The entry point for panicking with a formatted message. +/// +/// This is designed to reduce the amount of code required at the call +/// site as much as possible (so that `panic!()` has as low an impact +/// on (e.g.) the inlining of other functions as possible), by moving +/// the actual formatting into this shared place. #[cold] +// If panic_immediate_abort, inline the abort call, +// otherwise avoid inlining because of it is cold path. #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index ee93f00a7fb9b..8bae66ca007a7 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -698,7 +698,8 @@ impl hash::Hash for NonNull { } #[unstable(feature = "ptr_internals", issue = "none")] -impl From> for NonNull { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From> for NonNull { #[inline] fn from(unique: Unique) -> Self { // SAFETY: A Unique pointer cannot be null, so the conditions for @@ -708,7 +709,8 @@ impl From> for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] -impl From<&mut T> for NonNull { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From<&mut T> for NonNull { #[inline] fn from(reference: &mut T) -> Self { // SAFETY: A mutable reference cannot be null. @@ -717,7 +719,8 @@ impl From<&mut T> for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] -impl From<&T> for NonNull { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From<&T> for NonNull { #[inline] fn from(reference: &T) -> Self { // SAFETY: A reference cannot be null, so the conditions for diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index 5baceefb504a5..f6eb48f2967c8 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -176,7 +176,7 @@ impl fmt::Pointer for Unique { } #[unstable(feature = "ptr_internals", issue = "none")] -impl From<&mut T> for Unique { +impl const From<&mut T> for Unique { #[inline] fn from(reference: &mut T) -> Self { // SAFETY: A mutable reference cannot be null diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 1247f33087558..0915dcffe6ef0 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -1273,7 +1273,8 @@ impl AtomicPtr { #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "atomic_bool_from", since = "1.24.0")] -impl From for AtomicBool { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for AtomicBool { /// Converts a `bool` into an `AtomicBool`. /// /// # Examples @@ -1291,7 +1292,8 @@ impl From for AtomicBool { #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "atomic_from", since = "1.23.0")] -impl From<*mut T> for AtomicPtr { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From<*mut T> for AtomicPtr { #[inline] fn from(p: *mut T) -> Self { Self::new(p) @@ -1363,7 +1365,8 @@ macro_rules! atomic_int { } #[$stable_from] - impl From<$int_type> for $atomic_type { + #[rustc_const_unstable(feature = "const_convert", issue = "88674")] + impl const From<$int_type> for $atomic_type { #[doc = concat!("Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`.")] #[inline] fn from(v: $int_type) -> Self { Self::new(v) } diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs index 80e1458dc9421..72a030617ad8a 100644 --- a/library/core/src/task/poll.rs +++ b/library/core/src/task/poll.rs @@ -241,7 +241,8 @@ impl Poll>> { } #[stable(feature = "futures_api", since = "1.36.0")] -impl From for Poll { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for Poll { /// Convert to a `Ready` variant. /// /// # Example diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs index b735957666fc5..7f8672f035417 100644 --- a/library/core/tests/atomic.rs +++ b/library/core/tests/atomic.rs @@ -220,3 +220,10 @@ fn atomic_compare_exchange() { ATOMIC.compare_exchange_weak(0, 1, SeqCst, Acquire).ok(); ATOMIC.compare_exchange_weak(0, 1, SeqCst, SeqCst).ok(); } + +#[test] +fn atomic_const_from() { + const _ATOMIC_U8: AtomicU8 = AtomicU8::from(1); + const _ATOMIC_BOOL: AtomicBool = AtomicBool::from(true); + const _ATOMIC_PTR: AtomicPtr = AtomicPtr::from(core::ptr::null_mut()); +} diff --git a/library/core/tests/cell.rs b/library/core/tests/cell.rs index 85a006c5d5bef..4707cc7076ec0 100644 --- a/library/core/tests/cell.rs +++ b/library/core/tests/cell.rs @@ -465,4 +465,13 @@ fn const_cells() { const CELL: Cell = Cell::new(3); const _: i32 = CELL.into_inner(); + + const UNSAFE_CELL_FROM: UnsafeCell = UnsafeCell::from(3); + const _: i32 = UNSAFE_CELL.into_inner(); + + const REF_CELL_FROM: RefCell = RefCell::from(3); + const _: i32 = REF_CELL.into_inner(); + + const CELL_FROM: Cell = Cell::from(3); + const _: i32 = CELL.into_inner(); } diff --git a/library/core/tests/char.rs b/library/core/tests/char.rs index 51eca1e05d343..6e434cf1a8d0f 100644 --- a/library/core/tests/char.rs +++ b/library/core/tests/char.rs @@ -5,6 +5,8 @@ use std::{char, str}; #[test] fn test_convert() { assert_eq!(u32::from('a'), 0x61); + assert_eq!(u64::from('b'), 0x62); + assert_eq!(u128::from('c'), 0x63); assert_eq!(char::from(b'\0'), '\0'); assert_eq!(char::from(b'a'), 'a'); assert_eq!(char::from(b'\xFF'), '\u{FF}'); @@ -19,6 +21,16 @@ fn test_convert() { assert!(char::try_from(0xFFFF_FFFF_u32).is_err()); } +#[test] +const fn test_convert_const() { + assert!(u32::from('a') == 0x61); + assert!(u64::from('b') == 0x62); + assert!(u128::from('c') == 0x63); + assert!(char::from(b'\0') == '\0'); + assert!(char::from(b'a') == 'a'); + assert!(char::from(b'\xFF') == '\u{FF}'); +} + #[test] fn test_from_str() { assert_eq!(char::from_str("a").unwrap(), 'a'); diff --git a/library/core/tests/fmt/float.rs b/library/core/tests/fmt/float.rs index bd0daf7a8eb84..47a7400f76ef9 100644 --- a/library/core/tests/fmt/float.rs +++ b/library/core/tests/fmt/float.rs @@ -12,6 +12,16 @@ fn test_format_f64() { assert_eq!("1.23456789E3", format!("{:E}", 1234.56789f64)); assert_eq!("0.0", format!("{:?}", 0.0f64)); assert_eq!("1.01", format!("{:?}", 1.01f64)); + + let high_cutoff = 1e16_f64; + assert_eq!("1e16", format!("{:?}", high_cutoff)); + assert_eq!("-1e16", format!("{:?}", -high_cutoff)); + assert!(!is_exponential(&format!("{:?}", high_cutoff * (1.0 - 2.0 * f64::EPSILON)))); + assert_eq!("-3.0", format!("{:?}", -3f64)); + assert_eq!("0.0001", format!("{:?}", 0.0001f64)); + assert_eq!("9e-5", format!("{:?}", 0.00009f64)); + assert_eq!("1234567.9", format!("{:.1?}", 1234567.89f64)); + assert_eq!("1234.6", format!("{:.1?}", 1234.56789f64)); } #[test] @@ -28,4 +38,18 @@ fn test_format_f32() { assert_eq!("1.2345679E3", format!("{:E}", 1234.56789f32)); assert_eq!("0.0", format!("{:?}", 0.0f32)); assert_eq!("1.01", format!("{:?}", 1.01f32)); + + let high_cutoff = 1e16_f32; + assert_eq!("1e16", format!("{:?}", high_cutoff)); + assert_eq!("-1e16", format!("{:?}", -high_cutoff)); + assert!(!is_exponential(&format!("{:?}", high_cutoff * (1.0 - 2.0 * f32::EPSILON)))); + assert_eq!("-3.0", format!("{:?}", -3f32)); + assert_eq!("0.0001", format!("{:?}", 0.0001f32)); + assert_eq!("9e-5", format!("{:?}", 0.00009f32)); + assert_eq!("1234567.9", format!("{:.1?}", 1234567.89f32)); + assert_eq!("1234.6", format!("{:.1?}", 1234.56789f32)); +} + +fn is_exponential(s: &str) -> bool { + s.contains("e") || s.contains("E") } diff --git a/library/core/tests/lazy.rs b/library/core/tests/lazy.rs index 24f921ca7e4dc..064024ab87b28 100644 --- a/library/core/tests/lazy.rs +++ b/library/core/tests/lazy.rs @@ -47,6 +47,12 @@ fn unsync_once_cell_drop_empty() { drop(x); } +#[test] +const fn once_cell_const() { + let _once_cell: OnceCell = OnceCell::new(); + let _once_cell: OnceCell = OnceCell::from(32); +} + #[test] fn clone() { let s = OnceCell::new(); diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 6958f07227afe..ab0295c63143d 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -9,6 +9,7 @@ #![feature(cfg_target_has_atomic)] #![feature(const_assume)] #![feature(const_cell_into_inner)] +#![feature(const_convert)] #![feature(const_maybe_uninit_assume_init)] #![cfg_attr(bootstrap, feature(const_panic))] #![feature(const_ptr_read)] diff --git a/library/core/tests/nonzero.rs b/library/core/tests/nonzero.rs index c2c08522d0cae..4817d86ca6eb0 100644 --- a/library/core/tests/nonzero.rs +++ b/library/core/tests/nonzero.rs @@ -214,6 +214,9 @@ fn nonzero_const() { const ONE: Option = NonZeroU8::new(1); assert!(ONE.is_some()); + + const FROM_NONZERO: u8 = u8::from(NONZERO); + assert_eq!(FROM_NONZERO, 5); } #[test] diff --git a/library/core/tests/option.rs b/library/core/tests/option.rs index c9508c145258c..cd07d6c52c2ad 100644 --- a/library/core/tests/option.rs +++ b/library/core/tests/option.rs @@ -358,10 +358,17 @@ fn option_const() { // test that the methods of `Option` are usable in a const context const OPTION: Option = Some(32); + assert_eq!(OPTION, Some(32)); + + const OPTION_FROM: Option = Option::from(32); + assert_eq!(OPTION_FROM, Some(32)); const REF: Option<&usize> = OPTION.as_ref(); assert_eq!(REF, Some(&32)); + const REF_FROM: Option<&usize> = Option::from(&OPTION); + assert_eq!(REF_FROM, Some(&32)); + const IS_SOME: bool = OPTION.is_some(); assert!(IS_SOME); @@ -388,6 +395,14 @@ const fn option_const_mut() { None => unreachable!(), } } + + { + let as_mut: Option<&mut usize> = Option::from(&mut option); + match as_mut { + Some(v) => *v = 42, + None => unreachable!(), + } + } } #[test] diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 21e9669c11079..c0605b2f4121c 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -25,7 +25,7 @@ pub macro panic_2015 { $crate::rt::panic_display(&$arg) }), ($fmt:expr, $($arg:tt)+) => ({ - $crate::rt::begin_panic_fmt(&$crate::const_format_args!($fmt, $($arg)+)) + $crate::rt::panic_fmt($crate::const_format_args!($fmt, $($arg)+)) }), } diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 231c9fc19c08a..56646b72dd54f 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -437,31 +437,9 @@ pub fn panicking() -> bool { !panic_count::count_is_zero() } -/// The entry point for panicking with a formatted message. -/// -/// This is designed to reduce the amount of code required at the call -/// site as much as possible (so that `panic!()` has as low an impact -/// on (e.g.) the inlining of other functions as possible), by moving -/// the actual formatting into this shared place. -#[unstable(feature = "libstd_sys_internals", reason = "used by the panic! macro", issue = "none")] -#[cold] -// If panic_immediate_abort, inline the abort call, -// otherwise avoid inlining because of it is cold path. -#[cfg_attr(not(feature = "panic_immediate_abort"), track_caller)] -#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] -#[cfg_attr(feature = "panic_immediate_abort", inline)] -#[cfg_attr(not(test), lang = "begin_panic_fmt")] -pub fn begin_panic_fmt(msg: &fmt::Arguments<'_>) -> ! { - if cfg!(feature = "panic_immediate_abort") { - intrinsics::abort() - } - - let info = PanicInfo::internal_constructor(Some(msg), Location::caller()); - begin_panic_handler(&info) -} - /// Entry point of panics from the libcore crate (`panic_impl` lang item). -#[cfg_attr(not(test), panic_handler)] +#[cfg(not(test))] +#[panic_handler] pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { struct PanicPayload<'a> { inner: &'a fmt::Arguments<'a>, diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs index 4d72aff011684..121c214780d2d 100644 --- a/library/std/src/rt.rs +++ b/library/std/src/rt.rs @@ -19,8 +19,8 @@ use crate::ffi::CString; // Re-export some of our utilities which are expected by other crates. -pub use crate::panicking::{begin_panic, begin_panic_fmt, panic_count}; -pub use core::panicking::panic_display; +pub use crate::panicking::{begin_panic, panic_count}; +pub use core::panicking::{panic_display, panic_fmt}; use crate::sync::Once; use crate::sys; diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 4cfc57ac99588..58cd1018c316f 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -482,24 +482,26 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean:: + name.as_str().len() + generics_len; - wrap_item(w, "fn", |w| { - render_attributes_in_pre(w, it, ""); - w.reserve(header_len); - write!( - w, - "{vis}{constness}{asyncness}{unsafety}{abi}fn \ - {name}{generics}{decl}{notable_traits}{where_clause}", - vis = vis, - constness = constness, - asyncness = asyncness, - unsafety = unsafety, - abi = abi, - name = name, - generics = f.generics.print(cx), - where_clause = print_where_clause(&f.generics, cx, 0, true), - decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx), - notable_traits = notable_traits_decl(&f.decl, cx), - ); + wrap_into_docblock(w, |w| { + wrap_item(w, "fn", |w| { + render_attributes_in_pre(w, it, ""); + w.reserve(header_len); + write!( + w, + "{vis}{constness}{asyncness}{unsafety}{abi}fn \ + {name}{generics}{decl}{notable_traits}{where_clause}", + vis = vis, + constness = constness, + asyncness = asyncness, + unsafety = unsafety, + abi = abi, + name = name, + generics = f.generics.print(cx), + where_clause = print_where_clause(&f.generics, cx, 0, true), + decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx), + notable_traits = notable_traits_decl(&f.decl, cx), + ); + }); }); document(w, cx, it, None, HeadingOffset::H2) } @@ -844,16 +846,18 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra } fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::TraitAlias) { - wrap_item(w, "trait-alias", |w| { - render_attributes_in_pre(w, it, ""); - write!( - w, - "trait {}{}{} = {};", - it.name.as_ref().unwrap(), - t.generics.print(cx), - print_where_clause(&t.generics, cx, 0, true), - bounds(&t.bounds, true, cx) - ); + wrap_into_docblock(w, |w| { + wrap_item(w, "trait-alias", |w| { + render_attributes_in_pre(w, it, ""); + write!( + w, + "trait {}{}{} = {};", + it.name.as_ref().unwrap(), + t.generics.print(cx), + print_where_clause(&t.generics, cx, 0, true), + bounds(&t.bounds, true, cx) + ); + }); }); document(w, cx, it, None, HeadingOffset::H2); @@ -866,16 +870,18 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clea } fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::OpaqueTy) { - wrap_item(w, "opaque", |w| { - render_attributes_in_pre(w, it, ""); - write!( - w, - "type {}{}{where_clause} = impl {bounds};", - it.name.as_ref().unwrap(), - t.generics.print(cx), - where_clause = print_where_clause(&t.generics, cx, 0, true), - bounds = bounds(&t.bounds, false, cx), - ); + wrap_into_docblock(w, |w| { + wrap_item(w, "opaque", |w| { + render_attributes_in_pre(w, it, ""); + write!( + w, + "type {}{}{where_clause} = impl {bounds};", + it.name.as_ref().unwrap(), + t.generics.print(cx), + where_clause = print_where_clause(&t.generics, cx, 0, true), + bounds = bounds(&t.bounds, false, cx), + ); + }); }); document(w, cx, it, None, HeadingOffset::H2); @@ -894,20 +900,37 @@ fn item_typedef( t: &clean::Typedef, is_associated: bool, ) { - wrap_item(w, "typedef", |w| { - render_attributes_in_pre(w, it, ""); - if !is_associated { - write!(w, "{}", it.visibility.print_with_space(it.def_id, cx)); - } - write!( - w, - "type {}{}{where_clause} = {type_};", - it.name.as_ref().unwrap(), - t.generics.print(cx), - where_clause = print_where_clause(&t.generics, cx, 0, true), - type_ = t.type_.print(cx), - ); - }); + fn write_content( + w: &mut Buffer, + cx: &Context<'_>, + it: &clean::Item, + t: &clean::Typedef, + is_associated: bool, + ) { + wrap_item(w, "typedef", |w| { + render_attributes_in_pre(w, it, ""); + if !is_associated { + write!(w, "{}", it.visibility.print_with_space(it.def_id, cx)); + } + write!( + w, + "type {}{}{where_clause} = {type_};", + it.name.as_ref().unwrap(), + t.generics.print(cx), + where_clause = print_where_clause(&t.generics, cx, 0, true), + type_ = t.type_.print(cx), + ); + }); + } + + // If this is an associated typedef, we don't want to wrap it into a docblock. + if is_associated { + write_content(w, cx, it, t, is_associated); + } else { + wrap_into_docblock(w, |w| { + write_content(w, cx, it, t, is_associated); + }); + } document(w, cx, it, None, HeadingOffset::H2); @@ -1142,32 +1165,34 @@ fn item_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Mac } fn item_proc_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, m: &clean::ProcMacro) { - let name = it.name.as_ref().expect("proc-macros always have names"); - match m.kind { - MacroKind::Bang => { - wrap_item(w, "macro", |w| { - write!(w, "{}!() {{ /* proc-macro */ }}", name); - }); - } - MacroKind::Attr => { - wrap_item(w, "attr", |w| { - write!(w, "#[{}]", name); - }); - } - MacroKind::Derive => { - wrap_item(w, "derive", |w| { - write!(w, "#[derive({})]", name); - if !m.helpers.is_empty() { - w.push_str("\n{\n"); - w.push_str(" // Attributes available to this derive:\n"); - for attr in &m.helpers { - writeln!(w, " #[{}]", attr); + wrap_into_docblock(w, |w| { + let name = it.name.as_ref().expect("proc-macros always have names"); + match m.kind { + MacroKind::Bang => { + wrap_item(w, "macro", |w| { + write!(w, "{}!() {{ /* proc-macro */ }}", name); + }); + } + MacroKind::Attr => { + wrap_item(w, "attr", |w| { + write!(w, "#[{}]", name); + }); + } + MacroKind::Derive => { + wrap_item(w, "derive", |w| { + write!(w, "#[derive({})]", name); + if !m.helpers.is_empty() { + w.push_str("\n{\n"); + w.push_str(" // Attributes available to this derive:\n"); + for attr in &m.helpers { + writeln!(w, " #[{}]", attr); + } + w.push_str("}\n"); } - w.push_str("}\n"); - } - }); + }); + } } - } + }); document(w, cx, it, None, HeadingOffset::H2) } @@ -1177,38 +1202,40 @@ fn item_primitive(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { } fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::Constant) { - wrap_item(w, "const", |w| { - render_attributes_in_code(w, it); + wrap_into_docblock(w, |w| { + wrap_item(w, "const", |w| { + render_attributes_in_code(w, it); - write!( - w, - "{vis}const {name}: {typ}", - vis = it.visibility.print_with_space(it.def_id, cx), - name = it.name.as_ref().unwrap(), - typ = c.type_.print(cx), - ); + write!( + w, + "{vis}const {name}: {typ}", + vis = it.visibility.print_with_space(it.def_id, cx), + name = it.name.as_ref().unwrap(), + typ = c.type_.print(cx), + ); - let value = c.value(cx.tcx()); - let is_literal = c.is_literal(cx.tcx()); - let expr = c.expr(cx.tcx()); - if value.is_some() || is_literal { - write!(w, " = {expr};", expr = Escape(&expr)); - } else { - w.write_str(";"); - } + let value = c.value(cx.tcx()); + let is_literal = c.is_literal(cx.tcx()); + let expr = c.expr(cx.tcx()); + if value.is_some() || is_literal { + write!(w, " = {expr};", expr = Escape(&expr)); + } else { + w.write_str(";"); + } - if !is_literal { - if let Some(value) = &value { - let value_lowercase = value.to_lowercase(); - let expr_lowercase = expr.to_lowercase(); + if !is_literal { + if let Some(value) = &value { + let value_lowercase = value.to_lowercase(); + let expr_lowercase = expr.to_lowercase(); - if value_lowercase != expr_lowercase - && value_lowercase.trim_end_matches("i32") != expr_lowercase - { - write!(w, " // {value}", value = Escape(value)); + if value_lowercase != expr_lowercase + && value_lowercase.trim_end_matches("i32") != expr_lowercase + { + write!(w, " // {value}", value = Escape(value)); + } } } - } + }); }); document(w, cx, it, None, HeadingOffset::H2) @@ -1268,30 +1295,34 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St } fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Static) { - wrap_item(w, "static", |w| { - render_attributes_in_code(w, it); - write!( - w, - "{vis}static {mutability}{name}: {typ}", - vis = it.visibility.print_with_space(it.def_id, cx), - mutability = s.mutability.print_with_space(), - name = it.name.as_ref().unwrap(), - typ = s.type_.print(cx) - ); + wrap_into_docblock(w, |w| { + wrap_item(w, "static", |w| { + render_attributes_in_code(w, it); + write!( + w, + "{vis}static {mutability}{name}: {typ}", + vis = it.visibility.print_with_space(it.def_id, cx), + mutability = s.mutability.print_with_space(), + name = it.name.as_ref().unwrap(), + typ = s.type_.print(cx) + ); + }); }); document(w, cx, it, None, HeadingOffset::H2) } fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { - wrap_item(w, "foreigntype", |w| { - w.write_str("extern {\n"); - render_attributes_in_code(w, it); - write!( - w, - " {}type {};\n}}", - it.visibility.print_with_space(it.def_id, cx), - it.name.as_ref().unwrap(), - ); + wrap_into_docblock(w, |w| { + wrap_item(w, "foreigntype", |w| { + w.write_str("extern {\n"); + render_attributes_in_code(w, it); + write!( + w, + " {}type {};\n}}", + it.visibility.print_with_space(it.def_id, cx), + it.name.as_ref().unwrap(), + ); + }); }); document(w, cx, it, None, HeadingOffset::H2); @@ -1374,7 +1405,7 @@ fn wrap_into_docblock(w: &mut Buffer, f: F) where F: FnOnce(&mut Buffer), { - w.write_str("
"); + w.write_str("
"); f(w); w.write_str("
") } diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 11c54876dea30..e41c993a5285d 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -129,9 +129,14 @@ h3 { } h1, h2, h3, h4, h5, h6 { font-weight: 500; +} +h1, h2, h3, h4 { margin: 20px 0 15px 0; padding-bottom: 6px; } +h5, h6 { + margin: 15px 0 5px 0; +} h1.fqn { display: flex; border-bottom: 1px dashed; @@ -254,7 +259,10 @@ code, pre, a.test-arrow, .code-header { pre { padding: 14px; } -.type-decl pre { +.docblock.item-decl { + margin-left: 0; +} +.item-decl pre { overflow-x: auto; } @@ -502,14 +510,12 @@ nav.sub { white-space: pre-wrap; } -.docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5, .docblock h6 { - border-bottom: 1px solid; -} - .top-doc .docblock h2 { font-size: 1.3em; } .top-doc .docblock h3 { font-size: 1.15em; } .top-doc .docblock h4, -.top-doc .docblock h5, +.top-doc .docblock h5 { + font-size: 1.1em; +} .top-doc .docblock h6 { font-size: 1em; } @@ -550,6 +556,7 @@ nav.sub { flex-grow: 1; margin: 0px; padding: 0px; + overflow-wrap: anywhere; } .in-band > code, .in-band > .code-header { diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 0fd6462a8f5dd..ccb1a707032bb 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -220,7 +220,7 @@ body.source .example-wrap pre.rust a { background: #333; } -.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow), +.docblock:not(.item-decl) a:not(.srclink):not(.test-arrow), .docblock-short a:not(.srclink):not(.test-arrow), .item-info a, #help a { color: #39AFD7; diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index d863701dd73c7..93801af46ecc5 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -181,7 +181,7 @@ body.source .example-wrap pre.rust a { background: #333; } -.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow), +.docblock:not(.item-decl) a:not(.srclink):not(.test-arrow), .docblock-short a:not(.srclink):not(.test-arrow), .item-info a, #help a { color: #D2991D; diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index 28d2e99a3d073..fba8231caac31 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -176,7 +176,7 @@ body.source .example-wrap pre.rust a { background: #eee; } -.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow), +.docblock:not(.item-decl) a:not(.srclink):not(.test-arrow), .docblock-short a:not(.srclink):not(.test-arrow), .item-info a, #help a { color: #3873AD; diff --git a/src/test/rustdoc-gui/basic.goml b/src/test/rustdoc-gui/basic.goml index 44fcec3393744..239e51a91293f 100644 --- a/src/test/rustdoc-gui/basic.goml +++ b/src/test/rustdoc-gui/basic.goml @@ -1,4 +1,4 @@ goto: file://|DOC_PATH|/test_docs/index.html assert: ("#functions") goto: ./struct.Foo.html -assert: ("div.type-decl") +assert: ("div.item-decl") diff --git a/src/test/rustdoc-gui/check-code-blocks-margin.goml b/src/test/rustdoc-gui/check-code-blocks-margin.goml new file mode 100644 index 0000000000000..2de4768285679 --- /dev/null +++ b/src/test/rustdoc-gui/check-code-blocks-margin.goml @@ -0,0 +1,6 @@ +// This test ensures that the docblock elements have the appropriate left margin. +goto: file://|DOC_PATH|/test_docs/fn.foo.html +// The top docblock elements shouldn't have left margin... +assert-css: ("#main .docblock.item-decl", {"margin-left": "0px"}) +// ... but all the others should! +assert-css: ("#main .docblock:not(.item-decl)", {"margin-left": "24px"}) diff --git a/src/test/rustdoc-gui/font-weight.goml b/src/test/rustdoc-gui/font-weight.goml index d8411511c5aee..0459fd4b9c353 100644 --- a/src/test/rustdoc-gui/font-weight.goml +++ b/src/test/rustdoc-gui/font-weight.goml @@ -1,6 +1,6 @@ goto: file://|DOC_PATH|/lib2/struct.Foo.html // This test checks that the font weight is correctly applied. -assert-css: ("//*[@class='docblock type-decl']//a[text()='Alias']", {"font-weight": "400"}) +assert-css: ("//*[@class='docblock item-decl']//a[text()='Alias']", {"font-weight": "400"}) assert-css: ("//*[@class='structfield small-section-header']//a[text()='Alias']", {"font-weight": "400"}) assert-css: ("#method\.a_method > .code-header", {"font-weight": "600"}) assert-css: ("#associatedtype\.X > .code-header", {"font-weight": "600"}) @@ -16,7 +16,7 @@ goto: file://|DOC_PATH|/lib2/trait.Trait.html // This is a complex selector, so here's how it works: // -// * //*[@class='docblock type-decl'] — selects element of any tag with classes docblock and type-decl +// * //*[@class='docblock item-decl'] — selects element of any tag with classes docblock and item-decl // * /pre[@class='rust trait'] — selects immediate child with tag pre and classes rust and trait // * /code — selects immediate child with tag code // * /a[@class='constant'] — selects immediate child with tag a and class constant @@ -25,8 +25,8 @@ goto: file://|DOC_PATH|/lib2/trait.Trait.html // // This uses '/parent::*' as a proxy for the style of the text node. // We can't just select the '
' because intermediate tags could be added. -assert-count: ("//*[@class='docblock type-decl']/pre[@class='rust trait']/code/a[@class='constant']//text()/parent::*", 1) -assert-css: ("//*[@class='docblock type-decl']/pre[@class='rust trait']/code/a[@class='constant']//text()/parent::*", {"font-weight": "400"}) +assert-count: ("//*[@class='docblock item-decl']/pre[@class='rust trait']/code/a[@class='constant']//text()/parent::*", 1) +assert-css: ("//*[@class='docblock item-decl']/pre[@class='rust trait']/code/a[@class='constant']//text()/parent::*", {"font-weight": "400"}) assert-count: (".methods .type", 1) assert-css: (".methods .type", {"font-weight": "600"}) diff --git a/src/test/rustdoc-gui/src/lib2/lib.rs b/src/test/rustdoc-gui/src/lib2/lib.rs index d5835b78d2fcf..f2e76b546c4af 100644 --- a/src/test/rustdoc-gui/src/lib2/lib.rs +++ b/src/test/rustdoc-gui/src/lib2/lib.rs @@ -84,3 +84,20 @@ pub mod summary_table { /// | content | content | pub struct Foo; } + +pub mod too_long { +pub type ReallyLongTypeNameLongLongLong = Option *const u8>; + +pub const ReallyLongTypeNameLongLongLongConstBecauseWhyNotAConstRightGigaGigaSupraLong: u32 = 0; + +pub struct SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName { + pub a: u32, +} + +impl SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName { + /// ``` + /// let x = SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName { a: 0 }; + /// ``` + pub fn foo(&self) {} + } +} diff --git a/src/test/rustdoc-gui/type-declation-overflow.goml b/src/test/rustdoc-gui/type-declation-overflow.goml index 0a316e220a42c..63ab867fb1772 100644 --- a/src/test/rustdoc-gui/type-declation-overflow.goml +++ b/src/test/rustdoc-gui/type-declation-overflow.goml @@ -1,8 +1,25 @@ -// This test ensures that the type declaration content overflow is handled inside the
 directly.
+// This test ensures that the items declaration content overflow is handled inside the 
 directly.
 goto: file://|DOC_PATH|/lib2/long_trait/trait.ALongNameBecauseItHelpsTestingTheCurrentProblem.html
 // We set a fixed size so there is no chance of "random" resize.
 size: (1100, 800)
 // Logically, the  scroll width should be the width of the window.
 assert-property: ("body", {"scrollWidth": "1100"})
 // However, since there is overflow in the type declaration, its scroll width is bigger.
-assert-property: (".type-decl pre", {"scrollWidth": "1324"})
+assert-property: (".item-decl pre", {"scrollWidth": "1324"})
+
+// We now make the same check on type declaration...
+goto: file://|DOC_PATH|/lib2/too_long/type.ReallyLongTypeNameLongLongLong.html
+assert-property: ("body", {"scrollWidth": "1100"})
+// We now check that the section width hasn't grown because of it.
+assert-property: ("#main", {"scrollWidth": "840"})
+// And now checking that it has scrollable content.
+assert-property: (".item-decl pre", {"scrollWidth": "1103"})
+
+// ... and constant.
+// On a sidenote, it also checks that the (very) long title isn't changing the docblock width.
+goto: file://|DOC_PATH|/lib2/too_long/constant.ReallyLongTypeNameLongLongLongConstBecauseWhyNotAConstRightGigaGigaSupraLong.html
+assert-property: ("body", {"scrollWidth": "1100"})
+// We now check that the section width hasn't grown because of it.
+assert-property: ("#main", {"scrollWidth": "840"})
+// And now checking that it has scrollable content.
+assert-property: (".item-decl pre", {"scrollWidth": "950"})
diff --git a/src/test/rustdoc/attributes.rs b/src/test/rustdoc/attributes.rs
index 6a588fbd56e75..1c7f4b7241893 100644
--- a/src/test/rustdoc/attributes.rs
+++ b/src/test/rustdoc/attributes.rs
@@ -8,6 +8,6 @@ pub extern "C" fn f() {}
 #[export_name = "bar"]
 pub extern "C" fn g() {}
 
-// @has foo/struct.Repr.html '//*[@class="docblock type-decl"]' '#[repr(C, align(8))]'
+// @has foo/struct.Repr.html '//*[@class="docblock item-decl"]' '#[repr(C, align(8))]'
 #[repr(C, align(8))]
 pub struct Repr;
diff --git a/src/test/rustdoc/reexports-priv.rs b/src/test/rustdoc/reexports-priv.rs
index ff7424033aa49..509457f6c9649 100644
--- a/src/test/rustdoc/reexports-priv.rs
+++ b/src/test/rustdoc/reexports-priv.rs
@@ -5,25 +5,25 @@
 
 extern crate reexports;
 
-// @has 'foo/macro.addr_of.html' '//*[@class="docblock type-decl"]' 'pub macro addr_of($place : expr) {'
+// @has 'foo/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place : expr) {'
 pub use reexports::addr_of;
-// @has 'foo/macro.addr_of_crate.html' '//*[@class="docblock type-decl"]' 'pub(crate) macro addr_of_crate($place : expr) {'
+// @has 'foo/macro.addr_of_crate.html' '//*[@class="docblock item-decl"]' 'pub(crate) macro addr_of_crate($place : expr) {'
 pub(crate) use reexports::addr_of_crate;
-// @has 'foo/macro.addr_of_self.html' '//*[@class="docblock type-decl"]' 'pub(crate) macro addr_of_self($place : expr) {'
+// @has 'foo/macro.addr_of_self.html' '//*[@class="docblock item-decl"]' 'pub(crate) macro addr_of_self($place : expr) {'
 pub(self) use reexports::addr_of_self;
 
-// @has 'foo/struct.Foo.html' '//*[@class="docblock type-decl"]' 'pub struct Foo;'
+// @has 'foo/struct.Foo.html' '//*[@class="docblock item-decl"]' 'pub struct Foo;'
 pub use reexports::Foo;
-// @has 'foo/struct.FooCrate.html' '//*[@class="docblock type-decl"]' 'pub(crate) struct FooCrate;'
+// @has 'foo/struct.FooCrate.html' '//*[@class="docblock item-decl"]' 'pub(crate) struct FooCrate;'
 pub(crate) use reexports::FooCrate;
-// @has 'foo/struct.FooSelf.html' '//*[@class="docblock type-decl"]' 'pub(crate) struct FooSelf;'
+// @has 'foo/struct.FooSelf.html' '//*[@class="docblock item-decl"]' 'pub(crate) struct FooSelf;'
 pub(self) use reexports::FooSelf;
 
-// @has 'foo/enum.Bar.html' '//*[@class="docblock type-decl"]' 'pub enum Bar {'
+// @has 'foo/enum.Bar.html' '//*[@class="docblock item-decl"]' 'pub enum Bar {'
 pub use reexports::Bar;
-// @has 'foo/enum.BarCrate.html' '//*[@class="docblock type-decl"]' 'pub(crate) enum BarCrate {'
+// @has 'foo/enum.BarCrate.html' '//*[@class="docblock item-decl"]' 'pub(crate) enum BarCrate {'
 pub(crate) use reexports::BarCrate;
-// @has 'foo/enum.BarSelf.html' '//*[@class="docblock type-decl"]' 'pub(crate) enum BarSelf {'
+// @has 'foo/enum.BarSelf.html' '//*[@class="docblock item-decl"]' 'pub(crate) enum BarSelf {'
 pub(self) use reexports::BarSelf;
 
 // @has 'foo/fn.foo.html' '//*[@class="rust fn"]' 'pub fn foo()'
@@ -40,11 +40,11 @@ pub(crate) use reexports::TypeCrate;
 // @has 'foo/type.TypeSelf.html' '//*[@class="rust typedef"]' 'pub(crate) type TypeSelf ='
 pub(self) use reexports::TypeSelf;
 
-// @has 'foo/union.Union.html' '//*[@class="docblock type-decl"]' 'pub union Union {'
+// @has 'foo/union.Union.html' '//*[@class="docblock item-decl"]' 'pub union Union {'
 pub use reexports::Union;
-// @has 'foo/union.UnionCrate.html' '//*[@class="docblock type-decl"]' 'pub(crate) union UnionCrate {'
+// @has 'foo/union.UnionCrate.html' '//*[@class="docblock item-decl"]' 'pub(crate) union UnionCrate {'
 pub(crate) use reexports::UnionCrate;
-// @has 'foo/union.UnionSelf.html' '//*[@class="docblock type-decl"]' 'pub(crate) union UnionSelf {'
+// @has 'foo/union.UnionSelf.html' '//*[@class="docblock item-decl"]' 'pub(crate) union UnionSelf {'
 pub(self) use reexports::UnionSelf;
 
 pub mod foo {
diff --git a/src/test/rustdoc/reexports.rs b/src/test/rustdoc/reexports.rs
index ab4c5bc743907..c308d0c2f05cf 100644
--- a/src/test/rustdoc/reexports.rs
+++ b/src/test/rustdoc/reexports.rs
@@ -4,21 +4,21 @@
 
 extern crate reexports;
 
-// @has 'foo/macro.addr_of.html' '//*[@class="docblock type-decl"]' 'pub macro addr_of($place : expr) {'
+// @has 'foo/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place : expr) {'
 pub use reexports::addr_of;
 // @!has 'foo/macro.addr_of_crate.html'
 pub(crate) use reexports::addr_of_crate;
 // @!has 'foo/macro.addr_of_self.html'
 pub(self) use reexports::addr_of_self;
 
-// @has 'foo/struct.Foo.html' '//*[@class="docblock type-decl"]' 'pub struct Foo;'
+// @has 'foo/struct.Foo.html' '//*[@class="docblock item-decl"]' 'pub struct Foo;'
 pub use reexports::Foo;
 // @!has 'foo/struct.FooCrate.html'
 pub(crate) use reexports::FooCrate;
 // @!has 'foo/struct.FooSelf.html'
 pub(self) use reexports::FooSelf;
 
-// @has 'foo/enum.Bar.html' '//*[@class="docblock type-decl"]' 'pub enum Bar {'
+// @has 'foo/enum.Bar.html' '//*[@class="docblock item-decl"]' 'pub enum Bar {'
 pub use reexports::Bar;
 // @!has 'foo/enum.BarCrate.html'
 pub(crate) use reexports::BarCrate;
@@ -39,7 +39,7 @@ pub(crate) use reexports::TypeCrate;
 // @!has 'foo/type.TypeSelf.html'
 pub(self) use reexports::TypeSelf;
 
-// @has 'foo/union.Union.html' '//*[@class="docblock type-decl"]' 'pub union Union {'
+// @has 'foo/union.Union.html' '//*[@class="docblock item-decl"]' 'pub union Union {'
 pub use reexports::Union;
 // @!has 'foo/union.UnionCrate.html'
 pub(crate) use reexports::UnionCrate;
diff --git a/src/test/rustdoc/toggle-item-contents.rs b/src/test/rustdoc/toggle-item-contents.rs
index ae871e79d7f6b..937646987dd4f 100644
--- a/src/test/rustdoc/toggle-item-contents.rs
+++ b/src/test/rustdoc/toggle-item-contents.rs
@@ -55,7 +55,7 @@ pub union Union {
 
 // @has 'toggle_item_contents/struct.PrivStruct.html'
 // @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 0
-// @has - '//div[@class="docblock type-decl"]' 'fields omitted'
+// @has - '//div[@class="docblock item-decl"]' 'fields omitted'
 pub struct PrivStruct {
     a: usize,
     b: usize,
diff --git a/src/test/rustdoc/trait_alias.rs b/src/test/rustdoc/trait_alias.rs
index 6cd4a1a0afa08..c9fccf5a77cde 100644
--- a/src/test/rustdoc/trait_alias.rs
+++ b/src/test/rustdoc/trait_alias.rs
@@ -13,11 +13,14 @@ use std::fmt::Debug;
 // @has foo/index.html '//a[@class="traitalias"]' 'Alias2'
 // @has foo/index.html '//a[@class="traitalias"]' 'Foo'
 
-// @has foo/traitalias.CopyAlias.html '//section[@id="main"]/pre' 'trait CopyAlias = Copy;'
+// @has foo/traitalias.CopyAlias.html
+// @has - '//section[@id="main"]/div[@class="docblock item-decl"]/pre' 'trait CopyAlias = Copy;'
 pub trait CopyAlias = Copy;
-// @has foo/traitalias.Alias2.html '//section[@id="main"]/pre' 'trait Alias2 = Copy + Debug;'
+// @has foo/traitalias.Alias2.html
+// @has - '//section[@id="main"]/div[@class="docblock item-decl"]/pre' 'trait Alias2 = Copy + Debug;'
 pub trait Alias2 = Copy + Debug;
-// @has foo/traitalias.Foo.html '//section[@id="main"]/pre' 'trait Foo = Into + Debug;'
+// @has foo/traitalias.Foo.html
+// @has - '//section[@id="main"]/div[@class="docblock item-decl"]/pre' 'trait Foo = Into + Debug;'
 pub trait Foo = Into + Debug;
 // @has foo/fn.bar.html '//a[@href="traitalias.Alias2.html"]' 'Alias2'
 pub fn bar() where T: Alias2 {}
diff --git a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
index 89186817e099c..47c7f1c2c3340 100644
--- a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
   --> $SRC_DIR/core/src/hash/mod.rs:LL:COL
    |
 LL |     fn hash(&self, state: &mut H);
-   |                ^^^^^^ required by this bound in `std::hash::Hash::hash`
+   |             ^ required by this bound in `std::hash::Hash::hash`
    = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
diff --git a/src/test/ui/derives/derives-span-Hash-enum.stderr b/src/test/ui/derives/derives-span-Hash-enum.stderr
index 6abb7e78b1330..92f084b58e35b 100644
--- a/src/test/ui/derives/derives-span-Hash-enum.stderr
+++ b/src/test/ui/derives/derives-span-Hash-enum.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
   --> $SRC_DIR/core/src/hash/mod.rs:LL:COL
    |
 LL |     fn hash(&self, state: &mut H);
-   |                ^^^^^^ required by this bound in `std::hash::Hash::hash`
+   |             ^ required by this bound in `std::hash::Hash::hash`
    = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
diff --git a/src/test/ui/derives/derives-span-Hash-struct.stderr b/src/test/ui/derives/derives-span-Hash-struct.stderr
index 405285f883810..c57cebe04ebcb 100644
--- a/src/test/ui/derives/derives-span-Hash-struct.stderr
+++ b/src/test/ui/derives/derives-span-Hash-struct.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
   --> $SRC_DIR/core/src/hash/mod.rs:LL:COL
    |
 LL |     fn hash(&self, state: &mut H);
-   |                ^^^^^^ required by this bound in `std::hash::Hash::hash`
+   |             ^ required by this bound in `std::hash::Hash::hash`
    = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
diff --git a/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr b/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
index aa12314c05176..200937f0c9fc3 100644
--- a/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
@@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
   --> $SRC_DIR/core/src/hash/mod.rs:LL:COL
    |
 LL |     fn hash(&self, state: &mut H);
-   |                ^^^^^^ required by this bound in `std::hash::Hash::hash`
+   |             ^ required by this bound in `std::hash::Hash::hash`
    = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
diff --git a/src/test/ui/generic-associated-types/issue-74816.stderr b/src/test/ui/generic-associated-types/issue-74816.stderr
index d5cc5cfbe912d..49ae87cbfe9dc 100644
--- a/src/test/ui/generic-associated-types/issue-74816.stderr
+++ b/src/test/ui/generic-associated-types/issue-74816.stderr
@@ -1,34 +1,34 @@
-error[E0277]: the size for values of type `Self` cannot be known at compilation time
+error[E0277]: the trait bound `Self: Trait1` is not satisfied
   --> $DIR/issue-74816.rs:9:5
    |
 LL |     type Associated: Trait1 = Self;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait1` is not implemented for `Self`
    |
 note: required by a bound in `Trait2::Associated`
-  --> $DIR/issue-74816.rs:9:5
+  --> $DIR/issue-74816.rs:9:22
    |
 LL |     type Associated: Trait1 = Self;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait2::Associated`
+   |                      ^^^^^^ required by this bound in `Trait2::Associated`
 help: consider further restricting `Self`
    |
-LL | trait Trait2: Sized {
-   |             +++++++
+LL | trait Trait2: Trait1 {
+   |             ++++++++
 
-error[E0277]: the trait bound `Self: Trait1` is not satisfied
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
   --> $DIR/issue-74816.rs:9:5
    |
 LL |     type Associated: Trait1 = Self;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait1` is not implemented for `Self`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
 note: required by a bound in `Trait2::Associated`
-  --> $DIR/issue-74816.rs:9:22
+  --> $DIR/issue-74816.rs:9:5
    |
 LL |     type Associated: Trait1 = Self;
-   |                      ^^^^^^ required by this bound in `Trait2::Associated`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait2::Associated`
 help: consider further restricting `Self`
    |
-LL | trait Trait2: Trait1 {
-   |             ++++++++
+LL | trait Trait2: Sized {
+   |             +++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/generic-associated-types/issue-86483.stderr b/src/test/ui/generic-associated-types/issue-86483.stderr
index 5d0fcbca552d6..d6978794e1e95 100644
--- a/src/test/ui/generic-associated-types/issue-86483.stderr
+++ b/src/test/ui/generic-associated-types/issue-86483.stderr
@@ -20,13 +20,13 @@ LL |     for<'a> T: 'a,
    |                ^^
 
 error[E0311]: the parameter type `T` may not live long enough
-  --> $DIR/issue-86483.rs:9:19
+  --> $DIR/issue-86483.rs:9:5
    |
 LL | pub trait IceIce
    |                  - help: consider adding an explicit lifetime bound...: `T: 'a`
 ...
 LL |     type Ice<'v>: IntoIterator;
-   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
    |
 note: ...that is required by this bound
   --> $DIR/issue-86483.rs:7:16
diff --git a/src/test/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.stderr b/src/test/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.stderr
index 50f90618e4db7..2c397d80b013e 100644
--- a/src/test/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.stderr
+++ b/src/test/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.stderr
@@ -6,10 +6,10 @@ LL | impl Tsized for () {}
    |
    = help: the trait `Sized` is not implemented for `[()]`
 note: required by a bound in `Tsized`
-  --> $DIR/issue-61631-default-type-param-can-reference-self-in-trait.rs:17:17
+  --> $DIR/issue-61631-default-type-param-can-reference-self-in-trait.rs:17:14
    |
 LL | trait Tsized {}
-   |                 ^^^^^ required by this bound in `Tsized`
+   |              ^ required by this bound in `Tsized`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-16966.stderr b/src/test/ui/issues/issue-16966.stderr
index 7597824e08f9d..09e20c0c77731 100644
--- a/src/test/ui/issues/issue-16966.stderr
+++ b/src/test/ui/issues/issue-16966.stderr
@@ -1,21 +1,11 @@
-error[E0283]: type annotations needed
+error[E0282]: type annotations needed
   --> $DIR/issue-16966.rs:2:5
    |
 LL |     panic!(std::default::Default::default());
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `M` declared on the function `begin_panic`
    |
-   = note: cannot satisfy `_: Any`
-note: required by a bound in `begin_panic`
-  --> $SRC_DIR/std/src/panicking.rs:LL:COL
-   |
-LL | pub fn begin_panic(msg: M) -> ! {
-   |                       ^^^ required by this bound in `begin_panic`
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider specifying the type argument in the function call
-   |
-LL |         $crate::rt::begin_panic::($msg)
-   |                                +++++
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0283`.
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/issues/issue-21160.stderr b/src/test/ui/issues/issue-21160.stderr
index c2f6fc21acd7f..92742b50619e0 100644
--- a/src/test/ui/issues/issue-21160.stderr
+++ b/src/test/ui/issues/issue-21160.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `std::hash::Hash::hash`
   --> $SRC_DIR/core/src/hash/mod.rs:LL:COL
    |
 LL |     fn hash(&self, state: &mut H);
-   |                ^^^^^^ required by this bound in `std::hash::Hash::hash`
+   |             ^ required by this bound in `std::hash::Hash::hash`
    = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-23122-2.stderr b/src/test/ui/issues/issue-23122-2.stderr
index e6cec722978dd..b345e90178742 100644
--- a/src/test/ui/issues/issue-23122-2.stderr
+++ b/src/test/ui/issues/issue-23122-2.stderr
@@ -1,4 +1,4 @@
-error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Next`
+error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized`
   --> $DIR/issue-23122-2.rs:9:17
    |
 LL |     type Next =  as Next>::Next;
diff --git a/src/test/ui/issues/issue-54954.stderr b/src/test/ui/issues/issue-54954.stderr
index d88397fd7e15d..df76a985559d0 100644
--- a/src/test/ui/issues/issue-54954.stderr
+++ b/src/test/ui/issues/issue-54954.stderr
@@ -12,10 +12,10 @@ LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
    |
    = note: cannot satisfy `_: Tt`
 note: required by a bound in `Tt::const_val`
-  --> $DIR/issue-54954.rs:5:27
+  --> $DIR/issue-54954.rs:5:24
    |
 LL |     const fn const_val() -> usize {
-   |                           ^^^^^ required by this bound in `Tt::const_val`
+   |                        ^ required by this bound in `Tt::const_val`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
index 4a4544c16c941..fffb91f98700b 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
@@ -20,11 +20,11 @@ error[E0277]: the trait bound `T: Bar` is not satisfied
 LL |     T::c::();
    |     ^^^^^^^^^ the trait `Bar` is not implemented for `T`
    |
-note: required by a bound in `Foo::c`
-  --> $DIR/trait-where-clause.rs:9:10
+note: required by `Foo::c`
+  --> $DIR/trait-where-clause.rs:9:5
    |
 LL |     fn c();
-   |          ^ required by this bound in `Foo::c`
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 help: consider further restricting this bound
    |
 LL | const fn test1() {
@@ -52,11 +52,11 @@ error[E0277]: the trait bound `T: Bar` is not satisfied
 LL |     T::c::();
    |     ^^^^^^^^^ the trait `Bar` is not implemented for `T`
    |
-note: required by a bound in `Foo::c`
-  --> $DIR/trait-where-clause.rs:9:10
+note: required by `Foo::c`
+  --> $DIR/trait-where-clause.rs:9:5
    |
 LL |     fn c();
-   |          ^ required by this bound in `Foo::c`
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 help: consider further restricting this bound
    |
 LL | fn test3() {
diff --git a/src/test/ui/suggestions/issue-84973-blacklist.stderr b/src/test/ui/suggestions/issue-84973-blacklist.stderr
index 58075ed7caebc..ae55c96702ada 100644
--- a/src/test/ui/suggestions/issue-84973-blacklist.stderr
+++ b/src/test/ui/suggestions/issue-84973-blacklist.stderr
@@ -49,10 +49,10 @@ LL |     f_sized(*ref_cl);
    |
    = help: the trait `Sized` is not implemented for `dyn Fn()`
 note: required by a bound in `f_sized`
-  --> $DIR/issue-84973-blacklist.rs:9:15
+  --> $DIR/issue-84973-blacklist.rs:9:12
    |
 LL | fn f_sized(t: T) {}
-   |               ^^^^^ required by this bound in `f_sized`
+   |            ^ required by this bound in `f_sized`
 
 error[E0277]: `Rc<{integer}>` cannot be sent between threads safely
   --> $DIR/issue-84973-blacklist.rs:27:12
diff --git a/src/test/ui/suggestions/slice-issue-87994.stderr b/src/test/ui/suggestions/slice-issue-87994.stderr
index 9e0d4ced01153..0275fd475d8c6 100644
--- a/src/test/ui/suggestions/slice-issue-87994.stderr
+++ b/src/test/ui/suggestions/slice-issue-87994.stderr
@@ -1,4 +1,4 @@
-error[E0277]: `[i32]` is not an iterator
+error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
   --> $DIR/slice-issue-87994.rs:3:12
    |
 LL |   for _ in v[1..] {
@@ -18,7 +18,7 @@ LL |   for _ in &v[1..] {
 LL |   for _ in &mut v[1..] {
    |            ++++
 
-error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
+error[E0277]: `[i32]` is not an iterator
   --> $DIR/slice-issue-87994.rs:3:12
    |
 LL |   for _ in v[1..] {
@@ -38,7 +38,7 @@ LL |   for _ in &v[1..] {
 LL |   for _ in &mut v[1..] {
    |            ++++
 
-error[E0277]: `[K]` is not an iterator
+error[E0277]: the size for values of type `[K]` cannot be known at compilation time
   --> $DIR/slice-issue-87994.rs:11:13
    |
 LL |   for i2 in v2[1..] {
@@ -58,7 +58,7 @@ LL |   for i2 in &v2[1..] {
 LL |   for i2 in &mut v2[1..] {
    |             ++++
 
-error[E0277]: the size for values of type `[K]` cannot be known at compilation time
+error[E0277]: `[K]` is not an iterator
   --> $DIR/slice-issue-87994.rs:11:13
    |
 LL |   for i2 in v2[1..] {
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs
index 4baf198b12fae..747081933172b 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs
@@ -5,7 +5,7 @@ use std::fmt::Debug;
 fn main() {}
 
 type Two = impl Debug;
-//~^ ERROR the trait bound `A: Foo` is not satisfied
+//~^ ERROR the trait bound `A: Foo` is not satisfied in `(A, B, ::Bar)`
 //~| ERROR `A` doesn't implement `Debug`
 //~| ERROR `B` doesn't implement `Debug`
 
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
index f21e036edc2ca..a8eb53a50e38b 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
@@ -10,6 +10,18 @@ note: previous use here
 LL | fn two(t: T, u: U) -> Two {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error[E0277]: the trait bound `A: Foo` is not satisfied in `(A, B, ::Bar)`
+  --> $DIR/generic_duplicate_param_use9.rs:7:18
+   |
+LL | type Two = impl Debug;
+   |                  ^^^^^^^^^^ within `(A, B, ::Bar)`, the trait `Foo` is not implemented for `A`
+   |
+   = note: required because it appears within the type `(A, B, ::Bar)`
+help: consider restricting type parameter `A`
+   |
+LL | type Two = impl Debug;
+   |           +++++
+
 error[E0277]: `A` doesn't implement `Debug`
   --> $DIR/generic_duplicate_param_use9.rs:7:18
    |
@@ -34,18 +46,6 @@ help: consider restricting type parameter `B`
 LL | type Two = impl Debug;
    |              +++++++++++++++++
 
-error[E0277]: the trait bound `A: Foo` is not satisfied
-  --> $DIR/generic_duplicate_param_use9.rs:7:18
-   |
-LL | type Two = impl Debug;
-   |                  ^^^^^^^^^^ the trait `Foo` is not implemented for `A`
-   |
-   = note: required because of the requirements on the impl of `Debug` for `(A, B, ::Bar)`
-help: consider restricting type parameter `A`
-   |
-LL | type Two = impl Debug;
-   |           +++++
-
 error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/typeck/issue-89935.rs b/src/test/ui/typeck/issue-89935.rs
new file mode 100644
index 0000000000000..03f8f09a72201
--- /dev/null
+++ b/src/test/ui/typeck/issue-89935.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+trait Foo: Baz {}
+trait Bar {}
+trait Baz: Bar {
+    fn bar(&self);
+}
+
+impl Bar for T {}
+impl Baz for T {
+    fn bar(&self) {}
+}
+
+fn accept_foo(x: Box) {
+    x.bar();
+}
+
+fn main() {}
diff --git a/src/test/ui/unique-object-noncopyable.stderr b/src/test/ui/unique-object-noncopyable.stderr
index 8626b726f47c4..5c40787febfb7 100644
--- a/src/test/ui/unique-object-noncopyable.stderr
+++ b/src/test/ui/unique-object-noncopyable.stderr
@@ -19,10 +19,10 @@ LL | | >(Unique, A);
    | |________________- doesn't satisfy `Box: Clone`
    |
    = note: the following trait bounds were not satisfied:
-           `dyn Foo: Clone`
-           which is required by `Box: Clone`
            `dyn Foo: Sized`
            which is required by `Box: Clone`
+           `dyn Foo: Clone`
+           which is required by `Box: Clone`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unsized/unsized-bare-typaram.stderr b/src/test/ui/unsized/unsized-bare-typaram.stderr
index 0dd439e14e3cd..531e9b4c9c955 100644
--- a/src/test/ui/unsized/unsized-bare-typaram.stderr
+++ b/src/test/ui/unsized/unsized-bare-typaram.stderr
@@ -7,10 +7,10 @@ LL | fn foo() { bar::() }
    |        this type parameter needs to be `std::marker::Sized`
    |
 note: required by a bound in `bar`
-  --> $DIR/unsized-bare-typaram.rs:1:11
+  --> $DIR/unsized-bare-typaram.rs:1:8
    |
 LL | fn bar() { }
-   |           ^^^^^ required by this bound in `bar`
+   |        ^ required by this bound in `bar`
 help: consider removing the `?Sized` bound to make the type parameter `Sized`
    |
 LL - fn foo() { bar::() }
diff --git a/src/test/ui/unsized/unsized-struct.stderr b/src/test/ui/unsized/unsized-struct.stderr
index 88ba7567402db..1c70a840c77dc 100644
--- a/src/test/ui/unsized/unsized-struct.stderr
+++ b/src/test/ui/unsized/unsized-struct.stderr
@@ -38,10 +38,10 @@ note: required because it appears within the type `Bar`
 LL | struct Bar { data: T }
    |        ^^^
 note: required by a bound in `is_sized`
-  --> $DIR/unsized-struct.rs:1:15
+  --> $DIR/unsized-struct.rs:1:13
    |
 LL | fn is_sized() { }
-   |               ^^^^^ required by this bound in `is_sized`
+   |             ^ required by this bound in `is_sized`
 help: consider removing the `?Sized` bound to make the type parameter `Sized`
    |
 LL - fn bar2() { is_sized::>() }
diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs
index ba4d50bf74469..74cf323720cbb 100644
--- a/src/tools/clippy/clippy_utils/src/higher.rs
+++ b/src/tools/clippy/clippy_utils/src/higher.rs
@@ -619,7 +619,6 @@ impl PanicExpn<'tcx> {
             if let Some(init) = block.expr;
             if let ExprKind::Call(_, [format_args]) = init.kind;
             let expn_data = expr.span.ctxt().outer_expn_data();
-            if let ExprKind::AddrOf(_, _, format_args) = format_args.kind;
             if let Some(format_args) = FormatArgsExpn::parse(format_args);
             then {
                 Some(PanicExpn {
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index c47aa9170e547..8e94d16a33a0e 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -1646,7 +1646,6 @@ pub fn match_panic_def_id(cx: &LateContext<'_>, did: DefId) -> bool {
         did,
         &[
             &paths::BEGIN_PANIC,
-            &paths::BEGIN_PANIC_FMT,
             &paths::PANIC_ANY,
             &paths::PANICKING_PANIC,
             &paths::PANICKING_PANIC_FMT,
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index e43c575602145..81aff585ded1b 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -20,7 +20,6 @@ pub const ARC_PTR_EQ: [&str; 4] = ["alloc", "sync", "Arc", "ptr_eq"];
 pub const ASMUT_TRAIT: [&str; 3] = ["core", "convert", "AsMut"];
 pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"];
 pub(super) const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"];
-pub(super) const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"];
 /// Preferably use the diagnostic item `sym::Borrow` where possible
 pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"];
 pub const BTREEMAP_CONTAINS_KEY: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "contains_key"];