diff --git a/.mailmap b/.mailmap index 21e1adb43cff..26d6be9f0c60 100644 --- a/.mailmap +++ b/.mailmap @@ -429,6 +429,8 @@ Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> nils <48135649+Nilstrieb Nif Ward Nika Layzell NODA Kai +Oğuz Ağcayazı +Oğuz Ağcayazı oliver <16816606+o752d@users.noreply.github.com> Oliver Middleton Oliver Scherer diff --git a/.reuse/dep5 b/.reuse/dep5 index 35495de37382..60d9fed49dea 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -23,6 +23,7 @@ Files: compiler/* README.md RELEASES.md rustfmt.toml + rust-bors.toml triagebot.toml x x.ps1 diff --git a/Cargo.lock b/Cargo.lock index 977ef880b23c..33eddef5e948 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2643,9 +2643,9 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "jemalloc-sys" -version = "0.5.3+5.3.0-patched" +version = "0.5.4+5.3.0-patched" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9bd5d616ea7ed58b571b2e209a65759664d7fb021a0819d7a790afc67e47ca1" +checksum = "ac6c1946e1cea1788cbfde01c993b52a10e2da07f4bac608228d1bed20bfebf2" dependencies = [ "cc", "libc", @@ -2768,6 +2768,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "libloading" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "libm" version = "0.1.4" @@ -3043,7 +3053,7 @@ dependencies = [ "lazy_static", "libc", "libffi", - "libloading", + "libloading 0.8.1", "log", "measureme", "rand", @@ -3051,7 +3061,7 @@ dependencies = [ "rustc_version", "serde", "smallvec", - "ui_test 0.11.7", + "ui_test 0.21.2", ] [[package]] @@ -4667,7 +4677,7 @@ dependencies = [ name = "rustc_interface" version = "0.0.0" dependencies = [ - "libloading", + "libloading 0.7.4", "rustc-rayon", "rustc-rayon-core", "rustc_ast", @@ -4798,7 +4808,7 @@ name = "rustc_metadata" version = "0.0.0" dependencies = [ "bitflags 1.3.2", - "libloading", + "libloading 0.7.4", "odht", "rustc_ast", "rustc_attr", @@ -5013,7 +5023,7 @@ dependencies = [ name = "rustc_plugin_impl" version = "0.0.0" dependencies = [ - "libloading", + "libloading 0.7.4", "rustc_ast", "rustc_errors", "rustc_fluent_macro", @@ -5216,6 +5226,7 @@ dependencies = [ "rustc_data_structures", "rustc_feature", "rustc_fs_util", + "rustc_index", "rustc_macros", "rustc_serialize", "rustc_span", @@ -6543,18 +6554,23 @@ checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" [[package]] name = "ui_test" -version = "0.11.7" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c21899b59f53717dfad29e4f46e5b21a200a1b6888ab86532a07cfc8b48dd78c" +checksum = "bfd8fb9b15c8332cf51bfc2dc4830063b2446a9c9d732421b56f2478024a3971" dependencies = [ + "annotate-snippets", + "anyhow", "bstr", "cargo-platform", "cargo_metadata", "color-eyre", "colored", + "comma", "crossbeam-channel", - "diff", + "indicatif", "lazy_static", + "levenshtein", + "prettydiff", "regex", "rustc_version", "rustfix", @@ -6565,9 +6581,9 @@ dependencies = [ [[package]] name = "ui_test" -version = "0.20.0" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd8fb9b15c8332cf51bfc2dc4830063b2446a9c9d732421b56f2478024a3971" +checksum = "aaf4bf7c184b8dfc7a4d3b90df789b1eb992ee42811cd115f32a7a1eb781058d" dependencies = [ "annotate-snippets", "anyhow", diff --git a/RELEASES.md b/RELEASES.md index d390f2b7f5ea..e261294a032f 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,120 @@ +Version 1.73.0 (2023-10-05) +========================== + + + +Language +-------- + +- [Uplift `clippy::fn_null_check` lint as `useless_ptr_null_checks`.](https://github.com/rust-lang/rust/pull/111717/) +- [Make `noop_method_call` warn by default.](https://github.com/rust-lang/rust/pull/111916/) +- [Support interpolated block for `try` and `async` in macros.](https://github.com/rust-lang/rust/pull/112953/) +- [Make `unconditional_recursion` lint detect recursive drops.](https://github.com/rust-lang/rust/pull/113902/) +- [Future compatibility warning for some impls being incorrectly considered not overlapping.](https://github.com/rust-lang/rust/pull/114023/) +- [The `invalid_reference_casting` lint is now **deny-by-default** (instead of allow-by-default)](https://github.com/rust-lang/rust/pull/112431) + + + +Compiler +-------- + +- [Write version information in a `.comment` section like GCC/Clang.](https://github.com/rust-lang/rust/pull/97550/) +- [Add documentation on v0 symbol mangling.](https://github.com/rust-lang/rust/pull/97571/) +- [Stabilize `extern "thiscall"` and `"thiscall-unwind"` ABIs.](https://github.com/rust-lang/rust/pull/114562/) +- [Only check outlives goals on impl compared to trait.](https://github.com/rust-lang/rust/pull/109356/) +- [Infer type in irrefutable slice patterns with fixed length as array.](https://github.com/rust-lang/rust/pull/113199/) +- [Discard default auto trait impls if explicit ones exist.](https://github.com/rust-lang/rust/pull/113312/) +- Add several new tier 3 targets: + - [`aarch64-unknown-teeos`](https://github.com/rust-lang/rust/pull/113480/) + - [`csky-unknown-linux-gnuabiv2`](https://github.com/rust-lang/rust/pull/113658/) + - [`riscv64-linux-android`](https://github.com/rust-lang/rust/pull/112858/) + - [`riscv64gc-unknown-hermit`](https://github.com/rust-lang/rust/pull/114004/) + - [`x86_64-unikraft-linux-musl`](https://github.com/rust-lang/rust/pull/113411/) + - [`x86_64-unknown-linux-ohos`](https://github.com/rust-lang/rust/pull/113061/) +- [Add `wasm32-wasi-preview1-threads` as a tier 2 target.](https://github.com/rust-lang/rust/pull/112922/) + +Refer to Rust's [platform support page][platform-support-doc] +for more information on Rust's tiered platform support. + + + +Libraries +--------- + +- [Add `Read`, `Write` and `Seek` impls for `Arc`.](https://github.com/rust-lang/rust/pull/94748/) +- [Merge functionality of `io::Sink` into `io::Empty`.](https://github.com/rust-lang/rust/pull/98154/) +- [Implement `RefUnwindSafe` for `Backtrace`](https://github.com/rust-lang/rust/pull/100455/) +- [Make `ExitStatus` implement `Default`](https://github.com/rust-lang/rust/pull/106425/) +- [`impl SliceIndex for (Bound, Bound)`](https://github.com/rust-lang/rust/pull/111081/) +- [Change default panic handler message format.](https://github.com/rust-lang/rust/pull/112849/) +- [Cleaner `assert_eq!` & `assert_ne!` panic messages.](https://github.com/rust-lang/rust/pull/111071/) +- [Correct the (deprecated) Android `stat` struct definitions.](https://github.com/rust-lang/rust/pull/113130/) + + + +Stabilized APIs +--------------- + +- [Unsigned `{integer}::div_ceil`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.div_ceil) +- [Unsigned `{integer}::next_multiple_of`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.next_multiple_of) +- [Unsigned `{integer}::checked_next_multiple_of`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.checked_next_multiple_of) +- [`std::ffi::FromBytesUntilNulError`](https://doc.rust-lang.org/stable/std/ffi/struct.FromBytesUntilNulError.html) +- [`std::os::unix::fs::chown`](https://doc.rust-lang.org/stable/std/os/unix/fs/fn.chown.html) +- [`std::os::unix::fs::fchown`](https://doc.rust-lang.org/stable/std/os/unix/fs/fn.fchown.html) +- [`std::os::unix::fs::lchown`](https://doc.rust-lang.org/stable/std/os/unix/fs/fn.lchown.html) +- [`LocalKey::>::get`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.get) +- [`LocalKey::>::set`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.set) +- [`LocalKey::>::take`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.take) +- [`LocalKey::>::replace`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.replace) +- [`LocalKey::>::with_borrow`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.with_borrow) +- [`LocalKey::>::with_borrow_mut`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.with_borrow_mut) +- [`LocalKey::>::set`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.set-1) +- [`LocalKey::>::take`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.take-1) +- [`LocalKey::>::replace`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.replace-1) + +These APIs are now stable in const contexts: + +- [`rc::Weak::new`](https://doc.rust-lang.org/stable/alloc/rc/struct.Weak.html#method.new) +- [`sync::Weak::new`](https://doc.rust-lang.org/stable/alloc/sync/struct.Weak.html#method.new) +- [`NonNull::as_ref`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.as_ref) + + + +Cargo +----- + +- [Encode URL params correctly for `SourceId` in `Cargo.lock`.](https://github.com/rust-lang/cargo/pull/12280/) +- [Bail out an error when using `cargo::` in custom build script.](https://github.com/rust-lang/cargo/pull/12332/) + + + +Misc +---- + + + +Compatibility Notes +------------------- + +- [Update the minimum external LLVM to 15.](https://github.com/rust-lang/rust/pull/114148/) +- [Check for non-defining uses of return position `impl Trait`.](https://github.com/rust-lang/rust/pull/112842/) + + + +Internal Changes +---------------- + +These changes do not affect any public interfaces of Rust, but they represent +significant improvements to the performance or internals of rustc and related +tools. + +- [Remove LLVM pointee types, supporting only opaque pointers.](https://github.com/rust-lang/rust/pull/105545/) +- [Port PGO/LTO/BOLT optimized build pipeline to Rust.](https://github.com/rust-lang/rust/pull/112235/) +- [Replace in-tree `rustc_apfloat` with the new version of the crate.](https://github.com/rust-lang/rust/pull/113843/) +- [Update to LLVM 17.](https://github.com/rust-lang/rust/pull/114048/) +- [Add `internal_features` lint for internal unstable features.](https://github.com/rust-lang/rust/pull/108955/) +- [Mention style for new syntax in tracking issue template.](https://github.com/rust-lang/rust/pull/113586/) + Version 1.72.1 (2023-09-19) =========================== diff --git a/compiler/rustc_abi/Cargo.toml b/compiler/rustc_abi/Cargo.toml index 48b199cb8eed..c43fd745e8f5 100644 --- a/compiler/rustc_abi/Cargo.toml +++ b/compiler/rustc_abi/Cargo.toml @@ -15,7 +15,9 @@ rustc_serialize = { path = "../rustc_serialize", optional = true } [features] default = ["nightly", "randomize"] -randomize = ["rand", "rand_xoshiro"] +randomize = ["rand", "rand_xoshiro", "nightly"] +# rust-analyzer depends on this crate and we therefore require it to built on a stable toolchain +# without depending on rustc_data_structures, rustc_macros and rustc_serialize nightly = [ "rustc_data_structures", "rustc_index/nightly", diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 0706dc18f0ec..00d862ca27b7 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -1,21 +1,27 @@ -use super::*; -use std::fmt::Write; +use std::fmt::{self, Write}; +use std::ops::Deref; use std::{borrow::Borrow, cmp, iter, ops::Bound}; -#[cfg(feature = "randomize")] -use rand::{seq::SliceRandom, SeedableRng}; -#[cfg(feature = "randomize")] -use rand_xoshiro::Xoshiro128StarStar; - +use rustc_index::Idx; use tracing::debug; +use crate::{ + Abi, AbiAndPrefAlign, Align, FieldsShape, IndexSlice, IndexVec, Integer, LayoutS, Niche, + NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, TargetDataLayout, + Variants, WrappingRange, +}; + pub trait LayoutCalculator { type TargetDataLayoutRef: Borrow; fn delay_bug(&self, txt: String); fn current_data_layout(&self) -> Self::TargetDataLayoutRef; - fn scalar_pair(&self, a: Scalar, b: Scalar) -> LayoutS { + fn scalar_pair( + &self, + a: Scalar, + b: Scalar, + ) -> LayoutS { let dl = self.current_data_layout(); let dl = dl.borrow(); let b_align = b.align(dl); @@ -31,7 +37,7 @@ pub trait LayoutCalculator { .max_by_key(|niche| niche.available(dl)); LayoutS { - variants: Variants::Single { index: FIRST_VARIANT }, + variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Arbitrary { offsets: [Size::ZERO, b_offset].into(), memory_index: [0, 1].into(), @@ -45,40 +51,45 @@ pub trait LayoutCalculator { } } - fn univariant( + fn univariant< + 'a, + FieldIdx: Idx, + VariantIdx: Idx, + F: Deref> + fmt::Debug, + >( &self, dl: &TargetDataLayout, - fields: &IndexSlice>, + fields: &IndexSlice, repr: &ReprOptions, kind: StructKind, - ) -> Option { + ) -> Option> { let layout = univariant(self, dl, fields, repr, kind, NicheBias::Start); - // Enums prefer niches close to the beginning or the end of the variants so that other (smaller) - // data-carrying variants can be packed into the space after/before the niche. + // Enums prefer niches close to the beginning or the end of the variants so that other + // (smaller) data-carrying variants can be packed into the space after/before the niche. // If the default field ordering does not give us a niche at the front then we do a second - // run and bias niches to the right and then check which one is closer to one of the struct's - // edges. + // run and bias niches to the right and then check which one is closer to one of the + // struct's edges. if let Some(layout) = &layout { // Don't try to calculate an end-biased layout for unsizable structs, // otherwise we could end up with different layouts for - // Foo and Foo which would break unsizing + // Foo and Foo which would break unsizing. if !matches!(kind, StructKind::MaybeUnsized) { if let Some(niche) = layout.largest_niche { let head_space = niche.offset.bytes(); - let niche_length = niche.value.size(dl).bytes(); - let tail_space = layout.size.bytes() - head_space - niche_length; + let niche_len = niche.value.size(dl).bytes(); + let tail_space = layout.size.bytes() - head_space - niche_len; - // This may end up doing redundant work if the niche is already in the last field - // (e.g. a trailing bool) and there is tail padding. But it's non-trivial to get - // the unpadded size so we try anyway. + // This may end up doing redundant work if the niche is already in the last + // field (e.g. a trailing bool) and there is tail padding. But it's non-trivial + // to get the unpadded size so we try anyway. if fields.len() > 1 && head_space != 0 && tail_space > 0 { let alt_layout = univariant(self, dl, fields, repr, kind, NicheBias::End) .expect("alt layout should always work"); - let niche = alt_layout + let alt_niche = alt_layout .largest_niche .expect("alt layout should have a niche like the regular one"); - let alt_head_space = niche.offset.bytes(); - let alt_niche_len = niche.value.size(dl).bytes(); + let alt_head_space = alt_niche.offset.bytes(); + let alt_niche_len = alt_niche.value.size(dl).bytes(); let alt_tail_space = alt_layout.size.bytes() - alt_head_space - alt_niche_len; @@ -93,7 +104,7 @@ pub trait LayoutCalculator { alt_layout: {}\n", layout.size.bytes(), head_space, - niche_length, + niche_len, tail_space, alt_head_space, alt_niche_len, @@ -114,11 +125,13 @@ pub trait LayoutCalculator { layout } - fn layout_of_never_type(&self) -> LayoutS { + fn layout_of_never_type( + &self, + ) -> LayoutS { let dl = self.current_data_layout(); let dl = dl.borrow(); LayoutS { - variants: Variants::Single { index: FIRST_VARIANT }, + variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Primitive, abi: Abi::Uninhabited, largest_niche: None, @@ -129,10 +142,15 @@ pub trait LayoutCalculator { } } - fn layout_of_struct_or_enum( + fn layout_of_struct_or_enum< + 'a, + FieldIdx: Idx, + VariantIdx: Idx, + F: Deref> + fmt::Debug, + >( &self, repr: &ReprOptions, - variants: &IndexSlice>>, + variants: &IndexSlice>, is_enum: bool, is_unsafe_cell: bool, scalar_valid_range: (Bound, Bound), @@ -140,7 +158,7 @@ pub trait LayoutCalculator { discriminants: impl Iterator, dont_niche_optimize_enum: bool, always_sized: bool, - ) -> Option { + ) -> Option> { let dl = self.current_data_layout(); let dl = dl.borrow(); @@ -155,11 +173,11 @@ pub trait LayoutCalculator { // but *not* an encoding of the discriminant (e.g., a tag value). // See issue #49298 for more details on the need to leave space // for non-ZST uninhabited data (mostly partial initialization). - let absent = |fields: &IndexSlice>| { - let uninhabited = fields.iter().any(|f| f.abi().is_uninhabited()); + let absent = |fields: &IndexSlice| { + let uninhabited = fields.iter().any(|f| f.abi.is_uninhabited()); // We cannot ignore alignment; that might lead us to entirely discard a variant and // produce an enum that is less aligned than it should be! - let is_1zst = fields.iter().all(|f| f.0.is_1zst()); + let is_1zst = fields.iter().all(|f| f.is_1zst()); uninhabited && is_1zst }; let (present_first, present_second) = { @@ -176,7 +194,7 @@ pub trait LayoutCalculator { } // If it's a struct, still compute a layout so that we can still compute the // field offsets. - None => FIRST_VARIANT, + None => VariantIdx::new(0), }; let is_struct = !is_enum || @@ -279,12 +297,12 @@ pub trait LayoutCalculator { // variant layouts, so we can't store them in the // overall LayoutS. Store the overall LayoutS // and the variant LayoutSs here until then. - struct TmpLayout { - layout: LayoutS, - variants: IndexVec, + struct TmpLayout { + layout: LayoutS, + variants: IndexVec>, } - let calculate_niche_filling_layout = || -> Option { + let calculate_niche_filling_layout = || -> Option> { if dont_niche_optimize_enum { return None; } @@ -322,13 +340,14 @@ pub trait LayoutCalculator { let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap() ..=all_indices.rev().find(|v| needs_disc(*v)).unwrap(); - let count = niche_variants.size_hint().1.unwrap() as u128; + let count = + (niche_variants.end().index() as u128 - niche_variants.start().index() as u128) + 1; // Find the field with the largest niche let (field_index, niche, (niche_start, niche_scalar)) = variants[largest_variant_index] .iter() .enumerate() - .filter_map(|(j, field)| Some((j, field.largest_niche()?))) + .filter_map(|(j, field)| Some((j, field.largest_niche?))) .max_by_key(|(_, niche)| niche.available(dl)) .and_then(|(j, niche)| Some((j, niche, niche.reserve(dl, count)?)))?; let niche_offset = @@ -443,7 +462,7 @@ pub trait LayoutCalculator { let discr_type = repr.discr_type(); let bits = Integer::from_attr(dl, discr_type).size().bits(); for (i, mut val) in discriminants { - if variants[i].iter().any(|f| f.abi().is_uninhabited()) { + if variants[i].iter().any(|f| f.abi.is_uninhabited()) { continue; } if discr_type.is_signed() { @@ -484,7 +503,7 @@ pub trait LayoutCalculator { if repr.c() { for fields in variants { for field in fields { - prefix_align = prefix_align.max(field.align().abi); + prefix_align = prefix_align.max(field.align.abi); } } } @@ -503,9 +522,9 @@ pub trait LayoutCalculator { // Find the first field we can't move later // to make room for a larger discriminant. for field_idx in st.fields.index_by_increasing_offset() { - let field = &field_layouts[FieldIdx::from_usize(field_idx)]; - if !field.0.is_1zst() { - start_align = start_align.min(field.align().abi); + let field = &field_layouts[FieldIdx::new(field_idx)]; + if !field.is_1zst() { + start_align = start_align.min(field.align.abi); break; } } @@ -587,7 +606,7 @@ pub trait LayoutCalculator { let tag_mask = ity.size().unsigned_int_max(); let tag = Scalar::Initialized { - value: Int(ity, signed), + value: Primitive::Int(ity, signed), valid_range: WrappingRange { start: (min as u128 & tag_mask), end: (max as u128 & tag_mask), @@ -612,7 +631,7 @@ pub trait LayoutCalculator { }; // We skip *all* ZST here and later check if we are good in terms of alignment. // This lets us handle some cases involving aligned ZST. - let mut fields = iter::zip(field_layouts, offsets).filter(|p| !p.0.0.is_zst()); + let mut fields = iter::zip(field_layouts, offsets).filter(|p| !p.0.is_zst()); let (field, offset) = match (fields.next(), fields.next()) { (None, None) => { common_prim_initialized_in_all_variants = false; @@ -624,7 +643,7 @@ pub trait LayoutCalculator { break; } }; - let prim = match field.abi() { + let prim = match field.abi { Abi::Scalar(scalar) => { common_prim_initialized_in_all_variants &= matches!(scalar, Scalar::Initialized { .. }); @@ -655,7 +674,7 @@ pub trait LayoutCalculator { // Common prim might be uninit. Scalar::Union { value: prim } }; - let pair = self.scalar_pair(tag, prim_scalar); + let pair = self.scalar_pair::(tag, prim_scalar); let pair_offsets = match pair.fields { FieldsShape::Arbitrary { ref offsets, ref memory_index } => { assert_eq!(memory_index.raw, [0, 1]); @@ -663,8 +682,8 @@ pub trait LayoutCalculator { } _ => panic!(), }; - if pair_offsets[FieldIdx::from_u32(0)] == Size::ZERO - && pair_offsets[FieldIdx::from_u32(1)] == *offset + if pair_offsets[FieldIdx::new(0)] == Size::ZERO + && pair_offsets[FieldIdx::new(1)] == *offset && align == pair.align && size == pair.size { @@ -684,7 +703,8 @@ pub trait LayoutCalculator { // Also do not overwrite any already existing "clever" ABIs. if variant.fields.count() > 0 && matches!(variant.abi, Abi::Aggregate { .. }) { variant.abi = abi; - // Also need to bump up the size and alignment, so that the entire value fits in here. + // Also need to bump up the size and alignment, so that the entire value fits + // in here. variant.size = cmp::max(variant.size, size); variant.align.abi = cmp::max(variant.align.abi, align.abi); } @@ -720,8 +740,9 @@ pub trait LayoutCalculator { // pick the layout with the larger niche; otherwise, // pick tagged as it has simpler codegen. use cmp::Ordering::*; - let niche_size = - |tmp_l: &TmpLayout| tmp_l.layout.largest_niche.map_or(0, |n| n.available(dl)); + let niche_size = |tmp_l: &TmpLayout| { + tmp_l.layout.largest_niche.map_or(0, |n| n.available(dl)) + }; match (tl.layout.size.cmp(&nl.layout.size), niche_size(&tl).cmp(&niche_size(&nl))) { (Greater, _) => nl, (Equal, Less) => nl, @@ -741,11 +762,16 @@ pub trait LayoutCalculator { Some(best_layout.layout) } - fn layout_of_union( + fn layout_of_union< + 'a, + FieldIdx: Idx, + VariantIdx: Idx, + F: Deref> + fmt::Debug, + >( &self, repr: &ReprOptions, - variants: &IndexSlice>>, - ) -> Option { + variants: &IndexSlice>, + ) -> Option> { let dl = self.current_data_layout(); let dl = dl.borrow(); let mut align = if repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align }; @@ -762,24 +788,24 @@ pub trait LayoutCalculator { }; let mut size = Size::ZERO; - let only_variant = &variants[FIRST_VARIANT]; + let only_variant = &variants[VariantIdx::new(0)]; for field in only_variant { - if field.0.is_unsized() { + if field.is_unsized() { self.delay_bug("unsized field in union".to_string()); } - align = align.max(field.align()); - max_repr_align = max_repr_align.max(field.max_repr_align()); - size = cmp::max(size, field.size()); + align = align.max(field.align); + max_repr_align = max_repr_align.max(field.max_repr_align); + size = cmp::max(size, field.size); - if field.0.is_zst() { + if field.is_zst() { // Nothing more to do for ZST fields continue; } if let Ok(common) = common_non_zst_abi_and_align { // Discard valid range information and allow undef - let field_abi = field.abi().to_union(); + let field_abi = field.abi.to_union(); if let Some((common_abi, common_align)) = common { if common_abi != field_abi { @@ -790,15 +816,14 @@ pub trait LayoutCalculator { // have the same alignment if !matches!(common_abi, Abi::Aggregate { .. }) { assert_eq!( - common_align, - field.align().abi, + common_align, field.align.abi, "non-Aggregate field with matching ABI but differing alignment" ); } } } else { // First non-ZST field: record its ABI and alignment - common_non_zst_abi_and_align = Ok(Some((field_abi, field.align().abi))); + common_non_zst_abi_and_align = Ok(Some((field_abi, field.align.abi))); } } } @@ -830,7 +855,7 @@ pub trait LayoutCalculator { }; Some(LayoutS { - variants: Variants::Single { index: FIRST_VARIANT }, + variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Union(NonZeroUsize::new(only_variant.len())?), abi, largest_niche: None, @@ -848,14 +873,19 @@ enum NicheBias { End, } -fn univariant( +fn univariant< + 'a, + FieldIdx: Idx, + VariantIdx: Idx, + F: Deref> + fmt::Debug, +>( this: &(impl LayoutCalculator + ?Sized), dl: &TargetDataLayout, - fields: &IndexSlice>, + fields: &IndexSlice, repr: &ReprOptions, kind: StructKind, niche_bias: NicheBias, -) -> Option { +) -> Option> { let pack = repr.pack; let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align }; let mut max_repr_align = repr.align; @@ -868,15 +898,18 @@ fn univariant( // If `-Z randomize-layout` was enabled for the type definition we can shuffle // the field ordering to try and catch some code making assumptions about layouts - // we don't guarantee + // we don't guarantee. if repr.can_randomize_type_layout() && cfg!(feature = "randomize") { #[cfg(feature = "randomize")] { - // `ReprOptions.layout_seed` is a deterministic seed that we can use to - // randomize field ordering with - let mut rng = Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed.as_u64()); - - // Shuffle the ordering of the fields + use rand::{seq::SliceRandom, SeedableRng}; + // `ReprOptions.layout_seed` is a deterministic seed we can use to randomize field + // ordering. + let mut rng = rand_xoshiro::Xoshiro128StarStar::seed_from_u64( + repr.field_shuffle_seed.as_u64(), + ); + + // Shuffle the ordering of the fields. optimizing.shuffle(&mut rng); } // Otherwise we just leave things alone and actually optimize the type's fields @@ -884,35 +917,34 @@ fn univariant( // To allow unsizing `&Foo` -> `&Foo`, the layout of the struct must // not depend on the layout of the tail. let max_field_align = - fields_excluding_tail.iter().map(|f| f.align().abi.bytes()).max().unwrap_or(1); + fields_excluding_tail.iter().map(|f| f.align.abi.bytes()).max().unwrap_or(1); let largest_niche_size = fields_excluding_tail .iter() - .filter_map(|f| f.largest_niche()) + .filter_map(|f| f.largest_niche) .map(|n| n.available(dl)) .max() .unwrap_or(0); - // Calculates a sort key to group fields by their alignment or possibly some size-derived - // pseudo-alignment. - let alignment_group_key = |layout: Layout<'_>| { + // Calculates a sort key to group fields by their alignment or possibly some + // size-derived pseudo-alignment. + let alignment_group_key = |layout: &F| { if let Some(pack) = pack { - // return the packed alignment in bytes - layout.align().abi.min(pack).bytes() + // Return the packed alignment in bytes. + layout.align.abi.min(pack).bytes() } else { - // returns log2(effective-align). - // This is ok since `pack` applies to all fields equally. - // The calculation assumes that size is an integer multiple of align, except for ZSTs. - // - let align = layout.align().abi.bytes(); - let size = layout.size().bytes(); - let niche_size = layout.largest_niche().map(|n| n.available(dl)).unwrap_or(0); - // group [u8; 4] with align-4 or [u8; 6] with align-2 fields + // Returns `log2(effective-align)`. This is ok since `pack` applies to all + // fields equally. The calculation assumes that size is an integer multiple of + // align, except for ZSTs. + let align = layout.align.abi.bytes(); + let size = layout.size.bytes(); + let niche_size = layout.largest_niche.map(|n| n.available(dl)).unwrap_or(0); + // Group [u8; 4] with align-4 or [u8; 6] with align-2 fields. let size_as_align = align.max(size).trailing_zeros(); let size_as_align = if largest_niche_size > 0 { match niche_bias { - // Given `A(u8, [u8; 16])` and `B(bool, [u8; 16])` we want to bump the array - // to the front in the first case (for aligned loads) but keep the bool in front - // in the second case for its niches. + // Given `A(u8, [u8; 16])` and `B(bool, [u8; 16])` we want to bump the + // array to the front in the first case (for aligned loads) but keep + // the bool in front in the second case for its niches. NicheBias::Start => max_field_align.trailing_zeros().min(size_as_align), // When moving niches towards the end of the struct then for // A((u8, u8, u8, bool), (u8, bool, u8)) we want to keep the first tuple @@ -931,18 +963,18 @@ fn univariant( match kind { StructKind::AlwaysSized | StructKind::MaybeUnsized => { - // Currently `LayoutS` only exposes a single niche so sorting is usually sufficient - // to get one niche into the preferred position. If it ever supported multiple niches - // then a more advanced pick-and-pack approach could provide better results. - // But even for the single-niche cache it's not optimal. E.g. for - // A(u32, (bool, u8), u16) it would be possible to move the bool to the front - // but it would require packing the tuple together with the u16 to build a 4-byte - // group so that the u32 can be placed after it without padding. This kind - // of packing can't be achieved by sorting. + // Currently `LayoutS` only exposes a single niche so sorting is usually + // sufficient to get one niche into the preferred position. If it ever + // supported multiple niches then a more advanced pick-and-pack approach could + // provide better results. But even for the single-niche cache it's not + // optimal. E.g. for A(u32, (bool, u8), u16) it would be possible to move the + // bool to the front but it would require packing the tuple together with the + // u16 to build a 4-byte group so that the u32 can be placed after it without + // padding. This kind of packing can't be achieved by sorting. optimizing.sort_by_key(|&x| { - let f = fields[x]; - let field_size = f.size().bytes(); - let niche_size = f.largest_niche().map_or(0, |n| n.available(dl)); + let f = &fields[x]; + let field_size = f.size.bytes(); + let niche_size = f.largest_niche.map_or(0, |n| n.available(dl)); let niche_size_key = match niche_bias { // large niche first NicheBias::Start => !niche_size, @@ -950,8 +982,8 @@ fn univariant( NicheBias::End => niche_size, }; let inner_niche_offset_key = match niche_bias { - NicheBias::Start => f.largest_niche().map_or(0, |n| n.offset.bytes()), - NicheBias::End => f.largest_niche().map_or(0, |n| { + NicheBias::Start => f.largest_niche.map_or(0, |n| n.offset.bytes()), + NicheBias::End => f.largest_niche.map_or(0, |n| { !(field_size - n.value.size(dl).bytes() - n.offset.bytes()) }), }; @@ -975,8 +1007,8 @@ fn univariant( // And put the largest niche in an alignment group at the end // so it can be used as discriminant in jagged enums optimizing.sort_by_key(|&x| { - let f = fields[x]; - let niche_size = f.largest_niche().map_or(0, |n| n.available(dl)); + let f = &fields[x]; + let niche_size = f.largest_niche.map_or(0, |n| n.available(dl)); (alignment_group_key(f), niche_size) }); } @@ -1012,24 +1044,24 @@ fn univariant( )); } - if field.0.is_unsized() { + if field.is_unsized() { sized = false; } // Invariant: offset < dl.obj_size_bound() <= 1<<61 let field_align = if let Some(pack) = pack { - field.align().min(AbiAndPrefAlign::new(pack)) + field.align.min(AbiAndPrefAlign::new(pack)) } else { - field.align() + field.align }; offset = offset.align_to(field_align.abi); align = align.max(field_align); - max_repr_align = max_repr_align.max(field.max_repr_align()); + max_repr_align = max_repr_align.max(field.max_repr_align); debug!("univariant offset: {:?} field: {:#?}", offset, field); offsets[i] = offset; - if let Some(mut niche) = field.largest_niche() { + if let Some(mut niche) = field.largest_niche { let available = niche.available(dl); // Pick up larger niches. let prefer_new_niche = match niche_bias { @@ -1044,7 +1076,7 @@ fn univariant( } } - offset = offset.checked_add(field.size(), dl)?; + offset = offset.checked_add(field.size, dl)?; } // The unadjusted ABI alignment does not include repr(align), but does include repr(pack). @@ -1068,7 +1100,7 @@ fn univariant( inverse_memory_index.invert_bijective_mapping() } else { debug_assert!(inverse_memory_index.iter().copied().eq(fields.indices())); - inverse_memory_index.into_iter().map(FieldIdx::as_u32).collect() + inverse_memory_index.into_iter().map(|it| it.index() as u32).collect() }; let size = min_size.align_to(align.abi); let mut layout_of_single_non_zst_field = None; @@ -1077,7 +1109,7 @@ fn univariant( if sized && size.bytes() > 0 { // We skip *all* ZST here and later check if we are good in terms of alignment. // This lets us handle some cases involving aligned ZST. - let mut non_zst_fields = fields.iter_enumerated().filter(|&(_, f)| !f.0.is_zst()); + let mut non_zst_fields = fields.iter_enumerated().filter(|&(_, f)| !f.is_zst()); match (non_zst_fields.next(), non_zst_fields.next(), non_zst_fields.next()) { // We have exactly one non-ZST field. @@ -1085,18 +1117,17 @@ fn univariant( layout_of_single_non_zst_field = Some(field); // Field fills the struct and it has a scalar or scalar pair ABI. - if offsets[i].bytes() == 0 && align.abi == field.align().abi && size == field.size() - { - match field.abi() { + if offsets[i].bytes() == 0 && align.abi == field.align.abi && size == field.size { + match field.abi { // For plain scalars, or vectors of them, we can't unpack // newtypes for `#[repr(C)]`, as that affects C ABIs. Abi::Scalar(_) | Abi::Vector { .. } if optimize => { - abi = field.abi(); + abi = field.abi; } // But scalar pairs are Rust-specific and get // treated as aggregates by C ABIs anyway. Abi::ScalarPair(..) => { - abi = field.abi(); + abi = field.abi; } _ => {} } @@ -1105,7 +1136,7 @@ fn univariant( // Two non-ZST fields, and they're both scalars. (Some((i, a)), Some((j, b)), None) => { - match (a.abi(), b.abi()) { + match (a.abi, b.abi) { (Abi::Scalar(a), Abi::Scalar(b)) => { // Order by the memory placement, not source order. let ((i, a), (j, b)) = if offsets[i] < offsets[j] { @@ -1113,7 +1144,7 @@ fn univariant( } else { ((j, b), (i, a)) }; - let pair = this.scalar_pair(a, b); + let pair = this.scalar_pair::(a, b); let pair_offsets = match pair.fields { FieldsShape::Arbitrary { ref offsets, ref memory_index } => { assert_eq!(memory_index.raw, [0, 1]); @@ -1121,8 +1152,8 @@ fn univariant( } _ => panic!(), }; - if offsets[i] == pair_offsets[FieldIdx::from_usize(0)] - && offsets[j] == pair_offsets[FieldIdx::from_usize(1)] + if offsets[i] == pair_offsets[FieldIdx::new(0)] + && offsets[j] == pair_offsets[FieldIdx::new(1)] && align == pair.align && size == pair.size { @@ -1138,13 +1169,13 @@ fn univariant( _ => {} } } - if fields.iter().any(|f| f.abi().is_uninhabited()) { + if fields.iter().any(|f| f.abi.is_uninhabited()) { abi = Abi::Uninhabited; } let unadjusted_abi_align = if repr.transparent() { match layout_of_single_non_zst_field { - Some(l) => l.unadjusted_abi_align(), + Some(l) => l.unadjusted_abi_align, None => { // `repr(transparent)` with all ZST fields. align.abi @@ -1155,7 +1186,7 @@ fn univariant( }; Some(LayoutS { - variants: Variants::Single { index: FIRST_VARIANT }, + variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Arbitrary { offsets, memory_index }, abi, largest_niche, @@ -1166,17 +1197,22 @@ fn univariant( }) } -fn format_field_niches( - layout: &LayoutS, - fields: &IndexSlice>, +fn format_field_niches< + 'a, + FieldIdx: Idx, + VariantIdx: Idx, + F: Deref> + fmt::Debug, +>( + layout: &LayoutS, + fields: &IndexSlice, dl: &TargetDataLayout, ) -> String { let mut s = String::new(); for i in layout.fields.index_by_increasing_offset() { let offset = layout.fields.offset(i); - let f = fields[i.into()]; - write!(s, "[o{}a{}s{}", offset.bytes(), f.align().abi.bytes(), f.size().bytes()).unwrap(); - if let Some(n) = f.largest_niche() { + let f = &fields[FieldIdx::new(i)]; + write!(s, "[o{}a{}s{}", offset.bytes(), f.align.abi.bytes(), f.size.bytes()).unwrap(); + if let Some(n) = f.largest_niche { write!( s, " n{}b{}s{}", diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index b30ff058a309..45b3e76cca69 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1,23 +1,22 @@ -#![cfg_attr(feature = "nightly", feature(step_trait, rustc_attrs, min_specialization))] +#![cfg_attr(feature = "nightly", feature(step_trait))] #![cfg_attr(feature = "nightly", allow(internal_features))] use std::fmt; -#[cfg(feature = "nightly")] -use std::iter::Step; use std::num::{NonZeroUsize, ParseIntError}; use std::ops::{Add, AddAssign, Mul, RangeInclusive, Sub}; use std::str::FromStr; use bitflags::bitflags; -use rustc_data_structures::intern::Interned; -use rustc_data_structures::stable_hasher::Hash64; +use rustc_index::{Idx, IndexSlice, IndexVec}; + #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::StableOrd; -use rustc_index::{IndexSlice, IndexVec}; #[cfg(feature = "nightly")] use rustc_macros::HashStable_Generic; #[cfg(feature = "nightly")] use rustc_macros::{Decodable, Encodable}; +#[cfg(feature = "nightly")] +use std::iter::Step; mod layout; @@ -28,9 +27,6 @@ pub use layout::LayoutCalculator; /// instead of implementing everything in `rustc_middle`. pub trait HashStableContext {} -use Integer::*; -use Primitive::*; - bitflags! { #[derive(Default)] #[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] @@ -53,10 +49,11 @@ bitflags! { #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] pub enum IntegerType { - /// Pointer sized integer type, i.e. isize and usize. The field shows signedness, that - /// is, `Pointer(true)` is isize. + /// Pointer-sized integer type, i.e. `isize` and `usize`. The field shows signedness, e.g. + /// `Pointer(true)` means `isize`. Pointer(bool), - /// Fix sized integer type, e.g. i8, u32, i128 The bool field shows signedness, `Fixed(I8, false)` means `u8` + /// Fixed-sized integer type, e.g. `i8`, `u32`, `i128`. The bool field shows signedness, e.g. + /// `Fixed(I8, false)` means `u8`. Fixed(Integer, bool), } @@ -69,7 +66,7 @@ impl IntegerType { } } -/// Represents the repr options provided by the user, +/// Represents the repr options provided by the user. #[derive(Copy, Clone, Debug, Eq, PartialEq, Default)] #[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] pub struct ReprOptions { @@ -77,6 +74,7 @@ pub struct ReprOptions { pub align: Option, pub pack: Option, pub flags: ReprFlags, + #[cfg(feature = "randomize")] /// The seed to be used for randomizing a type's layout /// /// Note: This could technically be a `Hash128` which would @@ -84,7 +82,7 @@ pub struct ReprOptions { /// hash without loss, but it does pay the price of being larger. /// Everything's a tradeoff, a 64-bit seed should be sufficient for our /// purposes (primarily `-Z randomize-layout`) - pub field_shuffle_seed: Hash64, + pub field_shuffle_seed: rustc_data_structures::stable_hasher::Hash64, } impl ReprOptions { @@ -139,7 +137,7 @@ impl ReprOptions { } /// Returns `true` if this type is valid for reordering and `-Z randomize-layout` - /// was enabled for its declaration crate + /// was enabled for its declaration crate. pub fn can_randomize_type_layout(&self) -> bool { !self.inhibit_struct_field_reordering_opt() && self.flags.contains(ReprFlags::RANDOMIZE_LAYOUT) @@ -217,7 +215,8 @@ pub enum TargetDataLayoutErrors<'a> { } impl TargetDataLayout { - /// Parse data layout from an [llvm data layout string](https://llvm.org/docs/LangRef.html#data-layout) + /// Parse data layout from an + /// [llvm data layout string](https://llvm.org/docs/LangRef.html#data-layout) /// /// This function doesn't fill `c_enum_min_size` and it will always be `I32` since it can not be /// determined from llvm string. @@ -242,10 +241,11 @@ impl TargetDataLayout { }; // Parse a size string. - let size = |s: &'a str, cause: &'a str| parse_bits(s, "size", cause).map(Size::from_bits); + let parse_size = + |s: &'a str, cause: &'a str| parse_bits(s, "size", cause).map(Size::from_bits); // Parse an alignment string. - let align = |s: &[&'a str], cause: &'a str| { + let parse_align = |s: &[&'a str], cause: &'a str| { if s.is_empty() { return Err(TargetDataLayoutErrors::MissingAlignment { cause }); } @@ -269,22 +269,22 @@ impl TargetDataLayout { [p] if p.starts_with('P') => { dl.instruction_address_space = parse_address_space(&p[1..], "P")? } - ["a", ref a @ ..] => dl.aggregate_align = align(a, "a")?, - ["f32", ref a @ ..] => dl.f32_align = align(a, "f32")?, - ["f64", ref a @ ..] => dl.f64_align = align(a, "f64")?, + ["a", ref a @ ..] => dl.aggregate_align = parse_align(a, "a")?, + ["f32", ref a @ ..] => dl.f32_align = parse_align(a, "f32")?, + ["f64", ref a @ ..] => dl.f64_align = parse_align(a, "f64")?, // FIXME(erikdesjardins): we should be parsing nonzero address spaces // this will require replacing TargetDataLayout::{pointer_size,pointer_align} // with e.g. `fn pointer_size_in(AddressSpace)` [p @ "p", s, ref a @ ..] | [p @ "p0", s, ref a @ ..] => { - dl.pointer_size = size(s, p)?; - dl.pointer_align = align(a, p)?; + dl.pointer_size = parse_size(s, p)?; + dl.pointer_align = parse_align(a, p)?; } [s, ref a @ ..] if s.starts_with('i') => { let Ok(bits) = s[1..].parse::() else { - size(&s[1..], "i")?; // For the user error. + parse_size(&s[1..], "i")?; // For the user error. continue; }; - let a = align(a, s)?; + let a = parse_align(a, s)?; match bits { 1 => dl.i1_align = a, 8 => dl.i8_align = a, @@ -301,8 +301,8 @@ impl TargetDataLayout { } } [s, ref a @ ..] if s.starts_with('v') => { - let v_size = size(&s[1..], "v")?; - let a = align(a, s)?; + let v_size = parse_size(&s[1..], "v")?; + let a = parse_align(a, s)?; if let Some(v) = dl.vector_align.iter_mut().find(|v| v.0 == v_size) { v.1 = a; continue; @@ -339,6 +339,7 @@ impl TargetDataLayout { #[inline] pub fn ptr_sized_integer(&self) -> Integer { + use Integer::*; match self.pointer_size.bits() { 16 => I16, 32 => I32, @@ -747,7 +748,6 @@ impl Align { /// A pair of alignments, ABI-mandated and preferred. #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] - pub struct AbiAndPrefAlign { pub abi: Align, pub pref: Align, @@ -773,7 +773,6 @@ impl AbiAndPrefAlign { /// Integers, also used for enum discriminants. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] - pub enum Integer { I8, I16, @@ -785,6 +784,7 @@ pub enum Integer { impl Integer { #[inline] pub fn size(self) -> Size { + use Integer::*; match self { I8 => Size::from_bytes(1), I16 => Size::from_bytes(2), @@ -805,6 +805,7 @@ impl Integer { } pub fn align(self, cx: &C) -> AbiAndPrefAlign { + use Integer::*; let dl = cx.data_layout(); match self { @@ -819,6 +820,7 @@ impl Integer { /// Returns the largest signed value that can be represented by this Integer. #[inline] pub fn signed_max(self) -> i128 { + use Integer::*; match self { I8 => i8::MAX as i128, I16 => i16::MAX as i128, @@ -831,6 +833,7 @@ impl Integer { /// Finds the smallest Integer type which can represent the signed value. #[inline] pub fn fit_signed(x: i128) -> Integer { + use Integer::*; match x { -0x0000_0000_0000_0080..=0x0000_0000_0000_007f => I8, -0x0000_0000_0000_8000..=0x0000_0000_0000_7fff => I16, @@ -843,6 +846,7 @@ impl Integer { /// Finds the smallest Integer type which can represent the unsigned value. #[inline] pub fn fit_unsigned(x: u128) -> Integer { + use Integer::*; match x { 0..=0x0000_0000_0000_00ff => I8, 0..=0x0000_0000_0000_ffff => I16, @@ -854,6 +858,7 @@ impl Integer { /// Finds the smallest integer with the given alignment. pub fn for_align(cx: &C, wanted: Align) -> Option { + use Integer::*; let dl = cx.data_layout(); [I8, I16, I32, I64, I128].into_iter().find(|&candidate| { @@ -863,6 +868,7 @@ impl Integer { /// Find the largest integer with the given alignment or less. pub fn approximate_align(cx: &C, wanted: Align) -> Integer { + use Integer::*; let dl = cx.data_layout(); // FIXME(eddyb) maybe include I128 in the future, when it works everywhere. @@ -908,6 +914,7 @@ pub enum Primitive { impl Primitive { pub fn size(self, cx: &C) -> Size { + use Primitive::*; let dl = cx.data_layout(); match self { @@ -922,6 +929,7 @@ impl Primitive { } pub fn align(self, cx: &C) -> AbiAndPrefAlign { + use Primitive::*; let dl = cx.data_layout(); match self { @@ -937,8 +945,7 @@ impl Primitive { } /// Inclusive wrap-around range of valid values, that is, if -/// start > end, it represents `start..=MAX`, -/// followed by `0..=end`. +/// start > end, it represents `start..=MAX`, followed by `0..=end`. /// /// That is, for an i8 primitive, a range of `254..=2` means following /// sequence: @@ -970,21 +977,21 @@ impl WrappingRange { /// Returns `self` with replaced `start` #[inline(always)] - pub fn with_start(mut self, start: u128) -> Self { + fn with_start(mut self, start: u128) -> Self { self.start = start; self } /// Returns `self` with replaced `end` #[inline(always)] - pub fn with_end(mut self, end: u128) -> Self { + fn with_end(mut self, end: u128) -> Self { self.end = end; self } /// Returns `true` if `size` completely fills the range. #[inline] - pub fn is_full_for(&self, size: Size) -> bool { + fn is_full_for(&self, size: Size) -> bool { let max_value = size.unsigned_int_max(); debug_assert!(self.start <= max_value && self.end <= max_value); self.start == (self.end.wrapping_add(1) & max_value) @@ -1027,10 +1034,11 @@ pub enum Scalar { impl Scalar { #[inline] pub fn is_bool(&self) -> bool { + use Integer::*; matches!( self, Scalar::Initialized { - value: Int(I8, false), + value: Primitive::Int(I8, false), valid_range: WrappingRange { start: 0, end: 1 } } ) @@ -1066,7 +1074,8 @@ impl Scalar { } #[inline] - /// Allows the caller to mutate the valid range. This operation will panic if attempted on a union. + /// Allows the caller to mutate the valid range. This operation will panic if attempted on a + /// union. pub fn valid_range_mut(&mut self) -> &mut WrappingRange { match self { Scalar::Initialized { valid_range, .. } => valid_range, @@ -1074,7 +1083,8 @@ impl Scalar { } } - /// Returns `true` if all possible numbers are valid, i.e `valid_range` covers the whole layout + /// Returns `true` if all possible numbers are valid, i.e `valid_range` covers the whole + /// layout. #[inline] pub fn is_always_valid(&self, cx: &C) -> bool { match *self { @@ -1093,36 +1103,11 @@ impl Scalar { } } -rustc_index::newtype_index! { - /// The *source-order* index of a field in a variant. - /// - /// This is how most code after type checking refers to fields, rather than - /// using names (as names have hygiene complications and more complex lookup). - /// - /// Particularly for `repr(Rust)` types, this may not be the same as *layout* order. - /// (It is for `repr(C)` `struct`s, however.) - /// - /// For example, in the following types, - /// ```rust - /// # enum Never {} - /// # #[repr(u16)] - /// enum Demo1 { - /// Variant0 { a: Never, b: i32 } = 100, - /// Variant1 { c: u8, d: u64 } = 10, - /// } - /// struct Demo2 { e: u8, f: u16, g: u8 } - /// ``` - /// `b` is `FieldIdx(1)` in `VariantIdx(0)`, - /// `d` is `FieldIdx(1)` in `VariantIdx(1)`, and - /// `f` is `FieldIdx(1)` in `VariantIdx(0)`. - #[derive(HashStable_Generic)] - pub struct FieldIdx {} -} - +// NOTE: This struct is generic over the FieldIdx for rust-analyzer usage. /// Describes how the fields of a type are located in memory. #[derive(PartialEq, Eq, Hash, Clone, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] -pub enum FieldsShape { +pub enum FieldsShape { /// Scalar primitives and `!`, which never have fields. Primitive, @@ -1162,7 +1147,7 @@ pub enum FieldsShape { }, } -impl FieldsShape { +impl FieldsShape { #[inline] pub fn count(&self) -> usize { match *self { @@ -1188,7 +1173,7 @@ impl FieldsShape { assert!(i < count, "tried to access field {i} of array with {count} fields"); stride * i } - FieldsShape::Arbitrary { ref offsets, .. } => offsets[FieldIdx::from_usize(i)], + FieldsShape::Arbitrary { ref offsets, .. } => offsets[FieldIdx::new(i)], } } @@ -1200,7 +1185,7 @@ impl FieldsShape { } FieldsShape::Union(_) | FieldsShape::Array { .. } => i, FieldsShape::Arbitrary { ref memory_index, .. } => { - memory_index[FieldIdx::from_usize(i)].try_into().unwrap() + memory_index[FieldIdx::new(i)].try_into().unwrap() } } } @@ -1216,7 +1201,7 @@ impl FieldsShape { if let FieldsShape::Arbitrary { ref memory_index, .. } = *self { if use_small { for (field_idx, &mem_idx) in memory_index.iter_enumerated() { - inverse_small[mem_idx as usize] = field_idx.as_u32() as u8; + inverse_small[mem_idx as usize] = field_idx.index() as u8; } } else { inverse_big = memory_index.invert_bijective_mapping(); @@ -1229,7 +1214,7 @@ impl FieldsShape { if use_small { inverse_small[i] as usize } else { - inverse_big[i as u32].as_usize() + inverse_big[i as u32].index() } } }) @@ -1252,7 +1237,6 @@ impl AddressSpace { /// in terms of categories of C types there are ABI rules for. #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] - pub enum Abi { Uninhabited, Scalar(Scalar), @@ -1373,9 +1357,10 @@ impl Abi { } } +// NOTE: This struct is generic over the FieldIdx and VariantIdx for rust-analyzer usage. #[derive(PartialEq, Eq, Hash, Clone, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] -pub enum Variants { +pub enum Variants { /// Single enum variants, structs/tuples, unions, and all non-ADTs. Single { index: VariantIdx }, @@ -1387,15 +1372,16 @@ pub enum Variants { /// For enums, the tag is the sole field of the layout. Multiple { tag: Scalar, - tag_encoding: TagEncoding, + tag_encoding: TagEncoding, tag_field: usize, - variants: IndexVec, + variants: IndexVec>, }, } +// NOTE: This struct is generic over the VariantIdx for rust-analyzer usage. #[derive(PartialEq, Eq, Hash, Clone, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] -pub enum TagEncoding { +pub enum TagEncoding { /// The tag directly stores the discriminant, but possibly with a smaller layout /// (so converting the tag to the discriminant can require sign extension). Direct, @@ -1457,17 +1443,19 @@ impl Niche { return None; } - // Extend the range of valid values being reserved by moving either `v.start` or `v.end` bound. - // Given an eventual `Option`, we try to maximize the chance for `None` to occupy the niche of zero. - // This is accomplished by preferring enums with 2 variants(`count==1`) and always taking the shortest path to niche zero. - // Having `None` in niche zero can enable some special optimizations. + // Extend the range of valid values being reserved by moving either `v.start` or `v.end` + // bound. Given an eventual `Option`, we try to maximize the chance for `None` to occupy + // the niche of zero. This is accomplished by preferring enums with 2 variants(`count==1`) + // and always taking the shortest path to niche zero. Having `None` in niche zero can + // enable some special optimizations. // // Bound selection criteria: // 1. Select closest to zero given wrapping semantics. // 2. Avoid moving past zero if possible. // - // In practice this means that enums with `count > 1` are unlikely to claim niche zero, since they have to fit perfectly. - // If niche zero is already reserved, the selection of bounds are of little interest. + // In practice this means that enums with `count > 1` are unlikely to claim niche zero, + // since they have to fit perfectly. If niche zero is already reserved, the selection of + // bounds are of little interest. let move_start = |v: WrappingRange| { let start = v.start.wrapping_sub(count) & max_value; Some((start, Scalar::Initialized { value, valid_range: v.with_start(start) })) @@ -1501,29 +1489,12 @@ impl Niche { } } -rustc_index::newtype_index! { - /// The *source-order* index of a variant in a type. - /// - /// For enums, these are always `0..variant_count`, regardless of any - /// custom discriminants that may have been defined, and including any - /// variants that may end up uninhabited due to field types. (Some of the - /// variants may not be present in a monomorphized ABI [`Variants`], but - /// those skipped variants are always counted when determining the *index*.) - /// - /// `struct`s, `tuples`, and `unions`s are considered to have a single variant - /// with variant index zero, aka [`FIRST_VARIANT`]. - #[derive(HashStable_Generic)] - pub struct VariantIdx { - /// Equivalent to `VariantIdx(0)`. - const FIRST_VARIANT = 0; - } -} - +// NOTE: This struct is generic over the FieldIdx and VariantIdx for rust-analyzer usage. #[derive(PartialEq, Eq, Hash, Clone)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] -pub struct LayoutS { +pub struct LayoutS { /// Says where the fields are located within the layout. - pub fields: FieldsShape, + pub fields: FieldsShape, /// Encodes information about multi-variant layouts. /// Even with `Multiple` variants, a layout still has its own fields! Those are then @@ -1532,7 +1503,7 @@ pub struct LayoutS { /// /// To access all fields of this layout, both `fields` and the fields of the active variant /// must be taken into account. - pub variants: Variants, + pub variants: Variants, /// The `abi` defines how this data is passed between functions, and it defines /// value restrictions via `valid_range`. @@ -1561,13 +1532,13 @@ pub struct LayoutS { pub unadjusted_abi_align: Align, } -impl LayoutS { +impl LayoutS { pub fn scalar(cx: &C, scalar: Scalar) -> Self { let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar); let size = scalar.size(cx); let align = scalar.align(cx); LayoutS { - variants: Variants::Single { index: FIRST_VARIANT }, + variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Primitive, abi: Abi::Scalar(scalar), largest_niche, @@ -1579,7 +1550,11 @@ impl LayoutS { } } -impl fmt::Debug for LayoutS { +impl fmt::Debug for LayoutS +where + FieldsShape: fmt::Debug, + Variants: fmt::Debug, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // This is how `Layout` used to print before it become // `Interned`. We print it like this to avoid having to update @@ -1607,61 +1582,6 @@ impl fmt::Debug for LayoutS { } } -#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)] -#[rustc_pass_by_value] -pub struct Layout<'a>(pub Interned<'a, LayoutS>); - -impl<'a> fmt::Debug for Layout<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // See comment on `::fmt` above. - self.0.0.fmt(f) - } -} - -impl<'a> Layout<'a> { - pub fn fields(self) -> &'a FieldsShape { - &self.0.0.fields - } - - pub fn variants(self) -> &'a Variants { - &self.0.0.variants - } - - pub fn abi(self) -> Abi { - self.0.0.abi - } - - pub fn largest_niche(self) -> Option { - self.0.0.largest_niche - } - - pub fn align(self) -> AbiAndPrefAlign { - self.0.0.align - } - - pub fn size(self) -> Size { - self.0.0.size - } - - pub fn max_repr_align(self) -> Option { - self.0.0.max_repr_align - } - - pub fn unadjusted_abi_align(self) -> Align { - self.0.0.unadjusted_abi_align - } - - /// Whether the layout is from a type that implements [`std::marker::PointerLike`]. - /// - /// Currently, that means that the type is pointer-sized, pointer-aligned, - /// and has a scalar ABI. - pub fn is_pointer_like(self, data_layout: &TargetDataLayout) -> bool { - self.size() == data_layout.pointer_size - && self.align().abi == data_layout.pointer_align.abi - && matches!(self.abi(), Abi::Scalar(..)) - } -} - #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum PointerKind { /// Shared reference. `frozen` indicates the absence of any `UnsafeCell`. @@ -1681,7 +1601,7 @@ pub struct PointeeInfo { pub safe: Option, } -impl LayoutS { +impl LayoutS { /// Returns `true` if the layout corresponds to an unsized type. #[inline] pub fn is_unsized(&self) -> bool { diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 23fdd272ffd3..bf8a7eb293e0 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -15,7 +15,6 @@ #![feature(dropck_eyepatch)] #![feature(new_uninit)] #![feature(maybe_uninit_slice)] -#![feature(min_specialization)] #![feature(decl_macro)] #![feature(pointer_byte_offsets)] #![feature(rustc_attrs)] @@ -44,23 +43,6 @@ fn outline R, R>(f: F) -> R { f() } -/// An arena that can hold objects of only one type. -pub struct TypedArena { - /// A pointer to the next object to be allocated. - ptr: Cell<*mut T>, - - /// A pointer to the end of the allocated area. When this pointer is - /// reached, a new chunk is allocated. - end: Cell<*mut T>, - - /// A vector of arena chunks. - chunks: RefCell>>, - - /// Marker indicating that dropping the arena causes its owned - /// instances of `T` to be dropped. - _own: PhantomData, -} - struct ArenaChunk { /// The raw storage for the arena chunk. storage: NonNull<[MaybeUninit]>, @@ -130,6 +112,23 @@ impl ArenaChunk { const PAGE: usize = 4096; const HUGE_PAGE: usize = 2 * 1024 * 1024; +/// An arena that can hold objects of only one type. +pub struct TypedArena { + /// A pointer to the next object to be allocated. + ptr: Cell<*mut T>, + + /// A pointer to the end of the allocated area. When this pointer is + /// reached, a new chunk is allocated. + end: Cell<*mut T>, + + /// A vector of arena chunks. + chunks: RefCell>>, + + /// Marker indicating that dropping the arena causes its owned + /// instances of `T` to be dropped. + _own: PhantomData, +} + impl Default for TypedArena { /// Creates a new `TypedArena`. fn default() -> TypedArena { @@ -144,77 +143,6 @@ impl Default for TypedArena { } } -trait IterExt { - fn alloc_from_iter(self, arena: &TypedArena) -> &mut [T]; -} - -impl IterExt for I -where - I: IntoIterator, -{ - // This default collects into a `SmallVec` and then allocates by copying - // from it. The specializations below for types like `Vec` are more - // efficient, copying directly without the intermediate collecting step. - // This default could be made more efficient, like - // `DroplessArena::alloc_from_iter`, but it's not hot enough to bother. - #[inline] - default fn alloc_from_iter(self, arena: &TypedArena) -> &mut [T] { - let vec: SmallVec<[_; 8]> = self.into_iter().collect(); - vec.alloc_from_iter(arena) - } -} - -impl IterExt for std::array::IntoIter { - #[inline] - fn alloc_from_iter(self, arena: &TypedArena) -> &mut [T] { - let len = self.len(); - if len == 0 { - return &mut []; - } - // Move the content to the arena by copying and then forgetting it. - unsafe { - let start_ptr = arena.alloc_raw_slice(len); - self.as_slice().as_ptr().copy_to_nonoverlapping(start_ptr, len); - mem::forget(self); - slice::from_raw_parts_mut(start_ptr, len) - } - } -} - -impl IterExt for Vec { - #[inline] - fn alloc_from_iter(mut self, arena: &TypedArena) -> &mut [T] { - let len = self.len(); - if len == 0 { - return &mut []; - } - // Move the content to the arena by copying and then forgetting it. - unsafe { - let start_ptr = arena.alloc_raw_slice(len); - self.as_ptr().copy_to_nonoverlapping(start_ptr, len); - self.set_len(0); - slice::from_raw_parts_mut(start_ptr, len) - } - } -} - -impl IterExt for SmallVec { - #[inline] - fn alloc_from_iter(mut self, arena: &TypedArena) -> &mut [A::Item] { - let len = self.len(); - if len == 0 { - return &mut []; - } - // Move the content to the arena by copying and then forgetting it. - unsafe { - let start_ptr = arena.alloc_raw_slice(len); - self.as_ptr().copy_to_nonoverlapping(start_ptr, len); - self.set_len(0); - slice::from_raw_parts_mut(start_ptr, len) - } - } -} - impl TypedArena { /// Allocates an object in the `TypedArena`, returning a reference to it. #[inline] @@ -250,33 +178,55 @@ impl TypedArena { available_bytes >= additional_bytes } - /// Ensures there's enough space in the current chunk to fit `len` objects. #[inline] - fn ensure_capacity(&self, additional: usize) { - if !self.can_allocate(additional) { - self.grow(additional); - debug_assert!(self.can_allocate(additional)); - } - } - - #[inline] - unsafe fn alloc_raw_slice(&self, len: usize) -> *mut T { + fn alloc_raw_slice(&self, len: usize) -> *mut T { assert!(mem::size_of::() != 0); assert!(len != 0); - self.ensure_capacity(len); + // Ensure the current chunk can fit `len` objects. + if !self.can_allocate(len) { + self.grow(len); + debug_assert!(self.can_allocate(len)); + } let start_ptr = self.ptr.get(); - // SAFETY: `self.ensure_capacity` makes sure that there is enough space - // for `len` elements. + // SAFETY: `can_allocate`/`grow` ensures that there is enough space for + // `len` elements. unsafe { self.ptr.set(start_ptr.add(len)) }; start_ptr } #[inline] pub fn alloc_from_iter>(&self, iter: I) -> &mut [T] { + // This implementation is entirely separate to + // `DroplessIterator::alloc_from_iter`, even though conceptually they + // are the same. + // + // `DroplessIterator` (in the fast case) writes elements from the + // iterator one at a time into the allocated memory. That's easy + // because the elements don't implement `Drop`. But for `TypedArena` + // they do implement `Drop`, which means that if the iterator panics we + // could end up with some allocated-but-uninitialized elements, which + // will then cause UB in `TypedArena::drop`. + // + // Instead we use an approach where any iterator panic will occur + // before the memory is allocated. This function is much less hot than + // `DroplessArena::alloc_from_iter`, so it doesn't need to be + // hyper-optimized. assert!(mem::size_of::() != 0); - iter.alloc_from_iter(self) + + let mut vec: SmallVec<[_; 8]> = iter.into_iter().collect(); + if vec.is_empty() { + return &mut []; + } + // Move the content to the arena by copying and then forgetting it. + let len = vec.len(); + let start_ptr = self.alloc_raw_slice(len); + unsafe { + vec.as_ptr().copy_to_nonoverlapping(start_ptr, len); + vec.set_len(0); + slice::from_raw_parts_mut(start_ptr, len) + } } /// Grows the arena. @@ -407,6 +357,8 @@ impl Default for DroplessArena { #[inline] fn default() -> DroplessArena { DroplessArena { + // We set both `start` and `end` to 0 so that the first call to + // alloc() will trigger a grow(). start: Cell::new(ptr::null_mut()), end: Cell::new(ptr::null_mut()), chunks: Default::default(), @@ -415,9 +367,11 @@ impl Default for DroplessArena { } impl DroplessArena { + #[inline(never)] + #[cold] fn grow(&self, layout: Layout) { // Add some padding so we can align `self.end` while - // stilling fitting in a `layout` allocation. + // still fitting in a `layout` allocation. let additional = layout.size() + cmp::max(DROPLESS_ALIGNMENT, layout.align()) - 1; unsafe { @@ -441,7 +395,7 @@ impl DroplessArena { let mut chunk = ArenaChunk::new(align_up(new_cap, PAGE)); self.start.set(chunk.start()); - // Align the end to DROPLESS_ALIGNMENT + // Align the end to DROPLESS_ALIGNMENT. let end = align_down(chunk.end().addr(), DROPLESS_ALIGNMENT); // Make sure we don't go past `start`. This should not happen since the allocation @@ -454,55 +408,40 @@ impl DroplessArena { } } - #[inline(never)] - #[cold] - fn grow_and_alloc_raw(&self, layout: Layout) -> *mut u8 { - self.grow(layout); - self.alloc_raw_without_grow(layout).unwrap() - } - - #[inline(never)] - #[cold] - fn grow_and_alloc(&self) -> *mut u8 { - self.grow_and_alloc_raw(Layout::new::()) - } - - /// Allocates a byte slice with specified layout from the current memory - /// chunk. Returns `None` if there is no free space left to satisfy the - /// request. - #[inline] - fn alloc_raw_without_grow(&self, layout: Layout) -> Option<*mut u8> { - let start = self.start.get().addr(); - let old_end = self.end.get(); - let end = old_end.addr(); - - // Align allocated bytes so that `self.end` stays aligned to DROPLESS_ALIGNMENT - let bytes = align_up(layout.size(), DROPLESS_ALIGNMENT); - - // Tell LLVM that `end` is aligned to DROPLESS_ALIGNMENT - unsafe { intrinsics::assume(end == align_down(end, DROPLESS_ALIGNMENT)) }; - - let new_end = align_down(end.checked_sub(bytes)?, layout.align()); - if start <= new_end { - let new_end = old_end.with_addr(new_end); - // `new_end` is aligned to DROPLESS_ALIGNMENT as `align_down` preserves alignment - // as both `end` and `bytes` are already aligned to DROPLESS_ALIGNMENT. - self.end.set(new_end); - Some(new_end) - } else { - None - } - } - #[inline] pub fn alloc_raw(&self, layout: Layout) -> *mut u8 { assert!(layout.size() != 0); - if let Some(a) = self.alloc_raw_without_grow(layout) { - return a; + + // This loop executes once or twice: if allocation fails the first + // time, the `grow` ensures it will succeed the second time. + loop { + let start = self.start.get().addr(); + let old_end = self.end.get(); + let end = old_end.addr(); + + // Align allocated bytes so that `self.end` stays aligned to + // DROPLESS_ALIGNMENT. + let bytes = align_up(layout.size(), DROPLESS_ALIGNMENT); + + // Tell LLVM that `end` is aligned to DROPLESS_ALIGNMENT. + unsafe { intrinsics::assume(end == align_down(end, DROPLESS_ALIGNMENT)) }; + + if let Some(sub) = end.checked_sub(bytes) { + let new_end = align_down(sub, layout.align()); + if start <= new_end { + let new_end = old_end.with_addr(new_end); + // `new_end` is aligned to DROPLESS_ALIGNMENT as `align_down` + // preserves alignment as both `end` and `bytes` are already + // aligned to DROPLESS_ALIGNMENT. + self.end.set(new_end); + return new_end; + } + } + + // No free space left. Allocate a new chunk to satisfy the request. + // On failure the grow will panic or abort. + self.grow(layout); } - // No free space left. Allocate a new chunk to satisfy the request. - // On failure the grow will panic or abort. - self.grow_and_alloc_raw(layout) } #[inline] @@ -510,13 +449,7 @@ impl DroplessArena { assert!(!mem::needs_drop::()); assert!(mem::size_of::() != 0); - let mem = if let Some(a) = self.alloc_raw_without_grow(Layout::for_value::(&object)) { - a - } else { - // No free space left. Allocate a new chunk to satisfy the request. - // On failure the grow will panic or abort. - self.grow_and_alloc::() - } as *mut T; + let mem = self.alloc_raw(Layout::new::()) as *mut T; unsafe { // Write into uninitialized memory. @@ -713,10 +646,10 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) { } #[allow(clippy::mut_from_ref)] - pub fn alloc_from_iter<'a, T: ArenaAllocatable<'tcx, C>, C>( - &'a self, + pub fn alloc_from_iter, C>( + &self, iter: impl ::std::iter::IntoIterator, - ) -> &'a mut [T] { + ) -> &mut [T] { T::allocate_from_iter(self, iter) } } diff --git a/compiler/rustc_ast/src/entry.rs b/compiler/rustc_ast/src/entry.rs index 3370146193a5..2dd5e96e513a 100644 --- a/compiler/rustc_ast/src/entry.rs +++ b/compiler/rustc_ast/src/entry.rs @@ -1,3 +1,7 @@ +use crate::{attr, Attribute}; +use rustc_span::symbol::sym; +use rustc_span::Symbol; + #[derive(Debug)] pub enum EntryPointType { None, @@ -6,3 +10,26 @@ pub enum EntryPointType { Start, OtherMain, // Not an entry point, but some other function named main } + +pub fn entry_point_type( + attrs: &[Attribute], + at_root: bool, + name: Option, +) -> EntryPointType { + if attr::contains_name(attrs, sym::start) { + EntryPointType::Start + } else if attr::contains_name(attrs, sym::rustc_main) { + EntryPointType::RustcMainAttr + } else { + if let Some(name) = name && name == sym::main { + if at_root { + // This is a top-level function so it can be `main`. + EntryPointType::MainNamed + } else { + EntryPointType::OtherMain + } + } else { + EntryPointType::None + } + } +} diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 300b1486f9ba..09bfbd02198c 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -446,7 +446,7 @@ impl Token { } } - /// Returns `true` if the token can appear at the start of an pattern. + /// Returns `true` if the token can appear at the start of a pattern. /// /// Shamelessly borrowed from `can_begin_expr`, only used for diagnostics right now. pub fn can_begin_pattern(&self) -> bool { diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index 8115c4b55b0a..aaeef1ff77d3 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -99,7 +99,7 @@ ast_lowering_misplaced_double_dot = .note = only allowed in tuple, tuple struct, and slice patterns ast_lowering_misplaced_impl_trait = - `impl Trait` only allowed in function and inherent method return types, not in {$position} + `impl Trait` only allowed in function and inherent method argument and return types, not in {$position} ast_lowering_misplaced_relax_trait_bound = `?Trait` bounds are only permitted at the point where a type parameter is declared diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index afcf8b15cd80..45a9bebfcf62 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -410,15 +410,11 @@ fn expand_format_args<'hir>( let format_options = use_format_options.then(|| { // Generate: // &[format_spec_0, format_spec_1, format_spec_2] - let elements: Vec<_> = fmt - .template - .iter() - .filter_map(|piece| { - let FormatArgsPiece::Placeholder(placeholder) = piece else { return None }; - Some(make_format_spec(ctx, macsp, placeholder, &mut argmap)) - }) - .collect(); - ctx.expr_array_ref(macsp, ctx.arena.alloc_from_iter(elements)) + let elements = ctx.arena.alloc_from_iter(fmt.template.iter().filter_map(|piece| { + let FormatArgsPiece::Placeholder(placeholder) = piece else { return None }; + Some(make_format_spec(ctx, macsp, placeholder, &mut argmap)) + })); + ctx.expr_array_ref(macsp, elements) }); let arguments = fmt.arguments.all_args(); @@ -477,10 +473,8 @@ fn expand_format_args<'hir>( // ::new_debug(&arg2), // … // ] - let elements: Vec<_> = arguments - .iter() - .zip(argmap) - .map(|(arg, ((_, ty), placeholder_span))| { + let elements = ctx.arena.alloc_from_iter(arguments.iter().zip(argmap).map( + |(arg, ((_, ty), placeholder_span))| { let placeholder_span = placeholder_span.unwrap_or(arg.expr.span).with_ctxt(macsp.ctxt()); let arg_span = match arg.kind { @@ -493,9 +487,9 @@ fn expand_format_args<'hir>( hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, arg), )); make_argument(ctx, placeholder_span, ref_arg, ty) - }) - .collect(); - ctx.expr_array_ref(macsp, ctx.arena.alloc_from_iter(elements)) + }, + )); + ctx.expr_array_ref(macsp, elements) } else { // Generate: // &match (&arg0, &arg1, &…) { @@ -528,19 +522,14 @@ fn expand_format_args<'hir>( make_argument(ctx, placeholder_span, arg, ty) }, )); - let elements: Vec<_> = arguments - .iter() - .map(|arg| { - let arg_expr = ctx.lower_expr(&arg.expr); - ctx.expr( - arg.expr.span.with_ctxt(macsp.ctxt()), - hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, arg_expr), - ) - }) - .collect(); - let args_tuple = ctx - .arena - .alloc(ctx.expr(macsp, hir::ExprKind::Tup(ctx.arena.alloc_from_iter(elements)))); + let elements = ctx.arena.alloc_from_iter(arguments.iter().map(|arg| { + let arg_expr = ctx.lower_expr(&arg.expr); + ctx.expr( + arg.expr.span.with_ctxt(macsp.ctxt()), + hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, arg_expr), + ) + })); + let args_tuple = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Tup(elements))); let array = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Array(args))); let match_arms = ctx.arena.alloc_from_iter([ctx.arm(args_pat, array)]); let match_expr = ctx.arena.alloc(ctx.expr_match( diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 85ab5e7223bf..7e3ada9c1234 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1824,7 +1824,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } let fn_def_id = self.local_def_id(fn_node_id); - self.lower_async_fn_ret_ty(&decl.output, fn_def_id, ret_id, kind) + self.lower_async_fn_ret_ty(&decl.output, fn_def_id, ret_id, kind, fn_span) } else { match &decl.output { FnRetTy::Ty(ty) => { @@ -1901,8 +1901,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn_def_id: LocalDefId, opaque_ty_node_id: NodeId, fn_kind: FnDeclKind, + fn_span: Span, ) -> hir::FnRetTy<'hir> { - let span = self.lower_span(output.span()); + let span = self.lower_span(fn_span); let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None); let captured_lifetimes: Vec<_> = self diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 7bc685a54501..743fad8e8650 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -52,7 +52,8 @@ struct AstValidator<'a> { /// Are we inside a trait impl? in_trait_impl: bool, - in_const_trait_impl: bool, + /// Are we inside a const trait defn or impl? + in_const_trait_or_impl: bool, has_proc_macro_decls: bool, @@ -78,11 +79,19 @@ impl<'a> AstValidator<'a> { f: impl FnOnce(&mut Self), ) { let old = mem::replace(&mut self.in_trait_impl, is_in); - let old_const = - mem::replace(&mut self.in_const_trait_impl, matches!(constness, Some(Const::Yes(_)))); + let old_const = mem::replace( + &mut self.in_const_trait_or_impl, + matches!(constness, Some(Const::Yes(_))), + ); f(self); self.in_trait_impl = old; - self.in_const_trait_impl = old_const; + self.in_const_trait_or_impl = old_const; + } + + fn with_in_trait(&mut self, is_const: bool, f: impl FnOnce(&mut Self)) { + let old = mem::replace(&mut self.in_const_trait_or_impl, is_const); + f(self); + self.in_const_trait_or_impl = old; } fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) { @@ -933,23 +942,26 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } ItemKind::Trait(box Trait { is_auto, generics, bounds, items, .. }) => { - if *is_auto == IsAuto::Yes { - // Auto traits cannot have generics, super traits nor contain items. - self.deny_generic_params(generics, item.ident.span); - self.deny_super_traits(bounds, item.ident.span); - self.deny_where_clause(&generics.where_clause, item.ident.span); - self.deny_items(items, item.ident.span); - } + let is_const_trait = attr::contains_name(&item.attrs, sym::const_trait); + self.with_in_trait(is_const_trait, |this| { + if *is_auto == IsAuto::Yes { + // Auto traits cannot have generics, super traits nor contain items. + this.deny_generic_params(generics, item.ident.span); + this.deny_super_traits(bounds, item.ident.span); + this.deny_where_clause(&generics.where_clause, item.ident.span); + this.deny_items(items, item.ident.span); + } - // Equivalent of `visit::walk_item` for `ItemKind::Trait` that inserts a bound - // context for the supertraits. - self.visit_vis(&item.vis); - self.visit_ident(item.ident); - self.visit_generics(generics); - self.with_tilde_const_allowed(|this| { - walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits) + // Equivalent of `visit::walk_item` for `ItemKind::Trait` that inserts a bound + // context for the supertraits. + this.visit_vis(&item.vis); + this.visit_ident(item.ident); + this.visit_generics(generics); + this.with_tilde_const_allowed(|this| { + walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits) + }); + walk_list!(this, visit_assoc_item, items, AssocCtxt::Trait); }); - walk_list!(self, visit_assoc_item, items, AssocCtxt::Trait); walk_list!(self, visit_attribute, &item.attrs); return; // Avoid visiting again } @@ -1278,7 +1290,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { let tilde_const_allowed = matches!(fk.header(), Some(FnHeader { constness: ast::Const::Yes(_), .. })) - || matches!(fk.ctxt(), Some(FnCtxt::Assoc(_))); + || matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)) if self.in_const_trait_or_impl); let disallowed = (!tilde_const_allowed).then(|| DisallowTildeConstContext::Fn(fk)); @@ -1363,7 +1375,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { walk_list!(self, visit_ty, ty); } AssocItemKind::Fn(box Fn { sig, generics, body, .. }) - if self.in_const_trait_impl + if self.in_const_trait_or_impl || ctxt == AssocCtxt::Trait || matches!(sig.header.constness, Const::Yes(_)) => { @@ -1510,7 +1522,7 @@ pub fn check_crate( features, extern_mod: None, in_trait_impl: false, - in_const_trait_impl: false, + in_const_trait_or_impl: false, has_proc_macro_decls: false, outer_impl_trait: None, disallow_tilde_const: None, diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 62dc7ae58a2f..5d279943f1e8 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -603,6 +603,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { "exclusive range pattern syntax is experimental" ); gate_all_legacy_dont_use!(try_blocks, "`try` blocks are unstable"); + gate_all_legacy_dont_use!(auto_traits, "`auto` traits are unstable"); visit::walk_crate(&mut visitor, krate); } diff --git a/compiler/rustc_attr/Cargo.toml b/compiler/rustc_attr/Cargo.toml index 2c4c3a0c2635..a14d27968179 100644 --- a/compiler/rustc_attr/Cargo.toml +++ b/compiler/rustc_attr/Cargo.toml @@ -6,14 +6,14 @@ edition = "2021" [lib] [dependencies] +rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_serialize = { path = "../rustc_serialize" } -rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } -rustc_span = { path = "../rustc_span" } rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } +rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } -rustc_ast = { path = "../rustc_ast" } +rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index ca4b3662a089..6f82d6f93233 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -162,7 +162,7 @@ pub enum StabilityLevel { is_soft: bool, /// If part of a feature is stabilized and a new feature is added for the remaining parts, /// then the `implied_by` attribute is used to indicate which now-stable feature previously - /// contained a item. + /// contained an item. /// /// ```pseudo-Rust /// #[unstable(feature = "foo", issue = "...")] @@ -846,7 +846,7 @@ pub fn find_deprecation( ), ); } else { - sess.emit_err(session_diagnostics::IncorrectMetaItem2 { + sess.emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span, }); } diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index ee79545e304a..86f27254db25 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -165,15 +165,6 @@ pub(crate) struct MissingIssue { pub span: Span, } -// FIXME: This diagnostic is identical to `IncorrectMetaItem`, barring the error code. Consider -// changing this to `IncorrectMetaItem`. See #51489. -#[derive(Diagnostic)] -#[diag(attr_incorrect_meta_item, code = "E0551")] -pub(crate) struct IncorrectMetaItem2 { - #[primary_span] - pub span: Span, -} - // FIXME: Why is this the same error code as `InvalidReprHintNoParen` and `InvalidReprHintNoValue`? // It is more similar to `IncorrectReprFormatGeneric`. #[derive(Diagnostic)] diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 48d09f2c2b2a..4488276e0e7a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1364,7 +1364,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.note(format!( "a for loop advances the iterator for you, the result is stored in `{loop_bind}`." )); - err.help("if you want to call `next` on a iterator within the loop, consider using `while let`."); + err.help("if you want to call `next` on an iterator within the loop, consider using `while let`."); } } @@ -2828,6 +2828,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } + | ProjectionElem::Subtype(_) | ProjectionElem::Index(_) => kind, }, place_ty.projection_ty(tcx, elem), diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index f70263e9dcf0..c3cf7db32b14 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -242,6 +242,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ProjectionElem::Downcast(..) if opt.including_downcast => return None, ProjectionElem::Downcast(..) => (), ProjectionElem::OpaqueCast(..) => (), + ProjectionElem::Subtype(..) => (), ProjectionElem::Field(field, _ty) => { // FIXME(project-rfc_2229#36): print capture precisely here. if let Some(field) = self.is_upvar_field_projection(PlaceRef { @@ -322,7 +323,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { PlaceRef { local, projection: proj_base }.ty(self.body, self.infcx.tcx) } ProjectionElem::Downcast(..) => place.ty(self.body, self.infcx.tcx), - ProjectionElem::OpaqueCast(ty) => PlaceTy::from_ty(*ty), + ProjectionElem::Subtype(ty) | ProjectionElem::OpaqueCast(ty) => { + PlaceTy::from_ty(*ty) + } ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type), }, }; diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index a0edeec59d05..e6bde6a8c54d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -159,6 +159,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { [ .., ProjectionElem::Index(_) + | ProjectionElem::Subtype(_) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::OpaqueCast { .. } | ProjectionElem::Subslice { .. } @@ -1358,9 +1359,9 @@ fn suggest_ampmut<'tcx>( None => (false, decl_span), }; - // if the binding already exists and is a reference with a explicit + // if the binding already exists and is a reference with an explicit // lifetime, then we can suggest adding ` mut`. this is special-cased from - // the path without a explicit lifetime. + // the path without an explicit lifetime. if let Ok(src) = tcx.sess.source_map().span_to_snippet(span) && src.starts_with("&'") // note that `& 'a T` is invalid so this is correct. diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 8115c61e89d3..9c77767e7a70 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1803,6 +1803,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { for (place_base, elem) in place.iter_projections().rev() { match elem { ProjectionElem::Index(_/*operand*/) | + ProjectionElem::Subtype(_) | ProjectionElem::OpaqueCast(_) | ProjectionElem::ConstantIndex { .. } | // assigning to P[i] requires P to be valid. @@ -1966,7 +1967,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { Reservation(WriteKind::MutableBorrow(BorrowKind::Mut { kind: mut_borrow_kind })) | Write(WriteKind::MutableBorrow(BorrowKind::Mut { kind: mut_borrow_kind })) => { let is_local_mutation_allowed = match mut_borrow_kind { - // `ClosureCapture` is used for mutable variable with a immutable binding. + // `ClosureCapture` is used for mutable variable with an immutable binding. // This is only behaviour difference between `ClosureCapture` and mutable borrows. MutBorrowKind::ClosureCapture => LocalMutationIsAllowed::Yes, MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow => { @@ -2191,6 +2192,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { | ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } + | ProjectionElem::Subtype(..) | ProjectionElem::OpaqueCast { .. } | ProjectionElem::Downcast(..) => { let upvar_field_projection = self.is_upvar_field_projection(place); diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs index c02f6f3b6878..539d0837659c 100644 --- a/compiler/rustc_borrowck/src/places_conflict.rs +++ b/compiler/rustc_borrowck/src/places_conflict.rs @@ -249,6 +249,7 @@ fn place_components_conflict<'tcx>( | (ProjectionElem::ConstantIndex { .. }, _, _) | (ProjectionElem::Subslice { .. }, _, _) | (ProjectionElem::OpaqueCast { .. }, _, _) + | (ProjectionElem::Subtype(_), _, _) | (ProjectionElem::Downcast { .. }, _, _) => { // Recursive case. This can still be disjoint on a // further iteration if this a shallow access and @@ -508,6 +509,7 @@ fn place_projection_conflict<'tcx>( | ProjectionElem::Field(..) | ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } + | ProjectionElem::Subtype(_) | ProjectionElem::OpaqueCast { .. } | ProjectionElem::Subslice { .. } | ProjectionElem::Downcast(..), diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs index 6f2813498637..e9c9709bd1f1 100644 --- a/compiler/rustc_borrowck/src/prefixes.rs +++ b/compiler/rustc_borrowck/src/prefixes.rs @@ -89,6 +89,9 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { cursor = cursor_base; continue 'cursor; } + ProjectionElem::Subtype(..) => { + panic!("Subtype projection is not allowed before borrow check") + } ProjectionElem::Deref => { // (handled below) } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 9b952f3fe362..e7b1a489f5d7 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -716,6 +716,9 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { } PlaceTy::from_ty(fty) } + ProjectionElem::Subtype(_) => { + bug!("ProjectionElem::Subtype shouldn't exist in borrowck") + } ProjectionElem::OpaqueCast(ty) => { let ty = self.sanitize_type(place, ty); let ty = self.cx.normalize(ty, location); @@ -2563,6 +2566,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | ProjectionElem::Subslice { .. } => { // other field access } + ProjectionElem::Subtype(_) => { + bug!("ProjectionElem::Subtype shouldn't exist in borrowck") + } } } } diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index af437f36b9f8..c73192f44045 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -164,7 +164,7 @@ struct UniversalRegionIndices<'tcx> { /// be able to map them to our internal `RegionVid`. This is /// basically equivalent to an `GenericArgs`, except that it also /// contains an entry for `ReStatic` -- it might be nice to just - /// use a args, and then handle `ReStatic` another way. + /// use an args, and then handle `ReStatic` another way. indices: FxHashMap, RegionVid>, /// The vid assigned to `'static`. Used only for diagnostics. @@ -290,7 +290,7 @@ impl<'tcx> UniversalRegions<'tcx> { (FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::from_usize) } - /// Returns `true` if `r` is classified as an local region. + /// Returns `true` if `r` is classified as a local region. pub fn is_local_free_region(&self, r: RegionVid) -> bool { self.region_classification(r) == Some(RegionClassification::Local) } diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 53ff089d7b4e..9c57f68f0b81 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -169,29 +169,15 @@ impl<'a> Visitor<'a> for InnerItemLinter<'_> { } } -// Beware, this is duplicated in librustc_passes/entry.rs (with -// `rustc_hir::Item`), so make sure to keep them in sync. -fn entry_point_type(item: &ast::Item, depth: usize) -> EntryPointType { +fn entry_point_type(item: &ast::Item, at_root: bool) -> EntryPointType { match item.kind { ast::ItemKind::Fn(..) => { - if attr::contains_name(&item.attrs, sym::start) { - EntryPointType::Start - } else if attr::contains_name(&item.attrs, sym::rustc_main) { - EntryPointType::RustcMainAttr - } else if item.ident.name == sym::main { - if depth == 0 { - // This is a top-level function so can be 'main' - EntryPointType::MainNamed - } else { - EntryPointType::OtherMain - } - } else { - EntryPointType::None - } + rustc_ast::entry::entry_point_type(&item.attrs, at_root, Some(item.ident.name)) } _ => EntryPointType::None, } } + /// A folder used to remove any entry points (like fn main) because the harness /// generator will provide its own struct EntryPointCleaner<'a> { @@ -210,7 +196,7 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> { // Remove any #[rustc_main] or #[start] from the AST so it doesn't // clash with the one we're going to add, but mark it as // #[allow(dead_code)] to avoid printing warnings. - let item = match entry_point_type(&item, self.depth) { + let item = match entry_point_type(&item, self.depth == 0) { EntryPointType::MainNamed | EntryPointType::RustcMainAttr | EntryPointType::Start => { item.map(|ast::Item { id, ident, attrs, kind, vis, span, tokens }| { let allow_dead_code = attr::mk_attr_nested_word( diff --git a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh index e6bbac647e5a..f09b9ef12deb 100644 --- a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh +++ b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh @@ -31,7 +31,7 @@ index d95b5b7f17f..00b6f0e3635 100644 EOF cat > config.toml <( let inputs = fn_abi.args.iter().flat_map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()); let (return_ptr, returns) = fn_abi.ret.get_abi_return(tcx); - // Sometimes the first param is an pointer to the place where the return value needs to be stored. + // Sometimes the first param is a pointer to the place where the return value needs to be stored. let params: Vec<_> = return_ptr.into_iter().chain(inputs).collect(); Signature { params, returns, call_conv } diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 9b5a6b89191e..0a451dad9d23 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -875,7 +875,8 @@ pub(crate) fn codegen_place<'tcx>( PlaceElem::Deref => { cplace = cplace.place_deref(fx); } - PlaceElem::OpaqueCast(ty) => cplace = cplace.place_opaque_cast(fx, ty), + PlaceElem::OpaqueCast(ty) => bug!("encountered OpaqueCast({ty}) in codegen"), + PlaceElem::Subtype(ty) => cplace = cplace.place_transmute_type(fx, fx.monomorphize(ty)), PlaceElem::Field(field, _ty) => { cplace = cplace.place_field(fx, field); } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index c64a4008996d..6efbe1498635 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -21,7 +21,7 @@ fn report_simd_type_validation_error( pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, intrinsic: Symbol, - _args: GenericArgsRef<'tcx>, + generic_args: GenericArgsRef<'tcx>, args: &[mir::Operand<'tcx>], ret: CPlace<'tcx>, target: BasicBlock, @@ -117,6 +117,54 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }); } + // simd_shuffle_generic(x: T, y: T) -> U + sym::simd_shuffle_generic => { + let [x, y] = args else { + bug!("wrong number of args for intrinsic {intrinsic}"); + }; + let x = codegen_operand(fx, x); + let y = codegen_operand(fx, y); + + if !x.layout().ty.is_simd() { + report_simd_type_validation_error(fx, intrinsic, span, x.layout().ty); + return; + } + + let idx = generic_args[2] + .expect_const() + .eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(span)) + .unwrap() + .unwrap_branch(); + + assert_eq!(x.layout(), y.layout()); + let layout = x.layout(); + + let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx); + let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx); + + assert_eq!(lane_ty, ret_lane_ty); + assert_eq!(idx.len() as u64, ret_lane_count); + + let total_len = lane_count * 2; + + let indexes = + idx.iter().map(|idx| idx.unwrap_leaf().try_to_u16().unwrap()).collect::>(); + + for &idx in &indexes { + assert!(u64::from(idx) < total_len, "idx {} out of range 0..{}", idx, total_len); + } + + for (out_idx, in_idx) in indexes.into_iter().enumerate() { + let in_lane = if u64::from(in_idx) < lane_count { + x.value_lane(fx, in_idx.into()) + } else { + y.value_lane(fx, u64::from(in_idx) - lane_count) + }; + let out_lane = ret.place_lane(fx, u64::try_from(out_idx).unwrap()); + out_lane.write_cvalue(fx, in_lane); + } + } + // simd_shuffle(x: T, y: T, idx: I) -> U sym::simd_shuffle => { let (x, y, idx) = match args { diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index ff95141ce90f..45893a4f3ac4 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -674,7 +674,9 @@ impl<'tcx> CPlace<'tcx> { } } - pub(crate) fn place_opaque_cast( + /// Used for `ProjectionElem::Subtype`, `ty` has to be monomorphized before + /// passed on. + pub(crate) fn place_transmute_type( self, fx: &mut FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>, diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 308cb04cac3d..ecc293aee237 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1420,7 +1420,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.cx } - fn do_not_inline(&mut self, _llret: RValue<'gcc>) { + fn apply_attrs_to_cleanup_callsite(&mut self, _llret: RValue<'gcc>) { // FIXME(bjorn3): implement } diff --git a/compiler/rustc_codegen_gcc/test.sh b/compiler/rustc_codegen_gcc/test.sh index 592997b8ab9d..b462e5d156b2 100755 --- a/compiler/rustc_codegen_gcc/test.sh +++ b/compiler/rustc_codegen_gcc/test.sh @@ -214,7 +214,7 @@ function setup_rustc() { rm config.toml || true cat > config.toml < bool { match crate_type { - CrateType::Executable | CrateType::Dylib | CrateType::Staticlib | CrateType::Cdylib => true, - CrateType::Rlib | CrateType::ProcMacro => false, + CrateType::Executable + | CrateType::Dylib + | CrateType::Staticlib + | CrateType::Cdylib + | CrateType::ProcMacro => true, + CrateType::Rlib => false, } } @@ -87,6 +91,11 @@ fn prepare_lto( diag_handler.emit_err(LtoDylib); return Err(FatalError); } + } else if *crate_type == CrateType::ProcMacro { + if !cgcx.opts.unstable_opts.dylib_lto { + diag_handler.emit_err(LtoProcMacro); + return Err(FatalError); + } } } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index ac6d8f84142e..4f9b86ec20a7 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -3,6 +3,7 @@ use crate::attributes; use crate::common::Funclet; use crate::context::CodegenCx; use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, True}; +use crate::llvm_util; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; @@ -1225,9 +1226,16 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { unsafe { llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, UNNAMED) } } - fn do_not_inline(&mut self, llret: &'ll Value) { - let noinline = llvm::AttributeKind::NoInline.create_attr(self.llcx); - attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[noinline]); + fn apply_attrs_to_cleanup_callsite(&mut self, llret: &'ll Value) { + if llvm_util::get_version() < (17, 0, 2) { + // Work around https://github.com/llvm/llvm-project/issues/66984. + let noinline = llvm::AttributeKind::NoInline.create_attr(self.llcx); + attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[noinline]); + } else { + // Cleanup is always the cold path. + let cold_inline = llvm::AttributeKind::Cold.create_attr(self.llcx); + attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[cold_inline]); + } } } diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs index e83110dcad46..55f43aa53417 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs @@ -11,7 +11,7 @@ pub struct Expression { lhs: Operand, op: Op, rhs: Operand, - region: Option, + code_regions: Vec, } /// Collects all of the coverage regions associated with (a) injected counters, (b) counter @@ -30,7 +30,7 @@ pub struct FunctionCoverage<'tcx> { instance: Instance<'tcx>, source_hash: u64, is_used: bool, - counters: IndexVec>, + counters: IndexVec>>, expressions: IndexVec>, unreachable_regions: Vec, } @@ -77,28 +77,40 @@ impl<'tcx> FunctionCoverage<'tcx> { } } - /// Adds a code region to be counted by an injected counter intrinsic. - pub fn add_counter(&mut self, id: CounterId, region: CodeRegion) { - if let Some(previous_region) = self.counters[id].replace(region.clone()) { - assert_eq!(previous_region, region, "add_counter: code region for id changed"); + /// Adds code regions to be counted by an injected counter intrinsic. + #[instrument(level = "debug", skip(self))] + pub(crate) fn add_counter(&mut self, id: CounterId, code_regions: &[CodeRegion]) { + if code_regions.is_empty() { + return; + } + + let slot = &mut self.counters[id]; + match slot { + None => *slot = Some(code_regions.to_owned()), + // If this counter ID slot has already been filled, it should + // contain identical information. + Some(ref previous_regions) => assert_eq!( + previous_regions, code_regions, + "add_counter: code regions for id changed" + ), } } + /// Adds information about a coverage expression, along with zero or more + /// code regions mapped to that expression. + /// /// Both counters and "counter expressions" (or simply, "expressions") can be operands in other /// expressions. These are tracked as separate variants of `Operand`, so there is no ambiguity /// between operands that are counter IDs and operands that are expression IDs. - pub fn add_counter_expression( + #[instrument(level = "debug", skip(self))] + pub(crate) fn add_counter_expression( &mut self, expression_id: ExpressionId, lhs: Operand, op: Op, rhs: Operand, - region: Option, + code_regions: &[CodeRegion], ) { - debug!( - "add_counter_expression({:?}, lhs={:?}, op={:?}, rhs={:?} at {:?}", - expression_id, lhs, op, rhs, region - ); debug_assert!( expression_id.as_usize() < self.expressions.len(), "expression_id {} is out of range for expressions.len() = {} @@ -107,23 +119,25 @@ impl<'tcx> FunctionCoverage<'tcx> { self.expressions.len(), self, ); - if let Some(previous_expression) = self.expressions[expression_id].replace(Expression { - lhs, - op, - rhs, - region: region.clone(), - }) { - assert_eq!( - previous_expression, - Expression { lhs, op, rhs, region }, + + let expression = Expression { lhs, op, rhs, code_regions: code_regions.to_owned() }; + let slot = &mut self.expressions[expression_id]; + match slot { + None => *slot = Some(expression), + // If this expression ID slot has already been filled, it should + // contain identical information. + Some(ref previous_expression) => assert_eq!( + previous_expression, &expression, "add_counter_expression: expression for id changed" - ); + ), } } - /// Add a region that will be marked as "unreachable", with a constant "zero counter". - pub fn add_unreachable_region(&mut self, region: CodeRegion) { - self.unreachable_regions.push(region) + /// Adds regions that will be marked as "unreachable", with a constant "zero counter". + #[instrument(level = "debug", skip(self))] + pub(crate) fn add_unreachable_regions(&mut self, code_regions: &[CodeRegion]) { + assert!(!code_regions.is_empty(), "unreachable regions always have code regions"); + self.unreachable_regions.extend_from_slice(code_regions); } /// Perform some simplifications to make the final coverage mappings @@ -212,11 +226,16 @@ impl<'tcx> FunctionCoverage<'tcx> { } fn counter_regions(&self) -> impl Iterator { - self.counters.iter_enumerated().filter_map(|(index, entry)| { - // Option::map() will return None to filter out missing counters. This may happen - // if, for example, a MIR-instrumented counter is removed during an optimization. - entry.as_ref().map(|region| (Counter::counter_value_reference(index), region)) - }) + self.counters + .iter_enumerated() + // Filter out counter IDs that we never saw during MIR traversal. + // This can happen if a counter was optimized out by MIR transforms + // (and replaced with `CoverageKind::Unreachable` instead). + .filter_map(|(id, maybe_code_regions)| Some((id, maybe_code_regions.as_ref()?))) + .flat_map(|(id, code_regions)| { + let counter = Counter::counter_value_reference(id); + code_regions.iter().map(move |region| (counter, region)) + }) } /// Convert this function's coverage expression data into a form that can be @@ -254,13 +273,17 @@ impl<'tcx> FunctionCoverage<'tcx> { fn expression_regions(&self) -> Vec<(Counter, &CodeRegion)> { // Find all of the expression IDs that weren't optimized out AND have - // an attached code region, and return the corresponding mapping as a - // counter/region pair. + // one or more attached code regions, and return the corresponding + // mappings as counter/region pairs. self.expressions .iter_enumerated() - .filter_map(|(id, expression)| { - let code_region = expression.as_ref()?.region.as_ref()?; - Some((Counter::expression(id), code_region)) + .filter_map(|(id, maybe_expression)| { + let code_regions = &maybe_expression.as_ref()?.code_regions; + Some((id, code_regions)) + }) + .flat_map(|(id, code_regions)| { + let counter = Counter::expression(id); + code_regions.iter().map(move |code_region| (counter, code_region)) }) .collect::>() } diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index c70cb670e96f..dd2ce9b525b7 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -89,9 +89,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { /// `function_coverage_map` (keyed by function `Instance`) during codegen. /// But in this case, since the unused function was _not_ previously /// codegenned, collect the coverage `CodeRegion`s from the MIR and add - /// them. The first `CodeRegion` is used to add a single counter, with the - /// same counter ID used in the injected `instrprof.increment` intrinsic - /// call. Since the function is never called, all other `CodeRegion`s can be + /// them. Since the function is never called, all of its `CodeRegion`s can be /// added as `unreachable_region`s. fn define_unused_fn(&self, def_id: DefId) { let instance = declare_unused_fn(self, def_id); @@ -110,25 +108,15 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { .entry(instance) .or_insert_with(|| FunctionCoverage::new(bx.tcx(), instance)); - let Coverage { kind, code_region } = coverage.clone(); - match kind { + let Coverage { kind, code_regions } = coverage; + match *kind { CoverageKind::Counter { function_source_hash, id } => { debug!( "ensuring function source hash is set for instance={:?}; function_source_hash={}", instance, function_source_hash, ); func_coverage.set_function_source_hash(function_source_hash); - - if let Some(code_region) = code_region { - // Note: Some counters do not have code regions, but may still be referenced - // from expressions. In that case, don't add the counter to the coverage map, - // but do inject the counter intrinsic. - debug!( - "adding counter to coverage_map: instance={:?}, id={:?}, region={:?}", - instance, id, code_region, - ); - func_coverage.add_counter(id, code_region); - } + func_coverage.add_counter(id, code_regions); // We need to explicitly drop the `RefMut` before calling into `instrprof_increment`, // as that needs an exclusive borrow. drop(coverage_map); @@ -146,20 +134,10 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { bx.instrprof_increment(fn_name, hash, num_counters, index); } CoverageKind::Expression { id, lhs, op, rhs } => { - debug!( - "adding counter expression to coverage_map: instance={:?}, id={:?}, {:?} {:?} {:?}; region: {:?}", - instance, id, lhs, op, rhs, code_region, - ); - func_coverage.add_counter_expression(id, lhs, op, rhs, code_region); + func_coverage.add_counter_expression(id, lhs, op, rhs, code_regions); } CoverageKind::Unreachable => { - let code_region = - code_region.expect("unreachable regions always have code regions"); - debug!( - "adding unreachable code to coverage_map: instance={:?}, at {:?}", - instance, code_region, - ); - func_coverage.add_unreachable_region(code_region); + func_coverage.add_unreachable_regions(code_regions); } } } @@ -227,14 +205,9 @@ fn add_unused_function_coverage<'tcx>( let tcx = cx.tcx; let mut function_coverage = FunctionCoverage::unused(tcx, instance); - for (index, &code_region) in tcx.covered_code_regions(def_id).iter().enumerate() { - if index == 0 { - // Insert at least one real counter so the LLVM CoverageMappingReader will find expected - // definitions. - function_coverage.add_counter(UNUSED_FUNCTION_COUNTER_ID, code_region.clone()); - } else { - function_coverage.add_unreachable_region(code_region.clone()); - } + for &code_region in tcx.covered_code_regions(def_id) { + let code_region = std::slice::from_ref(code_region); + function_coverage.add_unreachable_regions(code_region); } if let Some(coverage_context) = cx.coverage_context() { diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 264c273ba307..665d195790c2 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -138,6 +138,10 @@ pub(crate) struct LtoDisallowed; #[diag(codegen_llvm_lto_dylib)] pub(crate) struct LtoDylib; +#[derive(Diagnostic)] +#[diag(codegen_llvm_lto_proc_macro)] +pub(crate) struct LtoProcMacro; + #[derive(Diagnostic)] #[diag(codegen_llvm_lto_bitcode_from_rlib)] pub(crate) struct LtoBitcodeFromRlib { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 9289c37d7635..a97b803fc645 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -15,7 +15,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::*; use rustc_hir as hir; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf}; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, GenericArgsRef, Ty}; use rustc_middle::{bug, span_bug}; use rustc_span::{sym, symbol::kw, Span, Symbol}; use rustc_target::abi::{self, Align, HasDataLayout, Primitive}; @@ -376,7 +376,9 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { } _ if name.as_str().starts_with("simd_") => { - match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) { + match generic_simd_intrinsic( + self, name, callee_ty, fn_args, args, ret_ty, llret_ty, span, + ) { Ok(llval) => llval, Err(()) => return, } @@ -911,6 +913,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, name: Symbol, callee_ty: Ty<'tcx>, + fn_args: GenericArgsRef<'tcx>, args: &[OperandRef<'tcx, &'ll Value>], ret_ty: Ty<'tcx>, llret_ty: &'ll Type, @@ -1030,6 +1033,56 @@ fn generic_simd_intrinsic<'ll, 'tcx>( )); } + if name == sym::simd_shuffle_generic { + let idx = fn_args[2] + .expect_const() + .eval(tcx, ty::ParamEnv::reveal_all(), Some(span)) + .unwrap() + .unwrap_branch(); + let n = idx.len() as u64; + + require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); + let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx()); + require!( + out_len == n, + InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len } + ); + require!( + in_elem == out_ty, + InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty } + ); + + let total_len = in_len * 2; + + let indices: Option> = idx + .iter() + .enumerate() + .map(|(arg_idx, val)| { + let idx = val.unwrap_leaf().try_to_i32().unwrap(); + if idx >= i32::try_from(total_len).unwrap() { + bx.sess().emit_err(InvalidMonomorphization::ShuffleIndexOutOfBounds { + span, + name, + arg_idx: arg_idx as u64, + total_len: total_len.into(), + }); + None + } else { + Some(bx.const_i32(idx)) + } + }) + .collect(); + let Some(indices) = indices else { + return Ok(bx.const_null(llret_ty)); + }; + + return Ok(bx.shuffle_vector( + args[0].immediate(), + args[1].immediate(), + bx.const_vector(&indices), + )); + } + if name == sym::simd_shuffle { // Make sure this is actually an array, since typeck only checks the length-suffixed // version of this intrinsic. diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index 8db6195d931f..06b7703672fe 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -112,7 +112,7 @@ impl<'ll> CodegenCx<'ll, '_> { } } - /// Return a LLVM type that has at most the required alignment, + /// Return an LLVM type that has at most the required alignment, /// and exactly the required size, as a best-effort padding array. pub(crate) fn type_padding_filler(&self, size: Size, align: Align) -> &'ll Type { let unit = Integer::approximate_align(self, align); diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index d0a078505d2d..6f7d7482aea8 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -46,8 +46,6 @@ codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files w codegen_ssa_illegal_link_ordinal_format = illegal ordinal format in `link_ordinal` .note = an unsuffixed integer value, e.g., `1`, is expected -codegen_ssa_incompatible_linking_modifiers = link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs - codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient. codegen_ssa_invalid_link_ordinal_nargs = incorrect number of arguments to `#[link_ordinal]` diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index a7ac728c59b0..c4a0f6291e7f 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -365,15 +365,9 @@ fn link_rlib<'a>( // loaded from the libraries found here and then encode that into the // metadata of the rlib we're generating somehow. for lib in codegen_results.crate_info.used_libraries.iter() { - let NativeLibKind::Static { bundle: None | Some(true), whole_archive } = lib.kind else { + let NativeLibKind::Static { bundle: None | Some(true), .. } = lib.kind else { continue; }; - if whole_archive == Some(true) - && flavor == RlibFlavor::Normal - && !codegen_results.crate_info.feature_packed_bundled_libs - { - sess.emit_err(errors::IncompatibleLinkingModifiers); - } if flavor == RlibFlavor::Normal && let Some(filename) = lib.filename { let path = find_native_static_library(filename.as_str(), true, &lib_search_paths, sess); let src = read(path).map_err(|e| sess.emit_fatal(errors::ReadFileError {message: e }))?; diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 3cca0eb7ae72..1e4ea73a1724 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -857,7 +857,6 @@ impl CrateInfo { dependency_formats: tcx.dependency_formats(()).clone(), windows_subsystem, natvis_debugger_visualizers: Default::default(), - feature_packed_bundled_libs: tcx.features().packed_bundled_libs, }; let crates = tcx.crates(()); diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index bfd572a2eeaf..14311ec08fd2 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -107,10 +107,6 @@ pub struct CreateTempDir { pub error: Error, } -#[derive(Diagnostic)] -#[diag(codegen_ssa_incompatible_linking_modifiers)] -pub struct IncompatibleLinkingModifiers; - #[derive(Diagnostic)] #[diag(codegen_ssa_add_native_library)] pub struct AddNativeLibrary { diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 7ebaca9b0bc6..f6186a290f81 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -164,7 +164,6 @@ pub struct CrateInfo { pub dependency_formats: Lrc, pub windows_subsystem: Option, pub natvis_debugger_visualizers: BTreeSet, - pub feature_packed_bundled_libs: bool, // unstable feature flag. } #[derive(Encodable, Decodable)] diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index bd0707edfd99..a0cb97d51a01 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -213,7 +213,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { self.funclet(fx), ); if fx.mir[self.bb].is_cleanup { - bx.do_not_inline(invokeret); + bx.apply_attrs_to_cleanup_callsite(invokeret); } if let Some((ret_dest, target)) = destination { @@ -228,11 +228,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { } else { let llret = bx.call(fn_ty, fn_attrs, Some(&fn_abi), fn_ptr, &llargs, self.funclet(fx)); if fx.mir[self.bb].is_cleanup { - // Cleanup is always the cold path. Don't inline - // drop glue. Also, when there is a deeply-nested - // struct, there are "symmetry" issues that cause - // exponential inlining - see issue #41696. - bx.do_not_inline(llret); + bx.apply_attrs_to_cleanup_callsite(llret); } if let Some((ret_dest, target)) = destination { @@ -1627,7 +1623,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let fn_ty = bx.fn_decl_backend_type(&fn_abi); let llret = bx.call(fn_ty, None, Some(&fn_abi), fn_ptr, &[], funclet.as_ref()); - bx.do_not_inline(llret); + bx.apply_attrs_to_cleanup_callsite(llret); bx.unreachable(); diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index a9ecbdc5f35e..eb590a45a63f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -463,7 +463,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::ProjectionElem::Field(ref field, _) => { cg_base.project_field(bx, field.index()) } - mir::ProjectionElem::OpaqueCast(ty) => cg_base.project_type(bx, ty), + mir::ProjectionElem::OpaqueCast(ty) => { + bug!("encountered OpaqueCast({ty}) in codegen") + } + mir::ProjectionElem::Subtype(ty) => cg_base.project_type(bx, self.monomorphize(ty)), mir::ProjectionElem::Index(index) => { let index = &mir::Operand::Copy(mir::Place::from(index)); let index = self.codegen_operand(bx, index); diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 853c6934c2c2..aa411f002a0c 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -332,5 +332,5 @@ pub trait BuilderMethods<'a, 'tcx>: ) -> Self::Value; fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; - fn do_not_inline(&mut self, llret: Self::Value); + fn apply_attrs_to_cleanup_callsite(&mut self, llret: Self::Value); } diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index dc3dbd9d8194..b1fde8e4d863 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -30,7 +30,7 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> { fn type_ptr_ext(&self, address_space: AddressSpace) -> Self::Type; fn element_type(&self, ty: Self::Type) -> Self::Type; - /// Returns the number of elements in `self` if it is a LLVM vector type. + /// Returns the number of elements in `self` if it is an LLVM vector type. fn vector_length(&self, ty: Self::Type) -> usize; fn float_width(&self, ty: Self::Type) -> usize; diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 14b9894aad5c..865e01d0aee0 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -207,7 +207,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> { ) -> InterpResult<'tcx, Option>> { let def_id = instance.def_id(); - if Some(def_id) == self.tcx.lang_items().panic_display() + if self.tcx.has_attr(def_id, sym::rustc_const_panic_str) || Some(def_id) == self.tcx.lang_items().begin_panic_fn() { let args = self.copy_fn_args(args)?; diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 94a5cc67d31c..af7dfbef2ff8 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::layout::{ self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout, }; -use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, Variance}; use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_session::Limit; use rustc_span::Span; @@ -384,7 +384,7 @@ pub(super) fn mir_assign_valid_types<'tcx>( // all normal lifetimes are erased, higher-ranked types with their // late-bound lifetimes are still around and can lead to type // differences. - if util::is_subtype(tcx, param_env, src.ty, dest.ty) { + if util::relate_types(tcx, param_env, Variance::Covariant, src.ty, dest.ty) { // Make sure the layout is equal, too -- just to be safe. Miri really // needs layout equality. For performance reason we skip this check when // the types are equal. Equal types *can* have different layouts when diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index a32ea204f984..99dba977a439 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -670,19 +670,24 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { trace!("eval_place_to_op: got {:?}", op); // Sanity-check the type we ended up with. - debug_assert!( - mir_assign_valid_types( + if cfg!(debug_assertions) { + let normalized_place_ty = self.subst_from_current_frame_and_normalize_erasing_regions( + mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty, + )?; + if !mir_assign_valid_types( *self.tcx, self.param_env, - self.layout_of(self.subst_from_current_frame_and_normalize_erasing_regions( - mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty - )?)?, + self.layout_of(normalized_place_ty)?, op.layout, - ), - "eval_place of a MIR place with type {:?} produced an interpreter operand with type {}", - mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty, - op.layout.ty, - ); + ) { + span_bug!( + self.cur_span(), + "eval_place of a MIR place with type {} produced an interpreter operand with type {}", + normalized_place_ty, + op.layout.ty, + ) + } + } Ok(op) } diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 503004cbbe1e..79448f07cae2 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -573,19 +573,24 @@ where trace!("{:?}", self.dump_place(&place)); // Sanity-check the type we ended up with. - debug_assert!( - mir_assign_valid_types( + if cfg!(debug_assertions) { + let normalized_place_ty = self.subst_from_current_frame_and_normalize_erasing_regions( + mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty, + )?; + if !mir_assign_valid_types( *self.tcx, self.param_env, - self.layout_of(self.subst_from_current_frame_and_normalize_erasing_regions( - mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty - )?)?, + self.layout_of(normalized_place_ty)?, place.layout, - ), - "eval_place of a MIR place with type {:?} produced an interpreter place with type {}", - mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty, - place.layout.ty, - ); + ) { + span_bug!( + self.cur_span(), + "eval_place of a MIR place with type {} produced an interpreter place with type {}", + normalized_place_ty, + place.layout.ty, + ) + } + } Ok(place) } diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 6c720ac4a574..70df3d8fd782 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -316,7 +316,11 @@ where { use rustc_middle::mir::ProjectionElem::*; Ok(match proj_elem { - OpaqueCast(ty) => base.transmute(self.layout_of(ty)?, self)?, + OpaqueCast(ty) => { + span_bug!(self.cur_span(), "OpaqueCast({ty}) encountered after borrowck") + } + // We don't want anything happening here, this is here as a dummy. + Subtype(_) => base.transmute(base.layout(), self)?, Field(field, _) => self.project_field(base, field.index())?, Downcast(_, variant) => self.project_downcast(base, variant)?, Deref => self.deref_pointer(&base.to_op(self)?)?.into(), diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 129e74425b6d..c4d806c51619 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -237,7 +237,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { if self.const_kind() == hir::ConstContext::ConstFn { for (idx, local) in body.local_decls.iter_enumerated() { // Handle the return place below. - if idx == RETURN_PLACE || local.internal { + if idx == RETURN_PLACE { continue; } @@ -664,6 +664,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { | ProjectionElem::Downcast(..) | ProjectionElem::OpaqueCast(..) | ProjectionElem::Subslice { .. } + | ProjectionElem::Subtype(..) | ProjectionElem::Field(..) | ProjectionElem::Index(_) => {} } @@ -886,7 +887,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // At this point, we are calling a function, `callee`, whose `DefId` is known... - // `begin_panic` and `panic_display` are generic functions that accept + // `begin_panic` and `#[rustc_const_panic_str]` functions accept generic // types other than str. Check to enforce that only str can be used in // const-eval. @@ -898,8 +899,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } } - // const-eval of the `panic_display` fn assumes the argument is `&&str` - if Some(callee) == tcx.lang_items().panic_display() { + // const-eval of `#[rustc_const_panic_str]` functions assumes the argument is `&&str` + if tcx.has_attr(callee, sym::rustc_const_panic_str) { match args[0].ty(&self.ccx.body.local_decls, tcx).kind() { ty::Ref(_, ty, _) if matches!(ty.kind(), ty::Ref(_, ty, _) if ty.is_str()) => { diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 34e9b76c4844..de3186a53c16 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -306,6 +306,7 @@ where ProjectionElem::Index(index) if in_local(index) => return true, ProjectionElem::Deref + | ProjectionElem::Subtype(_) | ProjectionElem::Field(_, _) | ProjectionElem::OpaqueCast(_) | ProjectionElem::ConstantIndex { .. } diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 4a9977add78c..8ede3bdd2b60 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -357,7 +357,9 @@ impl<'tcx> Validator<'_, 'tcx> { return Err(Unpromotable); } - ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {} + ProjectionElem::ConstantIndex { .. } + | ProjectionElem::Subtype(_) + | ProjectionElem::Subslice { .. } => {} ProjectionElem::Index(local) => { let mut promotable = false; diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 0d8733070a44..4711f7b47ccc 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -7,7 +7,7 @@ use rustc_infer::traits::Reveal; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; -use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt, Variance}; use rustc_mir_dataflow::impls::MaybeStorageLive; use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_mir_dataflow::{Analysis, ResultsCursor}; @@ -16,6 +16,8 @@ use rustc_target::spec::abi::Abi; use crate::util::is_within_packed; +use crate::util::relate_types; + #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum EdgeKind { Unwind, @@ -602,7 +604,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return true; } - crate::util::is_subtype(self.tcx, self.param_env, src, dest) + // After borrowck subtyping should be fully explicit via + // `Subtype` projections. + let variance = if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { + Variance::Invariant + } else { + Variance::Covariant + }; + + crate::util::relate_types(self.tcx, self.param_env, variance, src, dest) } } @@ -633,6 +643,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { location: Location, ) { match elem { + ProjectionElem::OpaqueCast(ty) + if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) => + { + self.fail( + location, + format!("explicit opaque type cast to `{ty}` after `RevealAll`"), + ) + } ProjectionElem::Index(index) => { let index_ty = self.body.local_decls[index].ty; if index_ty != self.tcx.types.usize { @@ -745,6 +763,23 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } } + ProjectionElem::Subtype(ty) => { + if !relate_types( + self.tcx, + self.param_env, + Variance::Covariant, + ty, + place_ref.ty(&self.body.local_decls, self.tcx).ty, + ) { + self.fail( + location, + format!( + "Failed subtyping {ty:#?} and {:#?}", + place_ref.ty(&self.body.local_decls, self.tcx).ty + ), + ) + } + } _ => {} } self.super_projection_elem(place_ref, elem, context, location); @@ -1080,6 +1115,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // LHS and RHS of the assignment must have the same type. let left_ty = dest.ty(&self.body.local_decls, self.tcx).ty; let right_ty = rvalue.ty(&self.body.local_decls, self.tcx); + if !self.mir_assign_valid_types(right_ty, left_ty) { self.fail( location, diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs index 83376c8e9928..265ca0c7884c 100644 --- a/compiler/rustc_const_eval/src/util/compare_types.rs +++ b/compiler/rustc_const_eval/src/util/compare_types.rs @@ -5,7 +5,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::traits::{DefiningAnchor, ObligationCause}; -use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, Variance}; use rustc_trait_selection::traits::ObligationCtxt; /// Returns whether the two types are equal up to subtyping. @@ -24,16 +24,22 @@ pub fn is_equal_up_to_subtyping<'tcx>( } // Check for subtyping in either direction. - is_subtype(tcx, param_env, src, dest) || is_subtype(tcx, param_env, dest, src) + relate_types(tcx, param_env, Variance::Covariant, src, dest) + || relate_types(tcx, param_env, Variance::Covariant, dest, src) } /// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`. /// +/// When validating assignments, the variance should be `Covariant`. When checking +/// during `MirPhase` >= `MirPhase::Runtime(RuntimePhase::Initial)` variance should be `Invariant` +/// because we want to check for type equality. +/// /// This mostly ignores opaque types as it can be used in constraining contexts /// while still computing the final underlying type. -pub fn is_subtype<'tcx>( +pub fn relate_types<'tcx>( tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, + variance: Variance, src: Ty<'tcx>, dest: Ty<'tcx>, ) -> bool { @@ -48,7 +54,7 @@ pub fn is_subtype<'tcx>( let cause = ObligationCause::dummy(); let src = ocx.normalize(&cause, param_env, src); let dest = ocx.normalize(&cause, param_env, dest); - match ocx.sub(&cause, param_env, src, dest) { + match ocx.relate(&cause, param_env, variance, src, dest) { Ok(()) => {} Err(_) => return false, }; diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs index 0aef7fa469e4..040b3071e6f8 100644 --- a/compiler/rustc_const_eval/src/util/mod.rs +++ b/compiler/rustc_const_eval/src/util/mod.rs @@ -7,7 +7,7 @@ mod type_name; pub use self::alignment::{is_disaligned, is_within_packed}; pub use self::check_validity_requirement::check_validity_requirement; -pub use self::compare_types::{is_equal_up_to_subtyping, is_subtype}; +pub use self::compare_types::{is_equal_up_to_subtyping, relate_types}; pub use self::type_name::type_name; /// Classify whether an operator is "left-homogeneous", i.e., the LHS has the diff --git a/compiler/rustc_error_codes/src/error_codes/E0551.md b/compiler/rustc_error_codes/src/error_codes/E0551.md index 53db559a4fcb..0e078fe71bfd 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0551.md +++ b/compiler/rustc_error_codes/src/error_codes/E0551.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler + An invalid meta-item was used inside an attribute. Erroneous code example: -```compile_fail,E0551 +```compile_fail,E0539 #[deprecated(note)] // error! fn i_am_deprecated() {} ``` diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index b747a62b864d..665b5d6adec3 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1376,16 +1376,16 @@ impl HandlerInner { self.emitted_diagnostic_codes.insert(code.clone()); } - let already_emitted = |this: &mut Self| { + let already_emitted = { let mut hasher = StableHasher::new(); diagnostic.hash(&mut hasher); let diagnostic_hash = hasher.finish(); - !this.emitted_diagnostics.insert(diagnostic_hash) + !self.emitted_diagnostics.insert(diagnostic_hash) }; // Only emit the diagnostic if we've been asked to deduplicate or // haven't already emitted an equivalent diagnostic. - if !(self.flags.deduplicate_diagnostics && already_emitted(self)) { + if !(self.flags.deduplicate_diagnostics && already_emitted) { debug!(?diagnostic); debug!(?self.emitted_diagnostics); let already_emitted_sub = |sub: &mut SubDiagnostic| { @@ -1401,6 +1401,11 @@ impl HandlerInner { }; diagnostic.children.extract_if(already_emitted_sub).for_each(|_| {}); + if already_emitted { + diagnostic.note( + "duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`", + ); + } self.emitter.emit_diagnostic(diagnostic); if diagnostic.is_error() { diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 6aa1e0c3e006..32d8380abd3a 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -269,6 +269,8 @@ declare_features! ( (accepted, non_modrs_mods, "1.30.0", Some(44660), None), /// Allows the use of or-patterns (e.g., `0 | 1`). (accepted, or_patterns, "1.53.0", Some(54883), None), + /// Allows using `+bundle,+whole-archive` link modifiers with native libs. + (accepted, packed_bundled_libs, "CURRENT_RUSTC_VERSION", Some(108081), None), /// Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`. /// This defines the behavior of panics. (accepted, panic_handler, "1.30.0", Some(44489), None), diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index aa071982876a..a02c04ecd3ec 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -241,8 +241,6 @@ declare_features! ( (active, linkage, "1.0.0", Some(29603), None), /// Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed. (internal, needs_panic_runtime, "1.10.0", Some(32837), None), - /// Allows using `+bundled,+whole-archive` native libs. - (active, packed_bundled_libs, "1.69.0", Some(108081), None), /// Allows using the `#![panic_runtime]` attribute. (internal, panic_runtime, "1.10.0", Some(32837), None), /// Allows `extern "platform-intrinsic" { ... }`. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 18397af565fa..65e697c8f3b8 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -666,6 +666,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!( rustc_do_not_const_check, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE ), + // Ensure the argument to this function is &&str during const-check. + rustc_attr!( + rustc_const_panic_str, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE + ), // ========================================================================== // Internal attributes, Layout related: diff --git a/compiler/rustc_fluent_macro/src/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs index 56e23ac27752..7479e4ef2b31 100644 --- a/compiler/rustc_fluent_macro/src/fluent.rs +++ b/compiler/rustc_fluent_macro/src/fluent.rs @@ -40,26 +40,35 @@ fn invocation_relative_path_to_absolute(span: Span, path: &str) -> PathBuf { } } -/// Tokens to be returned when the macro cannot proceed. -fn failed(crate_name: &Ident) -> proc_macro::TokenStream { +/// Final tokens. +fn finish(body: TokenStream, resource: TokenStream) -> proc_macro::TokenStream { quote! { - pub static DEFAULT_LOCALE_RESOURCE: &'static str = ""; + /// Raw content of Fluent resource for this crate, generated by `fluent_messages` macro, + /// imported by `rustc_driver` to include all crates' resources in one bundle. + pub static DEFAULT_LOCALE_RESOURCE: &'static str = #resource; #[allow(non_upper_case_globals)] #[doc(hidden)] + /// Auto-generated constants for type-checked references to Fluent messages. pub(crate) mod fluent_generated { - pub mod #crate_name { - } + #body + /// Constants expected to exist by the diagnostic derive macros to use as default Fluent + /// identifiers for different subdiagnostic kinds. pub mod _subdiag { + /// Default for `#[help]` pub const help: crate::SubdiagnosticMessage = crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("help")); + /// Default for `#[note]` pub const note: crate::SubdiagnosticMessage = crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("note")); + /// Default for `#[warn]` pub const warn: crate::SubdiagnosticMessage = crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("warn")); + /// Default for `#[label]` pub const label: crate::SubdiagnosticMessage = crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("label")); + /// Default for `#[suggestion]` pub const suggestion: crate::SubdiagnosticMessage = crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("suggestion")); } @@ -68,6 +77,11 @@ fn failed(crate_name: &Ident) -> proc_macro::TokenStream { .into() } +/// Tokens to be returned when the macro cannot proceed. +fn failed(crate_name: &Ident) -> proc_macro::TokenStream { + finish(quote! { pub mod #crate_name {} }, quote! { "" }) +} + /// See [rustc_fluent_macro::fluent_messages]. pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let crate_name = std::env::var("CARGO_PKG_NAME") @@ -311,39 +325,7 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok } } - quote! { - /// Raw content of Fluent resource for this crate, generated by `fluent_messages` macro, - /// imported by `rustc_driver` to include all crates' resources in one bundle. - pub static DEFAULT_LOCALE_RESOURCE: &'static str = include_str!(#relative_ftl_path); - - #[allow(non_upper_case_globals)] - #[doc(hidden)] - /// Auto-generated constants for type-checked references to Fluent messages. - pub(crate) mod fluent_generated { - #constants - - /// Constants expected to exist by the diagnostic derive macros to use as default Fluent - /// identifiers for different subdiagnostic kinds. - pub mod _subdiag { - /// Default for `#[help]` - pub const help: crate::SubdiagnosticMessage = - crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("help")); - /// Default for `#[note]` - pub const note: crate::SubdiagnosticMessage = - crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("note")); - /// Default for `#[warn]` - pub const warn: crate::SubdiagnosticMessage = - crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("warn")); - /// Default for `#[label]` - pub const label: crate::SubdiagnosticMessage = - crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("label")); - /// Default for `#[suggestion]` - pub const suggestion: crate::SubdiagnosticMessage = - crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("suggestion")); - } - } - } - .into() + finish(constants, quote! { include_str!(#relative_ftl_path) }) } fn variable_references<'a>(msg: &Message<&'a str>) -> Vec<&'a str> { diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 23b20543d535..4a89a6f7e392 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -230,7 +230,6 @@ language_item_table! { Panic, sym::panic, panic_fn, Target::Fn, GenericRequirement::Exact(0); PanicNounwind, sym::panic_nounwind, panic_nounwind, Target::Fn, GenericRequirement::Exact(0); PanicFmt, sym::panic_fmt, panic_fmt, Target::Fn, GenericRequirement::None; - PanicDisplay, sym::panic_display, panic_display, Target::Fn, GenericRequirement::None; ConstPanicFmt, sym::const_panic_fmt, const_panic_fmt, Target::Fn, GenericRequirement::None; PanicBoundsCheck, sym::panic_bounds_check, panic_bounds_check_fn, Target::Fn, GenericRequirement::Exact(0); PanicMisalignedPointerDereference, sym::panic_misaligned_pointer_dereference, panic_misaligned_pointer_dereference_fn, Target::Fn, GenericRequirement::Exact(0); diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 1c926533a27f..ee475e3de7e9 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -96,8 +96,6 @@ hir_analysis_enum_discriminant_overflowed = enum discriminant overflowed .label = overflowed on value after {$discr} .note = explicitly set `{$item_name} = {$wrapped_discr}` if that is desired outcome -hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` - hir_analysis_field_already_declared = field `{$field_name}` is already declared .label = field already declared diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index d081b0e35c66..6a1da615055b 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -16,6 +16,7 @@ use rustc_infer::traits::util; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::util::ExplicitSelf; +use rustc_middle::ty::ToPredicate; use rustc_middle::ty::{ self, GenericArgs, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; @@ -1188,7 +1189,7 @@ fn report_trait_method_mismatch<'tcx>( let ap = Applicability::MachineApplicable; match sig.decl.output { hir::FnRetTy::DefaultReturn(sp) => { - let sugg = format!("-> {} ", trait_sig.output()); + let sugg = format!(" -> {}", trait_sig.output()); diag.span_suggestion_verbose(sp, msg, sugg, ap); } hir::FnRetTy::Return(hir_ty) => { @@ -2279,16 +2280,16 @@ pub(super) fn check_type_bounds<'tcx>( // // impl X for T where T: X { type Y = ::Y; } } - _ => predicates.push(ty::Clause::from_projection_clause( - tcx, + _ => predicates.push( ty::Binder::bind_with_vars( ty::ProjectionPredicate { projection_ty: tcx.mk_alias_ty(trait_ty.def_id, rebased_args), term: normalize_impl_ty.into(), }, bound_vars, - ), - )), + ) + .to_predicate(tcx), + ), }; ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing) }; diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index d9e0e87eb471..bc5029a1d5e4 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -23,8 +23,12 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( if !tcx.impl_method_has_trait_impl_trait_tys(impl_m.def_id) { return; } - // crate-private traits don't have any library guarantees, there's no need to do this check. - if !tcx.visibility(trait_m.container_id(tcx)).is_public() { + // unreachable traits don't have any library guarantees, there's no need to do this check. + if trait_m + .container_id(tcx) + .as_local() + .is_some_and(|trait_def_id| !tcx.effective_visibilities(()).is_reachable(trait_def_id)) + { return; } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 3c0d977917fd..c61719c1fd29 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -20,6 +20,7 @@ fn equate_intrinsic_type<'tcx>( it: &hir::ForeignItem<'_>, n_tps: usize, n_lts: usize, + n_cts: usize, sig: ty::PolyFnSig<'tcx>, ) { let (own_counts, span) = match &it.kind { @@ -51,7 +52,7 @@ fn equate_intrinsic_type<'tcx>( if gen_count_ok(own_counts.lifetimes, n_lts, "lifetime") && gen_count_ok(own_counts.types, n_tps, "type") - && gen_count_ok(own_counts.consts, 0, "const") + && gen_count_ok(own_counts.consts, n_cts, "const") { let it_def_id = it.owner_id.def_id; check_function_signature( @@ -489,7 +490,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { }; let sig = tcx.mk_fn_sig(inputs, output, false, unsafety, Abi::RustIntrinsic); let sig = ty::Binder::bind_with_vars(sig, bound_vars); - equate_intrinsic_type(tcx, it, n_tps, n_lts, sig) + equate_intrinsic_type(tcx, it, n_tps, n_lts, 0, sig) } /// Type-check `extern "platform-intrinsic" { ... }` functions. @@ -501,9 +502,9 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) let name = it.ident.name; - let (n_tps, inputs, output) = match name { + let (n_tps, n_cts, inputs, output) = match name { sym::simd_eq | sym::simd_ne | sym::simd_lt | sym::simd_le | sym::simd_gt | sym::simd_ge => { - (2, vec![param(0), param(0)], param(1)) + (2, 0, vec![param(0), param(0)], param(1)) } sym::simd_add | sym::simd_sub @@ -519,8 +520,8 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) | sym::simd_fmax | sym::simd_fpow | sym::simd_saturating_add - | sym::simd_saturating_sub => (1, vec![param(0), param(0)], param(0)), - sym::simd_arith_offset => (2, vec![param(0), param(1)], param(0)), + | sym::simd_saturating_sub => (1, 0, vec![param(0), param(0)], param(0)), + sym::simd_arith_offset => (2, 0, vec![param(0), param(1)], param(0)), sym::simd_neg | sym::simd_bswap | sym::simd_bitreverse @@ -538,25 +539,25 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) | sym::simd_ceil | sym::simd_floor | sym::simd_round - | sym::simd_trunc => (1, vec![param(0)], param(0)), - sym::simd_fpowi => (1, vec![param(0), tcx.types.i32], param(0)), - sym::simd_fma => (1, vec![param(0), param(0), param(0)], param(0)), - sym::simd_gather => (3, vec![param(0), param(1), param(2)], param(0)), - sym::simd_scatter => (3, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)), - sym::simd_insert => (2, vec![param(0), tcx.types.u32, param(1)], param(0)), - sym::simd_extract => (2, vec![param(0), tcx.types.u32], param(1)), + | sym::simd_trunc => (1, 0, vec![param(0)], param(0)), + sym::simd_fpowi => (1, 0, vec![param(0), tcx.types.i32], param(0)), + sym::simd_fma => (1, 0, vec![param(0), param(0), param(0)], param(0)), + sym::simd_gather => (3, 0, vec![param(0), param(1), param(2)], param(0)), + sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)), + sym::simd_insert => (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0)), + sym::simd_extract => (2, 0, vec![param(0), tcx.types.u32], param(1)), sym::simd_cast | sym::simd_as | sym::simd_cast_ptr | sym::simd_expose_addr - | sym::simd_from_exposed_addr => (2, vec![param(0)], param(1)), - sym::simd_bitmask => (2, vec![param(0)], param(1)), + | sym::simd_from_exposed_addr => (2, 0, vec![param(0)], param(1)), + sym::simd_bitmask => (2, 0, vec![param(0)], param(1)), sym::simd_select | sym::simd_select_bitmask => { - (2, vec![param(0), param(1), param(1)], param(1)) + (2, 0, vec![param(0), param(1), param(1)], param(1)) } - sym::simd_reduce_all | sym::simd_reduce_any => (1, vec![param(0)], tcx.types.bool), + sym::simd_reduce_all | sym::simd_reduce_any => (1, 0, vec![param(0)], tcx.types.bool), sym::simd_reduce_add_ordered | sym::simd_reduce_mul_ordered => { - (2, vec![param(0), param(1)], param(1)) + (2, 0, vec![param(0), param(1)], param(1)) } sym::simd_reduce_add_unordered | sym::simd_reduce_mul_unordered @@ -566,8 +567,9 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) | sym::simd_reduce_min | sym::simd_reduce_max | sym::simd_reduce_min_nanless - | sym::simd_reduce_max_nanless => (2, vec![param(0)], param(1)), - sym::simd_shuffle => (3, vec![param(0), param(0), param(1)], param(2)), + | sym::simd_reduce_max_nanless => (2, 0, vec![param(0)], param(1)), + sym::simd_shuffle => (3, 0, vec![param(0), param(0), param(1)], param(2)), + sym::simd_shuffle_generic => (2, 1, vec![param(0), param(0)], param(1)), _ => { let msg = format!("unrecognized platform-specific intrinsic function: `{name}`"); tcx.sess.struct_span_err(it.span, msg).emit(); @@ -577,5 +579,5 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) let sig = tcx.mk_fn_sig(inputs, output, false, hir::Unsafety::Unsafe, Abi::PlatformIntrinsic); let sig = ty::Binder::dummy(sig); - equate_intrinsic_type(tcx, it, n_tps, 0, sig) + equate_intrinsic_type(tcx, it, n_tps, 0, n_cts, sig) } diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 88c98fa979e1..5fa65f33c763 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -329,41 +329,52 @@ fn bounds_from_generic_predicates<'tcx>( _ => {} } } - let generics = if types.is_empty() { - "".to_string() - } else { - format!( - "<{}>", - types - .keys() - .filter_map(|t| match t.kind() { - ty::Param(_) => Some(t.to_string()), - // Avoid suggesting the following: - // fn foo::Bar>(_: T) where T: Trait, ::Bar: Other {} - _ => None, - }) - .collect::>() - .join(", ") - ) - }; + let mut where_clauses = vec![]; + let mut types_str = vec![]; for (ty, bounds) in types { - where_clauses - .extend(bounds.into_iter().map(|bound| format!("{}: {}", ty, tcx.def_path_str(bound)))); - } - for projection in &projections { - let p = projection.skip_binder(); - // FIXME: this is not currently supported syntax, we should be looking at the `types` and - // insert the associated types where they correspond, but for now let's be "lazy" and - // propose this instead of the following valid resugaring: - // `T: Trait, Trait::Assoc = K` → `T: Trait` - where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.def_id), p.term)); + if let ty::Param(_) = ty.kind() { + let mut bounds_str = vec![]; + for bound in bounds { + let mut projections_str = vec![]; + for projection in &projections { + let p = projection.skip_binder(); + let alias_ty = p.projection_ty; + if bound == tcx.parent(alias_ty.def_id) && alias_ty.self_ty() == ty { + let name = tcx.item_name(alias_ty.def_id); + projections_str.push(format!("{} = {}", name, p.term)); + } + } + let bound_def_path = tcx.def_path_str(bound); + if projections_str.is_empty() { + where_clauses.push(format!("{}: {}", ty, bound_def_path)); + } else { + bounds_str.push(format!("{}<{}>", bound_def_path, projections_str.join(", "))); + } + } + if bounds_str.is_empty() { + types_str.push(ty.to_string()); + } else { + types_str.push(format!("{}: {}", ty, bounds_str.join(" + "))); + } + } else { + // Avoid suggesting the following: + // fn foo::Bar>(_: T) where T: Trait, ::Bar: Other {} + where_clauses.extend( + bounds.into_iter().map(|bound| format!("{}: {}", ty, tcx.def_path_str(bound))), + ); + } } + + let generics = + if types_str.is_empty() { "".to_string() } else { format!("<{}>", types_str.join(", ")) }; + let where_clauses = if where_clauses.is_empty() { - String::new() + "".to_string() } else { format!(" where {}", where_clauses.join(", ")) }; + (generics, where_clauses) } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index b7b162ce27bc..de6ca0d61dc9 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -24,6 +24,9 @@ use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; +use rustc_trait_selection::traits::misc::{ + type_allowed_to_implement_const_param_ty, ConstParamTyImplementationError, +}; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_trait_selection::traits::{ @@ -865,43 +868,65 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { ); }); } else { - let err_ty_str; - let mut is_ptr = true; - - let err = match ty.kind() { + let diag = match ty.kind() { ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None, - ty::FnPtr(_) => Some("function pointers"), - ty::RawPtr(_) => Some("raw pointers"), - _ => { - is_ptr = false; - err_ty_str = format!("`{ty}`"); - Some(err_ty_str.as_str()) - } + ty::FnPtr(_) => Some(tcx.sess.struct_span_err( + hir_ty.span, + "using function pointers as const generic parameters is forbidden", + )), + ty::RawPtr(_) => Some(tcx.sess.struct_span_err( + hir_ty.span, + "using raw pointers as const generic parameters is forbidden", + )), + _ => Some(tcx.sess.struct_span_err( + hir_ty.span, + format!("`{}` is forbidden as the type of a const generic parameter", ty), + )), }; - if let Some(unsupported_type) = err { - if is_ptr { - tcx.sess.span_err( - hir_ty.span, - format!( - "using {unsupported_type} as const generic parameters is forbidden", - ), - ); - } else { - let mut err = tcx.sess.struct_span_err( - hir_ty.span, - format!( - "{unsupported_type} is forbidden as the type of a const generic parameter", - ), - ); - err.note("the only supported types are integers, `bool` and `char`"); - if tcx.sess.is_nightly_build() { - err.help( - "more complex types are supported with `#![feature(adt_const_params)]`", - ); + if let Some(mut diag) = diag { + diag.note("the only supported types are integers, `bool` and `char`"); + + let cause = ObligationCause::misc(hir_ty.span, param.def_id); + let may_suggest_feature = match type_allowed_to_implement_const_param_ty( + tcx, + tcx.param_env(param.def_id), + ty, + cause, + ) { + // Can never implement `ConstParamTy`, don't suggest anything. + Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => false, + // May be able to implement `ConstParamTy`. Only emit the feature help + // if the type is local, since the user may be able to fix the local type. + Err(ConstParamTyImplementationError::InfrigingFields(..)) => { + fn ty_is_local(ty: Ty<'_>) -> bool { + match ty.kind() { + ty::Adt(adt_def, ..) => adt_def.did().is_local(), + // Arrays and slices use the inner type's `ConstParamTy`. + ty::Array(ty, ..) => ty_is_local(*ty), + ty::Slice(ty) => ty_is_local(*ty), + // `&` references use the inner type's `ConstParamTy`. + // `&mut` are not supported. + ty::Ref(_, ty, ast::Mutability::Not) => ty_is_local(*ty), + // Say that a tuple is local if any of its components are local. + // This is not strictly correct, but it's likely that the user can fix the local component. + ty::Tuple(tys) => tys.iter().any(|ty| ty_is_local(ty)), + _ => false, + } + } + + ty_is_local(ty) } - err.emit(); + // Implments `ConstParamTy`, suggest adding the feature to enable. + Ok(..) => true, + }; + if may_suggest_feature && tcx.sess.is_nightly_build() { + diag.help( + "add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types", + ); } + + diag.emit(); } } } @@ -1105,11 +1130,11 @@ fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocIt let wf_obligations = bounds.instantiate_identity_iter_copied().flat_map(|(bound, bound_span)| { let normalized_bound = wfcx.normalize(span, None, bound); - traits::wf::predicate_obligations( + traits::wf::clause_obligations( wfcx.infcx, wfcx.param_env, wfcx.body_def_id, - normalized_bound.as_predicate(), + normalized_bound, bound_span, ) }); @@ -1209,7 +1234,7 @@ fn check_impl<'tcx>( wfcx.infcx, wfcx.param_env, wfcx.body_def_id, - &trait_pred, + trait_pred, ast_trait_ref.path.span, item, ); @@ -1418,13 +1443,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id debug!(?predicates.predicates); assert_eq!(predicates.predicates.len(), predicates.spans.len()); let wf_obligations = predicates.into_iter().flat_map(|(p, sp)| { - traits::wf::predicate_obligations( - infcx, - wfcx.param_env, - wfcx.body_def_id, - p.as_predicate(), - sp, - ) + traits::wf::clause_obligations(infcx, wfcx.param_env, wfcx.body_def_id, p, sp) }); let obligations: Vec<_> = wf_obligations.chain(default_obligations).collect(); wfcx.register_obligations(obligations); diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 3760195a5e8e..dbd38e1b1fe7 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -376,9 +376,9 @@ fn check_predicates<'tcx>( let always_applicable_traits = impl1_predicates .iter() .copied() - .filter(|(clause, _span)| { + .filter(|&(clause, _span)| { matches!( - trait_predicate_kind(tcx, clause.as_predicate()), + trait_specialization_kind(tcx, clause), Some(TraitSpecializationKind::AlwaysApplicable) ) }) @@ -402,7 +402,7 @@ fn check_predicates<'tcx>( .iter() .any(|pred2| trait_predicates_eq(tcx, clause.as_predicate(), *pred2, span)) { - check_specialization_on(tcx, clause.as_predicate(), span) + check_specialization_on(tcx, clause, span) } } } @@ -441,19 +441,16 @@ fn trait_predicates_eq<'tcx>( } #[instrument(level = "debug", skip(tcx))] -fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tcx>, span: Span) { - match predicate.kind().skip_binder() { +fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, clause: ty::Clause<'tcx>, span: Span) { + match clause.kind().skip_binder() { // Global predicates are either always true or always false, so we // are fine to specialize on. - _ if predicate.is_global() => (), + _ if clause.is_global() => (), // We allow specializing on explicitly marked traits with no associated // items. - ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate { - trait_ref, - polarity: _, - })) => { + ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => { if !matches!( - trait_predicate_kind(tcx, predicate), + trait_specialization_kind(tcx, clause), Some(TraitSpecializationKind::Marker) ) { tcx.sess @@ -467,10 +464,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc .emit(); } } - ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate { - projection_ty, - term, - })) => { + ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => { tcx.sess .struct_span_err( span, @@ -478,7 +472,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc ) .emit(); } - ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) => { + ty::ClauseKind::ConstArgHasType(..) => { // FIXME(min_specialization), FIXME(const_generics): // It probably isn't right to allow _every_ `ConstArgHasType` but I am somewhat unsure // about the actual rules that would be sound. Can't just always error here because otherwise @@ -490,33 +484,25 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc } _ => { tcx.sess - .struct_span_err(span, format!("cannot specialize on predicate `{predicate}`")) + .struct_span_err(span, format!("cannot specialize on predicate `{clause}`")) .emit(); } } } -fn trait_predicate_kind<'tcx>( +fn trait_specialization_kind<'tcx>( tcx: TyCtxt<'tcx>, - predicate: ty::Predicate<'tcx>, + clause: ty::Clause<'tcx>, ) -> Option { - match predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate { - trait_ref, - polarity: _, - })) => Some(tcx.trait_def(trait_ref.def_id).specialization_kind), - ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(_)) - | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(_)) - | ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) - | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) - | ty::PredicateKind::AliasRelate(..) - | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) - | ty::PredicateKind::Subtype(_) - | ty::PredicateKind::Coerce(_) - | ty::PredicateKind::ObjectSafe(_) - | ty::PredicateKind::ClosureKind(..) - | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) - | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::Ambiguous => None, + match clause.kind().skip_binder() { + ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => { + Some(tcx.trait_def(trait_ref.def_id).specialization_kind) + } + ty::ClauseKind::RegionOutlives(_) + | ty::ClauseKind::TypeOutlives(_) + | ty::ClauseKind::Projection(_) + | ty::ClauseKind::ConstArgHasType(..) + | ty::ClauseKind::WellFormed(_) + | ty::ClauseKind::ConstEvaluatable(..) => None, } } diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 85e0000ab474..9fb39a0e93b6 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -192,5 +192,5 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc } } } - tcx.arena.alloc_from_iter(collector.variances.into_iter()) + tcx.arena.alloc_from_iter(collector.variances) } diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 1fa0ec173a7e..c8ffd7d15067 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -113,7 +113,11 @@ pub(super) fn check_fn<'a, 'tcx>( fcx.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig); - fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType); + let return_or_body_span = match decl.output { + hir::FnRetTy::DefaultReturn(_) => body.value.span, + hir::FnRetTy::Return(ty) => ty.span, + }; + fcx.require_type_is_sized(declared_ret_ty, return_or_body_span, traits::SizedReturnType); fcx.check_return_expr(&body.value, false); // We insert the deferred_generator_interiors entry after visiting the body. diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index d97691369c95..5c3f2b85966a 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -14,7 +14,7 @@ use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeFoldable}; +use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeFoldable, TypeVisitableExt}; use rustc_span::symbol::sym; use rustc_span::{BytePos, Span, DUMMY_SP}; use rustc_trait_selection::infer::InferCtxtExt as _; @@ -504,12 +504,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // incompatible fix at the original mismatch site. if matches!(source, TypeMismatchSource::Ty(_)) && let Some(ideal_method) = ideal_method + && let ideal_arg_ty = self.resolve_vars_if_possible(ideal_method.sig.inputs()[idx + 1]) + // HACK(compiler-errors): We don't actually consider the implications + // of our inference guesses in `emit_type_mismatch_suggestions`, so + // only suggest things when we know our type error is precisely due to + // a type mismatch, and not via some projection or something. See #116155. + && !ideal_arg_ty.has_non_region_infer() { self.emit_type_mismatch_suggestions( err, arg_expr, arg_ty, - self.resolve_vars_if_possible(ideal_method.sig.inputs()[idx + 1]), + ideal_arg_ty, None, None, ); diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 1526988fbd92..8efccd5ba3ee 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -110,7 +110,7 @@ pub struct AddressOfTemporaryTaken { pub enum AddReturnTypeSuggestion { #[suggestion( hir_typeck_add_return_type_add, - code = "-> {found} ", + code = " -> {found}", applicability = "machine-applicable" )] Add { @@ -120,7 +120,7 @@ pub enum AddReturnTypeSuggestion { }, #[suggestion( hir_typeck_add_return_type_missing_here, - code = "-> _ ", + code = " -> _", applicability = "has-placeholders" )] MissingHere { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index eead4da5e3ef..d9d0dd93010c 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -41,7 +41,6 @@ use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::InferOk; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::ObligationCause; -use rustc_middle::middle::stability; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase}; use rustc_middle::ty::error::{ ExpectedFound, @@ -1585,12 +1584,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_expr_struct_fields( adt_ty, expected, - expr.hir_id, + expr, qpath.span(), variant, fields, base_expr, - expr.span, ); self.require_type_is_sized(adt_ty, expr.span, traits::StructInitializerSized); @@ -1601,12 +1599,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, adt_ty: Ty<'tcx>, expected: Expectation<'tcx>, - expr_id: hir::HirId, + expr: &hir::Expr<'_>, span: Span, variant: &'tcx ty::VariantDef, ast_fields: &'tcx [hir::ExprField<'tcx>], base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>, - expr_span: Span, ) { let tcx = self.tcx; @@ -1646,7 +1643,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // struct-like enums (yet...), but it's definitely not // a bug to have constructed one. if adt_kind != AdtKind::Enum { - tcx.check_stability(v_field.did, Some(expr_id), field.span, None); + tcx.check_stability(v_field.did, Some(expr.hir_id), field.span, None); } self.field_ty(field.span, v_field, args) @@ -1662,10 +1659,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.report_unknown_field( adt_ty, variant, + expr, field, ast_fields, adt.variant_descr(), - expr_span, ) }; @@ -1731,7 +1728,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .map(|f| { let fru_ty = self - .normalize(expr_span, self.field_ty(base_expr.span, f, fresh_args)); + .normalize(expr.span, self.field_ty(base_expr.span, f, fresh_args)); let ident = self.tcx.adjust_ident(f.ident(self.tcx), variant.def_id); if let Some(_) = remaining_fields.remove(&ident) { let target_ty = self.field_ty(base_expr.span, f, args); @@ -1814,7 +1811,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Adt(adt, args) if adt.is_struct() => variant .fields .iter() - .map(|f| self.normalize(expr_span, f.ty(self.tcx, args))) + .map(|f| self.normalize(expr.span, f.ty(self.tcx, args))) .collect(), _ => { self.tcx @@ -1824,13 +1821,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } }; - self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr_id, fru_tys); + self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr.hir_id, fru_tys); } else if adt_kind != AdtKind::Union && !remaining_fields.is_empty() { debug!(?remaining_fields); let private_fields: Vec<&ty::FieldDef> = variant .fields .iter() - .filter(|field| !field.vis.is_accessible_from(tcx.parent_module(expr_id), tcx)) + .filter(|field| !field.vis.is_accessible_from(tcx.parent_module(expr.hir_id), tcx)) .collect(); if !private_fields.is_empty() { @@ -2049,16 +2046,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, ty: Ty<'tcx>, variant: &'tcx ty::VariantDef, + expr: &hir::Expr<'_>, field: &hir::ExprField<'_>, skip_fields: &[hir::ExprField<'_>], kind_name: &str, - expr_span: Span, ) -> ErrorGuaranteed { if variant.is_recovered() { let guar = self .tcx .sess - .delay_span_bug(expr_span, "parser recovered but no error was emitted"); + .delay_span_bug(expr.span, "parser recovered but no error was emitted"); self.set_tainted_by_errors(guar); return guar; } @@ -2102,7 +2099,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); err.span_label(field.ident.span, "field does not exist"); err.span_suggestion_verbose( - expr_span, + expr.span, format!( "`{adt}::{variant}` is a tuple {kind_name}, use the appropriate syntax", adt = ty, @@ -2120,7 +2117,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(variant_ident_span, format!("`{ty}` defined here")); err.span_label(field.ident.span, "field does not exist"); err.span_suggestion_verbose( - expr_span, + expr.span, format!("`{ty}` is a tuple {kind_name}, use the appropriate syntax",), format!("{ty}(/* fields */)"), Applicability::HasPlaceholders, @@ -2129,9 +2126,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, _ => { // prevent all specified fields from being suggested - let skip_fields: Vec<_> = skip_fields.iter().map(|x| x.ident.name).collect(); + let available_field_names = self.available_field_names(variant, expr, skip_fields); if let Some(field_name) = - self.suggest_field_name(variant, field.ident.name, &skip_fields, expr_span) + find_best_match_for_name(&available_field_names, field.ident.name, None) { err.span_suggestion( field.ident.span, @@ -2153,10 +2150,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("`{ty}` does not have this field"), ); } - let mut available_field_names = - self.available_field_names(variant, expr_span); - available_field_names - .retain(|name| skip_fields.iter().all(|skip| name != skip)); if available_field_names.is_empty() { err.note("all struct fields are already assigned"); } else { @@ -2174,63 +2167,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit() } - // Return a hint about the closest match in field names - fn suggest_field_name( - &self, - variant: &'tcx ty::VariantDef, - field: Symbol, - skip: &[Symbol], - // The span where stability will be checked - span: Span, - ) -> Option { - let names = variant - .fields - .iter() - .filter_map(|field| { - // ignore already set fields and private fields from non-local crates - // and unstable fields. - if skip.iter().any(|&x| x == field.name) - || (!variant.def_id.is_local() && !field.vis.is_public()) - || matches!( - self.tcx.eval_stability(field.did, None, span, None), - stability::EvalResult::Deny { .. } - ) - { - None - } else { - Some(field.name) - } - }) - .collect::>(); - - find_best_match_for_name(&names, field, None) - } - fn available_field_names( &self, variant: &'tcx ty::VariantDef, - access_span: Span, + expr: &hir::Expr<'_>, + skip_fields: &[hir::ExprField<'_>], ) -> Vec { - let body_owner_hir_id = self.tcx.hir().local_def_id_to_hir_id(self.body_id); variant .fields .iter() .filter(|field| { - let def_scope = self - .tcx - .adjust_ident_and_get_scope( - field.ident(self.tcx), - variant.def_id, - body_owner_hir_id, - ) - .1; - field.vis.is_accessible_from(def_scope, self.tcx) - && !matches!( - self.tcx.eval_stability(field.did, None, access_span, None), - stability::EvalResult::Deny { .. } - ) + skip_fields.iter().all(|&skip| skip.ident.name != field.name) + && self.is_field_suggestable(field, expr.hir_id, expr.span) }) - .filter(|field| !self.tcx.is_doc_hidden(field.did)) .map(|field| field.name) .collect() } @@ -2460,7 +2409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.suggest_first_deref_field(&mut err, expr, base, ident); } ty::Adt(def, _) if !def.is_enum() => { - self.suggest_fields_on_recordish(&mut err, def, ident, expr.span); + self.suggest_fields_on_recordish(&mut err, expr, def, ident); } ty::Param(param_ty) => { self.point_at_param_definition(&mut err, param_ty); @@ -2622,12 +2571,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn suggest_fields_on_recordish( &self, err: &mut Diagnostic, + expr: &hir::Expr<'_>, def: ty::AdtDef<'tcx>, field: Ident, - access_span: Span, ) { + let available_field_names = self.available_field_names(def.non_enum_variant(), expr, &[]); if let Some(suggested_field_name) = - self.suggest_field_name(def.non_enum_variant(), field.name, &[], access_span) + find_best_match_for_name(&available_field_names, field.name, None) { err.span_suggestion( field.span, @@ -2637,12 +2587,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } else { err.span_label(field.span, "unknown field"); - let struct_variant_def = def.non_enum_variant(); - let field_names = self.available_field_names(struct_variant_def, access_span); - if !field_names.is_empty() { + if !available_field_names.is_empty() { err.note(format!( "available fields are: {}", - self.name_series_display(field_names), + self.name_series_display(available_field_names), )); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index abb689892183..9999fa2e59cc 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -782,8 +782,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } hir::FnRetTy::Return(hir_ty) => { - let span = hir_ty.span; - if let hir::TyKind::OpaqueDef(item_id, ..) = hir_ty.kind && let hir::Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(op_ty), @@ -799,28 +797,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!(?found); if found.is_suggestable(self.tcx, false) { if term.span.is_empty() { - err.subdiagnostic(errors::AddReturnTypeSuggestion::Add { span, found: found.to_string() }); + err.subdiagnostic(errors::AddReturnTypeSuggestion::Add { span: term.span, found: found.to_string() }); return true; } else { - err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { span, expected }); + err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { span: term.span, expected }); } } - } - - // Only point to return type if the expected type is the return type, as if they - // are not, the expectation must have been caused by something else. - debug!("return type {:?}", hir_ty); - let ty = self.astconv().ast_ty_to_ty(hir_ty); - debug!("return type {:?}", ty); - debug!("expected type {:?}", expected); - let bound_vars = self.tcx.late_bound_vars(hir_ty.hir_id.owner.into()); - let ty = Binder::bind_with_vars(ty, bound_vars); - let ty = self.normalize(span, ty); - let ty = self.tcx.erase_late_bound_regions(ty); - if self.can_coerce(expected, ty) { - err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { span, expected }); - self.try_suggest_return_impl_trait(err, expected, ty, fn_id); - return true; + } else { + // Only point to return type if the expected type is the return type, as if they + // are not, the expectation must have been caused by something else. + debug!("return type {:?}", hir_ty); + let ty = self.astconv().ast_ty_to_ty(hir_ty); + debug!("return type {:?}", ty); + debug!("expected type {:?}", expected); + let bound_vars = self.tcx.late_bound_vars(hir_ty.hir_id.owner.into()); + let ty = Binder::bind_with_vars(ty, bound_vars); + let ty = self.normalize(hir_ty.span, ty); + let ty = self.tcx.erase_late_bound_regions(ty); + if self.can_coerce(expected, ty) { + err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { span: hir_ty.span, expected }); + self.try_suggest_return_impl_trait(err, expected, ty, fn_id); + return true; + } } } _ => {} @@ -1687,4 +1685,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { false } } + + pub(crate) fn is_field_suggestable( + &self, + field: &ty::FieldDef, + hir_id: HirId, + span: Span, + ) -> bool { + // The field must be visible in the containing module. + field.vis.is_accessible_from(self.tcx.parent_module(hir_id), self.tcx) + // The field must not be unstable. + && !matches!( + self.tcx.eval_stability(field.did, None, rustc_span::DUMMY_SP, None), + rustc_middle::middle::stability::EvalResult::Deny { .. } + ) + // If the field is from an external crate it must not be `doc(hidden)`. + && (field.did.is_local() || !self.tcx.is_doc_hidden(field.did)) + // If the field is hygienic it must come from the same syntax context. + && self.tcx.def_ident_span(field.did).unwrap().normalize_to_macros_2_0().eq_ctxt(span) + } } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 6873382c4ac6..cd6adb345e7a 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -5,7 +5,6 @@ #![feature(box_patterns)] #![feature(min_specialization)] #![feature(control_flow_enum)] -#![feature(option_as_slice)] #![recursion_limit = "256"] #[macro_use] diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 07c48ec6392a..a4bbb16026a7 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2494,10 +2494,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Try alternative arbitrary self types that could fulfill this call. // FIXME: probe for all types that *could* be arbitrary self-types, not // just this list. - for (rcvr_ty, post) in &[ - (rcvr_ty, ""), - (Ty::new_mut_ref(self.tcx, self.tcx.lifetimes.re_erased, rcvr_ty), "&mut "), - (Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, rcvr_ty), "&"), + for (rcvr_ty, post, pin_call) in &[ + (rcvr_ty, "", None), + ( + Ty::new_mut_ref(self.tcx, self.tcx.lifetimes.re_erased, rcvr_ty), + "&mut ", + Some("as_mut"), + ), + ( + Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, rcvr_ty), + "&", + Some("as_ref"), + ), ] { match self.lookup_probe_for_diagnostic( item_name, @@ -2531,6 +2539,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Err(_) => (), } + let pred = ty::TraitRef::new( + self.tcx, + self.tcx.lang_items().unpin_trait().unwrap(), + [*rcvr_ty], + ); + let unpin = self.predicate_must_hold_considering_regions(&Obligation::new( + self.tcx, + ObligationCause::misc(rcvr.span, self.body_id), + self.param_env, + pred, + )); for (rcvr_ty, pre) in &[ (Ty::new_lang_item(self.tcx, *rcvr_ty, LangItem::OwnedBox), "Box::new"), (Ty::new_lang_item(self.tcx, *rcvr_ty, LangItem::Pin), "Pin::new"), @@ -2554,7 +2573,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Explicitly ignore the `Pin::as_ref()` method as `Pin` does not // implement the `AsRef` trait. let skip = skippable.contains(&did) - || (("Pin::new" == *pre) && (sym::as_ref == item_name.name)) + || (("Pin::new" == *pre) && ((sym::as_ref == item_name.name) || !unpin)) || inputs_len.is_some_and(|inputs_len| pick.item.kind == ty::AssocKind::Fn && self.tcx.fn_sig(pick.item.def_id).skip_binder().skip_binder().inputs().len() != inputs_len); // Make sure the method is defined for the *actual* receiver: we don't // want to treat `Box` as a receiver if it only works because of @@ -2566,7 +2585,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); err.multipart_suggestion( "consider wrapping the receiver expression with the \ - appropriate type", + appropriate type", vec![ (rcvr.span.shrink_to_lo(), format!("{pre}({post}")), (rcvr.span.shrink_to_hi(), ")".to_string()), @@ -2578,6 +2597,49 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } + // We special case the situation where `Pin::new` wouldn't work, and instead + // suggest using the `pin!()` macro instead. + if let Some(new_rcvr_t) = Ty::new_lang_item(self.tcx, *rcvr_ty, LangItem::Pin) + // We didn't find an alternative receiver for the method. + && !alt_rcvr_sugg + // `T: !Unpin` + && !unpin + // The method isn't `as_ref`, as it would provide a wrong suggestion for `Pin`. + && sym::as_ref != item_name.name + // Either `Pin::as_ref` or `Pin::as_mut`. + && let Some(pin_call) = pin_call + // Search for `item_name` as a method accessible on `Pin`. + && let Ok(pick) = self.lookup_probe_for_diagnostic( + item_name, + new_rcvr_t, + rcvr, + ProbeScope::AllTraits, + return_type, + ) + // We skip some common traits that we don't want to consider because autoderefs + // would take care of them. + && !skippable.contains(&Some(pick.item.container_id(self.tcx))) + // We don't want to go through derefs. + && pick.autoderefs == 0 + // Check that the method of the same name that was found on the new `Pin` + // receiver has the same number of arguments that appear in the user's code. + && inputs_len.is_some_and(|inputs_len| pick.item.kind == ty::AssocKind::Fn && self.tcx.fn_sig(pick.item.def_id).skip_binder().skip_binder().inputs().len() == inputs_len) + { + let indent = self.tcx.sess + .source_map() + .indentation_before(rcvr.span) + .unwrap_or_else(|| " ".to_string()); + err.multipart_suggestion( + "consider pinning the expression", + vec![ + (rcvr.span.shrink_to_lo(), format!("let mut pinned = std::pin::pin!(")), + (rcvr.span.shrink_to_hi(), format!(");\n{indent}pinned.{pin_call}()")), + ], + Applicability::MaybeIncorrect, + ); + // We don't care about the other suggestions. + alt_rcvr_sugg = true; + } } } if self.suggest_valid_traits(err, valid_out_of_scope_traits) { diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 8fc236f46b22..3f9c9b3381ba 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -12,7 +12,6 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::{HirId, Pat, PatKind}; use rustc_infer::infer; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc_middle::middle::stability::EvalResult; use rustc_middle::ty::{self, Adt, BindingMode, Ty, TypeVisitableExt}; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_span::edit_distance::find_best_match_for_name; @@ -1408,6 +1407,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { adt.variant_descr(), &inexistent_fields, &mut unmentioned_fields, + pat, variant, args, )) @@ -1434,15 +1434,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let accessible_unmentioned_fields: Vec<_> = unmentioned_fields .iter() .copied() - .filter(|(field, _)| { - field.vis.is_accessible_from(tcx.parent_module(pat.hir_id), tcx) - && !matches!( - tcx.eval_stability(field.did, None, DUMMY_SP, None), - EvalResult::Deny { .. } - ) - // We only want to report the error if it is hidden and not local - && !(tcx.is_doc_hidden(field.did) && !field.did.is_local()) - }) + .filter(|(field, _)| self.is_field_suggestable(field, pat.hir_id, pat.span)) .collect(); if !has_rest_pat { @@ -1578,12 +1570,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { kind_name: &str, inexistent_fields: &[&hir::PatField<'tcx>], unmentioned_fields: &mut Vec<(&'tcx ty::FieldDef, Ident)>, + pat: &'tcx Pat<'tcx>, variant: &ty::VariantDef, args: &'tcx ty::List>, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let tcx = self.tcx; - let (field_names, t, plural) = if inexistent_fields.len() == 1 { - (format!("a field named `{}`", inexistent_fields[0].ident), "this", "") + let (field_names, t, plural) = if let [field] = inexistent_fields { + (format!("a field named `{}`", field.ident), "this", "") } else { ( format!( @@ -1620,10 +1613,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ), ); - if unmentioned_fields.len() == 1 { - let input = - unmentioned_fields.iter().map(|(_, field)| field.name).collect::>(); - let suggested_name = find_best_match_for_name(&input, pat_field.ident.name, None); + if let [(field_def, field)] = unmentioned_fields.as_slice() + && self.is_field_suggestable(field_def, pat.hir_id, pat.span) + { + let suggested_name = + find_best_match_for_name(&[field.name], pat_field.ident.name, None); if let Some(suggested_name) = suggested_name { err.span_suggestion( pat_field.ident.span, @@ -1646,22 +1640,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { PatKind::Lit(expr) if !self.can_coerce( self.typeck_results.borrow().expr_ty(expr), - self.field_ty( - unmentioned_fields[0].1.span, - unmentioned_fields[0].0, - args, - ), + self.field_ty(field.span, field_def, args), ) => {} _ => { - let unmentioned_field = unmentioned_fields[0].1.name; err.span_suggestion_short( pat_field.ident.span, format!( "`{}` has a field named `{}`", tcx.def_path_str(variant.def_id), - unmentioned_field + field.name, ), - unmentioned_field.to_string(), + field.name, Applicability::MaybeIncorrect, ); } @@ -1871,8 +1860,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fields: &'tcx [hir::PatField<'tcx>], ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let inaccessible = if have_inaccessible_fields { " and inaccessible fields" } else { "" }; - let field_names = if unmentioned_fields.len() == 1 { - format!("field `{}`{}", unmentioned_fields[0].1, inaccessible) + let field_names = if let [(_, field)] = unmentioned_fields { + format!("field `{field}`{inaccessible}") } else { let fields = unmentioned_fields .iter() diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl index 46558997f723..b36fb6a4dbac 100644 --- a/compiler/rustc_infer/messages.ftl +++ b/compiler/rustc_infer/messages.ftl @@ -66,7 +66,6 @@ infer_await_both_futures = consider `await`ing on both `Future`s infer_await_future = consider `await`ing on the `Future` infer_await_note = calling an async function returns a future -infer_borrowed_too_long = a value of type `{$ty}` is borrowed for too long infer_but_calling_introduces = {$has_param_name -> [true] `{$param_name}` *[false] `fn` parameter @@ -181,8 +180,6 @@ infer_more_targeted = {$has_param_name -> } but calling `{$ident}` introduces an implicit `'static` lifetime requirement infer_msl_introduces_static = introduces a `'static` lifetime requirement -infer_msl_trait_note = this has an implicit `'static` lifetime requirement -infer_msl_trait_sugg = consider relaxing the implicit `'static` requirement infer_msl_unmet_req = because this has an unmet lifetime requirement infer_need_type_info_in_generator = type inside {$generator_kind -> @@ -233,7 +230,6 @@ infer_prlf_known_limitation = this is a known limitation that will be removed in infer_prlf_must_outlive_with_sup = ...must outlive the lifetime `{$sup_symbol}` defined here infer_prlf_must_outlive_without_sup = ...must outlive the lifetime defined here infer_reborrow = ...so that reference does not outlive borrowed content -infer_reborrow_upvar = ...so that closure can access `{$name}` infer_ref_longer_than_data = in type `{$ty}`, reference has a longer lifetime than the data it references infer_reference_outlives_referent = ...so that the reference type `{$name}` does not outlive the data it points at diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index ad4525c922b4..3ff1a5c0c14b 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -194,13 +194,13 @@ impl<'a> SourceKindMultiSuggestion<'a> { data: &'a FnRetTy<'a>, should_wrap_expr: Option, ) -> Self { - let (arrow, post) = match data { - FnRetTy::DefaultReturn(_) => ("-> ", " "), - _ => ("", ""), + let arrow = match data { + FnRetTy::DefaultReturn(_) => " -> ", + _ => "", }; let (start_span, start_span_code, end_span) = match should_wrap_expr { - Some(end_span) => (data.span(), format!("{arrow}{ty_info}{post}{{ "), Some(end_span)), - None => (data.span(), format!("{arrow}{ty_info}{post}"), None), + Some(end_span) => (data.span(), format!("{arrow}{ty_info} {{"), Some(end_span)), + None => (data.span(), format!("{arrow}{ty_info}"), None), }; Self::ClosureReturn { start_span, start_span_code, end_span } } diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs index fefa8959545a..2d6b88226adb 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -44,7 +44,7 @@ pub fn extract_verify_if_eq<'tcx>( test_ty: Ty<'tcx>, ) -> Option> { assert!(!verify_if_eq_b.has_escaping_bound_vars()); - let mut m = Match::new(tcx, param_env); + let mut m = MatchAgainstHigherRankedOutlives::new(tcx, param_env); let verify_if_eq = verify_if_eq_b.skip_binder(); m.relate(verify_if_eq.ty, test_ty).ok()?; @@ -87,24 +87,32 @@ pub(super) fn can_match_erased_ty<'tcx>( // pointless micro-optimization true } else { - Match::new(tcx, param_env).relate(outlives_ty, erased_ty).is_ok() + MatchAgainstHigherRankedOutlives::new(tcx, param_env).relate(outlives_ty, erased_ty).is_ok() } } -struct Match<'tcx> { +struct MatchAgainstHigherRankedOutlives<'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, pattern_depth: ty::DebruijnIndex, map: FxHashMap>, } -impl<'tcx> Match<'tcx> { - fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Match<'tcx> { - Match { tcx, param_env, pattern_depth: ty::INNERMOST, map: FxHashMap::default() } +impl<'tcx> MatchAgainstHigherRankedOutlives<'tcx> { + fn new( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ) -> MatchAgainstHigherRankedOutlives<'tcx> { + MatchAgainstHigherRankedOutlives { + tcx, + param_env, + pattern_depth: ty::INNERMOST, + map: FxHashMap::default(), + } } } -impl<'tcx> Match<'tcx> { +impl<'tcx> MatchAgainstHigherRankedOutlives<'tcx> { /// Creates the "Error" variant that signals "no match". fn no_match(&self) -> RelateResult<'tcx, T> { Err(TypeError::Mismatch) @@ -134,7 +142,7 @@ impl<'tcx> Match<'tcx> { } } -impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { +impl<'tcx> TypeRelation<'tcx> for MatchAgainstHigherRankedOutlives<'tcx> { fn tag(&self) -> &'static str { "Match" } diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 7377c6e2f35a..fa4b8e4c36b8 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -5,6 +5,10 @@ lint_array_into_iter = .use_explicit_into_iter_suggestion = or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value +lint_async_fn_in_trait = use of `async fn` in public traits is discouraged as auto trait bounds cannot be specified + .note = you can suppress this lint if you plan to use the trait only in your own code, or do not care about auto traits like `Send` on the `Future` + .suggestion = you can alternatively desugar to a normal `fn` that returns `impl Future` and add any desired bounds such as `Send` + lint_atomic_ordering_fence = memory fences cannot have `Relaxed` ordering .help = consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst` @@ -319,6 +323,8 @@ lint_invalid_reference_casting_borrow_as_mut = casting `&T` to `&mut T` is undef lint_invalid_reference_casting_note_book = for more information, visit +lint_invalid_reference_casting_note_ty_has_interior_mutability = even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get` + lint_lintpass_by_hand = implementing `LintPass` by hand .help = try using `declare_lint_pass!` or `impl_lint_pass!` instead diff --git a/compiler/rustc_lint/src/async_fn_in_trait.rs b/compiler/rustc_lint/src/async_fn_in_trait.rs new file mode 100644 index 000000000000..ff4c81e2fc9b --- /dev/null +++ b/compiler/rustc_lint/src/async_fn_in_trait.rs @@ -0,0 +1,128 @@ +use crate::lints::AsyncFnInTraitDiag; +use crate::LateContext; +use crate::LateLintPass; +use rustc_hir as hir; +use rustc_trait_selection::traits::error_reporting::suggestions::suggest_desugaring_async_fn_to_impl_future_in_trait; + +declare_lint! { + /// The `async_fn_in_trait` lint detects use of `async fn` in the + /// definition of a publicly-reachable trait. + /// + /// ### Example + /// + /// ```rust + /// # #![feature(async_fn_in_trait)] + /// pub trait Trait { + /// async fn method(&self); + /// } + /// # fn main() {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// When `async fn` is used in a trait definition, the trait does not + /// promise that the opaque [`Future`] returned by the associated function + /// or method will implement any [auto traits] such as [`Send`]. This may + /// be surprising and may make the associated functions or methods on the + /// trait less useful than intended. On traits exposed publicly from a + /// crate, this may affect downstream crates whose authors cannot alter + /// the trait definition. + /// + /// For example, this code is invalid: + /// + /// ```rust,compile_fail + /// # #![feature(async_fn_in_trait)] + /// pub trait Trait { + /// async fn method(&self) {} + /// } + /// + /// fn test(x: T) { + /// fn spawn(_: T) {} + /// spawn(x.method()); // Not OK. + /// } + /// ``` + /// + /// This lint exists to warn authors of publicly-reachable traits that + /// they may want to consider desugaring the `async fn` to a normal `fn` + /// that returns an opaque `impl Future<..> + Send` type. + /// + /// For example, instead of: + /// + /// ```rust + /// # #![feature(async_fn_in_trait)] + /// pub trait Trait { + /// async fn method(&self) {} + /// } + /// ``` + /// + /// The author of the trait may want to write: + /// + /// + /// ```rust + /// # #![feature(return_position_impl_trait_in_trait)] + /// use core::future::Future; + /// pub trait Trait { + /// fn method(&self) -> impl Future + Send { async {} } + /// } + /// ``` + /// + /// This still allows the use of `async fn` within impls of the trait. + /// However, it also means that the trait will never be compatible with + /// impls where the returned [`Future`] of the method does not implement + /// `Send`. + /// + /// Conversely, if the trait is used only locally, if it is never used in + /// generic functions, or if it is only used in single-threaded contexts + /// that do not care whether the returned [`Future`] implements [`Send`], + /// then the lint may be suppressed. + /// + /// [`Future`]: https://doc.rust-lang.org/core/future/trait.Future.html + /// [`Send`]: https://doc.rust-lang.org/core/marker/trait.Send.html + /// [auto traits]: https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits + pub ASYNC_FN_IN_TRAIT, + Warn, + "use of `async fn` in definition of a publicly-reachable trait" +} + +declare_lint_pass!( + /// Lint for use of `async fn` in the definition of a publicly-reachable + /// trait. + AsyncFnInTrait => [ASYNC_FN_IN_TRAIT] +); + +impl<'tcx> LateLintPass<'tcx> for AsyncFnInTrait { + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'tcx>) { + if let hir::TraitItemKind::Fn(sig, body) = item.kind + && let hir::IsAsync::Async(async_span) = sig.header.asyncness + { + // RTN can be used to bound `async fn` in traits in a better way than "always" + if cx.tcx.features().return_type_notation { + return; + } + + // Only need to think about library implications of reachable traits + if !cx.tcx.effective_visibilities(()).is_reachable(item.owner_id.def_id) { + return; + } + + let hir::FnRetTy::Return(hir::Ty { kind: hir::TyKind::OpaqueDef(def, ..), .. }) = + sig.decl.output + else { + // This should never happen, but let's not ICE. + return; + }; + let sugg = suggest_desugaring_async_fn_to_impl_future_in_trait( + cx.tcx, + sig, + body, + def.owner_id.def_id, + " + Send", + ); + cx.tcx.emit_spanned_lint(ASYNC_FN_IN_TRAIT, item.hir_id(), async_span, AsyncFnInTraitDiag { + sugg + }); + } + } +} diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index 7b291d558e03..e1df69bdaf25 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -5,19 +5,18 @@ use rustc_hir::def::DefKind; use rustc_middle::query::Providers; use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; -use rustc_session::lint::{lint_array, LintArray}; use rustc_span::{sym, Span, Symbol}; use rustc_target::abi::FIRST_VARIANT; use crate::lints::{BuiltinClashingExtern, BuiltinClashingExternSub}; -use crate::types; +use crate::{types, LintVec}; pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { clashing_extern_declarations, ..*providers }; } -pub(crate) fn get_lints() -> LintArray { - lint_array!(CLASHING_EXTERN_DECLARATIONS) +pub(crate) fn get_lints() -> LintVec { + vec![CLASHING_EXTERN_DECLARATIONS] } fn clashing_extern_declarations(tcx: TyCtxt<'_>, (): ()) { diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 0f7d58fe68a4..af2132fb8997 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -50,6 +50,7 @@ extern crate rustc_session; extern crate tracing; mod array_into_iter; +mod async_fn_in_trait; pub mod builtin; mod context; mod deref_into_dyn_supertrait; @@ -96,6 +97,7 @@ use rustc_session::lint::builtin::{ }; use array_into_iter::ArrayIntoIter; +use async_fn_in_trait::AsyncFnInTrait; use builtin::*; use deref_into_dyn_supertrait::*; use drop_forget_useless::*; @@ -130,7 +132,7 @@ pub use late::{check_crate, late_lint_mod, unerased_lint_store}; pub use passes::{EarlyLintPass, LateLintPass}; pub use rustc_session::lint::Level::{self, *}; pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Lint, LintId}; -pub use rustc_session::lint::{LintArray, LintPass}; +pub use rustc_session::lint::{LintPass, LintVec}; fluent_messages! { "../messages.ftl" } @@ -234,6 +236,7 @@ late_lint_methods!( MapUnitFn: MapUnitFn, MissingDebugImplementations: MissingDebugImplementations, MissingDoc: MissingDoc, + AsyncFnInTrait: AsyncFnInTrait, ] ] ); diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index c091c260a470..c776d3bb7fed 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -771,12 +771,16 @@ pub enum InvalidReferenceCastingDiag { BorrowAsMut { #[label] orig_cast: Option, + #[note(lint_invalid_reference_casting_note_ty_has_interior_mutability)] + ty_has_interior_mutability: Option<()>, }, #[diag(lint_invalid_reference_casting_assign_to_ref)] #[note(lint_invalid_reference_casting_note_book)] AssignToRef { #[label] orig_cast: Option, + #[note(lint_invalid_reference_casting_note_ty_has_interior_mutability)] + ty_has_interior_mutability: Option<()>, }, } @@ -1818,3 +1822,24 @@ pub struct UnusedAllocationDiag; #[derive(LintDiagnostic)] #[diag(lint_unused_allocation_mut)] pub struct UnusedAllocationMutDiag; + +pub struct AsyncFnInTraitDiag { + pub sugg: Option>, +} + +impl<'a> DecorateLint<'a, ()> for AsyncFnInTraitDiag { + fn decorate_lint<'b>( + self, + diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, + ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { + diag.note(fluent::lint_note); + if let Some(sugg) = self.sugg { + diag.multipart_suggestion(fluent::lint_suggestion, sugg, Applicability::MaybeIncorrect); + } + diag + } + + fn msg(&self) -> rustc_errors::DiagnosticMessage { + fluent::lint_async_fn_in_trait + } +} diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs index bc0b9d6d8187..cfbca6efbfa5 100644 --- a/compiler/rustc_lint/src/noop_method_call.rs +++ b/compiler/rustc_lint/src/noop_method_call.rs @@ -98,6 +98,12 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, cx.param_env, did, args) else { return }; // (Re)check that it implements the noop diagnostic. let Some(name) = cx.tcx.get_diagnostic_name(i.def_id()) else { return }; + if !matches!( + name, + sym::noop_method_borrow | sym::noop_method_clone | sym::noop_method_deref + ) { + return; + } let receiver_ty = cx.typeck_results().expr_ty(receiver); let expr_ty = cx.typeck_results().expr_ty_adjusted(expr); diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 79b0b32bef24..c24846ca9398 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -37,8 +37,6 @@ declare_lint! { /// type Assoc: Duh; /// } /// - /// struct Struct; - /// /// impl Trait for F { /// type Assoc = F; /// } @@ -53,12 +51,12 @@ declare_lint! { /// {{produces}} /// /// In this example, `test` declares that the associated type `Assoc` for - /// `impl Trait` is `impl Sized`, which does not satisfy the `Send` bound + /// `impl Trait` is `impl Sized`, which does not satisfy the bound `Duh` /// on the associated type. /// /// Although the hidden type, `i32` does satisfy this bound, we do not /// consider the return type to be well-formed with this lint. It can be - /// fixed by changing `Tait = impl Sized` into `Tait = impl Sized + Send`. + /// fixed by changing `Tait = impl Sized` into `Tait = impl Sized + Duh`. pub OPAQUE_HIDDEN_INFERRED_BOUND, Warn, "detects the use of nested `impl Trait` types in associated type bounds that are not general enough" @@ -79,9 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { for (pred, pred_span) in cx.tcx.explicit_item_bounds(def_id).instantiate_identity_iter_copied() { - // Liberate bound regions in the predicate since we - // don't actually care about lifetimes in this check. - let predicate = cx.tcx.liberate_late_bound_regions(def_id, pred.kind()); + let predicate = infcx.instantiate_binder_with_placeholders(pred.kind()); let ty::ClauseKind::Projection(proj) = predicate else { continue; }; diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index 7d2a91026404..508f3e1ec310 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -111,7 +111,7 @@ macro_rules! declare_combined_late_lint_pass { } } - $v fn get_lints() -> $crate::LintArray { + $v fn get_lints() -> $crate::LintVec { let mut lints = Vec::new(); $(lints.extend_from_slice(&$pass::get_lints());)* lints @@ -226,7 +226,7 @@ macro_rules! declare_combined_early_lint_pass { } } - $v fn get_lints() -> $crate::LintArray { + $v fn get_lints() -> $crate::LintVec { let mut lints = Vec::new(); $(lints.extend_from_slice(&$pass::get_lints());)* lints diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index 39def599be8d..0c52fbaf78ca 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -43,19 +43,19 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting { let init = cx.expr_or_init(e); - let orig_cast = if is_cast_from_const_to_mut(cx, init) { - if init.span != e.span { Some(init.span) } else { None } - } else { + let Some(ty_has_interior_mutability) = is_cast_from_const_to_mut(cx, init) else { return; }; + let orig_cast = if init.span != e.span { Some(init.span) } else { None }; + let ty_has_interior_mutability = ty_has_interior_mutability.then_some(()); cx.emit_spanned_lint( INVALID_REFERENCE_CASTING, expr.span, if is_assignment { - InvalidReferenceCastingDiag::AssignToRef { orig_cast } + InvalidReferenceCastingDiag::AssignToRef { orig_cast, ty_has_interior_mutability } } else { - InvalidReferenceCastingDiag::BorrowAsMut { orig_cast } + InvalidReferenceCastingDiag::BorrowAsMut { orig_cast, ty_has_interior_mutability } }, ); } @@ -104,7 +104,10 @@ fn is_operation_we_care_about<'tcx>( deref_assign_or_addr_of(e).or_else(|| ptr_write(cx, e)) } -fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, orig_expr: &'tcx Expr<'tcx>) -> bool { +fn is_cast_from_const_to_mut<'tcx>( + cx: &LateContext<'tcx>, + orig_expr: &'tcx Expr<'tcx>, +) -> Option { let mut need_check_freeze = false; let mut e = orig_expr; @@ -112,7 +115,7 @@ fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, orig_expr: &'tcx Expr // Bail out early if the end type is **not** a mutable pointer. if !matches!(end_ty.kind(), ty::RawPtr(TypeAndMut { ty: _, mutbl: Mutability::Mut })) { - return false; + return None; } loop { @@ -155,10 +158,11 @@ fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, orig_expr: &'tcx Expr // // We also consider non concrete skeleton types (ie generics) // to be an issue since there is no way to make it safe for abitrary types. - !need_check_freeze - || inner_ty.is_freeze(cx.tcx, cx.param_env) - || !inner_ty.has_concrete_skeleton() + let inner_ty_has_interior_mutability = + !inner_ty.is_freeze(cx.tcx, cx.param_env) && inner_ty.has_concrete_skeleton(); + (!need_check_freeze || !inner_ty_has_interior_mutability) + .then_some(inner_ty_has_interior_mutability) } else { - false + None } } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 84e7ecb0b881..7ba589c3b5a3 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -785,16 +785,7 @@ macro_rules! declare_tool_lint { ); } -/// Declares a static `LintArray` and return it as an expression. -#[macro_export] -macro_rules! lint_array { - ($( $lint:expr ),* ,) => { lint_array!( $($lint),* ) }; - ($( $lint:expr ),*) => {{ - vec![$($lint),*] - }} -} - -pub type LintArray = Vec<&'static Lint>; +pub type LintVec = Vec<&'static Lint>; pub trait LintPass { fn name(&self) -> &'static str; @@ -808,7 +799,7 @@ macro_rules! impl_lint_pass { fn name(&self) -> &'static str { stringify!($ty) } } impl $ty { - pub fn get_lints() -> $crate::LintArray { $crate::lint_array!($($lint),*) } + pub fn get_lints() -> $crate::LintVec { vec![$($lint),*] } } }; } diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index 34556df3c6d7..3880f25a9ba9 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -3,10 +3,6 @@ name = "rustc_llvm" version = "0.0.0" edition = "2021" -[features] -static-libstdcpp = [] -emscripten = [] - [dependencies] libc = "0.2.73" diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs index e7b80c64184b..3e43bcb3b8f6 100644 --- a/compiler/rustc_log/src/lib.rs +++ b/compiler/rustc_log/src/lib.rs @@ -23,10 +23,10 @@ //! } //! ``` //! -//! Now `LOG=debug cargo run` will run your minimal main.rs and show +//! Now `LOG=debug cargo +nightly run` will run your minimal main.rs and show //! rustc's debug logging. In a workflow like this, one might also add //! `std::env::set_var("LOG", "debug")` to the top of main so that `cargo -//! run` by itself is sufficient to get logs. +//! +nightly run` by itself is sufficient to get logs. //! //! The reason rustc_log is a tiny separate crate, as opposed to exposing the //! same things in rustc_driver only, is to enable the above workflow. If you diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 952c796f52e7..1d573a746b91 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -8,7 +8,7 @@ macro_rules! arena_types { ($macro:path) => ( $macro!([ - [] layout: rustc_target::abi::LayoutS, + [] layout: rustc_target::abi::LayoutS, [] fn_abi: rustc_target::abi::call::FnAbi<'tcx, rustc_middle::ty::Ty<'tcx>>, // AdtDef are interned and compared by address [decode] adt_def: rustc_middle::ty::AdtDefData, diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index cd770c395e4d..3ecd5b9cd345 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -63,11 +63,14 @@ impl<'tcx> BasicBlocks<'tcx> { } /// Returns basic blocks in a reverse postorder. + /// + /// See [`traversal::reverse_postorder`]'s docs to learn what is preorder traversal. + /// + /// [`traversal::reverse_postorder`]: crate::mir::traversal::reverse_postorder #[inline] pub fn reverse_postorder(&self) -> &[BasicBlock] { self.cache.reverse_postorder.get_or_init(|| { - let mut rpo: Vec<_> = - Postorder::new(&self.basic_blocks, START_BLOCK).map(|(bb, _)| bb).collect(); + let mut rpo: Vec<_> = Postorder::new(&self.basic_blocks, START_BLOCK).collect(); rpo.reverse(); rpo }) diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index 7c8a57b840b7..8f63ed757bad 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -288,7 +288,16 @@ impl<'tcx> Const<'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Option { - self.try_eval_scalar(tcx, param_env)?.try_to_int().ok() + match self { + // If the constant is already evaluated, we shortcut here. + Const::Ty(c) if let ty::ConstKind::Value(valtree) = c.kind() => { + valtree.try_to_scalar_int() + }, + // This is a more general form of the previous case. + _ => { + self.try_eval_scalar(tcx, param_env)?.try_to_int().ok() + }, + } } #[inline] diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index 9ef673922911..a6d6f6f5df4b 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -18,11 +18,6 @@ rustc_index::newtype_index! { impl CounterId { pub const START: Self = Self::from_u32(0); - - #[inline(always)] - pub fn next_id(self) -> Self { - Self::from_u32(self.as_u32() + 1) - } } rustc_index::newtype_index! { @@ -38,11 +33,6 @@ rustc_index::newtype_index! { impl ExpressionId { pub const START: Self = Self::from_u32(0); - - #[inline(always)] - pub fn next_id(self) -> Self { - Self::from_u32(self.as_u32() + 1) - } } /// Operand of a coverage-counter expression. diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 0bb1c66da0cb..7534c9c0a685 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -830,22 +830,6 @@ pub struct LocalDecl<'tcx> { // FIXME(matthewjasper) Don't store in this in `Body` pub local_info: ClearCrossCrate>>, - /// `true` if this is an internal local. - /// - /// These locals are not based on types in the source code and are only used - /// for a few desugarings at the moment. - /// - /// The generator transformation will sanity check the locals which are live - /// across a suspension point against the type components of the generator - /// which type checking knows are live across a suspension point. We need to - /// flag drop flags to avoid triggering this check as they are introduced - /// outside of type inference. - /// - /// This should be sound because the drop flags are fully algebraic, and - /// therefore don't affect the auto-trait or outlives properties of the - /// generator. - pub internal: bool, - /// The type of this local. pub ty: Ty<'tcx>, @@ -1058,7 +1042,7 @@ impl<'tcx> LocalDecl<'tcx> { self.source_info.span.desugaring_kind().is_some() } - /// Creates a new `LocalDecl` for a temporary: mutable, non-internal. + /// Creates a new `LocalDecl` for a temporary, mutable. #[inline] pub fn new(ty: Ty<'tcx>, span: Span) -> Self { Self::with_source_info(ty, SourceInfo::outermost(span)) @@ -1070,20 +1054,12 @@ impl<'tcx> LocalDecl<'tcx> { LocalDecl { mutability: Mutability::Mut, local_info: ClearCrossCrate::Set(Box::new(LocalInfo::Boring)), - internal: false, ty, user_ty: None, source_info, } } - /// Converts `self` into same `LocalDecl` except tagged as internal. - #[inline] - pub fn internal(mut self) -> Self { - self.internal = true; - self - } - /// Converts `self` into same `LocalDecl` except tagged as immutable. #[inline] pub fn immutable(mut self) -> Self { diff --git a/compiler/rustc_middle/src/mir/patch.rs b/compiler/rustc_middle/src/mir/patch.rs index da486c3465a6..ce2ddec01161 100644 --- a/compiler/rustc_middle/src/mir/patch.rs +++ b/compiler/rustc_middle/src/mir/patch.rs @@ -127,7 +127,7 @@ impl<'tcx> MirPatch<'tcx> { Location { block: bb, statement_index: offset } } - pub fn new_internal_with_info( + pub fn new_local_with_info( &mut self, ty: Ty<'tcx>, span: Span, @@ -135,7 +135,7 @@ impl<'tcx> MirPatch<'tcx> { ) -> Local { let index = self.next_local; self.next_local += 1; - let mut new_decl = LocalDecl::new(ty, span).internal(); + let mut new_decl = LocalDecl::new(ty, span); **new_decl.local_info.as_mut().assert_crate_local() = local_info; self.new_locals.push(new_decl); Local::new(index) @@ -148,13 +148,6 @@ impl<'tcx> MirPatch<'tcx> { Local::new(index) } - pub fn new_internal(&mut self, ty: Ty<'tcx>, span: Span) -> Local { - let index = self.next_local; - self.next_local += 1; - self.new_locals.push(LocalDecl::new(ty, span).internal()); - Local::new(index) - } - pub fn new_block(&mut self, data: BasicBlockData<'tcx>) -> BasicBlock { let block = BasicBlock::new(self.patch_map.len()); debug!("MirPatch: new_block: {:?}: {:?}", block, data); diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 76567c3f6b0a..c5e3ee575e1a 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -16,7 +16,7 @@ use rustc_middle::mir::interpret::{ Pointer, Provenance, }; use rustc_middle::mir::visit::Visitor; -use rustc_middle::mir::*; +use rustc_middle::mir::{self, *}; use rustc_middle::ty::{self, TyCtxt}; use rustc_target::abi::Size; @@ -685,10 +685,13 @@ impl Debug for Statement<'_> { AscribeUserType(box (ref place, ref c_ty), ref variance) => { write!(fmt, "AscribeUserType({place:?}, {variance:?}, {c_ty:?})") } - Coverage(box self::Coverage { ref kind, code_region: Some(ref rgn) }) => { - write!(fmt, "Coverage::{kind:?} for {rgn:?}") + Coverage(box mir::Coverage { ref kind, ref code_regions }) => { + if code_regions.is_empty() { + write!(fmt, "Coverage::{kind:?}") + } else { + write!(fmt, "Coverage::{kind:?} for {code_regions:?}") + } } - Coverage(box ref coverage) => write!(fmt, "Coverage::{:?}", coverage.kind), Intrinsic(box ref intrinsic) => write!(fmt, "{intrinsic}"), ConstEvalCounter => write!(fmt, "ConstEvalCounter"), Nop => write!(fmt, "nop"), @@ -1103,6 +1106,7 @@ fn pre_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) -> for &elem in projection.iter().rev() { match elem { ProjectionElem::OpaqueCast(_) + | ProjectionElem::Subtype(_) | ProjectionElem::Downcast(_, _) | ProjectionElem::Field(_, _) => { write!(fmt, "(").unwrap(); @@ -1125,6 +1129,9 @@ fn post_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) -> ProjectionElem::OpaqueCast(ty) => { write!(fmt, " as {ty})")?; } + ProjectionElem::Subtype(ty) => { + write!(fmt, " as subtype {ty})")?; + } ProjectionElem::Downcast(Some(name), _index) => { write!(fmt, " as {name})")?; } diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 5ac108bc8290..5864acaed7b2 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -57,6 +57,7 @@ impl ProjectionElem { Self::Field(_, _) | Self::Index(_) | Self::OpaqueCast(_) + | Self::Subtype(_) | Self::ConstantIndex { .. } | Self::Subslice { .. } | Self::Downcast(_, _) => false, @@ -70,6 +71,7 @@ impl ProjectionElem { Self::Deref | Self::Index(_) => false, Self::Field(_, _) | Self::OpaqueCast(_) + | Self::Subtype(_) | Self::ConstantIndex { .. } | Self::Subslice { .. } | Self::Downcast(_, _) => true, @@ -95,6 +97,7 @@ impl ProjectionElem { | Self::Field(_, _) => true, Self::ConstantIndex { from_end: true, .. } | Self::Index(_) + | Self::Subtype(_) | Self::OpaqueCast(_) | Self::Subslice { .. } => false, } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 201926fee3e0..30fc69caa3bd 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -139,6 +139,7 @@ pub enum RuntimePhase { /// * [`TerminatorKind::Yield`] /// * [`TerminatorKind::GeneratorDrop`] /// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array` + /// * [`PlaceElem::OpaqueCast`] /// /// And the following variants are allowed: /// * [`StatementKind::Retag`] @@ -513,7 +514,7 @@ pub enum FakeReadCause { #[derive(TypeFoldable, TypeVisitable)] pub struct Coverage { pub kind: CoverageKind, - pub code_region: Option, + pub code_regions: Vec, } #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)] @@ -995,7 +996,7 @@ pub type AssertMessage<'tcx> = AssertKind>; /// /// [UCG#319]: https://github.com/rust-lang/unsafe-code-guidelines/issues/319 /// -/// Rust currently requires that every place obey those two rules. This is checked by MIRI and taken +/// Rust currently requires that every place obey those two rules. This is checked by Miri and taken /// advantage of by codegen (via `gep inbounds`). That is possibly subject to change. #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, HashStable, TypeFoldable, TypeVisitable)] pub struct Place<'tcx> { @@ -1074,6 +1075,18 @@ pub enum ProjectionElem { /// Like an explicit cast from an opaque type to a concrete type, but without /// requiring an intermediate variable. OpaqueCast(T), + + /// A `Subtype(T)` projection is applied to any `StatementKind::Assign` where + /// type of lvalue doesn't match the type of rvalue, the primary goal is making subtyping + /// explicit during optimizations and codegen. + /// + /// This projection doesn't impact the runtime behavior of the program except for potentially changing + /// some type metadata of the interpreter or codegen backend. + /// + /// This goal is achieved with mir_transform pass `Subtyper`, which runs right after + /// borrowchecker, as we only care about subtyping that can affect trait selection and + /// `TypeId`. + Subtype(T), } /// Alias for projections as they appear in places, where the base is a place diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 01c04f638905..44ae75e2de70 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -69,7 +69,7 @@ impl<'tcx> PlaceTy<'tcx> { param_env: ty::ParamEnv<'tcx>, elem: &ProjectionElem, mut handle_field: impl FnMut(&Self, FieldIdx, T) -> Ty<'tcx>, - mut handle_opaque_cast: impl FnMut(&Self, T) -> Ty<'tcx>, + mut handle_opaque_cast_and_subtype: impl FnMut(&Self, T) -> Ty<'tcx>, ) -> PlaceTy<'tcx> where V: ::std::fmt::Debug, @@ -110,7 +110,12 @@ impl<'tcx> PlaceTy<'tcx> { PlaceTy { ty: self.ty, variant_index: Some(index) } } ProjectionElem::Field(f, fty) => PlaceTy::from_ty(handle_field(&self, f, fty)), - ProjectionElem::OpaqueCast(ty) => PlaceTy::from_ty(handle_opaque_cast(&self, ty)), + ProjectionElem::OpaqueCast(ty) => { + PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty)) + } + ProjectionElem::Subtype(ty) => { + PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty)) + } }; debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer); answer diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index ec16a8470c41..a1ff8410eac4 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -41,6 +41,12 @@ impl<'a, 'tcx> Preorder<'a, 'tcx> { } } +/// Preorder traversal of a graph. +/// +/// This function creates an iterator over the `Body`'s basic blocks, that +/// returns basic blocks in a preorder. +/// +/// See [`Preorder`]'s docs to learn what is preorder traversal. pub fn preorder<'a, 'tcx>(body: &'a Body<'tcx>) -> Preorder<'a, 'tcx> { Preorder::new(body, START_BLOCK) } @@ -178,7 +184,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> { // When we yield `C` and call `traverse_successor`, we push `B` to the stack, but // since we've already visited `E`, that child isn't added to the stack. The last // two iterations yield `B` and finally `A` for a final traversal of [E, D, C, B, A] - while let Some(&mut (_, ref mut iter)) = self.visit_stack.last_mut() && let Some(bb) = iter.next_back() { + while let Some(bb) = self.visit_stack.last_mut().and_then(|(_, iter)| iter.next_back()) { if self.visited.insert(bb) { if let Some(term) = &self.basic_blocks[bb].terminator { self.visit_stack.push((bb, term.successors())); @@ -188,16 +194,14 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> { } } -impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> { - type Item = (BasicBlock, &'a BasicBlockData<'tcx>); +impl<'tcx> Iterator for Postorder<'_, 'tcx> { + type Item = BasicBlock; - fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> { - let next = self.visit_stack.pop(); - if next.is_some() { - self.traverse_successor(); - } + fn next(&mut self) -> Option { + let (bb, _) = self.visit_stack.pop()?; + self.traverse_successor(); - next.map(|(bb, _)| (bb, &self.basic_blocks[bb])) + Some(bb) } fn size_hint(&self) -> (usize, Option) { @@ -215,10 +219,14 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> { } } -/// Creates an iterator over the `Body`'s basic blocks, that: +/// Postorder traversal of a graph. +/// +/// This function creates an iterator over the `Body`'s basic blocks, that: /// - returns basic blocks in a postorder, /// - traverses the `BasicBlocks` CFG cache's reverse postorder backwards, and does not cache the /// postorder itself. +/// +/// See [`Postorder`]'s docs to learn what is postorder traversal. pub fn postorder<'a, 'tcx>( body: &'a Body<'tcx>, ) -> impl Iterator)> + ExactSizeIterator + DoubleEndedIterator @@ -226,7 +234,28 @@ pub fn postorder<'a, 'tcx>( reverse_postorder(body).rev() } -/// Reverse postorder traversal of a graph +/// Returns an iterator over all basic blocks reachable from the `START_BLOCK` in no particular +/// order. +/// +/// This is clearer than writing `preorder` in cases where the order doesn't matter. +pub fn reachable<'a, 'tcx>( + body: &'a Body<'tcx>, +) -> impl 'a + Iterator)> { + preorder(body) +} + +/// Returns a `BitSet` containing all basic blocks reachable from the `START_BLOCK`. +pub fn reachable_as_bitset(body: &Body<'_>) -> BitSet { + let mut iter = preorder(body); + iter.by_ref().for_each(drop); + iter.visited +} + +/// Reverse postorder traversal of a graph. +/// +/// This function creates an iterator over the `Body`'s basic blocks, that: +/// - returns basic blocks in a reverse postorder, +/// - makes use of the `BasicBlocks` CFG cache's reverse postorder. /// /// Reverse postorder is the reverse order of a postorder traversal. /// This is different to a preorder traversal and represents a natural @@ -246,65 +275,6 @@ pub fn postorder<'a, 'tcx>( /// A reverse postorder traversal of this graph is either `A B C D` or `A C B D` /// Note that for a graph containing no loops (i.e., A DAG), this is equivalent to /// a topological sort. -/// -/// Construction of a `ReversePostorder` traversal requires doing a full -/// postorder traversal of the graph, therefore this traversal should be -/// constructed as few times as possible. Use the `reset` method to be able -/// to re-use the traversal -#[derive(Clone)] -pub struct ReversePostorder<'a, 'tcx> { - body: &'a Body<'tcx>, - blocks: Vec, - idx: usize, -} - -impl<'a, 'tcx> ReversePostorder<'a, 'tcx> { - pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> ReversePostorder<'a, 'tcx> { - let blocks: Vec<_> = Postorder::new(&body.basic_blocks, root).map(|(bb, _)| bb).collect(); - let len = blocks.len(); - ReversePostorder { body, blocks, idx: len } - } -} - -impl<'a, 'tcx> Iterator for ReversePostorder<'a, 'tcx> { - type Item = (BasicBlock, &'a BasicBlockData<'tcx>); - - fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> { - if self.idx == 0 { - return None; - } - self.idx -= 1; - - self.blocks.get(self.idx).map(|&bb| (bb, &self.body[bb])) - } - - fn size_hint(&self) -> (usize, Option) { - (self.idx, Some(self.idx)) - } -} - -impl<'a, 'tcx> ExactSizeIterator for ReversePostorder<'a, 'tcx> {} - -/// Returns an iterator over all basic blocks reachable from the `START_BLOCK` in no particular -/// order. -/// -/// This is clearer than writing `preorder` in cases where the order doesn't matter. -pub fn reachable<'a, 'tcx>( - body: &'a Body<'tcx>, -) -> impl 'a + Iterator)> { - preorder(body) -} - -/// Returns a `BitSet` containing all basic blocks reachable from the `START_BLOCK`. -pub fn reachable_as_bitset(body: &Body<'_>) -> BitSet { - let mut iter = preorder(body); - (&mut iter).for_each(drop); - iter.visited -} - -/// Creates an iterator over the `Body`'s basic blocks, that: -/// - returns basic blocks in a reverse postorder, -/// - makes use of the `BasicBlocks` CFG cache's reverse postorder. pub fn reverse_postorder<'a, 'tcx>( body: &'a Body<'tcx>, ) -> impl Iterator)> + ExactSizeIterator + DoubleEndedIterator diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 51ec6da1ac8e..9bd682d37ab1 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -815,7 +815,6 @@ macro_rules! make_mir_visitor { ty, user_ty, source_info, - internal: _, local_info: _, } = local_decl; @@ -1109,6 +1108,11 @@ macro_rules! visit_place_fns { self.visit_ty(&mut new_ty, TyContext::Location(location)); if ty != new_ty { Some(PlaceElem::OpaqueCast(new_ty)) } else { None } } + PlaceElem::Subtype(ty) => { + let mut new_ty = ty; + self.visit_ty(&mut new_ty, TyContext::Location(location)); + if ty != new_ty { Some(PlaceElem::Subtype(new_ty)) } else { None } + } PlaceElem::Deref | PlaceElem::ConstantIndex { .. } | PlaceElem::Subslice { .. } @@ -1175,7 +1179,9 @@ macro_rules! visit_place_fns { location: Location, ) { match elem { - ProjectionElem::OpaqueCast(ty) | ProjectionElem::Field(_, ty) => { + ProjectionElem::OpaqueCast(ty) + | ProjectionElem::Subtype(ty) + | ProjectionElem::Field(_, ty) => { self.visit_ty(ty, TyContext::Location(location)); } ProjectionElem::Index(local) => { diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index 09517200b0dd..85181720d17e 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -18,20 +18,20 @@ use crate::ty::{self, InferConst, Ty, TyCtxt}; /// Like subtyping, matching is really a binary relation, so the only /// important thing about the result is Ok/Err. Also, matching never /// affects any type variables or unification state. -pub struct Match<'tcx> { +pub struct MatchAgainstFreshVars<'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, } -impl<'tcx> Match<'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Match<'tcx> { - Match { tcx, param_env } +impl<'tcx> MatchAgainstFreshVars<'tcx> { + pub fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> MatchAgainstFreshVars<'tcx> { + MatchAgainstFreshVars { tcx, param_env } } } -impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { +impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> { fn tag(&self) -> &'static str { - "Match" + "MatchAgainstFreshVars" } fn tcx(&self) -> TyCtxt<'tcx> { self.tcx diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index dff7ff8c66bf..e4069e11df27 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -348,9 +348,10 @@ impl<'tcx, D: TyDecoder>> Decodable for ty::Const<'tcx> { impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for [ty::ValTree<'tcx>] { fn decode(decoder: &mut D) -> &'tcx Self { - decoder.interner().arena.alloc_from_iter( - (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::>(), - ) + decoder + .interner() + .arena + .alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder))) } } @@ -368,9 +369,10 @@ impl<'tcx, D: TyDecoder>> Decodable for AdtDef<'tcx> { impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for [(ty::Clause<'tcx>, Span)] { fn decode(decoder: &mut D) -> &'tcx Self { - decoder.interner().arena.alloc_from_iter( - (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::>(), - ) + decoder + .interner() + .arena + .alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder))) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index c06b8b2dfa08..83adbc3c7904 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -152,7 +152,7 @@ pub struct CtxtInterners<'tcx> { const_: InternedSet<'tcx, ConstData<'tcx>>, const_allocation: InternedSet<'tcx, Allocation>, bound_variable_kinds: InternedSet<'tcx, List>, - layout: InternedSet<'tcx, LayoutS>, + layout: InternedSet<'tcx, LayoutS>, adt_def: InternedSet<'tcx, AdtDefData>, external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>, predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<'tcx>>, @@ -1521,7 +1521,7 @@ direct_interners! { region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>, const_: intern_const(ConstData<'tcx>): Const -> Const<'tcx>, const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>, - layout: pub mk_layout(LayoutS): Layout -> Layout<'tcx>, + layout: pub mk_layout(LayoutS): Layout -> Layout<'tcx>, adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>, external_constraints: pub mk_external_constraints(ExternalConstraintsData<'tcx>): ExternalConstraints -> ExternalConstraints<'tcx>, diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 0b0a708e42bb..0a425be52ffb 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -617,12 +617,17 @@ impl<'tcx> Instance<'tcx> { v: EarlyBinder, ) -> Result> where - T: TypeFoldable> + Clone, + T: TypeFoldable>, { if let Some(args) = self.args_for_mir_body() { tcx.try_instantiate_and_normalize_erasing_regions(args, param_env, v) } else { - tcx.try_normalize_erasing_regions(param_env, v.skip_binder()) + // We're using `instantiate_identity` as e.g. + // `FnPtrShim` is separately generated for every + // instantiation of the `FnDef`, so the MIR body + // is already instantiated. Any generic parameters it + // contains are generic parameters from the caller. + tcx.try_normalize_erasing_regions(param_env, v.instantiate_identity()) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index aa1e7f216a06..b7d2e3d9493f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -578,11 +578,6 @@ impl rustc_errors::IntoDiagnosticArg for Clause<'_> { pub struct Clause<'tcx>(Interned<'tcx, WithCachedTypeInfo>>>); impl<'tcx> Clause<'tcx> { - pub fn from_projection_clause(tcx: TyCtxt<'tcx>, pred: PolyProjectionPredicate<'tcx>) -> Self { - let pred: Predicate<'tcx> = pred.to_predicate(tcx); - pred.expect_clause() - } - pub fn as_predicate(self) -> Predicate<'tcx> { Predicate(self.0) } @@ -1296,12 +1291,25 @@ impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for Binder<'tcx, TraitRef } } +impl<'tcx> ToPredicate<'tcx> for TraitPredicate<'tcx> { + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { + PredicateKind::Clause(ClauseKind::Trait(self)).to_predicate(tcx) + } +} + impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { self.map_bound(|p| PredicateKind::Clause(ClauseKind::Trait(p))).to_predicate(tcx) } } +impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for TraitPredicate<'tcx> { + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { + let p: Predicate<'tcx> = self.to_predicate(tcx); + p.expect_clause() + } +} + impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for PolyTraitPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { let p: Predicate<'tcx> = self.to_predicate(tcx); @@ -1340,9 +1348,10 @@ impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for ProjectionPredicate<'tcx> { } } -impl<'tcx> ToPredicate<'tcx> for TraitPredicate<'tcx> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - PredicateKind::Clause(ClauseKind::Trait(self)).to_predicate(tcx) +impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for PolyProjectionPredicate<'tcx> { + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { + let p: Predicate<'tcx> = self.to_predicate(tcx); + p.expect_clause() } } @@ -1743,30 +1752,9 @@ impl<'tcx> ParamEnv<'tcx> { Self::new(List::empty(), self.reveal()) } - /// Creates a suitable environment in which to perform trait - /// queries on the given value. When type-checking, this is simply - /// the pair of the environment plus value. But when reveal is set to - /// All, then if `value` does not reference any type parameters, we will - /// pair it with the empty environment. This improves caching and is generally - /// invisible. - /// - /// N.B., we preserve the environment when type-checking because it - /// is possible for the user to have wacky where-clauses like - /// `where Box: Copy`, which are clearly never - /// satisfiable. We generally want to behave as if they were true, - /// although the surrounding function is never reachable. + /// Creates a pair of param-env and value for use in queries. pub fn and>>(self, value: T) -> ParamEnvAnd<'tcx, T> { - match self.reveal() { - Reveal::UserFacing => ParamEnvAnd { param_env: self, value }, - - Reveal::All => { - if value.is_global() { - ParamEnvAnd { param_env: self.without_caller_bounds(), value } - } else { - ParamEnvAnd { param_env: self, value } - } - } - } + ParamEnvAnd { param_env: self, value } } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 1e57392e0e7d..e5f418bbb4b1 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -725,7 +725,7 @@ impl<'tcx> PolyExistentialPredicate<'tcx> { self.rebind(tr).with_self_ty(tcx, self_ty).to_predicate(tcx) } ExistentialPredicate::Projection(p) => { - ty::Clause::from_projection_clause(tcx, self.rebind(p.with_self_ty(tcx, self_ty))) + self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx) } ExistentialPredicate::AutoTrait(did) => { let generics = tcx.generics_of(did); diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 2e7ef265a93c..4aff406b3768 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -102,7 +102,7 @@ fn convert_to_hir_projections_and_truncate_for_capture( continue; } // These do not affect anything, they just make sure we know the right type. - ProjectionElem::OpaqueCast(_) => continue, + ProjectionElem::OpaqueCast(_) | ProjectionElem::Subtype(..) => continue, ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => { @@ -709,6 +709,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ProjectionElem::Field(..) | ProjectionElem::Downcast(..) | ProjectionElem::OpaqueCast(..) + | ProjectionElem::Subtype(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => (), } diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index d4089eef4833..afb65ffbe8c9 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -183,7 +183,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // The `Box` temporary created here is not a part of the HIR, // and therefore is not considered during generator auto-trait // determination. See the comment about `box` at `yield_in_scope`. - let result = this.local_decls.push(LocalDecl::new(expr.ty, expr_span).internal()); + let result = this.local_decls.push(LocalDecl::new(expr.ty, expr_span)); this.cfg.push( block, Statement { source_info, kind: StatementKind::StorageLive(result) }, diff --git a/compiler/rustc_mir_build/src/build/expr/as_temp.rs b/compiler/rustc_mir_build/src/build/expr/as_temp.rs index c8910c272b1b..a4ab365fa9a7 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_temp.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_temp.rs @@ -52,12 +52,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let local_info = match expr.kind { ExprKind::StaticRef { def_id, .. } => { assert!(!this.tcx.is_thread_local_static(def_id)); - local_decl.internal = true; LocalInfo::StaticRef { def_id, is_thread_local: false } } ExprKind::ThreadLocalRef(def_id) => { assert!(this.tcx.is_thread_local_static(def_id)); - local_decl.internal = true; LocalInfo::StaticRef { def_id, is_thread_local: true } } ExprKind::NamedConst { def_id, .. } | ExprKind::ConstParam { def_id, .. } => { diff --git a/compiler/rustc_mir_build/src/build/expr/mod.rs b/compiler/rustc_mir_build/src/build/expr/mod.rs index f5ae060d603f..dfe85b858cd0 100644 --- a/compiler/rustc_mir_build/src/build/expr/mod.rs +++ b/compiler/rustc_mir_build/src/build/expr/mod.rs @@ -44,7 +44,7 @@ //! the most suitable spot to implement it, and then just let the //! other fns cycle around. The handoff works like this: //! -//! - `into(place)` -> fallback is to create a rvalue with `as_rvalue` and assign it to `place` +//! - `into(place)` -> fallback is to create an rvalue with `as_rvalue` and assign it to `place` //! - `as_rvalue` -> fallback is to create an Operand with `as_operand` and use `Rvalue::use` //! - `as_operand` -> either invokes `as_constant` or `as_temp` //! - `as_constant` -> (no fallback) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 921a5ca1175c..eb1c6a9824a4 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -1798,7 +1798,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let fake_borrow_ty = Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, fake_borrow_deref_ty); let mut fake_borrow_temp = LocalDecl::new(fake_borrow_ty, temp_span); - fake_borrow_temp.internal = self.local_decls[matched_place.local].internal; fake_borrow_temp.local_info = ClearCrossCrate::Set(Box::new(LocalInfo::FakeBorrow)); let fake_borrow_temp = self.local_decls.push(fake_borrow_temp); @@ -2268,7 +2267,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ty: var_ty, user_ty: if user_ty.is_empty() { None } else { Some(Box::new(user_ty)) }, source_info, - internal: false, local_info: ClearCrossCrate::Set(Box::new(LocalInfo::User(BindingForm::Var( VarBindingForm { binding_mode, @@ -2298,7 +2296,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ty: Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, var_ty), user_ty: None, source_info, - internal: false, local_info: ClearCrossCrate::Set(Box::new(LocalInfo::User( BindingForm::RefForGuard, ))), diff --git a/compiler/rustc_mir_build/src/build/misc.rs b/compiler/rustc_mir_build/src/build/misc.rs index c96e99ef0e7e..c263de79c3b8 100644 --- a/compiler/rustc_mir_build/src/build/misc.rs +++ b/compiler/rustc_mir_build/src/build/misc.rs @@ -15,9 +15,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// N.B., **No cleanup is scheduled for this temporary.** You should /// call `schedule_drop` once the temporary is initialized. pub(crate) fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Place<'tcx> { - // Mark this local as internal to avoid temporaries with types not present in the - // user's code resulting in ICEs from the generator transform. - let temp = self.local_decls.push(LocalDecl::new(ty, span).internal()); + let temp = self.local_decls.push(LocalDecl::new(ty, span)); let place = Place::from(temp); debug!("temp: created temp {:?} with type {:?}", place, self.local_decls[temp].ty); place diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 4cf6a349af76..bc151cc70589 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -725,7 +725,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Add a dummy `Assign` statement to the CFG, with the span for the source code's `continue` // statement. fn add_dummy_assignment(&mut self, span: Span, block: BasicBlock, source_info: SourceInfo) { - let local_decl = LocalDecl::new(Ty::new_unit(self.tcx), span).internal(); + let local_decl = LocalDecl::new(Ty::new_unit(self.tcx), span); let temp_place = Place::from(self.local_decls.push(local_decl)); self.cfg.push_assign_unit(block, source_info, temp_place, self.tcx); } diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index b79beb1c537a..3ee4befa1218 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -50,6 +50,7 @@ use std::ops::RangeInclusive; use smallvec::{smallvec, SmallVec}; +use rustc_apfloat::ieee::{DoubleS, IeeeFloat, SingleS}; use rustc_data_structures::captures::Captures; use rustc_hir::{HirId, RangeEnd}; use rustc_index::Idx; @@ -60,12 +61,11 @@ use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef}; use rustc_session::lint; use rustc_span::{Span, DUMMY_SP}; -use rustc_target::abi::{FieldIdx, Integer, Size, VariantIdx, FIRST_VARIANT}; +use rustc_target::abi::{FieldIdx, Integer, VariantIdx, FIRST_VARIANT}; use self::Constructor::*; use self::SliceKind::*; -use super::compare_const_vals; use super::usefulness::{MatchCheckCtxt, PatCtxt}; use crate::errors::{Overlap, OverlappingRangeEndpoints}; @@ -99,10 +99,6 @@ fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> { #[derive(Clone, PartialEq, Eq)] pub(crate) struct IntRange { range: RangeInclusive, - /// Keeps the bias used for encoding the range. It depends on the type of the range and - /// possibly the pointer size of the current architecture. The algorithm ensures we never - /// compare `IntRange`s with different types/architectures. - bias: u128, } impl IntRange { @@ -120,37 +116,12 @@ impl IntRange { } #[inline] - fn integral_size_and_signed_bias(tcx: TyCtxt<'_>, ty: Ty<'_>) -> Option<(Size, u128)> { - match *ty.kind() { - ty::Bool => Some((Size::from_bytes(1), 0)), - ty::Char => Some((Size::from_bytes(4), 0)), - ty::Int(ity) => { - let size = Integer::from_int_ty(&tcx, ity).size(); - Some((size, 1u128 << (size.bits() as u128 - 1))) - } - ty::Uint(uty) => Some((Integer::from_uint_ty(&tcx, uty).size(), 0)), - _ => None, - } - } - - #[inline] - fn from_constant<'tcx>( - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - value: mir::Const<'tcx>, - ) -> Option { - let ty = value.ty(); - let (target_size, bias) = Self::integral_size_and_signed_bias(tcx, ty)?; - let val = match value { - mir::Const::Ty(c) if let ty::ConstKind::Value(valtree) = c.kind() => { - valtree.unwrap_leaf().to_bits(target_size).ok() - }, - // This is a more general form of the previous case. - _ => value.try_eval_bits(tcx, param_env), - }?; - - let val = val ^ bias; - Some(IntRange { range: val..=val, bias }) + fn from_bits<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, bits: u128) -> IntRange { + let bias = IntRange::signed_bias(tcx, ty); + // Perform a shift if the underlying types are signed, + // which makes the interval arithmetic simpler. + let val = bits ^ bias; + IntRange { range: val..=val } } #[inline] @@ -159,20 +130,18 @@ impl IntRange { lo: u128, hi: u128, ty: Ty<'tcx>, - end: &RangeEnd, - ) -> Option { - Self::is_integral(ty).then(|| { - // Perform a shift if the underlying types are signed, - // which makes the interval arithmetic simpler. - let bias = IntRange::signed_bias(tcx, ty); - let (lo, hi) = (lo ^ bias, hi ^ bias); - let offset = (*end == RangeEnd::Excluded) as u128; - if lo > hi || (lo == hi && *end == RangeEnd::Excluded) { - // This should have been caught earlier by E0030. - bug!("malformed range pattern: {}..={}", lo, (hi - offset)); - } - IntRange { range: lo..=(hi - offset), bias } - }) + end: RangeEnd, + ) -> IntRange { + // Perform a shift if the underlying types are signed, + // which makes the interval arithmetic simpler. + let bias = IntRange::signed_bias(tcx, ty); + let (lo, hi) = (lo ^ bias, hi ^ bias); + let offset = (end == RangeEnd::Excluded) as u128; + if lo > hi || (lo == hi && end == RangeEnd::Excluded) { + // This should have been caught earlier by E0030. + bug!("malformed range pattern: {}..={}", lo, (hi - offset)); + } + IntRange { range: lo..=(hi - offset) } } // The return value of `signed_bias` should be XORed with an endpoint to encode/decode it. @@ -194,7 +163,7 @@ impl IntRange { let (lo, hi) = self.boundaries(); let (other_lo, other_hi) = other.boundaries(); if lo <= other_hi && other_lo <= hi { - Some(IntRange { range: max(lo, other_lo)..=min(hi, other_hi), bias: self.bias }) + Some(IntRange { range: max(lo, other_lo)..=min(hi, other_hi) }) } else { None } @@ -221,7 +190,7 @@ impl IntRange { fn to_pat<'tcx>(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Pat<'tcx> { let (lo, hi) = self.boundaries(); - let bias = self.bias; + let bias = IntRange::signed_bias(tcx, ty); let (lo, hi) = (lo ^ bias, hi ^ bias); let env = ty::ParamEnv::empty().and(ty); @@ -304,8 +273,6 @@ impl IntRange { impl fmt::Debug for IntRange { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let (lo, hi) = self.boundaries(); - let bias = self.bias; - let (lo, hi) = (lo ^ bias, hi ^ bias); write!(f, "{lo}")?; write!(f, "{}", RangeEnd::Included)?; write!(f, "{hi}") @@ -402,7 +369,7 @@ impl SplitIntRange { (JustBefore(n), AfterMax) => n..=u128::MAX, _ => unreachable!(), // Ruled out by the sorting and filtering we did }; - IntRange { range, bias: self.range.bias } + IntRange { range } }) } } @@ -619,7 +586,8 @@ pub(super) enum Constructor<'tcx> { /// Ranges of integer literal values (`2`, `2..=5` or `2..5`). IntRange(IntRange), /// Ranges of floating-point literal values (`2.0..=5.2`). - FloatRange(mir::Const<'tcx>, mir::Const<'tcx>, RangeEnd), + F32Range(IeeeFloat, IeeeFloat, RangeEnd), + F64Range(IeeeFloat, IeeeFloat, RangeEnd), /// String literals. Strings are not quite the same as `&[u8]` so we treat them separately. Str(mir::Const<'tcx>), /// Array and slice patterns. @@ -634,7 +602,9 @@ pub(super) enum Constructor<'tcx> { /// Stands for constructors that are not seen in the matrix, as explained in the documentation /// for [`SplitWildcard`]. The carried `bool` is used for the `non_exhaustive_omitted_patterns` /// lint. - Missing { nonexhaustive_enum_missing_real_variants: bool }, + Missing { + nonexhaustive_enum_missing_real_variants: bool, + }, /// Wildcard pattern. Wildcard, /// Or-pattern. @@ -722,7 +692,8 @@ impl<'tcx> Constructor<'tcx> { }, Slice(slice) => slice.arity(), Str(..) - | FloatRange(..) + | F32Range(..) + | F64Range(..) | IntRange(..) | NonExhaustive | Opaque @@ -795,21 +766,21 @@ impl<'tcx> Constructor<'tcx> { (Variant(self_id), Variant(other_id)) => self_id == other_id, (IntRange(self_range), IntRange(other_range)) => self_range.is_covered_by(other_range), - ( - FloatRange(self_from, self_to, self_end), - FloatRange(other_from, other_to, other_end), - ) => { - match ( - compare_const_vals(pcx.cx.tcx, *self_to, *other_to, pcx.cx.param_env), - compare_const_vals(pcx.cx.tcx, *self_from, *other_from, pcx.cx.param_env), - ) { - (Some(to), Some(from)) => { - (from == Ordering::Greater || from == Ordering::Equal) - && (to == Ordering::Less - || (other_end == self_end && to == Ordering::Equal)) + (F32Range(self_from, self_to, self_end), F32Range(other_from, other_to, other_end)) => { + self_from.ge(other_from) + && match self_to.partial_cmp(other_to) { + Some(Ordering::Less) => true, + Some(Ordering::Equal) => other_end == self_end, + _ => false, + } + } + (F64Range(self_from, self_to, self_end), F64Range(other_from, other_to, other_end)) => { + self_from.ge(other_from) + && match self_to.partial_cmp(other_to) { + Some(Ordering::Less) => true, + Some(Ordering::Equal) => other_end == self_end, + _ => false, } - _ => false, - } } (Str(self_val), Str(other_val)) => { // FIXME Once valtrees are available we can directly use the bytes @@ -859,7 +830,7 @@ impl<'tcx> Constructor<'tcx> { .any(|other| slice.is_covered_by(other)), // This constructor is never covered by anything else NonExhaustive => false, - Str(..) | FloatRange(..) | Opaque | Missing { .. } | Wildcard | Or => { + Str(..) | F32Range(..) | F64Range(..) | Opaque | Missing { .. } | Wildcard | Or => { span_bug!(pcx.span, "found unexpected ctor in all_ctors: {:?}", self) } } @@ -896,7 +867,7 @@ impl<'tcx> SplitWildcard<'tcx> { let make_range = |start, end| { IntRange( // `unwrap()` is ok because we know the type is an integer. - IntRange::from_range(cx.tcx, start, end, pcx.ty, &RangeEnd::Included).unwrap(), + IntRange::from_range(cx.tcx, start, end, pcx.ty, RangeEnd::Included), ) }; // This determines the set of all possible constructors for the type `pcx.ty`. For numbers, @@ -1203,7 +1174,8 @@ impl<'p, 'tcx> Fields<'p, 'tcx> { _ => bug!("bad slice pattern {:?} {:?}", constructor, pcx), }, Str(..) - | FloatRange(..) + | F32Range(..) + | F64Range(..) | IntRange(..) | NonExhaustive | Opaque @@ -1343,50 +1315,78 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> { } } PatKind::Constant { value } => { - if let Some(int_range) = IntRange::from_constant(cx.tcx, cx.param_env, *value) { - ctor = IntRange(int_range); - fields = Fields::empty(); - } else { - match pat.ty.kind() { - ty::Float(_) => { - ctor = FloatRange(*value, *value, RangeEnd::Included); - fields = Fields::empty(); - } - ty::Ref(_, t, _) if t.is_str() => { - // We want a `&str` constant to behave like a `Deref` pattern, to be compatible - // with other `Deref` patterns. This could have been done in `const_to_pat`, - // but that causes issues with the rest of the matching code. - // So here, the constructor for a `"foo"` pattern is `&` (represented by - // `Single`), and has one field. That field has constructor `Str(value)` and no - // fields. - // Note: `t` is `str`, not `&str`. - let subpattern = - DeconstructedPat::new(Str(*value), Fields::empty(), *t, pat.span); - ctor = Single; - fields = Fields::singleton(cx, subpattern) - } - // All constants that can be structurally matched have already been expanded - // into the corresponding `Pat`s by `const_to_pat`. Constants that remain are - // opaque. - _ => { - ctor = Opaque; - fields = Fields::empty(); - } + match pat.ty.kind() { + ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) => { + ctor = match value.try_eval_bits(cx.tcx, cx.param_env) { + Some(bits) => IntRange(IntRange::from_bits(cx.tcx, pat.ty, bits)), + None => Opaque, + }; + fields = Fields::empty(); + } + ty::Float(ty::FloatTy::F32) => { + ctor = match value.try_eval_bits(cx.tcx, cx.param_env) { + Some(bits) => { + use rustc_apfloat::Float; + let value = rustc_apfloat::ieee::Single::from_bits(bits); + F32Range(value, value, RangeEnd::Included) + } + None => Opaque, + }; + fields = Fields::empty(); + } + ty::Float(ty::FloatTy::F64) => { + ctor = match value.try_eval_bits(cx.tcx, cx.param_env) { + Some(bits) => { + use rustc_apfloat::Float; + let value = rustc_apfloat::ieee::Double::from_bits(bits); + F64Range(value, value, RangeEnd::Included) + } + None => Opaque, + }; + fields = Fields::empty(); + } + ty::Ref(_, t, _) if t.is_str() => { + // We want a `&str` constant to behave like a `Deref` pattern, to be compatible + // with other `Deref` patterns. This could have been done in `const_to_pat`, + // but that causes issues with the rest of the matching code. + // So here, the constructor for a `"foo"` pattern is `&` (represented by + // `Single`), and has one field. That field has constructor `Str(value)` and no + // fields. + // Note: `t` is `str`, not `&str`. + let subpattern = + DeconstructedPat::new(Str(*value), Fields::empty(), *t, pat.span); + ctor = Single; + fields = Fields::singleton(cx, subpattern) + } + // All constants that can be structurally matched have already been expanded + // into the corresponding `Pat`s by `const_to_pat`. Constants that remain are + // opaque. + _ => { + ctor = Opaque; + fields = Fields::empty(); } } } - &PatKind::Range(box PatRange { lo, hi, end }) => { + PatKind::Range(box PatRange { lo, hi, end }) => { + use rustc_apfloat::Float; let ty = lo.ty(); - ctor = if let Some(int_range) = IntRange::from_range( - cx.tcx, - lo.eval_bits(cx.tcx, cx.param_env), - hi.eval_bits(cx.tcx, cx.param_env), - ty, - &end, - ) { - IntRange(int_range) - } else { - FloatRange(lo, hi, end) + let lo = lo.try_eval_bits(cx.tcx, cx.param_env).unwrap(); + let hi = hi.try_eval_bits(cx.tcx, cx.param_env).unwrap(); + ctor = match ty.kind() { + ty::Char | ty::Int(_) | ty::Uint(_) => { + IntRange(IntRange::from_range(cx.tcx, lo, hi, ty, *end)) + } + ty::Float(ty::FloatTy::F32) => { + let lo = rustc_apfloat::ieee::Single::from_bits(lo); + let hi = rustc_apfloat::ieee::Single::from_bits(hi); + F32Range(lo, hi, *end) + } + ty::Float(ty::FloatTy::F64) => { + let lo = rustc_apfloat::ieee::Double::from_bits(lo); + let hi = rustc_apfloat::ieee::Double::from_bits(hi); + F64Range(lo, hi, *end) + } + _ => bug!("invalid type for range pattern: {}", ty), }; fields = Fields::empty(); } @@ -1491,14 +1491,13 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> { } } &Str(value) => PatKind::Constant { value }, - &FloatRange(lo, hi, end) => PatKind::Range(Box::new(PatRange { lo, hi, end })), IntRange(range) => return range.to_pat(cx.tcx, self.ty), Wildcard | NonExhaustive => PatKind::Wild, Missing { .. } => bug!( "trying to convert a `Missing` constructor into a `Pat`; this is probably a bug, `Missing` should have been processed in `apply_constructors`" ), - Opaque | Or => { + F32Range(..) | F64Range(..) | Opaque | Or => { bug!("can't convert to pattern: {:?}", self) } }; @@ -1673,11 +1672,8 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> { } write!(f, "]") } - &FloatRange(lo, hi, end) => { - write!(f, "{lo}")?; - write!(f, "{end}")?; - write!(f, "{hi}") - } + F32Range(lo, hi, end) => write!(f, "{lo}{end}{hi}"), + F64Range(lo, hi, end) => write!(f, "{lo}{end}{hi}"), IntRange(range) => write!(f, "{range:?}"), // Best-effort, will render e.g. `false` as `0..=0` Wildcard | Missing { .. } | NonExhaustive => write!(f, "_ : {:?}", self.ty), Or => { diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index e24685cb90f7..c9991e499b32 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -194,6 +194,7 @@ where D: DropElaborator<'b, 'tcx>, 'tcx: 'b, { + #[instrument(level = "trace", skip(self), ret)] fn place_ty(&self, place: Place<'tcx>) -> Ty<'tcx> { place.ty(self.elaborator.body(), self.tcx()).ty } @@ -220,11 +221,9 @@ where // // FIXME: I think we should just control the flags externally, // and then we do not need this machinery. + #[instrument(level = "debug")] pub fn elaborate_drop(&mut self, bb: BasicBlock) { - debug!("elaborate_drop({:?}, {:?})", bb, self); - let style = self.elaborator.drop_style(self.path, DropFlagMode::Deep); - debug!("elaborate_drop({:?}, {:?}): live - {:?}", bb, self, style); - match style { + match self.elaborator.drop_style(self.path, DropFlagMode::Deep) { DropStyle::Dead => { self.elaborator .patch() diff --git a/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs b/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs index 7806e8f45d3a..2a7f23ef6d25 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs @@ -57,6 +57,7 @@ impl<'tcx> Lift for PlaceElem<'tcx> { ProjectionElem::ConstantIndex { offset, min_length, from_end } } ProjectionElem::Downcast(a, u) => ProjectionElem::Downcast(a, u), + ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty.lift()), } } } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 9ced3a7f3cd6..7a5b3585d597 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -227,10 +227,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { } _ => bug!("Unexpected type {place_ty:#?}"), }, - // `OpaqueCast` only transmutes the type, so no moves there and - // `Downcast` only changes information about a `Place` without moving + // `OpaqueCast`:Only transmutes the type, so no moves there. + // `Downcast` :Only changes information about a `Place` without moving. + // `Subtype` :Only transmutes the type, so moves. // So it's safe to skip these. - ProjectionElem::OpaqueCast(_) | ProjectionElem::Downcast(_, _) => (), + ProjectionElem::OpaqueCast(_) + | ProjectionElem::Subtype(_) + | ProjectionElem::Downcast(_, _) => (), } if union_path.is_none() { // inlined from add_move_path because of a borrowck conflict with the iterator diff --git a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs new file mode 100644 index 000000000000..e5be7c0ca76e --- /dev/null +++ b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs @@ -0,0 +1,70 @@ +use crate::MirPass; +use rustc_index::IndexVec; +use rustc_middle::mir::patch::MirPatch; +use rustc_middle::mir::visit::MutVisitor; +use rustc_middle::mir::*; +use rustc_middle::ty::TyCtxt; + +pub struct Subtyper; + +pub struct SubTypeChecker<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + patcher: MirPatch<'tcx>, + local_decls: &'a IndexVec>, +} + +impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn visit_assign( + &mut self, + place: &mut Place<'tcx>, + rvalue: &mut Rvalue<'tcx>, + location: Location, + ) { + // We don't need to do anything for deref temps as they are + // not part of the source code, but used for desugaring purposes. + if self.local_decls[place.local].is_deref_temp() { + return; + } + let mut place_ty = place.ty(self.local_decls, self.tcx).ty; + let mut rval_ty = rvalue.ty(self.local_decls, self.tcx); + // Not erasing this causes `Free Regions` errors in validator, + // when rval is `ReStatic`. + rval_ty = self.tcx.erase_regions_ty(rval_ty); + place_ty = self.tcx.erase_regions(place_ty); + if place_ty != rval_ty { + let temp = self + .patcher + .new_temp(rval_ty, self.local_decls[place.as_ref().local].source_info.span); + let new_place = Place::from(temp); + self.patcher.add_assign(location, new_place, rvalue.clone()); + let subtyped = new_place.project_deeper(&[ProjectionElem::Subtype(place_ty)], self.tcx); + *rvalue = Rvalue::Use(Operand::Move(subtyped)); + } + } +} + +// Aim here is to do this kind of transformation: +// +// let place: place_ty = rval; +// // gets transformed to +// let temp: rval_ty = rval; +// let place: place_ty = temp as place_ty; +pub fn subtype_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + let patch = MirPatch::new(body); + let mut checker = SubTypeChecker { tcx, patcher: patch, local_decls: &body.local_decls }; + + for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() { + checker.visit_basic_block_data(bb, data); + } + checker.patcher.apply(body); +} + +impl<'tcx> MirPass<'tcx> for Subtyper { + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + subtype_finder(tcx, body); + } +} diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index bacabc62ee40..c428007707ee 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -179,7 +179,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { // Check the base local: it might be an unsafe-to-access static. We only check derefs of the // temporary holding the static pointer to avoid duplicate errors // . - if decl.internal && place.projection.first() == Some(&ProjectionElem::Deref) { + if place.projection.first() == Some(&ProjectionElem::Deref) { // If the projection root is an artificial local that we introduced when // desugaring `static`, give a more specific error message // (avoid the general "raw pointer" clause below, that would only be confusing). diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs index d56d4ad4f1e7..78845af01627 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters.rs @@ -1,10 +1,8 @@ use super::Error; use super::graph; -use super::spans; use graph::{BasicCoverageBlock, BcbBranch, CoverageGraph, TraverseCoverageGraphWithLoops}; -use spans::CoverageSpan; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph::WithNumNodes; @@ -93,14 +91,14 @@ impl CoverageCounters { } /// Makes [`BcbCounter`] `Counter`s and `Expressions` for the `BasicCoverageBlock`s directly or - /// indirectly associated with `CoverageSpans`, and accumulates additional `Expression`s + /// indirectly associated with coverage spans, and accumulates additional `Expression`s /// representing intermediate values. pub fn make_bcb_counters( &mut self, basic_coverage_blocks: &CoverageGraph, - coverage_spans: &[CoverageSpan], + bcb_has_coverage_spans: impl Fn(BasicCoverageBlock) -> bool, ) -> Result<(), Error> { - MakeBcbCounters::new(self, basic_coverage_blocks).make_bcb_counters(coverage_spans) + MakeBcbCounters::new(self, basic_coverage_blocks).make_bcb_counters(bcb_has_coverage_spans) } fn make_counter(&mut self) -> BcbCounter { @@ -113,14 +111,10 @@ impl CoverageCounters { BcbCounter::Expression { id, lhs, op, rhs } } - pub fn make_identity_counter(&mut self, counter_operand: Operand) -> BcbCounter { - self.make_expression(counter_operand, Op::Add, Operand::Zero) - } - /// Counter IDs start from one and go up. fn next_counter(&mut self) -> CounterId { let next = self.next_counter_id; - self.next_counter_id = next.next_id(); + self.next_counter_id = self.next_counter_id + 1; next } @@ -128,7 +122,7 @@ impl CoverageCounters { /// (Counter IDs and Expression IDs are distinguished by the `Operand` enum.) fn next_expression(&mut self) -> ExpressionId { let next = self.next_expression_id; - self.next_expression_id = next.next_id(); + self.next_expression_id = self.next_expression_id + 1; next } @@ -208,7 +202,7 @@ impl CoverageCounters { } /// Traverse the `CoverageGraph` and add either a `Counter` or `Expression` to every BCB, to be -/// injected with `CoverageSpan`s. `Expressions` have no runtime overhead, so if a viable expression +/// injected with coverage spans. `Expressions` have no runtime overhead, so if a viable expression /// (adding or subtracting two other counters or expressions) can compute the same result as an /// embedded counter, an `Expression` should be used. struct MakeBcbCounters<'a> { @@ -234,17 +228,14 @@ impl<'a> MakeBcbCounters<'a> { /// Returns any non-code-span expressions created to represent intermediate values (such as to /// add two counters so the result can be subtracted from another counter), or an Error with /// message for subsequent debugging. - fn make_bcb_counters(&mut self, coverage_spans: &[CoverageSpan]) -> Result<(), Error> { + fn make_bcb_counters( + &mut self, + bcb_has_coverage_spans: impl Fn(BasicCoverageBlock) -> bool, + ) -> Result<(), Error> { debug!("make_bcb_counters(): adding a counter or expression to each BasicCoverageBlock"); - let num_bcbs = self.basic_coverage_blocks.num_nodes(); - - let mut bcbs_with_coverage = BitSet::new_empty(num_bcbs); - for covspan in coverage_spans { - bcbs_with_coverage.insert(covspan.bcb); - } // Walk the `CoverageGraph`. For each `BasicCoverageBlock` node with an associated - // `CoverageSpan`, add a counter. If the `BasicCoverageBlock` branches, add a counter or + // coverage span, add a counter. If the `BasicCoverageBlock` branches, add a counter or // expression to each branch `BasicCoverageBlock` (if the branch BCB has only one incoming // edge) or edge from the branching BCB to the branch BCB (if the branch BCB has multiple // incoming edges). @@ -255,8 +246,8 @@ impl<'a> MakeBcbCounters<'a> { // the current BCB is in one or more nested loops or not. let mut traversal = TraverseCoverageGraphWithLoops::new(&self.basic_coverage_blocks); while let Some(bcb) = traversal.next(self.basic_coverage_blocks) { - if bcbs_with_coverage.contains(bcb) { - debug!("{:?} has at least one `CoverageSpan`. Get or make its counter", bcb); + if bcb_has_coverage_spans(bcb) { + debug!("{:?} has at least one coverage span. Get or make its counter", bcb); let branching_counter_operand = self.get_or_make_counter_operand(bcb)?; if self.bcb_needs_branch_counters(bcb) { @@ -264,7 +255,7 @@ impl<'a> MakeBcbCounters<'a> { } } else { debug!( - "{:?} does not have any `CoverageSpan`s. A counter will only be added if \ + "{:?} does not have any coverage spans. A counter will only be added if \ and when a covered BCB has an expression dependency.", bcb, ); diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index ff2254d6941e..812633348e3b 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -288,9 +288,9 @@ rustc_index::newtype_index! { /// not relevant to coverage analysis. `FalseUnwind`, for example, can be treated the same as /// a `Goto`, and merged with its successor into the same BCB. /// -/// Each BCB with at least one computed `CoverageSpan` will have no more than one `Counter`. +/// Each BCB with at least one computed coverage span will have no more than one `Counter`. /// In some cases, a BCB's execution count can be computed by `Expression`. Additional -/// disjoint `CoverageSpan`s in a BCB can also be counted by `Expression` (by adding `ZERO` +/// disjoint coverage spans in a BCB can also be counted by `Expression` (by adding `ZERO` /// to the BCB's primary counter or expression). /// /// The BCB CFG is critical to simplifying the coverage analysis by ensuring graph path-based diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index c75d33eeb315..abf13519e9ee 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -9,13 +9,11 @@ mod tests; use self::counters::{BcbCounter, CoverageCounters}; use self::graph::{BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph}; -use self::spans::{CoverageSpan, CoverageSpans}; +use self::spans::CoverageSpans; use crate::MirPass; -use rustc_data_structures::graph::WithNumNodes; use rustc_data_structures::sync::Lrc; -use rustc_index::IndexVec; use rustc_middle::hir; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::coverage::*; @@ -154,7 +152,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { let body_span = self.body_span; //////////////////////////////////////////////////// - // Compute `CoverageSpan`s from the `CoverageGraph`. + // Compute coverage spans from the `CoverageGraph`. let coverage_spans = CoverageSpans::generate_coverage_spans( &self.mir_body, fn_sig_span, @@ -164,32 +162,33 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { //////////////////////////////////////////////////// // Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure - // every `CoverageSpan` has a `Counter` or `Expression` assigned to its `BasicCoverageBlock` + // every coverage span has a `Counter` or `Expression` assigned to its `BasicCoverageBlock` // and all `Expression` dependencies (operands) are also generated, for any other - // `BasicCoverageBlock`s not already associated with a `CoverageSpan`. + // `BasicCoverageBlock`s not already associated with a coverage span. // // Intermediate expressions (used to compute other `Expression` values), which have no // direct association with any `BasicCoverageBlock`, are accumulated inside `coverage_counters`. + let bcb_has_coverage_spans = |bcb| coverage_spans.bcb_has_coverage_spans(bcb); let result = self .coverage_counters - .make_bcb_counters(&mut self.basic_coverage_blocks, &coverage_spans); + .make_bcb_counters(&mut self.basic_coverage_blocks, bcb_has_coverage_spans); if let Ok(()) = result { //////////////////////////////////////////////////// - // Remove the counter or edge counter from of each `CoverageSpan`s associated + // Remove the counter or edge counter from of each coverage cpan's associated // `BasicCoverageBlock`, and inject a `Coverage` statement into the MIR. // - // `Coverage` statements injected from `CoverageSpan`s will include the code regions + // `Coverage` statements injected from coverage spans will include the code regions // (source code start and end positions) to be counted by the associated counter. // - // These `CoverageSpan`-associated counters are removed from their associated + // These coverage-span-associated counters are removed from their associated // `BasicCoverageBlock`s so that the only remaining counters in the `CoverageGraph` // are indirect counters (to be injected next, without associated code regions). - self.inject_coverage_span_counters(coverage_spans); + self.inject_coverage_span_counters(&coverage_spans); //////////////////////////////////////////////////// // For any remaining `BasicCoverageBlock` counters (that were not associated with - // any `CoverageSpan`), inject `Coverage` statements (_without_ code region `Span`s) + // any coverage span), inject `Coverage` statements (_without_ code region spans) // to ensure `BasicCoverageBlock` counters that other `Expression`s may depend on // are in fact counted, even though they don't directly contribute to counting // their own independent code region's coverage. @@ -214,47 +213,40 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { } } - /// Inject a counter for each `CoverageSpan`. There can be multiple `CoverageSpan`s for a given - /// BCB, but only one actual counter needs to be incremented per BCB. `bb_counters` maps each - /// `bcb` to its `Counter`, when injected. Subsequent `CoverageSpan`s for a BCB that already has - /// a `Counter` will inject an `Expression` instead, and compute its value by adding `ZERO` to - /// the BCB `Counter` value. - fn inject_coverage_span_counters(&mut self, coverage_spans: Vec) { + /// Injects a single [`StatementKind::Coverage`] for each BCB that has one + /// or more coverage spans. + fn inject_coverage_span_counters(&mut self, coverage_spans: &CoverageSpans) { let tcx = self.tcx; let source_map = tcx.sess.source_map(); let body_span = self.body_span; let file_name = Symbol::intern(&self.source_file.name.prefer_remapped().to_string_lossy()); - let mut bcb_counters = IndexVec::from_elem_n(None, self.basic_coverage_blocks.num_nodes()); - for covspan in coverage_spans { - let bcb = covspan.bcb; - let span = covspan.span; - let counter_kind = if let Some(&counter_operand) = bcb_counters[bcb].as_ref() { - self.coverage_counters.make_identity_counter(counter_operand) - } else if let Some(counter_kind) = self.coverage_counters.take_bcb_counter(bcb) { - bcb_counters[bcb] = Some(counter_kind.as_operand()); - counter_kind - } else { + for (bcb, spans) in coverage_spans.bcbs_with_coverage_spans() { + let counter_kind = self.coverage_counters.take_bcb_counter(bcb).unwrap_or_else(|| { bug!("Every BasicCoverageBlock should have a Counter or Expression"); - }; + }); - let code_region = make_code_region(source_map, file_name, span, body_span); + // Convert the coverage spans into a vector of code regions to be + // associated with this BCB's coverage statement. + let code_regions = spans + .iter() + .map(|&span| make_code_region(source_map, file_name, span, body_span)) + .collect::>(); inject_statement( self.mir_body, self.make_mir_coverage_kind(&counter_kind), self.bcb_leader_bb(bcb), - Some(code_region), + code_regions, ); } } - /// `inject_coverage_span_counters()` looped through the `CoverageSpan`s and injected the - /// counter from the `CoverageSpan`s `BasicCoverageBlock`, removing it from the BCB in the - /// process (via `take_counter()`). + /// At this point, any BCB with coverage counters has already had its counter injected + /// into MIR, and had its counter removed from `coverage_counters` (via `take_counter()`). /// /// Any other counter associated with a `BasicCoverageBlock`, or its incoming edge, but not - /// associated with a `CoverageSpan`, should only exist if the counter is an `Expression` + /// associated with a coverage span, should only exist if the counter is an `Expression` /// dependency (one of the expression operands). Collect them, and inject the additional /// counters into the MIR, without a reportable coverage span. fn inject_indirect_counters(&mut self) { @@ -303,7 +295,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { self.mir_body, self.make_mir_coverage_kind(&counter_kind), inject_to_bb, - None, + Vec::new(), ); } BcbCounter::Expression { .. } => inject_intermediate_expression( @@ -368,20 +360,14 @@ fn inject_statement( mir_body: &mut mir::Body<'_>, counter_kind: CoverageKind, bb: BasicBlock, - some_code_region: Option, + code_regions: Vec, ) { - debug!( - " injecting statement {:?} for {:?} at code region: {:?}", - counter_kind, bb, some_code_region - ); + debug!(" injecting statement {counter_kind:?} for {bb:?} at code regions: {code_regions:?}"); let data = &mut mir_body[bb]; let source_info = data.terminator().source_info; let statement = Statement { source_info, - kind: StatementKind::Coverage(Box::new(Coverage { - kind: counter_kind, - code_region: some_code_region, - })), + kind: StatementKind::Coverage(Box::new(Coverage { kind: counter_kind, code_regions })), }; data.statements.insert(0, statement); } @@ -395,7 +381,10 @@ fn inject_intermediate_expression(mir_body: &mut mir::Body<'_>, expression: Cove let source_info = data.terminator().source_info; let statement = Statement { source_info, - kind: StatementKind::Coverage(Box::new(Coverage { kind: expression, code_region: None })), + kind: StatementKind::Coverage(Box::new(Coverage { + kind: expression, + code_regions: Vec::new(), + })), }; data.statements.push(statement); } diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs index 56365c5d474a..2c0164e765c7 100644 --- a/compiler/rustc_mir_transform/src/coverage/query.rs +++ b/compiler/rustc_mir_transform/src/coverage/query.rs @@ -93,8 +93,8 @@ fn coverageinfo<'tcx>(tcx: TyCtxt<'tcx>, instance_def: ty::InstanceDef<'tcx>) -> fn covered_code_regions(tcx: TyCtxt<'_>, def_id: DefId) -> Vec<&CodeRegion> { let body = mir_body(tcx, def_id); all_coverage_in_mir_body(body) - // Not all coverage statements have an attached code region. - .filter_map(|coverage| coverage.code_region.as_ref()) + // Coverage statements have a list of code regions (possibly empty). + .flat_map(|coverage| coverage.code_regions.as_slice()) .collect() } diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 767f8e9f4fa1..dd87694f97cd 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -1,6 +1,7 @@ use super::graph::{BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB}; use rustc_data_structures::graph::WithNumNodes; +use rustc_index::IndexVec; use rustc_middle::mir::{ self, AggregateKind, BasicBlock, FakeReadCause, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, @@ -10,6 +11,48 @@ use rustc_span::{BytePos, ExpnKind, MacroKind, Span, Symbol}; use std::cell::OnceCell; +pub(super) struct CoverageSpans { + /// Map from BCBs to their list of coverage spans. + bcb_to_spans: IndexVec>, +} + +impl CoverageSpans { + pub(super) fn generate_coverage_spans( + mir_body: &mir::Body<'_>, + fn_sig_span: Span, + body_span: Span, + basic_coverage_blocks: &CoverageGraph, + ) -> Self { + let coverage_spans = CoverageSpansGenerator::generate_coverage_spans( + mir_body, + fn_sig_span, + body_span, + basic_coverage_blocks, + ); + + // Group the coverage spans by BCB, with the BCBs in sorted order. + let mut bcb_to_spans = IndexVec::from_elem_n(Vec::new(), basic_coverage_blocks.num_nodes()); + for CoverageSpan { bcb, span, .. } in coverage_spans { + bcb_to_spans[bcb].push(span); + } + + Self { bcb_to_spans } + } + + pub(super) fn bcb_has_coverage_spans(&self, bcb: BasicCoverageBlock) -> bool { + !self.bcb_to_spans[bcb].is_empty() + } + + pub(super) fn bcbs_with_coverage_spans( + &self, + ) -> impl Iterator { + self.bcb_to_spans.iter_enumerated().filter_map(|(bcb, spans)| { + // Only yield BCBs that have at least one coverage span. + (!spans.is_empty()).then_some((bcb, spans.as_slice())) + }) + } +} + #[derive(Debug, Copy, Clone)] pub(super) enum CoverageStatement { Statement(BasicBlock, Span, usize), @@ -35,7 +78,7 @@ impl CoverageStatement { /// or is subsumed by the `Span` associated with this `CoverageSpan`, and it's `BasicBlock` /// `dominates()` the `BasicBlock`s in this `CoverageSpan`. #[derive(Debug, Clone)] -pub(super) struct CoverageSpan { +struct CoverageSpan { pub span: Span, pub expn_span: Span, pub current_macro_or_none: OnceCell>, @@ -162,7 +205,7 @@ impl CoverageSpan { /// * Merge spans that represent continuous (both in source code and control flow), non-branching /// execution /// * Carve out (leave uncovered) any span that will be counted by another MIR (notably, closures) -pub struct CoverageSpans<'a, 'tcx> { +struct CoverageSpansGenerator<'a, 'tcx> { /// The MIR, used to look up `BasicBlockData`. mir_body: &'a mir::Body<'tcx>, @@ -218,7 +261,7 @@ pub struct CoverageSpans<'a, 'tcx> { refined_spans: Vec, } -impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { +impl<'a, 'tcx> CoverageSpansGenerator<'a, 'tcx> { /// Generate a minimal set of `CoverageSpan`s, each representing a contiguous code region to be /// counted. /// @@ -246,7 +289,7 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { body_span: Span, basic_coverage_blocks: &'a CoverageGraph, ) -> Vec { - let mut coverage_spans = CoverageSpans { + let mut coverage_spans = Self { mir_body, fn_sig_span, body_span, @@ -734,7 +777,7 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { /// If the MIR `Statement` has a span contributive to computing coverage spans, /// return it; otherwise return `None`. -pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option { +fn filtered_statement_span(statement: &Statement<'_>) -> Option { match statement.kind { // These statements have spans that are often outside the scope of the executed source code // for their parent `BasicBlock`. @@ -781,7 +824,7 @@ pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option /// If the MIR `Terminator` has a span contributive to computing coverage spans, /// return it; otherwise return `None`. -pub(super) fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option { +fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option { match terminator.kind { // These terminators have spans that don't positively contribute to computing a reasonable // span of actually executed source code. (For example, SwitchInt terminators extracted from @@ -828,7 +871,7 @@ pub(super) fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option Span { +fn function_source_span(span: Span, body_span: Span) -> Span { let original_span = original_sp(span, body_span).with_ctxt(body_span.ctxt()); if body_span.contains(original_span) { original_span } else { body_span } } diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index 4a066ed3abde..7476d3ce9272 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -25,8 +25,7 @@ //! to: `rustc_span::create_default_session_globals_then(|| { test_here(); })`. use super::counters; -use super::graph; -use super::spans; +use super::graph::{self, BasicCoverageBlock}; use coverage_test_macros::let_bcb; @@ -644,39 +643,18 @@ fn test_traverse_coverage_with_loops() { ); } -fn synthesize_body_span_from_terminators(mir_body: &Body<'_>) -> Span { - let mut some_span: Option = None; - for (_, data) in mir_body.basic_blocks.iter_enumerated() { - let term_span = data.terminator().source_info.span; - if let Some(span) = some_span.as_mut() { - *span = span.to(term_span); - } else { - some_span = Some(term_span) - } - } - some_span.expect("body must have at least one BasicBlock") -} - #[test] fn test_make_bcb_counters() { rustc_span::create_default_session_globals_then(|| { let mir_body = goto_switchint(); - let body_span = synthesize_body_span_from_terminators(&mir_body); let mut basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body); - let mut coverage_spans = Vec::new(); - for (bcb, data) in basic_coverage_blocks.iter_enumerated() { - if let Some(span) = spans::filtered_terminator_span(data.terminator(&mir_body)) { - coverage_spans.push(spans::CoverageSpan::for_terminator( - spans::function_source_span(span, body_span), - span, - bcb, - data.last_bb(), - )); - } - } + // Historically this test would use `spans` internals to set up fake + // coverage spans for BCBs 1 and 2. Now we skip that step and just tell + // BCB counter construction that those BCBs have spans. + let bcb_has_coverage_spans = |bcb: BasicCoverageBlock| (1..=2).contains(&bcb.as_usize()); let mut coverage_counters = counters::CoverageCounters::new(&basic_coverage_blocks); coverage_counters - .make_bcb_counters(&mut basic_coverage_blocks, &coverage_spans) + .make_bcb_counters(&mut basic_coverage_blocks, bcb_has_coverage_spans) .expect("should be Ok"); assert_eq!(coverage_counters.intermediate_expressions.len(), 0); diff --git a/compiler/rustc_mir_transform/src/deref_separator.rs b/compiler/rustc_mir_transform/src/deref_separator.rs index 95898b5b73cd..42be74570184 100644 --- a/compiler/rustc_mir_transform/src/deref_separator.rs +++ b/compiler/rustc_mir_transform/src/deref_separator.rs @@ -37,7 +37,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for DerefChecker<'a, 'tcx> { for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() { if !p_ref.projection.is_empty() && p_elem == ProjectionElem::Deref { let ty = p_ref.ty(self.local_decls, self.tcx).ty; - let temp = self.patcher.new_internal_with_info( + let temp = self.patcher.new_local_with_info( ty, self.local_decls[p_ref.local].source_info.span, LocalInfo::DerefTemp, diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs index e51f771e00db..1c917a85c038 100644 --- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs +++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs @@ -69,7 +69,7 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> { let (unique_ty, nonnull_ty, ptr_ty) = build_ptr_tys(tcx, base_ty.boxed_ty(), self.unique_did, self.nonnull_did); - let ptr_local = self.patch.new_internal(ptr_ty, source_info.span); + let ptr_local = self.patch.new_temp(ptr_ty, source_info.span); self.patch.add_assign( location, diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 6a89d0672757..d18fdaaf22ff 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -170,6 +170,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> { self.ctxt.param_env() } + #[instrument(level = "debug", skip(self), ret)] fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle { let ((maybe_live, maybe_dead), multipart) = match mode { DropFlagMode::Shallow => (self.ctxt.init_data.maybe_live_dead(path), false), @@ -270,7 +271,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { let tcx = self.tcx; let patch = &mut self.patch; debug!("create_drop_flag({:?})", self.body.span); - self.drop_flags[index].get_or_insert_with(|| patch.new_internal(tcx.types.bool, span)); + self.drop_flags[index].get_or_insert_with(|| patch.new_temp(tcx.types.bool, span)); } fn drop_flag(&mut self, index: MovePathIndex) -> Option> { diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 8a807d786a5b..c16f07a453c3 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -321,7 +321,7 @@ impl<'tcx> TransformVisitor<'tcx> { // Create a statement which reads the discriminant into a temporary fn get_discr(&self, body: &mut Body<'tcx>) -> (Statement<'tcx>, Place<'tcx>) { - let temp_decl = LocalDecl::new(self.discr_ty, body.span).internal(); + let temp_decl = LocalDecl::new(self.discr_ty, body.span); let local_decls_len = body.local_decls.push(temp_decl); let temp = Place::from(local_decls_len); diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 449bade33226..56bdc5a171ac 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -306,6 +306,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } ProjectionElem::Downcast(name, index) => ProjectionElem::Downcast(name, index), ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty), + ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty), }; value = self.insert(Value::Projection(value, proj)); } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index ebd61f8ad953..32dfb7439053 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -218,7 +218,13 @@ impl<'tcx> Inliner<'tcx> { // Normally, this shouldn't be required, but trait normalization failure can create a // validation ICE. let output_type = callee_body.return_ty(); - if !util::is_subtype(self.tcx, self.param_env, output_type, destination_ty) { + if !util::relate_types( + self.tcx, + self.param_env, + ty::Variance::Covariant, + output_type, + destination_ty, + ) { trace!(?output_type, ?destination_ty); return Err("failed to normalize return type"); } @@ -248,7 +254,13 @@ impl<'tcx> Inliner<'tcx> { self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter()) { let input_type = callee_body.local_decls[input].ty; - if !util::is_subtype(self.tcx, self.param_env, input_type, arg_ty) { + if !util::relate_types( + self.tcx, + self.param_env, + ty::Variance::Covariant, + input_type, + arg_ty, + ) { trace!(?arg_ty, ?input_type); return Err("failed to normalize tuple argument type"); } @@ -257,7 +269,13 @@ impl<'tcx> Inliner<'tcx> { for (arg, input) in args.iter().zip(callee_body.args_iter()) { let input_type = callee_body.local_decls[input].ty; let arg_ty = arg.ty(&caller_body.local_decls, self.tcx); - if !util::is_subtype(self.tcx, self.param_env, input_type, arg_ty) { + if !util::relate_types( + self.tcx, + self.param_env, + ty::Variance::Covariant, + input_type, + arg_ty, + ) { trace!(?arg_ty, ?input_type); return Err("failed to normalize argument type"); } @@ -598,9 +616,7 @@ impl<'tcx> Inliner<'tcx> { // If there are any locals without storage markers, give them storage only for the // duration of the call. for local in callee_body.vars_and_temps_iter() { - if !callee_body.local_decls[local].internal - && integrator.always_live_locals.contains(local) - { + if integrator.always_live_locals.contains(local) { let new_local = integrator.map_local(local); caller_body[callsite.block].statements.push(Statement { source_info: callsite.source_info, @@ -623,9 +639,7 @@ impl<'tcx> Inliner<'tcx> { n += 1; } for local in callee_body.vars_and_temps_iter().rev() { - if !callee_body.local_decls[local].internal - && integrator.always_live_locals.contains(local) - { + if integrator.always_live_locals.contains(local) { let new_local = integrator.map_local(local); caller_body[block].statements.push(Statement { source_info: callsite.source_info, diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 9e4bc456d51a..c0a09b7a7612 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -54,6 +54,7 @@ mod check_packed_ref; pub mod check_unsafety; mod remove_place_mention; // This pass is public to allow external drivers to perform MIR cleanup +mod add_subtyping_projections; pub mod cleanup_post_borrowck; mod const_debuginfo; mod const_goto; @@ -480,6 +481,8 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let passes: &[&dyn MirPass<'tcx>] = &[ // These next passes must be executed together &add_call_guards::CriticalCallEdges, + &reveal_all::RevealAll, // has to be done before drop elaboration, since we need to drop opaque types, too. + &add_subtyping_projections::Subtyper, // calling this after reveal_all ensures that we don't deal with opaque types &elaborate_drops::ElaborateDrops, // This will remove extraneous landing pads which are no longer // necessary as well as well as forcing any call in a non-unwinding @@ -526,7 +529,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { body, &[ &check_alignment::CheckAlignment, - &reveal_all::RevealAll, // has to be done before inlining, since inlined code is in RevealAll mode. &lower_slice_len::LowerSliceLenCalls, // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first &unreachable_prop::UnreachablePropagation, &uninhabited_enum_branching::UninhabitedEnumBranching, diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs index 065793348e4c..1626cf3c035e 100644 --- a/compiler/rustc_mir_transform/src/reveal_all.rs +++ b/compiler/rustc_mir_transform/src/reveal_all.rs @@ -8,16 +8,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; pub struct RevealAll; impl<'tcx> MirPass<'tcx> for RevealAll { - fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.mir_opt_level() >= 3 || super::inline::Inline.is_enabled(sess) - } - fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - // Do not apply this transformation to generators. - if body.generator.is_some() { - return; - } - let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); RevealAllVisitor { tcx, param_env }.visit_body_preserves_cfg(body); } @@ -35,13 +26,38 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> { } #[inline] - fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, _: Location) { + fn visit_place( + &mut self, + place: &mut Place<'tcx>, + _context: PlaceContext, + _location: Location, + ) { + // Performance optimization: don't reintern if there is no `OpaqueCast` to remove. + if place.projection.iter().all(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) { + return; + } + // `OpaqueCast` projections are only needed if there are opaque types on which projections are performed. + // After the `RevealAll` pass, all opaque types are replaced with their hidden types, so we don't need these + // projections anymore. + place.projection = self.tcx.mk_place_elems( + &place + .projection + .into_iter() + .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) + .collect::>(), + ); + self.super_place(place, _context, _location); + } + + #[inline] + fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, location: Location) { // We have to use `try_normalize_erasing_regions` here, since it's // possible that we visit impossible-to-satisfy where clauses here, // see #91745 if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.param_env, constant.const_) { constant.const_ = c; } + self.super_constant(constant, location); } #[inline] diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 2795cf157028..73dae0443553 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -441,21 +441,23 @@ fn save_unreachable_coverage( let dead_block = &basic_blocks[dead_block]; for statement in &dead_block.statements { let StatementKind::Coverage(coverage) = &statement.kind else { continue }; - let Some(code_region) = &coverage.code_region else { continue }; + if coverage.code_regions.is_empty() { + continue; + }; let instance = statement.source_info.scope.inlined_instance(source_scopes); if live.contains(&instance) { - retained_coverage.push((statement.source_info, code_region.clone())); + retained_coverage.push((statement.source_info, coverage.code_regions.clone())); } } } let start_block = &mut basic_blocks[START_BLOCK]; start_block.statements.extend(retained_coverage.into_iter().map( - |(source_info, code_region)| Statement { + |(source_info, code_regions)| Statement { source_info, kind: StatementKind::Coverage(Box::new(Coverage { kind: CoverageKind::Unreachable, - code_region: Some(code_region), + code_regions, })), }, )); diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index 3a675752fba9..af9514ed6bb5 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -78,14 +78,10 @@ impl SsaLocals { visitor.assignments[local] = Set1::One(LocationExtended::Arg); } - if body.basic_blocks.len() > 2 { - for (bb, data) in traversal::reverse_postorder(body) { - visitor.visit_basic_block_data(bb, data); - } - } else { - for (bb, data) in body.basic_blocks.iter_enumerated() { - visitor.visit_basic_block_data(bb, data); - } + // For SSA assignments, a RPO visit will see the assignment before it sees any use. + // We only visit reachable nodes: computing `dominates` on an unreachable node ICEs. + for (bb, data) in traversal::reverse_postorder(body) { + visitor.visit_basic_block_data(bb, data); } for var_debug_info in &body.var_debug_info { diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl index 2b7d9bd34139..cf23d79afaf1 100644 --- a/compiler/rustc_monomorphize/messages.ftl +++ b/compiler/rustc_monomorphize/messages.ftl @@ -7,8 +7,6 @@ monomorphize_couldnt_dump_mono_stats = monomorphize_encountered_error_while_instantiating = the above error was encountered while instantiating `{$formatted_item}` -monomorphize_fatal_error = {$error_message} - monomorphize_large_assignments = moving {$size} bytes .label = value moved from here diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 05b6c4062065..88a305e8214d 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -59,7 +59,6 @@ parse_bare_cr = {$double_quotes -> parse_bare_cr_in_raw_string = bare CR not allowed in raw string -parse_binary_float_literal_not_supported = binary float literal is not supported parse_bounds_not_allowed_on_trait_aliases = bounds are not allowed on trait aliases parse_box_not_pat = expected pattern, found {$descr} @@ -284,7 +283,6 @@ parse_generics_in_path = unexpected generic arguments in path parse_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml` parse_help_set_edition_standalone = pass `--edition {$edition}` to `rustc` -parse_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported parse_if_expression_missing_condition = missing condition for `if` expression .condition_label = expected condition here .block_label = if this block is the condition of the `if` expression, then it must be followed by another block @@ -356,8 +354,6 @@ parse_inner_doc_comment_not_permitted = expected outer doc comment .label_does_not_annotate_this = the inner doc comment doesn't annotate this {$item} .sugg_change_inner_to_outer = to annotate the {$item}, change the doc comment from inner to outer style -parse_int_literal_too_large = integer literal is too large - parse_invalid_block_macro_segment = cannot use a `block` macro fragment here .label = the `block` fragment is within this context .suggestion = wrap this in another block @@ -382,18 +378,8 @@ parse_invalid_dyn_keyword = invalid `dyn` keyword .suggestion = remove this keyword parse_invalid_expression_in_let_else = a `{$operator}` expression cannot be directly assigned in `let...else` -parse_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal - .label = invalid suffix `{$suffix}` - .help = valid suffixes are `f32` and `f64` - -parse_invalid_float_literal_width = invalid width `{$width}` for float literal - .help = valid widths are 32 and 64 - parse_invalid_identifier_with_leading_number = identifiers cannot start with a number -parse_invalid_int_literal_width = invalid width `{$width}` for integer literal - .help = valid widths are 8, 16, 32, 64 and 128 - parse_invalid_interpolated_expression = invalid interpolated expression parse_invalid_literal_suffix = suffixes on {$kind} literals are invalid @@ -412,14 +398,6 @@ parse_invalid_logical_operator = `{$incorrect}` is not a logical operator parse_invalid_meta_item = expected unsuffixed literal or identifier, found `{$token}` -parse_invalid_num_literal_base_prefix = invalid base prefix for number literal - .note = base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase - .suggestion = try making the prefix lowercase - -parse_invalid_num_literal_suffix = invalid suffix `{$suffix}` for number literal - .label = invalid suffix `{$suffix}` - .help = the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) - parse_invalid_unicode_escape = invalid unicode character escape .label = invalid escape .help = unicode escape must {$surrogate -> @@ -603,13 +581,6 @@ parse_no_brace_unicode_escape = incorrect unicode escape sequence parse_no_digits_literal = no valid digits found for number -parse_non_item_in_item_list = non-item in item list - .suggestion_use_const_not_let = consider using `const` instead of `let` for associated const - .label_list_start = item list starts here - .label_non_item = non-item starts here - .label_list_end = item list ends here - .suggestion_remove_semicolon = consider removing this semicolon - parse_non_string_abi_literal = non-string ABI literal .suggestion = specify the ABI with a string literal @@ -626,7 +597,6 @@ parse_note_mut_pattern_usage = `mut` may be followed by `variable` and `variable parse_note_pattern_alternatives_use_single_vert = alternatives in or-patterns are separated with `|`, not `||` -parse_octal_float_literal_not_supported = octal float literal is not supported parse_or_pattern_not_allowed_in_fn_parameters = top-level or-patterns are not allowed in function parameters parse_or_pattern_not_allowed_in_let_binding = top-level or-patterns are not allowed in `let` bindings parse_out_of_range_hex_escape = out of range hex escape diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index aad4edaba90b..cc54cc5bebbd 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -813,7 +813,12 @@ impl<'a> Parser<'a> { fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemInfo> { let unsafety = self.parse_unsafety(Case::Sensitive); // Parse optional `auto` prefix. - let is_auto = if self.eat_keyword(kw::Auto) { IsAuto::Yes } else { IsAuto::No }; + let is_auto = if self.eat_keyword(kw::Auto) { + self.sess.gated_spans.gate(sym::auto_traits, self.prev_token.span); + IsAuto::Yes + } else { + IsAuto::No + }; self.expect_keyword(kw::Trait)?; let ident = self.parse_ident()?; diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index a25b0f1f8930..0a64b2f806a5 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -247,7 +247,7 @@ impl<'a> Parser<'a> { )?; FnRetTy::Ty(ty) } else { - FnRetTy::Default(self.token.span.shrink_to_lo()) + FnRetTy::Default(self.prev_token.span.shrink_to_hi()) }) } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 493daf314ced..f853039f72ce 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -1,6 +1,7 @@ -// This implements the dead-code warning pass. It follows middle::reachable -// closely. The idea is that all reachable symbols are live, codes called -// from live codes are live, and everything else is dead. +// This implements the dead-code warning pass. +// All reachable symbols are live, code called from live code is live, code with certain lint +// expectations such as `#[expect(unused)]` and `#[expect(dead_code)]` is live, and everything else +// is dead. use hir::def_id::{LocalDefIdMap, LocalDefIdSet}; use itertools::Itertools; @@ -747,7 +748,7 @@ fn live_symbols_and_ignored_derived_traits( (symbol_visitor.live_symbols, symbol_visitor.ignored_derived_traits) } -struct DeadVariant { +struct DeadItem { def_id: LocalDefId, name: Symbol, level: lint::Level, @@ -785,7 +786,13 @@ impl<'tcx> DeadVisitor<'tcx> { ShouldWarnAboutField::Yes(is_positional) } - fn warn_multiple_dead_codes( + // # Panics + // All `dead_codes` must have the same lint level, otherwise we will intentionally ICE. + // This is because we emit a multi-spanned lint using the lint level of the `dead_codes`'s + // first local def id. + // Prefer calling `Self.warn_dead_code` or `Self.warn_dead_code_grouped_by_lint_level` + // since those methods group by lint level before calling this method. + fn lint_at_single_level( &self, dead_codes: &[LocalDefId], participle: &str, @@ -796,6 +803,15 @@ impl<'tcx> DeadVisitor<'tcx> { return; }; let tcx = self.tcx; + + let first_hir_id = tcx.hir().local_def_id_to_hir_id(first_id); + let first_lint_level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, first_hir_id).0; + assert!(dead_codes.iter().skip(1).all(|id| { + let hir_id = tcx.hir().local_def_id_to_hir_id(*id); + let level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0; + level == first_lint_level + })); + let names: Vec<_> = dead_codes.iter().map(|&def_id| tcx.item_name(def_id.to_def_id())).collect(); let spans: Vec<_> = dead_codes @@ -876,31 +892,26 @@ impl<'tcx> DeadVisitor<'tcx> { } }; - self.tcx.emit_spanned_lint( - lint, - tcx.hir().local_def_id_to_hir_id(first_id), - MultiSpan::from_spans(spans), - diag, - ); + self.tcx.emit_spanned_lint(lint, first_hir_id, MultiSpan::from_spans(spans), diag); } - fn warn_dead_fields_and_variants( + fn warn_multiple( &self, def_id: LocalDefId, participle: &str, - dead_codes: Vec, + dead_codes: Vec, is_positional: bool, ) { let mut dead_codes = dead_codes .iter() .filter(|v| !v.name.as_str().starts_with('_')) - .collect::>(); + .collect::>(); if dead_codes.is_empty() { return; } dead_codes.sort_by_key(|v| v.level); for (_, group) in &dead_codes.into_iter().group_by(|v| v.level) { - self.warn_multiple_dead_codes( + self.lint_at_single_level( &group.map(|v| v.def_id).collect::>(), participle, Some(def_id), @@ -910,7 +921,7 @@ impl<'tcx> DeadVisitor<'tcx> { } fn warn_dead_code(&mut self, id: LocalDefId, participle: &str) { - self.warn_multiple_dead_codes(&[id], participle, None, false); + self.lint_at_single_level(&[id], participle, None, false); } fn check_definition(&mut self, def_id: LocalDefId) { @@ -954,17 +965,16 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) { if let hir::ItemKind::Impl(impl_item) = tcx.hir().item(item).kind { let mut dead_items = Vec::new(); for item in impl_item.items { - let did = item.id.owner_id.def_id; - if !visitor.is_live_code(did) { - dead_items.push(did) + let def_id = item.id.owner_id.def_id; + if !visitor.is_live_code(def_id) { + let name = tcx.item_name(def_id.to_def_id()); + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); + let level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0; + + dead_items.push(DeadItem { def_id, name, level }) } } - visitor.warn_multiple_dead_codes( - &dead_items, - "used", - Some(item.owner_id.def_id), - false, - ); + visitor.warn_multiple(item.owner_id.def_id, "used", dead_items, false); } if !live_symbols.contains(&item.owner_id.def_id) { @@ -988,7 +998,7 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) { // Record to group diagnostics. let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); let level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0; - dead_variants.push(DeadVariant { def_id, name: variant.name, level }); + dead_variants.push(DeadItem { def_id, name: variant.name, level }); continue; } @@ -1013,21 +1023,16 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) { hir_id, ) .0; - Some(DeadVariant { def_id, name: field.name, level }) + Some(DeadItem { def_id, name: field.name, level }) } else { None } }) .collect(); - visitor.warn_dead_fields_and_variants(def_id, "read", dead_fields, is_positional) + visitor.warn_multiple(def_id, "read", dead_fields, is_positional); } - visitor.warn_dead_fields_and_variants( - item.owner_id.def_id, - "constructed", - dead_variants, - false, - ); + visitor.warn_multiple(item.owner_id.def_id, "constructed", dead_variants, false); } } diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index 4f71704b8853..c92d0b878eaf 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -52,31 +52,6 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> { configure_main(tcx, &ctxt) } -// Beware, this is duplicated in `librustc_builtin_macros/test_harness.rs` -// (with `ast::Item`), so make sure to keep them in sync. -// A small optimization was added so that hir::Item is fetched only when needed. -// An equivalent optimization was not applied to the duplicated code in test_harness.rs. -fn entry_point_type(ctxt: &EntryContext<'_>, id: ItemId, at_root: bool) -> EntryPointType { - let attrs = ctxt.tcx.hir().attrs(id.hir_id()); - if attr::contains_name(attrs, sym::start) { - EntryPointType::Start - } else if attr::contains_name(attrs, sym::rustc_main) { - EntryPointType::RustcMainAttr - } else { - if let Some(name) = ctxt.tcx.opt_item_name(id.owner_id.to_def_id()) - && name == sym::main { - if at_root { - // This is a top-level function so can be `main`. - EntryPointType::MainNamed - } else { - EntryPointType::OtherMain - } - } else { - EntryPointType::None - } - } -} - fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Option { let attrs = ctxt.tcx.hir().attrs(id.hir_id()); attr::find_by_name(attrs, sym).map(|attr| attr.span) @@ -85,7 +60,13 @@ fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Opti fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) { let at_root = ctxt.tcx.opt_local_parent(id.owner_id.def_id) == Some(CRATE_DEF_ID); - match entry_point_type(ctxt, id, at_root) { + let attrs = ctxt.tcx.hir().attrs(id.hir_id()); + let entry_point_type = rustc_ast::entry::entry_point_type( + attrs, + at_root, + ctxt.tcx.opt_item_name(id.owner_id.to_def_id()), + ); + match entry_point_type { EntryPointType::None => { if let Some(span) = attr_span_by_symbol(ctxt, id, sym::unix_sigpipe) { ctxt.tcx.sess.emit_err(AttrOnlyOnMain { span, attr: sym::unix_sigpipe }); diff --git a/compiler/rustc_query_system/messages.ftl b/compiler/rustc_query_system/messages.ftl index d5fed8fe179f..d7ab75575111 100644 --- a/compiler/rustc_query_system/messages.ftl +++ b/compiler/rustc_query_system/messages.ftl @@ -15,8 +15,6 @@ query_system_cycle_stack_single = ...which immediately requires {$stack_bottom} query_system_cycle_usage = cycle used when {$usage} -query_system_cycle_which_requires = ...which requires {$desc}... - query_system_increment_compilation = internal compiler error: encountered incremental compilation error with {$dep_node} .help = This is a known issue with the compiler. Run {$run_cmd} to allow your project to compile diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 9a970f5db397..272483d4a987 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -130,9 +130,6 @@ resolve_generic_params_from_outer_item_ty_param = type parameter from outer item resolve_glob_import_doesnt_reexport = glob import doesn't reexport anything because no candidate is public enough -resolve_help_try_using_local_generic_param = - try using a local generic parameter instead - resolve_ident_bound_more_than_once_in_parameter_list = identifier `{$identifier}` is bound more than once in this parameter list .label = used as parameter more than once @@ -249,9 +246,6 @@ resolve_self_in_generic_param_default = generic parameters cannot use `Self` in their defaults .label = `Self` in generic parameter default -resolve_self_type_implicitly_declared_by_impl = - `Self` type implicitly declared here, by this `impl` - resolve_tool_module_imported = cannot use a tool module through an import .note = the tool module imported here @@ -267,12 +261,6 @@ resolve_trait_impl_mismatch = .label = does not match trait .label_trait_item = item in trait -resolve_try_adding_local_generic_param_on_method = - try adding a local generic parameter in this method instead - -resolve_try_using_local_generic_parameter = - try using a local generic parameter instead - resolve_try_using_similarly_named_label = try using similarly named label diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 907a6b1c46c6..110286255c5c 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1169,6 +1169,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { return; } + if ident.name == kw::Underscore { + return; + } + let child_accessible = accessible && this.is_accessible_from(name_binding.vis, parent_scope.module); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index c3c43346ed82..ece8b7f6ec96 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -41,9 +41,6 @@ type Res = def::Res; type IdentMap = FxHashMap; -/// Map from the name in a pattern to its binding mode. -type BindingMap = IdentMap; - use diagnostics::{ ElisionFnParameter, LifetimeElisionCandidate, MissingLifetime, MissingLifetimeKind, }; @@ -3164,8 +3161,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { /// this is done hygienically. This could arise for a macro /// that expands into an or-pattern where one 'x' was from the /// user and one 'x' came from the macro. - fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap { - let mut binding_map = FxHashMap::default(); + fn binding_mode_map(&mut self, pat: &Pat) -> FxIndexMap { + let mut binding_map = FxIndexMap::default(); pat.walk(&mut |pat| { match pat.kind { @@ -3200,22 +3197,28 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { /// Checks that all of the arms in an or-pattern have exactly the /// same set of bindings, with the same binding modes for each. - fn check_consistent_bindings(&mut self, pats: &[P]) -> Vec { - let mut missing_vars = FxHashMap::default(); - let mut inconsistent_vars = FxHashMap::default(); + fn check_consistent_bindings( + &mut self, + pats: &[P], + ) -> Vec> { + // pats is consistent. + let mut missing_vars = FxIndexMap::default(); + let mut inconsistent_vars = FxIndexMap::default(); // 1) Compute the binding maps of all arms. let maps = pats.iter().map(|pat| self.binding_mode_map(pat)).collect::>(); // 2) Record any missing bindings or binding mode inconsistencies. - for (map_outer, pat_outer) in pats.iter().enumerate().map(|(idx, pat)| (&maps[idx], pat)) { + for (map_outer, pat_outer) in maps.iter().zip(pats.iter()) { // Check against all arms except for the same pattern which is always self-consistent. - let inners = pats + let inners = maps .iter() - .enumerate() + .zip(pats.iter()) .filter(|(_, pat)| pat.id != pat_outer.id) - .flat_map(|(idx, _)| maps[idx].iter()) - .map(|(key, binding)| (key.name, map_outer.get(&key), binding)); + .flat_map(|(map, _)| map) + .map(|(key, binding)| (key.name, map_outer.get(key), binding)); + + let inners = inners.collect::>(); for (name, info, &binding_inner) in inners { match info { @@ -3244,10 +3247,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } // 3) Report all missing variables we found. - let mut missing_vars = missing_vars.into_iter().collect::>(); - missing_vars.sort_by_key(|&(sym, ref _err)| sym); - - for (name, mut v) in missing_vars.into_iter() { + for (name, mut v) in missing_vars { if inconsistent_vars.contains_key(&name) { v.could_be_path = false; } @@ -3258,10 +3258,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } // 4) Report all inconsistencies in binding modes we found. - let mut inconsistent_vars = inconsistent_vars.iter().collect::>(); - inconsistent_vars.sort(); for (name, v) in inconsistent_vars { - self.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(*name, v.1)); + self.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(name, v.1)); } // 5) Finally bubble up all the binding maps. @@ -4140,6 +4138,12 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { }); } + fn resolve_expr_field(&mut self, f: &'ast ExprField, e: &'ast Expr) { + self.resolve_expr(&f.expr, Some(e)); + self.visit_ident(f.ident); + walk_list!(self, visit_attribute, f.attrs.iter()); + } + fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) { // First, record candidate traits for this expression if it could // result in the invocation of a method call. @@ -4155,7 +4159,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { ExprKind::Struct(ref se) => { self.smart_resolve_path(expr.id, &se.qself, &se.path, PathSource::Struct); - visit::walk_expr(self, expr); + // This is the same as `visit::walk_expr(self, expr);`, but we want to pass the + // parent in for accurate suggestions when encountering `Foo { bar }` that should + // have been `Foo { bar: self.bar }`. + if let Some(qself) = &se.qself { + self.visit_ty(&qself.ty); + } + self.visit_path(&se.path, expr.id); + walk_list!(self, resolve_expr_field, &se.fields, expr); + match &se.rest { + StructRest::Base(expr) => self.visit_expr(expr), + StructRest::Rest(_span) => {} + StructRest::None => {} + } } ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index adddc419dafb..bc5f8a37b0ff 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -41,7 +41,7 @@ type Res = def::Res; /// A field or associated item from self type suggested in case of resolution failure. enum AssocSuggestion { - Field, + Field(Span), MethodWithSelf { called: bool }, AssocFn { called: bool }, AssocType, @@ -51,7 +51,7 @@ enum AssocSuggestion { impl AssocSuggestion { fn action(&self) -> &'static str { match self { - AssocSuggestion::Field => "use the available field", + AssocSuggestion::Field(_) => "use the available field", AssocSuggestion::MethodWithSelf { called: true } => { "call the method with the fully-qualified path" } @@ -215,7 +215,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } } else { let mut span_label = None; - let item_span = path.last().unwrap().ident.span; + let item_ident = path.last().unwrap().ident; + let item_span = item_ident.span; let (mod_prefix, mod_str, module, suggestion) = if path.len() == 1 { debug!(?self.diagnostic_metadata.current_impl_items); debug!(?self.diagnostic_metadata.current_function); @@ -231,9 +232,35 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { }) { let sp = item_span.shrink_to_lo(); + + // Account for `Foo { field }` when suggesting `self.field` so we result on + // `Foo { field: self.field }`. + let field = match source { + PathSource::Expr(Some(Expr { kind: ExprKind::Struct(expr), .. })) => { + expr.fields.iter().find(|f| f.ident == item_ident) + } + _ => None, + }; + let pre = if let Some(field) = field && field.is_shorthand { + format!("{item_ident}: ") + } else { + String::new() + }; + // Ensure we provide a structured suggestion for an assoc fn only for + // expressions that are actually a fn call. + let is_call = match field { + Some(ast::ExprField { expr, .. }) => { + matches!(expr.kind, ExprKind::Call(..)) + } + _ => matches!( + source, + PathSource::Expr(Some(Expr { kind: ExprKind::Call(..), ..})), + ), + }; + match &item.kind { AssocItemKind::Fn(fn_) - if !sig.decl.has_self() && fn_.sig.decl.has_self() => { + if (!sig.decl.has_self() || !is_call) && fn_.sig.decl.has_self() => { // Ensure that we only suggest `self.` if `self` is available, // you can't call `fn foo(&self)` from `fn bar()` (#115992). // We also want to mention that the method exists. @@ -243,20 +270,28 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { )); None } + AssocItemKind::Fn(fn_) + if !fn_.sig.decl.has_self() && !is_call => { + span_label = Some(( + item.ident.span, + "an associated function by that name is available on `Self` here", + )); + None + } AssocItemKind::Fn(fn_) if fn_.sig.decl.has_self() => Some(( sp, "consider using the method on `Self`", - "self.".to_string(), + format!("{pre}self."), )), AssocItemKind::Fn(_) => Some(( sp, "consider using the associated function on `Self`", - "Self::".to_string(), + format!("{pre}Self::"), )), AssocItemKind::Const(..) => Some(( sp, "consider using the associated constant on `Self`", - "Self::".to_string(), + format!("{pre}Self::"), )), _ => None } @@ -621,17 +656,30 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { self.lookup_assoc_candidate(ident, ns, is_expected, source.is_call()) { let self_is_available = self.self_value_is_available(path[0].ident.span); + // Account for `Foo { field }` when suggesting `self.field` so we result on + // `Foo { field: self.field }`. + let pre = match source { + PathSource::Expr(Some(Expr { kind: ExprKind::Struct(expr), .. })) + if expr + .fields + .iter() + .any(|f| f.ident == path[0].ident && f.is_shorthand) => + { + format!("{path_str}: ") + } + _ => String::new(), + }; match candidate { - AssocSuggestion::Field => { + AssocSuggestion::Field(field_span) => { if self_is_available { - err.span_suggestion( - span, + err.span_suggestion_verbose( + span.shrink_to_lo(), "you might have meant to use the available field", - format!("self.{path_str}"), + format!("{pre}self."), Applicability::MachineApplicable, ); } else { - err.span_label(span, "a field by this name exists in `Self`"); + err.span_label(field_span, "a field by that name exists in `Self`"); } } AssocSuggestion::MethodWithSelf { called } if self_is_available => { @@ -640,10 +688,10 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } else { "you might have meant to refer to the method" }; - err.span_suggestion( - span, + err.span_suggestion_verbose( + span.shrink_to_lo(), msg, - format!("self.{path_str}"), + "self.".to_string(), Applicability::MachineApplicable, ); } @@ -651,10 +699,10 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { | AssocSuggestion::AssocFn { .. } | AssocSuggestion::AssocConst | AssocSuggestion::AssocType => { - err.span_suggestion( - span, + err.span_suggestion_verbose( + span.shrink_to_lo(), format!("you might have meant to {}", candidate.action()), - format!("Self::{path_str}"), + "Self::".to_string(), Applicability::MachineApplicable, ); } @@ -1667,11 +1715,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { resolution.full_res() { if let Some(field_ids) = self.r.field_def_ids(did) { - if field_ids + if let Some(field_id) = field_ids .iter() - .any(|&field_id| ident.name == self.r.tcx.item_name(field_id)) + .find(|&&field_id| ident.name == self.r.tcx.item_name(field_id)) { - return Some(AssocSuggestion::Field); + return Some(AssocSuggestion::Field(self.r.def_span(*field_id))); } } } diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index e06b63809445..b356b503aa54 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -25,8 +25,6 @@ session_feature_diagnostic_for_issue = session_feature_diagnostic_help = add `#![feature({$feature})]` to the crate attributes to enable -session_feature_gate_error = {$explain} - session_file_is_not_writeable = output file {$file} is not writeable -- check its permissions session_file_write_fail = failed to write `{$path}` due to error `{$err}` diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 441aafd1257b..1a9dea99f643 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -86,6 +86,10 @@ impl<'tcx> Tables<'tcx> { stable_mir::ty::ImplDef(self.create_def_id(did)) } + pub fn region_def(&mut self, did: DefId) -> stable_mir::ty::RegionDef { + stable_mir::ty::RegionDef(self.create_def_id(did)) + } + pub fn prov(&mut self, aid: AllocId) -> stable_mir::ty::Prov { stable_mir::ty::Prov(self.create_alloc_id(aid)) } diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 5ff17613b4e5..7d1122c2fd21 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,14 +7,15 @@ //! //! For now, we are developing everything inside `rustc`, thus, we keep this module private. -use hir::def::DefKind; +use crate::rustc_smir::hir::def::DefKind; +use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region}; use rustc_hir as hir; use rustc_middle::mir; use rustc_middle::mir::interpret::{alloc_range, AllocId}; use rustc_middle::ty::{self, Ty, TyCtxt, Variance}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_target::abi::FieldIdx; -use stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; +use stable_mir::mir::{CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx}; use stable_mir::ty::{FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy}; use stable_mir::{self, opaque, Context}; use tracing::debug; @@ -105,7 +106,14 @@ impl<'tcx> Context for Tables<'tcx> { .collect(), }) .collect(), - locals: mir.local_decls.iter().map(|decl| self.intern_ty(decl.ty)).collect(), + locals: mir + .local_decls + .iter() + .map(|decl| stable_mir::mir::LocalDecl { + ty: self.intern_ty(decl.ty), + span: decl.source_info.span.stable(self), + }) + .collect(), } } @@ -222,41 +230,64 @@ pub(crate) trait Stable<'tcx> { impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> { type T = stable_mir::mir::Statement; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use rustc_middle::mir::StatementKind::*; - match &self.kind { - Assign(assign) => { - stable_mir::mir::Statement::Assign(assign.0.stable(tables), assign.1.stable(tables)) - } - FakeRead(fake_read_place) => stable_mir::mir::Statement::FakeRead( - fake_read_place.0.stable(tables), - fake_read_place.1.stable(tables), + Statement { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) } + } +} + +impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> { + type T = stable_mir::mir::StatementKind; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + match self { + mir::StatementKind::Assign(assign) => stable_mir::mir::StatementKind::Assign( + assign.0.stable(tables), + assign.1.stable(tables), ), - SetDiscriminant { place: plc, variant_index: idx } => { - stable_mir::mir::Statement::SetDiscriminant { - place: plc.as_ref().stable(tables), - variant_index: idx.stable(tables), + mir::StatementKind::FakeRead(fake_read_place) => { + stable_mir::mir::StatementKind::FakeRead( + fake_read_place.0.stable(tables), + fake_read_place.1.stable(tables), + ) + } + mir::StatementKind::SetDiscriminant { place, variant_index } => { + stable_mir::mir::StatementKind::SetDiscriminant { + place: place.as_ref().stable(tables), + variant_index: variant_index.stable(tables), } } - Deinit(place) => stable_mir::mir::Statement::Deinit(place.stable(tables)), - StorageLive(place) => stable_mir::mir::Statement::StorageLive(place.stable(tables)), - StorageDead(place) => stable_mir::mir::Statement::StorageDead(place.stable(tables)), - Retag(retag, place) => { - stable_mir::mir::Statement::Retag(retag.stable(tables), place.stable(tables)) + mir::StatementKind::Deinit(place) => { + stable_mir::mir::StatementKind::Deinit(place.stable(tables)) } - PlaceMention(place) => stable_mir::mir::Statement::PlaceMention(place.stable(tables)), - AscribeUserType(place_projection, variance) => { - stable_mir::mir::Statement::AscribeUserType { + + mir::StatementKind::StorageLive(place) => { + stable_mir::mir::StatementKind::StorageLive(place.stable(tables)) + } + + mir::StatementKind::StorageDead(place) => { + stable_mir::mir::StatementKind::StorageDead(place.stable(tables)) + } + mir::StatementKind::Retag(retag, place) => { + stable_mir::mir::StatementKind::Retag(retag.stable(tables), place.stable(tables)) + } + mir::StatementKind::PlaceMention(place) => { + stable_mir::mir::StatementKind::PlaceMention(place.stable(tables)) + } + mir::StatementKind::AscribeUserType(place_projection, variance) => { + stable_mir::mir::StatementKind::AscribeUserType { place: place_projection.as_ref().0.stable(tables), projections: place_projection.as_ref().1.stable(tables), variance: variance.stable(tables), } } - Coverage(coverage) => stable_mir::mir::Statement::Coverage(opaque(coverage)), - Intrinsic(intrinstic) => { - stable_mir::mir::Statement::Intrinsic(intrinstic.stable(tables)) + mir::StatementKind::Coverage(coverage) => { + stable_mir::mir::StatementKind::Coverage(opaque(coverage)) } - ConstEvalCounter => stable_mir::mir::Statement::ConstEvalCounter, - Nop => stable_mir::mir::Statement::Nop, + mir::StatementKind::Intrinsic(intrinstic) => { + stable_mir::mir::StatementKind::Intrinsic(intrinstic.stable(tables)) + } + mir::StatementKind::ConstEvalCounter => { + stable_mir::mir::StatementKind::ConstEvalCounter + } + mir::StatementKind::Nop => stable_mir::mir::StatementKind::Nop, } } } @@ -805,11 +836,20 @@ impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> { impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> { type T = stable_mir::mir::Terminator; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use rustc_middle::mir::TerminatorKind::*; use stable_mir::mir::Terminator; - match &self.kind { - Goto { target } => Terminator::Goto { target: target.as_usize() }, - SwitchInt { discr, targets } => Terminator::SwitchInt { + Terminator { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) } + } +} + +impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> { + type T = stable_mir::mir::TerminatorKind; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::mir::TerminatorKind; + match self { + mir::TerminatorKind::Goto { target } => { + TerminatorKind::Goto { target: target.as_usize() } + } + mir::TerminatorKind::SwitchInt { discr, targets } => TerminatorKind::SwitchInt { discr: discr.stable(tables), targets: targets .iter() @@ -820,42 +860,60 @@ impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> { .collect(), otherwise: targets.otherwise().as_usize(), }, - UnwindResume => Terminator::Resume, - UnwindTerminate(_) => Terminator::Abort, - Return => Terminator::Return, - Unreachable => Terminator::Unreachable, - Drop { place, target, unwind, replace: _ } => Terminator::Drop { - place: place.stable(tables), - target: target.as_usize(), - unwind: unwind.stable(tables), - }, - Call { func, args, destination, target, unwind, call_source: _, fn_span: _ } => { - Terminator::Call { - func: func.stable(tables), - args: args.iter().map(|arg| arg.stable(tables)).collect(), - destination: destination.stable(tables), - target: target.map(|t| t.as_usize()), + mir::TerminatorKind::UnwindResume => TerminatorKind::Resume, + mir::TerminatorKind::UnwindTerminate(_) => TerminatorKind::Abort, + mir::TerminatorKind::Return => TerminatorKind::Return, + mir::TerminatorKind::Unreachable => TerminatorKind::Unreachable, + mir::TerminatorKind::Drop { place, target, unwind, replace: _ } => { + TerminatorKind::Drop { + place: place.stable(tables), + target: target.as_usize(), unwind: unwind.stable(tables), } } - Assert { cond, expected, msg, target, unwind } => Terminator::Assert { - cond: cond.stable(tables), - expected: *expected, - msg: msg.stable(tables), - target: target.as_usize(), + mir::TerminatorKind::Call { + func, + args, + destination, + target, + unwind, + call_source: _, + fn_span: _, + } => TerminatorKind::Call { + func: func.stable(tables), + args: args.iter().map(|arg| arg.stable(tables)).collect(), + destination: destination.stable(tables), + target: target.map(|t| t.as_usize()), unwind: unwind.stable(tables), }, - InlineAsm { template, operands, options, line_spans, destination, unwind } => { - Terminator::InlineAsm { - template: format!("{template:?}"), - operands: operands.iter().map(|operand| operand.stable(tables)).collect(), - options: format!("{options:?}"), - line_spans: format!("{line_spans:?}"), - destination: destination.map(|d| d.as_usize()), + mir::TerminatorKind::Assert { cond, expected, msg, target, unwind } => { + TerminatorKind::Assert { + cond: cond.stable(tables), + expected: *expected, + msg: msg.stable(tables), + target: target.as_usize(), unwind: unwind.stable(tables), } } - Yield { .. } | GeneratorDrop | FalseEdge { .. } | FalseUnwind { .. } => unreachable!(), + mir::TerminatorKind::InlineAsm { + template, + operands, + options, + line_spans, + destination, + unwind, + } => TerminatorKind::InlineAsm { + template: format!("{template:?}"), + operands: operands.iter().map(|operand| operand.stable(tables)).collect(), + options: format!("{options:?}"), + line_spans: format!("{line_spans:?}"), + destination: destination.map(|d| d.as_usize()), + unwind: unwind.stable(tables), + }, + mir::TerminatorKind::Yield { .. } + | mir::TerminatorKind::GeneratorDrop + | mir::TerminatorKind::FalseEdge { .. } + | mir::TerminatorKind::FalseUnwind { .. } => unreachable!(), } } } @@ -1500,9 +1558,39 @@ impl<'tcx> Stable<'tcx> for ty::ImplPolarity { impl<'tcx> Stable<'tcx> for ty::Region<'tcx> { type T = stable_mir::ty::Region; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - // FIXME: add a real implementation of stable regions - opaque(self) + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + Region { kind: self.kind().stable(tables) } + } +} + +impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { + type T = stable_mir::ty::RegionKind; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::RegionKind; + match self { + ty::ReEarlyBound(early_reg) => RegionKind::ReEarlyBound(EarlyBoundRegion { + def_id: tables.region_def(early_reg.def_id), + index: early_reg.index, + name: early_reg.name.to_string(), + }), + ty::ReLateBound(db_index, bound_reg) => RegionKind::ReLateBound( + db_index.as_u32(), + BoundRegion { var: bound_reg.var.as_u32(), kind: bound_reg.kind.stable(tables) }, + ), + ty::ReStatic => RegionKind::ReStatic, + ty::RePlaceholder(place_holder) => { + RegionKind::RePlaceholder(stable_mir::ty::Placeholder { + universe: place_holder.universe.as_u32(), + bound: BoundRegion { + var: place_holder.bound.var.as_u32(), + kind: place_holder.bound.kind.stable(tables), + }, + }) + } + ty::ReErased => RegionKind::ReErased, + _ => unreachable!("{self:?}"), + } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 382754be2ca8..a62fa246ac41 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -129,9 +129,11 @@ symbols! { Alignment, Any, Arc, + ArcWeak, Argument, ArgumentMethods, Arguments, + ArrayIntoIter, AsMut, AsRef, AssertParamIsClone, @@ -164,6 +166,7 @@ symbols! { Capture, Center, Clone, + Command, ConstParamTy, Context, Continue, @@ -171,6 +174,7 @@ symbols! { Count, Cow, Debug, + DebugStruct, Decodable, Decoder, DecorateLint, @@ -194,6 +198,8 @@ symbols! { From, FromIterator, FromResidual, + FsOpenOptions, + FsPermissions, Future, FutureOutput, FxHashMap, @@ -207,16 +213,22 @@ symbols! { Implied, IndexOutput, Input, + Instant, Into, IntoDiagnostic, IntoFuture, IntoIterator, + IoLines, IoRead, + IoSeek, IoWrite, IpAddr, IrTyKind, Is, ItemContext, + IterEmpty, + IterOnce, + IterPeekable, Iterator, IteratorItem, Layout, @@ -227,6 +239,7 @@ symbols! { Mutex, MutexGuard, N, + NonNull, NonZeroI128, NonZeroI16, NonZeroI32, @@ -259,15 +272,19 @@ symbols! { ProcMacro, ProceduralMasqueradeDummyType, Range, + RangeBounds, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive, Rc, + RcWeak, Ready, Receiver, RefCell, + RefCellRef, + RefCellRefMut, Relaxed, Release, Result, @@ -284,6 +301,7 @@ symbols! { Send, SeqCst, SliceIndex, + SliceIter, Some, String, StructuralEq, @@ -561,6 +579,7 @@ symbols! { constant, constructor, context, + convert_identity, copy, copy_closures, copy_nonoverlapping, @@ -616,6 +635,7 @@ symbols! { declare_lint_pass, decode, default_alloc_error_handler, + default_fn, default_lib_allocator, default_method_body_is_const, default_type_parameter_fallback, @@ -628,6 +648,7 @@ symbols! { deref, deref_method, deref_mut, + deref_mut_method, deref_target, derive, derive_const, @@ -777,11 +798,14 @@ symbols! { from_desugaring, from_fn, from_iter, + from_iter_fn, from_output, from_residual, from_size_align_unchecked, + from_str_method, from_usize, from_yeet, + fs_create_dir, fsub_fast, fundamental, future, @@ -868,6 +892,10 @@ symbols! { into_iter, intra_doc_pointers, intrinsics, + intrinsics_unaligned_volatile_load, + intrinsics_unaligned_volatile_store, + io_stderr, + io_stdout, irrefutable_let_patterns, isa_attribute, isize, @@ -962,6 +990,7 @@ symbols! { mem_replace, mem_size_of, mem_size_of_val, + mem_swap, mem_uninitialized, mem_variant_count, mem_zeroed, @@ -1091,6 +1120,7 @@ symbols! { options, or, or_patterns, + ord_cmp_method, other, out, overflow_checks, @@ -1104,7 +1134,6 @@ symbols! { panic_abort, panic_bounds_check, panic_cannot_unwind, - panic_display, panic_fmt, panic_handler, panic_impl, @@ -1172,6 +1201,7 @@ symbols! { proc_macro_mod, proc_macro_non_items, proc_macro_path_invoc, + process_exit, profiler_builtins, profiler_runtime, ptr, @@ -1179,6 +1209,10 @@ symbols! { ptr_cast_const, ptr_cast_mut, ptr_const_is_null, + ptr_copy, + ptr_copy_nonoverlapping, + ptr_drop_in_place, + ptr_eq, ptr_from_ref, ptr_guaranteed_cmp, ptr_is_null, @@ -1187,8 +1221,17 @@ symbols! { ptr_null_mut, ptr_offset_from, ptr_offset_from_unsigned, + ptr_read, + ptr_read_unaligned, + ptr_read_volatile, + ptr_replace, + ptr_slice_from_raw_parts, + ptr_slice_from_raw_parts_mut, + ptr_swap, + ptr_swap_nonoverlapping, ptr_unique, ptr_write, + ptr_write_bytes, ptr_write_unaligned, ptr_write_volatile, pub_macro_rules, @@ -1299,6 +1342,7 @@ symbols! { rustc_coherence_is_core, rustc_coinductive, rustc_confusables, + rustc_const_panic_str, rustc_const_stable, rustc_const_unstable, rustc_conversion_suggestion, @@ -1465,6 +1509,7 @@ symbols! { simd_shl, simd_shr, simd_shuffle, + simd_shuffle_generic, simd_sub, simd_trunc, simd_xor, @@ -1477,6 +1522,8 @@ symbols! { sized, skip, slice, + slice_from_raw_parts, + slice_from_raw_parts_mut, slice_len_fn, slice_patterns, slicing_syntax, @@ -1564,7 +1611,9 @@ symbols! { thumb2, thumb_mode: "thumb-mode", tmm_reg, + to_owned_method, to_string, + to_string_method, to_vec, todo_macro, tool_attributes, @@ -1587,6 +1636,7 @@ symbols! { try_blocks, try_capture, try_from, + try_from_fn, try_into, try_trait_v2, tt, diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml index 393e59e8b007..a91eb41b18ae 100644 --- a/compiler/rustc_target/Cargo.toml +++ b/compiler/rustc_target/Cargo.toml @@ -14,6 +14,7 @@ rustc_feature = { path = "../rustc_feature" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } +rustc_index = { path = "../rustc_index" } [dependencies.object] version = "0.32.0" diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 74fe98920c45..f6f8b53d130b 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -1,3 +1,4 @@ +use rustc_data_structures::intern::Interned; pub use Integer::*; pub use Primitive::*; @@ -18,6 +19,111 @@ impl ToJson for Endian { } } +rustc_index::newtype_index! { + /// The *source-order* index of a field in a variant. + /// + /// This is how most code after type checking refers to fields, rather than + /// using names (as names have hygiene complications and more complex lookup). + /// + /// Particularly for `repr(Rust)` types, this may not be the same as *layout* order. + /// (It is for `repr(C)` `struct`s, however.) + /// + /// For example, in the following types, + /// ```rust + /// # enum Never {} + /// # #[repr(u16)] + /// enum Demo1 { + /// Variant0 { a: Never, b: i32 } = 100, + /// Variant1 { c: u8, d: u64 } = 10, + /// } + /// struct Demo2 { e: u8, f: u16, g: u8 } + /// ``` + /// `b` is `FieldIdx(1)` in `VariantIdx(0)`, + /// `d` is `FieldIdx(1)` in `VariantIdx(1)`, and + /// `f` is `FieldIdx(1)` in `VariantIdx(0)`. + #[derive(HashStable_Generic)] + pub struct FieldIdx {} +} + +rustc_index::newtype_index! { + /// The *source-order* index of a variant in a type. + /// + /// For enums, these are always `0..variant_count`, regardless of any + /// custom discriminants that may have been defined, and including any + /// variants that may end up uninhabited due to field types. (Some of the + /// variants may not be present in a monomorphized ABI [`Variants`], but + /// those skipped variants are always counted when determining the *index*.) + /// + /// `struct`s, `tuples`, and `unions`s are considered to have a single variant + /// with variant index zero, aka [`FIRST_VARIANT`]. + #[derive(HashStable_Generic)] + pub struct VariantIdx { + /// Equivalent to `VariantIdx(0)`. + const FIRST_VARIANT = 0; + } +} +#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)] +#[rustc_pass_by_value] +pub struct Layout<'a>(pub Interned<'a, LayoutS>); + +impl<'a> fmt::Debug for Layout<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // See comment on `::fmt` above. + self.0.0.fmt(f) + } +} + +impl<'a> Deref for Layout<'a> { + type Target = &'a LayoutS; + fn deref(&self) -> &&'a LayoutS { + &self.0.0 + } +} + +impl<'a> Layout<'a> { + pub fn fields(self) -> &'a FieldsShape { + &self.0.0.fields + } + + pub fn variants(self) -> &'a Variants { + &self.0.0.variants + } + + pub fn abi(self) -> Abi { + self.0.0.abi + } + + pub fn largest_niche(self) -> Option { + self.0.0.largest_niche + } + + pub fn align(self) -> AbiAndPrefAlign { + self.0.0.align + } + + pub fn size(self) -> Size { + self.0.0.size + } + + pub fn max_repr_align(self) -> Option { + self.0.0.max_repr_align + } + + pub fn unadjusted_abi_align(self) -> Align { + self.0.0.unadjusted_abi_align + } + + /// Whether the layout is from a type that implements [`std::marker::PointerLike`]. + /// + /// Currently, that means that the type is pointer-sized, pointer-aligned, + /// and has a scalar ABI. + pub fn is_pointer_like(self, data_layout: &TargetDataLayout) -> bool { + self.size() == data_layout.pointer_size + && self.align().abi == data_layout.pointer_align.abi + && matches!(self.abi(), Abi::Scalar(..)) + } +} + /// The layout of a type, alongside the type itself. /// Provides various type traversal APIs (e.g., recursing into fields). /// @@ -42,8 +148,8 @@ impl<'a, Ty: fmt::Display> fmt::Debug for TyAndLayout<'a, Ty> { } impl<'a, Ty> Deref for TyAndLayout<'a, Ty> { - type Target = &'a LayoutS; - fn deref(&self) -> &&'a LayoutS { + type Target = &'a LayoutS; + fn deref(&self) -> &&'a LayoutS { &self.layout.0.0 } } diff --git a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs index 8d80fcd5fe57..624837a22d60 100644 --- a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs @@ -3,7 +3,7 @@ use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions}; // This target if is for the Android v7a ABI in thumb mode with // NEON unconditionally enabled and, therefore, with 32 FPU registers // enabled as well. See section A2.6.2 on page A2-56 in -// https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf +// https://web.archive.org/web/20210307234416/https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf // See https://developer.android.com/ndk/guides/abis.html#v7a // for target ABI requirements. diff --git a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs index 28c81340ad89..b500c50de985 100644 --- a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs @@ -4,7 +4,7 @@ use crate::spec::{Target, TargetOptions}; // (for consistency with Android and Debian-based distributions) // and with NEON unconditionally enabled and, therefore, with 32 FPU // registers enabled as well. See section A2.6.2 on page A2-56 in -// https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf +// https://web.archive.org/web/20210307234416/https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf pub fn target() -> Target { Target { diff --git a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs index 2c375ab22d79..dce0cbcef026 100644 --- a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs @@ -4,7 +4,7 @@ use crate::spec::{Target, TargetOptions}; // (for consistency with Android and Debian-based distributions) // and with NEON unconditionally enabled and, therefore, with 32 FPU // registers enabled as well. See section A2.6.2 on page A2-56 in -// https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf +// https://web.archive.org/web/20210307234416/https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf pub fn target() -> Target { Target { diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 0f9d36342ad2..339a3e738467 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -346,14 +346,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output]) }); - let pred = ty::Clause::from_projection_clause( - tcx, - tupled_inputs_and_output.map_bound(|(inputs, output)| ty::ProjectionPredicate { + let pred = tupled_inputs_and_output + .map_bound(|(inputs, output)| ty::ProjectionPredicate { projection_ty: tcx .mk_alias_ty(goal.predicate.def_id(), [goal.predicate.self_ty(), inputs]), term: output.into(), - }), - ); + }) + .to_predicate(tcx); // A built-in `Fn` impl only holds if the output is sized. // (FIXME: technically we only need to check this if the type is a fn ptr...) diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 820973dc090a..015e38b2ac08 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -23,6 +23,7 @@ use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::ToPredicate; use rustc_middle::ty::TypeFoldable; +use rustc_middle::ty::Variance; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::config::TraitSolver; @@ -156,6 +157,20 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } + pub fn relate>( + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + variance: Variance, + expected: T, + actual: T, + ) -> Result<(), TypeError<'tcx>> { + self.infcx + .at(cause, param_env) + .relate(DefineOpaqueTypes::Yes, expected, variance, actual) + .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) + } + /// Checks whether `expected` is a supertype of `actual`: `expected :> actual`. pub fn sup>( &self, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 2a586f810d62..9a728b1060fb 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength :( + mod ambiguity; pub mod on_unimplemented; pub mod suggestions; @@ -67,6 +69,7 @@ pub enum CandidateSimilarity { pub struct ImplCandidate<'tcx> { pub trait_ref: ty::TraitRef<'tcx>, pub similarity: CandidateSimilarity, + impl_def_id: DefId, } enum GetSafeTransmuteErrorAndReason { @@ -1331,6 +1334,7 @@ trait InferCtxtPrivExt<'tcx> { body_def_id: LocalDefId, err: &mut Diagnostic, other: bool, + param_env: ty::ParamEnv<'tcx>, ) -> bool; fn report_similar_impl_candidates_for_root_obligation( @@ -1918,8 +1922,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let imp = self.tcx.impl_trait_ref(def_id).unwrap().skip_binder(); - self.fuzzy_match_tys(trait_pred.skip_binder().self_ty(), imp.self_ty(), false) - .map(|similarity| ImplCandidate { trait_ref: imp, similarity }) + self.fuzzy_match_tys(trait_pred.skip_binder().self_ty(), imp.self_ty(), false).map( + |similarity| ImplCandidate { trait_ref: imp, similarity, impl_def_id: def_id }, + ) }) .collect(); if candidates.iter().any(|c| matches!(c.similarity, CandidateSimilarity::Exact { .. })) { @@ -1938,7 +1943,82 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { body_def_id: LocalDefId, err: &mut Diagnostic, other: bool, + param_env: ty::ParamEnv<'tcx>, ) -> bool { + // If we have a single implementation, try to unify it with the trait ref + // that failed. This should uncover a better hint for what *is* implemented. + if let [single] = &impl_candidates { + if self.probe(|_| { + let ocx = ObligationCtxt::new(self); + let obligation_trait_ref = self.instantiate_binder_with_placeholders(trait_ref); + let impl_args = self.fresh_args_for_item(DUMMY_SP, single.impl_def_id); + let impl_trait_ref = ocx.normalize( + &ObligationCause::dummy(), + param_env, + ty::EarlyBinder::bind(single.trait_ref).instantiate(self.tcx, impl_args), + ); + + ocx.register_obligations( + self.tcx + .predicates_of(single.impl_def_id) + .instantiate(self.tcx, impl_args) + .into_iter() + .map(|(clause, _)| { + Obligation::new(self.tcx, ObligationCause::dummy(), param_env, clause) + }), + ); + if !ocx.select_where_possible().is_empty() { + return false; + } + + let mut terrs = vec![]; + for (obligation_arg, impl_arg) in + std::iter::zip(obligation_trait_ref.args, impl_trait_ref.args) + { + if let Err(terr) = + ocx.eq(&ObligationCause::dummy(), param_env, impl_arg, obligation_arg) + { + terrs.push(terr); + } + if !ocx.select_where_possible().is_empty() { + return false; + } + } + + // Literally nothing unified, just give up. + if terrs.len() == impl_trait_ref.args.len() { + return false; + } + + let cand = + self.resolve_vars_if_possible(impl_trait_ref).fold_with(&mut BottomUpFolder { + tcx: self.tcx, + ty_op: |ty| ty, + lt_op: |lt| lt, + ct_op: |ct| ct.normalize(self.tcx, ty::ParamEnv::empty()), + }); + err.highlighted_help(vec![ + (format!("the trait `{}` ", cand.print_only_trait_path()), Style::NoStyle), + ("is".to_string(), Style::Highlight), + (" implemented for `".to_string(), Style::NoStyle), + (cand.self_ty().to_string(), Style::Highlight), + ("`".to_string(), Style::NoStyle), + ]); + + if let [TypeError::Sorts(exp_found)] = &terrs[..] { + let exp_found = self.resolve_vars_if_possible(*exp_found); + err.help(format!( + "for that trait implementation, expected `{}`, found `{}`", + exp_found.expected, exp_found.found + )); + } + + true + }) { + return true; + } + } + let other = if other { "other " } else { "" }; let report = |candidates: Vec>, err: &mut Diagnostic| { if candidates.is_empty() { @@ -2062,9 +2142,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { }) .collect(); impl_candidates.sort_by_key(|cand| (cand.similarity, cand.trait_ref)); + let mut impl_candidates: Vec<_> = + impl_candidates.into_iter().map(|cand| cand.trait_ref).collect(); impl_candidates.dedup(); - report(impl_candidates.into_iter().map(|cand| cand.trait_ref).collect(), err) + report(impl_candidates, err) } fn report_similar_impl_candidates_for_root_obligation( @@ -2108,6 +2190,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { body_def_id, err, true, + obligation.param_env, ); } } @@ -2316,6 +2399,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { obligation.cause.body_id, &mut err, false, + obligation.param_env, ); } } @@ -3051,6 +3135,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { body_def_id, err, true, + obligation.param_env, ) { self.report_similar_impl_candidates_for_root_obligation( &obligation, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 15f2ba809a4a..b7c735012802 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4000,14 +4000,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // ... whose signature is `async` (i.e. this is an AFIT) let (sig, body) = item.expect_fn(); - let hir::IsAsync::Async(async_span) = sig.header.asyncness else { - return; - }; - let Ok(async_span) = - self.tcx.sess.source_map().span_extend_while(async_span, |c| c.is_whitespace()) - else { - return; - }; let hir::FnRetTy::Return(hir::Ty { kind: hir::TyKind::OpaqueDef(def, ..), .. }) = sig.decl.output else { @@ -4021,55 +4013,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { return; } - let future = self.tcx.hir().item(*def).expect_opaque_ty(); - let Some(hir::GenericBound::LangItemTrait(_, _, _, generics)) = future.bounds.get(0) else { - // `async fn` should always lower to a lang item bound... but don't ICE. - return; - }; - let Some(hir::TypeBindingKind::Equality { term: hir::Term::Ty(future_output_ty) }) = - generics.bindings.get(0).map(|binding| binding.kind) - else { - // Also should never happen. + let Some(sugg) = suggest_desugaring_async_fn_to_impl_future_in_trait( + self.tcx, + *sig, + *body, + opaque_def_id.expect_local(), + &format!(" + {auto_trait}"), + ) else { return; }; let function_name = self.tcx.def_path_str(fn_def_id); - - let mut sugg = if future_output_ty.span.is_empty() { - vec![ - (async_span, String::new()), - ( - future_output_ty.span, - format!(" -> impl std::future::Future + {auto_trait}"), - ), - ] - } else { - vec![ - ( - future_output_ty.span.shrink_to_lo(), - "impl std::future::Future + {auto_trait}")), - (async_span, String::new()), - ] - }; - - // If there's a body, we also need to wrap it in `async {}` - if let hir::TraitFn::Provided(body) = body { - let body = self.tcx.hir().body(*body); - let body_span = body.value.span; - let body_span_without_braces = - body_span.with_lo(body_span.lo() + BytePos(1)).with_hi(body_span.hi() - BytePos(1)); - if body_span_without_braces.is_empty() { - sugg.push((body_span_without_braces, " async {} ".to_owned())); - } else { - sugg.extend([ - (body_span_without_braces.shrink_to_lo(), "async {".to_owned()), - (body_span_without_braces.shrink_to_hi(), "} ".to_owned()), - ]); - } - } - err.multipart_suggestion( format!( "`{auto_trait}` can be made part of the associated future's \ @@ -4321,3 +4275,65 @@ impl<'tcx> TypeFolder> for ReplaceImplTraitFolder<'tcx> { self.tcx } } + +pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>( + tcx: TyCtxt<'tcx>, + sig: hir::FnSig<'tcx>, + body: hir::TraitFn<'tcx>, + opaque_def_id: LocalDefId, + add_bounds: &str, +) -> Option> { + let hir::IsAsync::Async(async_span) = sig.header.asyncness else { + return None; + }; + let Ok(async_span) = tcx.sess.source_map().span_extend_while(async_span, |c| c.is_whitespace()) + else { + return None; + }; + + let future = tcx.hir().get_by_def_id(opaque_def_id).expect_item().expect_opaque_ty(); + let Some(hir::GenericBound::LangItemTrait(_, _, _, generics)) = future.bounds.get(0) else { + // `async fn` should always lower to a lang item bound... but don't ICE. + return None; + }; + let Some(hir::TypeBindingKind::Equality { term: hir::Term::Ty(future_output_ty) }) = + generics.bindings.get(0).map(|binding| binding.kind) + else { + // Also should never happen. + return None; + }; + + let mut sugg = if future_output_ty.span.is_empty() { + vec![ + (async_span, String::new()), + ( + future_output_ty.span, + format!(" -> impl std::future::Future{add_bounds}"), + ), + ] + } else { + vec![ + (future_output_ty.span.shrink_to_lo(), "impl std::future::Future{add_bounds}")), + (async_span, String::new()), + ] + }; + + // If there's a body, we also need to wrap it in `async {}` + if let hir::TraitFn::Provided(body) = body { + let body = tcx.hir().body(body); + let body_span = body.value.span; + let body_span_without_braces = + body_span.with_lo(body_span.lo() + BytePos(1)).with_hi(body_span.hi() - BytePos(1)); + if body_span_without_braces.is_empty() { + sugg.push((body_span_without_braces, " async {} ".to_owned())); + } else { + sugg.extend([ + (body_span_without_braces.shrink_to_lo(), "async {".to_owned()), + (body_span_without_braces.shrink_to_hi(), "} ".to_owned()), + ]); + } + } + + Some(sugg) +} diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 154cc7a71416..73c2ff3c5366 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1644,7 +1644,7 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>( let env_predicates = data .projection_bounds() .filter(|bound| bound.item_def_id() == obligation.predicate.def_id) - .map(|p| ty::Clause::from_projection_clause(tcx, p.with_self_ty(tcx, object_ty))); + .map(|p| p.with_self_ty(tcx, object_ty).to_predicate(tcx)); assemble_candidates_from_predicates( selcx, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index bc9ba85fc9f1..8871de194a63 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -39,6 +39,7 @@ use rustc_middle::dep_graph::dep_kinds; use rustc_middle::dep_graph::DepNodeIndex; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::traits::DefiningAnchor; +use rustc_middle::ty::_match::MatchAgainstFreshVars; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::relate::TypeRelation; @@ -2642,7 +2643,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { current: ty::PolyTraitPredicate<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> bool { - let mut matcher = ty::_match::Match::new(self.tcx(), param_env); + let mut matcher = MatchAgainstFreshVars::new(self.tcx(), param_env); matcher.relate(previous, current).is_ok() } @@ -3115,9 +3116,6 @@ fn bind_generator_hidden_types_above<'tcx>( bty.instantiate(tcx, args) }) .collect(); - if considering_regions { - debug_assert!(!hidden_types.has_erased_regions()); - } let bound_vars = tcx.mk_bound_variable_kinds_from_iter(bound_vars.iter().chain( (num_bound_variables..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon)), diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index e41073937be1..f23c100a686c 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -316,7 +316,7 @@ fn vtable_entries<'tcx>( dump_vtable_entries(tcx, sp, trait_ref, &entries); } - tcx.arena.alloc_from_iter(entries.into_iter()) + tcx.arena.alloc_from_iter(entries) } /// Find slot base for trait methods within vtable entries of another trait diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index b04008d9ee56..060df7726138 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -105,13 +105,13 @@ pub fn unnormalized_obligations<'tcx>( /// Returns the obligations that make this trait reference /// well-formed. For example, if there is a trait `Set` defined like -/// `trait Set`, then the trait reference `Foo: Set` is WF +/// `trait Set`, then the trait bound `Foo: Set` is WF /// if `Bar: Eq`. pub fn trait_obligations<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, body_id: LocalDefId, - trait_pred: &ty::TraitPredicate<'tcx>, + trait_pred: ty::TraitPredicate<'tcx>, span: Span, item: &'tcx hir::Item<'tcx>, ) -> Vec> { @@ -129,12 +129,17 @@ pub fn trait_obligations<'tcx>( wf.normalize(infcx) } +/// Returns the requirements for `clause` to be well-formed. +/// +/// For example, if there is a trait `Set` defined like +/// `trait Set`, then the trait bound `Foo: Set` is WF +/// if `Bar: Eq`. #[instrument(skip(infcx), ret)] -pub fn predicate_obligations<'tcx>( +pub fn clause_obligations<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, body_id: LocalDefId, - predicate: ty::Predicate<'tcx>, + clause: ty::Clause<'tcx>, span: Span, ) -> Vec> { let mut wf = WfPredicates { @@ -148,45 +153,32 @@ pub fn predicate_obligations<'tcx>( }; // It's ok to skip the binder here because wf code is prepared for it - match predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(t)) => { - wf.compute_trait_pred(&t, Elaborate::None); + match clause.kind().skip_binder() { + ty::ClauseKind::Trait(t) => { + wf.compute_trait_pred(t, Elaborate::None); } - ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..)) => {} - ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate( - ty, - _reg, - ))) => { + ty::ClauseKind::RegionOutlives(..) => {} + ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => { wf.compute(ty.into()); } - ty::PredicateKind::Clause(ty::ClauseKind::Projection(t)) => { + ty::ClauseKind::Projection(t) => { wf.compute_projection(t.projection_ty); wf.compute(match t.term.unpack() { ty::TermKind::Ty(ty) => ty.into(), ty::TermKind::Const(c) => c.into(), }) } - ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { + ty::ClauseKind::ConstArgHasType(ct, ty) => { wf.compute(ct.into()); wf.compute(ty.into()); } - ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => { + ty::ClauseKind::WellFormed(arg) => { wf.compute(arg); } - ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => { + ty::ClauseKind::ConstEvaluatable(ct) => { wf.compute(ct.into()); } - - ty::PredicateKind::ObjectSafe(_) - | ty::PredicateKind::ClosureKind(..) - | ty::PredicateKind::Subtype(..) - | ty::PredicateKind::Coerce(..) - | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::Ambiguous - | ty::PredicateKind::AliasRelate(..) => { - bug!("We should only wf check where clauses, unexpected predicate: {predicate:?}") - } } wf.normalize(infcx) @@ -233,7 +225,7 @@ enum Elaborate { fn extend_cause_with_original_assoc_item_obligation<'tcx>( tcx: TyCtxt<'tcx>, - trait_ref: &ty::TraitRef<'tcx>, + trait_ref: ty::TraitRef<'tcx>, item: Option<&hir::Item<'tcx>>, cause: &mut traits::ObligationCause<'tcx>, pred: ty::Predicate<'tcx>, @@ -336,9 +328,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { } /// Pushes the obligations required for `trait_ref` to be WF into `self.out`. - fn compute_trait_pred(&mut self, trait_pred: &ty::TraitPredicate<'tcx>, elaborate: Elaborate) { + fn compute_trait_pred(&mut self, trait_pred: ty::TraitPredicate<'tcx>, elaborate: Elaborate) { let tcx = self.tcx(); - let trait_ref = &trait_pred.trait_ref; + let trait_ref = trait_pred.trait_ref; // Negative trait predicates don't require supertraits to hold, just // that their args are WF. @@ -411,7 +403,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // Compute the obligations that are required for `trait_ref` to be WF, // given that it is a *negative* trait predicate. - fn compute_negative_trait_pred(&mut self, trait_ref: &ty::TraitRef<'tcx>) { + fn compute_negative_trait_pred(&mut self, trait_ref: ty::TraitRef<'tcx>) { for arg in trait_ref.args { self.compute(arg); } diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 16183403d67a..b118ddaab2b8 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -528,7 +528,7 @@ fn fn_abi_adjust_for_abi<'tcx>( arg.make_indirect(); } else { // We want to pass small aggregates as immediates, but using - // a LLVM aggregate type for this leads to bad optimizations, + // an LLVM aggregate type for this leads to bad optimizations, // so we pick an appropriately sized integer type instead. arg.cast_to(Reg { kind: RegKind::Integer, size }); } diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 383cc996b9e6..35487d3b6982 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -71,7 +71,7 @@ pub(crate) fn destructure_const<'tcx>( _ => bug!("cannot destructure constant {:?}", const_), }; - let fields = tcx.arena.alloc_from_iter(fields.into_iter()); + let fields = tcx.arena.alloc_from_iter(fields); ty::DestructuredConst { variant, fields } } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 5bd68d7ccaa7..8132742d1df2 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -85,7 +85,7 @@ fn univariant_uninterned<'tcx>( fields: &IndexSlice>, repr: &ReprOptions, kind: StructKind, -) -> Result> { +) -> Result, &'tcx LayoutError<'tcx>> { let dl = cx.data_layout(); let pack = repr.pack; if pack.is_some() && repr.align.is_some() { diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 4234e69e8546..c22c67bd9075 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -3,9 +3,8 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; use rustc_middle::query::Providers; -use rustc_middle::ty::{ - self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, -}; +use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeVisitor}; +use rustc_middle::ty::{ToPredicate, TypeSuperVisitable, TypeVisitable}; use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_span::DUMMY_SP; use rustc_trait_selection::traits; @@ -214,10 +213,10 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { // strategy, then just reinterpret the associated type like an opaque :^) let default_ty = self.tcx.type_of(shifted_alias_ty.def_id).instantiate(self.tcx, shifted_alias_ty.args); - self.predicates.push(ty::Clause::from_projection_clause(self.tcx, ty::Binder::bind_with_vars( + self.predicates.push(ty::Binder::bind_with_vars( ty::ProjectionPredicate { projection_ty: shifted_alias_ty, term: default_ty.into() }, self.bound_vars, - ))); + ).to_predicate(self.tcx)); // We walk the *un-shifted* alias ty, because we're tracking the de bruijn // binder depth, and if we were to walk `shifted_alias_ty` instead, we'd diff --git a/compiler/stable_mir/src/fold.rs b/compiler/stable_mir/src/fold.rs index 1da123e922b3..6471b2c2a3a5 100644 --- a/compiler/stable_mir/src/fold.rs +++ b/compiler/stable_mir/src/fold.rs @@ -4,17 +4,20 @@ use crate::Opaque; use super::ty::{ Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind, - GenericArgs, Promoted, RigidTy, TermKind, Ty, TyKind, UnevaluatedConst, + GenericArgs, Promoted, Region, RigidTy, TermKind, Ty, TyKind, UnevaluatedConst, }; pub trait Folder: Sized { type Break; - fn visit_ty(&mut self, ty: &Ty) -> ControlFlow { + fn fold_ty(&mut self, ty: &Ty) -> ControlFlow { ty.super_fold(self) } fn fold_const(&mut self, c: &Const) -> ControlFlow { c.super_fold(self) } + fn fold_reg(&mut self, reg: &Region) -> ControlFlow { + reg.super_fold(self) + } } pub trait Foldable: Sized + Clone { @@ -26,7 +29,7 @@ pub trait Foldable: Sized + Clone { impl Foldable for Ty { fn fold(&self, folder: &mut V) -> ControlFlow { - folder.visit_ty(self) + folder.fold_ty(self) } fn super_fold(&self, folder: &mut V) -> ControlFlow { let mut kind = self.kind(); @@ -106,6 +109,15 @@ impl Foldable for GenericArgs { } } +impl Foldable for Region { + fn fold(&self, folder: &mut V) -> ControlFlow { + folder.fold_reg(self) + } + fn super_fold(&self, _: &mut V) -> ControlFlow { + ControlFlow::Continue(self.clone()) + } +} + impl Foldable for GenericArgKind { fn super_fold(&self, folder: &mut V) -> ControlFlow { let mut this = self.clone(); @@ -136,7 +148,10 @@ impl Foldable for RigidTy { } RigidTy::Slice(inner) => *inner = inner.fold(folder)?, RigidTy::RawPtr(ty, _) => *ty = ty.fold(folder)?, - RigidTy::Ref(_, ty, _) => *ty = ty.fold(folder)?, + RigidTy::Ref(reg, ty, _) => { + *reg = reg.fold(folder)?; + *ty = ty.fold(folder)? + } RigidTy::FnDef(_, args) => *args = args.fold(folder)?, RigidTy::FnPtr(sig) => *sig = sig.fold(folder)?, RigidTy::Closure(_, args) => *args = args.fold(folder)?, @@ -214,7 +229,7 @@ pub enum Never {} impl Folder for GenericArgs { type Break = Never; - fn visit_ty(&mut self, ty: &Ty) -> ControlFlow { + fn fold_ty(&mut self, ty: &Ty) -> ControlFlow { ControlFlow::Continue(match ty.kind() { TyKind::Param(p) => self[p], _ => *ty, diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 6f8f7b06fa39..72f026ee8de0 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -5,7 +5,13 @@ use crate::{ty::Ty, Span}; #[derive(Clone, Debug)] pub struct Body { pub blocks: Vec, - pub locals: Vec, + pub locals: Vec, +} + +#[derive(Clone, Debug)] +pub struct LocalDecl { + pub ty: Ty, + pub span: Span, } #[derive(Clone, Debug)] @@ -15,7 +21,13 @@ pub struct BasicBlock { } #[derive(Clone, Debug)] -pub enum Terminator { +pub struct Terminator { + pub kind: TerminatorKind, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub enum TerminatorKind { Goto { target: usize, }, @@ -179,7 +191,13 @@ pub enum NonDivergingIntrinsic { } #[derive(Clone, Debug)] -pub enum Statement { +pub struct Statement { + pub kind: StatementKind, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub enum StatementKind { Assign(Place, Rvalue), FakeRead(FakeReadCause, Place), SetDiscriminant { place: Place, variant_index: VariantIdx }, diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index 82007e306834..6029e3c11ade 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -1,7 +1,7 @@ use super::{ mir::Safety, mir::{Body, Mutability}, - with, AllocId, DefId, + with, AllocId, DefId, Symbol, }; use crate::Opaque; use std::fmt::{self, Debug, Formatter}; @@ -34,7 +34,46 @@ pub struct Const { } type Ident = Opaque; -pub type Region = Opaque; + +#[derive(Debug, Clone)] +pub struct Region { + pub kind: RegionKind, +} + +#[derive(Debug, Clone)] +pub enum RegionKind { + ReEarlyBound(EarlyBoundRegion), + ReLateBound(DebruijnIndex, BoundRegion), + ReStatic, + RePlaceholder(Placeholder), + ReErased, +} + +pub(crate) type DebruijnIndex = u32; + +#[derive(Debug, Clone)] +pub struct EarlyBoundRegion { + pub def_id: RegionDef, + pub index: u32, + pub name: Symbol, +} + +pub(crate) type BoundVar = u32; + +#[derive(Debug, Clone)] +pub struct BoundRegion { + pub var: BoundVar, + pub kind: BoundRegionKind, +} + +pub(crate) type UniverseIndex = u32; + +#[derive(Debug, Clone)] +pub struct Placeholder { + pub universe: UniverseIndex, + pub bound: T, +} + #[derive(Clone, Copy, PartialEq, Eq)] pub struct Span(pub usize); @@ -152,6 +191,9 @@ pub struct ConstDef(pub DefId); #[derive(Clone, PartialEq, Eq, Debug)] pub struct ImplDef(pub DefId); +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct RegionDef(pub DefId); + #[derive(Clone, Debug)] pub struct GenericArgs(pub Vec); diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs index 9c3b4cd994a4..961009581388 100644 --- a/compiler/stable_mir/src/visitor.rs +++ b/compiler/stable_mir/src/visitor.rs @@ -4,7 +4,7 @@ use crate::Opaque; use super::ty::{ Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs, - Promoted, RigidTy, TermKind, Ty, UnevaluatedConst, + Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst, }; pub trait Visitor: Sized { @@ -15,6 +15,9 @@ pub trait Visitor: Sized { fn visit_const(&mut self, c: &Const) -> ControlFlow { c.super_visit(self) } + fn visit_reg(&mut self, reg: &Region) -> ControlFlow { + reg.super_visit(self) + } } pub trait Visitable { @@ -101,6 +104,16 @@ impl Visitable for GenericArgs { } } +impl Visitable for Region { + fn visit(&self, visitor: &mut V) -> ControlFlow { + visitor.visit_reg(self) + } + + fn super_visit(&self, _: &mut V) -> ControlFlow { + ControlFlow::Continue(()) + } +} + impl Visitable for GenericArgKind { fn super_visit(&self, visitor: &mut V) -> ControlFlow { match self { @@ -128,7 +141,10 @@ impl Visitable for RigidTy { } RigidTy::Slice(inner) => inner.visit(visitor), RigidTy::RawPtr(ty, _) => ty.visit(visitor), - RigidTy::Ref(_, ty, _) => ty.visit(visitor), + RigidTy::Ref(reg, ty, _) => { + reg.visit(visitor); + ty.visit(visitor) + } RigidTy::FnDef(_, args) => args.visit(visitor), RigidTy::FnPtr(sig) => sig.visit(visitor), RigidTy::Closure(_, args) => args.visit(visitor), diff --git a/config.example.toml b/config.example.toml index 3435a60d189a..f315b5539c6f 100644 --- a/config.example.toml +++ b/config.example.toml @@ -19,11 +19,18 @@ # Note that this has no default value (x.py uses the defaults in `config.example.toml`). #profile = -# Keeps track of the last version of `x.py` used. -# If `changelog-seen` does not match the version that is currently running, -# `x.py` will prompt you to update it and to read the changelog. -# See `src/bootstrap/CHANGELOG.md` for more information. -changelog-seen = 2 +# Keeps track of major changes made to this configuration. +# +# This value also represents ID of the PR that caused major changes. Meaning, +# you can visit github.com/rust-lang/rust/pull/{change-id} to check for more details. +# +# A 'major change' includes any of the following +# - A new option +# - A change in the default values +# +# If `change-id` does not match the version that is currently running, +# `x.py` will prompt you to update it and check the related PR for more details. +change-id = 115898 # ============================================================================= # Tweaking how LLVM is compiled diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index 84331eba2d49..b6b6246baa67 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -55,6 +55,7 @@ pub trait ToOwned { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "cloning is often expensive and is not expected to have side effects"] + #[cfg_attr(not(test), rustc_diagnostic_item = "to_owned_method")] fn to_owned(&self) -> Self::Owned; /// Uses borrowed data to replace owned data, usually by cloning. diff --git a/library/alloc/src/collections/btree/dedup_sorted_iter.rs b/library/alloc/src/collections/btree/dedup_sorted_iter.rs index 17ee78045a9b..cd6a88f32912 100644 --- a/library/alloc/src/collections/btree/dedup_sorted_iter.rs +++ b/library/alloc/src/collections/btree/dedup_sorted_iter.rs @@ -1,6 +1,6 @@ use core::iter::Peekable; -/// A iterator for deduping the key of a sorted iterator. +/// An iterator for deduping the key of a sorted iterator. /// When encountering the duplicated key, only the last key-value pair is yielded. /// /// Used by [`BTreeMap::bulk_build_from_sorted_iter`][1]. diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index f435f503fc16..cd3648214a48 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -140,6 +140,7 @@ #![feature(maybe_uninit_uninit_array_transpose)] #![feature(pattern)] #![feature(pointer_byte_offsets)] +#![feature(ptr_addr_eq)] #![feature(ptr_internals)] #![feature(ptr_metadata)] #![feature(ptr_sub_ptr)] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 8dbaca223aa9..73cb746c41d0 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1649,7 +1649,7 @@ impl Rc { /// assert!(!Rc::ptr_eq(&five, &other_five)); /// ``` pub fn ptr_eq(this: &Self, other: &Self) -> bool { - this.ptr.as_ptr() as *const () == other.ptr.as_ptr() as *const () + ptr::addr_eq(this.ptr.as_ptr(), other.ptr.as_ptr()) } } @@ -2701,6 +2701,7 @@ impl> ToRcSlice for I { /// /// [`upgrade`]: Weak::upgrade #[stable(feature = "rc_weak", since = "1.4.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "RcWeak")] pub struct Weak< T: ?Sized, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, @@ -3146,7 +3147,7 @@ impl Weak { #[must_use] #[stable(feature = "weak_ptr_eq", since = "1.39.0")] pub fn ptr_eq(&self, other: &Self) -> bool { - ptr::eq(self.ptr.as_ptr() as *const (), other.ptr.as_ptr() as *const ()) + ptr::addr_eq(self.ptr.as_ptr(), other.ptr.as_ptr()) } } diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index ed43244ebda1..e42bed7d2644 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2435,6 +2435,7 @@ pub trait ToString { /// ``` #[rustc_conversion_suggestion] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(test), rustc_diagnostic_item = "to_string_method")] fn to_string(&self) -> String; } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 9df971af49c0..0c6f3ef9b733 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -311,6 +311,7 @@ impl Arc { /// /// [`upgrade`]: Weak::upgrade #[stable(feature = "arc_weak", since = "1.4.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "ArcWeak")] pub struct Weak< T: ?Sized, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, @@ -1618,7 +1619,7 @@ impl Arc { #[must_use] #[stable(feature = "arc_counts", since = "1.15.0")] pub fn weak_count(this: &Self) -> usize { - let cnt = this.inner().weak.load(Acquire); + let cnt = this.inner().weak.load(Relaxed); // If the weak count is currently locked, the value of the // count was 0 just before taking the lock. if cnt == usize::MAX { 0 } else { cnt - 1 } @@ -1648,7 +1649,7 @@ impl Arc { #[must_use] #[stable(feature = "arc_counts", since = "1.15.0")] pub fn strong_count(this: &Self) -> usize { - this.inner().strong.load(Acquire) + this.inner().strong.load(Relaxed) } /// Increments the strong reference count on the `Arc` associated with the @@ -1778,7 +1779,7 @@ impl Arc { #[must_use] #[stable(feature = "ptr_eq", since = "1.17.0")] pub fn ptr_eq(this: &Self, other: &Self) -> bool { - this.ptr.as_ptr() as *const () == other.ptr.as_ptr() as *const () + ptr::addr_eq(this.ptr.as_ptr(), other.ptr.as_ptr()) } } @@ -2803,7 +2804,7 @@ impl Weak { #[must_use] #[stable(feature = "weak_counts", since = "1.41.0")] pub fn strong_count(&self) -> usize { - if let Some(inner) = self.inner() { inner.strong.load(Acquire) } else { 0 } + if let Some(inner) = self.inner() { inner.strong.load(Relaxed) } else { 0 } } /// Gets an approximation of the number of `Weak` pointers pointing to this @@ -2822,7 +2823,7 @@ impl Weak { pub fn weak_count(&self) -> usize { if let Some(inner) = self.inner() { let weak = inner.weak.load(Acquire); - let strong = inner.strong.load(Acquire); + let strong = inner.strong.load(Relaxed); if strong == 0 { 0 } else { @@ -2900,7 +2901,7 @@ impl Weak { #[must_use] #[stable(feature = "weak_ptr_eq", since = "1.39.0")] pub fn ptr_eq(&self, other: &Self) -> bool { - ptr::eq(self.ptr.as_ptr() as *const (), other.ptr.as_ptr() as *const ()) + ptr::addr_eq(self.ptr.as_ptr(), other.ptr.as_ptr()) } } diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index 587877dff552..8815cb21fc49 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -13,6 +13,7 @@ use crate::{ /// A by-value [array] iterator. #[stable(feature = "array_value_iter", since = "1.51.0")] #[rustc_insignificant_dtor] +#[rustc_diagnostic_item = "ArrayIntoIter"] pub struct IntoIter { /// This is the array we are iterating over. /// diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 3b4d99221f29..db07ef7e3c96 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1423,6 +1423,7 @@ impl Clone for BorrowRef<'_> { /// See the [module-level documentation](self) for more. #[stable(feature = "rust1", since = "1.0.0")] #[must_not_suspend = "holding a Ref across suspend points can cause BorrowErrors"] +#[rustc_diagnostic_item = "RefCellRef"] pub struct Ref<'b, T: ?Sized + 'b> { // NB: we use a pointer instead of `&'b T` to avoid `noalias` violations, because a // `Ref` argument doesn't hold immutability for its whole scope, only until it drops. @@ -1804,6 +1805,7 @@ impl<'b> BorrowRefMut<'b> { /// See the [module-level documentation](self) for more. #[stable(feature = "rust1", since = "1.0.0")] #[must_not_suspend = "holding a RefMut across suspend points can cause BorrowErrors"] +#[rustc_diagnostic_item = "RefCellRefMut"] pub struct RefMut<'b, T: ?Sized + 'b> { // NB: we use a pointer instead of `&'b mut T` to avoid `noalias` violations, because a // `RefMut` argument doesn't hold exclusivity for its whole scope, only until it drops. diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 360806167671..ca4e6be71efa 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -3,14 +3,17 @@ //! This module contains various tools for comparing and ordering values. In //! summary: //! -//! * [`Eq`] and [`PartialEq`] are traits that allow you to define total and -//! partial equality between values, respectively. Implementing them overloads -//! the `==` and `!=` operators. +//! * [`PartialEq`] overloads the `==` and `!=` operators. In cases where +//! `Rhs` (the right hand side's type) is `Self`, this trait corresponds to a +//! partial equivalence relation. +//! * [`Eq`] indicates that the overloaded `==` operator corresponds to an +//! equivalence relation. //! * [`Ord`] and [`PartialOrd`] are traits that allow you to define total and //! partial orderings between values, respectively. Implementing them overloads //! the `<`, `<=`, `>`, and `>=` operators. //! * [`Ordering`] is an enum returned by the main functions of [`Ord`] and -//! [`PartialOrd`], and describes an ordering. +//! [`PartialOrd`], and describes an ordering of two values (less, equal, or +//! greater). //! * [`Reverse`] is a struct that allows you to easily reverse an ordering. //! * [`max`] and [`min`] are functions that build off of [`Ord`] and allow you //! to find the maximum or minimum of two values. @@ -27,16 +30,21 @@ pub(crate) use bytewise::BytewiseEq; use self::Ordering::*; -/// Trait for equality comparisons. +/// Trait for comparisons using the equality operator. +/// +/// Implementing this trait for types provides the `==` and `!=` operators for +/// those types. /// /// `x.eq(y)` can also be written `x == y`, and `x.ne(y)` can be written `x != y`. /// We use the easier-to-read infix notation in the remainder of this documentation. /// -/// This trait allows for partial equality, for types that do not have a full -/// equivalence relation. For example, in floating point numbers `NaN != NaN`, -/// so floating point types implement `PartialEq` but not [`trait@Eq`]. -/// Formally speaking, when `Rhs == Self`, this trait corresponds to a [partial equivalence -/// relation](https://en.wikipedia.org/wiki/Partial_equivalence_relation). +/// This trait allows for comparisons using the equality operator, for types +/// that do not have a full equivalence relation. For example, in floating point +/// numbers `NaN != NaN`, so floating point types implement `PartialEq` but not +/// [`trait@Eq`]. Formally speaking, when `Rhs == Self`, this trait corresponds +/// to a [partial equivalence relation]. +/// +/// [partial equivalence relation]: https://en.wikipedia.org/wiki/Partial_equivalence_relation /// /// Implementations must ensure that `eq` and `ne` are consistent with each other: /// @@ -242,15 +250,15 @@ pub macro PartialEq($item:item) { /* compiler built-in */ } -/// Trait for equality comparisons which are [equivalence relations]( +/// Trait for comparisons corresponding to [equivalence relations]( /// https://en.wikipedia.org/wiki/Equivalence_relation). /// -/// This means, that in addition to `a == b` and `a != b` being strict inverses, the equality must -/// be (for all `a`, `b` and `c`): +/// This means, that in addition to `a == b` and `a != b` being strict inverses, +/// the relation must be (for all `a`, `b` and `c`): /// /// - reflexive: `a == a`; -/// - symmetric: `a == b` implies `b == a`; and -/// - transitive: `a == b` and `b == c` implies `a == c`. +/// - symmetric: `a == b` implies `b == a` (required by `PartialEq` as well); and +/// - transitive: `a == b` and `b == c` implies `a == c` (required by `PartialEq` as well). /// /// This property cannot be checked by the compiler, and therefore `Eq` implies /// [`PartialEq`], and has no extra methods. @@ -260,6 +268,10 @@ pub macro PartialEq($item:item) { /// undefined behavior. This means that `unsafe` code **must not** rely on the correctness of these /// methods. /// +/// Implement `Eq` in addition to `PartialEq` if it's guaranteed that +/// `PartialEq::eq(a, a)` always returns `true` (reflexivity), in addition to +/// the symmetric and transitive properties already required by `PartialEq`. +/// /// ## Derivable /// /// This trait can be used with `#[derive]`. When `derive`d, because `Eq` has @@ -676,12 +688,19 @@ impl Clone for Reverse { /// /// ## Corollaries /// -/// From the above and the requirements of `PartialOrd`, it follows that `<` defines a strict total order. -/// This means that for all `a`, `b` and `c`: +/// From the above and the requirements of `PartialOrd`, it follows that for +/// all `a`, `b` and `c`: /// /// - exactly one of `a < b`, `a == b` or `a > b` is true; and /// - `<` is transitive: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`. /// +/// Mathematically speaking, the `<` operator defines a strict [weak order]. In +/// cases where `==` conforms to mathematical equality, it also defines a +/// strict [total order]. +/// +/// [weak order]: https://en.wikipedia.org/wiki/Weak_ordering +/// [total order]: https://en.wikipedia.org/wiki/Total_order +/// /// ## Derivable /// /// This trait can be used with `#[derive]`. @@ -790,6 +809,7 @@ pub trait Ord: Eq + PartialOrd { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_diagnostic_item = "ord_cmp_method"] fn cmp(&self, other: &Self) -> Ordering; /// Compares and returns the maximum of two values. @@ -920,6 +940,20 @@ pub macro Ord($item:item) { /// - transitivity of `>`: if `a > b` and `b > c` then `a > c` /// - duality of `partial_cmp`: `partial_cmp(a, b) == partial_cmp(b, a).map(Ordering::reverse)` /// +/// ## Strict and non-strict partial orders +/// +/// The `<` and `>` operators behave according to a *strict* partial order. +/// However, `<=` and `>=` do **not** behave according to a *non-strict* +/// partial order. +/// That is because mathematically, a non-strict partial order would require +/// reflexivity, i.e. `a <= a` would need to be true for every `a`. This isn't +/// always the case for types that implement `PartialOrd`, for example: +/// +/// ``` +/// let a = f64::sqrt(-1.0); +/// assert_eq!(a <= a, false); +/// ``` +/// /// ## Derivable /// /// This trait can be used with `#[derive]`. diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index ff5a4c913b7e..9e4fdcda06e5 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -100,6 +100,7 @@ pub use num::FloatToInt; #[stable(feature = "convert_id", since = "1.33.0")] #[rustc_const_stable(feature = "const_identity", since = "1.33.0")] #[inline(always)] +#[rustc_diagnostic_item = "convert_identity"] pub const fn identity(x: T) -> T { x } @@ -642,6 +643,7 @@ pub trait TryFrom: Sized { /// Performs the conversion. #[stable(feature = "try_from", since = "1.34.0")] + #[rustc_diagnostic_item = "try_from_fn"] fn try_from(value: T) -> Result; } diff --git a/library/core/src/default.rs b/library/core/src/default.rs index 5242e97eb9ae..16618b38769d 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -130,6 +130,7 @@ pub trait Default: Sized { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_diagnostic_item = "default_fn"] fn default() -> Self; } diff --git a/library/core/src/fmt/builders.rs b/library/core/src/fmt/builders.rs index 9227248041e9..47db53ac6f34 100644 --- a/library/core/src/fmt/builders.rs +++ b/library/core/src/fmt/builders.rs @@ -84,6 +84,7 @@ impl fmt::Write for PadAdapter<'_, '_> { #[must_use = "must eventually call `finish()` on Debug builders"] #[allow(missing_debug_implementations)] #[stable(feature = "debug_builders", since = "1.2.0")] +#[rustc_diagnostic_item = "DebugStruct"] pub struct DebugStruct<'a, 'b: 'a> { fmt: &'a mut fmt::Formatter<'b>, result: fmt::Result, diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index fc91d1afc431..c45ab094a20d 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -239,6 +239,7 @@ impl Write for &mut W { /// documentation of the methods defined on `Formatter` below. #[allow(missing_debug_implementations)] #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_diagnostic_item = "Formatter"] pub struct Formatter<'a> { flags: u32, fill: char, @@ -791,8 +792,10 @@ pub trait Octal { /// assert_eq!(format!("l as binary is: {l:b}"), "l as binary is: 1101011"); /// /// assert_eq!( -/// format!("l as binary is: {l:#032b}"), -/// "l as binary is: 0b000000000000000000000001101011" +/// // Note that the `0b` prefix added by `#` is included in the total width, so we +/// // need to add two to correctly display all 32 bits. +/// format!("l as binary is: {l:#034b}"), +/// "l as binary is: 0b00000000000000000000000001101011" /// ); /// ``` #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs index d37888c27bde..5bf221b429fa 100644 --- a/library/core/src/fmt/rt.rs +++ b/library/core/src/fmt/rt.rs @@ -133,6 +133,10 @@ impl<'a> Argument<'a> { Self::new(x, USIZE_MARKER) } + // FIXME: Transmuting formatter in new and indirectly branching to/calling + // it here is an explicit CFI violation. + #[allow(inline_no_sanitize)] + #[no_sanitize(cfi, kcfi)] #[inline(always)] pub(super) fn fmt(&self, f: &mut Formatter<'_>) -> Result { (self.formatter)(self.value, f) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 4bf3da07354f..ff177c70d39c 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -277,7 +277,7 @@ pub fn spin_loop() { /// - Treats the call to `contains` and its result as volatile: the body of `benchmark` cannot /// optimize this away /// -/// This makes our benchmark much more realistic to how the function would be used in situ, where +/// This makes our benchmark much more realistic to how the function would actually be used, where /// arguments are usually not known at compile time and the result is used in some way. #[inline] #[stable(feature = "bench_black_box", since = "1.66.0")] diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 4c76662ac097..e4d6c2c2928d 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1509,12 +1509,14 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] + #[rustc_diagnostic_item = "intrinsics_unaligned_volatile_load"] pub fn unaligned_volatile_load(src: *const T) -> T; /// Performs a volatile store to the `dst` pointer. /// The pointer is not required to be aligned. /// /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] + #[rustc_diagnostic_item = "intrinsics_unaligned_volatile_store"] pub fn unaligned_volatile_store(dst: *mut T, val: T); /// Returns the square root of an `f32` @@ -2666,6 +2668,7 @@ pub(crate) fn is_nonoverlapping(src: *const T, dst: *const T, count: usize) - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[rustc_diagnostic_item = "ptr_copy_nonoverlapping"] pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize) { extern "rust-intrinsic" { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] @@ -2761,6 +2764,7 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[rustc_diagnostic_item = "ptr_copy"] pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { extern "rust-intrinsic" { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")] @@ -2834,6 +2838,7 @@ pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[rustc_diagnostic_item = "ptr_write_bytes"] pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { extern "rust-intrinsic" { #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] diff --git a/library/core/src/iter/adapters/peekable.rs b/library/core/src/iter/adapters/peekable.rs index 20aca323bab7..65ba42920c93 100644 --- a/library/core/src/iter/adapters/peekable.rs +++ b/library/core/src/iter/adapters/peekable.rs @@ -12,6 +12,7 @@ use crate::ops::{ControlFlow, Try}; #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_diagnostic_item = "IterPeekable"] pub struct Peekable { iter: I, /// Remember a peeked value, even if it was None. diff --git a/library/core/src/iter/sources/empty.rs b/library/core/src/iter/sources/empty.rs index 243df015f9a2..438e046a4dfd 100644 --- a/library/core/src/iter/sources/empty.rs +++ b/library/core/src/iter/sources/empty.rs @@ -27,6 +27,7 @@ pub const fn empty() -> Empty { /// This `struct` is created by the [`empty()`] function. See its documentation for more. #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "iter_empty", since = "1.2.0")] +#[rustc_diagnostic_item = "IterEmpty"] pub struct Empty(marker::PhantomData T>); #[stable(feature = "core_impl_debug", since = "1.9.0")] diff --git a/library/core/src/iter/sources/once.rs b/library/core/src/iter/sources/once.rs index 6e9ed0d3c527..21be4377da1c 100644 --- a/library/core/src/iter/sources/once.rs +++ b/library/core/src/iter/sources/once.rs @@ -61,6 +61,7 @@ pub fn once(value: T) -> Once { /// This `struct` is created by the [`once()`] function. See its documentation for more. #[derive(Clone, Debug)] #[stable(feature = "iter_once", since = "1.2.0")] +#[rustc_diagnostic_item = "IterOnce"] pub struct Once { inner: crate::option::IntoIter, } diff --git a/library/core/src/iter/sources/successors.rs b/library/core/src/iter/sources/successors.rs index 6a6cbe905e46..7f7b2c775662 100644 --- a/library/core/src/iter/sources/successors.rs +++ b/library/core/src/iter/sources/successors.rs @@ -17,7 +17,7 @@ where F: FnMut(&T) -> Option, { // If this function returned `impl Iterator` - // it could be based on `unfold` and not need a dedicated type. + // it could be based on `from_fn` and not need a dedicated type. // However having a named `Successors` type allows it to be `Clone` when `T` and `F` are. Successors { next: first, succ } } diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index e0ef5071c408..0d1cf7941fb6 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -146,6 +146,7 @@ pub trait FromIterator: Sized { /// assert_eq!(v, vec![5, 5, 5, 5, 5]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_diagnostic_item = "from_iter_fn"] fn from_iter>(iter: T) -> Self; } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 8b04bafcda54..7fa7e83a7442 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -178,6 +178,7 @@ #![feature(ip)] #![feature(ip_bits)] #![feature(is_ascii_octdigit)] +#![feature(isqrt)] #![feature(maybe_uninit_uninit_array)] #![feature(ptr_alignment_type)] #![feature(ptr_metadata)] @@ -237,6 +238,7 @@ #![feature(negative_impls)] #![feature(never_type)] #![feature(no_core)] +#![feature(no_sanitize)] #![feature(platform_intrinsics)] #![feature(prelude_import)] #![feature(repr_simd)] @@ -417,6 +419,7 @@ pub mod primitive; // FIXME: This annotation should be moved into rust-lang/stdarch after clashing_extern_declarations is // merged. It currently cannot because bootstrap fails as the lint hasn't been defined yet. #[allow(clashing_extern_declarations)] +#[cfg_attr(bootstrap, allow(deprecated_in_future))] #[unstable(feature = "stdsimd", issue = "48556")] mod core_arch; diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index c27be8d2ffd3..c367b53b7202 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -719,7 +719,8 @@ macro_rules! unreachable { /// The difference between `unimplemented!` and [`todo!`] is that while `todo!` /// conveys an intent of implementing the functionality later and the message is "not yet /// implemented", `unimplemented!` makes no such claims. Its message is "not implemented". -/// Also some IDEs will mark `todo!`s. +/// +/// Also, some IDEs will mark `todo!`s. /// /// # Panics /// @@ -805,11 +806,15 @@ macro_rules! unimplemented { /// The difference between [`unimplemented!`] and `todo!` is that while `todo!` conveys /// an intent of implementing the functionality later and the message is "not yet /// implemented", `unimplemented!` makes no such claims. Its message is "not implemented". -/// Also some IDEs will mark `todo!`s. +/// +/// Also, some IDEs will mark `todo!`s. /// /// # Panics /// -/// This will always [`panic!`]. +/// This will always [`panic!`] because `todo!` is just a shorthand for `panic!` with a +/// fixed, specific message. +/// +/// Like `panic!`, this macro has a second form for displaying custom values. /// /// # Examples /// @@ -817,38 +822,47 @@ macro_rules! unimplemented { /// /// ``` /// trait Foo { -/// fn bar(&self); +/// fn bar(&self) -> u8; /// fn baz(&self); +/// fn qux(&self) -> Result; /// } /// ``` /// /// We want to implement `Foo` on one of our types, but we also want to work on /// just `bar()` first. In order for our code to compile, we need to implement -/// `baz()`, so we can use `todo!`: +/// `baz()` and `qux()`, so we can use `todo!`: /// /// ``` /// # trait Foo { -/// # fn bar(&self); +/// # fn bar(&self) -> u8; /// # fn baz(&self); +/// # fn qux(&self) -> Result; /// # } /// struct MyStruct; /// /// impl Foo for MyStruct { -/// fn bar(&self) { -/// // implementation goes here +/// fn bar(&self) -> u8 { +/// 1 + 1 /// } /// /// fn baz(&self) { -/// // let's not worry about implementing baz() for now +/// // Let's not worry about implementing baz() for now /// todo!(); /// } +/// +/// fn qux(&self) -> Result { +/// // We can add a message to todo! to display our omission. +/// // This will display: +/// // "thread 'main' panicked at 'not yet implemented: MyStruct is not yet quxable'". +/// todo!("MyStruct is not yet quxable"); +/// } /// } /// /// fn main() { /// let s = MyStruct; /// s.bar(); /// -/// // we aren't even using baz(), so this is fine. +/// // We aren't even using baz() or qux(), so this is fine. /// } /// ``` #[macro_export] diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index 5f3d66e3773f..98cff3493a7e 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -4,12 +4,12 @@ use crate::ptr; /// A wrapper to inhibit compiler from automatically calling `T`’s destructor. /// This wrapper is 0-cost. /// -/// `ManuallyDrop` is guaranteed to have the same layout as `T`, and is subject -/// to the same layout optimizations as `T`. As a consequence, it has *no effect* -/// on the assumptions that the compiler makes about its contents. For example, -/// initializing a `ManuallyDrop<&mut T>` with [`mem::zeroed`] is undefined -/// behavior. If you need to handle uninitialized data, use [`MaybeUninit`] -/// instead. +/// `ManuallyDrop` is guaranteed to have the same layout and bit validity as +/// `T`, and is subject to the same layout optimizations as `T`. As a consequence, +/// it has *no effect* on the assumptions that the compiler makes about its +/// contents. For example, initializing a `ManuallyDrop<&mut T>` with [`mem::zeroed`] +/// is undefined behavior. If you need to handle uninitialized data, use +/// [`MaybeUninit`] instead. /// /// Note that accessing the value inside a `ManuallyDrop` is safe. /// This means that a `ManuallyDrop` whose content has been dropped must not diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index d7abc9a0e23a..d1b1eb7624ba 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -723,15 +723,12 @@ pub unsafe fn uninitialized() -> T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_swap", issue = "83163")] +#[rustc_diagnostic_item = "mem_swap"] pub const fn swap(x: &mut T, y: &mut T) { // NOTE(eddyb) SPIR-V's Logical addressing model doesn't allow for arbitrary // reinterpretation of values as (chunkable) byte arrays, and the loop in the // block optimization in `swap_slice` is hard to rewrite back // into the (unoptimized) direct swapping implementation, so we disable it. - // FIXME(eddyb) the block optimization also prevents MIR optimizations from - // understanding `mem::replace`, `Option::take`, etc. - a better overall - // solution might be to make `ptr::swap_nonoverlapping` into an intrinsic, which - // a backend can choose to implement using the block optimization, or not. #[cfg(not(any(target_arch = "spirv")))] { // For types that are larger multiples of their alignment, the simple way @@ -768,11 +765,14 @@ pub(crate) const fn swap_simple(x: &mut T, y: &mut T) { // And LLVM actually optimizes it to 3×memcpy if called with // a type larger than it's willing to keep in a register. // Having typed reads and writes in MIR here is also good as - // it lets MIRI and CTFE understand them better, including things + // it lets Miri and CTFE understand them better, including things // like enforcing type validity for them. // Importantly, read+copy_nonoverlapping+write introduces confusing // asymmetry to the behaviour where one value went through read+write // whereas the other was copied over by the intrinsic (see #94371). + // Furthermore, using only read+write here benefits limited backends + // such as SPIR-V that work on an underlying *typed* view of memory, + // and thus have trouble with Rust's untyped memory operations. // SAFETY: exclusive references are always valid to read/write, // including being aligned, and nothing here panics so it's drop-safe. @@ -930,7 +930,7 @@ pub const fn replace(dest: &mut T, src: T) -> T { /// This function is not magic; it is literally defined as /// /// ``` -/// pub fn drop(_x: T) { } +/// pub fn drop(_x: T) {} /// ``` /// /// Because `_x` is moved into the function, it is automatically dropped before diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 290f649f9acd..f60626b00dc8 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -377,6 +377,13 @@ impl f32 { pub const MANTISSA_DIGITS: u32 = 24; /// Approximate number of significant digits in base 10. + /// + /// This is the maximum x such that any decimal number with x + /// significant digits can be converted to `f32` and back without loss. + /// + /// Equal to floor(log10 2[`MANTISSA_DIGITS`] − 1). + /// + /// [`MANTISSA_DIGITS`]: f32::MANTISSA_DIGITS #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const DIGITS: u32 = 6; @@ -384,31 +391,62 @@ impl f32 { /// /// This is the difference between `1.0` and the next larger representable number. /// + /// Equal to 21 − [`MANTISSA_DIGITS`]. + /// /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon + /// [`MANTISSA_DIGITS`]: f32::MANTISSA_DIGITS #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const EPSILON: f32 = 1.19209290e-07_f32; /// Smallest finite `f32` value. + /// + /// Equal to −[`MAX`]. + /// + /// [`MAX`]: f32::MAX #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MIN: f32 = -3.40282347e+38_f32; /// Smallest positive normal `f32` value. + /// + /// Equal to 2[`MIN_EXP`] − 1. + /// + /// [`MIN_EXP`]: f32::MIN_EXP #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MIN_POSITIVE: f32 = 1.17549435e-38_f32; /// Largest finite `f32` value. + /// + /// Equal to + /// (1 − 2−[`MANTISSA_DIGITS`]) 2[`MAX_EXP`]. + /// + /// [`MANTISSA_DIGITS`]: f32::MANTISSA_DIGITS + /// [`MAX_EXP`]: f32::MAX_EXP #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MAX: f32 = 3.40282347e+38_f32; /// One greater than the minimum possible normal power of 2 exponent. + /// + /// If x = `MIN_EXP`, then normal numbers + /// ≥ 0.5 × 2x. #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MIN_EXP: i32 = -125; /// Maximum possible power of 2 exponent. + /// + /// If x = `MAX_EXP`, then normal numbers + /// < 1 × 2x. #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MAX_EXP: i32 = 128; - /// Minimum possible normal power of 10 exponent. + /// Minimum x for which 10x is normal. + /// + /// Equal to ceil(log10 [`MIN_POSITIVE`]). + /// + /// [`MIN_POSITIVE`]: f32::MIN_POSITIVE #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MIN_10_EXP: i32 = -37; - /// Maximum possible power of 10 exponent. + /// Maximum x for which 10x is normal. + /// + /// Equal to floor(log10 [`MAX`]). + /// + /// [`MAX`]: f32::MAX #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MAX_10_EXP: i32 = 38; @@ -820,7 +858,7 @@ impl f32 { /// let angle = std::f32::consts::PI; /// /// let abs_difference = (angle.to_degrees() - 180.0).abs(); - /// + /// # #[cfg(any(not(target_arch = "x86"), target_feature = "sse2"))] /// assert!(abs_difference <= f32::EPSILON); /// ``` #[must_use = "this returns the result of the operation, \ diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 7569d2cd6ca9..0a87021d8c18 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -376,6 +376,13 @@ impl f64 { #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MANTISSA_DIGITS: u32 = 53; /// Approximate number of significant digits in base 10. + /// + /// This is the maximum x such that any decimal number with x + /// significant digits can be converted to `f64` and back without loss. + /// + /// Equal to floor(log10 2[`MANTISSA_DIGITS`] − 1). + /// + /// [`MANTISSA_DIGITS`]: f64::MANTISSA_DIGITS #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const DIGITS: u32 = 15; @@ -383,31 +390,62 @@ impl f64 { /// /// This is the difference between `1.0` and the next larger representable number. /// + /// Equal to 21 − [`MANTISSA_DIGITS`]. + /// /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon + /// [`MANTISSA_DIGITS`]: f64::MANTISSA_DIGITS #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const EPSILON: f64 = 2.2204460492503131e-16_f64; /// Smallest finite `f64` value. + /// + /// Equal to −[`MAX`]. + /// + /// [`MAX`]: f64::MAX #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MIN: f64 = -1.7976931348623157e+308_f64; /// Smallest positive normal `f64` value. + /// + /// Equal to 2[`MIN_EXP`] − 1. + /// + /// [`MIN_EXP`]: f64::MIN_EXP #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MIN_POSITIVE: f64 = 2.2250738585072014e-308_f64; /// Largest finite `f64` value. + /// + /// Equal to + /// (1 − 2−[`MANTISSA_DIGITS`]) 2[`MAX_EXP`]. + /// + /// [`MANTISSA_DIGITS`]: f64::MANTISSA_DIGITS + /// [`MAX_EXP`]: f64::MAX_EXP #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MAX: f64 = 1.7976931348623157e+308_f64; /// One greater than the minimum possible normal power of 2 exponent. + /// + /// If x = `MIN_EXP`, then normal numbers + /// ≥ 0.5 × 2x. #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MIN_EXP: i32 = -1021; /// Maximum possible power of 2 exponent. + /// + /// If x = `MAX_EXP`, then normal numbers + /// < 1 × 2x. #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MAX_EXP: i32 = 1024; - /// Minimum possible normal power of 10 exponent. + /// Minimum x for which 10x is normal. + /// + /// Equal to ceil(log10 [`MIN_POSITIVE`]). + /// + /// [`MIN_POSITIVE`]: f64::MIN_POSITIVE #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MIN_10_EXP: i32 = -307; - /// Maximum possible power of 10 exponent. + /// Maximum x for which 10x is normal. + /// + /// Equal to floor(log10 [`MAX`]). + /// + /// [`MAX`]: f64::MAX #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MAX_10_EXP: i32 = 308; diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 1f43520e1b30..3cbb55af3bc6 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -898,6 +898,30 @@ macro_rules! int_impl { acc.checked_mul(base) } + /// Returns the square root of the number, rounded down. + /// + /// Returns `None` if `self` is negative. + /// + /// # Examples + /// + /// Basic usage: + /// ``` + /// #![feature(isqrt)] + #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_isqrt(), Some(3));")] + /// ``` + #[unstable(feature = "isqrt", issue = "116226")] + #[rustc_const_unstable(feature = "isqrt", issue = "116226")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn checked_isqrt(self) -> Option { + if self < 0 { + None + } else { + Some((self as $UnsignedT).isqrt() as Self) + } + } + /// Saturating integer addition. Computes `self + rhs`, saturating at the numeric /// bounds instead of overflowing. /// @@ -2061,6 +2085,36 @@ macro_rules! int_impl { acc * base } + /// Returns the square root of the number, rounded down. + /// + /// # Panics + /// + /// This function will panic if `self` is negative. + /// + /// # Examples + /// + /// Basic usage: + /// ``` + /// #![feature(isqrt)] + #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")] + /// ``` + #[unstable(feature = "isqrt", issue = "116226")] + #[rustc_const_unstable(feature = "isqrt", issue = "116226")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn isqrt(self) -> Self { + // I would like to implement it as + // ``` + // self.checked_isqrt().expect("argument of integer square root must be non-negative") + // ``` + // but `expect` is not yet stable as a `const fn`. + match self.checked_isqrt() { + Some(sqrt) => sqrt, + None => panic!("argument of integer square root must be non-negative"), + } + } + /// Calculates the quotient of Euclidean division of `self` by `rhs`. /// /// This computes the integer `q` such that `self = q * rhs + r`, with diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 7cbef9e77937..a9c5312a1c02 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1995,6 +1995,54 @@ macro_rules! uint_impl { acc * base } + /// Returns the square root of the number, rounded down. + /// + /// # Examples + /// + /// Basic usage: + /// ``` + /// #![feature(isqrt)] + #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")] + /// ``` + #[unstable(feature = "isqrt", issue = "116226")] + #[rustc_const_unstable(feature = "isqrt", issue = "116226")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn isqrt(self) -> Self { + if self < 2 { + return self; + } + + // The algorithm is based on the one presented in + // + // which cites as source the following C code: + // . + + let mut op = self; + let mut res = 0; + let mut one = 1 << (self.ilog2() & !1); + + while one != 0 { + if op >= res + one { + op -= res + one; + res = (res >> 1) + one; + } else { + res >>= 1; + } + one >>= 2; + } + + // SAFETY: the result is positive and fits in an integer with half as many bits. + // Inform the optimizer about it. + unsafe { + intrinsics::assume(0 < res); + intrinsics::assume(res < 1 << (Self::BITS / 2)); + } + + res + } + /// Performs Euclidean division. /// /// Since, for the positive integers, all common diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index 911761c6edd2..d6f2f5ca3662 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -180,6 +180,7 @@ impl Deref for &mut T { pub trait DerefMut: Deref { /// Mutably dereferences the value. #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_diagnostic_item = "deref_mut_method"] fn deref_mut(&mut self) -> &mut Self::Target; } diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs index cc596293ca3f..b41600958876 100644 --- a/library/core/src/ops/range.rs +++ b/library/core/src/ops/range.rs @@ -758,6 +758,7 @@ impl Bound<&T> { /// `RangeBounds` is implemented by Rust's built-in range types, produced /// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`. #[stable(feature = "collections_range", since = "1.28.0")] +#[rustc_diagnostic_item = "RangeBounds"] pub trait RangeBounds { /// Start index bound. /// diff --git a/library/core/src/option.rs b/library/core/src/option.rs index f2909a81d492..9899014e85a7 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -743,8 +743,6 @@ impl Option { /// # Examples /// /// ```rust - /// #![feature(option_as_slice)] - /// /// assert_eq!( /// [Some(1234).as_slice(), None.as_slice()], /// [&[1234][..], &[][..]], @@ -755,15 +753,13 @@ impl Option { /// borrowing) [`[_]::first`](slice::first): /// /// ```rust - /// #![feature(option_as_slice)] - /// /// for i in [Some(1234_u16), None] { /// assert_eq!(i.as_ref(), i.as_slice().first()); /// } /// ``` #[inline] #[must_use] - #[unstable(feature = "option_as_slice", issue = "108545")] + #[stable(feature = "option_as_slice", since = "CURRENT_RUSTC_VERSION")] pub fn as_slice(&self) -> &[T] { // SAFETY: When the `Option` is `Some`, we're using the actual pointer // to the payload, with a length of 1, so this is equivalent to @@ -794,8 +790,6 @@ impl Option { /// # Examples /// /// ```rust - /// #![feature(option_as_slice)] - /// /// assert_eq!( /// [Some(1234).as_mut_slice(), None.as_mut_slice()], /// [&mut [1234][..], &mut [][..]], @@ -806,8 +800,6 @@ impl Option { /// our original `Option`: /// /// ```rust - /// #![feature(option_as_slice)] - /// /// let mut x = Some(1234); /// x.as_mut_slice()[0] += 1; /// assert_eq!(x, Some(1235)); @@ -817,13 +809,11 @@ impl Option { /// is [`[_]::first_mut`](slice::first_mut): /// /// ```rust - /// #![feature(option_as_slice)] - /// /// assert_eq!(Some(123).as_mut_slice().first_mut(), Some(&mut 123)) /// ``` #[inline] #[must_use] - #[unstable(feature = "option_as_slice", issue = "108545")] + #[stable(feature = "option_as_slice", since = "CURRENT_RUSTC_VERSION")] pub fn as_mut_slice(&mut self) -> &mut [T] { // SAFETY: When the `Option` is `Some`, we're using the actual pointer // to the payload, with a length of 1, so this is equivalent to diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs index 386f5fcbd6ab..a00fd322b3ce 100644 --- a/library/core/src/panic.rs +++ b/library/core/src/panic.rs @@ -47,6 +47,7 @@ pub macro panic_2015 { #[allow_internal_unstable(core_panic, const_format_args)] #[rustc_diagnostic_item = "core_panic_2021_macro"] #[rustc_macro_transparency = "semitransparent"] +#[cfg(any(bootstrap, feature = "panic_immediate_abort"))] pub macro panic_2021 { () => ( $crate::panicking::panic("explicit panic") @@ -62,6 +63,50 @@ pub macro panic_2021 { }), } +#[doc(hidden)] +#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")] +#[allow_internal_unstable( + core_panic, + core_intrinsics, + const_dispatch, + const_eval_select, + const_format_args, + rustc_attrs +)] +#[rustc_diagnostic_item = "core_panic_2021_macro"] +#[rustc_macro_transparency = "semitransparent"] +#[cfg(not(any(bootstrap, feature = "panic_immediate_abort")))] +pub macro panic_2021 { + () => ({ + // Create a function so that the argument for `track_caller` + // can be moved inside if possible. + #[cold] + #[track_caller] + #[inline(never)] + const fn panic_cold_explicit() -> ! { + $crate::panicking::panic_explicit() + } + panic_cold_explicit(); + }), + // Special-case the single-argument case for const_panic. + ("{}", $arg:expr $(,)?) => ({ + #[cold] + #[track_caller] + #[inline(never)] + #[rustc_const_panic_str] // enforce a &&str argument in const-check and hook this by const-eval + #[rustc_do_not_const_check] // hooked by const-eval + const fn panic_cold_display(arg: &T) -> ! { + $crate::panicking::panic_display(arg) + } + panic_cold_display(&$arg); + }), + ($($t:tt)+) => ({ + // Semicolon to prevent temporaries inside the formatting machinery from + // being considered alive in the caller after the panic_fmt call. + $crate::panicking::panic_fmt($crate::const_format_args!($($t)+)); + }), +} + #[doc(hidden)] #[unstable(feature = "edition_panic", issue = "none", reason = "use unreachable!() instead")] #[allow_internal_unstable(core_panic)] diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index e6cdffd96afb..1a32cf92ffbe 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -152,6 +152,14 @@ pub const fn panic_str(expr: &str) -> ! { panic_display(&expr); } +#[track_caller] +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] +#[cfg_attr(feature = "panic_immediate_abort", inline)] +#[rustc_const_unstable(feature = "core_panic", issue = "none")] +pub const fn panic_explicit() -> ! { + panic_display(&"explicit panic"); +} + #[inline] #[track_caller] #[rustc_diagnostic_item = "unreachable_display"] // needed for `non-fmt-panics` lint @@ -161,8 +169,10 @@ pub fn unreachable_display(x: &T) -> ! { #[inline] #[track_caller] -#[lang = "panic_display"] // needed for const-evaluated panics #[rustc_do_not_const_check] // hooked by const-eval +#[cfg_attr(bootstrap, lang = "panic_display")] +// enforce a &&str argument in const-check and hook this by const-eval +#[cfg_attr(not(bootstrap), rustc_const_panic_str)] #[rustc_const_unstable(feature = "core_panic", issue = "none")] pub const fn panic_display(x: &T) -> ! { panic_fmt(format_args!("{}", *x)); diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index fd5fe5a04f4d..380a21b376bd 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1142,10 +1142,9 @@ impl Copy for (T,) { /// surprising results upon inspecting the bit patterns, /// as the same calculations might produce NaNs with different bit patterns. /// -/// When the number resulting from a primitive operation (addition, -/// subtraction, multiplication, or division) on this type is not exactly -/// representable as `f32`, it is rounded according to the roundTiesToEven -/// direction defined in IEEE 754-2008. That means: +/// When a primitive operation (addition, subtraction, multiplication, or +/// division) is performed on this type, the result is rounded according to the +/// roundTiesToEven direction defined in IEEE 754-2008. That means: /// /// - The result is the representable value closest to the true value, if there /// is a unique closest representable value. @@ -1154,6 +1153,9 @@ impl Copy for (T,) { /// - If the true value's magnitude is ≥ `f32::MAX` + 2(`f32::MAX_EXP` − /// `f32::MANTISSA_DIGITS` − 1), the result is ∞ or −∞ (preserving the /// true value's sign). +/// - If the result of a sum exactly equals zero, the outcome is +0.0 unless +/// both arguments were negative, then it is -0.0. Subtraction `a - b` is +/// regarded as a sum `a + (-b)`. /// /// For more information on floating point numbers, see [Wikipedia][wikipedia]. /// diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index ee69d89a4b72..9af8f1228f0b 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -607,7 +607,16 @@ impl *const T { /// Calculates the distance between two pointers. The returned value is in /// units of T: the distance in bytes divided by `mem::size_of::()`. /// - /// This function is the inverse of [`offset`]. + /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::() as isize)`, + /// except that it has a lot more opportunities for UB, in exchange for the compiler + /// better understanding what you are doing. + /// + /// The primary motivation of this method is for computing the `len` of an array/slice + /// of `T` that you are currently representing as a "start" and "end" pointer + /// (and "end" is "one past the end" of the array). + /// In that case, `end.offset_from(start)` gets you the length of the array. + /// + /// All of the following safety requirements are trivially satisfied for this usecase. /// /// [`offset`]: #method.offset /// @@ -616,7 +625,7 @@ impl *const T { /// If any of the following conditions are violated, the result is Undefined /// Behavior: /// - /// * Both the starting and other pointer must be either in bounds or one + /// * Both `self` and `origin` must be either in bounds or one /// byte past the end of the same [allocated object]. /// /// * Both pointers must be *derived from* a pointer to the same object. @@ -646,6 +655,14 @@ impl *const T { /// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on /// such large allocations either.) /// + /// The requirement for pointers to be derived from the same allocated object is primarily + /// needed for `const`-compatibility: the distance between pointers into *different* allocated + /// objects is not known at compile-time. However, the requirement also exists at + /// runtime and may be exploited by optimizations. If you wish to compute the difference between + /// pointers that are not guaranteed to be from the same allocation, use `(self as isize - + /// origin as isize) / mem::size_of::()`. + // FIXME: recommend `addr()` instead of `as usize` once that is stable. + /// /// [`add`]: #method.add /// [allocated object]: crate::ptr#allocated-object /// @@ -703,7 +720,7 @@ impl *const T { /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and - /// using [offset_from][pointer::offset_from] on it. See that method for + /// using [`offset_from`][pointer::offset_from] on it. See that method for /// documentation and safety requirements. /// /// For non-`Sized` pointees this operation considers only the data pointers, diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index d1286a1dea79..5039ff53d031 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -494,6 +494,7 @@ mod mut_ptr; #[stable(feature = "drop_in_place", since = "1.8.0")] #[lang = "drop_in_place"] #[allow(unconditional_recursion)] +#[rustc_diagnostic_item = "ptr_drop_in_place"] pub unsafe fn drop_in_place(to_drop: *mut T) { // Code here does not matter - this is replaced by the // real drop glue by the compiler. @@ -740,6 +741,7 @@ pub const fn from_mut(r: &mut T) -> *mut T { #[stable(feature = "slice_from_raw_parts", since = "1.42.0")] #[rustc_const_stable(feature = "const_slice_from_raw_parts", since = "1.64.0")] #[rustc_allow_const_fn_unstable(ptr_metadata)] +#[rustc_diagnostic_item = "ptr_slice_from_raw_parts"] pub const fn slice_from_raw_parts(data: *const T, len: usize) -> *const [T] { from_raw_parts(data.cast(), len) } @@ -772,6 +774,7 @@ pub const fn slice_from_raw_parts(data: *const T, len: usize) -> *const [T] { #[inline] #[stable(feature = "slice_from_raw_parts", since = "1.42.0")] #[rustc_const_unstable(feature = "const_slice_from_raw_parts_mut", issue = "67456")] +#[rustc_diagnostic_item = "ptr_slice_from_raw_parts_mut"] pub const fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { from_raw_parts_mut(data.cast(), len) } @@ -850,6 +853,7 @@ pub const fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_swap", issue = "83163")] +#[rustc_diagnostic_item = "ptr_swap"] pub const unsafe fn swap(x: *mut T, y: *mut T) { // Give ourselves some scratch space to work with. // We do not have to worry about drops: `MaybeUninit` does nothing when dropped. @@ -911,6 +915,7 @@ pub const unsafe fn swap(x: *mut T, y: *mut T) { #[inline] #[stable(feature = "swap_nonoverlapping", since = "1.27.0")] #[rustc_const_unstable(feature = "const_swap", issue = "83163")] +#[rustc_diagnostic_item = "ptr_swap_nonoverlapping"] pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { #[allow(unused)] macro_rules! attempt_swap_as_chunks { @@ -1022,6 +1027,7 @@ const unsafe fn swap_nonoverlapping_simple_untyped(x: *mut T, y: *mut T, coun #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_replace", issue = "83164")] +#[rustc_diagnostic_item = "ptr_replace"] pub const unsafe fn replace(dst: *mut T, mut src: T) -> T { // SAFETY: the caller must guarantee that `dst` is valid to be // cast to a mutable reference (valid for writes, aligned, initialized), @@ -1147,6 +1153,7 @@ pub const unsafe fn replace(dst: *mut T, mut src: T) -> T { #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")] #[rustc_allow_const_fn_unstable(const_mut_refs, const_maybe_uninit_as_mut_ptr)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[rustc_diagnostic_item = "ptr_read"] pub const unsafe fn read(src: *const T) -> T { // It would be semantically correct to implement this via `copy_nonoverlapping` // and `MaybeUninit`, as was done before PR #109035. Calling `assume_init` @@ -1264,6 +1271,7 @@ pub const unsafe fn read(src: *const T) -> T { #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")] #[rustc_allow_const_fn_unstable(const_mut_refs, const_maybe_uninit_as_mut_ptr)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[rustc_diagnostic_item = "ptr_read_unaligned"] pub const unsafe fn read_unaligned(src: *const T) -> T { let mut tmp = MaybeUninit::::uninit(); // SAFETY: the caller must guarantee that `src` is valid for reads. @@ -1539,6 +1547,7 @@ pub const unsafe fn write_unaligned(dst: *mut T, src: T) { #[inline] #[stable(feature = "volatile", since = "1.9.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[rustc_diagnostic_item = "ptr_read_volatile"] pub unsafe fn read_volatile(src: *const T) -> T { // SAFETY: the caller must uphold the safety contract for `volatile_load`. unsafe { @@ -1864,10 +1873,35 @@ pub(crate) const unsafe fn align_offset(p: *const T, a: usize) -> usiz /// ``` #[stable(feature = "ptr_eq", since = "1.17.0")] #[inline(always)] +#[must_use = "pointer comparison produces a value"] +#[rustc_diagnostic_item = "ptr_eq"] pub fn eq(a: *const T, b: *const T) -> bool { a == b } +/// Compares the *addresses* of the two pointers for equality, +/// ignoring any metadata in fat pointers. +/// +/// If the arguments are thin pointers of the same type, +/// then this is the same as [`eq`]. +/// +/// # Examples +/// +/// ``` +/// #![feature(ptr_addr_eq)] +/// +/// let whole: &[i32; 3] = &[1, 2, 3]; +/// let first: &i32 = &whole[0]; +/// assert!(std::ptr::addr_eq(whole, first)); +/// assert!(!std::ptr::eq::(whole, first)); +/// ``` +#[unstable(feature = "ptr_addr_eq", issue = "116324")] +#[inline(always)] +#[must_use = "pointer comparison produces a value"] +pub fn addr_eq(p: *const T, q: *const U) -> bool { + (p as *const ()) == (q as *const ()) +} + /// Hash a raw pointer. /// /// This can be used to hash a `&T` reference (which coerces to `*const T` implicitly) diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 6d623b82c1cf..109c286929b4 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -781,7 +781,16 @@ impl *mut T { /// Calculates the distance between two pointers. The returned value is in /// units of T: the distance in bytes divided by `mem::size_of::()`. /// - /// This function is the inverse of [`offset`]. + /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::() as isize)`, + /// except that it has a lot more opportunities for UB, in exchange for the compiler + /// better understanding what you are doing. + /// + /// The primary motivation of this method is for computing the `len` of an array/slice + /// of `T` that you are currently representing as a "start" and "end" pointer + /// (and "end" is "one past the end" of the array). + /// In that case, `end.offset_from(start)` gets you the length of the array. + /// + /// All of the following safety requirements are trivially satisfied for this usecase. /// /// [`offset`]: pointer#method.offset-1 /// @@ -790,7 +799,7 @@ impl *mut T { /// If any of the following conditions are violated, the result is Undefined /// Behavior: /// - /// * Both the starting and other pointer must be either in bounds or one + /// * Both `self` and `origin` must be either in bounds or one /// byte past the end of the same [allocated object]. /// /// * Both pointers must be *derived from* a pointer to the same object. @@ -820,6 +829,14 @@ impl *mut T { /// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on /// such large allocations either.) /// + /// The requirement for pointers to be derived from the same allocated object is primarily + /// needed for `const`-compatibility: the distance between pointers into *different* allocated + /// objects is not known at compile-time. However, the requirement also exists at + /// runtime and may be exploited by optimizations. If you wish to compute the difference between + /// pointers that are not guaranteed to be from the same allocation, use `(self as isize - + /// origin as isize) / mem::size_of::()`. + // FIXME: recommend `addr()` instead of `as usize` once that is stable. + /// /// [`add`]: #method.add /// [allocated object]: crate::ptr#allocated-object /// @@ -875,7 +892,7 @@ impl *mut T { /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and - /// using [offset_from][pointer::offset_from] on it. See that method for + /// using [`offset_from`][pointer::offset_from] on it. See that method for /// documentation and safety requirements. /// /// For non-`Sized` pointees this operation considers only the data pointers, diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index d5bd54fd59ad..5f5a10bbdf32 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -68,6 +68,7 @@ use crate::slice::{self, SliceIndex}; #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] +#[rustc_diagnostic_item = "NonNull"] pub struct NonNull { pointer: *const T, } diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 6981abc9be19..50127b27f8bf 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -1422,6 +1422,7 @@ impl Result { /// assert_eq!(Err("foo").unwrap_or_else(count), 3); /// ``` #[inline] + #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] pub fn unwrap_or_else T>(self, op: F) -> T { match self { diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index cc9313553183..5e229bf52441 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -59,6 +59,7 @@ impl<'a, T> IntoIterator for &'a mut [T] { /// [slices]: slice #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "iterators are lazy and do nothing unless consumed"] +#[rustc_diagnostic_item = "SliceIter"] pub struct Iter<'a, T: 'a> { /// The pointer to the next element to return, or the past-the-end location /// if the iterator is empty. diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 48a6eb03b5e1..9cdf9b68afb7 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -90,6 +90,7 @@ use crate::ptr; #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_from_raw_parts", since = "1.64.0")] #[must_use] +#[rustc_diagnostic_item = "slice_from_raw_parts"] pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { // SAFETY: the caller must uphold the safety contract for `from_raw_parts`. unsafe { @@ -136,6 +137,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_slice_from_raw_parts_mut", issue = "67456")] #[must_use] +#[rustc_diagnostic_item = "slice_from_raw_parts_mut"] pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { // SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`. unsafe { diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index eb0c424e2d25..899d572f0e34 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -808,7 +808,7 @@ impl str { /// assert_eq!(Some((0, 'y')), char_indices.next()); // not (0, 'y̆') /// assert_eq!(Some((1, '\u{0306}')), char_indices.next()); /// - /// // note the 3 here - the last character took up two bytes + /// // note the 3 here - the previous character took up two bytes /// assert_eq!(Some((3, 'e')), char_indices.next()); /// assert_eq!(Some((4, 's')), char_indices.next()); /// diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index 2b37af66bd6a..16fb1dad7230 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -624,6 +624,7 @@ pub trait FromStr: Sized { /// assert_eq!(5, x); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_diagnostic_item = "from_str_method"] fn from_str(s: &str) -> Result; } diff --git a/library/core/src/sync/exclusive.rs b/library/core/src/sync/exclusive.rs index 3f3e19c55d4b..ff538d55c607 100644 --- a/library/core/src/sync/exclusive.rs +++ b/library/core/src/sync/exclusive.rs @@ -2,6 +2,8 @@ use core::fmt; use core::future::Future; +use core::marker::Tuple; +use core::ops::{Generator, GeneratorState}; use core::pin::Pin; use core::task::{Context, Poll}; @@ -168,10 +170,52 @@ impl From for Exclusive { } #[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl Future for Exclusive { +impl FnOnce for Exclusive +where + F: FnOnce, + Args: Tuple, +{ + type Output = F::Output; + + extern "rust-call" fn call_once(self, args: Args) -> Self::Output { + self.into_inner().call_once(args) + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +impl FnMut for Exclusive +where + F: FnMut, + Args: Tuple, +{ + extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output { + self.get_mut().call_mut(args) + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +impl Future for Exclusive +where + T: Future + ?Sized, +{ type Output = T::Output; + #[inline] fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { self.get_pin_mut().poll(cx) } } + +#[unstable(feature = "generator_trait", issue = "43122")] // also #98407 +impl Generator for Exclusive +where + G: Generator + ?Sized, +{ + type Yield = G::Yield; + type Return = G::Return; + + #[inline] + fn resume(self: Pin<&mut Self>, arg: R) -> GeneratorState { + G::resume(self.get_pin_mut(), arg) + } +} diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 1e8d28979e6b..6ef35d8414be 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -910,6 +910,7 @@ impl Duration { impl Add for Duration { type Output = Duration; + #[inline] fn add(self, rhs: Duration) -> Duration { self.checked_add(rhs).expect("overflow when adding durations") } @@ -917,6 +918,7 @@ impl Add for Duration { #[stable(feature = "time_augmented_assignment", since = "1.9.0")] impl AddAssign for Duration { + #[inline] fn add_assign(&mut self, rhs: Duration) { *self = *self + rhs; } @@ -926,6 +928,7 @@ impl AddAssign for Duration { impl Sub for Duration { type Output = Duration; + #[inline] fn sub(self, rhs: Duration) -> Duration { self.checked_sub(rhs).expect("overflow when subtracting durations") } @@ -933,6 +936,7 @@ impl Sub for Duration { #[stable(feature = "time_augmented_assignment", since = "1.9.0")] impl SubAssign for Duration { + #[inline] fn sub_assign(&mut self, rhs: Duration) { *self = *self - rhs; } @@ -942,6 +946,7 @@ impl SubAssign for Duration { impl Mul for Duration { type Output = Duration; + #[inline] fn mul(self, rhs: u32) -> Duration { self.checked_mul(rhs).expect("overflow when multiplying duration by scalar") } @@ -951,6 +956,7 @@ impl Mul for Duration { impl Mul for u32 { type Output = Duration; + #[inline] fn mul(self, rhs: Duration) -> Duration { rhs * self } @@ -958,6 +964,7 @@ impl Mul for u32 { #[stable(feature = "time_augmented_assignment", since = "1.9.0")] impl MulAssign for Duration { + #[inline] fn mul_assign(&mut self, rhs: u32) { *self = *self * rhs; } @@ -967,6 +974,7 @@ impl MulAssign for Duration { impl Div for Duration { type Output = Duration; + #[inline] fn div(self, rhs: u32) -> Duration { self.checked_div(rhs).expect("divide by zero error when dividing duration by scalar") } @@ -974,6 +982,7 @@ impl Div for Duration { #[stable(feature = "time_augmented_assignment", since = "1.9.0")] impl DivAssign for Duration { + #[inline] fn div_assign(&mut self, rhs: u32) { *self = *self / rhs; } diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs index 982d7853f693..81da75d32a1c 100644 --- a/library/core/tests/array.rs +++ b/library/core/tests/array.rs @@ -663,7 +663,7 @@ fn array_mixed_equality_nans() { #[test] fn array_into_iter_fold() { - // Strings to help MIRI catch if we double-free or something + // Strings to help Miri catch if we double-free or something let a = ["Aa".to_string(), "Bb".to_string(), "Cc".to_string()]; let mut s = "s".to_string(); a.into_iter().for_each(|b| s += &b); @@ -679,7 +679,7 @@ fn array_into_iter_fold() { #[test] fn array_into_iter_rfold() { - // Strings to help MIRI catch if we double-free or something + // Strings to help Miri catch if we double-free or something let a = ["Aa".to_string(), "Bb".to_string(), "Cc".to_string()]; let mut s = "s".to_string(); a.into_iter().rev().for_each(|b| s += &b); diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 773f2b955d84..e4003a208bc9 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -56,6 +56,7 @@ #![feature(min_specialization)] #![feature(numfmt)] #![feature(num_midpoint)] +#![feature(isqrt)] #![feature(step_trait)] #![feature(str_internals)] #![feature(std_internals)] diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs index 439bbe669978..165d9a296176 100644 --- a/library/core/tests/num/int_macros.rs +++ b/library/core/tests/num/int_macros.rs @@ -290,6 +290,38 @@ macro_rules! int_module { assert_eq!(r.saturating_pow(0), 1 as $T); } + #[test] + fn test_isqrt() { + assert_eq!($T::MIN.checked_isqrt(), None); + assert_eq!((-1 as $T).checked_isqrt(), None); + assert_eq!((0 as $T).isqrt(), 0 as $T); + assert_eq!((1 as $T).isqrt(), 1 as $T); + assert_eq!((2 as $T).isqrt(), 1 as $T); + assert_eq!((99 as $T).isqrt(), 9 as $T); + assert_eq!((100 as $T).isqrt(), 10 as $T); + } + + #[cfg(not(miri))] // Miri is too slow + #[test] + fn test_lots_of_isqrt() { + let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T; + for n in 0..=n_max { + let isqrt: $T = n.isqrt(); + + assert!(isqrt.pow(2) <= n); + let (square, overflow) = (isqrt + 1).overflowing_pow(2); + assert!(overflow || square > n); + } + + for n in ($T::MAX - 127)..=$T::MAX { + let isqrt: $T = n.isqrt(); + + assert!(isqrt.pow(2) <= n); + let (square, overflow) = (isqrt + 1).overflowing_pow(2); + assert!(overflow || square > n); + } + } + #[test] fn test_div_floor() { let a: $T = 8; diff --git a/library/core/tests/num/uint_macros.rs b/library/core/tests/num/uint_macros.rs index 7d6203db0b94..955440647eb9 100644 --- a/library/core/tests/num/uint_macros.rs +++ b/library/core/tests/num/uint_macros.rs @@ -206,6 +206,35 @@ macro_rules! uint_module { assert_eq!(r.saturating_pow(2), MAX); } + #[test] + fn test_isqrt() { + assert_eq!((0 as $T).isqrt(), 0 as $T); + assert_eq!((1 as $T).isqrt(), 1 as $T); + assert_eq!((2 as $T).isqrt(), 1 as $T); + assert_eq!((99 as $T).isqrt(), 9 as $T); + assert_eq!((100 as $T).isqrt(), 10 as $T); + assert_eq!($T::MAX.isqrt(), (1 << ($T::BITS / 2)) - 1); + } + + #[cfg(not(miri))] // Miri is too slow + #[test] + fn test_lots_of_isqrt() { + let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T; + for n in 0..=n_max { + let isqrt: $T = n.isqrt(); + + assert!(isqrt.pow(2) <= n); + assert!(isqrt + 1 == (1 as $T) << ($T::BITS / 2) || (isqrt + 1).pow(2) > n); + } + + for n in ($T::MAX - 255)..=$T::MAX { + let isqrt: $T = n.isqrt(); + + assert!(isqrt.pow(2) <= n); + assert!(isqrt + 1 == (1 as $T) << ($T::BITS / 2) || (isqrt + 1).pow(2) > n); + } + } + #[test] fn test_div_floor() { assert_eq!((8 as $T).div_floor(3), 2); diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 73cce35ac591..c44223a2f32c 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -184,6 +184,7 @@ pub struct DirEntry(fs_imp::DirEntry); /// ``` #[derive(Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "FsOpenOptions")] pub struct OpenOptions(fs_imp::OpenOptions); /// Representation of the various timestamps on a file. @@ -201,6 +202,7 @@ pub struct FileTimes(fs_imp::FileTimes); /// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt #[derive(Clone, PartialEq, Eq, Debug)] #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "FsPermissions")] pub struct Permissions(fs_imp::FilePermissions); /// A structure representing a type of file with accessors for each file type. @@ -2241,6 +2243,7 @@ pub fn canonicalize>(path: P) -> io::Result { /// ``` #[doc(alias = "mkdir")] #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "fs_create_dir")] pub fn create_dir>(path: P) -> io::Result<()> { DirBuilder::new().create(path.as_ref()) } diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 604b795cd52a..c93bf0202523 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1830,6 +1830,7 @@ pub trait Write { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "IoSeek")] pub trait Seek { /// Seek to an offset, in bytes, in a stream. /// @@ -2893,6 +2894,7 @@ impl Iterator for Split { /// [`lines`]: BufRead::lines #[stable(feature = "rust1", since = "1.0.0")] #[derive(Debug)] +#[cfg_attr(not(test), rustc_diagnostic_item = "IoLines")] pub struct Lines { buf: B, } diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 9098d36ee538..05b21eeb40f7 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -611,6 +611,7 @@ static STDOUT: OnceLock>>> = OnceLo /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "io_stdout")] pub fn stdout() -> Stdout { Stdout { inner: STDOUT @@ -847,6 +848,7 @@ pub struct StderrLock<'a> { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "io_stderr")] pub fn stderr() -> Stderr { // Note that unlike `stdout()` we don't use `at_exit` here to register a // destructor. Stderr is not buffered, so there's no need to run a diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index f1f0f8b1653d..02f4d5bc7ae1 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -259,7 +259,7 @@ all(target_vendor = "fortanix", target_env = "sgx"), feature(slice_index_methods, coerce_unsized, sgx_platform) )] -#![cfg_attr(windows, feature(round_char_boundary))] +#![cfg_attr(any(windows, target_os = "uefi"), feature(round_char_boundary))] #![cfg_attr(target_os = "xous", feature(slice_ptr_len))] // // Language features: @@ -270,6 +270,7 @@ #![feature(allow_internal_unstable)] #![feature(c_unwind)] #![feature(cfg_target_thread_local)] +#![feature(cfi_encoding)] #![feature(concat_idents)] #![feature(const_mut_refs)] #![feature(const_trait_impl)] @@ -292,6 +293,7 @@ #![feature(needs_panic_runtime)] #![feature(negative_impls)] #![feature(never_type)] +#![feature(no_sanitize)] #![feature(platform_intrinsics)] #![feature(prelude_import)] #![feature(rustc_attrs)] diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs index 227e418b7099..60347a11da9c 100644 --- a/library/std/src/net/udp.rs +++ b/library/std/src/net/udp.rs @@ -99,6 +99,16 @@ impl UdpSocket { /// /// let socket = UdpSocket::bind("127.0.0.1:0").unwrap(); /// ``` + /// + /// Note that `bind` declares the scope of your network connection. + /// You can only receive datagrams from and send datagrams to + /// participants in that view of the network. + /// For instance, binding to a loopback address as in the example + /// above will prevent you from sending datagrams to another device + /// in your local network. + /// + /// In order to limit your view of the network the least, `bind` to + /// [`Ipv4Addr::UNSPECIFIED`] or [`Ipv6Addr::UNSPECIFIED`]. #[stable(feature = "rust1", since = "1.0.0")] pub fn bind(addr: A) -> io::Result { super::each_addr(addr, net_imp::UdpSocket::bind).map(UdpSocket) @@ -157,7 +167,9 @@ impl UdpSocket { } /// Sends data on the socket to the given address. On success, returns the - /// number of bytes written. + /// number of bytes written. Note that the operating system may refuse + /// buffers larger than 65507. However, partial writes are not possible + /// until buffer sizes above `i32::MAX`. /// /// Address type can be any implementor of [`ToSocketAddrs`] trait. See its /// documentation for concrete examples. @@ -652,12 +664,19 @@ impl UdpSocket { /// function of a UDP socket is not a useful thing to do: The OS will be /// unable to determine whether something is listening on the remote /// address without the application sending data. + /// + /// If your first `connect` is to a loopback address, subsequent + /// `connect`s to non-loopback addresses might fail, depending + /// on the platform. #[stable(feature = "net2_mutators", since = "1.9.0")] pub fn connect(&self, addr: A) -> io::Result<()> { super::each_addr(addr, |addr| self.0.connect(addr)) } /// Sends data on the socket to the remote address to which it is connected. + /// On success, returns the number of bytes written. Note that the operating + /// system may refuse buffers larger than 65507. However, partial writes are + /// not possible until buffer sizes above `i32::MAX`. /// /// [`UdpSocket::connect`] will connect this socket to a remote address. This /// method will fail if the socket is not connected. diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 6cf3bd619b25..e148635f5819 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -526,6 +526,7 @@ impl fmt::Debug for ChildStderr { /// list_dir.status().expect("process failed to execute"); /// ``` #[stable(feature = "process", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "Command")] pub struct Command { inner: imp::Command, } @@ -607,7 +608,7 @@ impl Command { /// /// Note that the argument is not passed through a shell, but given /// literally to the program. This means that shell syntax like quotes, - /// escaped characters, word splitting, glob patterns, substitution, etc. + /// escaped characters, word splitting, glob patterns, variable substitution, etc. /// have no effect. /// /// # Examples @@ -637,7 +638,7 @@ impl Command { /// /// Note that the arguments are not passed through a shell, but given /// literally to the program. This means that shell syntax like quotes, - /// escaped characters, word splitting, glob patterns, substitution, etc. + /// escaped characters, word splitting, glob patterns, variable substitution, etc. /// have no effect. /// /// # Examples @@ -2196,6 +2197,7 @@ impl Child { /// process::exit(0x0100); /// ``` #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "process_exit")] pub fn exit(code: i32) -> ! { crate::rt::cleanup(); crate::sys::os::exit(code) diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index 26aaa2414c97..ac7c800ff6f8 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -380,7 +380,7 @@ impl RwLock { /// /// If the lock is poisoned, it will remain poisoned until this function is called. This allows /// recovering from a poisoned state and marking that it has recovered. For example, if the - /// value is overwritten by a known-good value, then the mutex can be marked as un-poisoned. Or + /// value is overwritten by a known-good value, then the lock can be marked as un-poisoned. Or /// possibly, the value could be inspected to determine if it is in a consistent state, and if /// so the poison is removed. /// @@ -397,7 +397,7 @@ impl RwLock { /// /// let _ = thread::spawn(move || { /// let _lock = c_lock.write().unwrap(); - /// panic!(); // the mutex gets poisoned + /// panic!(); // the lock gets poisoned /// }).join(); /// /// assert_eq!(lock.is_poisoned(), true); diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs index e477a0cd7ab8..559d2c7db471 100644 --- a/library/std/src/sys/personality/gcc.rs +++ b/library/std/src/sys/personality/gcc.rs @@ -95,7 +95,7 @@ const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1 cfg_if::cfg_if! { if #[cfg(all(target_arch = "arm", not(target_os = "ios"), not(target_os = "tvos"), not(target_os = "watchos"), not(target_os = "netbsd")))] { // ARM EHABI personality routine. - // https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf + // https://web.archive.org/web/20190728160938/https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf // // iOS uses the default routine instead since it uses SjLj unwinding. #[lang = "eh_personality"] diff --git a/library/std/src/sys/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/sgx/abi/usercalls/alloc.rs index 01505e94487b..817c33b66037 100644 --- a/library/std/src/sys/sgx/abi/usercalls/alloc.rs +++ b/library/std/src/sys/sgx/abi/usercalls/alloc.rs @@ -3,6 +3,8 @@ use crate::arch::asm; use crate::cell::UnsafeCell; use crate::cmp; +use crate::convert::TryInto; +use crate::intrinsics; use crate::mem; use crate::ops::{CoerceUnsized, Deref, DerefMut, Index, IndexMut}; use crate::ptr::{self, NonNull}; @@ -306,20 +308,35 @@ where } } -// Split a memory region ptr..ptr + len into three parts: -// +--------+ -// | small0 | Chunk smaller than 8 bytes -// +--------+ -// | big | Chunk 8-byte aligned, and size a multiple of 8 bytes -// +--------+ -// | small1 | Chunk smaller than 8 bytes -// +--------+ -fn region_as_aligned_chunks(ptr: *const u8, len: usize) -> (usize, usize, usize) { - let small0_size = if ptr.is_aligned_to(8) { 0 } else { 8 - ptr.addr() % 8 }; - let small1_size = (len - small0_size) % 8; - let big_size = len - small0_size - small1_size; - - (small0_size, big_size, small1_size) +/// Divide the slice `(ptr, len)` into three parts, where the middle part is +/// aligned to `u64`. +/// +/// The return values `(prefix_len, mid_len, suffix_len)` add back up to `len`. +/// The return values are such that the memory region `(ptr + prefix_len, +/// mid_len)` is the largest possible region where `ptr + prefix_len` is aligned +/// to `u64` and `mid_len` is a multiple of the byte size of `u64`. This means +/// that `prefix_len` and `suffix_len` are guaranteed to be less than the byte +/// size of `u64`, and that `(ptr, prefix_len)` and `(ptr + prefix_len + +/// mid_len, suffix_len)` don't straddle an alignment boundary. +// Standard Rust functions such as `<[u8]>::align_to::` and +// `<*const u8>::align_offset` aren't _guaranteed_ to compute the largest +// possible middle region, and as such can't be used. +fn u64_align_to_guaranteed(ptr: *const u8, mut len: usize) -> (usize, usize, usize) { + const QWORD_SIZE: usize = mem::size_of::(); + + let offset = ptr as usize % QWORD_SIZE; + + let prefix_len = if intrinsics::unlikely(offset > 0) { QWORD_SIZE - offset } else { 0 }; + + len = match len.checked_sub(prefix_len) { + Some(remaining_len) => remaining_len, + None => return (len, 0, 0), + }; + + let suffix_len = len % QWORD_SIZE; + len -= suffix_len; + + (prefix_len, len, suffix_len) } unsafe fn copy_quadwords(src: *const u8, dst: *mut u8, len: usize) { @@ -352,7 +369,13 @@ unsafe fn copy_quadwords(src: *const u8, dst: *mut u8, len: usize) { /// - https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00615.html /// - https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/processor-mmio-stale-data-vulnerabilities.html#inpage-nav-3-2-2 pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize) { - unsafe fn copy_bytewise_to_userspace(src: *const u8, dst: *mut u8, len: usize) { + /// Like `ptr::copy(src, dst, len)`, except it uses the Intel-recommended + /// instruction sequence for unaligned writes. + unsafe fn write_bytewise_to_userspace(src: *const u8, dst: *mut u8, len: usize) { + if intrinsics::likely(len == 0) { + return; + } + unsafe { let mut seg_sel: u16 = 0; for off in 0..len { @@ -380,41 +403,15 @@ pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize) assert!(!src.addr().overflowing_add(len).1); assert!(!dst.addr().overflowing_add(len).1); - if len < 8 { - // Can't align on 8 byte boundary: copy safely byte per byte - unsafe { - copy_bytewise_to_userspace(src, dst, len); - } - } else if len % 8 == 0 && dst.is_aligned_to(8) { - // Copying 8-byte aligned quadwords: copy quad word per quad word - unsafe { - copy_quadwords(src, dst, len); - } - } else { - // Split copies into three parts: - // +--------+ - // | small0 | Chunk smaller than 8 bytes - // +--------+ - // | big | Chunk 8-byte aligned, and size a multiple of 8 bytes - // +--------+ - // | small1 | Chunk smaller than 8 bytes - // +--------+ - let (small0_size, big_size, small1_size) = region_as_aligned_chunks(dst, len); + unsafe { + let (len1, len2, len3) = u64_align_to_guaranteed(dst, len); + let (src1, dst1) = (src, dst); + let (src2, dst2) = (src1.add(len1), dst1.add(len1)); + let (src3, dst3) = (src2.add(len2), dst2.add(len2)); - unsafe { - // Copy small0 - copy_bytewise_to_userspace(src, dst, small0_size); - - // Copy big - let big_src = src.add(small0_size); - let big_dst = dst.add(small0_size); - copy_quadwords(big_src, big_dst, big_size); - - // Copy small1 - let small1_src = src.add(big_size + small0_size); - let small1_dst = dst.add(big_size + small0_size); - copy_bytewise_to_userspace(small1_src, small1_dst, small1_size); - } + write_bytewise_to_userspace(src1, dst1, len1); + copy_quadwords(src2, dst2, len2); + write_bytewise_to_userspace(src3, dst3, len3); } } @@ -434,45 +431,33 @@ pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize) /// - https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00657.html /// - https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/advisory-guidance/stale-data-read-from-xapic.html pub(crate) unsafe fn copy_from_userspace(src: *const u8, dst: *mut u8, len: usize) { - // Copies memory region `src..src + len` to the enclave at `dst`. The source memory region - // is: - // - strictly less than 8 bytes in size and may be - // - located at a misaligned memory location - fn copy_misaligned_chunk_to_enclave(src: *const u8, dst: *mut u8, len: usize) { - let mut tmp_buff = [0u8; 16]; + /// Like `ptr::copy(src, dst, len)`, except it uses only u64-aligned reads. + /// + /// # Safety + /// The source memory region must not straddle an alignment boundary. + unsafe fn read_misaligned_from_userspace(src: *const u8, dst: *mut u8, len: usize) { + if intrinsics::likely(len == 0) { + return; + } unsafe { - // Compute an aligned memory region to read from - // +--------+ <-- aligned_src + aligned_len (8B-aligned) - // | pad1 | - // +--------+ <-- src + len (misaligned) - // | | - // | | - // | | - // +--------+ <-- src (misaligned) - // | pad0 | - // +--------+ <-- aligned_src (8B-aligned) - let pad0_size = src as usize % 8; - let aligned_src = src.sub(pad0_size); - - let pad1_size = 8 - (src.add(len) as usize % 8); - let aligned_len = pad0_size + len + pad1_size; - - debug_assert!(len < 8); - debug_assert_eq!(aligned_src as usize % 8, 0); - debug_assert_eq!(aligned_len % 8, 0); - debug_assert!(aligned_len <= 16); - - // Copy the aligned buffer to a temporary buffer - // Note: copying from a slightly different memory location is a bit odd. In this case it - // can't lead to page faults or inadvertent copying from the enclave as we only ensured - // that the `src` pointer is aligned at an 8 byte boundary. As pages are 4096 bytes - // aligned, `aligned_src` must be on the same page as `src`. A similar argument can be made - // for `src + len` - copy_quadwords(aligned_src as _, tmp_buff.as_mut_ptr(), aligned_len); - - // Copy the correct parts of the temporary buffer to the destination - ptr::copy(tmp_buff.as_ptr().add(pad0_size), dst, len); + let offset: usize; + let data: u64; + // doing a memory read that's potentially out of bounds for `src`, + // this isn't supported by Rust, so have to use assembly + asm!(" + movl {src:e}, {offset:e} + andl $7, {offset:e} + andq $-8, {src} + movq ({src}), {dst} + ", + src = inout(reg) src => _, + offset = out(reg) offset, + dst = out(reg) data, + options(nostack, att_syntax, readonly, pure) + ); + let data = data.to_le_bytes(); + ptr::copy_nonoverlapping(data.as_ptr().add(offset), dst, len); } } @@ -480,41 +465,19 @@ pub(crate) unsafe fn copy_from_userspace(src: *const u8, dst: *mut u8, len: usiz assert!(!dst.is_null()); assert!(is_user_range(src, len)); assert!(is_enclave_range(dst, len)); - assert!(!(src as usize).overflowing_add(len + 8).1); - assert!(!(dst as usize).overflowing_add(len + 8).1); + assert!(len < isize::MAX as usize); + assert!(!(src as usize).overflowing_add(len).1); + assert!(!(dst as usize).overflowing_add(len).1); - if len < 8 { - copy_misaligned_chunk_to_enclave(src, dst, len); - } else if len % 8 == 0 && src as usize % 8 == 0 { - // Copying 8-byte aligned quadwords: copy quad word per quad word - unsafe { - copy_quadwords(src, dst, len); - } - } else { - // Split copies into three parts: - // +--------+ - // | small0 | Chunk smaller than 8 bytes - // +--------+ - // | big | Chunk 8-byte aligned, and size a multiple of 8 bytes - // +--------+ - // | small1 | Chunk smaller than 8 bytes - // +--------+ - let (small0_size, big_size, small1_size) = region_as_aligned_chunks(dst, len); + unsafe { + let (len1, len2, len3) = u64_align_to_guaranteed(src, len); + let (src1, dst1) = (src, dst); + let (src2, dst2) = (src1.add(len1), dst1.add(len1)); + let (src3, dst3) = (src2.add(len2), dst2.add(len2)); - unsafe { - // Copy small0 - copy_misaligned_chunk_to_enclave(src, dst, small0_size); - - // Copy big - let big_src = src.add(small0_size); - let big_dst = dst.add(small0_size); - copy_quadwords(big_src, big_dst, big_size); - - // Copy small1 - let small1_src = src.add(big_size + small0_size); - let small1_dst = dst.add(big_size + small0_size); - copy_misaligned_chunk_to_enclave(small1_src, small1_dst, small1_size); - } + read_misaligned_from_userspace(src1, dst1, len1); + copy_quadwords(src2, dst2, len2); + read_misaligned_from_userspace(src3, dst3, len3); } } @@ -609,9 +572,9 @@ where /// Copies the value from user memory into enclave memory. pub fn to_enclave(&self) -> T { unsafe { - let mut data: T = mem::MaybeUninit::uninit().assume_init(); - copy_from_userspace(self.0.get() as _, &mut data as *mut T as _, mem::size_of::()); - data + let mut data = mem::MaybeUninit::uninit(); + copy_from_userspace(self.0.get() as _, data.as_mut_ptr() as _, mem::size_of::()); + data.assume_init() } } } diff --git a/library/std/src/sys/sgx/waitqueue/mod.rs b/library/std/src/sys/sgx/waitqueue/mod.rs index 5e1d859ee99c..25eca61d67b6 100644 --- a/library/std/src/sys/sgx/waitqueue/mod.rs +++ b/library/std/src/sys/sgx/waitqueue/mod.rs @@ -18,6 +18,7 @@ mod unsafe_list; use crate::num::NonZeroUsize; use crate::ops::{Deref, DerefMut}; +use crate::panic::{self, AssertUnwindSafe}; use crate::time::Duration; use super::abi::thread; @@ -147,7 +148,8 @@ impl WaitQueue { /// Adds the calling thread to the `WaitVariable`'s wait queue, then wait /// until a wakeup event. /// - /// This function does not return until this thread has been awoken. + /// This function does not return until this thread has been awoken. When `before_wait` panics, + /// this function will abort. pub fn wait(mut guard: SpinMutexGuard<'_, WaitVariable>, before_wait: F) { // very unsafe: check requirements of UnsafeList::push unsafe { @@ -157,8 +159,13 @@ impl WaitQueue { })); let entry = guard.queue.inner.push(&mut entry); drop(guard); - before_wait(); + if let Err(_e) = panic::catch_unwind(AssertUnwindSafe(|| before_wait())) { + rtabort!("Panic before wait on wakeup event") + } while !entry.lock().wake { + // `entry.wake` is only set in `notify_one` and `notify_all` functions. Both ensure + // the entry is removed from the queue _before_ setting this bool. There are no + // other references to `entry`. // don't panic, this would invalidate `entry` during unwinding let eventset = rtunwrap!(Ok, usercalls::wait(EV_UNPARK, WAIT_INDEFINITE)); rtassert!(eventset & EV_UNPARK == EV_UNPARK); @@ -169,6 +176,7 @@ impl WaitQueue { /// Adds the calling thread to the `WaitVariable`'s wait queue, then wait /// until a wakeup event or timeout. If event was observed, returns true. /// If not, it will remove the calling thread from the wait queue. + /// When `before_wait` panics, this function will abort. pub fn wait_timeout( lock: &SpinMutex>, timeout: Duration, @@ -181,9 +189,13 @@ impl WaitQueue { wake: false, })); let entry_lock = lock.lock().queue.inner.push(&mut entry); - before_wait(); + if let Err(_e) = panic::catch_unwind(AssertUnwindSafe(|| before_wait())) { + rtabort!("Panic before wait on wakeup event or timeout") + } usercalls::wait_timeout(EV_UNPARK, timeout, || entry_lock.lock().wake); - // acquire the wait queue's lock first to avoid deadlock. + // acquire the wait queue's lock first to avoid deadlock + // and ensure no other function can simultaneously access the list + // (e.g., `notify_one` or `notify_all`) let mut guard = lock.lock(); let success = entry_lock.lock().wake; if !success { @@ -204,8 +216,8 @@ impl WaitQueue { ) -> Result, SpinMutexGuard<'_, WaitVariable>> { // SAFETY: lifetime of the pop() return value is limited to the map // closure (The closure return value is 'static). The underlying - // stack frame won't be freed until after the WaitGuard created below - // is dropped. + // stack frame won't be freed until after the lock on the queue is released + // (i.e., `guard` is dropped). unsafe { let tcs = guard.queue.inner.pop().map(|entry| -> Tcs { let mut entry_guard = entry.lock(); @@ -231,7 +243,7 @@ impl WaitQueue { ) -> Result, SpinMutexGuard<'_, WaitVariable>> { // SAFETY: lifetime of the pop() return values are limited to the // while loop body. The underlying stack frames won't be freed until - // after the WaitGuard created below is dropped. + // after the lock on the queue is released (i.e., `guard` is dropped). unsafe { let mut count = 0; while let Some(entry) = guard.queue.inner.pop() { diff --git a/library/std/src/sys/uefi/mod.rs b/library/std/src/sys/uefi/mod.rs index 9a10395af8e3..097396ae9939 100644 --- a/library/std/src/sys/uefi/mod.rs +++ b/library/std/src/sys/uefi/mod.rs @@ -36,7 +36,6 @@ pub mod path; pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; -#[path = "../unsupported/stdio.rs"] pub mod stdio; #[path = "../unsupported/thread.rs"] pub mod thread; diff --git a/library/std/src/sys/uefi/stdio.rs b/library/std/src/sys/uefi/stdio.rs new file mode 100644 index 000000000000..a533d8a05750 --- /dev/null +++ b/library/std/src/sys/uefi/stdio.rs @@ -0,0 +1,162 @@ +use crate::io; +use crate::iter::Iterator; +use crate::mem::MaybeUninit; +use crate::os::uefi; +use crate::ptr::NonNull; + +const MAX_BUFFER_SIZE: usize = 8192; + +pub struct Stdin; +pub struct Stdout; +pub struct Stderr; + +impl Stdin { + pub const fn new() -> Stdin { + Stdin + } +} + +impl io::Read for Stdin { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let st: NonNull = uefi::env::system_table().cast(); + let stdin = unsafe { (*st.as_ptr()).con_in }; + + // Try reading any pending data + let inp = match read_key_stroke(stdin) { + Ok(x) => x, + Err(e) if e == r_efi::efi::Status::NOT_READY => { + // Wait for keypress for new data + wait_stdin(stdin)?; + read_key_stroke(stdin).map_err(|x| io::Error::from_raw_os_error(x.as_usize()))? + } + Err(e) => { + return Err(io::Error::from_raw_os_error(e.as_usize())); + } + }; + + // Check if the key is printiable character + if inp.scan_code != 0x00 { + return Err(io::const_io_error!(io::ErrorKind::Interrupted, "Special Key Press")); + } + + // SAFETY: Iterator will have only 1 character since we are reading only 1 Key + // SAFETY: This character will always be UCS-2 and thus no surrogates. + let ch: char = char::decode_utf16([inp.unicode_char]).next().unwrap().unwrap(); + if ch.len_utf8() > buf.len() { + return Ok(0); + } + + ch.encode_utf8(buf); + + Ok(ch.len_utf8()) + } +} + +impl Stdout { + pub const fn new() -> Stdout { + Stdout + } +} + +impl io::Write for Stdout { + fn write(&mut self, buf: &[u8]) -> io::Result { + let st: NonNull = uefi::env::system_table().cast(); + let stdout = unsafe { (*st.as_ptr()).con_out }; + + write(stdout, buf) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl Stderr { + pub const fn new() -> Stderr { + Stderr + } +} + +impl io::Write for Stderr { + fn write(&mut self, buf: &[u8]) -> io::Result { + let st: NonNull = uefi::env::system_table().cast(); + let stderr = unsafe { (*st.as_ptr()).std_err }; + + write(stderr, buf) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +// UCS-2 character should occupy 3 bytes at most in UTF-8 +pub const STDIN_BUF_SIZE: usize = 3; + +pub fn is_ebadf(_err: &io::Error) -> bool { + true +} + +pub fn panic_output() -> Option { + uefi::env::try_system_table().map(|_| Stderr::new()) +} + +fn write( + protocol: *mut r_efi::protocols::simple_text_output::Protocol, + buf: &[u8], +) -> io::Result { + let mut utf16 = [0; MAX_BUFFER_SIZE / 2]; + + // Get valid UTF-8 buffer + let utf8 = match crate::str::from_utf8(buf) { + Ok(x) => x, + Err(e) => unsafe { crate::str::from_utf8_unchecked(&buf[..e.valid_up_to()]) }, + }; + // Clip UTF-8 buffer to max UTF-16 buffer we support + let utf8 = &utf8[..utf8.floor_char_boundary(utf16.len() - 1)]; + + for (i, ch) in utf8.encode_utf16().enumerate() { + utf16[i] = ch; + } + + unsafe { simple_text_output(protocol, &mut utf16) }?; + + Ok(utf8.len()) +} + +unsafe fn simple_text_output( + protocol: *mut r_efi::protocols::simple_text_output::Protocol, + buf: &mut [u16], +) -> io::Result<()> { + let res = unsafe { ((*protocol).output_string)(protocol, buf.as_mut_ptr()) }; + if res.is_error() { Err(io::Error::from_raw_os_error(res.as_usize())) } else { Ok(()) } +} + +fn wait_stdin(stdin: *mut r_efi::protocols::simple_text_input::Protocol) -> io::Result<()> { + let boot_services: NonNull = + uefi::env::boot_services().unwrap().cast(); + let wait_for_event = unsafe { (*boot_services.as_ptr()).wait_for_event }; + let wait_for_key_event = unsafe { (*stdin).wait_for_key }; + + let r = { + let mut x: usize = 0; + (wait_for_event)(1, [wait_for_key_event].as_mut_ptr(), &mut x) + }; + if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } +} + +fn read_key_stroke( + stdin: *mut r_efi::protocols::simple_text_input::Protocol, +) -> Result { + let mut input_key: MaybeUninit = + MaybeUninit::uninit(); + + let r = unsafe { ((*stdin).read_key_stroke)(stdin, input_key.as_mut_ptr()) }; + + if r.is_error() { + Err(r) + } else { + let input_key = unsafe { input_key.assume_init() }; + Ok(input_key) + } +} diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 764e1f257901..5ed2bdd7fe32 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -1391,6 +1391,7 @@ impl FromInner for File { } impl AsFd for File { + #[inline] fn as_fd(&self) -> BorrowedFd<'_> { self.0.as_fd() } diff --git a/library/std/src/sys/unix/thread_local_dtor.rs b/library/std/src/sys/unix/thread_local_dtor.rs index fba2a676f280..e9d19766592c 100644 --- a/library/std/src/sys/unix/thread_local_dtor.rs +++ b/library/std/src/sys/unix/thread_local_dtor.rs @@ -11,28 +11,47 @@ // Note, however, that we run on lots older linuxes, as well as cross // compiling from a newer linux to an older linux, so we also have a // fallback implementation to use as well. +#[allow(unexpected_cfgs)] #[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "redox", target_os = "hurd"))] +// FIXME: The Rust compiler currently omits weakly function definitions (i.e., +// __cxa_thread_atexit_impl) and its metadata from LLVM IR. +#[no_sanitize(cfi, kcfi)] pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { use crate::mem; use crate::sys_common::thread_local_dtor::register_dtor_fallback; + /// This is necessary because the __cxa_thread_atexit_impl implementation + /// std links to by default may be a C or C++ implementation that was not + /// compiled using the Clang integer normalization option. + #[cfg(not(sanitizer_cfi_normalize_integers))] + #[cfi_encoding = "i"] + #[repr(transparent)] + pub struct c_int(pub libc::c_int); + extern "C" { #[linkage = "extern_weak"] static __dso_handle: *mut u8; #[linkage = "extern_weak"] - static __cxa_thread_atexit_impl: *const libc::c_void; + static __cxa_thread_atexit_impl: Option< + extern "C" fn( + unsafe extern "C" fn(*mut libc::c_void), + *mut libc::c_void, + *mut libc::c_void, + ) -> c_int, + >; } - if !__cxa_thread_atexit_impl.is_null() { - type F = unsafe extern "C" fn( - dtor: unsafe extern "C" fn(*mut u8), - arg: *mut u8, - dso_handle: *mut u8, - ) -> libc::c_int; - mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl)( - dtor, - t, - &__dso_handle as *const _ as *mut _, - ); + + if let Some(f) = __cxa_thread_atexit_impl { + unsafe { + f( + mem::transmute::< + unsafe extern "C" fn(*mut u8), + unsafe extern "C" fn(*mut libc::c_void), + >(dtor), + t.cast(), + &__dso_handle as *const _ as *mut _, + ); + } return; } register_dtor_fallback(t, dtor); diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index f3637cbb981d..a349e24b0395 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -46,6 +46,10 @@ pub use FD_SET as fd_set; pub use LINGER as linger; pub use TIMEVAL as timeval; +// https://learn.microsoft.com/en-us/cpp/c-runtime-library/exit-success-exit-failure?view=msvc-170 +pub const EXIT_SUCCESS: u32 = 0; +pub const EXIT_FAILURE: u32 = 1; + pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { Ptr: ptr::null_mut() }; pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { Ptr: ptr::null_mut() }; pub const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { Ptr: ptr::null_mut() }; diff --git a/library/std/src/sys/windows/cmath.rs b/library/std/src/sys/windows/cmath.rs index 1b2a86f3c0eb..36578d5a34e1 100644 --- a/library/std/src/sys/windows/cmath.rs +++ b/library/std/src/sys/windows/cmath.rs @@ -1,6 +1,6 @@ #![cfg(not(test))] -use libc::{c_double, c_float, c_int}; +use core::ffi::{c_double, c_float, c_int}; extern "C" { pub fn acos(n: c_double) -> c_double; @@ -33,7 +33,7 @@ pub use self::shims::*; #[cfg(not(all(target_env = "msvc", target_arch = "x86")))] mod shims { - use libc::c_float; + use core::ffi::c_float; extern "C" { pub fn acosf(n: c_float) -> c_float; @@ -52,7 +52,7 @@ mod shims { // back to f32. While not precisely correct should be "correct enough" for now. #[cfg(all(target_env = "msvc", target_arch = "x86"))] mod shims { - use libc::c_float; + use core::ffi::c_float; #[inline] pub unsafe fn acosf(n: c_float) -> c_float { diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index 21a65bc25f35..0113196b8247 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -16,6 +16,8 @@ use crate::sys::{c, cvt, Align8}; use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::thread; +use core::ffi::c_void; + use super::path::maybe_verbatim; use super::to_u16s; @@ -371,7 +373,7 @@ impl File { cvt(c::GetFileInformationByHandleEx( self.handle.as_raw_handle(), c::FileBasicInfo, - &mut info as *mut _ as *mut libc::c_void, + &mut info as *mut _ as *mut c_void, size as c::DWORD, ))?; let mut attr = FileAttr { @@ -399,7 +401,7 @@ impl File { cvt(c::GetFileInformationByHandleEx( self.handle.as_raw_handle(), c::FileStandardInfo, - &mut info as *mut _ as *mut libc::c_void, + &mut info as *mut _ as *mut c_void, size as c::DWORD, ))?; attr.file_size = info.AllocationSize as u64; @@ -624,7 +626,7 @@ impl File { cvt(c::GetFileInformationByHandleEx( self.handle.as_raw_handle(), c::FileBasicInfo, - &mut info as *mut _ as *mut libc::c_void, + &mut info as *mut _ as *mut c_void, size as c::DWORD, ))?; Ok(info) diff --git a/library/std/src/sys/windows/io.rs b/library/std/src/sys/windows/io.rs index fc9856caed62..9b540ee071f4 100644 --- a/library/std/src/sys/windows/io.rs +++ b/library/std/src/sys/windows/io.rs @@ -3,7 +3,7 @@ use crate::mem::size_of; use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle}; use crate::slice; use crate::sys::c; -use libc; +use core::ffi::c_void; #[derive(Copy, Clone)] #[repr(transparent)] @@ -136,7 +136,7 @@ unsafe fn msys_tty_on(handle: c::HANDLE) -> bool { let res = c::GetFileInformationByHandleEx( handle, c::FileNameInfo, - &mut name_info as *mut _ as *mut libc::c_void, + &mut name_info as *mut _ as *mut c_void, size_of::() as u32, ); if res == 0 { diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs index abdcab4247fa..4b7115f97c50 100644 --- a/library/std/src/sys/windows/net.rs +++ b/library/std/src/sys/windows/net.rs @@ -15,7 +15,7 @@ use crate::sys_common::net; use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::time::Duration; -use libc::{c_int, c_long, c_ulong, c_ushort}; +use core::ffi::{c_int, c_long, c_ulong, c_ushort}; pub type wrlen_t = i32; diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index cd5bf7f1538c..f4078d359448 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -19,8 +19,7 @@ use crate::path::{Path, PathBuf}; use crate::ptr; use crate::sync::Mutex; use crate::sys::args::{self, Arg}; -use crate::sys::c; -use crate::sys::c::NonZeroDWORD; +use crate::sys::c::{self, NonZeroDWORD, EXIT_FAILURE, EXIT_SUCCESS}; use crate::sys::cvt; use crate::sys::fs::{File, OpenOptions}; use crate::sys::handle::Handle; @@ -30,7 +29,7 @@ use crate::sys::stdio; use crate::sys_common::process::{CommandEnv, CommandEnvs}; use crate::sys_common::IntoInner; -use libc::{c_void, EXIT_FAILURE, EXIT_SUCCESS}; +use core::ffi::c_void; //////////////////////////////////////////////////////////////////////////////// // Command diff --git a/library/std/src/sys/windows/thread.rs b/library/std/src/sys/windows/thread.rs index 18cecb65681d..4b825d2a9f51 100644 --- a/library/std/src/sys/windows/thread.rs +++ b/library/std/src/sys/windows/thread.rs @@ -10,7 +10,7 @@ use crate::sys::stack_overflow; use crate::sys_common::FromInner; use crate::time::Duration; -use libc::c_void; +use core::ffi::c_void; use super::to_u16s; diff --git a/library/std/src/time.rs b/library/std/src/time.rs index c638cc61856f..90ac0098dec9 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -58,6 +58,8 @@ pub use core::time::TryFromFloatSecsError; /// some seconds may be longer than others). An instant may jump forwards or /// experience time dilation (slow down or speed up), but it will never go /// backwards. +/// As part of this non-guarantee it is also not specified whether system suspends count as +/// elapsed time or not. The behavior varies across platforms and rust versions. /// /// Instants are opaque types that can only be compared to one another. There is /// no method to get "the number of seconds" from an instant. Instead, it only @@ -151,6 +153,7 @@ pub use core::time::TryFromFloatSecsError; /// #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[stable(feature = "time2", since = "1.8.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "Instant")] pub struct Instant(time::Instant); /// A measurement of the system clock, useful for talking to diff --git a/rust-bors.toml b/rust-bors.toml new file mode 100644 index 000000000000..54f4f641248c --- /dev/null +++ b/rust-bors.toml @@ -0,0 +1 @@ +timeout = 7200 diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md deleted file mode 100644 index 1aba0713850a..000000000000 --- a/src/bootstrap/CHANGELOG.md +++ /dev/null @@ -1,71 +0,0 @@ -# Changelog - -All notable changes to bootstrap will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - - -## [Changes since the last major version] - -- Vendoring is no longer done automatically when building from git sources. To use vendoring, run `cargo vendor` manually, or use the pre-vendored `rustc-src` tarball. -- `llvm-libunwind` now accepts `in-tree` (formerly true), `system` or `no` (formerly false) [#77703](https://github.com/rust-lang/rust/pull/77703) -- The options `infodir`, `localstatedir`, and `gpg-password-file` are no longer allowed in config.toml. Previously, they were ignored without warning. Note that `infodir` and `localstatedir` are still accepted by `./configure`, with a warning. [#82451](https://github.com/rust-lang/rust/pull/82451) -- Change the names for `dist` commands to match the component they generate. [#90684](https://github.com/rust-lang/rust/pull/90684) -- The `build.fast-submodules` option has been removed. Fast submodule checkouts are enabled unconditionally. Automatic submodule handling can still be disabled with `build.submodules = false`. -- Several unsupported `./configure` options have been removed: `optimize`, `parallel-compiler`. These can still be enabled with `--set`, although it isn't recommended. -- `remote-test-server`'s `verbose` argument has been removed in favor of the `--verbose` flag -- `remote-test-server`'s `remote` argument has been removed in favor of the `--bind` flag. Use `--bind 0.0.0.0:12345` to replicate the behavior of the `remote` argument. -- `x.py fmt` now formats only files modified between the merge-base of HEAD and the last commit in the master branch of the rust-lang repository and the current working directory. To restore old behaviour, use `x.py fmt .`. The check mode is not affected by this change. [#105702](https://github.com/rust-lang/rust/pull/105702) -- The `llvm.version-check` config option has been removed. Older versions were never supported. If you still need to support older versions (e.g. you are applying custom patches), patch `check_llvm_version` in bootstrap to change the minimum version. [#108619](https://github.com/rust-lang/rust/pull/108619) -- The `rust.ignore-git` option has been renamed to `rust.omit-git-hash`. [#110059](https://github.com/rust-lang/rust/pull/110059) -- `--exclude` no longer accepts a `Kind` as part of a Step; instead it uses the top-level Kind of the subcommand. If this matches how you were already using --exclude (e.g. `x test --exclude test::std`), simply remove the kind: `--exclude std`. If you were using a kind that did not match the top-level subcommand, please open an issue explaining why you wanted this feature. - -### Non-breaking changes - -- `x.py check` needs opt-in to check tests (--all-targets) [#77473](https://github.com/rust-lang/rust/pull/77473) -- The default bootstrap profiles are now located at `bootstrap/defaults/config.$PROFILE.toml` (previously they were located at `bootstrap/defaults/config.toml.$PROFILE`) [#77558](https://github.com/rust-lang/rust/pull/77558) -- If you have Rust already installed, `x.py` will now infer the host target - from the default rust toolchain. [#78513](https://github.com/rust-lang/rust/pull/78513) -- Add options for enabling overflow checks, one for std (`overflow-checks-std`) and one for everything else (`overflow-checks`). Both default to false. -- Add llvm option `enable-warnings` to have control on llvm compilation warnings. Default to false. -- Add `rpath` option in `target` section to support set rpath option for each target independently. [#111242](https://github.com/rust-lang/rust/pull/111242) - - -## [Version 2] - 2020-09-25 - -- `host` now defaults to the value of `build` in all cases - + Previously `host` defaulted to an empty list when `target` was overridden, and to `build` otherwise - -### Non-breaking changes - -- Add `x.py setup` [#76631](https://github.com/rust-lang/rust/pull/76631) -- Add a changelog for x.py [#76626](https://github.com/rust-lang/rust/pull/76626) -- Optionally, download LLVM from CI on Linux and NixOS. This can be enabled with `download-ci-llvm = true` under `[llvm]`. - + [#76439](https://github.com/rust-lang/rust/pull/76349) - + [#76667](https://github.com/rust-lang/rust/pull/76667) - + [#76708](https://github.com/rust-lang/rust/pull/76708) -- Distribute rustc sources as part of `rustc-dev` [#76856](https://github.com/rust-lang/rust/pull/76856) -- Make the default stage for x.py configurable [#76625](https://github.com/rust-lang/rust/pull/76625). This can be enabled with `build-stage = N`, `doc-stage = N`, etc. -- Add a dedicated debug-logging option [#76588](https://github.com/rust-lang/rust/pull/76588). Previously, `debug-logging` could only be set with `debug-assertions`, slowing down the compiler more than necessary. -- Add sample defaults for x.py [#76628](https://github.com/rust-lang/rust/pull/76628) -- Add `--keep-stage-std`, which behaves like `keep-stage` but allows the stage - 0 compiler artifacts (i.e., stage1/bin/rustc) to be rebuilt if changed - [#77120](https://github.com/rust-lang/rust/pull/77120). -- File locking is now used to avoid collisions between multiple running instances of `x.py` (e.g. when using `rust-analyzer` and `x.py` at the same time). Note that Solaris and possibly other non Unix and non Windows systems don't support it [#108607](https://github.com/rust-lang/rust/pull/108607). This might possibly lead to build data corruption. - - -## [Version 1] - 2020-09-11 - -This is the first changelog entry, and it does not attempt to be an exhaustive list of features in x.py. -Instead, this documents the changes to bootstrap in the past 2 months. - -- Improve defaults in `x.py` [#73964](https://github.com/rust-lang/rust/pull/73964) - (see [blog post] for details) -- Set `ninja = true` by default [#74922](https://github.com/rust-lang/rust/pull/74922) -- Avoid trying to inversely cross-compile for build triple from host triples [#76415](https://github.com/rust-lang/rust/pull/76415) -- Allow blessing expect-tests in tools [#75975](https://github.com/rust-lang/rust/pull/75975) -- `x.py check` checks tests/examples/benches [#76258](https://github.com/rust-lang/rust/pull/76258) -- Fix `rust.use-lld` when linker is not set [#76326](https://github.com/rust-lang/rust/pull/76326) -- Build tests with LLD if `use-lld = true` was passed [#76378](https://github.com/rust-lang/rust/pull/76378) - -[blog post]: https://blog.rust-lang.org/inside-rust/2020/08/30/changes-to-x-py-defaults.html diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md index 548281ca5068..e7998a40a652 100644 --- a/src/bootstrap/README.md +++ b/src/bootstrap/README.md @@ -181,11 +181,10 @@ Some general areas that you may be interested in modifying are: `Config` struct. * Adding a sanity check? Take a look at `bootstrap/sanity.rs`. -If you make a major change, please remember to: +If you make a major change on bootstrap configuration, please remember to: -+ Update `VERSION` in `src/bootstrap/main.rs`. -* Update `changelog-seen = N` in `config.example.toml`. -* Add an entry in `src/bootstrap/CHANGELOG.md`. ++ Update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/lib.rs`. +* Update `change-id = {pull-request-id}` in `config.example.toml`. A 'major change' includes @@ -193,7 +192,7 @@ A 'major change' includes * A change in the default options. Changes that do not affect contributors to the compiler or users -building rustc from source don't need an update to `VERSION`. +building rustc from source don't need an update to `CONFIG_CHANGE_HISTORY`. If you have any questions, feel free to reach out on the `#t-infra/bootstrap` channel at [Rust Bootstrap Zulip server][rust-bootstrap-zulip]. When you encounter bugs, @@ -201,3 +200,8 @@ please file issues on the [Rust issue tracker][rust-issue-tracker]. [rust-bootstrap-zulip]: https://rust-lang.zulipchat.com/#narrow/stream/t-infra.2Fbootstrap [rust-issue-tracker]: https://github.com/rust-lang/rust/issues + +## Changelog + +Because we do not release bootstrap with versions, we also do not maintain CHANGELOG files. To +review the changes made to bootstrap, simply run `git log --no-merges --oneline -- src/bootstrap`. diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs index c497cabbd692..d87fb6a9cef0 100644 --- a/src/bootstrap/bin/main.rs +++ b/src/bootstrap/bin/main.rs @@ -13,7 +13,7 @@ use std::{env, fs}; #[cfg(all(any(unix, windows), not(target_os = "solaris")))] use bootstrap::t; -use bootstrap::{Build, Config, Subcommand, VERSION}; +use bootstrap::{find_recent_config_change_ids, Build, Config, Subcommand, CONFIG_CHANGE_HISTORY}; fn main() { let args = env::args().skip(1).collect::>(); @@ -42,7 +42,7 @@ fn main() { } err => { drop(err); - println!("warning: build directory locked by process {pid}, waiting for lock"); + println!("WARNING: build directory locked by process {pid}, waiting for lock"); let mut lock = t!(build_lock.write()); t!(lock.write(&process::id().to_string().as_ref())); lock @@ -51,7 +51,7 @@ fn main() { } #[cfg(any(not(any(unix, windows)), target_os = "solaris"))] - println!("warning: file locking not supported for target, not locking build directory"); + println!("WARNING: file locking not supported for target, not locking build directory"); // check_version warnings are not printed during setup let changelog_suggestion = @@ -61,7 +61,7 @@ fn main() { // changelog warning, not the `x.py setup` message. let suggest_setup = config.config.is_none() && !matches!(config.cmd, Subcommand::Setup { .. }); if suggest_setup { - println!("warning: you have not made a `config.toml`"); + println!("WARNING: you have not made a `config.toml`"); println!( "help: consider running `./x.py setup` or copying `config.example.toml` by running \ `cp config.example.toml config.toml`" @@ -74,7 +74,7 @@ fn main() { Build::new(config).build(); if suggest_setup { - println!("warning: you have not made a `config.toml`"); + println!("WARNING: you have not made a `config.toml`"); println!( "help: consider running `./x.py setup` or copying `config.example.toml` by running \ `cp config.example.toml config.toml`" @@ -91,7 +91,7 @@ fn main() { contents.contains("https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570") }) { println!( - "warning: You have the pre-push script installed to .git/hooks/pre-commit. \ + "WARNING: You have the pre-push script installed to .git/hooks/pre-commit. \ Consider moving it to .git/hooks/pre-push instead, which runs less often." ); } @@ -104,19 +104,34 @@ fn main() { fn check_version(config: &Config) -> Option { let mut msg = String::new(); - let suggestion = if let Some(seen) = config.changelog_seen { - if seen != VERSION { - msg.push_str("warning: there have been changes to x.py since you last updated.\n"); - format!("update `config.toml` to use `changelog-seen = {VERSION}` instead") + if config.changelog_seen.is_some() { + msg.push_str("WARNING: The use of `changelog-seen` is deprecated. Please refer to `change-id` option in `config.example.toml` instead.\n"); + } + + let latest_config_id = CONFIG_CHANGE_HISTORY.last().unwrap(); + let suggestion = if let Some(id) = config.change_id { + if &id != latest_config_id { + msg.push_str("WARNING: there have been changes to x.py since you last updated.\n"); + let change_links: Vec = find_recent_config_change_ids(id) + .iter() + .map(|id| format!("https://github.com/rust-lang/rust/pull/{id}")) + .collect(); + if !change_links.is_empty() { + msg.push_str("To see more detail about these changes, visit the following PRs:\n"); + for link in change_links { + msg.push_str(&format!(" - {link}\n")); + } + } + msg.push_str("WARNING: there have been changes to x.py since you last updated.\n"); + format!("update `config.toml` to use `change-id = {latest_config_id}` instead") } else { return None; } } else { - msg.push_str("warning: x.py has made several changes recently you may want to look at\n"); - format!("add `changelog-seen = {VERSION}` at the top of `config.toml`") + msg.push_str("WARNING: The `change-id` is missing in the `config.toml`. This means that you will not be able to track the major changes made to the bootstrap configurations.\n"); + format!("add `change-id = {latest_config_id}` at the top of `config.toml`") }; - msg.push_str("help: consider looking at the changes in `src/bootstrap/CHANGELOG.md`\n"); msg.push_str("note: to silence this warning, "); msg.push_str(&suggestion); diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index d58f0d54d3ae..4af97b2f466d 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -41,6 +41,10 @@ def get_cpus(): return 1 +def eprint(*args, **kwargs): + kwargs["file"] = sys.stderr + print(*args, **kwargs) + def get(base, url, path, checksums, verbose=False): with tempfile.NamedTemporaryFile(delete=False) as temp_file: @@ -57,23 +61,23 @@ def get(base, url, path, checksums, verbose=False): if os.path.exists(path): if verify(path, sha256, False): if verbose: - print("using already-download file", path, file=sys.stderr) + eprint("using already-download file", path) return else: if verbose: - print("ignoring already-download file", - path, "due to failed verification", file=sys.stderr) + eprint("ignoring already-download file", + path, "due to failed verification") os.unlink(path) download(temp_path, "{}/{}".format(base, url), True, verbose) if not verify(temp_path, sha256, verbose): raise RuntimeError("failed verification") if verbose: - print("moving {} to {}".format(temp_path, path), file=sys.stderr) + eprint("moving {} to {}".format(temp_path, path)) shutil.move(temp_path, path) finally: if os.path.isfile(temp_path): if verbose: - print("removing", temp_path, file=sys.stderr) + eprint("removing", temp_path) os.unlink(temp_path) @@ -83,7 +87,7 @@ def download(path, url, probably_big, verbose): _download(path, url, probably_big, verbose, True) return except RuntimeError: - print("\nspurious failure, trying again", file=sys.stderr) + eprint("\nspurious failure, trying again") _download(path, url, probably_big, verbose, False) @@ -94,7 +98,7 @@ def _download(path, url, probably_big, verbose, exception): # - If we are on win32 fallback to powershell # - Otherwise raise the error if appropriate if probably_big or verbose: - print("downloading {}".format(url), file=sys.stderr) + eprint("downloading {}".format(url)) try: if (probably_big or verbose) and "GITHUB_ACTIONS" not in os.environ: @@ -129,20 +133,20 @@ def _download(path, url, probably_big, verbose, exception): def verify(path, expected, verbose): """Check if the sha256 sum of the given path is valid""" if verbose: - print("verifying", path, file=sys.stderr) + eprint("verifying", path) with open(path, "rb") as source: found = hashlib.sha256(source.read()).hexdigest() verified = found == expected if not verified: - print("invalid checksum:\n" + eprint("invalid checksum:\n" " found: {}\n" - " expected: {}".format(found, expected), file=sys.stderr) + " expected: {}".format(found, expected)) return verified def unpack(tarball, tarball_suffix, dst, verbose=False, match=None): """Unpack the given tarball file""" - print("extracting", tarball, file=sys.stderr) + eprint("extracting", tarball) fname = os.path.basename(tarball).replace(tarball_suffix, "") with contextlib.closing(tarfile.open(tarball)) as tar: for member in tar.getnames(): @@ -155,7 +159,7 @@ def unpack(tarball, tarball_suffix, dst, verbose=False, match=None): dst_path = os.path.join(dst, name) if verbose: - print(" extracting", member, file=sys.stderr) + eprint(" extracting", member) tar.extract(member, dst) src_path = os.path.join(dst, member) if os.path.isdir(src_path) and os.path.exists(dst_path): @@ -167,7 +171,7 @@ def unpack(tarball, tarball_suffix, dst, verbose=False, match=None): def run(args, verbose=False, exception=False, is_bootstrap=False, **kwargs): """Run a child program in a new process""" if verbose: - print("running: " + ' '.join(args), file=sys.stderr) + eprint("running: " + ' '.join(args)) sys.stdout.flush() # Ensure that the .exe is used on Windows just in case a Linux ELF has been # compiled in the same directory. @@ -207,8 +211,8 @@ def require(cmd, exit=True, exception=False): if exception: raise elif exit: - print("error: unable to run `{}`: {}".format(' '.join(cmd), exc), file=sys.stderr) - print("Please make sure it's installed and in the path.", file=sys.stderr) + eprint("error: unable to run `{}`: {}".format(' '.join(cmd), exc)) + eprint("Please make sure it's installed and in the path.") sys.exit(1) return None @@ -239,14 +243,12 @@ def default_build_triple(verbose): host = next(x for x in version.split('\n') if x.startswith("host: ")) triple = host.split("host: ")[1] if verbose: - print("detected default triple {} from pre-installed rustc".format(triple), - file=sys.stderr) + eprint("detected default triple {} from pre-installed rustc".format(triple)) return triple except Exception as e: if verbose: - print("pre-installed rustc not detected: {}".format(e), - file=sys.stderr) - print("falling back to auto-detect", file=sys.stderr) + eprint("pre-installed rustc not detected: {}".format(e)) + eprint("falling back to auto-detect") required = not platform_is_win32() uname = require(["uname", "-smp"], exit=required) @@ -672,15 +674,14 @@ def get_answer(): if not is_nixos: in_nix_shell = os.getenv('IN_NIX_SHELL') if in_nix_shell: - print("The IN_NIX_SHELL environment variable is `{}`;".format(in_nix_shell), - "you may need to set `patch-binaries-for-nix=true` in config.toml", - file=sys.stderr) + eprint("The IN_NIX_SHELL environment variable is `{}`;".format(in_nix_shell), + "you may need to set `patch-binaries-for-nix=true` in config.toml") return is_nixos answer = self._should_fix_bins_and_dylibs = get_answer() if answer: - print("info: You seem to be using Nix.", file=sys.stderr) + eprint("info: You seem to be using Nix.") return answer def fix_bin_or_dylib(self, fname): @@ -693,7 +694,7 @@ def fix_bin_or_dylib(self, fname): Please see https://nixos.org/patchelf.html for more information """ assert self._should_fix_bins_and_dylibs is True - print("attempting to patch", fname, file=sys.stderr) + eprint("attempting to patch", fname) # Only build `.nix-deps` once. nix_deps_dir = self.nix_deps_dir @@ -726,7 +727,7 @@ def fix_bin_or_dylib(self, fname): "nix-build", "-E", nix_expr, "-o", nix_deps_dir, ]) except subprocess.CalledProcessError as reason: - print("warning: failed to call nix-build:", reason, file=sys.stderr) + eprint("warning: failed to call nix-build:", reason) return self.nix_deps_dir = nix_deps_dir @@ -746,7 +747,7 @@ def fix_bin_or_dylib(self, fname): try: subprocess.check_output([patchelf] + patchelf_args + [fname]) except subprocess.CalledProcessError as reason: - print("warning: failed to call patchelf:", reason, file=sys.stderr) + eprint("warning: failed to call patchelf:", reason) return def rustc_stamp(self): @@ -888,7 +889,7 @@ def build_bootstrap(self): if "GITHUB_ACTIONS" in env: print("::group::Building bootstrap") else: - print("Building bootstrap", file=sys.stderr) + eprint("Building bootstrap") args = self.build_bootstrap_cmd(env) # Run this from the source directory so cargo finds .cargo/config @@ -997,12 +998,9 @@ def check_vendored_status(self): if 'SUDO_USER' in os.environ and not self.use_vendored_sources: if os.getuid() == 0: self.use_vendored_sources = True - print('info: looks like you\'re trying to run this command as root', - file=sys.stderr) - print(' and so in order to preserve your $HOME this will now', - file=sys.stderr) - print(' use vendored sources by default.', - file=sys.stderr) + eprint('info: looks like you\'re trying to run this command as root') + eprint(' and so in order to preserve your $HOME this will now') + eprint(' use vendored sources by default.') cargo_dir = os.path.join(self.rust_root, '.cargo') if self.use_vendored_sources: @@ -1012,18 +1010,14 @@ def check_vendored_status(self): "--sync ./src/tools/rust-analyzer/Cargo.toml " \ "--sync ./compiler/rustc_codegen_cranelift/Cargo.toml " \ "--sync ./src/bootstrap/Cargo.toml " - print('error: vendoring required, but vendor directory does not exist.', - file=sys.stderr) - print(' Run `cargo vendor {}` to initialize the ' - 'vendor directory.'.format(sync_dirs), - file=sys.stderr) - print('Alternatively, use the pre-vendored `rustc-src` dist component.', - file=sys.stderr) + eprint('error: vendoring required, but vendor directory does not exist.') + eprint(' Run `cargo vendor {}` to initialize the ' + 'vendor directory.'.format(sync_dirs)) + eprint('Alternatively, use the pre-vendored `rustc-src` dist component.') raise Exception("{} not found".format(vendor_dir)) if not os.path.exists(cargo_dir): - print('error: vendoring required, but .cargo/config does not exist.', - file=sys.stderr) + eprint('error: vendoring required, but .cargo/config does not exist.') raise Exception("{} not found".format(cargo_dir)) else: if os.path.exists(cargo_dir): @@ -1048,6 +1042,12 @@ def bootstrap(args): """Configure, fetch, build and run the initial bootstrap""" rust_root = os.path.abspath(os.path.join(__file__, '../../..')) + if not os.path.exists(os.path.join(rust_root, '.git')) and \ + os.path.exists(os.path.join(rust_root, '.github')): + eprint("warn: Looks like you are trying to bootstrap Rust from a source that is neither a " + "git clone nor distributed tarball.\nThis build may fail due to missing submodules " + "unless you put them in place manually.") + # Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then `./config.toml`, # then `config.toml` in the root directory. toml_path = args.config or os.getenv('RUST_BOOTSTRAP_CONFIG') @@ -1117,10 +1117,9 @@ def main(): # If the user is asking for help, let them know that the whole download-and-build # process has to happen before anything is printed out. if help_triggered: - print( + eprint( "info: Downloading and building bootstrap before processing --help command.\n" - " See src/bootstrap/README.md for help with common commands." - , file=sys.stderr) + " See src/bootstrap/README.md for help with common commands.") exit_code = 0 success_word = "successfully" @@ -1131,12 +1130,11 @@ def main(): exit_code = error.code else: exit_code = 1 - print(error, file=sys.stderr) + eprint(error) success_word = "unsuccessfully" if not help_triggered: - print("Build completed", success_word, "in", format_build_time(time() - start_time), - file=sys.stderr) + eprint("Build completed", success_word, "in", format_build_time(time() - start_time)) sys.exit(exit_code) diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py index dc06a4c97343..fefd6b187394 100644 --- a/src/bootstrap/bootstrap_test.py +++ b/src/bootstrap/bootstrap_test.py @@ -103,7 +103,7 @@ class GenerateAndParseConfig(unittest.TestCase): """Test that we can serialize and deserialize a config.toml file""" def test_no_args(self): build = serialize_and_parse([]) - self.assertEqual(build.get_toml("changelog-seen"), '2') + self.assertEqual(build.get_toml("change-id"), '115898') self.assertEqual(build.get_toml("profile"), 'dist') self.assertIsNone(build.get_toml("llvm.download-ci-llvm")) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 292ccc5780fa..cf1f97c5b416 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -158,6 +158,25 @@ impl Step for Std { target_deps.extend(copy_third_party_objects(builder, &compiler, target)); target_deps.extend(copy_self_contained_objects(builder, &compiler, target)); + // The LLD wrappers and `rust-lld` are self-contained linking components that can be + // necessary to link the stdlib on some targets. We'll also need to copy these binaries to + // the `stage0-sysroot` to ensure the linker is found when bootstrapping on such a target. + if compiler.stage == 0 && compiler.host == builder.config.build { + // We want to copy the host `bin` folder within the `rustlib` folder in the sysroot. + let src_sysroot_bin = builder + .rustc_snapshot_sysroot() + .join("lib") + .join("rustlib") + .join(compiler.host.triple) + .join("bin"); + if src_sysroot_bin.exists() { + let target_sysroot_bin = + builder.sysroot_libdir(compiler, target).parent().unwrap().join("bin"); + t!(fs::create_dir_all(&target_sysroot_bin)); + builder.cp_r(&src_sysroot_bin, &target_sysroot_bin); + } + } + let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "build"); std_cargo(builder, target, compiler.stage, &mut cargo); for krate in &*self.crates { diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 98ce4363cf47..990c0c1274b7 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -112,7 +112,8 @@ impl Display for DebuginfoLevel { /// `config.example.toml`. #[derive(Default, Clone)] pub struct Config { - pub changelog_seen: Option, + pub changelog_seen: Option, // FIXME: Deprecated field. Remove it at 2024. + pub change_id: Option, pub ccache: Option, /// Call Build::ninja() instead of this. pub ninja_in_file: bool, @@ -571,7 +572,8 @@ impl Target { #[derive(Deserialize, Default)] #[serde(deny_unknown_fields, rename_all = "kebab-case")] struct TomlConfig { - changelog_seen: Option, + changelog_seen: Option, // FIXME: Deprecated field. Remove it at 2024. + change_id: Option, build: Option, install: Option, llvm: Option, @@ -610,6 +612,7 @@ impl Merge for TomlConfig { ferrocene, profile: _, changelog_seen, + change_id, }: Self, replace: ReplaceOpt, ) { @@ -623,6 +626,7 @@ impl Merge for TomlConfig { } } self.changelog_seen.merge(changelog_seen, replace); + self.change_id.merge(change_id, replace); do_merge(&mut self.build, build, replace); do_merge(&mut self.install, install, replace); do_merge(&mut self.llvm, llvm, replace); @@ -1291,6 +1295,7 @@ impl Config { toml.merge(override_toml, ReplaceOpt::Override); config.changelog_seen = toml.changelog_seen; + config.change_id = toml.change_id; let build = toml.build.unwrap_or_default(); if let Some(file_build) = build.build { diff --git a/src/bootstrap/config/tests.rs b/src/bootstrap/config/tests.rs index aac76cdcbcf8..d091f33eee44 100644 --- a/src/bootstrap/config/tests.rs +++ b/src/bootstrap/config/tests.rs @@ -102,7 +102,7 @@ fn override_toml() { &[ "check".to_owned(), "--config=/does/not/exist".to_owned(), - "--set=changelog-seen=1".to_owned(), + "--set=change-id=1".to_owned(), "--set=rust.lto=fat".to_owned(), "--set=rust.deny-warnings=false".to_owned(), "--set=build.gdb=\"bar\"".to_owned(), @@ -112,7 +112,7 @@ fn override_toml() { |&_| { toml::from_str( r#" -changelog-seen = 0 +change-id = 0 [rust] lto = "off" deny-warnings = true @@ -129,7 +129,7 @@ build-config = {} .unwrap() }, ); - assert_eq!(config.changelog_seen, Some(1), "setting top-level value"); + assert_eq!(config.change_id, Some(1), "setting top-level value"); assert_eq!( config.rust_lto, crate::config::RustcLto::Fat, @@ -156,10 +156,10 @@ fn override_toml_duplicate() { &[ "check".to_owned(), "--config=/does/not/exist".to_owned(), - "--set=changelog-seen=1".to_owned(), - "--set=changelog-seen=2".to_owned(), + "--set=change-id=1".to_owned(), + "--set=change-id=2".to_owned(), ], - |&_| toml::from_str("changelog-seen = 0").unwrap(), + |&_| toml::from_str("change-id = 0").unwrap(), ); } diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index b62aa9992469..885b3a782367 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -45,6 +45,23 @@ fn sanitize_sh(path: &Path) -> String { } } +fn is_dir_writable_for_user(dir: &PathBuf) -> bool { + let tmp = dir.join(".tmp"); + match fs::create_dir_all(&tmp) { + Ok(_) => { + fs::remove_dir_all(tmp).unwrap(); + true + } + Err(e) => { + if e.kind() == std::io::ErrorKind::PermissionDenied { + false + } else { + panic!("Failed the write access check for the current user. {}", e); + } + } + } +} + fn install_sh( builder: &Builder<'_>, package: &str, @@ -56,6 +73,17 @@ fn install_sh( let prefix = default_path(&builder.config.prefix, "/usr/local"); let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc")); + + // Sanity check for the user write access on prefix and sysconfdir + assert!( + is_dir_writable_for_user(&prefix), + "User doesn't have write access on `install.prefix` path in the `config.toml`.", + ); + assert!( + is_dir_writable_for_user(&sysconfdir), + "User doesn't have write access on `install.sysconfdir` path in `config.toml`." + ); + let datadir = prefix.join(default_path(&builder.config.datadir, "share")); let docdir = prefix.join(default_path(&builder.config.docdir, "share/doc/rust")); let mandir = prefix.join(default_path(&builder.config.mandir, "share/man")); @@ -92,6 +120,9 @@ fn prepare_dir(mut path: PathBuf) -> String { // More information on the environment variable is available here: // https://www.gnu.org/prep/standards/html_node/DESTDIR.html if let Some(destdir) = env::var_os("DESTDIR").map(PathBuf::from) { + // Sanity check for the user write access on DESTDIR + assert!(is_dir_writable_for_user(&destdir), "User doesn't have write access on DESTDIR."); + let without_destdir = path.clone(); path = destdir; // Custom .join() which ignores disk roots. diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 8a302b8b64d9..9e8dc2ec9088 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -113,7 +113,15 @@ const LLVM_TOOLS: &[&str] = &[ /// LLD file names for all flavors. const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"]; -pub const VERSION: usize = 2; +/// Keeps track of major changes made to the bootstrap configuration. +/// +/// These values also represent the IDs of the PRs that caused major changes. +/// You can visit `https://github.com/rust-lang/rust/pull/{any-id-from-the-list}` to +/// check for more details regarding each change. +/// +/// If you make any major changes (such as adding new values or changing default values), please +/// ensure that the associated PR ID is added to the end of this list. +pub const CONFIG_CHANGE_HISTORY: &[usize] = &[115898]; /// Extra --check-cfg to add when building /// (Mode restriction, config name, config values (if any)) @@ -1870,3 +1878,16 @@ fn envify(s: &str) -> String { .flat_map(|c| c.to_uppercase()) .collect() } + +pub fn find_recent_config_change_ids(current_id: usize) -> Vec { + let index = CONFIG_CHANGE_HISTORY + .iter() + .position(|&id| id == current_id) + .expect(&format!("Value `{}` was not found in `CONFIG_CHANGE_HISTORY`.", current_id)); + + CONFIG_CHANGE_HISTORY + .iter() + .skip(index + 1) // Skip the current_id and IDs before it + .cloned() + .collect() +} diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index a9865e262fec..0b67079917c7 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -6,6 +6,13 @@ Q := @ BOOTSTRAP_ARGS := endif +# Pass `-jN` to the bootstrap if it is specified. +ifdef MAKEFLAGS + ifneq (,$(findstring -j, $(MAKEFLAGS))) + BOOTSTRAP_ARGS += $(filter -j%, $(MAKEFLAGS)) + endif +endif + BOOTSTRAP := $(CFG_PYTHON) $(CFG_SRC_DIR)src/bootstrap/bootstrap.py all: diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index ef0234957b58..14ec33147fb9 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -1,6 +1,6 @@ use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::Config; -use crate::{t, VERSION}; +use crate::{t, CONFIG_CHANGE_HISTORY}; use sha2::Digest; use std::env::consts::EXE_SUFFIX; use std::fmt::Write as _; @@ -208,10 +208,11 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) { crate::exit!(1); } + let latest_change_id = CONFIG_CHANGE_HISTORY.last().unwrap(); let settings = format!( "# Includes one of the default files in src/bootstrap/defaults\n\ profile = \"{profile}\"\n\ - changelog-seen = {VERSION}\n" + change-id = {latest_change_id}\n" ); t!(fs::write(path, settings)); diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index b83b198780ba..2e6456837130 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -271,7 +271,7 @@ For targets: `loongarch64-unknown-linux-gnu` - Operating System > Linux kernel version = 5.19.16 - Binary utilities > Version of binutils = 2.40 - C-library > glibc version = 2.36 -- C compiler > gcc version = 13.1.0 +- C compiler > gcc version = 13.2.0 - C compiler > C++ = ENABLE -- to cross compile LLVM ### `mips-linux-gnu.defconfig` @@ -407,7 +407,7 @@ For targets: `riscv64-unknown-linux-gnu` - Target options > Bitness = 64-bit - Operating System > Target OS = linux - Operating System > Linux kernel version = 4.20.17 -- Binary utilities > Version of binutils = 2.32 +- Binary utilities > Version of binutils = 2.36.1 - C-library > glibc version = 2.29 - C compiler > gcc version = 8.5.0 - C compiler > C++ = ENABLE -- to cross compile LLVM diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile index 78689c429c2e..55c737bd0aa3 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile @@ -3,9 +3,8 @@ FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -# The latest released version does not support LoongArch. -COPY scripts/crosstool-ng-git.sh /scripts/ -RUN sh /scripts/crosstool-ng-git.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index 670e37b9d01a..01b46118b9c1 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -128,6 +128,8 @@ ENV TARGETS=$TARGETS,armv7-unknown-linux-gnueabi ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabi ENV TARGETS=$TARGETS,i686-unknown-freebsd ENV TARGETS=$TARGETS,x86_64-unknown-none +ENV TARGETS=$TARGETS,loongarch64-unknown-none +ENV TARGETS=$TARGETS,loongarch64-unknown-none-softfloat ENV TARGETS=$TARGETS,aarch64-unknown-uefi ENV TARGETS=$TARGETS,i686-unknown-uefi ENV TARGETS=$TARGETS,x86_64-unknown-uefi diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index 6f1b2a6a638b..c04121a8bee6 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -84,7 +84,8 @@ ENV RUST_CONFIGURE_ARGS \ --set llvm.ninja=false \ --set rust.jemalloc \ --set rust.use-lld=true \ - --set rust.lto=thin + --set rust.lto=thin \ + --set rust.codegen-units=1 ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \ ./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \ diff --git a/src/ci/docker/host-x86_64/wasm32/Dockerfile b/src/ci/docker/host-x86_64/wasm32/Dockerfile deleted file mode 100644 index 0d0f1edd003c..000000000000 --- a/src/ci/docker/host-x86_64/wasm32/Dockerfile +++ /dev/null @@ -1,63 +0,0 @@ -FROM ubuntu:22.04 - -ARG DEBIAN_FRONTEND=noninteractive -RUN apt-get update && apt-get install -y --no-install-recommends \ - g++ \ - make \ - ninja-build \ - file \ - curl \ - ca-certificates \ - python3 \ - git \ - cmake \ - sudo \ - gdb \ - xz-utils \ - libssl-dev \ - bzip2 \ - && rm -rf /var/lib/apt/lists/* - -COPY scripts/emscripten.sh /scripts/ -RUN bash /scripts/emscripten.sh - -COPY scripts/sccache.sh /scripts/ -RUN sh /scripts/sccache.sh - -# emcc seems to need python to specifically be "python" and not "python3" -RUN ln `which python3` /usr/bin/python - -ENV PATH=$PATH:/emsdk-portable -ENV PATH=$PATH:/emsdk-portable/upstream/emscripten/ - -# Rust's build system requires NodeJS to be in the path, but the directory in -# which emsdk stores it contains the version number. This caused breakages in -# the past when emsdk bumped the node version causing the path to point to a -# missing directory. -# -# To avoid the problem this symlinks the latest NodeJs version available to -# "latest", and adds that to the path. -RUN ln -s /emsdk-portable/node/$(ls /emsdk-portable/node | sort -V | tail -n 1) \ - /emsdk-portable/node/latest -ENV PATH=$PATH:/emsdk-portable/node/latest/bin/ - -ENV BINARYEN_ROOT=/emsdk-portable/upstream/ -ENV EMSDK=/emsdk-portable -ENV EM_CONFIG=/emsdk-portable/.emscripten -ENV EM_CACHE=/emsdk-portable/upstream/emscripten/cache - -ENV TARGETS=wasm32-unknown-emscripten - -# Use -O1 optimizations in the link step to reduce time spent optimizing. -ENV EMCC_CFLAGS=-O1 - -COPY static/gitconfig /etc/gitconfig - -# Emscripten installation is user-specific -ENV NO_CHANGE_USER=1 -RUN chown 10719 -R /emsdk-portable/ - -# Exclude library/alloc due to OOM in benches. -# FIXME: Fix std tests -ENV SCRIPT python3 ../x.py test --stage 2 --host='' --target $TARGETS \ - --skip library/alloc --skip library/std diff --git a/src/ci/docker/scripts/crosstool-ng-git.sh b/src/ci/docker/scripts/crosstool-ng-git.sh deleted file mode 100644 index b8d399153271..000000000000 --- a/src/ci/docker/scripts/crosstool-ng-git.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -set -ex - -URL=https://github.com/crosstool-ng/crosstool-ng -REV=227d99d7f3115f3a078595a580d2b307dcd23e93 - -mkdir crosstool-ng -cd crosstool-ng -git init -git fetch --depth=1 ${URL} ${REV} -git reset --hard FETCH_HEAD -./bootstrap -./configure --prefix=/usr/local -make -j$(nproc) -make install -cd .. -rm -rf crosstool-ng diff --git a/src/ci/docker/scripts/crosstool-ng.sh b/src/ci/docker/scripts/crosstool-ng.sh index a28d7bde2acc..c3ee19b8d2c1 100644 --- a/src/ci/docker/scripts/crosstool-ng.sh +++ b/src/ci/docker/scripts/crosstool-ng.sh @@ -1,7 +1,7 @@ #!/bin/sh set -ex -CT_NG=1.25.0 +CT_NG=1.26.0 url="https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-$CT_NG.tar.gz" curl -Lf $url | tar xzf - diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index cbf848cb4a3b..838c72612d6a 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -281,6 +281,8 @@ on: - auto - try - try-perf + - automation/bors/try + - automation/bors/try-merge - master pull_request: branches: @@ -427,9 +429,6 @@ jobs: - name: test-various <<: *job-linux-8c - - name: wasm32 - <<: *job-linux-8c - - name: x86_64-gnu <<: *job-linux-4c @@ -691,7 +690,7 @@ jobs: env: DIST_TRY_BUILD: 1 <<: [*shared-ci-variables, *prod-variables] - if: github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust' + if: github.event_name == 'push' && (((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust') || ((github.ref == 'refs/heads/automation/bors/try') && github.repository == 'rust-lang/rust')) strategy: matrix: include: diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index c4585bd150f6..a51ec467cb45 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -33,9 +33,9 @@ All tier 1 targets with host tools support the full standard library. target | notes -------|------- `aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+) [^missing-stack-probes] -`i686-pc-windows-gnu` | 32-bit MinGW (Windows 7+) [^windows-support] -`i686-pc-windows-msvc` | 32-bit MSVC (Windows 7+) [^windows-support] -`i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+) +`i686-pc-windows-gnu` | 32-bit MinGW (Windows 7+) [^windows-support] [^x86_32-floats-return-ABI] +`i686-pc-windows-msvc` | 32-bit MSVC (Windows 7+) [^windows-support] [^x86_32-floats-return-ABI] +`i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+) [^x86_32-floats-return-ABI] `x86_64-apple-darwin` | 64-bit macOS (10.12+, Sierra+) `x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 7+) [^windows-support] `x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 7+) [^windows-support] @@ -47,7 +47,10 @@ target | notes [^windows-support]: Only Windows 10 currently undergoes automated testing. Earlier versions of Windows rely on testing and support from the community. +[^x86_32-floats-return-ABI]: Due to limitations of the C ABI, floating-point support on `i686` targets is non-compliant: floating-point return values are passed via an x87 register, so NaN payload bits can be lost. See [issue #114479][x86-32-float-issue]. + [77071]: https://github.com/rust-lang/rust/issues/77071 +[x86-32-float-issue]: https://github.com/rust-lang/rust/issues/114479 ## Tier 1 @@ -150,13 +153,15 @@ target | std | notes `armv7r-none-eabi` | * | Bare ARMv7-R `armv7r-none-eabihf` | * | Bare ARMv7-R, hardfloat `asmjs-unknown-emscripten` | ✓ | asm.js via Emscripten -`i586-pc-windows-msvc` | * | 32-bit Windows w/o SSE -`i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 3.2, glibc 2.17) -`i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, MUSL -[`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android -`i686-unknown-freebsd` | ✓ | 32-bit FreeBSD -`i686-unknown-linux-musl` | ✓ | 32-bit Linux with MUSL +`i586-pc-windows-msvc` | * | 32-bit Windows w/o SSE [^x86_32-floats-x87] +`i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 3.2, glibc 2.17) [^x86_32-floats-x87] +`i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, MUSL [^x86_32-floats-x87] +[`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android [^x86_32-floats-return-ABI] +`i686-unknown-freebsd` | ✓ | 32-bit FreeBSD [^x86_32-floats-return-ABI] +`i686-unknown-linux-musl` | ✓ | 32-bit Linux with MUSL [^x86_32-floats-return-ABI] [`i686-unknown-uefi`](platform-support/unknown-uefi.md) | * | 32-bit UEFI +[`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64D ABI) +[`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64S ABI) `mips-unknown-linux-musl` | ✓ | MIPS Linux with MUSL `mips64-unknown-linux-muslabi64` | ✓ | MIPS64 Linux, n64 ABI, MUSL `mips64el-unknown-linux-muslabi64` | ✓ | MIPS64 (LE) Linux, n64 ABI, MUSL @@ -193,6 +198,8 @@ target | std | notes `x86_64-unknown-redox` | ✓ | Redox OS [`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | * | 64-bit UEFI +[^x86_32-floats-x87]: Floating-point support on `i586` targets is non-compliant: the `x87` registers and instructions used for these targets do not provide IEEE-754-compliant behavior, in particular when it comes to rounding and NaN payload bits. See [issue #114479][x86-32-float-issue]. + [Fortanix ABI]: https://edp.fortanix.com/ ## Tier 3 @@ -262,19 +269,19 @@ target | std | host | notes `bpfel-unknown-none` | * | | BPF (little endian) `csky-unknown-linux-gnuabiv2` | ✓ | | C-SKY abiv2 Linux(little endian) `hexagon-unknown-linux-musl` | ? | | -`i386-apple-ios` | ✓ | | 32-bit x86 iOS +`i386-apple-ios` | ✓ | | 32-bit x86 iOS [^x86_32-floats-return-ABI] [`i386-lynx-lynxos178`](platform-support/i386-lynx-lynxos178.md) | * | | 32-bit LynxOS-178 (2022.07) -[`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS | -`i686-apple-darwin` | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+) -`i686-pc-windows-msvc` | * | | 32-bit Windows XP support -[`i686-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | -`i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku -[`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd -[`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 with SSE2 -[`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD -`i686-uwp-windows-gnu` | ? | | -`i686-uwp-windows-msvc` | ? | | -`i686-wrs-vxworks` | ? | | +[`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS [^x86_32-floats-return-ABI] +`i686-apple-darwin` | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+) [^x86_32-floats-return-ABI] +`i686-pc-windows-msvc` | * | | 32-bit Windows XP support [^x86_32-floats-return-ABI] +[`i686-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | [^x86_32-floats-return-ABI] +`i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku [^x86_32-floats-return-ABI] +[`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd [^x86_32-floats-return-ABI] +[`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 with SSE2 [^x86_32-floats-return-ABI] +[`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD [^x86_32-floats-return-ABI] +`i686-uwp-windows-gnu` | ? | | [^x86_32-floats-return-ABI] +`i686-uwp-windows-msvc` | ? | | [^x86_32-floats-return-ABI] +`i686-wrs-vxworks` | ? | | [^x86_32-floats-return-ABI] [`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64D ABI) [`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64S ABI) [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux diff --git a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md index f8cd92f9257e..9233a36db3d7 100644 --- a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md +++ b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md @@ -58,7 +58,7 @@ To build a rust toolchain, create a `config.toml` with the following contents: ```toml profile = "compiler" -changelog-seen = 2 +change-id = 115898 [build] sanitizers = true diff --git a/src/doc/rustc/src/platform-support/loongarch-none.md b/src/doc/rustc/src/platform-support/loongarch-none.md index d0ae3425fa8e..68d7c9d85e44 100644 --- a/src/doc/rustc/src/platform-support/loongarch-none.md +++ b/src/doc/rustc/src/platform-support/loongarch-none.md @@ -1,6 +1,6 @@ # `loongarch*-unknown-none*` -**Tier: 3** +**Tier: 2** Freestanding/bare-metal LoongArch64 binaries in ELF format: firmware, kernels, etc. diff --git a/src/doc/rustc/src/platform-support/mips-release-6.md b/src/doc/rustc/src/platform-support/mips-release-6.md index 3f1912fc6f95..9203a31e9f4e 100644 --- a/src/doc/rustc/src/platform-support/mips-release-6.md +++ b/src/doc/rustc/src/platform-support/mips-release-6.md @@ -67,7 +67,7 @@ The following procedure outlines the build process for the MIPS64 R6 target with ### Prerequisite: Disable debuginfo -A LLVM bug makes rustc crash if debug or debug info generation is enabled. You need to edit `config.toml` to disable this: +An LLVM bug makes rustc crash if debug or debug info generation is enabled. You need to edit `config.toml` to disable this: ```toml [rust] diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index b376c4a84ac9..9f0662783a4e 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -98,7 +98,7 @@ Example content: ```toml profile = "compiler" -changelog-seen = 2 +change-id = 115898 ``` 2. Compile the Rust toolchain for an `x86_64-unknown-linux-gnu` host (for both `aarch64` and `x86_64` targets) diff --git a/src/doc/rustc/src/platform-support/openharmony.md b/src/doc/rustc/src/platform-support/openharmony.md index 89539f3888c8..05fd407ed71e 100644 --- a/src/doc/rustc/src/platform-support/openharmony.md +++ b/src/doc/rustc/src/platform-support/openharmony.md @@ -101,7 +101,7 @@ To build a rust toolchain, create a `config.toml` with the following contents: ```toml profile = "compiler" -changelog-seen = 2 +change-id = 115898 [build] sanitizers = true diff --git a/src/doc/rustc/src/platform-support/unknown-uefi.md b/src/doc/rustc/src/platform-support/unknown-uefi.md index 68cd7fae3197..370939520dc0 100644 --- a/src/doc/rustc/src/platform-support/unknown-uefi.md +++ b/src/doc/rustc/src/platform-support/unknown-uefi.md @@ -265,9 +265,12 @@ cargo build --target x86_64-unknown-uefi -Zbuild-std=std,panic_abort #### os_str - While the strings in UEFI should be valid UCS-2, in practice, many implementations just do not care and use UTF-16 strings. - Thus, the current implementation supports full UTF-16 strings. +#### stdio +- Uses `Simple Text Input Protocol` and `Simple Text Output Protocol`. +- Note: UEFI uses CRLF for new line. This means Enter key is registered as CR instead of LF. ## Example: Hello World With std -The following code features a valid UEFI application, including stdio and `alloc` (`OsString` and `Vec`): +The following code features a valid UEFI application, including `stdio` and `alloc` (`OsString` and `Vec`): This example can be compiled as binary crate via `cargo` using the toolchain compiled from the above source (named custom): @@ -286,6 +289,9 @@ use std::{ }; pub fn main() { + println!("Starting Rust Application..."); + + // Use System Table Directly let st = env::system_table().as_ptr() as *mut efi::SystemTable; let mut s: Vec = OsString::from("Hello World!\n").encode_wide().collect(); s.push(0); diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index 49389b28c8fc..502853f39ae4 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -197,22 +197,26 @@ Shadow byte legend (one shadow byte represents 8 application bytes): # ControlFlowIntegrity -The LLVM Control Flow Integrity (CFI) support in the Rust compiler provides -forward-edge control flow protection for both Rust-compiled code only and for C -or C++ and Rust -compiled code mixed-language binaries, also known as “mixed -binaries” (i.e., for when C or C++ and Rust -compiled code share the same -virtual address space), by aggregating function pointers in groups identified by -their return and parameter types. - -LLVM CFI can be enabled with `-Zsanitizer=cfi` and requires LTO (i.e., `-Clto`). -Cross-language LLVM CFI can be enabled with `-Zsanitizer=cfi`, and requires the -`-Zsanitizer-cfi-normalize-integers` option to be used with Clang -`-fsanitize-cfi-icall-normalize-integers` for normalizing integer types, and -proper (i.e., non-rustc) LTO (i.e., `-Clinker-plugin-lto`). +The LLVM CFI support in the Rust compiler provides forward-edge control flow +protection for both Rust-compiled code only and for C or C++ and Rust -compiled +code mixed-language binaries, also known as “mixed binaries” (i.e., for when C +or C++ and Rust -compiled code share the same virtual address space), by +aggregating function pointers in groups identified by their return and parameter +types. + +LLVM CFI can be enabled with `-Zsanitizer=cfi` and requires LTO (i.e., +`-Clinker-plugin-lto` or `-Clto`). Cross-language LLVM CFI can be enabled with +`-Zsanitizer=cfi`, and requires the `-Zsanitizer-cfi-normalize-integers` option +to be used with Clang `-fsanitize-cfi-icall-experimental-normalize-integers` +option for cross-language LLVM CFI support, and proper (i.e., non-rustc) LTO +(i.e., `-Clinker-plugin-lto`). + +It is recommended to rebuild the standard library with CFI enabled by using the +Cargo build-std feature (i.e., `-Zbuild-std`) when enabling CFI. See the [Clang ControlFlowIntegrity documentation][clang-cfi] for more details. -## Example +## Example 1: Redirecting control flow using an indirect branch/call to an invalid destination ```rust,ignore (making doc tests pass cross-platform is hard) #![feature(naked_functions)] @@ -239,7 +243,7 @@ pub extern "C" fn add_two(x: i32) { nop nop nop - lea eax, [edi+2] + lea eax, [rdi+2] ret ", options(noreturn) @@ -258,8 +262,9 @@ fn main() { println!("With CFI enabled, you should not see the next answer"); let f: fn(i32) -> i32 = unsafe { - // Offsets 0-8 make it land in the landing pad/nop block, and offsets 1-8 are - // invalid branch/call destinations (i.e., within the body of the function). + // Offset 0 is a valid branch/call destination (i.e., the function entry + // point), but offsets 1-8 within the landing pad/nop block are invalid + // branch/call destinations (i.e., within the body of the function). mem::transmute::<*const u8, fn(i32) -> i32>((add_two as *const u8).offset(5)) }; let next_answer = do_twice(f, 5); @@ -267,38 +272,40 @@ fn main() { println!("The next answer is: {}", next_answer); } ``` -Fig. 1. Modified example from the [Advanced Functions and -Closures][rust-book-ch19-05] chapter of the [The Rust Programming -Language][rust-book] book. +Fig. 1. Redirecting control flow using an indirect branch/call to an invalid +destination (i.e., within the body of the function). ```shell $ cargo run --release Compiling rust-cfi-1 v0.1.0 (/home/rcvalle/rust-cfi-1) - Finished release [optimized] target(s) in 0.76s + Finished release [optimized] target(s) in 0.42s Running `target/release/rust-cfi-1` The answer is: 12 With CFI enabled, you should not see the next answer The next answer is: 14 $ ``` -Fig. 2. Build and execution of the modified example with LLVM CFI disabled. +Fig. 2. Build and execution of Fig. 1 with LLVM CFI disabled. ```shell -$ RUSTFLAGS="-Zsanitizer=cfi -Cembed-bitcode=yes -Clto" cargo run --release +$ RUSTFLAGS="-Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld -Zsanitizer=cfi" cargo run -Zbuild-std -Zbuild-std-features --release --target x86_64-unknown-linux-gnu + ... Compiling rust-cfi-1 v0.1.0 (/home/rcvalle/rust-cfi-1) - Finished release [optimized] target(s) in 3.39s - Running `target/release/rust-cfi-1` + Finished release [optimized] target(s) in 1m 08s + Running `target/x86_64-unknown-linux-gnu/release/rust-cfi-1` The answer is: 12 With CFI enabled, you should not see the next answer Illegal instruction $ ``` -Fig. 3. Build and execution of the modified example with LLVM CFI enabled. +Fig. 3. Build and execution of Fig. 1 with LLVM CFI enabled. When LLVM CFI is enabled, if there are any attempts to change/hijack control flow using an indirect branch/call to an invalid destination, the execution is terminated (see Fig. 3). +## Example 2: Redirecting control flow using an indirect branch/call to a function with a different number of parameters + ```rust use std::mem; @@ -327,39 +334,42 @@ fn main() { println!("The next answer is: {}", next_answer); } ``` -Fig. 4. Another modified example from the [Advanced Functions and -Closures][rust-book-ch19-05] chapter of the [The Rust Programming -Language][rust-book] book. +Fig. 4. Redirecting control flow using an indirect branch/call to a function +with a different number of parameters than arguments intended/passed in the +call/branch site. ```shell $ cargo run --release Compiling rust-cfi-2 v0.1.0 (/home/rcvalle/rust-cfi-2) - Finished release [optimized] target(s) in 0.76s + Finished release [optimized] target(s) in 0.43s Running `target/release/rust-cfi-2` The answer is: 12 With CFI enabled, you should not see the next answer The next answer is: 14 $ ``` -Fig. 5. Build and execution of the modified example with LLVM CFI disabled. +Fig. 5. Build and execution of Fig. 4 with LLVM CFI disabled. ```shell -$ RUSTFLAGS="-Cembed-bitcode=yes -Clto -Zsanitizer=cfi" cargo run --release +$ RUSTFLAGS="-Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld -Zsanitizer=cfi" cargo run -Zbuild-std -Zbuild-std-features --release --target x86_64-unknown-linux-gnu + ... Compiling rust-cfi-2 v0.1.0 (/home/rcvalle/rust-cfi-2) - Finished release [optimized] target(s) in 3.38s - Running `target/release/rust-cfi-2` + Finished release [optimized] target(s) in 1m 08s + Running `target/x86_64-unknown-linux-gnu/release/rust-cfi-2` The answer is: 12 With CFI enabled, you should not see the next answer Illegal instruction $ ``` -Fig. 6. Build and execution of the modified example with LLVM CFI enabled. +Fig. 6. Build and execution of Fig. 4 with LLVM CFI enabled. When LLVM CFI is enabled, if there are any attempts to change/hijack control flow using an indirect branch/call to a function with different number of parameters than arguments intended/passed in the call/branch site, the execution is also terminated (see Fig. 6). +## Example 3: Redirecting control flow using an indirect branch/call to a function with different return and parameter types + ```rust use std::mem; @@ -388,42 +398,46 @@ fn main() { println!("The next answer is: {}", next_answer); } ``` -Fig. 7. Another modified example from the [Advanced Functions and -Closures][rust-book-ch19-05] chapter of the [The Rust Programming -Language][rust-book] book. +Fig. 7. Redirecting control flow using an indirect branch/call to a function +with different return and parameter types than the return type expected and +arguments intended/passed at the call/branch site. ```shell $ cargo run --release Compiling rust-cfi-3 v0.1.0 (/home/rcvalle/rust-cfi-3) - Finished release [optimized] target(s) in 0.74s + Finished release [optimized] target(s) in 0.44s Running `target/release/rust-cfi-3` The answer is: 12 With CFI enabled, you should not see the next answer The next answer is: 14 $ ``` -Fig. 8. Build and execution of the modified example with LLVM CFI disabled. +Fig. 8. Build and execution of Fig. 7 with LLVM CFI disabled. ```shell -$ RUSTFLAGS="-Cembed-bitcode=yes -Clto -Zsanitizer=cfi" cargo run --release +$ RUSTFLAGS="-Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld -Zsanitizer=cfi" cargo run -Zbuild-std -Zbuild-std-features --release --target x86_64-unknown-linux-gnu + ... Compiling rust-cfi-3 v0.1.0 (/home/rcvalle/rust-cfi-3) - Finished release [optimized] target(s) in 3.40s - Running `target/release/rust-cfi-3` + Finished release [optimized] target(s) in 1m 07s + Running `target/x86_64-unknown-linux-gnu/release/rust-cfi-3` The answer is: 12 With CFI enabled, you should not see the next answer Illegal instruction $ ``` -Fig. 9. Build and execution of the modified example with LLVM CFI enabled. +Fig. 9. Build and execution of Fig. 7 with LLVM CFI enabled. When LLVM CFI is enabled, if there are any attempts to change/hijack control flow using an indirect branch/call to a function with different return and parameter types than the return type expected and arguments intended/passed in the call/branch site, the execution is also terminated (see Fig. 9). +## Example 4: Redirecting control flow using an indirect branch/call to a function with different return and parameter types across the FFI boundary + ```ignore (cannot-test-this-because-uses-custom-build) int -do_twice(int (*fn)(int), int arg) { +do_twice(int (*fn)(int), int arg) +{ return fn(arg) + fn(arg); } ``` @@ -459,54 +473,49 @@ fn main() { println!("The next answer is: {}", next_answer); } ``` -Fig. 11. Another modified example from the [Advanced Functions and -Closures][rust-book-ch19-05] chapter of the [The Rust Programming -Language][rust-book] book. +Fig. 11. Redirecting control flow using an indirect branch/call to a function +with different return and parameter types than the return type expected and +arguments intended/passed in the call/branch site, across the FFI boundary. ```shell $ make -mkdir -p target/debug -clang -I. -Isrc -Wall -flto -fvisibility=hidden -c -emit-llvm src/foo.c -o target/debug/libfoo.bc -llvm-ar rcs target/debug/libfoo.a target/debug/libfoo.bc -RUSTFLAGS="-L./target/debug -Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld" cargo build - Compiling main v0.1.0 (/home/rcvalle/rust-cross-cfi-1) - Finished dev [unoptimized + debuginfo] target(s) in 0.45s -$ ./target/debug/main +mkdir -p target/release +clang -I. -Isrc -Wall -c src/foo.c -o target/release/libfoo.o +llvm-ar rcs target/release/libfoo.a target/release/libfoo.o +RUSTFLAGS="-L./target/release -Clinker=clang -Clink-arg=-fuse-ld=lld" cargo build --release + Compiling rust-cfi-4 v0.1.0 (/home/rcvalle/rust-cfi-4) + Finished release [optimized] target(s) in 0.49s +$ ./target/release/rust-cfi-4 The answer is: 12 With CFI enabled, you should not see the next answer The next answer is: 14 $ ``` -Fig. 12. Build and execution of the modified example with LLVM CFI disabled. +Fig. 12. Build and execution of Figs. 10–11 with LLVM CFI disabled. ```shell $ make -mkdir -p target/debug -clang -I. -Isrc -Wall -flto -fvisibility=hidden -fsanitize=cfi -fsanitize-cfi-icall-normalize-integers -c -emit-llvm src/foo.c -o target/debug/libfoo.bc -llvm-ar rcs target/debug/libfoo.a target/debug/libfoo.bc -RUSTFLAGS="-L./target/debug -Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers" cargo build - Compiling main v0.1.0 (/home/rcvalle/rust-cross-cfi-1) - Finished dev [unoptimized + debuginfo] target(s) in 0.45s -$ ./target/debug/main +mkdir -p target/release +clang -I. -Isrc -Wall -flto -fsanitize=cfi -fsanitize-cfi-icall-experimental-normalize-integers -fvisibility=hidden -c -emit-llvm src/foo.c -o target/release/libfoo.bc +llvm-ar rcs target/release/libfoo.a target/release/libfoo.bc +RUSTFLAGS="-L./target/release -Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers" cargo build -Zbuild-std -Zbuild-std-features --release --target x86_64-unknown-linux-gnu + ... + Compiling rust-cfi-4 v0.1.0 (/home/rcvalle/rust-cfi-4) + Finished release [optimized] target(s) in 1m 06s +$ ./target/x86_64-unknown-linux-gnu/release/rust-cfi-4 The answer is: 12 With CFI enabled, you should not see the next answer Illegal instruction $ ``` -Fig. 13. Build and execution of the modified example with LLVM CFI enabled. - -When LLVM CFI is enabled, if there are any attempts to change/hijack control -flow using an indirect branch/call to a function with different return and -parameter types than the return type expected and arguments intended/passed in -the call/branch site, even across the FFI boundary and for extern "C" function -types indirectly called (i.e., callbacks/function pointers) across the FFI -boundary, in C or C++ and Rust -compiled code mixed-language binaries, also -known as “mixed binaries” (i.e., for when C or C++ and Rust -compiled code share -the same virtual address space), the execution is also terminated (see Fig. 13). - - -[rust-book-ch19-05]: https://doc.rust-lang.org/book/ch19-05-advanced-functions-and-closures.html -[rust-book]: https://doc.rust-lang.org/book/title-page.html +Fig. 13. Build and execution of FIgs. 10–11 with LLVM CFI enabled. + +When LLVM CFI is enabled, if there are any attempts to redirect control flow +using an indirect branch/call to a function with different return and parameter +types than the return type expected and arguments intended/passed in the +call/branch site, even across the FFI boundary and for extern "C" function types +indirectly called (i.e., callbacks/function pointers) across the FFI boundary, +the execution is also terminated (see Fig. 13). # HWAddressSanitizer diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index 1fade6ce95b8..d9421a428f1e 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -33,7 +33,7 @@ of a library. Plugins can extend [Rust's lint infrastructure](../../reference/attributes/diagnostics.md#lint-check-attributes) with additional checks for code style, safety, etc. Now let's write a plugin -[`lint-plugin-test.rs`](https://github.com/rust-lang/rust/blob/master/tests/ui-fulldeps/auxiliary/lint-plugin-test.rs) +[`lint-plugin-test.rs`](https://github.com/rust-lang/rust/blob/master/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs) that warns about any item named `lintme`. ```rust,ignore (requires-stage-2) @@ -43,14 +43,14 @@ extern crate rustc_ast; // Load rustc as a plugin to get macros extern crate rustc_driver; -#[macro_use] extern crate rustc_lint; #[macro_use] extern crate rustc_session; -use rustc_driver::plugin::Registry; -use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; use rustc_ast::ast; +use rustc_driver::plugin::Registry; +use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; + declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); declare_lint_pass!(Pass => [TEST_LINT]); @@ -58,9 +58,7 @@ declare_lint_pass!(Pass => [TEST_LINT]); impl EarlyLintPass for Pass { fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) { if it.ident.name.as_str() == "lintme" { - cx.lint(TEST_LINT, |lint| { - lint.build("item is named 'lintme'").set_span(it.span).emit() - }); + cx.lint(TEST_LINT, "item is named 'lintme'", |lint| lint.set_span(it.span)); } } } diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index a06f31a93291..bdf6a0f6b239 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -551,8 +551,8 @@ where WherePredicate::RegionPredicate { lifetime, bounds } => { lifetime_to_bounds.entry(lifetime).or_default().extend(bounds); } - WherePredicate::EqPredicate { lhs, rhs, bound_params } => { - match *lhs { + WherePredicate::EqPredicate { lhs, rhs } => { + match lhs { Type::QPath(box QPathData { ref assoc, ref self_type, @@ -590,14 +590,13 @@ where GenericArgs::AngleBracketed { ref mut bindings, .. } => { bindings.push(TypeBinding { assoc: assoc.clone(), - kind: TypeBindingKind::Equality { term: *rhs }, + kind: TypeBindingKind::Equality { term: rhs }, }); } GenericArgs::Parenthesized { .. } => { existing_predicates.push(WherePredicate::EqPredicate { lhs: lhs.clone(), rhs, - bound_params, }); continue; // If something other than a Fn ends up // with parentheses, leave it alone diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index fcbcfbf5c67c..eb18ecf662c1 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -18,9 +18,9 @@ use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; use crate::clean::{ - self, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item, clean_middle_assoc_item, - clean_middle_field, clean_middle_ty, clean_trait_ref_with_bindings, clean_ty, - clean_ty_alias_inner_type, clean_ty_generics, clean_variant_def, utils, Attributes, + self, clean_bound_vars, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item, + clean_middle_assoc_item, clean_middle_field, clean_middle_ty, clean_trait_ref_with_bindings, + clean_ty, clean_ty_alias_inner_type, clean_ty_generics, clean_variant_def, utils, Attributes, AttributesExt, ImplKind, ItemId, Type, }; use crate::core::DocContext; @@ -239,20 +239,13 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> Box { let sig = cx.tcx.fn_sig(did).instantiate_identity(); - - let late_bound_regions = sig.bound_vars().into_iter().filter_map(|var| match var { - ty::BoundVariableKind::Region(ty::BrNamed(_, name)) if name != kw::UnderscoreLifetime => { - Some(clean::GenericParamDef::lifetime(name)) - } - _ => None, - }); - let predicates = cx.tcx.explicit_predicates_of(did); + let (generics, decl) = clean::enter_impl_trait(cx, |cx| { // NOTE: generics need to be cleaned before the decl! let mut generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); // FIXME: This does not place parameters in source order (late-bound ones come last) - generics.params.extend(late_bound_regions); + generics.params.extend(clean_bound_vars(sig.bound_vars())); let decl = clean_fn_decl_from_did_and_sig(cx, Some(did), sig); (generics, decl) }); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 34d81f51f76e..b9d7acee63c2 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -232,20 +232,11 @@ fn clean_poly_trait_ref_with_bindings<'tcx>( poly_trait_ref: ty::PolyTraitRef<'tcx>, bindings: ThinVec, ) -> GenericBound { - // collect any late bound regions - let late_bound_regions: Vec<_> = cx - .tcx - .collect_referenced_late_bound_regions(&poly_trait_ref) - .into_iter() - .filter_map(|br| match br { - ty::BrNamed(_, name) if br.is_named() => Some(GenericParamDef::lifetime(name)), - _ => None, - }) - .collect(); - - let trait_ = clean_trait_ref_with_bindings(cx, poly_trait_ref, bindings); GenericBound::TraitBound( - PolyTrait { trait_, generic_params: late_bound_regions }, + PolyTrait { + trait_: clean_trait_ref_with_bindings(cx, poly_trait_ref, bindings), + generic_params: clean_bound_vars(poly_trait_ref.bound_vars()), + }, hir::TraitBoundModifier::None, ) } @@ -338,9 +329,8 @@ fn clean_where_predicate<'tcx>( }, hir::WherePredicate::EqPredicate(ref wrp) => WherePredicate::EqPredicate { - lhs: Box::new(clean_ty(wrp.lhs_ty, cx)), - rhs: Box::new(clean_ty(wrp.rhs_ty, cx).into()), - bound_params: Vec::new(), + lhs: clean_ty(wrp.lhs_ty, cx), + rhs: clean_ty(wrp.rhs_ty, cx).into(), }, }) } @@ -436,20 +426,9 @@ fn clean_projection_predicate<'tcx>( pred: ty::Binder<'tcx, ty::ProjectionPredicate<'tcx>>, cx: &mut DocContext<'tcx>, ) -> WherePredicate { - let late_bound_regions = cx - .tcx - .collect_referenced_late_bound_regions(&pred) - .into_iter() - .filter_map(|br| match br { - ty::BrNamed(_, name) if br.is_named() => Some(GenericParamDef::lifetime(name)), - _ => None, - }) - .collect(); - WherePredicate::EqPredicate { - lhs: Box::new(clean_projection(pred.map_bound(|p| p.projection_ty), cx, None)), - rhs: Box::new(clean_middle_term(pred.map_bound(|p| p.term), cx)), - bound_params: late_bound_regions, + lhs: clean_projection(pred.map_bound(|p| p.projection_ty), cx, None), + rhs: clean_middle_term(pred.map_bound(|p| p.term), cx), } } @@ -703,8 +682,8 @@ pub(crate) fn clean_generics<'tcx>( } } } - WherePredicate::EqPredicate { lhs, rhs, bound_params } => { - eq_predicates.push(WherePredicate::EqPredicate { lhs, rhs, bound_params }); + WherePredicate::EqPredicate { lhs, rhs } => { + eq_predicates.push(WherePredicate::EqPredicate { lhs, rhs }); } } } @@ -798,11 +777,9 @@ fn clean_ty_generics<'tcx>( }) .collect::>(); - // param index -> [(trait DefId, associated type name & generics, term, higher-ranked params)] - let mut impl_trait_proj = FxHashMap::< - u32, - Vec<(DefId, PathSegment, ty::Binder<'_, ty::Term<'_>>, Vec)>, - >::default(); + // param index -> [(trait DefId, associated type name & generics, term)] + let mut impl_trait_proj = + FxHashMap::>)>>::default(); let where_predicates = preds .predicates @@ -854,11 +831,6 @@ fn clean_ty_generics<'tcx>( trait_did, name, proj.map_bound(|p| p.term), - pred.get_bound_params() - .into_iter() - .flatten() - .cloned() - .collect(), )); } @@ -894,9 +866,9 @@ fn clean_ty_generics<'tcx>( let crate::core::ImplTraitParam::ParamIndex(idx) = param else { unreachable!() }; if let Some(proj) = impl_trait_proj.remove(&idx) { - for (trait_did, name, rhs, bound_params) in proj { + for (trait_did, name, rhs) in proj { let rhs = clean_middle_term(rhs, cx); - simplify::merge_bounds(cx, &mut bounds, bound_params, trait_did, name, &rhs); + simplify::merge_bounds(cx, &mut bounds, trait_did, name, &rhs); } } @@ -1183,7 +1155,13 @@ fn clean_fn_decl_from_did_and_sig<'tcx>( // but shouldn't change any code meaning. let mut output = clean_middle_ty(sig.output(), cx, None, None); - if let Some(did) = did && cx.tcx.asyncness(did).is_async() { + // If the return type isn't an `impl Trait`, we can safely assume that this + // function isn't async without needing to execute the query `asyncness` at + // all which gives us a noticeable performance boost. + if let Some(did) = did + && let Type::ImplTrait(_) = output + && cx.tcx.asyncness(did).is_async() + { output = output.sugared_async_return_type(); } @@ -1357,23 +1335,13 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( } ty::AssocKind::Fn => { let sig = tcx.fn_sig(assoc_item.def_id).instantiate_identity(); - - let late_bound_regions = sig.bound_vars().into_iter().filter_map(|var| match var { - ty::BoundVariableKind::Region(ty::BrNamed(_, name)) - if name != kw::UnderscoreLifetime => - { - Some(GenericParamDef::lifetime(name)) - } - _ => None, - }); - let mut generics = clean_ty_generics( cx, tcx.generics_of(assoc_item.def_id), tcx.explicit_predicates_of(assoc_item.def_id), ); // FIXME: This does not place parameters in source order (late-bound ones come last) - generics.params.extend(late_bound_regions); + generics.params.extend(clean_bound_vars(sig.bound_vars())); let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(assoc_item.def_id), sig); @@ -2109,9 +2077,11 @@ pub(crate) fn clean_middle_ty<'tcx>( // FIXME: should we merge the outer and inner binders somehow? let sig = bound_ty.skip_binder().fn_sig(cx.tcx); let decl = clean_fn_decl_from_did_and_sig(cx, None, sig); + let generic_params = clean_bound_vars(sig.bound_vars()); + BareFunction(Box::new(BareFunctionDecl { unsafety: sig.unsafety(), - generic_params: Vec::new(), + generic_params, decl, abi: sig.abi(), })) @@ -2187,8 +2157,8 @@ pub(crate) fn clean_middle_ty<'tcx>( let late_bound_regions: FxIndexSet<_> = obj .iter() - .flat_map(|pb| pb.bound_vars()) - .filter_map(|br| match br { + .flat_map(|pred| pred.bound_vars()) + .filter_map(|var| match var { ty::BoundVariableKind::Region(ty::BrNamed(_, name)) if name != kw::UnderscoreLifetime => { @@ -2262,6 +2232,11 @@ pub(crate) fn clean_middle_ty<'tcx>( } } + ty::Bound(_, ref ty) => match ty.kind { + ty::BoundTyKind::Param(_, name) => Generic(name), + ty::BoundTyKind::Anon => panic!("unexpected anonymous bound type variable"), + }, + ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => { // If it's already in the same alias, don't get an infinite loop. if cx.current_type_aliases.contains_key(&def_id) { @@ -2290,7 +2265,6 @@ pub(crate) fn clean_middle_ty<'tcx>( ty::Closure(..) => panic!("Closure"), ty::Generator(..) => panic!("Generator"), - ty::Bound(..) => panic!("Bound"), ty::Placeholder(..) => panic!("Placeholder"), ty::GeneratorWitness(..) => panic!("GeneratorWitness"), ty::Infer(..) => panic!("Infer"), @@ -3121,3 +3095,30 @@ fn clean_type_binding<'tcx>( }, } } + +fn clean_bound_vars<'tcx>( + bound_vars: &'tcx ty::List, +) -> Vec { + bound_vars + .into_iter() + .filter_map(|var| match var { + ty::BoundVariableKind::Region(ty::BrNamed(_, name)) + if name != kw::UnderscoreLifetime => + { + Some(GenericParamDef::lifetime(name)) + } + ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(did, name)) => Some(GenericParamDef { + name, + kind: GenericParamDefKind::Type { + did, + bounds: Vec::new(), + default: None, + synthetic: false, + }, + }), + // FIXME(non_lifetime_binders): Support higher-ranked const parameters. + ty::BoundVariableKind::Const => None, + _ => None, + }) + .collect() +} diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 7b8f20326ed4..eea8c1906c5b 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -40,18 +40,18 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec) -> ThinVec { lifetimes.push((lifetime, bounds)); } - WP::EqPredicate { lhs, rhs, bound_params } => equalities.push((lhs, rhs, bound_params)), + WP::EqPredicate { lhs, rhs } => equalities.push((lhs, rhs)), } } // Look for equality predicates on associated types that can be merged into // general bound predicates. - equalities.retain(|(lhs, rhs, bound_params)| { + equalities.retain(|(lhs, rhs)| { let Some((ty, trait_did, name)) = lhs.projection() else { return true; }; let Some((bounds, _)) = tybounds.get_mut(ty) else { return true }; - merge_bounds(cx, bounds, bound_params.clone(), trait_did, name, rhs) + merge_bounds(cx, bounds, trait_did, name, rhs) }); // And finally, let's reassemble everything @@ -64,18 +64,13 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec) -> ThinVec, bounds: &mut Vec, - mut bound_params: Vec, trait_did: DefId, assoc: clean::PathSegment, rhs: &clean::Term, @@ -93,12 +88,6 @@ pub(crate) fn merge_bounds( } let last = trait_ref.trait_.segments.last_mut().expect("segments were empty"); - trait_ref.generic_params.append(&mut bound_params); - // Sort parameters (likely) originating from a hashset alphabetically to - // produce predictable output (and to allow for full deduplication). - trait_ref.generic_params.sort_unstable_by(|p, q| p.name.as_str().cmp(q.name.as_str())); - trait_ref.generic_params.dedup_by_key(|p| p.name); - match last.args { PP::AngleBracketed { ref mut bindings, .. } => { bindings.push(clean::TypeBinding { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index f5251f50b7a7..b891dc59cb1d 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1289,7 +1289,7 @@ impl Lifetime { pub(crate) enum WherePredicate { BoundPredicate { ty: Type, bounds: Vec, bound_params: Vec }, RegionPredicate { lifetime: Lifetime, bounds: Vec }, - EqPredicate { lhs: Box, rhs: Box, bound_params: Vec }, + EqPredicate { lhs: Type, rhs: Term }, } impl WherePredicate { @@ -1300,15 +1300,6 @@ impl WherePredicate { _ => None, } } - - pub(crate) fn get_bound_params(&self) -> Option<&[GenericParamDef]> { - match self { - Self::BoundPredicate { bound_params, .. } | Self::EqPredicate { bound_params, .. } => { - Some(bound_params) - } - _ => None, - } - } } #[derive(Clone, PartialEq, Eq, Debug, Hash)] @@ -1604,14 +1595,16 @@ impl Type { /// /// This function will panic if the return type does not match the expected sugaring for async /// functions. - pub(crate) fn sugared_async_return_type(&self) -> Type { - if let Type::ImplTrait(v) = self && - let [GenericBound::TraitBound(PolyTrait { trait_, .. }, _ )] = &v[..] + pub(crate) fn sugared_async_return_type(self) -> Type { + if let Type::ImplTrait(mut v) = self + && let Some(GenericBound::TraitBound(PolyTrait { mut trait_, .. }, _ )) = v.pop() + && let Some(segment) = trait_.segments.pop() + && let GenericArgs::AngleBracketed { mut bindings, .. } = segment.args + && let Some(binding) = bindings.pop() + && let TypeBindingKind::Equality { term } = binding.kind + && let Term::Type(ty) = term { - let bindings = trait_.bindings().unwrap(); - let ret_ty = bindings[0].term(); - let ty = ret_ty.ty().expect("unexpected constant in async fn return term"); - ty.clone() + ty } else { panic!("unexpected async fn return type") } @@ -2189,16 +2182,6 @@ impl Path { } }) } - - pub(crate) fn bindings(&self) -> Option<&[TypeBinding]> { - self.segments.last().and_then(|seg| { - if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args { - Some(&**bindings) - } else { - None - } - }) - } } #[derive(Clone, PartialEq, Eq, Debug, Hash)] @@ -2478,15 +2461,6 @@ pub(crate) enum TypeBindingKind { Constraint { bounds: Vec }, } -impl TypeBinding { - pub(crate) fn term(&self) -> &Term { - match self.kind { - TypeBindingKind::Equality { ref term } => term, - _ => panic!("expected equality type binding for parenthesized generic args"), - } - } -} - /// The type, lifetime, or constant that a private type alias's parameter should be /// replaced with when expanding a use of that type alias. /// diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 170e559e6980..1983bb11e5b1 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -326,8 +326,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( bounds_display.truncate(bounds_display.len() - " + ".len()); write!(f, "{}: {bounds_display}", lifetime.print()) } - // FIXME(fmease): Render bound params. - clean::WherePredicate::EqPredicate { lhs, rhs, bound_params: _ } => { + clean::WherePredicate::EqPredicate { lhs, rhs } => { if f.alternate() { write!(f, "{:#} == {:#}", lhs.print(cx), rhs.print(cx)) } else { diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 2f0cae0a48e2..7a282a99e9ce 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1555,7 +1555,7 @@ function initSearch(rawSearchIndex) { return false; } } - } else if (fnType.id !== null) { + } else { if (queryElem.id === typeNameIdOfArrayOrSlice && (fnType.id === typeNameIdOfSlice || fnType.id === typeNameIdOfArray) ) { diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 088650159605..472cde51be59 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -506,9 +506,8 @@ impl FromWithTcx for WherePredicate { lifetime: convert_lifetime(lifetime), bounds: bounds.into_tcx(tcx), }, - // FIXME(fmease): Convert bound parameters as well. - EqPredicate { lhs, rhs, bound_params: _ } => { - WherePredicate::EqPredicate { lhs: (*lhs).into_tcx(tcx), rhs: (*rhs).into_tcx(tcx) } + EqPredicate { lhs, rhs } => { + WherePredicate::EqPredicate { lhs: lhs.into_tcx(tcx), rhs: rhs.into_tcx(tcx) } } } } diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 0f7a3c2f952a..5153dd26f4ad 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -98,6 +98,8 @@ static TARGETS: &[&str] = &[ "i686-unknown-linux-musl", "i686-unknown-uefi", "loongarch64-unknown-linux-gnu", + "loongarch64-unknown-none", + "loongarch64-unknown-none-softfloat", "m68k-unknown-linux-gnu", "csky-unknown-linux-gnuabiv2", "mips-unknown-linux-gnu", diff --git a/src/tools/build_helper/src/ci.rs b/src/tools/build_helper/src/ci.rs index a8505ec95967..09489b0d9b7d 100644 --- a/src/tools/build_helper/src/ci.rs +++ b/src/tools/build_helper/src/ci.rs @@ -82,15 +82,15 @@ pub mod gha { fn start_group(name: impl std::fmt::Display) { if is_in_gha() { - eprintln!("::group::{name}"); + println!("::group::{name}"); } else { - eprintln!("{name}") + println!("{name}") } } fn end_group() { if is_in_gha() { - eprintln!("::endgroup::"); + println!("::endgroup::"); } } diff --git a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs index 7dd808a7b3b7..accff9b0a34c 100644 --- a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs +++ b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs @@ -287,5 +287,5 @@ fn is_mutex_guard(cx: &LateContext<'_>, def_id: DefId) -> bool { } fn is_refcell_ref(cx: &LateContext<'_>, def_id: DefId) -> bool { - match_def_path(cx, def_id, &paths::REFCELL_REF) || match_def_path(cx, def_id, &paths::REFCELL_REFMUT) + matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::RefCellRef | sym::RefCellRefMut)) } diff --git a/src/tools/clippy/clippy_lints/src/box_default.rs b/src/tools/clippy/clippy_lints/src/box_default.rs index fa9c525fc08d..3f1ff66b8cf6 100644 --- a/src/tools/clippy/clippy_lints/src/box_default.rs +++ b/src/tools/clippy/clippy_lints/src/box_default.rs @@ -1,10 +1,10 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::macros::macro_backtrace; use clippy_utils::ty::expr_sig; -use clippy_utils::{get_parent_node, is_default_equivalent, match_path, path_def_id, paths}; +use clippy_utils::{get_parent_node, is_default_equivalent, path_def_id}; use rustc_errors::Applicability; use rustc_hir::intravisit::{walk_ty, Visitor}; -use rustc_hir::{Block, Expr, ExprKind, Local, Node, QPath, TyKind}; +use rustc_hir::{def::Res, Block, Expr, ExprKind, Local, Node, QPath, TyKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::print::with_forced_trimmed_paths; @@ -55,7 +55,7 @@ impl LateLintPass<'_> for BoxDefault { expr.span, "`Box::new(_)` of default value", "try", - if is_plain_default(arg_path) || given_type(cx, expr) { + if is_plain_default(cx, arg_path) || given_type(cx, expr) { "Box::default()".into() } else if let Some(arg_ty) = cx.typeck_results().expr_ty(arg).make_suggestable(cx.tcx, true) { with_forced_trimmed_paths!(format!("Box::<{arg_ty}>::default()")) @@ -68,11 +68,13 @@ impl LateLintPass<'_> for BoxDefault { } } -fn is_plain_default(arg_path: &Expr<'_>) -> bool { +fn is_plain_default(cx: &LateContext<'_>, arg_path: &Expr<'_>) -> bool { // we need to match the actual path so we don't match e.g. "u8::default" - if let ExprKind::Path(QPath::Resolved(None, path)) = &arg_path.kind { + if let ExprKind::Path(QPath::Resolved(None, path)) = &arg_path.kind + && let Res::Def(_, def_id) = path.res + { // avoid generic parameters - match_path(path, &paths::DEFAULT_TRAIT_METHOD) && path.segments.iter().all(|seg| seg.args.is_none()) + cx.tcx.is_diagnostic_item(sym::default_fn, def_id) && path.segments.iter().all(|seg| seg.args.is_none()) } else { false } diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs index 1de69122101c..9e8ef2825374 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::ty::is_c_void; -use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, match_any_def_paths, paths}; +use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant}; use rustc_hir::{Expr, ExprKind, GenericArg}; use rustc_lint::LateContext; use rustc_middle::ty::layout::LayoutOf; @@ -75,16 +75,17 @@ fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { } }, ExprKind::Call(func, [arg, ..]) if arg.hir_id == e.hir_id => { - static PATHS: &[&[&str]] = &[ - paths::PTR_READ_UNALIGNED.as_slice(), - paths::PTR_UNALIGNED_VOLATILE_LOAD.as_slice(), - paths::PTR_UNALIGNED_VOLATILE_STORE.as_slice(), - ]; - if let ExprKind::Path(path) = &func.kind && let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id() - && (match_any_def_paths(cx, def_id, PATHS).is_some() - || cx.tcx.is_diagnostic_item(sym::ptr_write_unaligned, def_id)) + && matches!( + cx.tcx.get_diagnostic_name(def_id), + Some( + sym::ptr_write_unaligned + | sym::ptr_read_unaligned + | sym::intrinsics_unaligned_volatile_load + | sym::intrinsics_unaligned_volatile_store + ) + ) { true } else { diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs index 5e0123842b04..eb0f75b2f605 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs @@ -1,13 +1,13 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; -use clippy_utils::{match_def_path, paths}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; use rustc_middle::ty::{self, Ty}; +use rustc_span::sym; use super::CAST_SLICE_FROM_RAW_PARTS; @@ -17,12 +17,10 @@ enum RawPartsKind { } fn raw_parts_kind(cx: &LateContext<'_>, did: DefId) -> Option { - if match_def_path(cx, did, &paths::SLICE_FROM_RAW_PARTS) { - Some(RawPartsKind::Immutable) - } else if match_def_path(cx, did, &paths::SLICE_FROM_RAW_PARTS_MUT) { - Some(RawPartsKind::Mutable) - } else { - None + match cx.tcx.get_diagnostic_name(did)? { + sym::slice_from_raw_parts => Some(RawPartsKind::Immutable), + sym::slice_from_raw_parts_mut => Some(RawPartsKind::Mutable), + _ => None, } } diff --git a/src/tools/clippy/clippy_lints/src/create_dir.rs b/src/tools/clippy/clippy_lints/src/create_dir.rs index 878248a6bdc8..2bca695c43b1 100644 --- a/src/tools/clippy/clippy_lints/src/create_dir.rs +++ b/src/tools/clippy/clippy_lints/src/create_dir.rs @@ -1,11 +1,11 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; -use clippy_utils::{match_def_path, paths}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::sym; declare_clippy_lint! { /// ### What it does @@ -37,7 +37,7 @@ impl LateLintPass<'_> for CreateDir { if let ExprKind::Call(func, [arg, ..]) = expr.kind; if let ExprKind::Path(ref path) = func.kind; if let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id(); - if match_def_path(cx, def_id, &paths::STD_FS_CREATE_DIR); + if cx.tcx.is_diagnostic_item(sym::fs_create_dir, def_id); then { span_lint_and_sugg( cx, diff --git a/src/tools/clippy/clippy_lints/src/default.rs b/src/tools/clippy/clippy_lints/src/default.rs index 763ad0264ad9..5787f19cc6cb 100644 --- a/src/tools/clippy/clippy_lints/src/default.rs +++ b/src/tools/clippy/clippy_lints/src/default.rs @@ -1,9 +1,7 @@ use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg}; use clippy_utils::source::snippet_with_context; use clippy_utils::ty::{has_drop, is_copy}; -use clippy_utils::{ - any_parent_is_automatically_derived, contains_name, get_parent_expr, is_from_proc_macro, match_def_path, paths, -}; +use clippy_utils::{any_parent_is_automatically_derived, contains_name, get_parent_expr, is_from_proc_macro}; use if_chain::if_chain; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; @@ -14,7 +12,7 @@ use rustc_middle::ty; use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::symbol::{Ident, Symbol}; -use rustc_span::Span; +use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does @@ -91,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for Default { if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id); if let ExprKind::Path(ref qpath) = path.kind; if let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id(); - if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD); + if cx.tcx.is_diagnostic_item(sym::default_fn, def_id); if !is_update_syntax_base(cx, expr); // Detect and ignore ::default() because these calls do explicitly name the type. if let QPath::Resolved(None, _path) = qpath; @@ -268,7 +266,7 @@ fn is_expr_default<'tcx>(expr: &'tcx Expr<'tcx>, cx: &LateContext<'tcx>) -> bool if let Res::Def(_, def_id) = cx.qpath_res(qpath, fn_expr.hir_id); then { // right hand side of assignment is `Default::default` - match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD) + cx.tcx.is_diagnostic_item(sym::default_fn, def_id) } else { false } diff --git a/src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs b/src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs index a294c6937877..0676777e7968 100644 --- a/src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs +++ b/src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::{is_ty_alias, match_def_path, paths}; +use clippy_utils::is_ty_alias; use hir::def::Res; use hir::ExprKind; use rustc_errors::Applicability; @@ -7,6 +7,7 @@ use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::sym; declare_clippy_lint! { /// ### What it does @@ -63,7 +64,7 @@ impl LateLintPass<'_> for DefaultConstructedUnitStructs { // `::Assoc` cannot be used as a constructor if !is_alias(*base); if let Res::Def(_, def_id) = cx.qpath_res(qpath, fn_expr.hir_id); - if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD); + if cx.tcx.is_diagnostic_item(sym::default_fn, def_id); // make sure we have a struct with no fields (unit struct) if let ty::Adt(def, ..) = cx.typeck_results().expr_ty(expr).kind(); if def.is_struct(); diff --git a/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs b/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs index 572990aaba10..3d6d257e386b 100644 --- a/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs +++ b/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs @@ -1,11 +1,11 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_context; -use clippy_utils::{last_path_segment, match_def_path, paths}; +use clippy_utils::last_path_segment; use rustc_errors::Applicability; use rustc_hir::{def, Expr, ExprKind, GenericArg, QPath, TyKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::SyntaxContext; +use rustc_span::{sym, SyntaxContext}; declare_clippy_lint! { /// ### What it does @@ -37,7 +37,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultIterEmpty { && let TyKind::Path(ty_path) = &ty.kind && let QPath::Resolved(None, path) = ty_path && let def::Res::Def(_, def_id) = &path.res - && match_def_path(cx, *def_id, &paths::ITER_EMPTY) + && cx.tcx.is_diagnostic_item(sym::IterEmpty, *def_id) && let ctxt = expr.span.ctxt() && ty.span.ctxt() == ctxt { diff --git a/src/tools/clippy/clippy_lints/src/exit.rs b/src/tools/clippy/clippy_lints/src/exit.rs index 8ba6a9e48763..5de79133c7dc 100644 --- a/src/tools/clippy/clippy_lints/src/exit.rs +++ b/src/tools/clippy/clippy_lints/src/exit.rs @@ -1,9 +1,10 @@ use clippy_utils::diagnostics::span_lint; -use clippy_utils::{is_entrypoint_fn, match_def_path, paths}; +use clippy_utils::{is_entrypoint_fn}; use if_chain::if_chain; use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::sym; declare_clippy_lint! { /// ### What it does @@ -45,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for Exit { if let ExprKind::Call(path_expr, _args) = e.kind; if let ExprKind::Path(ref path) = path_expr.kind; if let Some(def_id) = cx.qpath_res(path, path_expr.hir_id).opt_def_id(); - if match_def_path(cx, def_id, &paths::EXIT); + if cx.tcx.is_diagnostic_item(sym::process_exit, def_id); let parent = cx.tcx.hir().get_parent_item(e.hir_id).def_id; if let Some(Node::Item(Item{kind: ItemKind::Fn(..), ..})) = cx.tcx.hir().find_by_def_id(parent); // If the next item up is a function we check if it is an entry point diff --git a/src/tools/clippy/clippy_lints/src/explicit_write.rs b/src/tools/clippy/clippy_lints/src/explicit_write.rs index b612cc00bf97..6f6177340f48 100644 --- a/src/tools/clippy/clippy_lints/src/explicit_write.rs +++ b/src/tools/clippy/clippy_lints/src/explicit_write.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::macros::{find_format_args, format_args_inputs_span}; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::{is_expn_of, match_function_call, paths}; +use clippy_utils::{is_expn_of, path_def_id}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::def::Res; @@ -47,18 +47,19 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite { if let ExprKind::MethodCall(unwrap_fun, write_call, [], _) = expr.kind && unwrap_fun.ident.name == sym::unwrap // match call to write_fmt - && let ExprKind::MethodCall(write_fun, write_recv, [write_arg], _) = look_in_block(cx, &write_call.kind) + && let ExprKind::MethodCall(write_fun, write_recv, [write_arg], _) = *look_in_block(cx, &write_call.kind) + && let ExprKind::Call(write_recv_path, _) = write_recv.kind && write_fun.ident.name == sym!(write_fmt) - // match calls to std::io::stdout() / std::io::stderr () - && let Some(dest_name) = if match_function_call(cx, write_recv, &paths::STDOUT).is_some() { - Some("stdout") - } else if match_function_call(cx, write_recv, &paths::STDERR).is_some() { - Some("stderr") - } else { - None - } - && let Some(format_args) = find_format_args(cx, write_arg, ExpnId::root()) + && let Some(def_id) = path_def_id(cx, write_recv_path) { + // match calls to std::io::stdout() / std::io::stderr () + let (dest_name, prefix) = match cx.tcx.get_diagnostic_name(def_id) { + Some(sym::io_stdout) => ("stdout", ""), + Some(sym::io_stderr) => ("stderr", "e"), + _ => return, + }; + let Some(format_args) = find_format_args(cx, write_arg, ExpnId::root()) else { return; }; + // ordering is important here, since `writeln!` uses `write!` internally let calling_macro = if is_expn_of(write_call.span, "writeln").is_some() { Some("writeln") @@ -67,11 +68,6 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite { } else { None }; - let prefix = if dest_name == "stderr" { - "e" - } else { - "" - }; // We need to remove the last trailing newline from the string because the // underlying `fmt::write` function doesn't know whether `println!` or `print!` was diff --git a/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs b/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs index 5e859d97c624..d82ea6d2fc80 100644 --- a/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs +++ b/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::ty::is_c_void; -use clippy_utils::{match_def_path, path_def_id, paths}; +use clippy_utils::path_def_id; use rustc_hir::def_id::DefId; use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; @@ -68,7 +68,7 @@ fn def_id_matches_type(cx: &LateContext<'_>, def_id: DefId) -> Option<&'static s } } - if match_def_path(cx, def_id, &paths::WEAK_RC) || match_def_path(cx, def_id, &paths::WEAK_ARC) { + if matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::RcWeak | sym::ArcWeak)) { Some("Weak") } else { None diff --git a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs index 8df7dfb8b9e5..a1a115f6d79f 100644 --- a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs +++ b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs @@ -130,11 +130,7 @@ fn is_instant_now_call(cx: &LateContext<'_>, expr_block: &'_ Expr<'_>) -> bool { fn is_an_instant(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { let expr_ty = cx.typeck_results().expr_ty(expr); - - match expr_ty.kind() { - rustc_middle::ty::Adt(def, _) => clippy_utils::match_def_path(cx, def.did(), &clippy_utils::paths::INSTANT), - _ => false, - } + ty::is_type_diagnostic_item(cx, expr_ty, sym::Instant) } fn is_a_duration(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { diff --git a/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs b/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs index 49425ff0a8e0..ac949b672609 100644 --- a/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs +++ b/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::ty::match_type; +use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::{is_diag_item_method, is_trait_method, match_def_path, path_to_local_id, paths}; use rustc_errors::Applicability; use rustc_hir::{Body, Closure, Expr, ExprKind}; @@ -62,7 +62,7 @@ impl LateLintPass<'_> for LinesFilterMapOk { if let ExprKind::MethodCall(fm_method, fm_receiver, [fm_arg], fm_span) = expr.kind && is_trait_method(cx, expr, sym::Iterator) && (fm_method.ident.as_str() == "filter_map" || fm_method.ident.as_str() == "flat_map") && - match_type(cx, cx.typeck_results().expr_ty_adjusted(fm_receiver), &paths::STD_IO_LINES) + is_type_diagnostic_item(cx, cx.typeck_results().expr_ty_adjusted(fm_receiver), sym::IoLines) { let lint = match &fm_arg.kind { // Detect `Result::ok` diff --git a/src/tools/clippy/clippy_lints/src/manual_retain.rs b/src/tools/clippy/clippy_lints/src/manual_retain.rs index 1a69a48c582b..f923413f4348 100644 --- a/src/tools/clippy/clippy_lints/src/manual_retain.rs +++ b/src/tools/clippy/clippy_lints/src/manual_retain.rs @@ -135,7 +135,7 @@ fn check_to_owned( if msrv.meets(msrvs::STRING_RETAIN) && let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind && let Some(to_owned_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id) - && match_def_path(cx, to_owned_def_id, &paths::TO_OWNED_METHOD) + && cx.tcx.is_diagnostic_item(sym::to_owned_method, to_owned_def_id) && let hir::ExprKind::MethodCall(_, chars_expr, [_], _) = &filter_expr.kind && let Some(filter_def_id) = cx.typeck_results().type_dependent_def_id(filter_expr.hir_id) && match_def_path(cx, filter_def_id, &paths::CORE_ITER_FILTER) diff --git a/src/tools/clippy/clippy_lints/src/methods/bytecount.rs b/src/tools/clippy/clippy_lints/src/methods/bytecount.rs index f490a7175540..35370355f834 100644 --- a/src/tools/clippy/clippy_lints/src/methods/bytecount.rs +++ b/src/tools/clippy/clippy_lints/src/methods/bytecount.rs @@ -1,8 +1,8 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::ty::match_type; +use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::visitors::is_local_used; -use clippy_utils::{path_to_local_id, paths, peel_blocks, peel_ref_operators, strip_pat_refs}; +use clippy_utils::{path_to_local_id, peel_blocks, peel_ref_operators, strip_pat_refs}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Closure, Expr, ExprKind, PatKind}; @@ -25,9 +25,9 @@ pub(super) fn check<'tcx>( if let PatKind::Binding(_, arg_id, _, _) = strip_pat_refs(param.pat).kind; if let ExprKind::Binary(ref op, l, r) = body.value.kind; if op.node == BinOpKind::Eq; - if match_type(cx, + if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(filter_recv).peel_refs(), - &paths::SLICE_ITER); + sym::SliceIter); let operand_is_arg = |expr| { let expr = peel_ref_operators(cx, peel_blocks(expr)); path_to_local_id(expr, arg_id) diff --git a/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs b/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs index ddf3c9f27df2..926bd06bacbd 100644 --- a/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs +++ b/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs @@ -1,7 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::paths; use clippy_utils::source::snippet_with_context; -use clippy_utils::ty::{is_type_diagnostic_item, match_type}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; @@ -22,15 +20,14 @@ pub(super) fn check( } let obj_ty = cx.typeck_results().expr_ty(receiver).peel_refs(); - if let ty::Adt(_, subst) = obj_ty.kind() { - let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) { - "Rc" - } else if is_type_diagnostic_item(cx, obj_ty, sym::Arc) { - "Arc" - } else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) { - "Weak" - } else { - return; + if let ty::Adt(adt, subst) = obj_ty.kind() + && let Some(name) = cx.tcx.get_diagnostic_name(adt.did()) + { + let caller_type = match name { + sym::Rc => "Rc", + sym::Arc => "Arc", + sym::RcWeak | sym::ArcWeak => "Weak", + _ => return, }; // Sometimes unnecessary ::<_> after Rc/Arc/Weak diff --git a/src/tools/clippy/clippy_lints/src/methods/from_iter_instead_of_collect.rs b/src/tools/clippy/clippy_lints/src/methods/from_iter_instead_of_collect.rs index 66dfce3682b5..4040d3a5fe13 100644 --- a/src/tools/clippy/clippy_lints/src/methods/from_iter_instead_of_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/from_iter_instead_of_collect.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_opt; use clippy_utils::ty::implements_trait; -use clippy_utils::{is_expr_path_def_path, paths, sugg}; +use clippy_utils::{is_path_diagnostic_item, sugg}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir as hir; @@ -13,7 +13,7 @@ use super::FROM_ITER_INSTEAD_OF_COLLECT; pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>], func: &hir::Expr<'_>) { if_chain! { - if is_expr_path_def_path(cx, func, &paths::FROM_ITERATOR_METHOD); + if is_path_diagnostic_item(cx, func, sym::from_iter_fn); let ty = cx.typeck_results().expr_ty(expr); let arg_ty = cx.typeck_results().expr_ty(&args[0]); if let Some(iter_id) = cx.tcx.get_diagnostic_item(sym::Iterator); diff --git a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs index 631741d9290c..6686d42c95f8 100644 --- a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs +++ b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::{is_type_lang_item, walk_ptrs_ty_depth}; -use clippy_utils::{match_def_path, paths}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir as hir; @@ -22,7 +21,7 @@ pub fn check( if_chain! { if args.is_empty() && method_name == sym::to_string; if let Some(to_string_meth_did) = cx.typeck_results().type_dependent_def_id(expr.hir_id); - if match_def_path(cx, to_string_meth_did, &paths::TO_STRING_METHOD); + if cx.tcx.is_diagnostic_item(sym::to_string_method, to_string_meth_did); if let Some(args) = cx.typeck_results().node_args_opt(expr.hir_id); let arg_ty = cx.typeck_results().expr_ty_adjusted(receiver); let self_ty = args.type_at(0); diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs b/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs index 79c6d63254b2..99ea7f03df4e 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_note; use clippy_utils::higher::VecArgs; -use clippy_utils::{expr_or_init, is_trait_method, match_def_path, paths}; +use clippy_utils::{expr_or_init, is_trait_method}; use rustc_ast::LitKind; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; @@ -26,14 +26,14 @@ fn get_iterator_length<'tcx>(cx: &LateContext<'tcx>, iter: &'tcx Expr<'tcx>) -> }; let did = adt.did(); - if match_def_path(cx, did, &paths::ARRAY_INTO_ITER) { + if cx.tcx.is_diagnostic_item(sym::ArrayIntoIter, did) { // For array::IntoIter, the length is the second generic // parameter. substs .const_at(1) .try_eval_target_usize(cx.tcx, cx.param_env) .map(u128::from) - } else if match_def_path(cx, did, &paths::SLICE_ITER) + } else if cx.tcx.is_diagnostic_item(sym::SliceIter, did) && let ExprKind::MethodCall(_, recv, ..) = iter.kind { if let ty::Array(_, len) = cx.typeck_results().expr_ty(recv).peel_refs().kind() { @@ -47,9 +47,9 @@ fn get_iterator_length<'tcx>(cx: &LateContext<'tcx>, iter: &'tcx Expr<'tcx>) -> } else { None } - } else if match_def_path(cx, did, &paths::ITER_EMPTY) { + } else if cx.tcx.is_diagnostic_item(sym::IterEmpty, did) { Some(0) - } else if match_def_path(cx, did, &paths::ITER_ONCE) { + } else if cx.tcx.is_diagnostic_item(sym::IterOnce, did) { Some(1) } else { None diff --git a/src/tools/clippy/clippy_lints/src/methods/open_options.rs b/src/tools/clippy/clippy_lints/src/methods/open_options.rs index 1c664e76d74f..c0f5a2799451 100644 --- a/src/tools/clippy/clippy_lints/src/methods/open_options.rs +++ b/src/tools/clippy/clippy_lints/src/methods/open_options.rs @@ -1,17 +1,17 @@ use clippy_utils::diagnostics::span_lint; -use clippy_utils::paths; -use clippy_utils::ty::match_type; +use clippy_utils::ty::is_type_diagnostic_item; use rustc_ast::ast::LitKind; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; use rustc_span::source_map::{Span, Spanned}; +use rustc_span::sym; use super::NONSENSICAL_OPEN_OPTIONS; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) && let Some(impl_id) = cx.tcx.impl_of_method(method_id) - && match_type(cx, cx.tcx.type_of(impl_id).instantiate_identity(), &paths::OPEN_OPTIONS) + && is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::FsOpenOptions) { let mut options = Vec::new(); get_open_options(cx, recv, &mut options); @@ -40,7 +40,7 @@ fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec let obj_ty = cx.typeck_results().expr_ty(receiver).peel_refs(); // Only proceed if this is a call on some object of type std::fs::OpenOptions - if match_type(cx, obj_ty, &paths::OPEN_OPTIONS) && !arguments.is_empty() { + if is_type_diagnostic_item(cx, obj_ty, sym::FsOpenOptions) && !arguments.is_empty() { let argument_option = match arguments[0].kind { ExprKind::Lit(span) => { if let Spanned { diff --git a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs index 3e33f9193374..d0c27f9631f7 100644 --- a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs +++ b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs @@ -32,8 +32,7 @@ pub(super) fn check( return; } - let deref_aliases: [&[&str]; 8] = [ - &paths::DEREF_MUT_TRAIT_METHOD, + let deref_aliases: [&[&str]; 7] = [ &paths::CSTRING_AS_C_STR, &paths::OS_STRING_AS_OS_STR, &paths::PATH_BUF_AS_PATH, @@ -49,6 +48,7 @@ pub(super) fn check( .opt_def_id() .map_or(false, |fun_def_id| { cx.tcx.is_diagnostic_item(sym::deref_method, fun_def_id) + || cx.tcx.is_diagnostic_item(sym::deref_mut_method, fun_def_id) || deref_aliases.iter().any(|path| match_def_path(cx, fun_def_id, path)) }) }, @@ -70,6 +70,7 @@ pub(super) fn check( then { let method_did = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id).unwrap(); cx.tcx.is_diagnostic_item(sym::deref_method, method_did) + || cx.tcx.is_diagnostic_item(sym::deref_mut_method, method_did) || deref_aliases.iter().any(|path| match_def_path(cx, method_did, path)) } else { false diff --git a/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs b/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs index f3d6a15ede01..4ea87027a9e6 100644 --- a/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs +++ b/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs @@ -2,18 +2,19 @@ use rustc_ast::ast::{LitIntType, LitKind}; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; +use rustc_span::sym; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::implements_trait; -use clippy_utils::{get_trait_def_id, match_def_path, paths}; +use clippy_utils::{match_def_path, paths}; use super::SEEK_FROM_CURRENT; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'tcx Expr<'_>, arg: &'tcx Expr<'_>) { let ty = cx.typeck_results().expr_ty(recv); - if let Some(def_id) = get_trait_def_id(cx, &paths::STD_IO_SEEK) { + if let Some(def_id) = cx.tcx.get_diagnostic_item(sym::IoSeek) { if implements_trait(cx, ty, def_id, &[]) && arg_is_seek_from_current(cx, arg) { let mut applicability = Applicability::MachineApplicable; let snip = snippet_with_applicability(cx, recv.span, "..", &mut applicability); diff --git a/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs b/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs index 787e9e0ebd24..50d4de7a6800 100644 --- a/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs +++ b/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs @@ -1,11 +1,11 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::ty::implements_trait; -use clippy_utils::{get_trait_def_id, is_expr_used_or_unified, match_def_path, paths}; +use clippy_utils::{is_expr_used_or_unified, match_def_path, paths}; use rustc_ast::ast::{LitIntType, LitKind}; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; -use rustc_span::Span; +use rustc_span::{sym, Span}; use super::SEEK_TO_START_INSTEAD_OF_REWIND; @@ -23,7 +23,7 @@ pub(super) fn check<'tcx>( return; } - if let Some(seek_trait_id) = get_trait_def_id(cx, &paths::STD_IO_SEEK) && + if let Some(seek_trait_id) = cx.tcx.get_diagnostic_item(sym::IoSeek) && implements_trait(cx, ty, seek_trait_id, &[]) && let ExprKind::Call(func, args1) = arg.kind && let ExprKind::Path(ref path) = func.kind && diff --git a/src/tools/clippy/clippy_lints/src/methods/suspicious_command_arg_space.rs b/src/tools/clippy/clippy_lints/src/methods/suspicious_command_arg_space.rs index bc8f01767641..8959e2c1d75f 100644 --- a/src/tools/clippy/clippy_lints/src/methods/suspicious_command_arg_space.rs +++ b/src/tools/clippy/clippy_lints/src/methods/suspicious_command_arg_space.rs @@ -1,9 +1,8 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::paths; -use clippy_utils::ty::match_type; +use clippy_utils::ty::is_type_diagnostic_item; use rustc_errors::{Applicability, Diagnostic}; use rustc_lint::LateContext; -use rustc_span::Span; +use rustc_span::{sym, Span}; use {rustc_ast as ast, rustc_hir as hir}; use super::SUSPICIOUS_COMMAND_ARG_SPACE; @@ -11,7 +10,7 @@ use super::SUSPICIOUS_COMMAND_ARG_SPACE; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, recv: &'tcx hir::Expr<'_>, arg: &'tcx hir::Expr<'_>, span: Span) { let ty = cx.typeck_results().expr_ty(recv).peel_refs(); - if match_type(cx, ty, &paths::STD_PROCESS_COMMAND) + if is_type_diagnostic_item(cx, ty, sym::Command) && let hir::ExprKind::Lit(lit) = &arg.kind && let ast::LitKind::Str(s, _) = &lit.node && let Some((arg1, arg2)) = s.as_str().split_once(' ') diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs index 937aac8d25ef..24c0ea3f60a9 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs @@ -102,14 +102,10 @@ pub(super) fn check( ]), ("None", "unwrap_or_else", _) => match args[0].kind { hir::ExprKind::Closure(hir::Closure { - fn_decl: - hir::FnDecl { - output: hir::FnRetTy::DefaultReturn(span) | hir::FnRetTy::Return(hir::Ty { span, .. }), - .. - }, + body, .. }) => Some(vec![ - (expr.span.with_hi(span.hi()), String::new()), + (expr.span.with_hi(cx.tcx.hir().body(*body).value.span.lo()), String::new()), (expr.span.with_lo(args[0].span.hi()), String::new()), ]), _ => None, diff --git a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs index 2f63b9b9f0b8..f0b865be8042 100644 --- a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs +++ b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs @@ -1,9 +1,9 @@ use std::ops::ControlFlow; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::ty::match_type; +use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::visitors::{for_each_expr, Visitable}; -use clippy_utils::{is_path_lang_item, paths}; +use clippy_utils::is_path_lang_item; use rustc_ast::LitKind; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::{DefKind, Res}; @@ -114,9 +114,11 @@ fn should_lint<'tcx>( if let ExprKind::MethodCall(path, recv, ..) = &expr.kind { let recv_ty = typeck_results.expr_ty(recv).peel_refs(); - if path.ident.name == sym::debug_struct && match_type(cx, recv_ty, &paths::FORMATTER) { + if path.ident.name == sym::debug_struct && is_type_diagnostic_item(cx, recv_ty, sym::Formatter) { has_debug_struct = true; - } else if path.ident.name == sym!(finish_non_exhaustive) && match_type(cx, recv_ty, &paths::DEBUG_STRUCT) { + } else if path.ident.name == sym!(finish_non_exhaustive) + && is_type_diagnostic_item(cx, recv_ty, sym::DebugStruct) + { has_finish_non_exhaustive = true; } } @@ -137,7 +139,7 @@ fn as_field_call<'tcx>( ) -> Option { if let ExprKind::MethodCall(path, recv, [debug_field, _], _) = &expr.kind && let recv_ty = typeck_results.expr_ty(recv).peel_refs() - && match_type(cx, recv_ty, &paths::DEBUG_STRUCT) + && is_type_diagnostic_item(cx, recv_ty, sym::DebugStruct) && path.ident.name == sym::field && let ExprKind::Lit(lit) = &debug_field.kind && let LitKind::Str(sym, ..) = lit.node diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs index 367cd6bd4133..ea6a9bc5657d 100644 --- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs +++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs @@ -134,15 +134,30 @@ impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> { } } +fn stmt_might_diverge(stmt: &Stmt<'_>) -> bool { + match stmt.kind { + StmtKind::Item(..) => false, + _ => true, + } +} + impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> { fn visit_expr(&mut self, e: &'tcx Expr<'_>) { match e.kind { // fix #10776 ExprKind::Block(block, ..) => match (block.stmts, block.expr) { - ([], Some(e)) => self.visit_expr(e), - ([stmt], None) => match stmt.kind { - StmtKind::Expr(e) | StmtKind::Semi(e) => self.visit_expr(e), - _ => {}, + (stmts, Some(e)) => { + if stmts.iter().all(|stmt| !stmt_might_diverge(stmt)) { + self.visit_expr(e) + } + }, + ([first @ .., stmt], None) => { + if first.iter().all(|stmt| !stmt_might_diverge(stmt)) { + match stmt.kind { + StmtKind::Expr(e) | StmtKind::Semi(e) => self.visit_expr(e), + _ => {}, + } + } }, _ => {}, }, diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 5ee26966fa71..6d7df2eac629 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -4,7 +4,7 @@ use clippy_utils::source::{snippet, snippet_opt}; use clippy_utils::ty::{ implements_trait, implements_trait_with_env_from_iter, is_copy, is_type_diagnostic_item, is_type_lang_item, }; -use clippy_utils::{get_trait_def_id, is_self, paths}; +use clippy_utils::is_self; use if_chain::if_chain; use rustc_ast::ast::Attribute; use rustc_errors::{Applicability, Diagnostic}; @@ -115,7 +115,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { need!(cx.tcx.lang_items().fn_trait()), need!(cx.tcx.lang_items().fn_once_trait()), need!(cx.tcx.lang_items().fn_mut_trait()), - need!(get_trait_def_id(cx, &paths::RANGE_ARGUMENT_TRAIT)), + need!(cx.tcx.get_diagnostic_item(sym::RangeBounds)), ]; let sized_trait = need!(cx.tcx.lang_items().sized_trait()); diff --git a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs index 20b4b4f03ed4..4be140647fcc 100644 --- a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs +++ b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; -use clippy_utils::paths::ORD_CMP; use clippy_utils::ty::implements_trait; -use clippy_utils::{get_parent_node, is_res_lang_ctor, last_path_segment, match_def_path, path_res, std_or_core}; +use clippy_utils::{get_parent_node, is_res_lang_ctor, last_path_segment, path_res, std_or_core}; use rustc_errors::Applicability; use rustc_hir::def_id::LocalDefId; use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, LangItem, Node, UnOp}; @@ -261,7 +260,7 @@ fn self_cmp_call<'tcx>( match cmp_expr.kind { ExprKind::Call(path, [_self, _other]) => path_res(cx, path) .opt_def_id() - .is_some_and(|def_id| match_def_path(cx, def_id, &ORD_CMP)), + .is_some_and(|def_id| cx.tcx.is_diagnostic_item(sym::ord_cmp_method, def_id)), ExprKind::MethodCall(_, _, [_other], ..) => { // We can set this to true here no matter what as if it's a `MethodCall` and goes to the // `else` branch, it must be a method named `cmp` that isn't `Ord::cmp` @@ -273,7 +272,7 @@ fn self_cmp_call<'tcx>( cx.tcx .typeck(def_id) .type_dependent_def_id(cmp_expr.hir_id) - .is_some_and(|def_id| match_def_path(cx, def_id, &ORD_CMP)) + .is_some_and(|def_id| cx.tcx.is_diagnostic_item(sym::ord_cmp_method, def_id)) }, _ => false, } diff --git a/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs b/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs index e1de494eb41c..d47728f190ab 100644 --- a/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs +++ b/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs @@ -1,6 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::{snippet_opt, snippet_with_applicability}; -use clippy_utils::ty::{is_type_diagnostic_item, match_type}; use clippy_utils::{match_def_path, paths}; use if_chain::if_chain; use rustc_errors::Applicability; @@ -45,13 +44,12 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { match &expr.kind { ExprKind::MethodCall(path, func, [param], _) => { - let obj_ty = cx.typeck_results().expr_ty(func).peel_refs(); - if_chain! { + if let Some(adt) = cx.typeck_results().expr_ty(func).peel_refs().ty_adt_def(); if (path.ident.name == sym!(mode) - && (match_type(cx, obj_ty, &paths::OPEN_OPTIONS) - || is_type_diagnostic_item(cx, obj_ty, sym::DirBuilder))) - || (path.ident.name == sym!(set_mode) && match_type(cx, obj_ty, &paths::PERMISSIONS)); + && matches!(cx.tcx.get_diagnostic_name(adt.did()), Some(sym::FsOpenOptions | sym::DirBuilder))) + || (path.ident.name == sym!(set_mode) + && cx.tcx.is_diagnostic_item(sym::FsPermissions, adt.did())); if let ExprKind::Lit(_) = param.kind; if param.span.ctxt() == expr.span.ctxt(); diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs index c5e777c20702..d388dfc08f3b 100644 --- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs +++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet; use clippy_utils::ty::{implements_trait, is_copy}; -use clippy_utils::{is_lint_allowed, match_def_path, paths}; +use clippy_utils::is_lint_allowed; use rustc_ast::ImplPolarity; use rustc_hir::def_id::DefId; use rustc_hir::{FieldDef, Item, ItemKind, Node}; @@ -233,7 +233,7 @@ fn contains_pointer_like<'tcx>(cx: &LateContext<'tcx>, target_ty: Ty<'tcx>) -> b return true; }, ty::Adt(adt_def, _) => { - if match_def_path(cx, adt_def.did(), &paths::PTR_NON_NULL) { + if cx.tcx.is_diagnostic_item(sym::NonNull, adt_def.did()) { return true; } }, diff --git a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs index d3de9699fe9d..136642d69dca 100644 --- a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs +++ b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet; use clippy_utils::ty::{implements_trait, is_copy}; -use clippy_utils::{match_def_path, path_def_id, paths}; +use clippy_utils::path_def_id; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp}; use rustc_lint::LateContext; @@ -50,7 +50,7 @@ fn check_op(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool) }, ExprKind::Call(path, [arg]) if path_def_id(cx, path).map_or(false, |did| { - if match_def_path(cx, did, &paths::FROM_STR_METHOD) { + if cx.tcx.is_diagnostic_item(sym::from_str_method, did) { true } else if cx.tcx.is_diagnostic_item(sym::from_fn, did) { !is_copy(cx, typeck.expr_ty(expr)) diff --git a/src/tools/clippy/clippy_lints/src/permissions_set_readonly_false.rs b/src/tools/clippy/clippy_lints/src/permissions_set_readonly_false.rs index 664d44d6504d..f3089d716ff1 100644 --- a/src/tools/clippy/clippy_lints/src/permissions_set_readonly_false.rs +++ b/src/tools/clippy/clippy_lints/src/permissions_set_readonly_false.rs @@ -1,10 +1,10 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::paths; -use clippy_utils::ty::match_type; +use clippy_utils::ty::is_type_diagnostic_item; use rustc_ast::ast::LitKind; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::sym; declare_clippy_lint! { /// ### What it does @@ -31,7 +31,7 @@ declare_lint_pass!(PermissionsSetReadonlyFalse => [PERMISSIONS_SET_READONLY_FALS impl<'tcx> LateLintPass<'tcx> for PermissionsSetReadonlyFalse { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if let ExprKind::MethodCall(path, receiver, [arg], _) = &expr.kind - && match_type(cx, cx.typeck_results().expr_ty(receiver), &paths::PERMISSIONS) + && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(receiver), sym::FsPermissions) && path.ident.name == sym!(set_readonly) && let ExprKind::Lit(lit) = &arg.kind && LitKind::Bool(false) == lit.node diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index 7dabdcd58ec2..310051efc508 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -4,9 +4,8 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_the use clippy_utils::source::snippet_opt; use clippy_utils::ty::expr_sig; use clippy_utils::visitors::contains_unsafe_block; -use clippy_utils::{get_expr_use_or_unification_node, is_lint_allowed, path_def_id, path_to_local, paths}; +use clippy_utils::{get_expr_use_or_unification_node, is_lint_allowed, path_def_id, path_to_local}; use hir::LifetimeName; -use if_chain::if_chain; use rustc_errors::{Applicability, MultiSpan}; use rustc_hir::def_id::DefId; use rustc_hir::hir_id::HirIdMap; @@ -271,60 +270,43 @@ impl<'tcx> LateLintPass<'tcx> for Ptr { } fn check_invalid_ptr_usage<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - // (fn_path, arg_indices) - `arg_indices` are the `arg` positions where null would cause U.B. - const INVALID_NULL_PTR_USAGE_TABLE: [(&[&str], &[usize]); 13] = [ - (&paths::SLICE_FROM_RAW_PARTS, &[0]), - (&paths::SLICE_FROM_RAW_PARTS_MUT, &[0]), - (&paths::PTR_COPY, &[0, 1]), - (&paths::PTR_COPY_NONOVERLAPPING, &[0, 1]), - (&paths::PTR_READ, &[0]), - (&paths::PTR_READ_UNALIGNED, &[0]), - (&paths::PTR_READ_VOLATILE, &[0]), - (&paths::PTR_REPLACE, &[0]), - (&paths::PTR_SLICE_FROM_RAW_PARTS, &[0]), - (&paths::PTR_SLICE_FROM_RAW_PARTS_MUT, &[0]), - (&paths::PTR_SWAP, &[0, 1]), - (&paths::PTR_SWAP_NONOVERLAPPING, &[0, 1]), - (&paths::PTR_WRITE_BYTES, &[0]), - ]; - let invalid_null_ptr_usage_table_diag_items: [(Option, &[usize]); 3] = [ - (cx.tcx.get_diagnostic_item(sym::ptr_write), &[0]), - (cx.tcx.get_diagnostic_item(sym::ptr_write_unaligned), &[0]), - (cx.tcx.get_diagnostic_item(sym::ptr_write_volatile), &[0]), - ]; - - if_chain! { - if let ExprKind::Call(fun, args) = expr.kind; - if let ExprKind::Path(ref qpath) = fun.kind; - if let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id(); - let fun_def_path = cx.get_def_path(fun_def_id).into_iter().map(Symbol::to_ident_string).collect::>(); - if let Some(arg_indices) = INVALID_NULL_PTR_USAGE_TABLE - .iter() - .find_map(|&(fn_path, indices)| if fn_path == fun_def_path { Some(indices) } else { None }) - .or_else(|| { - invalid_null_ptr_usage_table_diag_items - .iter() - .find_map(|&(def_id, indices)| { - if def_id == Some(fun_def_id) { - Some(indices) - } else { - None - } - }) - }); - then { - for &arg_idx in arg_indices { - if let Some(arg) = args.get(arg_idx).filter(|arg| is_null_path(cx, arg)) { - span_lint_and_sugg( - cx, - INVALID_NULL_PTR_USAGE, - arg.span, - "pointer must be non-null", - "change this to", - "core::ptr::NonNull::dangling().as_ptr()".to_string(), - Applicability::MachineApplicable, - ); - } + if let ExprKind::Call(fun, args) = expr.kind + && let ExprKind::Path(ref qpath) = fun.kind + && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id() + && let Some(name) = cx.tcx.get_diagnostic_name(fun_def_id) + { + // `arg` positions where null would cause U.B. + let arg_indices: &[_] = match name { + sym::ptr_read + | sym::ptr_read_unaligned + | sym::ptr_read_volatile + | sym::ptr_replace + | sym::ptr_slice_from_raw_parts + | sym::ptr_slice_from_raw_parts_mut + | sym::ptr_write + | sym::ptr_write_bytes + | sym::ptr_write_unaligned + | sym::ptr_write_volatile + | sym::slice_from_raw_parts + | sym::slice_from_raw_parts_mut => &[0], + sym::ptr_copy + | sym::ptr_copy_nonoverlapping + | sym::ptr_swap + | sym::ptr_swap_nonoverlapping => &[0, 1], + _ => return, + }; + + for &arg_idx in arg_indices { + if let Some(arg) = args.get(arg_idx).filter(|arg| is_null_path(cx, arg)) { + span_lint_and_sugg( + cx, + INVALID_NULL_PTR_USAGE, + arg.span, + "pointer must be non-null", + "change this to", + "core::ptr::NonNull::dangling().as_ptr()".to_string(), + Applicability::MachineApplicable, + ); } } } diff --git a/src/tools/clippy/clippy_lints/src/raw_strings.rs b/src/tools/clippy/clippy_lints/src/raw_strings.rs index 2895595e0390..8a7e48746661 100644 --- a/src/tools/clippy/clippy_lints/src/raw_strings.rs +++ b/src/tools/clippy/clippy_lints/src/raw_strings.rs @@ -50,7 +50,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.72.0"] pub NEEDLESS_RAW_STRING_HASHES, - style, + pedantic, "suggests reducing the number of hashes around a raw string literal" } impl_lint_pass!(RawStrings => [NEEDLESS_RAW_STRINGS, NEEDLESS_RAW_STRING_HASHES]); diff --git a/src/tools/clippy/clippy_lints/src/rc_clone_in_vec_init.rs b/src/tools/clippy/clippy_lints/src/rc_clone_in_vec_init.rs index 8e85c55e7563..1a127c2bcf68 100644 --- a/src/tools/clippy/clippy_lints/src/rc_clone_in_vec_init.rs +++ b/src/tools/clippy/clippy_lints/src/rc_clone_in_vec_init.rs @@ -2,11 +2,11 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::VecArgs; use clippy_utils::macros::root_macro_call_first_node; use clippy_utils::source::{indent_of, snippet}; -use clippy_utils::ty::match_type; -use clippy_utils::{last_path_segment, paths}; +use clippy_utils::last_path_segment; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, QPath, TyKind}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{sym, Span, Symbol}; @@ -133,8 +133,9 @@ fn ref_init(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<(Symbol, Span)> { return Some((symbol, func.span)); } - let ty_path = cx.typeck_results().expr_ty(expr); - if match_type(cx, ty_path, &paths::WEAK_RC) || match_type(cx, ty_path, &paths::WEAK_ARC) { + if let ty::Adt(adt, _) = *cx.typeck_results().expr_ty(expr).kind() + && matches!(cx.tcx.get_diagnostic_name(adt.did()), Some(sym::RcWeak | sym::ArcWeak)) + { return Some((Symbol::intern("Weak"), func.span)); } } diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs index e36adef555e6..2c0086b09813 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs @@ -99,8 +99,8 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone { unwrap_or_continue!(is_call_with_ref_arg(cx, mir, &terminator.kind)); let from_borrow = match_def_path(cx, fn_def_id, &paths::CLONE_TRAIT_METHOD) - || match_def_path(cx, fn_def_id, &paths::TO_OWNED_METHOD) - || (match_def_path(cx, fn_def_id, &paths::TO_STRING_METHOD) + || cx.tcx.is_diagnostic_item(sym::to_owned_method, fn_def_id) + || (cx.tcx.is_diagnostic_item(sym::to_string_method, fn_def_id) && is_type_lang_item(cx, arg_ty, LangItem::String)); let from_deref = !from_borrow diff --git a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs index bd783b4e0054..b940cac6047b 100644 --- a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs +++ b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs @@ -2,7 +2,6 @@ //! expecting a count of T use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::{match_def_path, paths}; use if_chain::if_chain; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -67,16 +66,6 @@ fn get_pointee_ty_and_count_expr<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, ) -> Option<(Ty<'tcx>, &'tcx Expr<'tcx>)> { - const FUNCTIONS: [&[&str]; 8] = [ - &paths::PTR_COPY_NONOVERLAPPING, - &paths::PTR_COPY, - &paths::PTR_WRITE_BYTES, - &paths::PTR_SWAP_NONOVERLAPPING, - &paths::PTR_SLICE_FROM_RAW_PARTS, - &paths::PTR_SLICE_FROM_RAW_PARTS_MUT, - &paths::SLICE_FROM_RAW_PARTS, - &paths::SLICE_FROM_RAW_PARTS_MUT, - ]; const METHODS: [&str; 11] = [ "write_bytes", "copy_to", @@ -97,7 +86,16 @@ fn get_pointee_ty_and_count_expr<'tcx>( if let ExprKind::Call(func, [.., count]) = expr.kind; if let ExprKind::Path(ref func_qpath) = func.kind; if let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id(); - if FUNCTIONS.iter().any(|func_path| match_def_path(cx, def_id, func_path)); + if matches!(cx.tcx.get_diagnostic_name(def_id), Some( + sym::ptr_copy + | sym::ptr_copy_nonoverlapping + | sym::ptr_slice_from_raw_parts + | sym::ptr_slice_from_raw_parts_mut + | sym::ptr_swap_nonoverlapping + | sym::ptr_write_bytes + | sym::slice_from_raw_parts + | sym::slice_from_raw_parts_mut + )); // Get the pointee type if let Some(pointee_ty) = cx.typeck_results().node_args(func.hir_id).types().next(); diff --git a/src/tools/clippy/clippy_lints/src/swap_ptr_to_ref.rs b/src/tools/clippy/clippy_lints/src/swap_ptr_to_ref.rs index d085dda3582b..3685432a2539 100644 --- a/src/tools/clippy/clippy_lints/src/swap_ptr_to_ref.rs +++ b/src/tools/clippy/clippy_lints/src/swap_ptr_to_ref.rs @@ -1,11 +1,11 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet_with_context; -use clippy_utils::{match_def_path, path_def_id, paths}; +use clippy_utils::path_def_id; use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::{Span, SyntaxContext}; +use rustc_span::{sym, Span, SyntaxContext}; declare_clippy_lint! { /// ### What it does @@ -42,7 +42,7 @@ impl LateLintPass<'_> for SwapPtrToRef { fn check_expr(&mut self, cx: &LateContext<'_>, e: &Expr<'_>) { if let ExprKind::Call(fn_expr, [arg1, arg2]) = e.kind && let Some(fn_id) = path_def_id(cx, fn_expr) - && match_def_path(cx, fn_id, &paths::MEM_SWAP) + && cx.tcx.is_diagnostic_item(sym::mem_swap, fn_id) && let ctxt = e.span.ctxt() && let (from_ptr1, arg1_span) = is_ptr_to_ref(cx, arg1, ctxt) && let (from_ptr2, arg2_span) = is_ptr_to_ref(cx, arg2, ctxt) diff --git a/src/tools/clippy/clippy_lints/src/unnamed_address.rs b/src/tools/clippy/clippy_lints/src/unnamed_address.rs index dea8a1e35bbb..996e7edf5573 100644 --- a/src/tools/clippy/clippy_lints/src/unnamed_address.rs +++ b/src/tools/clippy/clippy_lints/src/unnamed_address.rs @@ -1,10 +1,10 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_help}; -use clippy_utils::{match_def_path, paths}; use if_chain::if_chain; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::sym; declare_clippy_lint! { /// ### What it does @@ -96,7 +96,7 @@ impl LateLintPass<'_> for UnnamedAddress { if let ExprKind::Call(func, [ref _left, ref _right]) = expr.kind; if let ExprKind::Path(ref func_qpath) = func.kind; if let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id(); - if match_def_path(cx, def_id, &paths::PTR_EQ); + if cx.tcx.is_diagnostic_item(sym::ptr_eq, def_id); let ty_param = cx.typeck_results().node_args(func.hir_id).type_at(0); if ty_param.is_trait(); then { diff --git a/src/tools/clippy/clippy_lints/src/unused_peekable.rs b/src/tools/clippy/clippy_lints/src/unused_peekable.rs index 4ee16d9a5e4a..db91beec0efa 100644 --- a/src/tools/clippy/clippy_lints/src/unused_peekable.rs +++ b/src/tools/clippy/clippy_lints/src/unused_peekable.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::ty::{match_type, peel_mid_ty_refs_is_mutable}; -use clippy_utils::{fn_def_id, is_trait_method, path_to_local_id, paths, peel_ref_operators}; +use clippy_utils::ty::{is_type_diagnostic_item, peel_mid_ty_refs_is_mutable}; +use clippy_utils::{fn_def_id, is_trait_method, path_to_local_id, peel_ref_operators}; use rustc_ast::Mutability; use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::{Block, Expr, ExprKind, HirId, Local, Node, PatKind, PathSegment, StmtKind}; @@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedPeekable { // Don't lint `Peekable`s returned from a block if let Some(expr) = block.expr && let Some(ty) = cx.typeck_results().expr_ty_opt(peel_ref_operators(cx, expr)) - && match_type(cx, ty, &paths::PEEKABLE) + && is_type_diagnostic_item(cx, ty, sym::IterPeekable) { return; } @@ -62,7 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedPeekable { && !init.span.from_expansion() && let Some(ty) = cx.typeck_results().expr_ty_opt(init) && let (ty, _, Mutability::Mut) = peel_mid_ty_refs_is_mutable(ty) - && match_type(cx, ty, &paths::PEEKABLE) + && is_type_diagnostic_item(cx, ty, sym::IterPeekable) { let mut vis = PeekableVisitor::new(cx, binding); @@ -222,7 +222,7 @@ impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> { fn arg_is_mut_peekable(cx: &LateContext<'_>, arg: &Expr<'_>) -> bool { if let Some(ty) = cx.typeck_results().expr_ty_opt(arg) && let (ty, _, Mutability::Mut) = peel_mid_ty_refs_is_mutable(ty) - && match_type(cx, ty, &paths::PEEKABLE) + && is_type_diagnostic_item(cx, ty, sym::IterPeekable) { true } else { diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs index f32e7edad6cb..3cc91838c000 100644 --- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs +++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lin use clippy_utils::source::{snippet, snippet_with_applicability, snippet_with_context}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::{is_copy, is_type_diagnostic_item, same_type_and_consts}; -use clippy_utils::{get_parent_expr, is_trait_method, is_ty_alias, match_def_path, path_to_local, paths}; +use clippy_utils::{get_parent_expr, is_trait_method, is_ty_alias, path_to_local}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::def::DefKind; @@ -331,7 +331,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { let a = cx.typeck_results().expr_ty(e); let b = cx.typeck_results().expr_ty(arg); if_chain! { - if match_def_path(cx, def_id, &paths::TRY_FROM); + if cx.tcx.is_diagnostic_item(sym::try_from_fn, def_id); if is_type_diagnostic_item(cx, a, sym::Result); if let ty::Adt(_, args) = a.kind(); if let Some(a_type) = args.types().next(); diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index 87380f14f9a4..bbb5ade8b9f3 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -28,8 +28,8 @@ declare_clippy_lint! { /// know the name of the lint. /// /// ### Known problems - /// Only checks for lints associated using the - /// `declare_lint_pass!`, `impl_lint_pass!`, and `lint_array!` macros. + /// Only checks for lints associated using the `declare_lint_pass!` and + /// `impl_lint_pass!` macros. /// /// ### Example /// ```rust,ignore diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs index 802adbd4d2d5..741f9f54883d 100644 --- a/src/tools/clippy/clippy_utils/src/higher.rs +++ b/src/tools/clippy/clippy_utils/src/higher.rs @@ -457,7 +457,7 @@ pub fn get_vec_init_kind<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) - }; }, ExprKind::Path(QPath::Resolved(_, path)) - if match_def_path(cx, path.res.opt_def_id()?, &paths::DEFAULT_TRAIT_METHOD) + if cx.tcx.is_diagnostic_item(sym::default_fn, path.res.opt_def_id()?) && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(expr), sym::Vec) => { return Some(VecInitKind::Default); diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 13da79fba7e8..64ca2ff78736 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -2076,7 +2076,7 @@ pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool match expr.kind { ExprKind::Closure(&Closure { body, .. }) => is_body_identity_function(cx, cx.tcx.hir().body(body)), - _ => path_def_id(cx, expr).map_or(false, |id| match_def_path(cx, id, &paths::CONVERT_IDENTITY)), + _ => path_def_id(cx, expr).map_or(false, |id| cx.tcx.is_diagnostic_item(sym::convert_identity, id)), } } diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs index 82508bcdb857..eaf590f6ad77 100644 --- a/src/tools/clippy/clippy_utils/src/macros.rs +++ b/src/tools/clippy/clippy_utils/src/macros.rs @@ -228,16 +228,26 @@ pub enum PanicExpn<'a> { impl<'a> PanicExpn<'a> { pub fn parse(expr: &'a Expr<'a>) -> Option { - let ExprKind::Call(callee, [arg, rest @ ..]) = &expr.kind else { + let ExprKind::Call(callee, args) = &expr.kind else { return None; }; let ExprKind::Path(QPath::Resolved(_, path)) = &callee.kind else { return None; }; - let result = match path.segments.last().unwrap().ident.as_str() { + let name = path.segments.last().unwrap().ident.as_str(); + + // This has no argument + if name == "panic_cold_explicit" { + return Some(Self::Empty); + }; + + let [arg, rest @ ..] = args else { + return None; + }; + let result = match name { "panic" if arg.span.ctxt() == expr.span.ctxt() => Self::Empty, "panic" | "panic_str" => Self::Str(arg), - "panic_display" => { + "panic_display" | "panic_cold_display" => { let ExprKind::AddrOf(_, _, e) = &arg.kind else { return None; }; diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs index f04467dc19d3..9dbb4c68d13f 100644 --- a/src/tools/clippy/clippy_utils/src/mir/mod.rs +++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs @@ -30,20 +30,26 @@ pub fn visit_local_usage(locals: &[Local], mir: &Body<'_>, location: Location) - locals.len() ]; - traversal::ReversePostorder::new(mir, location.block).try_fold(init, |usage, (tbb, tdata)| { - // Give up on loops - if tdata.terminator().successors().any(|s| s == location.block) { - return None; - } + traversal::Postorder::new(&mir.basic_blocks, location.block) + .collect::>() + .into_iter() + .rev() + .try_fold(init, |usage, tbb| { + let tdata = &mir.basic_blocks[tbb]; + + // Give up on loops + if tdata.terminator().successors().any(|s| s == location.block) { + return None; + } - let mut v = V { - locals, - location, - results: usage, - }; - v.visit_basic_block_data(tbb, tdata); - Some(v.results) - }) + let mut v = V { + locals, + location, + results: usage, + }; + v.visit_basic_block_data(tbb, tdata); + Some(v.results) + }) } struct V<'a> { diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs index 2fb24b5c7ed9..1f2bb16f459f 100644 --- a/src/tools/clippy/clippy_utils/src/paths.rs +++ b/src/tools/clippy/clippy_utils/src/paths.rs @@ -25,17 +25,12 @@ pub const CORE_ITER_COPIED: [&str; 6] = ["core", "iter", "traits", "iterator", " pub const CORE_ITER_FILTER: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "filter"]; pub const CORE_RESULT_OK_METHOD: [&str; 4] = ["core", "result", "Result", "ok"]; pub const CSTRING_AS_C_STR: [&str; 5] = ["alloc", "ffi", "c_str", "CString", "as_c_str"]; -pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"]; -pub const DEREF_MUT_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "DerefMut", "deref_mut"]; #[cfg(feature = "internal")] pub const EARLY_CONTEXT: [&str; 2] = ["rustc_lint", "EarlyContext"]; #[cfg(feature = "internal")] pub const EARLY_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "EarlyLintPass"]; -pub const EXIT: [&str; 3] = ["std", "process", "exit"]; pub const F32_EPSILON: [&str; 4] = ["core", "f32", "", "EPSILON"]; pub const F64_EPSILON: [&str; 4] = ["core", "f64", "", "EPSILON"]; -pub const FROM_ITERATOR_METHOD: [&str; 6] = ["core", "iter", "traits", "collect", "FromIterator", "from_iter"]; -pub const FROM_STR_METHOD: [&str; 5] = ["core", "str", "traits", "FromStr", "from_str"]; #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates pub const FUTURES_IO_ASYNCREADEXT: [&str; 3] = ["futures_util", "io", "AsyncReadExt"]; #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates @@ -48,8 +43,6 @@ pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"]; #[cfg(feature = "internal")] pub const IDENT_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Ident", "as_str"]; pub const INSERT_STR: [&str; 4] = ["alloc", "string", "String", "insert_str"]; -pub const ITER_EMPTY: [&str; 5] = ["core", "iter", "sources", "empty", "Empty"]; -pub const ITER_ONCE: [&str; 5] = ["core", "iter", "sources", "once", "Once"]; pub const ITERTOOLS_NEXT_TUPLE: [&str; 3] = ["itertools", "Itertools", "next_tuple"]; #[cfg(feature = "internal")] pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"]; @@ -59,10 +52,8 @@ pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"]; pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"]; #[cfg(feature = "internal")] pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"]; -pub const MEM_SWAP: [&str; 3] = ["core", "mem", "swap"]; #[cfg(feature = "internal")] pub const MSRV: [&str; 3] = ["clippy_utils", "msrvs", "Msrv"]; -pub const OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"]; pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString", "as_os_str"]; pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"]; pub const PARKING_LOT_MUTEX_GUARD: [&str; 3] = ["lock_api", "mutex", "MutexGuard"]; @@ -71,28 +62,9 @@ pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 3] = ["lock_api", "rwlock", "Rw pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"]; pub const PATH_MAIN_SEPARATOR: [&str; 3] = ["std", "path", "MAIN_SEPARATOR"]; pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"]; -pub const PEEKABLE: [&str; 5] = ["core", "iter", "adapters", "peekable", "Peekable"]; -pub const PERMISSIONS: [&str; 3] = ["std", "fs", "Permissions"]; #[cfg_attr(not(unix), allow(clippy::invalid_paths))] pub const PERMISSIONS_FROM_MODE: [&str; 6] = ["std", "os", "unix", "fs", "PermissionsExt", "from_mode"]; -pub const PTR_COPY: [&str; 3] = ["core", "intrinsics", "copy"]; -pub const PTR_COPY_NONOVERLAPPING: [&str; 3] = ["core", "intrinsics", "copy_nonoverlapping"]; -pub const PTR_EQ: [&str; 3] = ["core", "ptr", "eq"]; -pub const PTR_SLICE_FROM_RAW_PARTS: [&str; 3] = ["core", "ptr", "slice_from_raw_parts"]; -pub const PTR_SLICE_FROM_RAW_PARTS_MUT: [&str; 3] = ["core", "ptr", "slice_from_raw_parts_mut"]; -pub const PTR_SWAP_NONOVERLAPPING: [&str; 3] = ["core", "ptr", "swap_nonoverlapping"]; -pub const PTR_READ: [&str; 3] = ["core", "ptr", "read"]; -pub const PTR_READ_UNALIGNED: [&str; 3] = ["core", "ptr", "read_unaligned"]; -pub const PTR_READ_VOLATILE: [&str; 3] = ["core", "ptr", "read_volatile"]; -pub const PTR_REPLACE: [&str; 3] = ["core", "ptr", "replace"]; -pub const PTR_SWAP: [&str; 3] = ["core", "ptr", "swap"]; -pub const PTR_UNALIGNED_VOLATILE_LOAD: [&str; 3] = ["core", "intrinsics", "unaligned_volatile_load"]; -pub const PTR_UNALIGNED_VOLATILE_STORE: [&str; 3] = ["core", "intrinsics", "unaligned_volatile_store"]; -pub const PTR_WRITE_BYTES: [&str; 3] = ["core", "intrinsics", "write_bytes"]; pub const PUSH_STR: [&str; 4] = ["alloc", "string", "String", "push_str"]; -pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"]; -pub const REFCELL_REF: [&str; 3] = ["core", "cell", "Ref"]; -pub const REFCELL_REFMUT: [&str; 3] = ["core", "cell", "RefMut"]; pub const REGEX_BUILDER_NEW: [&str; 3] = ["regex", "RegexBuilder", "new"]; pub const REGEX_BYTES_BUILDER_NEW: [&str; 4] = ["regex", "bytes", "RegexBuilder", "new"]; pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "bytes", "Regex", "new"]; @@ -101,21 +73,11 @@ pub const REGEX_NEW: [&str; 3] = ["regex", "Regex", "new"]; pub const REGEX_SET_NEW: [&str; 3] = ["regex", "RegexSet", "new"]; pub const SERDE_DESERIALIZE: [&str; 3] = ["serde", "de", "Deserialize"]; pub const SERDE_DE_VISITOR: [&str; 3] = ["serde", "de", "Visitor"]; -pub const SLICE_FROM_RAW_PARTS: [&str; 4] = ["core", "slice", "raw", "from_raw_parts"]; -pub const SLICE_FROM_RAW_PARTS_MUT: [&str; 4] = ["core", "slice", "raw", "from_raw_parts_mut"]; pub const SLICE_GET: [&str; 4] = ["core", "slice", "", "get"]; pub const SLICE_INTO_VEC: [&str; 4] = ["alloc", "slice", "", "into_vec"]; pub const SLICE_INTO: [&str; 4] = ["core", "slice", "", "iter"]; -pub const SLICE_ITER: [&str; 4] = ["core", "slice", "iter", "Iter"]; -pub const STDERR: [&str; 4] = ["std", "io", "stdio", "stderr"]; -pub const STDOUT: [&str; 4] = ["std", "io", "stdio", "stdout"]; -pub const CONVERT_IDENTITY: [&str; 3] = ["core", "convert", "identity"]; -pub const STD_FS_CREATE_DIR: [&str; 3] = ["std", "fs", "create_dir"]; -pub const STD_IO_LINES: [&str; 3] = ["std", "io", "Lines"]; -pub const STD_IO_SEEK: [&str; 3] = ["std", "io", "Seek"]; pub const STD_IO_SEEK_FROM_CURRENT: [&str; 4] = ["std", "io", "SeekFrom", "Current"]; pub const STD_IO_SEEKFROM_START: [&str; 4] = ["std", "io", "SeekFrom", "Start"]; -pub const STD_PROCESS_COMMAND: [&str; 3] = ["std", "process", "Command"]; pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"]; pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"]; pub const STRING_NEW: [&str; 4] = ["alloc", "string", "String", "new"]; @@ -136,13 +98,11 @@ pub const SYMBOL_TO_IDENT_STRING: [&str; 4] = ["rustc_span", "symbol", "Symbol", pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"]; #[cfg(feature = "internal")] pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"]; -pub const TO_OWNED_METHOD: [&str; 4] = ["alloc", "borrow", "ToOwned", "to_owned"]; pub const TO_STRING_METHOD: [&str; 4] = ["alloc", "string", "ToString", "to_string"]; #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates pub const TOKIO_IO_ASYNCREADEXT: [&str; 5] = ["tokio", "io", "util", "async_read_ext", "AsyncReadExt"]; #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates pub const TOKIO_IO_ASYNCWRITEEXT: [&str; 5] = ["tokio", "io", "util", "async_write_ext", "AsyncWriteExt"]; -pub const TRY_FROM: [&str; 4] = ["core", "convert", "TryFrom", "try_from"]; pub const VEC_AS_MUT_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_mut_slice"]; pub const VEC_AS_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_slice"]; pub const VEC_DEQUE_ITER: [&str; 5] = ["alloc", "collections", "vec_deque", "VecDeque", "iter"]; @@ -150,18 +110,10 @@ pub const VEC_FROM_ELEM: [&str; 3] = ["alloc", "vec", "from_elem"]; pub const VEC_NEW: [&str; 4] = ["alloc", "vec", "Vec", "new"]; pub const VEC_WITH_CAPACITY: [&str; 4] = ["alloc", "vec", "Vec", "with_capacity"]; pub const VEC_RESIZE: [&str; 4] = ["alloc", "vec", "Vec", "resize"]; -pub const WEAK_ARC: [&str; 3] = ["alloc", "sync", "Weak"]; -pub const WEAK_RC: [&str; 3] = ["alloc", "rc", "Weak"]; -pub const PTR_NON_NULL: [&str; 4] = ["core", "ptr", "non_null", "NonNull"]; pub const INSTANT_NOW: [&str; 4] = ["std", "time", "Instant", "now"]; -pub const INSTANT: [&str; 3] = ["std", "time", "Instant"]; pub const VEC_IS_EMPTY: [&str; 4] = ["alloc", "vec", "Vec", "is_empty"]; pub const VEC_POP: [&str; 4] = ["alloc", "vec", "Vec", "pop"]; pub const OPTION_UNWRAP: [&str; 4] = ["core", "option", "Option", "unwrap"]; pub const OPTION_EXPECT: [&str; 4] = ["core", "option", "Option", "expect"]; -pub const FORMATTER: [&str; 3] = ["core", "fmt", "Formatter"]; -pub const DEBUG_STRUCT: [&str; 4] = ["core", "fmt", "builders", "DebugStruct"]; -pub const ORD_CMP: [&str; 4] = ["core", "cmp", "Ord", "cmp"]; #[expect(clippy::invalid_paths)] // not sure why it thinks this, it works so pub const BOOL_THEN: [&str; 4] = ["core", "bool", "", "then"]; -pub const ARRAY_INTO_ITER: [&str; 4] = ["core", "array", "iter", "IntoIter"]; diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 17233058c9c9..55f9cb27ad4d 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -272,6 +272,7 @@ fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &B | ProjectionElem::Downcast(..) | ProjectionElem::Subslice { .. } | ProjectionElem::Deref + | ProjectionElem::Subtype(_) | ProjectionElem::Index(_) => {}, } } diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 604dc76912e6..2d305a63eca1 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -31,7 +31,7 @@ use rustc_trait_selection::traits::{Obligation, ObligationCause}; use std::assert_matches::debug_assert_matches; use std::iter; -use crate::{match_def_path, path_res, paths}; +use crate::{match_def_path, path_res}; mod type_certainty; pub use type_certainty::expr_type_is_certain; @@ -461,10 +461,8 @@ pub fn needs_ordered_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { else if is_type_lang_item(cx, ty, LangItem::OwnedBox) || matches!( get_type_diagnostic_name(cx, ty), - Some(sym::HashSet | sym::Rc | sym::Arc | sym::cstring_type) + Some(sym::HashSet | sym::Rc | sym::Arc | sym::cstring_type | sym::RcWeak | sym::ArcWeak) ) - || match_type(cx, ty, &paths::WEAK_RC) - || match_type(cx, ty, &paths::WEAK_ARC) { // Check all of the generic arguments. if let ty::Adt(_, subs) = ty.kind() { diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.rs b/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.rs index b5ff3a542056..60be29788134 100644 --- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.rs +++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.rs @@ -11,6 +11,6 @@ fn main() { const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"]; const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"]; - // Don't lint, not yet a diagnostic or language item - const DEREF_MUT_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "DerefMut", "deref_mut"]; + // Don't lint, not a diagnostic or language item + const OPS_MOD: [&str; 5] = ["core", "ops"]; } diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr b/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr index 58b1fd92b5dc..076786329cd9 100644 --- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr +++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr @@ -19,8 +19,8 @@ LL | const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"] error: hardcoded path to a diagnostic item --> $DIR/unnecessary_def_path_hardcoded_path.rs:12:43 | -LL | const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const OPS_MOD: [&str; 5] = ["core", "ops"]; + | ^^^^^^^^^^^^^^^ | = help: convert all references to use `sym::deref_method` diff --git a/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr index a52e1fcb9e3a..8b9d159b59c3 100644 --- a/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr +++ b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr @@ -2,7 +2,7 @@ error: this function has too many arguments (11/10) --> $DIR/too_many_arguments.rs:4:1 | LL | fn too_many(p1: u8, p2: u8, p3: u8, p4: u8, p5: u8, p6: u8, p7: u8, p8: u8, p9: u8, p10: u8, p11: u8) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::too-many-arguments` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::too_many_arguments)]` diff --git a/src/tools/clippy/tests/ui/crashes/ice-10645.stderr b/src/tools/clippy/tests/ui/crashes/ice-10645.stderr index fc5347c86cde..7fc62d4fcf85 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-10645.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-10645.stderr @@ -1,8 +1,8 @@ warning: future cannot be sent between threads safely - --> $DIR/ice-10645.rs:5:35 + --> $DIR/ice-10645.rs:5:1 | LL | pub async fn bar<'a, T: 'a>(_: T) {} - | ^ future returned by `bar` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `bar` is not `Send` | note: captured value is not `Send` --> $DIR/ice-10645.rs:5:29 diff --git a/src/tools/clippy/tests/ui/functions.stderr b/src/tools/clippy/tests/ui/functions.stderr index 371ea1612601..4b06cd038899 100644 --- a/src/tools/clippy/tests/ui/functions.stderr +++ b/src/tools/clippy/tests/ui/functions.stderr @@ -2,7 +2,7 @@ error: this function has too many arguments (8/7) --> $DIR/functions.rs:8:1 | LL | fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::too-many-arguments` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::too_many_arguments)]` @@ -17,7 +17,7 @@ LL | | two: u32, ... | LL | | eight: () LL | | ) { - | |__^ + | |_^ error: this function has too many arguments (8/7) --> $DIR/functions.rs:48:5 @@ -29,7 +29,7 @@ error: this function has too many arguments (8/7) --> $DIR/functions.rs:58:5 | LL | fn bad_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this public function might dereference a raw pointer but is not marked `unsafe` --> $DIR/functions.rs:68:34 diff --git a/src/tools/clippy/tests/ui/future_not_send.stderr b/src/tools/clippy/tests/ui/future_not_send.stderr index f43e3c8ff9f7..7ef4947f1d6c 100644 --- a/src/tools/clippy/tests/ui/future_not_send.stderr +++ b/src/tools/clippy/tests/ui/future_not_send.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:7:62 + --> $DIR/future_not_send.rs:7:1 | LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { - | ^^^^ future returned by `private_future` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await --> $DIR/future_not_send.rs:9:20 @@ -23,10 +23,10 @@ LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { = help: to override `-D warnings` add `#[allow(clippy::future_not_send)]` error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:12:42 + --> $DIR/future_not_send.rs:12:1 | LL | pub async fn public_future(rc: Rc<[u8]>) { - | ^ future returned by `public_future` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` | note: future is not `Send` as this value is used across an await --> $DIR/future_not_send.rs:14:20 @@ -39,10 +39,10 @@ LL | async { true }.await; = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:21:63 + --> $DIR/future_not_send.rs:21:1 | LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { - | ^^^^ future returned by `private_future2` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future2` is not `Send` | note: captured value is not `Send` --> $DIR/future_not_send.rs:21:26 @@ -58,10 +58,10 @@ LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { = note: `std::cell::Cell` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:26:43 + --> $DIR/future_not_send.rs:26:1 | LL | pub async fn public_future2(rc: Rc<[u8]>) {} - | ^ future returned by `public_future2` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future2` is not `Send` | note: captured value is not `Send` --> $DIR/future_not_send.rs:26:29 @@ -71,10 +71,10 @@ LL | pub async fn public_future2(rc: Rc<[u8]>) {} = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:38:39 + --> $DIR/future_not_send.rs:38:5 | LL | async fn private_future(&self) -> usize { - | ^^^^^ future returned by `private_future` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await --> $DIR/future_not_send.rs:40:24 @@ -87,10 +87,10 @@ LL | async { true }.await; = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:44:39 + --> $DIR/future_not_send.rs:44:5 | LL | pub async fn public_future(&self) { - | ^ future returned by `public_future` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` | note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` --> $DIR/future_not_send.rs:44:32 @@ -100,10 +100,13 @@ LL | pub async fn public_future(&self) { = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:55:37 + --> $DIR/future_not_send.rs:55:1 | -LL | async fn generic_future(t: T) -> T - | ^ future returned by `generic_future` is not `Send` +LL | / async fn generic_future(t: T) -> T +LL | | +LL | | where +LL | | T: Send, + | |____________^ future returned by `generic_future` is not `Send` | note: future is not `Send` as this value is used across an await --> $DIR/future_not_send.rs:61:20 @@ -115,10 +118,10 @@ LL | async { true }.await; = note: `T` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> $DIR/future_not_send.rs:73:34 + --> $DIR/future_not_send.rs:73:1 | LL | async fn unclear_future(t: T) {} - | ^ future returned by `unclear_future` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `unclear_future` is not `Send` | note: captured value is not `Send` --> $DIR/future_not_send.rs:73:28 diff --git a/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.rs b/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.rs index 1ee048bf7f6c..e1b95aa57760 100644 --- a/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.rs +++ b/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.rs @@ -4,14 +4,18 @@ //@no-rustfix use std::sync::atomic::Ordering; // #[non_exhaustive] enum +fn repeat() -> ! { + panic!() +} + pub fn f(x: Ordering) { match x { Ordering::Relaxed => println!("relaxed"), Ordering::Release => println!("release"), Ordering::Acquire => println!("acquire"), - Ordering::AcqRel | Ordering::SeqCst => panic!(), + Ordering::AcqRel | Ordering::SeqCst => repeat(), #[deny(non_exhaustive_omitted_patterns)] - _ => panic!(), + _ => repeat(), } } @@ -25,8 +29,8 @@ mod f { Ordering::Relaxed => println!("relaxed"), Ordering::Release => println!("release"), Ordering::Acquire => println!("acquire"), - Ordering::AcqRel | Ordering::SeqCst => panic!(), - _ => panic!(), + Ordering::AcqRel | Ordering::SeqCst => repeat(), + _ => repeat(), } } } @@ -38,9 +42,9 @@ pub fn g(x: Ordering) { Ordering::Relaxed => println!("relaxed"), Ordering::Release => println!("release"), Ordering::Acquire => println!("acquire"), - Ordering::AcqRel | Ordering::SeqCst => panic!(), + Ordering::AcqRel | Ordering::SeqCst => repeat(), //~^ ERROR: this match arm has an identical body to the `_` wildcard arm - _ => panic!(), + _ => repeat(), } } @@ -52,9 +56,9 @@ mod g { Ordering::Relaxed => println!("relaxed"), Ordering::Release => println!("release"), Ordering::Acquire => println!("acquire"), - Ordering::AcqRel | Ordering::SeqCst => panic!(), + Ordering::AcqRel | Ordering::SeqCst => repeat(), //~^ ERROR: this match arm has an identical body to the `_` wildcard arm - _ => panic!(), + _ => repeat(), } } } diff --git a/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.stderr b/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.stderr index a039536338bc..ae6b02ab1b50 100644 --- a/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.stderr +++ b/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.stderr @@ -1,29 +1,29 @@ error: this match arm has an identical body to the `_` wildcard arm - --> $DIR/match_same_arms_non_exhaustive.rs:41:9 + --> $DIR/match_same_arms_non_exhaustive.rs:45:9 | -LL | Ordering::AcqRel | Ordering::SeqCst => panic!(), +LL | Ordering::AcqRel | Ordering::SeqCst => repeat(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the arm | = help: or try changing either arm body note: `_` wildcard arm here - --> $DIR/match_same_arms_non_exhaustive.rs:43:9 + --> $DIR/match_same_arms_non_exhaustive.rs:47:9 | -LL | _ => panic!(), +LL | _ => repeat(), | ^^^^^^^^^^^^^ = note: `-D clippy::match-same-arms` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]` error: this match arm has an identical body to the `_` wildcard arm - --> $DIR/match_same_arms_non_exhaustive.rs:55:13 + --> $DIR/match_same_arms_non_exhaustive.rs:59:13 | -LL | Ordering::AcqRel | Ordering::SeqCst => panic!(), +LL | Ordering::AcqRel | Ordering::SeqCst => repeat(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the arm | = help: or try changing either arm body note: `_` wildcard arm here - --> $DIR/match_same_arms_non_exhaustive.rs:57:13 + --> $DIR/match_same_arms_non_exhaustive.rs:61:13 | -LL | _ => panic!(), +LL | _ => repeat(), | ^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/must_use_unit.stderr b/src/tools/clippy/tests/ui/must_use_unit.stderr index e67d9b5b9d8d..f2ee185857d3 100644 --- a/src/tools/clippy/tests/ui/must_use_unit.stderr +++ b/src/tools/clippy/tests/ui/must_use_unit.stderr @@ -4,7 +4,7 @@ error: this unit-returning function has a `#[must_use]` attribute LL | #[must_use] | ----------- help: remove the attribute LL | pub fn must_use_default() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::must-use-unit` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::must_use_unit)]` @@ -23,7 +23,7 @@ error: this unit-returning function has a `#[must_use]` attribute LL | #[must_use = "With note"] | ------------------------- help: remove the attribute LL | pub fn must_use_with_note() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed index 87df1f8cb08f..b17343aa9ba5 100644 --- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed @@ -23,7 +23,7 @@ fn unwrap_option_none() { let _val: u16 = 234; let _val: u16 = 234; let _val: u16 = { 234 }; - let _val: u16 = { 234 }; + let _val: u16 = { 234 }; panic!(); panic!("this always happens"); @@ -31,7 +31,7 @@ fn unwrap_option_none() { 234; 234; { 234 }; - { 234 }; + { 234 }; } fn unwrap_result_ok() { diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr index 013907f59c46..4940091be60a 100644 --- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr @@ -116,7 +116,7 @@ LL | let _val: u16 = None.unwrap_or_else(|| -> u16 { 234 }); help: remove the `None` and `unwrap_or_else()` | LL - let _val: u16 = None.unwrap_or_else(|| -> u16 { 234 }); -LL + let _val: u16 = { 234 }; +LL + let _val: u16 = { 234 }; | error: used `unwrap()` on `None` value @@ -187,7 +187,7 @@ LL | None::.unwrap_or_else(|| -> u16 { 234 }); help: remove the `None` and `unwrap_or_else()` | LL - None::.unwrap_or_else(|| -> u16 { 234 }); -LL + { 234 }; +LL + { 234 }; | error: used `unwrap()` on `Ok` value diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index f253d71e50d3..3f11e4db327e 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -26,6 +26,25 @@ dependencies = [ "memchr", ] +[[package]] +name = "annotate-snippets" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3b9d411ecbaf79885c6df4d75fff75858d5995ff25385657a28af47e82f9c36" +dependencies = [ + "unicode-width", + "yansi-term", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "anyhow" version = "1.0.71" @@ -159,6 +178,25 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "comma" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55b672471b4e9f9e95499ea597ff64941a309b2cdbffcc46f2cc5e2d971fd335" + +[[package]] +name = "console" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.45.0", +] + [[package]] name = "crossbeam-channel" version = "0.5.8" @@ -189,10 +227,10 @@ dependencies = [ ] [[package]] -name = "diff" -version = "0.1.13" +name = "encode_unicode" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "env_logger" @@ -282,6 +320,19 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" +[[package]] +name = "indicatif" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + [[package]] name = "instant" version = "0.1.12" @@ -325,6 +376,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "levenshtein" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" + [[package]] name = "libc" version = "0.2.148" @@ -352,12 +409,12 @@ dependencies = [ [[package]] name = "libloading" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" dependencies = [ "cfg-if", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -463,6 +520,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "object" version = "0.30.3" @@ -484,6 +547,15 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" +[[package]] +name = "pad" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ad9b889f1b12e0b9ee24db044b5129150d5eada288edc800f789928dc8c0e3" +dependencies = [ + "unicode-width", +] + [[package]] name = "parking_lot" version = "0.11.2" @@ -524,12 +596,28 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +[[package]] +name = "portable-atomic" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b" + [[package]] name = "ppv-lite86" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "prettydiff" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ff1fec61082821f8236cf6c0c14e8172b62ce8a72a0eedc30d3b247bb68dc11" +dependencies = [ + "ansi_term", + "pad", +] + [[package]] name = "proc-macro2" version = "1.0.66" @@ -859,18 +947,23 @@ dependencies = [ [[package]] name = "ui_test" -version = "0.11.7" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c21899b59f53717dfad29e4f46e5b21a200a1b6888ab86532a07cfc8b48dd78c" +checksum = "aaf4bf7c184b8dfc7a4d3b90df789b1eb992ee42811cd115f32a7a1eb781058d" dependencies = [ + "annotate-snippets", + "anyhow", "bstr", "cargo-platform", "cargo_metadata", "color-eyre", "colored", + "comma", "crossbeam-channel", - "diff", + "indicatif", "lazy_static", + "levenshtein", + "prettydiff", "regex", "rustc_version", "rustfix", @@ -885,6 +978,12 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + [[package]] name = "valuable" version = "0.1.0" @@ -1059,3 +1158,12 @@ name = "windows_x86_64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "yansi-term" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5c30ade05e61656247b2e334a031dfd0cc466fadef865bdcdea8d537951bf1" +dependencies = [ + "winapi", +] diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index 2ae6f922e3a1..c911a153c137 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -32,11 +32,11 @@ libc = "0.2" [target.'cfg(target_os = "linux")'.dependencies] libffi = "3.2.0" -libloading = "0.7" +libloading = "0.8" [dev-dependencies] colored = "2" -ui_test = "0.11.7" +ui_test = "0.21.1" rustc_version = "0.4" # Features chosen to match those required by env_logger, to avoid rebuilds regex = { version = "1.5.5", default-features = false, features = ["perf", "std"] } diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index f6a023181d85..6127eada2221 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -478,6 +478,8 @@ Moreover, Miri recognizes some environment variables: * `MIRI_TEST_TARGET` (recognized by the test suite and the `./miri` script) indicates which target architecture to test against. `miri` and `cargo miri` accept the `--target` flag for the same purpose. +* `MIRI_TEST_THREADS` (recognized by the test suite): set the number of threads to use for running tests. + By default the number of cores is used. * `MIRI_NO_STD` (recognized by `cargo miri` and the test suite) makes sure that the target's sysroot is built without libstd. This allows testing and running no_std programs. * `RUSTC_BLESS` (recognized by the test suite and `cargo-miri-test/run-test.py`): overwrite all diff --git a/src/tools/miri/bench-cargo-miri/invalidate/Cargo.lock b/src/tools/miri/bench-cargo-miri/invalidate/Cargo.lock new file mode 100644 index 000000000000..7bf23225ea5b --- /dev/null +++ b/src/tools/miri/bench-cargo-miri/invalidate/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "invalidate" +version = "0.1.0" diff --git a/src/tools/miri/bench-cargo-miri/invalidate/Cargo.toml b/src/tools/miri/bench-cargo-miri/invalidate/Cargo.toml new file mode 100644 index 000000000000..14cf0882f0b6 --- /dev/null +++ b/src/tools/miri/bench-cargo-miri/invalidate/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "invalidate" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/tools/miri/bench-cargo-miri/invalidate/src/main.rs b/src/tools/miri/bench-cargo-miri/invalidate/src/main.rs new file mode 100644 index 000000000000..fa8deb851c37 --- /dev/null +++ b/src/tools/miri/bench-cargo-miri/invalidate/src/main.rs @@ -0,0 +1,4 @@ +fn main() { + // The end of the range is just chosen to make the benchmark run for a few seconds. + for _ in 0..200_000 {} +} diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs index 80ce63255826..d655df6d994d 100644 --- a/src/tools/miri/cargo-miri/src/phases.rs +++ b/src/tools/miri/cargo-miri/src/phases.rs @@ -10,7 +10,7 @@ use rustc_version::VersionMeta; use crate::{setup::*, util::*}; -const CARGO_MIRI_HELP: &str = r#"Runs binary crates and tests in Miri +const CARGO_MIRI_HELP: &str = r"Runs binary crates and tests in Miri Usage: cargo miri [subcommand] [...] [--] [...] @@ -31,7 +31,7 @@ Examples: This will print the path to the generated sysroot (and nothing else) on stdout. stderr will still contain progress information about how the build is doing. -"#; +"; fn show_help() { println!("{CARGO_MIRI_HELP}"); diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 458bba9a6166..b60de8344d94 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -42ca6e4e5760a548a6fa858482de6d237f6fb3b8 +bb6c66be3793ac5c738eeac91ecdc4b99388d0b4 diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs index 9b0f13dd62c5..1ef30cb9fad2 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs @@ -1,6 +1,7 @@ use smallvec::SmallVec; use std::fmt; +use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir::interpret::{alloc_range, AllocId, AllocRange, InterpError}; use rustc_span::{Span, SpanData}; use rustc_target::abi::Size; @@ -233,6 +234,12 @@ impl AllocHistory { protectors: SmallVec::new(), } } + + pub fn retain(&mut self, live_tags: &FxHashSet) { + self.invalidations.retain(|event| live_tags.contains(&event.tag)); + self.creations.retain(|event| live_tags.contains(&event.retag.new_tag)); + self.protectors.retain(|event| live_tags.contains(&event.tag)); + } } impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> { diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index a54bd32cd409..e670dcef330c 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -456,6 +456,7 @@ impl Stacks { stack.retain(live_tags); } } + self.history.retain(live_tags); self.modified_since_last_gc = false; } } diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs index d54145dbdc7f..8c90ceba1e4a 100644 --- a/src/tools/miri/src/shims/intrinsics/mod.rs +++ b/src/tools/miri/src/shims/intrinsics/mod.rs @@ -60,7 +60,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } // The rest jumps to `ret` immediately. - this.emulate_intrinsic_by_name(intrinsic_name, args, dest)?; + this.emulate_intrinsic_by_name(intrinsic_name, instance.args, args, dest)?; trace!("{:?}", this.dump_place(dest)); this.go_to_block(ret); @@ -71,6 +71,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn emulate_intrinsic_by_name( &mut self, intrinsic_name: &str, + generic_args: ty::GenericArgsRef<'tcx>, args: &[OpTy<'tcx, Provenance>], dest: &PlaceTy<'tcx, Provenance>, ) -> InterpResult<'tcx> { @@ -80,7 +81,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { return this.emulate_atomic_intrinsic(name, args, dest); } if let Some(name) = intrinsic_name.strip_prefix("simd_") { - return this.emulate_simd_intrinsic(name, args, dest); + return this.emulate_simd_intrinsic(name, generic_args, args, dest); } match intrinsic_name { @@ -324,7 +325,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "fmaf32" => { let [a, b, c] = check_arg_count(args)?; - // FIXME: Using host floats, to work around https://github.com/rust-lang/miri/issues/2468. + // FIXME: Using host floats, to work around https://github.com/rust-lang/rustc_apfloat/issues/11 let a = f32::from_bits(this.read_scalar(a)?.to_u32()?); let b = f32::from_bits(this.read_scalar(b)?.to_u32()?); let c = f32::from_bits(this.read_scalar(c)?.to_u32()?); @@ -334,7 +335,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "fmaf64" => { let [a, b, c] = check_arg_count(args)?; - // FIXME: Using host floats, to work around https://github.com/rust-lang/miri/issues/2468. + // FIXME: Using host floats, to work around https://github.com/rust-lang/rustc_apfloat/issues/11 let a = f64::from_bits(this.read_scalar(a)?.to_u64()?); let b = f64::from_bits(this.read_scalar(b)?.to_u64()?); let c = f64::from_bits(this.read_scalar(c)?.to_u64()?); diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs index de0c58de44fd..200f37efa27b 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/shims/intrinsics/simd.rs @@ -12,6 +12,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn emulate_simd_intrinsic( &mut self, intrinsic_name: &str, + generic_args: ty::GenericArgsRef<'tcx>, args: &[OpTy<'tcx, Provenance>], dest: &PlaceTy<'tcx, Provenance>, ) -> InterpResult<'tcx> { @@ -488,6 +489,44 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_immediate(*val, &dest)?; } } + "shuffle_generic" => { + let [left, right] = check_arg_count(args)?; + let (left, left_len) = this.operand_to_simd(left)?; + let (right, right_len) = this.operand_to_simd(right)?; + let (dest, dest_len) = this.place_to_simd(dest)?; + + let index = generic_args[2] + .expect_const() + .eval(*this.tcx, this.param_env(), Some(this.tcx.span)) + .unwrap() + .unwrap_branch(); + let index_len = index.len(); + + assert_eq!(left_len, right_len); + assert_eq!(index_len as u64, dest_len); + + for i in 0..dest_len { + let src_index: u64 = index[usize::try_from(i).unwrap()] + .unwrap_leaf() + .try_to_u32() + .unwrap() + .into(); + let dest = this.project_index(&dest, i)?; + + let val = if src_index < left_len { + this.read_immediate(&this.project_index(&left, src_index)?)? + } else if src_index < left_len.checked_add(right_len).unwrap() { + let right_idx = src_index.checked_sub(left_len).unwrap(); + this.read_immediate(&this.project_index(&right, right_idx)?)? + } else { + span_bug!( + this.cur_span(), + "simd_shuffle index {src_index} is out of bounds for 2 vectors of size {left_len}", + ); + }; + this.write_immediate(*val, &dest)?; + } + } "shuffle" => { let [left, right, index] = check_arg_count(args)?; let (left, left_len) = this.operand_to_simd(left)?; diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index fbfe00e03dbc..7c280109cb01 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -9,6 +9,8 @@ use shims::foreign_items::EmulateByNameResult; mod sse; mod sse2; +mod sse3; +mod ssse3; impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: @@ -88,6 +90,16 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: this, link_name, abi, args, dest, ); } + name if name.starts_with("sse3.") => { + return sse3::EvalContextExt::emulate_x86_sse3_intrinsic( + this, link_name, abi, args, dest, + ); + } + name if name.starts_with("ssse3.") => { + return ssse3::EvalContextExt::emulate_x86_ssse3_intrinsic( + this, link_name, abi, args, dest, + ); + } _ => return Ok(EmulateByNameResult::NotSupported), } Ok(EmulateByNameResult::NeedsJumping) @@ -286,3 +298,44 @@ fn bin_op_simd_float_all<'tcx, F: rustc_apfloat::Float>( Ok(()) } + +/// Horizontaly performs `which` operation on adjacent values of +/// `left` and `right` SIMD vectors and stores the result in `dest`. +fn horizontal_bin_op<'tcx>( + this: &mut crate::MiriInterpCx<'_, 'tcx>, + which: mir::BinOp, + saturating: bool, + left: &OpTy<'tcx, Provenance>, + right: &OpTy<'tcx, Provenance>, + dest: &PlaceTy<'tcx, Provenance>, +) -> InterpResult<'tcx, ()> { + let (left, left_len) = this.operand_to_simd(left)?; + let (right, right_len) = this.operand_to_simd(right)?; + let (dest, dest_len) = this.place_to_simd(dest)?; + + assert_eq!(dest_len, left_len); + assert_eq!(dest_len, right_len); + assert_eq!(dest_len % 2, 0); + + let middle = dest_len / 2; + for i in 0..dest_len { + // `i` is the index in `dest` + // `j` is the index of the 2-item chunk in `src` + let (j, src) = + if i < middle { (i, &left) } else { (i.checked_sub(middle).unwrap(), &right) }; + // `base_i` is the index of the first item of the 2-item chunk in `src` + let base_i = j.checked_mul(2).unwrap(); + let lhs = this.read_immediate(&this.project_index(src, base_i)?)?; + let rhs = this.read_immediate(&this.project_index(src, base_i.checked_add(1).unwrap())?)?; + + let res = if saturating { + Immediate::from(this.saturating_arith(which, &lhs, &rhs)?) + } else { + *this.wrapping_binary_op(which, &lhs, &rhs)? + }; + + this.write_immediate(res, &this.project_index(&dest, i)?)?; + } + + Ok(()) +} diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index 2ca882167bf4..2ef6a9b59ede 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -82,6 +82,42 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: this.write_immediate(*res, &dest)?; } } + // Used to implement the _mm_madd_epi16 function. + // Multiplies packed signed 16-bit integers in `left` and `right`, producing + // intermediate signed 32-bit integers. Horizontally add adjacent pairs of + // intermediate 32-bit integers, and pack the results in `dest`. + "pmadd.wd" => { + let [left, right] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + + let (left, left_len) = this.operand_to_simd(left)?; + let (right, right_len) = this.operand_to_simd(right)?; + let (dest, dest_len) = this.place_to_simd(dest)?; + + assert_eq!(left_len, right_len); + assert_eq!(dest_len.checked_mul(2).unwrap(), left_len); + + for i in 0..dest_len { + let j1 = i.checked_mul(2).unwrap(); + let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_i16()?; + let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i16()?; + + let j2 = j1.checked_add(1).unwrap(); + let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_i16()?; + let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i16()?; + + let dest = this.project_index(&dest, i)?; + + // Multiplications are i16*i16->i32, which will not overflow. + let mul1 = i32::from(left1).checked_mul(right1.into()).unwrap(); + let mul2 = i32::from(left2).checked_mul(right2.into()).unwrap(); + // However, this addition can overflow in the most extreme case + // (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000 + let res = mul1.wrapping_add(mul2); + + this.write_scalar(Scalar::from_i32(res), &dest)?; + } + } // Used to implement the _mm_mulhi_epi16 and _mm_mulhi_epu16 functions. "pmulh.w" | "pmulhu.w" => { let [left, right] = diff --git a/src/tools/miri/src/shims/x86/sse3.rs b/src/tools/miri/src/shims/x86/sse3.rs new file mode 100644 index 000000000000..f5c30a521fa8 --- /dev/null +++ b/src/tools/miri/src/shims/x86/sse3.rs @@ -0,0 +1,90 @@ +use rustc_middle::mir; +use rustc_span::Symbol; +use rustc_target::abi::Align; +use rustc_target::spec::abi::Abi; + +use super::horizontal_bin_op; +use crate::*; +use shims::foreign_items::EmulateByNameResult; + +impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} +pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: + crate::MiriInterpCxExt<'mir, 'tcx> +{ + fn emulate_x86_sse3_intrinsic( + &mut self, + link_name: Symbol, + abi: Abi, + args: &[OpTy<'tcx, Provenance>], + dest: &PlaceTy<'tcx, Provenance>, + ) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> { + let this = self.eval_context_mut(); + // Prefix should have already been checked. + let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse3.").unwrap(); + + match unprefixed_name { + // Used to implement the _mm_addsub_ps and _mm_addsub_pd functions. + // Alternatingly add and subtract floating point (f32 or f64) from + // `left` and `right` + "addsub.ps" | "addsub.pd" => { + let [left, right] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + + let (left, left_len) = this.operand_to_simd(left)?; + let (right, right_len) = this.operand_to_simd(right)?; + let (dest, dest_len) = this.place_to_simd(dest)?; + + assert_eq!(dest_len, left_len); + assert_eq!(dest_len, right_len); + + for i in 0..dest_len { + let left = this.read_immediate(&this.project_index(&left, i)?)?; + let right = this.read_immediate(&this.project_index(&right, i)?)?; + let dest = this.project_index(&dest, i)?; + + // Even elements are subtracted and odd elements are added. + let op = if i % 2 == 0 { mir::BinOp::Sub } else { mir::BinOp::Add }; + let res = this.wrapping_binary_op(op, &left, &right)?; + + this.write_immediate(*res, &dest)?; + } + } + // Used to implement the _mm_h{add,sub}_p{s,d} functions. + // Horizontally add/subtract adjacent floating point values + // in `left` and `right`. + "hadd.ps" | "hadd.pd" | "hsub.ps" | "hsub.pd" => { + let [left, right] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + + let which = match unprefixed_name { + "hadd.ps" | "hadd.pd" => mir::BinOp::Add, + "hsub.ps" | "hsub.pd" => mir::BinOp::Sub, + _ => unreachable!(), + }; + + horizontal_bin_op(this, which, /*saturating*/ false, left, right, dest)?; + } + // Used to implement the _mm_lddqu_si128 function. + // Reads a 128-bit vector from an unaligned pointer. This intrinsic + // is expected to perform better than a regular unaligned read when + // the data crosses a cache line, but for Miri this is just a regular + // unaligned read. + "ldu.dq" => { + let [src_ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let src_ptr = this.read_pointer(src_ptr)?; + let dest = dest.force_mplace(this)?; + + this.mem_copy( + src_ptr, + Align::ONE, + dest.ptr(), + Align::ONE, + dest.layout.size, + /*nonoverlapping*/ true, + )?; + } + _ => return Ok(EmulateByNameResult::NotSupported), + } + Ok(EmulateByNameResult::NeedsJumping) + } +} diff --git a/src/tools/miri/src/shims/x86/ssse3.rs b/src/tools/miri/src/shims/x86/ssse3.rs new file mode 100644 index 000000000000..b01546722346 --- /dev/null +++ b/src/tools/miri/src/shims/x86/ssse3.rs @@ -0,0 +1,199 @@ +use rustc_middle::mir; +use rustc_span::Symbol; +use rustc_target::spec::abi::Abi; + +use super::horizontal_bin_op; +use crate::*; +use shims::foreign_items::EmulateByNameResult; + +impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} +pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: + crate::MiriInterpCxExt<'mir, 'tcx> +{ + fn emulate_x86_ssse3_intrinsic( + &mut self, + link_name: Symbol, + abi: Abi, + args: &[OpTy<'tcx, Provenance>], + dest: &PlaceTy<'tcx, Provenance>, + ) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> { + let this = self.eval_context_mut(); + // Prefix should have already been checked. + let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.ssse3.").unwrap(); + + match unprefixed_name { + // Used to implement the _mm_abs_epi{8,16,32} functions. + // Calculates the absolute value of packed 8/16/32-bit integers. + "pabs.b.128" | "pabs.w.128" | "pabs.d.128" => { + let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + + let (op, op_len) = this.operand_to_simd(op)?; + let (dest, dest_len) = this.place_to_simd(dest)?; + + assert_eq!(op_len, dest_len); + + for i in 0..dest_len { + let op = this.read_scalar(&this.project_index(&op, i)?)?; + let dest = this.project_index(&dest, i)?; + + // Converting to a host "i128" works since the input is always signed. + let res = op.to_int(dest.layout.size)?.unsigned_abs(); + + this.write_scalar(Scalar::from_uint(res, dest.layout.size), &dest)?; + } + } + // Used to implement the _mm_shuffle_epi8 intrinsic. + // Shuffles bytes from `left` using `right` as pattern. + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shuffle_epi8 + "pshuf.b.128" => { + let [left, right] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + + let (left, left_len) = this.operand_to_simd(left)?; + let (right, right_len) = this.operand_to_simd(right)?; + let (dest, dest_len) = this.place_to_simd(dest)?; + + assert_eq!(dest_len, left_len); + assert_eq!(dest_len, right_len); + + for i in 0..dest_len { + let right = this.read_scalar(&this.project_index(&right, i)?)?.to_u8()?; + let dest = this.project_index(&dest, i)?; + + let res = if right & 0x80 == 0 { + let j = right % 16; // index wraps around + this.read_scalar(&this.project_index(&left, j.into())?)? + } else { + // If the highest bit in `right` is 1, write zero. + Scalar::from_u8(0) + }; + + this.write_scalar(res, &dest)?; + } + } + // Used to implement the _mm_h{add,adds,sub}_epi{16,32} functions. + // Horizontally add / add with saturation / subtract adjacent 16/32-bit + // integer values in `left` and `right`. + "phadd.w.128" | "phadd.sw.128" | "phadd.d.128" | "phsub.w.128" | "phsub.sw.128" + | "phsub.d.128" => { + let [left, right] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + + let (which, saturating) = match unprefixed_name { + "phadd.w.128" | "phadd.d.128" => (mir::BinOp::Add, false), + "phadd.sw.128" => (mir::BinOp::Add, true), + "phsub.w.128" | "phsub.d.128" => (mir::BinOp::Sub, false), + "phsub.sw.128" => (mir::BinOp::Sub, true), + _ => unreachable!(), + }; + + horizontal_bin_op(this, which, saturating, left, right, dest)?; + } + // Used to implement the _mm_maddubs_epi16 function. + // Multiplies packed 8-bit unsigned integers from `left` and packed + // signed 8-bit integers from `right` into 16-bit signed integers. Then, + // the saturating sum of the products with indices `2*i` and `2*i+1` + // produces the output at index `i`. + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_maddubs_epi16 + "pmadd.ub.sw.128" => { + let [left, right] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + + let (left, left_len) = this.operand_to_simd(left)?; + let (right, right_len) = this.operand_to_simd(right)?; + let (dest, dest_len) = this.place_to_simd(dest)?; + + assert_eq!(left_len, right_len); + assert_eq!(dest_len.checked_mul(2).unwrap(), left_len); + + for i in 0..dest_len { + let j1 = i.checked_mul(2).unwrap(); + let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_u8()?; + let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i8()?; + + let j2 = j1.checked_add(1).unwrap(); + let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_u8()?; + let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i8()?; + + let dest = this.project_index(&dest, i)?; + + // Multiplication of a u8 and an i8 into an i16 cannot overflow. + let mul1 = i16::from(left1).checked_mul(right1.into()).unwrap(); + let mul2 = i16::from(left2).checked_mul(right2.into()).unwrap(); + let res = mul1.saturating_add(mul2); + + this.write_scalar(Scalar::from_i16(res), &dest)?; + } + } + // Used to implement the _mm_mulhrs_epi16 function. + // Multiplies packed 16-bit signed integer values, truncates the 32-bit + // product to the 18 most significant bits by right-shifting, and then + // divides the 18-bit value by 2 (rounding to nearest) by first adding + // 1 and then taking the bits `1..=16`. + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mulhrs_epi16 + "pmul.hr.sw.128" => { + let [left, right] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + + let (left, left_len) = this.operand_to_simd(left)?; + let (right, right_len) = this.operand_to_simd(right)?; + let (dest, dest_len) = this.place_to_simd(dest)?; + + assert_eq!(dest_len, left_len); + assert_eq!(dest_len, right_len); + + for i in 0..dest_len { + let left = this.read_scalar(&this.project_index(&left, i)?)?.to_i16()?; + let right = this.read_scalar(&this.project_index(&right, i)?)?.to_i16()?; + let dest = this.project_index(&dest, i)?; + + let res = (i32::from(left).checked_mul(right.into()).unwrap() >> 14) + .checked_add(1) + .unwrap() + >> 1; + + // The result of this operation can overflow a signed 16-bit integer. + // When `left` and `right` are -0x8000, the result is 0x8000. + #[allow(clippy::cast_possible_truncation)] + let res = res as i16; + + this.write_scalar(Scalar::from_i16(res), &dest)?; + } + } + // Used to implement the _mm_sign_epi{8,16,32} functions. + // Negates elements from `left` when the corresponding element in + // `right` is negative. If an element from `right` is zero, zero + // is writen to the corresponding output element. + // Basically, we multiply `left` with `right.signum()`. + "psign.b.128" | "psign.w.128" | "psign.d.128" => { + let [left, right] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + + let (left, left_len) = this.operand_to_simd(left)?; + let (right, right_len) = this.operand_to_simd(right)?; + let (dest, dest_len) = this.place_to_simd(dest)?; + + assert_eq!(dest_len, left_len); + assert_eq!(dest_len, right_len); + + for i in 0..dest_len { + let dest = this.project_index(&dest, i)?; + let left = this.read_immediate(&this.project_index(&left, i)?)?; + let right = this + .read_scalar(&this.project_index(&right, i)?)? + .to_int(dest.layout.size)?; + + let res = this.wrapping_binary_op( + mir::BinOp::Mul, + &left, + &ImmTy::from_int(right.signum(), dest.layout), + )?; + + this.write_immediate(*res, &dest)?; + } + } + _ => return Ok(EmulateByNameResult::NotSupported), + } + Ok(EmulateByNameResult::NeedsJumping) + } +} diff --git a/src/tools/miri/tests/compiletest.rs b/src/tools/miri/tests/compiletest.rs index 78dd3df01ec5..035846f0ef95 100644 --- a/src/tools/miri/tests/compiletest.rs +++ b/src/tools/miri/tests/compiletest.rs @@ -1,10 +1,11 @@ use colored::*; use regex::bytes::Regex; use std::ffi::OsString; +use std::num::NonZeroUsize; use std::path::{Path, PathBuf}; use std::{env, process::Command}; use ui_test::{color_eyre::Result, Config, Match, Mode, OutputConflictHandling}; -use ui_test::{status_emitter, CommandBuilder}; +use ui_test::{status_emitter, CommandBuilder, Format, RustfixMode}; fn miri_path() -> PathBuf { PathBuf::from(option_env!("MIRI").unwrap_or(env!("CARGO_BIN_EXE_miri"))) @@ -78,26 +79,18 @@ fn test_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) -> program.args.push(flag); } - let bless = env::var_os("RUSTC_BLESS").is_some_and(|v| v != "0"); - let skip_ui_checks = env::var_os("MIRI_SKIP_UI_CHECKS").is_some(); - - let output_conflict_handling = match (bless, skip_ui_checks) { - (false, false) => OutputConflictHandling::Error("./miri test --bless".into()), - (true, false) => OutputConflictHandling::Bless, - (false, true) => OutputConflictHandling::Ignore, - (true, true) => panic!("cannot use RUSTC_BLESS and MIRI_SKIP_UI_CHECKS at the same time"), - }; - let mut config = Config { target: Some(target.to_owned()), stderr_filters: STDERR.clone(), stdout_filters: STDOUT.clone(), mode, program, - output_conflict_handling, out_dir: PathBuf::from(std::env::var_os("CARGO_TARGET_DIR").unwrap()).join("ui"), edition: Some("2021".into()), - ..Config::rustc(path.into()) + threads: std::env::var("MIRI_TEST_THREADS") + .ok() + .map(|threads| NonZeroUsize::new(threads.parse().unwrap()).unwrap()), + ..Config::rustc(path) }; let use_std = env::var_os("MIRI_NO_STD").is_none(); @@ -120,51 +113,32 @@ fn test_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) -> } fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> Result<()> { - let config = test_config(target, path, mode, with_dependencies); + let mut config = test_config(target, path, mode, with_dependencies); // Handle command-line arguments. - let mut after_dashdash = false; - let mut quiet = false; - let filters = std::env::args() - .skip(1) - .filter(|arg| { - if after_dashdash { - // Just propagate everything. - return true; - } - match &**arg { - "--quiet" => { - quiet = true; - false - } - "--" => { - after_dashdash = true; - false - } - s if s.starts_with('-') => { - panic!("unknown compiletest flag `{s}`"); - } - _ => true, - } - }) - .collect::>(); + let args = ui_test::Args::test()?; + let default_bless = env::var_os("RUSTC_BLESS").is_some_and(|v| v != "0"); + config.with_args(&args, default_bless); + if let OutputConflictHandling::Error(msg) = &mut config.output_conflict_handling { + *msg = "./miri test --bless".into(); + } + if env::var_os("MIRI_SKIP_UI_CHECKS").is_some() { + assert!(!default_bless, "cannot use RUSTC_BLESS and MIRI_SKIP_UI_CHECKS at the same time"); + config.output_conflict_handling = OutputConflictHandling::Ignore; + } eprintln!(" Compiler: {}", config.program.display()); ui_test::run_tests_generic( - config, + // Only run one test suite. In the future we can add all test suites to one `Vec` and run + // them all at once, making best use of systems with high parallelism. + vec![config], // The files we're actually interested in (all `.rs` files). - |path| { - path.extension().is_some_and(|ext| ext == "rs") - && (filters.is_empty() - || filters.iter().any(|f| path.display().to_string().contains(f))) - }, + ui_test::default_file_filter, // This could be used to overwrite the `Config` on a per-test basis. - |_, _| None, + |_, _, _| {}, ( - if quiet { - Box::::default() - as Box - } else { - Box::new(status_emitter::Text) + match args.format { + Format::Terse => status_emitter::Text::quiet(), + Format::Pretty => status_emitter::Text::verbose(), }, status_emitter::Gha:: { name: format!("{mode:?} {path} ({target})"), @@ -205,8 +179,6 @@ regexes! { r" +at (.*\.rs)" => " at $1", // erase generics in backtraces "([0-9]+: .*)::<.*>" => "$1", - // erase addresses in backtraces - "([0-9]+: ) +0x[0-9a-f]+ - (.*)" => "$1$2", // erase long hexadecimals r"0x[0-9a-fA-F]+[0-9a-fA-F]{2,2}" => "$$HEX", // erase specific alignments @@ -218,7 +190,7 @@ regexes! { // Windows file paths r"\\" => "/", // erase Rust stdlib path - "[^ `]*/(rust[^/]*|checkout)/library/" => "RUSTLIB/", + "[^ \n`]*/(rust[^/]*|checkout)/library/" => "RUSTLIB/", // erase platform file paths "sys/[a-z]+/" => "sys/PLATFORM/", // erase paths into the crate registry @@ -269,11 +241,22 @@ fn main() -> Result<()> { ui(Mode::Pass, "tests/pass", &target, WithoutDependencies)?; ui(Mode::Pass, "tests/pass-dep", &target, WithDependencies)?; ui(Mode::Panic, "tests/panic", &target, WithDependencies)?; - ui(Mode::Fail { require_patterns: true }, "tests/fail", &target, WithDependencies)?; + ui( + Mode::Fail { require_patterns: true, rustfix: RustfixMode::Disabled }, + "tests/fail", + &target, + WithoutDependencies, + )?; + ui( + Mode::Fail { require_patterns: true, rustfix: RustfixMode::Disabled }, + "tests/fail-dep", + &target, + WithDependencies, + )?; if cfg!(target_os = "linux") { ui(Mode::Pass, "tests/extern-so/pass", &target, WithoutDependencies)?; ui( - Mode::Fail { require_patterns: true }, + Mode::Fail { require_patterns: true, rustfix: RustfixMode::Disabled }, "tests/extern-so/fail", &target, WithoutDependencies, @@ -285,11 +268,17 @@ fn main() -> Result<()> { fn run_dep_mode(target: String, mut args: impl Iterator) -> Result<()> { let path = args.next().expect("./miri run-dep must be followed by a file name"); - let mut config = test_config(&target, "", Mode::Yolo, /* with dependencies */ true); + let mut config = test_config( + &target, + "", + Mode::Yolo { rustfix: RustfixMode::Disabled }, + /* with dependencies */ true, + ); config.program.args.clear(); // We want to give the user full control over flags - config.build_dependencies_and_link_them()?; + let dep_args = config.build_dependencies()?; let mut cmd = config.program.build(&config.out_dir); + cmd.args(dep_args); cmd.arg(path); diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.rs similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.rs rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.rs diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.stderr similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.stderr rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.stderr diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.rs rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.stderr rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.rs rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.stderr rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_detached.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.rs similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_join_detached.rs rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.rs diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_detached.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.stderr similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_join_detached.stderr rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.stderr diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_joined.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.rs similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_join_joined.rs rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.rs diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_joined.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.stderr similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_join_joined.stderr rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.stderr diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_main.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.rs similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_join_main.rs rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.rs diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_main.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_join_main.stderr rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_multiple.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.rs similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_join_multiple.rs rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.rs diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_multiple.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_join_multiple.stderr rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_self.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.rs similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_join_self.rs rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.rs diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_self.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr similarity index 100% rename from src/tools/miri/tests/fail/concurrency/libc_pthread_join_self.stderr rename to src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr diff --git a/src/tools/miri/tests/fail/concurrency/unwind_top_of_stack.rs b/src/tools/miri/tests/fail-dep/concurrency/unwind_top_of_stack.rs similarity index 100% rename from src/tools/miri/tests/fail/concurrency/unwind_top_of_stack.rs rename to src/tools/miri/tests/fail-dep/concurrency/unwind_top_of_stack.rs diff --git a/src/tools/miri/tests/fail/concurrency/unwind_top_of_stack.stderr b/src/tools/miri/tests/fail-dep/concurrency/unwind_top_of_stack.stderr similarity index 100% rename from src/tools/miri/tests/fail/concurrency/unwind_top_of_stack.stderr rename to src/tools/miri/tests/fail-dep/concurrency/unwind_top_of_stack.stderr diff --git a/src/tools/miri/tests/fail/shims/fs/close_stdout.rs b/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/fs/close_stdout.rs rename to src/tools/miri/tests/fail-dep/shims/fs/close_stdout.rs diff --git a/src/tools/miri/tests/fail/shims/fs/close_stdout.stderr b/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/fs/close_stdout.stderr rename to src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr diff --git a/src/tools/miri/tests/fail/shims/fs/isolated_stdin.rs b/src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/fs/isolated_stdin.rs rename to src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.rs diff --git a/src/tools/miri/tests/fail/shims/fs/isolated_stdin.stderr b/src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/fs/isolated_stdin.stderr rename to src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.stderr diff --git a/src/tools/miri/tests/fail/shims/fs/mkstemp_immutable_arg.rs b/src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/fs/mkstemp_immutable_arg.rs rename to src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.rs diff --git a/src/tools/miri/tests/fail/shims/fs/mkstemp_immutable_arg.stderr b/src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/fs/mkstemp_immutable_arg.stderr rename to src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.stderr diff --git a/src/tools/miri/tests/fail/shims/fs/read_from_stdout.rs b/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/fs/read_from_stdout.rs rename to src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.rs diff --git a/src/tools/miri/tests/fail/shims/fs/read_from_stdout.stderr b/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/fs/read_from_stdout.stderr rename to src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr diff --git a/src/tools/miri/tests/fail/shims/fs/unix_open_missing_required_mode.rs b/src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/fs/unix_open_missing_required_mode.rs rename to src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.rs diff --git a/src/tools/miri/tests/fail/shims/fs/unix_open_missing_required_mode.stderr b/src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/fs/unix_open_missing_required_mode.stderr rename to src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.stderr diff --git a/src/tools/miri/tests/fail/shims/fs/write_to_stdin.rs b/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/fs/write_to_stdin.rs rename to src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.rs diff --git a/src/tools/miri/tests/fail/shims/fs/write_to_stdin.stderr b/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/fs/write_to_stdin.stderr rename to src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr diff --git a/src/tools/miri/tests/fail/shims/memchr_null.rs b/src/tools/miri/tests/fail-dep/shims/memchr_null.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/memchr_null.rs rename to src/tools/miri/tests/fail-dep/shims/memchr_null.rs diff --git a/src/tools/miri/tests/fail/shims/memchr_null.stderr b/src/tools/miri/tests/fail-dep/shims/memchr_null.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/memchr_null.stderr rename to src/tools/miri/tests/fail-dep/shims/memchr_null.stderr diff --git a/src/tools/miri/tests/fail/shims/memcmp_null.rs b/src/tools/miri/tests/fail-dep/shims/memcmp_null.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/memcmp_null.rs rename to src/tools/miri/tests/fail-dep/shims/memcmp_null.rs diff --git a/src/tools/miri/tests/fail/shims/memcmp_null.stderr b/src/tools/miri/tests/fail-dep/shims/memcmp_null.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/memcmp_null.stderr rename to src/tools/miri/tests/fail-dep/shims/memcmp_null.stderr diff --git a/src/tools/miri/tests/fail/shims/memcmp_zero.rs b/src/tools/miri/tests/fail-dep/shims/memcmp_zero.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/memcmp_zero.rs rename to src/tools/miri/tests/fail-dep/shims/memcmp_zero.rs diff --git a/src/tools/miri/tests/fail/shims/memcmp_zero.stderr b/src/tools/miri/tests/fail-dep/shims/memcmp_zero.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/memcmp_zero.stderr rename to src/tools/miri/tests/fail-dep/shims/memcmp_zero.stderr diff --git a/src/tools/miri/tests/fail/shims/memcpy_zero.rs b/src/tools/miri/tests/fail-dep/shims/memcpy_zero.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/memcpy_zero.rs rename to src/tools/miri/tests/fail-dep/shims/memcpy_zero.rs diff --git a/src/tools/miri/tests/fail/shims/memcpy_zero.stderr b/src/tools/miri/tests/fail-dep/shims/memcpy_zero.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/memcpy_zero.stderr rename to src/tools/miri/tests/fail-dep/shims/memcpy_zero.stderr diff --git a/src/tools/miri/tests/fail/shims/memrchr_null.rs b/src/tools/miri/tests/fail-dep/shims/memrchr_null.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/memrchr_null.rs rename to src/tools/miri/tests/fail-dep/shims/memrchr_null.rs diff --git a/src/tools/miri/tests/fail/shims/memrchr_null.stderr b/src/tools/miri/tests/fail-dep/shims/memrchr_null.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/memrchr_null.stderr rename to src/tools/miri/tests/fail-dep/shims/memrchr_null.stderr diff --git a/src/tools/miri/tests/fail/shims/mmap_invalid_dealloc.rs b/src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/mmap_invalid_dealloc.rs rename to src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.rs diff --git a/src/tools/miri/tests/fail/shims/mmap_invalid_dealloc.stderr b/src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/mmap_invalid_dealloc.stderr rename to src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.stderr diff --git a/src/tools/miri/tests/fail/shims/mmap_use_after_munmap.rs b/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/mmap_use_after_munmap.rs rename to src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.rs diff --git a/src/tools/miri/tests/fail/shims/mmap_use_after_munmap.stderr b/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/mmap_use_after_munmap.stderr rename to src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.stderr diff --git a/src/tools/miri/tests/fail/shims/munmap.rs b/src/tools/miri/tests/fail-dep/shims/munmap.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/munmap.rs rename to src/tools/miri/tests/fail-dep/shims/munmap.rs diff --git a/src/tools/miri/tests/fail/shims/munmap.stderr b/src/tools/miri/tests/fail-dep/shims/munmap.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/munmap.stderr rename to src/tools/miri/tests/fail-dep/shims/munmap.stderr diff --git a/src/tools/miri/tests/fail/shims/munmap_partial.rs b/src/tools/miri/tests/fail-dep/shims/munmap_partial.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/munmap_partial.rs rename to src/tools/miri/tests/fail-dep/shims/munmap_partial.rs diff --git a/src/tools/miri/tests/fail/shims/munmap_partial.stderr b/src/tools/miri/tests/fail-dep/shims/munmap_partial.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/munmap_partial.stderr rename to src/tools/miri/tests/fail-dep/shims/munmap_partial.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_cond_double_destroy.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_cond_double_destroy.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_cond_double_destroy.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_cond_double_destroy.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_condattr_double_destroy.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_condattr_double_destroy.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_condattr_double_destroy.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_condattr_double_destroy.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_NULL_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_NULL_deadlock.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_NULL_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_NULL_deadlock.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_deadlock.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_deadlock.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_default_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_default_deadlock.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_default_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_default_deadlock.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_destroy_locked.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_destroy_locked.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_destroy_locked.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_destroy_locked.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_double_destroy.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_double_destroy.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_double_destroy.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_double_destroy.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_deadlock.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_deadlock.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_wrong_owner.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_wrong_owner.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_wrong_owner.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutexattr_double_destroy.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutexattr_double_destroy.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutexattr_double_destroy.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutexattr_double_destroy.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_read_locked.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_read_locked.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_read_locked.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_read_locked.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_write_locked.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_write_locked.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_write_locked.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_write_locked.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_double_destroy.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_double_destroy.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_double_destroy.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_double_destroy.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_wrong_owner.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_wrong_owner.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_wrong_owner.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_unlock_unlocked.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_unlock_unlocked.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_unlock_unlocked.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_unlock_unlocked.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_wrong_owner.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.rs similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_wrong_owner.rs rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.rs diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.stderr similarity index 100% rename from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_wrong_owner.stderr rename to src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.stderr diff --git a/src/tools/miri/tests/fail/tokio/sleep.rs b/src/tools/miri/tests/fail-dep/tokio/sleep.rs similarity index 100% rename from src/tools/miri/tests/fail/tokio/sleep.rs rename to src/tools/miri/tests/fail-dep/tokio/sleep.rs diff --git a/src/tools/miri/tests/fail/tokio/sleep.stderr b/src/tools/miri/tests/fail-dep/tokio/sleep.stderr similarity index 100% rename from src/tools/miri/tests/fail/tokio/sleep.stderr rename to src/tools/miri/tests/fail-dep/tokio/sleep.stderr diff --git a/src/tools/miri/tests/fail/unsupported_incomplete_function.rs b/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.rs similarity index 100% rename from src/tools/miri/tests/fail/unsupported_incomplete_function.rs rename to src/tools/miri/tests/fail-dep/unsupported_incomplete_function.rs diff --git a/src/tools/miri/tests/fail/unsupported_incomplete_function.stderr b/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr similarity index 100% rename from src/tools/miri/tests/fail/unsupported_incomplete_function.stderr rename to src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.rs b/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.rs index 5cd12959ca40..8d3173da400f 100644 --- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.rs +++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.rs @@ -41,6 +41,8 @@ fn main() { eprintln!("{}", out); // Print the 'main' frame (and everything before it) to stdout, skipping // the printing of internal (and possibly fragile) libstd frames. + // Stdout is less normalized so we see more, but it also means we can print less + // as platform differences would lead to test suite failures. if !seen_main { println!("{}", out); seen_main = name == "main"; diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stderr b/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stderr index ee556b3e4a05..bc24d6de734d 100644 --- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stderr +++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stderr @@ -2,4 +2,17 @@ $DIR/backtrace-api-v0.rs:LL:CC (func_d) $DIR/backtrace-api-v0.rs:LL:CC (func_c) $DIR/backtrace-api-v0.rs:LL:CC (func_b) $DIR/backtrace-api-v0.rs:LL:CC (func_a) -$DIR/backtrace-api-v0.rs:LL:CC RUSTLIB/core/src/ops/function.rs:LL:CC (>::call_once - RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC (std::sys_common::backtrace::__rust_begin_short_backtrace) +$DIR/backtrace-api-v0.rs:LL:CC (main) +RUSTLIB/core/src/ops/function.rs:LL:CC (>::call_once - shim(fn())) +RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC (std::sys_common::backtrace::__rust_begin_short_backtrace) +RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start::{closure#0}) +RUSTLIB/core/src/ops/function.rs:LL:CC (std::ops::function::impls::call_once) +RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call) +RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try) +RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind) +RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal::{closure#2}) +RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call) +RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try) +RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind) +RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal) +RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start) diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stdout b/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stdout index 2fe31dd0e6ba..c9cab268168c 100644 --- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stdout +++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stdout @@ -1,5 +1,5 @@ $DIR/backtrace-api-v0.rs:24:14 (func_d) $DIR/backtrace-api-v0.rs:20:5 (func_c) -$DIR/backtrace-api-v0.rs:9:5 (func_b) +$DIR/backtrace-api-v0.rs:9:5 (func_b::) $DIR/backtrace-api-v0.rs:5:5 (func_a) $DIR/backtrace-api-v0.rs:29:18 (main) diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.rs b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.rs index 1e35574b39b6..ad05271ca519 100644 --- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.rs +++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.rs @@ -54,6 +54,8 @@ fn main() { eprintln!("{}", out); // Print the 'main' frame (and everything before it) to stdout, skipping // the printing of internal (and possibly fragile) libstd frames. + // Stdout is less normalized so we see more, but it also means we can print less + // as platform differences would lead to test suite failures. if !seen_main { println!("{}", out); seen_main = name == "main"; diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr index 7dc281af31dd..246e54becd82 100644 --- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr +++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr @@ -2,4 +2,17 @@ $DIR/backtrace-api-v1.rs:LL:CC (func_d) $DIR/backtrace-api-v1.rs:LL:CC (func_c) $DIR/backtrace-api-v1.rs:LL:CC (func_b) $DIR/backtrace-api-v1.rs:LL:CC (func_a) -$DIR/backtrace-api-v1.rs:LL:CC RUSTLIB/core/src/ops/function.rs:LL:CC (>::call_once - RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC (std::sys_common::backtrace::__rust_begin_short_backtrace) +$DIR/backtrace-api-v1.rs:LL:CC (main) +RUSTLIB/core/src/ops/function.rs:LL:CC (>::call_once - shim(fn())) +RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC (std::sys_common::backtrace::__rust_begin_short_backtrace) +RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start::{closure#0}) +RUSTLIB/core/src/ops/function.rs:LL:CC (std::ops::function::impls::call_once) +RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call) +RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try) +RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind) +RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal::{closure#2}) +RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call) +RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try) +RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind) +RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal) +RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start) diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stdout b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stdout index 0d2ae3b516a8..e145c167e880 100644 --- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stdout +++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stdout @@ -1,5 +1,5 @@ $DIR/backtrace-api-v1.rs:27:9 (func_d) $DIR/backtrace-api-v1.rs:20:5 (func_c) -$DIR/backtrace-api-v1.rs:9:5 (func_b) +$DIR/backtrace-api-v1.rs:9:5 (func_b::) $DIR/backtrace-api-v1.rs:5:5 (func_a) $DIR/backtrace-api-v1.rs:34:18 (main) diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs index fee5ca44ffb3..70c64485fe93 100644 --- a/src/tools/miri/tests/pass/float.rs +++ b/src/tools/miri/tests/pass/float.rs @@ -168,6 +168,16 @@ fn basic() { let x: u32 = unsafe { std::mem::transmute(42.0_f32) }; let y: f32 = unsafe { std::mem::transmute(x) }; assert_eq(y, 42.0_f32); + + // `%` sign behavior, some of this used to be buggy + assert!((black_box(1.0f32) % 1.0).is_sign_positive()); + assert!((black_box(1.0f32) % -1.0).is_sign_positive()); + assert!((black_box(-1.0f32) % 1.0).is_sign_negative()); + assert!((black_box(-1.0f32) % -1.0).is_sign_negative()); + assert!((black_box(1.0f64) % 1.0).is_sign_positive()); + assert!((black_box(1.0f64) % -1.0).is_sign_positive()); + assert!((black_box(-1.0f64) % 1.0).is_sign_negative()); + assert!((black_box(-1.0f64) % -1.0).is_sign_negative()); } /// Many of these test values are taken from diff --git a/src/tools/miri/tests/pass/intrinsics-math.rs b/src/tools/miri/tests/pass/intrinsics-math.rs index e0e4f5654d6a..5f7730a3e86a 100644 --- a/src/tools/miri/tests/pass/intrinsics-math.rs +++ b/src/tools/miri/tests/pass/intrinsics-math.rs @@ -1,4 +1,5 @@ #![feature(float_gamma)] +use std::{f32, f64}; macro_rules! assert_approx_eq { ($a:expr, $b:expr) => {{ @@ -15,8 +16,7 @@ fn ldexp(a: f64, b: i32) -> f64 { } pub fn main() { - use std::f32; - use std::f64; + mul_add(); assert_approx_eq!(64f32.sqrt(), 8f32); assert_approx_eq!(64f64.sqrt(), 8f64); @@ -48,13 +48,6 @@ pub fn main() { assert_approx_eq!(8f32.log2(), 3f32); assert_approx_eq!(f64::consts::E.log2(), f64::consts::LOG2_E); - assert_approx_eq!(3.0f32.mul_add(2.0f32, 5.0f32), 11.0); - assert_eq!(0.0f32.mul_add(-2.0, f32::consts::E), f32::consts::E); - assert_approx_eq!(3.0f64.mul_add(2.0, 5.0), 11.0); - assert_eq!(0.0f64.mul_add(-2.0f64, f64::consts::E), f64::consts::E); - assert_eq!((-3.2f32).mul_add(2.4, f32::NEG_INFINITY), f32::NEG_INFINITY); - assert_eq!((-3.2f64).mul_add(2.4, f64::NEG_INFINITY), f64::NEG_INFINITY); - assert_approx_eq!((-1.0f32).abs(), 1.0f32); assert_approx_eq!(34.2f64.abs(), 34.2f64); @@ -146,3 +139,19 @@ pub fn main() { assert_approx_eq!(val, (2.0 * f64::consts::PI.sqrt()).ln()); assert_eq!(sign, -1); } + +fn mul_add() { + assert_approx_eq!(3.0f32.mul_add(2.0f32, 5.0f32), 11.0); + assert_eq!(0.0f32.mul_add(-2.0, f32::consts::E), f32::consts::E); + assert_approx_eq!(3.0f64.mul_add(2.0, 5.0), 11.0); + assert_eq!(0.0f64.mul_add(-2.0f64, f64::consts::E), f64::consts::E); + assert_eq!((-3.2f32).mul_add(2.4, f32::NEG_INFINITY), f32::NEG_INFINITY); + assert_eq!((-3.2f64).mul_add(2.4, f64::NEG_INFINITY), f64::NEG_INFINITY); + + let f = f32::mul_add( + -0.000000000000000000000000000000000000014728589, + 0.0000037105144, + 0.000000000000000000000000000000000000000000055, + ); + assert_eq!(f.to_bits(), f32::to_bits(-0.0)); +} diff --git a/src/tools/miri/tests/pass/intrinsics-x86-sse2.rs b/src/tools/miri/tests/pass/intrinsics-x86-sse2.rs index fa9df04d3684..2c7665bc7363 100644 --- a/src/tools/miri/tests/pass/intrinsics-x86-sse2.rs +++ b/src/tools/miri/tests/pass/intrinsics-x86-sse2.rs @@ -70,6 +70,24 @@ mod tests { } test_mm_avg_epu16(); + #[target_feature(enable = "sse2")] + unsafe fn test_mm_madd_epi16() { + let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); + let b = _mm_setr_epi16(9, 10, 11, 12, 13, 14, 15, 16); + let r = _mm_madd_epi16(a, b); + let e = _mm_setr_epi32(29, 81, 149, 233); + assert_eq_m128i(r, e); + + let a = + _mm_setr_epi16(i16::MAX, i16::MAX, i16::MIN, i16::MIN, i16::MIN, i16::MAX, 0, 0); + let b = + _mm_setr_epi16(i16::MAX, i16::MAX, i16::MIN, i16::MIN, i16::MAX, i16::MIN, 0, 0); + let r = _mm_madd_epi16(a, b); + let e = _mm_setr_epi32(0x7FFE0002, i32::MIN, -0x7FFF0000, 0); + assert_eq_m128i(r, e); + } + test_mm_madd_epi16(); + #[target_feature(enable = "sse2")] unsafe fn test_mm_mulhi_epi16() { let (a, b) = (_mm_set1_epi16(1000), _mm_set1_epi16(-1001)); diff --git a/src/tools/miri/tests/pass/intrinsics-x86-sse3-ssse3.rs b/src/tools/miri/tests/pass/intrinsics-x86-sse3-ssse3.rs new file mode 100644 index 000000000000..0805d9bc3003 --- /dev/null +++ b/src/tools/miri/tests/pass/intrinsics-x86-sse3-ssse3.rs @@ -0,0 +1,395 @@ +// Ignore everything except x86 and x86_64 +// Any additional target are added to CI should be ignored here +// (We cannot use `cfg`-based tricks here since the `target-feature` flags below only work on x86.) +//@ignore-target-aarch64 +//@ignore-target-arm +//@ignore-target-avr +//@ignore-target-s390x +//@ignore-target-thumbv7em +//@ignore-target-wasm32 +// SSSE3 implicitly enables SSE3 +//@compile-flags: -C target-feature=+ssse3 + +use core::mem::transmute; +#[cfg(target_arch = "x86")] +use std::arch::x86::*; +#[cfg(target_arch = "x86_64")] +use std::arch::x86_64::*; + +fn main() { + // SSSE3 implicitly enables SSE3, still check it to be sure + assert!(is_x86_feature_detected!("sse3")); + assert!(is_x86_feature_detected!("ssse3")); + + unsafe { + test_sse3(); + test_ssse3(); + } +} + +#[target_feature(enable = "sse3")] +unsafe fn test_sse3() { + // Mostly copied from library/stdarch/crates/core_arch/src/x86/sse3.rs + + #[target_feature(enable = "sse3")] + unsafe fn test_mm_addsub_ps() { + let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); + let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0); + let r = _mm_addsub_ps(a, b); + assert_eq_m128(r, _mm_setr_ps(99.0, 25.0, 0.0, -15.0)); + } + test_mm_addsub_ps(); + + #[target_feature(enable = "sse3")] + unsafe fn test_mm_addsub_pd() { + let a = _mm_setr_pd(-1.0, 5.0); + let b = _mm_setr_pd(-100.0, 20.0); + let r = _mm_addsub_pd(a, b); + assert_eq_m128d(r, _mm_setr_pd(99.0, 25.0)); + } + test_mm_addsub_pd(); + + #[target_feature(enable = "sse3")] + unsafe fn test_mm_hadd_ps() { + let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); + let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0); + let r = _mm_hadd_ps(a, b); + assert_eq_m128(r, _mm_setr_ps(4.0, -10.0, -80.0, -5.0)); + } + test_mm_hadd_ps(); + + #[target_feature(enable = "sse3")] + unsafe fn test_mm_hadd_pd() { + let a = _mm_setr_pd(-1.0, 5.0); + let b = _mm_setr_pd(-100.0, 20.0); + let r = _mm_hadd_pd(a, b); + assert_eq_m128d(r, _mm_setr_pd(4.0, -80.0)); + } + test_mm_hadd_pd(); + + #[target_feature(enable = "sse3")] + unsafe fn test_mm_hsub_ps() { + let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); + let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0); + let r = _mm_hsub_ps(a, b); + assert_eq_m128(r, _mm_setr_ps(-6.0, 10.0, -120.0, 5.0)); + } + test_mm_hsub_ps(); + + #[target_feature(enable = "sse3")] + unsafe fn test_mm_hsub_pd() { + let a = _mm_setr_pd(-1.0, 5.0); + let b = _mm_setr_pd(-100.0, 20.0); + let r = _mm_hsub_pd(a, b); + assert_eq_m128d(r, _mm_setr_pd(-6.0, -120.0)); + } + test_mm_hsub_pd(); + + #[target_feature(enable = "sse3")] + unsafe fn test_mm_lddqu_si128() { + let a = _mm_setr_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + let r = _mm_lddqu_si128(&a); + assert_eq_m128i(a, r); + } + test_mm_lddqu_si128(); +} + +#[target_feature(enable = "ssse3")] +unsafe fn test_ssse3() { + // Mostly copied from library/stdarch/crates/core_arch/src/x86/ssse3.rs + + #[target_feature(enable = "ssse3")] + unsafe fn test_mm_abs_epi8() { + let r = _mm_abs_epi8(_mm_set1_epi8(-5)); + assert_eq_m128i(r, _mm_set1_epi8(5)); + } + test_mm_abs_epi8(); + + #[target_feature(enable = "ssse3")] + unsafe fn test_mm_abs_epi16() { + let r = _mm_abs_epi16(_mm_set1_epi16(-5)); + assert_eq_m128i(r, _mm_set1_epi16(5)); + } + test_mm_abs_epi16(); + + #[target_feature(enable = "ssse3")] + unsafe fn test_mm_abs_epi32() { + let r = _mm_abs_epi32(_mm_set1_epi32(-5)); + assert_eq_m128i(r, _mm_set1_epi32(5)); + } + test_mm_abs_epi32(); + + #[target_feature(enable = "ssse3")] + unsafe fn test_mm_shuffle_epi8() { + let a = _mm_setr_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + let b = _mm_setr_epi8(4, 128_u8 as i8, 4, 3, 24, 12, 6, 19, 12, 5, 5, 10, 4, 1, 8, 0); + let expected = _mm_setr_epi8(5, 0, 5, 4, 9, 13, 7, 4, 13, 6, 6, 11, 5, 2, 9, 1); + let r = _mm_shuffle_epi8(a, b); + assert_eq_m128i(r, expected); + + // Test indices greater than 15 wrapping around + let b = _mm_add_epi8(b, _mm_set1_epi8(32)); + let r = _mm_shuffle_epi8(a, b); + assert_eq_m128i(r, expected); + } + test_mm_shuffle_epi8(); + + #[target_feature(enable = "ssse3")] + unsafe fn test_mm_hadd_epi16() { + let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); + let b = _mm_setr_epi16(4, 128, 4, 3, 24, 12, 6, 19); + let expected = _mm_setr_epi16(3, 7, 11, 15, 132, 7, 36, 25); + let r = _mm_hadd_epi16(a, b); + assert_eq_m128i(r, expected); + + // Test wrapping on overflow + let a = _mm_setr_epi16(i16::MAX, 1, i16::MAX, 2, i16::MAX, 3, i16::MAX, 4); + let b = _mm_setr_epi16(i16::MIN, -1, i16::MIN, -2, i16::MIN, -3, i16::MIN, -4); + let expected = _mm_setr_epi16( + i16::MIN, + i16::MIN + 1, + i16::MIN + 2, + i16::MIN + 3, + i16::MAX, + i16::MAX - 1, + i16::MAX - 2, + i16::MAX - 3, + ); + let r = _mm_hadd_epi16(a, b); + assert_eq_m128i(r, expected); + } + test_mm_hadd_epi16(); + + #[target_feature(enable = "ssse3")] + unsafe fn test_mm_hadds_epi16() { + let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); + let b = _mm_setr_epi16(4, 128, 4, 3, 32767, 1, -32768, -1); + let expected = _mm_setr_epi16(3, 7, 11, 15, 132, 7, 32767, -32768); + let r = _mm_hadds_epi16(a, b); + assert_eq_m128i(r, expected); + + // Test saturating on overflow + let a = _mm_setr_epi16(i16::MAX, 1, i16::MAX, 2, i16::MAX, 3, i16::MAX, 4); + let b = _mm_setr_epi16(i16::MIN, -1, i16::MIN, -2, i16::MIN, -3, i16::MIN, -4); + let expected = _mm_setr_epi16( + i16::MAX, + i16::MAX, + i16::MAX, + i16::MAX, + i16::MIN, + i16::MIN, + i16::MIN, + i16::MIN, + ); + let r = _mm_hadds_epi16(a, b); + assert_eq_m128i(r, expected); + } + test_mm_hadds_epi16(); + + #[target_feature(enable = "ssse3")] + unsafe fn test_mm_hadd_epi32() { + let a = _mm_setr_epi32(1, 2, 3, 4); + let b = _mm_setr_epi32(4, 128, 4, 3); + let expected = _mm_setr_epi32(3, 7, 132, 7); + let r = _mm_hadd_epi32(a, b); + assert_eq_m128i(r, expected); + + // Test wrapping on overflow + let a = _mm_setr_epi32(i32::MAX, 1, i32::MAX, 2); + let b = _mm_setr_epi32(i32::MIN, -1, i32::MIN, -2); + let expected = _mm_setr_epi32(i32::MIN, i32::MIN + 1, i32::MAX, i32::MAX - 1); + let r = _mm_hadd_epi32(a, b); + assert_eq_m128i(r, expected); + } + test_mm_hadd_epi32(); + + #[target_feature(enable = "ssse3")] + unsafe fn test_mm_hsub_epi16() { + let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); + let b = _mm_setr_epi16(4, 128, 4, 3, 24, 12, 6, 19); + let expected = _mm_setr_epi16(-1, -1, -1, -1, -124, 1, 12, -13); + let r = _mm_hsub_epi16(a, b); + assert_eq_m128i(r, expected); + + // Test wrapping on overflow + let a = _mm_setr_epi16(i16::MAX, -1, i16::MAX, -2, i16::MAX, -3, i16::MAX, -4); + let b = _mm_setr_epi16(i16::MIN, 1, i16::MIN, 2, i16::MIN, 3, i16::MIN, 4); + let expected = _mm_setr_epi16( + i16::MIN, + i16::MIN + 1, + i16::MIN + 2, + i16::MIN + 3, + i16::MAX, + i16::MAX - 1, + i16::MAX - 2, + i16::MAX - 3, + ); + let r = _mm_hsub_epi16(a, b); + assert_eq_m128i(r, expected); + } + test_mm_hsub_epi16(); + + #[target_feature(enable = "ssse3")] + unsafe fn test_mm_hsubs_epi16() { + let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); + let b = _mm_setr_epi16(4, 128, 4, 3, 32767, -1, -32768, 1); + let expected = _mm_setr_epi16(-1, -1, -1, -1, -124, 1, 32767, -32768); + let r = _mm_hsubs_epi16(a, b); + assert_eq_m128i(r, expected); + + // Test saturating on overflow + let a = _mm_setr_epi16(i16::MAX, -1, i16::MAX, -2, i16::MAX, -3, i16::MAX, -4); + let b = _mm_setr_epi16(i16::MIN, 1, i16::MIN, 2, i16::MIN, 3, i16::MIN, 4); + let expected = _mm_setr_epi16( + i16::MAX, + i16::MAX, + i16::MAX, + i16::MAX, + i16::MIN, + i16::MIN, + i16::MIN, + i16::MIN, + ); + let r = _mm_hsubs_epi16(a, b); + assert_eq_m128i(r, expected); + } + test_mm_hsubs_epi16(); + + #[target_feature(enable = "ssse3")] + unsafe fn test_mm_hsub_epi32() { + let a = _mm_setr_epi32(1, 2, 3, 4); + let b = _mm_setr_epi32(4, 128, 4, 3); + let expected = _mm_setr_epi32(-1, -1, -124, 1); + let r = _mm_hsub_epi32(a, b); + assert_eq_m128i(r, expected); + + // Test wrapping on overflow + let a = _mm_setr_epi32(i32::MAX, -1, i32::MAX, -2); + let b = _mm_setr_epi32(i32::MIN, 1, i32::MIN, 2); + let expected = _mm_setr_epi32(i32::MIN, i32::MIN + 1, i32::MAX, i32::MAX - 1); + let r = _mm_hsub_epi32(a, b); + assert_eq_m128i(r, expected); + } + test_mm_hsub_epi32(); + + #[target_feature(enable = "ssse3")] + unsafe fn test_mm_maddubs_epi16() { + let a = _mm_setr_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + let b = _mm_setr_epi8(4, 63, 4, 3, 24, 12, 6, 19, 12, 5, 5, 10, 4, 1, 8, 0); + let expected = _mm_setr_epi16(130, 24, 192, 194, 158, 175, 66, 120); + let r = _mm_maddubs_epi16(a, b); + assert_eq_m128i(r, expected); + + // Test widening and saturation + let a = _mm_setr_epi8( + u8::MAX as i8, + u8::MAX as i8, + u8::MAX as i8, + u8::MAX as i8, + u8::MAX as i8, + u8::MAX as i8, + 100, + 100, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ); + let b = _mm_setr_epi8( + i8::MAX, + i8::MAX, + i8::MAX, + i8::MIN, + i8::MIN, + i8::MIN, + 50, + 15, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ); + let expected = _mm_setr_epi16(i16::MAX, -255, i16::MIN, 6500, 0, 0, 0, 0); + let r = _mm_maddubs_epi16(a, b); + assert_eq_m128i(r, expected); + } + test_mm_maddubs_epi16(); + + #[target_feature(enable = "ssse3")] + unsafe fn test_mm_mulhrs_epi16() { + let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); + let b = _mm_setr_epi16(4, 128, 4, 3, 32767, -1, -32768, 1); + let expected = _mm_setr_epi16(0, 0, 0, 0, 5, 0, -7, 0); + let r = _mm_mulhrs_epi16(a, b); + assert_eq_m128i(r, expected); + + // Test extreme values + let a = _mm_setr_epi16(i16::MAX, i16::MIN, i16::MIN, 0, 0, 0, 0, 0); + let b = _mm_setr_epi16(i16::MAX, i16::MIN, i16::MAX, 0, 0, 0, 0, 0); + let expected = _mm_setr_epi16(i16::MAX - 1, i16::MIN, -i16::MAX, 0, 0, 0, 0, 0); + let r = _mm_mulhrs_epi16(a, b); + assert_eq_m128i(r, expected); + } + test_mm_mulhrs_epi16(); + + #[target_feature(enable = "ssse3")] + unsafe fn test_mm_sign_epi8() { + let a = _mm_setr_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -14, -15, 16); + let b = _mm_setr_epi8(4, 63, -4, 3, 24, 12, -6, -19, 12, 5, -5, 10, 4, 1, -8, 0); + let expected = _mm_setr_epi8(1, 2, -3, 4, 5, 6, -7, -8, 9, 10, -11, 12, 13, -14, 15, 0); + let r = _mm_sign_epi8(a, b); + assert_eq_m128i(r, expected); + } + test_mm_sign_epi8(); + + #[target_feature(enable = "ssse3")] + unsafe fn test_mm_sign_epi16() { + let a = _mm_setr_epi16(1, 2, 3, 4, -5, -6, 7, 8); + let b = _mm_setr_epi16(4, 128, 0, 3, 1, -1, -2, 1); + let expected = _mm_setr_epi16(1, 2, 0, 4, -5, 6, -7, 8); + let r = _mm_sign_epi16(a, b); + assert_eq_m128i(r, expected); + } + test_mm_sign_epi16(); + + #[target_feature(enable = "ssse3")] + unsafe fn test_mm_sign_epi32() { + let a = _mm_setr_epi32(-1, 2, 3, 4); + let b = _mm_setr_epi32(1, -1, 1, 0); + let expected = _mm_setr_epi32(-1, -2, 3, 0); + let r = _mm_sign_epi32(a, b); + assert_eq_m128i(r, expected); + } + test_mm_sign_epi32(); +} + +#[track_caller] +#[target_feature(enable = "sse")] +unsafe fn assert_eq_m128(a: __m128, b: __m128) { + let r = _mm_cmpeq_ps(a, b); + if _mm_movemask_ps(r) != 0b1111 { + panic!("{:?} != {:?}", a, b); + } +} + +#[track_caller] +#[target_feature(enable = "sse2")] +unsafe fn assert_eq_m128d(a: __m128d, b: __m128d) { + if _mm_movemask_pd(_mm_cmpeq_pd(a, b)) != 0b11 { + panic!("{:?} != {:?}", a, b); + } +} + +#[track_caller] +#[target_feature(enable = "sse2")] +pub unsafe fn assert_eq_m128i(a: __m128i, b: __m128i) { + assert_eq!(transmute::<_, [u64; 2]>(a), transmute::<_, [u64; 2]>(b)) +} diff --git a/src/tools/miri/tests/pass/portable-simd.rs b/src/tools/miri/tests/pass/portable-simd.rs index ee67a65a4f9a..969162e2c1e9 100644 --- a/src/tools/miri/tests/pass/portable-simd.rs +++ b/src/tools/miri/tests/pass/portable-simd.rs @@ -1,5 +1,6 @@ //@compile-flags: -Zmiri-strict-provenance -#![feature(portable_simd, platform_intrinsics)] +#![feature(portable_simd, platform_intrinsics, adt_const_params, inline_const)] +#![allow(incomplete_features)] use std::simd::*; extern "platform-intrinsic" { @@ -390,6 +391,8 @@ fn simd_intrinsics() { fn simd_reduce_any(x: T) -> bool; fn simd_reduce_all(x: T) -> bool; fn simd_select(m: M, yes: T, no: T) -> T; + fn simd_shuffle_generic(x: T, y: T) -> U; + fn simd_shuffle(x: T, y: T, idx: IDX) -> U; } unsafe { // Make sure simd_eq returns all-1 for `true` @@ -413,6 +416,16 @@ fn simd_intrinsics() { simd_select(i8x4::from_array([0, -1, -1, 0]), b, a), i32x4::from_array([10, 2, 10, 10]) ); + assert_eq!(simd_shuffle_generic::<_, i32x4, { &[3, 1, 0, 2] }>(a, b), a,); + assert_eq!(simd_shuffle::<_, _, i32x4>(a, b, const { [3, 1, 0, 2] }), a,); + assert_eq!( + simd_shuffle_generic::<_, i32x4, { &[7, 5, 4, 6] }>(a, b), + i32x4::from_array([4, 2, 1, 10]), + ); + assert_eq!( + simd_shuffle::<_, _, i32x4>(a, b, const { [7, 5, 4, 6] }), + i32x4::from_array([4, 2, 1, 10]), + ); } } diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs index 31aabca09f39..8000c9e7fddc 100644 --- a/src/tools/opt-dist/src/tests.rs +++ b/src/tools/opt-dist/src/tests.rs @@ -61,7 +61,7 @@ pub fn run_tests(env: &Environment) -> anyhow::Result<()> { let config_content = format!( r#"profile = "user" -changelog-seen = 2 +change-id = 115898 [build] rustc = "{rustc}" diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index d5bc38303e00..002cffa9b0c0 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -2599,7 +2599,8 @@ fn rewrite_fn_base( if where_clause_str.is_empty() { if let ast::FnRetTy::Default(ret_span) = fd.output { match recover_missing_comment_in_span( - mk_sp(params_span.hi(), ret_span.hi()), + // from after the closing paren to right before block or semicolon + mk_sp(ret_span.lo(), span.hi()), shape, context, last_line_width(&result), diff --git a/src/version b/src/version index dc87e8af82f6..7c7053aa2388 100644 --- a/src/version +++ b/src/version @@ -1 +1 @@ -1.74.0 +1.75.0 diff --git a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs index 2a7747e88671..c69d1eaa84bf 100644 --- a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs +++ b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs @@ -10,6 +10,7 @@ // [basic] compile-flags: -Z stack-protector=basic // [none] compile-flags: -Z stack-protector=none // compile-flags: -C opt-level=2 -Z merge-functions=disabled +// min-llvm-version: 17.0.2 #![crate_type = "lib"] @@ -372,7 +373,7 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { // all: __stack_chk_fail - // strong: __stack_chk_fail + // strong-NOT: __stack_chk_fail // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail diff --git a/tests/codegen/issue-97217.rs b/tests/codegen/issue-97217.rs new file mode 100644 index 000000000000..af7345442fc5 --- /dev/null +++ b/tests/codegen/issue-97217.rs @@ -0,0 +1,22 @@ +// compile-flags: -C opt-level=3 +// ignore-debug: the debug assertions get in the way +// min-llvm-version: 17.0.2 +#![crate_type = "lib"] + +// Regression test for issue 97217 (the following should result in no allocations) + +// CHECK-LABEL: @issue97217 +#[no_mangle] +pub fn issue97217() -> i32 { + // drop_in_place should be inlined and never appear + // CHECK-NOT: drop_in_place + + // __rust_alloc should be optimized out + // CHECK-NOT: __rust_alloc + + let v1 = vec![5, 6, 7]; + let v1_iter = v1.iter(); + let total: i32 = v1_iter.sum(); + println!("{}",total); + total +} diff --git a/tests/codegen/simd/simd-wide-sum.rs b/tests/codegen/simd/simd-wide-sum.rs index ff357db470f1..867f7fe94704 100644 --- a/tests/codegen/simd/simd-wide-sum.rs +++ b/tests/codegen/simd/simd-wide-sum.rs @@ -11,14 +11,14 @@ #![feature(portable_simd)] use std::simd::{Simd, SimdUint}; -const N: usize = 8; +const N: usize = 16; #[no_mangle] // CHECK-LABEL: @wider_reduce_simd pub fn wider_reduce_simd(x: Simd) -> u16 { - // CHECK: zext <8 x i8> - // CHECK-SAME: to <8 x i16> - // CHECK: call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> + // CHECK: zext <16 x i8> + // CHECK-SAME: to <16 x i16> + // CHECK: call i16 @llvm.vector.reduce.add.v16i16(<16 x i16> let x: Simd = x.cast(); x.reduce_sum() } @@ -26,9 +26,9 @@ pub fn wider_reduce_simd(x: Simd) -> u16 { #[no_mangle] // CHECK-LABEL: @wider_reduce_loop pub fn wider_reduce_loop(x: Simd) -> u16 { - // CHECK: zext <8 x i8> - // CHECK-SAME: to <8 x i16> - // CHECK: call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> + // CHECK: zext <16 x i8> + // CHECK-SAME: to <16 x i16> + // CHECK: call i16 @llvm.vector.reduce.add.v16i16(<16 x i16> let mut sum = 0_u16; for i in 0..N { sum += u16::from(x[i]); @@ -39,9 +39,9 @@ pub fn wider_reduce_loop(x: Simd) -> u16 { #[no_mangle] // CHECK-LABEL: @wider_reduce_iter pub fn wider_reduce_iter(x: Simd) -> u16 { - // CHECK: zext <8 x i8> - // CHECK-SAME: to <8 x i16> - // CHECK: call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> + // CHECK: zext <16 x i8> + // CHECK-SAME: to <16 x i16> + // CHECK: call i16 @llvm.vector.reduce.add.v16i16(<16 x i16> x.as_array().iter().copied().map(u16::from).sum() } @@ -52,9 +52,9 @@ pub fn wider_reduce_iter(x: Simd) -> u16 { #[no_mangle] // CHECK-LABEL: @wider_reduce_into_iter pub fn wider_reduce_into_iter(x: Simd) -> u16 { - // CHECK: zext <8 x i8> - // CHECK-SAME: to <8 x i16> - // CHECK: call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> + // FIXME: It would be nice if this was exactly the same as the above tests, + // but at the time of writing this comment, that didn't happen on LLVM main. + // CHECK: call i16 @llvm.vector.reduce.add x.to_array().into_iter().map(u16::from).sum() } diff --git a/tests/codegen/unwind-landingpad-cold.rs b/tests/codegen/unwind-landingpad-cold.rs new file mode 100644 index 000000000000..3a902a7d7123 --- /dev/null +++ b/tests/codegen/unwind-landingpad-cold.rs @@ -0,0 +1,16 @@ +// compile-flags: -Cno-prepopulate-passes +// needs-unwind +// min-llvm-version: 17.0.2 +#![crate_type = "lib"] + +// This test checks that drop calls in unwind landing pads +// get the `cold` attribute. + +// CHECK-LABEL: @check_cold +// CHECK: {{(call|invoke) void .+}}drop_in_place{{.+}} [[ATTRIBUTES:#[0-9]+]] +// CHECK: attributes [[ATTRIBUTES]] = { cold } +#[no_mangle] +pub fn check_cold(f: fn(), x: Box) { + // this may unwind + f(); +} diff --git a/tests/codegen/unwind-landingpad-inline.rs b/tests/codegen/unwind-landingpad-inline.rs new file mode 100644 index 000000000000..0774cefdd2d1 --- /dev/null +++ b/tests/codegen/unwind-landingpad-inline.rs @@ -0,0 +1,39 @@ +// min-llvm-version: 17.0.2 +// compile-flags: -Copt-level=3 +// ignore-debug: the debug assertions get in the way +#![crate_type = "lib"] + +// This test checks that we can inline drop_in_place in +// unwind landing pads. + +// Without inlining, the box pointers escape via the call to drop_in_place, +// and LLVM will not optimize out the pointer comparison. +// With inlining, everything should be optimized out. +// See https://github.com/rust-lang/rust/issues/46515 +// CHECK-LABEL: @check_no_escape_in_landingpad +// CHECK: start: +// CHECK-NEXT: __rust_no_alloc_shim_is_unstable +// CHECK-NEXT: __rust_no_alloc_shim_is_unstable +// CHECK-NEXT: ret void +#[no_mangle] +pub fn check_no_escape_in_landingpad(f: fn()) { + let x = &*Box::new(0); + let y = &*Box::new(0); + + if x as *const _ == y as *const _ { + f(); + } +} + +// Without inlining, the compiler can't tell that +// dropping an empty string (in a landing pad) does nothing. +// With inlining, the landing pad should be optimized out. +// See https://github.com/rust-lang/rust/issues/87055 +// CHECK-LABEL: @check_eliminate_noop_drop +// CHECK: call void %g() +// CHECK-NEXT: ret void +#[no_mangle] +pub fn check_eliminate_noop_drop(g: fn()) { + let _var = String::new(); + g(); +} diff --git a/tests/coverage-map/status-quo/async.cov-map b/tests/coverage-map/status-quo/async.cov-map index 5f28252ef806..598791537ad6 100644 --- a/tests/coverage-map/status-quo/async.cov-map +++ b/tests/coverage-map/status-quo/async.cov-map @@ -38,42 +38,40 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 13, 20) to (start + 0, 25) Function name: async::e (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 01, 00, 14] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 01, 00, 14] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 20) +- Code(Zero) at (prev + 15, 1) to (start + 0, 20) Function name: async::e::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 14, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 14, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 15, 20) to (start + 0, 25) +- Code(Zero) at (prev + 15, 20) to (start + 0, 25) Function name: async::executor::block_on::> -Raw bytes (44): 0x[01, 01, 05, 0b, 05, 01, 05, 01, 05, 02, 00, 02, 00, 06, 01, 6e, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 0f, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 13, 02, 05, 00, 06] +Raw bytes (40): 0x[01, 01, 03, 0b, 05, 01, 05, 01, 05, 06, 01, 6e, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 02, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 02, 02, 05, 00, 06] Number of files: 1 - file 0 => global file 1 -Number of expressions: 5 +Number of expressions: 3 - expression 0 operands: lhs = Expression(2, Add), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(1) - expression 2 operands: lhs = Counter(0), rhs = Counter(1) -- expression 3 operands: lhs = Expression(0, Sub), rhs = Zero -- expression 4 operands: lhs = Expression(0, Sub), rhs = Zero Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 110, 5) to (start + 10, 54) - Code(Expression(0, Sub)) at (prev + 13, 32) to (start + 0, 35) = ((c0 + c1) - c1) - Code(Expression(2, Add)) at (prev + 0, 39) to (start + 0, 73) = (c0 + c1) -- Code(Expression(3, Add)) at (prev + 1, 23) to (start + 0, 26) - = (((c0 + c1) - c1) + Zero) +- Code(Expression(0, Sub)) at (prev + 1, 23) to (start + 0, 26) + = ((c0 + c1) - c1) - Code(Counter(1)) at (prev + 1, 14) to (start + 0, 15) -- Code(Expression(4, Add)) at (prev + 2, 5) to (start + 0, 6) - = (((c0 + c1) - c1) + Zero) +- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) + = ((c0 + c1) - c1) Function name: async::executor::block_on::VTABLE::{closure#0} Raw bytes (9): 0x[01, 01, 00, 01, 01, 72, 11, 00, 33] @@ -124,20 +122,20 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 17, 20) to (start + 0, 25) Function name: async::foo (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 1e] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 13, 01, 00, 1e] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 30) +- Code(Zero) at (prev + 19, 1) to (start + 0, 30) Function name: async::foo::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 1e, 00, 2d] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 13, 1e, 00, 2d] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 19, 30) to (start + 0, 45) +- Code(Zero) at (prev + 19, 30) to (start + 0, 45) Function name: async::g Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 01, 00, 17] @@ -148,14 +146,14 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 21, 1) to (start + 0, 23) Function name: async::g::{closure#0} (unused) -Raw bytes (69): 0x[01, 01, 00, 0d, 00, 15, 17, 01, 0c, 00, 02, 09, 00, 0a, 01, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (69): 0x[01, 01, 00, 0d, 00, 15, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 13 - Code(Zero) at (prev + 21, 23) to (start + 1, 12) - Code(Zero) at (prev + 2, 9) to (start + 0, 10) -- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17) +- Code(Zero) at (prev + 0, 14) to (start + 0, 17) - Code(Zero) at (prev + 0, 18) to (start + 0, 23) - Code(Zero) at (prev + 0, 27) to (start + 0, 28) - Code(Zero) at (prev + 0, 32) to (start + 0, 34) @@ -176,14 +174,14 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 29, 1) to (start + 0, 22) Function name: async::h::{closure#0} (unused) -Raw bytes (44): 0x[01, 01, 00, 08, 00, 1d, 16, 03, 0c, 00, 04, 09, 00, 0a, 01, 00, 0e, 00, 13, 00, 00, 14, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (44): 0x[01, 01, 00, 08, 00, 1d, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 13, 00, 00, 14, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 8 - Code(Zero) at (prev + 29, 22) to (start + 3, 12) - Code(Zero) at (prev + 4, 9) to (start + 0, 10) -- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 19) +- Code(Zero) at (prev + 0, 14) to (start + 0, 19) - Code(Zero) at (prev + 0, 20) to (start + 0, 25) - Code(Zero) at (prev + 0, 26) to (start + 0, 27) - Code(Zero) at (prev + 0, 32) to (start + 0, 34) @@ -199,58 +197,46 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 38, 1) to (start + 0, 19) Function name: async::i::{closure#0} -Raw bytes (84): 0x[01, 01, 05, 01, 00, 0d, 00, 1d, 00, 19, 13, 1d, 21, 0e, 01, 26, 13, 04, 0c, 0d, 05, 09, 00, 0a, 03, 00, 0e, 00, 12, 05, 00, 13, 00, 18, 09, 00, 1c, 00, 21, 07, 00, 27, 00, 2a, 15, 00, 2b, 00, 30, 1d, 01, 09, 00, 0a, 11, 00, 0e, 00, 11, 25, 00, 12, 00, 17, 29, 00, 1b, 00, 20, 0b, 00, 24, 00, 26, 21, 01, 0e, 00, 10, 0f, 02, 01, 00, 02] +Raw bytes (78): 0x[01, 01, 02, 19, 07, 1d, 21, 0e, 01, 26, 13, 04, 0c, 0d, 05, 09, 00, 0a, 01, 00, 0e, 00, 12, 05, 00, 13, 00, 18, 09, 00, 1c, 00, 21, 0d, 00, 27, 00, 2a, 15, 00, 2b, 00, 30, 1d, 01, 09, 00, 0a, 11, 00, 0e, 00, 11, 25, 00, 12, 00, 17, 29, 00, 1b, 00, 20, 1d, 00, 24, 00, 26, 21, 01, 0e, 00, 10, 03, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 5 -- expression 0 operands: lhs = Counter(0), rhs = Zero -- expression 1 operands: lhs = Counter(3), rhs = Zero -- expression 2 operands: lhs = Counter(7), rhs = Zero -- expression 3 operands: lhs = Counter(6), rhs = Expression(4, Add) -- expression 4 operands: lhs = Counter(7), rhs = Counter(8) +Number of expressions: 2 +- expression 0 operands: lhs = Counter(6), rhs = Expression(1, Add) +- expression 1 operands: lhs = Counter(7), rhs = Counter(8) Number of file 0 mappings: 14 - Code(Counter(0)) at (prev + 38, 19) to (start + 4, 12) - Code(Counter(3)) at (prev + 5, 9) to (start + 0, 10) -- Code(Expression(0, Add)) at (prev + 0, 14) to (start + 0, 18) - = (c0 + Zero) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 18) - Code(Counter(1)) at (prev + 0, 19) to (start + 0, 24) - Code(Counter(2)) at (prev + 0, 28) to (start + 0, 33) -- Code(Expression(1, Add)) at (prev + 0, 39) to (start + 0, 42) - = (c3 + Zero) +- Code(Counter(3)) at (prev + 0, 39) to (start + 0, 42) - Code(Counter(5)) at (prev + 0, 43) to (start + 0, 48) - Code(Counter(7)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(4)) at (prev + 0, 14) to (start + 0, 17) - Code(Counter(9)) at (prev + 0, 18) to (start + 0, 23) - Code(Counter(10)) at (prev + 0, 27) to (start + 0, 32) -- Code(Expression(2, Add)) at (prev + 0, 36) to (start + 0, 38) - = (c7 + Zero) +- Code(Counter(7)) at (prev + 0, 36) to (start + 0, 38) - Code(Counter(8)) at (prev + 1, 14) to (start + 0, 16) -- Code(Expression(3, Add)) at (prev + 2, 1) to (start + 0, 2) +- Code(Expression(0, Add)) at (prev + 2, 1) to (start + 0, 2) = (c6 + (c7 + c8)) Function name: async::j -Raw bytes (59): 0x[01, 01, 05, 01, 00, 05, 00, 09, 00, 05, 13, 09, 0d, 09, 01, 31, 01, 13, 0c, 05, 14, 09, 00, 0a, 03, 00, 0e, 00, 1b, 07, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 0b, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 0f, 02, 01, 00, 02] +Raw bytes (53): 0x[01, 01, 02, 05, 07, 09, 0d, 09, 01, 31, 01, 13, 0c, 05, 14, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 03, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 5 -- expression 0 operands: lhs = Counter(0), rhs = Zero -- expression 1 operands: lhs = Counter(1), rhs = Zero -- expression 2 operands: lhs = Counter(2), rhs = Zero -- expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add) -- expression 4 operands: lhs = Counter(2), rhs = Counter(3) +Number of expressions: 2 +- expression 0 operands: lhs = Counter(1), rhs = Expression(1, Add) +- expression 1 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 9 - Code(Counter(0)) at (prev + 49, 1) to (start + 19, 12) - Code(Counter(1)) at (prev + 20, 9) to (start + 0, 10) -- Code(Expression(0, Add)) at (prev + 0, 14) to (start + 0, 27) - = (c0 + Zero) -- Code(Expression(1, Add)) at (prev + 0, 31) to (start + 0, 39) - = (c1 + Zero) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 27) +- Code(Counter(1)) at (prev + 0, 31) to (start + 0, 39) - Code(Counter(2)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(4)) at (prev + 0, 14) to (start + 0, 26) -- Code(Expression(2, Add)) at (prev + 0, 30) to (start + 0, 32) - = (c2 + Zero) +- Code(Counter(2)) at (prev + 0, 30) to (start + 0, 32) - Code(Counter(3)) at (prev + 1, 14) to (start + 0, 16) -- Code(Expression(3, Add)) at (prev + 2, 1) to (start + 0, 2) +- Code(Expression(0, Add)) at (prev + 2, 1) to (start + 0, 2) = (c1 + (c2 + c3)) Function name: async::j::c @@ -285,12 +271,12 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 67, 5) to (start + 0, 23) Function name: async::k (unused) -Raw bytes (29): 0x[01, 01, 00, 05, 01, 4b, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 00, 4b, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 75, 1) to (start + 1, 12) +- Code(Zero) at (prev + 75, 1) to (start + 1, 12) - Code(Zero) at (prev + 2, 14) to (start + 0, 16) - Code(Zero) at (prev + 1, 14) to (start + 0, 16) - Code(Zero) at (prev + 1, 14) to (start + 0, 16) @@ -323,12 +309,12 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 91, 1) to (start + 0, 25) Function name: async::m::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 01, 5b, 19, 00, 22] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 5b, 19, 00, 22] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 91, 25) to (start + 0, 34) +- Code(Zero) at (prev + 91, 25) to (start + 0, 34) Function name: async::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 5d, 01, 08, 02] diff --git a/tests/coverage-map/status-quo/async2.cov-map b/tests/coverage-map/status-quo/async2.cov-map index fe74dcd88403..cc7aed9aee3a 100644 --- a/tests/coverage-map/status-quo/async2.cov-map +++ b/tests/coverage-map/status-quo/async2.cov-map @@ -38,48 +38,44 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 19, 36) to (start + 2, 2) Function name: async2::executor::block_on:: -Raw bytes (44): 0x[01, 01, 05, 0b, 05, 01, 05, 01, 05, 02, 00, 02, 00, 06, 01, 27, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 0f, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 13, 02, 05, 00, 06] +Raw bytes (40): 0x[01, 01, 03, 0b, 05, 01, 05, 01, 05, 06, 01, 27, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 02, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 02, 02, 05, 00, 06] Number of files: 1 - file 0 => global file 1 -Number of expressions: 5 +Number of expressions: 3 - expression 0 operands: lhs = Expression(2, Add), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(1) - expression 2 operands: lhs = Counter(0), rhs = Counter(1) -- expression 3 operands: lhs = Expression(0, Sub), rhs = Zero -- expression 4 operands: lhs = Expression(0, Sub), rhs = Zero Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 39, 5) to (start + 10, 54) - Code(Expression(0, Sub)) at (prev + 13, 32) to (start + 0, 35) = ((c0 + c1) - c1) - Code(Expression(2, Add)) at (prev + 0, 39) to (start + 0, 73) = (c0 + c1) -- Code(Expression(3, Add)) at (prev + 1, 23) to (start + 0, 26) - = (((c0 + c1) - c1) + Zero) +- Code(Expression(0, Sub)) at (prev + 1, 23) to (start + 0, 26) + = ((c0 + c1) - c1) - Code(Counter(1)) at (prev + 1, 14) to (start + 0, 15) -- Code(Expression(4, Add)) at (prev + 2, 5) to (start + 0, 6) - = (((c0 + c1) - c1) + Zero) +- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) + = ((c0 + c1) - c1) Function name: async2::executor::block_on:: -Raw bytes (44): 0x[01, 01, 05, 0b, 05, 01, 05, 01, 05, 02, 00, 02, 00, 06, 01, 27, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 0f, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 13, 02, 05, 00, 06] +Raw bytes (40): 0x[01, 01, 03, 0b, 05, 01, 05, 01, 05, 06, 01, 27, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 02, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 02, 02, 05, 00, 06] Number of files: 1 - file 0 => global file 1 -Number of expressions: 5 +Number of expressions: 3 - expression 0 operands: lhs = Expression(2, Add), rhs = Counter(1) - expression 1 operands: lhs = Counter(0), rhs = Counter(1) - expression 2 operands: lhs = Counter(0), rhs = Counter(1) -- expression 3 operands: lhs = Expression(0, Sub), rhs = Zero -- expression 4 operands: lhs = Expression(0, Sub), rhs = Zero Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 39, 5) to (start + 10, 54) - Code(Expression(0, Sub)) at (prev + 13, 32) to (start + 0, 35) = ((c0 + c1) - c1) - Code(Expression(2, Add)) at (prev + 0, 39) to (start + 0, 73) = (c0 + c1) -- Code(Expression(3, Add)) at (prev + 1, 23) to (start + 0, 26) - = (((c0 + c1) - c1) + Zero) +- Code(Expression(0, Sub)) at (prev + 1, 23) to (start + 0, 26) + = ((c0 + c1) - c1) - Code(Counter(1)) at (prev + 1, 14) to (start + 0, 15) -- Code(Expression(4, Add)) at (prev + 2, 5) to (start + 0, 6) - = (((c0 + c1) - c1) + Zero) +- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) + = ((c0 + c1) - c1) Function name: async2::executor::block_on::VTABLE::{closure#0} Raw bytes (9): 0x[01, 01, 00, 01, 01, 2b, 11, 00, 33] diff --git a/tests/coverage-map/status-quo/closure.cov-map b/tests/coverage-map/status-quo/closure.cov-map index 7dbf6ec834da..522c1e73afe3 100644 --- a/tests/coverage-map/status-quo/closure.cov-map +++ b/tests/coverage-map/status-quo/closure.cov-map @@ -1,77 +1,36 @@ Function name: closure::main -Raw bytes (170): 0x[01, 01, 17, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 05, 05, 5a, 01, 05, 18, 01, 08, 01, 0f, 0d, 03, 16, 0e, 06, 0a, 07, 10, 05, 13, 0d, 0b, 1a, 0e, 06, 0a, 0f, 10, 05, 0c, 16, 13, 16, 05, 0d, 18, 17, 19, 09, 01, 1e, 1b, 04, 09, 00, 29, 1f, 01, 09, 00, 2d, 23, 01, 09, 00, 24, 27, 05, 09, 00, 24, 2b, 02, 09, 00, 21, 2f, 04, 09, 00, 21, 33, 04, 09, 00, 28, 37, 09, 09, 00, 32, 3b, 04, 09, 00, 33, 3f, 07, 09, 00, 4b, 43, 08, 09, 00, 48, 47, 0a, 09, 00, 47, 4b, 08, 09, 00, 44, 4f, 0a, 08, 00, 10, 05, 00, 11, 04, 06, 5a, 04, 06, 00, 07, 57, 01, 05, 03, 02] +Raw bytes (128): 0x[01, 01, 02, 01, 05, 05, 02, 18, 01, 08, 01, 0f, 0d, 01, 16, 0e, 06, 0a, 01, 10, 05, 13, 0d, 01, 1a, 0e, 06, 0a, 01, 10, 05, 0c, 16, 01, 16, 05, 0d, 18, 01, 19, 09, 01, 1e, 01, 04, 09, 00, 29, 01, 01, 09, 00, 2d, 01, 01, 09, 00, 24, 01, 05, 09, 00, 24, 01, 02, 09, 00, 21, 01, 04, 09, 00, 21, 01, 04, 09, 00, 28, 01, 09, 09, 00, 32, 01, 04, 09, 00, 33, 01, 07, 09, 00, 4b, 01, 08, 09, 00, 48, 01, 0a, 09, 00, 47, 01, 08, 09, 00, 44, 01, 0a, 08, 00, 10, 05, 00, 11, 04, 06, 02, 04, 06, 00, 07, 07, 01, 05, 03, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 23 -- expression 0 operands: lhs = Counter(0), rhs = Zero -- expression 1 operands: lhs = Counter(0), rhs = Zero -- expression 2 operands: lhs = Counter(0), rhs = Zero -- expression 3 operands: lhs = Counter(0), rhs = Zero -- expression 4 operands: lhs = Counter(0), rhs = Zero -- expression 5 operands: lhs = Counter(0), rhs = Zero -- expression 6 operands: lhs = Counter(0), rhs = Zero -- expression 7 operands: lhs = Counter(0), rhs = Zero -- expression 8 operands: lhs = Counter(0), rhs = Zero -- expression 9 operands: lhs = Counter(0), rhs = Zero -- expression 10 operands: lhs = Counter(0), rhs = Zero -- expression 11 operands: lhs = Counter(0), rhs = Zero -- expression 12 operands: lhs = Counter(0), rhs = Zero -- expression 13 operands: lhs = Counter(0), rhs = Zero -- expression 14 operands: lhs = Counter(0), rhs = Zero -- expression 15 operands: lhs = Counter(0), rhs = Zero -- expression 16 operands: lhs = Counter(0), rhs = Zero -- expression 17 operands: lhs = Counter(0), rhs = Zero -- expression 18 operands: lhs = Counter(0), rhs = Zero -- expression 19 operands: lhs = Counter(0), rhs = Zero -- expression 20 operands: lhs = Counter(0), rhs = Counter(1) -- expression 21 operands: lhs = Counter(1), rhs = Expression(22, Sub) -- expression 22 operands: lhs = Counter(0), rhs = Counter(1) +Number of expressions: 2 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 24 - Code(Counter(0)) at (prev + 8, 1) to (start + 15, 13) -- Code(Expression(0, Add)) at (prev + 22, 14) to (start + 6, 10) - = (c0 + Zero) -- Code(Expression(1, Add)) at (prev + 16, 5) to (start + 19, 13) - = (c0 + Zero) -- Code(Expression(2, Add)) at (prev + 26, 14) to (start + 6, 10) - = (c0 + Zero) -- Code(Expression(3, Add)) at (prev + 16, 5) to (start + 12, 22) - = (c0 + Zero) -- Code(Expression(4, Add)) at (prev + 22, 5) to (start + 13, 24) - = (c0 + Zero) -- Code(Expression(5, Add)) at (prev + 25, 9) to (start + 1, 30) - = (c0 + Zero) -- Code(Expression(6, Add)) at (prev + 4, 9) to (start + 0, 41) - = (c0 + Zero) -- Code(Expression(7, Add)) at (prev + 1, 9) to (start + 0, 45) - = (c0 + Zero) -- Code(Expression(8, Add)) at (prev + 1, 9) to (start + 0, 36) - = (c0 + Zero) -- Code(Expression(9, Add)) at (prev + 5, 9) to (start + 0, 36) - = (c0 + Zero) -- Code(Expression(10, Add)) at (prev + 2, 9) to (start + 0, 33) - = (c0 + Zero) -- Code(Expression(11, Add)) at (prev + 4, 9) to (start + 0, 33) - = (c0 + Zero) -- Code(Expression(12, Add)) at (prev + 4, 9) to (start + 0, 40) - = (c0 + Zero) -- Code(Expression(13, Add)) at (prev + 9, 9) to (start + 0, 50) - = (c0 + Zero) -- Code(Expression(14, Add)) at (prev + 4, 9) to (start + 0, 51) - = (c0 + Zero) -- Code(Expression(15, Add)) at (prev + 7, 9) to (start + 0, 75) - = (c0 + Zero) -- Code(Expression(16, Add)) at (prev + 8, 9) to (start + 0, 72) - = (c0 + Zero) -- Code(Expression(17, Add)) at (prev + 10, 9) to (start + 0, 71) - = (c0 + Zero) -- Code(Expression(18, Add)) at (prev + 8, 9) to (start + 0, 68) - = (c0 + Zero) -- Code(Expression(19, Add)) at (prev + 10, 8) to (start + 0, 16) - = (c0 + Zero) +- Code(Counter(0)) at (prev + 22, 14) to (start + 6, 10) +- Code(Counter(0)) at (prev + 16, 5) to (start + 19, 13) +- Code(Counter(0)) at (prev + 26, 14) to (start + 6, 10) +- Code(Counter(0)) at (prev + 16, 5) to (start + 12, 22) +- Code(Counter(0)) at (prev + 22, 5) to (start + 13, 24) +- Code(Counter(0)) at (prev + 25, 9) to (start + 1, 30) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 41) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 45) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 36) +- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 36) +- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 33) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 33) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 40) +- Code(Counter(0)) at (prev + 9, 9) to (start + 0, 50) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 51) +- Code(Counter(0)) at (prev + 7, 9) to (start + 0, 75) +- Code(Counter(0)) at (prev + 8, 9) to (start + 0, 72) +- Code(Counter(0)) at (prev + 10, 9) to (start + 0, 71) +- Code(Counter(0)) at (prev + 8, 9) to (start + 0, 68) +- Code(Counter(0)) at (prev + 10, 8) to (start + 0, 16) - Code(Counter(1)) at (prev + 0, 17) to (start + 4, 6) -- Code(Expression(22, Sub)) at (prev + 4, 6) to (start + 0, 7) +- Code(Expression(0, Sub)) at (prev + 4, 6) to (start + 0, 7) = (c0 - c1) -- Code(Expression(21, Add)) at (prev + 1, 5) to (start + 3, 2) +- Code(Expression(1, Add)) at (prev + 1, 5) to (start + 3, 2) = (c1 + (c0 - c1)) Function name: closure::main::{closure#0} @@ -90,46 +49,45 @@ Number of file 0 mappings: 4 = (c1 + (c0 - c1)) Function name: closure::main::{closure#10} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 01, 9a, 01, 07, 00, 21] +Raw bytes (10): 0x[01, 01, 00, 01, 00, 9a, 01, 07, 00, 21] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 154, 7) to (start + 0, 33) +- Code(Zero) at (prev + 154, 7) to (start + 0, 33) Function name: closure::main::{closure#11} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 01, 9e, 01, 07, 00, 21] +Raw bytes (10): 0x[01, 01, 00, 01, 00, 9e, 01, 07, 00, 21] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 158, 7) to (start + 0, 33) +- Code(Zero) at (prev + 158, 7) to (start + 0, 33) Function name: closure::main::{closure#12} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 01, a6, 01, 01, 00, 17] +Raw bytes (10): 0x[01, 01, 00, 01, 00, a6, 01, 01, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 166, 1) to (start + 0, 23) +- Code(Zero) at (prev + 166, 1) to (start + 0, 23) Function name: closure::main::{closure#13} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 01, ab, 01, 0d, 02, 0e] +Raw bytes (10): 0x[01, 01, 00, 01, 00, ab, 01, 0d, 02, 0e] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 171, 13) to (start + 2, 14) +- Code(Zero) at (prev + 171, 13) to (start + 2, 14) Function name: closure::main::{closure#14} -Raw bytes (38): 0x[01, 01, 04, 05, 0a, 01, 05, 01, 05, 03, 00, 05, 03, b2, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0a, 00, 2f, 00, 33, 0f, 01, 0d, 00, 0e] +Raw bytes (36): 0x[01, 01, 03, 05, 0a, 01, 05, 01, 05, 05, 03, b2, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0a, 00, 2f, 00, 33, 03, 01, 0d, 00, 0e] Number of files: 1 - file 0 => global file 1 -Number of expressions: 4 +Number of expressions: 3 - expression 0 operands: lhs = Counter(1), rhs = Expression(2, Sub) - expression 1 operands: lhs = Counter(0), rhs = Counter(1) - expression 2 operands: lhs = Counter(0), rhs = Counter(1) -- expression 3 operands: lhs = Expression(0, Add), rhs = Zero Number of file 0 mappings: 5 - Code(Expression(0, Add)) at (prev + 178, 13) to (start + 0, 21) = (c1 + (c0 - c1)) @@ -137,40 +95,36 @@ Number of file 0 mappings: 5 - Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37) - Code(Expression(2, Sub)) at (prev + 0, 47) to (start + 0, 51) = (c0 - c1) -- Code(Expression(3, Add)) at (prev + 1, 13) to (start + 0, 14) - = ((c1 + (c0 - c1)) + Zero) +- Code(Expression(0, Add)) at (prev + 1, 13) to (start + 0, 14) + = (c1 + (c0 - c1)) Function name: closure::main::{closure#15} -Raw bytes (45): 0x[01, 01, 05, 05, 0e, 01, 05, 01, 00, 01, 05, 03, 00, 06, 01, ba, 01, 09, 00, 0a, 03, 01, 0d, 00, 15, 0b, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0e, 00, 2f, 00, 33, 13, 02, 09, 00, 0a] +Raw bytes (41): 0x[01, 01, 03, 05, 0a, 01, 05, 01, 05, 06, 01, ba, 01, 09, 00, 0a, 03, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0a, 00, 2f, 00, 33, 03, 02, 09, 00, 0a] Number of files: 1 - file 0 => global file 1 -Number of expressions: 5 -- expression 0 operands: lhs = Counter(1), rhs = Expression(3, Sub) +Number of expressions: 3 +- expression 0 operands: lhs = Counter(1), rhs = Expression(2, Sub) - expression 1 operands: lhs = Counter(0), rhs = Counter(1) -- expression 2 operands: lhs = Counter(0), rhs = Zero -- expression 3 operands: lhs = Counter(0), rhs = Counter(1) -- expression 4 operands: lhs = Expression(0, Add), rhs = Zero +- expression 2 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 186, 9) to (start + 0, 10) - Code(Expression(0, Add)) at (prev + 1, 13) to (start + 0, 21) = (c1 + (c0 - c1)) -- Code(Expression(2, Add)) at (prev + 1, 17) to (start + 1, 27) - = (c0 + Zero) +- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 27) - Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37) -- Code(Expression(3, Sub)) at (prev + 0, 47) to (start + 0, 51) +- Code(Expression(2, Sub)) at (prev + 0, 47) to (start + 0, 51) = (c0 - c1) -- Code(Expression(4, Add)) at (prev + 2, 9) to (start + 0, 10) - = ((c1 + (c0 - c1)) + Zero) +- Code(Expression(0, Add)) at (prev + 2, 9) to (start + 0, 10) + = (c1 + (c0 - c1)) Function name: closure::main::{closure#16} -Raw bytes (38): 0x[01, 01, 04, 05, 0a, 01, 05, 01, 05, 03, 00, 05, 03, c4, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0a, 00, 2f, 00, 33, 0f, 01, 0d, 00, 0e] +Raw bytes (36): 0x[01, 01, 03, 05, 0a, 01, 05, 01, 05, 05, 03, c4, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0a, 00, 2f, 00, 33, 03, 01, 0d, 00, 0e] Number of files: 1 - file 0 => global file 1 -Number of expressions: 4 +Number of expressions: 3 - expression 0 operands: lhs = Counter(1), rhs = Expression(2, Sub) - expression 1 operands: lhs = Counter(0), rhs = Counter(1) - expression 2 operands: lhs = Counter(0), rhs = Counter(1) -- expression 3 operands: lhs = Expression(0, Add), rhs = Zero Number of file 0 mappings: 5 - Code(Expression(0, Add)) at (prev + 196, 13) to (start + 0, 21) = (c1 + (c0 - c1)) @@ -178,30 +132,27 @@ Number of file 0 mappings: 5 - Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37) - Code(Expression(2, Sub)) at (prev + 0, 47) to (start + 0, 51) = (c0 - c1) -- Code(Expression(3, Add)) at (prev + 1, 13) to (start + 0, 14) - = ((c1 + (c0 - c1)) + Zero) +- Code(Expression(0, Add)) at (prev + 1, 13) to (start + 0, 14) + = (c1 + (c0 - c1)) Function name: closure::main::{closure#17} -Raw bytes (45): 0x[01, 01, 05, 05, 0e, 01, 05, 01, 00, 01, 05, 03, 00, 06, 01, cc, 01, 09, 00, 0a, 03, 01, 0d, 00, 15, 0b, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0e, 00, 2f, 00, 33, 13, 02, 09, 00, 0a] +Raw bytes (41): 0x[01, 01, 03, 05, 0a, 01, 05, 01, 05, 06, 01, cc, 01, 09, 00, 0a, 03, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0a, 00, 2f, 00, 33, 03, 02, 09, 00, 0a] Number of files: 1 - file 0 => global file 1 -Number of expressions: 5 -- expression 0 operands: lhs = Counter(1), rhs = Expression(3, Sub) +Number of expressions: 3 +- expression 0 operands: lhs = Counter(1), rhs = Expression(2, Sub) - expression 1 operands: lhs = Counter(0), rhs = Counter(1) -- expression 2 operands: lhs = Counter(0), rhs = Zero -- expression 3 operands: lhs = Counter(0), rhs = Counter(1) -- expression 4 operands: lhs = Expression(0, Add), rhs = Zero +- expression 2 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 204, 9) to (start + 0, 10) - Code(Expression(0, Add)) at (prev + 1, 13) to (start + 0, 21) = (c1 + (c0 - c1)) -- Code(Expression(2, Add)) at (prev + 1, 17) to (start + 1, 27) - = (c0 + Zero) +- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 27) - Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37) -- Code(Expression(3, Sub)) at (prev + 0, 47) to (start + 0, 51) +- Code(Expression(2, Sub)) at (prev + 0, 47) to (start + 0, 51) = (c0 - c1) -- Code(Expression(4, Add)) at (prev + 2, 9) to (start + 0, 10) - = ((c1 + (c0 - c1)) + Zero) +- Code(Expression(0, Add)) at (prev + 2, 9) to (start + 0, 10) + = (c1 + (c0 - c1)) Function name: closure::main::{closure#18} Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 18, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 12, 00, 13, 07, 01, 11, 01, 0e] @@ -264,23 +215,23 @@ Number of file 0 mappings: 4 = (c1 + (c0 - c1)) Function name: closure::main::{closure#3} (unused) -Raw bytes (25): 0x[01, 01, 00, 04, 01, 80, 01, 05, 01, 14, 00, 01, 15, 02, 0a, 00, 02, 0a, 00, 0b, 00, 01, 09, 01, 06] +Raw bytes (25): 0x[01, 01, 00, 04, 00, 80, 01, 05, 01, 14, 00, 01, 15, 02, 0a, 00, 02, 0a, 00, 0b, 00, 01, 09, 01, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 128, 5) to (start + 1, 20) +- Code(Zero) at (prev + 128, 5) to (start + 1, 20) - Code(Zero) at (prev + 1, 21) to (start + 2, 10) - Code(Zero) at (prev + 2, 10) to (start + 0, 11) - Code(Zero) at (prev + 1, 9) to (start + 1, 6) Function name: closure::main::{closure#4} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 01, 88, 01, 35, 00, 43] +Raw bytes (10): 0x[01, 01, 00, 01, 00, 88, 01, 35, 00, 43] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 136, 53) to (start + 0, 67) +- Code(Zero) at (prev + 136, 53) to (start + 0, 67) Function name: closure::main::{closure#5} Raw bytes (10): 0x[01, 01, 00, 01, 01, 8b, 01, 3d, 00, 4f] @@ -299,26 +250,26 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 140, 65) to (start + 0, 87) Function name: closure::main::{closure#7} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 01, 8d, 01, 3b, 00, 51] +Raw bytes (10): 0x[01, 01, 00, 01, 00, 8d, 01, 3b, 00, 51] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 141, 59) to (start + 0, 81) +- Code(Zero) at (prev + 141, 59) to (start + 0, 81) Function name: closure::main::{closure#8} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 01, 92, 01, 3b, 00, 55] +Raw bytes (10): 0x[01, 01, 00, 01, 00, 92, 01, 3b, 00, 55] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 146, 59) to (start + 0, 85) +- Code(Zero) at (prev + 146, 59) to (start + 0, 85) Function name: closure::main::{closure#9} (unused) -Raw bytes (10): 0x[01, 01, 00, 01, 01, 94, 01, 38, 02, 06] +Raw bytes (10): 0x[01, 01, 00, 01, 00, 94, 01, 38, 02, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 148, 56) to (start + 2, 6) +- Code(Zero) at (prev + 148, 56) to (start + 2, 6) diff --git a/tests/coverage-map/status-quo/closure_bug.cov-map b/tests/coverage-map/status-quo/closure_bug.cov-map index 4fe2e5ad243d..90eeb1a6686f 100644 --- a/tests/coverage-map/status-quo/closure_bug.cov-map +++ b/tests/coverage-map/status-quo/closure_bug.cov-map @@ -1,89 +1,74 @@ Function name: closure_bug::main -Raw bytes (241): 0x[01, 01, 34, 01, 00, 01, 05, 05, ce, 01, 01, 05, cb, 01, 00, 05, ce, 01, 01, 05, cb, 01, 09, 05, ce, 01, 01, 05, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, c3, 01, 00, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, c3, 01, 0d, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, 0d, be, 01, c3, 01, 0d, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, bb, 01, 00, 0d, be, 01, c3, 01, 0d, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, bb, 01, 11, 0d, be, 01, c3, 01, 0d, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, 11, b6, 01, bb, 01, 11, 0d, be, 01, c3, 01, 0d, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, 11, 01, 06, 01, 03, 0a, 03, 09, 05, 01, 0e, 05, 01, 0f, 00, 17, ce, 01, 00, 17, 00, 18, cb, 01, 02, 09, 00, 0a, 13, 06, 05, 01, 0e, 09, 01, 0f, 00, 17, c6, 01, 00, 17, 00, 18, c3, 01, 02, 09, 00, 0a, 3b, 06, 05, 01, 0e, 0d, 01, 0f, 00, 17, be, 01, 00, 17, 00, 18, bb, 01, 02, 09, 00, 0a, 7b, 06, 05, 01, 0e, 11, 01, 0f, 00, 17, b6, 01, 00, 17, 00, 18, b3, 01, 01, 01, 00, 02] +Raw bytes (201): 0x[01, 01, 26, 01, 05, 05, 02, 05, 02, 97, 01, 09, 05, 02, 09, 92, 01, 97, 01, 09, 05, 02, 09, 92, 01, 97, 01, 09, 05, 02, 8f, 01, 0d, 09, 92, 01, 97, 01, 09, 05, 02, 0d, 8a, 01, 8f, 01, 0d, 09, 92, 01, 97, 01, 09, 05, 02, 0d, 8a, 01, 8f, 01, 0d, 09, 92, 01, 97, 01, 09, 05, 02, 87, 01, 11, 0d, 8a, 01, 8f, 01, 0d, 09, 92, 01, 97, 01, 09, 05, 02, 11, 82, 01, 87, 01, 11, 0d, 8a, 01, 8f, 01, 0d, 09, 92, 01, 97, 01, 09, 05, 02, 11, 01, 06, 01, 03, 0a, 01, 09, 05, 01, 0e, 05, 01, 0f, 00, 17, 02, 00, 17, 00, 18, 97, 01, 02, 09, 00, 0a, 97, 01, 06, 05, 01, 0e, 09, 01, 0f, 00, 17, 92, 01, 00, 17, 00, 18, 8f, 01, 02, 09, 00, 0a, 8f, 01, 06, 05, 01, 0e, 0d, 01, 0f, 00, 17, 8a, 01, 00, 17, 00, 18, 87, 01, 02, 09, 00, 0a, 87, 01, 06, 05, 01, 0e, 11, 01, 0f, 00, 17, 82, 01, 00, 17, 00, 18, 7f, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 52 -- expression 0 operands: lhs = Counter(0), rhs = Zero -- expression 1 operands: lhs = Counter(0), rhs = Counter(1) -- expression 2 operands: lhs = Counter(1), rhs = Expression(51, Sub) -- expression 3 operands: lhs = Counter(0), rhs = Counter(1) -- expression 4 operands: lhs = Expression(50, Add), rhs = Zero -- expression 5 operands: lhs = Counter(1), rhs = Expression(51, Sub) -- expression 6 operands: lhs = Counter(0), rhs = Counter(1) -- expression 7 operands: lhs = Expression(50, Add), rhs = Counter(2) -- expression 8 operands: lhs = Counter(1), rhs = Expression(51, Sub) -- expression 9 operands: lhs = Counter(0), rhs = Counter(1) -- expression 10 operands: lhs = Counter(2), rhs = Expression(49, Sub) -- expression 11 operands: lhs = Expression(50, Add), rhs = Counter(2) -- expression 12 operands: lhs = Counter(1), rhs = Expression(51, Sub) -- expression 13 operands: lhs = Counter(0), rhs = Counter(1) -- expression 14 operands: lhs = Expression(48, Add), rhs = Zero -- expression 15 operands: lhs = Counter(2), rhs = Expression(49, Sub) -- expression 16 operands: lhs = Expression(50, Add), rhs = Counter(2) -- expression 17 operands: lhs = Counter(1), rhs = Expression(51, Sub) -- expression 18 operands: lhs = Counter(0), rhs = Counter(1) -- expression 19 operands: lhs = Expression(48, Add), rhs = Counter(3) -- expression 20 operands: lhs = Counter(2), rhs = Expression(49, Sub) -- expression 21 operands: lhs = Expression(50, Add), rhs = Counter(2) -- expression 22 operands: lhs = Counter(1), rhs = Expression(51, Sub) -- expression 23 operands: lhs = Counter(0), rhs = Counter(1) -- expression 24 operands: lhs = Counter(3), rhs = Expression(47, Sub) -- expression 25 operands: lhs = Expression(48, Add), rhs = Counter(3) -- expression 26 operands: lhs = Counter(2), rhs = Expression(49, Sub) -- expression 27 operands: lhs = Expression(50, Add), rhs = Counter(2) -- expression 28 operands: lhs = Counter(1), rhs = Expression(51, Sub) -- expression 29 operands: lhs = Counter(0), rhs = Counter(1) -- expression 30 operands: lhs = Expression(46, Add), rhs = Zero -- expression 31 operands: lhs = Counter(3), rhs = Expression(47, Sub) -- expression 32 operands: lhs = Expression(48, Add), rhs = Counter(3) -- expression 33 operands: lhs = Counter(2), rhs = Expression(49, Sub) -- expression 34 operands: lhs = Expression(50, Add), rhs = Counter(2) -- expression 35 operands: lhs = Counter(1), rhs = Expression(51, Sub) -- expression 36 operands: lhs = Counter(0), rhs = Counter(1) -- expression 37 operands: lhs = Expression(46, Add), rhs = Counter(4) -- expression 38 operands: lhs = Counter(3), rhs = Expression(47, Sub) -- expression 39 operands: lhs = Expression(48, Add), rhs = Counter(3) -- expression 40 operands: lhs = Counter(2), rhs = Expression(49, Sub) -- expression 41 operands: lhs = Expression(50, Add), rhs = Counter(2) -- expression 42 operands: lhs = Counter(1), rhs = Expression(51, Sub) -- expression 43 operands: lhs = Counter(0), rhs = Counter(1) -- expression 44 operands: lhs = Counter(4), rhs = Expression(45, Sub) -- expression 45 operands: lhs = Expression(46, Add), rhs = Counter(4) -- expression 46 operands: lhs = Counter(3), rhs = Expression(47, Sub) -- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(3) -- expression 48 operands: lhs = Counter(2), rhs = Expression(49, Sub) -- expression 49 operands: lhs = Expression(50, Add), rhs = Counter(2) -- expression 50 operands: lhs = Counter(1), rhs = Expression(51, Sub) -- expression 51 operands: lhs = Counter(0), rhs = Counter(1) +Number of expressions: 38 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 2 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 3 operands: lhs = Expression(37, Add), rhs = Counter(2) +- expression 4 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 5 operands: lhs = Counter(2), rhs = Expression(36, Sub) +- expression 6 operands: lhs = Expression(37, Add), rhs = Counter(2) +- expression 7 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 8 operands: lhs = Counter(2), rhs = Expression(36, Sub) +- expression 9 operands: lhs = Expression(37, Add), rhs = Counter(2) +- expression 10 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 11 operands: lhs = Expression(35, Add), rhs = Counter(3) +- expression 12 operands: lhs = Counter(2), rhs = Expression(36, Sub) +- expression 13 operands: lhs = Expression(37, Add), rhs = Counter(2) +- expression 14 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 15 operands: lhs = Counter(3), rhs = Expression(34, Sub) +- expression 16 operands: lhs = Expression(35, Add), rhs = Counter(3) +- expression 17 operands: lhs = Counter(2), rhs = Expression(36, Sub) +- expression 18 operands: lhs = Expression(37, Add), rhs = Counter(2) +- expression 19 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 20 operands: lhs = Counter(3), rhs = Expression(34, Sub) +- expression 21 operands: lhs = Expression(35, Add), rhs = Counter(3) +- expression 22 operands: lhs = Counter(2), rhs = Expression(36, Sub) +- expression 23 operands: lhs = Expression(37, Add), rhs = Counter(2) +- expression 24 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 25 operands: lhs = Expression(33, Add), rhs = Counter(4) +- expression 26 operands: lhs = Counter(3), rhs = Expression(34, Sub) +- expression 27 operands: lhs = Expression(35, Add), rhs = Counter(3) +- expression 28 operands: lhs = Counter(2), rhs = Expression(36, Sub) +- expression 29 operands: lhs = Expression(37, Add), rhs = Counter(2) +- expression 30 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 31 operands: lhs = Counter(4), rhs = Expression(32, Sub) +- expression 32 operands: lhs = Expression(33, Add), rhs = Counter(4) +- expression 33 operands: lhs = Counter(3), rhs = Expression(34, Sub) +- expression 34 operands: lhs = Expression(35, Add), rhs = Counter(3) +- expression 35 operands: lhs = Counter(2), rhs = Expression(36, Sub) +- expression 36 operands: lhs = Expression(37, Add), rhs = Counter(2) +- expression 37 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 17 - Code(Counter(0)) at (prev + 6, 1) to (start + 3, 10) -- Code(Expression(0, Add)) at (prev + 9, 5) to (start + 1, 14) - = (c0 + Zero) +- Code(Counter(0)) at (prev + 9, 5) to (start + 1, 14) - Code(Counter(1)) at (prev + 1, 15) to (start + 0, 23) -- Code(Expression(51, Sub)) at (prev + 0, 23) to (start + 0, 24) +- Code(Expression(0, Sub)) at (prev + 0, 23) to (start + 0, 24) = (c0 - c1) -- Code(Expression(50, Add)) at (prev + 2, 9) to (start + 0, 10) +- Code(Expression(37, Add)) at (prev + 2, 9) to (start + 0, 10) + = (c1 + (c0 - c1)) +- Code(Expression(37, Add)) at (prev + 6, 5) to (start + 1, 14) = (c1 + (c0 - c1)) -- Code(Expression(4, Add)) at (prev + 6, 5) to (start + 1, 14) - = ((c1 + (c0 - c1)) + Zero) - Code(Counter(2)) at (prev + 1, 15) to (start + 0, 23) -- Code(Expression(49, Sub)) at (prev + 0, 23) to (start + 0, 24) +- Code(Expression(36, Sub)) at (prev + 0, 23) to (start + 0, 24) = ((c1 + (c0 - c1)) - c2) -- Code(Expression(48, Add)) at (prev + 2, 9) to (start + 0, 10) +- Code(Expression(35, Add)) at (prev + 2, 9) to (start + 0, 10) + = (c2 + ((c1 + (c0 - c1)) - c2)) +- Code(Expression(35, Add)) at (prev + 6, 5) to (start + 1, 14) = (c2 + ((c1 + (c0 - c1)) - c2)) -- Code(Expression(14, Add)) at (prev + 6, 5) to (start + 1, 14) - = ((c2 + ((c1 + (c0 - c1)) - c2)) + Zero) - Code(Counter(3)) at (prev + 1, 15) to (start + 0, 23) -- Code(Expression(47, Sub)) at (prev + 0, 23) to (start + 0, 24) +- Code(Expression(34, Sub)) at (prev + 0, 23) to (start + 0, 24) = ((c2 + ((c1 + (c0 - c1)) - c2)) - c3) -- Code(Expression(46, Add)) at (prev + 2, 9) to (start + 0, 10) +- Code(Expression(33, Add)) at (prev + 2, 9) to (start + 0, 10) + = (c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) +- Code(Expression(33, Add)) at (prev + 6, 5) to (start + 1, 14) = (c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) -- Code(Expression(30, Add)) at (prev + 6, 5) to (start + 1, 14) - = ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) + Zero) - Code(Counter(4)) at (prev + 1, 15) to (start + 0, 23) -- Code(Expression(45, Sub)) at (prev + 0, 23) to (start + 0, 24) +- Code(Expression(32, Sub)) at (prev + 0, 23) to (start + 0, 24) = ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4) -- Code(Expression(44, Add)) at (prev + 1, 1) to (start + 0, 2) +- Code(Expression(31, Add)) at (prev + 1, 1) to (start + 0, 2) = (c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) Function name: closure_bug::main::{closure#0} diff --git a/tests/coverage-map/status-quo/closure_macro.cov-map b/tests/coverage-map/status-quo/closure_macro.cov-map index ac017eb44681..b02c7e2e4c66 100644 --- a/tests/coverage-map/status-quo/closure_macro.cov-map +++ b/tests/coverage-map/status-quo/closure_macro.cov-map @@ -7,27 +7,23 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 29, 1) to (start + 2, 2) Function name: closure_macro::main -Raw bytes (49): 0x[01, 01, 05, 01, 05, 02, 00, 05, 00, 02, 00, 05, 02, 07, 01, 21, 01, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 12, 00, 13, 07, 00, 12, 00, 13, 0b, 00, 54, 00, 55, 0f, 02, 09, 02, 0b, 13, 03, 01, 00, 02] +Raw bytes (43): 0x[01, 01, 02, 01, 05, 05, 02, 07, 01, 21, 01, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 12, 00, 13, 02, 00, 12, 00, 13, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 07, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 5 +Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Expression(0, Sub), rhs = Zero -- expression 2 operands: lhs = Counter(1), rhs = Zero -- expression 3 operands: lhs = Expression(0, Sub), rhs = Zero -- expression 4 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 7 - Code(Counter(0)) at (prev + 33, 1) to (start + 1, 33) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15) = (c0 - c1) - Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19) -- Code(Expression(1, Add)) at (prev + 0, 18) to (start + 0, 19) - = ((c0 - c1) + Zero) -- Code(Expression(2, Add)) at (prev + 0, 84) to (start + 0, 85) - = (c1 + Zero) -- Code(Expression(3, Add)) at (prev + 2, 9) to (start + 2, 11) - = ((c0 - c1) + Zero) -- Code(Expression(4, Add)) at (prev + 3, 1) to (start + 0, 2) +- Code(Expression(0, Sub)) at (prev + 0, 18) to (start + 0, 19) + = (c0 - c1) +- Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85) +- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11) + = (c0 - c1) +- Code(Expression(1, Add)) at (prev + 3, 1) to (start + 0, 2) = (c1 + (c0 - c1)) Function name: closure_macro::main::{closure#0} diff --git a/tests/coverage-map/status-quo/closure_macro_async.cov-map b/tests/coverage-map/status-quo/closure_macro_async.cov-map index c9a142e5aebc..7f8666948d90 100644 --- a/tests/coverage-map/status-quo/closure_macro_async.cov-map +++ b/tests/coverage-map/status-quo/closure_macro_async.cov-map @@ -15,27 +15,23 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 33, 1) to (start + 0, 43) Function name: closure_macro_async::test::{closure#0} -Raw bytes (49): 0x[01, 01, 05, 01, 05, 02, 00, 05, 00, 02, 00, 05, 02, 07, 01, 21, 2b, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 12, 00, 13, 07, 00, 12, 00, 13, 0b, 00, 54, 00, 55, 0f, 02, 09, 02, 0b, 13, 03, 01, 00, 02] +Raw bytes (43): 0x[01, 01, 02, 01, 05, 05, 02, 07, 01, 21, 2b, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 12, 00, 13, 02, 00, 12, 00, 13, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 07, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 5 +Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Expression(0, Sub), rhs = Zero -- expression 2 operands: lhs = Counter(1), rhs = Zero -- expression 3 operands: lhs = Expression(0, Sub), rhs = Zero -- expression 4 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 7 - Code(Counter(0)) at (prev + 33, 43) to (start + 1, 33) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15) = (c0 - c1) - Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19) -- Code(Expression(1, Add)) at (prev + 0, 18) to (start + 0, 19) - = ((c0 - c1) + Zero) -- Code(Expression(2, Add)) at (prev + 0, 84) to (start + 0, 85) - = (c1 + Zero) -- Code(Expression(3, Add)) at (prev + 2, 9) to (start + 2, 11) - = ((c0 - c1) + Zero) -- Code(Expression(4, Add)) at (prev + 3, 1) to (start + 0, 2) +- Code(Expression(0, Sub)) at (prev + 0, 18) to (start + 0, 19) + = (c0 - c1) +- Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85) +- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11) + = (c0 - c1) +- Code(Expression(1, Add)) at (prev + 3, 1) to (start + 0, 2) = (c1 + (c0 - c1)) Function name: closure_macro_async::test::{closure#0}::{closure#0} diff --git a/tests/coverage-map/status-quo/conditions.cov-map b/tests/coverage-map/status-quo/conditions.cov-map index d82b8389b4d0..7600d2d96bdf 100644 --- a/tests/coverage-map/status-quo/conditions.cov-map +++ b/tests/coverage-map/status-quo/conditions.cov-map @@ -1,14 +1,14 @@ Function name: conditions::main -Raw bytes (793): 0x[01, 01, 90, 01, 09, 33, 37, 41, 3b, 3d, 35, 39, 05, 00, bf, 04, 09, 05, 00, 0d, 35, 26, 39, 0d, 35, 3b, 3d, 35, 39, 37, 41, 3b, 3d, 35, 39, ba, 04, 0d, bf, 04, 09, 05, 00, 03, 00, 45, 00, 87, 01, 49, 45, 00, 82, 01, 31, 87, 01, 49, 45, 00, 7e, 4d, 82, 01, 31, 87, 01, 49, 45, 00, 7a, 51, 7e, 4d, 82, 01, 31, 87, 01, 49, 45, 00, ab, 01, 55, 4d, 51, a7, 01, 59, ab, 01, 55, 4d, 51, 49, a3, 01, a7, 01, 59, ab, 01, 55, 4d, 51, 61, 00, e7, 01, 65, 61, 00, e2, 01, 2d, e7, 01, 65, 61, 00, de, 01, 69, e2, 01, 2d, e7, 01, 65, 61, 00, da, 01, 6d, de, 01, 69, e2, 01, 2d, e7, 01, 65, 61, 00, 8f, 02, 71, 69, 6d, 8b, 02, 75, 8f, 02, 71, 69, 6d, 83, 02, 00, 65, 87, 02, 8b, 02, 75, 8f, 02, 71, 69, 6d, 7d, f3, 03, f7, 03, 8d, 01, fb, 03, 89, 01, 81, 01, 85, 01, 79, 00, db, 02, 7d, 79, 00, d6, 02, 29, db, 02, 7d, 79, 00, d2, 02, 81, 01, d6, 02, 29, db, 02, 7d, 79, 00, ce, 02, 85, 01, d2, 02, 81, 01, d6, 02, 29, db, 02, 7d, 79, 00, fb, 03, 89, 01, 81, 01, 85, 01, f7, 03, 8d, 01, fb, 03, 89, 01, 81, 01, 85, 01, 11, 9b, 04, 9f, 04, 21, a3, 04, 1d, 15, 19, ef, 03, 00, 7d, f3, 03, f7, 03, 8d, 01, fb, 03, 89, 01, 81, 01, 85, 01, ef, 03, 11, 7d, f3, 03, f7, 03, 8d, 01, fb, 03, 89, 01, 81, 01, 85, 01, ea, 03, 25, ef, 03, 11, 7d, f3, 03, f7, 03, 8d, 01, fb, 03, 89, 01, 81, 01, 85, 01, e6, 03, 15, ea, 03, 25, ef, 03, 11, 7d, f3, 03, f7, 03, 8d, 01, fb, 03, 89, 01, 81, 01, 85, 01, e2, 03, 19, e6, 03, 15, ea, 03, 25, ef, 03, 11, 7d, f3, 03, f7, 03, 8d, 01, fb, 03, 89, 01, 81, 01, 85, 01, a3, 04, 1d, 15, 19, 9f, 04, 21, a3, 04, 1d, 15, 19, 97, 04, a7, 04, 11, 9b, 04, 9f, 04, 21, a3, 04, 1d, 15, 19, ab, 04, b6, 04, af, 04, b3, 04, 25, 29, 2d, 31, ba, 04, 0d, bf, 04, 09, 05, 00, 44, 01, 03, 01, 02, 0c, 05, 02, 0d, 02, 06, 00, 02, 06, 00, 07, 03, 03, 09, 00, 0a, bf, 04, 00, 10, 00, 1d, 09, 01, 09, 01, 0a, ba, 04, 02, 0f, 00, 1c, 0d, 01, 0c, 00, 19, 26, 00, 1d, 00, 2a, 22, 00, 2e, 00, 3c, 37, 00, 3d, 02, 0a, 41, 02, 0a, 00, 0b, 33, 01, 09, 01, 12, b6, 04, 03, 09, 00, 0f, 4b, 03, 09, 01, 0c, 45, 01, 0d, 02, 06, 00, 02, 06, 00, 07, 87, 01, 02, 08, 00, 15, 49, 00, 16, 02, 06, 82, 01, 02, 0f, 00, 1c, 7e, 01, 0c, 00, 19, 7a, 00, 1d, 00, 2a, 76, 00, 2e, 00, 3c, a7, 01, 00, 3d, 02, 0a, 59, 02, 0a, 00, 0b, a3, 01, 01, 09, 00, 17, 31, 02, 09, 00, 0f, 9f, 01, 03, 08, 00, 0c, 5d, 01, 0d, 01, 10, 61, 01, 11, 02, 0a, 00, 02, 0a, 00, 0b, e7, 01, 02, 0c, 00, 19, 65, 00, 1a, 02, 0a, e2, 01, 03, 11, 00, 1e, de, 01, 01, 10, 00, 1d, da, 01, 00, 21, 00, 2e, d6, 01, 00, 32, 00, 40, 8b, 02, 00, 41, 02, 0e, 75, 02, 0e, 00, 0f, 87, 02, 01, 0d, 00, 1b, 2d, 02, 0d, 00, 13, 00, 02, 06, 00, 07, ff, 01, 02, 09, 01, 0c, 79, 01, 0d, 02, 06, 00, 02, 06, 00, 07, ef, 03, 02, 09, 00, 0a, db, 02, 00, 10, 00, 1d, 7d, 00, 1e, 02, 06, d6, 02, 02, 0f, 00, 1c, d2, 02, 01, 0c, 00, 19, ce, 02, 00, 1d, 00, 2a, ca, 02, 00, 2e, 00, 3c, f7, 03, 00, 3d, 02, 0a, 8d, 01, 02, 0a, 00, 0b, f3, 03, 01, 09, 00, 17, 29, 02, 0d, 02, 0f, 97, 04, 05, 09, 00, 0a, 83, 03, 00, 10, 00, 1d, 11, 00, 1e, 02, 06, ea, 03, 02, 0f, 00, 1c, e6, 03, 01, 0c, 00, 19, e2, 03, 00, 1d, 00, 2a, de, 03, 00, 2e, 00, 3c, 9f, 04, 00, 3d, 02, 0a, 21, 02, 0a, 00, 0b, 9b, 04, 01, 09, 00, 17, 25, 02, 09, 00, 0f, 93, 04, 02, 01, 00, 02] +Raw bytes (784): 0x[01, 01, 8e, 01, 09, 33, 37, 41, 3b, 3d, 35, 39, 05, 00, b7, 04, 09, 05, 00, 0d, 35, 26, 39, 0d, 35, 3b, 3d, 35, 39, 37, 41, 3b, 3d, 35, 39, b2, 04, 0d, b7, 04, 09, 05, 00, 45, 00, 83, 01, 49, 45, 00, 7e, 31, 83, 01, 49, 45, 00, 7a, 4d, 7e, 31, 83, 01, 49, 45, 00, 76, 51, 7a, 4d, 7e, 31, 83, 01, 49, 45, 00, a7, 01, 55, 4d, 51, a3, 01, 59, a7, 01, 55, 4d, 51, 49, 9f, 01, a3, 01, 59, a7, 01, 55, 4d, 51, 61, 00, e3, 01, 65, 61, 00, de, 01, 2d, e3, 01, 65, 61, 00, da, 01, 69, de, 01, 2d, e3, 01, 65, 61, 00, d6, 01, 6d, da, 01, 69, de, 01, 2d, e3, 01, 65, 61, 00, 8b, 02, 71, 69, 6d, 87, 02, 75, 8b, 02, 71, 69, 6d, ff, 01, 00, 65, 83, 02, 87, 02, 75, 8b, 02, 71, 69, 6d, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, 79, 00, d7, 02, 7d, 79, 00, d2, 02, 29, d7, 02, 7d, 79, 00, ce, 02, 81, 01, d2, 02, 29, d7, 02, 7d, 79, 00, ca, 02, 85, 01, ce, 02, 81, 01, d2, 02, 29, d7, 02, 7d, 79, 00, f3, 03, 89, 01, 81, 01, 85, 01, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, 11, 93, 04, 97, 04, 21, 9b, 04, 1d, 15, 19, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, e2, 03, 25, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, de, 03, 15, e2, 03, 25, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, da, 03, 19, de, 03, 15, e2, 03, 25, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, 9b, 04, 1d, 15, 19, 97, 04, 21, 9b, 04, 1d, 15, 19, 8f, 04, 9f, 04, 11, 93, 04, 97, 04, 21, 9b, 04, 1d, 15, 19, a3, 04, ae, 04, a7, 04, ab, 04, 25, 29, 2d, 31, b2, 04, 0d, b7, 04, 09, 05, 00, 44, 01, 03, 01, 02, 0c, 05, 02, 0d, 02, 06, 00, 02, 06, 00, 07, 03, 03, 09, 00, 0a, b7, 04, 00, 10, 00, 1d, 09, 01, 09, 01, 0a, b2, 04, 02, 0f, 00, 1c, 0d, 01, 0c, 00, 19, 26, 00, 1d, 00, 2a, 22, 00, 2e, 00, 3c, 37, 00, 3d, 02, 0a, 41, 02, 0a, 00, 0b, 33, 01, 09, 01, 12, ae, 04, 03, 09, 00, 0f, 03, 03, 09, 01, 0c, 45, 01, 0d, 02, 06, 00, 02, 06, 00, 07, 83, 01, 02, 08, 00, 15, 49, 00, 16, 02, 06, 7e, 02, 0f, 00, 1c, 7a, 01, 0c, 00, 19, 76, 00, 1d, 00, 2a, 72, 00, 2e, 00, 3c, a3, 01, 00, 3d, 02, 0a, 59, 02, 0a, 00, 0b, 9f, 01, 01, 09, 00, 17, 31, 02, 09, 00, 0f, 9b, 01, 03, 08, 00, 0c, 5d, 01, 0d, 01, 10, 61, 01, 11, 02, 0a, 00, 02, 0a, 00, 0b, e3, 01, 02, 0c, 00, 19, 65, 00, 1a, 02, 0a, de, 01, 03, 11, 00, 1e, da, 01, 01, 10, 00, 1d, d6, 01, 00, 21, 00, 2e, d2, 01, 00, 32, 00, 40, 87, 02, 00, 41, 02, 0e, 75, 02, 0e, 00, 0f, 83, 02, 01, 0d, 00, 1b, 2d, 02, 0d, 00, 13, 00, 02, 06, 00, 07, fb, 01, 02, 09, 01, 0c, 79, 01, 0d, 02, 06, 00, 02, 06, 00, 07, e7, 03, 02, 09, 00, 0a, d7, 02, 00, 10, 00, 1d, 7d, 00, 1e, 02, 06, d2, 02, 02, 0f, 00, 1c, ce, 02, 01, 0c, 00, 19, ca, 02, 00, 1d, 00, 2a, c6, 02, 00, 2e, 00, 3c, ef, 03, 00, 3d, 02, 0a, 8d, 01, 02, 0a, 00, 0b, eb, 03, 01, 09, 00, 17, 29, 02, 0d, 02, 0f, 8f, 04, 05, 09, 00, 0a, e7, 03, 00, 10, 00, 1d, 11, 00, 1e, 02, 06, e2, 03, 02, 0f, 00, 1c, de, 03, 01, 0c, 00, 19, da, 03, 00, 1d, 00, 2a, d6, 03, 00, 2e, 00, 3c, 97, 04, 00, 3d, 02, 0a, 21, 02, 0a, 00, 0b, 93, 04, 01, 09, 00, 17, 25, 02, 09, 00, 0f, 8b, 04, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 144 +Number of expressions: 142 - expression 0 operands: lhs = Counter(2), rhs = Expression(12, Add) - expression 1 operands: lhs = Expression(13, Add), rhs = Counter(16) - expression 2 operands: lhs = Expression(14, Add), rhs = Counter(15) - expression 3 operands: lhs = Counter(13), rhs = Counter(14) - expression 4 operands: lhs = Counter(1), rhs = Zero -- expression 5 operands: lhs = Expression(143, Add), rhs = Counter(2) +- expression 5 operands: lhs = Expression(141, Add), rhs = Counter(2) - expression 6 operands: lhs = Counter(1), rhs = Zero - expression 7 operands: lhs = Counter(3), rhs = Counter(13) - expression 8 operands: lhs = Expression(9, Sub), rhs = Counter(14) @@ -18,145 +18,143 @@ Number of expressions: 144 - expression 12 operands: lhs = Expression(13, Add), rhs = Counter(16) - expression 13 operands: lhs = Expression(14, Add), rhs = Counter(15) - expression 14 operands: lhs = Counter(13), rhs = Counter(14) -- expression 15 operands: lhs = Expression(142, Sub), rhs = Counter(3) -- expression 16 operands: lhs = Expression(143, Add), rhs = Counter(2) +- expression 15 operands: lhs = Expression(140, Sub), rhs = Counter(3) +- expression 16 operands: lhs = Expression(141, Add), rhs = Counter(2) - expression 17 operands: lhs = Counter(1), rhs = Zero -- expression 18 operands: lhs = Expression(0, Add), rhs = Zero -- expression 19 operands: lhs = Counter(17), rhs = Zero -- expression 20 operands: lhs = Expression(33, Add), rhs = Counter(18) -- expression 21 operands: lhs = Counter(17), rhs = Zero -- expression 22 operands: lhs = Expression(32, Sub), rhs = Counter(12) -- expression 23 operands: lhs = Expression(33, Add), rhs = Counter(18) -- expression 24 operands: lhs = Counter(17), rhs = Zero -- expression 25 operands: lhs = Expression(31, Sub), rhs = Counter(19) -- expression 26 operands: lhs = Expression(32, Sub), rhs = Counter(12) -- expression 27 operands: lhs = Expression(33, Add), rhs = Counter(18) -- expression 28 operands: lhs = Counter(17), rhs = Zero -- expression 29 operands: lhs = Expression(30, Sub), rhs = Counter(20) -- expression 30 operands: lhs = Expression(31, Sub), rhs = Counter(19) -- expression 31 operands: lhs = Expression(32, Sub), rhs = Counter(12) -- expression 32 operands: lhs = Expression(33, Add), rhs = Counter(18) -- expression 33 operands: lhs = Counter(17), rhs = Zero -- expression 34 operands: lhs = Expression(42, Add), rhs = Counter(21) -- expression 35 operands: lhs = Counter(19), rhs = Counter(20) -- expression 36 operands: lhs = Expression(41, Add), rhs = Counter(22) -- expression 37 operands: lhs = Expression(42, Add), rhs = Counter(21) -- expression 38 operands: lhs = Counter(19), rhs = Counter(20) -- expression 39 operands: lhs = Counter(18), rhs = Expression(40, Add) -- expression 40 operands: lhs = Expression(41, Add), rhs = Counter(22) -- expression 41 operands: lhs = Expression(42, Add), rhs = Counter(21) -- expression 42 operands: lhs = Counter(19), rhs = Counter(20) -- expression 43 operands: lhs = Counter(24), rhs = Zero -- expression 44 operands: lhs = Expression(57, Add), rhs = Counter(25) -- expression 45 operands: lhs = Counter(24), rhs = Zero -- expression 46 operands: lhs = Expression(56, Sub), rhs = Counter(11) -- expression 47 operands: lhs = Expression(57, Add), rhs = Counter(25) -- expression 48 operands: lhs = Counter(24), rhs = Zero -- expression 49 operands: lhs = Expression(55, Sub), rhs = Counter(26) -- expression 50 operands: lhs = Expression(56, Sub), rhs = Counter(11) -- expression 51 operands: lhs = Expression(57, Add), rhs = Counter(25) -- expression 52 operands: lhs = Counter(24), rhs = Zero -- expression 53 operands: lhs = Expression(54, Sub), rhs = Counter(27) -- expression 54 operands: lhs = Expression(55, Sub), rhs = Counter(26) -- expression 55 operands: lhs = Expression(56, Sub), rhs = Counter(11) -- expression 56 operands: lhs = Expression(57, Add), rhs = Counter(25) -- expression 57 operands: lhs = Counter(24), rhs = Zero -- expression 58 operands: lhs = Expression(67, Add), rhs = Counter(28) -- expression 59 operands: lhs = Counter(26), rhs = Counter(27) -- expression 60 operands: lhs = Expression(66, Add), rhs = Counter(29) -- expression 61 operands: lhs = Expression(67, Add), rhs = Counter(28) -- expression 62 operands: lhs = Counter(26), rhs = Counter(27) -- expression 63 operands: lhs = Expression(64, Add), rhs = Zero -- expression 64 operands: lhs = Counter(25), rhs = Expression(65, Add) -- expression 65 operands: lhs = Expression(66, Add), rhs = Counter(29) -- expression 66 operands: lhs = Expression(67, Add), rhs = Counter(28) -- expression 67 operands: lhs = Counter(26), rhs = Counter(27) -- expression 68 operands: lhs = Counter(31), rhs = Expression(124, Add) -- expression 69 operands: lhs = Expression(125, Add), rhs = Counter(35) -- expression 70 operands: lhs = Expression(126, Add), rhs = Counter(34) -- expression 71 operands: lhs = Counter(32), rhs = Counter(33) -- expression 72 operands: lhs = Counter(30), rhs = Zero -- expression 73 operands: lhs = Expression(86, Add), rhs = Counter(31) -- expression 74 operands: lhs = Counter(30), rhs = Zero -- expression 75 operands: lhs = Expression(85, Sub), rhs = Counter(10) -- expression 76 operands: lhs = Expression(86, Add), rhs = Counter(31) -- expression 77 operands: lhs = Counter(30), rhs = Zero -- expression 78 operands: lhs = Expression(84, Sub), rhs = Counter(32) -- expression 79 operands: lhs = Expression(85, Sub), rhs = Counter(10) -- expression 80 operands: lhs = Expression(86, Add), rhs = Counter(31) -- expression 81 operands: lhs = Counter(30), rhs = Zero -- expression 82 operands: lhs = Expression(83, Sub), rhs = Counter(33) -- expression 83 operands: lhs = Expression(84, Sub), rhs = Counter(32) -- expression 84 operands: lhs = Expression(85, Sub), rhs = Counter(10) -- expression 85 operands: lhs = Expression(86, Add), rhs = Counter(31) -- expression 86 operands: lhs = Counter(30), rhs = Zero -- expression 87 operands: lhs = Expression(126, Add), rhs = Counter(34) -- expression 88 operands: lhs = Counter(32), rhs = Counter(33) -- expression 89 operands: lhs = Expression(125, Add), rhs = Counter(35) -- expression 90 operands: lhs = Expression(126, Add), rhs = Counter(34) -- expression 91 operands: lhs = Counter(32), rhs = Counter(33) -- expression 92 operands: lhs = Counter(4), rhs = Expression(134, Add) -- expression 93 operands: lhs = Expression(135, Add), rhs = Counter(8) -- expression 94 operands: lhs = Expression(136, Add), rhs = Counter(7) -- expression 95 operands: lhs = Counter(5), rhs = Counter(6) -- expression 96 operands: lhs = Expression(123, Add), rhs = Zero -- expression 97 operands: lhs = Counter(31), rhs = Expression(124, Add) -- expression 98 operands: lhs = Expression(125, Add), rhs = Counter(35) -- expression 99 operands: lhs = Expression(126, Add), rhs = Counter(34) -- expression 100 operands: lhs = Counter(32), rhs = Counter(33) -- expression 101 operands: lhs = Expression(123, Add), rhs = Counter(4) -- expression 102 operands: lhs = Counter(31), rhs = Expression(124, Add) -- expression 103 operands: lhs = Expression(125, Add), rhs = Counter(35) -- expression 104 operands: lhs = Expression(126, Add), rhs = Counter(34) -- expression 105 operands: lhs = Counter(32), rhs = Counter(33) -- expression 106 operands: lhs = Expression(122, Sub), rhs = Counter(9) -- expression 107 operands: lhs = Expression(123, Add), rhs = Counter(4) -- expression 108 operands: lhs = Counter(31), rhs = Expression(124, Add) -- expression 109 operands: lhs = Expression(125, Add), rhs = Counter(35) -- expression 110 operands: lhs = Expression(126, Add), rhs = Counter(34) -- expression 111 operands: lhs = Counter(32), rhs = Counter(33) -- expression 112 operands: lhs = Expression(121, Sub), rhs = Counter(5) -- expression 113 operands: lhs = Expression(122, Sub), rhs = Counter(9) -- expression 114 operands: lhs = Expression(123, Add), rhs = Counter(4) -- expression 115 operands: lhs = Counter(31), rhs = Expression(124, Add) -- expression 116 operands: lhs = Expression(125, Add), rhs = Counter(35) -- expression 117 operands: lhs = Expression(126, Add), rhs = Counter(34) -- expression 118 operands: lhs = Counter(32), rhs = Counter(33) -- expression 119 operands: lhs = Expression(120, Sub), rhs = Counter(6) -- expression 120 operands: lhs = Expression(121, Sub), rhs = Counter(5) -- expression 121 operands: lhs = Expression(122, Sub), rhs = Counter(9) -- expression 122 operands: lhs = Expression(123, Add), rhs = Counter(4) -- expression 123 operands: lhs = Counter(31), rhs = Expression(124, Add) -- expression 124 operands: lhs = Expression(125, Add), rhs = Counter(35) -- expression 125 operands: lhs = Expression(126, Add), rhs = Counter(34) -- expression 126 operands: lhs = Counter(32), rhs = Counter(33) -- expression 127 operands: lhs = Expression(136, Add), rhs = Counter(7) -- expression 128 operands: lhs = Counter(5), rhs = Counter(6) -- expression 129 operands: lhs = Expression(135, Add), rhs = Counter(8) -- expression 130 operands: lhs = Expression(136, Add), rhs = Counter(7) -- expression 131 operands: lhs = Counter(5), rhs = Counter(6) -- expression 132 operands: lhs = Expression(133, Add), rhs = Expression(137, Add) -- expression 133 operands: lhs = Counter(4), rhs = Expression(134, Add) -- expression 134 operands: lhs = Expression(135, Add), rhs = Counter(8) -- expression 135 operands: lhs = Expression(136, Add), rhs = Counter(7) -- expression 136 operands: lhs = Counter(5), rhs = Counter(6) -- expression 137 operands: lhs = Expression(138, Add), rhs = Expression(141, Sub) -- expression 138 operands: lhs = Expression(139, Add), rhs = Expression(140, Add) -- expression 139 operands: lhs = Counter(9), rhs = Counter(10) -- expression 140 operands: lhs = Counter(11), rhs = Counter(12) -- expression 141 operands: lhs = Expression(142, Sub), rhs = Counter(3) -- expression 142 operands: lhs = Expression(143, Add), rhs = Counter(2) -- expression 143 operands: lhs = Counter(1), rhs = Zero +- expression 18 operands: lhs = Counter(17), rhs = Zero +- expression 19 operands: lhs = Expression(32, Add), rhs = Counter(18) +- expression 20 operands: lhs = Counter(17), rhs = Zero +- expression 21 operands: lhs = Expression(31, Sub), rhs = Counter(12) +- expression 22 operands: lhs = Expression(32, Add), rhs = Counter(18) +- expression 23 operands: lhs = Counter(17), rhs = Zero +- expression 24 operands: lhs = Expression(30, Sub), rhs = Counter(19) +- expression 25 operands: lhs = Expression(31, Sub), rhs = Counter(12) +- expression 26 operands: lhs = Expression(32, Add), rhs = Counter(18) +- expression 27 operands: lhs = Counter(17), rhs = Zero +- expression 28 operands: lhs = Expression(29, Sub), rhs = Counter(20) +- expression 29 operands: lhs = Expression(30, Sub), rhs = Counter(19) +- expression 30 operands: lhs = Expression(31, Sub), rhs = Counter(12) +- expression 31 operands: lhs = Expression(32, Add), rhs = Counter(18) +- expression 32 operands: lhs = Counter(17), rhs = Zero +- expression 33 operands: lhs = Expression(41, Add), rhs = Counter(21) +- expression 34 operands: lhs = Counter(19), rhs = Counter(20) +- expression 35 operands: lhs = Expression(40, Add), rhs = Counter(22) +- expression 36 operands: lhs = Expression(41, Add), rhs = Counter(21) +- expression 37 operands: lhs = Counter(19), rhs = Counter(20) +- expression 38 operands: lhs = Counter(18), rhs = Expression(39, Add) +- expression 39 operands: lhs = Expression(40, Add), rhs = Counter(22) +- expression 40 operands: lhs = Expression(41, Add), rhs = Counter(21) +- expression 41 operands: lhs = Counter(19), rhs = Counter(20) +- expression 42 operands: lhs = Counter(24), rhs = Zero +- expression 43 operands: lhs = Expression(56, Add), rhs = Counter(25) +- expression 44 operands: lhs = Counter(24), rhs = Zero +- expression 45 operands: lhs = Expression(55, Sub), rhs = Counter(11) +- expression 46 operands: lhs = Expression(56, Add), rhs = Counter(25) +- expression 47 operands: lhs = Counter(24), rhs = Zero +- expression 48 operands: lhs = Expression(54, Sub), rhs = Counter(26) +- expression 49 operands: lhs = Expression(55, Sub), rhs = Counter(11) +- expression 50 operands: lhs = Expression(56, Add), rhs = Counter(25) +- expression 51 operands: lhs = Counter(24), rhs = Zero +- expression 52 operands: lhs = Expression(53, Sub), rhs = Counter(27) +- expression 53 operands: lhs = Expression(54, Sub), rhs = Counter(26) +- expression 54 operands: lhs = Expression(55, Sub), rhs = Counter(11) +- expression 55 operands: lhs = Expression(56, Add), rhs = Counter(25) +- expression 56 operands: lhs = Counter(24), rhs = Zero +- expression 57 operands: lhs = Expression(66, Add), rhs = Counter(28) +- expression 58 operands: lhs = Counter(26), rhs = Counter(27) +- expression 59 operands: lhs = Expression(65, Add), rhs = Counter(29) +- expression 60 operands: lhs = Expression(66, Add), rhs = Counter(28) +- expression 61 operands: lhs = Counter(26), rhs = Counter(27) +- expression 62 operands: lhs = Expression(63, Add), rhs = Zero +- expression 63 operands: lhs = Counter(25), rhs = Expression(64, Add) +- expression 64 operands: lhs = Expression(65, Add), rhs = Counter(29) +- expression 65 operands: lhs = Expression(66, Add), rhs = Counter(28) +- expression 66 operands: lhs = Counter(26), rhs = Counter(27) +- expression 67 operands: lhs = Counter(31), rhs = Expression(122, Add) +- expression 68 operands: lhs = Expression(123, Add), rhs = Counter(35) +- expression 69 operands: lhs = Expression(124, Add), rhs = Counter(34) +- expression 70 operands: lhs = Counter(32), rhs = Counter(33) +- expression 71 operands: lhs = Counter(30), rhs = Zero +- expression 72 operands: lhs = Expression(85, Add), rhs = Counter(31) +- expression 73 operands: lhs = Counter(30), rhs = Zero +- expression 74 operands: lhs = Expression(84, Sub), rhs = Counter(10) +- expression 75 operands: lhs = Expression(85, Add), rhs = Counter(31) +- expression 76 operands: lhs = Counter(30), rhs = Zero +- expression 77 operands: lhs = Expression(83, Sub), rhs = Counter(32) +- expression 78 operands: lhs = Expression(84, Sub), rhs = Counter(10) +- expression 79 operands: lhs = Expression(85, Add), rhs = Counter(31) +- expression 80 operands: lhs = Counter(30), rhs = Zero +- expression 81 operands: lhs = Expression(82, Sub), rhs = Counter(33) +- expression 82 operands: lhs = Expression(83, Sub), rhs = Counter(32) +- expression 83 operands: lhs = Expression(84, Sub), rhs = Counter(10) +- expression 84 operands: lhs = Expression(85, Add), rhs = Counter(31) +- expression 85 operands: lhs = Counter(30), rhs = Zero +- expression 86 operands: lhs = Expression(124, Add), rhs = Counter(34) +- expression 87 operands: lhs = Counter(32), rhs = Counter(33) +- expression 88 operands: lhs = Expression(123, Add), rhs = Counter(35) +- expression 89 operands: lhs = Expression(124, Add), rhs = Counter(34) +- expression 90 operands: lhs = Counter(32), rhs = Counter(33) +- expression 91 operands: lhs = Counter(4), rhs = Expression(132, Add) +- expression 92 operands: lhs = Expression(133, Add), rhs = Counter(8) +- expression 93 operands: lhs = Expression(134, Add), rhs = Counter(7) +- expression 94 operands: lhs = Counter(5), rhs = Counter(6) +- expression 95 operands: lhs = Counter(31), rhs = Expression(122, Add) +- expression 96 operands: lhs = Expression(123, Add), rhs = Counter(35) +- expression 97 operands: lhs = Expression(124, Add), rhs = Counter(34) +- expression 98 operands: lhs = Counter(32), rhs = Counter(33) +- expression 99 operands: lhs = Expression(121, Add), rhs = Counter(4) +- expression 100 operands: lhs = Counter(31), rhs = Expression(122, Add) +- expression 101 operands: lhs = Expression(123, Add), rhs = Counter(35) +- expression 102 operands: lhs = Expression(124, Add), rhs = Counter(34) +- expression 103 operands: lhs = Counter(32), rhs = Counter(33) +- expression 104 operands: lhs = Expression(120, Sub), rhs = Counter(9) +- expression 105 operands: lhs = Expression(121, Add), rhs = Counter(4) +- expression 106 operands: lhs = Counter(31), rhs = Expression(122, Add) +- expression 107 operands: lhs = Expression(123, Add), rhs = Counter(35) +- expression 108 operands: lhs = Expression(124, Add), rhs = Counter(34) +- expression 109 operands: lhs = Counter(32), rhs = Counter(33) +- expression 110 operands: lhs = Expression(119, Sub), rhs = Counter(5) +- expression 111 operands: lhs = Expression(120, Sub), rhs = Counter(9) +- expression 112 operands: lhs = Expression(121, Add), rhs = Counter(4) +- expression 113 operands: lhs = Counter(31), rhs = Expression(122, Add) +- expression 114 operands: lhs = Expression(123, Add), rhs = Counter(35) +- expression 115 operands: lhs = Expression(124, Add), rhs = Counter(34) +- expression 116 operands: lhs = Counter(32), rhs = Counter(33) +- expression 117 operands: lhs = Expression(118, Sub), rhs = Counter(6) +- expression 118 operands: lhs = Expression(119, Sub), rhs = Counter(5) +- expression 119 operands: lhs = Expression(120, Sub), rhs = Counter(9) +- expression 120 operands: lhs = Expression(121, Add), rhs = Counter(4) +- expression 121 operands: lhs = Counter(31), rhs = Expression(122, Add) +- expression 122 operands: lhs = Expression(123, Add), rhs = Counter(35) +- expression 123 operands: lhs = Expression(124, Add), rhs = Counter(34) +- expression 124 operands: lhs = Counter(32), rhs = Counter(33) +- expression 125 operands: lhs = Expression(134, Add), rhs = Counter(7) +- expression 126 operands: lhs = Counter(5), rhs = Counter(6) +- expression 127 operands: lhs = Expression(133, Add), rhs = Counter(8) +- expression 128 operands: lhs = Expression(134, Add), rhs = Counter(7) +- expression 129 operands: lhs = Counter(5), rhs = Counter(6) +- expression 130 operands: lhs = Expression(131, Add), rhs = Expression(135, Add) +- expression 131 operands: lhs = Counter(4), rhs = Expression(132, Add) +- expression 132 operands: lhs = Expression(133, Add), rhs = Counter(8) +- expression 133 operands: lhs = Expression(134, Add), rhs = Counter(7) +- expression 134 operands: lhs = Counter(5), rhs = Counter(6) +- expression 135 operands: lhs = Expression(136, Add), rhs = Expression(139, Sub) +- expression 136 operands: lhs = Expression(137, Add), rhs = Expression(138, Add) +- expression 137 operands: lhs = Counter(9), rhs = Counter(10) +- expression 138 operands: lhs = Counter(11), rhs = Counter(12) +- expression 139 operands: lhs = Expression(140, Sub), rhs = Counter(3) +- expression 140 operands: lhs = Expression(141, Add), rhs = Counter(2) +- expression 141 operands: lhs = Counter(1), rhs = Zero Number of file 0 mappings: 68 - Code(Counter(0)) at (prev + 3, 1) to (start + 2, 12) - Code(Counter(1)) at (prev + 2, 13) to (start + 2, 6) - Code(Zero) at (prev + 2, 6) to (start + 0, 7) - Code(Expression(0, Add)) at (prev + 3, 9) to (start + 0, 10) = (c2 + (((c13 + c14) + c15) + c16)) -- Code(Expression(143, Add)) at (prev + 0, 16) to (start + 0, 29) +- Code(Expression(141, Add)) at (prev + 0, 16) to (start + 0, 29) = (c1 + Zero) - Code(Counter(2)) at (prev + 1, 9) to (start + 1, 10) -- Code(Expression(142, Sub)) at (prev + 2, 15) to (start + 0, 28) +- Code(Expression(140, Sub)) at (prev + 2, 15) to (start + 0, 28) = ((c1 + Zero) - c2) - Code(Counter(3)) at (prev + 1, 12) to (start + 0, 25) - Code(Expression(9, Sub)) at (prev + 0, 29) to (start + 0, 42) @@ -168,94 +166,94 @@ Number of file 0 mappings: 68 - Code(Counter(16)) at (prev + 2, 10) to (start + 0, 11) - Code(Expression(12, Add)) at (prev + 1, 9) to (start + 1, 18) = (((c13 + c14) + c15) + c16) -- Code(Expression(141, Sub)) at (prev + 3, 9) to (start + 0, 15) +- Code(Expression(139, Sub)) at (prev + 3, 9) to (start + 0, 15) = (((c1 + Zero) - c2) - c3) -- Code(Expression(18, Add)) at (prev + 3, 9) to (start + 1, 12) - = ((c2 + (((c13 + c14) + c15) + c16)) + Zero) +- Code(Expression(0, Add)) at (prev + 3, 9) to (start + 1, 12) + = (c2 + (((c13 + c14) + c15) + c16)) - Code(Counter(17)) at (prev + 1, 13) to (start + 2, 6) - Code(Zero) at (prev + 2, 6) to (start + 0, 7) -- Code(Expression(33, Add)) at (prev + 2, 8) to (start + 0, 21) +- Code(Expression(32, Add)) at (prev + 2, 8) to (start + 0, 21) = (c17 + Zero) - Code(Counter(18)) at (prev + 0, 22) to (start + 2, 6) -- Code(Expression(32, Sub)) at (prev + 2, 15) to (start + 0, 28) +- Code(Expression(31, Sub)) at (prev + 2, 15) to (start + 0, 28) = ((c17 + Zero) - c18) -- Code(Expression(31, Sub)) at (prev + 1, 12) to (start + 0, 25) +- Code(Expression(30, Sub)) at (prev + 1, 12) to (start + 0, 25) = (((c17 + Zero) - c18) - c12) -- Code(Expression(30, Sub)) at (prev + 0, 29) to (start + 0, 42) +- Code(Expression(29, Sub)) at (prev + 0, 29) to (start + 0, 42) = ((((c17 + Zero) - c18) - c12) - c19) -- Code(Expression(29, Sub)) at (prev + 0, 46) to (start + 0, 60) +- Code(Expression(28, Sub)) at (prev + 0, 46) to (start + 0, 60) = (((((c17 + Zero) - c18) - c12) - c19) - c20) -- Code(Expression(41, Add)) at (prev + 0, 61) to (start + 2, 10) +- Code(Expression(40, Add)) at (prev + 0, 61) to (start + 2, 10) = ((c19 + c20) + c21) - Code(Counter(22)) at (prev + 2, 10) to (start + 0, 11) -- Code(Expression(40, Add)) at (prev + 1, 9) to (start + 0, 23) +- Code(Expression(39, Add)) at (prev + 1, 9) to (start + 0, 23) = (((c19 + c20) + c21) + c22) - Code(Counter(12)) at (prev + 2, 9) to (start + 0, 15) -- Code(Expression(39, Add)) at (prev + 3, 8) to (start + 0, 12) +- Code(Expression(38, Add)) at (prev + 3, 8) to (start + 0, 12) = (c18 + (((c19 + c20) + c21) + c22)) - Code(Counter(23)) at (prev + 1, 13) to (start + 1, 16) - Code(Counter(24)) at (prev + 1, 17) to (start + 2, 10) - Code(Zero) at (prev + 2, 10) to (start + 0, 11) -- Code(Expression(57, Add)) at (prev + 2, 12) to (start + 0, 25) +- Code(Expression(56, Add)) at (prev + 2, 12) to (start + 0, 25) = (c24 + Zero) - Code(Counter(25)) at (prev + 0, 26) to (start + 2, 10) -- Code(Expression(56, Sub)) at (prev + 3, 17) to (start + 0, 30) +- Code(Expression(55, Sub)) at (prev + 3, 17) to (start + 0, 30) = ((c24 + Zero) - c25) -- Code(Expression(55, Sub)) at (prev + 1, 16) to (start + 0, 29) +- Code(Expression(54, Sub)) at (prev + 1, 16) to (start + 0, 29) = (((c24 + Zero) - c25) - c11) -- Code(Expression(54, Sub)) at (prev + 0, 33) to (start + 0, 46) +- Code(Expression(53, Sub)) at (prev + 0, 33) to (start + 0, 46) = ((((c24 + Zero) - c25) - c11) - c26) -- Code(Expression(53, Sub)) at (prev + 0, 50) to (start + 0, 64) +- Code(Expression(52, Sub)) at (prev + 0, 50) to (start + 0, 64) = (((((c24 + Zero) - c25) - c11) - c26) - c27) -- Code(Expression(66, Add)) at (prev + 0, 65) to (start + 2, 14) +- Code(Expression(65, Add)) at (prev + 0, 65) to (start + 2, 14) = ((c26 + c27) + c28) - Code(Counter(29)) at (prev + 2, 14) to (start + 0, 15) -- Code(Expression(65, Add)) at (prev + 1, 13) to (start + 0, 27) +- Code(Expression(64, Add)) at (prev + 1, 13) to (start + 0, 27) = (((c26 + c27) + c28) + c29) - Code(Counter(11)) at (prev + 2, 13) to (start + 0, 19) - Code(Zero) at (prev + 2, 6) to (start + 0, 7) -- Code(Expression(63, Add)) at (prev + 2, 9) to (start + 1, 12) +- Code(Expression(62, Add)) at (prev + 2, 9) to (start + 1, 12) = ((c25 + (((c26 + c27) + c28) + c29)) + Zero) - Code(Counter(30)) at (prev + 1, 13) to (start + 2, 6) - Code(Zero) at (prev + 2, 6) to (start + 0, 7) -- Code(Expression(123, Add)) at (prev + 2, 9) to (start + 0, 10) +- Code(Expression(121, Add)) at (prev + 2, 9) to (start + 0, 10) = (c31 + (((c32 + c33) + c34) + c35)) -- Code(Expression(86, Add)) at (prev + 0, 16) to (start + 0, 29) +- Code(Expression(85, Add)) at (prev + 0, 16) to (start + 0, 29) = (c30 + Zero) - Code(Counter(31)) at (prev + 0, 30) to (start + 2, 6) -- Code(Expression(85, Sub)) at (prev + 2, 15) to (start + 0, 28) +- Code(Expression(84, Sub)) at (prev + 2, 15) to (start + 0, 28) = ((c30 + Zero) - c31) -- Code(Expression(84, Sub)) at (prev + 1, 12) to (start + 0, 25) +- Code(Expression(83, Sub)) at (prev + 1, 12) to (start + 0, 25) = (((c30 + Zero) - c31) - c10) -- Code(Expression(83, Sub)) at (prev + 0, 29) to (start + 0, 42) +- Code(Expression(82, Sub)) at (prev + 0, 29) to (start + 0, 42) = ((((c30 + Zero) - c31) - c10) - c32) -- Code(Expression(82, Sub)) at (prev + 0, 46) to (start + 0, 60) +- Code(Expression(81, Sub)) at (prev + 0, 46) to (start + 0, 60) = (((((c30 + Zero) - c31) - c10) - c32) - c33) -- Code(Expression(125, Add)) at (prev + 0, 61) to (start + 2, 10) +- Code(Expression(123, Add)) at (prev + 0, 61) to (start + 2, 10) = ((c32 + c33) + c34) - Code(Counter(35)) at (prev + 2, 10) to (start + 0, 11) -- Code(Expression(124, Add)) at (prev + 1, 9) to (start + 0, 23) +- Code(Expression(122, Add)) at (prev + 1, 9) to (start + 0, 23) = (((c32 + c33) + c34) + c35) - Code(Counter(10)) at (prev + 2, 13) to (start + 2, 15) -- Code(Expression(133, Add)) at (prev + 5, 9) to (start + 0, 10) +- Code(Expression(131, Add)) at (prev + 5, 9) to (start + 0, 10) = (c4 + (((c5 + c6) + c7) + c8)) -- Code(Expression(96, Add)) at (prev + 0, 16) to (start + 0, 29) - = ((c31 + (((c32 + c33) + c34) + c35)) + Zero) +- Code(Expression(121, Add)) at (prev + 0, 16) to (start + 0, 29) + = (c31 + (((c32 + c33) + c34) + c35)) - Code(Counter(4)) at (prev + 0, 30) to (start + 2, 6) -- Code(Expression(122, Sub)) at (prev + 2, 15) to (start + 0, 28) +- Code(Expression(120, Sub)) at (prev + 2, 15) to (start + 0, 28) = ((c31 + (((c32 + c33) + c34) + c35)) - c4) -- Code(Expression(121, Sub)) at (prev + 1, 12) to (start + 0, 25) +- Code(Expression(119, Sub)) at (prev + 1, 12) to (start + 0, 25) = (((c31 + (((c32 + c33) + c34) + c35)) - c4) - c9) -- Code(Expression(120, Sub)) at (prev + 0, 29) to (start + 0, 42) +- Code(Expression(118, Sub)) at (prev + 0, 29) to (start + 0, 42) = ((((c31 + (((c32 + c33) + c34) + c35)) - c4) - c9) - c5) -- Code(Expression(119, Sub)) at (prev + 0, 46) to (start + 0, 60) +- Code(Expression(117, Sub)) at (prev + 0, 46) to (start + 0, 60) = (((((c31 + (((c32 + c33) + c34) + c35)) - c4) - c9) - c5) - c6) -- Code(Expression(135, Add)) at (prev + 0, 61) to (start + 2, 10) +- Code(Expression(133, Add)) at (prev + 0, 61) to (start + 2, 10) = ((c5 + c6) + c7) - Code(Counter(8)) at (prev + 2, 10) to (start + 0, 11) -- Code(Expression(134, Add)) at (prev + 1, 9) to (start + 0, 23) +- Code(Expression(132, Add)) at (prev + 1, 9) to (start + 0, 23) = (((c5 + c6) + c7) + c8) - Code(Counter(9)) at (prev + 2, 9) to (start + 0, 15) -- Code(Expression(132, Add)) at (prev + 2, 1) to (start + 0, 2) +- Code(Expression(130, Add)) at (prev + 2, 1) to (start + 0, 2) = ((c4 + (((c5 + c6) + c7) + c8)) + (((c9 + c10) + (c11 + c12)) + (((c1 + Zero) - c2) - c3))) diff --git a/tests/coverage-map/status-quo/continue.cov-map b/tests/coverage-map/status-quo/continue.cov-map index c78cf293079e..82f3d7c60952 100644 --- a/tests/coverage-map/status-quo/continue.cov-map +++ b/tests/coverage-map/status-quo/continue.cov-map @@ -1,8 +1,8 @@ Function name: continue::main -Raw bytes (216): 0x[01, 01, 1f, 01, 07, 05, 09, 03, 0d, 0d, 1f, 11, 15, 1b, 19, 0d, 1f, 11, 15, 15, 00, 19, 37, 1d, 21, 33, 25, 19, 37, 1d, 21, 1d, 00, 25, 4f, 29, 2d, 4b, 31, 25, 4f, 29, 2d, 31, 67, 35, 39, 5f, 3d, 31, 67, 35, 39, 35, 39, 3d, 41, 73, 45, 3d, 41, 41, 00, 49, 45, 1e, 01, 03, 01, 03, 12, 03, 04, 0e, 00, 13, 0a, 01, 0f, 00, 16, 05, 02, 11, 00, 19, 09, 02, 12, 04, 0e, 1b, 06, 0e, 00, 13, 16, 01, 0f, 00, 16, 15, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 23, 03, 09, 00, 0e, 33, 02, 0e, 00, 13, 2e, 01, 0f, 00, 16, 1d, 01, 15, 02, 0e, 21, 04, 11, 00, 19, 3b, 03, 09, 00, 0e, 4b, 02, 0e, 00, 13, 46, 01, 0c, 00, 13, 29, 01, 0d, 00, 15, 2d, 01, 0a, 01, 0e, 5f, 03, 0e, 00, 13, 5a, 01, 0f, 00, 16, 39, 01, 16, 02, 0e, 35, 03, 12, 02, 0e, 67, 04, 09, 00, 0e, 73, 02, 0e, 00, 13, 6e, 01, 0f, 00, 16, 41, 01, 16, 02, 0e, 49, 04, 11, 00, 16, 77, 03, 09, 00, 0e, 7b, 02, 0d, 01, 02] +Raw bytes (210): 0x[01, 01, 1c, 01, 07, 05, 09, 03, 0d, 0d, 1f, 11, 15, 1b, 19, 0d, 1f, 11, 15, 19, 33, 1d, 21, 2f, 25, 19, 33, 1d, 21, 25, 47, 29, 2d, 43, 31, 25, 47, 29, 2d, 31, 5f, 35, 39, 57, 3d, 31, 5f, 35, 39, 35, 39, 3d, 41, 6b, 45, 3d, 41, 49, 45, 1e, 01, 03, 01, 03, 12, 03, 04, 0e, 00, 13, 0a, 01, 0f, 00, 16, 05, 02, 11, 00, 19, 09, 02, 12, 04, 0e, 1b, 06, 0e, 00, 13, 16, 01, 0f, 00, 16, 15, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 15, 03, 09, 00, 0e, 2f, 02, 0e, 00, 13, 2a, 01, 0f, 00, 16, 1d, 01, 15, 02, 0e, 21, 04, 11, 00, 19, 1d, 03, 09, 00, 0e, 43, 02, 0e, 00, 13, 3e, 01, 0c, 00, 13, 29, 01, 0d, 00, 15, 2d, 01, 0a, 01, 0e, 57, 03, 0e, 00, 13, 52, 01, 0f, 00, 16, 39, 01, 16, 02, 0e, 35, 03, 12, 02, 0e, 5f, 04, 09, 00, 0e, 6b, 02, 0e, 00, 13, 66, 01, 0f, 00, 16, 41, 01, 16, 02, 0e, 49, 04, 11, 00, 16, 41, 03, 09, 00, 0e, 6f, 02, 0d, 01, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 31 +Number of expressions: 28 - expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3) @@ -11,29 +11,26 @@ Number of expressions: 31 - expression 5 operands: lhs = Expression(6, Add), rhs = Counter(6) - expression 6 operands: lhs = Counter(3), rhs = Expression(7, Add) - expression 7 operands: lhs = Counter(4), rhs = Counter(5) -- expression 8 operands: lhs = Counter(5), rhs = Zero -- expression 9 operands: lhs = Counter(6), rhs = Expression(13, Add) -- expression 10 operands: lhs = Counter(7), rhs = Counter(8) -- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(9) -- expression 12 operands: lhs = Counter(6), rhs = Expression(13, Add) -- expression 13 operands: lhs = Counter(7), rhs = Counter(8) -- expression 14 operands: lhs = Counter(7), rhs = Zero -- expression 15 operands: lhs = Counter(9), rhs = Expression(19, Add) -- expression 16 operands: lhs = Counter(10), rhs = Counter(11) -- expression 17 operands: lhs = Expression(18, Add), rhs = Counter(12) -- expression 18 operands: lhs = Counter(9), rhs = Expression(19, Add) -- expression 19 operands: lhs = Counter(10), rhs = Counter(11) -- expression 20 operands: lhs = Counter(12), rhs = Expression(25, Add) -- expression 21 operands: lhs = Counter(13), rhs = Counter(14) -- expression 22 operands: lhs = Expression(23, Add), rhs = Counter(15) -- expression 23 operands: lhs = Counter(12), rhs = Expression(25, Add) -- expression 24 operands: lhs = Counter(13), rhs = Counter(14) -- expression 25 operands: lhs = Counter(13), rhs = Counter(14) +- expression 8 operands: lhs = Counter(6), rhs = Expression(12, Add) +- expression 9 operands: lhs = Counter(7), rhs = Counter(8) +- expression 10 operands: lhs = Expression(11, Add), rhs = Counter(9) +- expression 11 operands: lhs = Counter(6), rhs = Expression(12, Add) +- expression 12 operands: lhs = Counter(7), rhs = Counter(8) +- expression 13 operands: lhs = Counter(9), rhs = Expression(17, Add) +- expression 14 operands: lhs = Counter(10), rhs = Counter(11) +- expression 15 operands: lhs = Expression(16, Add), rhs = Counter(12) +- expression 16 operands: lhs = Counter(9), rhs = Expression(17, Add) +- expression 17 operands: lhs = Counter(10), rhs = Counter(11) +- expression 18 operands: lhs = Counter(12), rhs = Expression(23, Add) +- expression 19 operands: lhs = Counter(13), rhs = Counter(14) +- expression 20 operands: lhs = Expression(21, Add), rhs = Counter(15) +- expression 21 operands: lhs = Counter(12), rhs = Expression(23, Add) +- expression 22 operands: lhs = Counter(13), rhs = Counter(14) +- expression 23 operands: lhs = Counter(13), rhs = Counter(14) +- expression 24 operands: lhs = Counter(15), rhs = Counter(16) +- expression 25 operands: lhs = Expression(26, Add), rhs = Counter(17) - expression 26 operands: lhs = Counter(15), rhs = Counter(16) -- expression 27 operands: lhs = Expression(28, Add), rhs = Counter(17) -- expression 28 operands: lhs = Counter(15), rhs = Counter(16) -- expression 29 operands: lhs = Counter(16), rhs = Zero -- expression 30 operands: lhs = Counter(18), rhs = Counter(17) +- expression 27 operands: lhs = Counter(18), rhs = Counter(17) Number of file 0 mappings: 30 - Code(Counter(0)) at (prev + 3, 1) to (start + 3, 18) - Code(Expression(0, Add)) at (prev + 4, 14) to (start + 0, 19) @@ -48,38 +45,35 @@ Number of file 0 mappings: 30 = ((c3 + (c4 + c5)) - c6) - Code(Counter(5)) at (prev + 1, 22) to (start + 2, 14) - Code(Counter(4)) at (prev + 4, 17) to (start + 0, 25) -- Code(Expression(8, Add)) at (prev + 3, 9) to (start + 0, 14) - = (c5 + Zero) -- Code(Expression(12, Add)) at (prev + 2, 14) to (start + 0, 19) +- Code(Counter(5)) at (prev + 3, 9) to (start + 0, 14) +- Code(Expression(11, Add)) at (prev + 2, 14) to (start + 0, 19) = (c6 + (c7 + c8)) -- Code(Expression(11, Sub)) at (prev + 1, 15) to (start + 0, 22) +- Code(Expression(10, Sub)) at (prev + 1, 15) to (start + 0, 22) = ((c6 + (c7 + c8)) - c9) - Code(Counter(7)) at (prev + 1, 21) to (start + 2, 14) - Code(Counter(8)) at (prev + 4, 17) to (start + 0, 25) -- Code(Expression(14, Add)) at (prev + 3, 9) to (start + 0, 14) - = (c7 + Zero) -- Code(Expression(18, Add)) at (prev + 2, 14) to (start + 0, 19) +- Code(Counter(7)) at (prev + 3, 9) to (start + 0, 14) +- Code(Expression(16, Add)) at (prev + 2, 14) to (start + 0, 19) = (c9 + (c10 + c11)) -- Code(Expression(17, Sub)) at (prev + 1, 12) to (start + 0, 19) +- Code(Expression(15, Sub)) at (prev + 1, 12) to (start + 0, 19) = ((c9 + (c10 + c11)) - c12) - Code(Counter(10)) at (prev + 1, 13) to (start + 0, 21) - Code(Counter(11)) at (prev + 1, 10) to (start + 1, 14) -- Code(Expression(23, Add)) at (prev + 3, 14) to (start + 0, 19) +- Code(Expression(21, Add)) at (prev + 3, 14) to (start + 0, 19) = (c12 + (c13 + c14)) -- Code(Expression(22, Sub)) at (prev + 1, 15) to (start + 0, 22) +- Code(Expression(20, Sub)) at (prev + 1, 15) to (start + 0, 22) = ((c12 + (c13 + c14)) - c15) - Code(Counter(14)) at (prev + 1, 22) to (start + 2, 14) - Code(Counter(13)) at (prev + 3, 18) to (start + 2, 14) -- Code(Expression(25, Add)) at (prev + 4, 9) to (start + 0, 14) +- Code(Expression(23, Add)) at (prev + 4, 9) to (start + 0, 14) = (c13 + c14) -- Code(Expression(28, Add)) at (prev + 2, 14) to (start + 0, 19) +- Code(Expression(26, Add)) at (prev + 2, 14) to (start + 0, 19) = (c15 + c16) -- Code(Expression(27, Sub)) at (prev + 1, 15) to (start + 0, 22) +- Code(Expression(25, Sub)) at (prev + 1, 15) to (start + 0, 22) = ((c15 + c16) - c17) - Code(Counter(16)) at (prev + 1, 22) to (start + 2, 14) - Code(Counter(18)) at (prev + 4, 17) to (start + 0, 22) -- Code(Expression(29, Add)) at (prev + 3, 9) to (start + 0, 14) - = (c16 + Zero) -- Code(Expression(30, Add)) at (prev + 2, 13) to (start + 1, 2) +- Code(Counter(16)) at (prev + 3, 9) to (start + 0, 14) +- Code(Expression(27, Add)) at (prev + 2, 13) to (start + 1, 2) = (c18 + c17) diff --git a/tests/coverage-map/status-quo/dead_code.cov-map b/tests/coverage-map/status-quo/dead_code.cov-map index 8d5f88e63efb..0b8a40a8cde0 100644 --- a/tests/coverage-map/status-quo/dead_code.cov-map +++ b/tests/coverage-map/status-quo/dead_code.cov-map @@ -14,23 +14,23 @@ Number of file 0 mappings: 4 = (c1 + (c0 - c1)) Function name: dead_code::unused_fn (unused) -Raw bytes (24): 0x[01, 01, 00, 04, 01, 0f, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 00, 0f, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 15, 1) to (start + 7, 15) +- Code(Zero) at (prev + 15, 1) to (start + 7, 15) - Code(Zero) at (prev + 7, 16) to (start + 2, 6) - Code(Zero) at (prev + 2, 6) to (start + 0, 7) - Code(Zero) at (prev + 1, 1) to (start + 0, 2) Function name: dead_code::unused_pub_fn_not_in_library (unused) -Raw bytes (24): 0x[01, 01, 00, 04, 01, 03, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 00, 03, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 3, 1) to (start + 7, 15) +- Code(Zero) at (prev + 3, 1) to (start + 7, 15) - Code(Zero) at (prev + 7, 16) to (start + 2, 6) - Code(Zero) at (prev + 2, 6) to (start + 0, 7) - Code(Zero) at (prev + 1, 1) to (start + 0, 2) diff --git a/tests/coverage-map/status-quo/generator.cov-map b/tests/coverage-map/status-quo/generator.cov-map index a66c1af30f99..75704bcc2238 100644 --- a/tests/coverage-map/status-quo/generator.cov-map +++ b/tests/coverage-map/status-quo/generator.cov-map @@ -14,38 +14,33 @@ Number of file 0 mappings: 4 = (c1 + (c0 - c1)) Function name: generator::main -Raw bytes (71): 0x[01, 01, 0b, 01, 00, 05, 0b, 09, 0d, 11, 00, 11, 15, 2a, 19, 11, 15, 15, 19, 26, 00, 2a, 19, 11, 15, 09, 01, 0f, 01, 02, 16, 03, 07, 0b, 00, 2e, 11, 01, 2b, 00, 2d, 07, 01, 0e, 00, 35, 0f, 02, 0b, 00, 2e, 2a, 01, 22, 00, 27, 26, 00, 2c, 00, 2e, 1f, 01, 0e, 00, 35, 23, 02, 01, 00, 02] +Raw bytes (65): 0x[01, 01, 08, 05, 07, 09, 0d, 11, 15, 1e, 19, 11, 15, 15, 19, 1e, 19, 11, 15, 09, 01, 0f, 01, 02, 16, 01, 07, 0b, 00, 2e, 11, 01, 2b, 00, 2d, 03, 01, 0e, 00, 35, 11, 02, 0b, 00, 2e, 1e, 01, 22, 00, 27, 1a, 00, 2c, 00, 2e, 17, 01, 0e, 00, 35, 1a, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 11 -- expression 0 operands: lhs = Counter(0), rhs = Zero -- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add) -- expression 2 operands: lhs = Counter(2), rhs = Counter(3) -- expression 3 operands: lhs = Counter(4), rhs = Zero +Number of expressions: 8 +- expression 0 operands: lhs = Counter(1), rhs = Expression(1, Add) +- expression 1 operands: lhs = Counter(2), rhs = Counter(3) +- expression 2 operands: lhs = Counter(4), rhs = Counter(5) +- expression 3 operands: lhs = Expression(7, Sub), rhs = Counter(6) - expression 4 operands: lhs = Counter(4), rhs = Counter(5) -- expression 5 operands: lhs = Expression(10, Sub), rhs = Counter(6) -- expression 6 operands: lhs = Counter(4), rhs = Counter(5) -- expression 7 operands: lhs = Counter(5), rhs = Counter(6) -- expression 8 operands: lhs = Expression(9, Sub), rhs = Zero -- expression 9 operands: lhs = Expression(10, Sub), rhs = Counter(6) -- expression 10 operands: lhs = Counter(4), rhs = Counter(5) +- expression 5 operands: lhs = Counter(5), rhs = Counter(6) +- expression 6 operands: lhs = Expression(7, Sub), rhs = Counter(6) +- expression 7 operands: lhs = Counter(4), rhs = Counter(5) Number of file 0 mappings: 9 - Code(Counter(0)) at (prev + 15, 1) to (start + 2, 22) -- Code(Expression(0, Add)) at (prev + 7, 11) to (start + 0, 46) - = (c0 + Zero) +- Code(Counter(0)) at (prev + 7, 11) to (start + 0, 46) - Code(Counter(4)) at (prev + 1, 43) to (start + 0, 45) -- Code(Expression(1, Add)) at (prev + 1, 14) to (start + 0, 53) +- Code(Expression(0, Add)) at (prev + 1, 14) to (start + 0, 53) = (c1 + (c2 + c3)) -- Code(Expression(3, Add)) at (prev + 2, 11) to (start + 0, 46) - = (c4 + Zero) -- Code(Expression(10, Sub)) at (prev + 1, 34) to (start + 0, 39) +- Code(Counter(4)) at (prev + 2, 11) to (start + 0, 46) +- Code(Expression(7, Sub)) at (prev + 1, 34) to (start + 0, 39) = (c4 - c5) -- Code(Expression(9, Sub)) at (prev + 0, 44) to (start + 0, 46) +- Code(Expression(6, Sub)) at (prev + 0, 44) to (start + 0, 46) = ((c4 - c5) - c6) -- Code(Expression(7, Add)) at (prev + 1, 14) to (start + 0, 53) +- Code(Expression(5, Add)) at (prev + 1, 14) to (start + 0, 53) = (c5 + c6) -- Code(Expression(8, Add)) at (prev + 2, 1) to (start + 0, 2) - = (((c4 - c5) - c6) + Zero) +- Code(Expression(6, Sub)) at (prev + 2, 1) to (start + 0, 2) + = ((c4 - c5) - c6) Function name: generator::main::{closure#0} Raw bytes (14): 0x[01, 01, 00, 02, 01, 11, 1c, 01, 1f, 05, 02, 10, 01, 06] diff --git a/tests/coverage-map/status-quo/inline-dead.cov-map b/tests/coverage-map/status-quo/inline-dead.cov-map index dec43d3e8bbd..483f7ef79c63 100644 --- a/tests/coverage-map/status-quo/inline-dead.cov-map +++ b/tests/coverage-map/status-quo/inline-dead.cov-map @@ -1,10 +1,10 @@ Function name: inline_dead::dead (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 01, 19, 01, 02, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 01, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 25, 1) to (start + 2, 2) +- Code(Zero) at (prev + 25, 1) to (start + 2, 2) Function name: inline_dead::live:: Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 10, 01, 01, 09, 00, 02, 09, 00, 0f, 02, 02, 09, 00, 0a, 07, 02, 01, 00, 02] @@ -22,15 +22,13 @@ Number of file 0 mappings: 4 = (c1 + (c0 - c1)) Function name: inline_dead::main -Raw bytes (16): 0x[01, 01, 01, 01, 00, 02, 01, 04, 01, 03, 0d, 03, 07, 06, 02, 02] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 01, 03, 0d, 01, 07, 06, 02, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 1 -- expression 0 operands: lhs = Counter(0), rhs = Zero +Number of expressions: 0 Number of file 0 mappings: 2 - Code(Counter(0)) at (prev + 4, 1) to (start + 3, 13) -- Code(Expression(0, Add)) at (prev + 7, 6) to (start + 2, 2) - = (c0 + Zero) +- Code(Counter(0)) at (prev + 7, 6) to (start + 2, 2) Function name: inline_dead::main::{closure#0} Raw bytes (16): 0x[01, 01, 01, 01, 05, 02, 00, 09, 0d, 00, 0e, 03, 02, 05, 00, 06] diff --git a/tests/coverage-map/status-quo/inline.cov-map b/tests/coverage-map/status-quo/inline.cov-map index 57ae85623fb7..72b10fd0cc27 100644 --- a/tests/coverage-map/status-quo/inline.cov-map +++ b/tests/coverage-map/status-quo/inline.cov-map @@ -1,19 +1,17 @@ Function name: inline::display:: -Raw bytes (35): 0x[01, 01, 03, 01, 05, 05, 00, 03, 05, 05, 01, 29, 01, 00, 22, 05, 01, 09, 00, 0a, 03, 00, 0e, 00, 10, 07, 00, 11, 02, 06, 0a, 03, 05, 01, 02] +Raw bytes (33): 0x[01, 01, 02, 01, 05, 03, 05, 05, 01, 29, 01, 00, 22, 05, 01, 09, 00, 0a, 03, 00, 0e, 00, 10, 05, 00, 11, 02, 06, 06, 03, 05, 01, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 3 +Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Zero -- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(1) +- expression 1 operands: lhs = Expression(0, Add), rhs = Counter(1) Number of file 0 mappings: 5 - Code(Counter(0)) at (prev + 41, 1) to (start + 0, 34) - Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10) - Code(Expression(0, Add)) at (prev + 0, 14) to (start + 0, 16) = (c0 + c1) -- Code(Expression(1, Add)) at (prev + 0, 17) to (start + 2, 6) - = (c1 + Zero) -- Code(Expression(2, Sub)) at (prev + 3, 5) to (start + 1, 2) +- Code(Counter(1)) at (prev + 0, 17) to (start + 2, 6) +- Code(Expression(1, Sub)) at (prev + 3, 5) to (start + 1, 2) = ((c0 + c1) - c1) Function name: inline::error @@ -41,15 +39,14 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 5, 1) to (start + 2, 2) Function name: inline::permutate:: -Raw bytes (54): 0x[01, 01, 05, 01, 05, 02, 0d, 11, 00, 05, 13, 09, 0d, 08, 01, 0f, 01, 02, 0e, 05, 02, 0f, 02, 06, 02, 02, 0f, 00, 14, 11, 01, 0d, 00, 0e, 06, 00, 12, 00, 16, 0b, 00, 17, 04, 0a, 0d, 05, 0c, 02, 06, 0f, 03, 01, 00, 02] +Raw bytes (52): 0x[01, 01, 04, 01, 05, 02, 0d, 05, 0f, 09, 0d, 08, 01, 0f, 01, 02, 0e, 05, 02, 0f, 02, 06, 02, 02, 0f, 00, 14, 11, 01, 0d, 00, 0e, 06, 00, 12, 00, 16, 11, 00, 17, 04, 0a, 0d, 05, 0c, 02, 06, 0b, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 5 +Number of expressions: 4 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Expression(0, Sub), rhs = Counter(3) -- expression 2 operands: lhs = Counter(4), rhs = Zero -- expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add) -- expression 4 operands: lhs = Counter(2), rhs = Counter(3) +- expression 2 operands: lhs = Counter(1), rhs = Expression(3, Add) +- expression 3 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 8 - Code(Counter(0)) at (prev + 15, 1) to (start + 2, 14) - Code(Counter(1)) at (prev + 2, 15) to (start + 2, 6) @@ -58,10 +55,9 @@ Number of file 0 mappings: 8 - Code(Counter(4)) at (prev + 1, 13) to (start + 0, 14) - Code(Expression(1, Sub)) at (prev + 0, 18) to (start + 0, 22) = ((c0 - c1) - c3) -- Code(Expression(2, Add)) at (prev + 0, 23) to (start + 4, 10) - = (c4 + Zero) +- Code(Counter(4)) at (prev + 0, 23) to (start + 4, 10) - Code(Counter(3)) at (prev + 5, 12) to (start + 2, 6) -- Code(Expression(3, Add)) at (prev + 3, 1) to (start + 0, 2) +- Code(Expression(2, Add)) at (prev + 3, 1) to (start + 0, 2) = (c1 + (c2 + c3)) Function name: inline::permutations:: diff --git a/tests/coverage-map/status-quo/issue-93054.cov-map b/tests/coverage-map/status-quo/issue-93054.cov-map index 52fe7f58d15d..c2c6e9a65167 100644 --- a/tests/coverage-map/status-quo/issue-93054.cov-map +++ b/tests/coverage-map/status-quo/issue-93054.cov-map @@ -1,10 +1,10 @@ Function name: issue_93054::foo2 (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 01, 00, 1d] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 01, 00, 1d] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 29) +- Code(Zero) at (prev + 22, 1) to (start + 0, 29) Function name: issue_93054::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 1e, 01, 00, 0d] @@ -15,10 +15,10 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 30, 1) to (start + 0, 13) Function name: issue_93054::make (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 01, 02, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 1a, 01, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 26, 1) to (start + 2, 2) +- Code(Zero) at (prev + 26, 1) to (start + 2, 2) diff --git a/tests/coverage-map/status-quo/lazy_boolean.cov-map b/tests/coverage-map/status-quo/lazy_boolean.cov-map index b18a96404335..0ad393c40fa7 100644 --- a/tests/coverage-map/status-quo/lazy_boolean.cov-map +++ b/tests/coverage-map/status-quo/lazy_boolean.cov-map @@ -1,223 +1,219 @@ Function name: lazy_boolean::main -Raw bytes (646): 0x[01, 01, a8, 01, 01, 05, 09, 9a, 05, 9f, 05, 09, 05, 02, 05, 02, 9f, 05, 09, 05, 02, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 97, 05, 00, 09, 9a, 05, 9f, 05, 09, 05, 02, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 8f, 05, 00, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 87, 05, 00, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, ff, 04, 00, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 19, fa, 04, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, f7, 04, 1d, 19, fa, 04, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 1d, f2, 04, f7, 04, 1d, 19, fa, 04, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, ef, 04, 21, 1d, f2, 04, f7, 04, 1d, 19, fa, 04, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 21, ea, 04, ef, 04, 21, 1d, f2, 04, f7, 04, 1d, 19, fa, 04, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, e7, 04, 25, 21, ea, 04, ef, 04, 21, 1d, f2, 04, f7, 04, 1d, 19, fa, 04, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 25, e2, 04, e7, 04, 25, 21, ea, 04, ef, 04, 21, 1d, f2, 04, f7, 04, 1d, 19, fa, 04, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 1c, 01, 03, 01, 07, 0f, 05, 07, 10, 04, 06, 02, 04, 06, 00, 07, 97, 05, 02, 09, 00, 11, 9f, 05, 02, 0d, 00, 12, 9a, 05, 02, 0d, 00, 12, 8f, 05, 03, 09, 00, 11, 33, 02, 0d, 00, 12, 92, 05, 02, 0d, 00, 12, 87, 05, 02, 09, 00, 11, 6f, 00, 14, 00, 19, 11, 00, 1d, 00, 22, ff, 04, 01, 09, 00, 11, ab, 01, 00, 14, 00, 19, 15, 00, 1d, 00, 22, cb, 01, 04, 09, 00, 10, fa, 04, 01, 05, 03, 06, 19, 03, 06, 00, 07, f7, 04, 03, 09, 00, 10, 1d, 01, 05, 03, 06, f2, 04, 05, 05, 03, 06, ef, 04, 05, 09, 00, 10, ea, 04, 00, 11, 02, 06, 21, 02, 06, 00, 07, e7, 04, 02, 08, 00, 0f, 25, 00, 10, 02, 06, e2, 04, 02, 0c, 02, 06, df, 04, 03, 01, 00, 02] +Raw bytes (636): 0x[01, 01, a4, 01, 01, 05, 09, 8a, 05, 8f, 05, 09, 05, 02, 05, 02, 8f, 05, 09, 05, 02, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 09, 8a, 05, 8f, 05, 09, 05, 02, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 19, ea, 04, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, e7, 04, 1d, 19, ea, 04, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 1d, e2, 04, e7, 04, 1d, 19, ea, 04, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, df, 04, 21, 1d, e2, 04, e7, 04, 1d, 19, ea, 04, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 21, da, 04, df, 04, 21, 1d, e2, 04, e7, 04, 1d, 19, ea, 04, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, d7, 04, 25, 21, da, 04, df, 04, 21, 1d, e2, 04, e7, 04, 1d, 19, ea, 04, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 25, d2, 04, d7, 04, 25, 21, da, 04, df, 04, 21, 1d, e2, 04, e7, 04, 1d, 19, ea, 04, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 1c, 01, 03, 01, 07, 0f, 05, 07, 10, 04, 06, 02, 04, 06, 00, 07, 87, 05, 02, 09, 00, 11, 8f, 05, 02, 0d, 00, 12, 8a, 05, 02, 0d, 00, 12, ff, 04, 03, 09, 00, 11, 87, 05, 02, 0d, 00, 12, 82, 05, 02, 0d, 00, 12, f7, 04, 02, 09, 00, 11, ff, 04, 00, 14, 00, 19, 11, 00, 1d, 00, 22, ef, 04, 01, 09, 00, 11, f7, 04, 00, 14, 00, 19, 15, 00, 1d, 00, 22, ef, 04, 04, 09, 00, 10, ea, 04, 01, 05, 03, 06, 19, 03, 06, 00, 07, e7, 04, 03, 09, 00, 10, 1d, 01, 05, 03, 06, e2, 04, 05, 05, 03, 06, df, 04, 05, 09, 00, 10, da, 04, 00, 11, 02, 06, 21, 02, 06, 00, 07, d7, 04, 02, 08, 00, 0f, 25, 00, 10, 02, 06, d2, 04, 02, 0c, 02, 06, cf, 04, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 168 +Number of expressions: 164 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 2 operands: lhs = Expression(167, Add), rhs = Counter(2) +- expression 1 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 2 operands: lhs = Expression(163, Add), rhs = Counter(2) - expression 3 operands: lhs = Counter(1), rhs = Expression(0, Sub) - expression 4 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 5 operands: lhs = Expression(167, Add), rhs = Counter(2) +- expression 5 operands: lhs = Expression(163, Add), rhs = Counter(2) - expression 6 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 7 operands: lhs = Counter(3), rhs = Expression(164, Sub) -- expression 8 operands: lhs = Expression(165, Add), rhs = Counter(3) -- expression 9 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 10 operands: lhs = Expression(167, Add), rhs = Counter(2) +- expression 7 operands: lhs = Counter(3), rhs = Expression(160, Sub) +- expression 8 operands: lhs = Expression(161, Add), rhs = Counter(3) +- expression 9 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 10 operands: lhs = Expression(163, Add), rhs = Counter(2) - expression 11 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 12 operands: lhs = Expression(165, Add), rhs = Zero -- expression 13 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 14 operands: lhs = Expression(167, Add), rhs = Counter(2) -- expression 15 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 16 operands: lhs = Expression(165, Add), rhs = Counter(3) -- expression 17 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 18 operands: lhs = Expression(167, Add), rhs = Counter(2) -- expression 19 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 20 operands: lhs = Counter(4), rhs = Expression(162, Sub) -- expression 21 operands: lhs = Expression(163, Add), rhs = Counter(4) -- expression 22 operands: lhs = Counter(3), rhs = Expression(164, Sub) -- expression 23 operands: lhs = Expression(165, Add), rhs = Counter(3) -- expression 24 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 25 operands: lhs = Expression(167, Add), rhs = Counter(2) -- expression 26 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 27 operands: lhs = Expression(163, Add), rhs = Zero -- expression 28 operands: lhs = Counter(3), rhs = Expression(164, Sub) -- expression 29 operands: lhs = Expression(165, Add), rhs = Counter(3) -- expression 30 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 31 operands: lhs = Expression(167, Add), rhs = Counter(2) -- expression 32 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 33 operands: lhs = Counter(5), rhs = Expression(160, Sub) -- expression 34 operands: lhs = Expression(161, Add), rhs = Counter(5) -- expression 35 operands: lhs = Counter(4), rhs = Expression(162, Sub) -- expression 36 operands: lhs = Expression(163, Add), rhs = Counter(4) -- expression 37 operands: lhs = Counter(3), rhs = Expression(164, Sub) -- expression 38 operands: lhs = Expression(165, Add), rhs = Counter(3) -- expression 39 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 40 operands: lhs = Expression(167, Add), rhs = Counter(2) -- expression 41 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 42 operands: lhs = Expression(161, Add), rhs = Zero -- expression 43 operands: lhs = Counter(4), rhs = Expression(162, Sub) -- expression 44 operands: lhs = Expression(163, Add), rhs = Counter(4) -- expression 45 operands: lhs = Counter(3), rhs = Expression(164, Sub) -- expression 46 operands: lhs = Expression(165, Add), rhs = Counter(3) -- expression 47 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 48 operands: lhs = Expression(167, Add), rhs = Counter(2) -- expression 49 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 50 operands: lhs = Expression(159, Add), rhs = Zero -- expression 51 operands: lhs = Counter(5), rhs = Expression(160, Sub) -- expression 52 operands: lhs = Expression(161, Add), rhs = Counter(5) -- expression 53 operands: lhs = Counter(4), rhs = Expression(162, Sub) -- expression 54 operands: lhs = Expression(163, Add), rhs = Counter(4) -- expression 55 operands: lhs = Counter(3), rhs = Expression(164, Sub) -- expression 56 operands: lhs = Expression(165, Add), rhs = Counter(3) -- expression 57 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 58 operands: lhs = Expression(167, Add), rhs = Counter(2) -- expression 59 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 60 operands: lhs = Expression(159, Add), rhs = Counter(6) -- expression 61 operands: lhs = Counter(5), rhs = Expression(160, Sub) -- expression 62 operands: lhs = Expression(161, Add), rhs = Counter(5) -- expression 63 operands: lhs = Counter(4), rhs = Expression(162, Sub) -- expression 64 operands: lhs = Expression(163, Add), rhs = Counter(4) -- expression 65 operands: lhs = Counter(3), rhs = Expression(164, Sub) -- expression 66 operands: lhs = Expression(165, Add), rhs = Counter(3) -- expression 67 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 68 operands: lhs = Expression(167, Add), rhs = Counter(2) -- expression 69 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 70 operands: lhs = Counter(6), rhs = Expression(158, Sub) -- expression 71 operands: lhs = Expression(159, Add), rhs = Counter(6) -- expression 72 operands: lhs = Counter(5), rhs = Expression(160, Sub) -- expression 73 operands: lhs = Expression(161, Add), rhs = Counter(5) -- expression 74 operands: lhs = Counter(4), rhs = Expression(162, Sub) -- expression 75 operands: lhs = Expression(163, Add), rhs = Counter(4) -- expression 76 operands: lhs = Counter(3), rhs = Expression(164, Sub) -- expression 77 operands: lhs = Expression(165, Add), rhs = Counter(3) -- expression 78 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 79 operands: lhs = Expression(167, Add), rhs = Counter(2) -- expression 80 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 81 operands: lhs = Expression(157, Add), rhs = Counter(7) -- expression 82 operands: lhs = Counter(6), rhs = Expression(158, Sub) -- expression 83 operands: lhs = Expression(159, Add), rhs = Counter(6) -- expression 84 operands: lhs = Counter(5), rhs = Expression(160, Sub) -- expression 85 operands: lhs = Expression(161, Add), rhs = Counter(5) -- expression 86 operands: lhs = Counter(4), rhs = Expression(162, Sub) -- expression 87 operands: lhs = Expression(163, Add), rhs = Counter(4) -- expression 88 operands: lhs = Counter(3), rhs = Expression(164, Sub) -- expression 89 operands: lhs = Expression(165, Add), rhs = Counter(3) -- expression 90 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 91 operands: lhs = Expression(167, Add), rhs = Counter(2) -- expression 92 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 93 operands: lhs = Counter(7), rhs = Expression(156, Sub) -- expression 94 operands: lhs = Expression(157, Add), rhs = Counter(7) -- expression 95 operands: lhs = Counter(6), rhs = Expression(158, Sub) -- expression 96 operands: lhs = Expression(159, Add), rhs = Counter(6) -- expression 97 operands: lhs = Counter(5), rhs = Expression(160, Sub) -- expression 98 operands: lhs = Expression(161, Add), rhs = Counter(5) -- expression 99 operands: lhs = Counter(4), rhs = Expression(162, Sub) -- expression 100 operands: lhs = Expression(163, Add), rhs = Counter(4) -- expression 101 operands: lhs = Counter(3), rhs = Expression(164, Sub) -- expression 102 operands: lhs = Expression(165, Add), rhs = Counter(3) -- expression 103 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 104 operands: lhs = Expression(167, Add), rhs = Counter(2) -- expression 105 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 106 operands: lhs = Expression(155, Add), rhs = Counter(8) -- expression 107 operands: lhs = Counter(7), rhs = Expression(156, Sub) -- expression 108 operands: lhs = Expression(157, Add), rhs = Counter(7) -- expression 109 operands: lhs = Counter(6), rhs = Expression(158, Sub) -- expression 110 operands: lhs = Expression(159, Add), rhs = Counter(6) -- expression 111 operands: lhs = Counter(5), rhs = Expression(160, Sub) -- expression 112 operands: lhs = Expression(161, Add), rhs = Counter(5) -- expression 113 operands: lhs = Counter(4), rhs = Expression(162, Sub) -- expression 114 operands: lhs = Expression(163, Add), rhs = Counter(4) -- expression 115 operands: lhs = Counter(3), rhs = Expression(164, Sub) -- expression 116 operands: lhs = Expression(165, Add), rhs = Counter(3) -- expression 117 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 118 operands: lhs = Expression(167, Add), rhs = Counter(2) -- expression 119 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 120 operands: lhs = Counter(8), rhs = Expression(154, Sub) -- expression 121 operands: lhs = Expression(155, Add), rhs = Counter(8) -- expression 122 operands: lhs = Counter(7), rhs = Expression(156, Sub) -- expression 123 operands: lhs = Expression(157, Add), rhs = Counter(7) -- expression 124 operands: lhs = Counter(6), rhs = Expression(158, Sub) -- expression 125 operands: lhs = Expression(159, Add), rhs = Counter(6) -- expression 126 operands: lhs = Counter(5), rhs = Expression(160, Sub) -- expression 127 operands: lhs = Expression(161, Add), rhs = Counter(5) -- expression 128 operands: lhs = Counter(4), rhs = Expression(162, Sub) -- expression 129 operands: lhs = Expression(163, Add), rhs = Counter(4) -- expression 130 operands: lhs = Counter(3), rhs = Expression(164, Sub) -- expression 131 operands: lhs = Expression(165, Add), rhs = Counter(3) -- expression 132 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 133 operands: lhs = Expression(167, Add), rhs = Counter(2) -- expression 134 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 135 operands: lhs = Expression(153, Add), rhs = Counter(9) -- expression 136 operands: lhs = Counter(8), rhs = Expression(154, Sub) -- expression 137 operands: lhs = Expression(155, Add), rhs = Counter(8) -- expression 138 operands: lhs = Counter(7), rhs = Expression(156, Sub) -- expression 139 operands: lhs = Expression(157, Add), rhs = Counter(7) -- expression 140 operands: lhs = Counter(6), rhs = Expression(158, Sub) -- expression 141 operands: lhs = Expression(159, Add), rhs = Counter(6) -- expression 142 operands: lhs = Counter(5), rhs = Expression(160, Sub) -- expression 143 operands: lhs = Expression(161, Add), rhs = Counter(5) -- expression 144 operands: lhs = Counter(4), rhs = Expression(162, Sub) -- expression 145 operands: lhs = Expression(163, Add), rhs = Counter(4) -- expression 146 operands: lhs = Counter(3), rhs = Expression(164, Sub) -- expression 147 operands: lhs = Expression(165, Add), rhs = Counter(3) -- expression 148 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 149 operands: lhs = Expression(167, Add), rhs = Counter(2) -- expression 150 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 151 operands: lhs = Counter(9), rhs = Expression(152, Sub) -- expression 152 operands: lhs = Expression(153, Add), rhs = Counter(9) -- expression 153 operands: lhs = Counter(8), rhs = Expression(154, Sub) -- expression 154 operands: lhs = Expression(155, Add), rhs = Counter(8) -- expression 155 operands: lhs = Counter(7), rhs = Expression(156, Sub) -- expression 156 operands: lhs = Expression(157, Add), rhs = Counter(7) -- expression 157 operands: lhs = Counter(6), rhs = Expression(158, Sub) -- expression 158 operands: lhs = Expression(159, Add), rhs = Counter(6) -- expression 159 operands: lhs = Counter(5), rhs = Expression(160, Sub) -- expression 160 operands: lhs = Expression(161, Add), rhs = Counter(5) -- expression 161 operands: lhs = Counter(4), rhs = Expression(162, Sub) -- expression 162 operands: lhs = Expression(163, Add), rhs = Counter(4) -- expression 163 operands: lhs = Counter(3), rhs = Expression(164, Sub) -- expression 164 operands: lhs = Expression(165, Add), rhs = Counter(3) -- expression 165 operands: lhs = Counter(2), rhs = Expression(166, Sub) -- expression 166 operands: lhs = Expression(167, Add), rhs = Counter(2) -- expression 167 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 12 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 13 operands: lhs = Expression(163, Add), rhs = Counter(2) +- expression 14 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 15 operands: lhs = Expression(161, Add), rhs = Counter(3) +- expression 16 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 17 operands: lhs = Expression(163, Add), rhs = Counter(2) +- expression 18 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 19 operands: lhs = Counter(4), rhs = Expression(158, Sub) +- expression 20 operands: lhs = Expression(159, Add), rhs = Counter(4) +- expression 21 operands: lhs = Counter(3), rhs = Expression(160, Sub) +- expression 22 operands: lhs = Expression(161, Add), rhs = Counter(3) +- expression 23 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 24 operands: lhs = Expression(163, Add), rhs = Counter(2) +- expression 25 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 26 operands: lhs = Counter(3), rhs = Expression(160, Sub) +- expression 27 operands: lhs = Expression(161, Add), rhs = Counter(3) +- expression 28 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 29 operands: lhs = Expression(163, Add), rhs = Counter(2) +- expression 30 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 31 operands: lhs = Counter(5), rhs = Expression(156, Sub) +- expression 32 operands: lhs = Expression(157, Add), rhs = Counter(5) +- expression 33 operands: lhs = Counter(4), rhs = Expression(158, Sub) +- expression 34 operands: lhs = Expression(159, Add), rhs = Counter(4) +- expression 35 operands: lhs = Counter(3), rhs = Expression(160, Sub) +- expression 36 operands: lhs = Expression(161, Add), rhs = Counter(3) +- expression 37 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 38 operands: lhs = Expression(163, Add), rhs = Counter(2) +- expression 39 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 40 operands: lhs = Counter(4), rhs = Expression(158, Sub) +- expression 41 operands: lhs = Expression(159, Add), rhs = Counter(4) +- expression 42 operands: lhs = Counter(3), rhs = Expression(160, Sub) +- expression 43 operands: lhs = Expression(161, Add), rhs = Counter(3) +- expression 44 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 45 operands: lhs = Expression(163, Add), rhs = Counter(2) +- expression 46 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 47 operands: lhs = Counter(5), rhs = Expression(156, Sub) +- expression 48 operands: lhs = Expression(157, Add), rhs = Counter(5) +- expression 49 operands: lhs = Counter(4), rhs = Expression(158, Sub) +- expression 50 operands: lhs = Expression(159, Add), rhs = Counter(4) +- expression 51 operands: lhs = Counter(3), rhs = Expression(160, Sub) +- expression 52 operands: lhs = Expression(161, Add), rhs = Counter(3) +- expression 53 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 54 operands: lhs = Expression(163, Add), rhs = Counter(2) +- expression 55 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 56 operands: lhs = Expression(155, Add), rhs = Counter(6) +- expression 57 operands: lhs = Counter(5), rhs = Expression(156, Sub) +- expression 58 operands: lhs = Expression(157, Add), rhs = Counter(5) +- expression 59 operands: lhs = Counter(4), rhs = Expression(158, Sub) +- expression 60 operands: lhs = Expression(159, Add), rhs = Counter(4) +- expression 61 operands: lhs = Counter(3), rhs = Expression(160, Sub) +- expression 62 operands: lhs = Expression(161, Add), rhs = Counter(3) +- expression 63 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 64 operands: lhs = Expression(163, Add), rhs = Counter(2) +- expression 65 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 66 operands: lhs = Counter(6), rhs = Expression(154, Sub) +- expression 67 operands: lhs = Expression(155, Add), rhs = Counter(6) +- expression 68 operands: lhs = Counter(5), rhs = Expression(156, Sub) +- expression 69 operands: lhs = Expression(157, Add), rhs = Counter(5) +- expression 70 operands: lhs = Counter(4), rhs = Expression(158, Sub) +- expression 71 operands: lhs = Expression(159, Add), rhs = Counter(4) +- expression 72 operands: lhs = Counter(3), rhs = Expression(160, Sub) +- expression 73 operands: lhs = Expression(161, Add), rhs = Counter(3) +- expression 74 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 75 operands: lhs = Expression(163, Add), rhs = Counter(2) +- expression 76 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 77 operands: lhs = Expression(153, Add), rhs = Counter(7) +- expression 78 operands: lhs = Counter(6), rhs = Expression(154, Sub) +- expression 79 operands: lhs = Expression(155, Add), rhs = Counter(6) +- expression 80 operands: lhs = Counter(5), rhs = Expression(156, Sub) +- expression 81 operands: lhs = Expression(157, Add), rhs = Counter(5) +- expression 82 operands: lhs = Counter(4), rhs = Expression(158, Sub) +- expression 83 operands: lhs = Expression(159, Add), rhs = Counter(4) +- expression 84 operands: lhs = Counter(3), rhs = Expression(160, Sub) +- expression 85 operands: lhs = Expression(161, Add), rhs = Counter(3) +- expression 86 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 87 operands: lhs = Expression(163, Add), rhs = Counter(2) +- expression 88 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 89 operands: lhs = Counter(7), rhs = Expression(152, Sub) +- expression 90 operands: lhs = Expression(153, Add), rhs = Counter(7) +- expression 91 operands: lhs = Counter(6), rhs = Expression(154, Sub) +- expression 92 operands: lhs = Expression(155, Add), rhs = Counter(6) +- expression 93 operands: lhs = Counter(5), rhs = Expression(156, Sub) +- expression 94 operands: lhs = Expression(157, Add), rhs = Counter(5) +- expression 95 operands: lhs = Counter(4), rhs = Expression(158, Sub) +- expression 96 operands: lhs = Expression(159, Add), rhs = Counter(4) +- expression 97 operands: lhs = Counter(3), rhs = Expression(160, Sub) +- expression 98 operands: lhs = Expression(161, Add), rhs = Counter(3) +- expression 99 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 100 operands: lhs = Expression(163, Add), rhs = Counter(2) +- expression 101 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 102 operands: lhs = Expression(151, Add), rhs = Counter(8) +- expression 103 operands: lhs = Counter(7), rhs = Expression(152, Sub) +- expression 104 operands: lhs = Expression(153, Add), rhs = Counter(7) +- expression 105 operands: lhs = Counter(6), rhs = Expression(154, Sub) +- expression 106 operands: lhs = Expression(155, Add), rhs = Counter(6) +- expression 107 operands: lhs = Counter(5), rhs = Expression(156, Sub) +- expression 108 operands: lhs = Expression(157, Add), rhs = Counter(5) +- expression 109 operands: lhs = Counter(4), rhs = Expression(158, Sub) +- expression 110 operands: lhs = Expression(159, Add), rhs = Counter(4) +- expression 111 operands: lhs = Counter(3), rhs = Expression(160, Sub) +- expression 112 operands: lhs = Expression(161, Add), rhs = Counter(3) +- expression 113 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 114 operands: lhs = Expression(163, Add), rhs = Counter(2) +- expression 115 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 116 operands: lhs = Counter(8), rhs = Expression(150, Sub) +- expression 117 operands: lhs = Expression(151, Add), rhs = Counter(8) +- expression 118 operands: lhs = Counter(7), rhs = Expression(152, Sub) +- expression 119 operands: lhs = Expression(153, Add), rhs = Counter(7) +- expression 120 operands: lhs = Counter(6), rhs = Expression(154, Sub) +- expression 121 operands: lhs = Expression(155, Add), rhs = Counter(6) +- expression 122 operands: lhs = Counter(5), rhs = Expression(156, Sub) +- expression 123 operands: lhs = Expression(157, Add), rhs = Counter(5) +- expression 124 operands: lhs = Counter(4), rhs = Expression(158, Sub) +- expression 125 operands: lhs = Expression(159, Add), rhs = Counter(4) +- expression 126 operands: lhs = Counter(3), rhs = Expression(160, Sub) +- expression 127 operands: lhs = Expression(161, Add), rhs = Counter(3) +- expression 128 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 129 operands: lhs = Expression(163, Add), rhs = Counter(2) +- expression 130 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 131 operands: lhs = Expression(149, Add), rhs = Counter(9) +- expression 132 operands: lhs = Counter(8), rhs = Expression(150, Sub) +- expression 133 operands: lhs = Expression(151, Add), rhs = Counter(8) +- expression 134 operands: lhs = Counter(7), rhs = Expression(152, Sub) +- expression 135 operands: lhs = Expression(153, Add), rhs = Counter(7) +- expression 136 operands: lhs = Counter(6), rhs = Expression(154, Sub) +- expression 137 operands: lhs = Expression(155, Add), rhs = Counter(6) +- expression 138 operands: lhs = Counter(5), rhs = Expression(156, Sub) +- expression 139 operands: lhs = Expression(157, Add), rhs = Counter(5) +- expression 140 operands: lhs = Counter(4), rhs = Expression(158, Sub) +- expression 141 operands: lhs = Expression(159, Add), rhs = Counter(4) +- expression 142 operands: lhs = Counter(3), rhs = Expression(160, Sub) +- expression 143 operands: lhs = Expression(161, Add), rhs = Counter(3) +- expression 144 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 145 operands: lhs = Expression(163, Add), rhs = Counter(2) +- expression 146 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 147 operands: lhs = Counter(9), rhs = Expression(148, Sub) +- expression 148 operands: lhs = Expression(149, Add), rhs = Counter(9) +- expression 149 operands: lhs = Counter(8), rhs = Expression(150, Sub) +- expression 150 operands: lhs = Expression(151, Add), rhs = Counter(8) +- expression 151 operands: lhs = Counter(7), rhs = Expression(152, Sub) +- expression 152 operands: lhs = Expression(153, Add), rhs = Counter(7) +- expression 153 operands: lhs = Counter(6), rhs = Expression(154, Sub) +- expression 154 operands: lhs = Expression(155, Add), rhs = Counter(6) +- expression 155 operands: lhs = Counter(5), rhs = Expression(156, Sub) +- expression 156 operands: lhs = Expression(157, Add), rhs = Counter(5) +- expression 157 operands: lhs = Counter(4), rhs = Expression(158, Sub) +- expression 158 operands: lhs = Expression(159, Add), rhs = Counter(4) +- expression 159 operands: lhs = Counter(3), rhs = Expression(160, Sub) +- expression 160 operands: lhs = Expression(161, Add), rhs = Counter(3) +- expression 161 operands: lhs = Counter(2), rhs = Expression(162, Sub) +- expression 162 operands: lhs = Expression(163, Add), rhs = Counter(2) +- expression 163 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 28 - Code(Counter(0)) at (prev + 3, 1) to (start + 7, 15) - Code(Counter(1)) at (prev + 7, 16) to (start + 4, 6) - Code(Expression(0, Sub)) at (prev + 4, 6) to (start + 0, 7) = (c0 - c1) -- Code(Expression(165, Add)) at (prev + 2, 9) to (start + 0, 17) +- Code(Expression(161, Add)) at (prev + 2, 9) to (start + 0, 17) = (c2 + ((c1 + (c0 - c1)) - c2)) -- Code(Expression(167, Add)) at (prev + 2, 13) to (start + 0, 18) +- Code(Expression(163, Add)) at (prev + 2, 13) to (start + 0, 18) = (c1 + (c0 - c1)) -- Code(Expression(166, Sub)) at (prev + 2, 13) to (start + 0, 18) +- Code(Expression(162, Sub)) at (prev + 2, 13) to (start + 0, 18) = ((c1 + (c0 - c1)) - c2) -- Code(Expression(163, Add)) at (prev + 3, 9) to (start + 0, 17) +- Code(Expression(159, Add)) at (prev + 3, 9) to (start + 0, 17) = (c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) -- Code(Expression(12, Add)) at (prev + 2, 13) to (start + 0, 18) - = ((c2 + ((c1 + (c0 - c1)) - c2)) + Zero) -- Code(Expression(164, Sub)) at (prev + 2, 13) to (start + 0, 18) +- Code(Expression(161, Add)) at (prev + 2, 13) to (start + 0, 18) + = (c2 + ((c1 + (c0 - c1)) - c2)) +- Code(Expression(160, Sub)) at (prev + 2, 13) to (start + 0, 18) = ((c2 + ((c1 + (c0 - c1)) - c2)) - c3) -- Code(Expression(161, Add)) at (prev + 2, 9) to (start + 0, 17) +- Code(Expression(157, Add)) at (prev + 2, 9) to (start + 0, 17) = (c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) -- Code(Expression(27, Add)) at (prev + 0, 20) to (start + 0, 25) - = ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) + Zero) +- Code(Expression(159, Add)) at (prev + 0, 20) to (start + 0, 25) + = (c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - Code(Counter(4)) at (prev + 0, 29) to (start + 0, 34) -- Code(Expression(159, Add)) at (prev + 1, 9) to (start + 0, 17) +- Code(Expression(155, Add)) at (prev + 1, 9) to (start + 0, 17) = (c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) -- Code(Expression(42, Add)) at (prev + 0, 20) to (start + 0, 25) - = ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) + Zero) +- Code(Expression(157, Add)) at (prev + 0, 20) to (start + 0, 25) + = (c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - Code(Counter(5)) at (prev + 0, 29) to (start + 0, 34) -- Code(Expression(50, Add)) at (prev + 4, 9) to (start + 0, 16) - = ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) + Zero) -- Code(Expression(158, Sub)) at (prev + 1, 5) to (start + 3, 6) +- Code(Expression(155, Add)) at (prev + 4, 9) to (start + 0, 16) + = (c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) +- Code(Expression(154, Sub)) at (prev + 1, 5) to (start + 3, 6) = ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6) - Code(Counter(6)) at (prev + 3, 6) to (start + 0, 7) -- Code(Expression(157, Add)) at (prev + 3, 9) to (start + 0, 16) +- Code(Expression(153, Add)) at (prev + 3, 9) to (start + 0, 16) = (c6 + ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6)) - Code(Counter(7)) at (prev + 1, 5) to (start + 3, 6) -- Code(Expression(156, Sub)) at (prev + 5, 5) to (start + 3, 6) +- Code(Expression(152, Sub)) at (prev + 5, 5) to (start + 3, 6) = ((c6 + ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6)) - c7) -- Code(Expression(155, Add)) at (prev + 5, 9) to (start + 0, 16) +- Code(Expression(151, Add)) at (prev + 5, 9) to (start + 0, 16) = (c7 + ((c6 + ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6)) - c7)) -- Code(Expression(154, Sub)) at (prev + 0, 17) to (start + 2, 6) +- Code(Expression(150, Sub)) at (prev + 0, 17) to (start + 2, 6) = ((c7 + ((c6 + ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6)) - c7)) - c8) - Code(Counter(8)) at (prev + 2, 6) to (start + 0, 7) -- Code(Expression(153, Add)) at (prev + 2, 8) to (start + 0, 15) +- Code(Expression(149, Add)) at (prev + 2, 8) to (start + 0, 15) = (c8 + ((c7 + ((c6 + ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6)) - c7)) - c8)) - Code(Counter(9)) at (prev + 0, 16) to (start + 2, 6) -- Code(Expression(152, Sub)) at (prev + 2, 12) to (start + 2, 6) +- Code(Expression(148, Sub)) at (prev + 2, 12) to (start + 2, 6) = ((c8 + ((c7 + ((c6 + ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6)) - c7)) - c8)) - c9) -- Code(Expression(151, Add)) at (prev + 3, 1) to (start + 0, 2) +- Code(Expression(147, Add)) at (prev + 3, 1) to (start + 0, 2) = (c9 + ((c8 + ((c7 + ((c6 + ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6)) - c7)) - c8)) - c9)) diff --git a/tests/coverage-map/status-quo/loops_branches.cov-map b/tests/coverage-map/status-quo/loops_branches.cov-map index 480bbfd97957..ebace8cbd713 100644 --- a/tests/coverage-map/status-quo/loops_branches.cov-map +++ b/tests/coverage-map/status-quo/loops_branches.cov-map @@ -1,58 +1,57 @@ Function name: ::fmt -Raw bytes (251): 0x[01, 01, 32, 05, 09, 00, 02, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, c3, 01, c7, 01, 0d, 00, 11, 15, ba, 01, 00, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, ba, 01, 15, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, b6, 01, 1d, ba, 01, 15, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, 00, b2, 01, b6, 01, 1d, ba, 01, 15, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, af, 01, 11, 00, b2, 01, b6, 01, 1d, ba, 01, 15, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, 25, a7, 01, aa, 01, 19, af, 01, 11, 00, b2, 01, b6, 01, 1d, ba, 01, 15, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, 14, 01, 09, 05, 01, 10, 05, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 02, 01, 0e, 00, 0f, 07, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, ba, 01, 03, 0d, 00, 0e, bf, 01, 00, 12, 00, 17, 27, 01, 10, 00, 14, b6, 01, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, b2, 01, 01, 12, 00, 13, af, 01, 01, 11, 00, 22, aa, 01, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 19, 03, 09, 00, 0f, a3, 01, 01, 05, 00, 06] +Raw bytes (249): 0x[01, 01, 31, 05, 09, 00, 02, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 15, bf, 01, c3, 01, 0d, 00, 11, 15, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 15, b6, 01, 15, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 15, b2, 01, 1d, b6, 01, 15, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 15, 00, ae, 01, b2, 01, 1d, b6, 01, 15, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 15, ab, 01, 11, 00, ae, 01, b2, 01, 1d, b6, 01, 15, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 15, 25, a3, 01, a6, 01, 19, ab, 01, 11, 00, ae, 01, b2, 01, 1d, b6, 01, 15, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 15, 14, 01, 09, 05, 01, 10, 05, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 02, 01, 0e, 00, 0f, 07, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, b6, 01, 03, 0d, 00, 0e, bb, 01, 00, 12, 00, 17, b6, 01, 01, 10, 00, 14, b2, 01, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, ae, 01, 01, 12, 00, 13, ab, 01, 01, 11, 00, 22, a6, 01, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 19, 03, 09, 00, 0f, 9f, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => global file 1 -Number of expressions: 50 +Number of expressions: 49 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) - expression 1 operands: lhs = Zero, rhs = Expression(0, Sub) -- expression 2 operands: lhs = Expression(47, Add), rhs = Counter(6) -- expression 3 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) +- expression 2 operands: lhs = Expression(46, Add), rhs = Counter(6) +- expression 3 operands: lhs = Expression(47, Add), rhs = Expression(48, Add) - expression 4 operands: lhs = Counter(3), rhs = Zero - expression 5 operands: lhs = Counter(4), rhs = Counter(5) -- expression 6 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) +- expression 6 operands: lhs = Expression(47, Add), rhs = Expression(48, Add) - expression 7 operands: lhs = Counter(3), rhs = Zero - expression 8 operands: lhs = Counter(4), rhs = Counter(5) -- expression 9 operands: lhs = Expression(46, Sub), rhs = Zero -- expression 10 operands: lhs = Expression(47, Add), rhs = Counter(6) -- expression 11 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) -- expression 12 operands: lhs = Counter(3), rhs = Zero -- expression 13 operands: lhs = Counter(4), rhs = Counter(5) -- expression 14 operands: lhs = Expression(46, Sub), rhs = Counter(5) -- expression 15 operands: lhs = Expression(47, Add), rhs = Counter(6) -- expression 16 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) -- expression 17 operands: lhs = Counter(3), rhs = Zero -- expression 18 operands: lhs = Counter(4), rhs = Counter(5) -- expression 19 operands: lhs = Expression(45, Sub), rhs = Counter(7) -- expression 20 operands: lhs = Expression(46, Sub), rhs = Counter(5) -- expression 21 operands: lhs = Expression(47, Add), rhs = Counter(6) -- expression 22 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) -- expression 23 operands: lhs = Counter(3), rhs = Zero -- expression 24 operands: lhs = Counter(4), rhs = Counter(5) -- expression 25 operands: lhs = Zero, rhs = Expression(44, Sub) -- expression 26 operands: lhs = Expression(45, Sub), rhs = Counter(7) -- expression 27 operands: lhs = Expression(46, Sub), rhs = Counter(5) -- expression 28 operands: lhs = Expression(47, Add), rhs = Counter(6) -- expression 29 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) -- expression 30 operands: lhs = Counter(3), rhs = Zero -- expression 31 operands: lhs = Counter(4), rhs = Counter(5) -- expression 32 operands: lhs = Expression(43, Add), rhs = Counter(4) -- expression 33 operands: lhs = Zero, rhs = Expression(44, Sub) -- expression 34 operands: lhs = Expression(45, Sub), rhs = Counter(7) -- expression 35 operands: lhs = Expression(46, Sub), rhs = Counter(5) -- expression 36 operands: lhs = Expression(47, Add), rhs = Counter(6) -- expression 37 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) -- expression 38 operands: lhs = Counter(3), rhs = Zero -- expression 39 operands: lhs = Counter(4), rhs = Counter(5) -- expression 40 operands: lhs = Counter(9), rhs = Expression(41, Add) -- expression 41 operands: lhs = Expression(42, Sub), rhs = Counter(6) -- expression 42 operands: lhs = Expression(43, Add), rhs = Counter(4) -- expression 43 operands: lhs = Zero, rhs = Expression(44, Sub) -- expression 44 operands: lhs = Expression(45, Sub), rhs = Counter(7) -- expression 45 operands: lhs = Expression(46, Sub), rhs = Counter(5) -- expression 46 operands: lhs = Expression(47, Add), rhs = Counter(6) -- expression 47 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) -- expression 48 operands: lhs = Counter(3), rhs = Zero -- expression 49 operands: lhs = Counter(4), rhs = Counter(5) +- expression 9 operands: lhs = Expression(46, Add), rhs = Counter(6) +- expression 10 operands: lhs = Expression(47, Add), rhs = Expression(48, Add) +- expression 11 operands: lhs = Counter(3), rhs = Zero +- expression 12 operands: lhs = Counter(4), rhs = Counter(5) +- expression 13 operands: lhs = Expression(45, Sub), rhs = Counter(5) +- expression 14 operands: lhs = Expression(46, Add), rhs = Counter(6) +- expression 15 operands: lhs = Expression(47, Add), rhs = Expression(48, Add) +- expression 16 operands: lhs = Counter(3), rhs = Zero +- expression 17 operands: lhs = Counter(4), rhs = Counter(5) +- expression 18 operands: lhs = Expression(44, Sub), rhs = Counter(7) +- expression 19 operands: lhs = Expression(45, Sub), rhs = Counter(5) +- expression 20 operands: lhs = Expression(46, Add), rhs = Counter(6) +- expression 21 operands: lhs = Expression(47, Add), rhs = Expression(48, Add) +- expression 22 operands: lhs = Counter(3), rhs = Zero +- expression 23 operands: lhs = Counter(4), rhs = Counter(5) +- expression 24 operands: lhs = Zero, rhs = Expression(43, Sub) +- expression 25 operands: lhs = Expression(44, Sub), rhs = Counter(7) +- expression 26 operands: lhs = Expression(45, Sub), rhs = Counter(5) +- expression 27 operands: lhs = Expression(46, Add), rhs = Counter(6) +- expression 28 operands: lhs = Expression(47, Add), rhs = Expression(48, Add) +- expression 29 operands: lhs = Counter(3), rhs = Zero +- expression 30 operands: lhs = Counter(4), rhs = Counter(5) +- expression 31 operands: lhs = Expression(42, Add), rhs = Counter(4) +- expression 32 operands: lhs = Zero, rhs = Expression(43, Sub) +- expression 33 operands: lhs = Expression(44, Sub), rhs = Counter(7) +- expression 34 operands: lhs = Expression(45, Sub), rhs = Counter(5) +- expression 35 operands: lhs = Expression(46, Add), rhs = Counter(6) +- expression 36 operands: lhs = Expression(47, Add), rhs = Expression(48, Add) +- expression 37 operands: lhs = Counter(3), rhs = Zero +- expression 38 operands: lhs = Counter(4), rhs = Counter(5) +- expression 39 operands: lhs = Counter(9), rhs = Expression(40, Add) +- expression 40 operands: lhs = Expression(41, Sub), rhs = Counter(6) +- expression 41 operands: lhs = Expression(42, Add), rhs = Counter(4) +- expression 42 operands: lhs = Zero, rhs = Expression(43, Sub) +- expression 43 operands: lhs = Expression(44, Sub), rhs = Counter(7) +- expression 44 operands: lhs = Expression(45, Sub), rhs = Counter(5) +- expression 45 operands: lhs = Expression(46, Add), rhs = Counter(6) +- expression 46 operands: lhs = Expression(47, Add), rhs = Expression(48, Add) +- expression 47 operands: lhs = Counter(3), rhs = Zero +- expression 48 operands: lhs = Counter(4), rhs = Counter(5) Number of file 0 mappings: 20 - Code(Counter(0)) at (prev + 9, 5) to (start + 1, 16) - Code(Counter(1)) at (prev + 2, 16) to (start + 0, 21) @@ -64,84 +63,83 @@ Number of file 0 mappings: 20 = (Zero + (c1 - c2)) - Code(Counter(9)) at (prev + 0, 30) to (start + 0, 31) - Code(Zero) at (prev + 1, 16) to (start + 1, 10) -- Code(Expression(46, Sub)) at (prev + 3, 13) to (start + 0, 14) +- Code(Expression(45, Sub)) at (prev + 3, 13) to (start + 0, 14) = (((c3 + Zero) + (c4 + c5)) - c6) -- Code(Expression(47, Add)) at (prev + 0, 18) to (start + 0, 23) +- Code(Expression(46, Add)) at (prev + 0, 18) to (start + 0, 23) = ((c3 + Zero) + (c4 + c5)) -- Code(Expression(9, Add)) at (prev + 1, 16) to (start + 0, 20) - = ((((c3 + Zero) + (c4 + c5)) - c6) + Zero) -- Code(Expression(45, Sub)) at (prev + 1, 20) to (start + 0, 25) +- Code(Expression(45, Sub)) at (prev + 1, 16) to (start + 0, 20) + = (((c3 + Zero) + (c4 + c5)) - c6) +- Code(Expression(44, Sub)) at (prev + 1, 20) to (start + 0, 25) = ((((c3 + Zero) + (c4 + c5)) - c6) - c5) - Code(Zero) at (prev + 1, 27) to (start + 0, 31) - Code(Zero) at (prev + 0, 32) to (start + 0, 34) -- Code(Expression(44, Sub)) at (prev + 1, 18) to (start + 0, 19) +- Code(Expression(43, Sub)) at (prev + 1, 18) to (start + 0, 19) = (((((c3 + Zero) + (c4 + c5)) - c6) - c5) - c7) -- Code(Expression(43, Add)) at (prev + 1, 17) to (start + 0, 34) +- Code(Expression(42, Add)) at (prev + 1, 17) to (start + 0, 34) = (Zero + (((((c3 + Zero) + (c4 + c5)) - c6) - c5) - c7)) -- Code(Expression(42, Sub)) at (prev + 0, 34) to (start + 0, 35) +- Code(Expression(41, Sub)) at (prev + 0, 34) to (start + 0, 35) = ((Zero + (((((c3 + Zero) + (c4 + c5)) - c6) - c5) - c7)) - c4) - Code(Zero) at (prev + 1, 20) to (start + 1, 14) - Code(Counter(6)) at (prev + 3, 9) to (start + 0, 15) -- Code(Expression(40, Add)) at (prev + 1, 5) to (start + 0, 6) +- Code(Expression(39, Add)) at (prev + 1, 5) to (start + 0, 6) = (c9 + (((Zero + (((((c3 + Zero) + (c4 + c5)) - c6) - c5) - c7)) - c4) + c6)) Function name: ::fmt -Raw bytes (255): 0x[01, 01, 34, 01, 05, 02, 09, 00, 0e, 02, 09, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, c7, 01, cb, 01, 05, 0d, 11, 15, be, 01, 00, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, be, 01, 11, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, ba, 01, 1d, be, 01, 11, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, 00, b6, 01, ba, 01, 1d, be, 01, 11, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, b3, 01, 15, 00, b6, 01, ba, 01, 1d, be, 01, 11, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, ae, 01, cf, 01, b3, 01, 15, 00, b6, 01, ba, 01, 1d, be, 01, 11, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, 19, 25, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 02, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 0e, 01, 0e, 00, 0f, 0b, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, be, 01, 02, 0d, 00, 0e, c3, 01, 00, 12, 00, 17, 2f, 01, 10, 00, 15, 00, 00, 16, 01, 0e, ba, 01, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, b6, 01, 01, 12, 00, 13, b3, 01, 01, 11, 00, 22, ae, 01, 00, 22, 00, 23, 19, 03, 09, 00, 0f, ab, 01, 01, 05, 00, 06] +Raw bytes (253): 0x[01, 01, 33, 01, 05, 02, 09, 00, 0e, 02, 09, bf, 01, 19, c3, 01, c7, 01, 05, 0d, 11, 15, c3, 01, c7, 01, 05, 0d, 11, 15, bf, 01, 19, c3, 01, c7, 01, 05, 0d, 11, 15, ba, 01, 11, bf, 01, 19, c3, 01, c7, 01, 05, 0d, 11, 15, b6, 01, 1d, ba, 01, 11, bf, 01, 19, c3, 01, c7, 01, 05, 0d, 11, 15, 00, b2, 01, b6, 01, 1d, ba, 01, 11, bf, 01, 19, c3, 01, c7, 01, 05, 0d, 11, 15, af, 01, 15, 00, b2, 01, b6, 01, 1d, ba, 01, 11, bf, 01, 19, c3, 01, c7, 01, 05, 0d, 11, 15, aa, 01, cb, 01, af, 01, 15, 00, b2, 01, b6, 01, 1d, ba, 01, 11, bf, 01, 19, c3, 01, c7, 01, 05, 0d, 11, 15, 19, 25, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 02, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 0e, 01, 0e, 00, 0f, 0b, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, ba, 01, 02, 0d, 00, 0e, bf, 01, 00, 12, 00, 17, ba, 01, 01, 10, 00, 15, 00, 00, 16, 01, 0e, b6, 01, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, b2, 01, 01, 12, 00, 13, af, 01, 01, 11, 00, 22, aa, 01, 00, 22, 00, 23, 19, 03, 09, 00, 0f, a7, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => global file 1 -Number of expressions: 52 +Number of expressions: 51 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Expression(0, Sub), rhs = Counter(2) - expression 2 operands: lhs = Zero, rhs = Expression(3, Sub) - expression 3 operands: lhs = Expression(0, Sub), rhs = Counter(2) -- expression 4 operands: lhs = Expression(48, Add), rhs = Counter(6) -- expression 5 operands: lhs = Expression(49, Add), rhs = Expression(50, Add) +- expression 4 operands: lhs = Expression(47, Add), rhs = Counter(6) +- expression 5 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) - expression 6 operands: lhs = Counter(1), rhs = Counter(3) - expression 7 operands: lhs = Counter(4), rhs = Counter(5) -- expression 8 operands: lhs = Expression(49, Add), rhs = Expression(50, Add) +- expression 8 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) - expression 9 operands: lhs = Counter(1), rhs = Counter(3) - expression 10 operands: lhs = Counter(4), rhs = Counter(5) -- expression 11 operands: lhs = Expression(47, Sub), rhs = Zero -- expression 12 operands: lhs = Expression(48, Add), rhs = Counter(6) -- expression 13 operands: lhs = Expression(49, Add), rhs = Expression(50, Add) -- expression 14 operands: lhs = Counter(1), rhs = Counter(3) -- expression 15 operands: lhs = Counter(4), rhs = Counter(5) -- expression 16 operands: lhs = Expression(47, Sub), rhs = Counter(4) -- expression 17 operands: lhs = Expression(48, Add), rhs = Counter(6) -- expression 18 operands: lhs = Expression(49, Add), rhs = Expression(50, Add) -- expression 19 operands: lhs = Counter(1), rhs = Counter(3) -- expression 20 operands: lhs = Counter(4), rhs = Counter(5) -- expression 21 operands: lhs = Expression(46, Sub), rhs = Counter(7) -- expression 22 operands: lhs = Expression(47, Sub), rhs = Counter(4) -- expression 23 operands: lhs = Expression(48, Add), rhs = Counter(6) -- expression 24 operands: lhs = Expression(49, Add), rhs = Expression(50, Add) -- expression 25 operands: lhs = Counter(1), rhs = Counter(3) -- expression 26 operands: lhs = Counter(4), rhs = Counter(5) -- expression 27 operands: lhs = Zero, rhs = Expression(45, Sub) -- expression 28 operands: lhs = Expression(46, Sub), rhs = Counter(7) -- expression 29 operands: lhs = Expression(47, Sub), rhs = Counter(4) -- expression 30 operands: lhs = Expression(48, Add), rhs = Counter(6) -- expression 31 operands: lhs = Expression(49, Add), rhs = Expression(50, Add) -- expression 32 operands: lhs = Counter(1), rhs = Counter(3) -- expression 33 operands: lhs = Counter(4), rhs = Counter(5) -- expression 34 operands: lhs = Expression(44, Add), rhs = Counter(5) -- expression 35 operands: lhs = Zero, rhs = Expression(45, Sub) -- expression 36 operands: lhs = Expression(46, Sub), rhs = Counter(7) -- expression 37 operands: lhs = Expression(47, Sub), rhs = Counter(4) -- expression 38 operands: lhs = Expression(48, Add), rhs = Counter(6) -- expression 39 operands: lhs = Expression(49, Add), rhs = Expression(50, Add) -- expression 40 operands: lhs = Counter(1), rhs = Counter(3) -- expression 41 operands: lhs = Counter(4), rhs = Counter(5) -- expression 42 operands: lhs = Expression(43, Sub), rhs = Expression(51, Add) -- expression 43 operands: lhs = Expression(44, Add), rhs = Counter(5) -- expression 44 operands: lhs = Zero, rhs = Expression(45, Sub) -- expression 45 operands: lhs = Expression(46, Sub), rhs = Counter(7) -- expression 46 operands: lhs = Expression(47, Sub), rhs = Counter(4) -- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(6) -- expression 48 operands: lhs = Expression(49, Add), rhs = Expression(50, Add) -- expression 49 operands: lhs = Counter(1), rhs = Counter(3) -- expression 50 operands: lhs = Counter(4), rhs = Counter(5) -- expression 51 operands: lhs = Counter(6), rhs = Counter(9) +- expression 11 operands: lhs = Expression(47, Add), rhs = Counter(6) +- expression 12 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) +- expression 13 operands: lhs = Counter(1), rhs = Counter(3) +- expression 14 operands: lhs = Counter(4), rhs = Counter(5) +- expression 15 operands: lhs = Expression(46, Sub), rhs = Counter(4) +- expression 16 operands: lhs = Expression(47, Add), rhs = Counter(6) +- expression 17 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) +- expression 18 operands: lhs = Counter(1), rhs = Counter(3) +- expression 19 operands: lhs = Counter(4), rhs = Counter(5) +- expression 20 operands: lhs = Expression(45, Sub), rhs = Counter(7) +- expression 21 operands: lhs = Expression(46, Sub), rhs = Counter(4) +- expression 22 operands: lhs = Expression(47, Add), rhs = Counter(6) +- expression 23 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) +- expression 24 operands: lhs = Counter(1), rhs = Counter(3) +- expression 25 operands: lhs = Counter(4), rhs = Counter(5) +- expression 26 operands: lhs = Zero, rhs = Expression(44, Sub) +- expression 27 operands: lhs = Expression(45, Sub), rhs = Counter(7) +- expression 28 operands: lhs = Expression(46, Sub), rhs = Counter(4) +- expression 29 operands: lhs = Expression(47, Add), rhs = Counter(6) +- expression 30 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) +- expression 31 operands: lhs = Counter(1), rhs = Counter(3) +- expression 32 operands: lhs = Counter(4), rhs = Counter(5) +- expression 33 operands: lhs = Expression(43, Add), rhs = Counter(5) +- expression 34 operands: lhs = Zero, rhs = Expression(44, Sub) +- expression 35 operands: lhs = Expression(45, Sub), rhs = Counter(7) +- expression 36 operands: lhs = Expression(46, Sub), rhs = Counter(4) +- expression 37 operands: lhs = Expression(47, Add), rhs = Counter(6) +- expression 38 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) +- expression 39 operands: lhs = Counter(1), rhs = Counter(3) +- expression 40 operands: lhs = Counter(4), rhs = Counter(5) +- expression 41 operands: lhs = Expression(42, Sub), rhs = Expression(50, Add) +- expression 42 operands: lhs = Expression(43, Add), rhs = Counter(5) +- expression 43 operands: lhs = Zero, rhs = Expression(44, Sub) +- expression 44 operands: lhs = Expression(45, Sub), rhs = Counter(7) +- expression 45 operands: lhs = Expression(46, Sub), rhs = Counter(4) +- expression 46 operands: lhs = Expression(47, Add), rhs = Counter(6) +- expression 47 operands: lhs = Expression(48, Add), rhs = Expression(49, Add) +- expression 48 operands: lhs = Counter(1), rhs = Counter(3) +- expression 49 operands: lhs = Counter(4), rhs = Counter(5) +- expression 50 operands: lhs = Counter(6), rhs = Counter(9) Number of file 0 mappings: 20 - Code(Counter(0)) at (prev + 34, 5) to (start + 1, 17) - Code(Zero) at (prev + 1, 18) to (start + 1, 10) @@ -154,25 +152,25 @@ Number of file 0 mappings: 20 - Code(Expression(2, Add)) at (prev + 1, 13) to (start + 0, 30) = (Zero + ((c0 - c1) - c2)) - Code(Counter(9)) at (prev + 0, 30) to (start + 0, 31) -- Code(Expression(47, Sub)) at (prev + 2, 13) to (start + 0, 14) +- Code(Expression(46, Sub)) at (prev + 2, 13) to (start + 0, 14) = (((c1 + c3) + (c4 + c5)) - c6) -- Code(Expression(48, Add)) at (prev + 0, 18) to (start + 0, 23) +- Code(Expression(47, Add)) at (prev + 0, 18) to (start + 0, 23) = ((c1 + c3) + (c4 + c5)) -- Code(Expression(11, Add)) at (prev + 1, 16) to (start + 0, 21) - = ((((c1 + c3) + (c4 + c5)) - c6) + Zero) +- Code(Expression(46, Sub)) at (prev + 1, 16) to (start + 0, 21) + = (((c1 + c3) + (c4 + c5)) - c6) - Code(Zero) at (prev + 0, 22) to (start + 1, 14) -- Code(Expression(46, Sub)) at (prev + 2, 20) to (start + 0, 25) +- Code(Expression(45, Sub)) at (prev + 2, 20) to (start + 0, 25) = ((((c1 + c3) + (c4 + c5)) - c6) - c4) - Code(Zero) at (prev + 1, 27) to (start + 0, 31) - Code(Zero) at (prev + 0, 32) to (start + 0, 34) -- Code(Expression(45, Sub)) at (prev + 1, 18) to (start + 0, 19) +- Code(Expression(44, Sub)) at (prev + 1, 18) to (start + 0, 19) = (((((c1 + c3) + (c4 + c5)) - c6) - c4) - c7) -- Code(Expression(44, Add)) at (prev + 1, 17) to (start + 0, 34) +- Code(Expression(43, Add)) at (prev + 1, 17) to (start + 0, 34) = (Zero + (((((c1 + c3) + (c4 + c5)) - c6) - c4) - c7)) -- Code(Expression(43, Sub)) at (prev + 0, 34) to (start + 0, 35) +- Code(Expression(42, Sub)) at (prev + 0, 34) to (start + 0, 35) = ((Zero + (((((c1 + c3) + (c4 + c5)) - c6) - c4) - c7)) - c5) - Code(Counter(6)) at (prev + 3, 9) to (start + 0, 15) -- Code(Expression(42, Add)) at (prev + 1, 5) to (start + 0, 6) +- Code(Expression(41, Add)) at (prev + 1, 5) to (start + 0, 6) = (((Zero + (((((c1 + c3) + (c4 + c5)) - c6) - c4) - c7)) - c5) + (c6 + c9)) Function name: loops_branches::main diff --git a/tests/coverage-map/status-quo/no_cov_crate.cov-map b/tests/coverage-map/status-quo/no_cov_crate.cov-map index 7ab5995dc289..05b6448bbd24 100644 --- a/tests/coverage-map/status-quo/no_cov_crate.cov-map +++ b/tests/coverage-map/status-quo/no_cov_crate.cov-map @@ -15,12 +15,12 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 24, 1) to (start + 2, 2) Function name: no_cov_crate::add_coverage_not_called (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 02, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 1d, 01, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 29, 1) to (start + 2, 2) +- Code(Zero) at (prev + 29, 1) to (start + 2, 2) Function name: no_cov_crate::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 4d, 01, 0b, 02] diff --git a/tests/coverage-map/status-quo/partial_eq.cov-map b/tests/coverage-map/status-quo/partial_eq.cov-map index dd61cd77ab61..3549116db7ad 100644 --- a/tests/coverage-map/status-quo/partial_eq.cov-map +++ b/tests/coverage-map/status-quo/partial_eq.cov-map @@ -1,27 +1,27 @@ Function name: ::clone (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 01, 04, 0a, 00, 0f] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 04, 0a, 00, 0f] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 4, 10) to (start + 0, 15) +- Code(Zero) at (prev + 4, 10) to (start + 0, 15) Function name: ::cmp (unused) -Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 33, 00, 34, 00, 00, 35, 00, 36] +Raw bytes (14): 0x[01, 01, 00, 02, 00, 04, 33, 00, 34, 00, 00, 35, 00, 36] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 4, 51) to (start + 0, 52) +- Code(Zero) at (prev + 4, 51) to (start + 0, 52) - Code(Zero) at (prev + 0, 53) to (start + 0, 54) Function name: ::eq (unused) -Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 18, 00, 19, 00, 00, 20, 00, 21] +Raw bytes (14): 0x[01, 01, 00, 02, 00, 04, 18, 00, 19, 00, 00, 20, 00, 21] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 4, 24) to (start + 0, 25) +- Code(Zero) at (prev + 4, 24) to (start + 0, 25) - Code(Zero) at (prev + 0, 32) to (start + 0, 33) Function name: ::partial_cmp diff --git a/tests/coverage-map/status-quo/simple_loop.cov-map b/tests/coverage-map/status-quo/simple_loop.cov-map index eb49c2324ccc..f1691ffc5e6a 100644 --- a/tests/coverage-map/status-quo/simple_loop.cov-map +++ b/tests/coverage-map/status-quo/simple_loop.cov-map @@ -1,28 +1,27 @@ Function name: simple_loop::main -Raw bytes (59): 0x[01, 01, 0a, 01, 05, 27, 09, 05, 02, 23, 09, 27, 09, 05, 02, 1e, 00, 23, 09, 27, 09, 05, 02, 07, 01, 03, 01, 09, 10, 05, 0a, 05, 05, 06, 02, 05, 06, 00, 07, 23, 05, 0d, 02, 0e, 1e, 04, 0d, 00, 12, 09, 02, 0a, 03, 0a, 1b, 06, 01, 00, 02] +Raw bytes (57): 0x[01, 01, 09, 01, 05, 23, 09, 05, 02, 1f, 09, 23, 09, 05, 02, 1f, 09, 23, 09, 05, 02, 07, 01, 03, 01, 09, 10, 05, 0a, 05, 05, 06, 02, 05, 06, 00, 07, 1f, 05, 0d, 02, 0e, 1a, 04, 0d, 00, 12, 09, 02, 0a, 03, 0a, 1a, 06, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 10 +Number of expressions: 9 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Expression(9, Add), rhs = Counter(2) +- expression 1 operands: lhs = Expression(8, Add), rhs = Counter(2) - expression 2 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 3 operands: lhs = Expression(8, Add), rhs = Counter(2) -- expression 4 operands: lhs = Expression(9, Add), rhs = Counter(2) +- expression 3 operands: lhs = Expression(7, Add), rhs = Counter(2) +- expression 4 operands: lhs = Expression(8, Add), rhs = Counter(2) - expression 5 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 6 operands: lhs = Expression(7, Sub), rhs = Zero +- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(2) - expression 7 operands: lhs = Expression(8, Add), rhs = Counter(2) -- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(2) -- expression 9 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 8 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 7 - Code(Counter(0)) at (prev + 3, 1) to (start + 9, 16) - Code(Counter(1)) at (prev + 10, 5) to (start + 5, 6) - Code(Expression(0, Sub)) at (prev + 5, 6) to (start + 0, 7) = (c0 - c1) -- Code(Expression(8, Add)) at (prev + 5, 13) to (start + 2, 14) +- Code(Expression(7, Add)) at (prev + 5, 13) to (start + 2, 14) = ((c1 + (c0 - c1)) + c2) -- Code(Expression(7, Sub)) at (prev + 4, 13) to (start + 0, 18) +- Code(Expression(6, Sub)) at (prev + 4, 13) to (start + 0, 18) = (((c1 + (c0 - c1)) + c2) - c2) - Code(Counter(2)) at (prev + 2, 10) to (start + 3, 10) -- Code(Expression(6, Add)) at (prev + 6, 1) to (start + 0, 2) - = ((((c1 + (c0 - c1)) + c2) - c2) + Zero) +- Code(Expression(6, Sub)) at (prev + 6, 1) to (start + 0, 2) + = (((c1 + (c0 - c1)) + c2) - c2) diff --git a/tests/coverage-map/status-quo/simple_match.cov-map b/tests/coverage-map/status-quo/simple_match.cov-map index d5389f04b261..4a32745d2929 100644 --- a/tests/coverage-map/status-quo/simple_match.cov-map +++ b/tests/coverage-map/status-quo/simple_match.cov-map @@ -1,36 +1,33 @@ Function name: simple_match::main -Raw bytes (82): 0x[01, 01, 0e, 01, 05, 2f, 33, 05, 02, 09, 0d, 2b, 11, 2f, 33, 05, 02, 09, 0d, 26, 00, 2b, 11, 2f, 33, 05, 02, 09, 0d, 09, 00, 0a, 01, 03, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 06, 00, 07, 2b, 05, 09, 00, 0d, 26, 05, 0d, 00, 16, 09, 02, 0d, 00, 0e, 23, 02, 11, 02, 12, 37, 04, 0d, 07, 0e, 0d, 0a, 0d, 00, 0f, 11, 03, 01, 00, 02] +Raw bytes (78): 0x[01, 01, 0c, 01, 05, 2b, 2f, 05, 02, 09, 0d, 27, 11, 2b, 2f, 05, 02, 09, 0d, 27, 11, 2b, 2f, 05, 02, 09, 0d, 0a, 01, 03, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 06, 00, 07, 27, 05, 09, 00, 0d, 22, 05, 0d, 00, 16, 09, 02, 0d, 00, 0e, 22, 02, 11, 02, 12, 09, 04, 0d, 07, 0e, 0d, 0a, 0d, 00, 0f, 11, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 14 +Number of expressions: 12 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Expression(11, Add), rhs = Expression(12, Add) +- expression 1 operands: lhs = Expression(10, Add), rhs = Expression(11, Add) - expression 2 operands: lhs = Counter(1), rhs = Expression(0, Sub) - expression 3 operands: lhs = Counter(2), rhs = Counter(3) -- expression 4 operands: lhs = Expression(10, Add), rhs = Counter(4) -- expression 5 operands: lhs = Expression(11, Add), rhs = Expression(12, Add) +- expression 4 operands: lhs = Expression(9, Add), rhs = Counter(4) +- expression 5 operands: lhs = Expression(10, Add), rhs = Expression(11, Add) - expression 6 operands: lhs = Counter(1), rhs = Expression(0, Sub) - expression 7 operands: lhs = Counter(2), rhs = Counter(3) -- expression 8 operands: lhs = Expression(9, Sub), rhs = Zero -- expression 9 operands: lhs = Expression(10, Add), rhs = Counter(4) -- expression 10 operands: lhs = Expression(11, Add), rhs = Expression(12, Add) -- expression 11 operands: lhs = Counter(1), rhs = Expression(0, Sub) -- expression 12 operands: lhs = Counter(2), rhs = Counter(3) -- expression 13 operands: lhs = Counter(2), rhs = Zero +- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(4) +- expression 9 operands: lhs = Expression(10, Add), rhs = Expression(11, Add) +- expression 10 operands: lhs = Counter(1), rhs = Expression(0, Sub) +- expression 11 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 10 - Code(Counter(0)) at (prev + 3, 1) to (start + 7, 15) - Code(Counter(1)) at (prev + 7, 16) to (start + 2, 6) - Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7) = (c0 - c1) -- Code(Expression(10, Add)) at (prev + 5, 9) to (start + 0, 13) +- Code(Expression(9, Add)) at (prev + 5, 9) to (start + 0, 13) = ((c1 + (c0 - c1)) + (c2 + c3)) -- Code(Expression(9, Sub)) at (prev + 5, 13) to (start + 0, 22) +- Code(Expression(8, Sub)) at (prev + 5, 13) to (start + 0, 22) = (((c1 + (c0 - c1)) + (c2 + c3)) - c4) - Code(Counter(2)) at (prev + 2, 13) to (start + 0, 14) -- Code(Expression(8, Add)) at (prev + 2, 17) to (start + 2, 18) - = ((((c1 + (c0 - c1)) + (c2 + c3)) - c4) + Zero) -- Code(Expression(13, Add)) at (prev + 4, 13) to (start + 7, 14) - = (c2 + Zero) +- Code(Expression(8, Sub)) at (prev + 2, 17) to (start + 2, 18) + = (((c1 + (c0 - c1)) + (c2 + c3)) - c4) +- Code(Counter(2)) at (prev + 4, 13) to (start + 7, 14) - Code(Counter(3)) at (prev + 10, 13) to (start + 0, 15) - Code(Counter(4)) at (prev + 3, 1) to (start + 0, 2) diff --git a/tests/coverage-map/status-quo/test_harness.cov-map b/tests/coverage-map/status-quo/test_harness.cov-map index b0e955dd142a..6940d2e28243 100644 --- a/tests/coverage-map/status-quo/test_harness.cov-map +++ b/tests/coverage-map/status-quo/test_harness.cov-map @@ -15,10 +15,10 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 9, 1) to (start + 0, 8) Function name: test_harness::unused (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 00, 0f] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 07, 01, 00, 0f] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 15) +- Code(Zero) at (prev + 7, 1) to (start + 0, 15) diff --git a/tests/coverage-map/status-quo/try_error_result.cov-map b/tests/coverage-map/status-quo/try_error_result.cov-map index b52e78d1195a..8367103a21a4 100644 --- a/tests/coverage-map/status-quo/try_error_result.cov-map +++ b/tests/coverage-map/status-quo/try_error_result.cov-map @@ -91,136 +91,130 @@ Number of file 0 mappings: 11 = ((c4 + (c5 + c6)) + c3) Function name: try_error_result::test2 -Raw bytes (373): 0x[01, 01, 41, 01, 07, 05, 09, 03, 0d, 41, 11, 52, 15, 41, 11, 4a, 1d, 4e, 19, 52, 15, 41, 11, 4e, 00, 52, 15, 41, 11, 4e, 19, 52, 15, 41, 11, 46, 00, 4a, 1d, 4e, 19, 52, 15, 41, 11, 6a, 25, 49, 21, 49, 21, 66, 00, 6a, 25, 49, 21, 9a, 01, 2d, 9e, 01, 29, a2, 01, 41, 03, 0d, a2, 01, 41, 03, 0d, 9e, 01, 29, a2, 01, 41, 03, 0d, 96, 01, 00, 9a, 01, 2d, 9e, 01, 29, a2, 01, 41, 03, 0d, ba, 01, 35, 45, 31, 45, 31, b6, 01, 00, ba, 01, 35, 45, 31, d2, 01, 3d, 4d, 39, 4d, 39, ce, 01, 00, d2, 01, 3d, 4d, 39, db, 01, 0d, 11, df, 01, e3, 01, f3, 01, 15, e7, 01, eb, 01, ef, 01, 19, 1d, 21, 25, f7, 01, fb, 01, 29, 2d, ff, 01, 83, 02, 31, 35, 39, 3d, 28, 01, 3c, 01, 03, 17, 03, 08, 09, 00, 0e, a2, 01, 02, 09, 04, 1a, 41, 06, 0d, 00, 2f, 11, 00, 2f, 00, 30, 52, 00, 31, 03, 35, 15, 04, 11, 00, 12, 4e, 02, 11, 04, 12, 46, 05, 11, 00, 14, 2b, 00, 17, 00, 41, 19, 00, 41, 00, 42, 4a, 00, 43, 00, 5f, 1d, 00, 5f, 00, 60, 43, 01, 0d, 00, 20, 66, 01, 11, 00, 14, 49, 00, 17, 00, 41, 21, 00, 41, 00, 42, 6a, 00, 43, 00, 60, 25, 00, 60, 00, 61, 63, 01, 0d, 00, 20, 96, 01, 04, 11, 00, 14, 9e, 01, 00, 17, 00, 42, 29, 00, 42, 00, 43, 9a, 01, 00, 44, 00, 61, 2d, 00, 61, 00, 62, 93, 01, 01, 0d, 00, 20, b6, 01, 01, 11, 00, 14, 45, 00, 17, 01, 36, 31, 01, 36, 00, 37, ba, 01, 01, 12, 00, 2f, 35, 00, 2f, 00, 30, b3, 01, 01, 0d, 00, 20, ce, 01, 01, 11, 00, 14, 4d, 00, 17, 01, 36, 39, 02, 11, 00, 12, d2, 01, 01, 12, 00, 2f, 3d, 01, 11, 00, 12, cb, 01, 02, 0d, 00, 20, 0d, 03, 05, 00, 0b, d7, 01, 01, 01, 00, 02] +Raw bytes (358): 0x[01, 01, 3b, 01, 07, 05, 09, 03, 0d, 41, 11, 4a, 15, 41, 11, 42, 1d, 46, 19, 4a, 15, 41, 11, 4a, 15, 41, 11, 46, 19, 4a, 15, 41, 11, 42, 1d, 46, 19, 4a, 15, 41, 11, 5e, 25, 49, 21, 49, 21, 5e, 25, 49, 21, 8a, 01, 2d, 8e, 01, 29, 92, 01, 41, 03, 0d, 92, 01, 41, 03, 0d, 8e, 01, 29, 92, 01, 41, 03, 0d, 8a, 01, 2d, 8e, 01, 29, 92, 01, 41, 03, 0d, a6, 01, 35, 45, 31, 45, 31, a6, 01, 35, 45, 31, ba, 01, 3d, 4d, 39, 4d, 39, ba, 01, 3d, 4d, 39, c3, 01, 0d, 11, c7, 01, cb, 01, db, 01, 15, cf, 01, d3, 01, d7, 01, 19, 1d, 21, 25, df, 01, e3, 01, 29, 2d, e7, 01, eb, 01, 31, 35, 39, 3d, 28, 01, 3c, 01, 03, 17, 03, 08, 09, 00, 0e, 92, 01, 02, 09, 04, 1a, 41, 06, 0d, 00, 2f, 11, 00, 2f, 00, 30, 4a, 00, 31, 03, 35, 15, 04, 11, 00, 12, 46, 02, 11, 04, 12, 3e, 05, 11, 00, 14, 46, 00, 17, 00, 41, 19, 00, 41, 00, 42, 42, 00, 43, 00, 5f, 1d, 00, 5f, 00, 60, 3e, 01, 0d, 00, 20, 5a, 01, 11, 00, 14, 49, 00, 17, 00, 41, 21, 00, 41, 00, 42, 5e, 00, 43, 00, 60, 25, 00, 60, 00, 61, 5a, 01, 0d, 00, 20, 86, 01, 04, 11, 00, 14, 8e, 01, 00, 17, 00, 42, 29, 00, 42, 00, 43, 8a, 01, 00, 44, 00, 61, 2d, 00, 61, 00, 62, 86, 01, 01, 0d, 00, 20, a2, 01, 01, 11, 00, 14, 45, 00, 17, 01, 36, 31, 01, 36, 00, 37, a6, 01, 01, 12, 00, 2f, 35, 00, 2f, 00, 30, a2, 01, 01, 0d, 00, 20, b6, 01, 01, 11, 00, 14, 4d, 00, 17, 01, 36, 39, 02, 11, 00, 12, ba, 01, 01, 12, 00, 2f, 3d, 01, 11, 00, 12, b6, 01, 02, 0d, 00, 20, 0d, 03, 05, 00, 0b, bf, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 65 +Number of expressions: 59 - expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3) - expression 3 operands: lhs = Counter(16), rhs = Counter(4) -- expression 4 operands: lhs = Expression(20, Sub), rhs = Counter(5) +- expression 4 operands: lhs = Expression(18, Sub), rhs = Counter(5) - expression 5 operands: lhs = Counter(16), rhs = Counter(4) -- expression 6 operands: lhs = Expression(18, Sub), rhs = Counter(7) -- expression 7 operands: lhs = Expression(19, Sub), rhs = Counter(6) -- expression 8 operands: lhs = Expression(20, Sub), rhs = Counter(5) +- expression 6 operands: lhs = Expression(16, Sub), rhs = Counter(7) +- expression 7 operands: lhs = Expression(17, Sub), rhs = Counter(6) +- expression 8 operands: lhs = Expression(18, Sub), rhs = Counter(5) - expression 9 operands: lhs = Counter(16), rhs = Counter(4) -- expression 10 operands: lhs = Expression(19, Sub), rhs = Zero -- expression 11 operands: lhs = Expression(20, Sub), rhs = Counter(5) -- expression 12 operands: lhs = Counter(16), rhs = Counter(4) -- expression 13 operands: lhs = Expression(19, Sub), rhs = Counter(6) -- expression 14 operands: lhs = Expression(20, Sub), rhs = Counter(5) -- expression 15 operands: lhs = Counter(16), rhs = Counter(4) -- expression 16 operands: lhs = Expression(17, Sub), rhs = Zero -- expression 17 operands: lhs = Expression(18, Sub), rhs = Counter(7) -- expression 18 operands: lhs = Expression(19, Sub), rhs = Counter(6) -- expression 19 operands: lhs = Expression(20, Sub), rhs = Counter(5) -- expression 20 operands: lhs = Counter(16), rhs = Counter(4) -- expression 21 operands: lhs = Expression(26, Sub), rhs = Counter(9) -- expression 22 operands: lhs = Counter(18), rhs = Counter(8) +- expression 10 operands: lhs = Expression(18, Sub), rhs = Counter(5) +- expression 11 operands: lhs = Counter(16), rhs = Counter(4) +- expression 12 operands: lhs = Expression(17, Sub), rhs = Counter(6) +- expression 13 operands: lhs = Expression(18, Sub), rhs = Counter(5) +- expression 14 operands: lhs = Counter(16), rhs = Counter(4) +- expression 15 operands: lhs = Expression(16, Sub), rhs = Counter(7) +- expression 16 operands: lhs = Expression(17, Sub), rhs = Counter(6) +- expression 17 operands: lhs = Expression(18, Sub), rhs = Counter(5) +- expression 18 operands: lhs = Counter(16), rhs = Counter(4) +- expression 19 operands: lhs = Expression(23, Sub), rhs = Counter(9) +- expression 20 operands: lhs = Counter(18), rhs = Counter(8) +- expression 21 operands: lhs = Counter(18), rhs = Counter(8) +- expression 22 operands: lhs = Expression(23, Sub), rhs = Counter(9) - expression 23 operands: lhs = Counter(18), rhs = Counter(8) -- expression 24 operands: lhs = Expression(25, Sub), rhs = Zero -- expression 25 operands: lhs = Expression(26, Sub), rhs = Counter(9) -- expression 26 operands: lhs = Counter(18), rhs = Counter(8) -- expression 27 operands: lhs = Expression(38, Sub), rhs = Counter(11) -- expression 28 operands: lhs = Expression(39, Sub), rhs = Counter(10) -- expression 29 operands: lhs = Expression(40, Sub), rhs = Counter(16) -- expression 30 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 31 operands: lhs = Expression(40, Sub), rhs = Counter(16) +- expression 24 operands: lhs = Expression(34, Sub), rhs = Counter(11) +- expression 25 operands: lhs = Expression(35, Sub), rhs = Counter(10) +- expression 26 operands: lhs = Expression(36, Sub), rhs = Counter(16) +- expression 27 operands: lhs = Expression(0, Add), rhs = Counter(3) +- expression 28 operands: lhs = Expression(36, Sub), rhs = Counter(16) +- expression 29 operands: lhs = Expression(0, Add), rhs = Counter(3) +- expression 30 operands: lhs = Expression(35, Sub), rhs = Counter(10) +- expression 31 operands: lhs = Expression(36, Sub), rhs = Counter(16) - expression 32 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 33 operands: lhs = Expression(39, Sub), rhs = Counter(10) -- expression 34 operands: lhs = Expression(40, Sub), rhs = Counter(16) -- expression 35 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 36 operands: lhs = Expression(37, Sub), rhs = Zero -- expression 37 operands: lhs = Expression(38, Sub), rhs = Counter(11) -- expression 38 operands: lhs = Expression(39, Sub), rhs = Counter(10) -- expression 39 operands: lhs = Expression(40, Sub), rhs = Counter(16) -- expression 40 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 41 operands: lhs = Expression(46, Sub), rhs = Counter(13) -- expression 42 operands: lhs = Counter(17), rhs = Counter(12) -- expression 43 operands: lhs = Counter(17), rhs = Counter(12) -- expression 44 operands: lhs = Expression(45, Sub), rhs = Zero -- expression 45 operands: lhs = Expression(46, Sub), rhs = Counter(13) -- expression 46 operands: lhs = Counter(17), rhs = Counter(12) -- expression 47 operands: lhs = Expression(52, Sub), rhs = Counter(15) -- expression 48 operands: lhs = Counter(19), rhs = Counter(14) -- expression 49 operands: lhs = Counter(19), rhs = Counter(14) -- expression 50 operands: lhs = Expression(51, Sub), rhs = Zero -- expression 51 operands: lhs = Expression(52, Sub), rhs = Counter(15) -- expression 52 operands: lhs = Counter(19), rhs = Counter(14) -- expression 53 operands: lhs = Expression(54, Add), rhs = Counter(3) -- expression 54 operands: lhs = Counter(4), rhs = Expression(55, Add) -- expression 55 operands: lhs = Expression(56, Add), rhs = Expression(60, Add) -- expression 56 operands: lhs = Counter(5), rhs = Expression(57, Add) -- expression 57 operands: lhs = Expression(58, Add), rhs = Expression(59, Add) -- expression 58 operands: lhs = Counter(6), rhs = Counter(7) -- expression 59 operands: lhs = Counter(8), rhs = Counter(9) -- expression 60 operands: lhs = Expression(61, Add), rhs = Expression(62, Add) -- expression 61 operands: lhs = Counter(10), rhs = Counter(11) -- expression 62 operands: lhs = Expression(63, Add), rhs = Expression(64, Add) -- expression 63 operands: lhs = Counter(12), rhs = Counter(13) -- expression 64 operands: lhs = Counter(14), rhs = Counter(15) +- expression 33 operands: lhs = Expression(34, Sub), rhs = Counter(11) +- expression 34 operands: lhs = Expression(35, Sub), rhs = Counter(10) +- expression 35 operands: lhs = Expression(36, Sub), rhs = Counter(16) +- expression 36 operands: lhs = Expression(0, Add), rhs = Counter(3) +- expression 37 operands: lhs = Expression(41, Sub), rhs = Counter(13) +- expression 38 operands: lhs = Counter(17), rhs = Counter(12) +- expression 39 operands: lhs = Counter(17), rhs = Counter(12) +- expression 40 operands: lhs = Expression(41, Sub), rhs = Counter(13) +- expression 41 operands: lhs = Counter(17), rhs = Counter(12) +- expression 42 operands: lhs = Expression(46, Sub), rhs = Counter(15) +- expression 43 operands: lhs = Counter(19), rhs = Counter(14) +- expression 44 operands: lhs = Counter(19), rhs = Counter(14) +- expression 45 operands: lhs = Expression(46, Sub), rhs = Counter(15) +- expression 46 operands: lhs = Counter(19), rhs = Counter(14) +- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(3) +- expression 48 operands: lhs = Counter(4), rhs = Expression(49, Add) +- expression 49 operands: lhs = Expression(50, Add), rhs = Expression(54, Add) +- expression 50 operands: lhs = Counter(5), rhs = Expression(51, Add) +- expression 51 operands: lhs = Expression(52, Add), rhs = Expression(53, Add) +- expression 52 operands: lhs = Counter(6), rhs = Counter(7) +- expression 53 operands: lhs = Counter(8), rhs = Counter(9) +- expression 54 operands: lhs = Expression(55, Add), rhs = Expression(56, Add) +- expression 55 operands: lhs = Counter(10), rhs = Counter(11) +- expression 56 operands: lhs = Expression(57, Add), rhs = Expression(58, Add) +- expression 57 operands: lhs = Counter(12), rhs = Counter(13) +- expression 58 operands: lhs = Counter(14), rhs = Counter(15) Number of file 0 mappings: 40 - Code(Counter(0)) at (prev + 60, 1) to (start + 3, 23) - Code(Expression(0, Add)) at (prev + 8, 9) to (start + 0, 14) = (c0 + (c1 + c2)) -- Code(Expression(40, Sub)) at (prev + 2, 9) to (start + 4, 26) +- Code(Expression(36, Sub)) at (prev + 2, 9) to (start + 4, 26) = ((c0 + (c1 + c2)) - c3) - Code(Counter(16)) at (prev + 6, 13) to (start + 0, 47) - Code(Counter(4)) at (prev + 0, 47) to (start + 0, 48) -- Code(Expression(20, Sub)) at (prev + 0, 49) to (start + 3, 53) +- Code(Expression(18, Sub)) at (prev + 0, 49) to (start + 3, 53) = (c16 - c4) - Code(Counter(5)) at (prev + 4, 17) to (start + 0, 18) -- Code(Expression(19, Sub)) at (prev + 2, 17) to (start + 4, 18) +- Code(Expression(17, Sub)) at (prev + 2, 17) to (start + 4, 18) = ((c16 - c4) - c5) -- Code(Expression(17, Sub)) at (prev + 5, 17) to (start + 0, 20) +- Code(Expression(15, Sub)) at (prev + 5, 17) to (start + 0, 20) = ((((c16 - c4) - c5) - c6) - c7) -- Code(Expression(10, Add)) at (prev + 0, 23) to (start + 0, 65) - = (((c16 - c4) - c5) + Zero) +- Code(Expression(17, Sub)) at (prev + 0, 23) to (start + 0, 65) + = ((c16 - c4) - c5) - Code(Counter(6)) at (prev + 0, 65) to (start + 0, 66) -- Code(Expression(18, Sub)) at (prev + 0, 67) to (start + 0, 95) +- Code(Expression(16, Sub)) at (prev + 0, 67) to (start + 0, 95) = (((c16 - c4) - c5) - c6) - Code(Counter(7)) at (prev + 0, 95) to (start + 0, 96) -- Code(Expression(16, Add)) at (prev + 1, 13) to (start + 0, 32) - = (((((c16 - c4) - c5) - c6) - c7) + Zero) -- Code(Expression(25, Sub)) at (prev + 1, 17) to (start + 0, 20) +- Code(Expression(15, Sub)) at (prev + 1, 13) to (start + 0, 32) + = ((((c16 - c4) - c5) - c6) - c7) +- Code(Expression(22, Sub)) at (prev + 1, 17) to (start + 0, 20) = ((c18 - c8) - c9) - Code(Counter(18)) at (prev + 0, 23) to (start + 0, 65) - Code(Counter(8)) at (prev + 0, 65) to (start + 0, 66) -- Code(Expression(26, Sub)) at (prev + 0, 67) to (start + 0, 96) +- Code(Expression(23, Sub)) at (prev + 0, 67) to (start + 0, 96) = (c18 - c8) - Code(Counter(9)) at (prev + 0, 96) to (start + 0, 97) -- Code(Expression(24, Add)) at (prev + 1, 13) to (start + 0, 32) - = (((c18 - c8) - c9) + Zero) -- Code(Expression(37, Sub)) at (prev + 4, 17) to (start + 0, 20) +- Code(Expression(22, Sub)) at (prev + 1, 13) to (start + 0, 32) + = ((c18 - c8) - c9) +- Code(Expression(33, Sub)) at (prev + 4, 17) to (start + 0, 20) = (((((c0 + (c1 + c2)) - c3) - c16) - c10) - c11) -- Code(Expression(39, Sub)) at (prev + 0, 23) to (start + 0, 66) +- Code(Expression(35, Sub)) at (prev + 0, 23) to (start + 0, 66) = (((c0 + (c1 + c2)) - c3) - c16) - Code(Counter(10)) at (prev + 0, 66) to (start + 0, 67) -- Code(Expression(38, Sub)) at (prev + 0, 68) to (start + 0, 97) +- Code(Expression(34, Sub)) at (prev + 0, 68) to (start + 0, 97) = ((((c0 + (c1 + c2)) - c3) - c16) - c10) - Code(Counter(11)) at (prev + 0, 97) to (start + 0, 98) -- Code(Expression(36, Add)) at (prev + 1, 13) to (start + 0, 32) - = ((((((c0 + (c1 + c2)) - c3) - c16) - c10) - c11) + Zero) -- Code(Expression(45, Sub)) at (prev + 1, 17) to (start + 0, 20) +- Code(Expression(33, Sub)) at (prev + 1, 13) to (start + 0, 32) + = (((((c0 + (c1 + c2)) - c3) - c16) - c10) - c11) +- Code(Expression(40, Sub)) at (prev + 1, 17) to (start + 0, 20) = ((c17 - c12) - c13) - Code(Counter(17)) at (prev + 0, 23) to (start + 1, 54) - Code(Counter(12)) at (prev + 1, 54) to (start + 0, 55) -- Code(Expression(46, Sub)) at (prev + 1, 18) to (start + 0, 47) +- Code(Expression(41, Sub)) at (prev + 1, 18) to (start + 0, 47) = (c17 - c12) - Code(Counter(13)) at (prev + 0, 47) to (start + 0, 48) -- Code(Expression(44, Add)) at (prev + 1, 13) to (start + 0, 32) - = (((c17 - c12) - c13) + Zero) -- Code(Expression(51, Sub)) at (prev + 1, 17) to (start + 0, 20) +- Code(Expression(40, Sub)) at (prev + 1, 13) to (start + 0, 32) + = ((c17 - c12) - c13) +- Code(Expression(45, Sub)) at (prev + 1, 17) to (start + 0, 20) = ((c19 - c14) - c15) - Code(Counter(19)) at (prev + 0, 23) to (start + 1, 54) - Code(Counter(14)) at (prev + 2, 17) to (start + 0, 18) -- Code(Expression(52, Sub)) at (prev + 1, 18) to (start + 0, 47) +- Code(Expression(46, Sub)) at (prev + 1, 18) to (start + 0, 47) = (c19 - c14) - Code(Counter(15)) at (prev + 1, 17) to (start + 0, 18) -- Code(Expression(50, Add)) at (prev + 2, 13) to (start + 0, 32) - = (((c19 - c14) - c15) + Zero) +- Code(Expression(45, Sub)) at (prev + 2, 13) to (start + 0, 32) + = ((c19 - c14) - c15) - Code(Counter(3)) at (prev + 3, 5) to (start + 0, 11) -- Code(Expression(53, Add)) at (prev + 1, 1) to (start + 0, 2) +- Code(Expression(47, Add)) at (prev + 1, 1) to (start + 0, 2) = ((c4 + ((c5 + ((c6 + c7) + (c8 + c9))) + ((c10 + c11) + ((c12 + c13) + (c14 + c15))))) + c3) diff --git a/tests/coverage-map/status-quo/unused.cov-map b/tests/coverage-map/status-quo/unused.cov-map index c8b8f195fbd5..9383d1e90ac2 100644 --- a/tests/coverage-map/status-quo/unused.cov-map +++ b/tests/coverage-map/status-quo/unused.cov-map @@ -47,45 +47,45 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 37, 1) to (start + 4, 2) Function name: unused::unused_func (unused) -Raw bytes (24): 0x[01, 01, 00, 04, 01, 13, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 00, 13, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 19, 1) to (start + 1, 14) +- Code(Zero) at (prev + 19, 1) to (start + 1, 14) - Code(Zero) at (prev + 1, 15) to (start + 2, 6) - Code(Zero) at (prev + 2, 6) to (start + 0, 7) - Code(Zero) at (prev + 1, 1) to (start + 0, 2) Function name: unused::unused_func2 (unused) -Raw bytes (24): 0x[01, 01, 00, 04, 01, 19, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 00, 19, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 25, 1) to (start + 1, 14) +- Code(Zero) at (prev + 25, 1) to (start + 1, 14) - Code(Zero) at (prev + 1, 15) to (start + 2, 6) - Code(Zero) at (prev + 2, 6) to (start + 0, 7) - Code(Zero) at (prev + 1, 1) to (start + 0, 2) Function name: unused::unused_func3 (unused) -Raw bytes (24): 0x[01, 01, 00, 04, 01, 1f, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02] +Raw bytes (24): 0x[01, 01, 00, 04, 00, 1f, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 31, 1) to (start + 1, 14) +- Code(Zero) at (prev + 31, 1) to (start + 1, 14) - Code(Zero) at (prev + 1, 15) to (start + 2, 6) - Code(Zero) at (prev + 2, 6) to (start + 0, 7) - Code(Zero) at (prev + 1, 1) to (start + 0, 2) Function name: unused::unused_template_func::<_> (unused) -Raw bytes (34): 0x[01, 01, 00, 06, 01, 0b, 01, 01, 12, 00, 02, 0b, 00, 11, 00, 01, 09, 00, 0f, 00, 00, 13, 00, 19, 00, 01, 09, 00, 0f, 00, 02, 01, 00, 02] +Raw bytes (34): 0x[01, 01, 00, 06, 00, 0b, 01, 01, 12, 00, 02, 0b, 00, 11, 00, 01, 09, 00, 0f, 00, 00, 13, 00, 19, 00, 01, 09, 00, 0f, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 11, 1) to (start + 1, 18) +- Code(Zero) at (prev + 11, 1) to (start + 1, 18) - Code(Zero) at (prev + 2, 11) to (start + 0, 17) - Code(Zero) at (prev + 1, 9) to (start + 0, 15) - Code(Zero) at (prev + 0, 19) to (start + 0, 25) diff --git a/tests/coverage-map/status-quo/yield.cov-map b/tests/coverage-map/status-quo/yield.cov-map index 16caa2db343b..c9c9709fa4f3 100644 --- a/tests/coverage-map/status-quo/yield.cov-map +++ b/tests/coverage-map/status-quo/yield.cov-map @@ -1,54 +1,44 @@ Function name: yield::main -Raw bytes (118): 0x[01, 01, 11, 01, 00, 05, 09, 0d, 00, 0d, 11, 32, 15, 0d, 11, 11, 15, 2e, 00, 32, 15, 0d, 11, 2e, 00, 32, 15, 0d, 11, 19, 1d, 21, 00, 25, 29, 2d, 00, 10, 01, 07, 01, 01, 16, 03, 06, 0b, 00, 2e, 0d, 01, 27, 00, 29, 07, 01, 0e, 00, 34, 0b, 02, 0b, 00, 2e, 32, 01, 22, 00, 27, 2e, 00, 2c, 00, 2e, 1b, 01, 0e, 00, 34, 1f, 03, 09, 00, 16, 2b, 07, 0b, 00, 2e, 21, 01, 27, 00, 29, 37, 01, 0e, 00, 34, 3b, 02, 0b, 00, 2e, 2d, 01, 27, 00, 29, 3f, 01, 0e, 00, 34, 43, 02, 01, 00, 02] +Raw bytes (106): 0x[01, 01, 0b, 05, 09, 0d, 11, 22, 15, 0d, 11, 11, 15, 22, 15, 0d, 11, 22, 15, 0d, 11, 19, 1d, 25, 29, 10, 01, 07, 01, 01, 16, 01, 06, 0b, 00, 2e, 0d, 01, 27, 00, 29, 03, 01, 0e, 00, 34, 0d, 02, 0b, 00, 2e, 22, 01, 22, 00, 27, 1e, 00, 2c, 00, 2e, 13, 01, 0e, 00, 34, 1e, 03, 09, 00, 16, 1e, 07, 0b, 00, 2e, 21, 01, 27, 00, 29, 27, 01, 0e, 00, 34, 21, 02, 0b, 00, 2e, 2d, 01, 27, 00, 29, 2b, 01, 0e, 00, 34, 2d, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 17 -- expression 0 operands: lhs = Counter(0), rhs = Zero -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) -- expression 2 operands: lhs = Counter(3), rhs = Zero +Number of expressions: 11 +- expression 0 operands: lhs = Counter(1), rhs = Counter(2) +- expression 1 operands: lhs = Counter(3), rhs = Counter(4) +- expression 2 operands: lhs = Expression(8, Sub), rhs = Counter(5) - expression 3 operands: lhs = Counter(3), rhs = Counter(4) -- expression 4 operands: lhs = Expression(12, Sub), rhs = Counter(5) -- expression 5 operands: lhs = Counter(3), rhs = Counter(4) -- expression 6 operands: lhs = Counter(4), rhs = Counter(5) -- expression 7 operands: lhs = Expression(11, Sub), rhs = Zero -- expression 8 operands: lhs = Expression(12, Sub), rhs = Counter(5) -- expression 9 operands: lhs = Counter(3), rhs = Counter(4) -- expression 10 operands: lhs = Expression(11, Sub), rhs = Zero -- expression 11 operands: lhs = Expression(12, Sub), rhs = Counter(5) -- expression 12 operands: lhs = Counter(3), rhs = Counter(4) -- expression 13 operands: lhs = Counter(6), rhs = Counter(7) -- expression 14 operands: lhs = Counter(8), rhs = Zero -- expression 15 operands: lhs = Counter(9), rhs = Counter(10) -- expression 16 operands: lhs = Counter(11), rhs = Zero +- expression 4 operands: lhs = Counter(4), rhs = Counter(5) +- expression 5 operands: lhs = Expression(8, Sub), rhs = Counter(5) +- expression 6 operands: lhs = Counter(3), rhs = Counter(4) +- expression 7 operands: lhs = Expression(8, Sub), rhs = Counter(5) +- expression 8 operands: lhs = Counter(3), rhs = Counter(4) +- expression 9 operands: lhs = Counter(6), rhs = Counter(7) +- expression 10 operands: lhs = Counter(9), rhs = Counter(10) Number of file 0 mappings: 16 - Code(Counter(0)) at (prev + 7, 1) to (start + 1, 22) -- Code(Expression(0, Add)) at (prev + 6, 11) to (start + 0, 46) - = (c0 + Zero) +- Code(Counter(0)) at (prev + 6, 11) to (start + 0, 46) - Code(Counter(3)) at (prev + 1, 39) to (start + 0, 41) -- Code(Expression(1, Add)) at (prev + 1, 14) to (start + 0, 52) +- Code(Expression(0, Add)) at (prev + 1, 14) to (start + 0, 52) = (c1 + c2) -- Code(Expression(2, Add)) at (prev + 2, 11) to (start + 0, 46) - = (c3 + Zero) -- Code(Expression(12, Sub)) at (prev + 1, 34) to (start + 0, 39) +- Code(Counter(3)) at (prev + 2, 11) to (start + 0, 46) +- Code(Expression(8, Sub)) at (prev + 1, 34) to (start + 0, 39) = (c3 - c4) -- Code(Expression(11, Sub)) at (prev + 0, 44) to (start + 0, 46) +- Code(Expression(7, Sub)) at (prev + 0, 44) to (start + 0, 46) = ((c3 - c4) - c5) -- Code(Expression(6, Add)) at (prev + 1, 14) to (start + 0, 52) +- Code(Expression(4, Add)) at (prev + 1, 14) to (start + 0, 52) = (c4 + c5) -- Code(Expression(7, Add)) at (prev + 3, 9) to (start + 0, 22) - = (((c3 - c4) - c5) + Zero) -- Code(Expression(10, Add)) at (prev + 7, 11) to (start + 0, 46) - = (((c3 - c4) - c5) + Zero) +- Code(Expression(7, Sub)) at (prev + 3, 9) to (start + 0, 22) + = ((c3 - c4) - c5) +- Code(Expression(7, Sub)) at (prev + 7, 11) to (start + 0, 46) + = ((c3 - c4) - c5) - Code(Counter(8)) at (prev + 1, 39) to (start + 0, 41) -- Code(Expression(13, Add)) at (prev + 1, 14) to (start + 0, 52) +- Code(Expression(9, Add)) at (prev + 1, 14) to (start + 0, 52) = (c6 + c7) -- Code(Expression(14, Add)) at (prev + 2, 11) to (start + 0, 46) - = (c8 + Zero) +- Code(Counter(8)) at (prev + 2, 11) to (start + 0, 46) - Code(Counter(11)) at (prev + 1, 39) to (start + 0, 41) -- Code(Expression(15, Add)) at (prev + 1, 14) to (start + 0, 52) +- Code(Expression(10, Add)) at (prev + 1, 14) to (start + 0, 52) = (c9 + c10) -- Code(Expression(16, Add)) at (prev + 2, 1) to (start + 0, 2) - = (c11 + Zero) +- Code(Counter(11)) at (prev + 2, 1) to (start + 0, 2) Function name: yield::main::{closure#0} Raw bytes (14): 0x[01, 01, 00, 02, 01, 08, 1c, 01, 10, 05, 02, 10, 01, 06] diff --git a/tests/coverage-map/unreachable.cov-map b/tests/coverage-map/unreachable.cov-map new file mode 100644 index 000000000000..495419820c1f --- /dev/null +++ b/tests/coverage-map/unreachable.cov-map @@ -0,0 +1,24 @@ +Function name: unreachable::UNREACHABLE_CLOSURE::{closure#0} +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 27, 00, 49] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Counter(0)) at (prev + 15, 39) to (start + 0, 73) + +Function name: unreachable::unreachable_function +Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 01, 02, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Counter(0)) at (prev + 17, 1) to (start + 2, 2) + +Function name: unreachable::unreachable_intrinsic +Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 01, 02, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Counter(0)) at (prev + 22, 1) to (start + 2, 2) + diff --git a/tests/coverage-map/unreachable.rs b/tests/coverage-map/unreachable.rs new file mode 100644 index 000000000000..6385bfa160d7 --- /dev/null +++ b/tests/coverage-map/unreachable.rs @@ -0,0 +1,37 @@ +#![feature(core_intrinsics)] +#![feature(coverage_attribute)] +// compile-flags: --edition=2021 + +// +// If we instrument a function for coverage, but all of its counter-increment +// statements are removed by MIR optimizations, LLVM will think it isn't +// instrumented and it will disappear from coverage maps and coverage reports. +// Most MIR opts won't cause this because they tend not to remove statements +// from bb0, but `UnreachablePropagation` can do so if it sees that bb0 ends +// with `TerminatorKind::Unreachable`. + +use std::hint::{black_box, unreachable_unchecked}; + +static UNREACHABLE_CLOSURE: fn() = || unsafe { unreachable_unchecked() }; + +fn unreachable_function() { + unsafe { unreachable_unchecked() } +} + +// Use an intrinsic to more reliably trigger unreachable-propagation. +fn unreachable_intrinsic() { + unsafe { std::intrinsics::unreachable() } +} + +#[coverage(off)] +fn main() { + if black_box(false) { + UNREACHABLE_CLOSURE(); + } + if black_box(false) { + unreachable_function(); + } + if black_box(false) { + unreachable_intrinsic(); + } +} diff --git a/tests/incremental/hashes/function_interfaces.rs b/tests/incremental/hashes/function_interfaces.rs index 182ca7d926c6..23b81705f9aa 100644 --- a/tests/incremental/hashes/function_interfaces.rs +++ b/tests/incremental/hashes/function_interfaces.rs @@ -302,7 +302,7 @@ pub fn return_impl_trait() -> i32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, typeck, fn_sig, optimized_mir")] +#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, typeck, fn_sig")] #[rustc_clean(cfg = "cfail3")] #[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, typeck, fn_sig, optimized_mir")] #[rustc_clean(cfg = "cfail6")] diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir index 4d3baee7f117..15330b13cc21 100644 --- a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir +++ b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir @@ -2,13 +2,16 @@ /* generator_layout = GeneratorLayout { field_tys: { _0: GeneratorSavedTy { - ty: Alias( - Opaque, - AliasTy { - args: [ - ], - def_id: DefId(0:7 ~ async_await[ccf8]::a::{opaque#0}), - }, + ty: Generator( + DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), + [ + std::future::ResumeTy, + (), + (), + GeneratorWitness(DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), []), + (), + ], + Static, ), source_info: SourceInfo { span: $DIR/async_await.rs:15:9: 15:14 (#8), @@ -17,13 +20,16 @@ ignore_for_traits: false, }, _1: GeneratorSavedTy { - ty: Alias( - Opaque, - AliasTy { - args: [ - ], - def_id: DefId(0:7 ~ async_await[ccf8]::a::{opaque#0}), - }, + ty: Generator( + DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), + [ + std::future::ResumeTy, + (), + (), + GeneratorWitness(DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), []), + (), + ], + Static, ), source_info: SourceInfo { span: $DIR/async_await.rs:16:9: 16:14 (#10), @@ -49,15 +55,15 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, debug _task_context => _38; let mut _0: std::task::Poll<()>; let _3: (); - let mut _4: impl std::future::Future; - let mut _5: impl std::future::Future; - let mut _6: impl std::future::Future; + let mut _4: {async fn body@$DIR/async_await.rs:11:14: 11:16}; + let mut _5: {async fn body@$DIR/async_await.rs:11:14: 11:16}; + let mut _6: {async fn body@$DIR/async_await.rs:11:14: 11:16}; let mut _7: (); let _8: (); let mut _9: std::task::Poll<()>; - let mut _10: std::pin::Pin<&mut impl std::future::Future>; - let mut _11: &mut impl std::future::Future; - let mut _12: &mut impl std::future::Future; + let mut _10: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>; + let mut _11: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16}; + let mut _12: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16}; let mut _13: &mut std::task::Context<'_>; let mut _14: &mut std::task::Context<'_>; let mut _15: &mut std::task::Context<'_>; @@ -65,14 +71,14 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, let mut _18: !; let mut _19: &mut std::task::Context<'_>; let mut _20: (); - let mut _21: impl std::future::Future; - let mut _22: impl std::future::Future; - let mut _23: impl std::future::Future; + let mut _21: {async fn body@$DIR/async_await.rs:11:14: 11:16}; + let mut _22: {async fn body@$DIR/async_await.rs:11:14: 11:16}; + let mut _23: {async fn body@$DIR/async_await.rs:11:14: 11:16}; let _24: (); let mut _25: std::task::Poll<()>; - let mut _26: std::pin::Pin<&mut impl std::future::Future>; - let mut _27: &mut impl std::future::Future; - let mut _28: &mut impl std::future::Future; + let mut _26: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>; + let mut _27: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16}; + let mut _28: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16}; let mut _29: &mut std::task::Context<'_>; let mut _30: &mut std::task::Context<'_>; let mut _31: &mut std::task::Context<'_>; @@ -84,7 +90,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, let mut _38: &mut std::task::Context<'_>; let mut _39: u32; scope 1 { - debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: impl std::future::Future); + debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}); let _17: (); scope 2 { } @@ -93,7 +99,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, } } scope 4 { - debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: impl std::future::Future); + debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}); let _33: (); scope 5 { } @@ -116,13 +122,13 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, } bb2: { - _4 = as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable]; + _4 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable]; } bb3: { StorageDead(_5); nop; - (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: impl std::future::Future) = move _4; + (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}) = move _4; goto -> bb4; } @@ -132,9 +138,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, StorageLive(_10); StorageLive(_11); StorageLive(_12); - _12 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: impl std::future::Future); + _12 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}); _11 = &mut (*_12); - _10 = Pin::<&mut impl Future>::new_unchecked(move _11) -> [return: bb5, unwind unreachable]; + _10 = Pin::<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>::new_unchecked(move _11) -> [return: bb5, unwind unreachable]; } bb5: { @@ -150,7 +156,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, bb6: { _13 = &mut (*_14); StorageDead(_15); - _9 = as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable]; + _9 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable]; } bb7: { @@ -187,7 +193,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, StorageDead(_12); StorageDead(_9); StorageDead(_8); - drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: impl std::future::Future)) -> [return: bb12, unwind unreachable]; + drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16})) -> [return: bb12, unwind unreachable]; } bb11: { @@ -212,13 +218,13 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, } bb14: { - _21 = as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable]; + _21 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable]; } bb15: { StorageDead(_22); nop; - (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: impl std::future::Future) = move _21; + (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}) = move _21; goto -> bb16; } @@ -228,9 +234,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, StorageLive(_26); StorageLive(_27); StorageLive(_28); - _28 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: impl std::future::Future); + _28 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}); _27 = &mut (*_28); - _26 = Pin::<&mut impl Future>::new_unchecked(move _27) -> [return: bb17, unwind unreachable]; + _26 = Pin::<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>::new_unchecked(move _27) -> [return: bb17, unwind unreachable]; } bb17: { @@ -246,7 +252,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, bb18: { _29 = &mut (*_30); StorageDead(_31); - _25 = as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable]; + _25 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable]; } bb19: { @@ -279,7 +285,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, StorageDead(_28); StorageDead(_25); StorageDead(_24); - drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: impl std::future::Future)) -> [return: bb23, unwind unreachable]; + drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16})) -> [return: bb23, unwind unreachable]; } bb22: { diff --git a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-abort.diff index 7ba51ccdbf6d..d585ae89e829 100644 --- a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-abort.diff @@ -20,6 +20,7 @@ _2 = const u8::MAX; StorageLive(_3); _3 = const 1_u8; + StorageLive(_4); - _4 = CheckedAdd(_2, _3); - assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind unreachable]; + _4 = const (0_u8, true); @@ -29,6 +30,7 @@ bb1: { - _1 = move (_4.0: u8); + _1 = const 0_u8; + StorageDead(_4); StorageDead(_3); StorageDead(_2); StorageDead(_1); diff --git a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff index 545b7f22f6e0..9fe390906380 100644 --- a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff @@ -20,6 +20,7 @@ _2 = const u8::MAX; StorageLive(_3); _3 = const 1_u8; + StorageLive(_4); - _4 = CheckedAdd(_2, _3); - assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind continue]; + _4 = const (0_u8, true); @@ -29,6 +30,7 @@ bb1: { - _1 = move (_4.0: u8); + _1 = const 0_u8; + StorageDead(_4); StorageDead(_3); StorageDead(_2); StorageDead(_1); diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-abort.diff index 9a68d3b51b56..87bb1454c962 100644 --- a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-abort.diff @@ -20,6 +20,7 @@ _2 = const u8::MAX; StorageLive(_3); _3 = const 1_u8; + StorageLive(_4); - _4 = CheckedAdd(_2, _3); - assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind unreachable]; + _4 = CheckedAdd(const u8::MAX, const 1_u8); @@ -29,6 +30,7 @@ bb1: { - _1 = move (_4.0: u8); + _1 = const 0_u8; + StorageDead(_4); StorageDead(_3); StorageDead(_2); StorageDead(_1); diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff index c1d281ab788f..b2f13640a4c0 100644 --- a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff @@ -20,6 +20,7 @@ _2 = const u8::MAX; StorageLive(_3); _3 = const 1_u8; + StorageLive(_4); - _4 = CheckedAdd(_2, _3); - assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind continue]; + _4 = CheckedAdd(const u8::MAX, const 1_u8); @@ -29,6 +30,7 @@ bb1: { - _1 = move (_4.0: u8); + _1 = const 0_u8; + StorageDead(_4); StorageDead(_3); StorageDead(_2); StorageDead(_1); diff --git a/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir b/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir index 721fac27d885..10b81e59b5f4 100644 --- a/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir +++ b/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir @@ -41,6 +41,8 @@ fn foo(_1: T, _2: i32) -> (i32, T) { _7 = (move _8,); StorageLive(_9); _9 = move (_7.0: i32); + StorageLive(_10); + StorageLive(_12); StorageLive(_11); _10 = ((*_6).0: &i32); _11 = (*_10); @@ -50,6 +52,8 @@ fn foo(_1: T, _2: i32) -> (i32, T) { _0 = (move _11, move _13); StorageDead(_13); StorageDead(_11); + StorageDead(_12); + StorageDead(_10); StorageDead(_9); StorageDead(_8); StorageDead(_7); diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff index 6779003b6930..06ee8c464d5b 100644 --- a/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff @@ -40,6 +40,8 @@ + StorageDead(_3); + StorageLive(_5); + _5 = const false; ++ StorageLive(_6); ++ StorageLive(_7); + _6 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8}); + _7 = discriminant((*_6)); + switchInt(move _7) -> [0: bb3, 1: bb7, 3: bb8, otherwise: bb9]; @@ -48,6 +50,8 @@ bb1: { - _3 = &mut _4; - _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new(move _3) -> [return: bb2, unwind unreachable]; ++ StorageDead(_7); ++ StorageDead(_6); + StorageDead(_5); + StorageDead(_2); + drop(_4) -> [return: bb2, unwind unreachable]; diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff index 31744be99ec6..da29ba5f50d7 100644 --- a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff @@ -48,6 +48,8 @@ - _1 = <{generator@$DIR/inline_generator.rs:16:5: 16:8} as Generator>::resume(move _2, const false) -> [return: bb3, unwind: bb5]; + StorageLive(_5); + _5 = const false; ++ StorageLive(_6); ++ StorageLive(_7); + _6 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8}); + _7 = discriminant((*_6)); + switchInt(move _7) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11]; @@ -55,6 +57,8 @@ - bb3: { + bb1: { ++ StorageDead(_7); ++ StorageDead(_6); + StorageDead(_5); StorageDead(_2); - drop(_4) -> [return: bb4, unwind: bb6]; diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff index dc0ab255afd9..b90e0505c54e 100644 --- a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff @@ -122,9 +122,14 @@ + _3 = const _; + _2 = Vec:: { buf: move _3, len: const 0_usize }; + StorageDead(_3); ++ StorageLive(_4); ++ StorageLive(_5); ++ StorageLive(_6); ++ StorageLive(_7); + _4 = SizeOf(std::vec::Vec); + _5 = AlignOf(std::vec::Vec); + StorageLive(_8); ++ StorageLive(_10); + StorageLive(_11); + StorageLive(_12); + StorageLive(_13); @@ -178,10 +183,15 @@ + StorageDead(_13); + StorageDead(_12); + StorageDead(_11); ++ StorageDead(_10); + StorageDead(_8); + _1 = ShallowInitBox(move _6, std::vec::Vec); + _7 = (((_1.0: std::ptr::Unique>).0: std::ptr::NonNull>).0: *const std::vec::Vec); + (*_7) = move _2; ++ StorageDead(_7); ++ StorageDead(_6); ++ StorageDead(_5); ++ StorageDead(_4); StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb3, unwind unreachable]; diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff index 675292f06d66..f9c637caa18a 100644 --- a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff @@ -122,9 +122,14 @@ + _3 = const _; + _2 = Vec:: { buf: move _3, len: const 0_usize }; + StorageDead(_3); ++ StorageLive(_4); ++ StorageLive(_5); ++ StorageLive(_6); ++ StorageLive(_7); + _4 = SizeOf(std::vec::Vec); + _5 = AlignOf(std::vec::Vec); + StorageLive(_8); ++ StorageLive(_10); + StorageLive(_11); + StorageLive(_12); + StorageLive(_13); @@ -195,10 +200,15 @@ + StorageDead(_13); + StorageDead(_12); + StorageDead(_11); ++ StorageDead(_10); + StorageDead(_8); + _1 = ShallowInitBox(move _6, std::vec::Vec); + _7 = (((_1.0: std::ptr::Unique>).0: std::ptr::NonNull>).0: *const std::vec::Vec); + (*_7) = move _2; ++ StorageDead(_7); ++ StorageDead(_6); ++ StorageDead(_5); ++ StorageDead(_4); + StorageDead(_2); + _0 = const (); + drop(_1) -> [return: bb1, unwind: bb2]; diff --git a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff index 3d0c10725275..688ab9c563a7 100644 --- a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff @@ -18,6 +18,7 @@ bb0: { - _0 = inner() -> [return: bb1, unwind unreachable]; + StorageLive(_1); ++ StorageLive(_2); + _1 = const _; + _0 = index() -> [return: bb1, unwind unreachable]; } @@ -40,6 +41,7 @@ + + bb4: { + StorageDead(_3); ++ StorageDead(_2); + StorageDead(_1); return; } diff --git a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff index 16a19f4a3569..e4d2b1a7ffbd 100644 --- a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff @@ -18,6 +18,7 @@ bb0: { - _0 = inner() -> [return: bb1, unwind continue]; + StorageLive(_1); ++ StorageLive(_2); + _1 = const _; + _0 = index() -> [return: bb1, unwind continue]; } @@ -40,6 +41,7 @@ + + bb4: { + StorageDead(_3); ++ StorageDead(_2); + StorageDead(_1); return; } diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir index 6837da27a96f..62d7e839f5a8 100644 --- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir @@ -17,9 +17,13 @@ fn b(_1: &mut Box) -> &mut T { StorageLive(_3); StorageLive(_4); _4 = &mut (*_1); + StorageLive(_5); + StorageLive(_6); _5 = deref_copy (*_4); _6 = (((_5.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const T); _3 = &mut (*_6); + StorageDead(_6); + StorageDead(_5); _2 = &mut (*_3); StorageDead(_4); _0 = &mut (*_2); diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir index d09bfc33ff13..bc0aa06a7523 100644 --- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir @@ -15,9 +15,13 @@ fn d(_1: &Box) -> &T { StorageLive(_2); StorageLive(_3); _3 = &(*_1); + StorageLive(_4); + StorageLive(_5); _4 = deref_copy (*_3); _5 = (((_4.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const T); _2 = &(*_5); + StorageDead(_5); + StorageDead(_4); _0 = &(*_2); StorageDead(_3); StorageDead(_2); diff --git a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff index c94dd2556956..b532b133a83a 100644 --- a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff +++ b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff @@ -15,28 +15,44 @@ StorageLive(_2); StorageLive(_3); StorageLive(_4); - _4 = hide_foo() -> [return: bb1, unwind unreachable]; + _4 = hide_foo() -> [return: bb1, unwind: bb6]; } bb1: { _3 = &_4; StorageLive(_5); _5 = (); -- _2 = >::call(move _3, move _5) -> [return: bb2, unwind unreachable]; -+ _2 = >::call(move _3, move _5) -> [return: bb2, unwind unreachable]; +- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb5]; ++ _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb5]; } bb2: { StorageDead(_5); StorageDead(_3); + drop(_4) -> [return: bb3, unwind: bb6]; + } + + bb3: { StorageDead(_4); StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb3, unwind unreachable]; + drop(_1) -> [return: bb4, unwind: bb7]; } - bb3: { + bb4: { return; } + + bb5 (cleanup): { + drop(_4) -> [return: bb6, unwind terminate(cleanup)]; + } + + bb6 (cleanup): { + drop(_1) -> [return: bb7, unwind terminate(cleanup)]; + } + + bb7 (cleanup): { + resume; + } } diff --git a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff index cbfb39115b37..bcebcf297c2b 100644 --- a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff +++ b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff @@ -15,35 +15,43 @@ StorageLive(_2); StorageLive(_3); StorageLive(_4); - _4 = hide_foo() -> [return: bb1, unwind: bb4]; + _4 = hide_foo() -> [return: bb1, unwind: bb6]; } bb1: { _3 = &_4; StorageLive(_5); _5 = (); -- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; -+ _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; +- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb5]; ++ _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb5]; } bb2: { StorageDead(_5); StorageDead(_3); + drop(_4) -> [return: bb3, unwind: bb6]; + } + + bb3: { StorageDead(_4); StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb3, unwind: bb5]; + drop(_1) -> [return: bb4, unwind continue]; } - bb3: { + bb4: { return; } - bb4 (cleanup): { - drop(_1) -> [return: bb5, unwind terminate(cleanup)]; + bb5 (cleanup): { + drop(_4) -> [return: bb6, unwind terminate(cleanup)]; } - bb5 (cleanup): { + bb6 (cleanup): { + drop(_1) -> [return: bb7, unwind terminate(cleanup)]; + } + + bb7 (cleanup): { resume; } } diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff index e3c57347392a..018b6c1ee958 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff @@ -30,6 +30,7 @@ _2 = move _1; - _0 = Option::::unwrap_unchecked(move _2) -> [return: bb1, unwind unreachable]; + StorageLive(_3); ++ StorageLive(_4); + _4 = discriminant(_2); + switchInt(move _4) -> [1: bb2, otherwise: bb1]; } @@ -40,6 +41,7 @@ + + bb2: { + _0 = move ((_2 as Some).0: T); ++ StorageDead(_4); + StorageDead(_3); StorageDead(_2); return; diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff index fc638cb3acef..47845758a3f6 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff @@ -30,6 +30,7 @@ _2 = move _1; - _0 = Option::::unwrap_unchecked(move _2) -> [return: bb1, unwind: bb2]; + StorageLive(_3); ++ StorageLive(_4); + _4 = discriminant(_2); + switchInt(move _4) -> [1: bb2, otherwise: bb1]; } @@ -44,6 +45,7 @@ - resume; + bb2: { + _0 = move ((_2 as Some).0: T); ++ StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + return; diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir index fcc4d43ced66..392f085bd4d1 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir @@ -25,12 +25,14 @@ fn unwrap_unchecked(_1: Option) -> T { bb0: { StorageLive(_3); + StorageLive(_2); _2 = discriminant(_1); switchInt(move _2) -> [1: bb1, otherwise: bb2]; } bb1: { _0 = move ((_1 as Some).0: T); + StorageDead(_2); StorageDead(_3); return; } diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir index fcc4d43ced66..392f085bd4d1 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir @@ -25,12 +25,14 @@ fn unwrap_unchecked(_1: Option) -> T { bb0: { StorageLive(_3); + StorageLive(_2); _2 = discriminant(_1); switchInt(move _2) -> [1: bb1, otherwise: bb2]; } bb1: { _0 = move ((_1 as Some).0: T); + StorageDead(_2); StorageDead(_3); return; } diff --git a/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff index b887b74474fe..bf107dc81a62 100644 --- a/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff +++ b/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff @@ -1,13 +1,13 @@ - // MIR for `bar` before InstrumentCoverage + // MIR for `bar` after InstrumentCoverage - + fn bar() -> bool { let mut _0: bool; - + bb0: { -+ Coverage::Counter(0) for /the/src/instrument_coverage.rs:21:1 - 23:2; ++ Coverage::Counter(0) for [/the/src/instrument_coverage.rs:20:1 - 22:2]; _0 = const true; return; } } - + diff --git a/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff index 810b4646325f..660fcb567841 100644 --- a/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff +++ b/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff @@ -1,48 +1,47 @@ - // MIR for `main` before InstrumentCoverage + // MIR for `main` after InstrumentCoverage - + fn main() -> () { let mut _0: (); let mut _1: (); let mut _2: bool; let mut _3: !; - + bb0: { -+ Coverage::Counter(0) for /the/src/instrument_coverage.rs:12:1 - 12:11; ++ Coverage::Counter(0) for [/the/src/instrument_coverage.rs:12:1 - 12:11]; goto -> bb1; } - + bb1: { -+ Coverage::Expression(0) = Counter(0) + Counter(1) for /the/src/instrument_coverage.rs:13:5 - 14:17; ++ Coverage::Expression(0) = Counter(0) + Counter(1) for [/the/src/instrument_coverage.rs:13:5 - 14:17]; falseUnwind -> [real: bb2, unwind: bb6]; } - + bb2: { StorageLive(_2); _2 = bar() -> [return: bb3, unwind: bb6]; } - + bb3: { switchInt(move _2) -> [0: bb5, otherwise: bb4]; } - + bb4: { -+ Coverage::Expression(2) = Expression(1) + Zero for /the/src/instrument_coverage.rs:18:1 - 18:2; -+ Coverage::Expression(1) = Expression(0) - Counter(1) for /the/src/instrument_coverage.rs:15:13 - 15:18; ++ Coverage::Expression(1) = Expression(0) - Counter(1) for [/the/src/instrument_coverage.rs:15:13 - 15:18, /the/src/instrument_coverage.rs:18:1 - 18:2]; _0 = const (); StorageDead(_2); return; } - + bb5: { -+ Coverage::Counter(1) for /the/src/instrument_coverage.rs:16:10 - 16:11; ++ Coverage::Counter(1) for [/the/src/instrument_coverage.rs:16:10 - 16:11]; _1 = const (); StorageDead(_2); goto -> bb1; } - + bb6 (cleanup): { resume; } } - + diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir index f8c85941813c..55ccf6a8b450 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir @@ -30,6 +30,7 @@ fn num_to_digit(_1: char) -> u32 { } bb1: { + StorageLive(_3); _3 = discriminant(_2); StorageDead(_7); StorageDead(_2); @@ -37,11 +38,13 @@ fn num_to_digit(_1: char) -> u32 { } bb2: { + StorageDead(_3); StorageLive(_4); _4 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb3, unwind unreachable]; } bb3: { + StorageLive(_5); _5 = discriminant(_4); switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb6]; } @@ -52,6 +55,7 @@ fn num_to_digit(_1: char) -> u32 { bb5: { _0 = move ((_4 as Some).0: u32); + StorageDead(_5); StorageDead(_4); goto -> bb8; } @@ -61,6 +65,7 @@ fn num_to_digit(_1: char) -> u32 { } bb7: { + StorageDead(_3); _0 = const 0_u32; goto -> bb8; } diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir index df7392edc50c..cb70a83e7f85 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir @@ -30,6 +30,7 @@ fn num_to_digit(_1: char) -> u32 { } bb1: { + StorageLive(_3); _3 = discriminant(_2); StorageDead(_7); StorageDead(_2); @@ -37,11 +38,13 @@ fn num_to_digit(_1: char) -> u32 { } bb2: { + StorageDead(_3); StorageLive(_4); _4 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb3, unwind continue]; } bb3: { + StorageLive(_5); _5 = discriminant(_4); switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb6]; } @@ -52,6 +55,7 @@ fn num_to_digit(_1: char) -> u32 { bb5: { _0 = move ((_4 as Some).0: u32); + StorageDead(_5); StorageDead(_4); goto -> bb8; } @@ -61,6 +65,7 @@ fn num_to_digit(_1: char) -> u32 { } bb7: { + StorageDead(_3); _0 = const 0_u32; goto -> bb8; } diff --git a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir index 75f81c5aacaf..e3c81061a461 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir @@ -36,8 +36,10 @@ fn step_forward(_1: u32, _2: usize) -> u32 { bb1: { StorageLive(_5); + StorageLive(_4); _4 = discriminant(_3); _5 = Eq(_4, const 1_isize); + StorageDead(_4); _6 = Not(move _5); StorageDead(_5); switchInt(move _6) -> [0: bb2, otherwise: bb3]; diff --git a/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir index 48b780aea62e..80a470c94824 100644 --- a/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir @@ -18,6 +18,7 @@ fn ezmap(_1: Option) -> Option { } bb0: { + StorageLive(_2); _2 = discriminant(_1); switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; } @@ -37,6 +38,7 @@ fn ezmap(_1: Option) -> Option { } bb3: { + StorageDead(_2); return; } diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir index ed286beb4ca6..9c10e96b0ea9 100644 --- a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir @@ -98,6 +98,8 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 StorageLive(_35); StorageLive(_11); _11 = _8; + StorageLive(_12); + StorageLive(_13); _12 = deref_copy _4; _13 = deref_copy _11; StorageLive(_14); @@ -107,6 +109,8 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 _16 = Le(move _14, move _15); StorageDead(_15); StorageDead(_14); + StorageDead(_13); + StorageDead(_12); switchInt(move _16) -> [0: bb1, otherwise: bb2]; } @@ -126,6 +130,8 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 StorageLive(_37); StorageLive(_17); _17 = _6; + StorageLive(_18); + StorageLive(_19); _18 = deref_copy _10; _19 = deref_copy _17; StorageLive(_20); @@ -135,6 +141,8 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 _22 = Le(move _20, move _21); StorageDead(_21); StorageDead(_20); + StorageDead(_19); + StorageDead(_18); switchInt(move _22) -> [0: bb3, otherwise: bb8]; } @@ -151,6 +159,8 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 StorageLive(_39); StorageLive(_23); _23 = _4; + StorageLive(_24); + StorageLive(_25); _24 = deref_copy _8; _25 = deref_copy _23; StorageLive(_26); @@ -160,6 +170,8 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 _28 = Le(move _26, move _27); StorageDead(_27); StorageDead(_26); + StorageDead(_25); + StorageDead(_24); switchInt(move _28) -> [0: bb5, otherwise: bb6]; } @@ -179,6 +191,8 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 StorageLive(_41); StorageLive(_29); _29 = _10; + StorageLive(_30); + StorageLive(_31); _30 = deref_copy _6; _31 = deref_copy _29; StorageLive(_32); @@ -188,6 +202,8 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 _0 = Le(move _32, move _33); StorageDead(_33); StorageDead(_32); + StorageDead(_31); + StorageDead(_30); StorageDead(_29); StorageDead(_41); StorageDead(_40); diff --git a/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff index ca1528b6ab1a..491db551a7d2 100644 --- a/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff +++ b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff @@ -48,6 +48,7 @@ bb0: { StorageLive(_3); + StorageLive(_9); StorageLive(_10); StorageLive(_11); _9 = discriminant(_1); @@ -57,6 +58,7 @@ bb1: { StorageDead(_11); StorageDead(_10); + StorageDead(_9); _5 = discriminant(_3); switchInt(move _5) -> [0: bb2, 1: bb4, otherwise: bb3]; } diff --git a/tests/mir-opt/ssa_unreachable_116212.rs b/tests/mir-opt/ssa_unreachable_116212.rs new file mode 100644 index 000000000000..f588665876c8 --- /dev/null +++ b/tests/mir-opt/ssa_unreachable_116212.rs @@ -0,0 +1,14 @@ +// Regression test for issue #116212. + +#![feature(never_type)] + +use std::mem::MaybeUninit; + +struct Foo { + x: u8, + y: !, +} + +fn main() { + let foo = unsafe { MaybeUninit::::uninit().assume_init() }; +} diff --git a/tests/run-coverage/unreachable.coverage b/tests/run-coverage/unreachable.coverage new file mode 100644 index 000000000000..fa0ac9ccfa1c --- /dev/null +++ b/tests/run-coverage/unreachable.coverage @@ -0,0 +1,38 @@ + LL| |#![feature(core_intrinsics)] + LL| |#![feature(coverage_attribute)] + LL| |// compile-flags: --edition=2021 + LL| | + LL| |// + LL| |// If we instrument a function for coverage, but all of its counter-increment + LL| |// statements are removed by MIR optimizations, LLVM will think it isn't + LL| |// instrumented and it will disappear from coverage maps and coverage reports. + LL| |// Most MIR opts won't cause this because they tend not to remove statements + LL| |// from bb0, but `UnreachablePropagation` can do so if it sees that bb0 ends + LL| |// with `TerminatorKind::Unreachable`. + LL| | + LL| |use std::hint::{black_box, unreachable_unchecked}; + LL| | + LL| 0|static UNREACHABLE_CLOSURE: fn() = || unsafe { unreachable_unchecked() }; + LL| | + LL| 0|fn unreachable_function() { + LL| 0| unsafe { unreachable_unchecked() } + LL| 0|} + LL| | + LL| |// Use an intrinsic to more reliably trigger unreachable-propagation. + LL| 0|fn unreachable_intrinsic() { + LL| 0| unsafe { std::intrinsics::unreachable() } + LL| 0|} + LL| | + LL| |#[coverage(off)] + LL| |fn main() { + LL| | if black_box(false) { + LL| | UNREACHABLE_CLOSURE(); + LL| | } + LL| | if black_box(false) { + LL| | unreachable_function(); + LL| | } + LL| | if black_box(false) { + LL| | unreachable_intrinsic(); + LL| | } + LL| |} + diff --git a/tests/run-coverage/unreachable.rs b/tests/run-coverage/unreachable.rs new file mode 100644 index 000000000000..6385bfa160d7 --- /dev/null +++ b/tests/run-coverage/unreachable.rs @@ -0,0 +1,37 @@ +#![feature(core_intrinsics)] +#![feature(coverage_attribute)] +// compile-flags: --edition=2021 + +// +// If we instrument a function for coverage, but all of its counter-increment +// statements are removed by MIR optimizations, LLVM will think it isn't +// instrumented and it will disappear from coverage maps and coverage reports. +// Most MIR opts won't cause this because they tend not to remove statements +// from bb0, but `UnreachablePropagation` can do so if it sees that bb0 ends +// with `TerminatorKind::Unreachable`. + +use std::hint::{black_box, unreachable_unchecked}; + +static UNREACHABLE_CLOSURE: fn() = || unsafe { unreachable_unchecked() }; + +fn unreachable_function() { + unsafe { unreachable_unchecked() } +} + +// Use an intrinsic to more reliably trigger unreachable-propagation. +fn unreachable_intrinsic() { + unsafe { std::intrinsics::unreachable() } +} + +#[coverage(off)] +fn main() { + if black_box(false) { + UNREACHABLE_CLOSURE(); + } + if black_box(false) { + unreachable_function(); + } + if black_box(false) { + unreachable_intrinsic(); + } +} diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile index 1f2812cb0879..9ba077b18547 100644 --- a/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile @@ -3,7 +3,7 @@ include ../tools.mk # ignore-cross-compile # only-linux -# Make sure -Zpacked_bundled_libs-like behavior activates with whole-archive. +# Make sure -Zpacked_bundled_libs-like behavior activates with +bundle,+whole-archive. # We're using the llvm-nm instead of the system nm to ensure it is compatible # with the LLVM bitcode generated by rustc. @@ -11,7 +11,7 @@ NM = "$(LLVM_BIN_DIR)"/llvm-nm all: $(call NATIVE_STATICLIB,native_dep_1) $(call NATIVE_STATICLIB,native_dep_2) $(call NATIVE_STATICLIB,native_dep_3) $(call NATIVE_STATICLIB,native_dep_4) # test cfg with packed bundle - $(RUSTC) rust_dep_cfg.rs --crate-type=rlib -Zpacked_bundled_libs + $(RUSTC) rust_dep_cfg.rs --crate-type=rlib $(RUSTC) main.rs --extern rust_dep=$(TMPDIR)/librust_dep_cfg.rlib --crate-type=staticlib --cfg should_add $(AR) t $(TMPDIR)/librust_dep_cfg.rlib | $(CGREP) -e "libnative_dep_1.a" $(AR) t $(TMPDIR)/librust_dep_cfg.rlib | $(CGREP) -e "libnative_dep_2.a" diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs index abd846b6862d..bde9b739de6a 100644 --- a/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs @@ -1,5 +1,3 @@ -#![feature(packed_bundled_libs)] - #[link(name = "native_dep_1", kind = "static", modifiers = "+whole-archive,+bundle")] extern "C" {} diff --git a/tests/rustdoc-js/impl-trait.js b/tests/rustdoc-js/impl-trait.js index 710e594b5477..00d67d639bd0 100644 --- a/tests/rustdoc-js/impl-trait.js +++ b/tests/rustdoc-js/impl-trait.js @@ -1,3 +1,4 @@ +// exact-check // ignore-order const EXPECTED = [ @@ -20,9 +21,16 @@ const EXPECTED = [ { 'query': '-> Aaaaaaa', 'others': [ - { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' }, - { 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' }, { 'path': 'impl_trait', 'name': 'bbbbbbb' }, + { 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' }, + { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' }, + { 'path': 'impl_trait::Ccccccc', 'name': 'ggggggg' }, + ], + }, + { + 'query': '-> Bbbbbbb', + 'others': [ + { 'path': 'impl_trait::Ccccccc', 'name': 'ggggggg' }, ], }, { @@ -31,13 +39,14 @@ const EXPECTED = [ { 'path': 'impl_trait', 'name': 'Aaaaaaa' }, ], 'in_args': [ - { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' }, { 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' }, + { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' }, ], 'returned': [ - { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' }, - { 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' }, { 'path': 'impl_trait', 'name': 'bbbbbbb' }, + { 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' }, + { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' }, + { 'path': 'impl_trait::Ccccccc', 'name': 'ggggggg' }, ], }, ]; diff --git a/tests/rustdoc-js/impl-trait.rs b/tests/rustdoc-js/impl-trait.rs index fb8869b46f3d..d20fdd60ec96 100644 --- a/tests/rustdoc-js/impl-trait.rs +++ b/tests/rustdoc-js/impl-trait.rs @@ -1,6 +1,9 @@ pub trait Aaaaaaa {} +pub trait Bbbbbbb {} + impl Aaaaaaa for () {} +impl Bbbbbbb for () {} pub fn bbbbbbb() -> impl Aaaaaaa { () @@ -18,4 +21,7 @@ impl Ccccccc { pub fn fffffff(&self, x: impl Aaaaaaa) -> impl Aaaaaaa { x } + pub fn ggggggg(&self) -> impl Aaaaaaa + Bbbbbbb { + () + } } diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr index 4f2ded78c29f..ad049804213d 100644 --- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr @@ -28,6 +28,8 @@ LL | | LL | | /// main; LL | | /// ``` | |_______^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/rustdoc-ui/intra-doc/broken-link-in-unused-doc-string.stderr b/tests/rustdoc-ui/intra-doc/broken-link-in-unused-doc-string.stderr index 83e0d3962ca1..b25849f25b45 100644 --- a/tests/rustdoc-ui/intra-doc/broken-link-in-unused-doc-string.stderr +++ b/tests/rustdoc-ui/intra-doc/broken-link-in-unused-doc-string.stderr @@ -22,6 +22,7 @@ LL | /// [1] | ^ no item named `1` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/rustdoc-ui/issues/issue-105742.stderr b/tests/rustdoc-ui/issues/issue-105742.stderr index b63176c91490..4d3f9f5bced7 100644 --- a/tests/rustdoc-ui/issues/issue-105742.stderr +++ b/tests/rustdoc-ui/issues/issue-105742.stderr @@ -169,6 +169,7 @@ note: associated type defined here, with 1 lifetime parameter: `'a` | LL | type Item<'a, T>; | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | ::Item<'a>, @@ -185,6 +186,7 @@ note: associated type defined here, with 1 generic parameter: `T` | LL | type Item<'a, T>; | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing generic argument | LL | ::Item, @@ -201,6 +203,7 @@ note: associated type defined here, with 1 lifetime parameter: `'a` | LL | type Item<'a, T>; | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | Output = ::Item<'a>, @@ -217,6 +220,7 @@ note: associated type defined here, with 1 generic parameter: `T` | LL | type Item<'a, T>; | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing generic argument | LL | Output = ::Item, @@ -233,6 +237,7 @@ note: associated type defined here, with 1 lifetime parameter: `'a` | LL | type Item<'a, T>; | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | Output = ::Item<'a>> as SVec>::Item, @@ -249,6 +254,7 @@ note: associated type defined here, with 1 generic parameter: `T` | LL | type Item<'a, T>; | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing generic argument | LL | Output = ::Item> as SVec>::Item, @@ -265,6 +271,7 @@ note: associated type defined here, with 1 lifetime parameter: `'a` | LL | type Item<'a, T>; | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | Output = ::Item> as SVec>::Item<'a>, @@ -281,6 +288,7 @@ note: associated type defined here, with 1 generic parameter: `T` | LL | type Item<'a, T>; | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing generic argument | LL | Output = ::Item> as SVec>::Item, @@ -327,6 +335,7 @@ note: associated type defined here, with 1 lifetime parameter: `'a` | LL | type Item<'a, T>; | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | ::Item<'a>, @@ -343,6 +352,7 @@ note: associated type defined here, with 1 generic parameter: `T` | LL | type Item<'a, T>; | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing generic argument | LL | ::Item, @@ -359,6 +369,7 @@ note: associated type defined here, with 1 lifetime parameter: `'a` | LL | type Item<'a, T>; | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | Output = ::Item<'a>, @@ -375,6 +386,7 @@ note: associated type defined here, with 1 generic parameter: `T` | LL | type Item<'a, T>; | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing generic argument | LL | Output = ::Item, @@ -391,6 +403,7 @@ note: associated type defined here, with 1 lifetime parameter: `'a` | LL | type Item<'a, T>; | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | Output = ::Item<'a>> as SVec>::Item, @@ -407,6 +420,7 @@ note: associated type defined here, with 1 generic parameter: `T` | LL | type Item<'a, T>; | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing generic argument | LL | Output = ::Item> as SVec>::Item, @@ -423,6 +437,7 @@ note: associated type defined here, with 1 lifetime parameter: `'a` | LL | type Item<'a, T>; | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | Output = ::Item> as SVec>::Item<'a>, @@ -439,6 +454,7 @@ note: associated type defined here, with 1 generic parameter: `T` | LL | type Item<'a, T>; | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing generic argument | LL | Output = ::Item> as SVec>::Item, diff --git a/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.rs b/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.rs index c34ea0567a9d..ce94a06c39ea 100644 --- a/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.rs +++ b/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.rs @@ -1,12 +1,7 @@ +// compile-flags: -Zdeduplicate-diagnostics=yes #![deny(unknown_lints)] //~^ NOTE defined here #![allow(rustdoc::missing_doc_code_examples)] //~^ ERROR unknown lint -//~| ERROR unknown lint -//~| ERROR unknown lint //~| NOTE lint is unstable -//~| NOTE lint is unstable -//~| NOTE lint is unstable -//~| NOTE see issue -//~| NOTE see issue //~| NOTE see issue diff --git a/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.stderr b/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.stderr index 326dcfe3bdef..b8a08e943127 100644 --- a/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.stderr +++ b/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.stderr @@ -1,5 +1,5 @@ error: unknown lint: `rustdoc::missing_doc_code_examples` - --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:3:1 + --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:4:1 | LL | #![allow(rustdoc::missing_doc_code_examples)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,30 +8,10 @@ LL | #![allow(rustdoc::missing_doc_code_examples)] = note: see issue #101730 for more information = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable note: the lint level is defined here - --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:1:9 + --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:2:9 | LL | #![deny(unknown_lints)] | ^^^^^^^^^^^^^ -error: unknown lint: `rustdoc::missing_doc_code_examples` - --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:3:1 - | -LL | #![allow(rustdoc::missing_doc_code_examples)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: the `rustdoc::missing_doc_code_examples` lint is unstable - = note: see issue #101730 for more information - = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable - -error: unknown lint: `rustdoc::missing_doc_code_examples` - --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:3:1 - | -LL | #![allow(rustdoc::missing_doc_code_examples)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: the `rustdoc::missing_doc_code_examples` lint is unstable - = note: see issue #101730 for more information - = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable - -error: aborting due to 3 previous errors +error: aborting due to previous error diff --git a/tests/rustdoc-ui/unescaped_backticks.stderr b/tests/rustdoc-ui/unescaped_backticks.stderr index 83822f778d0f..2b4e491b1fe9 100644 --- a/tests/rustdoc-ui/unescaped_backticks.stderr +++ b/tests/rustdoc-ui/unescaped_backticks.stderr @@ -302,6 +302,7 @@ LL | | /// level changes. = help: if you meant to use a literal backtick, escape it change: or `None` if it isn't. to this: or `None\` if it isn't. + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: unescaped backtick --> $DIR/unescaped_backticks.rs:323:5 @@ -321,6 +322,7 @@ LL | | /// level changes. = help: if you meant to use a literal backtick, escape it change: `on_event` should be called. to this: `on_event\` should be called. + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: unescaped backtick --> $DIR/unescaped_backticks.rs:323:5 @@ -340,6 +342,7 @@ LL | | /// level changes. = help: if you meant to use a literal backtick, escape it change: [`rebuild_interest_cache`][rebuild] is called after the value of the max to this: [`rebuild_interest_cache\`][rebuild] is called after the value of the max + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: unescaped backtick --> $DIR/unescaped_backticks.rs:349:56 diff --git a/tests/rustdoc/issue-25001.rs b/tests/rustdoc/anchor-id-duplicate-method-name-25001.rs similarity index 94% rename from tests/rustdoc/issue-25001.rs rename to tests/rustdoc/anchor-id-duplicate-method-name-25001.rs index 268fae59496a..ffb0765d3c3f 100644 --- a/tests/rustdoc/issue-25001.rs +++ b/tests/rustdoc/anchor-id-duplicate-method-name-25001.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/25001 +#![crate_name="issue_25001"] + // @has issue_25001/struct.Foo.html pub struct Foo(T); diff --git a/tests/rustdoc/issue-28478.rs b/tests/rustdoc/anchor-id-trait-tymethod-28478.rs similarity index 92% rename from tests/rustdoc/issue-28478.rs rename to tests/rustdoc/anchor-id-trait-tymethod-28478.rs index 497276e6826a..5685040dc1e1 100644 --- a/tests/rustdoc/issue-28478.rs +++ b/tests/rustdoc/anchor-id-trait-tymethod-28478.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/28478 +#![crate_name="issue_28478"] + #![feature(associated_type_defaults)] // @has issue_28478/trait.Bar.html diff --git a/tests/rustdoc/issue-21474.rs b/tests/rustdoc/deduplicate-glob-import-impl-21474.rs similarity index 73% rename from tests/rustdoc/issue-21474.rs rename to tests/rustdoc/deduplicate-glob-import-impl-21474.rs index 5de26abace6f..2a675b4b6ef5 100644 --- a/tests/rustdoc/issue-21474.rs +++ b/tests/rustdoc/deduplicate-glob-import-impl-21474.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/21474 +#![crate_name="issue_21474"] + pub use inner::*; mod inner { diff --git a/tests/rustdoc/issue-22025.rs b/tests/rustdoc/deduplicate-trait-impl-22025.rs similarity index 59% rename from tests/rustdoc/issue-22025.rs rename to tests/rustdoc/deduplicate-trait-impl-22025.rs index a721a15f463b..65a556e3a70f 100644 --- a/tests/rustdoc/issue-22025.rs +++ b/tests/rustdoc/deduplicate-trait-impl-22025.rs @@ -1,6 +1,9 @@ // aux-build:issue-22025.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/22025 +#![crate_name="issue_22025"] + extern crate issue_22025; pub use issue_22025::foo::{Foo, Bar}; diff --git a/tests/rustdoc/doctest-hide-empty-line-23106.rs b/tests/rustdoc/doctest-hide-empty-line-23106.rs new file mode 100644 index 000000000000..8e1e2cf098cf --- /dev/null +++ b/tests/rustdoc/doctest-hide-empty-line-23106.rs @@ -0,0 +1,10 @@ +// compile-flags:--test + +// https://github.com/rust-lang/rust/issues/23106 +#![crate_name="issue_23106"] + +/// ``` +/// # +/// ``` +pub fn main() { +} diff --git a/tests/rustdoc/issue-23744.rs b/tests/rustdoc/doctest-markdown-inline-parse-23744.rs similarity index 76% rename from tests/rustdoc/issue-23744.rs rename to tests/rustdoc/doctest-markdown-inline-parse-23744.rs index 642817396b2a..128e2daba071 100644 --- a/tests/rustdoc/issue-23744.rs +++ b/tests/rustdoc/doctest-markdown-inline-parse-23744.rs @@ -1,5 +1,8 @@ // compile-flags:--test +// https://github.com/rust-lang/rust/issues/23744 +#![crate_name="issue_23744"] + /// Example of rustdoc incorrectly parsing ```rust,should_panic. /// /// ```should_panic diff --git a/tests/rustdoc/issue-25944.rs b/tests/rustdoc/doctest-multi-line-string-literal-25944.rs similarity index 63% rename from tests/rustdoc/issue-25944.rs rename to tests/rustdoc/doctest-multi-line-string-literal-25944.rs index 49625294bbea..eec796e4fbf2 100644 --- a/tests/rustdoc/issue-25944.rs +++ b/tests/rustdoc/doctest-multi-line-string-literal-25944.rs @@ -1,5 +1,8 @@ // compile-flags:--test +// https://github.com/rust-lang/rust/issues/25944 +#![crate_name="issue_25944"] + /// ``` /// let a = r#" /// foo diff --git a/tests/rustdoc/issue-22038.rs b/tests/rustdoc/extern-fn-22038.rs similarity index 87% rename from tests/rustdoc/issue-22038.rs rename to tests/rustdoc/extern-fn-22038.rs index de6cc78707c6..72d39c32a1c6 100644 --- a/tests/rustdoc/issue-22038.rs +++ b/tests/rustdoc/extern-fn-22038.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/22038 +#![crate_name="issue_22038"] + extern "C" { // @has issue_22038/fn.foo1.html \ // '//pre[@class="rust item-decl"]' 'pub unsafe extern "C" fn foo1()' diff --git a/tests/rustdoc/issue-28927.rs b/tests/rustdoc/ice-reexport-crate-root-28927.rs similarity index 65% rename from tests/rustdoc/issue-28927.rs rename to tests/rustdoc/ice-reexport-crate-root-28927.rs index 38a520850b6d..26debfc60e46 100644 --- a/tests/rustdoc/issue-28927.rs +++ b/tests/rustdoc/ice-reexport-crate-root-28927.rs @@ -2,5 +2,8 @@ // aux-build:issue-28927-1.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/28927 +#![crate_name="issue_28927"] + pub extern crate issue_28927_1 as inner1; pub use inner1 as foo; diff --git a/tests/rustdoc/issue-21092.rs b/tests/rustdoc/impl-assoc-type-21092.rs similarity index 72% rename from tests/rustdoc/issue-21092.rs rename to tests/rustdoc/impl-assoc-type-21092.rs index b054145a4831..f01f098a92f5 100644 --- a/tests/rustdoc/issue-21092.rs +++ b/tests/rustdoc/impl-assoc-type-21092.rs @@ -1,6 +1,9 @@ // aux-build:issue-21092.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/21092 +#![crate_name="issue_21092"] + extern crate issue_21092; // @has issue_21092/struct.Bar.html diff --git a/tests/rustdoc/inline_cross/auxiliary/fn-type.rs b/tests/rustdoc/inline_cross/auxiliary/fn-type.rs new file mode 100644 index 000000000000..dacda516bb88 --- /dev/null +++ b/tests/rustdoc/inline_cross/auxiliary/fn-type.rs @@ -0,0 +1 @@ +pub type F = for<'z, 'a, '_unused> fn(&'z for<'b> fn(&'b str), &'a ()) -> &'a (); diff --git a/tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs b/tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs index 42cfc3dc3197..fa61312ebc87 100644 --- a/tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs +++ b/tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs @@ -15,7 +15,7 @@ pub fn func4>(_x: T) {} pub fn func5( _f: impl for<'any> Fn(&'any str, &'any str) -> bool + for<'r> Other = ()>, - _a: impl for<'alpha, 'beta> Auxiliary<'alpha, Item<'beta> = fn(&'beta ())>, + _a: impl for<'beta, 'alpha, '_gamma> Auxiliary<'alpha, Item<'beta> = fn(&'beta ())>, ) {} pub trait Other { diff --git a/tests/rustdoc/auxiliary/issue-21801.rs b/tests/rustdoc/inline_cross/auxiliary/issue-21801.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-21801.rs rename to tests/rustdoc/inline_cross/auxiliary/issue-21801.rs diff --git a/tests/rustdoc/auxiliary/issue-23207-1.rs b/tests/rustdoc/inline_cross/auxiliary/issue-23207-1.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-23207-1.rs rename to tests/rustdoc/inline_cross/auxiliary/issue-23207-1.rs diff --git a/tests/rustdoc/auxiliary/issue-23207-2.rs b/tests/rustdoc/inline_cross/auxiliary/issue-23207-2.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-23207-2.rs rename to tests/rustdoc/inline_cross/auxiliary/issue-23207-2.rs diff --git a/tests/rustdoc/auxiliary/issue-27362-aux.rs b/tests/rustdoc/inline_cross/auxiliary/issue-27362-aux.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-27362-aux.rs rename to tests/rustdoc/inline_cross/auxiliary/issue-27362-aux.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/non_lifetime_binders.rs b/tests/rustdoc/inline_cross/auxiliary/non_lifetime_binders.rs new file mode 100644 index 000000000000..9170be16892b --- /dev/null +++ b/tests/rustdoc/inline_cross/auxiliary/non_lifetime_binders.rs @@ -0,0 +1,10 @@ +#![feature(non_lifetime_binders)] + +pub trait Trait {} + +pub fn f(_: impl for Trait) {} + +pub fn g(_: T) +where + T: for Trait, +{} diff --git a/tests/rustdoc/issue-27362.rs b/tests/rustdoc/inline_cross/const-fn-27362.rs similarity index 81% rename from tests/rustdoc/issue-27362.rs rename to tests/rustdoc/inline_cross/const-fn-27362.rs index 097e4e3b03d9..39b904662e06 100644 --- a/tests/rustdoc/issue-27362.rs +++ b/tests/rustdoc/inline_cross/const-fn-27362.rs @@ -1,6 +1,9 @@ // aux-build:issue-27362-aux.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/27362 +#![crate_name="issue_27362"] + extern crate issue_27362_aux; pub use issue_27362_aux::*; diff --git a/tests/rustdoc/issue-23207.rs b/tests/rustdoc/inline_cross/deduplicate-inlined-items-23207.rs similarity index 72% rename from tests/rustdoc/issue-23207.rs rename to tests/rustdoc/inline_cross/deduplicate-inlined-items-23207.rs index 1a4b849ee820..4e9596db589e 100644 --- a/tests/rustdoc/issue-23207.rs +++ b/tests/rustdoc/inline_cross/deduplicate-inlined-items-23207.rs @@ -2,6 +2,9 @@ // aux-build:issue-23207-2.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/23207 +#![crate_name="issue_23207"] + extern crate issue_23207_2; // @has issue_23207/fmt/index.html diff --git a/tests/rustdoc/inline_cross/fn-type.rs b/tests/rustdoc/inline_cross/fn-type.rs new file mode 100644 index 000000000000..e65790d3b05a --- /dev/null +++ b/tests/rustdoc/inline_cross/fn-type.rs @@ -0,0 +1,12 @@ +// Make sure that we print the higher-ranked parameters of cross-crate function pointer types. +// They should be rendered exactly as the user wrote it, i.e., in source order and with unused +// parameters present, not stripped. + +// aux-crate:fn_type=fn-type.rs +// edition: 2021 +#![crate_name = "user"] + +// @has user/type.F.html +// @has - '//*[@class="rust item-decl"]//code' \ +// "for<'z, 'a, '_unused> fn(_: &'z for<'b> fn(_: &'b str), _: &'a ()) -> &'a ();" +pub use fn_type::F; diff --git a/tests/rustdoc/inline_cross/impl_trait.rs b/tests/rustdoc/inline_cross/impl_trait.rs index 5c802c514861..9b22026e4906 100644 --- a/tests/rustdoc/inline_cross/impl_trait.rs +++ b/tests/rustdoc/inline_cross/impl_trait.rs @@ -29,7 +29,7 @@ pub use impl_trait_aux::func4; // @has impl_trait/fn.func5.html // @has - '//pre[@class="rust item-decl"]' "func5(" // @has - '//pre[@class="rust item-decl"]' "_f: impl for<'any> Fn(&'any str, &'any str) -> bool + for<'r> Other = ()>," -// @has - '//pre[@class="rust item-decl"]' "_a: impl for<'alpha, 'beta> Auxiliary<'alpha, Item<'beta> = fn(_: &'beta ())>" +// @has - '//pre[@class="rust item-decl"]' "_a: impl for<'beta, 'alpha, '_gamma> Auxiliary<'alpha, Item<'beta> = fn(_: &'beta ())>" // @!has - '//pre[@class="rust item-decl"]' 'where' pub use impl_trait_aux::func5; diff --git a/tests/rustdoc/inline_cross/non_lifetime_binders.rs b/tests/rustdoc/inline_cross/non_lifetime_binders.rs new file mode 100644 index 000000000000..9d3085c3ef26 --- /dev/null +++ b/tests/rustdoc/inline_cross/non_lifetime_binders.rs @@ -0,0 +1,13 @@ +// aux-crate:non_lifetime_binders=non_lifetime_binders.rs +// edition: 2021 +#![crate_name = "user"] + +// @has user/fn.f.html +// @has - '//pre[@class="rust item-decl"]' "f(_: impl for Trait)" +pub use non_lifetime_binders::f; + +// @has user/fn.g.html +// @has - '//pre[@class="rust item-decl"]' "g(_: T)\ +// where \ +// T: for Trait" +pub use non_lifetime_binders::g; diff --git a/tests/rustdoc/issue-21801.rs b/tests/rustdoc/inline_cross/sugar-closure-crate-21801.rs similarity index 74% rename from tests/rustdoc/issue-21801.rs rename to tests/rustdoc/inline_cross/sugar-closure-crate-21801.rs index 29d2ec64c206..bcbb2e9f4088 100644 --- a/tests/rustdoc/issue-21801.rs +++ b/tests/rustdoc/inline_cross/sugar-closure-crate-21801.rs @@ -1,6 +1,9 @@ // aux-build:issue-21801.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/21801 +#![crate_name="issue_21801"] + extern crate issue_21801; // @has issue_21801/struct.Foo.html diff --git a/tests/rustdoc/issue-23106.rs b/tests/rustdoc/issue-23106.rs deleted file mode 100644 index 8cda2fc33805..000000000000 --- a/tests/rustdoc/issue-23106.rs +++ /dev/null @@ -1,7 +0,0 @@ -// compile-flags:--test - -/// ``` -/// # -/// ``` -pub fn main() { -} diff --git a/tests/rustdoc/issue-23812.rs b/tests/rustdoc/macro-doc-comment-23812.rs similarity index 89% rename from tests/rustdoc/issue-23812.rs rename to tests/rustdoc/macro-doc-comment-23812.rs index 08fd1833bcef..57c18510b1e0 100644 --- a/tests/rustdoc/issue-23812.rs +++ b/tests/rustdoc/macro-doc-comment-23812.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/23812 +#![crate_name="issue_23812"] + macro_rules! doc { (#[$outer:meta] mod $i:ident { #![$inner:meta] }) => ( diff --git a/tests/rustdoc/issue-27862.rs b/tests/rustdoc/markdown-table-escape-pipe-27862.rs similarity index 63% rename from tests/rustdoc/issue-27862.rs rename to tests/rustdoc/markdown-table-escape-pipe-27862.rs index 77522f1be230..9af75d248884 100644 --- a/tests/rustdoc/issue-27862.rs +++ b/tests/rustdoc/markdown-table-escape-pipe-27862.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/27862 +#![crate_name="issue_27862"] + /// Tests | Table /// ------|------------- /// t = b | id = \|x\| x diff --git a/tests/rustdoc/issue-23511.rs b/tests/rustdoc/search-index-primitive-inherent-method-23511.rs similarity index 75% rename from tests/rustdoc/issue-23511.rs rename to tests/rustdoc/search-index-primitive-inherent-method-23511.rs index 21d02842431d..1d0fe27e1927 100644 --- a/tests/rustdoc/issue-23511.rs +++ b/tests/rustdoc/search-index-primitive-inherent-method-23511.rs @@ -2,6 +2,9 @@ #![feature(rustdoc_internals)] #![no_std] +// https://github.com/rust-lang/rust/issues/23511 +#![crate_name="issue_23511"] + pub mod str { #![rustc_doc_primitive = "str"] diff --git a/tests/rustdoc/issue-26606.rs b/tests/rustdoc/src-link-external-macro-26606.rs similarity index 56% rename from tests/rustdoc/issue-26606.rs rename to tests/rustdoc/src-link-external-macro-26606.rs index d5cb2c710cde..de717a5273bb 100644 --- a/tests/rustdoc/issue-26606.rs +++ b/tests/rustdoc/src-link-external-macro-26606.rs @@ -2,10 +2,13 @@ // ignore-cross-compile // build-aux-docs +// https://github.com/rust-lang/rust/issues/26606 +#![crate_name="issue_26606"] + // @has issue_26606_macro/macro.make_item.html #[macro_use] extern crate issue_26606_macro; // @has issue_26606/constant.FOO.html -// @has - '//a[@href="../src/issue_26606/issue-26606.rs.html#11"]' 'source' +// @has - '//a[@href="../src/issue_26606/src-link-external-macro-26606.rs.html#14"]' 'source' make_item!(FOO); diff --git a/tests/rustdoc/issue-26995.rs b/tests/rustdoc/src-mod-path-absolute-26995.rs similarity index 72% rename from tests/rustdoc/issue-26995.rs rename to tests/rustdoc/src-mod-path-absolute-26995.rs index fedc9f517492..b67fd9b26db4 100644 --- a/tests/rustdoc/issue-26995.rs +++ b/tests/rustdoc/src-mod-path-absolute-26995.rs @@ -1,6 +1,9 @@ // ignore-windows // compile-flags: --no-defaults +// https://github.com/rust-lang/rust/issues/26995 +#![crate_name="issue_26995"] + // @has src/issue_26995/dev/null.html // @has issue_26995/null/index.html '//a/@href' '../../src/issue_26995/dev/null.html' #[path="/dev/null"] diff --git a/tests/rustdoc/issue-27759.rs b/tests/rustdoc/staged-api-feature-issue-27759.rs similarity index 86% rename from tests/rustdoc/issue-27759.rs rename to tests/rustdoc/staged-api-feature-issue-27759.rs index 65e0f7cb87b0..56a45a600da6 100644 --- a/tests/rustdoc/issue-27759.rs +++ b/tests/rustdoc/staged-api-feature-issue-27759.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/27759 +#![crate_name="issue_27759"] + #![feature(staged_api)] #![doc(issue_tracker_base_url = "http://issue_url/")] diff --git a/tests/rustdoc/issue-27104.rs b/tests/rustdoc/strip-priv-imports-pass-27104.rs similarity index 77% rename from tests/rustdoc/issue-27104.rs rename to tests/rustdoc/strip-priv-imports-pass-27104.rs index 9f2fd9071144..e400a8f50118 100644 --- a/tests/rustdoc/issue-27104.rs +++ b/tests/rustdoc/strip-priv-imports-pass-27104.rs @@ -2,6 +2,9 @@ // aux-build:empty.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/27104 +#![crate_name="issue_27104"] + // @has issue_27104/index.html // @!hasraw - 'extern crate std' // @!hasraw - 'use std::prelude::' diff --git a/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs b/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs index f6f0c038536c..fa6734b6c6c3 100644 --- a/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs +++ b/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs @@ -6,7 +6,7 @@ extern crate rustc_middle; extern crate rustc_session; -use rustc_session::lint::{LintArray, LintPass}; +use rustc_session::lint::{LintPass, LintVec}; use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass}; declare_lint! { diff --git a/tests/ui-fulldeps/lint-pass-macros.rs b/tests/ui-fulldeps/lint-pass-macros.rs index b3c2a542792f..4c61783418fb 100644 --- a/tests/ui-fulldeps/lint-pass-macros.rs +++ b/tests/ui-fulldeps/lint-pass-macros.rs @@ -5,7 +5,7 @@ extern crate rustc_session; -use rustc_session::lint::{LintArray, LintPass}; +use rustc_session::lint::{LintPass, LintVec}; use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass}; declare_lint! { diff --git a/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs index 4a41e7fbb72a..150f0c6b9a2d 100644 --- a/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs @@ -5,13 +5,12 @@ // Load rustc as a plugin to get macros. extern crate rustc_driver; extern crate rustc_hir; -#[macro_use] extern crate rustc_lint; #[macro_use] extern crate rustc_session; use rustc_driver::plugin::Registry; -use rustc_lint::{LateContext, LateLintPass, LintArray, LintContext, LintId, LintPass}; +use rustc_lint::{LateContext, LateLintPass, LintContext, LintId}; declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); diff --git a/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs index 30956deb799e..acc5fe76051b 100644 --- a/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs @@ -6,14 +6,14 @@ extern crate rustc_ast; // Load rustc as a plugin to get macros extern crate rustc_driver; -#[macro_use] extern crate rustc_lint; #[macro_use] extern crate rustc_session; +use rustc_ast::ast; use rustc_driver::plugin::Registry; -use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; -use rustc_ast as ast; +use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; + declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); declare_lint_pass!(Pass => [TEST_LINT]); diff --git a/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs index c2c024865e8a..21de4aa7008f 100644 --- a/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs @@ -4,14 +4,14 @@ extern crate rustc_ast; // Load rustc as a plugin to get macros extern crate rustc_driver; -#[macro_use] extern crate rustc_lint; #[macro_use] extern crate rustc_session; -use rustc_driver::plugin::Registry; -use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintId, LintPass}; use rustc_ast as ast; +use rustc_driver::plugin::Registry; +use rustc_lint::{EarlyContext, EarlyLintPass, LintContext, LintId}; + declare_tool_lint!(pub clippy::TEST_LINT, Warn, "Warn about stuff"); declare_tool_lint!( /// Some docs diff --git a/tests/ui-fulldeps/plugin/lint-plugin-forbid-attrs.stderr b/tests/ui-fulldeps/plugin/lint-plugin-forbid-attrs.stderr index ae34b25cc2f8..66ea2e88f0c5 100644 --- a/tests/ui-fulldeps/plugin/lint-plugin-forbid-attrs.stderr +++ b/tests/ui-fulldeps/plugin/lint-plugin-forbid-attrs.stderr @@ -27,6 +27,8 @@ LL | #![forbid(test_lint)] ... LL | #[allow(test_lint)] | ^^^^^^^^^ overruled by previous forbid + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 --> $DIR/lint-plugin-forbid-attrs.rs:5:1 diff --git a/tests/ui-fulldeps/plugin/lint-plugin-forbid-cmdline.stderr b/tests/ui-fulldeps/plugin/lint-plugin-forbid-cmdline.stderr index 491c4d206468..9dbad702545c 100644 --- a/tests/ui-fulldeps/plugin/lint-plugin-forbid-cmdline.stderr +++ b/tests/ui-fulldeps/plugin/lint-plugin-forbid-cmdline.stderr @@ -21,6 +21,7 @@ LL | #[allow(test_lint)] | ^^^^^^^^^ overruled by previous forbid | = note: `forbid` lint level was set on command line + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 --> $DIR/lint-plugin-forbid-cmdline.rs:6:1 diff --git a/tests/ui-fulldeps/plugin/lint-tool-cmdline-allow.stderr b/tests/ui-fulldeps/plugin/lint-tool-cmdline-allow.stderr index 0e6617959998..4916b180a367 100644 --- a/tests/ui-fulldeps/plugin/lint-tool-cmdline-allow.stderr +++ b/tests/ui-fulldeps/plugin/lint-tool-cmdline-allow.stderr @@ -8,6 +8,7 @@ warning: lint name `test_lint` is deprecated and may not have an effect in the f | = help: change it to clippy::test_lint = note: requested on the command line with `-A test_lint` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: item is named 'lintme' --> $DIR/lint-tool-cmdline-allow.rs:9:1 @@ -29,6 +30,7 @@ warning: lint name `test_lint` is deprecated and may not have an effect in the f | = help: change it to clippy::test_lint = note: requested on the command line with `-A test_lint` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 5 warnings emitted diff --git a/tests/ui-fulldeps/plugin/lint-tool-test.stderr b/tests/ui-fulldeps/plugin/lint-tool-test.stderr index 027cf8f80cff..d1f0714f0423 100644 --- a/tests/ui-fulldeps/plugin/lint-tool-test.stderr +++ b/tests/ui-fulldeps/plugin/lint-tool-test.stderr @@ -23,12 +23,16 @@ warning: lint name `test_lint` is deprecated and may not have an effect in the f | LL | #![cfg_attr(foo, warn(test_lint))] | ^^^^^^^^^ help: change it to: `clippy::test_lint` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: lint name `clippy_group` is deprecated and may not have an effect in the future. --> $DIR/lint-tool-test.rs:13:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ help: change it to: `clippy::group` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: item is named 'lintme' --> $DIR/lint-tool-test.rs:18:1 @@ -56,6 +60,8 @@ warning: lint name `test_group` is deprecated and may not have an effect in the | LL | #[allow(test_group)] | ^^^^^^^^^^ help: change it to: `clippy::test_group` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `this_lint_does_not_exist` --> $DIR/lint-tool-test.rs:33:8 @@ -78,18 +84,24 @@ warning: lint name `test_lint` is deprecated and may not have an effect in the f | LL | #![cfg_attr(foo, warn(test_lint))] | ^^^^^^^^^ help: change it to: `clippy::test_lint` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: lint name `clippy_group` is deprecated and may not have an effect in the future. --> $DIR/lint-tool-test.rs:13:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ help: change it to: `clippy::group` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: lint name `test_group` is deprecated and may not have an effect in the future. --> $DIR/lint-tool-test.rs:29:9 | LL | #[allow(test_group)] | ^^^^^^^^^^ help: change it to: `clippy::test_group` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors; 11 warnings emitted diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index ca09f1f0153f..014cd5a73bd8 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -414,6 +414,8 @@ error: `#[lint(...)]` is not a valid attribute | LL | #[lint(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:601:1 diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index ce4ee3c2463e..d482f62ff064 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -47,12 +47,12 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> { assert_eq!(body.blocks.len(), 1); let block = &body.blocks[0]; assert_eq!(block.statements.len(), 1); - match &block.statements[0] { - stable_mir::mir::Statement::Assign(..) => {} + match &block.statements[0].kind { + stable_mir::mir::StatementKind::Assign(..) => {} other => panic!("{other:?}"), } - match &block.terminator { - stable_mir::mir::Terminator::Return => {} + match &block.terminator.kind { + stable_mir::mir::TerminatorKind::Return => {} other => panic!("{other:?}"), } @@ -61,8 +61,8 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> { assert_eq!(body.locals.len(), 7); assert_eq!(body.blocks.len(), 4); let block = &body.blocks[0]; - match &block.terminator { - stable_mir::mir::Terminator::Call { .. } => {} + match &block.terminator.kind { + stable_mir::mir::TerminatorKind::Call { .. } => {} other => panic!("{other:?}"), } @@ -70,27 +70,27 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> { let body = types.body(); assert_eq!(body.locals.len(), 6); assert_matches!( - body.locals[0].kind(), + body.locals[0].ty.kind(), stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::Bool) ); assert_matches!( - body.locals[1].kind(), + body.locals[1].ty.kind(), stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::Bool) ); assert_matches!( - body.locals[2].kind(), + body.locals[2].ty.kind(), stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::Char) ); assert_matches!( - body.locals[3].kind(), + body.locals[3].ty.kind(), stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::Int(stable_mir::ty::IntTy::I32)) ); assert_matches!( - body.locals[4].kind(), + body.locals[4].ty.kind(), stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::Uint(stable_mir::ty::UintTy::U64)) ); assert_matches!( - body.locals[5].kind(), + body.locals[5].ty.kind(), stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::Float( stable_mir::ty::FloatTy::F64 )) @@ -100,8 +100,8 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> { let body = drop.body(); assert_eq!(body.blocks.len(), 2); let block = &body.blocks[0]; - match &block.terminator { - stable_mir::mir::Terminator::Drop { .. } => {} + match &block.terminator.kind { + stable_mir::mir::TerminatorKind::Drop { .. } => {} other => panic!("{other:?}"), } @@ -109,15 +109,15 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> { let body = assert.body(); assert_eq!(body.blocks.len(), 2); let block = &body.blocks[0]; - match &block.terminator { - stable_mir::mir::Terminator::Assert { .. } => {} + match &block.terminator.kind { + stable_mir::mir::TerminatorKind::Assert { .. } => {} other => panic!("{other:?}"), } let monomorphic = get_item(&items, (DefKind::Fn, "monomorphic")).unwrap(); for block in monomorphic.body().blocks { - match &block.terminator { - stable_mir::mir::Terminator::Call { func, .. } => match func { + match &block.terminator.kind { + stable_mir::mir::TerminatorKind::Call { func, .. } => match func { stable_mir::mir::Operand::Constant(c) => match &c.literal.literal { stable_mir::ty::ConstantKind::Allocated(alloc) => { assert!(alloc.bytes.is_empty()); @@ -127,7 +127,7 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> { mut args, )) => { let func = def.body(); - match func.locals[1] + match func.locals[1].ty .fold(&mut args) .continue_value() .unwrap() @@ -149,7 +149,7 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> { }, other => panic!("{other:?}"), }, - stable_mir::mir::Terminator::Return => {} + stable_mir::mir::TerminatorKind::Return => {} other => panic!("{other:?}"), } } diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index 249e81762830..1f049b1785a6 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -1,16 +1,174 @@ // check-pass +// revisions: host +// revisions: arm +//[arm] compile-flags: --target arm-unknown-linux-gnueabi +//[arm] needs-llvm-components: arm +// revisions: aarch64 +//[aarch64] compile-flags: --target aarch64-unknown-linux-gnu +//[aarch64] needs-llvm-components: aarch64 +// revisions: s390x +//[s390x] compile-flags: --target s390x-unknown-linux-gnu +//[s390x] needs-llvm-components: systemz +// revisions: mips +//[mips] compile-flags: --target mips-unknown-linux-gnu +//[mips] needs-llvm-components: mips +// revisions: mips64 +//[mips64] compile-flags: --target mips64-unknown-linux-gnuabi64 +//[mips64] needs-llvm-components: mips +// revisions: sparc +//[sparc] compile-flags: --target sparc-unknown-linux-gnu +//[sparc] needs-llvm-components: sparc +// revisions: sparc64 +//[sparc64] compile-flags: --target sparc64-unknown-linux-gnu +//[sparc64] needs-llvm-components: sparc +// revisions: powerpc64 +//[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu +//[powerpc64] needs-llvm-components: powerpc +// revisions: riscv +//[riscv] compile-flags: --target riscv64gc-unknown-linux-gnu +//[riscv] needs-llvm-components: riscv +// revisions: loongarch64 +//[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu +//[loongarch64] needs-llvm-components: loongarch +// revisions: wasm +//[wasm] compile-flags: --target wasm32-unknown-unknown +//[wasm] needs-llvm-components: webassembly +// revisions: wasi +//[wasi] compile-flags: --target wasm32-wasi +//[wasi] needs-llvm-components: webassembly +// revisions: nvptx64 +//[nvptx64] compile-flags: --target nvptx64-nvidia-cuda +//[nvptx64] needs-llvm-components: nvptx #![feature(rustc_attrs, unsized_fn_params, transparent_unions)] +#![cfg_attr(not(host), feature(no_core, lang_items), no_std, no_core)] #![allow(unused, improper_ctypes_definitions, internal_features)] -use std::marker::PhantomData; -use std::mem::ManuallyDrop; -use std::num::NonZeroI32; -use std::ptr::NonNull; -// FIXME: a bunch of targets are broken in various ways. +// FIXME: some targets are broken in various ways. // Hence there are `cfg` throughout this test to disable parts of it on those targets. // sparc64: https://github.com/rust-lang/rust/issues/115336 // mips64: https://github.com/rust-lang/rust/issues/115404 +#[cfg(host)] +use std::{ + any::Any, marker::PhantomData, mem::ManuallyDrop, num::NonZeroI32, ptr::NonNull, rc::Rc, + sync::Arc, +}; + +/// To work cross-target this test must be no_core. +/// This little prelude supplies what we need. +#[cfg(not(host))] +mod prelude { + #[lang = "sized"] + pub trait Sized {} + + #[lang = "receiver"] + pub trait Receiver {} + impl Receiver for &T {} + impl Receiver for &mut T {} + + #[lang = "copy"] + pub trait Copy: Sized {} + impl Copy for i32 {} + impl Copy for f32 {} + impl Copy for &T {} + impl Copy for *const T {} + impl Copy for *mut T {} + + #[lang = "clone"] + pub trait Clone: Sized { + fn clone(&self) -> Self; + } + + #[lang = "phantom_data"] + pub struct PhantomData; + impl Copy for PhantomData {} + + #[lang = "unsafe_cell"] + #[repr(transparent)] + pub struct UnsafeCell { + value: T, + } + + pub trait Any: 'static {} + + pub enum Option { + None, + Some(T), + } + impl Copy for Option {} + + pub enum Result { + Ok(T), + Err(E), + } + impl Copy for Result {} + + #[lang = "manually_drop"] + #[repr(transparent)] + pub struct ManuallyDrop { + value: T, + } + impl Copy for ManuallyDrop {} + + #[repr(transparent)] + #[rustc_layout_scalar_valid_range_start(1)] + #[rustc_nonnull_optimization_guaranteed] + pub struct NonNull { + pointer: *const T, + } + impl Copy for NonNull {} + + #[repr(transparent)] + #[rustc_layout_scalar_valid_range_start(1)] + #[rustc_nonnull_optimization_guaranteed] + pub struct NonZeroI32(i32); + + // This just stands in for a non-trivial type. + pub struct Vec { + ptr: NonNull, + cap: usize, + len: usize, + } + + pub struct Unique { + pub pointer: NonNull, + pub _marker: PhantomData, + } + + pub struct Global; + + #[lang = "owned_box"] + pub struct Box(Unique, A); + + #[repr(C)] + struct RcBox { + strong: UnsafeCell, + weak: UnsafeCell, + value: T, + } + pub struct Rc { + ptr: NonNull>, + phantom: PhantomData>, + alloc: A, + } + + #[repr(C, align(8))] + struct AtomicUsize(usize); + #[repr(C)] + struct ArcInner { + strong: AtomicUsize, + weak: AtomicUsize, + data: T, + } + pub struct Arc { + ptr: NonNull>, + phantom: PhantomData>, + alloc: A, + } +} +#[cfg(not(host))] +use prelude::*; + macro_rules! assert_abi_compatible { ($name:ident, $t1:ty, $t2:ty) => { mod $name { @@ -26,8 +184,13 @@ macro_rules! assert_abi_compatible { }; } -#[derive(Copy, Clone)] struct Zst; +impl Copy for Zst {} +impl Clone for Zst { + fn clone(&self) -> Self { + Zst + } +} #[repr(C)] struct ReprC1(T); @@ -85,8 +248,8 @@ test_abi_compatible!(nonzero_int, NonZeroI32, i32); // `DispatchFromDyn` relies on ABI compatibility. // This is interesting since these types are not `repr(transparent)`. -test_abi_compatible!(rc, std::rc::Rc, *mut i32); -test_abi_compatible!(arc, std::sync::Arc, *mut i32); +test_abi_compatible!(rc, Rc, *mut i32); +test_abi_compatible!(arc, Arc, *mut i32); // `repr(transparent)` compatibility. #[repr(transparent)] @@ -160,7 +323,7 @@ mod unsized_ { use super::*; test_transparent_unsized!(str_, str); test_transparent_unsized!(slice, [u8]); - test_transparent_unsized!(dyn_trait, dyn std::any::Any); + test_transparent_unsized!(dyn_trait, dyn Any); } // RFC 3391 . @@ -185,7 +348,7 @@ test_nonnull!(ref_unsized, &[i32]); test_nonnull!(mut_unsized, &mut [i32]); test_nonnull!(fn_, fn()); test_nonnull!(nonnull, NonNull); -test_nonnull!(nonnull_unsized, NonNull); +test_nonnull!(nonnull_unsized, NonNull); test_nonnull!(non_zero, NonZeroI32); fn main() {} diff --git a/tests/ui/allocator/not-an-allocator.stderr b/tests/ui/allocator/not-an-allocator.stderr index 62bb0679f813..e1967b700133 100644 --- a/tests/ui/allocator/not-an-allocator.stderr +++ b/tests/ui/allocator/not-an-allocator.stderr @@ -18,6 +18,7 @@ LL | static A: usize = 0; | ^^^^^ the trait `GlobalAlloc` is not implemented for `usize` | = help: the trait `GlobalAlloc` is implemented for `System` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied @@ -29,6 +30,7 @@ LL | static A: usize = 0; | ^^^^^ the trait `GlobalAlloc` is not implemented for `usize` | = help: the trait `GlobalAlloc` is implemented for `System` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied @@ -40,6 +42,7 @@ LL | static A: usize = 0; | ^^^^^ the trait `GlobalAlloc` is not implemented for `usize` | = help: the trait `GlobalAlloc` is implemented for `System` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/tests/ui/associated-consts/defaults-not-assumed-fail.stderr b/tests/ui/associated-consts/defaults-not-assumed-fail.stderr index d659912341aa..ac5ec8e05ea9 100644 --- a/tests/ui/associated-consts/defaults-not-assumed-fail.stderr +++ b/tests/ui/associated-consts/defaults-not-assumed-fail.stderr @@ -24,6 +24,7 @@ note: erroneous constant encountered LL | assert_eq!(<() as Tr>::B, 0); // causes the error above | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr index 927422fa8dca..200856caa251 100644 --- a/tests/ui/associated-consts/issue-105330.stderr +++ b/tests/ui/associated-consts/issue-105330.stderr @@ -33,7 +33,7 @@ LL | fn main>() { = note: see issue #92827 for more information = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in impl headers --> $DIR/issue-105330.rs:6:27 | LL | impl TraitWAssocConst for impl Demo { diff --git a/tests/ui/associated-inherent-types/issue-109789.stderr b/tests/ui/associated-inherent-types/issue-109789.stderr index 84fc85cd09e4..e844f6795e6f 100644 --- a/tests/ui/associated-inherent-types/issue-109789.stderr +++ b/tests/ui/associated-inherent-types/issue-109789.stderr @@ -15,6 +15,7 @@ LL | fn bar(_: Foo fn(&'a ())>::Assoc) {} | = note: expected struct `Foo` found struct `Foo fn(&'a ())>` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr index 08721eff7b0c..3629aa4fceac 100644 --- a/tests/ui/associated-type-bounds/duplicate.stderr +++ b/tests/ui/associated-type-bounds/duplicate.stderr @@ -373,6 +373,8 @@ LL | trait TRS1: Iterator {} | ---------- ^^^^^^^^^^ re-bound here | | | `Item` bound here first + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified --> $DIR/duplicate.rs:197:34 @@ -389,6 +391,8 @@ LL | trait TRS2: Iterator {} | ---------- ^^^^^^^^^^ re-bound here | | | `Item` bound here first + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified --> $DIR/duplicate.rs:200:37 @@ -405,6 +409,8 @@ LL | trait TRS3: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here | | | `Item` bound here first + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified --> $DIR/duplicate.rs:205:29 @@ -445,6 +451,8 @@ LL | Self: Iterator, | ---------- ^^^^^^^^^^ re-bound here | | | `Item` bound here first + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified --> $DIR/duplicate.rs:230:32 @@ -461,6 +469,8 @@ LL | Self: Iterator, | ---------- ^^^^^^^^^^ re-bound here | | | `Item` bound here first + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified --> $DIR/duplicate.rs:237:35 @@ -477,6 +487,8 @@ LL | Self: Iterator, | ------------- ^^^^^^^^^^^^^ re-bound here | | | `Item` bound here first + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified --> $DIR/duplicate.rs:255:40 diff --git a/tests/ui/associated-type-bounds/issue-71443-1.stderr b/tests/ui/associated-type-bounds/issue-71443-1.stderr index 15cc9646b2c8..09c8ec2e289f 100644 --- a/tests/ui/associated-type-bounds/issue-71443-1.stderr +++ b/tests/ui/associated-type-bounds/issue-71443-1.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-71443-1.rs:6:5 | LL | fn hello Iterator>() { - | - help: try adding a return type: `-> Incorrect` + | - help: try adding a return type: `-> Incorrect` LL | Incorrect | ^^^^^^^^^ expected `()`, found `Incorrect` diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr index 366670269d7c..1a749007ab67 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr @@ -45,6 +45,7 @@ LL | trait Z<'a, T: ?Sized> ... LL | for<'b> >::W: Clone, | ^^^^^ required by this bound in `Z` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 3 previous errors diff --git a/tests/ui/async-await/async-await-let-else.stderr b/tests/ui/async-await/async-await-let-else.stderr index 9a1c1782233f..c3b4e761824f 100644 --- a/tests/ui/async-await/async-await-let-else.stderr +++ b/tests/ui/async-await/async-await-let-else.stderr @@ -22,7 +22,7 @@ error[E0277]: `Rc<()>` cannot be sent between threads safely --> $DIR/async-await-let-else.rs:47:13 | LL | async fn foo2(x: Option) { - | - within this `impl Future` + | ------------------------------ within this `impl Future` ... LL | is_send(foo2(Some(true))); | ------- ^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely diff --git a/tests/ui/async-await/drop-tracking-unresolved-typeck-results.stderr b/tests/ui/async-await/drop-tracking-unresolved-typeck-results.stderr index cfb0ebe38b66..0d3ee8a93776 100644 --- a/tests/ui/async-await/drop-tracking-unresolved-typeck-results.stderr +++ b/tests/ui/async-await/drop-tracking-unresolved-typeck-results.stderr @@ -23,6 +23,7 @@ LL | | }); | = note: `fn(&'0 ()) -> std::future::Ready<&'0 ()> {std::future::ready::<&'0 ()>}` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`... = note: ...but it actually implements `FnOnce<(&(),)>` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/in-trait/async-associated-types.rs b/tests/ui/async-await/in-trait/async-associated-types.rs index 3e2739a164f1..14f18811c1e2 100644 --- a/tests/ui/async-await/in-trait/async-associated-types.rs +++ b/tests/ui/async-await/in-trait/async-associated-types.rs @@ -9,12 +9,14 @@ use std::fmt::Debug; trait MyTrait<'a, 'b, T> where Self: 'a, T: Debug + Sized + 'b { type MyAssoc; + #[allow(async_fn_in_trait)] async fn foo(&'a self, key: &'b T) -> Self::MyAssoc; } impl<'a, 'b, T: Debug + Sized + 'b, U: 'a> MyTrait<'a, 'b, T> for U { type MyAssoc = (&'a U, &'b T); + #[allow(async_fn_in_trait)] async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) { (self, key) } diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs index 06413fe6f827..8143f0bca031 100644 --- a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs +++ b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs @@ -6,10 +6,12 @@ use std::future::Future; trait AsyncTrait { + #[allow(async_fn_in_trait)] async fn default_impl() { assert!(false); } + #[allow(async_fn_in_trait)] async fn call_default_impl() { Self::default_impl().await } diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr index 168ef8e9ee4e..3f1f1766eb58 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr @@ -1,8 +1,8 @@ error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/async-example-desugared-boxed-in-trait.rs:15:28 + --> $DIR/async-example-desugared-boxed-in-trait.rs:15:5 | LL | async fn foo(&self) -> i32 { - | ^^^ expected `Pin>>`, found future + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin>>`, found future | note: type in trait --> $DIR/async-example-desugared-boxed-in-trait.rs:11:22 diff --git a/tests/ui/async-await/in-trait/async-example-desugared-extra.rs b/tests/ui/async-await/in-trait/async-example-desugared-extra.rs index 3505690f1ec7..5d5aa817b4cb 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-extra.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared-extra.rs @@ -10,6 +10,7 @@ use std::pin::Pin; use std::task::Poll; pub trait MyTrait { + #[allow(async_fn_in_trait)] async fn foo(&self) -> i32; } diff --git a/tests/ui/async-await/in-trait/async-example-desugared.rs b/tests/ui/async-await/in-trait/async-example-desugared.rs index 0a5023176fef..7987645c97b2 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared.rs @@ -8,6 +8,7 @@ use std::future::Future; trait MyTrait { + #[allow(async_fn_in_trait)] async fn foo(&self) -> i32; } diff --git a/tests/ui/async-await/in-trait/async-example.rs b/tests/ui/async-await/in-trait/async-example.rs index abf94ef7450f..8c80c21eabec 100644 --- a/tests/ui/async-await/in-trait/async-example.rs +++ b/tests/ui/async-await/in-trait/async-example.rs @@ -5,7 +5,10 @@ #![allow(incomplete_features)] trait MyTrait { + #[allow(async_fn_in_trait)] async fn foo(&self) -> i32; + + #[allow(async_fn_in_trait)] async fn bar(&self) -> i32; } diff --git a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr b/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr index 5c8d64fc6cb4..90b40e221e45 100644 --- a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr +++ b/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr @@ -1,8 +1,8 @@ error[E0311]: the parameter type `U` may not live long enough - --> $DIR/async-generics-and-bounds.rs:12:28 + --> $DIR/async-generics-and-bounds.rs:12:5 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the parameter type `U` must be valid for the anonymous lifetime as defined here... --> $DIR/async-generics-and-bounds.rs:12:18 @@ -10,16 +10,16 @@ note: the parameter type `U` must be valid for the anonymous lifetime as defined LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; | ^ note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics-and-bounds.rs:12:28 + --> $DIR/async-generics-and-bounds.rs:12:5 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0311]: the parameter type `T` may not live long enough - --> $DIR/async-generics-and-bounds.rs:12:28 + --> $DIR/async-generics-and-bounds.rs:12:5 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the parameter type `T` must be valid for the anonymous lifetime as defined here... --> $DIR/async-generics-and-bounds.rs:12:18 @@ -27,10 +27,10 @@ note: the parameter type `T` must be valid for the anonymous lifetime as defined LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; | ^ note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics-and-bounds.rs:12:28 + --> $DIR/async-generics-and-bounds.rs:12:5 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/in-trait/async-generics.stderr b/tests/ui/async-await/in-trait/async-generics.stderr index 6ae73d9e3a60..07f986e94e02 100644 --- a/tests/ui/async-await/in-trait/async-generics.stderr +++ b/tests/ui/async-await/in-trait/async-generics.stderr @@ -1,8 +1,8 @@ error[E0311]: the parameter type `U` may not live long enough - --> $DIR/async-generics.rs:9:28 + --> $DIR/async-generics.rs:9:5 | LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the parameter type `U` must be valid for the anonymous lifetime as defined here... --> $DIR/async-generics.rs:9:18 @@ -10,16 +10,16 @@ note: the parameter type `U` must be valid for the anonymous lifetime as defined LL | async fn foo(&self) -> &(T, U); | ^ note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics.rs:9:28 + --> $DIR/async-generics.rs:9:5 | LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0311]: the parameter type `T` may not live long enough - --> $DIR/async-generics.rs:9:28 + --> $DIR/async-generics.rs:9:5 | LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the parameter type `T` must be valid for the anonymous lifetime as defined here... --> $DIR/async-generics.rs:9:18 @@ -27,10 +27,10 @@ note: the parameter type `T` must be valid for the anonymous lifetime as defined LL | async fn foo(&self) -> &(T, U); | ^ note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics.rs:9:28 + --> $DIR/async-generics.rs:9:5 | LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/in-trait/async-lifetimes-and-bounds.rs b/tests/ui/async-await/in-trait/async-lifetimes-and-bounds.rs index d5481d277e40..96cda4e35da7 100644 --- a/tests/ui/async-await/in-trait/async-lifetimes-and-bounds.rs +++ b/tests/ui/async-await/in-trait/async-lifetimes-and-bounds.rs @@ -7,6 +7,7 @@ use std::fmt::Debug; trait MyTrait<'a, 'b, T> { + #[allow(async_fn_in_trait)] async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized; } diff --git a/tests/ui/async-await/in-trait/async-lifetimes.rs b/tests/ui/async-await/in-trait/async-lifetimes.rs index f298e45d2390..4b0264bc8d01 100644 --- a/tests/ui/async-await/in-trait/async-lifetimes.rs +++ b/tests/ui/async-await/in-trait/async-lifetimes.rs @@ -5,6 +5,7 @@ #![allow(incomplete_features)] trait MyTrait<'a, 'b, T> { + #[allow(async_fn_in_trait)] async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T); } diff --git a/tests/ui/async-await/in-trait/async-recursive-generic.stderr b/tests/ui/async-await/in-trait/async-recursive-generic.stderr index cab173bdd5b7..6897bf1c9994 100644 --- a/tests/ui/async-await/in-trait/async-recursive-generic.stderr +++ b/tests/ui/async-await/in-trait/async-recursive-generic.stderr @@ -1,8 +1,8 @@ error[E0733]: recursion in an `async fn` requires boxing - --> $DIR/async-recursive-generic.rs:11:48 + --> $DIR/async-recursive-generic.rs:11:5 | LL | async fn foo_recursive(&self, n: usize) -> T { - | ^ recursive `async fn` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive `async fn` | = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion diff --git a/tests/ui/async-await/in-trait/async-recursive.stderr b/tests/ui/async-await/in-trait/async-recursive.stderr index 9feff37b3fe4..c9b4784e3b40 100644 --- a/tests/ui/async-await/in-trait/async-recursive.stderr +++ b/tests/ui/async-await/in-trait/async-recursive.stderr @@ -1,8 +1,8 @@ error[E0733]: recursion in an `async fn` requires boxing - --> $DIR/async-recursive.rs:11:48 + --> $DIR/async-recursive.rs:11:5 | LL | async fn foo_recursive(&self, n: usize) -> i32 { - | ^^^ recursive `async fn` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive `async fn` | = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr index 7c750bf51018..4ba6d4cba0cb 100644 --- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr @@ -1,14 +1,14 @@ error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/dont-project-to-specializable-projection.rs:14:35 + --> $DIR/dont-project-to-specializable-projection.rs:14:5 | LL | default async fn foo(_: T) -> &'static str { - | ^^^^^^^^^^^^ expected associated type, found future + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found future | note: type in trait - --> $DIR/dont-project-to-specializable-projection.rs:10:27 + --> $DIR/dont-project-to-specializable-projection.rs:10:5 | LL | async fn foo(_: T) -> &'static str; - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature `fn(_) -> impl Future` found signature `fn(_) -> impl Future` diff --git a/tests/ui/async-await/in-trait/early-bound-1.rs b/tests/ui/async-await/in-trait/early-bound-1.rs index 6b3b142014bd..bc410cc29546 100644 --- a/tests/ui/async-await/in-trait/early-bound-1.rs +++ b/tests/ui/async-await/in-trait/early-bound-1.rs @@ -5,6 +5,7 @@ #![allow(incomplete_features)] pub trait Foo { + #[allow(async_fn_in_trait)] async fn foo(&mut self); } diff --git a/tests/ui/async-await/in-trait/early-bound-2.rs b/tests/ui/async-await/in-trait/early-bound-2.rs index 270443229b05..1974b1d9f7a4 100644 --- a/tests/ui/async-await/in-trait/early-bound-2.rs +++ b/tests/ui/async-await/in-trait/early-bound-2.rs @@ -5,6 +5,7 @@ #![allow(incomplete_features)] pub trait Foo { + #[allow(async_fn_in_trait)] async fn foo(&mut self); } diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.rs b/tests/ui/async-await/in-trait/fn-not-async-err2.rs index 78017429f73d..e1703415dbd5 100644 --- a/tests/ui/async-await/in-trait/fn-not-async-err2.rs +++ b/tests/ui/async-await/in-trait/fn-not-async-err2.rs @@ -11,7 +11,7 @@ trait MyTrait { impl MyTrait for i32 { fn foo(&self) -> impl Future { - //~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types, not in `impl` method return types async { *self } } } diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.stderr b/tests/ui/async-await/in-trait/fn-not-async-err2.stderr index 37d9669c0124..a7c897f786e4 100644 --- a/tests/ui/async-await/in-trait/fn-not-async-err2.stderr +++ b/tests/ui/async-await/in-trait/fn-not-async-err2.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `impl` method return types --> $DIR/fn-not-async-err2.rs:13:22 | LL | fn foo(&self) -> impl Future { diff --git a/tests/ui/async-await/in-trait/implied-bounds.rs b/tests/ui/async-await/in-trait/implied-bounds.rs index 52bceb3cc5cd..40eebad86c27 100644 --- a/tests/ui/async-await/in-trait/implied-bounds.rs +++ b/tests/ui/async-await/in-trait/implied-bounds.rs @@ -7,6 +7,8 @@ trait TcpStack { type Connection<'a>: Sized where Self: 'a; fn connect<'a>(&'a self) -> Self::Connection<'a>; + + #[allow(async_fn_in_trait)] async fn async_connect<'a>(&'a self) -> Self::Connection<'a>; } diff --git a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr index e0c1acfedfc3..41e84466a144 100644 --- a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr +++ b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr @@ -2,7 +2,7 @@ error[E0391]: cycle detected when computing layout of `{async fn body@$DIR/indir | = note: ...which requires computing layout of `<::Second as Second>::{opaque#0}`... = note: ...which again requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:35:27: 37:6}`, completing the cycle - = note: cycle used when computing layout of `::second::{opaque#0}` + = note: cycle used when computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:8:13: 10:6}` = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/async-await/in-trait/issue-102138.rs b/tests/ui/async-await/in-trait/issue-102138.rs index f61b34ed99e0..3d9cef0210fa 100644 --- a/tests/ui/async-await/in-trait/issue-102138.rs +++ b/tests/ui/async-await/in-trait/issue-102138.rs @@ -10,6 +10,8 @@ async fn yield_now() {} trait AsyncIterator { type Item; + + #[allow(async_fn_in_trait)] async fn next(&mut self) -> Option; } diff --git a/tests/ui/async-await/in-trait/issue-102219.rs b/tests/ui/async-await/in-trait/issue-102219.rs index 9a35f6515cb1..4a23e4be4f71 100644 --- a/tests/ui/async-await/in-trait/issue-102219.rs +++ b/tests/ui/async-await/in-trait/issue-102219.rs @@ -6,5 +6,6 @@ #![allow(incomplete_features)] trait T { + #[allow(async_fn_in_trait)] async fn foo(); } diff --git a/tests/ui/async-await/in-trait/issue-102310.rs b/tests/ui/async-await/in-trait/issue-102310.rs index 49c3e9feeb4c..327d432a6a6d 100644 --- a/tests/ui/async-await/in-trait/issue-102310.rs +++ b/tests/ui/async-await/in-trait/issue-102310.rs @@ -5,6 +5,7 @@ #![allow(incomplete_features)] pub trait SpiDevice { + #[allow(async_fn_in_trait)] async fn transaction(&mut self); } diff --git a/tests/ui/async-await/in-trait/issue-104678.rs b/tests/ui/async-await/in-trait/issue-104678.rs index e396df4e5d11..0a3347075054 100644 --- a/tests/ui/async-await/in-trait/issue-104678.rs +++ b/tests/ui/async-await/in-trait/issue-104678.rs @@ -8,6 +8,7 @@ use std::future::Future; pub trait Pool { type Conn; + #[allow(async_fn_in_trait)] async fn async_callback<'a, F: FnOnce(&'a Self::Conn) -> Fut, Fut: Future>( &'a self, callback: F, diff --git a/tests/ui/async-await/in-trait/missing-feature-flag.stderr b/tests/ui/async-await/in-trait/missing-feature-flag.stderr index f6aba1fcdbf8..87a7e85bfbbb 100644 --- a/tests/ui/async-await/in-trait/missing-feature-flag.stderr +++ b/tests/ui/async-await/in-trait/missing-feature-flag.stderr @@ -7,6 +7,12 @@ LL | async fn foo(_: T) -> &'static str; LL | impl MyTrait for MyStruct {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation +error[E0308]: mismatched types + --> $DIR/missing-feature-flag.rs:16:42 + | +LL | async fn foo(_: i32) -> &'static str {} + | ^^ expected `&str`, found `()` + error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default` --> $DIR/missing-feature-flag.rs:16:5 | @@ -18,12 +24,6 @@ LL | async fn foo(_: i32) -> &'static str {} | = note: to specialize, `foo` in the parent `impl` must be marked `default` -error[E0308]: mismatched types - --> $DIR/missing-feature-flag.rs:16:42 - | -LL | async fn foo(_: i32) -> &'static str {} - | ^^ expected `&str`, found `()` - error: aborting due to 3 previous errors Some errors have detailed explanations: E0046, E0308, E0520. diff --git a/tests/ui/async-await/in-trait/nested-rpit.rs b/tests/ui/async-await/in-trait/nested-rpit.rs index 9cdc23bbc780..8c43e1b07e29 100644 --- a/tests/ui/async-await/in-trait/nested-rpit.rs +++ b/tests/ui/async-await/in-trait/nested-rpit.rs @@ -9,6 +9,7 @@ use std::future::Future; use std::marker::PhantomData; trait Lockable { + #[allow(async_fn_in_trait)] async fn lock_all_entries(&self) -> impl Future>; } diff --git a/tests/ui/async-await/in-trait/normalize-opaque-with-bound-vars.rs b/tests/ui/async-await/in-trait/normalize-opaque-with-bound-vars.rs index c4008f2b7e7a..f8fe0d1bde88 100644 --- a/tests/ui/async-await/in-trait/normalize-opaque-with-bound-vars.rs +++ b/tests/ui/async-await/in-trait/normalize-opaque-with-bound-vars.rs @@ -11,6 +11,7 @@ pub struct SharedState {} pub trait State { + #[allow(async_fn_in_trait)] async fn execute(self, shared_state: &SharedState); } diff --git a/tests/ui/async-await/in-trait/warn.rs b/tests/ui/async-await/in-trait/warn.rs new file mode 100644 index 000000000000..4f981c31f5c0 --- /dev/null +++ b/tests/ui/async-await/in-trait/warn.rs @@ -0,0 +1,23 @@ +// edition: 2021 + +#![feature(async_fn_in_trait)] +#![deny(async_fn_in_trait)] + +pub trait Foo { + async fn not_send(); + //~^ ERROR use of `async fn` in public traits is discouraged +} + +mod private { + pub trait FooUnreachable { + async fn not_send(); + // No warning + } +} + +pub(crate) trait FooCrate { + async fn not_send(); + // No warning +} + +fn main() {} diff --git a/tests/ui/async-await/in-trait/warn.stderr b/tests/ui/async-await/in-trait/warn.stderr new file mode 100644 index 000000000000..eac41a6e9242 --- /dev/null +++ b/tests/ui/async-await/in-trait/warn.stderr @@ -0,0 +1,20 @@ +error: use of `async fn` in public traits is discouraged as auto trait bounds cannot be specified + --> $DIR/warn.rs:7:5 + | +LL | async fn not_send(); + | ^^^^^ + | + = note: you can suppress this lint if you plan to use the trait only in your own code, or do not care about auto traits like `Send` on the `Future` +note: the lint level is defined here + --> $DIR/warn.rs:4:9 + | +LL | #![deny(async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ +help: you can alternatively desugar to a normal `fn` that returns `impl Future` and add any desired bounds such as `Send` + | +LL - async fn not_send(); +LL + fn not_send() -> impl std::future::Future + Send; + | + +error: aborting due to previous error + diff --git a/tests/ui/async-await/issue-108572.fixed b/tests/ui/async-await/issue-108572.fixed new file mode 100644 index 000000000000..8f0133d97b54 --- /dev/null +++ b/tests/ui/async-await/issue-108572.fixed @@ -0,0 +1,16 @@ +// edition: 2021 +// run-rustfix +#![allow(unused_must_use, dead_code)] + +use std::future::Future; +fn foo() -> impl Future { + async { } +} + +fn bar(cx: &mut std::task::Context<'_>) { + let fut = foo(); + let mut pinned = std::pin::pin!(fut); + pinned.as_mut().poll(cx); + //~^ ERROR no method named `poll` found for opaque type `impl Future` in the current scope [E0599] +} +fn main() {} diff --git a/tests/ui/async-await/issue-108572.rs b/tests/ui/async-await/issue-108572.rs index efcb8b8ebab0..3596580763c5 100644 --- a/tests/ui/async-await/issue-108572.rs +++ b/tests/ui/async-await/issue-108572.rs @@ -1,12 +1,15 @@ // edition: 2021 +// run-rustfix +#![allow(unused_must_use, dead_code)] use std::future::Future; fn foo() -> impl Future { async { } } -fn main() { +fn bar(cx: &mut std::task::Context<'_>) { let fut = foo(); - fut.poll(); + fut.poll(cx); //~^ ERROR no method named `poll` found for opaque type `impl Future` in the current scope [E0599] } +fn main() {} diff --git a/tests/ui/async-await/issue-108572.stderr b/tests/ui/async-await/issue-108572.stderr index 0dbcf4d660a9..588669092b01 100644 --- a/tests/ui/async-await/issue-108572.stderr +++ b/tests/ui/async-await/issue-108572.stderr @@ -1,11 +1,16 @@ error[E0599]: no method named `poll` found for opaque type `impl Future` in the current scope - --> $DIR/issue-108572.rs:10:9 + --> $DIR/issue-108572.rs:12:9 | -LL | fut.poll(); +LL | fut.poll(cx); | ^^^^ method not found in `impl Future` | = help: method `poll` found on `Pin<&mut impl Future>`, see documentation for `std::pin::Pin` = help: self type must be pinned to call `Future::poll`, see https://rust-lang.github.io/async-book/04_pinning/01_chapter.html#pinning-in-practice +help: consider pinning the expression + | +LL ~ let mut pinned = std::pin::pin!(fut); +LL ~ pinned.as_mut().poll(cx); + | error: aborting due to previous error diff --git a/tests/ui/async-await/issue-64130-3-other.stderr b/tests/ui/async-await/issue-64130-3-other.stderr index 573da1034c57..4bbb7731b110 100644 --- a/tests/ui/async-await/issue-64130-3-other.stderr +++ b/tests/ui/async-await/issue-64130-3-other.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `Foo: Qux` is not satisfied in `impl Future $DIR/issue-64130-3-other.rs:25:12 | LL | async fn bar() { - | - within this `impl Future` + | -------------- within this `impl Future` ... LL | is_qux(bar()); | ^^^^^ within `impl Future`, the trait `Qux` is not implemented for `Foo` diff --git a/tests/ui/async-await/issues/issue-67893.stderr b/tests/ui/async-await/issues/issue-67893.stderr index f36269e8f365..3d6d1fb5c091 100644 --- a/tests/ui/async-await/issues/issue-67893.stderr +++ b/tests/ui/async-await/issues/issue-67893.stderr @@ -6,10 +6,10 @@ LL | g(issue_67893::run()) | | | required by a bound introduced by this call | - ::: $DIR/auxiliary/issue_67893.rs:9:20 + ::: $DIR/auxiliary/issue_67893.rs:9:1 | LL | pub async fn run() { - | - within this `impl Future` + | ------------------ within this `impl Future` | = help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, ()>` = note: required because it captures the following types: `Arc>`, `MutexGuard<'_, ()>`, `impl Future` diff --git a/tests/ui/async-await/mutually-recursive-async-impl-trait-type.stderr b/tests/ui/async-await/mutually-recursive-async-impl-trait-type.stderr index f789ad2a05c7..9442609e8058 100644 --- a/tests/ui/async-await/mutually-recursive-async-impl-trait-type.stderr +++ b/tests/ui/async-await/mutually-recursive-async-impl-trait-type.stderr @@ -1,17 +1,17 @@ error[E0733]: recursion in an `async fn` requires boxing - --> $DIR/mutually-recursive-async-impl-trait-type.rs:5:18 + --> $DIR/mutually-recursive-async-impl-trait-type.rs:5:1 | LL | async fn rec_1() { - | ^ recursive `async fn` + | ^^^^^^^^^^^^^^^^ recursive `async fn` | = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion error[E0733]: recursion in an `async fn` requires boxing - --> $DIR/mutually-recursive-async-impl-trait-type.rs:9:18 + --> $DIR/mutually-recursive-async-impl-trait-type.rs:9:1 | LL | async fn rec_2() { - | ^ recursive `async fn` + | ^^^^^^^^^^^^^^^^ recursive `async fn` | = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion diff --git a/tests/ui/async-await/partial-drop-partial-reinit.stderr b/tests/ui/async-await/partial-drop-partial-reinit.stderr index 85e1830c78e9..d115c1b1cc4b 100644 --- a/tests/ui/async-await/partial-drop-partial-reinit.stderr +++ b/tests/ui/async-await/partial-drop-partial-reinit.stderr @@ -7,7 +7,7 @@ LL | gimme_send(foo()); | required by a bound introduced by this call ... LL | async fn foo() { - | - within this `impl Future` + | -------------- within this `impl Future` | = help: within `impl Future`, the trait `Send` is not implemented for `NotSend` = note: required because it appears within the type `(NotSend,)` diff --git a/tests/ui/async-await/pin-needed-to-poll.stderr b/tests/ui/async-await/pin-needed-to-poll.stderr index b1f4a73aafea..964709daeda2 100644 --- a/tests/ui/async-await/pin-needed-to-poll.stderr +++ b/tests/ui/async-await/pin-needed-to-poll.stderr @@ -6,14 +6,12 @@ LL | struct Sleep; ... LL | self.sleep.poll(cx) | ^^^^ method not found in `Sleep` - --> $SRC_DIR/core/src/future/future.rs:LL:COL | - = note: the method is available for `Pin<&mut Sleep>` here +help: consider pinning the expression | -help: consider wrapping the receiver expression with the appropriate type +LL ~ let mut pinned = std::pin::pin!(self.sleep); +LL ~ pinned.as_mut().poll(cx) | -LL | Pin::new(&mut self.sleep).poll(cx) - | +++++++++++++ + error: aborting due to previous error diff --git a/tests/ui/async-await/recursive-async-impl-trait-type.stderr b/tests/ui/async-await/recursive-async-impl-trait-type.stderr index 63f64f445574..64917329c499 100644 --- a/tests/ui/async-await/recursive-async-impl-trait-type.stderr +++ b/tests/ui/async-await/recursive-async-impl-trait-type.stderr @@ -1,8 +1,8 @@ error[E0733]: recursion in an `async fn` requires boxing - --> $DIR/recursive-async-impl-trait-type.rs:5:40 + --> $DIR/recursive-async-impl-trait-type.rs:5:1 | LL | async fn recursive_async_function() -> () { - | ^^ recursive `async fn` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive `async fn` | = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.stderr b/tests/ui/async-await/return-type-notation/issue-110963-early.stderr index 969094a2c580..98e3cbd0d7f4 100644 --- a/tests/ui/async-await/return-type-notation/issue-110963-early.stderr +++ b/tests/ui/async-await/return-type-notation/issue-110963-early.stderr @@ -44,6 +44,7 @@ note: the lifetime requirement is introduced here | LL | F: Future + Send + 'static, | ^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/auto-traits/pre-cfg.rs b/tests/ui/auto-traits/pre-cfg.rs new file mode 100644 index 000000000000..e6e840dcbab6 --- /dev/null +++ b/tests/ui/auto-traits/pre-cfg.rs @@ -0,0 +1,8 @@ +// check-pass + +#[cfg(FALSE)] +auto trait Foo {} +//~^ WARN `auto` traits are unstable +//~| WARN unstable syntax can change at any point in the future, causing a hard error! + +fn main() {} diff --git a/tests/ui/auto-traits/pre-cfg.stderr b/tests/ui/auto-traits/pre-cfg.stderr new file mode 100644 index 000000000000..6efa05b4326d --- /dev/null +++ b/tests/ui/auto-traits/pre-cfg.stderr @@ -0,0 +1,13 @@ +warning: `auto` traits are unstable + --> $DIR/pre-cfg.rs:4:1 + | +LL | auto trait Foo {} + | ^^^^ + | + = note: see issue #13231 for more information + = help: add `#![feature(auto_traits)]` to the crate attributes to enable + = warning: unstable syntax can change at any point in the future, causing a hard error! + = note: for more information, see issue #65860 + +warning: 1 warning emitted + diff --git a/tests/ui/block-result/block-must-not-have-result-res.stderr b/tests/ui/block-result/block-must-not-have-result-res.stderr index 0080d06dd207..b7427462bcbd 100644 --- a/tests/ui/block-result/block-must-not-have-result-res.stderr +++ b/tests/ui/block-result/block-must-not-have-result-res.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/block-must-not-have-result-res.rs:5:9 | LL | fn drop(&mut self) { - | - expected `()` because of default return type + | - expected `()` because of default return type LL | true | ^^^^ expected `()`, found `bool` diff --git a/tests/ui/block-result/issue-20862.stderr b/tests/ui/block-result/issue-20862.stderr index 17b524fe3117..1df3a6836206 100644 --- a/tests/ui/block-result/issue-20862.stderr +++ b/tests/ui/block-result/issue-20862.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-20862.rs:2:5 | LL | fn foo(x: i32) { - | - help: a return type might be missing here: `-> _` + | - help: a return type might be missing here: `-> _` LL | |y| x + y | ^^^^^^^^^ expected `()`, found closure | diff --git a/tests/ui/block-result/issue-22645.stderr b/tests/ui/block-result/issue-22645.stderr index 677b40aaa9da..1064848f5139 100644 --- a/tests/ui/block-result/issue-22645.stderr +++ b/tests/ui/block-result/issue-22645.stderr @@ -17,7 +17,7 @@ error[E0308]: mismatched types --> $DIR/issue-22645.rs:15:3 | LL | fn main() { - | - expected `()` because of default return type + | - expected `()` because of default return type LL | let b = Bob + 3.5; LL | b + 3 | ^^^^^ expected `()`, found `Bob` diff --git a/tests/ui/block-result/issue-5500.stderr b/tests/ui/block-result/issue-5500.stderr index 8cd4bd65871a..417991e9e0bb 100644 --- a/tests/ui/block-result/issue-5500.stderr +++ b/tests/ui/block-result/issue-5500.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-5500.rs:2:5 | LL | fn main() { - | - expected `()` because of default return type + | - expected `()` because of default return type LL | &panic!() | ^^^^^^^^^ expected `()`, found `&_` | diff --git a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr index 930fea9158d4..7ebea3c03d36 100644 --- a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr +++ b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr @@ -53,6 +53,7 @@ note: ...does not necessarily outlive the lifetime `'c` as defined here | LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { | ^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0195]: lifetime parameters or bounds on method `wrong_bound2` do not match the trait declaration --> $DIR/regions-bound-missing-bound-in-impl.rs:42:20 diff --git a/tests/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr b/tests/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr index 9ce4710d69bc..75df314e0baa 100644 --- a/tests/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr +++ b/tests/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr @@ -25,6 +25,7 @@ LL | #![cfg_attr(foo, crate_type="bin")] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #91632 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `crate_name` within an `#![cfg_attr] attribute is deprecated` --> $DIR/future-compat-crate-attributes-using-cfg_attr.rs:9:18 @@ -34,6 +35,7 @@ LL | #![cfg_attr(foo, crate_name="bar")] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #91632 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors diff --git a/tests/ui/closures/add_semicolon_non_block_closure.stderr b/tests/ui/closures/add_semicolon_non_block_closure.stderr index ed829fc98f86..6f9c309edda2 100644 --- a/tests/ui/closures/add_semicolon_non_block_closure.stderr +++ b/tests/ui/closures/add_semicolon_non_block_closure.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/add_semicolon_non_block_closure.rs:8:12 | LL | fn main() { - | - expected `()` because of default return type + | - expected `()` because of default return type LL | foo(|| bar()) | ^^^^^ expected `()`, found `i32` | diff --git a/tests/ui/closures/binder/implicit-return.stderr b/tests/ui/closures/binder/implicit-return.stderr index 5bfb97113344..35db34ce21d1 100644 --- a/tests/ui/closures/binder/implicit-return.stderr +++ b/tests/ui/closures/binder/implicit-return.stderr @@ -1,8 +1,8 @@ error: implicit types in closure signatures are forbidden when `for<...>` is present - --> $DIR/implicit-return.rs:4:34 + --> $DIR/implicit-return.rs:4:33 | LL | let _f = for<'a> |_: &'a ()| {}; - | ------- ^ + | ------- ^ | | | `for<...>` is here diff --git a/tests/ui/closures/binder/implicit-stuff.stderr b/tests/ui/closures/binder/implicit-stuff.stderr index 779a08a44e5a..cec2a60ba28c 100644 --- a/tests/ui/closures/binder/implicit-stuff.stderr +++ b/tests/ui/closures/binder/implicit-stuff.stderr @@ -41,10 +41,10 @@ LL | let _ = for<'a> |x: &'a ()| -> &() { x }; | ^ explicit lifetime name needed here error: implicit types in closure signatures are forbidden when `for<...>` is present - --> $DIR/implicit-stuff.rs:5:22 + --> $DIR/implicit-stuff.rs:5:21 | LL | let _ = for<> || {}; - | ----- ^ + | ----- ^ | | | `for<...>` is here diff --git a/tests/ui/codegen/issue-79865-llvm-miscompile.rs b/tests/ui/codegen/issue-79865-llvm-miscompile.rs index b77f09f8e9a7..6f994a5cb741 100644 --- a/tests/ui/codegen/issue-79865-llvm-miscompile.rs +++ b/tests/ui/codegen/issue-79865-llvm-miscompile.rs @@ -4,7 +4,7 @@ // Regression test for issue #79865. // The assertion will fail when compiled with Rust 1.56..=1.59 -// due to a LLVM miscompilation. +// due to an LLVM miscompilation. use std::arch::x86_64::*; diff --git a/tests/ui/codemap_tests/tab.stderr b/tests/ui/codemap_tests/tab.stderr index c3f19d20d395..d2de7486557f 100644 --- a/tests/ui/codemap_tests/tab.stderr +++ b/tests/ui/codemap_tests/tab.stderr @@ -8,7 +8,7 @@ error[E0308]: mismatched types --> $DIR/tab.rs:8:2 | LL | fn foo() { - | - help: try adding a return type: `-> &'static str` + | - help: try adding a return type: `-> &'static str` LL | "bar boo" | ^^^^^^^^^^^^^^^^^^^^ expected `()`, found `&str` diff --git a/tests/ui/compare-method/bad-self-type.stderr b/tests/ui/compare-method/bad-self-type.stderr index f632a53f264e..a87b713c2b4b 100644 --- a/tests/ui/compare-method/bad-self-type.stderr +++ b/tests/ui/compare-method/bad-self-type.stderr @@ -28,10 +28,10 @@ LL | fn foo(self); found signature `fn(Box)` error[E0053]: method `bar` has an incompatible type for trait - --> $DIR/bad-self-type.rs:24:18 + --> $DIR/bad-self-type.rs:24:17 | LL | fn bar(self) {} - | ^ expected `Option<()>`, found `()` + | ^ expected `Option<()>`, found `()` | note: type in trait --> $DIR/bad-self-type.rs:18:21 diff --git a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr index d5b4349c00f6..12557ff63604 100644 --- a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr +++ b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr @@ -74,6 +74,7 @@ LL | #[cfg(feature = $expr)] LL | generate_s10!(concat!("nonexistent")); | ------------------------------------- in this macro invocation | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: this error originates in the macro `generate_s10` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 11 previous errors diff --git a/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.rs b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.rs new file mode 100644 index 000000000000..a83830178d40 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.rs @@ -0,0 +1,44 @@ +// Test that when adt_const_params is not enabled, we suggest adding the feature only when +// it would be possible for the type to be used as a const generic or when it's likely +// possible for the user to fix their type to be used. + +// Can never be used as const generics. +fn uwu_0() {} +//~^ ERROR: forbidden as the type of a const generic + +// Needs the feature but can be used, so suggest adding the feature. +fn owo_0() {} +//~^ ERROR: forbidden as the type of a const generic +//~^^ HELP: add `#![feature(adt_const_params)]` + +// Can only be used in const generics with changes. +struct Meow { + meow: u8, +} + +fn meow_0() {} +//~^ ERROR: forbidden as the type of a const generic +//~^^ HELP: add `#![feature(adt_const_params)]` +fn meow_1() {} +//~^ ERROR: forbidden as the type of a const generic +//~^^ HELP: add `#![feature(adt_const_params)]` +fn meow_2() {} +//~^ ERROR: forbidden as the type of a const generic +//~^^ HELP: add `#![feature(adt_const_params)]` +fn meow_3() {} +//~^ ERROR: forbidden as the type of a const generic +//~^^ HELP: add `#![feature(adt_const_params)]` + +// This is suboptimal that it thinks it can be used +// but better to suggest the feature to the user. +fn meow_4() {} +//~^ ERROR: forbidden as the type of a const generic +//~^^ HELP: add `#![feature(adt_const_params)]` + +// Non-local ADT that does not impl `ConstParamTy` +fn nya_0() {} +//~^ ERROR: forbidden as the type of a const generic +fn nya_1>() {} +//~^ ERROR: forbidden as the type of a const generic + +fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.stderr b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.stderr new file mode 100644 index 000000000000..04527e3158ed --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.stderr @@ -0,0 +1,80 @@ +error: `&'static mut ()` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:6:19 + | +LL | fn uwu_0() {} + | ^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error: `&'static u32` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:10:19 + | +LL | fn owo_0() {} + | ^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + +error: `Meow` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:19:20 + | +LL | fn meow_0() {} + | ^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + +error: `&'static Meow` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:22:20 + | +LL | fn meow_1() {} + | ^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + +error: `[Meow; 100]` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:25:20 + | +LL | fn meow_2() {} + | ^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + +error: `(Meow, u8)` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:28:20 + | +LL | fn meow_3() {} + | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + +error: `(Meow, String)` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:34:20 + | +LL | fn meow_4() {} + | ^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + +error: `String` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:39:19 + | +LL | fn nya_0() {} + | ^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error: `Vec` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:41:19 + | +LL | fn nya_1>() {} + | ^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error: aborting due to 9 previous errors + diff --git a/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr b/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr index d7e5e50cba82..6d5cd45479ec 100644 --- a/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr +++ b/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr @@ -39,6 +39,7 @@ note: associated constant defined here | LL | const MODE: Mode; | ^^^^^^^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/const-param-elided-lifetime.min.stderr b/tests/ui/const-generics/const-param-elided-lifetime.min.stderr index 656bc29466f2..ffe452859885 100644 --- a/tests/ui/const-generics/const-param-elided-lifetime.min.stderr +++ b/tests/ui/const-generics/const-param-elided-lifetime.min.stderr @@ -35,7 +35,7 @@ LL | struct A; | ^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:14:15 @@ -44,7 +44,7 @@ LL | impl A { | ^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:22:15 @@ -53,7 +53,7 @@ LL | impl B for A {} | ^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:26:17 @@ -62,7 +62,7 @@ LL | fn bar() {} | ^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:17:21 @@ -71,7 +71,7 @@ LL | fn foo(&self) {} | ^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 10 previous errors diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr index f829526ca1dc..daeeadeed7cf 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr +++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr @@ -21,7 +21,7 @@ LL | pub struct Dependent([(); N]); | ^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `[u8; N]` is forbidden as the type of a const generic parameter --> $DIR/const-param-type-depends-on-const-param.rs:15:35 @@ -30,7 +30,7 @@ LL | pub struct SelfDependent; | ^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/float-generic.simple.stderr b/tests/ui/const-generics/float-generic.simple.stderr index 89ca36b0f631..aeb19dc75322 100644 --- a/tests/ui/const-generics/float-generic.simple.stderr +++ b/tests/ui/const-generics/float-generic.simple.stderr @@ -5,7 +5,6 @@ LL | fn foo() {} | ^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` error: aborting due to previous error diff --git a/tests/ui/const-generics/fn-const-param-call.min.stderr b/tests/ui/const-generics/fn-const-param-call.min.stderr index d984449e6ca6..2d316fba1e90 100644 --- a/tests/ui/const-generics/fn-const-param-call.min.stderr +++ b/tests/ui/const-generics/fn-const-param-call.min.stderr @@ -3,12 +3,16 @@ error: using function pointers as const generic parameters is forbidden | LL | struct Wrapper u32>; | ^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: using function pointers as const generic parameters is forbidden --> $DIR/fn-const-param-call.rs:13:15 | LL | impl u32> Wrapper { | ^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/fn-const-param-infer.min.stderr b/tests/ui/const-generics/fn-const-param-infer.min.stderr index f0767a10994a..a7afa4842759 100644 --- a/tests/ui/const-generics/fn-const-param-infer.min.stderr +++ b/tests/ui/const-generics/fn-const-param-infer.min.stderr @@ -3,6 +3,8 @@ error: using function pointers as const generic parameters is forbidden | LL | struct Checked bool>; | ^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to previous error diff --git a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr index 956e9c9c988a..64d1e0bcff4e 100644 --- a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr @@ -23,7 +23,7 @@ LL | struct B { | ^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr b/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr index b8a1027c9ebd..4c45339b93b3 100644 --- a/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr +++ b/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr @@ -14,7 +14,7 @@ LL | trait Trait {} | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-56445-1.min.stderr b/tests/ui/const-generics/issues/issue-56445-1.min.stderr index 71a7051f25bf..fc10aba0fecd 100644 --- a/tests/ui/const-generics/issues/issue-56445-1.min.stderr +++ b/tests/ui/const-generics/issues/issue-56445-1.min.stderr @@ -13,7 +13,7 @@ LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); | ^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-62878.min.stderr b/tests/ui/const-generics/issues/issue-62878.min.stderr index 9c0e5179cc4c..eb8b9732f58c 100644 --- a/tests/ui/const-generics/issues/issue-62878.min.stderr +++ b/tests/ui/const-generics/issues/issue-62878.min.stderr @@ -13,7 +13,7 @@ LL | fn foo() {} | ^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr index 9f6c7ccf3fe7..9d80f1cd01bc 100644 --- a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr +++ b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr @@ -5,7 +5,7 @@ LL | fn test() { | ^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-68615-adt.min.stderr b/tests/ui/const-generics/issues/issue-68615-adt.min.stderr index df04c4896b45..c8b9f17196ac 100644 --- a/tests/ui/const-generics/issues/issue-68615-adt.min.stderr +++ b/tests/ui/const-generics/issues/issue-68615-adt.min.stderr @@ -5,7 +5,7 @@ LL | struct Const {} | ^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-68615-array.min.stderr b/tests/ui/const-generics/issues/issue-68615-array.min.stderr index 1b4517087e22..fc6cef9d44e5 100644 --- a/tests/ui/const-generics/issues/issue-68615-array.min.stderr +++ b/tests/ui/const-generics/issues/issue-68615-array.min.stderr @@ -5,7 +5,7 @@ LL | struct Foo {} | ^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-71169.min.stderr b/tests/ui/const-generics/issues/issue-71169.min.stderr index ebfb24bec28d..bba92f32a784 100644 --- a/tests/ui/const-generics/issues/issue-71169.min.stderr +++ b/tests/ui/const-generics/issues/issue-71169.min.stderr @@ -13,7 +13,7 @@ LL | fn foo() {} | ^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-71381.min.stderr b/tests/ui/const-generics/issues/issue-71381.min.stderr index e1e140071fc1..e16d3b7a8a46 100644 --- a/tests/ui/const-generics/issues/issue-71381.min.stderr +++ b/tests/ui/const-generics/issues/issue-71381.min.stderr @@ -19,12 +19,16 @@ error: using function pointers as const generic parameters is forbidden | LL | pub fn call_me(&self) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: using function pointers as const generic parameters is forbidden --> $DIR/issue-71381.rs:23:19 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/issues/issue-71382.min.stderr b/tests/ui/const-generics/issues/issue-71382.min.stderr index 715037bd5f1e..217166d84793 100644 --- a/tests/ui/const-generics/issues/issue-71382.min.stderr +++ b/tests/ui/const-generics/issues/issue-71382.min.stderr @@ -3,6 +3,8 @@ error: using function pointers as const generic parameters is forbidden | LL | fn test(&self) { | ^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-71611.min.stderr b/tests/ui/const-generics/issues/issue-71611.min.stderr index b33d7cf9850f..b01936f4d251 100644 --- a/tests/ui/const-generics/issues/issue-71611.min.stderr +++ b/tests/ui/const-generics/issues/issue-71611.min.stderr @@ -11,6 +11,8 @@ error: using function pointers as const generic parameters is forbidden | LL | fn func(outer: A) { | ^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-72352.min.stderr b/tests/ui/const-generics/issues/issue-72352.min.stderr index eedd73c4dcc0..b010996b8969 100644 --- a/tests/ui/const-generics/issues/issue-72352.min.stderr +++ b/tests/ui/const-generics/issues/issue-72352.min.stderr @@ -3,6 +3,8 @@ error: using function pointers as const generic parameters is forbidden | LL | unsafe fn unsafely_do_the_thing usize>(ptr: *const i8) -> usize { | ^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-73491.min.stderr b/tests/ui/const-generics/issues/issue-73491.min.stderr index f03354fc472c..fdf057bdbe47 100644 --- a/tests/ui/const-generics/issues/issue-73491.min.stderr +++ b/tests/ui/const-generics/issues/issue-73491.min.stderr @@ -5,7 +5,7 @@ LL | fn hoge() {} | ^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr b/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr index 0a7db62472a9..bed0a02a7267 100644 --- a/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr +++ b/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr @@ -5,7 +5,7 @@ LL | fn a() {} | ^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-74101.min.stderr b/tests/ui/const-generics/issues/issue-74101.min.stderr index 134c248347d3..7852ce5bcfce 100644 --- a/tests/ui/const-generics/issues/issue-74101.min.stderr +++ b/tests/ui/const-generics/issues/issue-74101.min.stderr @@ -5,7 +5,7 @@ LL | fn test() {} | ^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `[u8; 1 + 2]` is forbidden as the type of a const generic parameter --> $DIR/issue-74101.rs:9:21 @@ -14,7 +14,7 @@ LL | struct Foo; | ^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-74255.min.stderr b/tests/ui/const-generics/issues/issue-74255.min.stderr index bbcf8682b711..affeca167e97 100644 --- a/tests/ui/const-generics/issues/issue-74255.min.stderr +++ b/tests/ui/const-generics/issues/issue-74255.min.stderr @@ -5,7 +5,7 @@ LL | fn ice_struct_fn() {} | ^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-74950.min.stderr b/tests/ui/const-generics/issues/issue-74950.min.stderr index c37ee93d420f..54ef1ea1e94c 100644 --- a/tests/ui/const-generics/issues/issue-74950.min.stderr +++ b/tests/ui/const-generics/issues/issue-74950.min.stderr @@ -5,7 +5,7 @@ LL | struct Outer; | ^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `Inner` is forbidden as the type of a const generic parameter --> $DIR/issue-74950.rs:20:23 @@ -14,7 +14,8 @@ LL | struct Outer; | ^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `Inner` is forbidden as the type of a const generic parameter --> $DIR/issue-74950.rs:20:23 @@ -23,7 +24,8 @@ LL | struct Outer; | ^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `Inner` is forbidden as the type of a const generic parameter --> $DIR/issue-74950.rs:20:23 @@ -32,7 +34,8 @@ LL | struct Outer; | ^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `Inner` is forbidden as the type of a const generic parameter --> $DIR/issue-74950.rs:20:23 @@ -41,7 +44,8 @@ LL | struct Outer; | ^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 5 previous errors diff --git a/tests/ui/const-generics/issues/issue-75047.min.stderr b/tests/ui/const-generics/issues/issue-75047.min.stderr index 46af19ef3954..e316b4624a00 100644 --- a/tests/ui/const-generics/issues/issue-75047.min.stderr +++ b/tests/ui/const-generics/issues/issue-75047.min.stderr @@ -5,7 +5,7 @@ LL | struct Foo::value()]>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/lifetime-in-const-param.stderr b/tests/ui/const-generics/lifetime-in-const-param.stderr index 8fd9068e8efd..c2fcdcf1a712 100644 --- a/tests/ui/const-generics/lifetime-in-const-param.stderr +++ b/tests/ui/const-generics/lifetime-in-const-param.stderr @@ -11,7 +11,7 @@ LL | struct S<'a, const N: S2>(&'a ()); | ^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/min_const_generics/complex-types.stderr b/tests/ui/const-generics/min_const_generics/complex-types.stderr index 4ddbadb54661..8cc75dbaff9c 100644 --- a/tests/ui/const-generics/min_const_generics/complex-types.stderr +++ b/tests/ui/const-generics/min_const_generics/complex-types.stderr @@ -5,7 +5,7 @@ LL | struct Foo; | ^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `()` is forbidden as the type of a const generic parameter --> $DIR/complex-types.rs:6:21 @@ -14,7 +14,7 @@ LL | struct Bar; | ^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `No` is forbidden as the type of a const generic parameter --> $DIR/complex-types.rs:11:21 @@ -23,7 +23,7 @@ LL | struct Fez; | ^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&'static u8` is forbidden as the type of a const generic parameter --> $DIR/complex-types.rs:14:21 @@ -32,7 +32,7 @@ LL | struct Faz; | ^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `!` is forbidden as the type of a const generic parameter --> $DIR/complex-types.rs:17:21 @@ -41,7 +41,6 @@ LL | struct Fiz; | ^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` error: `()` is forbidden as the type of a const generic parameter --> $DIR/complex-types.rs:20:19 @@ -50,7 +49,7 @@ LL | enum Goo { A, B } | ^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `()` is forbidden as the type of a const generic parameter --> $DIR/complex-types.rs:23:20 @@ -59,7 +58,7 @@ LL | union Boo { a: () } | ^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 7 previous errors diff --git a/tests/ui/const-generics/nested-type.min.stderr b/tests/ui/const-generics/nested-type.min.stderr index 257a9e31e14b..ca5af5f969f5 100644 --- a/tests/ui/const-generics/nested-type.min.stderr +++ b/tests/ui/const-generics/nested-type.min.stderr @@ -30,7 +30,7 @@ LL | | }]>; | |__^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/occurs-check/unused-substs-1.stderr b/tests/ui/const-generics/occurs-check/unused-substs-1.stderr index 51ef354e3ed4..61d055e80847 100644 --- a/tests/ui/const-generics/occurs-check/unused-substs-1.stderr +++ b/tests/ui/const-generics/occurs-check/unused-substs-1.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `A<_>: Bar<_>` is not satisfied LL | let _ = A; | ^ the trait `Bar<_>` is not implemented for `A<_>` | - = help: the trait `Bar` is implemented for `A<7>` + = help: the trait `Bar<_>` is implemented for `A<7>` note: required by a bound in `A` --> $DIR/unused-substs-1.rs:9:11 | diff --git a/tests/ui/const-generics/projection-as-arg-const.stderr b/tests/ui/const-generics/projection-as-arg-const.stderr index 803ed9c95975..9f727231edfb 100644 --- a/tests/ui/const-generics/projection-as-arg-const.stderr +++ b/tests/ui/const-generics/projection-as-arg-const.stderr @@ -5,7 +5,6 @@ LL | pub fn foo::Identity>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` error: aborting due to previous error diff --git a/tests/ui/const-generics/raw-ptr-const-param-deref.min.stderr b/tests/ui/const-generics/raw-ptr-const-param-deref.min.stderr index 04bc46cb4ab1..1eb238255abc 100644 --- a/tests/ui/const-generics/raw-ptr-const-param-deref.min.stderr +++ b/tests/ui/const-generics/raw-ptr-const-param-deref.min.stderr @@ -3,12 +3,16 @@ error: using raw pointers as const generic parameters is forbidden | LL | struct Const; | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: using raw pointers as const generic parameters is forbidden --> $DIR/raw-ptr-const-param-deref.rs:11:15 | LL | impl Const

{ | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/raw-ptr-const-param.min.stderr b/tests/ui/const-generics/raw-ptr-const-param.min.stderr index 310422aafcd3..13fbc34e51a0 100644 --- a/tests/ui/const-generics/raw-ptr-const-param.min.stderr +++ b/tests/ui/const-generics/raw-ptr-const-param.min.stderr @@ -3,6 +3,8 @@ error: using raw pointers as const generic parameters is forbidden | LL | struct Const; | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to previous error diff --git a/tests/ui/const-generics/slice-const-param-mismatch.min.stderr b/tests/ui/const-generics/slice-const-param-mismatch.min.stderr index fed802f6adc6..3c086f59b278 100644 --- a/tests/ui/const-generics/slice-const-param-mismatch.min.stderr +++ b/tests/ui/const-generics/slice-const-param-mismatch.min.stderr @@ -5,7 +5,7 @@ LL | struct ConstString; | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&'static [u8]` is forbidden as the type of a const generic parameter --> $DIR/slice-const-param-mismatch.rs:9:28 @@ -14,7 +14,7 @@ LL | struct ConstBytes; | ^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/std/const-generics-range.min.stderr b/tests/ui/const-generics/std/const-generics-range.min.stderr index 53fca6e884a9..d45f749246c8 100644 --- a/tests/ui/const-generics/std/const-generics-range.min.stderr +++ b/tests/ui/const-generics/std/const-generics-range.min.stderr @@ -5,7 +5,7 @@ LL | struct _Range>; | ^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `RangeFrom` is forbidden as the type of a const generic parameter --> $DIR/const-generics-range.rs:13:28 @@ -14,7 +14,7 @@ LL | struct _RangeFrom>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `RangeFull` is forbidden as the type of a const generic parameter --> $DIR/const-generics-range.rs:18:28 @@ -23,7 +23,7 @@ LL | struct _RangeFull; | ^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `RangeInclusive` is forbidden as the type of a const generic parameter --> $DIR/const-generics-range.rs:24:33 @@ -32,7 +32,7 @@ LL | struct _RangeInclusive>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `RangeTo` is forbidden as the type of a const generic parameter --> $DIR/const-generics-range.rs:29:26 @@ -41,7 +41,7 @@ LL | struct _RangeTo>; | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `RangeToInclusive` is forbidden as the type of a const generic parameter --> $DIR/const-generics-range.rs:34:35 @@ -50,7 +50,7 @@ LL | struct _RangeToInclusive>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 6 previous errors diff --git a/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr b/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr index 039c4276c8b7..f18e149464d3 100644 --- a/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr +++ b/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr @@ -5,7 +5,7 @@ LL | struct Const; | ^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr index b8fbb3979799..6490592c1e1e 100644 --- a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr +++ b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr @@ -5,7 +5,7 @@ LL | trait Get<'a, const N: &'static str> { | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&'static str` is forbidden as the type of a const generic parameter --> $DIR/issue-71348.rs:18:25 @@ -14,7 +14,7 @@ LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Ta | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/type-dependent/issue-71382.stderr b/tests/ui/const-generics/type-dependent/issue-71382.stderr index ad522aead905..3f42feea562a 100644 --- a/tests/ui/const-generics/type-dependent/issue-71382.stderr +++ b/tests/ui/const-generics/type-dependent/issue-71382.stderr @@ -3,6 +3,8 @@ error: using function pointers as const generic parameters is forbidden | LL | fn test u8>(&self) -> u8 { | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to previous error diff --git a/tests/ui/consts/const-adt-align-mismatch.rs b/tests/ui/consts/const-adt-align-mismatch.rs index bd51bc9f215b..89b3a9b744bc 100644 --- a/tests/ui/consts/const-adt-align-mismatch.rs +++ b/tests/ui/consts/const-adt-align-mismatch.rs @@ -12,7 +12,7 @@ enum Foo { } // NOTE(eddyb) Don't make this a const, needs to be a static -// so it is always instantiated as a LLVM constant value. +// so it is always instantiated as an LLVM constant value. static FOO: Foo = Foo::C; fn main() { diff --git a/tests/ui/consts/const-err-late.stderr b/tests/ui/consts/const-err-late.stderr index 85bc56baed84..35c3d000117e 100644 --- a/tests/ui/consts/const-err-late.stderr +++ b/tests/ui/consts/const-err-late.stderr @@ -27,6 +27,8 @@ note: erroneous constant encountered | LL | black_box((S::::FOO, S::::FOO)); | ^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-eval/issue-44578.stderr b/tests/ui/consts/const-eval/issue-44578.stderr index c7aaee942713..eea42c8ce451 100644 --- a/tests/ui/consts/const-eval/issue-44578.stderr +++ b/tests/ui/consts/const-eval/issue-44578.stderr @@ -24,6 +24,7 @@ note: erroneous constant encountered LL | println!("{}", as Foo>::AMT); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/tests/ui/consts/const-eval/nrvo.rs b/tests/ui/consts/const-eval/nrvo.rs index 1d2c6acc06cd..22da96a3fc1e 100644 --- a/tests/ui/consts/const-eval/nrvo.rs +++ b/tests/ui/consts/const-eval/nrvo.rs @@ -1,7 +1,8 @@ // run-pass // When the NRVO is applied, the return place (`_0`) gets treated like a normal local. For example, -// its address may be taken and it may be written to indirectly. Ensure that MIRI can handle this. +// its address may be taken and it may be written to indirectly. Ensure that the const-eval +// interpreter can handle this. #![feature(const_mut_refs)] diff --git a/tests/ui/consts/const-eval/panic-assoc-never-type.stderr b/tests/ui/consts/const-eval/panic-assoc-never-type.stderr index 4706497dbc48..50660664f87f 100644 --- a/tests/ui/consts/const-eval/panic-assoc-never-type.stderr +++ b/tests/ui/consts/const-eval/panic-assoc-never-type.stderr @@ -17,6 +17,8 @@ note: erroneous constant encountered | LL | let _ = PrintName::VOID; | ^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to previous error diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr b/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr index 40fc4a876e9e..8eee392d15cd 100644 --- a/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr +++ b/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr @@ -40,6 +40,7 @@ help: the constant being evaluated | LL | const Y: u32 = simple_loop(35); | ^^^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: constant evaluation is taking a long time --> $DIR/ctfe-simple-loop.rs:9:5 diff --git a/tests/ui/consts/const-eval/union-const-eval-field.rs b/tests/ui/consts/const-eval/union-const-eval-field.rs index a94fcbbfa563..c9799989ea83 100644 --- a/tests/ui/consts/const-eval/union-const-eval-field.rs +++ b/tests/ui/consts/const-eval/union-const-eval-field.rs @@ -1,5 +1,3 @@ -// only-x86_64 - type Field1 = i32; type Field2 = f32; type Field3 = i64; diff --git a/tests/ui/consts/const-eval/union-const-eval-field.stderr b/tests/ui/consts/const-eval/union-const-eval-field.stderr index ce260300fc8c..b299208ae815 100644 --- a/tests/ui/consts/const-eval/union-const-eval-field.stderr +++ b/tests/ui/consts/const-eval/union-const-eval-field.stderr @@ -1,20 +1,22 @@ error[E0080]: evaluation of constant value failed - --> $DIR/union-const-eval-field.rs:28:37 + --> $DIR/union-const-eval-field.rs:26:37 | LL | const FIELD3: Field3 = unsafe { UNION.field3 }; | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory note: erroneous constant encountered - --> $DIR/union-const-eval-field.rs:31:5 + --> $DIR/union-const-eval-field.rs:29:5 | LL | FIELD3 | ^^^^^^ note: erroneous constant encountered - --> $DIR/union-const-eval-field.rs:31:5 + --> $DIR/union-const-eval-field.rs:29:5 | LL | FIELD3 | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to previous error diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.rs b/tests/ui/consts/const_in_pattern/reject_non_structural.rs index dc6b9a33197f..df772740ab12 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.rs +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.rs @@ -1,3 +1,5 @@ +// compile-flags: -Zdeduplicate-diagnostics=yes + // This test of structural match checking enumerates the different kinds of // const definitions, collecting cases where the const pattern is rejected. // @@ -78,9 +80,6 @@ fn main() { //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` //~| NOTE the traits must be derived //~| NOTE StructuralEq.html for details - //~| ERROR must be annotated with `#[derive(PartialEq, Eq)]` - //~| NOTE the traits must be derived - //~| NOTE StructuralEq.html for details trait Trait: Sized { const ASSOC: Option; } impl Trait for NoDerive { const ASSOC: Option = Some(NoDerive); } diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr index b6e439f21397..72bb0aeafa46 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr @@ -1,5 +1,5 @@ error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:40:36 + --> $DIR/reject_non_structural.rs:42:36 | LL | match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), }; | ^^^^ @@ -8,7 +8,7 @@ LL | match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops" = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:46:28 + --> $DIR/reject_non_structural.rs:48:28 | LL | match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), }; | ^^^^^ @@ -17,7 +17,7 @@ LL | match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), }; = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:53:27 + --> $DIR/reject_non_structural.rs:55:27 | LL | match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), }; | ^^^^^^^^ @@ -26,7 +26,7 @@ LL | match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops") = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:59:36 + --> $DIR/reject_non_structural.rs:61:36 | LL | match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), }; | ^^^^^ @@ -35,7 +35,7 @@ LL | match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoop = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:65:28 + --> $DIR/reject_non_structural.rs:67:28 | LL | match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), }; | ^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => p = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:71:36 + --> $DIR/reject_non_structural.rs:73:36 | LL | match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), }; | ^^^^^ @@ -53,7 +53,7 @@ LL | match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoop = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:77:33 + --> $DIR/reject_non_structural.rs:79:33 | LL | match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), }; | ^^^^^^ @@ -62,16 +62,7 @@ LL | match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:77:33 - | -LL | match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), }; - | ^^^^^^ - | - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details - -error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:87:28 + --> $DIR/reject_non_structural.rs:86:28 | LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; | ^^^^^^^^^^^^^^^ @@ -80,7 +71,7 @@ LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => p = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:93:28 + --> $DIR/reject_non_structural.rs:92:28 | LL | match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; | ^^^^^ @@ -89,7 +80,7 @@ LL | match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:99:29 + --> $DIR/reject_non_structural.rs:98:29 | LL | match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; | ^^^^^^^ @@ -99,10 +90,10 @@ LL | match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops") = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details note: the lint level is defined here - --> $DIR/reject_non_structural.rs:12:9 + --> $DIR/reject_non_structural.rs:14:9 | LL | #![warn(indirect_structural_match)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 10 previous errors; 1 warning emitted +error: aborting due to 9 previous errors; 1 warning emitted diff --git a/tests/ui/consts/enum-discr-type-err.stderr b/tests/ui/consts/enum-discr-type-err.stderr index 2f97582bea88..9a09d6a96f1a 100644 --- a/tests/ui/consts/enum-discr-type-err.stderr +++ b/tests/ui/consts/enum-discr-type-err.stderr @@ -24,6 +24,7 @@ LL | | B = T, LL | | } | |_- in this macro invocation | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr index 658a0b7b2a08..3d82837d5304 100644 --- a/tests/ui/consts/fn_trait_refs.stderr +++ b/tests/ui/consts/fn_trait_refs.stderr @@ -21,6 +21,8 @@ error: ~const can only be applied to `#[const_trait]` traits | LL | T: ~const Fn<()> + ~const Destruct, | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: ~const can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:22:15 @@ -33,6 +35,8 @@ error: ~const can only be applied to `#[const_trait]` traits | LL | T: ~const FnMut<()> + ~const Destruct, | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: ~const can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:29:15 @@ -45,6 +49,8 @@ error: ~const can only be applied to `#[const_trait]` traits | LL | T: ~const FnOnce<()>, | ^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: ~const can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:36:15 @@ -57,6 +63,8 @@ error: ~const can only be applied to `#[const_trait]` traits | LL | T: ~const Fn<()> + ~const Destruct, | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: ~const can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:50:15 @@ -69,6 +77,8 @@ error: ~const can only be applied to `#[const_trait]` traits | LL | T: ~const FnMut<()> + ~const Destruct, | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 12 previous errors diff --git a/tests/ui/consts/invalid-union.32bit.stderr b/tests/ui/consts/invalid-union.32bit.stderr index b6cf060e5aea..0c57751cbfa4 100644 --- a/tests/ui/consts/invalid-union.32bit.stderr +++ b/tests/ui/consts/invalid-union.32bit.stderr @@ -20,6 +20,8 @@ note: erroneous constant encountered | LL | let _: &'static _ = &C; | ^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to previous error diff --git a/tests/ui/consts/invalid-union.64bit.stderr b/tests/ui/consts/invalid-union.64bit.stderr index e3a3ef62c4ac..6c4d5882158d 100644 --- a/tests/ui/consts/invalid-union.64bit.stderr +++ b/tests/ui/consts/invalid-union.64bit.stderr @@ -20,6 +20,8 @@ note: erroneous constant encountered | LL | let _: &'static _ = &C; | ^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to previous error diff --git a/tests/ui/consts/issue-102117.stderr b/tests/ui/consts/issue-102117.stderr index f42bcf90fb75..a297916b30f9 100644 --- a/tests/ui/consts/issue-102117.stderr +++ b/tests/ui/consts/issue-102117.stderr @@ -15,6 +15,7 @@ error[E0310]: the parameter type `T` may not live long enough LL | type_id: TypeId::of::(), | ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider adding an explicit lifetime bound... | LL | pub fn new() -> &'static Self { diff --git a/tests/ui/consts/issue-17718-const-bad-values.stderr b/tests/ui/consts/issue-17718-const-bad-values.stderr index ce60aaa0797f..405c2195dec4 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.stderr +++ b/tests/ui/consts/issue-17718-const-bad-values.stderr @@ -19,6 +19,7 @@ LL | const C2: &'static mut usize = unsafe { &mut S }; | ^ | = help: consider extracting the value of the `static` to a `const`, and referring to that + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 3 previous errors diff --git a/tests/ui/consts/miri_unleashed/assoc_const.stderr b/tests/ui/consts/miri_unleashed/assoc_const.stderr index 274b1de7e7da..b129aef3452e 100644 --- a/tests/ui/consts/miri_unleashed/assoc_const.stderr +++ b/tests/ui/consts/miri_unleashed/assoc_const.stderr @@ -24,6 +24,8 @@ note: erroneous constant encountered | LL | let y = , String>>::F; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: skipping const checks | diff --git a/tests/ui/consts/miri_unleashed/assoc_const_2.stderr b/tests/ui/consts/miri_unleashed/assoc_const_2.stderr index c8e4cab4e71b..46408f6748d9 100644 --- a/tests/ui/consts/miri_unleashed/assoc_const_2.stderr +++ b/tests/ui/consts/miri_unleashed/assoc_const_2.stderr @@ -15,6 +15,8 @@ note: erroneous constant encountered | LL | let y = >::F; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to previous error diff --git a/tests/ui/consts/uninhabited-const-issue-61744.stderr b/tests/ui/consts/uninhabited-const-issue-61744.stderr index f48e6c4ce51c..c92824a0d1a1 100644 --- a/tests/ui/consts/uninhabited-const-issue-61744.stderr +++ b/tests/ui/consts/uninhabited-const-issue-61744.stderr @@ -656,6 +656,8 @@ note: erroneous constant encountered | LL | dbg!(i32::CONSTANT); | ^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to previous error diff --git a/tests/ui/crate-loading/invalid-rlib.rs b/tests/ui/crate-loading/invalid-rlib.rs index aea861e3261b..0997bee19bb6 100644 --- a/tests/ui/crate-loading/invalid-rlib.rs +++ b/tests/ui/crate-loading/invalid-rlib.rs @@ -8,3 +8,4 @@ use ::foo; //~ ERROR invalid metadata files for crate `foo` //~| NOTE failed to mmap file //~^^ ERROR invalid metadata files for crate `foo` //~| NOTE failed to mmap file +//~| NOTE duplicate diagnostic diff --git a/tests/ui/crate-loading/invalid-rlib.stderr b/tests/ui/crate-loading/invalid-rlib.stderr index 3c0d23bf7b4c..63bb1b95cbb7 100644 --- a/tests/ui/crate-loading/invalid-rlib.stderr +++ b/tests/ui/crate-loading/invalid-rlib.stderr @@ -13,6 +13,7 @@ LL | use ::foo; | ^^^ | = note: failed to mmap file 'auxiliary/libfoo.rlib' + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/debuginfo/sroa-fragment-debuginfo.rs b/tests/ui/debuginfo/sroa-fragment-debuginfo.rs index 9c3c359e395d..fc3bbb88efe8 100644 --- a/tests/ui/debuginfo/sroa-fragment-debuginfo.rs +++ b/tests/ui/debuginfo/sroa-fragment-debuginfo.rs @@ -1,4 +1,4 @@ -// Verify that we do not trigger a LLVM assertion by creating zero-sized DWARF fragments. +// Verify that we do not trigger an LLVM assertion by creating zero-sized DWARF fragments. // // build-pass // compile-flags: -g -Zmir-opt-level=0 -Zmir-enable-passes=+ScalarReplacementOfAggregates diff --git a/tests/ui/deduplicate-diagnostics.duplicate.stderr b/tests/ui/deduplicate-diagnostics.duplicate.stderr index cd4700c7a7c9..0544b993278d 100644 --- a/tests/ui/deduplicate-diagnostics.duplicate.stderr +++ b/tests/ui/deduplicate-diagnostics.duplicate.stderr @@ -15,12 +15,16 @@ error: cannot find derive macro `Unresolved` in this scope | LL | #[derive(Unresolved)] | ^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0452]: malformed lint attribute input --> $DIR/deduplicate-diagnostics.rs:8:8 | LL | #[deny("literal")] | ^^^^^^^^^ bad attribute argument + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors diff --git a/tests/ui/deprecation/deprecation-sanity.stderr b/tests/ui/deprecation/deprecation-sanity.stderr index 8b2b480d1958..383212ad9b4b 100644 --- a/tests/ui/deprecation/deprecation-sanity.stderr +++ b/tests/ui/deprecation/deprecation-sanity.stderr @@ -16,25 +16,25 @@ error[E0541]: unknown meta item 'reason' LL | #[deprecated(since = "a", note = "a", reason)] | ^^^^^^ expected one of `since`, `note` -error[E0551]: incorrect meta item +error[E0539]: incorrect meta item --> $DIR/deprecation-sanity.rs:7:31 | LL | #[deprecated(since = "a", note)] | ^^^^ -error[E0551]: incorrect meta item +error[E0539]: incorrect meta item --> $DIR/deprecation-sanity.rs:10:18 | LL | #[deprecated(since, note = "a")] | ^^^^^ -error[E0551]: incorrect meta item +error[E0539]: incorrect meta item --> $DIR/deprecation-sanity.rs:13:31 | LL | #[deprecated(since = "a", note(b))] | ^^^^^^^ -error[E0551]: incorrect meta item +error[E0539]: incorrect meta item --> $DIR/deprecation-sanity.rs:16:18 | LL | #[deprecated(since(b), note = "a")] @@ -70,5 +70,5 @@ LL | #[deprecated = "hello"] error: aborting due to 10 previous errors -Some errors have detailed explanations: E0538, E0541, E0551, E0565. +Some errors have detailed explanations: E0538, E0539, E0541, E0565. For more information about an error, try `rustc --explain E0538`. diff --git a/tests/ui/derives/deriving-bounds.stderr b/tests/ui/derives/deriving-bounds.stderr index 74ca37287d23..4461652eb02e 100644 --- a/tests/ui/derives/deriving-bounds.stderr +++ b/tests/ui/derives/deriving-bounds.stderr @@ -21,6 +21,7 @@ note: unsafe traits like `Sync` should be implemented explicitly | LL | #[derive(Sync)] | ^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: cannot find derive macro `Send` in this scope --> $DIR/deriving-bounds.rs:1:10 @@ -45,6 +46,7 @@ note: unsafe traits like `Send` should be implemented explicitly | LL | #[derive(Send)] | ^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors diff --git a/tests/ui/derives/deriving-meta-unknown-trait.stderr b/tests/ui/derives/deriving-meta-unknown-trait.stderr index 053d34f68251..28753b8f9f28 100644 --- a/tests/ui/derives/deriving-meta-unknown-trait.stderr +++ b/tests/ui/derives/deriving-meta-unknown-trait.stderr @@ -15,6 +15,8 @@ LL | #[derive(Eqr)] --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named derive macro `Eq` defined here + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/derives/deriving-primitive.stderr b/tests/ui/derives/deriving-primitive.stderr index ca64c9ee732c..b39637825e56 100644 --- a/tests/ui/derives/deriving-primitive.stderr +++ b/tests/ui/derives/deriving-primitive.stderr @@ -9,6 +9,8 @@ error: cannot find derive macro `FromPrimitive` in this scope | LL | #[derive(FromPrimitive)] | ^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr index bb1b29ef248f..bd39c91ffe88 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr +++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr @@ -35,6 +35,8 @@ warning: malformed `on_unimplemented` attribute | LL | #[diagnostic::on_unimplemented(unsupported = "foo")] | ^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the trait bound `i32: Foo` is not satisfied --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:31:14 @@ -60,6 +62,8 @@ warning: malformed `on_unimplemented` attribute | LL | #[diagnostic::on_unimplemented(message = "Boom", unsupported = "Bar")] | ^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: Boom --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:33:14 @@ -85,6 +89,8 @@ warning: malformed `on_unimplemented` attribute | LL | #[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message = "whatever"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: Boom --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:35:15 diff --git a/tests/ui/did_you_mean/auxiliary/doc-hidden-fields.rs b/tests/ui/did_you_mean/auxiliary/doc-hidden-fields.rs new file mode 100644 index 000000000000..4e2ee97403c5 --- /dev/null +++ b/tests/ui/did_you_mean/auxiliary/doc-hidden-fields.rs @@ -0,0 +1,6 @@ +#[derive(Default)] +pub struct B { + #[doc(hidden)] + pub hello: i32, + pub bye: i32, +} diff --git a/tests/ui/did_you_mean/dont-suggest-doc-hidden-fields.rs b/tests/ui/did_you_mean/dont-suggest-doc-hidden-fields.rs new file mode 100644 index 000000000000..6040f3f30a7b --- /dev/null +++ b/tests/ui/did_you_mean/dont-suggest-doc-hidden-fields.rs @@ -0,0 +1,38 @@ +// Regression test for issue #93210. + +// aux-crate:doc_hidden_fields=doc-hidden-fields.rs +// edition: 2021 + +#[derive(Default)] +pub struct A { + #[doc(hidden)] + pub hello: i32, + pub bye: i32, +} + +#[derive(Default)] +pub struct C { + pub hello: i32, + pub bye: i32, +} + +fn main() { + // We want to list the field `hello` despite being marked + // `doc(hidden)` because it's defined in this crate. + A::default().hey; + //~^ ERROR no field `hey` on type `A` + //~| NOTE unknown field + //~| NOTE available fields are: `hello`, `bye` + + // Here we want to hide the field `hello` since it's marked + // `doc(hidden)` and comes from an external crate. + doc_hidden_fields::B::default().hey; + //~^ ERROR no field `hey` on type `B` + //~| NOTE unknown field + //~| NOTE available fields are: `bye` + + C::default().hey; + //~^ ERROR no field `hey` on type `C` + //~| NOTE unknown field + //~| NOTE available fields are: `hello`, `bye` +} diff --git a/tests/ui/did_you_mean/dont-suggest-doc-hidden-fields.stderr b/tests/ui/did_you_mean/dont-suggest-doc-hidden-fields.stderr new file mode 100644 index 000000000000..b7fe3b79b475 --- /dev/null +++ b/tests/ui/did_you_mean/dont-suggest-doc-hidden-fields.stderr @@ -0,0 +1,27 @@ +error[E0609]: no field `hey` on type `A` + --> $DIR/dont-suggest-doc-hidden-fields.rs:22:18 + | +LL | A::default().hey; + | ^^^ unknown field + | + = note: available fields are: `hello`, `bye` + +error[E0609]: no field `hey` on type `B` + --> $DIR/dont-suggest-doc-hidden-fields.rs:29:37 + | +LL | doc_hidden_fields::B::default().hey; + | ^^^ unknown field + | + = note: available fields are: `bye` + +error[E0609]: no field `hey` on type `C` + --> $DIR/dont-suggest-doc-hidden-fields.rs:34:18 + | +LL | C::default().hey; + | ^^^ unknown field + | + = note: available fields are: `hello`, `bye` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0609`. diff --git a/tests/ui/did_you_mean/dont-suggest-hygienic-fields.rs b/tests/ui/did_you_mean/dont-suggest-hygienic-fields.rs new file mode 100644 index 000000000000..fb7040b2df09 --- /dev/null +++ b/tests/ui/did_you_mean/dont-suggest-hygienic-fields.rs @@ -0,0 +1,47 @@ +// Regression test for issue #116334. +// Don't include hygienic fields from different syntax contexts in +// the list of available or similarly named fields. + +#![feature(decl_macro)] + +macro compound($Ty:ident) { + #[derive(Default)] + struct $Ty { + field: u32, // field `field` is hygienic + } +} + +macro component($Ty:ident) { + struct $Ty(u64); // field `0` is hygienic (but still accessible via the constructor) +} + +compound! { Compound } +component! { Component } + +fn main() { + let ty = Compound::default(); + + let _ = ty.field; //~ ERROR no field `field` on type `Compound` + let _ = ty.fieeld; //~ ERROR no field `fieeld` on type `Compound` + + let Compound { field } = ty; + //~^ ERROR struct `Compound` does not have a field named `field` + //~| ERROR pattern requires `..` due to inaccessible fields + //~| HELP ignore the inaccessible and unused fields + + let ty = Component(90); + + let _ = ty.0; //~ ERROR no field `0` on type `Component` +} + +environment!(); + +macro environment() { + struct Crate { field: () } + + // Here, we do want to suggest `field` even though it's hygienic + // precisely because they come from the same syntax context. + const CRATE: Crate = Crate { fiel: () }; + //~^ ERROR struct `Crate` has no field named `fiel` + //~| HELP a field with a similar name exists +} diff --git a/tests/ui/did_you_mean/dont-suggest-hygienic-fields.stderr b/tests/ui/did_you_mean/dont-suggest-hygienic-fields.stderr new file mode 100644 index 000000000000..7066d29760e7 --- /dev/null +++ b/tests/ui/did_you_mean/dont-suggest-hygienic-fields.stderr @@ -0,0 +1,50 @@ +error[E0560]: struct `Crate` has no field named `fiel` + --> $DIR/dont-suggest-hygienic-fields.rs:44:34 + | +LL | environment!(); + | -------------- in this macro invocation +... +LL | const CRATE: Crate = Crate { fiel: () }; + | ^^^^ help: a field with a similar name exists: `field` + | + = note: this error originates in the macro `environment` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0609]: no field `field` on type `Compound` + --> $DIR/dont-suggest-hygienic-fields.rs:24:16 + | +LL | let _ = ty.field; + | ^^^^^ unknown field + +error[E0609]: no field `fieeld` on type `Compound` + --> $DIR/dont-suggest-hygienic-fields.rs:25:16 + | +LL | let _ = ty.fieeld; + | ^^^^^^ unknown field + +error[E0026]: struct `Compound` does not have a field named `field` + --> $DIR/dont-suggest-hygienic-fields.rs:27:20 + | +LL | let Compound { field } = ty; + | ^^^^^ struct `Compound` does not have this field + +error: pattern requires `..` due to inaccessible fields + --> $DIR/dont-suggest-hygienic-fields.rs:27:9 + | +LL | let Compound { field } = ty; + | ^^^^^^^^^^^^^^^^^^ + | +help: ignore the inaccessible and unused fields + | +LL | let Compound { field, .. } = ty; + | ++++ + +error[E0609]: no field `0` on type `Component` + --> $DIR/dont-suggest-hygienic-fields.rs:34:16 + | +LL | let _ = ty.0; + | ^ unknown field + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0026, E0560, E0609. +For more information about an error, try `rustc --explain E0026`. diff --git a/tests/ui/did_you_mean/issue-93210-ignore-doc-hidden.rs b/tests/ui/did_you_mean/issue-93210-ignore-doc-hidden.rs deleted file mode 100644 index 8be03e087880..000000000000 --- a/tests/ui/did_you_mean/issue-93210-ignore-doc-hidden.rs +++ /dev/null @@ -1,30 +0,0 @@ -#[derive(Default)] -pub struct A { - #[doc(hidden)] - pub hello: i32, - pub bye: i32, -} - -#[derive(Default)] -pub struct B { - pub hello: i32, - pub bye: i32, -} - -fn main() { - A::default().hey; - //~^ ERROR no field `hey` on type `A` - //~| NOTE unknown field - //~| NOTE available fields are: `bye` - - B::default().hey; - //~^ ERROR no field `hey` on type `B` - //~| NOTE unknown field - //~| NOTE available fields are: `hello`, `bye` -} - -// ferrocene-annotations: fls_18k3uajrgq5f -// Field Access Expressions -// -// ferrocene-annotations: fls_xcwfotmq2e5d -// Field Resolution diff --git a/tests/ui/did_you_mean/issue-93210-ignore-doc-hidden.stderr b/tests/ui/did_you_mean/issue-93210-ignore-doc-hidden.stderr deleted file mode 100644 index 784986d3b95f..000000000000 --- a/tests/ui/did_you_mean/issue-93210-ignore-doc-hidden.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0609]: no field `hey` on type `A` - --> $DIR/issue-93210-ignore-doc-hidden.rs:15:18 - | -LL | A::default().hey; - | ^^^ unknown field - | - = note: available fields are: `bye` - -error[E0609]: no field `hey` on type `B` - --> $DIR/issue-93210-ignore-doc-hidden.rs:20:18 - | -LL | B::default().hey; - | ^^^ unknown field - | - = note: available fields are: `hello`, `bye` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0609`. diff --git a/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr b/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr index 6bafff9192a3..931786672145 100644 --- a/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr +++ b/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr @@ -50,6 +50,7 @@ LL | fn function(x: &SomeTrait, y: Box) { | = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | fn function(x: &dyn SomeTrait, y: Box) { @@ -63,6 +64,7 @@ LL | fn function(x: &SomeTrait, y: Box) { | = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | fn function(x: &dyn SomeTrait, y: Box) { @@ -76,6 +78,7 @@ LL | fn function(x: &SomeTrait, y: Box) { | = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | fn function(x: &SomeTrait, y: Box) { @@ -89,6 +92,7 @@ LL | fn function(x: &SomeTrait, y: Box) { | = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | fn function(x: &SomeTrait, y: Box) { diff --git a/tests/ui/error-codes/E0452.stderr b/tests/ui/error-codes/E0452.stderr index f67b740ffe23..986c135ed89c 100644 --- a/tests/ui/error-codes/E0452.stderr +++ b/tests/ui/error-codes/E0452.stderr @@ -9,18 +9,24 @@ error[E0452]: malformed lint attribute input | LL | #![allow(foo = "")] | ^^^^^^^^ bad attribute argument + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0452]: malformed lint attribute input --> $DIR/E0452.rs:1:10 | LL | #![allow(foo = "")] | ^^^^^^^^ bad attribute argument + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0452]: malformed lint attribute input --> $DIR/E0452.rs:1:10 | LL | #![allow(foo = "")] | ^^^^^^^^ bad attribute argument + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors diff --git a/tests/ui/error-codes/E0453.stderr b/tests/ui/error-codes/E0453.stderr index f982ed26f5c0..bb2c39298c08 100644 --- a/tests/ui/error-codes/E0453.stderr +++ b/tests/ui/error-codes/E0453.stderr @@ -15,6 +15,8 @@ LL | #![forbid(non_snake_case)] LL | LL | #[allow(non_snake_case)] | ^^^^^^^^^^^^^^ overruled by previous forbid + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/error-codes/E0602.stderr b/tests/ui/error-codes/E0602.stderr index 60ecec7cdd7c..b6b5cd5c3d3e 100644 --- a/tests/ui/error-codes/E0602.stderr +++ b/tests/ui/error-codes/E0602.stderr @@ -6,10 +6,12 @@ warning[E0602]: unknown lint: `bogus` warning[E0602]: unknown lint: `bogus` | = note: requested on the command line with `-D bogus` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning[E0602]: unknown lint: `bogus` | = note: requested on the command line with `-D bogus` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/error-codes/E0719.stderr b/tests/ui/error-codes/E0719.stderr index e302f406d02b..685bd7175e3f 100644 --- a/tests/ui/error-codes/E0719.stderr +++ b/tests/ui/error-codes/E0719.stderr @@ -13,6 +13,8 @@ LL | trait Foo: Iterator {} | ---------- ^^^^^^^^^^ re-bound here | | | `Item` bound here first + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified --> $DIR/E0719.rs:7:42 diff --git a/tests/ui/error-codes/E0789.stderr b/tests/ui/error-codes/E0789.stderr index faab92bae035..6df9daafec76 100644 --- a/tests/ui/error-codes/E0789.stderr +++ b/tests/ui/error-codes/E0789.stderr @@ -9,6 +9,8 @@ error[E0789]: `rustc_allowed_through_unstable_modules` attribute must be paired | LL | struct Foo; | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/feature-gates/feature-gate-adt_const_params.stderr b/tests/ui/feature-gates/feature-gate-adt_const_params.stderr index d8f089a28b7e..13b9b84f0be4 100644 --- a/tests/ui/feature-gates/feature-gate-adt_const_params.stderr +++ b/tests/ui/feature-gates/feature-gate-adt_const_params.stderr @@ -5,7 +5,7 @@ LL | struct Foo; | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs b/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs index 49fb10e60295..152c7a8de66a 100644 --- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs +++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs @@ -54,20 +54,20 @@ fn _rpit_dyn() -> Box> { Box::new(S1) } const _cdef: impl Tr1 = S1; //~^ ERROR associated type bounds are unstable -//~| ERROR `impl Trait` only allowed in function and inherent method return types +//~| ERROR `impl Trait` only allowed in function and inherent method argument and return types // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. // const _cdef_dyn: &dyn Tr1 = &S1; static _sdef: impl Tr1 = S1; //~^ ERROR associated type bounds are unstable -//~| ERROR `impl Trait` only allowed in function and inherent method return types +//~| ERROR `impl Trait` only allowed in function and inherent method argument and return types // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. // static _sdef_dyn: &dyn Tr1 = &S1; fn main() { let _: impl Tr1 = S1; //~^ ERROR associated type bounds are unstable - //~| ERROR `impl Trait` only allowed in function and inherent method return types + //~| ERROR `impl Trait` only allowed in function and inherent method argument and return types // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. // let _: &dyn Tr1 = &S1; } diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr index 4233a8af9b6a..f2bceda9bea7 100644 --- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr +++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr @@ -115,19 +115,19 @@ LL | let _: impl Tr1 = S1; = note: see issue #52662 for more information = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in const types --> $DIR/feature-gate-associated_type_bounds.rs:55:14 | LL | const _cdef: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in const types --> $DIR/feature-gate-associated_type_bounds.rs:61:15 | LL | static _sdef: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings --> $DIR/feature-gate-associated_type_bounds.rs:68:12 | LL | let _: impl Tr1 = S1; diff --git a/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.rs b/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.rs index 0db8088f7eea..1b9530fa82f3 100644 --- a/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.rs +++ b/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.rs @@ -1,6 +1,6 @@ fn f() -> impl Fn() -> impl Sized { || () } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait return fn g() -> &'static dyn Fn() -> impl Sized { &|| () } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait return fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr b/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr index c8c3e13d7fc5..f0c0cd040e03 100644 --- a/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr +++ b/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait return types --> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:1:24 | LL | fn f() -> impl Fn() -> impl Sized { || () } @@ -7,7 +7,7 @@ LL | fn f() -> impl Fn() -> impl Sized { || () } = note: see issue #99697 for more information = help: add `#![feature(impl_trait_in_fn_trait_return)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait return types --> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:3:32 | LL | fn g() -> &'static dyn Fn() -> impl Sized { &|| () } diff --git a/tests/ui/feature-gates/feature-gate-lint-reasons.stderr b/tests/ui/feature-gates/feature-gate-lint-reasons.stderr index 12793c7a28fc..6d49b7ed2cd0 100644 --- a/tests/ui/feature-gates/feature-gate-lint-reasons.stderr +++ b/tests/ui/feature-gates/feature-gate-lint-reasons.stderr @@ -15,6 +15,7 @@ LL | #![warn(nonstandard_style, reason = "the standard should be respected")] | = note: see issue #54503 for more information = help: add `#![feature(lint_reasons)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/feature-gates/feature-gate-multiple_supertrait_upcastable.stderr b/tests/ui/feature-gates/feature-gate-multiple_supertrait_upcastable.stderr index 1f725f354177..5e14bf6397fe 100644 --- a/tests/ui/feature-gates/feature-gate-multiple_supertrait_upcastable.stderr +++ b/tests/ui/feature-gates/feature-gate-multiple_supertrait_upcastable.stderr @@ -25,6 +25,7 @@ LL | #![deny(multiple_supertrait_upcastable)] | = note: the `multiple_supertrait_upcastable` lint is unstable = help: add `#![feature(multiple_supertrait_upcastable)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `multiple_supertrait_upcastable` --> $DIR/feature-gate-multiple_supertrait_upcastable.rs:7:1 @@ -34,6 +35,7 @@ LL | #![warn(multiple_supertrait_upcastable)] | = note: the `multiple_supertrait_upcastable` lint is unstable = help: add `#![feature(multiple_supertrait_upcastable)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `multiple_supertrait_upcastable` --> $DIR/feature-gate-multiple_supertrait_upcastable.rs:3:1 @@ -43,6 +45,7 @@ LL | #![deny(multiple_supertrait_upcastable)] | = note: the `multiple_supertrait_upcastable` lint is unstable = help: add `#![feature(multiple_supertrait_upcastable)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `multiple_supertrait_upcastable` --> $DIR/feature-gate-multiple_supertrait_upcastable.rs:7:1 @@ -52,6 +55,7 @@ LL | #![warn(multiple_supertrait_upcastable)] | = note: the `multiple_supertrait_upcastable` lint is unstable = help: add `#![feature(multiple_supertrait_upcastable)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 6 warnings emitted diff --git a/tests/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr b/tests/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr index fb39c404c207..1c14622d6378 100644 --- a/tests/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr +++ b/tests/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr @@ -38,6 +38,7 @@ LL | #[allow(non_exhaustive_omitted_patterns)] = note: the `non_exhaustive_omitted_patterns` lint is unstable = note: see issue #89554 for more information = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `non_exhaustive_omitted_patterns` --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:29:9 @@ -58,6 +59,7 @@ LL | #![deny(non_exhaustive_omitted_patterns)] = note: the `non_exhaustive_omitted_patterns` lint is unstable = note: see issue #89554 for more information = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `non_exhaustive_omitted_patterns` --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:6:1 @@ -68,6 +70,7 @@ LL | #![allow(non_exhaustive_omitted_patterns)] = note: the `non_exhaustive_omitted_patterns` lint is unstable = note: see issue #89554 for more information = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `non_exhaustive_omitted_patterns` --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:15:5 @@ -78,6 +81,7 @@ LL | #[allow(non_exhaustive_omitted_patterns)] = note: the `non_exhaustive_omitted_patterns` lint is unstable = note: see issue #89554 for more information = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `non_exhaustive_omitted_patterns` --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:15:5 @@ -88,6 +92,7 @@ LL | #[allow(non_exhaustive_omitted_patterns)] = note: the `non_exhaustive_omitted_patterns` lint is unstable = note: see issue #89554 for more information = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `non_exhaustive_omitted_patterns` --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:29:9 @@ -98,6 +103,7 @@ LL | #[warn(non_exhaustive_omitted_patterns)] = note: the `non_exhaustive_omitted_patterns` lint is unstable = note: see issue #89554 for more information = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0004]: non-exhaustive patterns: `Foo::C` not covered --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:20:11 diff --git a/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs b/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs index 637765fff11e..a8d6365ca79a 100644 --- a/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs +++ b/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs @@ -5,14 +5,14 @@ #![feature(async_fn_in_trait)] trait Foo { - fn bar() -> impl Sized; //~ ERROR `impl Trait` only allowed in function and inherent method return types, not in trait method return - fn baz() -> Box; //~ ERROR `impl Trait` only allowed in function and inherent method return types, not in trait method return + fn bar() -> impl Sized; //~ ERROR `impl Trait` only allowed in function and inherent method argument and return types, not in trait method return + fn baz() -> Box; //~ ERROR `impl Trait` only allowed in function and inherent method argument and return types, not in trait method return } // Both return_position_impl_trait_in_trait and async_fn_in_trait are required for this (see also // feature-gate-async_fn_in_trait.rs) trait AsyncFoo { - async fn bar() -> impl Sized; //~ ERROR `impl Trait` only allowed in function and inherent method return types, not in trait method return + async fn bar() -> impl Sized; //~ ERROR `impl Trait` only allowed in function and inherent method argument and return types, not in trait method return } fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr b/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr index 0082b6fafee8..86f138fabdb9 100644 --- a/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr +++ b/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in trait method return types --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:8:17 | LL | fn bar() -> impl Sized; @@ -7,7 +7,7 @@ LL | fn bar() -> impl Sized; = note: see issue #91611 for more information = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in trait method return types --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:9:21 | LL | fn baz() -> Box; @@ -16,7 +16,7 @@ LL | fn baz() -> Box; = note: see issue #91611 for more information = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in trait method return types --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:15:23 | LL | async fn bar() -> impl Sized; diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr index 1bdb2574eadc..f6230b764635 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr @@ -1,5 +1,5 @@ error[E0658]: return type notation is experimental - --> $DIR/feature-gate-return_type_notation.rs:14:17 + --> $DIR/feature-gate-return_type_notation.rs:15:17 | LL | fn foo>() {} | ^^^^^^^^^ @@ -8,7 +8,7 @@ LL | fn foo>() {} = help: add `#![feature(return_type_notation)]` to the crate attributes to enable error: parenthesized generic arguments cannot be used in associated type constraints - --> $DIR/feature-gate-return_type_notation.rs:14:17 + --> $DIR/feature-gate-return_type_notation.rs:15:17 | LL | fn foo>() {} | ^-- @@ -16,7 +16,7 @@ LL | fn foo>() {} | help: remove these parentheses error[E0220]: associated type `m` not found for `Trait` - --> $DIR/feature-gate-return_type_notation.rs:14:17 + --> $DIR/feature-gate-return_type_notation.rs:15:17 | LL | fn foo>() {} | ^ associated type `m` not found diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr index dd6ebb610386..c7f52d7cddc2 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr @@ -1,5 +1,5 @@ warning: return type notation is experimental - --> $DIR/feature-gate-return_type_notation.rs:14:17 + --> $DIR/feature-gate-return_type_notation.rs:15:17 | LL | fn foo>() {} | ^^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.rs b/tests/ui/feature-gates/feature-gate-return_type_notation.rs index ae12495b5dc6..c0c285cef3cb 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.rs +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.rs @@ -7,6 +7,7 @@ #![feature(async_fn_in_trait)] trait Trait { + #[allow(async_fn_in_trait)] async fn m(); } diff --git a/tests/ui/feature-gates/feature-gate-strict_provenance.stderr b/tests/ui/feature-gates/feature-gate-strict_provenance.stderr index 751da87cc0d0..1e6d762a5406 100644 --- a/tests/ui/feature-gates/feature-gate-strict_provenance.stderr +++ b/tests/ui/feature-gates/feature-gate-strict_provenance.stderr @@ -28,6 +28,7 @@ LL | #![deny(fuzzy_provenance_casts)] = note: the `fuzzy_provenance_casts` lint is unstable = note: see issue #95228 for more information = help: add `#![feature(strict_provenance)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `lossy_provenance_casts` --> $DIR/feature-gate-strict_provenance.rs:7:1 @@ -38,6 +39,7 @@ LL | #![deny(lossy_provenance_casts)] = note: the `lossy_provenance_casts` lint is unstable = note: see issue #95228 for more information = help: add `#![feature(strict_provenance)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `fuzzy_provenance_casts` --> $DIR/feature-gate-strict_provenance.rs:3:1 @@ -48,6 +50,7 @@ LL | #![deny(fuzzy_provenance_casts)] = note: the `fuzzy_provenance_casts` lint is unstable = note: see issue #95228 for more information = help: add `#![feature(strict_provenance)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `lossy_provenance_casts` --> $DIR/feature-gate-strict_provenance.rs:7:1 @@ -58,6 +61,7 @@ LL | #![deny(lossy_provenance_casts)] = note: the `lossy_provenance_casts` lint is unstable = note: see issue #95228 for more information = help: add `#![feature(strict_provenance)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 6 warnings emitted diff --git a/tests/ui/feature-gates/feature-gate-test_unstable_lint.stderr b/tests/ui/feature-gates/feature-gate-test_unstable_lint.stderr index b4d6aa658e1b..562aa478a93e 100644 --- a/tests/ui/feature-gates/feature-gate-test_unstable_lint.stderr +++ b/tests/ui/feature-gates/feature-gate-test_unstable_lint.stderr @@ -16,6 +16,7 @@ LL | #![allow(test_unstable_lint)] | = note: the `test_unstable_lint` lint is unstable = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `test_unstable_lint` --> $DIR/feature-gate-test_unstable_lint.rs:4:1 @@ -25,6 +26,7 @@ LL | #![allow(test_unstable_lint)] | = note: the `test_unstable_lint` lint is unstable = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr b/tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr index 4349fea6f896..2614f2b3c35d 100644 --- a/tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr +++ b/tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr @@ -18,6 +18,7 @@ LL | #![warn(unnameable_types)] = note: the `unnameable_types` lint is unstable = note: see issue #48054 for more information = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `unnameable_types` --> $DIR/feature-gate-type_privacy_lints.rs:3:1 @@ -28,6 +29,7 @@ LL | #![warn(unnameable_types)] = note: the `unnameable_types` lint is unstable = note: see issue #48054 for more information = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr b/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr index ab1659173447..1e47259cb7ed 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr @@ -9,6 +9,8 @@ error: cannot find derive macro `x3300` in this scope | LL | #[derive(x3300)] | ^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: cannot find derive macro `x3300` in this scope --> $DIR/issue-43106-gating-of-derive-2.rs:9:14 @@ -21,6 +23,8 @@ error: cannot find derive macro `x3300` in this scope | LL | #[derive(x3300)] | ^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: cannot find derive macro `x3300` in this scope --> $DIR/issue-43106-gating-of-derive-2.rs:4:14 @@ -33,6 +37,8 @@ error: cannot find derive macro `x3300` in this scope | LL | #[derive(x3300)] | ^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 6 previous errors diff --git a/tests/ui/ferrocene/compiler-arguments/upper_a/upper-a_eq-empty-option.stderr b/tests/ui/ferrocene/compiler-arguments/upper_a/upper-a_eq-empty-option.stderr index 244e46d098d7..2b92f972d788 100644 --- a/tests/ui/ferrocene/compiler-arguments/upper_a/upper-a_eq-empty-option.stderr +++ b/tests/ui/ferrocene/compiler-arguments/upper_a/upper-a_eq-empty-option.stderr @@ -6,10 +6,12 @@ warning[E0602]: unknown lint: `=` warning[E0602]: unknown lint: `=` | = note: requested on the command line with `-A =` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning[E0602]: unknown lint: `=` | = note: requested on the command line with `-A =` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/ferrocene/compiler-arguments/upper_a/upper-a_eq-valid-option.stderr b/tests/ui/ferrocene/compiler-arguments/upper_a/upper-a_eq-valid-option.stderr index b47ab7770a7e..ec6455f00e0c 100644 --- a/tests/ui/ferrocene/compiler-arguments/upper_a/upper-a_eq-valid-option.stderr +++ b/tests/ui/ferrocene/compiler-arguments/upper_a/upper-a_eq-valid-option.stderr @@ -8,11 +8,13 @@ warning[E0602]: unknown lint: `=overflowing_literals` | = help: did you mean: `overflowing_literals` = note: requested on the command line with `-A =overflowing_literals` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning[E0602]: unknown lint: `=overflowing_literals` | = help: did you mean: `overflowing_literals` = note: requested on the command line with `-A =overflowing_literals` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: literal out of range for `u8` --> $DIR/upper-a_eq-valid-option.rs:8:17 diff --git a/tests/ui/ferrocene/compiler-arguments/upper_a/upper-a_space-invalid-option.stderr b/tests/ui/ferrocene/compiler-arguments/upper_a/upper-a_space-invalid-option.stderr index c32f240daa3a..0f6c240b6566 100644 --- a/tests/ui/ferrocene/compiler-arguments/upper_a/upper-a_space-invalid-option.stderr +++ b/tests/ui/ferrocene/compiler-arguments/upper_a/upper-a_space-invalid-option.stderr @@ -6,10 +6,12 @@ warning[E0602]: unknown lint: `invalid_lint_code` warning[E0602]: unknown lint: `invalid_lint_code` | = note: requested on the command line with `-A invalid_lint_code` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning[E0602]: unknown lint: `invalid_lint_code` | = note: requested on the command line with `-A invalid_lint_code` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/ferrocene/compiler-arguments/upper_d/upper-d_bad-lint.stderr b/tests/ui/ferrocene/compiler-arguments/upper_d/upper-d_bad-lint.stderr index 87ea002a99cd..55020acd0133 100644 --- a/tests/ui/ferrocene/compiler-arguments/upper_d/upper-d_bad-lint.stderr +++ b/tests/ui/ferrocene/compiler-arguments/upper_d/upper-d_bad-lint.stderr @@ -6,10 +6,12 @@ warning[E0602]: unknown lint: `junk` warning[E0602]: unknown lint: `junk` | = note: requested on the command line with `-D junk` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning[E0602]: unknown lint: `junk` | = note: requested on the command line with `-D junk` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/ferrocene/compiler-arguments/upper_f/upper-f_eq-empty-option.stderr b/tests/ui/ferrocene/compiler-arguments/upper_f/upper-f_eq-empty-option.stderr index 578e7c6e6bc6..bfdf9c3ca184 100644 --- a/tests/ui/ferrocene/compiler-arguments/upper_f/upper-f_eq-empty-option.stderr +++ b/tests/ui/ferrocene/compiler-arguments/upper_f/upper-f_eq-empty-option.stderr @@ -6,10 +6,12 @@ warning[E0602]: unknown lint: `=` warning[E0602]: unknown lint: `=` | = note: requested on the command line with `-F =` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning[E0602]: unknown lint: `=` | = note: requested on the command line with `-F =` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/ferrocene/compiler-arguments/upper_f/upper-f_eq-valid-option.stderr b/tests/ui/ferrocene/compiler-arguments/upper_f/upper-f_eq-valid-option.stderr index d0510330f26a..754f110958ee 100644 --- a/tests/ui/ferrocene/compiler-arguments/upper_f/upper-f_eq-valid-option.stderr +++ b/tests/ui/ferrocene/compiler-arguments/upper_f/upper-f_eq-valid-option.stderr @@ -8,11 +8,13 @@ warning[E0602]: unknown lint: `=missing_docs` | = help: did you mean: `missing_docs` = note: requested on the command line with `-F =missing_docs` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning[E0602]: unknown lint: `=missing_docs` | = help: did you mean: `missing_docs` = note: requested on the command line with `-F =missing_docs` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/ferrocene/compiler-arguments/upper_f/upper-f_space-invalid-option.stderr b/tests/ui/ferrocene/compiler-arguments/upper_f/upper-f_space-invalid-option.stderr index 1e23114824e2..175c32be7fc1 100644 --- a/tests/ui/ferrocene/compiler-arguments/upper_f/upper-f_space-invalid-option.stderr +++ b/tests/ui/ferrocene/compiler-arguments/upper_f/upper-f_space-invalid-option.stderr @@ -6,10 +6,12 @@ warning[E0602]: unknown lint: `invalid_lint_code` warning[E0602]: unknown lint: `invalid_lint_code` | = note: requested on the command line with `-F invalid_lint_code` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning[E0602]: unknown lint: `invalid_lint_code` | = note: requested on the command line with `-F invalid_lint_code` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/ferrocene/compiler-arguments/upper_w/upper-w_bad-lint.stderr b/tests/ui/ferrocene/compiler-arguments/upper_w/upper-w_bad-lint.stderr index 10b0e263ae81..4d04c10e13e4 100644 --- a/tests/ui/ferrocene/compiler-arguments/upper_w/upper-w_bad-lint.stderr +++ b/tests/ui/ferrocene/compiler-arguments/upper_w/upper-w_bad-lint.stderr @@ -6,10 +6,12 @@ warning[E0602]: unknown lint: `junk` warning[E0602]: unknown lint: `junk` | = note: requested on the command line with `-W junk` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning[E0602]: unknown lint: `junk` | = note: requested on the command line with `-W junk` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr index 499221637ba7..7f535ec432c1 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr +++ b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr @@ -25,6 +25,7 @@ note: associated type defined here, with 1 lifetime parameter: `'a` | LL | type Y<'a>; | ^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | fn foo<'a, T1: X = T1>>(t : T1) -> T1::Y<'a> { diff --git a/tests/ui/generic-associated-types/issue-91139.stderr b/tests/ui/generic-associated-types/issue-91139.stderr index d9d76adfbb55..89a4ba77e4e7 100644 --- a/tests/ui/generic-associated-types/issue-91139.stderr +++ b/tests/ui/generic-associated-types/issue-91139.stderr @@ -9,6 +9,8 @@ error: `T` does not live long enough | LL | let _: for<'a> fn(<() as Foo>::Type<'a>, &'a T) = |_, _| (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/generic-const-items/elided-lifetimes.stderr b/tests/ui/generic-const-items/elided-lifetimes.stderr index 8cd3f9ee7a91..e7df8ca5cfd9 100644 --- a/tests/ui/generic-const-items/elided-lifetimes.stderr +++ b/tests/ui/generic-const-items/elided-lifetimes.stderr @@ -28,7 +28,7 @@ LL | const I: &str = ""; | ^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 4 previous errors diff --git a/tests/ui/generic-const-items/unsatisfied-bounds.stderr b/tests/ui/generic-const-items/unsatisfied-bounds.stderr index 2cee53431a42..14894cef7708 100644 --- a/tests/ui/generic-const-items/unsatisfied-bounds.stderr +++ b/tests/ui/generic-const-items/unsatisfied-bounds.stderr @@ -17,6 +17,7 @@ LL | let () = K::<()>; | ^^ the trait `From<()>` is not implemented for `Infallible` | = help: the trait `From` is implemented for `Infallible` + = help: for that trait implementation, expected `!`, found `()` note: required by a bound in `K` --> $DIR/unsatisfied-bounds.rs:12:17 | @@ -48,6 +49,7 @@ LL | let _ = <() as Trait<&'static str>>::B::<()>; | ^^ the trait `From<()>` is not implemented for `Infallible` | = help: the trait `From` is implemented for `Infallible` + = help: for that trait implementation, expected `!`, found `()` note: required by a bound in `Trait::B` --> $DIR/unsatisfied-bounds.rs:21:21 | diff --git a/tests/ui/higher-ranked/subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr index a73c03feb876..48703186cc63 100644 --- a/tests/ui/higher-ranked/subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr +++ b/tests/ui/higher-ranked/subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr @@ -24,6 +24,7 @@ LL | | for<'a> fn(Inv<'a>, Inv<'a>)) } | = note: expected enum `Option fn(Inv<'a>, Inv<'b>)>` found enum `Option fn(Inv<'a>, Inv<'a>)>` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.stderr index 46f5308dd87b..69c58c5919e1 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.stderr +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.stderr @@ -15,6 +15,7 @@ LL | fn b() { want_foo2::(); } | = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`... = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr index fad0b812d43d..d3c2d5d5b9f8 100644 --- a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr +++ b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr @@ -20,6 +20,7 @@ LL | fn ice() -> impl AsRef { | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | fn ice() -> impl AsRef { @@ -33,6 +34,7 @@ LL | fn ice() -> impl AsRef { | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | fn ice() -> impl AsRef { diff --git a/tests/ui/impl-trait/impl-subtyper.rs b/tests/ui/impl-trait/impl-subtyper.rs new file mode 100644 index 000000000000..2d99cdd4f506 --- /dev/null +++ b/tests/ui/impl-trait/impl-subtyper.rs @@ -0,0 +1,18 @@ +// check-pass + +#![crate_type = "lib"] +fn checkpoints() -> impl Iterator { + Some(()).iter().flat_map(|_| std::iter::once(())) +} + +fn block_checkpoints() -> impl Iterator { + checkpoints() +} + +fn iter_raw() -> impl Iterator { + let mut iter = block_checkpoints(); + + (0..9).map(move |_| { + iter.next(); + }) +} diff --git a/tests/ui/impl-trait/impl-subtyper2.rs b/tests/ui/impl-trait/impl-subtyper2.rs new file mode 100644 index 000000000000..2e0acbae68b8 --- /dev/null +++ b/tests/ui/impl-trait/impl-subtyper2.rs @@ -0,0 +1,7 @@ +// check-pass + +fn ages() -> Option { + None::> +} + +fn main(){} diff --git a/tests/ui/impl-trait/in-trait/assumed-wf-bounds-in-impl.rs b/tests/ui/impl-trait/in-trait/assumed-wf-bounds-in-impl.rs index 2a61c5cc8dff..5de9c01e3e01 100644 --- a/tests/ui/impl-trait/in-trait/assumed-wf-bounds-in-impl.rs +++ b/tests/ui/impl-trait/in-trait/assumed-wf-bounds-in-impl.rs @@ -9,6 +9,7 @@ trait AsyncLendingIterator { where Self: 'a; + #[allow(async_fn_in_trait)] async fn next(&mut self) -> Option>; } diff --git a/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs b/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs index 25133214dc62..9c60cf4e72ad 100644 --- a/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs +++ b/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs @@ -7,6 +7,7 @@ use std::fmt::Debug; trait Foo { + #[allow(async_fn_in_trait)] async fn baz(&self) -> impl Debug { "" } diff --git a/tests/ui/impl-trait/in-trait/default-body.rs b/tests/ui/impl-trait/in-trait/default-body.rs index b0baf5bb10dd..d3ea9fbeabc3 100644 --- a/tests/ui/impl-trait/in-trait/default-body.rs +++ b/tests/ui/impl-trait/in-trait/default-body.rs @@ -7,6 +7,7 @@ use std::fmt::Debug; trait Foo { + #[allow(async_fn_in_trait)] async fn baz(&self) -> &str { "" } diff --git a/tests/ui/impl-trait/in-trait/early.rs b/tests/ui/impl-trait/in-trait/early.rs index 9c1c2b503390..bb5718b49344 100644 --- a/tests/ui/impl-trait/in-trait/early.rs +++ b/tests/ui/impl-trait/in-trait/early.rs @@ -5,6 +5,7 @@ #![allow(incomplete_features)] pub trait Foo { + #[allow(async_fn_in_trait)] async fn bar<'a: 'a>(&'a mut self); } diff --git a/tests/ui/impl-trait/in-trait/refine.rs b/tests/ui/impl-trait/in-trait/refine.rs index a91f9b3e7225..f00478b0bb99 100644 --- a/tests/ui/impl-trait/in-trait/refine.rs +++ b/tests/ui/impl-trait/in-trait/refine.rs @@ -45,4 +45,15 @@ impl Late for D { //~^ ERROR impl method signature does not match trait method signature } +mod unreachable { + pub trait UnreachablePub { + fn bar() -> impl Sized; + } + + struct E; + impl UnreachablePub for E { + fn bar() {} + } +} + fn main() {} diff --git a/tests/ui/impl-trait/in-trait/refine.stderr b/tests/ui/impl-trait/in-trait/refine.stderr index 29aa08e25bb9..1d9852c682cd 100644 --- a/tests/ui/impl-trait/in-trait/refine.stderr +++ b/tests/ui/impl-trait/in-trait/refine.stderr @@ -30,8 +30,8 @@ LL | fn bar() {} = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate help: replace the return type so that it matches the trait | -LL | fn bar() -> impl Sized {} - | +++++++++++++ +LL | fn bar()-> impl Sized {} + | +++++++++++++ error: impl trait in impl method signature does not match trait method signature --> $DIR/refine.rs:22:17 diff --git a/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed b/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed index d9f775a6c846..58d83384a238 100644 --- a/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed +++ b/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed @@ -4,12 +4,15 @@ #![feature(async_fn_in_trait, return_position_impl_trait_in_trait)] trait Trait { + #[allow(async_fn_in_trait)] async fn foo(); + #[allow(async_fn_in_trait)] async fn bar() -> i32; fn test(&self) -> impl Sized + '_; + #[allow(async_fn_in_trait)] async fn baz(&self) -> &i32; } diff --git a/tests/ui/impl-trait/in-trait/suggest-missing-item.rs b/tests/ui/impl-trait/in-trait/suggest-missing-item.rs index 26979b5149b0..c27229806e13 100644 --- a/tests/ui/impl-trait/in-trait/suggest-missing-item.rs +++ b/tests/ui/impl-trait/in-trait/suggest-missing-item.rs @@ -4,12 +4,15 @@ #![feature(async_fn_in_trait, return_position_impl_trait_in_trait)] trait Trait { + #[allow(async_fn_in_trait)] async fn foo(); + #[allow(async_fn_in_trait)] async fn bar() -> i32; fn test(&self) -> impl Sized + '_; + #[allow(async_fn_in_trait)] async fn baz(&self) -> &i32; } diff --git a/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr b/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr index 44f98896eb38..29f6bad86dc8 100644 --- a/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr +++ b/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr @@ -1,15 +1,15 @@ error[E0046]: not all trait items implemented, missing: `foo`, `bar`, `test`, `baz` - --> $DIR/suggest-missing-item.rs:18:1 + --> $DIR/suggest-missing-item.rs:21:1 | LL | async fn foo(); | --------------- `foo` from trait -LL | +... LL | async fn bar() -> i32; | ---------------------- `bar` from trait LL | LL | fn test(&self) -> impl Sized + '_; | ---------------------------------- `test` from trait -LL | +... LL | async fn baz(&self) -> &i32; | ---------------------------- `baz` from trait ... diff --git a/tests/ui/impl-trait/issue-55872-2.stderr b/tests/ui/impl-trait/issue-55872-2.stderr index 3e70f1cf8006..b5b7f293a40b 100644 --- a/tests/ui/impl-trait/issue-55872-2.stderr +++ b/tests/ui/impl-trait/issue-55872-2.stderr @@ -9,6 +9,8 @@ error: type parameter `T` is part of concrete type but not used in parameter lis | LL | async {} | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/issues/issue-54600.rs b/tests/ui/impl-trait/issues/issue-54600.rs index 3024fedf7b5f..ccf2767012e6 100644 --- a/tests/ui/impl-trait/issues/issue-54600.rs +++ b/tests/ui/impl-trait/issues/issue-54600.rs @@ -2,6 +2,6 @@ use std::fmt::Debug; fn main() { let x: Option = Some(44_u32); - //~^ `impl Trait` only allowed in function and inherent method return types + //~^ `impl Trait` only allowed in function and inherent method argument and return types println!("{:?}", x); } diff --git a/tests/ui/impl-trait/issues/issue-54600.stderr b/tests/ui/impl-trait/issues/issue-54600.stderr index 7ef063af9522..9a8e3675b956 100644 --- a/tests/ui/impl-trait/issues/issue-54600.stderr +++ b/tests/ui/impl-trait/issues/issue-54600.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings --> $DIR/issue-54600.rs:4:19 | LL | let x: Option = Some(44_u32); diff --git a/tests/ui/impl-trait/issues/issue-54840.rs b/tests/ui/impl-trait/issues/issue-54840.rs index 8f1e0ece03a6..910d23f1d938 100644 --- a/tests/ui/impl-trait/issues/issue-54840.rs +++ b/tests/ui/impl-trait/issues/issue-54840.rs @@ -3,5 +3,5 @@ use std::ops::Add; fn main() { let i: i32 = 0; let j: &impl Add = &i; - //~^ `impl Trait` only allowed in function and inherent method return types + //~^ `impl Trait` only allowed in function and inherent method argument and return types } diff --git a/tests/ui/impl-trait/issues/issue-54840.stderr b/tests/ui/impl-trait/issues/issue-54840.stderr index 1d1316f0e110..67cabf449506 100644 --- a/tests/ui/impl-trait/issues/issue-54840.stderr +++ b/tests/ui/impl-trait/issues/issue-54840.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings --> $DIR/issue-54840.rs:5:13 | LL | let j: &impl Add = &i; diff --git a/tests/ui/impl-trait/issues/issue-58504.rs b/tests/ui/impl-trait/issues/issue-58504.rs index e5865d0dfff3..f1d7b94ef2db 100644 --- a/tests/ui/impl-trait/issues/issue-58504.rs +++ b/tests/ui/impl-trait/issues/issue-58504.rs @@ -8,5 +8,5 @@ fn mk_gen() -> impl Generator { fn main() { let gens: [impl Generator;2] = [ mk_gen(), mk_gen() ]; - //~^ `impl Trait` only allowed in function and inherent method return types + //~^ `impl Trait` only allowed in function and inherent method argument and return types } diff --git a/tests/ui/impl-trait/issues/issue-58504.stderr b/tests/ui/impl-trait/issues/issue-58504.stderr index 26ec2a4f9cfe..1be676ee075d 100644 --- a/tests/ui/impl-trait/issues/issue-58504.stderr +++ b/tests/ui/impl-trait/issues/issue-58504.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings --> $DIR/issue-58504.rs:10:16 | LL | let gens: [impl Generator;2] = [ mk_gen(), mk_gen() ]; diff --git a/tests/ui/impl-trait/issues/issue-58956.rs b/tests/ui/impl-trait/issues/issue-58956.rs index 68cfcd9ba4f9..5d5566860c0f 100644 --- a/tests/ui/impl-trait/issues/issue-58956.rs +++ b/tests/ui/impl-trait/issues/issue-58956.rs @@ -5,9 +5,9 @@ impl Lam for B {} pub struct Wrap(T); const _A: impl Lam = { - //~^ `impl Trait` only allowed in function and inherent method return types + //~^ `impl Trait` only allowed in function and inherent method argument and return types let x: Wrap = Wrap(B); - //~^ `impl Trait` only allowed in function and inherent method return types + //~^ `impl Trait` only allowed in function and inherent method argument and return types x.0 }; diff --git a/tests/ui/impl-trait/issues/issue-58956.stderr b/tests/ui/impl-trait/issues/issue-58956.stderr index 2b4d0abdffca..5ee33352afa2 100644 --- a/tests/ui/impl-trait/issues/issue-58956.stderr +++ b/tests/ui/impl-trait/issues/issue-58956.stderr @@ -1,10 +1,10 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in const types --> $DIR/issue-58956.rs:7:11 | LL | const _A: impl Lam = { | ^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings --> $DIR/issue-58956.rs:9:17 | LL | let x: Wrap = Wrap(B); diff --git a/tests/ui/impl-trait/issues/issue-62742.stderr b/tests/ui/impl-trait/issues/issue-62742.stderr index d872291c8705..8d969e8e0f3d 100644 --- a/tests/ui/impl-trait/issues/issue-62742.stderr +++ b/tests/ui/impl-trait/issues/issue-62742.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied LL | WrongImpl::foo(0i32); | ^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>` | - = help: the trait `Raw<[T]>` is implemented for `RawImpl` + = help: the trait `Raw<[_]>` is implemented for `RawImpl<_>` note: required by a bound in `SafeImpl` --> $DIR/issue-62742.rs:26:35 | @@ -42,7 +42,8 @@ error[E0277]: the trait bound `RawImpl<()>: Raw<()>` is not satisfied LL | WrongImpl::<()>::foo(0i32); | ^^^^^^^^^^^^^^^ the trait `Raw<()>` is not implemented for `RawImpl<()>` | - = help: the trait `Raw<[T]>` is implemented for `RawImpl` + = help: the trait `Raw<[()]>` is implemented for `RawImpl<()>` + = help: for that trait implementation, expected `[()]`, found `()` note: required by a bound in `SafeImpl` --> $DIR/issue-62742.rs:26:35 | diff --git a/tests/ui/impl-trait/issues/issue-70971.rs b/tests/ui/impl-trait/issues/issue-70971.rs index f8ae18bacd67..c24259a71eb2 100644 --- a/tests/ui/impl-trait/issues/issue-70971.rs +++ b/tests/ui/impl-trait/issues/issue-70971.rs @@ -1,4 +1,4 @@ fn main() { let x : (impl Copy,) = (true,); - //~^ `impl Trait` only allowed in function and inherent method return types + //~^ `impl Trait` only allowed in function and inherent method argument and return types } diff --git a/tests/ui/impl-trait/issues/issue-70971.stderr b/tests/ui/impl-trait/issues/issue-70971.stderr index d066256bfb09..5609f8b9b012 100644 --- a/tests/ui/impl-trait/issues/issue-70971.stderr +++ b/tests/ui/impl-trait/issues/issue-70971.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings --> $DIR/issue-70971.rs:2:14 | LL | let x : (impl Copy,) = (true,); diff --git a/tests/ui/impl-trait/issues/issue-79099.rs b/tests/ui/impl-trait/issues/issue-79099.rs index 58c5e365c14e..6db2e30de2eb 100644 --- a/tests/ui/impl-trait/issues/issue-79099.rs +++ b/tests/ui/impl-trait/issues/issue-79099.rs @@ -1,7 +1,7 @@ struct Bug { V1: [(); { let f: impl core::future::Future = async { 1 }; - //~^ `impl Trait` only allowed in function and inherent method return types + //~^ `impl Trait` only allowed in function and inherent method argument and return types //~| expected identifier 1 }], diff --git a/tests/ui/impl-trait/issues/issue-79099.stderr b/tests/ui/impl-trait/issues/issue-79099.stderr index 580250a62fec..82fc03c61b3b 100644 --- a/tests/ui/impl-trait/issues/issue-79099.stderr +++ b/tests/ui/impl-trait/issues/issue-79099.stderr @@ -9,7 +9,7 @@ LL | let f: impl core::future::Future = async { 1 }; = help: pass `--edition 2021` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings --> $DIR/issue-79099.rs:3:16 | LL | let f: impl core::future::Future = async { 1 }; diff --git a/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.rs b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.rs index 344f359529b6..3224145bffeb 100644 --- a/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.rs +++ b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.rs @@ -1,8 +1,8 @@ struct Foo(T); -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types type Result = std::result::Result; -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // should not cause ICE fn x() -> Foo { diff --git a/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr index 656bd0470612..56be4577d51a 100644 --- a/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr +++ b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr @@ -1,10 +1,10 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generic parameter defaults --> $DIR/issue-83929-impl-trait-in-generic-default.rs:1:16 | LL | struct Foo(T); | ^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generic parameter defaults --> $DIR/issue-83929-impl-trait-in-generic-default.rs:4:20 | LL | type Result = std::result::Result; diff --git a/tests/ui/impl-trait/issues/issue-84919.rs b/tests/ui/impl-trait/issues/issue-84919.rs index a0b73743a2b2..77d27d7c06b6 100644 --- a/tests/ui/impl-trait/issues/issue-84919.rs +++ b/tests/ui/impl-trait/issues/issue-84919.rs @@ -3,7 +3,7 @@ impl Trait for () {} fn foo<'a: 'a>() { let _x: impl Trait = (); - //~^ `impl Trait` only allowed in function and inherent method return types + //~^ `impl Trait` only allowed in function and inherent method argument and return types } fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-84919.stderr b/tests/ui/impl-trait/issues/issue-84919.stderr index 36010fdef36c..20b131b8bd20 100644 --- a/tests/ui/impl-trait/issues/issue-84919.stderr +++ b/tests/ui/impl-trait/issues/issue-84919.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings --> $DIR/issue-84919.rs:5:13 | LL | let _x: impl Trait = (); diff --git a/tests/ui/impl-trait/issues/issue-86642.rs b/tests/ui/impl-trait/issues/issue-86642.rs index e6e95771400d..49f8944ac4af 100644 --- a/tests/ui/impl-trait/issues/issue-86642.rs +++ b/tests/ui/impl-trait/issues/issue-86642.rs @@ -1,5 +1,5 @@ static x: impl Fn(&str) -> Result<&str, ()> = move |source| { - //~^ `impl Trait` only allowed in function and inherent method return types + //~^ `impl Trait` only allowed in function and inherent method argument and return types let res = (move |source| Ok(source))(source); let res = res.or((move |source| Ok(source))(source)); res diff --git a/tests/ui/impl-trait/issues/issue-86642.stderr b/tests/ui/impl-trait/issues/issue-86642.stderr index b6f8a54f35ae..6d3be3fff0e1 100644 --- a/tests/ui/impl-trait/issues/issue-86642.stderr +++ b/tests/ui/impl-trait/issues/issue-86642.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in const types --> $DIR/issue-86642.rs:1:11 | LL | static x: impl Fn(&str) -> Result<&str, ()> = move |source| { diff --git a/tests/ui/impl-trait/issues/issue-87295.rs b/tests/ui/impl-trait/issues/issue-87295.rs index aeb8f83326e4..eb44020ac0e7 100644 --- a/tests/ui/impl-trait/issues/issue-87295.rs +++ b/tests/ui/impl-trait/issues/issue-87295.rs @@ -14,5 +14,5 @@ impl Struct { fn main() { let _do_not_waste: Struct> = Struct::new(()); - //~^ `impl Trait` only allowed in function and inherent method return types + //~^ `impl Trait` only allowed in function and inherent method argument and return types } diff --git a/tests/ui/impl-trait/issues/issue-87295.stderr b/tests/ui/impl-trait/issues/issue-87295.stderr index ec59b719c10e..3fe4ee73c80c 100644 --- a/tests/ui/impl-trait/issues/issue-87295.stderr +++ b/tests/ui/impl-trait/issues/issue-87295.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings --> $DIR/issue-87295.rs:16:31 | LL | let _do_not_waste: Struct> = Struct::new(()); diff --git a/tests/ui/impl-trait/nested_impl_trait.rs b/tests/ui/impl-trait/nested_impl_trait.rs index e95fab3b6505..c036b9e367a1 100644 --- a/tests/ui/impl-trait/nested_impl_trait.rs +++ b/tests/ui/impl-trait/nested_impl_trait.rs @@ -9,7 +9,7 @@ fn bad_in_ret_position(x: impl Into) -> impl Into { x } fn bad_in_fn_syntax(x: fn() -> impl Into) {} //~^ ERROR nested `impl Trait` is not allowed -//~| `impl Trait` only allowed in function and inherent method return types +//~| `impl Trait` only allowed in function and inherent method argument and return types fn bad_in_arg_position(_: impl Into) { } //~^ ERROR nested `impl Trait` is not allowed diff --git a/tests/ui/impl-trait/nested_impl_trait.stderr b/tests/ui/impl-trait/nested_impl_trait.stderr index ffe84b8e86fc..f1cafd958b05 100644 --- a/tests/ui/impl-trait/nested_impl_trait.stderr +++ b/tests/ui/impl-trait/nested_impl_trait.stderr @@ -34,7 +34,7 @@ LL | fn bad(x: impl Into) -> impl Into { x } | | nested `impl Trait` here | outer `impl Trait` -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `fn` pointer return types --> $DIR/nested_impl_trait.rs:10:32 | LL | fn bad_in_fn_syntax(x: fn() -> impl Into) {} diff --git a/tests/ui/impl-trait/where-allowed.rs b/tests/ui/impl-trait/where-allowed.rs index 509d2716649e..d3fab326e748 100644 --- a/tests/ui/impl-trait/where-allowed.rs +++ b/tests/ui/impl-trait/where-allowed.rs @@ -16,47 +16,47 @@ fn in_adt_in_parameters(_: Vec) { panic!() } // Disallowed fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Disallowed fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Disallowed fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Disallowed fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Disallowed fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Disallowed fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Disallowed fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Allowed fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() } // Disallowed fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types //~^^ ERROR nested `impl Trait` is not allowed // Disallowed fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Disallowed fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types //~| ERROR nested `impl Trait` is not allowed // Allowed @@ -64,11 +64,11 @@ fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() // Disallowed fn in_Fn_parameter_in_generics (_: F) { panic!() } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Disallowed fn in_Fn_return_in_generics impl Debug> (_: F) { panic!() } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Allowed @@ -81,22 +81,22 @@ fn in_impl_Trait_in_return() -> impl IntoIterator { // Disallowed struct InBraceStructField { x: impl Debug } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Disallowed struct InAdtInBraceStructField { x: Vec } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Disallowed struct InTupleStructField(impl Debug); -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Disallowed enum InEnum { InBraceVariant { x: impl Debug }, - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types InTupleVariant(impl Debug), - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types } // Allowed @@ -107,7 +107,7 @@ trait InTraitDefnParameters { // Disallowed trait InTraitDefnReturn { fn in_return() -> impl Debug; - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types } // Allowed and disallowed in trait impls @@ -124,7 +124,7 @@ impl DummyTrait for () { // Allowed fn in_trait_impl_return() -> impl Debug { () } - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types } // Allowed @@ -137,10 +137,10 @@ impl DummyType { // Disallowed extern "C" { fn in_foreign_parameters(_: impl Debug); - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types fn in_foreign_return() -> impl Debug; - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types } // Allowed @@ -156,97 +156,97 @@ type InTypeAlias = impl Debug; //~^ ERROR `impl Trait` in type aliases is unstable type InReturnInTypeAlias = fn() -> impl Debug; -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types //~| ERROR `impl Trait` in type aliases is unstable // Disallowed in impl headers impl PartialEq for () { - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types } // Disallowed in impl headers impl PartialEq<()> for impl Debug { - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types } // Disallowed in inherent impls impl impl Debug { - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types } // Disallowed in inherent impls struct InInherentImplAdt { t: T } impl InInherentImplAdt { - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types } // Disallowed in where clauses fn in_fn_where_clause() where impl Debug: Debug -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types { } // Disallowed in where clauses fn in_adt_in_fn_where_clause() where Vec: Debug -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types { } // Disallowed fn in_trait_parameter_in_fn_where_clause() where T: PartialEq -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types { } // Disallowed fn in_Fn_parameter_in_fn_where_clause() where T: Fn(impl Debug) -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types { } // Disallowed fn in_Fn_return_in_fn_where_clause() where T: Fn() -> impl Debug -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types { } // Disallowed struct InStructGenericParamDefault(T); -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Disallowed enum InEnumGenericParamDefault { Variant(T) } -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Disallowed trait InTraitGenericParamDefault {} -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Disallowed type InTypeAliasGenericParamDefault = T; -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types // Disallowed impl T {} //~^ ERROR defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions //~| WARNING this was previously accepted by the compiler but is being phased out -//~| ERROR `impl Trait` only allowed in function and inherent method return types +//~| ERROR `impl Trait` only allowed in function and inherent method argument and return types //~| ERROR no nominal type found // Disallowed fn in_method_generic_param_default(_: T) {} //~^ ERROR defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions //~| WARNING this was previously accepted by the compiler but is being phased out -//~| ERROR `impl Trait` only allowed in function and inherent method return types +//~| ERROR `impl Trait` only allowed in function and inherent method argument and return types fn main() { let _in_local_variable: impl Fn() = || {}; - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types let _in_return_in_local_variable = || -> impl Fn() { || {} }; - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types } diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index 3e2934379755..bd7c9a947932 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -43,109 +43,109 @@ LL | type InReturnInTypeAlias = fn() -> impl Debug; = note: see issue #63063 for more information = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer params +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `fn` pointer params --> $DIR/where-allowed.rs:18:40 | LL | fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `fn` pointer return types --> $DIR/where-allowed.rs:22:42 | LL | fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer params +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `fn` pointer params --> $DIR/where-allowed.rs:26:38 | LL | fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `fn` pointer return types --> $DIR/where-allowed.rs:30:40 | LL | fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait params --> $DIR/where-allowed.rs:34:49 | LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait return types --> $DIR/where-allowed.rs:38:51 | LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait params --> $DIR/where-allowed.rs:42:55 | LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait params --> $DIR/where-allowed.rs:49:51 | LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait return types --> $DIR/where-allowed.rs:54:53 | LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait params --> $DIR/where-allowed.rs:58:57 | LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait params --> $DIR/where-allowed.rs:66:38 | LL | fn in_Fn_parameter_in_generics (_: F) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait return types --> $DIR/where-allowed.rs:70:40 | LL | fn in_Fn_return_in_generics impl Debug> (_: F) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in field types --> $DIR/where-allowed.rs:83:32 | LL | struct InBraceStructField { x: impl Debug } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in field types --> $DIR/where-allowed.rs:87:41 | LL | struct InAdtInBraceStructField { x: Vec } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in field types --> $DIR/where-allowed.rs:91:27 | LL | struct InTupleStructField(impl Debug); | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in field types --> $DIR/where-allowed.rs:96:25 | LL | InBraceVariant { x: impl Debug }, | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in field types --> $DIR/where-allowed.rs:98:20 | LL | InTupleVariant(impl Debug), | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in trait method return types --> $DIR/where-allowed.rs:109:23 | LL | fn in_return() -> impl Debug; @@ -154,7 +154,7 @@ LL | fn in_return() -> impl Debug; = note: see issue #91611 for more information = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `impl` method return types --> $DIR/where-allowed.rs:126:34 | LL | fn in_trait_impl_return() -> impl Debug { () } @@ -163,121 +163,121 @@ LL | fn in_trait_impl_return() -> impl Debug { () } = note: see issue #91611 for more information = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` params +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `extern fn` params --> $DIR/where-allowed.rs:139:33 | LL | fn in_foreign_parameters(_: impl Debug); | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `extern fn` return types --> $DIR/where-allowed.rs:142:31 | LL | fn in_foreign_return() -> impl Debug; | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `fn` pointer return types --> $DIR/where-allowed.rs:158:39 | LL | type InReturnInTypeAlias = fn() -> impl Debug; | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in traits +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in traits --> $DIR/where-allowed.rs:163:16 | LL | impl PartialEq for () { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in impl headers --> $DIR/where-allowed.rs:168:24 | LL | impl PartialEq<()> for impl Debug { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in impl headers --> $DIR/where-allowed.rs:173:6 | LL | impl impl Debug { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in impl headers --> $DIR/where-allowed.rs:179:24 | LL | impl InInherentImplAdt { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bounds +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in bounds --> $DIR/where-allowed.rs:185:11 | LL | where impl Debug: Debug | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bounds +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in bounds --> $DIR/where-allowed.rs:192:15 | LL | where Vec: Debug | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bounds +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in bounds --> $DIR/where-allowed.rs:199:24 | LL | where T: PartialEq | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait params --> $DIR/where-allowed.rs:206:17 | LL | where T: Fn(impl Debug) | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait return types --> $DIR/where-allowed.rs:213:22 | LL | where T: Fn() -> impl Debug | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generic parameter defaults --> $DIR/where-allowed.rs:219:40 | LL | struct InStructGenericParamDefault(T); | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generic parameter defaults --> $DIR/where-allowed.rs:223:36 | LL | enum InEnumGenericParamDefault { Variant(T) } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generic parameter defaults --> $DIR/where-allowed.rs:227:38 | LL | trait InTraitGenericParamDefault {} | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generic parameter defaults --> $DIR/where-allowed.rs:231:41 | LL | type InTypeAliasGenericParamDefault = T; | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generic parameter defaults --> $DIR/where-allowed.rs:235:11 | LL | impl T {} | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generic parameter defaults --> $DIR/where-allowed.rs:242:40 | LL | fn in_method_generic_param_default(_: T) {} | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings --> $DIR/where-allowed.rs:248:29 | LL | let _in_local_variable: impl Fn() = || {}; | ^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in closure return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in closure return types --> $DIR/where-allowed.rs:250:46 | LL | let _in_return_in_local_variable = || -> impl Fn() { || {} }; diff --git a/tests/ui/imports/ambiguous-9.stderr b/tests/ui/imports/ambiguous-9.stderr index 6c7d79174daf..2731ed2ba86d 100644 --- a/tests/ui/imports/ambiguous-9.stderr +++ b/tests/ui/imports/ambiguous-9.stderr @@ -60,6 +60,7 @@ note: `date_range` could also refer to the function imported here LL | use prelude::*; | ^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 4 warnings emitted diff --git a/tests/ui/imports/issue-55457.stderr b/tests/ui/imports/issue-55457.stderr index 788fcc830ae9..30d2373652b4 100644 --- a/tests/ui/imports/issue-55457.stderr +++ b/tests/ui/imports/issue-55457.stderr @@ -38,6 +38,7 @@ LL | #[derive(NonExistent)] | ^^^^^^^^^^^ | = note: import resolution is stuck, try simplifying macro imports + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: cannot determine resolution for the derive macro `NonExistent` --> $DIR/issue-55457.rs:5:10 @@ -46,6 +47,7 @@ LL | #[derive(NonExistent)] | ^^^^^^^^^^^ | = note: import resolution is stuck, try simplifying macro imports + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 6 previous errors diff --git a/tests/ui/indexing/index-help.stderr b/tests/ui/indexing/index-help.stderr index e020d0298757..2cb212a01396 100644 --- a/tests/ui/indexing/index-help.stderr +++ b/tests/ui/indexing/index-help.stderr @@ -5,7 +5,8 @@ LL | x[0i32]; | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `i32` = note: required for `Vec<{integer}>` to implement `Index` error: aborting due to previous error diff --git a/tests/ui/indexing/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr index 7a741cfc7def..6ea6bb600e94 100644 --- a/tests/ui/indexing/indexing-requires-a-uint.stderr +++ b/tests/ui/indexing/indexing-requires-a-uint.stderr @@ -5,7 +5,8 @@ LL | [0][0u8]; | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `u8` = note: required for `[{integer}]` to implement `Index` error[E0308]: mismatched types diff --git a/tests/ui/integral-indexing.stderr b/tests/ui/integral-indexing.stderr index bbbb2a86a22d..97e658617cf0 100644 --- a/tests/ui/integral-indexing.stderr +++ b/tests/ui/integral-indexing.stderr @@ -5,7 +5,8 @@ LL | v[3u8]; | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `u8` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[isize]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `u8` = note: required for `Vec` to implement `Index` error[E0277]: the type `[isize]` cannot be indexed by `i8` @@ -15,7 +16,8 @@ LL | v[3i8]; | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `i8` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[isize]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `i8` = note: required for `Vec` to implement `Index` error[E0277]: the type `[isize]` cannot be indexed by `u32` @@ -25,7 +27,8 @@ LL | v[3u32]; | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `u32` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[isize]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `u32` = note: required for `Vec` to implement `Index` error[E0277]: the type `[isize]` cannot be indexed by `i32` @@ -35,7 +38,8 @@ LL | v[3i32]; | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `i32` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[isize]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `i32` = note: required for `Vec` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `u8` @@ -45,7 +49,8 @@ LL | s.as_bytes()[3u8]; | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `u8` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[u8]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `u8` = note: required for `[u8]` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `i8` @@ -55,7 +60,8 @@ LL | s.as_bytes()[3i8]; | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `i8` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[u8]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `i8` = note: required for `[u8]` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `u32` @@ -65,7 +71,8 @@ LL | s.as_bytes()[3u32]; | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `u32` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[u8]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `u32` = note: required for `[u8]` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `i32` @@ -75,7 +82,8 @@ LL | s.as_bytes()[3i32]; | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `i32` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[u8]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `i32` = note: required for `[u8]` to implement `Index` error: aborting due to 8 previous errors diff --git a/tests/ui/issues/issue-33571.stderr b/tests/ui/issues/issue-33571.stderr index 2a9ba5ba71b8..819a533ddbe2 100644 --- a/tests/ui/issues/issue-33571.stderr +++ b/tests/ui/issues/issue-33571.stderr @@ -21,6 +21,7 @@ note: unsafe traits like `Sync` should be implemented explicitly | LL | Sync, | ^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-34334.stderr b/tests/ui/issues/issue-34334.stderr index 9d2c315e4dbc..753942dd1d18 100644 --- a/tests/ui/issues/issue-34334.stderr +++ b/tests/ui/issues/issue-34334.stderr @@ -19,7 +19,8 @@ LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_rece | ^^^^^^^ value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>` - = help: the trait `FromIterator` is implemented for `Vec` + = help: the trait `FromIterator<(u32, _, _)>` is implemented for `Vec<(u32, _, _)>` + = help: for that trait implementation, expected `(u32, _, _)`, found `()` note: the method call chain might not have had the expected associated types --> $DIR/issue-34334.rs:5:43 | diff --git a/tests/ui/issues/issue-40000.stderr b/tests/ui/issues/issue-40000.stderr index c41fbb9d2ec1..0737a9610e29 100644 --- a/tests/ui/issues/issue-40000.stderr +++ b/tests/ui/issues/issue-40000.stderr @@ -15,6 +15,7 @@ LL | foo(bar); | = note: expected trait object `dyn for<'a> Fn(&'a i32)` found trait object `dyn Fn(&i32)` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-45801.stderr b/tests/ui/issues/issue-45801.stderr index 8967f49df02a..e651e2a68d16 100644 --- a/tests/ui/issues/issue-45801.stderr +++ b/tests/ui/issues/issue-45801.stderr @@ -5,6 +5,7 @@ LL | req.get_ref::(); | ^^^^^^^ the trait `Plugin` is not implemented for `Params` | = help: the trait `Plugin` is implemented for `Params` + = help: for that trait implementation, expected `Foo`, found `i32` error: aborting due to previous error diff --git a/tests/ui/issues/issue-46101.stderr b/tests/ui/issues/issue-46101.stderr index 40295b8a1153..a0cdd5d5f053 100644 --- a/tests/ui/issues/issue-46101.stderr +++ b/tests/ui/issues/issue-46101.stderr @@ -9,6 +9,8 @@ error[E0433]: failed to resolve: partially resolved path in a derive macro | LL | #[derive(Foo::Anything)] | ^^^^^^^^^^^^^ partially resolved path in a derive macro + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-47715.rs b/tests/ui/issues/issue-47715.rs index b8088c18dadf..0a770593bc9c 100644 --- a/tests/ui/issues/issue-47715.rs +++ b/tests/ui/issues/issue-47715.rs @@ -7,22 +7,22 @@ trait Iterable { } struct Container> { - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types field: T } enum Enum> { - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types A(T), } union Union + Copy> { - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types x: T, } type Type> = T; -//~^ ERROR `impl Trait` only allowed in function and inherent method return types +//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types fn main() { } diff --git a/tests/ui/issues/issue-47715.stderr b/tests/ui/issues/issue-47715.stderr index dadea34b6883..2ded98781c64 100644 --- a/tests/ui/issues/issue-47715.stderr +++ b/tests/ui/issues/issue-47715.stderr @@ -1,22 +1,22 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generics --> $DIR/issue-47715.rs:9:37 | LL | struct Container> { | ^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generics --> $DIR/issue-47715.rs:14:30 | LL | enum Enum> { | ^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generics --> $DIR/issue-47715.rs:19:32 | LL | union Union + Copy> { | ^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in generics --> $DIR/issue-47715.rs:24:30 | LL | type Type> = T; diff --git a/tests/ui/issues/issue-53251.stderr b/tests/ui/issues/issue-53251.stderr index d5f14e8deb90..05ea63115896 100644 --- a/tests/ui/issues/issue-53251.stderr +++ b/tests/ui/issues/issue-53251.stderr @@ -32,6 +32,7 @@ note: associated function defined here, with 0 generic parameters | LL | fn f() {} | ^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: this error originates in the macro `impl_add` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-66667-function-cmp-cycle.stderr b/tests/ui/issues/issue-66667-function-cmp-cycle.stderr index d9a960ce1973..cec8117702a9 100644 --- a/tests/ui/issues/issue-66667-function-cmp-cycle.stderr +++ b/tests/ui/issues/issue-66667-function-cmp-cycle.stderr @@ -19,7 +19,7 @@ error[E0308]: mismatched types --> $DIR/issue-66667-function-cmp-cycle.rs:2:5 | LL | fn first() { - | - help: try adding a return type: `-> bool` + | - help: try adding a return type: `-> bool` LL | second == 1 | ^^^^^^^^^^^ expected `()`, found `bool` @@ -44,7 +44,7 @@ error[E0308]: mismatched types --> $DIR/issue-66667-function-cmp-cycle.rs:8:5 | LL | fn second() { - | - help: try adding a return type: `-> bool` + | - help: try adding a return type: `-> bool` LL | first == 1 | ^^^^^^^^^^ expected `()`, found `bool` @@ -69,7 +69,7 @@ error[E0308]: mismatched types --> $DIR/issue-66667-function-cmp-cycle.rs:14:5 | LL | fn bar() { - | - help: try adding a return type: `-> bool` + | - help: try adding a return type: `-> bool` LL | bar == 1 | ^^^^^^^^ expected `()`, found `bool` diff --git a/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr b/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr index 22b1da64cb31..128288e28f5a 100644 --- a/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr +++ b/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr @@ -5,7 +5,8 @@ LL | let x2: Vec = x1.into_iter().collect(); | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<&f64>` is not implemented for `Vec` - = help: the trait `FromIterator` is implemented for `Vec` + = help: the trait `FromIterator` is implemented for `Vec` + = help: for that trait implementation, expected `f64`, found `&f64` note: the method call chain might not have had the expected associated types --> $DIR/issue-66923-show-error-for-correct-call.rs:8:27 | @@ -25,7 +26,8 @@ LL | let x3 = x1.into_iter().collect::>(); | required by a bound introduced by this call | = help: the trait `FromIterator<&f64>` is not implemented for `Vec` - = help: the trait `FromIterator` is implemented for `Vec` + = help: the trait `FromIterator` is implemented for `Vec` + = help: for that trait implementation, expected `f64`, found `&f64` note: the method call chain might not have had the expected associated types --> $DIR/issue-66923-show-error-for-correct-call.rs:12:17 | diff --git a/tests/ui/iterators/invalid-iterator-chain.stderr b/tests/ui/iterators/invalid-iterator-chain.stderr index b355da5cb768..2601c9c0d69d 100644 --- a/tests/ui/iterators/invalid-iterator-chain.stderr +++ b/tests/ui/iterators/invalid-iterator-chain.stderr @@ -5,7 +5,8 @@ LL | i.collect() | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<&X>` is not implemented for `Vec` - = help: the trait `FromIterator` is implemented for `Vec` + = help: the trait `FromIterator` is implemented for `Vec` + = help: for that trait implementation, expected `X`, found `&X` note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:4:26 | @@ -159,7 +160,8 @@ LL | let g: Vec = f.collect(); | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<()>` is not implemented for `Vec` - = help: the trait `FromIterator` is implemented for `Vec` + = help: the trait `FromIterator` is implemented for `Vec` + = help: for that trait implementation, expected `i32`, found `()` note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:44:15 | diff --git a/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr b/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr index 2bb29f911a12..14bfcc3d04d9 100644 --- a/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr +++ b/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr @@ -1,8 +1,8 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:29:84 + --> $DIR/start_lang_item_args.rs:29:83 | LL | fn start(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) {} - | ^ expected `isize`, found `()` + | ^ expected `isize`, found `()` | = note: expected signature `fn(fn() -> _, _, _, _) -> isize` found signature `fn(fn() -> _, _, _, _)` diff --git a/tests/ui/lifetimes/issue-105675.stderr b/tests/ui/lifetimes/issue-105675.stderr index 66415f72bcb4..54ecd35ed6ac 100644 --- a/tests/ui/lifetimes/issue-105675.stderr +++ b/tests/ui/lifetimes/issue-105675.stderr @@ -81,6 +81,7 @@ note: the lifetime requirement is introduced here | LL | fn thing(x: impl FnOnce(&u32, &u32, u32)) {} | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider specifying the type of the closure parameters | LL | let f = |x: &_, y: &_, z: u32| (); diff --git a/tests/ui/lifetimes/unusual-rib-combinations.stderr b/tests/ui/lifetimes/unusual-rib-combinations.stderr index 01ec69a6110f..92a2ef2f432f 100644 --- a/tests/ui/lifetimes/unusual-rib-combinations.stderr +++ b/tests/ui/lifetimes/unusual-rib-combinations.stderr @@ -56,7 +56,7 @@ LL | fn d() {} | ^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&dyn for<'a> Foo<'a>` is forbidden as the type of a const generic parameter --> $DIR/unusual-rib-combinations.rs:29:21 @@ -65,7 +65,7 @@ LL | struct Bar Foo<'a>)>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 9 previous errors diff --git a/tests/ui/limits/issue-55878.stderr b/tests/ui/limits/issue-55878.stderr index 93716c0b3473..6b463930b007 100644 --- a/tests/ui/limits/issue-55878.stderr +++ b/tests/ui/limits/issue-55878.stderr @@ -25,6 +25,7 @@ note: erroneous constant encountered LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/tests/ui/lint/cli-unknown-force-warn.stderr b/tests/ui/lint/cli-unknown-force-warn.stderr index 2ee718a8c8e1..5084b4a40013 100644 --- a/tests/ui/lint/cli-unknown-force-warn.stderr +++ b/tests/ui/lint/cli-unknown-force-warn.stderr @@ -6,10 +6,12 @@ warning[E0602]: unknown lint: `foo_qux` warning[E0602]: unknown lint: `foo_qux` | = note: requested on the command line with `--force-warn foo_qux` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning[E0602]: unknown lint: `foo_qux` | = note: requested on the command line with `--force-warn foo_qux` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/lint/command-line-register-unknown-lint-tool.stderr b/tests/ui/lint/command-line-register-unknown-lint-tool.stderr index c9a2aff2137a..65aa19628308 100644 --- a/tests/ui/lint/command-line-register-unknown-lint-tool.stderr +++ b/tests/ui/lint/command-line-register-unknown-lint-tool.stderr @@ -5,6 +5,7 @@ error[E0602]: unknown lint tool: `unknown_tool` error[E0602]: unknown lint tool: `unknown_tool` | = note: requested on the command line with `-A unknown_tool::foo` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/crate_level_only_lint.stderr b/tests/ui/lint/crate_level_only_lint.stderr index 8fb06df2a481..fbb1ec381c8f 100644 --- a/tests/ui/lint/crate_level_only_lint.stderr +++ b/tests/ui/lint/crate_level_only_lint.stderr @@ -27,36 +27,48 @@ error: allow(uncommon_codepoints) is ignored unless specified at crate level | LL | #![allow(uncommon_codepoints)] | ^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: allow(uncommon_codepoints) is ignored unless specified at crate level --> $DIR/crate_level_only_lint.rs:9:9 | LL | #[allow(uncommon_codepoints)] | ^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: allow(uncommon_codepoints) is ignored unless specified at crate level --> $DIR/crate_level_only_lint.rs:17:9 | LL | #[allow(uncommon_codepoints)] | ^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: allow(uncommon_codepoints) is ignored unless specified at crate level --> $DIR/crate_level_only_lint.rs:4:10 | LL | #![allow(uncommon_codepoints)] | ^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: allow(uncommon_codepoints) is ignored unless specified at crate level --> $DIR/crate_level_only_lint.rs:9:9 | LL | #[allow(uncommon_codepoints)] | ^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: allow(uncommon_codepoints) is ignored unless specified at crate level --> $DIR/crate_level_only_lint.rs:17:9 | LL | #[allow(uncommon_codepoints)] | ^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 9 previous errors diff --git a/tests/ui/lint/forbid-group-group-2.stderr b/tests/ui/lint/forbid-group-group-2.stderr index b2e2bcea1b40..4a2c8fbd68ab 100644 --- a/tests/ui/lint/forbid-group-group-2.stderr +++ b/tests/ui/lint/forbid-group-group-2.stderr @@ -26,6 +26,7 @@ LL | #[allow(nonstandard_style)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #81670 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: allow(nonstandard_style) incompatible with previous forbid --> $DIR/forbid-group-group-2.rs:7:9 @@ -38,6 +39,7 @@ LL | #[allow(nonstandard_style)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #81670 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: allow(nonstandard_style) incompatible with previous forbid --> $DIR/forbid-group-group-2.rs:7:9 @@ -50,6 +52,7 @@ LL | #[allow(nonstandard_style)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #81670 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: allow(nonstandard_style) incompatible with previous forbid --> $DIR/forbid-group-group-2.rs:7:9 @@ -62,6 +65,7 @@ LL | #[allow(nonstandard_style)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #81670 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: allow(nonstandard_style) incompatible with previous forbid --> $DIR/forbid-group-group-2.rs:7:9 @@ -74,6 +78,7 @@ LL | #[allow(nonstandard_style)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #81670 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: allow(nonstandard_style) incompatible with previous forbid --> $DIR/forbid-group-group-2.rs:7:9 @@ -86,6 +91,7 @@ LL | #[allow(nonstandard_style)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #81670 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: allow(nonstandard_style) incompatible with previous forbid --> $DIR/forbid-group-group-2.rs:7:9 @@ -98,6 +104,7 @@ LL | #[allow(nonstandard_style)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #81670 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: allow(nonstandard_style) incompatible with previous forbid --> $DIR/forbid-group-group-2.rs:7:9 @@ -110,6 +117,7 @@ LL | #[allow(nonstandard_style)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #81670 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 9 previous errors diff --git a/tests/ui/lint/forbid-group-member.stderr b/tests/ui/lint/forbid-group-member.stderr index 47336d4d890b..ddaaafa12ec2 100644 --- a/tests/ui/lint/forbid-group-member.stderr +++ b/tests/ui/lint/forbid-group-member.stderr @@ -22,6 +22,7 @@ LL | #[allow(unused_variables)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #81670 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: allow(unused_variables) incompatible with previous forbid --> $DIR/forbid-group-member.rs:8:9 @@ -34,6 +35,7 @@ LL | #[allow(unused_variables)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #81670 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/lint/forbid-member-group.stderr b/tests/ui/lint/forbid-member-group.stderr index e65301778332..612dccd8d6ca 100644 --- a/tests/ui/lint/forbid-member-group.stderr +++ b/tests/ui/lint/forbid-member-group.stderr @@ -15,6 +15,8 @@ LL | #![forbid(unused_variables)] LL | LL | #[allow(unused)] | ^^^^^^ overruled by previous forbid + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr index 0f58953a54ba..ecdc625015e4 100644 --- a/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr +++ b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr @@ -20,6 +20,7 @@ LL | pub fn function(_x: Box) {} | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | pub fn function(_x: Box) {} @@ -33,6 +34,7 @@ LL | pub fn function(_x: Box) {} | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | pub fn function(_x: Box) {} diff --git a/tests/ui/lint/force-warn/cap-lints-allow.stderr b/tests/ui/lint/force-warn/cap-lints-allow.stderr index 03a32fa6f085..5f5f2ff52b6d 100644 --- a/tests/ui/lint/force-warn/cap-lints-allow.stderr +++ b/tests/ui/lint/force-warn/cap-lints-allow.stderr @@ -20,6 +20,7 @@ LL | pub fn function(_x: Box) {} | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | pub fn function(_x: Box) {} @@ -33,6 +34,7 @@ LL | pub fn function(_x: Box) {} | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | pub fn function(_x: Box) {} diff --git a/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr index b0cd3ddd26f2..3a0b1201b0cd 100644 --- a/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr +++ b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr @@ -21,6 +21,7 @@ LL | pub fn function(_x: Box) {} | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | pub fn function(_x: Box) {} @@ -34,6 +35,7 @@ LL | pub fn function(_x: Box) {} | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | pub fn function(_x: Box) {} diff --git a/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr index 8c841916c93d..92555eda2a73 100644 --- a/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr +++ b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr @@ -21,6 +21,7 @@ LL | pub fn function(_x: Box) {} | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | pub fn function(_x: Box) {} @@ -34,6 +35,7 @@ LL | pub fn function(_x: Box) {} | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | pub fn function(_x: Box) {} diff --git a/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr index c0144205d6a9..c14c7957a25f 100644 --- a/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr +++ b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr @@ -21,6 +21,7 @@ LL | pub fn function(_x: Box) {} | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | pub fn function(_x: Box) {} @@ -34,6 +35,7 @@ LL | pub fn function(_x: Box) {} | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | pub fn function(_x: Box) {} diff --git a/tests/ui/lint/force-warn/warnings-lint-group.stderr b/tests/ui/lint/force-warn/warnings-lint-group.stderr index 1faeed337045..3e73269a233e 100644 --- a/tests/ui/lint/force-warn/warnings-lint-group.stderr +++ b/tests/ui/lint/force-warn/warnings-lint-group.stderr @@ -1,6 +1,8 @@ error[E0602]: `warnings` lint group is not supported with ´--force-warn´ error[E0602]: `warnings` lint group is not supported with ´--force-warn´ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/issue-80988.stderr b/tests/ui/lint/issue-80988.stderr index 73e27ffda7fe..7a65881b5eda 100644 --- a/tests/ui/lint/issue-80988.stderr +++ b/tests/ui/lint/issue-80988.stderr @@ -22,6 +22,7 @@ LL | #[deny(warnings)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #81670 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: deny(warnings) incompatible with previous forbid --> $DIR/issue-80988.rs:7:8 @@ -34,6 +35,7 @@ LL | #[deny(warnings)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #81670 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/lint/lint-forbid-attr.stderr b/tests/ui/lint/lint-forbid-attr.stderr index 5977b9c949d5..bd476a0e362d 100644 --- a/tests/ui/lint/lint-forbid-attr.stderr +++ b/tests/ui/lint/lint-forbid-attr.stderr @@ -15,6 +15,8 @@ LL | #![forbid(deprecated)] LL | LL | #[allow(deprecated)] | ^^^^^^^^^^ overruled by previous forbid + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/lint-forbid-cmdline.stderr b/tests/ui/lint/lint-forbid-cmdline.stderr index 0a92e58c04aa..ed49a2cb4274 100644 --- a/tests/ui/lint/lint-forbid-cmdline.stderr +++ b/tests/ui/lint/lint-forbid-cmdline.stderr @@ -13,6 +13,7 @@ LL | #[allow(deprecated)] | ^^^^^^^^^^ overruled by previous forbid | = note: `forbid` lint level was set on command line + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/lint-malformed.stderr b/tests/ui/lint/lint-malformed.stderr index 91b4e509b269..2c9f045de71f 100644 --- a/tests/ui/lint/lint-malformed.stderr +++ b/tests/ui/lint/lint-malformed.stderr @@ -9,6 +9,8 @@ error[E0452]: malformed lint attribute input | LL | #![allow(bar = "baz")] | ^^^^^^^^^^^ bad attribute argument + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: malformed `deny` attribute input --> $DIR/lint-malformed.rs:1:1 @@ -21,12 +23,16 @@ error[E0452]: malformed lint attribute input | LL | #![allow(bar = "baz")] | ^^^^^^^^^^^ bad attribute argument + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0452]: malformed lint attribute input --> $DIR/lint-malformed.rs:2:10 | LL | #![allow(bar = "baz")] | ^^^^^^^^^^^ bad attribute argument + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 5 previous errors diff --git a/tests/ui/lint/lint-removed-cmdline-deny.stderr b/tests/ui/lint/lint-removed-cmdline-deny.stderr index 80c85d01e53c..3321afa7fcd7 100644 --- a/tests/ui/lint/lint-removed-cmdline-deny.stderr +++ b/tests/ui/lint/lint-removed-cmdline-deny.stderr @@ -6,10 +6,12 @@ error: lint `raw_pointer_derive` has been removed: using derive with raw pointer error: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok | = note: requested on the command line with `-D raw_pointer_derive` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok | = note: requested on the command line with `-D raw_pointer_derive` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: unused variable: `unused` --> $DIR/lint-removed-cmdline-deny.rs:13:17 diff --git a/tests/ui/lint/lint-removed-cmdline.stderr b/tests/ui/lint/lint-removed-cmdline.stderr index ebfae34ade92..6b76ad3b578c 100644 --- a/tests/ui/lint/lint-removed-cmdline.stderr +++ b/tests/ui/lint/lint-removed-cmdline.stderr @@ -6,10 +6,12 @@ warning: lint `raw_pointer_derive` has been removed: using derive with raw point warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok | = note: requested on the command line with `-D raw_pointer_derive` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok | = note: requested on the command line with `-D raw_pointer_derive` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: unused variable: `unused` --> $DIR/lint-removed-cmdline.rs:13:17 diff --git a/tests/ui/lint/lint-renamed-cmdline-deny.stderr b/tests/ui/lint/lint-renamed-cmdline-deny.stderr index df22ef60daf1..0e182a4e5dea 100644 --- a/tests/ui/lint/lint-renamed-cmdline-deny.stderr +++ b/tests/ui/lint/lint-renamed-cmdline-deny.stderr @@ -8,11 +8,13 @@ error: lint `bare_trait_object` has been renamed to `bare_trait_objects` | = help: use the new name `bare_trait_objects` = note: requested on the command line with `-D bare_trait_object` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: lint `bare_trait_object` has been renamed to `bare_trait_objects` | = help: use the new name `bare_trait_objects` = note: requested on the command line with `-D bare_trait_object` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: unused variable: `unused` --> $DIR/lint-renamed-cmdline-deny.rs:10:17 diff --git a/tests/ui/lint/lint-renamed-cmdline.stderr b/tests/ui/lint/lint-renamed-cmdline.stderr index a41284003ed6..675443ddedf5 100644 --- a/tests/ui/lint/lint-renamed-cmdline.stderr +++ b/tests/ui/lint/lint-renamed-cmdline.stderr @@ -8,11 +8,13 @@ warning: lint `bare_trait_object` has been renamed to `bare_trait_objects` | = help: use the new name `bare_trait_objects` = note: requested on the command line with `-D bare_trait_object` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: lint `bare_trait_object` has been renamed to `bare_trait_objects` | = help: use the new name `bare_trait_objects` = note: requested on the command line with `-D bare_trait_object` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: unused variable: `unused` --> $DIR/lint-renamed-cmdline.rs:9:17 diff --git a/tests/ui/lint/lint-stability-deprecated.stderr b/tests/ui/lint/lint-stability-deprecated.stderr index 19a4649e1680..609fc56a8ae5 100644 --- a/tests/ui/lint/lint-stability-deprecated.stderr +++ b/tests/ui/lint/lint-stability-deprecated.stderr @@ -639,18 +639,24 @@ warning: use of deprecated associated type `lint_stability::TraitWithAssociatedT | LL | struct S2(T::TypeDeprecated); | ^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text --> $DIR/lint-stability-deprecated.rs:102:13 | LL | TypeDeprecated = u16, | ^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text --> $DIR/lint-stability-deprecated.rs:102:13 | LL | TypeDeprecated = u16, | ^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 108 warnings emitted diff --git a/tests/ui/lint/lint-unexported-no-mangle.stderr b/tests/ui/lint/lint-unexported-no-mangle.stderr index 858527822220..0efec51abaf6 100644 --- a/tests/ui/lint/lint-unexported-no-mangle.stderr +++ b/tests/ui/lint/lint-unexported-no-mangle.stderr @@ -10,18 +10,22 @@ warning: lint `private_no_mangle_statics` has been removed: no longer a warning, warning: lint `private_no_mangle_fns` has been removed: no longer a warning, `#[no_mangle]` functions always exported | = note: requested on the command line with `-F private_no_mangle_fns` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: lint `private_no_mangle_statics` has been removed: no longer a warning, `#[no_mangle]` statics always exported | = note: requested on the command line with `-F private_no_mangle_statics` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: lint `private_no_mangle_fns` has been removed: no longer a warning, `#[no_mangle]` functions always exported | = note: requested on the command line with `-F private_no_mangle_fns` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: lint `private_no_mangle_statics` has been removed: no longer a warning, `#[no_mangle]` statics always exported | = note: requested on the command line with `-F private_no_mangle_statics` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: const items should never be `#[no_mangle]` --> $DIR/lint-unexported-no-mangle.rs:9:1 diff --git a/tests/ui/lint/lint-unknown-lint-cmdline-deny.stderr b/tests/ui/lint/lint-unknown-lint-cmdline-deny.stderr index 677b5edc894b..f12ce03ddfce 100644 --- a/tests/ui/lint/lint-unknown-lint-cmdline-deny.stderr +++ b/tests/ui/lint/lint-unknown-lint-cmdline-deny.stderr @@ -11,20 +11,24 @@ error[E0602]: unknown lint: `dead_cod` error[E0602]: unknown lint: `bogus` | = note: requested on the command line with `-D bogus` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0602]: unknown lint: `dead_cod` | = help: did you mean: `dead_code` = note: requested on the command line with `-D dead_cod` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0602]: unknown lint: `bogus` | = note: requested on the command line with `-D bogus` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0602]: unknown lint: `dead_cod` | = help: did you mean: `dead_code` = note: requested on the command line with `-D dead_cod` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 6 previous errors diff --git a/tests/ui/lint/lint-unknown-lint-cmdline.stderr b/tests/ui/lint/lint-unknown-lint-cmdline.stderr index 10db76ac4f16..f452fc9eb943 100644 --- a/tests/ui/lint/lint-unknown-lint-cmdline.stderr +++ b/tests/ui/lint/lint-unknown-lint-cmdline.stderr @@ -11,20 +11,24 @@ warning[E0602]: unknown lint: `dead_cod` warning[E0602]: unknown lint: `bogus` | = note: requested on the command line with `-D bogus` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning[E0602]: unknown lint: `dead_cod` | = help: did you mean: `dead_code` = note: requested on the command line with `-D dead_cod` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning[E0602]: unknown lint: `bogus` | = note: requested on the command line with `-D bogus` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning[E0602]: unknown lint: `dead_cod` | = help: did you mean: `dead_code` = note: requested on the command line with `-D dead_cod` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 6 warnings emitted diff --git a/tests/ui/lint/must_not_suspend/gated.stderr b/tests/ui/lint/must_not_suspend/gated.stderr index 64de1ebeaabe..f0d2117d42b5 100644 --- a/tests/ui/lint/must_not_suspend/gated.stderr +++ b/tests/ui/lint/must_not_suspend/gated.stderr @@ -18,6 +18,7 @@ LL | #![deny(must_not_suspend)] = note: the `must_not_suspend` lint is unstable = note: see issue #83310 for more information = help: add `#![feature(must_not_suspend)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `must_not_suspend` --> $DIR/gated.rs:4:1 @@ -28,6 +29,7 @@ LL | #![deny(must_not_suspend)] = note: the `must_not_suspend` lint is unstable = note: see issue #83310 for more information = help: add `#![feature(must_not_suspend)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/lint/noop-method-call.fixed b/tests/ui/lint/noop-method-call.fixed index eeb80279fd81..4d9834f7df62 100644 --- a/tests/ui/lint/noop-method-call.fixed +++ b/tests/ui/lint/noop-method-call.fixed @@ -1,6 +1,7 @@ // check-pass // run-rustfix +#![feature(rustc_attrs)] #![allow(unused)] use std::borrow::Borrow; @@ -49,3 +50,15 @@ fn non_generic(non_clone_type: &PlainType) { non_clone_type; //~^ WARN call to `.clone()` on a reference in this situation does nothing } + +struct DiagnosticClone; +impl Clone for DiagnosticClone { + #[rustc_diagnostic_item = "other_clone"] + fn clone(&self) -> Self { + DiagnosticClone + } +} + +fn with_other_diagnostic_item(x: DiagnosticClone) { + x.clone(); +} diff --git a/tests/ui/lint/noop-method-call.rs b/tests/ui/lint/noop-method-call.rs index 9569a0dfc617..6242a00e0334 100644 --- a/tests/ui/lint/noop-method-call.rs +++ b/tests/ui/lint/noop-method-call.rs @@ -1,6 +1,7 @@ // check-pass // run-rustfix +#![feature(rustc_attrs)] #![allow(unused)] use std::borrow::Borrow; @@ -49,3 +50,15 @@ fn non_generic(non_clone_type: &PlainType) { non_clone_type.clone(); //~^ WARN call to `.clone()` on a reference in this situation does nothing } + +struct DiagnosticClone; +impl Clone for DiagnosticClone { + #[rustc_diagnostic_item = "other_clone"] + fn clone(&self) -> Self { + DiagnosticClone + } +} + +fn with_other_diagnostic_item(x: DiagnosticClone) { + x.clone(); +} diff --git a/tests/ui/lint/noop-method-call.stderr b/tests/ui/lint/noop-method-call.stderr index aefc2706fd52..d04f44022eef 100644 --- a/tests/ui/lint/noop-method-call.stderr +++ b/tests/ui/lint/noop-method-call.stderr @@ -1,5 +1,5 @@ warning: call to `.clone()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:15:25 + --> $DIR/noop-method-call.rs:16:25 | LL | let _ = &mut encoded.clone(); | ^^^^^^^^ help: remove this redundant call @@ -8,7 +8,7 @@ LL | let _ = &mut encoded.clone(); = note: `#[warn(noop_method_call)]` on by default warning: call to `.clone()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:17:21 + --> $DIR/noop-method-call.rs:18:21 | LL | let _ = &encoded.clone(); | ^^^^^^^^ help: remove this redundant call @@ -16,7 +16,7 @@ LL | let _ = &encoded.clone(); = note: the type `[u8]` does not implement `Clone`, so calling `clone` on `&[u8]` copies the reference, which does not do anything and can be removed warning: call to `.clone()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:23:71 + --> $DIR/noop-method-call.rs:24:71 | LL | let non_clone_type_ref_clone: &PlainType = non_clone_type_ref.clone(); | ^^^^^^^^ help: remove this redundant call @@ -24,7 +24,7 @@ LL | let non_clone_type_ref_clone: &PlainType = non_clone_type_ref.clon = note: the type `PlainType` does not implement `Clone`, so calling `clone` on `&PlainType` copies the reference, which does not do anything and can be removed warning: call to `.deref()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:31:63 + --> $DIR/noop-method-call.rs:32:63 | LL | let non_deref_type_deref: &PlainType = non_deref_type.deref(); | ^^^^^^^^ help: remove this redundant call @@ -32,7 +32,7 @@ LL | let non_deref_type_deref: &PlainType = non_deref_type.deref(); = note: the type `PlainType` does not implement `Deref`, so calling `deref` on `&PlainType` copies the reference, which does not do anything and can be removed warning: call to `.borrow()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:35:66 + --> $DIR/noop-method-call.rs:36:66 | LL | let non_borrow_type_borrow: &PlainType = non_borrow_type.borrow(); | ^^^^^^^^^ help: remove this redundant call @@ -40,7 +40,7 @@ LL | let non_borrow_type_borrow: &PlainType = non_borrow_type.borrow(); = note: the type `PlainType` does not implement `Borrow`, so calling `borrow` on `&PlainType` copies the reference, which does not do anything and can be removed warning: call to `.clone()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:44:19 + --> $DIR/noop-method-call.rs:45:19 | LL | non_clone_type.clone(); | ^^^^^^^^ help: remove this redundant call @@ -48,7 +48,7 @@ LL | non_clone_type.clone(); = note: the type `PlainType` does not implement `Clone`, so calling `clone` on `&PlainType` copies the reference, which does not do anything and can be removed warning: call to `.clone()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:49:19 + --> $DIR/noop-method-call.rs:50:19 | LL | non_clone_type.clone(); | ^^^^^^^^ help: remove this redundant call diff --git a/tests/ui/lint/reasons-erroneous.rs b/tests/ui/lint/reasons-erroneous.rs index cd693ae166cd..7b286eb1d18e 100644 --- a/tests/ui/lint/reasons-erroneous.rs +++ b/tests/ui/lint/reasons-erroneous.rs @@ -1,51 +1,27 @@ +// compile-flags: -Zdeduplicate-diagnostics=yes + #![feature(lint_reasons)] #![warn(absolute_paths_not_starting_with_crate, reason = 0)] //~^ ERROR malformed lint attribute -//~| ERROR malformed lint attribute -//~| NOTE reason must be a string literal //~| NOTE reason must be a string literal #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")] //~^ ERROR malformed lint attribute -//~| ERROR malformed lint attribute -//~| NOTE reason must be a string literal //~| NOTE reason must be a string literal #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] //~^ ERROR malformed lint attribute -//~| ERROR malformed lint attribute -//~| ERROR malformed lint attribute -//~| ERROR malformed lint attribute -//~| NOTE bad attribute argument -//~| NOTE bad attribute argument -//~| NOTE bad attribute argument //~| NOTE bad attribute argument #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] //~^ ERROR malformed lint attribute -//~| ERROR malformed lint attribute -//~| ERROR malformed lint attribute -//~| ERROR malformed lint attribute -//~| NOTE bad attribute argument -//~| NOTE bad attribute argument -//~| NOTE bad attribute argument //~| NOTE bad attribute argument #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] //~^ ERROR malformed lint attribute -//~| ERROR malformed lint attribute -//~| ERROR malformed lint attribute -//~| ERROR malformed lint attribute -//~| NOTE bad attribute argument -//~| NOTE bad attribute argument -//~| NOTE bad attribute argument //~| NOTE bad attribute argument #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")] //~^ ERROR malformed lint attribute -//~| ERROR malformed lint attribute -//~| NOTE reason in lint attribute must come last //~| NOTE reason in lint attribute must come last #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)] //~^ ERROR malformed lint attribute -//~| ERROR malformed lint attribute -//~| NOTE reason in lint attribute must come last //~| NOTE reason in lint attribute must come last #![warn(missing_copy_implementations, reason)] //~^ WARN unknown lint diff --git a/tests/ui/lint/reasons-erroneous.stderr b/tests/ui/lint/reasons-erroneous.stderr index 5521af17c841..003da5673704 100644 --- a/tests/ui/lint/reasons-erroneous.stderr +++ b/tests/ui/lint/reasons-erroneous.stderr @@ -1,5 +1,5 @@ error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:3:58 + --> $DIR/reasons-erroneous.rs:5:58 | LL | #![warn(absolute_paths_not_starting_with_crate, reason = 0)] | ^ reason must be a string literal @@ -11,121 +11,43 @@ LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condem | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:13:29 + --> $DIR/reasons-erroneous.rs:11:29 | LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:13:29 - | -LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument - -error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:22:23 - | -LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument - -error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:22:23 - | -LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument - -error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:31:36 - | -LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument - -error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:31:36 - | -LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument - -error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:40:44 - | -LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")] - | ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last - -error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:45:25 - | -LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last - -error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:3:58 - | -LL | #![warn(absolute_paths_not_starting_with_crate, reason = 0)] - | ^ reason must be a string literal - -error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:8:40 - | -LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal - -error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:13:29 - | -LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument - -error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:13:29 - | -LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument - -error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:22:23 - | -LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument - -error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:22:23 + --> $DIR/reasons-erroneous.rs:14:23 | LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:31:36 - | -LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument - -error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:31:36 + --> $DIR/reasons-erroneous.rs:17:36 | LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:40:44 + --> $DIR/reasons-erroneous.rs:20:44 | LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")] | ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:45:25 + --> $DIR/reasons-erroneous.rs:23:25 | LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last warning: unknown lint: `reason` - --> $DIR/reasons-erroneous.rs:50:39 + --> $DIR/reasons-erroneous.rs:26:39 | LL | #![warn(missing_copy_implementations, reason)] | ^^^^^^ | = note: `#[warn(unknown_lints)]` on by default -error: aborting due to 20 previous errors; 1 warning emitted +error: aborting due to 7 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0452`. diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs index fba8789e999e..25e0c75f70db 100644 --- a/tests/ui/lint/reference_casting.rs +++ b/tests/ui/lint/reference_casting.rs @@ -64,6 +64,10 @@ unsafe fn ref_to_mut() { let _num = &mut *num; //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let cell = &std::cell::UnsafeCell::new(0); + let _num = &mut *(cell as *const _ as *mut i32); + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + unsafe fn generic_ref_cast_mut(this: &T) -> &mut T { &mut *((this as *const _) as *mut _) //~^ ERROR casting `&T` to `&mut T` is undefined behavior @@ -106,6 +110,8 @@ unsafe fn assign_to_ref() { std::mem::transmute::<*const i32, *mut i32>(num), -1i32, ); + *((&std::cell::UnsafeCell::new(0)) as *const _ as *mut i32) = 5; + //~^ ERROR assigning to `&T` is undefined behavior let value = num as *const i32 as *mut i32; *value = 1; @@ -148,6 +154,8 @@ unsafe fn no_warn() { *RAW_PTR = 42; // RAW_PTR is defined outside the function body, // make sure we don't ICE on it when trying to // determine if we should lint on it or not. + let cell = &std::cell::UnsafeCell::new(0); + let _num = &mut *(cell.get() as *mut i32); fn safe_as_mut(x: &std::cell::UnsafeCell) -> &mut T { unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } diff --git a/tests/ui/lint/reference_casting.stderr b/tests/ui/lint/reference_casting.stderr index 8f89cf9805b0..8d5f8da6852b 100644 --- a/tests/ui/lint/reference_casting.stderr +++ b/tests/ui/lint/reference_casting.stderr @@ -158,7 +158,16 @@ LL | let _num = &mut *num; = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:68:9 + --> $DIR/reference_casting.rs:68:16 + | +LL | let _num = &mut *(cell as *const _ as *mut i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit + = note: even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get` + +error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` + --> $DIR/reference_casting.rs:72:9 | LL | &mut *((this as *const _) as *mut _) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +175,7 @@ LL | &mut *((this as *const _) as *mut _) = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:73:18 + --> $DIR/reference_casting.rs:77:18 | LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -174,7 +183,7 @@ LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:78:18 + --> $DIR/reference_casting.rs:82:18 | LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -182,7 +191,7 @@ LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:88:5 + --> $DIR/reference_casting.rs:92:5 | LL | *(a as *const _ as *mut _) = String::from("Replaced"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -190,7 +199,7 @@ LL | *(a as *const _ as *mut _) = String::from("Replaced"); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:90:5 + --> $DIR/reference_casting.rs:94:5 | LL | *(a as *const _ as *mut String) += " world"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +207,7 @@ LL | *(a as *const _ as *mut String) += " world"; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:92:5 + --> $DIR/reference_casting.rs:96:5 | LL | *std::ptr::from_ref(num).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -206,7 +215,7 @@ LL | *std::ptr::from_ref(num).cast_mut() += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:94:5 + --> $DIR/reference_casting.rs:98:5 | LL | *std::ptr::from_ref({ num }).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -214,7 +223,7 @@ LL | *std::ptr::from_ref({ num }).cast_mut() += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:96:5 + --> $DIR/reference_casting.rs:100:5 | LL | *{ std::ptr::from_ref(num) }.cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -222,7 +231,7 @@ LL | *{ std::ptr::from_ref(num) }.cast_mut() += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:98:5 + --> $DIR/reference_casting.rs:102:5 | LL | *(std::ptr::from_ref({ num }) as *mut i32) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -230,7 +239,7 @@ LL | *(std::ptr::from_ref({ num }) as *mut i32) += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:100:5 + --> $DIR/reference_casting.rs:104:5 | LL | *std::mem::transmute::<_, *mut i32>(num) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -238,7 +247,7 @@ LL | *std::mem::transmute::<_, *mut i32>(num) += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:102:5 + --> $DIR/reference_casting.rs:106:5 | LL | *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -246,7 +255,7 @@ LL | *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:104:5 + --> $DIR/reference_casting.rs:108:5 | LL | / std::ptr::write( LL | | @@ -258,7 +267,16 @@ LL | | ); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:111:5 + --> $DIR/reference_casting.rs:113:5 + | +LL | *((&std::cell::UnsafeCell::new(0)) as *const _ as *mut i32) = 5; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit + = note: even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get` + +error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` + --> $DIR/reference_casting.rs:117:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -268,7 +286,7 @@ LL | *value = 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:114:5 + --> $DIR/reference_casting.rs:120:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -279,7 +297,7 @@ LL | *value_rebind = 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:116:5 + --> $DIR/reference_casting.rs:122:5 | LL | *(num as *const i32).cast::().cast_mut() = 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -287,7 +305,7 @@ LL | *(num as *const i32).cast::().cast_mut() = 2; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:118:5 + --> $DIR/reference_casting.rs:124:5 | LL | *(num as *const _ as usize as *mut i32) = 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -295,7 +313,7 @@ LL | *(num as *const _ as usize as *mut i32) = 2; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:120:5 + --> $DIR/reference_casting.rs:126:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -306,7 +324,7 @@ LL | std::ptr::write(value, 2); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:122:5 + --> $DIR/reference_casting.rs:128:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -317,7 +335,7 @@ LL | std::ptr::write_unaligned(value, 2); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:124:5 + --> $DIR/reference_casting.rs:130:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -328,12 +346,12 @@ LL | std::ptr::write_volatile(value, 2); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:128:9 + --> $DIR/reference_casting.rs:134:9 | LL | *(this as *const _ as *mut _) = a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, visit -error: aborting due to 38 previous errors +error: aborting due to 40 previous errors diff --git a/tests/ui/lint/register-tool-lint.stderr b/tests/ui/lint/register-tool-lint.stderr index 842d845ff7c3..7ebdbdec9297 100644 --- a/tests/ui/lint/register-tool-lint.stderr +++ b/tests/ui/lint/register-tool-lint.stderr @@ -13,6 +13,7 @@ LL | #![warn(abc::my_lint)] | ^^^ | = help: add `#![register_tool(abc)]` to the crate root + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_unused_inside_impl_block.rs b/tests/ui/lint/rfc-2383-lint-reason/expect_unused_inside_impl_block.rs new file mode 100644 index 000000000000..1e2ff12a2062 --- /dev/null +++ b/tests/ui/lint/rfc-2383-lint-reason/expect_unused_inside_impl_block.rs @@ -0,0 +1,30 @@ +// check-pass +// incremental + +#![feature(lint_reasons)] +#![warn(unused)] + +struct OneUnused; +struct TwoUnused; + +impl OneUnused { + #[expect(unused)] + fn unused() {} +} + +impl TwoUnused { + #[expect(unused)] + fn unused1(){} + + // This unused method has `#[expect(unused)]`, so the compiler should not emit a warning. + // This ui test was added after a regression in the compiler where it did not recognize multiple + // `#[expect(unused)]` annotations inside of impl blocks. + // issue 114416 + #[expect(unused)] + fn unused2(){} +} + +fn main() { + let _ = OneUnused; + let _ = TwoUnused; +} diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.rs b/tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.rs index 479ee198e174..77cb5e88bf71 100644 --- a/tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.rs +++ b/tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.rs @@ -1,24 +1,20 @@ +// compile-flags: -Zdeduplicate-diagnostics=yes + #![feature(lint_reasons)] #[forbid(unused_variables)] //~^ NOTE `forbid` level set here -//~| NOTE `forbid` level set here #[expect(unused_variables)] //~^ ERROR incompatible with previous forbid [E0453] //~| NOTE overruled by previous forbid -//~| ERROR incompatible with previous forbid [E0453] -//~| NOTE overruled by previous forbid fn expect_forbidden_lint_1() {} #[forbid(while_true)] //~^ NOTE `forbid` level set here -//~| NOTE `forbid` level set here //~| NOTE the lint level is defined here #[expect(while_true)] //~^ ERROR incompatible with previous forbid [E0453] //~| NOTE overruled by previous forbid -//~| ERROR incompatible with previous forbid [E0453] -//~| NOTE overruled by previous forbid fn expect_forbidden_lint_2() { // This while loop will produce a `while_true` lint as the lint level // at this node is still `forbid` and the `while_true` check happens diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.stderr b/tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.stderr index a8116e93404f..0f42ffbdea36 100644 --- a/tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.stderr +++ b/tests/ui/lint/rfc-2383-lint-reason/expect_with_forbid.stderr @@ -1,32 +1,14 @@ error[E0453]: expect(unused_variables) incompatible with previous forbid - --> $DIR/expect_with_forbid.rs:6:10 + --> $DIR/expect_with_forbid.rs:7:10 | LL | #[forbid(unused_variables)] | ---------------- `forbid` level set here -... -LL | #[expect(unused_variables)] - | ^^^^^^^^^^^^^^^^ overruled by previous forbid - -error[E0453]: expect(while_true) incompatible with previous forbid - --> $DIR/expect_with_forbid.rs:17:10 - | -LL | #[forbid(while_true)] - | ---------- `forbid` level set here -... -LL | #[expect(while_true)] - | ^^^^^^^^^^ overruled by previous forbid - -error[E0453]: expect(unused_variables) incompatible with previous forbid - --> $DIR/expect_with_forbid.rs:6:10 - | -LL | #[forbid(unused_variables)] - | ---------------- `forbid` level set here -... +LL | LL | #[expect(unused_variables)] | ^^^^^^^^^^^^^^^^ overruled by previous forbid error[E0453]: expect(while_true) incompatible with previous forbid - --> $DIR/expect_with_forbid.rs:17:10 + --> $DIR/expect_with_forbid.rs:15:10 | LL | #[forbid(while_true)] | ---------- `forbid` level set here @@ -35,17 +17,17 @@ LL | #[expect(while_true)] | ^^^^^^^^^^ overruled by previous forbid error: denote infinite loops with `loop { ... }` - --> $DIR/expect_with_forbid.rs:26:5 + --> $DIR/expect_with_forbid.rs:22:5 | LL | while true {} | ^^^^^^^^^^ help: use `loop` | note: the lint level is defined here - --> $DIR/expect_with_forbid.rs:13:10 + --> $DIR/expect_with_forbid.rs:12:10 | LL | #[forbid(while_true)] | ^^^^^^^^^^ -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/tests/ui/loops/loop-break-value.stderr b/tests/ui/loops/loop-break-value.stderr index 6c83bc7575c3..a691960f9625 100644 --- a/tests/ui/loops/loop-break-value.stderr +++ b/tests/ui/loops/loop-break-value.stderr @@ -319,7 +319,7 @@ error[E0308]: mismatched types --> $DIR/loop-break-value.rs:159:15 | LL | fn main() { - | - expected `()` because of this return type + | - expected `()` because of this return type ... LL | loop { // point at the return type | ---- this loop is expected to be of type `()` diff --git a/tests/ui/lub-glb/old-lub-glb-object.stderr b/tests/ui/lub-glb/old-lub-glb-object.stderr index 3d0c171e013b..c476d6f692b7 100644 --- a/tests/ui/lub-glb/old-lub-glb-object.stderr +++ b/tests/ui/lub-glb/old-lub-glb-object.stderr @@ -15,6 +15,7 @@ LL | _ => y, | = note: expected trait object `dyn for<'a, 'b> Foo<&'a u8, &'b u8>` found trait object `dyn for<'a> Foo<&'a u8, &'a u8>` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/macros/builtin-std-paths-fail.stderr b/tests/ui/macros/builtin-std-paths-fail.stderr index 004a39043b77..331943843c02 100644 --- a/tests/ui/macros/builtin-std-paths-fail.stderr +++ b/tests/ui/macros/builtin-std-paths-fail.stderr @@ -15,12 +15,16 @@ error[E0433]: failed to resolve: could not find `RustcDecodable` in `core` | LL | core::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0433]: failed to resolve: could not find `RustcDecodable` in `core` --> $DIR/builtin-std-paths-fail.rs:4:11 | LL | core::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0433]: failed to resolve: could not find `bench` in `core` --> $DIR/builtin-std-paths-fail.rs:7:9 @@ -63,12 +67,16 @@ error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` | LL | std::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` --> $DIR/builtin-std-paths-fail.rs:16:10 | LL | std::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0433]: failed to resolve: could not find `bench` in `std` --> $DIR/builtin-std-paths-fail.rs:19:8 diff --git a/tests/ui/macros/meta-item-absolute-path.stderr b/tests/ui/macros/meta-item-absolute-path.stderr index c53971e245fd..f0d763d7abba 100644 --- a/tests/ui/macros/meta-item-absolute-path.stderr +++ b/tests/ui/macros/meta-item-absolute-path.stderr @@ -9,6 +9,8 @@ error[E0433]: failed to resolve: maybe a missing crate `Absolute`? | LL | #[derive(::Absolute)] | ^^^^^^^^ maybe a missing crate `Absolute`? + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index af7ef286f745..f1ce2d4455c9 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -3,6 +3,7 @@ // compile-flags: --test #![feature(async_closure)] +#![feature(auto_traits)] #![feature(box_patterns)] #![feature(const_trait_impl)] #![feature(decl_macro)] diff --git a/tests/ui/mismatched_types/issue-19109.stderr b/tests/ui/mismatched_types/issue-19109.stderr index 5cef64bb1692..ca819d93a50a 100644 --- a/tests/ui/mismatched_types/issue-19109.stderr +++ b/tests/ui/mismatched_types/issue-19109.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-19109.rs:4:5 | LL | fn function(t: &mut dyn Trait) { - | - help: try adding a return type: `-> *mut dyn Trait` + | - help: try adding a return type: `-> *mut dyn Trait` LL | t as *mut dyn Trait | ^^^^^^^^^^^^^^^^^^^ expected `()`, found `*mut dyn Trait` | diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs deleted file mode 100644 index 8d09a0fab453..000000000000 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs +++ /dev/null @@ -1,14 +0,0 @@ -// gate-test-packed_bundled_libs - -// ignore-wasm32-bare -// compile-flags: --crate-type rlib -// error-pattern: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs -// build-fail - -#[link(name = "rust_test_helpers", kind = "static", modifiers = "+bundle,+whole-archive")] -extern "C" {} - -fn main() {} - -// ferrocene-annotations: fls_o0f9ae22ug1x -// Attribute link diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr deleted file mode 100644 index 8a9fed740b04..000000000000 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr +++ /dev/null @@ -1,4 +0,0 @@ -error: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs - -error: aborting due to previous error - diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs deleted file mode 100644 index 118e41bcc93f..000000000000 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs +++ /dev/null @@ -1,10 +0,0 @@ -// gate-test-packed_bundled_libs - -// ignore-wasm32-bare -// compile-flags: -l static:+bundle,+whole-archive=rust_test_helpers --crate-type rlib -// error-pattern: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs -// build-fail - -fn main() {} - -// ferrocene-annotations: um_rustc_l diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr deleted file mode 100644 index 8a9fed740b04..000000000000 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr +++ /dev/null @@ -1,4 +0,0 @@ -error: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs - -error: aborting due to previous error - diff --git a/tests/ui/native-library-link-flags/modifiers-override.stderr b/tests/ui/native-library-link-flags/modifiers-override.stderr index eb3ab55c3104..64427651e9f6 100644 --- a/tests/ui/native-library-link-flags/modifiers-override.stderr +++ b/tests/ui/native-library-link-flags/modifiers-override.stderr @@ -21,6 +21,8 @@ error: overriding linking modifiers from command line is not supported | LL | extern "C" {} | ^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors diff --git a/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr b/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr index 54c16230fe68..cb3786305893 100644 --- a/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr +++ b/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr @@ -5,6 +5,7 @@ LL | >::from(never); | ^ the trait `From<()>` is not implemented for `E` | = help: the trait `From` is implemented for `E` + = help: for that trait implementation, expected `!`, found `()` error: aborting due to previous error diff --git a/tests/ui/nll/closure-malformed-projection-input-issue-102800.stderr b/tests/ui/nll/closure-malformed-projection-input-issue-102800.stderr index 46dba0064339..aeb0a1394ccc 100644 --- a/tests/ui/nll/closure-malformed-projection-input-issue-102800.stderr +++ b/tests/ui/nll/closure-malformed-projection-input-issue-102800.stderr @@ -15,6 +15,7 @@ LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {}; | = note: `&'0 ()` must implement `Trait`, for any lifetime `'0`... = note: ...but `Trait` is actually implemented for the type `&'static ()` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/nll/issue-97997.stderr b/tests/ui/nll/issue-97997.stderr index 46440c021f54..89eaf77adf06 100644 --- a/tests/ui/nll/issue-97997.stderr +++ b/tests/ui/nll/issue-97997.stderr @@ -15,6 +15,7 @@ LL | ::ASSOC; | = note: `Foo` would have to be implemented for the type `for<'a> fn(&'a u8)` = note: ...but `Foo` is actually implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/nll/missing-universe-cause-issue-114907.stderr b/tests/ui/nll/missing-universe-cause-issue-114907.stderr index c3dd4257a736..988eee61027b 100644 --- a/tests/ui/nll/missing-universe-cause-issue-114907.stderr +++ b/tests/ui/nll/missing-universe-cause-issue-114907.stderr @@ -38,6 +38,7 @@ LL | accept(callback); | = note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0308]: mismatched types --> $DIR/missing-universe-cause-issue-114907.rs:33:5 @@ -73,6 +74,8 @@ error: higher-ranked subtype error | LL | accept(callback); | ^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 6 previous errors diff --git a/tests/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr b/tests/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr index b945ffedda5a..804071a3e6f7 100644 --- a/tests/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr +++ b/tests/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.stderr @@ -15,6 +15,7 @@ LL | let _x = ::make_f(); | = note: `Y` would have to be implemented for the type `for<'a> fn(&'a ())` = note: ...but `Y` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: implementation of `Y` is not general enough --> $DIR/impl-fn-ignore-binder-via-bottom.rs:30:14 @@ -24,6 +25,7 @@ LL | let _x = ::make_f(); | = note: `Y` would have to be implemented for the type `for<'a> fn(&'a ())` = note: ...but `Y` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 3 previous errors diff --git a/tests/ui/nll/type-check-pointer-comparisons.stderr b/tests/ui/nll/type-check-pointer-comparisons.stderr index 0d8480a42c1e..37098b585dfe 100644 --- a/tests/ui/nll/type-check-pointer-comparisons.stderr +++ b/tests/ui/nll/type-check-pointer-comparisons.stderr @@ -61,6 +61,8 @@ LL | x == y; = help: see for more information about variance help: `'a` and `'b` must be the same: replace one with the other + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: lifetime may not live long enough --> $DIR/type-check-pointer-comparisons.rs:16:5 @@ -93,6 +95,8 @@ LL | f == g; = help: see for more information about variance help: `'a` and `'b` must be the same: replace one with the other + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 6 previous errors diff --git a/tests/ui/nll/user-annotations/normalization-2.stderr b/tests/ui/nll/user-annotations/normalization-2.stderr index 6b0dcb414aea..dcf049a7a61a 100644 --- a/tests/ui/nll/user-annotations/normalization-2.stderr +++ b/tests/ui/nll/user-annotations/normalization-2.stderr @@ -131,6 +131,7 @@ help: the following changes may resolve your lifetime errors | = help: replace `'a` with `'static` = help: replace `'b` with `'static` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: lifetime may not live long enough --> $DIR/normalization-2.rs:89:5 @@ -185,6 +186,7 @@ help: the following changes may resolve your lifetime errors | = help: replace `'a` with `'static` = help: replace `'b` with `'static` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: lifetime may not live long enough --> $DIR/normalization-2.rs:117:5 diff --git a/tests/ui/object-safety/assoc_type_bounds_sized_unnecessary.stderr b/tests/ui/object-safety/assoc_type_bounds_sized_unnecessary.stderr index d0a4179fe3e1..659679e44409 100644 --- a/tests/ui/object-safety/assoc_type_bounds_sized_unnecessary.stderr +++ b/tests/ui/object-safety/assoc_type_bounds_sized_unnecessary.stderr @@ -14,6 +14,7 @@ LL | fn foo(_: &dyn Foo) {} | ^^^^^^^^ help: remove this bound | = note: this associated type has a `where Self: Sized` bound. Thus, while the associated type can be specified, it cannot be used in any way, because trait objects are not `Sized`. + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unnecessary associated type bound for not object safe associated type --> $DIR/assoc_type_bounds_sized_unnecessary.rs:9:20 @@ -22,6 +23,7 @@ LL | fn foo(_: &dyn Foo) {} | ^^^^^^^^ help: remove this bound | = note: this associated type has a `where Self: Sized` bound. Thus, while the associated type can be specified, it cannot be used in any way, because trait objects are not `Sized`. + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/offset-of/offset-of-output-type.stderr b/tests/ui/offset-of/offset-of-output-type.stderr index 6133f3263ab6..233d49876436 100644 --- a/tests/ui/offset-of/offset-of-output-type.stderr +++ b/tests/ui/offset-of/offset-of-output-type.stderr @@ -42,7 +42,7 @@ error[E0308]: mismatched types --> $DIR/offset-of-output-type.rs:19:5 | LL | fn main() { - | - expected `()` because of default return type + | - expected `()` because of default return type ... LL | offset_of!(S, v) | ^^^^^^^^^^^^^^^^ expected `()`, found `usize` diff --git a/tests/ui/on-unimplemented/impl-substs.stderr b/tests/ui/on-unimplemented/impl-substs.stderr index a0fad0acd0b5..36d80f3e681b 100644 --- a/tests/ui/on-unimplemented/impl-substs.stderr +++ b/tests/ui/on-unimplemented/impl-substs.stderr @@ -7,7 +7,8 @@ LL | Foo::::foo((1i32, 1i32, 1i32)); | required by a bound introduced by this call | = help: the trait `Foo` is not implemented for `(i32, i32, i32)` - = help: the trait `Foo` is implemented for `(A, B, C)` + = help: the trait `Foo` is implemented for `(i32, i32, i32)` + = help: for that trait implementation, expected `i32`, found `usize` error: aborting due to previous error diff --git a/tests/ui/on-unimplemented/on-impl.stderr b/tests/ui/on-unimplemented/on-impl.stderr index 2253c5992a64..3a0b8353fa5e 100644 --- a/tests/ui/on-unimplemented/on-impl.stderr +++ b/tests/ui/on-unimplemented/on-impl.stderr @@ -8,6 +8,7 @@ LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); | = help: the trait `Index` is not implemented for `[i32]` = help: the trait `Index` is implemented for `[i32]` + = help: for that trait implementation, expected `usize`, found `u32` error[E0277]: the trait bound `[i32]: Index` is not satisfied --> $DIR/on-impl.rs:22:5 @@ -17,6 +18,7 @@ LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); | = help: the trait `Index` is not implemented for `[i32]` = help: the trait `Index` is implemented for `[i32]` + = help: for that trait implementation, expected `usize`, found `u32` error[E0277]: the trait bound `[i32]: Index` is not satisfied --> $DIR/on-impl.rs:22:5 @@ -26,6 +28,7 @@ LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); | = help: the trait `Index` is not implemented for `[i32]` = help: the trait `Index` is implemented for `[i32]` + = help: for that trait implementation, expected `usize`, found `u32` error: aborting due to 3 previous errors diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr index b9bca211f438..5e0117be5295 100644 --- a/tests/ui/on-unimplemented/slice-index.stderr +++ b/tests/ui/on-unimplemented/slice-index.stderr @@ -5,7 +5,8 @@ LL | x[1i32]; | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[i32]>` is not implemented for `i32` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[i32]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `i32` = note: required for `[i32]` to implement `Index` error[E0277]: the type `[i32]` cannot be indexed by `RangeTo` diff --git a/tests/ui/or-patterns/missing-bindings.stderr b/tests/ui/or-patterns/missing-bindings.stderr index 4457b7893d5d..7f182a857871 100644 --- a/tests/ui/or-patterns/missing-bindings.stderr +++ b/tests/ui/or-patterns/missing-bindings.stderr @@ -103,22 +103,6 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | | | variable not in all patterns -error[E0408]: variable `c` is not bound in all patterns - --> $DIR/missing-bindings.rs:45:33 - | -LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; - | - ^^^^ pattern doesn't bind `c` - | | - | variable not in all patterns - -error[E0408]: variable `d` is not bound in all patterns - --> $DIR/missing-bindings.rs:45:33 - | -LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; - | - ^^^^ pattern doesn't bind `d` - | | - | variable not in all patterns - error[E0408]: variable `e` is not bound in all patterns --> $DIR/missing-bindings.rs:45:10 | @@ -143,6 +127,22 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | | | variable not in all patterns +error[E0408]: variable `c` is not bound in all patterns + --> $DIR/missing-bindings.rs:45:33 + | +LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; + | - ^^^^ pattern doesn't bind `c` + | | + | variable not in all patterns + +error[E0408]: variable `d` is not bound in all patterns + --> $DIR/missing-bindings.rs:45:33 + | +LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; + | - ^^^^ pattern doesn't bind `d` + | | + | variable not in all patterns + error[E0408]: variable `a` is not bound in all patterns --> $DIR/missing-bindings.rs:61:29 | @@ -151,14 +151,6 @@ LL | Ok(a) | Err(_), | | | variable not in all patterns -error[E0408]: variable `a` is not bound in all patterns - --> $DIR/missing-bindings.rs:69:21 - | -LL | A(_, a) | - | - variable not in all patterns -LL | B(b), - | ^^^^ pattern doesn't bind `a` - error[E0408]: variable `b` is not bound in all patterns --> $DIR/missing-bindings.rs:68:21 | @@ -167,6 +159,14 @@ LL | A(_, a) | LL | B(b), | - variable not in all patterns +error[E0408]: variable `a` is not bound in all patterns + --> $DIR/missing-bindings.rs:69:21 + | +LL | A(_, a) | + | - variable not in all patterns +LL | B(b), + | ^^^^ pattern doesn't bind `a` + error[E0408]: variable `a` is not bound in all patterns --> $DIR/missing-bindings.rs:72:17 | @@ -185,6 +185,24 @@ LL | B(b), LL | B(_) | ^^^^ pattern doesn't bind `b` +error[E0408]: variable `b` is not bound in all patterns + --> $DIR/missing-bindings.rs:57:13 + | +LL | / V1( +LL | | +LL | | +LL | | A( +... | +LL | | B(Ok(a) | Err(a)) +LL | | ) | + | |_____________^ pattern doesn't bind `b` +... +LL | B(b), + | - variable not in all patterns +... +LL | V3(c), + | ^^^^^ pattern doesn't bind `b` + error[E0408]: variable `c` is not bound in all patterns --> $DIR/missing-bindings.rs:57:13 | @@ -219,24 +237,6 @@ LL | A(_, a) | LL | V3(c), | ^^^^^ pattern doesn't bind `a` -error[E0408]: variable `b` is not bound in all patterns - --> $DIR/missing-bindings.rs:57:13 - | -LL | / V1( -LL | | -LL | | -LL | | A( -... | -LL | | B(Ok(a) | Err(a)) -LL | | ) | - | |_____________^ pattern doesn't bind `b` -... -LL | B(b), - | - variable not in all patterns -... -LL | V3(c), - | ^^^^^ pattern doesn't bind `b` - error: aborting due to 26 previous errors For more information about this error, try `rustc --explain E0408`. diff --git a/tests/ui/parser/attr-stmt-expr-attr-bad.stderr b/tests/ui/parser/attr-stmt-expr-attr-bad.stderr index 96899fd3fc5c..e46c591080d4 100644 --- a/tests/ui/parser/attr-stmt-expr-attr-bad.stderr +++ b/tests/ui/parser/attr-stmt-expr-attr-bad.stderr @@ -27,6 +27,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } | = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files = note: outer attributes, like `#[test]`, annotate the item following them + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: expected expression, found `)` --> $DIR/attr-stmt-expr-attr-bad.rs:7:44 diff --git a/tests/ui/parser/issues/issue-84117.stderr b/tests/ui/parser/issues/issue-84117.stderr index 237bc11bd060..958f3b40bb0e 100644 --- a/tests/ui/parser/issues/issue-84117.stderr +++ b/tests/ui/parser/issues/issue-84117.stderr @@ -47,6 +47,7 @@ LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, } | | | while parsing the type for `inner_local` | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: you might have meant to end the type parameters here | LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str>, } @@ -61,6 +62,8 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, fo | LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, } | ^ expected one of 8 possible tokens + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,` --> $DIR/issue-84117.rs:2:33 diff --git a/tests/ui/parser/macro/macro-repeat.stderr b/tests/ui/parser/macro/macro-repeat.stderr index 63554b197b91..ade2bbf9b0b0 100644 --- a/tests/ui/parser/macro/macro-repeat.stderr +++ b/tests/ui/parser/macro/macro-repeat.stderr @@ -9,6 +9,8 @@ error: variable 'v' is still repeating at this depth | LL | $v | ^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/parser/recover-quantified-closure.stderr b/tests/ui/parser/recover-quantified-closure.stderr index 39eec80f658a..37e93cbee7be 100644 --- a/tests/ui/parser/recover-quantified-closure.stderr +++ b/tests/ui/parser/recover-quantified-closure.stderr @@ -25,10 +25,10 @@ LL | for ::Bar in x {} = help: consider removing `for<...>` error: implicit types in closure signatures are forbidden when `for<...>` is present - --> $DIR/recover-quantified-closure.rs:2:25 + --> $DIR/recover-quantified-closure.rs:2:24 | LL | for<'a> |x: &'a u8| *x + 1; - | ------- ^ + | ------- ^ | | | `for<...>` is here diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr index c0a6558a1bf3..0b432487615b 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr @@ -307,6 +307,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false | ^ move occurs because `b` has type `&mut U`, which does not implement the `Copy` trait | = note: variables bound in patterns cannot be moved from until after the end of the pattern guard + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0507]: cannot move out of `a` in pattern guard --> $DIR/borrowck-pat-ref-mut-and-ref.rs:109:66 @@ -323,6 +324,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false | ^ move occurs because `a` has type `&mut Result`, which does not implement the `Copy` trait | = note: variables bound in patterns cannot be moved from until after the end of the pattern guard + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:117:9 diff --git a/tests/ui/pattern/patkind-litrange-no-expr.stderr b/tests/ui/pattern/patkind-litrange-no-expr.stderr index eb1ee7e45673..45a261489403 100644 --- a/tests/ui/pattern/patkind-litrange-no-expr.stderr +++ b/tests/ui/pattern/patkind-litrange-no-expr.stderr @@ -9,6 +9,8 @@ error: arbitrary expressions aren't allowed in patterns | LL | Arith = 1 + 1, | ^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/pattern/usefulness/floats.rs b/tests/ui/pattern/usefulness/floats.rs index c921c40e3938..a4e6ffc35716 100644 --- a/tests/ui/pattern/usefulness/floats.rs +++ b/tests/ui/pattern/usefulness/floats.rs @@ -1,20 +1,46 @@ +#![feature(exclusive_range_pattern)] #![allow(illegal_floating_point_literal_pattern)] #![deny(unreachable_patterns)] fn main() { match 0.0 { - 0.0..=1.0 => {} - _ => {} // ok + 0.0..=1.0 => {} + _ => {} // ok } - match 0.0 { //~ ERROR non-exhaustive patterns - 0.0..=1.0 => {} + match 0.0 { + //~^ ERROR non-exhaustive patterns + 0.0..=1.0 => {} } match 1.0f64 { - 0.01f64 ..= 6.5f64 => {} - 0.02f64 => {} //~ ERROR unreachable pattern - _ => {} + 0.01f64..=6.5f64 => {} + 0.005f64 => {} + 0.01f64 => {} //~ ERROR unreachable pattern + 0.02f64 => {} //~ ERROR unreachable pattern + 6.5f64 => {} //~ ERROR unreachable pattern + 6.6f64 => {} + 1.0f64..=4.0f64 => {} //~ ERROR unreachable pattern + 5.0f64..=7.0f64 => {} + _ => {} + }; + match 1.0f64 { + 0.01f64..6.5f64 => {} + 6.5f64 => {} // this is reachable + _ => {} + }; + + match 1.0f32 { + 0.01f32..=6.5f32 => {} + 0.01f32 => {} //~ ERROR unreachable pattern + 0.02f32 => {} //~ ERROR unreachable pattern + 6.5f32 => {} //~ ERROR unreachable pattern + _ => {} + }; + match 1.0f32 { + 0.01f32..6.5f32 => {} + 6.5f32 => {} // this is reachable + _ => {} }; } diff --git a/tests/ui/pattern/usefulness/floats.stderr b/tests/ui/pattern/usefulness/floats.stderr index d66d4ba298be..f50419118246 100644 --- a/tests/ui/pattern/usefulness/floats.stderr +++ b/tests/ui/pattern/usefulness/floats.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/floats.rs:10:11 + --> $DIR/floats.rs:11:11 | LL | match 0.0 { | ^^^ pattern `_` not covered @@ -7,22 +7,58 @@ LL | match 0.0 { = note: the matched value is of type `f64` help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | -LL ~ 0.0..=1.0 => {}, -LL + _ => todo!() +LL ~ 0.0..=1.0 => {}, +LL + _ => todo!() | error: unreachable pattern - --> $DIR/floats.rs:16:7 + --> $DIR/floats.rs:19:9 | -LL | 0.02f64 => {} - | ^^^^^^^ +LL | 0.01f64 => {} + | ^^^^^^^ | note: the lint level is defined here - --> $DIR/floats.rs:2:9 + --> $DIR/floats.rs:3:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: unreachable pattern + --> $DIR/floats.rs:20:9 + | +LL | 0.02f64 => {} + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/floats.rs:21:9 + | +LL | 6.5f64 => {} + | ^^^^^^ + +error: unreachable pattern + --> $DIR/floats.rs:23:9 + | +LL | 1.0f64..=4.0f64 => {} + | ^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/floats.rs:35:9 + | +LL | 0.01f32 => {} + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/floats.rs:36:9 + | +LL | 0.02f32 => {} + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/floats.rs:37:9 + | +LL | 6.5f32 => {} + | ^^^^^^ + +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0004`. diff --git a/tests/ui/privacy/effective_visibilities.stderr b/tests/ui/privacy/effective_visibilities.stderr index f74f812e1a0e..41d63532dea4 100644 --- a/tests/ui/privacy/effective_visibilities.stderr +++ b/tests/ui/privacy/effective_visibilities.stderr @@ -45,6 +45,8 @@ error: not in the table | LL | struct PrivStruct; | ^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub --> $DIR/effective_visibilities.rs:25:9 @@ -81,6 +83,8 @@ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImpl | LL | A( | ^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub --> $DIR/effective_visibilities.rs:38:17 diff --git a/tests/ui/privacy/effective_visibilities_full_priv.stderr b/tests/ui/privacy/effective_visibilities_full_priv.stderr index 29d82e2ee01c..0577be1475fe 100644 --- a/tests/ui/privacy/effective_visibilities_full_priv.stderr +++ b/tests/ui/privacy/effective_visibilities_full_priv.stderr @@ -9,6 +9,8 @@ error: not in the table | LL | struct Priv; | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate) --> $DIR/effective_visibilities_full_priv.rs:13:5 diff --git a/tests/ui/privacy/privacy1.stderr b/tests/ui/privacy/privacy1.stderr index ca8f242e0bed..a3552e146a65 100644 --- a/tests/ui/privacy/privacy1.stderr +++ b/tests/ui/privacy/privacy1.stderr @@ -21,6 +21,7 @@ note: the module `baz` is defined here | LL | mod baz { | ^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0603]: module `baz` is private --> $DIR/privacy1.rs:141:18 diff --git a/tests/ui/proc-macro/issue-37788.stderr b/tests/ui/proc-macro/issue-37788.stderr index e437bb90b1df..0a116d6f80d3 100644 --- a/tests/ui/proc-macro/issue-37788.stderr +++ b/tests/ui/proc-macro/issue-37788.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-37788.rs:8:5 | LL | fn main() { - | - expected `()` because of default return type + | - expected `()` because of default return type LL | // Test that constructing the `visible_parent_map` (in `cstore_impl.rs`) does not ICE. LL | std::cell::Cell::new(0) | ^^^^^^^^^^^^^^^^^^^^^^^- help: consider using a semicolon here: `;` diff --git a/tests/ui/proc-macro/issue-75930-derive-cfg.stderr b/tests/ui/proc-macro/issue-75930-derive-cfg.stderr index 6d1efb0dc281..f3f470676e40 100644 --- a/tests/ui/proc-macro/issue-75930-derive-cfg.stderr +++ b/tests/ui/proc-macro/issue-75930-derive-cfg.stderr @@ -22,6 +22,7 @@ LL | #[derive(Print)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #79202 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 2 warnings emitted diff --git a/tests/ui/proc-macro/macro-namespace-reserved-2.stderr b/tests/ui/proc-macro/macro-namespace-reserved-2.stderr index b9effe7cf21f..0471124061ef 100644 --- a/tests/ui/proc-macro/macro-namespace-reserved-2.stderr +++ b/tests/ui/proc-macro/macro-namespace-reserved-2.stderr @@ -143,6 +143,7 @@ LL | #[derive(my_macro)] | ^^^^^^^^ | = note: `my_macro` is in scope, but it is a function-like macro + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 20 previous errors diff --git a/tests/ui/proc-macro/pretty-print-hack-show.local.stderr b/tests/ui/proc-macro/pretty-print-hack-show.local.stderr index 873054927c96..118882f73a3e 100644 --- a/tests/ui/proc-macro/pretty-print-hack-show.local.stderr +++ b/tests/ui/proc-macro/pretty-print-hack-show.local.stderr @@ -18,6 +18,7 @@ LL | enum ProceduralMasqueradeDummyType { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: using an old version of `rental` --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6 @@ -28,6 +29,7 @@ LL | enum ProceduralMasqueradeDummyType { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: using an old version of `rental` --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6 @@ -38,6 +40,7 @@ LL | enum ProceduralMasqueradeDummyType { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: using an old version of `rental` --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6 @@ -58,6 +61,7 @@ LL | enum ProceduralMasqueradeDummyType { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: using an old version of `rental` --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6 @@ -68,6 +72,7 @@ LL | enum ProceduralMasqueradeDummyType { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: using an old version of `rental` --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6 @@ -78,6 +83,7 @@ LL | enum ProceduralMasqueradeDummyType { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 8 previous errors diff --git a/tests/ui/proc-macro/pretty-print-hack-show.remapped.stderr b/tests/ui/proc-macro/pretty-print-hack-show.remapped.stderr index 873054927c96..118882f73a3e 100644 --- a/tests/ui/proc-macro/pretty-print-hack-show.remapped.stderr +++ b/tests/ui/proc-macro/pretty-print-hack-show.remapped.stderr @@ -18,6 +18,7 @@ LL | enum ProceduralMasqueradeDummyType { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: using an old version of `rental` --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6 @@ -28,6 +29,7 @@ LL | enum ProceduralMasqueradeDummyType { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: using an old version of `rental` --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6 @@ -38,6 +40,7 @@ LL | enum ProceduralMasqueradeDummyType { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: using an old version of `rental` --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6 @@ -58,6 +61,7 @@ LL | enum ProceduralMasqueradeDummyType { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: using an old version of `rental` --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6 @@ -68,6 +72,7 @@ LL | enum ProceduralMasqueradeDummyType { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: using an old version of `rental` --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6 @@ -78,6 +83,7 @@ LL | enum ProceduralMasqueradeDummyType { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 8 previous errors diff --git a/tests/ui/proc-macro/resolve-error.stderr b/tests/ui/proc-macro/resolve-error.stderr index 3c3f24d0ff22..e7639f474c75 100644 --- a/tests/ui/proc-macro/resolve-error.stderr +++ b/tests/ui/proc-macro/resolve-error.stderr @@ -44,6 +44,8 @@ error: cannot find derive macro `attr_proc_macra` in this scope | LL | #[derive(attr_proc_macra)] | ^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: cannot find derive macro `Dlona` in this scope --> $DIR/resolve-error.rs:40:10 @@ -66,6 +68,8 @@ LL | #[derive(Dlona)] | LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { | ------------------------------------------------------- similarly named derive macro `Clona` defined here + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: cannot find derive macro `Dlone` in this scope --> $DIR/resolve-error.rs:35:10 @@ -84,6 +88,8 @@ LL | #[derive(Dlone)] --> $SRC_DIR/core/src/clone.rs:LL:COL | = note: similarly named derive macro `Clone` defined here + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: cannot find attribute `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:32:3 @@ -123,6 +129,8 @@ LL | #[derive(FooWithLongNan)] | LL | pub fn derive_foo(input: TokenStream) -> TokenStream { | ---------------------------------------------------- similarly named derive macro `FooWithLongName` defined here + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 14 previous errors diff --git a/tests/ui/proc-macro/resolved-located-at.stderr b/tests/ui/proc-macro/resolved-located-at.stderr index 0b4dbcba6828..a4f838521fdd 100644 --- a/tests/ui/proc-macro/resolved-located-at.stderr +++ b/tests/ui/proc-macro/resolved-located-at.stderr @@ -10,7 +10,7 @@ error[E0308]: mismatched types --> $DIR/resolved-located-at.rs:7:27 | LL | fn main() { - | - expected `()` because of default return type + | - expected `()` because of default return type LL | resolve_located_at!(a b) | ^ expected `()`, found `S` | diff --git a/tests/ui/proc-macro/span-preservation.stderr b/tests/ui/proc-macro/span-preservation.stderr index 8c15cb9de982..3ad9c539f847 100644 --- a/tests/ui/proc-macro/span-preservation.stderr +++ b/tests/ui/proc-macro/span-preservation.stderr @@ -38,7 +38,7 @@ error[E0308]: mismatched types --> $DIR/span-preservation.rs:39:5 | LL | extern "C" fn bar() { - | - help: try adding a return type: `-> i32` + | - help: try adding a return type: `-> i32` LL | 0 | ^ expected `()`, found integer @@ -46,7 +46,7 @@ error[E0308]: mismatched types --> $DIR/span-preservation.rs:44:5 | LL | extern "C" fn baz() { - | - help: try adding a return type: `-> i32` + | - help: try adding a return type: `-> i32` LL | 0 | ^ expected `()`, found integer @@ -54,7 +54,7 @@ error[E0308]: mismatched types --> $DIR/span-preservation.rs:49:5 | LL | extern "Rust" fn rust_abi() { - | - help: try adding a return type: `-> i32` + | - help: try adding a return type: `-> i32` LL | 0 | ^ expected `()`, found integer @@ -62,7 +62,7 @@ error[E0308]: mismatched types --> $DIR/span-preservation.rs:54:5 | LL | extern "\x43" fn c_abi_escaped() { - | - help: try adding a return type: `-> i32` + | - help: try adding a return type: `-> i32` LL | 0 | ^ expected `()`, found integer diff --git a/tests/ui/recursion_limit/empty.stderr b/tests/ui/recursion_limit/empty.stderr index cb5c0c35a5eb..2f7306775070 100644 --- a/tests/ui/recursion_limit/empty.stderr +++ b/tests/ui/recursion_limit/empty.stderr @@ -13,6 +13,8 @@ LL | #![recursion_limit = ""] | ^^^^^^^^^^^^^^^^^^^^^--^ | | | `limit` must be a non-negative integer + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/recursion_limit/invalid_digit.stderr b/tests/ui/recursion_limit/invalid_digit.stderr index 4dc93ad5f67b..4fda3039032a 100644 --- a/tests/ui/recursion_limit/invalid_digit.stderr +++ b/tests/ui/recursion_limit/invalid_digit.stderr @@ -13,6 +13,8 @@ LL | #![recursion_limit = "-100"] | ^^^^^^^^^^^^^^^^^^^^^------^ | | | not a valid integer + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/recursion_limit/overflow.stderr b/tests/ui/recursion_limit/overflow.stderr index 2f622d28b45a..6057177deb2f 100644 --- a/tests/ui/recursion_limit/overflow.stderr +++ b/tests/ui/recursion_limit/overflow.stderr @@ -13,6 +13,8 @@ LL | #![recursion_limit = "999999999999999999999999"] | ^^^^^^^^^^^^^^^^^^^^^--------------------------^ | | | `limit` is too large + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/regions/regions-close-object-into-object-4.stderr b/tests/ui/regions/regions-close-object-into-object-4.stderr index 7a9f1ab00012..3ff7f891c661 100644 --- a/tests/ui/regions/regions-close-object-into-object-4.stderr +++ b/tests/ui/regions/regions-close-object-into-object-4.stderr @@ -26,6 +26,7 @@ error[E0310]: the parameter type `U` may not live long enough LL | Box::new(B(&*v)) as Box | ^^^^^^^^^^^^^^^^ ...so that the type `U` will meet its required lifetime bounds | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider adding an explicit lifetime bound... | LL | fn i<'a, T, U: 'static>(v: Box+'a>) -> Box { diff --git a/tests/ui/regions/regions-close-object-into-object-5.stderr b/tests/ui/regions/regions-close-object-into-object-5.stderr index 311e8868c095..88c134832637 100644 --- a/tests/ui/regions/regions-close-object-into-object-5.stderr +++ b/tests/ui/regions/regions-close-object-into-object-5.stderr @@ -26,6 +26,7 @@ error[E0310]: the parameter type `T` may not live long enough LL | Box::new(B(&*v)) as Box | ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider adding an explicit lifetime bound... | LL | fn f<'a, T: 'static, U>(v: Box + 'static>) -> Box { diff --git a/tests/ui/repr/repr-align-assign.stderr b/tests/ui/repr/repr-align-assign.stderr index b878ae0d1733..3606d02210ba 100644 --- a/tests/ui/repr/repr-align-assign.stderr +++ b/tests/ui/repr/repr-align-assign.stderr @@ -15,12 +15,16 @@ error[E0693]: incorrect `repr(align)` attribute format | LL | #[repr(align=8)] | ^^^^^^^ help: use parentheses instead: `align(8)` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0693]: incorrect `repr(align)` attribute format --> $DIR/repr-align-assign.rs:9:8 | LL | #[repr(align="8")] | ^^^^^^^^^ help: use parentheses instead: `align(8)` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors diff --git a/tests/ui/repr/repr-align.stderr b/tests/ui/repr/repr-align.stderr index 900a811bb8ad..84d33a08a6f5 100644 --- a/tests/ui/repr/repr-align.stderr +++ b/tests/ui/repr/repr-align.stderr @@ -39,36 +39,48 @@ error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer | LL | #[repr(align(16.0))] | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0589]: invalid `repr(align)` attribute: not a power of two --> $DIR/repr-align.rs:7:8 | LL | #[repr(align(15))] | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0589]: invalid `repr(align)` attribute: larger than 2^29 --> $DIR/repr-align.rs:11:8 | LL | #[repr(align(4294967296))] | ^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer --> $DIR/repr-align.rs:18:8 | LL | #[repr(align(16.0))] | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0589]: invalid `repr(align)` attribute: not a power of two --> $DIR/repr-align.rs:22:8 | LL | #[repr(align(15))] | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0589]: invalid `repr(align)` attribute: larger than 2^29 --> $DIR/repr-align.rs:26:8 | LL | #[repr(align(4294967296))] | ^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 12 previous errors diff --git a/tests/ui/resolve/associated-fn-called-as-fn.stderr b/tests/ui/resolve/associated-fn-called-as-fn.stderr index fbdea30d551f..7d28b959a1a4 100644 --- a/tests/ui/resolve/associated-fn-called-as-fn.stderr +++ b/tests/ui/resolve/associated-fn-called-as-fn.stderr @@ -2,13 +2,23 @@ error[E0425]: cannot find function `collect_primary` in this scope --> $DIR/associated-fn-called-as-fn.rs:6:30 | LL | '0'..='9' => collect_primary(&c), - | ^^^^^^^^^^^^^^^ help: you might have meant to call the associated function: `Self::collect_primary` + | ^^^^^^^^^^^^^^^ + | +help: you might have meant to call the associated function + | +LL | '0'..='9' => Self::collect_primary(&c), + | ++++++ error[E0425]: cannot find function `collect_primary` in this scope --> $DIR/associated-fn-called-as-fn.rs:23:30 | LL | '0'..='9' => collect_primary(&c), - | ^^^^^^^^^^^^^^^ help: you might have meant to call the associated function: `Self::collect_primary` + | ^^^^^^^^^^^^^^^ + | +help: you might have meant to call the associated function + | +LL | '0'..='9' => Self::collect_primary(&c), + | ++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs index 9e72c36151e5..b5f13959081b 100644 --- a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs +++ b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs @@ -11,5 +11,8 @@ impl Foo { field; //~ ERROR cannot find value `field` in this scope Foo { field } //~ ERROR cannot find value `field` in this scope } + fn clone(&self) -> Foo { + Foo { field } //~ ERROR cannot find value `field` in this scope + } } fn main() {} diff --git a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr index 2eb3861e5f11..3c44c1c249ce 100644 --- a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr +++ b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr @@ -1,21 +1,41 @@ error[E0425]: cannot find value `field` in this scope --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:11:9 | +LL | field: u32, + | ---------- a field by that name exists in `Self` +... LL | fn field(&self) -> u32 { | ----- a method by that name is available on `Self` here ... LL | field; - | ^^^^^ a field by this name exists in `Self` + | ^^^^^ error[E0425]: cannot find value `field` in this scope --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:12:15 | +LL | field: u32, + | ---------- a field by that name exists in `Self` +... LL | fn field(&self) -> u32 { | ----- a method by that name is available on `Self` here ... LL | Foo { field } - | ^^^^^ a field by this name exists in `Self` + | ^^^^^ + +error[E0425]: cannot find value `field` in this scope + --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:15:15 + | +LL | fn field(&self) -> u32 { + | ----- a method by that name is available on `Self` here +... +LL | Foo { field } + | ^^^^^ + | +help: you might have meant to use the available field + | +LL | Foo { field: self.field } + | ++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/resolve/issue-116164.rs b/tests/ui/resolve/issue-116164.rs new file mode 100644 index 000000000000..d30c8f514b3d --- /dev/null +++ b/tests/ui/resolve/issue-116164.rs @@ -0,0 +1,19 @@ +#![allow(unused_imports)] + +mod inner { + pub enum Example { + ExOne, + } +} + +mod reexports { + pub use crate::inner::Example as _; +} + +use crate::reexports::*; +//~^ SUGGESTION: use inner::Example::ExOne + +fn main() { + ExOne; + //~^ ERROR: cannot find value `ExOne` in this scope +} diff --git a/tests/ui/resolve/issue-116164.stderr b/tests/ui/resolve/issue-116164.stderr new file mode 100644 index 000000000000..5820a189fd57 --- /dev/null +++ b/tests/ui/resolve/issue-116164.stderr @@ -0,0 +1,14 @@ +error[E0425]: cannot find value `ExOne` in this scope + --> $DIR/issue-116164.rs:17:5 + | +LL | ExOne; + | ^^^^^ not found in this scope + | +help: consider importing this unit variant + | +LL + use inner::Example::ExOne; + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/resolve/issue-14254.stderr b/tests/ui/resolve/issue-14254.stderr index 690a40f7edd7..9284b4babc50 100644 --- a/tests/ui/resolve/issue-14254.stderr +++ b/tests/ui/resolve/issue-14254.stderr @@ -8,13 +8,23 @@ error[E0425]: cannot find value `x` in this scope --> $DIR/issue-14254.rs:30:9 | LL | x; - | ^ help: you might have meant to use the available field: `self.x` + | ^ + | +help: you might have meant to use the available field + | +LL | self.x; + | +++++ error[E0425]: cannot find value `y` in this scope --> $DIR/issue-14254.rs:32:9 | LL | y; - | ^ help: you might have meant to use the available field: `self.y` + | ^ + | +help: you might have meant to use the available field + | +LL | self.y; + | +++++ error[E0425]: cannot find value `a` in this scope --> $DIR/issue-14254.rs:34:9 @@ -31,7 +41,7 @@ LL | bah; help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find value `b` in this scope --> $DIR/issue-14254.rs:38:9 @@ -43,13 +53,23 @@ error[E0425]: cannot find value `x` in this scope --> $DIR/issue-14254.rs:47:9 | LL | x; - | ^ help: you might have meant to use the available field: `self.x` + | ^ + | +help: you might have meant to use the available field + | +LL | self.x; + | +++++ error[E0425]: cannot find value `y` in this scope --> $DIR/issue-14254.rs:49:9 | LL | y; - | ^ help: you might have meant to use the available field: `self.y` + | ^ + | +help: you might have meant to use the available field + | +LL | self.y; + | +++++ error[E0425]: cannot find value `a` in this scope --> $DIR/issue-14254.rs:51:9 @@ -66,7 +86,7 @@ LL | bah; help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find value `b` in this scope --> $DIR/issue-14254.rs:55:9 @@ -83,7 +103,7 @@ LL | bah; help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find value `bah` in this scope --> $DIR/issue-14254.rs:73:9 @@ -94,7 +114,7 @@ LL | bah; help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find value `bah` in this scope --> $DIR/issue-14254.rs:82:9 @@ -105,7 +125,7 @@ LL | bah; help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find value `bah` in this scope --> $DIR/issue-14254.rs:91:9 @@ -116,7 +136,7 @@ LL | bah; help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find value `bah` in this scope --> $DIR/issue-14254.rs:100:9 @@ -127,55 +147,95 @@ LL | bah; help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:19:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:28:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:45:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:62:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:71:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:80:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:89:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:98:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error: aborting due to 24 previous errors diff --git a/tests/ui/resolve/issue-2356.stderr b/tests/ui/resolve/issue-2356.stderr index 273e8b2a661f..5f75ae988702 100644 --- a/tests/ui/resolve/issue-2356.stderr +++ b/tests/ui/resolve/issue-2356.stderr @@ -1,8 +1,11 @@ error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:39:5 | +LL | whiskers: isize, + | --------------- a field by that name exists in `Self` +... LL | whiskers -= other; - | ^^^^^^^^ a field by this name exists in `Self` + | ^^^^^^^^ error[E0424]: expected value, found module `self` --> $DIR/issue-2356.rs:65:8 @@ -21,13 +24,21 @@ error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:79:5 | LL | whiskers = 0; - | ^^^^^^^^ help: you might have meant to use the available field: `self.whiskers` + | ^^^^^^^^ + | +help: you might have meant to use the available field + | +LL | self.whiskers = 0; + | +++++ error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:84:5 | +LL | whiskers: isize, + | --------------- a field by that name exists in `Self` +... LL | whiskers = 4; - | ^^^^^^^^ a field by this name exists in `Self` + | ^^^^^^^^ error[E0424]: expected value, found module `self` --> $DIR/issue-2356.rs:92:5 @@ -47,19 +58,34 @@ error[E0425]: cannot find function `clone` in this scope --> $DIR/issue-2356.rs:24:5 | LL | clone(); - | ^^^^^ help: you might have meant to call the method: `self.clone` + | ^^^^^ + | +help: you might have meant to call the method + | +LL | self.clone(); + | +++++ error[E0425]: cannot find function `default` in this scope --> $DIR/issue-2356.rs:31:5 | LL | default(); - | ^^^^^^^ help: you might have meant to call the associated function: `Self::default` + | ^^^^^^^ + | +help: you might have meant to call the associated function + | +LL | Self::default(); + | ++++++ error[E0425]: cannot find function `shave` in this scope --> $DIR/issue-2356.rs:41:5 | LL | shave(4); - | ^^^^^ help: you might have meant to call the associated function: `Self::shave` + | ^^^^^ + | +help: you might have meant to call the associated function + | +LL | Self::shave(4); + | ++++++ error[E0425]: cannot find function `purr` in this scope --> $DIR/issue-2356.rs:43:5 diff --git a/tests/ui/resolve/issue-60057.stderr b/tests/ui/resolve/issue-60057.stderr index 4d915fcd9fe3..a2ab86443536 100644 --- a/tests/ui/resolve/issue-60057.stderr +++ b/tests/ui/resolve/issue-60057.stderr @@ -1,14 +1,22 @@ error[E0425]: cannot find value `banana` in this scope --> $DIR/issue-60057.rs:8:21 | +LL | banana: u8, + | ---------- a field by that name exists in `Self` +... LL | banana: banana - | ^^^^^^ a field by this name exists in `Self` + | ^^^^^^ error[E0425]: cannot find value `banana` in this scope --> $DIR/issue-60057.rs:14:21 | LL | banana: banana - | ^^^^^^ help: you might have meant to use the available field: `self.banana` + | ^^^^^^ + | +help: you might have meant to use the available field + | +LL | banana: self.banana + | +++++ error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/resolve-assoc-suggestions.stderr b/tests/ui/resolve/resolve-assoc-suggestions.stderr index 8def9aa20253..3d9d4ffaa10c 100644 --- a/tests/ui/resolve/resolve-assoc-suggestions.stderr +++ b/tests/ui/resolve/resolve-assoc-suggestions.stderr @@ -14,13 +14,23 @@ error[E0425]: cannot find value `field` in this scope --> $DIR/resolve-assoc-suggestions.rs:20:9 | LL | field; - | ^^^^^ help: you might have meant to use the available field: `self.field` + | ^^^^^ + | +help: you might have meant to use the available field + | +LL | self.field; + | +++++ error[E0412]: cannot find type `Type` in this scope --> $DIR/resolve-assoc-suggestions.rs:23:16 | LL | let _: Type; - | ^^^^ help: you might have meant to use the associated type: `Self::Type` + | ^^^^ + | +help: you might have meant to use the associated type + | +LL | let _: Self::Type; + | ++++++ error[E0531]: cannot find tuple struct or tuple variant `Type` in this scope --> $DIR/resolve-assoc-suggestions.rs:25:13 @@ -50,7 +60,12 @@ error[E0425]: cannot find value `method` in this scope --> $DIR/resolve-assoc-suggestions.rs:34:9 | LL | method; - | ^^^^^^ help: you might have meant to refer to the method: `self.method` + | ^^^^^^ + | +help: you might have meant to refer to the method + | +LL | self.method; + | +++++ error: aborting due to 9 previous errors diff --git a/tests/ui/resolve/resolve-inconsistent-names.stderr b/tests/ui/resolve/resolve-inconsistent-names.stderr index 42b7281d7b06..d6240fb8f872 100644 --- a/tests/ui/resolve/resolve-inconsistent-names.stderr +++ b/tests/ui/resolve/resolve-inconsistent-names.stderr @@ -1,11 +1,3 @@ -error[E0408]: variable `a` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:13:12 - | -LL | a | b => {} - | - ^ pattern doesn't bind `a` - | | - | variable not in all patterns - error[E0408]: variable `b` is not bound in all patterns --> $DIR/resolve-inconsistent-names.rs:13:8 | @@ -14,6 +6,14 @@ LL | a | b => {} | | | pattern doesn't bind `b` +error[E0408]: variable `a` is not bound in all patterns + --> $DIR/resolve-inconsistent-names.rs:13:12 + | +LL | a | b => {} + | - ^ pattern doesn't bind `a` + | | + | variable not in all patterns + error[E0408]: variable `c` is not bound in all patterns --> $DIR/resolve-inconsistent-names.rs:19:9 | @@ -54,6 +54,19 @@ LL | (A, B) | (ref B, c) | (c, A) => () | | | first binding +error[E0408]: variable `Const2` is not bound in all patterns + --> $DIR/resolve-inconsistent-names.rs:31:9 + | +LL | (CONST1, _) | (_, Const2) => () + | ^^^^^^^^^^^ ------ variable not in all patterns + | | + | pattern doesn't bind `Const2` + | +help: if you meant to match on constant `m::Const2`, use the full path in the pattern + | +LL | (CONST1, _) | (_, m::Const2) => () + | ~~~~~~~~~ + error[E0408]: variable `CONST1` is not bound in all patterns --> $DIR/resolve-inconsistent-names.rs:31:23 | @@ -68,19 +81,6 @@ note: you might have meant to match on constant `m::CONST1`, which exists but is LL | const CONST1: usize = 10; | ^^^^^^^^^^^^^^^^^^^^^^^^^ not accessible -error[E0408]: variable `Const2` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:31:9 - | -LL | (CONST1, _) | (_, Const2) => () - | ^^^^^^^^^^^ ------ variable not in all patterns - | | - | pattern doesn't bind `Const2` - | -help: if you meant to match on constant `m::Const2`, use the full path in the pattern - | -LL | (CONST1, _) | (_, m::Const2) => () - | ~~~~~~~~~ - error[E0308]: mismatched types --> $DIR/resolve-inconsistent-names.rs:19:19 | diff --git a/tests/ui/resolve/resolve-speculative-adjustment.stderr b/tests/ui/resolve/resolve-speculative-adjustment.stderr index be11a7ebeca0..fb15472bdae8 100644 --- a/tests/ui/resolve/resolve-speculative-adjustment.stderr +++ b/tests/ui/resolve/resolve-speculative-adjustment.stderr @@ -8,13 +8,23 @@ error[E0425]: cannot find value `field` in this scope --> $DIR/resolve-speculative-adjustment.rs:23:9 | LL | field; - | ^^^^^ help: you might have meant to use the available field: `self.field` + | ^^^^^ + | +help: you might have meant to use the available field + | +LL | self.field; + | +++++ error[E0425]: cannot find function `method` in this scope --> $DIR/resolve-speculative-adjustment.rs:25:9 | LL | method(); - | ^^^^^^ help: you might have meant to call the method: `self.method` + | ^^^^^^ + | +help: you might have meant to call the method + | +LL | self.method(); + | +++++ error[E0425]: cannot find function `method` in this scope --> $DIR/resolve-speculative-adjustment.rs:19:13 diff --git a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr index f32e0404e46c..0306c8af87d8 100644 --- a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr +++ b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr @@ -1,20 +1,20 @@ error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:7:16 | +LL | config: String, + | -------------- a field by that name exists in `Self` +... LL | Self { config } - | ^^^^^^ - | | - | a field by this name exists in `Self` - | help: a local variable with a similar name exists: `cofig` + | ^^^^^^ help: a local variable with a similar name exists: `cofig` error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:11:20 | +LL | config: String, + | -------------- a field by that name exists in `Self` +... LL | println!("{config}"); - | ^^^^^^ - | | - | a field by this name exists in `Self` - | help: a local variable with a similar name exists: `cofig` + | ^^^^^^ help: a local variable with a similar name exists: `cofig` error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:15:20 @@ -25,7 +25,7 @@ LL | println!("{config}"); help: you might have meant to use the available field | LL | println!("{self.config}"); - | ~~~~~~~~~~~ + | +++++ help: a local variable with a similar name exists | LL | println!("{cofig}"); @@ -43,7 +43,7 @@ LL | fn ba() {} help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ help: a function with a similar name exists | LL | ba; @@ -61,7 +61,7 @@ LL | const BARR: u32 = 3; help: you might have meant to use the associated `const` | LL | Self::BAR; - | ~~~~~~~~~ + | ++++++ help: a constant with a similar name exists | LL | BARR; @@ -79,7 +79,7 @@ LL | type Bar = String; help: you might have meant to use the associated type | LL | let foo: Self::Baz = "".to_string(); - | ~~~~~~~~~ + | ++++++ help: a type alias with a similar name exists | LL | let foo: Bar = "".to_string(); @@ -97,7 +97,7 @@ LL | fn ba() {} help: you might have meant to call the method | LL | self.baz(); - | ~~~~~~~~ + | +++++ help: a function with a similar name exists | LL | ba(); diff --git a/tests/ui/resolve/unresolved_static_type_field.stderr b/tests/ui/resolve/unresolved_static_type_field.stderr index 06926b53ddd3..035dc9b9656a 100644 --- a/tests/ui/resolve/unresolved_static_type_field.stderr +++ b/tests/ui/resolve/unresolved_static_type_field.stderr @@ -1,8 +1,11 @@ error[E0425]: cannot find value `cx` in this scope --> $DIR/unresolved_static_type_field.rs:9:11 | +LL | cx: bool, + | -------- a field by that name exists in `Self` +... LL | f(cx); - | ^^ a field by this name exists in `Self` + | ^^ error: aborting due to previous error diff --git a/tests/ui/return/return-struct.stderr b/tests/ui/return/return-struct.stderr index e6c0363e3631..282e6498ebe3 100644 --- a/tests/ui/return/return-struct.stderr +++ b/tests/ui/return/return-struct.stderr @@ -17,7 +17,7 @@ error[E0308]: mismatched types --> $DIR/return-struct.rs:15:5 | LL | fn bar() { - | - help: try adding a return type: `-> Age` + | - help: try adding a return type: `-> Age` LL | let mut age = 29; LL | Age::Years(age, 55) | ^^^^^^^^^^^^^^^^^^^ expected `()`, found `Age` @@ -26,7 +26,7 @@ error[E0308]: mismatched types --> $DIR/return-struct.rs:20:5 | LL | fn baz() { - | - help: try adding a return type: `-> S` + | - help: try adding a return type: `-> S` LL | S | ^ expected `()`, found `S` diff --git a/tests/ui/rfcs/rfc-1623-static/rfc1623-2.stderr b/tests/ui/rfcs/rfc-1623-static/rfc1623-2.stderr index d183eaaa6236..5f8c5dbe6193 100644 --- a/tests/ui/rfcs/rfc-1623-static/rfc1623-2.stderr +++ b/tests/ui/rfcs/rfc-1623-static/rfc1623-2.stderr @@ -15,6 +15,7 @@ LL | f: &id, | = note: expected trait `for<'a, 'b> Fn<(&'a Foo<'b>,)>` found trait `Fn<(&Foo<'_>,)>` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: implementation of `FnOnce` is not general enough --> $DIR/rfc1623-2.rs:28:8 diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const-bound-on-not-const-associated-fn.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const-bound-on-not-const-associated-fn.rs new file mode 100644 index 000000000000..1e22ddcea8d3 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const-bound-on-not-const-associated-fn.rs @@ -0,0 +1,28 @@ +#![feature(const_trait_impl, effects)] + +#[const_trait] +trait MyTrait { + fn do_something(&self); +} + +trait OtherTrait { + fn do_something_else() where Self: ~const MyTrait; + //~^ ERROR `~const` is not allowed here +} + +struct MyStruct(T); + +impl const MyTrait for u32 { + fn do_something(&self) {} +} + +impl MyStruct { + pub fn foo(&self) where T: ~const MyTrait { + //~^ ERROR `~const` is not allowed here + self.0.do_something(); + } +} + +fn main() { + MyStruct(0u32).foo(); +} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const-bound-on-not-const-associated-fn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const-bound-on-not-const-associated-fn.stderr new file mode 100644 index 000000000000..9210f6427064 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const-bound-on-not-const-associated-fn.stderr @@ -0,0 +1,26 @@ +error: `~const` is not allowed here + --> $DIR/const-bound-on-not-const-associated-fn.rs:9:40 + | +LL | fn do_something_else() where Self: ~const MyTrait; + | ^^^^^^^^^^^^^^ + | +note: this function is not `const`, so it cannot have `~const` trait bounds + --> $DIR/const-bound-on-not-const-associated-fn.rs:9:8 + | +LL | fn do_something_else() where Self: ~const MyTrait; + | ^^^^^^^^^^^^^^^^^ + +error: `~const` is not allowed here + --> $DIR/const-bound-on-not-const-associated-fn.rs:20:32 + | +LL | pub fn foo(&self) where T: ~const MyTrait { + | ^^^^^^^^^^^^^^ + | +note: this function is not `const`, so it cannot have `~const` trait bounds + --> $DIR/const-bound-on-not-const-associated-fn.rs:20:12 + | +LL | pub fn foo(&self) where T: ~const MyTrait { + | ^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102156.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102156.stderr index 8bf00eaff1fb..e8ae7e4e36ce 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102156.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102156.stderr @@ -13,6 +13,7 @@ LL | use core::convert::{From, TryFrom}; | ^^^^ maybe a missing crate `core`? | = help: consider adding `extern crate core` to use the `core` crate + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr index 97f346e8c1db..b60399c57dca 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr @@ -9,6 +9,8 @@ error: ~const can only be applied to `#[const_trait]` traits | LL | trait Bar: ~const Foo {} | ^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr index 97f346e8c1db..b60399c57dca 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr @@ -9,6 +9,8 @@ error: ~const can only be applied to `#[const_trait]` traits | LL | trait Bar: ~const Foo {} | ^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr index 2897eabb0815..eb12a236d8c3 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr @@ -9,6 +9,8 @@ error: ~const can only be applied to `#[const_trait]` traits | LL | trait Bar: ~const Foo {} | ^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: ~const can only be applied to `#[const_trait]` traits --> $DIR/super-traits-fail-3.rs:17:24 diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr index 9839a4f2480b..cd0ee73277d6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr @@ -9,6 +9,8 @@ error: ~const can only be applied to `#[const_trait]` traits | LL | trait Bar: ~const Foo {} | ^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs index 89d74cecfdb7..4b720b534a49 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs @@ -7,7 +7,8 @@ struct Foo; impl Foo { fn add(self) -> Foo<{ A::add(N) }> { - //~^ ERROR mismatched types + //~^ ERROR `~const` is not allowed here + //~| ERROR mismatched types Foo } } @@ -30,7 +31,7 @@ fn bar(_: Foo) -> Foo<{ A::add(N) }> { } fn main() { - let foo = Foo::<0>; - let foo = bar::<(), _>(foo); - let _foo = bar::<(), _>(foo); + let foo = Foo::<0>; + let foo = bar::<(), _>(foo); + let _foo = bar::<(), _>(foo); } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr index ec5d21d33c6e..be7a83dc1841 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr @@ -1,17 +1,29 @@ error: `~const` is not allowed here - --> $DIR/tilde-const-and-const-params.rs:26:11 + --> $DIR/tilde-const-and-const-params.rs:9:15 + | +LL | fn add(self) -> Foo<{ A::add(N) }> { + | ^^^^^^^^^^^^ + | +note: this function is not `const`, so it cannot have `~const` trait bounds + --> $DIR/tilde-const-and-const-params.rs:9:8 + | +LL | fn add(self) -> Foo<{ A::add(N) }> { + | ^^^ + +error: `~const` is not allowed here + --> $DIR/tilde-const-and-const-params.rs:27:11 | LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { | ^^^^^^^^^^^^ | note: this function is not `const`, so it cannot have `~const` trait bounds - --> $DIR/tilde-const-and-const-params.rs:26:4 + --> $DIR/tilde-const-and-const-params.rs:27:4 | LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { | ^^^ error[E0308]: mismatched types - --> $DIR/tilde-const-and-const-params.rs:26:61 + --> $DIR/tilde-const-and-const-params.rs:27:61 | LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { | ^^^^^^^^^ expected `false`, found `true` @@ -28,6 +40,6 @@ LL | fn add(self) -> Foo<{ A::add(N) }> { = note: expected constant `false` found constant `true` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.rs index 85ca5fc90487..11f353f3f8ad 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.rs @@ -6,7 +6,9 @@ trait Bar {} trait Foo { fn a(); fn b() where Self: ~const Bar; + //~^ ERROR `~const` is not allowed here fn c(); + //~^ ERROR `~const` is not allowed here } fn test1() { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr index 255878e17752..3d6fedbabbf6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr @@ -1,5 +1,29 @@ +error: `~const` is not allowed here + --> $DIR/trait-where-clause.rs:8:24 + | +LL | fn b() where Self: ~const Bar; + | ^^^^^^^^^^ + | +note: this function is not `const`, so it cannot have `~const` trait bounds + --> $DIR/trait-where-clause.rs:8:8 + | +LL | fn b() where Self: ~const Bar; + | ^ + +error: `~const` is not allowed here + --> $DIR/trait-where-clause.rs:10:13 + | +LL | fn c(); + | ^^^^^^^^^^ + | +note: this function is not `const`, so it cannot have `~const` trait bounds + --> $DIR/trait-where-clause.rs:10:8 + | +LL | fn c(); + | ^ + error[E0277]: the trait bound `T: Bar` is not satisfied - --> $DIR/trait-where-clause.rs:14:5 + --> $DIR/trait-where-clause.rs:16:5 | LL | T::b(); | ^ the trait `Bar` is not implemented for `T` @@ -15,13 +39,13 @@ LL | fn test1() { | +++++ error[E0277]: the trait bound `T: Bar` is not satisfied - --> $DIR/trait-where-clause.rs:16:12 + --> $DIR/trait-where-clause.rs:18:12 | 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:13 + --> $DIR/trait-where-clause.rs:10:13 | LL | fn c(); | ^^^^^^^^^^ required by this bound in `Foo::c` @@ -30,6 +54,6 @@ help: consider further restricting this bound LL | fn test1() { | +++++ -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr b/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr index 497ee440dfdb..c0a322edcd64 100644 --- a/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr @@ -20,6 +20,7 @@ LL | let _: ::Bar = (); | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #53130 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-fully-qualified-paths.rs:25:13 diff --git a/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr b/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr index 8769cbb35b0c..041572be8441 100644 --- a/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr @@ -29,6 +29,7 @@ LL | use foo::{bar::{XX, baz::{}}}; | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #53130 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-nested-empty-paths.rs:27:5 @@ -47,6 +48,7 @@ LL | use foo::{bar::{baz::{}, baz1::{}}}; | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #53130 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 5 previous errors diff --git a/tests/ui/rust-2018/edition-lint-nested-paths.stderr b/tests/ui/rust-2018/edition-lint-nested-paths.stderr index 354a6fe32526..4a70bb7e5c87 100644 --- a/tests/ui/rust-2018/edition-lint-nested-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-nested-paths.stderr @@ -20,6 +20,7 @@ LL | use foo::{a, b}; | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #53130 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-nested-paths.rs:23:13 @@ -38,6 +39,7 @@ LL | use foo::{self as x, c}; | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #53130 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors diff --git a/tests/ui/rust-2018/edition-lint-paths.stderr b/tests/ui/rust-2018/edition-lint-paths.stderr index 42652be9401c..fde17338d98a 100644 --- a/tests/ui/rust-2018/edition-lint-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-paths.stderr @@ -38,6 +38,7 @@ LL | use {main, Bar as SomethingElse}; | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #53130 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:25:9 @@ -47,6 +48,7 @@ LL | use {main, Bar as SomethingElse}; | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #53130 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:40:5 diff --git a/tests/ui/rust-2018/uniform-paths/cross-crate.stderr b/tests/ui/rust-2018/uniform-paths/cross-crate.stderr index 45f77a0c9fe6..8682c56d2a5a 100644 --- a/tests/ui/rust-2018/uniform-paths/cross-crate.stderr +++ b/tests/ui/rust-2018/uniform-paths/cross-crate.stderr @@ -33,6 +33,7 @@ note: the tool module imported here | LL | use cross_crate::*; | ^^^^^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 3 previous errors diff --git a/tests/ui/rust-2018/uniform-paths/prelude-fail-2.stderr b/tests/ui/rust-2018/uniform-paths/prelude-fail-2.stderr index 908bb4985861..3dacb7969114 100644 --- a/tests/ui/rust-2018/uniform-paths/prelude-fail-2.stderr +++ b/tests/ui/rust-2018/uniform-paths/prelude-fail-2.stderr @@ -51,6 +51,7 @@ note: the tool module imported here | LL | use rustfmt as imported_rustfmt; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: cannot use a tool module through an import --> $DIR/prelude-fail-2.rs:19:13 @@ -63,6 +64,7 @@ note: the tool module imported here | LL | pub use rustfmt as imported_rustfmt; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 6 previous errors diff --git a/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.aarch64.stderr b/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.aarch64.stderr index 8328178e8d0a..1006c3bc17ef 100644 --- a/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.aarch64.stderr +++ b/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.aarch64.stderr @@ -3,6 +3,8 @@ error: cfi sanitizer is not supported for this target error: `-Zsanitizer=cfi` is incompatible with `-Zsanitizer=kcfi` error: `-Zsanitizer=cfi` is incompatible with `-Zsanitizer=kcfi` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 3 previous errors diff --git a/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.x86_64.stderr b/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.x86_64.stderr index 8328178e8d0a..1006c3bc17ef 100644 --- a/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.x86_64.stderr +++ b/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-saniziter-kcfi.x86_64.stderr @@ -3,6 +3,8 @@ error: cfi sanitizer is not supported for this target error: `-Zsanitizer=cfi` is incompatible with `-Zsanitizer=kcfi` error: `-Zsanitizer=cfi` is incompatible with `-Zsanitizer=kcfi` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 3 previous errors diff --git a/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed b/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed index ccd65ff40913..a400a1672a43 100644 --- a/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed +++ b/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed @@ -8,5 +8,6 @@ impl S { } fn main() { - Pin::new(&mut S).x(); //~ ERROR no method named `x` found + let mut pinned = std::pin::pin!(S); + pinned.as_mut().x(); //~ ERROR no method named `x` found } diff --git a/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr b/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr index f34ce4dce490..5dcb5861120a 100644 --- a/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr +++ b/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr @@ -4,16 +4,14 @@ error[E0599]: no method named `x` found for struct `S` in the current scope LL | struct S; | -------- method `x` not found for this struct ... -LL | fn x(self: Pin<&mut Self>) { - | - the method is available for `Pin<&mut S>` here -... LL | S.x(); | ^ method not found in `S` | -help: consider wrapping the receiver expression with the appropriate type +help: consider pinning the expression + | +LL ~ let mut pinned = std::pin::pin!(S); +LL ~ pinned.as_mut().x(); | -LL | Pin::new(&mut S).x(); - | +++++++++++++ + error: aborting due to previous error diff --git a/tests/ui/self/class-missing-self.stderr b/tests/ui/self/class-missing-self.stderr index 08493b4f9a2d..ca7a896200fc 100644 --- a/tests/ui/self/class-missing-self.stderr +++ b/tests/ui/self/class-missing-self.stderr @@ -2,7 +2,12 @@ error[E0425]: cannot find value `meows` in this scope --> $DIR/class-missing-self.rs:9:7 | LL | meows += 1; - | ^^^^^ help: you might have meant to use the available field: `self.meows` + | ^^^^^ + | +help: you might have meant to use the available field + | +LL | self.meows += 1; + | +++++ error[E0425]: cannot find function `sleep` in this scope --> $DIR/class-missing-self.rs:10:7 diff --git a/tests/ui/simd/intrinsic/generic-elements.rs b/tests/ui/simd/intrinsic/generic-elements.rs index 0ff2203ec722..6ba93e46f75e 100644 --- a/tests/ui/simd/intrinsic/generic-elements.rs +++ b/tests/ui/simd/intrinsic/generic-elements.rs @@ -1,6 +1,7 @@ // build-fail -#![feature(repr_simd, platform_intrinsics, rustc_attrs)] +#![feature(repr_simd, platform_intrinsics, rustc_attrs, adt_const_params)] +#![allow(incomplete_features)] #[repr(simd)] #[derive(Copy, Clone)] @@ -35,6 +36,7 @@ extern "platform-intrinsic" { fn simd_extract(x: T, idx: u32) -> E; fn simd_shuffle(x: T, y: T, idx: I) -> U; + fn simd_shuffle_generic(x: T, y: T) -> U; } fn main() { @@ -71,5 +73,29 @@ fn main() { //~^ ERROR expected return type of length 4, found `i32x8` with length 8 simd_shuffle::<_, _, i32x2>(x, x, IDX8); //~^ ERROR expected return type of length 8, found `i32x2` with length 2 + + const I2: &[u32] = &[0; 2]; + simd_shuffle_generic::(0, 0); + //~^ ERROR expected SIMD input type, found non-SIMD `i32` + const I4: &[u32] = &[0; 4]; + simd_shuffle_generic::(0, 0); + //~^ ERROR expected SIMD input type, found non-SIMD `i32` + const I8: &[u32] = &[0; 8]; + simd_shuffle_generic::(0, 0); + //~^ ERROR expected SIMD input type, found non-SIMD `i32` + + simd_shuffle_generic::<_, f32x2, I2>(x, x); +//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32` + simd_shuffle_generic::<_, f32x4, I4>(x, x); +//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32` + simd_shuffle_generic::<_, f32x8, I8>(x, x); +//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32` + + simd_shuffle_generic::<_, i32x8, I2>(x, x); + //~^ ERROR expected return type of length 2, found `i32x8` with length 8 + simd_shuffle_generic::<_, i32x8, I4>(x, x); + //~^ ERROR expected return type of length 4, found `i32x8` with length 8 + simd_shuffle_generic::<_, i32x2, I8>(x, x); + //~^ ERROR expected return type of length 8, found `i32x2` with length 2 } } diff --git a/tests/ui/simd/intrinsic/generic-elements.stderr b/tests/ui/simd/intrinsic/generic-elements.stderr index 115d9d4b3f3a..26e01344939c 100644 --- a/tests/ui/simd/intrinsic/generic-elements.stderr +++ b/tests/ui/simd/intrinsic/generic-elements.stderr @@ -1,75 +1,129 @@ error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:44:9 + --> $DIR/generic-elements.rs:46:9 | LL | simd_insert(0, 0, 0); | ^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected inserted type `i32` (element of input `i32x4`), found `f64` - --> $DIR/generic-elements.rs:46:9 + --> $DIR/generic-elements.rs:48:9 | LL | simd_insert(x, 0, 1.0); | ^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_extract` intrinsic: expected return type `i32` (element of input `i32x4`), found `f32` - --> $DIR/generic-elements.rs:48:9 + --> $DIR/generic-elements.rs:50:9 | LL | simd_extract::<_, f32>(x, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:52:9 + --> $DIR/generic-elements.rs:54:9 | LL | simd_shuffle::(0, 0, IDX2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:55:9 + --> $DIR/generic-elements.rs:57:9 | LL | simd_shuffle::(0, 0, IDX4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:58:9 + --> $DIR/generic-elements.rs:60:9 | LL | simd_shuffle::(0, 0, IDX8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32` - --> $DIR/generic-elements.rs:61:9 + --> $DIR/generic-elements.rs:63:9 | LL | simd_shuffle::<_, _, f32x2>(x, x, IDX2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32` - --> $DIR/generic-elements.rs:63:9 + --> $DIR/generic-elements.rs:65:9 | LL | simd_shuffle::<_, _, f32x4>(x, x, IDX4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32` - --> $DIR/generic-elements.rs:65:9 + --> $DIR/generic-elements.rs:67:9 | LL | simd_shuffle::<_, _, f32x8>(x, x, IDX8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `i32x8` with length 8 - --> $DIR/generic-elements.rs:68:9 + --> $DIR/generic-elements.rs:70:9 | LL | simd_shuffle::<_, _, i32x8>(x, x, IDX2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 4, found `i32x8` with length 8 - --> $DIR/generic-elements.rs:70:9 + --> $DIR/generic-elements.rs:72:9 | LL | simd_shuffle::<_, _, i32x8>(x, x, IDX4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 8, found `i32x2` with length 2 - --> $DIR/generic-elements.rs:72:9 + --> $DIR/generic-elements.rs:74:9 | LL | simd_shuffle::<_, _, i32x2>(x, x, IDX8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 12 previous errors +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` + --> $DIR/generic-elements.rs:78:9 + | +LL | simd_shuffle_generic::(0, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` + --> $DIR/generic-elements.rs:81:9 + | +LL | simd_shuffle_generic::(0, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` + --> $DIR/generic-elements.rs:84:9 + | +LL | simd_shuffle_generic::(0, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32` + --> $DIR/generic-elements.rs:87:9 + | +LL | simd_shuffle_generic::<_, f32x2, I2>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32` + --> $DIR/generic-elements.rs:89:9 + | +LL | simd_shuffle_generic::<_, f32x4, I4>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32` + --> $DIR/generic-elements.rs:91:9 + | +LL | simd_shuffle_generic::<_, f32x8, I8>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 2, found `i32x8` with length 8 + --> $DIR/generic-elements.rs:94:9 + | +LL | simd_shuffle_generic::<_, i32x8, I2>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 4, found `i32x8` with length 8 + --> $DIR/generic-elements.rs:96:9 + | +LL | simd_shuffle_generic::<_, i32x8, I4>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 8, found `i32x2` with length 2 + --> $DIR/generic-elements.rs:98:9 + | +LL | simd_shuffle_generic::<_, i32x2, I8>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 21 previous errors For more information about this error, try `rustc --explain E0511`. diff --git a/tests/ui/simd/monomorphize-shuffle-index.generic.stderr b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr new file mode 100644 index 000000000000..fc66b195674c --- /dev/null +++ b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr @@ -0,0 +1,12 @@ +error: overly complex generic constant + --> $DIR/monomorphize-shuffle-index.rs:29:45 + | +LL | return simd_shuffle_generic::<_, _, { &Self::I }>(a, b); + | ^^--------^^ + | | + | pointer casts are not allowed in generic constants + | + = help: consider moving this anonymous constant into a `const` function + +error: aborting due to previous error + diff --git a/tests/ui/simd/monomorphize-shuffle-index.rs b/tests/ui/simd/monomorphize-shuffle-index.rs index 2467baa08b0a..db7953f06dd4 100644 --- a/tests/ui/simd/monomorphize-shuffle-index.rs +++ b/tests/ui/simd/monomorphize-shuffle-index.rs @@ -1,8 +1,14 @@ -//run-pass -#![feature(repr_simd, platform_intrinsics)] +//[old]run-pass +//[generic_with_fn]run-pass +// revisions: old generic generic_with_fn +#![feature(repr_simd, platform_intrinsics, adt_const_params, generic_const_exprs)] +#![allow(incomplete_features)] extern "platform-intrinsic" { + #[cfg(old)] fn simd_shuffle(a: T, b: T, i: I) -> U; + #[cfg(any(generic, generic_with_fn))] + fn simd_shuffle_generic(a: T, b: T) -> U; } #[derive(Copy, Clone)] @@ -11,12 +17,24 @@ struct Simd([T; N]); trait Shuffle { const I: [u32; N]; - - unsafe fn shuffle(&self, a: Simd, b: Simd) -> Simd { - simd_shuffle(a, b, Self::I) + const J: &'static [u32] = &Self::I; + + unsafe fn shuffle(&self, a: Simd, b: Simd) -> Simd + where + Thing<{ Self::J }>:, + { + #[cfg(old)] + return simd_shuffle(a, b, Self::I); + #[cfg(generic)] + return simd_shuffle_generic::<_, _, { &Self::I }>(a, b); + //[generic]~^ overly complex generic constant + #[cfg(generic_with_fn)] + return simd_shuffle_generic::<_, _, { Self::J }>(a, b); } } +struct Thing; + fn main() { struct I1; impl Shuffle<4> for I1 { diff --git a/tests/ui/span/issue-39698.stderr b/tests/ui/span/issue-39698.stderr index 81211b20a013..500080832111 100644 --- a/tests/ui/span/issue-39698.stderr +++ b/tests/ui/span/issue-39698.stderr @@ -1,3 +1,13 @@ +error[E0408]: variable `b` is not bound in all patterns + --> $DIR/issue-39698.rs:10:9 + | +LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } + | ^^^^^^^^^^^ - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `b` + | | | | + | | | pattern doesn't bind `b` + | | variable not in all patterns + | pattern doesn't bind `b` + error[E0408]: variable `c` is not bound in all patterns --> $DIR/issue-39698.rs:10:9 | @@ -8,16 +18,6 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?} | | pattern doesn't bind `c` | pattern doesn't bind `c` -error[E0408]: variable `d` is not bound in all patterns - --> $DIR/issue-39698.rs:10:37 - | -LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } - | - - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d` - | | | | - | | | pattern doesn't bind `d` - | | variable not in all patterns - | variable not in all patterns - error[E0408]: variable `a` is not bound in all patterns --> $DIR/issue-39698.rs:10:23 | @@ -28,15 +28,15 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?} | | pattern doesn't bind `a` | variable not in all patterns -error[E0408]: variable `b` is not bound in all patterns - --> $DIR/issue-39698.rs:10:9 +error[E0408]: variable `d` is not bound in all patterns + --> $DIR/issue-39698.rs:10:37 | LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } - | ^^^^^^^^^^^ - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `b` - | | | | - | | | pattern doesn't bind `b` - | | variable not in all patterns - | pattern doesn't bind `b` + | - - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d` + | | | | + | | | pattern doesn't bind `d` + | | variable not in all patterns + | variable not in all patterns error: aborting due to 4 previous errors diff --git a/tests/ui/str/str-idx.stderr b/tests/ui/str/str-idx.stderr index cb1a6fcacfc9..e8bbb8058faf 100644 --- a/tests/ui/str/str-idx.stderr +++ b/tests/ui/str/str-idx.stderr @@ -7,7 +7,8 @@ LL | let _: u8 = s[4]; = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: for that trait implementation, expected `[_]`, found `str` = note: required for `str` to implement `Index<{integer}>` error[E0277]: the type `str` cannot be indexed by `{integer}` @@ -21,7 +22,8 @@ LL | let _ = s.get(4); = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: for that trait implementation, expected `[_]`, found `str` note: required by a bound in `core::str::::get` --> $SRC_DIR/core/src/str/mod.rs:LL:COL @@ -36,7 +38,8 @@ LL | let _ = s.get_unchecked(4); = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: for that trait implementation, expected `[_]`, found `str` note: required by a bound in `core::str::::get_unchecked` --> $SRC_DIR/core/src/str/mod.rs:LL:COL diff --git a/tests/ui/str/str-mut-idx.stderr b/tests/ui/str/str-mut-idx.stderr index ca4b86ba3065..e6835bb54fb3 100644 --- a/tests/ui/str/str-mut-idx.stderr +++ b/tests/ui/str/str-mut-idx.stderr @@ -31,7 +31,8 @@ LL | s[1usize] = bot(); | ^^^^^^ string indices are ranges of `usize` | = help: the trait `SliceIndex` is not implemented for `usize` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: for that trait implementation, expected `[_]`, found `str` = note: required for `str` to implement `Index` error[E0277]: the type `str` cannot be indexed by `{integer}` @@ -45,7 +46,8 @@ LL | s.get_mut(1); = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: for that trait implementation, expected `[_]`, found `str` note: required by a bound in `core::str::::get_mut` --> $SRC_DIR/core/src/str/mod.rs:LL:COL @@ -60,7 +62,8 @@ LL | s.get_unchecked_mut(1); = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: for that trait implementation, expected `[_]`, found `str` note: required by a bound in `core::str::::get_unchecked_mut` --> $SRC_DIR/core/src/str/mod.rs:LL:COL diff --git a/tests/ui/suggestions/assoc-type-in-method-return.stderr b/tests/ui/suggestions/assoc-type-in-method-return.stderr index 202e4a16eada..df3828ad411e 100644 --- a/tests/ui/suggestions/assoc-type-in-method-return.stderr +++ b/tests/ui/suggestions/assoc-type-in-method-return.stderr @@ -2,7 +2,12 @@ error[E0412]: cannot find type `Bla` in this scope --> $DIR/assoc-type-in-method-return.rs:3:25 | LL | fn to_bla(&self) -> Bla; - | ^^^ help: you might have meant to use the associated type: `Self::Bla` + | ^^^ + | +help: you might have meant to use the associated type + | +LL | fn to_bla(&self) -> Self::Bla; + | ++++++ error: aborting due to previous error diff --git a/tests/ui/suggestions/auxiliary/extern-issue-98562.rs b/tests/ui/suggestions/auxiliary/extern-issue-98562.rs new file mode 100644 index 000000000000..948e40549c6d --- /dev/null +++ b/tests/ui/suggestions/auxiliary/extern-issue-98562.rs @@ -0,0 +1,26 @@ +pub trait TraitE { + type I3; +} + +pub trait TraitD { + type I3; +} + +pub trait TraitC { + type I1; + type I2; +} + +pub trait TraitB { + type Item; +} + +pub trait TraitA { + fn baz< + U: TraitC + TraitD + TraitE, + V: TraitD + >(_: U, _: V) -> Self + where + U: TraitB, + ::Item: Copy; +} diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime.stderr index b476d61017f1..2c29cfa0b910 100644 --- a/tests/ui/suggestions/impl-trait-missing-lifetime.stderr +++ b/tests/ui/suggestions/impl-trait-missing-lifetime.stderr @@ -26,9 +26,9 @@ error: lifetime may not live long enough --> $DIR/impl-trait-missing-lifetime.rs:16:69 | LL | async fn i(mut x: impl Iterator) -> Option<&'_ ()> { x.next() } - | -------------- ^^^^^^^^ returning this value requires that `'1` must outlive `'static` - | | - | return type `impl Future>` contains a lifetime `'1` + | ----------------------------------------------------------------- ^^^^^^^^ returning this value requires that `'1` must outlive `'static` + | | + | return type `impl Future>` contains a lifetime `'1` error: aborting due to 3 previous errors diff --git a/tests/ui/suggestions/issue-101623.stderr b/tests/ui/suggestions/issue-101623.stderr index 361483cc08db..9f00de17484f 100644 --- a/tests/ui/suggestions/issue-101623.stderr +++ b/tests/ui/suggestions/issue-101623.stderr @@ -7,7 +7,8 @@ LL | Trait::do_stuff({ fun(&mut *inner) }); | | the trait `Trait<'_>` is not implemented for `*mut ()` | required by a bound introduced by this call | - = help: the trait `Trait<'a>` is implemented for `()` + = help: the trait `Trait<'_>` is implemented for `()` + = help: for that trait implementation, expected `()`, found `*mut ()` error: aborting due to previous error diff --git a/tests/ui/suggestions/issue-61963.stderr b/tests/ui/suggestions/issue-61963.stderr index b99b1b0b9b3b..ec62153b0a76 100644 --- a/tests/ui/suggestions/issue-61963.stderr +++ b/tests/ui/suggestions/issue-61963.stderr @@ -37,6 +37,7 @@ LL | bar: Box, | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | bar: Box, @@ -50,6 +51,7 @@ LL | bar: Box, | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | bar: Box, @@ -63,6 +65,7 @@ LL | pub struct Foo { | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | dyn pub struct Foo { @@ -76,6 +79,7 @@ LL | pub struct Foo { | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | dyn pub struct Foo { @@ -89,6 +93,7 @@ LL | pub struct Foo { | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: use `dyn` | LL | dyn pub struct Foo { diff --git a/tests/ui/suggestions/issue-83892.stderr b/tests/ui/suggestions/issue-83892.stderr index baf6b1447e69..5e471819b27b 100644 --- a/tests/ui/suggestions/issue-83892.stderr +++ b/tests/ui/suggestions/issue-83892.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-83892.rs:9:15 | LL | fn main() { - | - expected `()` because of default return type + | - expected `()` because of default return type LL | match () { LL | () => func() | ^^^^^^ expected `()`, found `u8` diff --git a/tests/ui/suggestions/issue-98562.rs b/tests/ui/suggestions/issue-98562.rs new file mode 100644 index 000000000000..de04050d5931 --- /dev/null +++ b/tests/ui/suggestions/issue-98562.rs @@ -0,0 +1,12 @@ +// aux-build:extern-issue-98562.rs + +extern crate extern_issue_98562; +use extern_issue_98562::TraitA; + +struct X; +impl TraitA for X { + //~^ ERROR not all trait items implemented +} +//~^ HELP implement the missing item: `fn baz + TraitD, V: TraitD>(_: U, _: V) -> Self where U: TraitE, U: TraitB, ::Item: Copy { todo!() }` + +fn main() {} diff --git a/tests/ui/suggestions/issue-98562.stderr b/tests/ui/suggestions/issue-98562.stderr new file mode 100644 index 000000000000..7897fa441a24 --- /dev/null +++ b/tests/ui/suggestions/issue-98562.stderr @@ -0,0 +1,11 @@ +error[E0046]: not all trait items implemented, missing: `baz` + --> $DIR/issue-98562.rs:7:1 + | +LL | impl TraitA for X { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `baz` in implementation + | + = help: implement the missing item: `fn baz + TraitD, V: TraitD>(_: U, _: V) -> Self where U: TraitE, U: TraitB, ::Item: Copy { todo!() }` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/suggestions/missing-assoc-fn.stderr b/tests/ui/suggestions/missing-assoc-fn.stderr index 77fa95628781..84cb6e98553e 100644 --- a/tests/ui/suggestions/missing-assoc-fn.stderr +++ b/tests/ui/suggestions/missing-assoc-fn.stderr @@ -28,7 +28,7 @@ error[E0046]: not all trait items implemented, missing: `from_iter` LL | impl FromIterator<()> for X { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_iter` in implementation | - = help: implement the missing item: `fn from_iter(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = () { todo!() }` + = help: implement the missing item: `fn from_iter>(_: T) -> Self { todo!() }` error: aborting due to 3 previous errors diff --git a/tests/ui/suggestions/missing-lifetime-specifier.stderr b/tests/ui/suggestions/missing-lifetime-specifier.stderr index 21d2378382cb..fa4bc2fa79d7 100644 --- a/tests/ui/suggestions/missing-lifetime-specifier.stderr +++ b/tests/ui/suggestions/missing-lifetime-specifier.stderr @@ -164,6 +164,7 @@ note: union defined here, with 2 lifetime parameters: `'t`, `'k` | LL | pub union Qux<'t, 'k, I> { | ^^^ -- -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | static e: RefCell>>>> = RefCell::new(HashMap::new()); @@ -182,6 +183,7 @@ note: union defined here, with 2 lifetime parameters: `'t`, `'k` | LL | pub union Qux<'t, 'k, I> { | ^^^ -- -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | static e: RefCell>>>> = RefCell::new(HashMap::new()); @@ -200,6 +202,7 @@ note: union defined here, with 2 lifetime parameters: `'t`, `'k` | LL | pub union Qux<'t, 'k, I> { | ^^^ -- -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | static e: RefCell>>>> = RefCell::new(HashMap::new()); @@ -218,6 +221,7 @@ note: union defined here, with 2 lifetime parameters: `'t`, `'k` | LL | pub union Qux<'t, 'k, I> { | ^^^ -- -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | static e: RefCell>>>> = RefCell::new(HashMap::new()); @@ -254,6 +258,7 @@ note: trait defined here, with 2 lifetime parameters: `'t`, `'k` | LL | trait Tar<'t, 'k, I> {} | ^^^ -- -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | static f: RefCell>>>> = RefCell::new(HashMap::new()); @@ -272,6 +277,7 @@ note: trait defined here, with 2 lifetime parameters: `'t`, `'k` | LL | trait Tar<'t, 'k, I> {} | ^^^ -- -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | static f: RefCell>>>> = RefCell::new(HashMap::new()); @@ -290,6 +296,7 @@ note: trait defined here, with 2 lifetime parameters: `'t`, `'k` | LL | trait Tar<'t, 'k, I> {} | ^^^ -- -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | static f: RefCell>>>> = RefCell::new(HashMap::new()); @@ -308,6 +315,7 @@ note: trait defined here, with 2 lifetime parameters: `'t`, `'k` | LL | trait Tar<'t, 'k, I> {} | ^^^ -- -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | static f: RefCell>>>> = RefCell::new(HashMap::new()); diff --git a/tests/ui/suggestions/return-closures.stderr b/tests/ui/suggestions/return-closures.stderr index f0810bbb2541..97c13200ac36 100644 --- a/tests/ui/suggestions/return-closures.stderr +++ b/tests/ui/suggestions/return-closures.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/return-closures.rs:3:5 | LL | fn foo() { - | - help: try adding a return type: `-> impl for<'a> Fn(&'a i32) -> i32` + | - help: try adding a return type: `-> impl for<'a> Fn(&'a i32) -> i32` LL | LL | |x: &i32| 1i32 | ^^^^^^^^^^^^^^ expected `()`, found closure @@ -14,7 +14,7 @@ error[E0308]: mismatched types --> $DIR/return-closures.rs:9:5 | LL | fn bar(i: impl Sized) { - | - help: a return type might be missing here: `-> _` + | - help: a return type might be missing here: `-> _` LL | LL | || i | ^^^^ expected `()`, found closure diff --git a/tests/ui/suggestions/suggest-dereferencing-index.stderr b/tests/ui/suggestions/suggest-dereferencing-index.stderr index 147dc9234c59..adf01339972e 100644 --- a/tests/ui/suggestions/suggest-dereferencing-index.stderr +++ b/tests/ui/suggestions/suggest-dereferencing-index.stderr @@ -5,7 +5,8 @@ LL | let one_item_please: i32 = [1, 2, 3][i]; | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `&usize` = note: required for `[{integer}]` to implement `Index<&usize>` help: dereference this index | diff --git a/tests/ui/suggestions/suggest-ret-on-async-w-late.fixed b/tests/ui/suggestions/suggest-ret-on-async-w-late.fixed new file mode 100644 index 000000000000..0a08383317f7 --- /dev/null +++ b/tests/ui/suggestions/suggest-ret-on-async-w-late.fixed @@ -0,0 +1,14 @@ +// edition: 2021 +// run-rustfix + +#![allow(unused)] + +// Make sure we don't ICE when suggesting a return type +// for an async fn that has late-bound vars... + +async fn ice(_: &i32) -> bool { + true + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/suggestions/suggest-ret-on-async-w-late.rs b/tests/ui/suggestions/suggest-ret-on-async-w-late.rs index 459b94f943b5..5c8f185bd4b0 100644 --- a/tests/ui/suggestions/suggest-ret-on-async-w-late.rs +++ b/tests/ui/suggestions/suggest-ret-on-async-w-late.rs @@ -1,4 +1,7 @@ // edition: 2021 +// run-rustfix + +#![allow(unused)] // Make sure we don't ICE when suggesting a return type // for an async fn that has late-bound vars... diff --git a/tests/ui/suggestions/suggest-ret-on-async-w-late.stderr b/tests/ui/suggestions/suggest-ret-on-async-w-late.stderr index bff864b222bf..352f6da3607b 100644 --- a/tests/ui/suggestions/suggest-ret-on-async-w-late.stderr +++ b/tests/ui/suggestions/suggest-ret-on-async-w-late.stderr @@ -1,8 +1,8 @@ error[E0308]: mismatched types - --> $DIR/suggest-ret-on-async-w-late.rs:7:5 + --> $DIR/suggest-ret-on-async-w-late.rs:10:5 | LL | async fn ice(_: &i32) { - | - help: try adding a return type: `-> bool` + | - help: try adding a return type: `-> bool` LL | true | ^^^^ expected `()`, found `bool` diff --git a/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr b/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr index 71fd5f1d44a8..2045dc6a36e1 100644 --- a/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr +++ b/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr @@ -9,6 +9,8 @@ error: cannot find derive macro `rustfmt` in this scope | LL | #[derive(rustfmt)] | ^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: cannot find attribute `rustfmt` in this scope --> $DIR/tool-attributes-misplaced-1.rs:9:3 diff --git a/tests/ui/tool_lints.stderr b/tests/ui/tool_lints.stderr index d36cd193b15c..f1d825caba15 100644 --- a/tests/ui/tool_lints.stderr +++ b/tests/ui/tool_lints.stderr @@ -13,6 +13,7 @@ LL | #[warn(foo::bar)] | ^^^ | = help: add `#![register_tool(foo)]` to the crate root + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/associated_type_bound/impl-is-shadowed.rs b/tests/ui/traits/associated_type_bound/impl-is-shadowed.rs new file mode 100644 index 000000000000..6c3125a9fc5f --- /dev/null +++ b/tests/ui/traits/associated_type_bound/impl-is-shadowed.rs @@ -0,0 +1,21 @@ +// check-pass +trait Bar<'a> { + type Assoc: 'static; +} + +impl<'a> Bar<'a> for () { + type Assoc = (); +} + +struct ImplsStatic> { + d: &'static >::Assoc, +} + +fn caller(b: ImplsStatic<()>) +where + for<'a> (): Bar<'a> +{ + let _: &<() as Bar<'static>>::Assoc = b.d; +} + +fn main() {} diff --git a/tests/ui/traits/coercion-generic-bad.stderr b/tests/ui/traits/coercion-generic-bad.stderr index e7e8a796796b..30a3c40db95b 100644 --- a/tests/ui/traits/coercion-generic-bad.stderr +++ b/tests/ui/traits/coercion-generic-bad.stderr @@ -5,6 +5,7 @@ LL | let s: Box> = Box::new(Struct { person: "Fred" }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `Struct` | = help: the trait `Trait<&'static str>` is implemented for `Struct` + = help: for that trait implementation, expected `&'static str`, found `isize` = note: required for the cast from `Box` to `Box>` error: aborting due to previous error diff --git a/tests/ui/traits/issue-38404.stderr b/tests/ui/traits/issue-38404.stderr index f8625f53b78f..a5c258eb36e9 100644 --- a/tests/ui/traits/issue-38404.stderr +++ b/tests/ui/traits/issue-38404.stderr @@ -25,6 +25,7 @@ LL | trait A: std::ops::Add + Sized {} | ^^^^^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter LL | trait B: A {} | - this trait cannot be made into an object... + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/issue-59029-1.stderr b/tests/ui/traits/issue-59029-1.stderr index 203a89285306..51354bcc5454 100644 --- a/tests/ui/traits/issue-59029-1.stderr +++ b/tests/ui/traits/issue-59029-1.stderr @@ -9,6 +9,8 @@ error[E0220]: associated type `Res` not found for `Self` | LL | trait MkSvc = Svc where Self::Res: Svc; | ^^^ there is a similarly named associated type `Res` in the trait `Svc` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/non_lifetime_binders/on-rpit.rs b/tests/ui/traits/non_lifetime_binders/on-rpit.rs new file mode 100644 index 000000000000..c501e057e283 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/on-rpit.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(non_lifetime_binders)] +//~^ WARN the feature `non_lifetime_binders` is incomplete + +trait Trait {} + +impl Trait for i32 {} + +fn produce() -> impl for Trait { + 16 +} + +fn main() { + let _ = produce(); +} diff --git a/tests/ui/traits/non_lifetime_binders/on-rpit.stderr b/tests/ui/traits/non_lifetime_binders/on-rpit.stderr new file mode 100644 index 000000000000..34c56068c5cc --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/on-rpit.stderr @@ -0,0 +1,11 @@ +warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/on-rpit.rs:3:12 + | +LL | #![feature(non_lifetime_binders)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #108185 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/try-block/try-block-bad-type.stderr b/tests/ui/try-block/try-block-bad-type.stderr index e11c3f810035..b41bf86d3d91 100644 --- a/tests/ui/try-block/try-block-bad-type.stderr +++ b/tests/ui/try-block/try-block-bad-type.stderr @@ -6,6 +6,7 @@ LL | Err("")?; | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = help: the trait `From` is implemented for `TryFromSliceError` + = help: for that trait implementation, expected `Infallible`, found `&str` = note: required for `Result` to implement `FromResidual>` error[E0271]: type mismatch resolving ` as Try>::Output == &str` diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index 7eb392faa66b..d8b9431becc6 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr @@ -73,7 +73,8 @@ LL | ControlFlow::Continue(Err("hello")?) | ^ this `?` produces `Result`, which is incompatible with `ControlFlow` | = help: the trait `FromResidual>` is not implemented for `ControlFlow` - = help: the trait `FromResidual` is implemented for `ControlFlow` + = help: the trait `FromResidual>` is implemented for `ControlFlow` + = help: for that trait implementation, expected `ControlFlow`, found `Result` error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow` --> $DIR/bad-interconversion.rs:37:12 @@ -84,7 +85,8 @@ LL | Some(3)?; | ^ this `?` produces `Option`, which is incompatible with `ControlFlow` | = help: the trait `FromResidual>` is not implemented for `ControlFlow` - = help: the trait `FromResidual` is implemented for `ControlFlow` + = help: the trait `FromResidual>` is implemented for `ControlFlow` + = help: for that trait implementation, expected `ControlFlow`, found `Option` error[E0277]: the `?` operator in a function that returns `ControlFlow` can only be used on other `ControlFlow`s (with the same Break type) --> $DIR/bad-interconversion.rs:43:29 @@ -96,7 +98,8 @@ LL | ControlFlow::Break(4_u8)?; | = help: the trait `FromResidual>` is not implemented for `ControlFlow` = note: unlike `Result`, there's no `From`-conversion performed for `ControlFlow` - = help: the trait `FromResidual` is implemented for `ControlFlow` + = help: the trait `FromResidual>` is implemented for `ControlFlow` + = help: for that trait implementation, expected `i64`, found `u8` error: aborting due to 8 previous errors diff --git a/tests/ui/tuple/tuple-struct-fields/test2.stderr b/tests/ui/tuple/tuple-struct-fields/test2.stderr index 64a9ac13566f..784411aba8f8 100644 --- a/tests/ui/tuple/tuple-struct-fields/test2.stderr +++ b/tests/ui/tuple/tuple-struct-fields/test2.stderr @@ -22,6 +22,8 @@ error[E0412]: cannot find type `foo` in this scope | LL | define_struct! { (foo) } | ^^^ not found in this scope + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 3 previous errors diff --git a/tests/ui/tuple/tuple-struct-fields/test3.stderr b/tests/ui/tuple/tuple-struct-fields/test3.stderr index 75262ed5780e..00b07c031529 100644 --- a/tests/ui/tuple/tuple-struct-fields/test3.stderr +++ b/tests/ui/tuple/tuple-struct-fields/test3.stderr @@ -22,6 +22,8 @@ error[E0412]: cannot find type `foo` in this scope | LL | define_struct! { foo } | ^^^ not found in this scope + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 3 previous errors diff --git a/tests/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr b/tests/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr index 0202a2fea496..359bd09ecd02 100644 --- a/tests/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr +++ b/tests/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr @@ -36,6 +36,7 @@ note: `V` could also refer to the associated type defined here | LL | type V; | ^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs index 9a50c0f988a5..31fea42fa5d8 100644 --- a/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs +++ b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs @@ -1,5 +1,5 @@ // compile-flags: --edition=2021 -// check-pass +// build-pass #![feature(type_alias_impl_trait)] fn main() { diff --git a/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs b/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs new file mode 100644 index 000000000000..7c2d68cceb8f --- /dev/null +++ b/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs @@ -0,0 +1,19 @@ +// build-pass +// edition: 2021 + +#![feature(type_alias_impl_trait)] + +pub struct Foo { + /// This type must have nontrivial drop glue + field: String, +} + +pub type Tait = impl Sized; + +pub async fn ice_cold(beverage: Tait) { + // Must destructure at least one field of `Foo` + let Foo { field } = beverage; + _ = field; +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/destructure_tait-layout_of-ice-113594.rs b/tests/ui/type-alias-impl-trait/destructure_tait-layout_of-ice-113594.rs new file mode 100644 index 000000000000..8568b26bea2a --- /dev/null +++ b/tests/ui/type-alias-impl-trait/destructure_tait-layout_of-ice-113594.rs @@ -0,0 +1,23 @@ +// build-pass +// edition: 2021 + +#![feature(type_alias_impl_trait)] + +fn foo(x: T) { + type Opaque = impl Sized; + let foo: Opaque = (x,); + let (a,): (T,) = foo; +} + +const fn bar(x: T) { + type Opaque = impl Copy; + let foo: Opaque = (x, 2u32); + let (a, b): (T, u32) = foo; +} + +fn main() { + foo::(1); + bar::(1); + const CONST: () = bar::(42u32); + CONST +} diff --git a/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr b/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr index 3312230bc81d..2063becdb083 100644 --- a/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr +++ b/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr @@ -1,6 +1,5 @@ error[E0391]: cycle detected when computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}` | - = note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit`... = note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit<{async fn body@$DIR/indirect-recursion-issue-112047.rs:15:31: 17:2}>`... = note: ...which requires computing layout of `core::mem::manually_drop::ManuallyDrop<{async fn body@$DIR/indirect-recursion-issue-112047.rs:15:31: 17:2}>`... = note: ...which requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:15:31: 17:2}`... @@ -8,7 +7,11 @@ error[E0391]: cycle detected when computing layout of `{async block@$DIR/indirec = note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit<{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}>`... = note: ...which requires computing layout of `core::mem::manually_drop::ManuallyDrop<{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}>`... = note: ...which again requires computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}`, completing the cycle - = note: cycle used when computing layout of `::Recur` +note: cycle used when elaborating drops for `::recur` + --> $DIR/indirect-recursion-issue-112047.rs:22:5 + | +LL | fn recur(self) -> Self::Recur { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/type-alias-impl-trait/normalize-alias-type.rs b/tests/ui/type-alias-impl-trait/normalize-alias-type.rs new file mode 100644 index 000000000000..7c62002b931b --- /dev/null +++ b/tests/ui/type-alias-impl-trait/normalize-alias-type.rs @@ -0,0 +1,32 @@ +// check-pass +// compile-flags: -Z mir-opt-level=3 +#![feature(type_alias_impl_trait)] +#![crate_type = "lib"] +pub trait Tr { + fn get(&self) -> u32; +} + +impl Tr for (u32,) { + #[inline] + fn get(&self) -> u32 { self.0 } +} + +pub fn tr1() -> impl Tr { + (32,) +} + +pub fn tr2() -> impl Tr { + struct Inner { + x: X, + } + type X = impl Tr; + impl Tr for Inner { + fn get(&self) -> u32 { + self.x.get() + } + } + + Inner { + x: tr1(), + } +} diff --git a/tests/ui/type-alias-impl-trait/tait-normalize.rs b/tests/ui/type-alias-impl-trait/tait-normalize.rs new file mode 100644 index 000000000000..26d94dbb42a3 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/tait-normalize.rs @@ -0,0 +1,14 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +fn enum_upvar() { + type T = impl Copy; + let foo: T = Some((1u32, 2u32)); + let x = move || match foo { + None => (), + Some((a, b)) => (), + }; +} + +fn main(){} diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs index 857066c78c90..9796823a7244 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs @@ -4,7 +4,7 @@ // FIXME: this is ruled out for now but should work type Foo = fn() -> impl Send; -//~^ ERROR: `impl Trait` only allowed in function and inherent method return types +//~^ ERROR: `impl Trait` only allowed in function and inherent method argument and return types fn make_foo() -> Foo { || 15 diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr index ff375b2ff863..e57c59d61657 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `fn` pointer return types --> $DIR/type-alias-impl-trait-fn-type.rs:6:20 | LL | type Foo = fn() -> impl Send; diff --git a/tests/ui/type/subtyping-opaque-type.rs b/tests/ui/type/subtyping-opaque-type.rs new file mode 100644 index 000000000000..beda232ea8b3 --- /dev/null +++ b/tests/ui/type/subtyping-opaque-type.rs @@ -0,0 +1,19 @@ +// check-pass +// compile-flags: -Zvalidate-mir +trait Duh {} + +impl Duh for i32 {} + +trait Trait { + type Assoc: Duh; +} + +impl R> Trait for F { + type Assoc = R; +} + +fn foo() -> impl Trait { + || 42 +} + +fn main() {} diff --git a/tests/ui/type/type-check/point-at-inference-issue-116155.rs b/tests/ui/type/type-check/point-at-inference-issue-116155.rs new file mode 100644 index 000000000000..1e9942d42e86 --- /dev/null +++ b/tests/ui/type/type-check/point-at-inference-issue-116155.rs @@ -0,0 +1,17 @@ +struct S(T); + +impl S { + fn new() -> Self { + loop {} + } + + fn constrain T>(&self, _f: F) {} +} + +fn main() { + let s = S::new(); + let c = || true; + s.constrain(c); + let _: S = s; + //~^ ERROR mismatched types +} diff --git a/tests/ui/type/type-check/point-at-inference-issue-116155.stderr b/tests/ui/type/type-check/point-at-inference-issue-116155.stderr new file mode 100644 index 000000000000..c8c01603cb84 --- /dev/null +++ b/tests/ui/type/type-check/point-at-inference-issue-116155.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/point-at-inference-issue-116155.rs:15:23 + | +LL | s.constrain(c); + | - - this argument has type `{closure@$DIR/point-at-inference-issue-116155.rs:13:13: 13:15}`... + | | + | ... which causes `s` to have type `S` +LL | let _: S = s; + | -------- ^ expected `S`, found `S` + | | + | expected due to this + | + = note: expected struct `S` + found struct `S` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/typeck/issue-104513-ice.rs b/tests/ui/typeck/issue-104513-ice.rs index bcac0fa1e70e..4968d3f51fe8 100644 --- a/tests/ui/typeck/issue-104513-ice.rs +++ b/tests/ui/typeck/issue-104513-ice.rs @@ -1,6 +1,6 @@ struct S; fn f() { let _: S = S; //~ ERROR cannot find trait `Oops` in this scope - //~^ ERROR `impl Trait` only allowed in function and inherent method return types + //~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types } fn main() {} diff --git a/tests/ui/typeck/issue-104513-ice.stderr b/tests/ui/typeck/issue-104513-ice.stderr index 09187d7863a6..56c6b3361546 100644 --- a/tests/ui/typeck/issue-104513-ice.stderr +++ b/tests/ui/typeck/issue-104513-ice.stderr @@ -4,7 +4,7 @@ error[E0405]: cannot find trait `Oops` in this scope LL | let _: S = S; | ^^^^ not found in this scope -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings +error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings --> $DIR/issue-104513-ice.rs:3:14 | LL | let _: S = S; diff --git a/tests/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr b/tests/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr index dc4bc5b5f44b..6c3302f29c2d 100644 --- a/tests/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr +++ b/tests/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-57673-ice-on-deref-of-boxed-trait.rs:5:5 | LL | fn ice(x: Box>) { - | - help: try adding a return type: `-> (dyn Iterator + 'static)` + | - help: try adding a return type: `-> (dyn Iterator + 'static)` LL | *x | ^^ expected `()`, found `dyn Iterator` | diff --git a/tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr b/tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr index 0d72ae118f3a..c46f4ec1ec30 100644 --- a/tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr +++ b/tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-90027-async-fn-return-suggestion.rs:4:5 | LL | async fn hello() { - | - help: try adding a return type: `-> i32` + | - help: try adding a return type: `-> i32` LL | 0 | ^ expected `()`, found integer diff --git a/tests/ui/typeck/issue-91267.stderr b/tests/ui/typeck/issue-91267.stderr index 72acd9c673b6..7e48b251980e 100644 --- a/tests/ui/typeck/issue-91267.stderr +++ b/tests/ui/typeck/issue-91267.stderr @@ -14,7 +14,7 @@ error[E0308]: mismatched types --> $DIR/issue-91267.rs:4:5 | LL | fn main() { - | - expected `()` because of default return type + | - expected `()` because of default return type LL | type_ascribe!(0, u8=e>) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `u8` diff --git a/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr b/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr index a3517af877cc..67ca2b061f9b 100644 --- a/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr +++ b/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr @@ -21,6 +21,8 @@ LL | trait Trait: Copy {} | ^^^^---------- help: remove these generics | | | expected 0 generic arguments + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/typeck-builtin-bound-type-parameters.rs:8:21 diff --git a/tests/ui/unknown-lint-tool-name.stderr b/tests/ui/unknown-lint-tool-name.stderr index 5f8349ce6c3c..72731ab1e3db 100644 --- a/tests/ui/unknown-lint-tool-name.stderr +++ b/tests/ui/unknown-lint-tool-name.stderr @@ -21,6 +21,7 @@ LL | #![deny(foo::bar)] | ^^^ | = help: add `#![register_tool(foo)]` to the crate root + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar` --> $DIR/unknown-lint-tool-name.rs:4:9 @@ -29,6 +30,7 @@ LL | #[allow(foo::bar)] | ^^^ | = help: add `#![register_tool(foo)]` to the crate root + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors diff --git a/tests/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr b/tests/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr index 32f8d2f45dc8..f0450aea49a4 100644 --- a/tests/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr +++ b/tests/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr @@ -8,11 +8,13 @@ error: unknown lint: `test_unstable_lint` | = note: the `test_unstable_lint` lint is unstable = help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: unknown lint: `test_unstable_lint` | = note: the `test_unstable_lint` lint is unstable = help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 3 previous errors diff --git a/tests/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr b/tests/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr index 2a2a9811bfb0..20a36b28dc69 100644 --- a/tests/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr +++ b/tests/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr @@ -20,6 +20,7 @@ LL | #![allow(test_unstable_lint)] | = note: the `test_unstable_lint` lint is unstable = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: unknown lint: `test_unstable_lint` --> $DIR/deny-unstable-lint-inline.rs:4:1 @@ -29,6 +30,7 @@ LL | #![allow(test_unstable_lint)] | = note: the `test_unstable_lint` lint is unstable = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 3 previous errors diff --git a/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr b/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr index dd9ecf02fa6b..a2deecf1caf5 100644 --- a/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr +++ b/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr @@ -8,11 +8,13 @@ warning: unknown lint: `test_unstable_lint` | = note: the `test_unstable_lint` lint is unstable = help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `test_unstable_lint` | = note: the `test_unstable_lint` lint is unstable = help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr b/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr index 0548cd226d80..12afb2e294a3 100644 --- a/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr +++ b/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr @@ -20,6 +20,7 @@ LL | #![allow(test_unstable_lint)] | = note: the `test_unstable_lint` lint is unstable = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `test_unstable_lint` --> $DIR/warn-unknown-unstable-lint-inline.rs:4:1 @@ -29,6 +30,7 @@ LL | #![allow(test_unstable_lint)] | = note: the `test_unstable_lint` lint is unstable = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: 3 warnings emitted diff --git a/tests/ui/use/use-super-global-path.stderr b/tests/ui/use/use-super-global-path.stderr index 7014a12e9ddd..00d172f4799a 100644 --- a/tests/ui/use/use-super-global-path.stderr +++ b/tests/ui/use/use-super-global-path.stderr @@ -9,6 +9,8 @@ error[E0433]: failed to resolve: global paths cannot start with `super` | LL | use ::super::{S, Z}; | ^^^^^ global paths cannot start with `super` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0433]: failed to resolve: global paths cannot start with `super` --> $DIR/use-super-global-path.rs:11:15 diff --git a/x b/x index d967988e1c44..ef3eb8b04b4b 100755 --- a/x +++ b/x @@ -8,7 +8,7 @@ set -eu # syntax check -sh -n $0 +sh -n "$0" realpath() { if [ -d "$1" ]; then