diff --git a/Cargo.lock b/Cargo.lock index a55ef7b61436e..8ea1d09fabf5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -876,24 +876,24 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.34" +version = "0.4.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e268162af1a5fe89917ae25ba3b0a77c8da752bdc58e7dbb4f15b91fbd33756e" +checksum = "d0bac9f84ca0977c4d9b8db998689de55b9e976656a6bc87fada2ca710d504c7" dependencies = [ "curl-sys", "libc", "openssl-probe", "openssl-sys", "schannel", - "socket2", + "socket2 0.4.0", "winapi 0.3.9", ] [[package]] name = "curl-sys" -version = "0.4.39+curl-7.74.0" +version = "0.4.42+curl-7.76.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07a8ce861e7b68a0b394e814d7ee9f1b2750ff8bd10372c6ad3bacc10e86f874" +checksum = "4636d8d6109c842707018a104051436bffb8991ea20b2d1293db70b6e0ee4c7c" dependencies = [ "cc", "libc", @@ -2285,7 +2285,7 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" dependencies = [ - "socket2", + "socket2 0.3.16", "winapi 0.3.9", ] @@ -2402,15 +2402,15 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.30" +version = "0.10.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4" +checksum = "a61075b62a23fef5a29815de7536d940aa35ce96d18ce0cc5076272db678a577" dependencies = [ "bitflags", - "cfg-if 0.1.10", + "cfg-if 1.0.0", "foreign-types", - "lazy_static", "libc", + "once_cell", "openssl-sys", ] @@ -2422,18 +2422,18 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" [[package]] name = "openssl-src" -version = "111.12.0+1.1.1h" +version = "111.15.0+1.1.1k" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "858a4132194f8570a7ee9eb8629e85b23cbc4565f2d4a162e87556e5956abf61" +checksum = "b1a5f6ae2ac04393b217ea9f700cd04fa9bf3d93fae2872069f3d15d908af70a" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.58" +version = "0.9.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de" +checksum = "313752393519e876837e09e1fa183ddef0be7735868dced3196f4472d536277f" dependencies = [ "autocfg", "cc", @@ -4943,6 +4943,16 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "socket2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" diff --git a/RELEASES.md b/RELEASES.md index 024610bc7a417..1f940e6bc2d3b 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,151 @@ +Version 1.52.0 (2021-05-06) +============================ + +Language +-------- +- [Added the `unsafe_op_in_unsafe_fn` lint, which checks whether the unsafe code + in an `unsafe fn` is wrapped in a `unsafe` block.][79208] This lint + is allowed by default, and may become a warning or hard error in a + future edition. +- [You can now cast mutable references to arrays to a pointer of the same type as + the element.][81479] + +Compiler +-------- +- [Upgraded the default LLVM to LLVM 12.][81451] + +Added tier 3\* support for the following targets. + +- [`s390x-unknown-linux-musl`][82166] +- [`riscv32gc-unknown-linux-musl` & `riscv64gc-unknown-linux-musl`][82202] +- [`powerpc-unknown-openbsd`][82733] + +\* Refer to Rust's [platform support page][platform-support-doc] for more +information on Rust's tiered platform support. + +Libraries +--------- +- [`OsString` now implements `Extend` and `FromIterator`.][82121] +- [`cmp::Reverse` now has `#[repr(transparent)]` representation.][81879] +- [`Arc` now implements `error::Error`.][80553] +- [All integer division and remainder operations are now `const`.][80962] + +Stabilised APIs +------------- +- [`Arguments::as_str`] +- [`char::MAX`] +- [`char::REPLACEMENT_CHARACTER`] +- [`char::UNICODE_VERSION`] +- [`char::decode_utf16`] +- [`char::from_digit`] +- [`char::from_u32_unchecked`] +- [`char::from_u32`] +- [`slice::partition_point`] +- [`str::rsplit_once`] +- [`str::split_once`] + +The following previously stable APIs are now `const`. + +- [`char::len_utf8`] +- [`char::len_utf16`] +- [`char::to_ascii_uppercase`] +- [`char::to_ascii_lowercase`] +- [`char::eq_ignore_ascii_case`] +- [`u8::to_ascii_uppercase`] +- [`u8::to_ascii_lowercase`] +- [`u8::eq_ignore_ascii_case`] + +Rustdoc +------- +- [Rustdoc lints are now treated as a tool lint, meaning that + lints are now prefixed with `rustdoc::` (e.g. `#[warn(rustdoc::non_autolinks)]`).][80527] + Using the old style is still allowed, and will become a warning in + a future release. +- [Rustdoc now supports argument files.][82261] +- [Rustdoc now generates smart punctuation for documentation.][79423] +- [You can now use "task lists" in Rustdoc Markdown.][81766] E.g. + ```markdown + - [x] Complete + - [ ] Todo + ``` + +Misc +---- +- [You can now pass multiple filters to tests.][81356] E.g. + `cargo test -- foo bar` will run all tests that match `foo` and `bar`. +- [Rustup now distributes PDB symbols for the `std` library on Windows, + allowing you to see `std` symbols when debugging.][82218] + +Internal Only +------------- +These changes provide no direct user facing benefits, but represent significant +improvements to the internals and overall performance of rustc and +related tools. + +- [Check the result cache before the DepGraph when ensuring queries][81855] +- [Try fast_reject::simplify_type in coherence before doing full check][81744] +- [Only store a LocalDefId in some HIR nodes][81611] +- [Store HIR attributes in a side table][79519] + +Compatibility Notes +------------------- +- [Cargo build scripts are now forbidden from setting `RUSTC_BOOTSTRAP`.][cargo/9181] +- [Removed support for the `x86_64-rumprun-netbsd` target.][82594] +- [Deprecated the `x86_64-sun-solaris` target in favor of `x86_64-pc-solaris`.][82216] +- [Rustdoc now only accepts `,`, ` `, and `\t` as delimiters for specifying + languages in code blocks.][78429] +- [Rustc now catches more cases of `pub_use_of_private_extern_crate`][80763] +- [Changes in how proc macros handle whitespace may lead to panics when used + with older `proc-macro-hack` versions. A `cargo update` should be sufficient to fix this in all cases.][84136] + +[84136]: https://github.com/rust-lang/rust/issues/84136 +[80763]: https://github.com/rust-lang/rust/pull/80763 +[82166]: https://github.com/rust-lang/rust/pull/82166 +[82121]: https://github.com/rust-lang/rust/pull/82121 +[81879]: https://github.com/rust-lang/rust/pull/81879 +[82261]: https://github.com/rust-lang/rust/pull/82261 +[82218]: https://github.com/rust-lang/rust/pull/82218 +[82216]: https://github.com/rust-lang/rust/pull/82216 +[82202]: https://github.com/rust-lang/rust/pull/82202 +[81855]: https://github.com/rust-lang/rust/pull/81855 +[81766]: https://github.com/rust-lang/rust/pull/81766 +[81744]: https://github.com/rust-lang/rust/pull/81744 +[81611]: https://github.com/rust-lang/rust/pull/81611 +[81479]: https://github.com/rust-lang/rust/pull/81479 +[81451]: https://github.com/rust-lang/rust/pull/81451 +[81356]: https://github.com/rust-lang/rust/pull/81356 +[80962]: https://github.com/rust-lang/rust/pull/80962 +[80553]: https://github.com/rust-lang/rust/pull/80553 +[80527]: https://github.com/rust-lang/rust/pull/80527 +[79519]: https://github.com/rust-lang/rust/pull/79519 +[79423]: https://github.com/rust-lang/rust/pull/79423 +[79208]: https://github.com/rust-lang/rust/pull/79208 +[78429]: https://github.com/rust-lang/rust/pull/78429 +[82733]: https://github.com/rust-lang/rust/pull/82733 +[82594]: https://github.com/rust-lang/rust/pull/82594 +[cargo/9181]: https://github.com/rust-lang/cargo/pull/9181 +[`char::MAX`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.MAX +[`char::REPLACEMENT_CHARACTER`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.REPLACEMENT_CHARACTER +[`char::UNICODE_VERSION`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.UNICODE_VERSION +[`char::decode_utf16`]: https://doc.rust-lang.org/std/primitive.char.html#method.decode_utf16 +[`char::from_u32`]: https://doc.rust-lang.org/std/primitive.char.html#method.from_u32 +[`char::from_u32_unchecked`]: https://doc.rust-lang.org/std/primitive.char.html#method.from_u32_unchecked +[`char::from_digit`]: https://doc.rust-lang.org/std/primitive.char.html#method.from_digit +[`Peekable::next_if`]: https://doc.rust-lang.org/stable/std/iter/struct.Peekable.html#method.next_if +[`Peekable::next_if_eq`]: https://doc.rust-lang.org/stable/std/iter/struct.Peekable.html#method.next_if_eq +[`Arguments::as_str`]: https://doc.rust-lang.org/stable/std/fmt/struct.Arguments.html#method.as_str +[`str::split_once`]: https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_once +[`str::rsplit_once`]: https://doc.rust-lang.org/stable/std/primitive.str.html#method.rsplit_once +[`slice::partition_point`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.partition_point +[`char::len_utf8`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.len_utf8 +[`char::len_utf16`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.len_utf16 +[`char::to_ascii_uppercase`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.to_ascii_uppercase +[`char::to_ascii_lowercase`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.to_ascii_lowercase +[`char::eq_ignore_ascii_case`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.eq_ignore_ascii_case +[`u8::to_ascii_uppercase`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_ascii_uppercase +[`u8::to_ascii_lowercase`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_ascii_lowercase +[`u8::eq_ignore_ascii_case`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.eq_ignore_ascii_case + Version 1.51.0 (2021-03-25) ============================ diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 77d8ab49ff258..8ba124a1fa88c 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -432,8 +432,6 @@ impl<'a> Linker for GccLinker<'a> { // insert it here. if self.sess.target.is_like_osx { self.linker_arg("-dead_strip"); - } else if self.sess.target.is_like_solaris { - self.linker_arg("-zignore"); // If we're building a dylib, we don't use --gc-sections because LLVM // has already done the best it can do, and we also don't want to @@ -655,6 +653,10 @@ impl<'a> Linker for GccLinker<'a> { fn add_as_needed(&mut self) { if self.sess.target.linker_is_gnu { self.linker_arg("--as-needed"); + } else if self.sess.target.is_like_solaris { + // -z ignore is the Solaris equivalent to the GNU ld --as-needed option + self.linker_arg("-z"); + self.linker_arg("ignore"); } } } diff --git a/compiler/rustc_mir/src/transform/const_goto.rs b/compiler/rustc_mir/src/transform/const_goto.rs index b5c8b4bebc360..ba10b54c5ae2e 100644 --- a/compiler/rustc_mir/src/transform/const_goto.rs +++ b/compiler/rustc_mir/src/transform/const_goto.rs @@ -47,7 +47,7 @@ impl<'tcx> MirPass<'tcx> for ConstGoto { // if we applied optimizations, we potentially have some cfg to cleanup to // make it easier for further passes if should_simplify { - simplify_cfg(body); + simplify_cfg(tcx, body); simplify_locals(body, tcx); } } diff --git a/compiler/rustc_mir/src/transform/deduplicate_blocks.rs b/compiler/rustc_mir/src/transform/deduplicate_blocks.rs index c41e71e09a4ef..912505c65983e 100644 --- a/compiler/rustc_mir/src/transform/deduplicate_blocks.rs +++ b/compiler/rustc_mir/src/transform/deduplicate_blocks.rs @@ -26,7 +26,7 @@ impl<'tcx> MirPass<'tcx> for DeduplicateBlocks { if has_opts_to_apply { let mut opt_applier = OptApplier { tcx, duplicates }; opt_applier.visit_body(body); - simplify_cfg(body); + simplify_cfg(tcx, body); } } } diff --git a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs index f7ea9faec4728..ac39206623308 100644 --- a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs +++ b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs @@ -164,7 +164,7 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { // Since this optimization adds new basic blocks and invalidates others, // clean up the cfg to make it nicer for other passes if should_cleanup { - simplify_cfg(body); + simplify_cfg(tcx, body); } } } diff --git a/compiler/rustc_mir/src/transform/generator.rs b/compiler/rustc_mir/src/transform/generator.rs index 003003a8abbea..3560b4b1e8645 100644 --- a/compiler/rustc_mir/src/transform/generator.rs +++ b/compiler/rustc_mir/src/transform/generator.rs @@ -964,7 +964,7 @@ fn create_generator_drop_shim<'tcx>( // Make sure we remove dead blocks to remove // unrelated code from the resume part of the function - simplify::remove_dead_blocks(&mut body); + simplify::remove_dead_blocks(tcx, &mut body); dump_mir(tcx, None, "generator_drop", &0, &body, |_, _| Ok(())); @@ -1137,7 +1137,7 @@ fn create_generator_resume_function<'tcx>( // Make sure we remove dead blocks to remove // unrelated code from the drop part of the function - simplify::remove_dead_blocks(body); + simplify::remove_dead_blocks(tcx, body); dump_mir(tcx, None, "generator_resume", &0, body, |_, _| Ok(())); } diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index b6f80763bc8c4..f1c95a84ade85 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -57,7 +57,7 @@ impl<'tcx> MirPass<'tcx> for Inline { if inline(tcx, body) { debug!("running simplify cfg on {:?}", body.source); CfgSimplifier::new(body).simplify(); - remove_dead_blocks(body); + remove_dead_blocks(tcx, body); } } } diff --git a/compiler/rustc_mir/src/transform/match_branches.rs b/compiler/rustc_mir/src/transform/match_branches.rs index f7a9835353e5c..21b208a08c2dc 100644 --- a/compiler/rustc_mir/src/transform/match_branches.rs +++ b/compiler/rustc_mir/src/transform/match_branches.rs @@ -167,7 +167,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { } if should_cleanup { - simplify_cfg(body); + simplify_cfg(tcx, body); } } } diff --git a/compiler/rustc_mir/src/transform/multiple_return_terminators.rs b/compiler/rustc_mir/src/transform/multiple_return_terminators.rs index 4aaa0baa9f46a..cd2db18055286 100644 --- a/compiler/rustc_mir/src/transform/multiple_return_terminators.rs +++ b/compiler/rustc_mir/src/transform/multiple_return_terminators.rs @@ -38,6 +38,6 @@ impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators { } } - simplify::remove_dead_blocks(body) + simplify::remove_dead_blocks(tcx, body) } } diff --git a/compiler/rustc_mir/src/transform/remove_unneeded_drops.rs b/compiler/rustc_mir/src/transform/remove_unneeded_drops.rs index 5144d48750de7..02e45021a0aaf 100644 --- a/compiler/rustc_mir/src/transform/remove_unneeded_drops.rs +++ b/compiler/rustc_mir/src/transform/remove_unneeded_drops.rs @@ -36,7 +36,7 @@ impl<'tcx> MirPass<'tcx> for RemoveUnneededDrops { // if we applied optimizations, we potentially have some cfg to cleanup to // make it easier for further passes if should_simplify { - simplify_cfg(body); + simplify_cfg(tcx, body); } } } diff --git a/compiler/rustc_mir/src/transform/simplify.rs b/compiler/rustc_mir/src/transform/simplify.rs index 65e2d096b2094..63373b0cffbb0 100644 --- a/compiler/rustc_mir/src/transform/simplify.rs +++ b/compiler/rustc_mir/src/transform/simplify.rs @@ -29,6 +29,7 @@ use crate::transform::MirPass; use rustc_index::vec::{Idx, IndexVec}; +use rustc_middle::mir::coverage::*; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; @@ -46,9 +47,9 @@ impl SimplifyCfg { } } -pub fn simplify_cfg(body: &mut Body<'_>) { +pub fn simplify_cfg(tcx: TyCtxt<'tcx>, body: &mut Body<'_>) { CfgSimplifier::new(body).simplify(); - remove_dead_blocks(body); + remove_dead_blocks(tcx, body); // FIXME: Should probably be moved into some kind of pass manager body.basic_blocks_mut().raw.shrink_to_fit(); @@ -59,9 +60,9 @@ impl<'tcx> MirPass<'tcx> for SimplifyCfg { Cow::Borrowed(&self.label) } - fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, body.source); - simplify_cfg(body); + simplify_cfg(tcx, body); } } @@ -286,7 +287,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } } -pub fn remove_dead_blocks(body: &mut Body<'_>) { +pub fn remove_dead_blocks(tcx: TyCtxt<'tcx>, body: &mut Body<'_>) { let reachable = traversal::reachable_as_bitset(body); let num_blocks = body.basic_blocks().len(); if num_blocks == reachable.count() { @@ -306,6 +307,11 @@ pub fn remove_dead_blocks(body: &mut Body<'_>) { } used_blocks += 1; } + + if tcx.sess.instrument_coverage() { + save_unreachable_coverage(basic_blocks, used_blocks); + } + basic_blocks.raw.truncate(used_blocks); for block in basic_blocks { @@ -315,6 +321,32 @@ pub fn remove_dead_blocks(body: &mut Body<'_>) { } } +fn save_unreachable_coverage( + basic_blocks: &mut IndexVec>, + first_dead_block: usize, +) { + // retain coverage info for dead blocks, so coverage reports will still + // report `0` executions for the uncovered code regions. + let mut dropped_coverage = Vec::new(); + for dead_block in first_dead_block..basic_blocks.len() { + for statement in basic_blocks[BasicBlock::new(dead_block)].statements.iter() { + if let StatementKind::Coverage(coverage) = &statement.kind { + if let Some(code_region) = &coverage.code_region { + dropped_coverage.push((statement.source_info, code_region.clone())); + } + } + } + } + for (source_info, code_region) in dropped_coverage { + basic_blocks[START_BLOCK].statements.push(Statement { + source_info, + kind: StatementKind::Coverage(box Coverage { + kind: CoverageKind::Unreachable, + code_region: Some(code_region), + }), + }) + } +} pub struct SimplifyLocals; impl<'tcx> MirPass<'tcx> for SimplifyLocals { diff --git a/compiler/rustc_mir/src/transform/simplify_try.rs b/compiler/rustc_mir/src/transform/simplify_try.rs index b42543c04eb3d..c9c4492062720 100644 --- a/compiler/rustc_mir/src/transform/simplify_try.rs +++ b/compiler/rustc_mir/src/transform/simplify_try.rs @@ -558,7 +558,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyBranchSame { if did_remove_blocks { // We have dead blocks now, so remove those. - simplify::remove_dead_blocks(body); + simplify::remove_dead_blocks(tcx, body); } } } diff --git a/compiler/rustc_mir/src/transform/unreachable_prop.rs b/compiler/rustc_mir/src/transform/unreachable_prop.rs index 658c6b6e9db20..e7fb6b4f6b4ad 100644 --- a/compiler/rustc_mir/src/transform/unreachable_prop.rs +++ b/compiler/rustc_mir/src/transform/unreachable_prop.rs @@ -60,7 +60,7 @@ impl MirPass<'_> for UnreachablePropagation { } if replaced { - simplify::remove_dead_blocks(body); + simplify::remove_dead_blocks(tcx, body); } } } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index d32180525bf70..3b21f00a001bd 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -3,6 +3,7 @@ // from live codes are live, and everything else is dead. use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; @@ -15,7 +16,7 @@ use rustc_middle::middle::privacy; use rustc_middle::ty::{self, DefIdTree, TyCtxt}; use rustc_session::lint; -use rustc_span::symbol::{sym, Symbol}; +use rustc_span::symbol::{sym, Ident, Symbol}; // Any local node that may call something in its body block should be // explored. For example, if it's a live Node::Item that is a @@ -507,6 +508,13 @@ fn find_live<'tcx>( symbol_visitor.live_symbols } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum ExtraNote { + /// Use this to provide some examples in the diagnostic of potential other purposes for a value + /// or field that is dead code + OtherPurposeExamples, +} + struct DeadVisitor<'tcx> { tcx: TyCtxt<'tcx>, live_symbols: FxHashSet, @@ -572,14 +580,42 @@ impl DeadVisitor<'tcx> { &mut self, id: hir::HirId, span: rustc_span::Span, - name: Symbol, + name: Ident, participle: &str, + extra_note: Option, ) { if !name.as_str().starts_with('_') { self.tcx.struct_span_lint_hir(lint::builtin::DEAD_CODE, id, span, |lint| { let def_id = self.tcx.hir().local_def_id(id); let descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id()); - lint.build(&format!("{} is never {}: `{}`", descr, participle, name)).emit() + + let prefixed = vec![(name.span, format!("_{}", name))]; + + let mut diag = + lint.build(&format!("{} is never {}: `{}`", descr, participle, name)); + + diag.multipart_suggestion( + "if this is intentional, prefix it with an underscore", + prefixed, + Applicability::MachineApplicable, + ); + + let mut note = format!( + "the leading underscore signals that this {} serves some other \ + purpose even if it isn't used in a way that we can detect.", + descr, + ); + if matches!(extra_note, Some(ExtraNote::OtherPurposeExamples)) { + note += " (e.g. for its effect when dropped or in foreign code)"; + } + + diag.note(¬e); + + // Force the note we added to the front, before any other subdiagnostics + // added in lint.build(...) + diag.children.rotate_right(1); + + diag.emit() }); } } @@ -625,7 +661,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { hir::ItemKind::Struct(..) => "constructed", // Issue #52325 _ => "used", }; - self.warn_dead_code(item.hir_id(), span, item.ident.name, participle); + self.warn_dead_code(item.hir_id(), span, item.ident, participle, None); } else { // Only continue if we didn't warn intravisit::walk_item(self, item); @@ -639,7 +675,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { id: hir::HirId, ) { if self.should_warn_about_variant(&variant) { - self.warn_dead_code(variant.id, variant.span, variant.ident.name, "constructed"); + self.warn_dead_code(variant.id, variant.span, variant.ident, "constructed", None); } else { intravisit::walk_variant(self, variant, g, id); } @@ -647,14 +683,20 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { fn visit_foreign_item(&mut self, fi: &'tcx hir::ForeignItem<'tcx>) { if self.should_warn_about_foreign_item(fi) { - self.warn_dead_code(fi.hir_id(), fi.span, fi.ident.name, "used"); + self.warn_dead_code(fi.hir_id(), fi.span, fi.ident, "used", None); } intravisit::walk_foreign_item(self, fi); } fn visit_field_def(&mut self, field: &'tcx hir::FieldDef<'tcx>) { if self.should_warn_about_field(&field) { - self.warn_dead_code(field.hir_id, field.span, field.ident.name, "read"); + self.warn_dead_code( + field.hir_id, + field.span, + field.ident, + "read", + Some(ExtraNote::OtherPurposeExamples), + ); } intravisit::walk_field_def(self, field); } @@ -666,8 +708,9 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { self.warn_dead_code( impl_item.hir_id(), impl_item.span, - impl_item.ident.name, + impl_item.ident, "used", + None, ); } self.visit_nested_body(body_id) @@ -685,7 +728,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { } else { impl_item.ident.span }; - self.warn_dead_code(impl_item.hir_id(), span, impl_item.ident.name, "used"); + self.warn_dead_code(impl_item.hir_id(), span, impl_item.ident, "used", None); } self.visit_nested_body(body_id) } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 1ddd7d694547d..08d6f4a46fefe 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2332,17 +2332,17 @@ crate mod dep_tracking { } macro_rules! impl_dep_tracking_hash_via_hash { - ($t:ty) => { + ($($t:ty),+ $(,)?) => {$( impl DepTrackingHash for $t { fn hash(&self, hasher: &mut DefaultHasher, _: ErrorOutputType) { Hash::hash(self, hasher); } } - }; + )+}; } macro_rules! impl_dep_tracking_hash_for_sortable_vec_of { - ($t:ty) => { + ($($t:ty),+ $(,)?) => {$( impl DepTrackingHash for Vec<$t> { fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) { let mut elems: Vec<&$t> = self.iter().collect(); @@ -2354,61 +2354,65 @@ crate mod dep_tracking { } } } - }; - } + )+}; + } + + impl_dep_tracking_hash_via_hash!( + bool, + usize, + u64, + String, + PathBuf, + lint::Level, + Option, + Option, + Option, + Option, + Option, + Option<(String, u64)>, + Option>, + Option, + Option, + Option, + Option, + Option, + Option, + Option, + Option, + Option, + Option, + CrateType, + MergeFunctions, + PanicStrategy, + RelroLevel, + Passes, + OptLevel, + LtoCli, + DebugInfo, + UnstableFeatures, + OutputTypes, + NativeLibKind, + SanitizerSet, + CFGuard, + TargetTriple, + Edition, + LinkerPluginLto, + Option, + SwitchWithOptPath, + Option, + Option, + TrimmedDefPaths, + ); - impl_dep_tracking_hash_via_hash!(bool); - impl_dep_tracking_hash_via_hash!(usize); - impl_dep_tracking_hash_via_hash!(u64); - impl_dep_tracking_hash_via_hash!(String); - impl_dep_tracking_hash_via_hash!(PathBuf); - impl_dep_tracking_hash_via_hash!(lint::Level); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Option<(String, u64)>); - impl_dep_tracking_hash_via_hash!(Option>); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(CrateType); - impl_dep_tracking_hash_via_hash!(MergeFunctions); - impl_dep_tracking_hash_via_hash!(PanicStrategy); - impl_dep_tracking_hash_via_hash!(RelroLevel); - impl_dep_tracking_hash_via_hash!(Passes); - impl_dep_tracking_hash_via_hash!(OptLevel); - impl_dep_tracking_hash_via_hash!(LtoCli); - impl_dep_tracking_hash_via_hash!(DebugInfo); - impl_dep_tracking_hash_via_hash!(UnstableFeatures); - impl_dep_tracking_hash_via_hash!(OutputTypes); - impl_dep_tracking_hash_via_hash!(NativeLibKind); - impl_dep_tracking_hash_via_hash!(SanitizerSet); - impl_dep_tracking_hash_via_hash!(CFGuard); - impl_dep_tracking_hash_via_hash!(TargetTriple); - impl_dep_tracking_hash_via_hash!(Edition); - impl_dep_tracking_hash_via_hash!(LinkerPluginLto); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(SwitchWithOptPath); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(TrimmedDefPaths); - - impl_dep_tracking_hash_for_sortable_vec_of!(String); - impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf); - impl_dep_tracking_hash_for_sortable_vec_of!((PathBuf, PathBuf)); - impl_dep_tracking_hash_for_sortable_vec_of!(CrateType); - impl_dep_tracking_hash_for_sortable_vec_of!((String, lint::Level)); - impl_dep_tracking_hash_for_sortable_vec_of!((String, Option, NativeLibKind)); - impl_dep_tracking_hash_for_sortable_vec_of!((String, u64)); + impl_dep_tracking_hash_for_sortable_vec_of!( + String, + PathBuf, + (PathBuf, PathBuf), + CrateType, + (String, lint::Level), + (String, Option, NativeLibKind), + (String, u64) + ); impl DepTrackingHash for (T1, T2) where diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 73e35f0171aa7..b2e4e7a981d20 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -579,6 +579,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let mut restrict_type_params = false; + let mut unsatisfied_bounds = false; if !unsatisfied_predicates.is_empty() { let def_span = |def_id| { self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id)) @@ -739,6 +740,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.note(&format!( "the following trait bounds were not satisfied:\n{bound_list}" )); + unsatisfied_bounds = true; } } @@ -752,6 +754,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { source, out_of_scope_traits, &unsatisfied_predicates, + unsatisfied_bounds, ); } @@ -984,9 +987,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { source: SelfSource<'tcx>, valid_out_of_scope_traits: Vec, unsatisfied_predicates: &[(ty::Predicate<'tcx>, Option>)], + unsatisfied_bounds: bool, ) { let mut alt_rcvr_sugg = false; - if let SelfSource::MethodCall(rcvr) = source { + if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) { debug!(?span, ?item_name, ?rcvr_ty, ?rcvr); let skippable = [ self.tcx.lang_items().clone_trait(), diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 51d5f4ebe2bd2..97b6f5cf41211 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -191,7 +191,25 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< Res::Def(DefKind::Ctor(..), def_id) => { tcx.generics_of(tcx.parent(def_id).unwrap()) } - Res::Def(_, def_id) => tcx.generics_of(def_id), + // Other `DefKind`s don't have generics and would ICE when calling + // `generics_of`. + Res::Def( + DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Variant + | DefKind::Trait + | DefKind::OpaqueTy + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::AssocTy + | DefKind::Fn + | DefKind::AssocFn + | DefKind::AssocConst + | DefKind::Impl, + def_id, + ) => tcx.generics_of(def_id), Res::Err => { tcx.sess.delay_span_bug(tcx.def_span(def_id), "anon const with Res::Err"); return None; diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 415bdde11eb88..2c324b15a1a1a 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -720,9 +720,6 @@ pub const unsafe fn read(src: *const T) -> T { /// /// ## On `packed` structs /// -/// It is currently impossible to create raw pointers to unaligned fields -/// of a packed struct. -/// /// Attempting to create a raw pointer to an `unaligned` struct field with /// an expression such as `&packed.unaligned as *const FieldType` creates an /// intermediate unaligned reference before converting that to a raw pointer. @@ -731,9 +728,13 @@ pub const unsafe fn read(src: *const T) -> T { /// As a result, using `&packed.unaligned as *const FieldType` causes immediate /// *undefined behavior* in your program. /// +/// Instead you must use the [`ptr::addr_of!`](addr_of) macro to +/// create the pointer. You may use that returned pointer together with this +/// function. +/// /// An example of what not to do and how this relates to `read_unaligned` is: /// -/// ```no_run +/// ``` /// #[repr(packed, C)] /// struct Packed { /// _padding: u8, @@ -745,24 +746,15 @@ pub const unsafe fn read(src: *const T) -> T { /// unaligned: 0x01020304, /// }; /// -/// #[allow(unaligned_references)] -/// let v = unsafe { -/// // Here we attempt to take the address of a 32-bit integer which is not aligned. -/// let unaligned = -/// // A temporary unaligned reference is created here which results in -/// // undefined behavior regardless of whether the reference is used or not. -/// &packed.unaligned -/// // Casting to a raw pointer doesn't help; the mistake already happened. -/// as *const u32; +/// // Take the address of a 32-bit integer which is not aligned. +/// // In contrast to `&packed.unaligned as *const _`, this has no undefined behavior. +/// let unaligned = std::ptr::addr_of!(packed.unaligned); /// -/// let v = std::ptr::read_unaligned(unaligned); -/// -/// v -/// }; +/// let v = unsafe { std::ptr::read_unaligned(unaligned) }; +/// assert_eq!(v, 0x01020304); /// ``` /// /// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however. -// FIXME: Update docs based on outcome of RFC #2582 and friends. /// /// # Examples /// @@ -916,9 +908,6 @@ pub const unsafe fn write(dst: *mut T, src: T) { /// /// ## On `packed` structs /// -/// It is currently impossible to create raw pointers to unaligned fields -/// of a packed struct. -/// /// Attempting to create a raw pointer to an `unaligned` struct field with /// an expression such as `&packed.unaligned as *const FieldType` creates an /// intermediate unaligned reference before converting that to a raw pointer. @@ -927,36 +916,32 @@ pub const unsafe fn write(dst: *mut T, src: T) { /// As a result, using `&packed.unaligned as *const FieldType` causes immediate /// *undefined behavior* in your program. /// -/// An example of what not to do and how this relates to `write_unaligned` is: +/// Instead you must use the [`ptr::addr_of_mut!`](addr_of_mut) +/// macro to create the pointer. You may use that returned pointer together with +/// this function. +/// +/// An example of how to do it and how this relates to `write_unaligned` is: /// -/// ```no_run +/// ``` /// #[repr(packed, C)] /// struct Packed { /// _padding: u8, /// unaligned: u32, /// } /// -/// let v = 0x01020304; /// let mut packed: Packed = unsafe { std::mem::zeroed() }; /// -/// #[allow(unaligned_references)] -/// let v = unsafe { -/// // Here we attempt to take the address of a 32-bit integer which is not aligned. -/// let unaligned = -/// // A temporary unaligned reference is created here which results in -/// // undefined behavior regardless of whether the reference is used or not. -/// &mut packed.unaligned -/// // Casting to a raw pointer doesn't help; the mistake already happened. -/// as *mut u32; +/// // Take the address of a 32-bit integer which is not aligned. +/// // In contrast to `&packed.unaligned as *mut _`, this has no undefined behavior. +/// let unaligned = std::ptr::addr_of_mut!(packed.unaligned); /// -/// std::ptr::write_unaligned(unaligned, v); +/// unsafe { std::ptr::write_unaligned(unaligned, 42) }; /// -/// v -/// }; +/// assert_eq!({packed.unaligned}, 42); // `{...}` forces copying the field instead of creating a reference. /// ``` /// -/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however. -// FIXME: Update docs based on outcome of RFC #2582 and friends. +/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however +/// (as can be seen in the `assert_eq!` above). /// /// # Examples /// diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index ec28cdd1ba0d9..0923175414edd 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -1948,8 +1948,9 @@ impl [T] { /// assert!(!v.contains(&50)); /// ``` /// - /// If you do not have an `&T`, but just an `&U` such that `T: Borrow` - /// (e.g. `String: Borrow`), you can use `iter().any`: + /// If you do not have a `&T`, but some other value that you can compare + /// with one (for example, `String` implements `PartialEq`), you can + /// use `iter().any`: /// /// ``` /// let v = [String::from("hello"), String::from("world")]; // slice of `String` diff --git a/library/core/src/time.rs b/library/core/src/time.rs index bfea39e3211fc..489b722440362 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -518,13 +518,11 @@ impl Duration { if let Some(mut secs) = self.secs.checked_sub(rhs.secs) { let nanos = if self.nanos >= rhs.nanos { self.nanos - rhs.nanos + } else if let Some(sub_secs) = secs.checked_sub(1) { + secs = sub_secs; + self.nanos + NANOS_PER_SEC - rhs.nanos } else { - if let Some(sub_secs) = secs.checked_sub(1) { - secs = sub_secs; - self.nanos + NANOS_PER_SEC - rhs.nanos - } else { - return None; - } + return None; }; debug_assert!(nanos < NANOS_PER_SEC); Some(Duration { secs, nanos }) diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index cd6b0b2d7ee7a..96ab32104ea2c 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -445,7 +445,27 @@ mod prim_unit {} /// Note that here the call to [`drop`] is for clarity - it indicates /// that we are done with the given value and it should be destroyed. /// -/// ## 3. Get it from C. +/// ## 3. Create it using `ptr::addr_of!` +/// +/// Instead of coercing a reference to a raw pointer, you can use the macros +/// [`ptr::addr_of!`] (for `*const T`) and [`ptr::addr_of_mut!`] (for `*mut T`). +/// These macros allow you to create raw pointers to fields to which you cannot +/// create a reference (without causing undefined behaviour), such as an +/// unaligned field. This might be necessary if packed structs or uninitialized +/// memory is involved. +/// +/// ``` +/// #[derive(Debug, Default, Copy, Clone)] +/// #[repr(C, packed)] +/// struct S { +/// aligned: u8, +/// unaligned: u32, +/// } +/// let s = S::default(); +/// let p = std::ptr::addr_of!(s.unaligned); // not allowed with coercion +/// ``` +/// +/// ## 4. Get it from C. /// /// ``` /// # #![feature(rustc_private)] diff --git a/library/std/src/sys/sgx/abi/mod.rs b/library/std/src/sys/sgx/abi/mod.rs index a5e453034762c..f9536c4203df2 100644 --- a/library/std/src/sys/sgx/abi/mod.rs +++ b/library/std/src/sys/sgx/abi/mod.rs @@ -62,10 +62,12 @@ unsafe extern "C" fn tcs_init(secondary: bool) { extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> EntryReturn { // FIXME: how to support TLS in library mode? let tls = Box::new(tls::Tls::new()); - let _tls_guard = unsafe { tls.activate() }; + let tls_guard = unsafe { tls.activate() }; if secondary { - super::thread::Thread::entry(); + let join_notifier = super::thread::Thread::entry(); + drop(tls_guard); + drop(join_notifier); EntryReturn(0, 0) } else { diff --git a/library/std/src/sys/sgx/thread.rs b/library/std/src/sys/sgx/thread.rs index 55ef460cc90c5..67e2e8b59d397 100644 --- a/library/std/src/sys/sgx/thread.rs +++ b/library/std/src/sys/sgx/thread.rs @@ -9,26 +9,37 @@ pub struct Thread(task_queue::JoinHandle); pub const DEFAULT_MIN_STACK_SIZE: usize = 4096; +pub use self::task_queue::JoinNotifier; + mod task_queue { - use crate::sync::mpsc; + use super::wait_notify; use crate::sync::{Mutex, MutexGuard, Once}; - pub type JoinHandle = mpsc::Receiver<()>; + pub type JoinHandle = wait_notify::Waiter; + + pub struct JoinNotifier(Option); + + impl Drop for JoinNotifier { + fn drop(&mut self) { + self.0.take().unwrap().notify(); + } + } pub(super) struct Task { p: Box, - done: mpsc::Sender<()>, + done: JoinNotifier, } impl Task { pub(super) fn new(p: Box) -> (Task, JoinHandle) { - let (done, recv) = mpsc::channel(); + let (done, recv) = wait_notify::new(); + let done = JoinNotifier(Some(done)); (Task { p, done }, recv) } - pub(super) fn run(self) { + pub(super) fn run(self) -> JoinNotifier { (self.p)(); - let _ = self.done.send(()); + self.done } } @@ -47,6 +58,48 @@ mod task_queue { } } +/// This module provides a synchronization primitive that does not use thread +/// local variables. This is needed for signaling that a thread has finished +/// execution. The signal is sent once all TLS destructors have finished at +/// which point no new thread locals should be created. +pub mod wait_notify { + use super::super::waitqueue::{SpinMutex, WaitQueue, WaitVariable}; + use crate::sync::Arc; + + pub struct Notifier(Arc>>); + + impl Notifier { + /// Notify the waiter. The waiter is either notified right away (if + /// currently blocked in `Waiter::wait()`) or later when it calls the + /// `Waiter::wait()` method. + pub fn notify(self) { + let mut guard = self.0.lock(); + *guard.lock_var_mut() = true; + let _ = WaitQueue::notify_one(guard); + } + } + + pub struct Waiter(Arc>>); + + impl Waiter { + /// Wait for a notification. If `Notifier::notify()` has already been + /// called, this will return immediately, otherwise the current thread + /// is blocked until notified. + pub fn wait(self) { + let guard = self.0.lock(); + if *guard.lock_var() { + return; + } + WaitQueue::wait(guard, || {}); + } + } + + pub fn new() -> (Notifier, Waiter) { + let inner = Arc::new(SpinMutex::new(WaitVariable::new(false))); + (Notifier(inner.clone()), Waiter(inner)) + } +} + impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements pub unsafe fn new(_stack: usize, p: Box) -> io::Result { @@ -57,7 +110,7 @@ impl Thread { Ok(Thread(handle)) } - pub(super) fn entry() { + pub(super) fn entry() -> JoinNotifier { let mut pending_tasks = task_queue::lock(); let task = rtunwrap!(Some, pending_tasks.pop()); drop(pending_tasks); // make sure to not hold the task queue lock longer than necessary @@ -78,7 +131,7 @@ impl Thread { } pub fn join(self) { - let _ = self.0.recv(); + self.0.wait(); } } diff --git a/library/std/src/thread/local/tests.rs b/library/std/src/thread/local/tests.rs index 80e6798d847b1..494ad4e5fda9a 100644 --- a/library/std/src/thread/local/tests.rs +++ b/library/std/src/thread/local/tests.rs @@ -1,4 +1,5 @@ use crate::cell::{Cell, UnsafeCell}; +use crate::sync::atomic::{AtomicU8, Ordering}; use crate::sync::mpsc::{channel, Sender}; use crate::thread::{self, LocalKey}; use crate::thread_local; @@ -207,3 +208,109 @@ fn dtors_in_dtors_in_dtors_const_init() { }); rx.recv().unwrap(); } + +// This test tests that TLS destructors have run before the thread joins. The +// test has no false positives (meaning: if the test fails, there's actually +// an ordering problem). It may have false negatives, where the test passes but +// join is not guaranteed to be after the TLS destructors. However, false +// negatives should be exceedingly rare due to judicious use of +// thread::yield_now and running the test several times. +#[test] +fn join_orders_after_tls_destructors() { + // We emulate a synchronous MPSC rendezvous channel using only atomics and + // thread::yield_now. We can't use std::mpsc as the implementation itself + // may rely on thread locals. + // + // The basic state machine for an SPSC rendezvous channel is: + // FRESH -> THREAD1_WAITING -> MAIN_THREAD_RENDEZVOUS + // where the first transition is done by the “receiving” thread and the 2nd + // transition is done by the “sending” thread. + // + // We add an additional state `THREAD2_LAUNCHED` between `FRESH` and + // `THREAD1_WAITING` to block until all threads are actually running. + // + // A thread that joins on the “receiving” thread completion should never + // observe the channel in the `THREAD1_WAITING` state. If this does occur, + // we switch to the “poison” state `THREAD2_JOINED` and panic all around. + // (This is equivalent to “sending” from an alternate producer thread.) + const FRESH: u8 = 0; + const THREAD2_LAUNCHED: u8 = 1; + const THREAD1_WAITING: u8 = 2; + const MAIN_THREAD_RENDEZVOUS: u8 = 3; + const THREAD2_JOINED: u8 = 4; + static SYNC_STATE: AtomicU8 = AtomicU8::new(FRESH); + + for _ in 0..10 { + SYNC_STATE.store(FRESH, Ordering::SeqCst); + + let jh = thread::Builder::new() + .name("thread1".into()) + .spawn(move || { + struct TlDrop; + + impl Drop for TlDrop { + fn drop(&mut self) { + loop { + match SYNC_STATE.load(Ordering::SeqCst) { + FRESH => thread::yield_now(), + THREAD2_LAUNCHED => break, + v => unreachable!("sync state: {}", v), + } + } + let mut sync_state = SYNC_STATE.swap(THREAD1_WAITING, Ordering::SeqCst); + loop { + match sync_state { + THREAD2_LAUNCHED | THREAD1_WAITING => thread::yield_now(), + MAIN_THREAD_RENDEZVOUS => break, + THREAD2_JOINED => panic!( + "Thread 1 still running after thread 2 joined on thread 1" + ), + v => unreachable!("sync state: {}", v), + } + sync_state = SYNC_STATE.load(Ordering::SeqCst); + } + } + } + + thread_local! { + static TL_DROP: TlDrop = TlDrop; + } + + TL_DROP.with(|_| {}) + }) + .unwrap(); + + let jh2 = thread::Builder::new() + .name("thread2".into()) + .spawn(move || { + assert_eq!(SYNC_STATE.swap(THREAD2_LAUNCHED, Ordering::SeqCst), FRESH); + jh.join().unwrap(); + match SYNC_STATE.swap(THREAD2_JOINED, Ordering::SeqCst) { + MAIN_THREAD_RENDEZVOUS => return, + THREAD2_LAUNCHED | THREAD1_WAITING => { + panic!("Thread 2 running after thread 1 join before main thread rendezvous") + } + v => unreachable!("sync state: {:?}", v), + } + }) + .unwrap(); + + loop { + match SYNC_STATE.compare_exchange_weak( + THREAD1_WAITING, + MAIN_THREAD_RENDEZVOUS, + Ordering::SeqCst, + Ordering::SeqCst, + ) { + Ok(_) => break, + Err(FRESH) => thread::yield_now(), + Err(THREAD2_LAUNCHED) => thread::yield_now(), + Err(THREAD2_JOINED) => { + panic!("Main thread rendezvous after thread 2 joined thread 1") + } + v => unreachable!("sync state: {:?}", v), + } + } + jh2.join().unwrap(); + } +} diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index de9c1882c7d48..35e2a52917e93 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1110,6 +1110,19 @@ struct Compiletest { compare_mode: Option<&'static str>, } +impl Compiletest { + fn add_lld_flags(builder: &Builder<'_>, target: TargetSelection, flags: &mut Vec) { + if builder.config.use_lld { + if builder.is_fuse_ld_lld(target) { + flags.push("-Clink-arg=-fuse-ld=lld".to_string()); + } + + let threads = if target.contains("windows") { "/threads:1" } else { "--threads=1" }; + flags.push(format!("-Clink-arg=-Wl,{}", threads)); + } + } +} + impl Step for Compiletest { type Output = (); @@ -1197,7 +1210,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the .arg(builder.ensure(tool::JsonDocCk { compiler: json_compiler, target })); } - if mode == "run-make" && suite.ends_with("fulldeps") { + if mode == "run-make" && !suite.ends_with("fulldeps") { let rust_demangler = builder .ensure(tool::RustDemangler { compiler, target, extra_features: Vec::new() }) .expect("in-tree tool"); @@ -1250,18 +1263,12 @@ note: if you're sure you want to do this, please open an issue as to why. In the let mut hostflags = flags.clone(); hostflags.push(format!("-Lnative={}", builder.test_helpers_out(compiler.host).display())); - if builder.is_fuse_ld_lld(compiler.host) { - hostflags.push("-Clink-args=-fuse-ld=lld".to_string()); - hostflags.push("-Clink-arg=-Wl,--threads=1".to_string()); - } + Self::add_lld_flags(builder, compiler.host, &mut hostflags); cmd.arg("--host-rustcflags").arg(hostflags.join(" ")); let mut targetflags = flags; targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display())); - if builder.is_fuse_ld_lld(target) { - targetflags.push("-Clink-args=-fuse-ld=lld".to_string()); - targetflags.push("-Clink-arg=-Wl,--threads=1".to_string()); - } + Self::add_lld_flags(builder, target, &mut targetflags); cmd.arg("--target-rustcflags").arg(targetflags.join(" ")); cmd.arg("--docck-python").arg(builder.python()); diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index b3c67b84da617..f9a7599c49744 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -113,7 +113,7 @@ The `std` column in the table below has the following meanings: [`no_std`]: https://rust-embedded.github.io/book/intro/no-std.html target | std | notes --------|-----|------- +-------|:---:|------- `aarch64-apple-ios` | ✓ | ARM64 iOS `aarch64-fuchsia` | ✓ | ARM64 Fuchsia `aarch64-linux-android` | ✓ | ARM64 Android @@ -194,7 +194,7 @@ The `host` column indicates whether the codebase includes support for building host tools. target | std | host | notes --------|-----|------|------- +-------|:---:|:----:|------- `aarch64-apple-ios-macabi` | ? | | Apple Catalyst on ARM64 `aarch64-apple-ios-sim` | ? | | Apple iOS Simulator on ARM64 `aarch64-apple-tvos` | * | | ARM64 tvOS diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 293c0a40fa799..18e9e04e2a30e 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -6,7 +6,7 @@ use std::rc::Rc; use std::sync::mpsc::{channel, Receiver}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::edition::Edition; @@ -50,9 +50,6 @@ crate struct Context<'tcx> { pub(super) render_redirect_pages: bool, /// The map used to ensure all generated 'id=' attributes are unique. pub(super) id_map: RefCell, - /// Tracks section IDs for `Deref` targets so they match in both the main - /// body and the sidebar. - pub(super) deref_id_map: RefCell>, /// Shared mutable state. /// /// Issue for improving the situation: [#82381][] @@ -73,7 +70,7 @@ crate struct Context<'tcx> { // `Context` is cloned a lot, so we don't want the size to grow unexpectedly. #[cfg(target_arch = "x86_64")] -rustc_data_structures::static_assert_size!(Context<'_>, 152); +rustc_data_structures::static_assert_size!(Context<'_>, 112); /// Shared mutable state used in [`Context`] and elsewhere. crate struct SharedContext<'tcx> { @@ -474,7 +471,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { dst, render_redirect_pages: false, id_map: RefCell::new(id_map), - deref_id_map: RefCell::new(FxHashMap::default()), shared: Rc::new(scx), cache: Rc::new(cache), }; @@ -492,7 +488,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { dst: self.dst.clone(), render_redirect_pages: self.render_redirect_pages, id_map: RefCell::new(IdMap::new()), - deref_id_map: RefCell::new(FxHashMap::default()), shared: Rc::clone(&self.shared), cache: Rc::clone(&self.cache), } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 1271b54debd16..f98e8f680214d 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1017,17 +1017,12 @@ fn render_assoc_items( RenderMode::Normal } AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => { - let id = - cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx)))); - debug!("Adding {} to deref id map", type_.print(cx)); - cx.deref_id_map.borrow_mut().insert(type_.def_id_full(cache).unwrap(), id.clone()); write!( w, - "

\ + "

\ Methods from {trait_}<Target = {type_}>\ - \ + \

", - id = id, trait_ = trait_.print(cx), type_ = type_.print(cx), ); @@ -1052,6 +1047,9 @@ fn render_assoc_items( ); } } + if let AssocItemRender::DerefFor { .. } = what { + return; + } if !traits.is_empty() { let deref_impl = traits .iter() @@ -1062,13 +1060,6 @@ fn render_assoc_items( .any(|t| t.inner_impl().trait_.def_id_full(cache) == cx.cache.deref_mut_trait_did); render_deref_methods(w, cx, impl_, containing_item, has_deref_mut); } - - // If we were already one level into rendering deref methods, we don't want to render - // anything after recursing into any further deref methods above. - if let AssocItemRender::DerefFor { .. } = what { - return; - } - let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = traits.iter().partition(|t| t.inner_impl().synthetic); let (blanket_impl, concrete): (Vec<&&Impl>, _) = @@ -1960,14 +1951,9 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V .flat_map(|i| get_methods(i.inner_impl(), true, &mut used_links, deref_mut, c)) .collect::>(); if !ret.is_empty() { - let deref_id_map = cx.deref_id_map.borrow(); - let id = deref_id_map - .get(&real_target.def_id_full(c).unwrap()) - .expect("Deref section without derived id"); write!( out, - "Methods from {}<Target={}>", - id, + "Methods from {}<Target={}>", Escape(&format!("{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print(cx))), Escape(&format!("{:#}", real_target.print(cx))), ); diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 7b0b2f28fdfff..12f16c9359235 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -3,7 +3,7 @@ use crate::clean::*; use crate::core::DocContext; use crate::fold::DocFolder; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::ty::DefIdTree; use rustc_span::symbol::sym; @@ -53,6 +53,39 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate { } } + let mut cleaner = BadImplStripper { prims, items: crate_items }; + + // scan through included items ahead of time to splice in Deref targets to the "valid" sets + for it in &new_items { + if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind { + if cleaner.keep_impl(for_) && trait_.def_id() == cx.tcx.lang_items().deref_trait() { + let target = items + .iter() + .find_map(|item| match *item.kind { + TypedefItem(ref t, true) => Some(&t.type_), + _ => None, + }) + .expect("Deref impl without Target type"); + + if let Some(prim) = target.primitive_type() { + cleaner.prims.insert(prim); + } else if let Some(did) = target.def_id() { + cleaner.items.insert(did); + } + } + } + } + + new_items.retain(|it| { + if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind { + cleaner.keep_impl(for_) + || trait_.as_ref().map_or(false, |t| cleaner.keep_impl(t)) + || blanket_impl.is_some() + } else { + true + } + }); + // `tcx.crates()` doesn't include the local crate, and `tcx.all_trait_implementations` // doesn't work with it anyway, so pull them from the HIR map instead let mut extra_attrs = Vec::new(); @@ -84,53 +117,6 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate { } } - let mut cleaner = BadImplStripper { prims, items: crate_items }; - - let mut type_did_to_deref_target: FxHashMap = FxHashMap::default(); - // Gather all type to `Deref` target edges. - for it in &new_items { - if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind { - if trait_.def_id() == cx.tcx.lang_items().deref_trait() { - let target = items.iter().find_map(|item| match *item.kind { - TypedefItem(ref t, true) => Some(&t.type_), - _ => None, - }); - if let (Some(for_did), Some(target)) = (for_.def_id(), target) { - type_did_to_deref_target.insert(for_did, target); - } - } - } - } - // Follow all `Deref` targets of included items and recursively add them as valid - fn add_deref_target( - map: &FxHashMap, - cleaner: &mut BadImplStripper, - type_did: &DefId, - ) { - if let Some(target) = map.get(type_did) { - debug!("add_deref_target: type {:?}, target {:?}", type_did, target); - if let Some(target_prim) = target.primitive_type() { - cleaner.prims.insert(target_prim); - } else if let Some(target_did) = target.def_id() { - // `impl Deref for S` - if target_did == *type_did { - // Avoid infinite cycles - return; - } - cleaner.items.insert(target_did); - add_deref_target(map, cleaner, &target_did); - } - } - } - for type_did in type_did_to_deref_target.keys() { - // Since only the `DefId` portion of the `Type` instances is known to be same for both the - // `Deref` target type and the impl for type positions, this map of types is keyed by - // `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly. - if cleaner.keep_impl_with_def_id(type_did) { - add_deref_target(&type_did_to_deref_target, &mut cleaner, type_did); - } - } - let items = if let ModuleItem(Module { ref mut items, .. }) = *krate.module.kind { items } else { @@ -138,19 +124,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate { }; items.extend(synth_impls); - for it in new_items.drain(..) { - if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind { - if !(cleaner.keep_impl(for_) - || trait_.as_ref().map_or(false, |t| cleaner.keep_impl(t)) - || blanket_impl.is_some()) - { - continue; - } - } - - items.push(it); - } - + items.extend(new_items); krate } @@ -204,13 +178,9 @@ impl BadImplStripper { } else if let Some(prim) = ty.primitive_type() { self.prims.contains(&prim) } else if let Some(did) = ty.def_id() { - self.keep_impl_with_def_id(&did) + self.items.contains(&did) } else { false } } - - fn keep_impl_with_def_id(&self, did: &DefId) -> bool { - self.items.contains(did) - } } diff --git a/src/test/run-make-fulldeps/coverage/compiletest-ignore-dir b/src/test/run-make-fulldeps/coverage/compiletest-ignore-dir deleted file mode 100644 index d1824d189e382..0000000000000 --- a/src/test/run-make-fulldeps/coverage/compiletest-ignore-dir +++ /dev/null @@ -1,3 +0,0 @@ -# Directory "coverage" supports the tests at prefix ../coverage-* - -# Use ./x.py [options] test src/test/run-make-fulldeps/coverage to run all related tests. diff --git a/src/test/run-make-fulldeps/coverage/coverage_tools.mk b/src/test/run-make-fulldeps/coverage/coverage_tools.mk deleted file mode 100644 index aa1dc7b91ce94..0000000000000 --- a/src/test/run-make-fulldeps/coverage/coverage_tools.mk +++ /dev/null @@ -1,6 +0,0 @@ -# Common Makefile include for Rust `run-make-fulldeps/coverage-* tests. Include this -# file with the line: -# -# -include ../coverage/coverage_tools.mk - --include ../tools.mk diff --git a/src/test/run-make-fulldeps/coverage-llvmir/Makefile b/src/test/run-make/coverage-llvmir/Makefile similarity index 100% rename from src/test/run-make-fulldeps/coverage-llvmir/Makefile rename to src/test/run-make/coverage-llvmir/Makefile diff --git a/src/test/run-make-fulldeps/coverage-llvmir/filecheck.testprog.txt b/src/test/run-make/coverage-llvmir/filecheck.testprog.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-llvmir/filecheck.testprog.txt rename to src/test/run-make/coverage-llvmir/filecheck.testprog.txt diff --git a/src/test/run-make-fulldeps/coverage-llvmir/testprog.rs b/src/test/run-make/coverage-llvmir/testprog.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage-llvmir/testprog.rs rename to src/test/run-make/coverage-llvmir/testprog.rs diff --git a/src/test/run-make-fulldeps/coverage-reports/Makefile b/src/test/run-make/coverage-reports/Makefile similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/Makefile rename to src/test/run-make/coverage-reports/Makefile diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.abort.txt b/src/test/run-make/coverage-reports/expected_show_coverage.abort.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.abort.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.abort.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt b/src/test/run-make/coverage-reports/expected_show_coverage.assert.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.assert.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt b/src/test/run-make/coverage-reports/expected_show_coverage.async.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.async.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async2.txt b/src/test/run-make/coverage-reports/expected_show_coverage.async2.txt similarity index 99% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async2.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.async2.txt index 8a445433ab65f..a8c79efd72356 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async2.txt +++ b/src/test/run-make/coverage-reports/expected_show_coverage.async2.txt @@ -12,6 +12,7 @@ 12| 1| if b { 13| 1| println!("non_async_func println in block"); 14| 1| } + ^0 15| 1|} 16| | 17| |// FIXME(#83985): The auto-generated closure in an async function is failing to include diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure.txt b/src/test/run-make/coverage-reports/expected_show_coverage.closure.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.closure.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure_macro.txt b/src/test/run-make/coverage-reports/expected_show_coverage.closure_macro.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure_macro.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.closure_macro.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure_macro_async.txt b/src/test/run-make/coverage-reports/expected_show_coverage.closure_macro_async.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure_macro_async.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.closure_macro_async.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.conditions.txt b/src/test/run-make/coverage-reports/expected_show_coverage.conditions.txt similarity index 93% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.conditions.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.conditions.txt index 656a26597759d..2d8a98a5d0c92 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.conditions.txt +++ b/src/test/run-make/coverage-reports/expected_show_coverage.conditions.txt @@ -5,6 +5,7 @@ 5| 1| if true { 6| 1| countdown = 10; 7| 1| } + ^0 8| | 9| | const B: u32 = 100; 10| 1| let x = if countdown > 7 { @@ -24,6 +25,7 @@ 24| 1| if true { 25| 1| countdown = 10; 26| 1| } + ^0 27| | 28| 1| if countdown > 7 { 29| 1| countdown -= 4; @@ -42,6 +44,7 @@ 41| 1| if true { 42| 1| countdown = 10; 43| 1| } + ^0 44| | 45| 1| if countdown > 7 { 46| 1| countdown -= 4; @@ -54,13 +57,14 @@ 53| | } else { 54| 0| return; 55| | } - 56| | } // Note: closing brace shows uncovered (vs. `0` for implicit else) because condition literal - 57| | // `true` was const-evaluated. The compiler knows the `if` block will be executed. + 56| 0| } + 57| | 58| | 59| 1| let mut countdown = 0; 60| 1| if true { 61| 1| countdown = 1; 62| 1| } + ^0 63| | 64| 1| let z = if countdown > 7 { ^0 diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.continue.txt b/src/test/run-make/coverage-reports/expected_show_coverage.continue.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.continue.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.continue.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.dead_code.txt b/src/test/run-make/coverage-reports/expected_show_coverage.dead_code.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.dead_code.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.dead_code.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt b/src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt similarity index 98% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt index 1b6bb9ff8891d..7ae0e978808e7 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt +++ b/src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt @@ -9,7 +9,7 @@ 8| 1|//! assert_eq!(1, 1); 9| |//! } else { 10| |//! // this is not! - 11| |//! assert_eq!(1, 2); + 11| 0|//! assert_eq!(1, 2); 12| |//! } 13| 1|//! ``` 14| |//! @@ -84,7 +84,7 @@ 74| 1| if true { 75| 1| assert_eq!(1, 1); 76| | } else { - 77| | assert_eq!(1, 2); + 77| 0| assert_eq!(1, 2); 78| | } 79| 1|} 80| | diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.drop_trait.txt b/src/test/run-make/coverage-reports/expected_show_coverage.drop_trait.txt similarity index 87% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.drop_trait.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.drop_trait.txt index fab5be41901c9..fe6a9e93cbf71 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.drop_trait.txt +++ b/src/test/run-make/coverage-reports/expected_show_coverage.drop_trait.txt @@ -19,11 +19,11 @@ 19| 1| if true { 20| 1| println!("Exiting with error..."); 21| 1| return Err(1); - 22| | } - 23| | - 24| | let _ = Firework { strength: 1000 }; - 25| | - 26| | Ok(()) + 22| 0| } + 23| 0| + 24| 0| let _ = Firework { strength: 1000 }; + 25| 0| + 26| 0| Ok(()) 27| 1|} 28| | 29| |// Expected program output: diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.generics.txt b/src/test/run-make/coverage-reports/expected_show_coverage.generics.txt similarity index 78% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.generics.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.generics.txt index 7b38ffb87cba8..8e8bc0fd18943 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.generics.txt +++ b/src/test/run-make/coverage-reports/expected_show_coverage.generics.txt @@ -52,15 +52,15 @@ 30| 1| if true { 31| 1| println!("Exiting with error..."); 32| 1| return Err(1); - 33| | } // The remaining lines below have no coverage because `if true` (with the constant literal - 34| | // `true`) is guaranteed to execute the `then` block, which is also guaranteed to `return`. - 35| | // Thankfully, in the normal case, conditions are not guaranteed ahead of time, and as shown - 36| | // in other tests, the lines below would have coverage (which would show they had `0` - 37| | // executions, assuming the condition still evaluated to `true`). - 38| | - 39| | let _ = Firework { strength: 1000 }; - 40| | - 41| | Ok(()) + 33| 0| } + 34| 0| + 35| 0| + 36| 0| + 37| 0| + 38| 0| + 39| 0| let _ = Firework { strength: 1000 }; + 40| 0| + 41| 0| Ok(()) 42| 1|} 43| | 44| |// Expected program output: diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.if.txt b/src/test/run-make/coverage-reports/expected_show_coverage.if.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.if.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.if.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.if_else.txt b/src/test/run-make/coverage-reports/expected_show_coverage.if_else.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.if_else.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.if_else.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline.txt b/src/test/run-make/coverage-reports/expected_show_coverage.inline.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.inline.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inner_items.txt b/src/test/run-make/coverage-reports/expected_show_coverage.inner_items.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inner_items.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.inner_items.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-83601.txt b/src/test/run-make/coverage-reports/expected_show_coverage.issue-83601.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-83601.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.issue-83601.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-84561.txt b/src/test/run-make/coverage-reports/expected_show_coverage.issue-84561.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-84561.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.issue-84561.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.lazy_boolean.txt b/src/test/run-make/coverage-reports/expected_show_coverage.lazy_boolean.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.lazy_boolean.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.lazy_boolean.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.loop_break_value.txt b/src/test/run-make/coverage-reports/expected_show_coverage.loop_break_value.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.loop_break_value.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.loop_break_value.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.loops_branches.txt b/src/test/run-make/coverage-reports/expected_show_coverage.loops_branches.txt similarity index 68% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.loops_branches.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.loops_branches.txt index 81d5c7d90346d..5d572db7cc60d 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.loops_branches.txt +++ b/src/test/run-make/coverage-reports/expected_show_coverage.loops_branches.txt @@ -9,23 +9,23 @@ 9| 1| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 10| 1| if true { 11| 1| if false { - 12| | while true { - 13| | } + 12| 0| while true { + 13| 0| } 14| 1| } - 15| 1| write!(f, "error")?; - ^0 - 16| | } else { - 17| | } + 15| 1| write!(f, "cool")?; + ^0 + 16| 0| } else { + 17| 0| } 18| | 19| 10| for i in 0..10 { 20| 10| if true { 21| 10| if false { - 22| | while true {} + 22| 0| while true {} 23| 10| } - 24| 10| write!(f, "error")?; - ^0 - 25| | } else { - 26| | } + 24| 10| write!(f, "cool")?; + ^0 + 25| 0| } else { + 26| 0| } 27| | } 28| 1| Ok(()) 29| 1| } @@ -36,21 +36,21 @@ 34| |impl std::fmt::Display for DisplayTest { 35| 1| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 36| 1| if false { - 37| | } else { + 37| 0| } else { 38| 1| if false { - 39| | while true {} + 39| 0| while true {} 40| 1| } - 41| 1| write!(f, "error")?; - ^0 + 41| 1| write!(f, "cool")?; + ^0 42| | } 43| 10| for i in 0..10 { 44| 10| if false { - 45| | } else { + 45| 0| } else { 46| 10| if false { - 47| | while true {} + 47| 0| while true {} 48| 10| } - 49| 10| write!(f, "error")?; - ^0 + 49| 10| write!(f, "cool")?; + ^0 50| | } 51| | } 52| 1| Ok(()) diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.match_or_pattern.txt b/src/test/run-make/coverage-reports/expected_show_coverage.match_or_pattern.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.match_or_pattern.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.match_or_pattern.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.nested_loops.txt b/src/test/run-make/coverage-reports/expected_show_coverage.nested_loops.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.nested_loops.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.nested_loops.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.no_cov_crate.txt b/src/test/run-make/coverage-reports/expected_show_coverage.no_cov_crate.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.no_cov_crate.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.no_cov_crate.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.no_cov_func.txt b/src/test/run-make/coverage-reports/expected_show_coverage.no_cov_func.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.no_cov_func.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.no_cov_func.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt b/src/test/run-make/coverage-reports/expected_show_coverage.overflow.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.overflow.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt b/src/test/run-make/coverage-reports/expected_show_coverage.panic_unwind.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.panic_unwind.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.partial_eq.txt b/src/test/run-make/coverage-reports/expected_show_coverage.partial_eq.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.partial_eq.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.partial_eq.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.simple_loop.txt b/src/test/run-make/coverage-reports/expected_show_coverage.simple_loop.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.simple_loop.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.simple_loop.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.simple_match.txt b/src/test/run-make/coverage-reports/expected_show_coverage.simple_match.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.simple_match.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.simple_match.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.tight_inf_loop.txt b/src/test/run-make/coverage-reports/expected_show_coverage.tight_inf_loop.txt similarity index 75% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.tight_inf_loop.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.tight_inf_loop.txt index 5adeef7d0850b..2d4c57f451a2d 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.tight_inf_loop.txt +++ b/src/test/run-make/coverage-reports/expected_show_coverage.tight_inf_loop.txt @@ -1,6 +1,6 @@ 1| 1|fn main() { 2| 1| if false { - 3| | loop {} + 3| 0| loop {} 4| 1| } 5| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.try_error_result.txt b/src/test/run-make/coverage-reports/expected_show_coverage.try_error_result.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.try_error_result.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.try_error_result.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.unused.txt b/src/test/run-make/coverage-reports/expected_show_coverage.unused.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.unused.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.unused.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt b/src/test/run-make/coverage-reports/expected_show_coverage.uses_crate.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.uses_crate.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt b/src/test/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_inline_crate.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.while.txt b/src/test/run-make/coverage-reports/expected_show_coverage.while.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.while.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.while.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.while_early_ret.txt b/src/test/run-make/coverage-reports/expected_show_coverage.while_early_ret.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.while_early_ret.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.while_early_ret.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.yield.txt b/src/test/run-make/coverage-reports/expected_show_coverage.yield.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.yield.txt rename to src/test/run-make/coverage-reports/expected_show_coverage.yield.txt diff --git a/src/test/run-make-fulldeps/coverage-reports/normalize_paths.py b/src/test/run-make/coverage-reports/normalize_paths.py similarity index 100% rename from src/test/run-make-fulldeps/coverage-reports/normalize_paths.py rename to src/test/run-make/coverage-reports/normalize_paths.py diff --git a/src/test/run-make-fulldeps/coverage/WARNING_KEEP_NAMES_SHORT.txt b/src/test/run-make/coverage/WARNING_KEEP_NAMES_SHORT.txt similarity index 100% rename from src/test/run-make-fulldeps/coverage/WARNING_KEEP_NAMES_SHORT.txt rename to src/test/run-make/coverage/WARNING_KEEP_NAMES_SHORT.txt diff --git a/src/test/run-make-fulldeps/coverage/abort.rs b/src/test/run-make/coverage/abort.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/abort.rs rename to src/test/run-make/coverage/abort.rs diff --git a/src/test/run-make-fulldeps/coverage/assert.rs b/src/test/run-make/coverage/assert.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/assert.rs rename to src/test/run-make/coverage/assert.rs diff --git a/src/test/run-make-fulldeps/coverage/async.rs b/src/test/run-make/coverage/async.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/async.rs rename to src/test/run-make/coverage/async.rs diff --git a/src/test/run-make-fulldeps/coverage/async2.rs b/src/test/run-make/coverage/async2.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/async2.rs rename to src/test/run-make/coverage/async2.rs diff --git a/src/test/run-make-fulldeps/coverage/closure.rs b/src/test/run-make/coverage/closure.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/closure.rs rename to src/test/run-make/coverage/closure.rs diff --git a/src/test/run-make-fulldeps/coverage/closure_macro.rs b/src/test/run-make/coverage/closure_macro.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/closure_macro.rs rename to src/test/run-make/coverage/closure_macro.rs diff --git a/src/test/run-make-fulldeps/coverage/closure_macro_async.rs b/src/test/run-make/coverage/closure_macro_async.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/closure_macro_async.rs rename to src/test/run-make/coverage/closure_macro_async.rs diff --git a/src/test/run-make/coverage/compiletest-ignore-dir b/src/test/run-make/coverage/compiletest-ignore-dir new file mode 100644 index 0000000000000..b533b272d38cf --- /dev/null +++ b/src/test/run-make/coverage/compiletest-ignore-dir @@ -0,0 +1,3 @@ +# Directory "coverage" supports the tests at prefix ../coverage-* + +# Use ./x.py [options] test src/test/run-make/coverage to run all related tests. diff --git a/src/test/run-make-fulldeps/coverage/conditions.rs b/src/test/run-make/coverage/conditions.rs similarity index 90% rename from src/test/run-make-fulldeps/coverage/conditions.rs rename to src/test/run-make/coverage/conditions.rs index 8a2a0b53e5862..057599d1b471a 100644 --- a/src/test/run-make-fulldeps/coverage/conditions.rs +++ b/src/test/run-make/coverage/conditions.rs @@ -53,8 +53,8 @@ fn main() { } else { return; } - } // Note: closing brace shows uncovered (vs. `0` for implicit else) because condition literal - // `true` was const-evaluated. The compiler knows the `if` block will be executed. + } + let mut countdown = 0; if true { diff --git a/src/test/run-make-fulldeps/coverage/continue.rs b/src/test/run-make/coverage/continue.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/continue.rs rename to src/test/run-make/coverage/continue.rs diff --git a/src/test/run-make/coverage/coverage_tools.mk b/src/test/run-make/coverage/coverage_tools.mk new file mode 100644 index 0000000000000..8fce5f1b958fc --- /dev/null +++ b/src/test/run-make/coverage/coverage_tools.mk @@ -0,0 +1,6 @@ +# Common Makefile include for Rust `run-make/coverage-* tests. Include this +# file with the line: +# +# -include ../coverage/coverage_tools.mk + +-include ../../run-make-fulldeps/tools.mk diff --git a/src/test/run-make-fulldeps/coverage/dead_code.rs b/src/test/run-make/coverage/dead_code.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/dead_code.rs rename to src/test/run-make/coverage/dead_code.rs diff --git a/src/test/run-make-fulldeps/coverage/doctest.rs b/src/test/run-make/coverage/doctest.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/doctest.rs rename to src/test/run-make/coverage/doctest.rs diff --git a/src/test/run-make-fulldeps/coverage/drop_trait.rs b/src/test/run-make/coverage/drop_trait.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/drop_trait.rs rename to src/test/run-make/coverage/drop_trait.rs diff --git a/src/test/run-make-fulldeps/coverage/generics.rs b/src/test/run-make/coverage/generics.rs similarity index 67% rename from src/test/run-make-fulldeps/coverage/generics.rs rename to src/test/run-make/coverage/generics.rs index cbeda35d3b8cf..18b38868496d4 100644 --- a/src/test/run-make-fulldeps/coverage/generics.rs +++ b/src/test/run-make/coverage/generics.rs @@ -30,11 +30,11 @@ fn main() -> Result<(),u8> { if true { println!("Exiting with error..."); return Err(1); - } // The remaining lines below have no coverage because `if true` (with the constant literal - // `true`) is guaranteed to execute the `then` block, which is also guaranteed to `return`. - // Thankfully, in the normal case, conditions are not guaranteed ahead of time, and as shown - // in other tests, the lines below would have coverage (which would show they had `0` - // executions, assuming the condition still evaluated to `true`). + } + + + + let _ = Firework { strength: 1000 }; diff --git a/src/test/run-make-fulldeps/coverage/if.rs b/src/test/run-make/coverage/if.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/if.rs rename to src/test/run-make/coverage/if.rs diff --git a/src/test/run-make-fulldeps/coverage/if_else.rs b/src/test/run-make/coverage/if_else.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/if_else.rs rename to src/test/run-make/coverage/if_else.rs diff --git a/src/test/run-make-fulldeps/coverage/inline.rs b/src/test/run-make/coverage/inline.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/inline.rs rename to src/test/run-make/coverage/inline.rs diff --git a/src/test/run-make-fulldeps/coverage/inner_items.rs b/src/test/run-make/coverage/inner_items.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/inner_items.rs rename to src/test/run-make/coverage/inner_items.rs diff --git a/src/test/run-make-fulldeps/coverage/issue-83601.rs b/src/test/run-make/coverage/issue-83601.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/issue-83601.rs rename to src/test/run-make/coverage/issue-83601.rs diff --git a/src/test/run-make-fulldeps/coverage/issue-84561.rs b/src/test/run-make/coverage/issue-84561.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/issue-84561.rs rename to src/test/run-make/coverage/issue-84561.rs diff --git a/src/test/run-make-fulldeps/coverage/lazy_boolean.rs b/src/test/run-make/coverage/lazy_boolean.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/lazy_boolean.rs rename to src/test/run-make/coverage/lazy_boolean.rs diff --git a/src/test/run-make-fulldeps/coverage/lib/doctest_crate.rs b/src/test/run-make/coverage/lib/doctest_crate.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/lib/doctest_crate.rs rename to src/test/run-make/coverage/lib/doctest_crate.rs diff --git a/src/test/run-make-fulldeps/coverage/lib/used_crate.rs b/src/test/run-make/coverage/lib/used_crate.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/lib/used_crate.rs rename to src/test/run-make/coverage/lib/used_crate.rs diff --git a/src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs b/src/test/run-make/coverage/lib/used_inline_crate.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/lib/used_inline_crate.rs rename to src/test/run-make/coverage/lib/used_inline_crate.rs diff --git a/src/test/run-make-fulldeps/coverage/loop_break_value.rs b/src/test/run-make/coverage/loop_break_value.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/loop_break_value.rs rename to src/test/run-make/coverage/loop_break_value.rs diff --git a/src/test/run-make-fulldeps/coverage/loops_branches.rs b/src/test/run-make/coverage/loops_branches.rs similarity index 90% rename from src/test/run-make-fulldeps/coverage/loops_branches.rs rename to src/test/run-make/coverage/loops_branches.rs index 4d9bbad3367f6..7116ce47f4b9d 100644 --- a/src/test/run-make-fulldeps/coverage/loops_branches.rs +++ b/src/test/run-make/coverage/loops_branches.rs @@ -12,7 +12,7 @@ impl std::fmt::Debug for DebugTest { while true { } } - write!(f, "error")?; + write!(f, "cool")?; } else { } @@ -21,7 +21,7 @@ impl std::fmt::Debug for DebugTest { if false { while true {} } - write!(f, "error")?; + write!(f, "cool")?; } else { } } @@ -38,7 +38,7 @@ impl std::fmt::Display for DisplayTest { if false { while true {} } - write!(f, "error")?; + write!(f, "cool")?; } for i in 0..10 { if false { @@ -46,7 +46,7 @@ impl std::fmt::Display for DisplayTest { if false { while true {} } - write!(f, "error")?; + write!(f, "cool")?; } } Ok(()) diff --git a/src/test/run-make-fulldeps/coverage/match_or_pattern.rs b/src/test/run-make/coverage/match_or_pattern.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/match_or_pattern.rs rename to src/test/run-make/coverage/match_or_pattern.rs diff --git a/src/test/run-make-fulldeps/coverage/nested_loops.rs b/src/test/run-make/coverage/nested_loops.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/nested_loops.rs rename to src/test/run-make/coverage/nested_loops.rs diff --git a/src/test/run-make-fulldeps/coverage/no_cov_crate.rs b/src/test/run-make/coverage/no_cov_crate.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/no_cov_crate.rs rename to src/test/run-make/coverage/no_cov_crate.rs diff --git a/src/test/run-make-fulldeps/coverage/no_cov_func.rs b/src/test/run-make/coverage/no_cov_func.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/no_cov_func.rs rename to src/test/run-make/coverage/no_cov_func.rs diff --git a/src/test/run-make-fulldeps/coverage/overflow.rs b/src/test/run-make/coverage/overflow.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/overflow.rs rename to src/test/run-make/coverage/overflow.rs diff --git a/src/test/run-make-fulldeps/coverage/panic_unwind.rs b/src/test/run-make/coverage/panic_unwind.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/panic_unwind.rs rename to src/test/run-make/coverage/panic_unwind.rs diff --git a/src/test/run-make-fulldeps/coverage/partial_eq.rs b/src/test/run-make/coverage/partial_eq.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/partial_eq.rs rename to src/test/run-make/coverage/partial_eq.rs diff --git a/src/test/run-make-fulldeps/coverage/simple_loop.rs b/src/test/run-make/coverage/simple_loop.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/simple_loop.rs rename to src/test/run-make/coverage/simple_loop.rs diff --git a/src/test/run-make-fulldeps/coverage/simple_match.rs b/src/test/run-make/coverage/simple_match.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/simple_match.rs rename to src/test/run-make/coverage/simple_match.rs diff --git a/src/test/run-make-fulldeps/coverage/tight_inf_loop.rs b/src/test/run-make/coverage/tight_inf_loop.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/tight_inf_loop.rs rename to src/test/run-make/coverage/tight_inf_loop.rs diff --git a/src/test/run-make-fulldeps/coverage/try_error_result.rs b/src/test/run-make/coverage/try_error_result.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/try_error_result.rs rename to src/test/run-make/coverage/try_error_result.rs diff --git a/src/test/run-make-fulldeps/coverage/unused.rs b/src/test/run-make/coverage/unused.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/unused.rs rename to src/test/run-make/coverage/unused.rs diff --git a/src/test/run-make-fulldeps/coverage/uses_crate.rs b/src/test/run-make/coverage/uses_crate.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/uses_crate.rs rename to src/test/run-make/coverage/uses_crate.rs diff --git a/src/test/run-make-fulldeps/coverage/uses_inline_crate.rs b/src/test/run-make/coverage/uses_inline_crate.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/uses_inline_crate.rs rename to src/test/run-make/coverage/uses_inline_crate.rs diff --git a/src/test/run-make-fulldeps/coverage/while.rs b/src/test/run-make/coverage/while.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/while.rs rename to src/test/run-make/coverage/while.rs diff --git a/src/test/run-make-fulldeps/coverage/while_early_ret.rs b/src/test/run-make/coverage/while_early_ret.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/while_early_ret.rs rename to src/test/run-make/coverage/while_early_ret.rs diff --git a/src/test/run-make-fulldeps/coverage/yield.rs b/src/test/run-make/coverage/yield.rs similarity index 100% rename from src/test/run-make-fulldeps/coverage/yield.rs rename to src/test/run-make/coverage/yield.rs diff --git a/src/test/rustdoc-ui/deref-recursive-cycle.rs b/src/test/rustdoc-ui/deref-recursive-cycle.rs deleted file mode 100644 index 4cb518cbbbd5c..0000000000000 --- a/src/test/rustdoc-ui/deref-recursive-cycle.rs +++ /dev/null @@ -1,17 +0,0 @@ -// check-pass -// #26207: Ensure `Deref` cycles are properly handled without errors. - -#[derive(Copy, Clone)] -struct S; - -impl std::ops::Deref for S { - type Target = S; - - fn deref(&self) -> &S { - self - } -} - -fn main() { - let s: S = *******S; -} diff --git a/src/test/rustdoc/deref-recursive-pathbuf.rs b/src/test/rustdoc/deref-recursive-pathbuf.rs deleted file mode 100644 index 459a30060c623..0000000000000 --- a/src/test/rustdoc/deref-recursive-pathbuf.rs +++ /dev/null @@ -1,24 +0,0 @@ -// #26207: Show all methods reachable via Deref impls, recursing through multiple dereferencing -// levels and across multiple crates. - -// @has 'foo/struct.Foo.html' -// @has '-' '//*[@id="deref-methods-PathBuf"]' 'Methods from Deref' -// @has '-' '//*[@class="impl-items"]//*[@id="method.as_path"]' 'pub fn as_path(&self)' -// @has '-' '//*[@id="deref-methods-Path"]' 'Methods from Deref' -// @has '-' '//*[@class="impl-items"]//*[@id="method.exists"]' 'pub fn exists(&self)' -// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-PathBuf"]' 'Methods from Deref' -// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.as_path"]' 'as_path' -// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-Path"]' 'Methods from Deref' -// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.exists"]' 'exists' - -#![crate_name = "foo"] - -use std::ops::Deref; -use std::path::PathBuf; - -pub struct Foo(PathBuf); - -impl Deref for Foo { - type Target = PathBuf; - fn deref(&self) -> &PathBuf { &self.0 } -} diff --git a/src/test/rustdoc/deref-recursive.rs b/src/test/rustdoc/deref-recursive.rs deleted file mode 100644 index b96b5397ad78b..0000000000000 --- a/src/test/rustdoc/deref-recursive.rs +++ /dev/null @@ -1,40 +0,0 @@ -// #26207: Show all methods reachable via Deref impls, recursing through multiple dereferencing -// levels if needed. - -// @has 'foo/struct.Foo.html' -// @has '-' '//*[@id="deref-methods-Bar"]' 'Methods from Deref' -// @has '-' '//*[@class="impl-items"]//*[@id="method.bar"]' 'pub fn bar(&self)' -// @has '-' '//*[@id="deref-methods-Baz"]' 'Methods from Deref' -// @has '-' '//*[@class="impl-items"]//*[@id="method.baz"]' 'pub fn baz(&self)' -// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-Bar"]' 'Methods from Deref' -// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.bar"]' 'bar' -// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-Baz"]' 'Methods from Deref' -// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.baz"]' 'baz' - -#![crate_name = "foo"] - -use std::ops::Deref; - -pub struct Foo(Bar); -pub struct Bar(Baz); -pub struct Baz; - -impl Deref for Foo { - type Target = Bar; - fn deref(&self) -> &Bar { &self.0 } -} - -impl Deref for Bar { - type Target = Baz; - fn deref(&self) -> &Baz { &self.0 } -} - -impl Bar { - /// This appears under `Foo` methods - pub fn bar(&self) {} -} - -impl Baz { - /// This should also appear in `Foo` methods when recursing - pub fn baz(&self) {} -} diff --git a/src/test/rustdoc/deref-typedef.rs b/src/test/rustdoc/deref-typedef.rs index 47009559e6f74..3fc48b46d7410 100644 --- a/src/test/rustdoc/deref-typedef.rs +++ b/src/test/rustdoc/deref-typedef.rs @@ -1,12 +1,12 @@ #![crate_name = "foo"] // @has 'foo/struct.Bar.html' -// @has '-' '//*[@id="deref-methods-FooJ"]' 'Methods from Deref' +// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref' // @has '-' '//*[@class="impl-items"]//*[@id="method.foo_a"]' 'pub fn foo_a(&self)' // @has '-' '//*[@class="impl-items"]//*[@id="method.foo_b"]' 'pub fn foo_b(&self)' // @has '-' '//*[@class="impl-items"]//*[@id="method.foo_c"]' 'pub fn foo_c(&self)' // @has '-' '//*[@class="impl-items"]//*[@id="method.foo_j"]' 'pub fn foo_j(&self)' -// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods-FooJ"]' 'Methods from Deref' +// @has '-' '//*[@class="sidebar-title"][@href="#deref-methods"]' 'Methods from Deref' // @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_a"]' 'foo_a' // @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_b"]' 'foo_b' // @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_c"]' 'foo_c' diff --git a/src/test/rustdoc/issue-82465-asref-for-and-of-local.rs b/src/test/rustdoc/issue-82465-asref-for-and-of-local.rs new file mode 100644 index 0000000000000..618ac20ac487d --- /dev/null +++ b/src/test/rustdoc/issue-82465-asref-for-and-of-local.rs @@ -0,0 +1,16 @@ +use std::convert::AsRef; +pub struct Local; + +// @has issue_82465_asref_for_and_of_local/struct.Local.html '//code' 'impl AsRef for Local' +impl AsRef for Local { + fn as_ref(&self) -> &str { + todo!() + } +} + +// @has - '//code' 'impl AsRef for str' +impl AsRef for str { + fn as_ref(&self) -> &Local { + todo!() + } +} diff --git a/src/test/ui/associated-consts/associated-const-dead-code.stderr b/src/test/ui/associated-consts/associated-const-dead-code.stderr index 9b6bbb68a71f7..e9915ba9e96a5 100644 --- a/src/test/ui/associated-consts/associated-const-dead-code.stderr +++ b/src/test/ui/associated-consts/associated-const-dead-code.stderr @@ -2,8 +2,11 @@ error: associated constant is never used: `BAR` --> $DIR/associated-const-dead-code.rs:6:5 | LL | const BAR: u32 = 1; - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^---^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_BAR` | + = note: the leading underscore signals that this associated constant serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/associated-const-dead-code.rs:1:9 | diff --git a/src/test/ui/derive-uninhabited-enum-38885.stderr b/src/test/ui/derive-uninhabited-enum-38885.stderr index 72607629d3c10..ff8fb9953fb53 100644 --- a/src/test/ui/derive-uninhabited-enum-38885.stderr +++ b/src/test/ui/derive-uninhabited-enum-38885.stderr @@ -2,8 +2,11 @@ warning: variant is never constructed: `Void` --> $DIR/derive-uninhabited-enum-38885.rs:13:5 | LL | Void(Void), - | ^^^^^^^^^^ + | ----^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_Void` | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. = note: `-W dead-code` implied by `-W unused` warning: 1 warning emitted diff --git a/src/test/ui/issues/issue-37515.stderr b/src/test/ui/issues/issue-37515.stderr index 204a39bc8e8e9..3223554a5b778 100644 --- a/src/test/ui/issues/issue-37515.stderr +++ b/src/test/ui/issues/issue-37515.stderr @@ -2,8 +2,11 @@ warning: type alias is never used: `Z` --> $DIR/issue-37515.rs:5:1 | LL | type Z = dyn for<'x> Send; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^-^^^^^^^^^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_Z` | + = note: the leading underscore signals that this type alias serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/issue-37515.rs:3:9 | diff --git a/src/test/ui/lint/dead-code/basic.stderr b/src/test/ui/lint/dead-code/basic.stderr index f7b9b9c613ae0..8264d0736e03e 100644 --- a/src/test/ui/lint/dead-code/basic.stderr +++ b/src/test/ui/lint/dead-code/basic.stderr @@ -2,8 +2,9 @@ error: function is never used: `foo` --> $DIR/basic.rs:4:4 | LL | fn foo() { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_foo` | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/basic.rs:1:9 | diff --git a/src/test/ui/lint/dead-code/const-and-self.stderr b/src/test/ui/lint/dead-code/const-and-self.stderr index c0e406189e8ab..e7233f386cc68 100644 --- a/src/test/ui/lint/dead-code/const-and-self.stderr +++ b/src/test/ui/lint/dead-code/const-and-self.stderr @@ -2,8 +2,9 @@ warning: variant is never constructed: `B` --> $DIR/const-and-self.rs:33:5 | LL | B, - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_B` | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/const-and-self.rs:3:9 | @@ -14,7 +15,9 @@ warning: variant is never constructed: `C` --> $DIR/const-and-self.rs:34:5 | LL | C, - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_C` + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. warning: 2 warnings emitted diff --git a/src/test/ui/lint/dead-code/drop-only-field-issue-81658.rs b/src/test/ui/lint/dead-code/drop-only-field-issue-81658.rs new file mode 100644 index 0000000000000..d28b6430bc587 --- /dev/null +++ b/src/test/ui/lint/dead-code/drop-only-field-issue-81658.rs @@ -0,0 +1,42 @@ +//! The field `guard` is never used directly, but it is still useful for its side effect when +//! dropped. Since rustc doesn't consider a `Drop` impl as a use, we want to make sure we at least +//! produce a helpful diagnostic that points the user to what they can do if they indeed intended to +//! have a field that is only used for its `Drop` side effect. +//! +//! Issue: https://github.com/rust-lang/rust/issues/81658 + +#![deny(dead_code)] + +use std::sync::{Mutex, MutexGuard}; + +/// Holds a locked value until it is dropped +pub struct Locked<'a, T> { + // Field is kept for its affect when dropped, but otherwise unused + guard: MutexGuard<'a, T>, //~ ERROR field is never read +} + +impl<'a, T> Locked<'a, T> { + pub fn new(value: &'a Mutex) -> Self { + Self { + guard: value.lock().unwrap(), + } + } +} + +fn main() { + let items = Mutex::new(vec![1, 2, 3]); + + // Hold a lock on items while doing something else + let result = { + // The lock will be released at the end of this scope + let _lock = Locked::new(&items); + + do_something_else() + }; + + println!("{}", result); +} + +fn do_something_else() -> i32 { + 1 + 1 +} diff --git a/src/test/ui/lint/dead-code/drop-only-field-issue-81658.stderr b/src/test/ui/lint/dead-code/drop-only-field-issue-81658.stderr new file mode 100644 index 0000000000000..f379a0941166f --- /dev/null +++ b/src/test/ui/lint/dead-code/drop-only-field-issue-81658.stderr @@ -0,0 +1,17 @@ +error: field is never read: `guard` + --> $DIR/drop-only-field-issue-81658.rs:15:5 + | +LL | guard: MutexGuard<'a, T>, + | -----^^^^^^^^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_guard` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) +note: the lint level is defined here + --> $DIR/drop-only-field-issue-81658.rs:8:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/dead-code/empty-unused-enum.stderr b/src/test/ui/lint/dead-code/empty-unused-enum.stderr index ed9a7ccd14b21..5c06cd5a6a0b2 100644 --- a/src/test/ui/lint/dead-code/empty-unused-enum.stderr +++ b/src/test/ui/lint/dead-code/empty-unused-enum.stderr @@ -2,8 +2,9 @@ error: enum is never used: `E` --> $DIR/empty-unused-enum.rs:3:6 | LL | enum E {} - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_E` | + = note: the leading underscore signals that this enum serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/empty-unused-enum.rs:1:9 | diff --git a/src/test/ui/lint/dead-code/field-used-in-ffi-issue-81658.rs b/src/test/ui/lint/dead-code/field-used-in-ffi-issue-81658.rs new file mode 100644 index 0000000000000..12eafe6ae4958 --- /dev/null +++ b/src/test/ui/lint/dead-code/field-used-in-ffi-issue-81658.rs @@ -0,0 +1,50 @@ +//! The field `items` is being "used" by FFI (implicitly through pointers). However, since rustc +//! doesn't know how to detect that, we produce a message that says the field is unused. This can +//! cause some confusion and we want to make sure our diagnostics help as much as they can. +//! +//! Issue: https://github.com/rust-lang/rust/issues/81658 + +#![deny(dead_code)] + +/// A struct for holding on to data while it is being used in our FFI code +pub struct FFIData { + /// These values cannot be dropped while the pointers to each item + /// are still in use + items: Option>, //~ ERROR field is never read +} + +impl FFIData { + pub fn new() -> Self { + Self {items: None} + } + + /// Load items into this type and return pointers to each item that can + /// be passed to FFI + pub fn load(&mut self, items: Vec) -> Vec<*const T> { + let ptrs = items.iter().map(|item| item as *const _).collect(); + + self.items = Some(items); + + ptrs + } +} + +extern { + /// The FFI code that uses items + fn process_item(item: *const i32); +} + +fn main() { + // Data cannot be dropped until the end of this scope or else the items + // will be dropped before they are processed + let mut data = FFIData::new(); + + let ptrs = data.load(vec![1, 2, 3, 4, 5]); + + for ptr in ptrs { + // Safety: This pointer is valid as long as the arena is in scope + unsafe { process_item(ptr); } + } + + // Items will be safely freed at the end of this scope +} diff --git a/src/test/ui/lint/dead-code/field-used-in-ffi-issue-81658.stderr b/src/test/ui/lint/dead-code/field-used-in-ffi-issue-81658.stderr new file mode 100644 index 0000000000000..d6a247d98e292 --- /dev/null +++ b/src/test/ui/lint/dead-code/field-used-in-ffi-issue-81658.stderr @@ -0,0 +1,17 @@ +error: field is never read: `items` + --> $DIR/field-used-in-ffi-issue-81658.rs:13:5 + | +LL | items: Option>, + | -----^^^^^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_items` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) +note: the lint level is defined here + --> $DIR/field-used-in-ffi-issue-81658.rs:7:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/dead-code/impl-trait.stderr b/src/test/ui/lint/dead-code/impl-trait.stderr index 09b6d08eb8fb8..fb18eb2819f76 100644 --- a/src/test/ui/lint/dead-code/impl-trait.stderr +++ b/src/test/ui/lint/dead-code/impl-trait.stderr @@ -2,8 +2,11 @@ error: type alias is never used: `Unused` --> $DIR/impl-trait.rs:12:1 | LL | type Unused = (); - | ^^^^^^^^^^^^^^^^^ + | ^^^^^------^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_Unused` | + = note: the leading underscore signals that this type alias serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/impl-trait.rs:1:9 | diff --git a/src/test/ui/lint/dead-code/lint-dead-code-1.stderr b/src/test/ui/lint/dead-code/lint-dead-code-1.stderr index af97ea98b2b6d..15448448e1169 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-1.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-1.stderr @@ -2,8 +2,9 @@ error: struct is never constructed: `Bar` --> $DIR/lint-dead-code-1.rs:12:16 | LL | pub struct Bar; - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_Bar` | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/lint-dead-code-1.rs:5:9 | @@ -14,55 +15,77 @@ error: static is never used: `priv_static` --> $DIR/lint-dead-code-1.rs:20:1 | LL | static priv_static: isize = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^-----------^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_priv_static` + | + = note: the leading underscore signals that this static serves some other purpose even if it isn't used in a way that we can detect. error: constant is never used: `priv_const` --> $DIR/lint-dead-code-1.rs:27:1 | LL | const priv_const: isize = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^----------^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_priv_const` + | + = note: the leading underscore signals that this constant serves some other purpose even if it isn't used in a way that we can detect. error: struct is never constructed: `PrivStruct` --> $DIR/lint-dead-code-1.rs:35:8 | LL | struct PrivStruct; - | ^^^^^^^^^^ + | ^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_PrivStruct` + | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. error: enum is never used: `priv_enum` --> $DIR/lint-dead-code-1.rs:64:6 | LL | enum priv_enum { foo2, bar2 } - | ^^^^^^^^^ + | ^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_priv_enum` + | + = note: the leading underscore signals that this enum serves some other purpose even if it isn't used in a way that we can detect. error: variant is never constructed: `bar3` --> $DIR/lint-dead-code-1.rs:67:5 | LL | bar3 - | ^^^^ + | ^^^^ help: if this is intentional, prefix it with an underscore: `_bar3` + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `priv_fn` --> $DIR/lint-dead-code-1.rs:88:4 | LL | fn priv_fn() { - | ^^^^^^^ + | ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_priv_fn` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `foo` --> $DIR/lint-dead-code-1.rs:93:4 | LL | fn foo() { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_foo` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `bar` --> $DIR/lint-dead-code-1.rs:98:4 | LL | fn bar() { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_bar` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `baz` --> $DIR/lint-dead-code-1.rs:102:4 | LL | fn baz() -> impl Copy { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_baz` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: aborting due to 10 previous errors diff --git a/src/test/ui/lint/dead-code/lint-dead-code-2.stderr b/src/test/ui/lint/dead-code/lint-dead-code-2.stderr index b01ba57f98580..5e19c7d02ffd3 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-2.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-2.stderr @@ -2,8 +2,9 @@ error: function is never used: `dead_fn` --> $DIR/lint-dead-code-2.rs:22:4 | LL | fn dead_fn() {} - | ^^^^^^^ + | ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_dead_fn` | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/lint-dead-code-2.rs:2:9 | @@ -14,13 +15,17 @@ error: function is never used: `dead_fn2` --> $DIR/lint-dead-code-2.rs:25:4 | LL | fn dead_fn2() {} - | ^^^^^^^^ + | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_dead_fn2` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `main` --> $DIR/lint-dead-code-2.rs:38:4 | LL | fn main() { - | ^^^^ + | ^^^^ help: if this is intentional, prefix it with an underscore: `_main` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: aborting due to 3 previous errors diff --git a/src/test/ui/lint/dead-code/lint-dead-code-3.stderr b/src/test/ui/lint/dead-code/lint-dead-code-3.stderr index cf8f01ea19f0c..d32fde5872d99 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-3.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-3.stderr @@ -2,8 +2,9 @@ error: struct is never constructed: `Foo` --> $DIR/lint-dead-code-3.rs:14:8 | LL | struct Foo; - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_Foo` | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/lint-dead-code-3.rs:4:9 | @@ -14,25 +15,35 @@ error: associated function is never used: `foo` --> $DIR/lint-dead-code-3.rs:16:8 | LL | fn foo(&self) { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_foo` + | + = note: the leading underscore signals that this associated function serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `bar` --> $DIR/lint-dead-code-3.rs:21:4 | LL | fn bar() { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_bar` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: enum is never used: `c_void` --> $DIR/lint-dead-code-3.rs:60:6 | LL | enum c_void {} - | ^^^^^^ + | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_c_void` + | + = note: the leading underscore signals that this enum serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `free` --> $DIR/lint-dead-code-3.rs:62:5 | LL | fn free(p: *const c_void); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^----^^^^^^^^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_free` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: aborting due to 5 previous errors diff --git a/src/test/ui/lint/dead-code/lint-dead-code-4.stderr b/src/test/ui/lint/dead-code/lint-dead-code-4.stderr index 3905d1a06bdfe..2785faa29f5d9 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-4.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-4.stderr @@ -2,8 +2,11 @@ error: field is never read: `b` --> $DIR/lint-dead-code-4.rs:7:5 | LL | b: bool, - | ^^^^^^^ + | -^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_b` | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) note: the lint level is defined here --> $DIR/lint-dead-code-4.rs:3:9 | @@ -14,59 +17,88 @@ error: variant is never constructed: `X` --> $DIR/lint-dead-code-4.rs:15:5 | LL | X, - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_X` + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. error: variant is never constructed: `Y` --> $DIR/lint-dead-code-4.rs:16:5 | -LL | / Y { +LL | Y { + | ^ help: if this is intentional, prefix it with an underscore: `_Y` + | _____| + | | LL | | a: String, LL | | b: i32, LL | | c: i32, LL | | }, | |_____^ + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. error: enum is never used: `ABC` --> $DIR/lint-dead-code-4.rs:24:6 | LL | enum ABC { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_ABC` + | + = note: the leading underscore signals that this enum serves some other purpose even if it isn't used in a way that we can detect. error: variant is never constructed: `I` --> $DIR/lint-dead-code-4.rs:36:5 | LL | I, - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_I` + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. error: field is never read: `b` --> $DIR/lint-dead-code-4.rs:39:9 | LL | b: i32, - | ^^^^^^ + | -^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_b` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `c` --> $DIR/lint-dead-code-4.rs:40:9 | LL | c: i32, - | ^^^^^^ + | -^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_c` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: variant is never constructed: `K` --> $DIR/lint-dead-code-4.rs:42:5 | LL | K - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_K` + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. error: field is never read: `x` --> $DIR/lint-dead-code-4.rs:61:5 | LL | x: usize, - | ^^^^^^^^ + | -^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_x` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `c` --> $DIR/lint-dead-code-4.rs:63:5 | LL | c: bool, - | ^^^^^^^ + | -^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_c` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: aborting due to 10 previous errors diff --git a/src/test/ui/lint/dead-code/lint-dead-code-5.stderr b/src/test/ui/lint/dead-code/lint-dead-code-5.stderr index 519add826273f..6375d98d35cb2 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-5.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-5.stderr @@ -2,8 +2,9 @@ error: variant is never constructed: `Variant2` --> $DIR/lint-dead-code-5.rs:6:5 | LL | Variant2 - | ^^^^^^^^ + | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_Variant2` | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/lint-dead-code-5.rs:2:9 | @@ -14,19 +15,29 @@ error: variant is never constructed: `Variant5` --> $DIR/lint-dead-code-5.rs:13:5 | LL | Variant5 { _x: isize }, - | ^^^^^^^^^^^^^^^^^^^^^^ + | --------^^^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_Variant5` + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. error: variant is never constructed: `Variant6` --> $DIR/lint-dead-code-5.rs:14:5 | LL | Variant6(isize), - | ^^^^^^^^^^^^^^^ + | --------^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_Variant6` + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. error: enum is never used: `Enum3` --> $DIR/lint-dead-code-5.rs:35:6 | LL | enum Enum3 { - | ^^^^^ + | ^^^^^ help: if this is intentional, prefix it with an underscore: `_Enum3` + | + = note: the leading underscore signals that this enum serves some other purpose even if it isn't used in a way that we can detect. error: aborting due to 4 previous errors diff --git a/src/test/ui/lint/dead-code/lint-dead-code-6.stderr b/src/test/ui/lint/dead-code/lint-dead-code-6.stderr index 7dc60730d6aad..ef26fe54ab589 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-6.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-6.stderr @@ -2,8 +2,9 @@ error: struct is never constructed: `UnusedStruct` --> $DIR/lint-dead-code-6.rs:3:8 | LL | struct UnusedStruct; - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_UnusedStruct` | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/lint-dead-code-6.rs:1:9 | @@ -14,19 +15,25 @@ error: associated function is never used: `unused_impl_fn_1` --> $DIR/lint-dead-code-6.rs:5:8 | LL | fn unused_impl_fn_1() { - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_impl_fn_1` + | + = note: the leading underscore signals that this associated function serves some other purpose even if it isn't used in a way that we can detect. error: associated function is never used: `unused_impl_fn_2` --> $DIR/lint-dead-code-6.rs:9:8 | LL | fn unused_impl_fn_2(var: i32) { - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_impl_fn_2` + | + = note: the leading underscore signals that this associated function serves some other purpose even if it isn't used in a way that we can detect. error: associated function is never used: `unused_impl_fn_3` --> $DIR/lint-dead-code-6.rs:13:8 | LL | fn unused_impl_fn_3( - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_impl_fn_3` + | + = note: the leading underscore signals that this associated function serves some other purpose even if it isn't used in a way that we can detect. error: aborting due to 4 previous errors diff --git a/src/test/ui/lint/dead-code/newline-span.stderr b/src/test/ui/lint/dead-code/newline-span.stderr index fd74405f2b648..5bd566be35e01 100644 --- a/src/test/ui/lint/dead-code/newline-span.stderr +++ b/src/test/ui/lint/dead-code/newline-span.stderr @@ -2,8 +2,9 @@ error: function is never used: `unused` --> $DIR/newline-span.rs:3:4 | LL | fn unused() { - | ^^^^^^ + | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused` | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/newline-span.rs:1:9 | @@ -14,13 +15,17 @@ error: function is never used: `unused2` --> $DIR/newline-span.rs:7:4 | LL | fn unused2(var: i32) { - | ^^^^^^^ + | ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused2` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `unused3` --> $DIR/newline-span.rs:11:4 | LL | fn unused3( - | ^^^^^^^ + | ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused3` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: aborting due to 3 previous errors diff --git a/src/test/ui/lint/dead-code/type-alias.stderr b/src/test/ui/lint/dead-code/type-alias.stderr index b2acd5d4213b3..1e7a030de3aa7 100644 --- a/src/test/ui/lint/dead-code/type-alias.stderr +++ b/src/test/ui/lint/dead-code/type-alias.stderr @@ -2,8 +2,11 @@ error: type alias is never used: `Unused` --> $DIR/type-alias.rs:4:1 | LL | type Unused = u8; - | ^^^^^^^^^^^^^^^^^ + | ^^^^^------^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_Unused` | + = note: the leading underscore signals that this type alias serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/type-alias.rs:1:9 | diff --git a/src/test/ui/lint/dead-code/unused-enum.stderr b/src/test/ui/lint/dead-code/unused-enum.stderr index 9f368fdd2f816..d536479c800ae 100644 --- a/src/test/ui/lint/dead-code/unused-enum.stderr +++ b/src/test/ui/lint/dead-code/unused-enum.stderr @@ -2,8 +2,9 @@ error: struct is never constructed: `F` --> $DIR/unused-enum.rs:3:8 | LL | struct F; - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_F` | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/unused-enum.rs:1:9 | @@ -15,13 +16,17 @@ error: struct is never constructed: `B` --> $DIR/unused-enum.rs:4:8 | LL | struct B; - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_B` + | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. error: enum is never used: `E` --> $DIR/unused-enum.rs:6:6 | LL | enum E { - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_E` + | + = note: the leading underscore signals that this enum serves some other purpose even if it isn't used in a way that we can detect. error: aborting due to 3 previous errors diff --git a/src/test/ui/lint/dead-code/unused-struct-variant.stderr b/src/test/ui/lint/dead-code/unused-struct-variant.stderr index b93d6d4ac1866..394ced3e81001 100644 --- a/src/test/ui/lint/dead-code/unused-struct-variant.stderr +++ b/src/test/ui/lint/dead-code/unused-struct-variant.stderr @@ -2,8 +2,11 @@ error: variant is never constructed: `Bar` --> $DIR/unused-struct-variant.rs:8:5 | LL | Bar(B), - | ^^^^^^ + | ---^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_Bar` | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/unused-struct-variant.rs:1:9 | diff --git a/src/test/ui/lint/dead-code/unused-variant.stderr b/src/test/ui/lint/dead-code/unused-variant.stderr index a547f5af4b082..7dcb79d0490c1 100644 --- a/src/test/ui/lint/dead-code/unused-variant.stderr +++ b/src/test/ui/lint/dead-code/unused-variant.stderr @@ -2,8 +2,9 @@ error: variant is never constructed: `Variant1` --> $DIR/unused-variant.rs:5:5 | LL | Variant1, - | ^^^^^^^^ + | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_Variant1` | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/unused-variant.rs:1:9 | diff --git a/src/test/ui/lint/dead-code/with-core-crate.stderr b/src/test/ui/lint/dead-code/with-core-crate.stderr index 2c63e60d67609..1bde434069ee7 100644 --- a/src/test/ui/lint/dead-code/with-core-crate.stderr +++ b/src/test/ui/lint/dead-code/with-core-crate.stderr @@ -2,8 +2,9 @@ error: function is never used: `foo` --> $DIR/with-core-crate.rs:7:4 | LL | fn foo() { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_foo` | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/with-core-crate.rs:1:9 | diff --git a/src/test/ui/lint/dead-code/write-only-field.stderr b/src/test/ui/lint/dead-code/write-only-field.stderr index a191d22c8b94c..13a21bb1193de 100644 --- a/src/test/ui/lint/dead-code/write-only-field.stderr +++ b/src/test/ui/lint/dead-code/write-only-field.stderr @@ -2,8 +2,11 @@ error: field is never read: `f` --> $DIR/write-only-field.rs:4:5 | LL | f: i32, - | ^^^^^^ + | -^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_f` | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) note: the lint level is defined here --> $DIR/write-only-field.rs:1:9 | @@ -14,31 +17,51 @@ error: field is never read: `sub` --> $DIR/write-only-field.rs:5:5 | LL | sub: Sub, - | ^^^^^^^^ + | ---^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_sub` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `f` --> $DIR/write-only-field.rs:9:5 | LL | f: i32, - | ^^^^^^ + | -^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_f` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `y` --> $DIR/write-only-field.rs:28:9 | LL | y: bool, - | ^^^^^^^ + | -^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_y` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `u` --> $DIR/write-only-field.rs:58:9 | LL | u: u32, - | ^^^^^^ + | -^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_u` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `v` --> $DIR/write-only-field.rs:59:9 | LL | v: u32, - | ^^^^^^ + | -^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_v` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: aborting due to 6 previous errors diff --git a/src/test/ui/lint/issue-17718-const-naming.stderr b/src/test/ui/lint/issue-17718-const-naming.stderr index ce4ebcb5e3ef6..e880006e114c1 100644 --- a/src/test/ui/lint/issue-17718-const-naming.stderr +++ b/src/test/ui/lint/issue-17718-const-naming.stderr @@ -2,8 +2,11 @@ error: constant is never used: `foo` --> $DIR/issue-17718-const-naming.rs:4:1 | LL | const foo: isize = 3; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^---^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_foo` | + = note: the leading underscore signals that this constant serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/issue-17718-const-naming.rs:2:9 | diff --git a/src/test/ui/span/macro-span-replacement.stderr b/src/test/ui/span/macro-span-replacement.stderr index 45cf5f8688cd1..f94a9e30a3dfa 100644 --- a/src/test/ui/span/macro-span-replacement.stderr +++ b/src/test/ui/span/macro-span-replacement.stderr @@ -2,11 +2,14 @@ warning: struct is never constructed: `S` --> $DIR/macro-span-replacement.rs:7:14 | LL | $b $a; - | ^ + | --^ + | | + | help: if this is intentional, prefix it with an underscore: `_S` ... LL | m!(S struct); | ------------- in this macro invocation | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/macro-span-replacement.rs:3:9 | diff --git a/src/test/ui/span/unused-warning-point-at-identifier.stderr b/src/test/ui/span/unused-warning-point-at-identifier.stderr index 6ef877da122f5..3bf342f197252 100644 --- a/src/test/ui/span/unused-warning-point-at-identifier.stderr +++ b/src/test/ui/span/unused-warning-point-at-identifier.stderr @@ -2,8 +2,9 @@ warning: enum is never used: `Enum` --> $DIR/unused-warning-point-at-identifier.rs:5:6 | LL | enum Enum { - | ^^^^ + | ^^^^ help: if this is intentional, prefix it with an underscore: `_Enum` | + = note: the leading underscore signals that this enum serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/unused-warning-point-at-identifier.rs:3:9 | @@ -15,19 +16,25 @@ warning: struct is never constructed: `Struct` --> $DIR/unused-warning-point-at-identifier.rs:12:8 | LL | struct Struct { - | ^^^^^^ + | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_Struct` + | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. warning: function is never used: `func` --> $DIR/unused-warning-point-at-identifier.rs:19:4 | LL | fn func() -> usize { - | ^^^^ + | ^^^^ help: if this is intentional, prefix it with an underscore: `_func` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. warning: function is never used: `func_complete_span` --> $DIR/unused-warning-point-at-identifier.rs:24:1 | LL | func_complete_span() - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_func_complete_span` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. warning: 4 warnings emitted diff --git a/src/test/ui/suggestions/import-trait-for-method-call.rs b/src/test/ui/suggestions/import-trait-for-method-call.rs index 646f68dea14e8..4dbadbdf98206 100644 --- a/src/test/ui/suggestions/import-trait-for-method-call.rs +++ b/src/test/ui/suggestions/import-trait-for-method-call.rs @@ -6,4 +6,11 @@ fn next_u64() -> u64 { h.finish() //~ ERROR no method named `finish` found for struct `DefaultHasher` } -fn main() {} +trait Bar {} +impl Bar for String {} + +fn main() { + let s = String::from("hey"); + let x: &dyn Bar = &s; + x.as_ref(); //~ ERROR the method `as_ref` exists for reference `&dyn Bar`, but its trait bounds +} diff --git a/src/test/ui/suggestions/import-trait-for-method-call.stderr b/src/test/ui/suggestions/import-trait-for-method-call.stderr index f3ae20552f3d5..a2b9b9d14ab09 100644 --- a/src/test/ui/suggestions/import-trait-for-method-call.stderr +++ b/src/test/ui/suggestions/import-trait-for-method-call.stderr @@ -15,6 +15,22 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use std::hash::Hasher; | -error: aborting due to previous error +error[E0599]: the method `as_ref` exists for reference `&dyn Bar`, but its trait bounds were not satisfied + --> $DIR/import-trait-for-method-call.rs:15:7 + | +LL | trait Bar {} + | --------- doesn't satisfy `dyn Bar: AsRef<_>` +... +LL | x.as_ref(); + | ^^^^^^ method cannot be called on `&dyn Bar` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `dyn Bar: AsRef<_>` + which is required by `&dyn Bar: AsRef<_>` + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `as_ref`, perhaps you need to implement it: + candidate #1: `AsRef` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/test-attrs/test-warns-dead-code.stderr b/src/test/ui/test-attrs/test-warns-dead-code.stderr index d3bcea2951364..e5a8dee6ccb68 100644 --- a/src/test/ui/test-attrs/test-warns-dead-code.stderr +++ b/src/test/ui/test-attrs/test-warns-dead-code.stderr @@ -2,8 +2,9 @@ error: function is never used: `dead` --> $DIR/test-warns-dead-code.rs:5:4 | LL | fn dead() {} - | ^^^^ + | ^^^^ help: if this is intentional, prefix it with an underscore: `_dead` | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/test-warns-dead-code.rs:3:9 | diff --git a/src/test/ui/typeck/issue-84831.rs b/src/test/ui/typeck/issue-84831.rs new file mode 100644 index 0000000000000..c646f71072532 --- /dev/null +++ b/src/test/ui/typeck/issue-84831.rs @@ -0,0 +1,9 @@ +fn f() { + std::<0>; //~ ERROR expected value +} +fn j() { + std::<_ as _>; //~ ERROR expected value + //~^ ERROR expected one of `,` or `>`, found keyword `as` +} + +fn main () {} diff --git a/src/test/ui/typeck/issue-84831.stderr b/src/test/ui/typeck/issue-84831.stderr new file mode 100644 index 0000000000000..e3cce10a00fd1 --- /dev/null +++ b/src/test/ui/typeck/issue-84831.stderr @@ -0,0 +1,26 @@ +error: expected one of `,` or `>`, found keyword `as` + --> $DIR/issue-84831.rs:5:13 + | +LL | std::<_ as _>; + | ^^ expected one of `,` or `>` + | +help: expressions must be enclosed in braces to be used as const generic arguments + | +LL | std::<{ _ as _ }>; + | ^ ^ + +error[E0423]: expected value, found crate `std` + --> $DIR/issue-84831.rs:2:5 + | +LL | std::<0>; + | ^^^^^^^^ not a value + +error[E0423]: expected value, found crate `std` + --> $DIR/issue-84831.rs:5:5 + | +LL | std::<_ as _>; + | ^^^^^^^^^^^^^ not a value + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0423`. diff --git a/src/test/ui/union/union-fields-1.stderr b/src/test/ui/union/union-fields-1.stderr index 87621cc01b1b9..3595bf6dce688 100644 --- a/src/test/ui/union/union-fields-1.stderr +++ b/src/test/ui/union/union-fields-1.stderr @@ -2,8 +2,11 @@ error: field is never read: `c` --> $DIR/union-fields-1.rs:6:5 | LL | c: u8, - | ^^^^^ + | -^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_c` | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) note: the lint level is defined here --> $DIR/union-fields-1.rs:1:9 | @@ -14,19 +17,31 @@ error: field is never read: `a` --> $DIR/union-fields-1.rs:9:5 | LL | a: u8, - | ^^^^^ + | -^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_a` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `a` --> $DIR/union-fields-1.rs:13:20 | LL | union NoDropLike { a: u8 } - | ^^^^^ + | -^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_a` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `c` --> $DIR/union-fields-1.rs:18:5 | LL | c: u8, - | ^^^^^ + | -^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_c` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: aborting due to 4 previous errors diff --git a/src/test/ui/union/union-lint-dead-code.stderr b/src/test/ui/union/union-lint-dead-code.stderr index 7de70ec33801f..8ead9cde9b333 100644 --- a/src/test/ui/union/union-lint-dead-code.stderr +++ b/src/test/ui/union/union-lint-dead-code.stderr @@ -2,8 +2,11 @@ error: field is never read: `b` --> $DIR/union-lint-dead-code.rs:5:5 | LL | b: bool, - | ^^^^^^^ + | -^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_b` | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) note: the lint level is defined here --> $DIR/union-lint-dead-code.rs:1:9 |