diff --git a/Cargo.lock b/Cargo.lock index eeb3c99a294a..7d22abc8611e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,9 +182,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" dependencies = [ "backtrace", ] @@ -367,7 +367,7 @@ dependencies = [ name = "cargo-miri" version = "0.1.0" dependencies = [ - "cargo_metadata", + "cargo_metadata 0.18.1", "directories", "rustc-build-sysroot", "rustc_tools_util", @@ -399,15 +399,29 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "cargo_metadata" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8769706aad5d996120af43197bf46ef6ad0fda35216b4505f926a365a232d924" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror 2.0.9", +] + [[package]] name = "cargotest2" version = "0.1.0" [[package]] name = "cc" -version = "1.2.5" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" dependencies = [ "shlex", ] @@ -519,7 +533,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -533,7 +547,7 @@ name = "clippy" version = "0.1.85" dependencies = [ "anstream", - "cargo_metadata", + "cargo_metadata 0.18.1", "clippy_config", "clippy_lints", "clippy_utils", @@ -550,7 +564,7 @@ dependencies = [ "rustc_tools_util", "serde", "serde_json", - "syn 2.0.90", + "syn 2.0.93", "tempfile", "termize", "tokio", @@ -589,7 +603,7 @@ name = "clippy_lints" version = "0.1.85" dependencies = [ "arrayvec", - "cargo_metadata", + "cargo_metadata 0.18.1", "clippy_config", "clippy_utils", "itertools", @@ -660,7 +674,7 @@ dependencies = [ "nom", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -885,7 +899,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -896,7 +910,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -933,7 +947,7 @@ checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -954,7 +968,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -964,7 +978,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -976,7 +990,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -1054,7 +1068,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -1351,7 +1365,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -1389,7 +1403,7 @@ name = "generate-copyright" version = "0.1.0" dependencies = [ "anyhow", - "cargo_metadata", + "cargo_metadata 0.18.1", "rinja", "serde", "serde_json", @@ -1463,9 +1477,9 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "globset" @@ -1585,7 +1599,7 @@ dependencies = [ "markup5ever", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -1774,7 +1788,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -2730,7 +2744,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -2952,9 +2966,9 @@ checksum = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -3140,7 +3154,7 @@ dependencies = [ "rinja_parser", "rustc-hash 2.1.0", "serde", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -3780,7 +3794,7 @@ dependencies = [ "fluent-syntax", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", "unic-langid", ] @@ -3915,7 +3929,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -4063,7 +4077,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", "synstructure", ] @@ -4651,7 +4665,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", "synstructure", ] @@ -4740,7 +4754,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -4750,7 +4764,7 @@ dependencies = [ "annotate-snippets 0.9.2", "anyhow", "bytecount", - "cargo_metadata", + "cargo_metadata 0.18.1", "clap", "clap-cargo", "diff", @@ -4787,9 +4801,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "ruzstd" @@ -4862,22 +4876,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -5135,9 +5149,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.90" +version = "2.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" dependencies = [ "proc-macro2", "quote", @@ -5152,7 +5166,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -5294,7 +5308,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -5305,7 +5319,7 @@ checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -5344,7 +5358,7 @@ name = "tidy" version = "0.1.0" dependencies = [ "build_helper", - "cargo_metadata", + "cargo_metadata 0.19.1", "fluent-syntax", "ignore", "miropt-test-tools", @@ -5506,7 +5520,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -5622,7 +5636,7 @@ dependencies = [ "anyhow", "bstr", "cargo-platform", - "cargo_metadata", + "cargo_metadata 0.18.1", "color-eyre", "colored", "comma", @@ -5677,15 +5691,15 @@ checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b" dependencies = [ "proc-macro-hack", "quote", - "syn 2.0.90", + "syn 2.0.93", "unic-langid-impl", ] [[package]] name = "unicase" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" @@ -5883,7 +5897,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", "wasm-bindgen-shared", ] @@ -5905,7 +5919,7 @@ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6087,7 +6101,7 @@ dependencies = [ "rayon", "serde", "serde_json", - "syn 2.0.90", + "syn 2.0.93", "windows-metadata", ] @@ -6120,7 +6134,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -6131,7 +6145,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -6410,7 +6424,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", "synstructure", ] @@ -6432,7 +6446,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -6452,7 +6466,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", "synstructure", ] @@ -6475,5 +6489,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index dce76fb1e770..4b1374ceef31 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -213,7 +213,9 @@ impl<'a> State<'a> { fn print_expr_call(&mut self, func: &ast::Expr, args: &[P], fixup: FixupContext) { let needs_paren = match func.kind { - ast::ExprKind::Field(..) => true, + // In order to call a named field, needs parens: `(self.fun)()` + // But not for an unnamed field: `self.0()` + ast::ExprKind::Field(_, name) => !name.is_numeric(), _ => func.precedence() < ExprPrecedence::Unambiguous, }; @@ -245,19 +247,21 @@ impl<'a> State<'a> { base_args: &[P], fixup: FixupContext, ) { - // Unlike in `print_expr_call`, no change to fixup here because + // The fixup here is different than in `print_expr_call` because // statement boundaries never occur in front of a `.` (or `?`) token. // - // match () { _ => f }.method(); + // Needs parens: + // + // (loop { break x; })(); + // + // Does not need parens: + // + // loop { break x; }.method(); // - // Parenthesizing only for precedence and not with regard to statement - // boundaries, `$receiver.method()` can be parsed back as a statement - // containing an expression if and only if `$receiver` can be parsed as - // a statement containing an expression. self.print_expr_cond_paren( receiver, receiver.precedence() < ExprPrecedence::Unambiguous, - fixup, + fixup.leftmost_subexpression_with_dot(), ); self.word("."); @@ -503,7 +507,7 @@ impl<'a> State<'a> { self.print_expr_cond_paren( expr, expr.precedence() < ExprPrecedence::Unambiguous, - fixup, + fixup.leftmost_subexpression_with_dot(), ); self.word_nbsp(".match"); } @@ -567,7 +571,7 @@ impl<'a> State<'a> { self.print_expr_cond_paren( expr, expr.precedence() < ExprPrecedence::Unambiguous, - fixup, + fixup.leftmost_subexpression_with_dot(), ); self.word(".await"); } @@ -606,7 +610,7 @@ impl<'a> State<'a> { self.print_expr_cond_paren( expr, expr.precedence() < ExprPrecedence::Unambiguous, - fixup, + fixup.leftmost_subexpression_with_dot(), ); self.word("."); self.print_ident(*ident); @@ -763,7 +767,11 @@ impl<'a> State<'a> { } } ast::ExprKind::Try(e) => { - self.print_expr_cond_paren(e, e.precedence() < ExprPrecedence::Unambiguous, fixup); + self.print_expr_cond_paren( + e, + e.precedence() < ExprPrecedence::Unambiguous, + fixup.leftmost_subexpression_with_dot(), + ); self.word("?") } ast::ExprKind::TryBlock(blk) => { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs index ff466703f737..3ef21f5cb29e 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs @@ -138,6 +138,20 @@ impl FixupContext { } } + /// Transform this fixup into the one that should apply when printing a + /// leftmost subexpression followed by a `.` or `?` token, which confer + /// different statement boundary rules compared to other leftmost + /// subexpressions. + pub(crate) fn leftmost_subexpression_with_dot(self) -> Self { + FixupContext { + stmt: self.stmt || self.leftmost_subexpression_in_stmt, + leftmost_subexpression_in_stmt: false, + match_arm: self.match_arm || self.leftmost_subexpression_in_match_arm, + leftmost_subexpression_in_match_arm: false, + ..self + } + } + /// Transform this fixup into the one that should apply when printing any /// subexpression that is neither a leftmost subexpression nor surrounded in /// delimiters. diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index 74de766ba231..7e8c48a15513 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -8,11 +8,12 @@ use rustc_middle::ty::TyCtxt; pub use super::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation}; pub use super::constraints::OutlivesConstraint; pub use super::dataflow::{BorrowIndex, Borrows, calculate_borrows_out_of_scope_at_location}; -pub use super::facts::{AllFacts as PoloniusInput, PoloniusRegionVid, RustcFacts}; -pub use super::location::{LocationTable, RichLocation}; -pub use super::nll::PoloniusOutput; pub use super::place_ext::PlaceExt; pub use super::places_conflict::{PlaceConflictBias, places_conflict}; +pub use super::polonius::legacy::{ + AllFacts as PoloniusInput, LocationTable, PoloniusOutput, PoloniusRegionVid, RichLocation, + RustcFacts, +}; pub use super::region_infer::RegionInferenceContext; /// Options determining the output behavior of [`get_body_with_borrowck_facts`]. diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 67be6ecdeb3d..180046ca2562 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1,6 +1,9 @@ //! Borrow checker diagnostics. +use std::collections::BTreeMap; + use rustc_abi::{FieldIdx, VariantIdx}; +use rustc_data_structures::fx::FxIndexMap; use rustc_errors::{Applicability, Diag, MultiSpan}; use rustc_hir::def::{CtorKind, Namespace}; use rustc_hir::{self as hir, CoroutineKind, LangItem}; @@ -17,10 +20,10 @@ use rustc_middle::mir::{ use rustc_middle::ty::print::Print; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_middle::util::{CallDesugaringKind, call_kind}; -use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult}; +use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveOutIndex}; use rustc_span::def_id::LocalDefId; use rustc_span::source_map::Spanned; -use rustc_span::{DUMMY_SP, Span, Symbol, sym}; +use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::{ @@ -68,6 +71,126 @@ pub(super) struct DescribePlaceOpt { pub(super) struct IncludingTupleField(pub(super) bool); +enum BufferedDiag<'infcx> { + Error(Diag<'infcx>), + NonError(Diag<'infcx, ()>), +} + +impl<'infcx> BufferedDiag<'infcx> { + fn sort_span(&self) -> Span { + match self { + BufferedDiag::Error(diag) => diag.sort_span, + BufferedDiag::NonError(diag) => diag.sort_span, + } + } +} + +#[derive(Default)] +pub(crate) struct BorrowckDiagnosticsBuffer<'infcx, 'tcx> { + /// This field keeps track of move errors that are to be reported for given move indices. + /// + /// There are situations where many errors can be reported for a single move out (see + /// #53807) and we want only the best of those errors. + /// + /// The `report_use_of_moved_or_uninitialized` function checks this map and replaces the + /// diagnostic (if there is one) if the `Place` of the error being reported is a prefix of + /// the `Place` of the previous most diagnostic. This happens instead of buffering the + /// error. Once all move errors have been reported, any diagnostics in this map are added + /// to the buffer to be emitted. + /// + /// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary + /// when errors in the map are being re-added to the error buffer so that errors with the + /// same primary span come out in a consistent order. + buffered_move_errors: BTreeMap, (PlaceRef<'tcx>, Diag<'infcx>)>, + + buffered_mut_errors: FxIndexMap, usize)>, + + /// Buffer of diagnostics to be reported. A mixture of error and non-error diagnostics. + buffered_diags: Vec>, +} + +impl<'infcx, 'tcx> BorrowckDiagnosticsBuffer<'infcx, 'tcx> { + pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { + self.buffered_diags.push(BufferedDiag::NonError(diag)); + } +} + +impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { + pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) { + self.diags_buffer.buffered_diags.push(BufferedDiag::Error(diag)); + } + + pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { + self.diags_buffer.buffer_non_error(diag); + } + + pub(crate) fn buffer_move_error( + &mut self, + move_out_indices: Vec, + place_and_err: (PlaceRef<'tcx>, Diag<'infcx>), + ) -> bool { + if let Some((_, diag)) = + self.diags_buffer.buffered_move_errors.insert(move_out_indices, place_and_err) + { + // Cancel the old diagnostic so we don't ICE + diag.cancel(); + false + } else { + true + } + } + + pub(crate) fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'infcx>, usize)> { + // FIXME(#120456) - is `swap_remove` correct? + self.diags_buffer.buffered_mut_errors.swap_remove(&span) + } + + pub(crate) fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) { + self.diags_buffer.buffered_mut_errors.insert(span, (diag, count)); + } + + pub(crate) fn emit_errors(&mut self) -> Option { + let mut res = self.infcx.tainted_by_errors(); + + // Buffer any move errors that we collected and de-duplicated. + for (_, (_, diag)) in std::mem::take(&mut self.diags_buffer.buffered_move_errors) { + // We have already set tainted for this error, so just buffer it. + self.buffer_error(diag); + } + for (_, (mut diag, count)) in std::mem::take(&mut self.diags_buffer.buffered_mut_errors) { + if count > 10 { + #[allow(rustc::diagnostic_outside_of_impl)] + #[allow(rustc::untranslatable_diagnostic)] + diag.note(format!("...and {} other attempted mutable borrows", count - 10)); + } + self.buffer_error(diag); + } + + if !self.diags_buffer.buffered_diags.is_empty() { + self.diags_buffer.buffered_diags.sort_by_key(|buffered_diag| buffered_diag.sort_span()); + for buffered_diag in self.diags_buffer.buffered_diags.drain(..) { + match buffered_diag { + BufferedDiag::Error(diag) => res = Some(diag.emit()), + BufferedDiag::NonError(diag) => diag.emit(), + } + } + } + + res + } + + pub(crate) fn has_buffered_diags(&self) -> bool { + self.diags_buffer.buffered_diags.is_empty() + } + + pub(crate) fn has_move_error( + &self, + move_out_indices: &[MoveOutIndex], + ) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> { + self.diags_buffer.buffered_move_errors.get(move_out_indices) + } +} + impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure /// is moved after being invoked. diff --git a/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs b/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs index d77c53a39844..876b8f214b01 100644 --- a/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs +++ b/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs @@ -31,7 +31,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { diag: &mut Diag<'_>, ) { // We look at all the locals. Why locals? Because it's the best thing - // I could think of that's correlated with the *instantiated* higer-ranked + // I could think of that's correlated with the *instantiated* higher-ranked // binder for calls, since we don't really store those anywhere else. for ty in self.body.local_decls.iter().map(|local| local.ty) { if !ty.has_opaque_types() { diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 8b968177c3c0..b061a450c83f 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -16,14 +16,12 @@ // tidy-alphabetical-end use std::cell::RefCell; -use std::collections::BTreeMap; use std::marker::PhantomData; use std::ops::Deref; use rustc_abi::FieldIdx; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::graph::dominators::Dominators; -use rustc_errors::Diag; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::{BitSet, MixedBitSet}; @@ -41,7 +39,7 @@ use rustc_mir_dataflow::impls::{ EverInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces, }; use rustc_mir_dataflow::move_paths::{ - InitIndex, InitLocation, LookupResult, MoveData, MoveOutIndex, MovePathIndex, + InitIndex, InitLocation, LookupResult, MoveData, MovePathIndex, }; use rustc_mir_dataflow::{Analysis, EntryStates, Results, ResultsVisitor, visit_results}; use rustc_session::lint::builtin::UNUSED_MUT; @@ -52,12 +50,13 @@ use tracing::{debug, instrument}; use crate::borrow_set::{BorrowData, BorrowSet}; use crate::consumers::{BodyWithBorrowckFacts, ConsumerOptions}; use crate::dataflow::{BorrowIndex, Borrowck, BorrowckDomain, Borrows}; -use crate::diagnostics::{AccessKind, IllegalMoveOriginKind, MoveError, RegionName}; -use crate::location::LocationTable; -use crate::nll::PoloniusOutput; +use crate::diagnostics::{ + AccessKind, BorrowckDiagnosticsBuffer, IllegalMoveOriginKind, MoveError, RegionName, +}; use crate::path_utils::*; use crate::place_ext::PlaceExt; use crate::places_conflict::{PlaceConflictBias, places_conflict}; +use crate::polonius::legacy::{LocationTable, PoloniusOutput}; use crate::prefixes::PrefixSet; use crate::region_infer::RegionInferenceContext; use crate::renumber::RegionCtxt; @@ -69,8 +68,6 @@ mod constraints; mod dataflow; mod def_use; mod diagnostics; -mod facts; -mod location; mod member_constraints; mod nll; mod path_utils; @@ -120,11 +117,10 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> { return tcx.arena.alloc(result); } - let promoted: &IndexSlice<_, _> = &promoted.borrow(); - let opt_closure_req = do_mir_borrowck(tcx, input_body, promoted, None).0; + let borrowck_result = do_mir_borrowck(tcx, input_body, &*promoted.borrow(), None).0; debug!("mir_borrowck done"); - tcx.arena.alloc(opt_closure_req) + tcx.arena.alloc(borrowck_result) } /// Perform the actual borrow checking. @@ -215,14 +211,21 @@ fn do_mir_borrowck<'tcx>( consumer_options, ); - // Dump MIR results into a file, if that is enabled. This let us + // Dump MIR results into a file, if that is enabled. This lets us // write unit-tests, as well as helping with debugging. nll::dump_nll_mir(&infcx, body, ®ioncx, &opt_closure_req, &borrow_set); // We also have a `#[rustc_regions]` annotation that causes us to dump // information. - let diags = &mut diags::BorrowckDiags::new(); - nll::dump_annotation(&infcx, body, ®ioncx, &opt_closure_req, &opaque_type_values, diags); + let diags_buffer = &mut BorrowckDiagnosticsBuffer::default(); + nll::dump_annotation( + &infcx, + body, + ®ioncx, + &opt_closure_req, + &opaque_type_values, + diags_buffer, + ); let movable_coroutine = // The first argument is the coroutine type passed by value @@ -261,7 +264,7 @@ fn do_mir_borrowck<'tcx>( next_region_name: RefCell::new(1), polonius_output: None, move_errors: Vec::new(), - diags, + diags_buffer, }; MoveVisitor { ctxt: &mut promoted_mbcx }.visit_body(promoted_body); promoted_mbcx.report_move_errors(); @@ -300,7 +303,7 @@ fn do_mir_borrowck<'tcx>( next_region_name: RefCell::new(1), polonius_output, move_errors: Vec::new(), - diags, + diags_buffer, }; // Compute and report region errors, if any. @@ -570,7 +573,7 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> { /// Results of Polonius analysis. polonius_output: Option>, - diags: &'a mut diags::BorrowckDiags<'infcx, 'tcx>, + diags_buffer: &'a mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>, move_errors: Vec>, } @@ -2403,146 +2406,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { } } -mod diags { - use rustc_errors::ErrorGuaranteed; - - use super::*; - - enum BufferedDiag<'infcx> { - Error(Diag<'infcx>), - NonError(Diag<'infcx, ()>), - } - - impl<'infcx> BufferedDiag<'infcx> { - fn sort_span(&self) -> Span { - match self { - BufferedDiag::Error(diag) => diag.sort_span, - BufferedDiag::NonError(diag) => diag.sort_span, - } - } - } - - pub(crate) struct BorrowckDiags<'infcx, 'tcx> { - /// This field keeps track of move errors that are to be reported for given move indices. - /// - /// There are situations where many errors can be reported for a single move out (see - /// #53807) and we want only the best of those errors. - /// - /// The `report_use_of_moved_or_uninitialized` function checks this map and replaces the - /// diagnostic (if there is one) if the `Place` of the error being reported is a prefix of - /// the `Place` of the previous most diagnostic. This happens instead of buffering the - /// error. Once all move errors have been reported, any diagnostics in this map are added - /// to the buffer to be emitted. - /// - /// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary - /// when errors in the map are being re-added to the error buffer so that errors with the - /// same primary span come out in a consistent order. - buffered_move_errors: BTreeMap, (PlaceRef<'tcx>, Diag<'infcx>)>, - - buffered_mut_errors: FxIndexMap, usize)>, - - /// Buffer of diagnostics to be reported. A mixture of error and non-error diagnostics. - buffered_diags: Vec>, - } - - impl<'infcx, 'tcx> BorrowckDiags<'infcx, 'tcx> { - pub(crate) fn new() -> Self { - BorrowckDiags { - buffered_move_errors: BTreeMap::new(), - buffered_mut_errors: Default::default(), - buffered_diags: Default::default(), - } - } - - pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) { - self.buffered_diags.push(BufferedDiag::Error(diag)); - } - - pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { - self.buffered_diags.push(BufferedDiag::NonError(diag)); - } - } - - impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { - pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) { - self.diags.buffer_error(diag); - } - - pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { - self.diags.buffer_non_error(diag); - } - - pub(crate) fn buffer_move_error( - &mut self, - move_out_indices: Vec, - place_and_err: (PlaceRef<'tcx>, Diag<'infcx>), - ) -> bool { - if let Some((_, diag)) = - self.diags.buffered_move_errors.insert(move_out_indices, place_and_err) - { - // Cancel the old diagnostic so we don't ICE - diag.cancel(); - false - } else { - true - } - } - - pub(crate) fn get_buffered_mut_error( - &mut self, - span: Span, - ) -> Option<(Diag<'infcx>, usize)> { - // FIXME(#120456) - is `swap_remove` correct? - self.diags.buffered_mut_errors.swap_remove(&span) - } - - pub(crate) fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) { - self.diags.buffered_mut_errors.insert(span, (diag, count)); - } - - pub(crate) fn emit_errors(&mut self) -> Option { - let mut res = self.infcx.tainted_by_errors(); - - // Buffer any move errors that we collected and de-duplicated. - for (_, (_, diag)) in std::mem::take(&mut self.diags.buffered_move_errors) { - // We have already set tainted for this error, so just buffer it. - self.diags.buffer_error(diag); - } - for (_, (mut diag, count)) in std::mem::take(&mut self.diags.buffered_mut_errors) { - if count > 10 { - #[allow(rustc::diagnostic_outside_of_impl)] - #[allow(rustc::untranslatable_diagnostic)] - diag.note(format!("...and {} other attempted mutable borrows", count - 10)); - } - self.diags.buffer_error(diag); - } - - if !self.diags.buffered_diags.is_empty() { - self.diags.buffered_diags.sort_by_key(|buffered_diag| buffered_diag.sort_span()); - for buffered_diag in self.diags.buffered_diags.drain(..) { - match buffered_diag { - BufferedDiag::Error(diag) => res = Some(diag.emit()), - BufferedDiag::NonError(diag) => diag.emit(), - } - } - } - - res - } - - pub(crate) fn has_buffered_diags(&self) -> bool { - self.diags.buffered_diags.is_empty() - } - - pub(crate) fn has_move_error( - &self, - move_out_indices: &[MoveOutIndex], - ) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> { - self.diags.buffered_move_errors.get(move_out_indices) - } - } -} - /// The degree of overlap between 2 places for borrow-checking. enum Overlap { /// The places might partially overlap - in this case, we give diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index abe27555b186..968b6d383c1b 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -26,17 +26,14 @@ use tracing::{debug, instrument}; use crate::borrow_set::BorrowSet; use crate::consumers::ConsumerOptions; -use crate::diagnostics::RegionErrors; -use crate::facts::{AllFacts, AllFactsExt, RustcFacts}; -use crate::location::LocationTable; +use crate::diagnostics::{BorrowckDiagnosticsBuffer, RegionErrors}; use crate::polonius::LocalizedOutlivesConstraintSet; +use crate::polonius::legacy::{AllFacts, AllFactsExt, LocationTable, PoloniusOutput}; use crate::region_infer::RegionInferenceContext; use crate::type_check::{self, MirTypeckResults}; use crate::universal_regions::UniversalRegions; use crate::{BorrowckInferCtxt, polonius, renumber}; -pub type PoloniusOutput = Output; - /// The output of `nll::compute_regions`. This includes the computed `RegionInferenceContext`, any /// closure requirements to propagate, and any generated errors. pub(crate) struct NllOutput<'tcx> { @@ -100,24 +97,28 @@ pub(crate) fn compute_regions<'a, 'tcx>( let elements = Rc::new(DenseLocationMap::new(body)); // Run the MIR type-checker. - let MirTypeckResults { constraints, universal_region_relations, opaque_type_values } = - type_check::type_check( - infcx, - body, - promoted, - universal_regions, - location_table, - borrow_set, - &mut all_facts, - flow_inits, - move_data, - Rc::clone(&elements), - ); + let MirTypeckResults { + constraints, + universal_region_relations, + opaque_type_values, + mut polonius_context, + } = type_check::type_check( + infcx, + body, + promoted, + universal_regions, + location_table, + borrow_set, + &mut all_facts, + flow_inits, + move_data, + Rc::clone(&elements), + ); // Create the region inference context, taking ownership of the // region inference data that was contained in `infcx`, and the // base constraints generated by the type-check. - let var_origins = infcx.get_region_var_origins(); + let var_infos = infcx.get_region_var_infos(); // If requested, emit legacy polonius facts. polonius::legacy::emit_facts( @@ -133,7 +134,7 @@ pub(crate) fn compute_regions<'a, 'tcx>( let mut regioncx = RegionInferenceContext::new( infcx, - var_origins, + var_infos, constraints, universal_region_relations, elements, @@ -141,12 +142,9 @@ pub(crate) fn compute_regions<'a, 'tcx>( // If requested for `-Zpolonius=next`, convert NLL constraints to localized outlives // constraints. - let localized_outlives_constraints = - if infcx.tcx.sess.opts.unstable_opts.polonius.is_next_enabled() { - Some(polonius::create_localized_constraints(&mut regioncx, body)) - } else { - None - }; + let localized_outlives_constraints = polonius_context + .as_mut() + .map(|polonius_context| polonius_context.create_localized_constraints(&mut regioncx, body)); // If requested: dump NLL facts, and run legacy polonius analysis. let polonius_output = all_facts.as_ref().and_then(|all_facts| { @@ -300,7 +298,7 @@ pub(super) fn dump_annotation<'tcx, 'infcx>( regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option>, opaque_type_values: &FxIndexMap>, - diags: &mut crate::diags::BorrowckDiags<'infcx, 'tcx>, + diagnostics_buffer: &mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>, ) { let tcx = infcx.tcx; let base_def_id = tcx.typeck_root_def_id(body.source.def_id()); @@ -346,7 +344,7 @@ pub(super) fn dump_annotation<'tcx, 'infcx>( err.note(format!("Inferred opaque type values:\n{opaque_type_values:#?}")); } - diags.buffer_non_error(err); + diagnostics_buffer.buffer_non_error(err); } fn for_each_region_constraint<'tcx>( diff --git a/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs b/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs index 9c4aa8ea1edb..4a0c8d9b4b46 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs @@ -4,9 +4,8 @@ use rustc_middle::ty::TyCtxt; use rustc_mir_dataflow::move_paths::{LookupResult, MoveData}; use tracing::debug; +use super::{AllFacts, LocationIndex, LocationTable}; use crate::def_use::{self, DefUse}; -use crate::facts::AllFacts; -use crate::location::{LocationIndex, LocationTable}; use crate::universal_regions::UniversalRegions; /// Emit polonius facts for variable defs, uses, drops, and path accesses. diff --git a/compiler/rustc_borrowck/src/facts.rs b/compiler/rustc_borrowck/src/polonius/legacy/facts.rs similarity index 96% rename from compiler/rustc_borrowck/src/facts.rs rename to compiler/rustc_borrowck/src/polonius/legacy/facts.rs index ef8e757a5478..42c4e7332183 100644 --- a/compiler/rustc_borrowck/src/facts.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/facts.rs @@ -4,18 +4,20 @@ use std::fs::{self, File}; use std::io::Write; use std::path::Path; -use polonius_engine::{AllFacts as PoloniusFacts, Atom}; +use polonius_engine::{AllFacts as PoloniusFacts, Atom, Output}; use rustc_macros::extension; use rustc_middle::mir::Local; use rustc_middle::ty::{RegionVid, TyCtxt}; use rustc_mir_dataflow::move_paths::MovePathIndex; +use super::{LocationIndex, LocationTable}; use crate::BorrowIndex; -use crate::location::{LocationIndex, LocationTable}; #[derive(Copy, Clone, Debug)] pub struct RustcFacts; +pub type PoloniusOutput = Output; + rustc_index::newtype_index! { /// A (kinda) newtype of `RegionVid` so we can implement `Atom` on it. #[orderable] @@ -246,6 +248,6 @@ impl FactCell for RegionVid { impl FactCell for LocationIndex { fn to_string(&self, location_table: &LocationTable) -> String { - format!("{:?}", location_table.to_location(*self)) + format!("{:?}", location_table.to_rich_location(*self)) } } diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs index 178f70a67304..bb6d593d0d88 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs @@ -9,9 +9,8 @@ use rustc_middle::mir::{ use rustc_middle::ty::TyCtxt; use tracing::debug; +use super::{AllFacts, LocationTable}; use crate::borrow_set::BorrowSet; -use crate::facts::AllFacts; -use crate::location::LocationTable; use crate::path_utils::*; use crate::{ AccessDepth, Activation, ArtificialField, BorrowIndex, Deep, LocalMutationIsAllowed, Read, diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs index fdde9fa04762..0148e0b28696 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs @@ -6,9 +6,8 @@ use rustc_middle::mir::{ use rustc_middle::ty::TyCtxt; use tracing::debug; +use super::{AllFacts, LocationTable}; use crate::borrow_set::BorrowSet; -use crate::facts::AllFacts; -use crate::location::LocationTable; use crate::places_conflict; /// Emit `loan_killed_at` and `cfg_edge` facts at the same time. diff --git a/compiler/rustc_borrowck/src/location.rs b/compiler/rustc_borrowck/src/polonius/legacy/location.rs similarity index 92% rename from compiler/rustc_borrowck/src/location.rs rename to compiler/rustc_borrowck/src/polonius/legacy/location.rs index fbe5f94ed42c..4cb1202033cb 100644 --- a/compiler/rustc_borrowck/src/location.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/location.rs @@ -65,7 +65,7 @@ impl LocationTable { LocationIndex::from_usize(start_index + statement_index * 2 + 1) } - pub fn to_location(&self, index: LocationIndex) -> RichLocation { + pub fn to_rich_location(&self, index: LocationIndex) -> RichLocation { let point_index = index.index(); // Find the basic block. We have a vector with the @@ -97,6 +97,13 @@ impl LocationTable { RichLocation::Mid(Location { block, statement_index }) } } + + pub fn to_location(&self, index: LocationIndex) -> Location { + match self.to_rich_location(index) { + RichLocation::Start(location) => location, + RichLocation::Mid(location) => location, + } + } } impl LocationIndex { diff --git a/compiler/rustc_borrowck/src/polonius/legacy/mod.rs b/compiler/rustc_borrowck/src/polonius/legacy/mod.rs index 60fd2afe63e1..45bdbd1e9997 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/mod.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/mod.rs @@ -13,8 +13,6 @@ use tracing::debug; use crate::borrow_set::BorrowSet; use crate::constraints::OutlivesConstraint; -use crate::facts::{AllFacts, PoloniusRegionVid}; -use crate::location::LocationTable; use crate::type_check::MirTypeckRegionConstraints; use crate::type_check::free_region_relations::UniversalRegionRelations; use crate::universal_regions::UniversalRegions; @@ -22,6 +20,10 @@ use crate::universal_regions::UniversalRegions; mod accesses; mod loan_invalidations; mod loan_kills; +mod location; +pub use self::location::*; +mod facts; +pub use self::facts::*; /// When requested, emit most of the facts needed by polonius: /// - moves and assignments diff --git a/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs new file mode 100644 index 000000000000..75ee29c9d0d5 --- /dev/null +++ b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs @@ -0,0 +1,336 @@ +use std::collections::BTreeMap; + +use rustc_index::bit_set::SparseBitMatrix; +use rustc_index::interval::SparseIntervalMatrix; +use rustc_middle::mir::{Body, Location}; +use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; +use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeVisitable}; +use rustc_mir_dataflow::points::PointIndex; + +use super::{ + ConstraintDirection, LocalizedOutlivesConstraint, LocalizedOutlivesConstraintSet, + PoloniusContext, +}; +use crate::region_infer::values::LivenessValues; +use crate::universal_regions::UniversalRegions; + +impl PoloniusContext { + /// Record the variance of each region contained within the given value. + pub(crate) fn record_live_region_variance<'tcx>( + &mut self, + tcx: TyCtxt<'tcx>, + universal_regions: &UniversalRegions<'tcx>, + value: impl TypeVisitable> + Relate>, + ) { + let mut extractor = VarianceExtractor { + tcx, + ambient_variance: ty::Variance::Covariant, + directions: &mut self.live_region_variances, + universal_regions, + }; + extractor.relate(value, value).expect("Can't have a type error relating to itself"); + } + + /// Unlike NLLs, in polonius we traverse the cfg to look for regions live across an edge, so we + /// need to transpose the "points where each region is live" matrix to a "live regions per point" + /// matrix. + // FIXME: avoid this conversion by always storing liveness data in this shape in the rest of + // borrowck. + pub(crate) fn record_live_regions_per_point( + &mut self, + num_regions: usize, + points_per_live_region: &SparseIntervalMatrix, + ) { + let mut live_regions_per_point = SparseBitMatrix::new(num_regions); + for region in points_per_live_region.rows() { + for point in points_per_live_region.row(region).unwrap().iter() { + live_regions_per_point.insert(point, region); + } + } + self.live_regions = Some(live_regions_per_point); + } +} + +/// Propagate loans throughout the CFG: for each statement in the MIR, create localized outlives +/// constraints for loans that are propagated to the next statements. +pub(super) fn create_liveness_constraints<'tcx>( + body: &Body<'tcx>, + liveness: &LivenessValues, + live_regions: &SparseBitMatrix, + live_region_variances: &BTreeMap, + universal_regions: &UniversalRegions<'tcx>, + localized_outlives_constraints: &mut LocalizedOutlivesConstraintSet, +) { + for (block, bb) in body.basic_blocks.iter_enumerated() { + let statement_count = bb.statements.len(); + for statement_index in 0..=statement_count { + let current_location = Location { block, statement_index }; + let current_point = liveness.point_from_location(current_location); + + if statement_index < statement_count { + // Intra-block edges, straight line constraints from each point to its successor + // within the same block. + let next_location = Location { block, statement_index: statement_index + 1 }; + let next_point = liveness.point_from_location(next_location); + propagate_loans_between_points( + current_point, + next_point, + live_regions, + live_region_variances, + universal_regions, + localized_outlives_constraints, + ); + } else { + // Inter-block edges, from the block's terminator to each successor block's entry + // point. + for successor_block in bb.terminator().successors() { + let next_location = Location { block: successor_block, statement_index: 0 }; + let next_point = liveness.point_from_location(next_location); + propagate_loans_between_points( + current_point, + next_point, + live_regions, + live_region_variances, + universal_regions, + localized_outlives_constraints, + ); + } + } + } + } +} + +/// Propagate loans within a region between two points in the CFG, if that region is live at both +/// the source and target points. +fn propagate_loans_between_points( + current_point: PointIndex, + next_point: PointIndex, + live_regions: &SparseBitMatrix, + live_region_variances: &BTreeMap, + universal_regions: &UniversalRegions<'_>, + localized_outlives_constraints: &mut LocalizedOutlivesConstraintSet, +) { + // Universal regions are semantically live at all points. + // Note: we always have universal regions but they're not always (or often) involved in the + // subset graph. For now, we emit all their edges unconditionally, but some of these subgraphs + // will be disconnected from the rest of the graph and thus, unnecessary. + // + // FIXME: only emit the edges of universal regions that existential regions can reach. + for region in universal_regions.universal_regions_iter() { + localized_outlives_constraints.push(LocalizedOutlivesConstraint { + source: region, + from: current_point, + target: region, + to: next_point, + }); + } + + let Some(current_live_regions) = live_regions.row(current_point) else { + // There are no constraints to add: there are no live regions at the current point. + return; + }; + let Some(next_live_regions) = live_regions.row(next_point) else { + // There are no constraints to add: there are no live regions at the next point. + return; + }; + + for region in next_live_regions.iter() { + if !current_live_regions.contains(region) { + continue; + } + + // `region` is indeed live at both points, add a constraint between them, according to + // variance. + if let Some(&direction) = live_region_variances.get(®ion) { + add_liveness_constraint( + region, + current_point, + next_point, + direction, + localized_outlives_constraints, + ); + } else { + // Note: there currently are cases related to promoted and const generics, where we + // don't yet have variance information (possibly about temporary regions created when + // typeck sanitizes the promoteds). Until that is done, we conservatively fallback to + // maximizing reachability by adding a bidirectional edge here. This will not limit + // traversal whatsoever, and thus propagate liveness when needed. + // + // FIXME: add the missing variance information and remove this fallback bidirectional + // edge. + let fallback = ConstraintDirection::Bidirectional; + add_liveness_constraint( + region, + current_point, + next_point, + fallback, + localized_outlives_constraints, + ); + } + } +} + +/// Adds `LocalizedOutlivesConstraint`s between two connected points, according to the given edge +/// direction. +fn add_liveness_constraint( + region: RegionVid, + current_point: PointIndex, + next_point: PointIndex, + direction: ConstraintDirection, + localized_outlives_constraints: &mut LocalizedOutlivesConstraintSet, +) { + match direction { + ConstraintDirection::Forward => { + // Covariant cases: loans flow in the regular direction, from the current point to the + // next point. + localized_outlives_constraints.push(LocalizedOutlivesConstraint { + source: region, + from: current_point, + target: region, + to: next_point, + }); + } + ConstraintDirection::Backward => { + // Contravariant cases: loans flow in the inverse direction, from the next point to the + // current point. + localized_outlives_constraints.push(LocalizedOutlivesConstraint { + source: region, + from: next_point, + target: region, + to: current_point, + }); + } + ConstraintDirection::Bidirectional => { + // For invariant cases, loans can flow in both directions: we add both edges. + localized_outlives_constraints.push(LocalizedOutlivesConstraint { + source: region, + from: current_point, + target: region, + to: next_point, + }); + localized_outlives_constraints.push(LocalizedOutlivesConstraint { + source: region, + from: next_point, + target: region, + to: current_point, + }); + } + } +} + +/// Extracts variances for regions contained within types. Follows the same structure as +/// `rustc_infer`'s `Generalizer`: we try to relate a type with itself to track and extract the +/// variances of regions. +struct VarianceExtractor<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + ambient_variance: ty::Variance, + directions: &'a mut BTreeMap, + universal_regions: &'a UniversalRegions<'tcx>, +} + +impl<'tcx> VarianceExtractor<'_, 'tcx> { + fn record_variance(&mut self, region: ty::Region<'tcx>, variance: ty::Variance) { + // We're only interested in the variance of vars and free regions. + // + // Note: even if we currently bail for two cases of unexpected region kinds here, missing + // variance data is not a soundness problem: the regions with missing variance will still be + // present in the constraint graph as they are live, and liveness edges construction has a + // fallback for this case. + // + // FIXME: that being said, we need to investigate these cases better to not ignore regions + // in general. + if region.is_bound() { + // We ignore these because they cannot be turned into the vids we need. + return; + } + + if region.is_erased() { + // These cannot be turned into a vid either, and we also ignore them: the fact that they + // show up here looks like either an issue upstream or a combination with unexpectedly + // continuing compilation too far when we're in a tainted by errors situation. + // + // FIXME: investigate the `generic_const_exprs` test that triggers this issue, + // `ui/const-generics/generic_const_exprs/issue-97047-ice-2.rs` + return; + } + + let direction = match variance { + ty::Covariant => ConstraintDirection::Forward, + ty::Contravariant => ConstraintDirection::Backward, + ty::Invariant => ConstraintDirection::Bidirectional, + ty::Bivariant => { + // We don't add edges for bivariant cases. + return; + } + }; + + let region = self.universal_regions.to_region_vid(region); + self.directions + .entry(region) + .and_modify(|entry| { + // If there's already a recorded direction for this region, we combine the two: + // - combining the same direction is idempotent + // - combining different directions is trivially bidirectional + if entry != &direction { + *entry = ConstraintDirection::Bidirectional; + } + }) + .or_insert(direction); + } +} + +impl<'tcx> TypeRelation> for VarianceExtractor<'_, 'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn relate_with_variance>>( + &mut self, + variance: ty::Variance, + _info: ty::VarianceDiagInfo>, + a: T, + b: T, + ) -> RelateResult<'tcx, T> { + let old_ambient_variance = self.ambient_variance; + self.ambient_variance = self.ambient_variance.xform(variance); + let r = self.relate(a, b)?; + self.ambient_variance = old_ambient_variance; + Ok(r) + } + + fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { + assert_eq!(a, b); // we are misusing TypeRelation here; both LHS and RHS ought to be == + relate::structurally_relate_tys(self, a, b) + } + + fn regions( + &mut self, + a: ty::Region<'tcx>, + b: ty::Region<'tcx>, + ) -> RelateResult<'tcx, ty::Region<'tcx>> { + assert_eq!(a, b); // we are misusing TypeRelation here; both LHS and RHS ought to be == + self.record_variance(a, self.ambient_variance); + Ok(a) + } + + fn consts( + &mut self, + a: ty::Const<'tcx>, + b: ty::Const<'tcx>, + ) -> RelateResult<'tcx, ty::Const<'tcx>> { + assert_eq!(a, b); // we are misusing TypeRelation here; both LHS and RHS ought to be == + relate::structurally_relate_consts(self, a, b) + } + + fn binders( + &mut self, + a: ty::Binder<'tcx, T>, + _: ty::Binder<'tcx, T>, + ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> + where + T: Relate>, + { + self.relate(a.skip_binder(), a.skip_binder())?; + Ok(a) + } +} diff --git a/compiler/rustc_borrowck/src/polonius/mod.rs b/compiler/rustc_borrowck/src/polonius/mod.rs index eee5e70efe34..a853ff266a11 100644 --- a/compiler/rustc_borrowck/src/polonius/mod.rs +++ b/compiler/rustc_borrowck/src/polonius/mod.rs @@ -34,45 +34,88 @@ //! mod constraints; -pub(crate) use constraints::*; mod dump; -pub(crate) use dump::dump_polonius_mir; pub(crate) mod legacy; +mod liveness_constraints; +use std::collections::BTreeMap; + +use rustc_index::bit_set::SparseBitMatrix; use rustc_middle::mir::{Body, Location}; +use rustc_middle::ty::RegionVid; use rustc_mir_dataflow::points::PointIndex; +pub(crate) use self::constraints::*; +pub(crate) use self::dump::dump_polonius_mir; +use self::liveness_constraints::create_liveness_constraints; use crate::RegionInferenceContext; use crate::constraints::OutlivesConstraint; use crate::region_infer::values::LivenessValues; use crate::type_check::Locations; -use crate::universal_regions::UniversalRegions; -/// Creates a constraint set for `-Zpolonius=next` by: -/// - converting NLL typeck constraints to be localized -/// - encoding liveness constraints -pub(crate) fn create_localized_constraints<'tcx>( - regioncx: &mut RegionInferenceContext<'tcx>, - body: &Body<'tcx>, -) -> LocalizedOutlivesConstraintSet { - let mut localized_outlives_constraints = LocalizedOutlivesConstraintSet::default(); - convert_typeck_constraints( - body, - regioncx.liveness_constraints(), - regioncx.outlives_constraints(), - &mut localized_outlives_constraints, - ); - create_liveness_constraints( - body, - regioncx.liveness_constraints(), - regioncx.universal_regions(), - &mut localized_outlives_constraints, - ); +/// This struct holds the data needed to create the Polonius localized constraints. +pub(crate) struct PoloniusContext { + /// The set of regions that are live at a given point in the CFG, used to create localized + /// outlives constraints between regions that are live at connected points in the CFG. + live_regions: Option>, - // FIXME: here, we can trace loan reachability in the constraint graph and record this as loan - // liveness for the next step in the chain, the NLL loan scope and active loans computations. + /// The expected edge direction per live region: the kind of directed edge we'll create as + /// liveness constraints depends on the variance of types with respect to each contained region. + live_region_variances: BTreeMap, +} - localized_outlives_constraints +/// The direction a constraint can flow into. Used to create liveness constraints according to +/// variance. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +enum ConstraintDirection { + /// For covariant cases, we add a forward edge `O at P1 -> O at P2`. + Forward, + + /// For contravariant cases, we add a backward edge `O at P2 -> O at P1` + Backward, + + /// For invariant cases, we add both the forward and backward edges `O at P1 <-> O at P2`. + Bidirectional, +} + +impl PoloniusContext { + pub(crate) fn new() -> PoloniusContext { + Self { live_region_variances: BTreeMap::new(), live_regions: None } + } + + /// Creates a constraint set for `-Zpolonius=next` by: + /// - converting NLL typeck constraints to be localized + /// - encoding liveness constraints + pub(crate) fn create_localized_constraints<'tcx>( + &self, + regioncx: &RegionInferenceContext<'tcx>, + body: &Body<'tcx>, + ) -> LocalizedOutlivesConstraintSet { + let mut localized_outlives_constraints = LocalizedOutlivesConstraintSet::default(); + convert_typeck_constraints( + body, + regioncx.liveness_constraints(), + regioncx.outlives_constraints(), + &mut localized_outlives_constraints, + ); + + let live_regions = self.live_regions.as_ref().expect( + "live regions per-point data should have been created at the end of MIR typeck", + ); + create_liveness_constraints( + body, + regioncx.liveness_constraints(), + live_regions, + &self.live_region_variances, + regioncx.universal_regions(), + &mut localized_outlives_constraints, + ); + + // FIXME: here, we can trace loan reachability in the constraint graph and record this as loan + // liveness for the next step in the chain, the NLL loan scope and active loans computations. + + localized_outlives_constraints + } } /// Propagate loans throughout the subset graph at a given point (with some subtleties around the @@ -109,72 +152,3 @@ fn convert_typeck_constraints<'tcx>( } } } - -/// Propagate loans throughout the CFG: for each statement in the MIR, create localized outlives -/// constraints for loans that are propagated to the next statements. -pub(crate) fn create_liveness_constraints<'tcx>( - body: &Body<'tcx>, - liveness: &LivenessValues, - universal_regions: &UniversalRegions<'tcx>, - localized_outlives_constraints: &mut LocalizedOutlivesConstraintSet, -) { - for (block, bb) in body.basic_blocks.iter_enumerated() { - let statement_count = bb.statements.len(); - for statement_index in 0..=statement_count { - let current_location = Location { block, statement_index }; - let current_point = liveness.point_from_location(current_location); - - if statement_index < statement_count { - // Intra-block edges, straight line constraints from each point to its successor - // within the same block. - let next_location = Location { block, statement_index: statement_index + 1 }; - let next_point = liveness.point_from_location(next_location); - propagate_loans_between_points( - current_point, - next_point, - liveness, - universal_regions, - localized_outlives_constraints, - ); - } else { - // Inter-block edges, from the block's terminator to each successor block's entry - // point. - for successor_block in bb.terminator().successors() { - let next_location = Location { block: successor_block, statement_index: 0 }; - let next_point = liveness.point_from_location(next_location); - propagate_loans_between_points( - current_point, - next_point, - liveness, - universal_regions, - localized_outlives_constraints, - ); - } - } - } - } -} - -/// Propagate loans within a region between two points in the CFG, if that region is live at both -/// the source and target points. -fn propagate_loans_between_points( - current_point: PointIndex, - next_point: PointIndex, - _liveness: &LivenessValues, - universal_regions: &UniversalRegions<'_>, - localized_outlives_constraints: &mut LocalizedOutlivesConstraintSet, -) { - // Universal regions are semantically live at all points. - // Note: we always have universal regions but they're not always (or often) involved in the - // subset graph. For now, we emit all their edges unconditionally, but some of these subgraphs - // will be disconnected from the rest of the graph and thus, unnecessary. - // FIXME: only emit the edges of universal regions that existential regions can reach. - for region in universal_regions.universal_regions_iter() { - localized_outlives_constraints.push(LocalizedOutlivesConstraint { - source: region, - from: current_point, - target: region, - to: next_point, - }); - } -} diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 907a3f16b068..2150759d329e 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -30,7 +30,7 @@ use crate::constraints::{ConstraintSccIndex, OutlivesConstraint, OutlivesConstra use crate::dataflow::BorrowIndex; use crate::diagnostics::{RegionErrorKind, RegionErrors, UniverseInfo}; use crate::member_constraints::{MemberConstraintSet, NllMemberConstraintIndex}; -use crate::nll::PoloniusOutput; +use crate::polonius::legacy::PoloniusOutput; use crate::region_infer::reverse_sccs::ReverseSccGraph; use crate::region_infer::values::{LivenessValues, RegionElement, RegionValues, ToElementIndex}; use crate::type_check::free_region_relations::UniversalRegionRelations; @@ -1950,8 +1950,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { target_test: impl Fn(RegionVid) -> bool, ) -> (BlameConstraint<'tcx>, Vec) { // Find all paths - let (path, target_region) = - self.find_constraint_paths_between_regions(from_region, target_test).unwrap(); + let (path, target_region) = self + .find_constraint_paths_between_regions(from_region, target_test) + .or_else(|| { + self.find_constraint_paths_between_regions(from_region, |r| { + self.cannot_name_placeholder(from_region, r) + }) + }) + .unwrap(); debug!( "path={:#?}", path.iter() diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 0b0757f16ab2..e567f3a8b0de 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -99,6 +99,14 @@ impl LivenessValues { } } + /// Returns the liveness matrix of points where each region is live. Panics if the liveness + /// values have been created without any per-point data (that is, for promoteds). + pub(crate) fn points(&self) -> &SparseIntervalMatrix { + self.points + .as_ref() + .expect("this `LivenessValues` wasn't created using `with_specific_points`") + } + /// Iterate through each region that has a value in this set. pub(crate) fn regions(&self) -> impl Iterator + '_ { self.points.as_ref().expect("use with_specific_points").rows() diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index 683293bf8286..3e9900cce5f5 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -3,6 +3,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir::visit::{TyContext, Visitor}; use rustc_middle::mir::{Body, Local, Location, SourceInfo}; use rustc_middle::span_bug; +use rustc_middle::ty::relate::Relate; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{GenericArgsRef, Region, RegionVid, Ty, TyCtxt}; use rustc_mir_dataflow::ResultsCursor; @@ -13,6 +14,7 @@ use tracing::debug; use super::TypeChecker; use crate::constraints::OutlivesConstraintSet; +use crate::polonius::PoloniusContext; use crate::region_infer::values::LivenessValues; use crate::universal_regions::UniversalRegions; @@ -56,7 +58,13 @@ pub(super) fn generate<'a, 'tcx>( // Mark regions that should be live where they appear within rvalues or within a call: like // args, regions, and types. - record_regular_live_regions(typeck.tcx(), &mut typeck.constraints.liveness_constraints, body); + record_regular_live_regions( + typeck.tcx(), + &mut typeck.constraints.liveness_constraints, + &typeck.universal_regions, + &mut typeck.polonius_context, + body, + ); } // The purpose of `compute_relevant_live_locals` is to define the subset of `Local` @@ -130,9 +138,12 @@ fn regions_that_outlive_free_regions<'tcx>( fn record_regular_live_regions<'tcx>( tcx: TyCtxt<'tcx>, liveness_constraints: &mut LivenessValues, + universal_regions: &UniversalRegions<'tcx>, + polonius_context: &mut Option, body: &Body<'tcx>, ) { - let mut visitor = LiveVariablesVisitor { tcx, liveness_constraints }; + let mut visitor = + LiveVariablesVisitor { tcx, liveness_constraints, universal_regions, polonius_context }; for (bb, data) in body.basic_blocks.iter_enumerated() { visitor.visit_basic_block_data(bb, data); } @@ -142,6 +153,8 @@ fn record_regular_live_regions<'tcx>( struct LiveVariablesVisitor<'a, 'tcx> { tcx: TyCtxt<'tcx>, liveness_constraints: &'a mut LivenessValues, + universal_regions: &'a UniversalRegions<'tcx>, + polonius_context: &'a mut Option, } impl<'a, 'tcx> Visitor<'tcx> for LiveVariablesVisitor<'a, 'tcx> { @@ -184,12 +197,17 @@ impl<'a, 'tcx> LiveVariablesVisitor<'a, 'tcx> { /// all regions appearing in the type of `value` must be live at `location`. fn record_regions_live_at(&mut self, value: T, location: Location) where - T: TypeVisitable>, + T: TypeVisitable> + Relate>, { debug!("record_regions_live_at(value={:?}, location={:?})", value, location); self.tcx.for_each_free_region(&value, |live_region| { let live_region_vid = live_region.as_var(); self.liveness_constraints.add_location(live_region_vid, location); }); + + // When using `-Zpolonius=next`, we record the variance of each live region. + if let Some(polonius_context) = self.polonius_context { + polonius_context.record_live_region_variance(self.tcx, self.universal_regions, value); + } } } diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index f510d193dd9f..c7a2d32b31dc 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -5,6 +5,7 @@ use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::for_liveness; use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location}; use rustc_middle::traits::query::DropckOutlivesResult; +use rustc_middle::ty::relate::Relate; use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable, TypeVisitableExt}; use rustc_mir_dataflow::ResultsCursor; use rustc_mir_dataflow::impls::MaybeInitializedPlaces; @@ -14,7 +15,6 @@ use rustc_span::DUMMY_SP; use rustc_trait_selection::traits::query::type_op::{DropckOutlives, TypeOp, TypeOpOutput}; use tracing::debug; -use crate::location::RichLocation; use crate::polonius; use crate::region_infer::values::{self, LiveLoans}; use crate::type_check::liveness::local_use_map::LocalUseMap; @@ -210,7 +210,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { /// /// Add facts for all locals with free regions, since regions may outlive /// the function body only at certain nodes in the CFG. - fn add_extra_drop_facts(&mut self, relevant_live_locals: &[Local]) -> Option<()> { + fn add_extra_drop_facts(&mut self, relevant_live_locals: &[Local]) { // This collect is more necessary than immediately apparent // because these facts go into `add_drop_live_facts_for()`, // which also writes to `all_facts`, and so this is genuinely @@ -220,41 +220,30 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { // and probably maybe plausibly does not need to go back in. // It may be necessary to just pick out the parts of // `add_drop_live_facts_for()` that make sense. + let Some(facts) = self.cx.typeck.all_facts.as_ref() else { return }; let facts_to_add: Vec<_> = { - let drop_used = &self.cx.typeck.all_facts.as_ref()?.var_dropped_at; - let relevant_live_locals: FxIndexSet<_> = relevant_live_locals.iter().copied().collect(); - drop_used + facts + .var_dropped_at .iter() - .filter_map(|(local, location_index)| { - let local_ty = self.cx.body.local_decls[*local].ty; - if relevant_live_locals.contains(local) || !local_ty.has_free_regions() { + .filter_map(|&(local, location_index)| { + let local_ty = self.cx.body.local_decls[local].ty; + if relevant_live_locals.contains(&local) || !local_ty.has_free_regions() { return None; } - let location = match self.cx.typeck.location_table.to_location(*location_index) - { - RichLocation::Start(l) => l, - RichLocation::Mid(l) => l, - }; - - Some((*local, local_ty, location)) + let location = self.cx.typeck.location_table.to_location(location_index); + Some((local, local_ty, location)) }) .collect() }; - // FIXME: these locations seem to have a special meaning (e.g. everywhere, at the end, - // ...), but I don't know which one. Please help me rename it to something descriptive! - // Also, if this IntervalSet is used in many places, it maybe should have a newtype'd - // name with a description of what it means for future mortals passing by. - let locations = IntervalSet::new(self.cx.elements.num_points()); - + let live_at = IntervalSet::new(self.cx.elements.num_points()); for (local, local_ty, location) in facts_to_add { - self.cx.add_drop_live_facts_for(local, local_ty, &[location], &locations); + self.cx.add_drop_live_facts_for(local, local_ty, &[location], &live_at); } - Some(()) } /// Clear the value of fields that are "per local variable". @@ -532,11 +521,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { /// Stores the result that all regions in `value` are live for the /// points `live_at`. - fn add_use_live_facts_for( - &mut self, - value: impl TypeVisitable>, - live_at: &IntervalSet, - ) { + fn add_use_live_facts_for(&mut self, value: Ty<'tcx>, live_at: &IntervalSet) { debug!("add_use_live_facts_for(value={:?})", value); Self::make_all_regions_live(self.elements, self.typeck, value, live_at); } @@ -603,7 +588,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { fn make_all_regions_live( elements: &DenseLocationMap, typeck: &mut TypeChecker<'_, 'tcx>, - value: impl TypeVisitable>, + value: impl TypeVisitable> + Relate>, live_at: &IntervalSet, ) { debug!("make_all_regions_live(value={:?})", value); @@ -621,6 +606,15 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { typeck.constraints.liveness_constraints.add_points(live_region_vid, live_at); }, }); + + // When using `-Zpolonius=next`, we record the variance of each live region. + if let Some(polonius_context) = typeck.polonius_context { + polonius_context.record_live_region_variance( + typeck.infcx.tcx, + typeck.universal_regions, + value, + ); + } } fn compute_drop_data(typeck: &TypeChecker<'_, 'tcx>, dropped_ty: Ty<'tcx>) -> DropData<'tcx> { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index c29f3033dd06..10fb8a399a26 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -47,9 +47,9 @@ use tracing::{debug, instrument, trace}; use crate::borrow_set::BorrowSet; use crate::constraints::{OutlivesConstraint, OutlivesConstraintSet}; use crate::diagnostics::UniverseInfo; -use crate::facts::AllFacts; -use crate::location::LocationTable; use crate::member_constraints::MemberConstraintSet; +use crate::polonius::PoloniusContext; +use crate::polonius::legacy::{AllFacts, LocationTable}; use crate::region_infer::TypeTest; use crate::region_infer::values::{LivenessValues, PlaceholderIndex, PlaceholderIndices}; use crate::renumber::RegionCtxt; @@ -140,8 +140,20 @@ pub(crate) fn type_check<'a, 'tcx>( &mut constraints, ); + let pre_obligations = infcx.take_registered_region_obligations(); + assert!( + pre_obligations.is_empty(), + "there should be no incoming region obligations = {pre_obligations:#?}", + ); + debug!(?normalized_inputs_and_output); + let mut polonius_context = if infcx.tcx.sess.opts.unstable_opts.polonius.is_next_enabled() { + Some(PoloniusContext::new()) + } else { + None + }; + let mut typeck = TypeChecker { infcx, last_span: body.span, @@ -156,6 +168,7 @@ pub(crate) fn type_check<'a, 'tcx>( all_facts, borrow_set, constraints: &mut constraints, + polonius_context: &mut polonius_context, }; typeck.check_user_type_annotations(); @@ -172,7 +185,18 @@ pub(crate) fn type_check<'a, 'tcx>( let opaque_type_values = opaque_types::take_opaques_and_register_member_constraints(&mut typeck); - MirTypeckResults { constraints, universal_region_relations, opaque_type_values } + if let Some(polonius_context) = typeck.polonius_context.as_mut() { + let num_regions = infcx.num_region_vars(); + let points_per_live_region = typeck.constraints.liveness_constraints.points(); + polonius_context.record_live_regions_per_point(num_regions, points_per_live_region); + } + + MirTypeckResults { + constraints, + universal_region_relations, + opaque_type_values, + polonius_context, + } } #[track_caller] @@ -540,6 +564,8 @@ struct TypeChecker<'a, 'tcx> { all_facts: &'a mut Option, borrow_set: &'a BorrowSet<'tcx>, constraints: &'a mut MirTypeckRegionConstraints<'tcx>, + /// When using `-Zpolonius=next`, the helper data used to create polonius constraints. + polonius_context: &'a mut Option, } /// Holder struct for passing results from MIR typeck to the rest of the non-lexical regions @@ -548,6 +574,7 @@ pub(crate) struct MirTypeckResults<'tcx> { pub(crate) constraints: MirTypeckRegionConstraints<'tcx>, pub(crate) universal_region_relations: Frozen>, pub(crate) opaque_type_values: FxIndexMap, OpaqueHiddenType<'tcx>>, + pub(crate) polonius_context: Option, } /// A collection of region constraints that must be satisfied for the diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 1ac45cbea38f..3dc4569c57b9 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -337,7 +337,7 @@ impl<'tcx> UniversalRegions<'tcx> { self.indices.indices.iter().map(|(&r, &v)| (r, v)) } - /// See `UniversalRegionIndices::to_region_vid`. + /// See [UniversalRegionIndices::to_region_vid]. pub(crate) fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { self.indices.to_region_vid(r) } diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch index 6012af6a8dd2..bf07e455a75f 100644 --- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch +++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch @@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644 [dependencies] core = { path = "../core" } --compiler_builtins = { version = "=0.1.138", features = ['rustc-dep-of-std'] } -+compiler_builtins = { version = "=0.1.138", features = ['rustc-dep-of-std', 'no-f16-f128'] } +-compiler_builtins = { version = "=0.1.140", features = ['rustc-dep-of-std'] } ++compiler_builtins = { version = "=0.1.140", features = ['rustc-dep-of-std', 'no-f16-f128'] } [dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 45294ea35b16..ae5e818d86f1 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -189,7 +189,7 @@ pub(crate) fn target_machine_factory( let reloc_model = to_llvm_relocation_model(sess.relocation_model()); let (opt_level, _) = to_llvm_opt_settings(optlvl); - let use_softfp = if sess.target.arch == "arm" && sess.target.abi == "eabihf" { + let use_softfp = if sess.target.arch == "arm" { sess.opts.cg.soft_float } else { // `validate_commandline_args_with_session_available` has already warned about this being diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index c38c5d4c6442..cabcfc9b42b4 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -340,6 +340,37 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { self.const_i32(cache_type), ]) } + sym::carrying_mul_add => { + let (size, signed) = fn_args.type_at(0).int_size_and_signed(self.tcx); + + let wide_llty = self.type_ix(size.bits() * 2); + let args = args.as_array().unwrap(); + let [a, b, c, d] = args.map(|a| self.intcast(a.immediate(), wide_llty, signed)); + + let wide = if signed { + let prod = self.unchecked_smul(a, b); + let acc = self.unchecked_sadd(prod, c); + self.unchecked_sadd(acc, d) + } else { + let prod = self.unchecked_umul(a, b); + let acc = self.unchecked_uadd(prod, c); + self.unchecked_uadd(acc, d) + }; + + let narrow_llty = self.type_ix(size.bits()); + let low = self.trunc(wide, narrow_llty); + let bits_const = self.const_uint(wide_llty, size.bits()); + // No need for ashr when signed; LLVM changes it to lshr anyway. + let high = self.lshr(wide, bits_const); + // FIXME: could be `trunc nuw`, even for signed. + let high = self.trunc(high, narrow_llty); + + let pair_llty = self.type_struct(&[narrow_llty, narrow_llty], false); + let pair = self.const_poison(pair_llty); + let pair = self.insert_value(pair, low, 0); + let pair = self.insert_value(pair, high, 1); + pair + } sym::ctlz | sym::ctlz_nonzero | sym::cttz diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 0de0c6a7a89e..dca7738daf77 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -17,6 +17,7 @@ #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(rustdoc_internals)] +#![feature(slice_as_array)] #![feature(try_blocks)] #![warn(unreachable_pub)] // tidy-alphabetical-end diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 3a9b4d368078..f0456e62442a 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -10,7 +10,7 @@ arrayvec = { version = "0.7", default-features = false } bitflags = "2.4.1" # Pinned so `cargo update` bumps don't cause breakage. Please also update the # `cc` in `rustc_llvm` if you update the `cc` here. -cc = "=1.2.5" +cc = "=1.2.6" either = "1.5.0" itertools = "0.12" pathdiff = "0.2.0" diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index d9eece1d8dc9..58eb137c0687 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -2,7 +2,7 @@ use std::env; use std::error::Error; use std::ffi::OsString; use std::fs::{self, File}; -use std::io::{self, Write}; +use std::io::{self, BufWriter, Write}; use std::path::{Path, PathBuf}; use ar_archive_writer::{ @@ -509,9 +509,10 @@ impl<'a> ArArchiveBuilder<'a> { io_error_context("couldn't create a directory for the temp file", err) })?; let archive_tmpfile_path = archive_tmpdir.path().join("tmp.a"); - let mut archive_tmpfile = File::create_new(&archive_tmpfile_path) + let archive_tmpfile = File::create_new(&archive_tmpfile_path) .map_err(|err| io_error_context("couldn't create the temp file", err))?; + let mut archive_tmpfile = BufWriter::new(archive_tmpfile); write_archive_to_stream( &mut archive_tmpfile, &entries, @@ -519,6 +520,8 @@ impl<'a> ArArchiveBuilder<'a> { false, /* is_ec = */ self.sess.target.arch == "arm64ec", )?; + archive_tmpfile.flush()?; + drop(archive_tmpfile); let any_entries = !entries.is_empty(); drop(entries); diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 299b98c0a4f0..304ac4544ee4 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -75,7 +75,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // If we're swapping something that's *not* an `OperandValue::Ref`, // then we can do it directly and avoid the alloca. // Otherwise, we'll let the fallback MIR body take care of it. - if let sym::typed_swap = name { + if let sym::typed_swap_nonoverlapping = name { let pointee_ty = fn_args.type_at(0); let pointee_layout = bx.layout_of(pointee_ty); if !bx.is_backend_ref(pointee_layout) diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index b0138ac8bfed..3ee13b19f665 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -382,7 +382,7 @@ pub trait BuilderMethods<'a, 'tcx>: /// Avoids `alloca`s for Immediates and ScalarPairs. /// /// FIXME: Maybe do something smarter for Ref types too? - /// For now, the `typed_swap` intrinsic just doesn't call this for those + /// For now, the `typed_swap_nonoverlapping` intrinsic just doesn't call this for those /// cases (in non-debug), preferring the fallback body instead. fn typed_place_swap( &mut self, diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index babf99c4c1fe..8af17d01b0a3 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -15,20 +15,14 @@ fn parent_impl_constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness } } -/// Checks whether an item is considered to be `const`. If it is a constructor, it is const. -/// If it is an assoc method or function, -/// return if it has a `const` modifier. If it is an intrinsic, report whether said intrinsic -/// has a `rustc_const_{un,}stable` attribute. Otherwise, panic. +/// Checks whether a function-like definition is considered to be `const`. fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { let node = tcx.hir_node_by_def_id(def_id); match node { - hir::Node::Ctor(hir::VariantData::Tuple(..)) - | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => { - hir::Constness::Const - } - hir::Node::ForeignItem(_) => { - // Foreign items cannot be evaluated at compile-time. + hir::Node::Ctor(hir::VariantData::Tuple(..)) => hir::Constness::Const, + hir::Node::ForeignItem(item) if let hir::ForeignItemKind::Fn(..) = item.kind => { + // Foreign functions cannot be evaluated at compile-time. hir::Constness::NotConst } hir::Node::Expr(e) if let hir::ExprKind::Closure(c) = e.kind => c.constness, diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 46720328ea47..99f0ac702c54 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -883,19 +883,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { .local_to_op(mir::RETURN_PLACE, None) .expect("return place should always be live"); let dest = self.frame().return_place.clone(); - let res = if self.stack().len() == 1 { - // The initializer of constants and statics will get validated separately - // after the constant has been fully evaluated. While we could fall back to the default - // code path, that will cause -Zenforce-validity to cycle on static initializers. - // Reading from a static's memory is not allowed during its evaluation, and will always - // trigger a cycle error. Validation must read from the memory of the current item. - // For Miri this means we do not validate the root frame return value, - // but Miri anyway calls `read_target_isize` on that so separate validation - // is not needed. - self.copy_op_no_dest_validation(&op, &dest) - } else { - self.copy_op_allow_transmute(&op, &dest) - }; + let res = self.copy_op_allow_transmute(&op, &dest); trace!("return value: {:?}", self.dump_place(&dest.into())); // We delay actually short-circuiting on this error until *after* the stack frame is // popped, since we want this error to be attributed to the caller, whose type defines diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index e9eca8814c3c..0664a882c1d5 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -424,8 +424,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let result = self.raw_eq_intrinsic(&args[0], &args[1])?; self.write_scalar(result, dest)?; } - sym::typed_swap => { - self.typed_swap_intrinsic(&args[0], &args[1])?; + sym::typed_swap_nonoverlapping => { + self.typed_swap_nonoverlapping_intrinsic(&args[0], &args[1])?; } sym::vtable_size => { @@ -638,19 +638,35 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } /// Does a *typed* swap of `*left` and `*right`. - fn typed_swap_intrinsic( + fn typed_swap_nonoverlapping_intrinsic( &mut self, left: &OpTy<'tcx, >::Provenance>, right: &OpTy<'tcx, >::Provenance>, ) -> InterpResult<'tcx> { let left = self.deref_pointer(left)?; let right = self.deref_pointer(right)?; - debug_assert_eq!(left.layout, right.layout); + assert_eq!(left.layout, right.layout); + assert!(left.layout.is_sized()); let kind = MemoryKind::Stack; let temp = self.allocate(left.layout, kind)?; - self.copy_op(&left, &temp)?; - self.copy_op(&right, &left)?; - self.copy_op(&temp, &right)?; + self.copy_op(&left, &temp)?; // checks alignment of `left` + + // We want to always enforce non-overlapping, even if this is a scalar type. + // Therefore we directly use the underlying `mem_copy` here. + self.mem_copy(right.ptr(), left.ptr(), left.layout.size, /*nonoverlapping*/ true)?; + // This means we also need to do the validation of the value that used to be in `right` + // ourselves. This value is now in `left.` The one that started out in `left` already got + // validated by the copy above. + if M::enforce_validity(self, left.layout) { + self.validate_operand( + &left.clone().into(), + M::enforce_validity_recursively(self, left.layout), + /*reset_provenance_and_padding*/ true, + )?; + } + + self.copy_op(&temp, &right)?; // checks alignment of `right` + self.deallocate_ptr(temp.ptr(), None, kind)?; interp_ok(()) } diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 027ba9644cba..0790db984e34 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -1359,6 +1359,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let src_alloc = self.get_alloc_raw(src_alloc_id)?; let src_range = alloc_range(src_offset, size); assert!(!self.memory.validation_in_progress, "we can't be copying during validation"); + // For the overlapping case, it is crucial that we trigger the read hook + // before the write hook -- the aliasing model cares about the order. M::before_memory_read( tcx, &self.machine, diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 810e9356b26c..0d9740716193 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -773,22 +773,6 @@ where interp_ok(()) } - /// Copies the data from an operand to a place. - /// The layouts of the `src` and `dest` may disagree. - /// Does not perform validation of the destination. - /// The only known use case for this function is checking the return - /// value of a static during stack frame popping. - #[inline(always)] - pub(super) fn copy_op_no_dest_validation( - &mut self, - src: &impl Projectable<'tcx, M::Provenance>, - dest: &impl Writeable<'tcx, M::Provenance>, - ) -> InterpResult<'tcx> { - self.copy_op_inner( - src, dest, /* allow_transmute */ true, /* validate_dest */ false, - ) - } - /// Copies the data from an operand to a place. /// The layouts of the `src` and `dest` may disagree. #[inline(always)] @@ -797,9 +781,7 @@ where src: &impl Projectable<'tcx, M::Provenance>, dest: &impl Writeable<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { - self.copy_op_inner( - src, dest, /* allow_transmute */ true, /* validate_dest */ true, - ) + self.copy_op_inner(src, dest, /* allow_transmute */ true) } /// Copies the data from an operand to a place. @@ -810,9 +792,7 @@ where src: &impl Projectable<'tcx, M::Provenance>, dest: &impl Writeable<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { - self.copy_op_inner( - src, dest, /* allow_transmute */ false, /* validate_dest */ true, - ) + self.copy_op_inner(src, dest, /* allow_transmute */ false) } /// Copies the data from an operand to a place. @@ -824,22 +804,21 @@ where src: &impl Projectable<'tcx, M::Provenance>, dest: &impl Writeable<'tcx, M::Provenance>, allow_transmute: bool, - validate_dest: bool, ) -> InterpResult<'tcx> { // These are technically *two* typed copies: `src` is a not-yet-loaded value, - // so we're going a typed copy at `src` type from there to some intermediate storage. + // so we're doing a typed copy at `src` type from there to some intermediate storage. // And then we're doing a second typed copy from that intermediate storage to `dest`. // But as an optimization, we only make a single direct copy here. // Do the actual copy. self.copy_op_no_validate(src, dest, allow_transmute)?; - if validate_dest && M::enforce_validity(self, dest.layout()) { + if M::enforce_validity(self, dest.layout()) { let dest = dest.to_place(); // Given that there were two typed copies, we have to ensure this is valid at both types, // and we have to ensure this loses provenance and padding according to both types. // But if the types are identical, we only do one pass. - if allow_transmute && src.layout().ty != dest.layout().ty { + if src.layout().ty != dest.layout().ty { self.validate_operand( &dest.transmute(src.layout(), self)?, M::enforce_validity_recursively(self, src.layout()), diff --git a/compiler/rustc_error_codes/src/error_codes/E0253.md b/compiler/rustc_error_codes/src/error_codes/E0253.md index aea51d402382..705d1bfc53e5 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0253.md +++ b/compiler/rustc_error_codes/src/error_codes/E0253.md @@ -1,19 +1,19 @@ -Attempt was made to import an unimportable value. This can happen when trying -to import a method from a trait. +Attempt was made to import an unimportable type. This can happen when trying +to import a type from a trait. Erroneous code example: ```compile_fail,E0253 mod foo { pub trait MyTrait { - fn do_something(); + type SomeType; } } -use foo::MyTrait::do_something; -// error: `do_something` is not directly importable +use foo::MyTrait::SomeType; +// error: `SomeType` is not directly importable fn main() {} ``` -It's invalid to directly import methods belonging to a trait or concrete type. +It's invalid to directly import types belonging to a trait. diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 977721a5b8a2..f938352820df 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2216,6 +2216,11 @@ impl HumanEmitter { show_code_change { for part in parts { + let snippet = if let Ok(snippet) = sm.span_to_snippet(part.span) { + snippet + } else { + String::new() + }; let span_start_pos = sm.lookup_char_pos(part.span.lo()).col_display; let span_end_pos = sm.lookup_char_pos(part.span.hi()).col_display; @@ -2263,13 +2268,80 @@ impl HumanEmitter { } if let DisplaySuggestion::Diff = show_code_change { // Colorize removal with red in diff format. - buffer.set_style_range( - row_num - 2, - (padding as isize + span_start_pos as isize) as usize, - (padding as isize + span_end_pos as isize) as usize, - Style::Removal, - true, - ); + + // Below, there's some tricky buffer indexing going on. `row_num` at this + // point corresponds to: + // + // | + // LL | CODE + // | ++++ <- `row_num` + // + // in the buffer. When we have a diff format output, we end up with + // + // | + // LL - OLDER <- row_num - 2 + // LL + NEWER + // | <- row_num + // + // The `row_num - 2` is to select the buffer line that has the "old version + // of the diff" at that point. When the removal is a single line, `i` is + // `0`, `newlines` is `1` so `(newlines - i - 1)` ends up being `0`, so row + // points at `LL - OLDER`. When the removal corresponds to multiple lines, + // we end up with `newlines > 1` and `i` being `0..newlines - 1`. + // + // | + // LL - OLDER <- row_num - 2 - (newlines - last_i - 1) + // LL - CODE + // LL - BEING + // LL - REMOVED <- row_num - 2 - (newlines - first_i - 1) + // LL + NEWER + // | <- row_num + + let newlines = snippet.lines().count(); + if newlines > 0 && row_num > newlines { + // Account for removals where the part being removed spans multiple + // lines. + // FIXME: We check the number of rows because in some cases, like in + // `tests/ui/lint/invalid-nan-comparison-suggestion.rs`, the rendered + // suggestion will only show the first line of code being replaced. The + // proper way of doing this would be to change the suggestion rendering + // logic to show the whole prior snippet, but the current output is not + // too bad to begin with, so we side-step that issue here. + for (i, line) in snippet.lines().enumerate() { + let line = normalize_whitespace(line); + let row = row_num - 2 - (newlines - i - 1); + // On the first line, we highlight between the start of the part + // span, and the end of that line. + // On the last line, we highlight between the start of the line, and + // the column of the part span end. + // On all others, we highlight the whole line. + let start = if i == 0 { + (padding as isize + span_start_pos as isize) as usize + } else { + padding + }; + let end = if i == 0 { + (padding as isize + + span_start_pos as isize + + line.len() as isize) + as usize + } else if i == newlines - 1 { + (padding as isize + span_end_pos as isize) as usize + } else { + (padding as isize + line.len() as isize) as usize + }; + buffer.set_style_range(row, start, end, Style::Removal, true); + } + } else { + // The removed code fits all in one line. + buffer.set_style_range( + row_num - 2, + (padding as isize + span_start_pos as isize) as usize, + (padding as isize + span_end_pos as isize) as usize, + Style::Removal, + true, + ); + } } // length of the code after substitution diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 4fb1eadd486e..ef209c2bce12 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -697,8 +697,10 @@ fn transcribe_metavar_expr<'a>( MetaVarExprConcatElem::Var(ident) => { match matched_from_ident(dcx, *ident, interp)? { NamedMatch::MatchedSeq(named_matches) => { - let curr_idx = repeats.last().unwrap().0; - match &named_matches[curr_idx] { + let Some((curr_idx, _)) = repeats.last() else { + return Err(dcx.struct_span_err(sp.entire(), "invalid syntax")); + }; + match &named_matches[*curr_idx] { // FIXME(c410-f3r) Nested repetitions are unimplemented MatchedSeq(_) => unimplemented!(), MatchedSingle(pnr) => { diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index d40823d2ed62..8b5cecc3e4fe 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -519,6 +519,8 @@ declare_features! ( (unstable, impl_trait_in_bindings, "1.64.0", Some(63065)), /// Allows `impl Trait` as output type in `Fn` traits in return position of functions. (unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697)), + /// Allows `use` associated functions from traits. + (unstable, import_trait_associated_functions, "CURRENT_RUSTC_VERSION", Some(134691)), /// Allows associated types in inherent impls. (incomplete, inherent_associated_types, "1.52.0", Some(8995)), /// Allow anonymous constants from an inline `const` block in pattern position diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 394794019109..fd78bf3e8fc6 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -94,6 +94,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) - | sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow + | sym::carrying_mul_add | sym::wrapping_add | sym::wrapping_sub | sym::wrapping_mul @@ -436,6 +437,10 @@ pub fn check_intrinsic_type( (1, 0, vec![param(0), param(0)], Ty::new_tup(tcx, &[param(0), tcx.types.bool])) } + sym::carrying_mul_add => { + (2, 0, vec![param(0); 4], Ty::new_tup(tcx, &[param(1), param(0)])) + } + sym::ptr_guaranteed_cmp => ( 1, 0, @@ -496,7 +501,9 @@ pub fn check_intrinsic_type( (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit) } - sym::typed_swap => (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)); 2], tcx.types.unit), + sym::typed_swap_nonoverlapping => { + (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)); 2], tcx.types.unit) + } sym::discriminant_value => { let assoc_items = tcx.associated_item_def_ids( diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 664b77fd49eb..38e2dbbde7d0 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -179,7 +179,12 @@ impl BitSet { /// Insert `elem`. Returns whether the set has changed. #[inline] pub fn insert(&mut self, elem: T) -> bool { - assert!(elem.index() < self.domain_size); + assert!( + elem.index() < self.domain_size, + "inserting element at index {} but domain size is {}", + elem.index(), + self.domain_size, + ); let (word_index, mask) = word_index_and_mask(elem); let word_ref = &mut self.words[word_index]; let word = *word_ref; diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index c5a56005c063..1f7180fb80a0 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -945,7 +945,7 @@ impl<'tcx> InferCtxt<'tcx> { /// Clone the list of variable regions. This is used only during NLL processing /// to put the set of region variables into the NLL region context. - pub fn get_region_var_origins(&self) -> VarInfos { + pub fn get_region_var_infos(&self) -> VarInfos { let inner = self.inner.borrow(); assert!(!UndoLogs::>::in_snapshot(&inner.undo_log)); let storage = inner.region_constraint_storage.as_ref().expect("regions already resolved"); diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 6dce4b2b21df..6496f38269a5 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -299,10 +299,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { self.storage.var_infos.len() } - pub fn region_constraint_data(&self) -> &RegionConstraintData<'tcx> { - &self.storage.data - } - /// Takes (and clears) the current set of constraints. Note that /// the set of variables remains intact, but all relationships /// between them are reset. This is used during NLL checking to diff --git a/compiler/rustc_lint/src/default_could_be_derived.rs b/compiler/rustc_lint/src/default_could_be_derived.rs new file mode 100644 index 000000000000..d95cbb051580 --- /dev/null +++ b/compiler/rustc_lint/src/default_could_be_derived.rs @@ -0,0 +1,185 @@ +use rustc_data_structures::fx::FxHashMap; +use rustc_errors::Diag; +use rustc_hir as hir; +use rustc_middle::ty; +use rustc_session::{declare_lint, impl_lint_pass}; +use rustc_span::Symbol; +use rustc_span::symbol::sym; + +use crate::{LateContext, LateLintPass}; + +declare_lint! { + /// The `default_overrides_default_fields` lint checks for manual `impl` blocks of the + /// `Default` trait of types with default field values. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// #![feature(default_field_values)] + /// struct Foo { + /// x: i32 = 101, + /// y: NonDefault, + /// } + /// + /// struct NonDefault; + /// + /// #[deny(default_overrides_default_fields)] + /// impl Default for Foo { + /// fn default() -> Foo { + /// Foo { x: 100, y: NonDefault } + /// } + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Manually writing a `Default` implementation for a type that has + /// default field values runs the risk of diverging behavior between + /// `Type { .. }` and `::default()`, which would be a + /// foot-gun for users of that type that would expect these to be + /// equivalent. If `Default` can't be derived due to some fields not + /// having a `Default` implementation, we encourage the use of `..` for + /// the fields that do have a default field value. + pub DEFAULT_OVERRIDES_DEFAULT_FIELDS, + Deny, + "detect `Default` impl that should use the type's default field values", + @feature_gate = default_field_values; +} + +#[derive(Default)] +pub(crate) struct DefaultCouldBeDerived; + +impl_lint_pass!(DefaultCouldBeDerived => [DEFAULT_OVERRIDES_DEFAULT_FIELDS]); + +impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived { + fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) { + // Look for manual implementations of `Default`. + let Some(default_def_id) = cx.tcx.get_diagnostic_item(sym::Default) else { return }; + let hir::ImplItemKind::Fn(_sig, body_id) = impl_item.kind else { return }; + let assoc = cx.tcx.associated_item(impl_item.owner_id); + let parent = assoc.container_id(cx.tcx); + if cx.tcx.has_attr(parent, sym::automatically_derived) { + // We don't care about what `#[derive(Default)]` produces in this lint. + return; + } + let Some(trait_ref) = cx.tcx.impl_trait_ref(parent) else { return }; + let trait_ref = trait_ref.instantiate_identity(); + if trait_ref.def_id != default_def_id { + return; + } + let ty = trait_ref.self_ty(); + let ty::Adt(def, _) = ty.kind() else { return }; + + // We now know we have a manually written definition of a `::default()`. + + let hir = cx.tcx.hir(); + + let type_def_id = def.did(); + let body = hir.body(body_id); + + // FIXME: evaluate bodies with statements and evaluate bindings to see if they would be + // derivable. + let hir::ExprKind::Block(hir::Block { stmts: _, expr: Some(expr), .. }, None) = + body.value.kind + else { + return; + }; + + // Keep a mapping of field name to `hir::FieldDef` for every field in the type. We'll use + // these to check for things like checking whether it has a default or using its span for + // suggestions. + let orig_fields = match hir.get_if_local(type_def_id) { + Some(hir::Node::Item(hir::Item { + kind: + hir::ItemKind::Struct(hir::VariantData::Struct { fields, recovered: _ }, _generics), + .. + })) => fields.iter().map(|f| (f.ident.name, f)).collect::>(), + _ => return, + }; + + // We check `fn default()` body is a single ADT literal and get all the fields that are + // being set. + let hir::ExprKind::Struct(_qpath, fields, tail) = expr.kind else { return }; + + // We have a struct literal + // + // struct Foo { + // field: Type, + // } + // + // impl Default for Foo { + // fn default() -> Foo { + // Foo { + // field: val, + // } + // } + // } + // + // We would suggest `#[derive(Default)]` if `field` has a default value, regardless of what + // it is; we don't want to encourage divergent behavior between `Default::default()` and + // `..`. + + if let hir::StructTailExpr::Base(_) = tail { + // This is *very* niche. We'd only get here if someone wrote + // impl Default for Ty { + // fn default() -> Ty { + // Ty { ..something() } + // } + // } + // where `something()` would have to be a call or path. + // We have nothing meaninful to do with this. + return; + } + + // At least one of the fields with a default value have been overriden in + // the `Default` implementation. We suggest removing it and relying on `..` + // instead. + let any_default_field_given = + fields.iter().any(|f| orig_fields.get(&f.ident.name).and_then(|f| f.default).is_some()); + + if !any_default_field_given { + // None of the default fields were actually provided explicitly, so the manual impl + // doesn't override them (the user used `..`), so there's no risk of divergent behavior. + return; + } + + let Some(local) = parent.as_local() else { return }; + let hir_id = cx.tcx.local_def_id_to_hir_id(local); + let hir::Node::Item(item) = cx.tcx.hir_node(hir_id) else { return }; + cx.tcx.node_span_lint(DEFAULT_OVERRIDES_DEFAULT_FIELDS, hir_id, item.span, |diag| { + mk_lint(diag, orig_fields, fields); + }); + } +} + +fn mk_lint( + diag: &mut Diag<'_, ()>, + orig_fields: FxHashMap>, + fields: &[hir::ExprField<'_>], +) { + diag.primary_message("`Default` impl doesn't use the declared default field values"); + + // For each field in the struct expression + // - if the field in the type has a default value, it should be removed + // - elif the field is an expression that could be a default value, it should be used as the + // field's default value (FIXME: not done). + // - else, we wouldn't touch this field, it would remain in the manual impl + let mut removed_all_fields = true; + for field in fields { + if orig_fields.get(&field.ident.name).and_then(|f| f.default).is_some() { + diag.span_label(field.expr.span, "this field has a default value"); + } else { + removed_all_fields = false; + } + } + + diag.help(if removed_all_fields { + "to avoid divergence in behavior between `Struct { .. }` and \ + `::default()`, derive the `Default`" + } else { + "use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them \ + diverging over time" + }); +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index d7f0d2a6941f..1465c2cff7bc 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -41,6 +41,7 @@ mod async_fn_in_trait; pub mod builtin; mod context; mod dangling; +mod default_could_be_derived; mod deref_into_dyn_supertrait; mod drop_forget_useless; mod early; @@ -85,6 +86,7 @@ use async_closures::AsyncClosureUsage; use async_fn_in_trait::AsyncFnInTrait; use builtin::*; use dangling::*; +use default_could_be_derived::DefaultCouldBeDerived; use deref_into_dyn_supertrait::*; use drop_forget_useless::*; use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; @@ -189,6 +191,7 @@ late_lint_methods!( BuiltinCombinedModuleLateLintPass, [ ForLoopsOverFallibles: ForLoopsOverFallibles, + DefaultCouldBeDerived: DefaultCouldBeDerived::default(), DerefIntoDynSupertrait: DerefIntoDynSupertrait, DropForgetUseless: DropForgetUseless, ImproperCTypesDeclarations: ImproperCTypesDeclarations, diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index 79a6454dbb94..b2a14a0022e8 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -12,5 +12,5 @@ libc = "0.2.73" # tidy-alphabetical-start # Pinned so `cargo update` bumps don't cause breakage. Please also update the # pinned `cc` in `rustc_codegen_ssa` if you update `cc` here. -cc = "=1.2.5" +cc = "=1.2.6" # tidy-alphabetical-end diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index f092110a324e..d9d28299413b 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -220,7 +220,7 @@ fn main() { let mut cmd = Command::new(&llvm_config); cmd.arg(llvm_link_arg).arg("--libs"); - // Don't link system libs if cross-compiling unless targetting Windows. + // Don't link system libs if cross-compiling unless targeting Windows. // On Windows system DLLs aren't linked directly, instead import libraries are used. // These import libraries are independent of the host. if !is_crossed || target.contains("windows") { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 2c2dffe8b88f..7e7b602c560b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -132,6 +132,7 @@ rustc_queries! { } /// Return the span for a definition. + /// /// Contrary to `def_span` below, this query returns the full absolute span of the definition. /// This span is meant for dep-tracking rather than diagnostics. It should not be used outside /// of rustc_middle::hir::source_map. @@ -142,6 +143,7 @@ rustc_queries! { } /// Represents crate as a whole (as distinct from the top-level crate module). + /// /// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`), /// we will have to assume that any change means that you need to be recompiled. /// This is because the `hir_crate` query gives you access to all other items. @@ -202,28 +204,40 @@ rustc_queries! { feedable } - /// Given the def_id of a const-generic parameter, computes the associated default const - /// parameter. e.g. `fn example` called on `N` would return `3`. + /// Returns the *default* of the const pararameter given by `DefId`. + /// + /// E.g., given `struct Ty;` this returns `3` for `N`. query const_param_default(param: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { - desc { |tcx| "computing const default for a given parameter `{}`", tcx.def_path_str(param) } + desc { |tcx| "computing the default for const parameter `{}`", tcx.def_path_str(param) } cache_on_disk_if { param.is_local() } separate_provide_extern } - /// Returns the [`Ty`][rustc_middle::ty::Ty] of the given [`DefId`]. If the [`DefId`] points - /// to an alias, it will "skip" this alias to return the aliased type. + /// Returns the *type* of the definition given by `DefId`. /// - /// [`DefId`]: rustc_hir::def_id::DefId + /// For type aliases (whether eager or lazy) and associated types, this returns + /// the underlying aliased type (not the corresponding [alias type]). + /// + /// For opaque types, this returns and thus reveals the hidden type! If you + /// want to detect cycle errors use `type_of_opaque` instead. + /// + /// To clarify, for type definitions, this does *not* return the "type of a type" + /// (aka *kind* or *sort*) in the type-theoretical sense! It merely returns + /// the type primarily *associated with* it. + /// + /// # Panics + /// + /// This query will panic if the given definition doesn't (and can't + /// conceptually) have an (underlying) type. + /// + /// [alias type]: rustc_middle::ty::AliasTy query type_of(key: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { desc { |tcx| "{action} `{path}`", - action = { - use rustc_hir::def::DefKind; - match tcx.def_kind(key) { - DefKind::TyAlias => "expanding type alias", - DefKind::TraitAlias => "expanding trait alias", - _ => "computing type of", - } + action = match tcx.def_kind(key) { + DefKind::TyAlias => "expanding type alias", + DefKind::TraitAlias => "expanding trait alias", + _ => "computing type of", }, path = tcx.def_path_str(key), } @@ -232,9 +246,14 @@ rustc_queries! { feedable } - /// Specialized instance of `type_of` that detects cycles that are due to - /// revealing opaque because of an auto trait bound. Unless `CyclePlaceholder` needs - /// to be handled separately, call `type_of` instead. + /// Returns the *hidden type* of the opaque type given by `DefId` unless a cycle occurred. + /// + /// This is a specialized instance of [`Self::type_of`] that detects query cycles. + /// Unless `CyclePlaceholder` needs to be handled separately, call [`Self::type_of`] instead. + /// + /// # Panics + /// + /// This query will panic if the given definition is not an opaque type. query type_of_opaque(key: DefId) -> Result>, CyclePlaceholder> { desc { |tcx| "computing type of opaque `{path}`", @@ -243,9 +262,22 @@ rustc_queries! { cycle_stash } + /// Returns whether the type alias given by `DefId` is lazy. + /// + /// I.e., if the type alias expands / ought to expand to a [weak] [alias type] + /// instead of the underyling aliased type. + /// + /// Relevant for features `lazy_type_alias` and `type_alias_impl_trait`. + /// + /// # Panics + /// + /// This query *may* panic if the given definition is not a type alias. + /// + /// [weak]: rustc_middle::ty::Weak + /// [alias type]: rustc_middle::ty::AliasTy query type_alias_is_lazy(key: DefId) -> bool { desc { |tcx| - "computing whether `{path}` is a lazy type alias", + "computing whether the type alias `{path}` is lazy", path = tcx.def_path_str(key), } separate_provide_extern @@ -299,8 +331,7 @@ rustc_queries! { desc { "checking lint expectations (RFC 2383)" } } - /// Maps from the `DefId` of an item (trait/struct/enum/fn) to its - /// associated generics. + /// Returns the *generics* of the definition given by `DefId`. query generics_of(key: DefId) -> &'tcx ty::Generics { desc { |tcx| "computing generics of `{}`", tcx.def_path_str(key) } arena_cache @@ -309,10 +340,13 @@ rustc_queries! { feedable } - /// Maps from the `DefId` of an item (trait/struct/enum/fn) to the - /// predicates (where-clauses) that must be proven true in order - /// to reference it. This is almost always the "predicates query" - /// that you want. + /// Returns the (elaborated) *predicates* of the definition given by `DefId` + /// that must be proven true at usage sites (and which can be assumed at definition site). + /// + /// This is almost always *the* "predicates query" that you want. + /// + /// **Tip**: You can use `#[rustc_dump_predicates]` on an item to basically print + /// the result of this query for use in UI tests or for debugging purposes. query predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } @@ -328,25 +362,24 @@ rustc_queries! { } } - /// Returns the list of bounds that are required to be satisfied - /// by a implementation or definition. For associated types, these - /// must be satisfied for an implementation to be well-formed, - /// and for opaque types, these are required to be satisfied by - /// the hidden-type of the opaque. + /// Returns the explicitly user-written *bounds* on the associated or opaque type given by `DefId` + /// that must be proven true at definition site (and which can be assumed at usage sites). /// - /// Syntactially, these are the bounds written on the trait's type - /// definition, or those after the `impl` keyword for an opaque: + /// For associated types, these must be satisfied for an implementation + /// to be well-formed, and for opaque types, these are required to be + /// satisfied by the hidden type of the opaque. /// - /// ```ignore (incomplete) - /// type X: Bound + 'lt - /// // ^^^^^^^^^^^ - /// impl Debug + Display - /// // ^^^^^^^^^^^^^^^ + /// Bounds from the parent (e.g. with nested `impl Trait`) are not included. + /// + /// Syntactially, these are the bounds written on associated types in trait + /// definitions, or those after the `impl` keyword for an opaque: + /// + /// ```ignore (illustrative) + /// trait Trait { type X: Bound + 'lt; } + /// // ^^^^^^^^^^^ + /// fn function() -> impl Debug + Display { /*...*/ } + /// // ^^^^^^^^^^^^^^^ /// ``` - /// - /// `key` is the `DefId` of the associated type or opaque type. - /// - /// Bounds from the parent (e.g. with nested impl trait) are not included. query explicit_item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } @@ -354,10 +387,12 @@ rustc_queries! { feedable } - /// The set of item bounds (see [`TyCtxt::explicit_item_bounds`]) that - /// share the `Self` type of the item. These are a subset of the bounds - /// that may explicitly be used for things like closure signature - /// deduction. + /// Returns the explicitly user-written *bounds* that share the `Self` type of the item. + /// + /// These are a subset of the [explicit item bounds] that may explicitly be used for things + /// like closure signature deduction. + /// + /// [explicit item bounds]: Self::explicit_item_bounds query explicit_item_super_predicates(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } @@ -365,26 +400,29 @@ rustc_queries! { feedable } - /// Elaborated version of the predicates from `explicit_item_bounds`. + /// Returns the (elaborated) *bounds* on the associated or opaque type given by `DefId` + /// that must be proven true at definition site (and which can be assumed at usage sites). /// - /// For example: + /// Bounds from the parent (e.g. with nested `impl Trait`) are not included. + /// + /// **Tip**: You can use `#[rustc_dump_item_bounds]` on an item to basically print + /// the result of this query for use in UI tests or for debugging purposes. + /// + /// # Examples /// /// ``` - /// trait MyTrait { - /// type MyAType: Eq + ?Sized; - /// } + /// trait Trait { type Assoc: Eq + ?Sized; } /// ``` /// - /// `explicit_item_bounds` returns `[::MyAType: Eq]`, - /// and `item_bounds` returns + /// While [`Self::explicit_item_bounds`] returns `[::Assoc: Eq]` + /// here, `item_bounds` returns: + /// /// ```text /// [ - /// ::MyAType: Eq, - /// ::MyAType: PartialEq<::MyAType> + /// ::Assoc: Eq, + /// ::Assoc: PartialEq<::Assoc> /// ] /// ``` - /// - /// Bounds from the parent (e.g. with nested impl trait) are not included. query item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) } } @@ -615,27 +653,35 @@ rustc_queries! { desc { "getting wasm import module map" } } - /// Returns everything that looks like a predicate written explicitly - /// by the user on a trait item. + /// Returns the explicitly user-written *predicates and bounds* of the trait given by `DefId`. /// /// Traits are unusual, because predicates on associated types are /// converted into bounds on that type for backwards compatibility: /// + /// ``` /// trait X where Self::U: Copy { type U; } + /// ``` /// /// becomes /// + /// ``` /// trait X { type U: Copy; } + /// ``` /// - /// `explicit_predicates_of` and `explicit_item_bounds` will then take - /// the appropriate subsets of the predicates here. + /// [`Self::explicit_predicates_of`] and [`Self::explicit_item_bounds`] will + /// then take the appropriate subsets of the predicates here. + /// + /// # Panics + /// + /// This query will panic if the given definition is not a trait. query trait_explicit_predicates_and_bounds(key: LocalDefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing explicit predicates of trait `{}`", tcx.def_path_str(key) } } - /// Returns the predicates written explicitly by the user. + /// Returns the explicitly user-written *predicates* of the definition given by `DefId` + /// that must be proven true at usage sites (and which can be assumed at definition site). /// - /// You should probably use `predicates_of` unless you're looking for + /// You should probably use [`Self::predicates_of`] unless you're looking for /// predicates with explicit spans for diagnostics purposes. query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) } @@ -644,18 +690,24 @@ rustc_queries! { feedable } - /// Returns the inferred outlives predicates (e.g., for `struct - /// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`). + /// Returns the *inferred outlives-predicates* of the item given by `DefId`. + /// + /// E.g., for `struct Foo<'a, T> { x: &'a T }`, this would return `[T: 'a]`. + /// + /// **Tip**: You can use `#[rustc_outlives]` on an item to basically print the + /// result of this query for use in UI tests or for debugging purposes. query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Clause<'tcx>, Span)] { - desc { |tcx| "computing inferred outlives predicates of `{}`", tcx.def_path_str(key) } + desc { |tcx| "computing inferred outlives-predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern feedable } - /// Maps from the `DefId` of a trait to the list of super-predicates of the trait, - /// *before* elaboration (so it doesn't contain transitive super-predicates). This - /// is a subset of the full list of predicates. We store these in a separate map + /// Returns the explicitly user-written *super-predicates* of the trait given by `DefId`. + /// + /// These predicates are unelaborated and consequently don't contain transitive super-predicates. + /// + /// This is a subset of the full list of predicates. We store these in a separate map /// because we must evaluate them even during type conversion, often before the full /// predicates are available (note that super-predicates must not be cyclic). query explicit_super_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { @@ -664,8 +716,9 @@ rustc_queries! { separate_provide_extern } - /// The predicates of the trait that are implied during elaboration. This is a - /// superset of the super-predicates of the trait, but a subset of the predicates + /// The predicates of the trait that are implied during elaboration. + /// + /// This is a superset of the super-predicates of the trait, but a subset of the predicates /// of the trait. For regular traits, this includes all super-predicates and their /// associated type bounds. For trait aliases, currently, this includes all of the /// predicates of the trait alias. @@ -745,14 +798,27 @@ rustc_queries! { desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) } } - /// Returns the constness of function-like things (tuple struct/variant constructors, functions, - /// methods) + /// Returns the constness of the function-like[^1] definition given by `DefId`. /// - /// Will ICE if used on things that are always const or never const. + /// Tuple struct/variant constructors are *always* const, foreign functions are + /// *never* const. The rest is const iff marked with keyword `const` (or rather + /// its parent in the case of associated functions). /// - /// **Do not call this function manually.** It is only meant to cache the base data for the + ///
+ /// + /// **Do not call this query** directly. It is only meant to cache the base data for the /// higher-level functions. Consider using `is_const_fn` or `is_const_trait_impl` instead. - /// Also note that neither of them takes into account feature gates and stability. + /// + /// Also note that neither of them takes into account feature gates, stability and + /// const predicates/conditions! + /// + ///
+ /// + /// # Panics + /// + /// This query will panic if the given definition is not function-like[^1]. + /// + /// [^1]: Tuple struct/variant constructors, closures and free, associated and foreign functions. query constness(key: DefId) -> hir::Constness { desc { |tcx| "checking if item is const: `{}`", tcx.def_path_str(key) } separate_provide_extern @@ -798,13 +864,25 @@ rustc_queries! { separate_provide_extern } - /// Gets a map with the variance of every item; use `variances_of` instead. + /// Gets a map with the variances of every item in the local crate. + /// + ///
+ /// + /// **Do not call this query** directly, use [`Self::variances_of`] instead. + /// + ///
query crate_variances(_: ()) -> &'tcx ty::CrateVariancesMap<'tcx> { arena_cache desc { "computing the variances for items in this crate" } } - /// Maps from the `DefId` of a type or region parameter to its (inferred) variance. + /// Returns the (inferred) variances of the item given by `DefId`. + /// + /// The list of variances corresponds to the list of (early-bound) generic + /// parameters of the item (including its parents). + /// + /// **Tip**: You can use `#[rustc_variance]` on an item to basically print the + /// result of this query for use in UI tests or for debugging purposes. query variances_of(def_id: DefId) -> &'tcx [ty::Variance] { desc { |tcx| "computing the variances of `{}`", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } @@ -812,10 +890,16 @@ rustc_queries! { cycle_delay_bug } - /// Maps from thee `DefId` of a type to its (inferred) outlives. + /// Gets a map with the inferred outlives-predicates of every item in the local crate. + /// + ///
+ /// + /// **Do not call this query** directly, use [`Self::inferred_outlives_of`] instead. + /// + ///
query inferred_outlives_crate(_: ()) -> &'tcx ty::CratePredicatesMap<'tcx> { arena_cache - desc { "computing the inferred outlives predicates for items in this crate" } + desc { "computing the inferred outlives-predicates for items in this crate" } } /// Maps from an impl/trait or struct/variant `DefId` @@ -1038,20 +1122,35 @@ rustc_queries! { } /// Gets a complete map from all types to their inherent impls. - /// Not meant to be used directly outside of coherence. + /// + ///
+ /// + /// **Not meant to be used** directly outside of coherence. + /// + ///
query crate_inherent_impls(k: ()) -> (&'tcx CrateInherentImpls, Result<(), ErrorGuaranteed>) { desc { "finding all inherent impls defined in crate" } } /// Checks all types in the crate for overlap in their inherent impls. Reports errors. - /// Not meant to be used directly outside of coherence. + /// + ///
+ /// + /// **Not meant to be used** directly outside of coherence. + /// + ///
query crate_inherent_impls_validity_check(_: ()) -> Result<(), ErrorGuaranteed> { desc { "check for inherent impls that should not be defined in crate" } ensure_forwards_result_if_red } /// Checks all types in the crate for overlap in their inherent impls. Reports errors. - /// Not meant to be used directly outside of coherence. + /// + ///
+ /// + /// **Not meant to be used** directly outside of coherence. + /// + ///
query crate_inherent_impls_overlap_check(_: ()) -> Result<(), ErrorGuaranteed> { desc { "check for overlap between inherent impls defined in this crate" } ensure_forwards_result_if_red @@ -1089,8 +1188,12 @@ rustc_queries! { } /// Computes the tag (if any) for a given type and variant. + /// /// `None` means that the variant doesn't need a tag (because it is niched). - /// Will panic for uninhabited variants. + /// + /// # Panics + /// + /// This query will panic for uninhabited variants and if the passed type is not an enum. query tag_for_variant( key: (Ty<'tcx>, abi::VariantIdx) ) -> Option { @@ -1099,7 +1202,12 @@ rustc_queries! { /// Evaluates a constant and returns the computed allocation. /// - /// **Do not use this** directly, use the `eval_to_const_value` or `eval_to_valtree` instead. + ///
+ /// + /// **Do not call this query** directly, use [`Self::eval_to_const_value_raw`] or + /// [`Self::eval_to_valtree`] instead. + /// + ///
query eval_to_allocation_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>) -> EvalToAllocationRawResult<'tcx> { desc { |tcx| @@ -1120,12 +1228,18 @@ rustc_queries! { feedable } - /// Evaluates const items or anonymous constants - /// (such as enum variant explicit discriminants or array lengths) - /// into a representation suitable for the type system and const generics. + /// Evaluates const items or anonymous constants[^1] into a representation + /// suitable for the type system and const generics. /// - /// **Do not use this** directly, use one of the following wrappers: `tcx.const_eval_poly`, - /// `tcx.const_eval_resolve`, `tcx.const_eval_instance`, or `tcx.const_eval_global_id`. + ///
+ /// + /// **Do not call this** directly, use one of the following wrappers: + /// [`TyCtxt::const_eval_poly`], [`TyCtxt::const_eval_resolve`], + /// [`TyCtxt::const_eval_instance`], or [`TyCtxt::const_eval_global_id`]. + /// + ///
+ /// + /// [^1]: Such as enum variant explicit discriminants or array lengths. query eval_to_const_value_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>) -> EvalToConstValueResult<'tcx> { desc { |tcx| @@ -1252,13 +1366,13 @@ rustc_queries! { separate_provide_extern } - /// Determines whether an item is annotated with `doc(hidden)`. + /// Determines whether an item is annotated with `#[doc(hidden)]`. query is_doc_hidden(def_id: DefId) -> bool { desc { |tcx| "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) } separate_provide_extern } - /// Determines whether an item is annotated with `doc(notable_trait)`. + /// Determines whether an item is annotated with `#[doc(notable_trait)]`. query is_doc_notable_trait(def_id: DefId) -> bool { desc { |tcx| "checking whether `{}` is `doc(notable_trait)`", tcx.def_path_str(def_id) } } @@ -1796,13 +1910,22 @@ rustc_queries! { query is_late_bound_map(owner_id: hir::OwnerId) -> Option<&'tcx FxIndexSet> { desc { |tcx| "testing if a region is late bound inside `{}`", tcx.def_path_str(owner_id) } } - /// For a given item's generic parameter, gets the default lifetimes to be used - /// for each parameter if a trait object were to be passed for that parameter. - /// For example, for `T` in `struct Foo<'a, T>`, this would be `'static`. - /// For `T` in `struct Foo<'a, T: 'a>`, this would instead be `'a`. - /// This query will panic if passed something that is not a type parameter. + /// Returns the *default lifetime* to be used if a trait object type were to be passed for + /// the type parameter given by `DefId`. + /// + /// **Tip**: You can use `#[rustc_object_lifetime_default]` on an item to basically + /// print the result of this query for use in UI tests or for debugging purposes. + /// + /// # Examples + /// + /// - For `T` in `struct Foo<'a, T: 'a>(&'a T);`, this would be `Param('a)` + /// - For `T` in `struct Bar<'a, T>(&'a T);`, this would be `Empty` + /// + /// # Panics + /// + /// This query will panic if the given definition is not a type parameter. query object_lifetime_default(def_id: DefId) -> ObjectLifetimeDefault { - desc { "looking up lifetime defaults for generic parameter `{}`", tcx.def_path_str(def_id) } + desc { "looking up lifetime defaults for type parameter `{}`", tcx.def_path_str(def_id) } separate_provide_extern } query late_bound_vars_map(owner_id: hir::OwnerId) diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs index b1f46d37d506..0659e3ea314b 100644 --- a/compiler/rustc_mir_build/src/check_tail_calls.rs +++ b/compiler/rustc_mir_build/src/check_tail_calls.rs @@ -117,7 +117,7 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { self.report_arguments_mismatch(expr.span, caller_sig, callee_sig); } - // FIXME(explicit_tail_calls): this currenly fails for cases where opaques are used. + // FIXME(explicit_tail_calls): this currently fails for cases where opaques are used. // e.g. // ``` // fn a() -> impl Sized { become b() } // ICE diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index aab4e1b1afc1..9ee6c2fae1ac 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -755,7 +755,7 @@ impl<'a> Parser<'a> { // When there are a few keywords in the last ten elements of `self.expected_token_types` // and the current token is an identifier, it's probably a misspelled keyword. This handles // code like `async Move {}`, misspelled `if` in match guard, misspelled `else` in - // `if`-`else` and mispelled `where` in a where clause. + // `if`-`else` and misspelled `where` in a where clause. if !expected_keywords.is_empty() && !curr_ident.is_used_keyword() && let Some(misspelled_kw) = find_similar_kw(curr_ident, &expected_keywords) @@ -1336,7 +1336,7 @@ impl<'a> Parser<'a> { ) -> bool { if let ExprKind::Binary(op, l1, r1) = &inner_op.kind { if let ExprKind::Field(_, ident) = l1.kind - && ident.as_str().parse::().is_err() + && !ident.is_numeric() && !matches!(r1.kind, ExprKind::Lit(_)) { // The parser has encountered `foo.bar Resolver<'ra, 'tcx> { let in_module_is_extern = !in_module.def_id().is_local(); in_module.for_each_child(self, |this, ident, ns, name_binding| { // avoid non-importable candidates - if !name_binding.is_importable() { + if !name_binding.is_importable() + // FIXME(import_trait_associated_functions): remove this when `import_trait_associated_functions` is stable + || name_binding.is_assoc_const_or_fn() + && !this.tcx.features().import_trait_associated_functions() + { return; } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 5b1d8d622bdd..cad45d3c2931 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -17,9 +17,10 @@ use rustc_session::lint::builtin::{ AMBIGUOUS_GLOB_REEXPORTS, HIDDEN_GLOB_REEXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE, REDUNDANT_IMPORTS, UNUSED_IMPORTS, }; +use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::hygiene::LocalExpnId; -use rustc_span::{Ident, Span, Symbol, kw}; +use rustc_span::{Ident, Span, Symbol, kw, sym}; use smallvec::SmallVec; use tracing::debug; @@ -829,6 +830,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Don't update the resolution, because it was never added. Err(Determined) if target.name == kw::Underscore => {} Ok(binding) if binding.is_importable() => { + if binding.is_assoc_const_or_fn() + && !this.tcx.features().import_trait_associated_functions() + { + feature_err( + this.tcx.sess, + sym::import_trait_associated_functions, + import.span, + "`use` associated items of traits is unstable", + ) + .emit(); + } let imported_binding = this.import(binding, import); target_bindings[ns].set(Some(imported_binding)); this.define(parent, target, ns, imported_binding); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index cc9ed566edac..8e457e68eecf 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -920,10 +920,13 @@ impl<'ra> NameBindingData<'ra> { } fn is_importable(&self) -> bool { - !matches!( - self.res(), - Res::Def(DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy, _) - ) + !matches!(self.res(), Res::Def(DefKind::AssocTy, _)) + } + + // FIXME(import_trait_associated_functions): associate `const` or `fn` are not importable unless + // the feature `import_trait_associated_functions` is enable + fn is_assoc_const_or_fn(&self) -> bool { + matches!(self.res(), Res::Def(DefKind::AssocConst | DefKind::AssocFn, _)) } fn macro_kind(&self) -> Option { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 54bb46229635..60f1154dc6d0 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1320,7 +1320,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } if sess.opts.cg.soft_float { - if sess.target.arch == "arm" && sess.target.abi == "eabihf" { + if sess.target.arch == "arm" { sess.dcx().emit_warn(errors::SoftFloatDeprecated); } else { // All `use_softfp` does is the equivalent of `-mfloat-abi` in GCC/clang, which only exists on ARM targets. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3d202f11722e..6c2dd1fc5796 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -555,6 +555,7 @@ symbols! { call_ref_future, caller_location, capture_disjoint_fields, + carrying_mul_add, catch_unwind, cause, cdylib, @@ -1092,6 +1093,7 @@ symbols! { import, import_name_type, import_shadowing, + import_trait_associated_functions, imported_main, in_band_lifetimes, include, @@ -2058,7 +2060,7 @@ symbols! { type_macros, type_name, type_privacy_lints, - typed_swap, + typed_swap_nonoverlapping, u128, u128_legacy_const_max, u128_legacy_const_min, @@ -2707,6 +2709,12 @@ impl Ident { pub fn is_raw_guess(self) -> bool { self.name.can_be_raw() && self.is_reserved() } + + /// Whether this would be the identifier for a tuple field like `self.0`, as + /// opposed to a named field like `self.thing`. + pub fn is_numeric(self) -> bool { + !self.name.is_empty() && self.as_str().bytes().all(|b| b.is_ascii_digit()) + } } /// Collect all the keywords in a given edition into a vector. diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs index 900dbed205c8..2e63ff215728 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, base}; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, StackProbeType, Target, base}; pub(crate) fn target() -> Target { let mut base = base::linux::opts(); @@ -7,6 +7,7 @@ pub(crate) fn target() -> Target { base.stack_probes = StackProbeType::Inline; base.linker_flavor = LinkerFlavor::Gnu(Cc::No, Lld::Yes); base.linker = Some("rust-lld".into()); + base.panic_strategy = PanicStrategy::Abort; Target { llvm_target: "x86_64-unknown-linux-none".into(), @@ -14,7 +15,7 @@ pub(crate) fn target() -> Target { description: None, tier: None, host_tools: None, - std: Some(true), + std: Some(false), }, pointer_width: 64, data_layout: diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 6730f28893d1..9a53e8a5d519 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -161,8 +161,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { let outlives_env = OutlivesEnvironment::new(full_env); let _ = infcx.process_registered_region_obligations(&outlives_env, |ty, _| Ok(ty)); - let region_data = - infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone(); + let region_data = infcx.inner.borrow_mut().unwrap_region_constraints().data().clone(); let vid_to_region = self.map_vid_to_region(®ion_data); diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index d6ac4baf8ad7..968dc631e50e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -819,7 +819,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidates.vec.push(AutoImplCandidate) } } - ty::Error(_) => {} // do not add an auto trait impl for `ty::Error` for now. + ty::Error(_) => { + candidates.vec.push(AutoImplCandidate); + } } } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 7857ed95cc71..9e7da5eb3689 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1843,7 +1843,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // a global and a non-global where-clause. // // Our handling of where-bounds is generally fairly messy but necessary for backwards - // compatability, see #50825 for why we need to handle global where-bounds like this. + // compatibility, see #50825 for why we need to handle global where-bounds like this. let is_global = |c: ty::PolyTraitPredicate<'tcx>| c.is_global() && !c.has_bound_vars(); let param_candidates = candidates .iter() diff --git a/library/Cargo.lock b/library/Cargo.lock index 22f6e1edf21f..40edd2c211cd 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.138" +version = "0.1.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53f0ea7fff95b51f84371588f06062557e96bbe363d2b36218ddb806f3ca8611" +checksum = "df14d41c5d172a886df3753d54238eefb0f61c96cbd8b363c33ccc92c457bee3" dependencies = [ "cc", "rustc-std-workspace-core", @@ -403,9 +403,9 @@ dependencies = [ [[package]] name = "unwinding" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2c6cb20f236dae10c69b0b45d82ef50af8b7e45c10e429e7901d26b49b4dbf3" +checksum = "51f06a05848f650946acef3bf525fe96612226b61f74ae23ffa4e98bfbb8ab3c" dependencies = [ "compiler_builtins", "gimli 0.31.1", diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 3464047d4ee9..07596fa16f98 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" [dependencies] core = { path = "../core" } -compiler_builtins = { version = "=0.1.138", features = ['rustc-dep-of-std'] } +compiler_builtins = { version = "=0.1.140", features = ['rustc-dep-of-std'] } [dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 23b85fbd4ebc..ca3bd24a4203 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -761,6 +761,26 @@ impl Box<[T]> { }; unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) } } + + /// Converts the boxed slice into a boxed array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub fn into_array(self) -> Option> { + if self.len() == N { + let ptr = Self::into_raw(self) as *mut [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Box::from_raw(ptr) }; + Some(me) + } else { + None + } + } } impl Box<[T], A> { diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index d1ce4e215ed9..6d305386dbfa 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -2289,6 +2289,10 @@ impl FusedIterator for RangeMut<'_, K, V> {} #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator<(K, V)> for BTreeMap { + /// Constructs a `BTreeMap` from an iterator of key-value pairs. + /// + /// If the iterator produces any pairs with equal keys, + /// all but one of the corresponding values will be dropped. fn from_iter>(iter: T) -> BTreeMap { let mut inputs: Vec<_> = iter.into_iter().collect(); @@ -2403,7 +2407,10 @@ where #[stable(feature = "std_collections_from_array", since = "1.56.0")] impl From<[(K, V); N]> for BTreeMap { - /// Converts a `[(K, V); N]` into a `BTreeMap<(K, V)>`. + /// Converts a `[(K, V); N]` into a `BTreeMap`. + /// + /// If any entries in the array have equal keys, + /// all but one of the corresponding values will be dropped. /// /// ``` /// use std::collections::BTreeMap; diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 6f8c3b2d152b..9660023d6945 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1491,6 +1491,11 @@ impl BTreeSet { impl From<[T; N]> for BTreeSet { /// Converts a `[T; N]` into a `BTreeSet`. /// + /// If the array contains any equal values, + /// all but one will be dropped. + /// + /// # Examples + /// /// ``` /// use std::collections::BTreeSet; /// diff --git a/library/alloc/src/ffi/mod.rs b/library/alloc/src/ffi/mod.rs index 4f9dc40a3cfc..695d7ad07cf7 100644 --- a/library/alloc/src/ffi/mod.rs +++ b/library/alloc/src/ffi/mod.rs @@ -83,7 +83,7 @@ #[doc(inline)] #[stable(feature = "alloc_c_string", since = "1.64.0")] pub use self::c_str::CString; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "alloc_c_string", since = "1.64.0")] pub use self::c_str::{FromVecWithNulError, IntoStringError, NulError}; diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 2c7cdcf0cfb4..e93ff2f90237 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -420,7 +420,7 @@ impl RawVecInner { match Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc, elem_layout) { Ok(this) => { unsafe { - // Make it more obvious that a subsquent Vec::reserve(capacity) will not allocate. + // Make it more obvious that a subsequent Vec::reserve(capacity) will not allocate. hint::assert_unchecked(!this.needs_to_grow(0, capacity, elem_layout)); } this diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index b7ec3af9818a..e014404eff35 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1084,6 +1084,26 @@ impl Rc<[T]> { )) } } + + /// Converts the reference-counted slice into a reference-counted array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub fn into_array(self) -> Option> { + if self.len() == N { + let ptr = Self::into_raw(self) as *const [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Rc::from_raw(ptr) }; + Some(me) + } else { + None + } + } } impl Rc<[T], A> { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 9be0b3e3e880..b34a6d3f660c 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1203,6 +1203,26 @@ impl Arc<[T]> { )) } } + + /// Converts the reference-counted slice into a reference-counted array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub fn into_array(self) -> Option> { + if self.len() == N { + let ptr = Self::into_raw(self) as *const [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Arc::from_raw(ptr) }; + Some(me) + } else { + None + } + } } impl Arc<[T], A> { diff --git a/library/alloc/tests/sort/tests.rs b/library/alloc/tests/sort/tests.rs index 14e6013f965d..4cc79010e8fe 100644 --- a/library/alloc/tests/sort/tests.rs +++ b/library/alloc/tests/sort/tests.rs @@ -33,7 +33,7 @@ fn check_is_sorted(v: &mut [T]) { known_good_stable_sort::sort(known_good_sorted_vec.as_mut_slice()); if is_small_test { - eprintln!("Orginal: {:?}", v_orig); + eprintln!("Original: {:?}", v_orig); eprintln!("Expected: {:?}", known_good_sorted_vec); eprintln!("Got: {:?}", v); } else { diff --git a/library/core/benches/num/int_pow/mod.rs b/library/core/benches/num/int_pow/mod.rs index 6cf902135828..46f47028d56e 100644 --- a/library/core/benches/num/int_pow/mod.rs +++ b/library/core/benches/num/int_pow/mod.rs @@ -25,7 +25,7 @@ macro_rules! pow_bench_template { let mut exp_iter = black_box(&exp_array).into_iter(); (0..ITERATIONS).fold((0 as IntType, false), |acc, _| { - // Sometimes constants don't propogate all the way to the + // Sometimes constants don't propagate all the way to the // inside of the loop, so we call a custom expression every cycle // rather than iter::repeat(CONST) let base: IntType = $base_macro!(base_iter); diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index 7a161f595f41..5f32775822be 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -12,10 +12,10 @@ #[doc(inline)] #[stable(feature = "core_c_str", since = "1.64.0")] pub use self::c_str::CStr; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] pub use self::c_str::FromBytesUntilNulError; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "core_c_str", since = "1.64.0")] pub use self::c_str::FromBytesWithNulError; use crate::fmt; diff --git a/library/core/src/intrinsics/fallback.rs b/library/core/src/intrinsics/fallback.rs new file mode 100644 index 000000000000..1779126b180e --- /dev/null +++ b/library/core/src/intrinsics/fallback.rs @@ -0,0 +1,111 @@ +#![unstable( + feature = "core_intrinsics_fallbacks", + reason = "The fallbacks will never be stable, as they exist only to be called \ + by the fallback MIR, but they're exported so they can be tested on \ + platforms where the fallback MIR isn't actually used", + issue = "none" +)] +#![allow(missing_docs)] + +#[const_trait] +pub trait CarryingMulAdd: Copy + 'static { + type Unsigned: Copy + 'static; + fn carrying_mul_add( + self, + multiplicand: Self, + addend: Self, + carry: Self, + ) -> (Self::Unsigned, Self); +} + +macro_rules! impl_carrying_mul_add_by_widening { + ($($t:ident $u:ident $w:ident,)+) => {$( + #[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")] + impl const CarryingMulAdd for $t { + type Unsigned = $u; + #[inline] + fn carrying_mul_add(self, a: Self, b: Self, c: Self) -> ($u, $t) { + let wide = (self as $w) * (a as $w) + (b as $w) + (c as $w); + (wide as _, (wide >> Self::BITS) as _) + } + } + )+}; +} +impl_carrying_mul_add_by_widening! { + u8 u8 u16, + u16 u16 u32, + u32 u32 u64, + u64 u64 u128, + usize usize UDoubleSize, + i8 u8 i16, + i16 u16 i32, + i32 u32 i64, + i64 u64 i128, + isize usize UDoubleSize, +} + +#[cfg(target_pointer_width = "16")] +type UDoubleSize = u32; +#[cfg(target_pointer_width = "32")] +type UDoubleSize = u64; +#[cfg(target_pointer_width = "64")] +type UDoubleSize = u128; + +#[inline] +const fn wide_mul_u128(a: u128, b: u128) -> (u128, u128) { + #[inline] + const fn to_low_high(x: u128) -> [u128; 2] { + const MASK: u128 = u64::MAX as _; + [x & MASK, x >> 64] + } + #[inline] + const fn from_low_high(x: [u128; 2]) -> u128 { + x[0] | (x[1] << 64) + } + #[inline] + const fn scalar_mul(low_high: [u128; 2], k: u128) -> [u128; 3] { + let [x, c] = to_low_high(k * low_high[0]); + let [y, z] = to_low_high(k * low_high[1] + c); + [x, y, z] + } + let a = to_low_high(a); + let b = to_low_high(b); + let low = scalar_mul(a, b[0]); + let high = scalar_mul(a, b[1]); + let r0 = low[0]; + let [r1, c] = to_low_high(low[1] + high[0]); + let [r2, c] = to_low_high(low[2] + high[1] + c); + let r3 = high[2] + c; + (from_low_high([r0, r1]), from_low_high([r2, r3])) +} + +#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")] +impl const CarryingMulAdd for u128 { + type Unsigned = u128; + #[inline] + fn carrying_mul_add(self, b: u128, c: u128, d: u128) -> (u128, u128) { + let (low, mut high) = wide_mul_u128(self, b); + let (low, carry) = u128::overflowing_add(low, c); + high += carry as u128; + let (low, carry) = u128::overflowing_add(low, d); + high += carry as u128; + (low, high) + } +} + +#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")] +impl const CarryingMulAdd for i128 { + type Unsigned = u128; + #[inline] + fn carrying_mul_add(self, b: i128, c: i128, d: i128) -> (u128, i128) { + let (low, high) = wide_mul_u128(self as u128, b as u128); + let mut high = high as i128; + high = high.wrapping_add(i128::wrapping_mul(self >> 127, b)); + high = high.wrapping_add(i128::wrapping_mul(self, b >> 127)); + let (low, carry) = u128::overflowing_add(low, c as u128); + high = high.wrapping_add((carry as i128) + (c >> 127)); + let (low, carry) = u128::overflowing_add(low, d as u128); + high = high.wrapping_add((carry as i128) + (d >> 127)); + (low, high) + } +} diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 42b8eb33a1a9..b5c31d824677 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -68,6 +68,7 @@ use crate::marker::{DiscriminantKind, Tuple}; use crate::mem::SizedTypeProperties; use crate::{ptr, ub_checks}; +pub mod fallback; pub mod mir; pub mod simd; @@ -3305,6 +3306,34 @@ pub const fn mul_with_overflow(_x: T, _y: T) -> (T, bool) { unimplemented!() } +/// Performs full-width multiplication and addition with a carry: +/// `multiplier * multiplicand + addend + carry`. +/// +/// This is possible without any overflow. For `uN`: +/// MAX * MAX + MAX + MAX +/// => (2ⁿ-1) × (2ⁿ-1) + (2ⁿ-1) + (2ⁿ-1) +/// => (2²ⁿ - 2ⁿ⁺¹ + 1) + (2ⁿ⁺¹ - 2) +/// => 2²ⁿ - 1 +/// +/// For `iN`, the upper bound is MIN * MIN + MAX + MAX => 2²ⁿ⁻² + 2ⁿ - 2, +/// and the lower bound is MAX * MIN + MIN + MIN => -2²ⁿ⁻² - 2ⁿ + 2ⁿ⁺¹. +/// +/// This currently supports unsigned integers *only*, no signed ones. +/// The stabilized versions of this intrinsic are available on integers. +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_const_unstable(feature = "const_carrying_mul_add", issue = "85532")] +#[rustc_nounwind] +#[cfg_attr(not(bootstrap), rustc_intrinsic)] +#[cfg_attr(not(bootstrap), miri::intrinsic_fallback_is_spec)] +pub const fn carrying_mul_add, U>( + multiplier: T, + multiplicand: T, + addend: T, + carry: T, +) -> (U, T) { + multiplier.carrying_mul_add(multiplicand, addend, carry) +} + /// Performs an exact division, resulting in undefined behavior where /// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1` /// @@ -3940,6 +3969,21 @@ pub const fn is_val_statically_known(_arg: T) -> bool { false } +#[rustc_nounwind] +#[inline] +#[rustc_intrinsic] +#[rustc_intrinsic_const_stable_indirect] +#[rustc_allow_const_fn_unstable(const_swap_nonoverlapping)] // this is anyway not called since CTFE implements the intrinsic +#[cfg(bootstrap)] +pub const unsafe fn typed_swap(x: *mut T, y: *mut T) { + // SAFETY: The caller provided single non-overlapping items behind + // pointers, so swapping them with `count: 1` is fine. + unsafe { ptr::swap_nonoverlapping(x, y, 1) }; +} + +#[cfg(bootstrap)] +pub use typed_swap as typed_swap_nonoverlapping; + /// Non-overlapping *typed* swap of a single value. /// /// The codegen backends will replace this with a better implementation when @@ -3953,9 +3997,10 @@ pub const fn is_val_statically_known(_arg: T) -> bool { #[rustc_nounwind] #[inline] #[rustc_intrinsic] -// Const-unstable because `swap_nonoverlapping` is const-unstable. -#[rustc_const_unstable(feature = "const_typed_swap", issue = "none")] -pub const unsafe fn typed_swap(x: *mut T, y: *mut T) { +#[rustc_intrinsic_const_stable_indirect] +#[rustc_allow_const_fn_unstable(const_swap_nonoverlapping)] // this is anyway not called since CTFE implements the intrinsic +#[cfg(not(bootstrap))] +pub const unsafe fn typed_swap_nonoverlapping(x: *mut T, y: *mut T) { // SAFETY: The caller provided single non-overlapping items behind // pointers, so swapping them with `count: 1` is fine. unsafe { ptr::swap_nonoverlapping(x, y, 1) }; @@ -4364,13 +4409,11 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us /// /// Behavior is undefined if any of the following conditions are violated: /// -/// * `src` must be [valid] for reads of `count * size_of::()` bytes, and must remain valid even -/// when `dst` is written for `count * size_of::()` bytes. (This means if the memory ranges -/// overlap, the two pointers must not be subject to aliasing restrictions relative to each -/// other.) +/// * `src` must be [valid] for reads of `count * size_of::()` bytes. /// /// * `dst` must be [valid] for writes of `count * size_of::()` bytes, and must remain valid even -/// when `src` is read for `count * size_of::()` bytes. +/// when `src` is read for `count * size_of::()` bytes. (This means if the memory ranges +/// overlap, the `dst` pointer must not be invalidated by `src` reads.) /// /// * Both `src` and `dst` must be properly aligned. /// diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index ff39e8ac25f8..91c3a4b29b53 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -3051,6 +3051,7 @@ pub trait Iterator { /// /// // we can still use `iter`, as there are more elements. /// assert_eq!(iter.next(), Some(&-1)); + /// assert_eq!(iter.next_back(), Some(&3)); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index a7f741a94089..0d8a3811eded 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -110,8 +110,8 @@ #![cfg_attr(bootstrap, feature(do_not_recommend))] #![feature(array_ptr_get)] #![feature(asm_experimental_arch)] +#![feature(const_carrying_mul_add)] #![feature(const_eval_select)] -#![feature(const_typed_swap)] #![feature(core_intrinsics)] #![feature(coverage_attribute)] #![feature(internal_impls_macro)] diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 57acc9dcd6ee..2d66e5c2f2a7 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -725,12 +725,12 @@ pub unsafe fn uninitialized() -> T { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_swap", issue = "83163")] +#[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")] #[rustc_diagnostic_item = "mem_swap"] pub const fn swap(x: &mut T, y: &mut T) { // SAFETY: `&mut` guarantees these are typed readable and writable // as well as non-overlapping. - unsafe { intrinsics::typed_swap(x, y) } + unsafe { intrinsics::typed_swap_nonoverlapping(x, y) } } /// Replaces `dest` with the default value of `T`, returning the previous `dest` value. diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 357a85ae843c..1f5b8ce6c6e2 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -228,134 +228,6 @@ macro_rules! midpoint_impl { }; } -macro_rules! widening_impl { - ($SelfT:ty, $WideT:ty, $BITS:literal, unsigned) => { - /// Calculates the complete product `self * rhs` without the possibility to overflow. - /// - /// This returns the low-order (wrapping) bits and the high-order (overflow) bits - /// of the result as two separate values, in that order. - /// - /// If you also need to add a carry to the wide result, then you want - /// [`Self::carrying_mul`] instead. - /// - /// # Examples - /// - /// Basic usage: - /// - /// Please note that this example is shared between integer types. - /// Which explains why `u32` is used here. - /// - /// ``` - /// #![feature(bigint_helper_methods)] - /// assert_eq!(5u32.widening_mul(2), (10, 0)); - /// assert_eq!(1_000_000_000u32.widening_mul(10), (1410065408, 2)); - /// ``` - #[unstable(feature = "bigint_helper_methods", issue = "85532")] - #[must_use = "this returns the result of the operation, \ - without modifying the original"] - #[inline] - pub const fn widening_mul(self, rhs: Self) -> (Self, Self) { - // note: longer-term this should be done via an intrinsic, - // but for now we can deal without an impl for u128/i128 - // SAFETY: overflow will be contained within the wider types - let wide = unsafe { (self as $WideT).unchecked_mul(rhs as $WideT) }; - (wide as $SelfT, (wide >> $BITS) as $SelfT) - } - - /// Calculates the "full multiplication" `self * rhs + carry` - /// without the possibility to overflow. - /// - /// This returns the low-order (wrapping) bits and the high-order (overflow) bits - /// of the result as two separate values, in that order. - /// - /// Performs "long multiplication" which takes in an extra amount to add, and may return an - /// additional amount of overflow. This allows for chaining together multiple - /// multiplications to create "big integers" which represent larger values. - /// - /// If you don't need the `carry`, then you can use [`Self::widening_mul`] instead. - /// - /// # Examples - /// - /// Basic usage: - /// - /// Please note that this example is shared between integer types. - /// Which explains why `u32` is used here. - /// - /// ``` - /// #![feature(bigint_helper_methods)] - /// assert_eq!(5u32.carrying_mul(2, 0), (10, 0)); - /// assert_eq!(5u32.carrying_mul(2, 10), (20, 0)); - /// assert_eq!(1_000_000_000u32.carrying_mul(10, 0), (1410065408, 2)); - /// assert_eq!(1_000_000_000u32.carrying_mul(10, 10), (1410065418, 2)); - #[doc = concat!("assert_eq!(", - stringify!($SelfT), "::MAX.carrying_mul(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX), ", - "(0, ", stringify!($SelfT), "::MAX));" - )] - /// ``` - /// - /// This is the core operation needed for scalar multiplication when - /// implementing it for wider-than-native types. - /// - /// ``` - /// #![feature(bigint_helper_methods)] - /// fn scalar_mul_eq(little_endian_digits: &mut Vec, multiplicand: u16) { - /// let mut carry = 0; - /// for d in little_endian_digits.iter_mut() { - /// (*d, carry) = d.carrying_mul(multiplicand, carry); - /// } - /// if carry != 0 { - /// little_endian_digits.push(carry); - /// } - /// } - /// - /// let mut v = vec![10, 20]; - /// scalar_mul_eq(&mut v, 3); - /// assert_eq!(v, [30, 60]); - /// - /// assert_eq!(0x87654321_u64 * 0xFEED, 0x86D3D159E38D); - /// let mut v = vec![0x4321, 0x8765]; - /// scalar_mul_eq(&mut v, 0xFEED); - /// assert_eq!(v, [0xE38D, 0xD159, 0x86D3]); - /// ``` - /// - /// If `carry` is zero, this is similar to [`overflowing_mul`](Self::overflowing_mul), - /// except that it gives the value of the overflow instead of just whether one happened: - /// - /// ``` - /// #![feature(bigint_helper_methods)] - /// let r = u8::carrying_mul(7, 13, 0); - /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(7, 13)); - /// let r = u8::carrying_mul(13, 42, 0); - /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(13, 42)); - /// ``` - /// - /// The value of the first field in the returned tuple matches what you'd get - /// by combining the [`wrapping_mul`](Self::wrapping_mul) and - /// [`wrapping_add`](Self::wrapping_add) methods: - /// - /// ``` - /// #![feature(bigint_helper_methods)] - /// assert_eq!( - /// 789_u16.carrying_mul(456, 123).0, - /// 789_u16.wrapping_mul(456).wrapping_add(123), - /// ); - /// ``` - #[unstable(feature = "bigint_helper_methods", issue = "85532")] - #[must_use = "this returns the result of the operation, \ - without modifying the original"] - #[inline] - pub const fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) { - // note: longer-term this should be done via an intrinsic, - // but for now we can deal without an impl for u128/i128 - // SAFETY: overflow will be contained within the wider types - let wide = unsafe { - (self as $WideT).unchecked_mul(rhs as $WideT).unchecked_add(carry as $WideT) - }; - (wide as $SelfT, (wide >> $BITS) as $SelfT) - } - }; -} - impl i8 { int_impl! { Self = i8, @@ -576,7 +448,6 @@ impl u8 { from_xe_bytes_doc = u8_xe_bytes_doc!(), bound_condition = "", } - widening_impl! { u8, u16, 8, unsigned } midpoint_impl! { u8, u16, unsigned } /// Checks if the value is within the ASCII range. @@ -1192,7 +1063,6 @@ impl u16 { from_xe_bytes_doc = "", bound_condition = "", } - widening_impl! { u16, u32, 16, unsigned } midpoint_impl! { u16, u32, unsigned } /// Checks if the value is a Unicode surrogate code point, which are disallowed values for [`char`]. @@ -1240,7 +1110,6 @@ impl u32 { from_xe_bytes_doc = "", bound_condition = "", } - widening_impl! { u32, u64, 32, unsigned } midpoint_impl! { u32, u64, unsigned } } @@ -1264,7 +1133,6 @@ impl u64 { from_xe_bytes_doc = "", bound_condition = "", } - widening_impl! { u64, u128, 64, unsigned } midpoint_impl! { u64, u128, unsigned } } @@ -1314,7 +1182,6 @@ impl usize { from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(), bound_condition = " on 16-bit targets", } - widening_impl! { usize, u32, 16, unsigned } midpoint_impl! { usize, u32, unsigned } } @@ -1339,7 +1206,6 @@ impl usize { from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(), bound_condition = " on 32-bit targets", } - widening_impl! { usize, u64, 32, unsigned } midpoint_impl! { usize, u64, unsigned } } @@ -1364,7 +1230,6 @@ impl usize { from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(), bound_condition = " on 64-bit targets", } - widening_impl! { usize, u128, 64, unsigned } midpoint_impl! { usize, u128, unsigned } } diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 151d879fabee..4a5fdbfb0ea2 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -3347,6 +3347,122 @@ macro_rules! uint_impl { unsafe { mem::transmute(bytes) } } + /// Calculates the complete product `self * rhs` without the possibility to overflow. + /// + /// This returns the low-order (wrapping) bits and the high-order (overflow) bits + /// of the result as two separate values, in that order. + /// + /// If you also need to add a carry to the wide result, then you want + /// [`Self::carrying_mul`] instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// Please note that this example is shared between integer types. + /// Which explains why `u32` is used here. + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// assert_eq!(5u32.widening_mul(2), (10, 0)); + /// assert_eq!(1_000_000_000u32.widening_mul(10), (1410065408, 2)); + /// ``` + #[unstable(feature = "bigint_helper_methods", issue = "85532")] + #[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn widening_mul(self, rhs: Self) -> (Self, Self) { + Self::carrying_mul(self, rhs, 0) + } + + /// Calculates the "full multiplication" `self * rhs + carry` + /// without the possibility to overflow. + /// + /// This returns the low-order (wrapping) bits and the high-order (overflow) bits + /// of the result as two separate values, in that order. + /// + /// Performs "long multiplication" which takes in an extra amount to add, and may return an + /// additional amount of overflow. This allows for chaining together multiple + /// multiplications to create "big integers" which represent larger values. + /// + /// If you don't need the `carry`, then you can use [`Self::widening_mul`] instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// Please note that this example is shared between integer types. + /// Which explains why `u32` is used here. + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// assert_eq!(5u32.carrying_mul(2, 0), (10, 0)); + /// assert_eq!(5u32.carrying_mul(2, 10), (20, 0)); + /// assert_eq!(1_000_000_000u32.carrying_mul(10, 0), (1410065408, 2)); + /// assert_eq!(1_000_000_000u32.carrying_mul(10, 10), (1410065418, 2)); + #[doc = concat!("assert_eq!(", + stringify!($SelfT), "::MAX.carrying_mul(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX), ", + "(0, ", stringify!($SelfT), "::MAX));" + )] + /// ``` + /// + /// This is the core operation needed for scalar multiplication when + /// implementing it for wider-than-native types. + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// fn scalar_mul_eq(little_endian_digits: &mut Vec, multiplicand: u16) { + /// let mut carry = 0; + /// for d in little_endian_digits.iter_mut() { + /// (*d, carry) = d.carrying_mul(multiplicand, carry); + /// } + /// if carry != 0 { + /// little_endian_digits.push(carry); + /// } + /// } + /// + /// let mut v = vec![10, 20]; + /// scalar_mul_eq(&mut v, 3); + /// assert_eq!(v, [30, 60]); + /// + /// assert_eq!(0x87654321_u64 * 0xFEED, 0x86D3D159E38D); + /// let mut v = vec![0x4321, 0x8765]; + /// scalar_mul_eq(&mut v, 0xFEED); + /// assert_eq!(v, [0xE38D, 0xD159, 0x86D3]); + /// ``` + /// + /// If `carry` is zero, this is similar to [`overflowing_mul`](Self::overflowing_mul), + /// except that it gives the value of the overflow instead of just whether one happened: + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// let r = u8::carrying_mul(7, 13, 0); + /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(7, 13)); + /// let r = u8::carrying_mul(13, 42, 0); + /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(13, 42)); + /// ``` + /// + /// The value of the first field in the returned tuple matches what you'd get + /// by combining the [`wrapping_mul`](Self::wrapping_mul) and + /// [`wrapping_add`](Self::wrapping_add) methods: + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// assert_eq!( + /// 789_u16.carrying_mul(456, 123).0, + /// 789_u16.wrapping_mul(456).wrapping_add(123), + /// ); + /// ``` + #[unstable(feature = "bigint_helper_methods", issue = "85532")] + #[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) { + intrinsics::carrying_mul_add(self, rhs, 0, carry) + } + /// New code should prefer to use #[doc = concat!("[`", stringify!($SelfT), "::MIN", "`] instead.")] /// diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index f18a45083ff7..83730285636f 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -595,7 +595,7 @@ //! [drop-impl]: self#implementing-drop-for-types-with-address-sensitive-states //! //! The [`drop`] function takes [`&mut self`], but this is called *even if that `self` has been -//! pinned*! Implementing [`Drop`] for a type with address-sensitive states, because if `self` was +//! pinned*! Implementing [`Drop`] for a type with address-sensitive states requires some care, because if `self` was //! indeed in an address-sensitive state before [`drop`] was called, it is as if the compiler //! automatically called [`Pin::get_unchecked_mut`]. //! diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index e6e13eaff7b0..ac074c097d94 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1009,9 +1009,8 @@ pub const fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_swap", issue = "83163")] +#[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")] #[rustc_diagnostic_item = "ptr_swap"] -#[rustc_const_stable_indirect] pub const unsafe fn swap(x: *mut T, y: *mut T) { // Give ourselves some scratch space to work with. // We do not have to worry about drops: `MaybeUninit` does nothing when dropped. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 34567917b523..d75d570a969f 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1594,7 +1594,7 @@ impl *mut T { /// /// [`ptr::swap`]: crate::ptr::swap() #[stable(feature = "pointer_methods", since = "1.26.0")] - #[rustc_const_unstable(feature = "const_swap", issue = "83163")] + #[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")] #[inline(always)] pub const unsafe fn swap(self, with: *mut T) where diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index e0ba469272ed..1058fa42cc1e 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1146,7 +1146,7 @@ impl NonNull { /// [`ptr::swap`]: crate::ptr::swap() #[inline(always)] #[stable(feature = "non_null_convenience", since = "1.80.0")] - #[rustc_const_unstable(feature = "const_swap", issue = "83163")] + #[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")] pub const unsafe fn swap(self, with: NonNull) where T: Sized, diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index ab65f9d6d2fc..3e8c698a7aba 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -913,7 +913,7 @@ impl [T] { /// assert!(v == ["a", "b", "e", "d", "c"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_swap", issue = "83163")] + #[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")] #[inline] #[track_caller] pub const fn swap(&mut self, a: usize, b: usize) { diff --git a/library/core/tests/intrinsics.rs b/library/core/tests/intrinsics.rs index 8b731cf5b25d..744a6a0d2dd8 100644 --- a/library/core/tests/intrinsics.rs +++ b/library/core/tests/intrinsics.rs @@ -125,3 +125,71 @@ fn test_three_way_compare_in_const_contexts() { assert_eq!(SIGNED_EQUAL, Equal); assert_eq!(SIGNED_GREATER, Greater); } + +fn fallback_cma( + a: T, + b: T, + c: T, + d: T, +) -> (T::Unsigned, T) { + a.carrying_mul_add(b, c, d) +} + +#[test] +fn carrying_mul_add_fallback_u32() { + let r = fallback_cma::(0x9e37_79b9, 0x7f4a_7c15, 0xf39c_c060, 0x5ced_c834); + assert_eq!(r, (0x2087_20c1, 0x4eab_8e1d)); + let r = fallback_cma::(0x1082_276b, 0xf3a2_7251, 0xf86c_6a11, 0xd0c1_8e95); + assert_eq!(r, (0x7aa0_1781, 0x0fb6_0528)); +} + +#[test] +fn carrying_mul_add_fallback_i32() { + let r = fallback_cma::(-1, -1, -1, -1); + assert_eq!(r, (u32::MAX, -1)); + let r = fallback_cma::(1, -1, 1, 1); + assert_eq!(r, (1, 0)); +} + +#[test] +fn carrying_mul_add_fallback_u128() { + assert_eq!(fallback_cma::(u128::MAX, u128::MAX, 0, 0), (1, u128::MAX - 1)); + assert_eq!(fallback_cma::(1, 1, 1, 1), (3, 0)); + assert_eq!(fallback_cma::(0, 0, u128::MAX, u128::MAX), (u128::MAX - 1, 1)); + assert_eq!( + fallback_cma::(u128::MAX, u128::MAX, u128::MAX, u128::MAX), + (u128::MAX, u128::MAX), + ); + + let r = fallback_cma::( + 0x243f6a8885a308d313198a2e03707344, + 0xa4093822299f31d0082efa98ec4e6c89, + 0x452821e638d01377be5466cf34e90c6c, + 0xc0ac29b7c97c50dd3f84d5b5b5470917, + ); + assert_eq!(r, (0x8050ec20ed554e40338d277e00b674e7, 0x1739ee6cea07da409182d003859b59d8)); + let r = fallback_cma::( + 0x9216d5d98979fb1bd1310ba698dfb5ac, + 0x2ffd72dbd01adfb7b8e1afed6a267e96, + 0xba7c9045f12c7f9924a19947b3916cf7, + 0x0801f2e2858efc16636920d871574e69, + ); + assert_eq!(r, (0x185525545fdb2fefb502a3a602efd628, 0x1b62d35fe3bff6b566f99667ef7ebfd6)); +} + +#[test] +fn carrying_mul_add_fallback_i128() { + assert_eq!(fallback_cma::(-1, -1, 0, 0), (1, 0)); + let r = fallback_cma::(-1, -1, -1, -1); + assert_eq!(r, (u128::MAX, -1)); + let r = fallback_cma::(1, -1, 1, 1); + assert_eq!(r, (1, 0)); + assert_eq!( + fallback_cma::(i128::MAX, i128::MAX, i128::MAX, i128::MAX), + (u128::MAX, i128::MAX / 2), + ); + assert_eq!( + fallback_cma::(i128::MIN, i128::MIN, i128::MAX, i128::MAX), + (u128::MAX - 1, -(i128::MIN / 2)), + ); +} diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 9f0ab7b3f297..f18a3f72df34 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -15,10 +15,10 @@ #![feature(clone_to_uninit)] #![feature(const_black_box)] #![feature(const_eval_select)] -#![feature(const_swap)] #![feature(const_swap_nonoverlapping)] #![feature(const_trait_impl)] #![feature(core_intrinsics)] +#![feature(core_intrinsics_fallbacks)] #![feature(core_io_borrowed_buf)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index f43dcc1630c6..6380c941e6ab 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.138" } +compiler_builtins = { version = "=0.1.140" } unwind = { path = "../unwind" } hashbrown = { version = "0.15", default-features = false, features = [ 'rustc-dep-of-std', diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 109bc3946346..56d734ba2fbf 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1446,6 +1446,11 @@ impl From<[(K, V); N]> for HashMap where K: Eq + Hash, { + /// Converts a `[(K, V); N]` into a `HashMap`. + /// + /// If any entries in the array have equal keys, + /// all but one of the corresponding values will be dropped. + /// /// # Examples /// /// ``` @@ -3219,6 +3224,10 @@ where K: Eq + Hash, S: BuildHasher + Default, { + /// Constructs a `HashMap` from an iterator of key-value pairs. + /// + /// If the iterator produces any pairs with equal keys, + /// all but one of the corresponding values will be dropped. fn from_iter>(iter: T) -> HashMap { let mut map = HashMap::with_hasher(Default::default()); map.extend(iter); diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 4c81aaff4588..bcf6d6b4ccf3 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -1091,6 +1091,11 @@ impl From<[T; N]> for HashSet where T: Eq + Hash, { + /// Converts a `[T; N]` into a `HashSet`. + /// + /// If the array contains any equal values, + /// all but one will be dropped. + /// /// # Examples /// /// ``` diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs index 469136be8838..7d7cce09a3f0 100644 --- a/library/std/src/ffi/mod.rs +++ b/library/std/src/ffi/mod.rs @@ -179,19 +179,19 @@ pub use core::ffi::{ c_ulong, c_ulonglong, c_ushort, }; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] pub use self::c_str::FromBytesUntilNulError; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "cstr_from_bytes", since = "1.10.0")] pub use self::c_str::FromBytesWithNulError; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")] pub use self::c_str::FromVecWithNulError; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "cstring_into", since = "1.7.0")] pub use self::c_str::IntoStringError; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "rust1", since = "1.0.0")] pub use self::c_str::NulError; #[doc(inline)] diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 0308a5f433a9..28f16da1ed8d 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1953,3 +1953,32 @@ fn test_rename_directory_to_non_empty_directory() { error!(fs::rename(source_path, target_path), 145); // ERROR_DIR_NOT_EMPTY } + +#[test] +fn test_rename_symlink() { + let tmpdir = tmpdir(); + let original = tmpdir.join("original"); + let dest = tmpdir.join("dest"); + let not_exist = Path::new("does not exist"); + + symlink_file(not_exist, &original).unwrap(); + fs::rename(&original, &dest).unwrap(); + // Make sure that renaming `original` to `dest` preserves the symlink. + assert_eq!(fs::read_link(&dest).unwrap().as_path(), not_exist); +} + +#[test] +#[cfg(windows)] +fn test_rename_junction() { + let tmpdir = tmpdir(); + let original = tmpdir.join("original"); + let dest = tmpdir.join("dest"); + let not_exist = Path::new("does not exist"); + + junction_point(¬_exist, &original).unwrap(); + fs::rename(&original, &dest).unwrap(); + + // Make sure that renaming `original` to `dest` preserves the junction point. + // Junction links are always absolute so we just check the file name is correct. + assert_eq!(fs::read_link(&dest).unwrap().file_name(), Some(not_exist.as_os_str())); +} diff --git a/library/std/src/sync/barrier.rs b/library/std/src/sync/barrier.rs index 82cc13a74b7f..14e4a9abe6f1 100644 --- a/library/std/src/sync/barrier.rs +++ b/library/std/src/sync/barrier.rs @@ -10,26 +10,22 @@ use crate::sync::{Condvar, Mutex}; /// # Examples /// /// ``` -/// use std::sync::{Arc, Barrier}; +/// use std::sync::Barrier; /// use std::thread; /// /// let n = 10; -/// let mut handles = Vec::with_capacity(n); -/// let barrier = Arc::new(Barrier::new(n)); -/// for _ in 0..n { -/// let c = Arc::clone(&barrier); -/// // The same messages will be printed together. -/// // You will NOT see any interleaving. -/// handles.push(thread::spawn(move || { -/// println!("before wait"); -/// c.wait(); -/// println!("after wait"); -/// })); -/// } -/// // Wait for other threads to finish. -/// for handle in handles { -/// handle.join().unwrap(); -/// } +/// let barrier = Barrier::new(n); +/// thread::scope(|s| { +/// for _ in 0..n { +/// // The same messages will be printed together. +/// // You will NOT see any interleaving. +/// s.spawn(|| { +/// println!("before wait"); +/// barrier.wait(); +/// println!("after wait"); +/// }); +/// } +/// }); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct Barrier { @@ -105,26 +101,22 @@ impl Barrier { /// # Examples /// /// ``` - /// use std::sync::{Arc, Barrier}; + /// use std::sync::Barrier; /// use std::thread; /// /// let n = 10; - /// let mut handles = Vec::with_capacity(n); - /// let barrier = Arc::new(Barrier::new(n)); - /// for _ in 0..n { - /// let c = Arc::clone(&barrier); - /// // The same messages will be printed together. - /// // You will NOT see any interleaving. - /// handles.push(thread::spawn(move || { - /// println!("before wait"); - /// c.wait(); - /// println!("after wait"); - /// })); - /// } - /// // Wait for other threads to finish. - /// for handle in handles { - /// handle.join().unwrap(); - /// } + /// let barrier = Barrier::new(n); + /// thread::scope(|s| { + /// for _ in 0..n { + /// // The same messages will be printed together. + /// // You will NOT see any interleaving. + /// s.spawn(|| { + /// println!("before wait"); + /// barrier.wait(); + /// println!("after wait"); + /// }); + /// } + /// }); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn wait(&self) -> BarrierWaitResult { diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 37029bcd36e3..3307fa47c7f8 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -168,7 +168,8 @@ cfg_has_statx! {{ ) -> c_int } - if STATX_SAVED_STATE.load(Ordering::Relaxed) == STATX_STATE::Unavailable as u8 { + let statx_availability = STATX_SAVED_STATE.load(Ordering::Relaxed); + if statx_availability == STATX_STATE::Unavailable as u8 { return None; } @@ -200,6 +201,9 @@ cfg_has_statx! {{ return None; } } + if statx_availability == STATX_STATE::Unknown as u8 { + STATX_SAVED_STATE.store(STATX_STATE::Present as u8, Ordering::Relaxed); + } // We cannot fill `stat64` exhaustively because of private padding fields. let mut stat: stat64 = mem::zeroed(); @@ -1944,7 +1948,7 @@ fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)> #[cfg(target_os = "espidf")] fn open_to_and_set_permissions( to: &Path, - _reader_metadata: crate::fs::Metadata, + _reader_metadata: &crate::fs::Metadata, ) -> io::Result<(crate::fs::File, crate::fs::Metadata)> { use crate::fs::OpenOptions; let writer = OpenOptions::new().open(to)?; @@ -1955,7 +1959,7 @@ fn open_to_and_set_permissions( #[cfg(not(target_os = "espidf"))] fn open_to_and_set_permissions( to: &Path, - reader_metadata: crate::fs::Metadata, + reader_metadata: &crate::fs::Metadata, ) -> io::Result<(crate::fs::File, crate::fs::Metadata)> { use crate::fs::OpenOptions; use crate::os::unix::fs::{OpenOptionsExt, PermissionsExt}; @@ -1980,30 +1984,63 @@ fn open_to_and_set_permissions( Ok((writer, writer_metadata)) } -#[cfg(not(any(target_os = "linux", target_os = "android", target_vendor = "apple")))] -pub fn copy(from: &Path, to: &Path) -> io::Result { - let (mut reader, reader_metadata) = open_from(from)?; - let (mut writer, _) = open_to_and_set_permissions(to, reader_metadata)?; +mod cfm { + use crate::fs::{File, Metadata}; + use crate::io::{BorrowedCursor, IoSlice, IoSliceMut, Read, Result, Write}; - io::copy(&mut reader, &mut writer) -} + #[allow(dead_code)] + pub struct CachedFileMetadata(pub File, pub Metadata); -#[cfg(any(target_os = "linux", target_os = "android"))] -pub fn copy(from: &Path, to: &Path) -> io::Result { - let (mut reader, reader_metadata) = open_from(from)?; - let max_len = u64::MAX; - let (mut writer, _) = open_to_and_set_permissions(to, reader_metadata)?; - - use super::kernel_copy::{CopyResult, copy_regular_files}; - - match copy_regular_files(reader.as_raw_fd(), writer.as_raw_fd(), max_len) { - CopyResult::Ended(bytes) => Ok(bytes), - CopyResult::Error(e, _) => Err(e), - CopyResult::Fallback(written) => match io::copy::generic_copy(&mut reader, &mut writer) { - Ok(bytes) => Ok(bytes + written), - Err(e) => Err(e), - }, + impl Read for CachedFileMetadata { + fn read(&mut self, buf: &mut [u8]) -> Result { + self.0.read(buf) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result { + self.0.read_vectored(bufs) + } + fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> Result<()> { + self.0.read_buf(cursor) + } + #[inline] + fn is_read_vectored(&self) -> bool { + self.0.is_read_vectored() + } + fn read_to_end(&mut self, buf: &mut Vec) -> Result { + self.0.read_to_end(buf) + } + fn read_to_string(&mut self, buf: &mut String) -> Result { + self.0.read_to_string(buf) + } } + impl Write for CachedFileMetadata { + fn write(&mut self, buf: &[u8]) -> Result { + self.0.write(buf) + } + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result { + self.0.write_vectored(bufs) + } + #[inline] + fn is_write_vectored(&self) -> bool { + self.0.is_write_vectored() + } + #[inline] + fn flush(&mut self) -> Result<()> { + self.0.flush() + } + } +} +#[cfg(any(target_os = "linux", target_os = "android"))] +pub(crate) use cfm::CachedFileMetadata; + +#[cfg(not(target_vendor = "apple"))] +pub fn copy(from: &Path, to: &Path) -> io::Result { + let (reader, reader_metadata) = open_from(from)?; + let (writer, writer_metadata) = open_to_and_set_permissions(to, &reader_metadata)?; + + io::copy( + &mut cfm::CachedFileMetadata(reader, reader_metadata), + &mut cfm::CachedFileMetadata(writer, writer_metadata), + ) } #[cfg(target_vendor = "apple")] @@ -2040,7 +2077,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { } // Fall back to using `fcopyfile` if `fclonefileat` does not succeed. - let (writer, writer_metadata) = open_to_and_set_permissions(to, reader_metadata)?; + let (writer, writer_metadata) = open_to_and_set_permissions(to, &reader_metadata)?; // We ensure that `FreeOnDrop` never contains a null pointer so it is // always safe to call `copyfile_state_free` diff --git a/library/std/src/sys/pal/unix/kernel_copy.rs b/library/std/src/sys/pal/unix/kernel_copy.rs index a671383cb795..36823a503b17 100644 --- a/library/std/src/sys/pal/unix/kernel_copy.rs +++ b/library/std/src/sys/pal/unix/kernel_copy.rs @@ -65,6 +65,7 @@ use crate::process::{ChildStderr, ChildStdin, ChildStdout}; use crate::ptr; use crate::sync::atomic::{AtomicBool, AtomicU8, Ordering}; use crate::sys::cvt; +use crate::sys::fs::CachedFileMetadata; use crate::sys::weak::syscall; #[cfg(test)] @@ -192,7 +193,7 @@ impl SpecCopy for Copier<'_, '_, R, W> { let w_cfg = writer.properties(); // before direct operations on file descriptors ensure that all source and sink buffers are empty - let mut flush = || -> crate::io::Result { + let mut flush = || -> Result { let bytes = reader.drain_to(writer, u64::MAX)?; // BufWriter buffered bytes have already been accounted for in earlier write() calls writer.flush()?; @@ -537,6 +538,18 @@ impl CopyWrite for BufWriter { } } +impl CopyRead for CachedFileMetadata { + fn properties(&self) -> CopyParams { + CopyParams(FdMeta::Metadata(self.1.clone()), Some(self.0.as_raw_fd())) + } +} + +impl CopyWrite for CachedFileMetadata { + fn properties(&self) -> CopyParams { + CopyParams(FdMeta::Metadata(self.1.clone()), Some(self.0.as_raw_fd())) + } +} + fn fd_to_meta(fd: &T) -> FdMeta { let fd = fd.as_raw_fd(); let file: ManuallyDrop = ManuallyDrop::new(unsafe { File::from_raw_fd(fd) }); diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt index d98e90eedfec..c06f274685c2 100644 --- a/library/std/src/sys/pal/windows/c/bindings.txt +++ b/library/std/src/sys/pal/windows/c/bindings.txt @@ -2426,6 +2426,7 @@ Windows.Win32.System.Console.ENABLE_VIRTUAL_TERMINAL_PROCESSING Windows.Win32.System.Console.ENABLE_WINDOW_INPUT Windows.Win32.System.Console.ENABLE_WRAP_AT_EOL_OUTPUT Windows.Win32.System.Console.GetConsoleMode +Windows.Win32.System.Console.GetConsoleOutputCP Windows.Win32.System.Console.GetStdHandle Windows.Win32.System.Console.ReadConsoleW Windows.Win32.System.Console.STD_ERROR_HANDLE diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs index ed29f3d264ca..79513d33a1ac 100644 --- a/library/std/src/sys/pal/windows/c/windows_sys.rs +++ b/library/std/src/sys/pal/windows/c/windows_sys.rs @@ -34,6 +34,7 @@ windows_targets::link!("kernel32.dll" "system" fn FreeEnvironmentStringsW(penv : windows_targets::link!("kernel32.dll" "system" fn GetActiveProcessorCount(groupnumber : u16) -> u32); windows_targets::link!("kernel32.dll" "system" fn GetCommandLineW() -> PCWSTR); windows_targets::link!("kernel32.dll" "system" fn GetConsoleMode(hconsolehandle : HANDLE, lpmode : *mut CONSOLE_MODE) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn GetConsoleOutputCP() -> u32); windows_targets::link!("kernel32.dll" "system" fn GetCurrentDirectoryW(nbufferlength : u32, lpbuffer : PWSTR) -> u32); windows_targets::link!("kernel32.dll" "system" fn GetCurrentProcess() -> HANDLE); windows_targets::link!("kernel32.dll" "system" fn GetCurrentProcessId() -> u32); @@ -3333,6 +3334,7 @@ pub struct XSAVE_FORMAT { pub XmmRegisters: [M128A; 8], pub Reserved4: [u8; 224], } + #[cfg(target_arch = "arm")] #[repr(C)] pub struct WSADATA { diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index dda4259919b6..b3659351b8c1 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -323,7 +323,7 @@ impl File { let alloc = c::FILE_ALLOCATION_INFO { AllocationSize: 0 }; let result = c::SetFileInformationByHandle( handle.as_raw_handle(), - c::FileEndOfFileInfo, + c::FileAllocationInfo, (&raw const alloc).cast::(), mem::size_of::() as u32, ); @@ -1295,15 +1295,18 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> { } else { // SAFETY: The struct has been initialized by GetFileInformationByHandleEx let file_attribute_tag_info = unsafe { file_attribute_tag_info.assume_init() }; + let file_type = FileType::new( + file_attribute_tag_info.FileAttributes, + file_attribute_tag_info.ReparseTag, + ); - if file_attribute_tag_info.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 - && file_attribute_tag_info.ReparseTag != c::IO_REPARSE_TAG_MOUNT_POINT - { - // The file is not a mount point: Reopen the file without inhibiting reparse point behavior. - None - } else { - // The file is a mount point: Don't reopen the file so that the mount point gets renamed. + if file_type.is_symlink() { + // The file is a mount point, junction point or symlink so + // don't reopen the file so that the link gets renamed. Some(Ok(handle)) + } else { + // Otherwise reopen the file without inhibiting reparse point behavior. + None } } } diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/pal/windows/stdio.rs index 642c8bc4df7d..1b735e7f0cb2 100644 --- a/library/std/src/sys/pal/windows/stdio.rs +++ b/library/std/src/sys/pal/windows/stdio.rs @@ -84,21 +84,43 @@ fn is_console(handle: c::HANDLE) -> bool { unsafe { c::GetConsoleMode(handle, &mut mode) != 0 } } +/// Returns true if the attached console's code page is currently UTF-8. +#[cfg(not(target_vendor = "win7"))] +fn is_utf8_console() -> bool { + unsafe { c::GetConsoleOutputCP() == c::CP_UTF8 } +} + +#[cfg(target_vendor = "win7")] +fn is_utf8_console() -> bool { + // Windows 7 has a fun "feature" where WriteFile on a console handle will return + // the number of UTF-16 code units written and not the number of bytes from the input string. + // So we always claim the console isn't UTF-8 to trigger the WriteConsole fallback code. + false +} + fn write(handle_id: u32, data: &[u8], incomplete_utf8: &mut IncompleteUtf8) -> io::Result { if data.is_empty() { return Ok(0); } let handle = get_handle(handle_id)?; - if !is_console(handle) { + if !is_console(handle) || is_utf8_console() { unsafe { let handle = Handle::from_raw_handle(handle); let ret = handle.write(data); let _ = handle.into_raw_handle(); // Don't close the handle return ret; } + } else { + write_console_utf16(data, incomplete_utf8, handle) } +} +fn write_console_utf16( + data: &[u8], + incomplete_utf8: &mut IncompleteUtf8, + handle: c::HANDLE, +) -> io::Result { if incomplete_utf8.len > 0 { assert!( incomplete_utf8.len < 4, diff --git a/library/std/src/thread/current.rs b/library/std/src/thread/current.rs index 1048ef973560..3d2c288b3608 100644 --- a/library/std/src/thread/current.rs +++ b/library/std/src/thread/current.rs @@ -136,7 +136,7 @@ pub(crate) fn set_current(thread: Thread) -> Result<(), Thread> { /// one thread and is guaranteed not to call the global allocator. #[inline] pub(crate) fn current_id() -> ThreadId { - // If accessing the persistant thread ID takes multiple TLS accesses, try + // If accessing the persistent thread ID takes multiple TLS accesses, try // to retrieve it from the current thread handle, which will only take one // TLS access. if !id::CHEAP { diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index 96ddae16f0ab..e13c9a06c05d 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -22,7 +22,7 @@ cfg-if = "1.0" libc = { version = "0.2.140", features = ['rustc-dep-of-std'], default-features = false } [target.'cfg(target_os = "xous")'.dependencies] -unwinding = { version = "0.2.3", features = ['rustc-dep-of-std', 'unwinder', 'fde-custom'], default-features = false } +unwinding = { version = "0.2.5", features = ['rustc-dep-of-std', 'unwinder', 'fde-custom'], default-features = false } [features] diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 6da716b7a895..d8775a67e193 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -7,7 +7,6 @@ default-run = "bootstrap" [features] build-metrics = ["sysinfo"] -bootstrap-self-test = [] # enabled in the bootstrap unit tests [lib] path = "src/lib.rs" diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index 88595ff7e519..610450675928 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -28,6 +28,9 @@ use shared_helpers::{ #[path = "../utils/shared_helpers.rs"] mod shared_helpers; +#[path = "../utils/proc_macro_deps.rs"] +mod proc_macro_deps; + fn main() { let orig_args = env::args_os().skip(1).collect::>(); let mut args = orig_args.clone(); @@ -167,7 +170,7 @@ fn main() { // issue https://github.com/rust-lang/rust/issues/100530 if env::var("RUSTC_TLS_MODEL_INITIAL_EXEC").is_ok() && crate_type != Some("proc-macro") - && !matches!(crate_name, Some("proc_macro2" | "quote" | "syn" | "synstructure")) + && proc_macro_deps::CRATES.binary_search(&crate_name.unwrap_or_default()).is_err() { cmd.arg("-Ztls-model=initial-exec"); } diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index f32d95fe8367..b4d37b25a6c7 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -501,6 +501,9 @@ tool_check_step!( ); tool_check_step!(Bootstrap, "bootstrap", "src/bootstrap", SourceType::InTree, false); +// Compiletest is implicitly "checked" when it gets built in order to run tests, +// so this is mainly for people working on compiletest to run locally. +tool_check_step!(Compiletest, "compiletest", "src/tools/compiletest", SourceType::InTree, false); /// Cargo's output path for the standard library in a given stage, compiled /// by a particular compiler for the specified target. diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index d30a0d028ff0..ca337aa9f4c3 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -396,7 +396,7 @@ fn copy_self_contained_objects( /// Resolves standard library crates for `Std::run_make` for any build kind (like check, build, clippy, etc.). pub fn std_crates_for_run_make(run: &RunConfig<'_>) -> Vec { // FIXME: Extend builder tests to cover the `crates` field of `Std` instances. - if cfg!(feature = "bootstrap-self-test") { + if cfg!(test) { return vec![]; } @@ -984,6 +984,7 @@ impl Step for Rustc { true, // Only ship rustc_driver.so and .rmeta files, not all intermediate .rlib files. ); + let target_root_dir = stamp.parent().unwrap(); // When building `librustc_driver.so` (like `libLLVM.so`) on linux, it can contain // unexpected debuginfo from dependencies, for example from the C++ standard library used in // our LLVM wrapper. Unless we're explicitly requesting `librustc_driver` to be built with @@ -992,11 +993,16 @@ impl Step for Rustc { if builder.config.rust_debuginfo_level_rustc == DebuginfoLevel::None && builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None { - let target_root_dir = stamp.parent().unwrap(); let rustc_driver = target_root_dir.join("librustc_driver.so"); strip_debug(builder, target, &rustc_driver); } + if builder.config.rust_debuginfo_level_rustc == DebuginfoLevel::None { + // Due to LTO a lot of debug info from C++ dependencies such as jemalloc can make it into + // our final binaries + strip_debug(builder, target, &target_root_dir.join("rustc-main")); + } + builder.ensure(RustcLink::from_rustc( self, builder.compiler(compiler.stage, builder.config.build), diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 636c88b099b4..6aa6e4e277d4 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1133,69 +1133,21 @@ fn testdir(builder: &Builder<'_>, host: TargetSelection) -> PathBuf { builder.out.join(host).join("test") } -macro_rules! default_test { - ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr }) => { - test!($name { path: $path, mode: $mode, suite: $suite, default: true, host: false }); - }; -} - -macro_rules! default_test_with_compare_mode { - ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr, - compare_mode: $compare_mode:expr }) => { - test_with_compare_mode!($name { - path: $path, - mode: $mode, - suite: $suite, - default: true, - host: false, - compare_mode: $compare_mode - }); - }; -} - -macro_rules! host_test { - ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr }) => { - test!($name { path: $path, mode: $mode, suite: $suite, default: true, host: true }); - }; -} - +/// Declares a test step that invokes compiletest on a particular test suite. macro_rules! test { - ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr, default: $default:expr, - host: $host:expr }) => { - test_definitions!($name { - path: $path, - mode: $mode, - suite: $suite, - default: $default, - host: $host, - compare_mode: None - }); - }; -} - -macro_rules! test_with_compare_mode { - ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr, default: $default:expr, - host: $host:expr, compare_mode: $compare_mode:expr }) => { - test_definitions!($name { - path: $path, - mode: $mode, - suite: $suite, - default: $default, - host: $host, - compare_mode: Some($compare_mode) - }); - }; -} - -macro_rules! test_definitions { - ($name:ident { - path: $path:expr, - mode: $mode:expr, - suite: $suite:expr, - default: $default:expr, - host: $host:expr, - compare_mode: $compare_mode:expr - }) => { + ( + $( #[$attr:meta] )* // allow docstrings and attributes + $name:ident { + path: $path:expr, + mode: $mode:expr, + suite: $suite:expr, + default: $default:expr + $( , only_hosts: $only_hosts:expr )? // default: false + $( , compare_mode: $compare_mode:expr )? // default: None + $( , )? // optional trailing comma + } + ) => { + $( #[$attr] )* #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct $name { pub compiler: Compiler, @@ -1205,7 +1157,12 @@ macro_rules! test_definitions { impl Step for $name { type Output = (); const DEFAULT: bool = $default; - const ONLY_HOSTS: bool = $host; + const ONLY_HOSTS: bool = (const { + #[allow(unused_assignments, unused_mut)] + let mut value = false; + $( value = $only_hosts; )? + value + }); fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.suite_path($path) @@ -1224,7 +1181,12 @@ macro_rules! test_definitions { mode: $mode, suite: $suite, path: $path, - compare_mode: $compare_mode, + compare_mode: (const { + #[allow(unused_assignments, unused_mut)] + let mut value = None; + $( value = $compare_mode; )? + value + }), }) } } @@ -1232,13 +1194,18 @@ macro_rules! test_definitions { } /// Declares an alias for running the [`Coverage`] tests in only one mode. -/// Adapted from [`test_definitions`]. +/// Adapted from [`test`]. macro_rules! coverage_test_alias { - ($name:ident { - alias_and_mode: $alias_and_mode:expr, // &'static str - default: $default:expr, // bool - only_hosts: $only_hosts:expr $(,)? // bool - }) => { + ( + $( #[$attr:meta] )* // allow docstrings and attributes + $name:ident { + alias_and_mode: $alias_and_mode:expr, // &'static str + default: $default:expr, // bool + only_hosts: $only_hosts:expr // bool + $( , )? // optional trailing comma + } + ) => { + $( #[$attr] )* #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct $name { pub compiler: Compiler, @@ -1410,37 +1377,74 @@ impl Step for CrateBuildHelper { } } -default_test!(Ui { path: "tests/ui", mode: "ui", suite: "ui" }); +test!(Ui { path: "tests/ui", mode: "ui", suite: "ui", default: true }); -default_test!(Crashes { path: "tests/crashes", mode: "crashes", suite: "crashes" }); +test!(Crashes { path: "tests/crashes", mode: "crashes", suite: "crashes", default: true }); -default_test!(Codegen { path: "tests/codegen", mode: "codegen", suite: "codegen" }); +test!(Codegen { path: "tests/codegen", mode: "codegen", suite: "codegen", default: true }); -default_test!(CodegenUnits { +test!(CodegenUnits { path: "tests/codegen-units", mode: "codegen-units", - suite: "codegen-units" + suite: "codegen-units", + default: true, }); -default_test!(Incremental { path: "tests/incremental", mode: "incremental", suite: "incremental" }); +test!(Incremental { + path: "tests/incremental", + mode: "incremental", + suite: "incremental", + default: true, +}); -default_test_with_compare_mode!(Debuginfo { +test!(Debuginfo { path: "tests/debuginfo", mode: "debuginfo", suite: "debuginfo", - compare_mode: "split-dwarf" + default: true, + compare_mode: Some("split-dwarf"), }); -host_test!(UiFullDeps { path: "tests/ui-fulldeps", mode: "ui", suite: "ui-fulldeps" }); +test!(UiFullDeps { + path: "tests/ui-fulldeps", + mode: "ui", + suite: "ui-fulldeps", + default: true, + only_hosts: true, +}); -host_test!(Rustdoc { path: "tests/rustdoc", mode: "rustdoc", suite: "rustdoc" }); -host_test!(RustdocUi { path: "tests/rustdoc-ui", mode: "ui", suite: "rustdoc-ui" }); +test!(Rustdoc { + path: "tests/rustdoc", + mode: "rustdoc", + suite: "rustdoc", + default: true, + only_hosts: true, +}); +test!(RustdocUi { + path: "tests/rustdoc-ui", + mode: "ui", + suite: "rustdoc-ui", + default: true, + only_hosts: true, +}); -host_test!(RustdocJson { path: "tests/rustdoc-json", mode: "rustdoc-json", suite: "rustdoc-json" }); +test!(RustdocJson { + path: "tests/rustdoc-json", + mode: "rustdoc-json", + suite: "rustdoc-json", + default: true, + only_hosts: true, +}); -host_test!(Pretty { path: "tests/pretty", mode: "pretty", suite: "pretty" }); +test!(Pretty { + path: "tests/pretty", + mode: "pretty", + suite: "pretty", + default: true, + only_hosts: true, +}); -/// Special-handling is needed for `run-make`, so don't use `default_test` for defining `RunMake` +/// Special-handling is needed for `run-make`, so don't use `test!` for defining `RunMake` /// tests. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct RunMake { @@ -1475,7 +1479,7 @@ impl Step for RunMake { } } -default_test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly" }); +test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly", default: true }); /// Coverage tests are a bit more complicated than other test suites, because /// we want to run the same set of test files in multiple different modes, @@ -1552,27 +1556,33 @@ impl Step for Coverage { } } -// Runs `tests/coverage` in "coverage-map" mode only. -// Used by `x test` and `x test coverage-map`. -coverage_test_alias!(CoverageMap { - alias_and_mode: "coverage-map", - default: true, - only_hosts: false, -}); -// Runs `tests/coverage` in "coverage-run" mode only. -// Used by `x test` and `x test coverage-run`. -coverage_test_alias!(CoverageRun { - alias_and_mode: "coverage-run", - default: true, - // Compiletest knows how to automatically skip these tests when cross-compiling, - // but skipping the whole step here makes it clearer that they haven't run at all. - only_hosts: true, -}); +coverage_test_alias! { + /// Runs the `tests/coverage` test suite in "coverage-map" mode only. + /// Used by `x test` and `x test coverage-map`. + CoverageMap { + alias_and_mode: "coverage-map", + default: true, + only_hosts: false, + } +} +coverage_test_alias! { + /// Runs the `tests/coverage` test suite in "coverage-run" mode only. + /// Used by `x test` and `x test coverage-run`. + CoverageRun { + alias_and_mode: "coverage-run", + default: true, + // Compiletest knows how to automatically skip these tests when cross-compiling, + // but skipping the whole step here makes it clearer that they haven't run at all. + only_hosts: true, + } +} -host_test!(CoverageRunRustdoc { +test!(CoverageRunRustdoc { path: "tests/coverage-run-rustdoc", mode: "coverage-run", - suite: "coverage-run-rustdoc" + suite: "coverage-run-rustdoc", + default: true, + only_hosts: true, }); // For the mir-opt suite we do not use macros, as we need custom behavior when blessing. @@ -1829,6 +1839,10 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--force-rerun"); } + if builder.config.cmd.no_capture() { + cmd.arg("--no-capture"); + } + let compare_mode = builder.config.cmd.compare_mode().or_else(|| { if builder.config.test_compare_mode { self.compare_mode } else { None } @@ -2623,7 +2637,7 @@ fn prepare_cargo_test( ) -> BootstrapCommand { let mut cargo = cargo.into(); - // Propegate `--bless` if it has not already been set/unset + // Propagate `--bless` if it has not already been set/unset // Any tools that want to use this should bless if `RUSTC_BLESS` is set to // anything other than `0`. if builder.config.cmd.bless() && !cargo.get_envs().any(|v| v.0 == "RUSTC_BLESS") { @@ -3148,9 +3162,8 @@ impl Step for Bootstrap { let mut cmd = command(&builder.initial_cargo); cmd.arg("test") - .args(["--features", "bootstrap-self-test"]) .current_dir(builder.src.join("src/bootstrap")) - .env("RUSTFLAGS", "-Cdebuginfo=2") + .env("RUSTFLAGS", "--cfg test -Cdebuginfo=2") .env("CARGO_TARGET_DIR", builder.out.join("bootstrap")) .env("RUSTC_BOOTSTRAP", "1") .env("RUSTDOC", builder.rustdoc(compiler)) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 04f1e10f4937..6b809a52bd29 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -5,7 +5,7 @@ use crate::core::build_steps::toolstate::ToolState; use crate::core::build_steps::{compile, llvm}; use crate::core::builder; use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step}; -use crate::core::config::TargetSelection; +use crate::core::config::{DebuginfoLevel, TargetSelection}; use crate::utils::channel::GitInfo; use crate::utils::exec::{BootstrapCommand, command}; use crate::utils::helpers::{add_dylib_path, exe, t}; @@ -671,6 +671,11 @@ impl Step for Rustdoc { // don't create a stage0-sysroot/bin directory. if target_compiler.stage > 0 { + if builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None { + // Due to LTO a lot of debug info from C++ dependencies such as jemalloc can make it into + // our final binaries + compile::strip_debug(builder, target, &tool_rustdoc); + } let bin_rustdoc = bin_rustdoc(); builder.copy_link(&tool_rustdoc, &bin_rustdoc); bin_rustdoc diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 98f765dbd0f5..18beaf3676d5 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -905,6 +905,7 @@ impl<'a> Builder<'a> { check::RustAnalyzer, check::TestFloatParse, check::Bootstrap, + check::Compiletest, ), Kind::Test => describe!( crate::core::build_steps::toolstate::ToolStateCheck, diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 819a552093be..a0acd8393744 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -637,6 +637,7 @@ mod dist { run: None, only_modified: false, extra_checks: None, + no_capture: false, }; let build = Build::new(config); @@ -702,6 +703,7 @@ mod dist { run: None, only_modified: false, extra_checks: None, + no_capture: false, }; // Make sure rustfmt binary not being found isn't an error. config.channel = "beta".to_string(); diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 435216ef534c..dd2f11ad4690 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1154,7 +1154,6 @@ define_config! { debuginfo_level_tests: Option = "debuginfo-level-tests", backtrace: Option = "backtrace", incremental: Option = "incremental", - parallel_compiler: Option = "parallel-compiler", default_linker: Option = "default-linker", channel: Option = "channel", description: Option = "description", @@ -1325,23 +1324,14 @@ impl Config { .into_iter() .chain(flags.exclude) .map(|p| { - let p = if cfg!(windows) { - PathBuf::from(p.to_str().unwrap().replace('/', "\\")) - } else { - p - }; - - // Jump to top-level project path to support passing paths - // from sub directories. - let top_level_path = config.src.join(&p); - if !config.src.join(&top_level_path).exists() { - eprintln!("WARNING: '{}' does not exist.", top_level_path.display()); - } - // Never return top-level path here as it would break `--skip` // logic on rustc's internal test framework which is utilized // by compiletest. - p + if cfg!(windows) { + PathBuf::from(p.to_str().unwrap().replace('/', "\\")) + } else { + p + } }) .collect(); @@ -1441,7 +1431,7 @@ impl Config { // Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path, // but not if `config.toml` hasn't been created. let mut toml = if !using_default_path || toml_path.exists() { - config.config = Some(if cfg!(not(feature = "bootstrap-self-test")) { + config.config = Some(if cfg!(not(test)) { toml_path.canonicalize().unwrap() } else { toml_path.clone() @@ -1764,7 +1754,6 @@ impl Config { debuginfo_level_tests: debuginfo_level_tests_toml, backtrace, incremental, - parallel_compiler, randomize_layout, default_linker, channel: _, // already handled above @@ -1874,13 +1863,6 @@ impl Config { config.rust_randomize_layout = randomize_layout.unwrap_or_default(); config.llvm_tools_enabled = llvm_tools.unwrap_or(true); - // FIXME: Remove this option at the end of 2024. - if parallel_compiler.is_some() { - println!( - "WARNING: The `rust.parallel-compiler` option is deprecated and does nothing. The parallel compiler (with one thread) is now the default" - ); - } - config.llvm_enzyme = llvm_enzyme.unwrap_or(config.channel == "dev" || config.channel == "nightly"); config.rustc_default_linker = default_linker; @@ -2793,11 +2775,11 @@ impl Config { } } - #[cfg(feature = "bootstrap-self-test")] + #[cfg(test)] pub fn check_stage0_version(&self, _program_path: &Path, _component_name: &'static str) {} /// check rustc/cargo version is same or lower with 1 apart from the building one - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] pub fn check_stage0_version(&self, program_path: &Path, component_name: &'static str) { use build_helper::util::fail; @@ -2939,7 +2921,7 @@ impl Config { } // Fetching the LLVM submodule is unnecessary for self-tests. - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] self.update_submodule("src/llvm-project"); // Check for untracked changes in `src/llvm-project`. @@ -3014,7 +2996,7 @@ impl Config { /// Compares the current `Llvm` options against those in the CI LLVM builder and detects any incompatible options. /// It does this by destructuring the `Llvm` instance to make sure every `Llvm` field is covered and not missing. -#[cfg(not(feature = "bootstrap-self-test"))] +#[cfg(not(test))] pub(crate) fn check_incompatible_options_for_ci_llvm( current_config_toml: TomlConfig, ci_config_toml: TomlConfig, @@ -3222,7 +3204,6 @@ fn check_incompatible_options_for_ci_rustc( debuginfo_level_tools: _, debuginfo_level_tests: _, backtrace: _, - parallel_compiler: _, musl_root: _, verbose_tests: _, optimize_tests: _, diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index 00bcbe9f86d4..f17103f97dc4 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -388,6 +388,9 @@ pub enum Subcommand { /// enable this to generate a Rustfix coverage file, which is saved in /// `//rustfix_missing_coverage.txt` rustfix_coverage: bool, + #[arg(long)] + /// don't capture stdout/stderr of tests + no_capture: bool, }, /// Build and run some test suites *in Miri* Miri { @@ -563,6 +566,13 @@ impl Subcommand { } } + pub fn no_capture(&self) -> bool { + match *self { + Subcommand::Test { no_capture, .. } => no_capture, + _ => false, + } + } + pub fn rustfix_coverage(&self) -> bool { match *self { Subcommand::Test { rustfix_coverage, .. } => rustfix_coverage, diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index db35e6907e66..b5f7ed531312 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -197,8 +197,7 @@ impl Config { if !path_is_dylib(fname) { // Finally, set the correct .interp for binaries let dynamic_linker_path = nix_deps_dir.join("nix-support/dynamic-linker"); - // FIXME: can we support utf8 here? `args` doesn't accept Vec, only OsString ... - let dynamic_linker = t!(String::from_utf8(t!(fs::read(dynamic_linker_path)))); + let dynamic_linker = t!(fs::read_to_string(dynamic_linker_path)); patchelf.args(["--set-interpreter", dynamic_linker.trim_end()]); } @@ -444,14 +443,14 @@ impl Config { cargo_clippy } - #[cfg(feature = "bootstrap-self-test")] + #[cfg(test)] pub(crate) fn maybe_download_rustfmt(&self) -> Option { None } /// NOTE: rustfmt is a completely different toolchain than the bootstrap compiler, so it can't /// reuse target directories or artifacts - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] pub(crate) fn maybe_download_rustfmt(&self) -> Option { use build_helper::stage0_parser::VersionMetadata; @@ -534,10 +533,10 @@ impl Config { ); } - #[cfg(feature = "bootstrap-self-test")] + #[cfg(test)] pub(crate) fn download_beta_toolchain(&self) {} - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] pub(crate) fn download_beta_toolchain(&self) { self.verbose(|| println!("downloading stage0 beta artifacts")); @@ -714,10 +713,10 @@ download-rustc = false self.unpack(&tarball, &bin_root, prefix); } - #[cfg(feature = "bootstrap-self-test")] + #[cfg(test)] pub(crate) fn maybe_download_ci_llvm(&self) {} - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] pub(crate) fn maybe_download_ci_llvm(&self) { use build_helper::exit; @@ -789,7 +788,7 @@ download-rustc = false }; } - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] fn download_ci_llvm(&self, llvm_sha: &str) { let llvm_assertions = self.llvm_assertions; diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index dcf68cbeeda7..ed0155622c22 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -14,10 +14,10 @@ use std::path::PathBuf; use std::{env, fs}; use crate::Build; -#[cfg(not(feature = "bootstrap-self-test"))] +#[cfg(not(test))] use crate::builder::Builder; use crate::builder::Kind; -#[cfg(not(feature = "bootstrap-self-test"))] +#[cfg(not(test))] use crate::core::build_steps::tool; use crate::core::config::Target; use crate::utils::exec::command; @@ -38,7 +38,7 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[ /// Minimum version threshold for libstdc++ required when using prebuilt LLVM /// from CI (with`llvm.download-ci-llvm` option). -#[cfg(not(feature = "bootstrap-self-test"))] +#[cfg(not(test))] const LIBSTDCXX_MIN_VERSION_THRESHOLD: usize = 8; impl Finder { @@ -106,7 +106,7 @@ pub fn check(build: &mut Build) { } // Ensure that a compatible version of libstdc++ is available on the system when using `llvm.download-ci-llvm`. - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] if !build.config.dry_run() && !build.build.is_msvc() && build.config.llvm_from_ci { let builder = Builder::new(build); let libcxx_version = builder.ensure(tool::LibcxxVersionTool { target: build.build }); @@ -226,8 +226,7 @@ than building it. } // Ignore fake targets that are only used for unit tests in bootstrap. - if cfg!(not(feature = "bootstrap-self-test")) && !skip_target_sanity && !build.local_rebuild - { + if cfg!(not(test)) && !skip_target_sanity && !build.local_rebuild { let mut has_target = false; let target_str = target.to_string(); diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 0ecf61ffcd90..4cc812829f9b 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -635,11 +635,12 @@ impl Build { if self.config.backtrace { features.insert("backtrace"); } + if self.config.profiler_enabled(target) { features.insert("profiler"); } - // Generate memcpy, etc. FIXME: Remove this once compiler-builtins - // automatically detects this target. + + // If zkvm target, generate memcpy, etc. if target.contains("zkvm") { features.insert("compiler-builtins-mem"); } @@ -1690,7 +1691,7 @@ Executed at: {executed_at}"#, } } if let Ok(()) = fs::hard_link(&src, dst) { - // Attempt to "easy copy" by creating a hard link (symlinks are priviledged on windows), + // Attempt to "easy copy" by creating a hard link (symlinks are privileged on windows), // but if that fails just fall back to a slow `copy` operation. } else { if let Err(e) = fs::copy(&src, dst) { diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index f4f189c718a3..8fd6c8aa23ae 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -315,4 +315,14 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "`build.vendor` is now enabled by default for dist/tarball sources when 'vendor' directory and '.cargo/config.toml' file are present.", }, + ChangeInfo { + change_id: 134809, + severity: ChangeSeverity::Warning, + summary: "compiletest now takes `--no-capture` instead of `--nocapture`; bootstrap now accepts `--no-capture` as an argument to test commands directly", + }, + ChangeInfo { + change_id: 134650, + severity: ChangeSeverity::Warning, + summary: "Removed `rust.parallel-compiler` as it was deprecated in #132282 long time ago.", + }, ]; diff --git a/src/bootstrap/src/utils/mod.rs b/src/bootstrap/src/utils/mod.rs index 53b41f157806..b5f5e2ba6dc8 100644 --- a/src/bootstrap/src/utils/mod.rs +++ b/src/bootstrap/src/utils/mod.rs @@ -14,3 +14,5 @@ pub(crate) mod metrics; pub(crate) mod render_tests; pub(crate) mod shared_helpers; pub(crate) mod tarball; +#[cfg(test)] +mod tests; diff --git a/src/bootstrap/src/utils/proc_macro_deps.rs b/src/bootstrap/src/utils/proc_macro_deps.rs new file mode 100644 index 000000000000..dbfd6f47dc67 --- /dev/null +++ b/src/bootstrap/src/utils/proc_macro_deps.rs @@ -0,0 +1,71 @@ +/// Do not update manually - use `./x.py test tidy --bless` +/// Holds all direct and indirect dependencies of proc-macro crates in tree. +/// See +pub static CRATES: &[&str] = &[ + // tidy-alphabetical-start + "annotate-snippets", + "anstyle", + "basic-toml", + "block-buffer", + "bumpalo", + "cfg-if", + "cpufeatures", + "crypto-common", + "darling", + "darling_core", + "derive_builder_core", + "digest", + "fluent-bundle", + "fluent-langneg", + "fluent-syntax", + "fnv", + "generic-array", + "heck", + "ident_case", + "intl-memoizer", + "intl_pluralrules", + "libc", + "log", + "memchr", + "mime", + "mime_guess", + "minimal-lexical", + "nom", + "num-conv", + "once_cell", + "pest", + "pest_generator", + "pest_meta", + "proc-macro2", + "quote", + "rinja_parser", + "rustc-hash", + "self_cell", + "serde", + "sha2", + "smallvec", + "stable_deref_trait", + "strsim", + "syn", + "synstructure", + "thiserror", + "time-core", + "tinystr", + "type-map", + "typenum", + "ucd-trie", + "unic-langid", + "unic-langid-impl", + "unic-langid-macros", + "unicase", + "unicode-ident", + "unicode-width", + "version_check", + "wasm-bindgen-backend", + "wasm-bindgen-macro-support", + "wasm-bindgen-shared", + "yoke", + "zerofrom", + "zerovec", + // tidy-alphabetical-end +]; diff --git a/src/bootstrap/src/utils/shared_helpers.rs b/src/bootstrap/src/utils/shared_helpers.rs index 6d3c276cc056..7b206c3ffe82 100644 --- a/src/bootstrap/src/utils/shared_helpers.rs +++ b/src/bootstrap/src/utils/shared_helpers.rs @@ -13,8 +13,9 @@ use std::io::Write; use std::process::Command; use std::str::FromStr; -#[cfg(test)] -mod tests; +// If we were to declare a tests submodule here, the shim binaries that include this +// module via `#[path]` would fail to find it, which breaks `./x check bootstrap`. +// So instead the unit tests for this module are in `super::tests::shared_helpers_tests`. /// Returns the environment variable which the dynamic library lookup path /// resides in for this platform. diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index 3c6c7a7fa180..843ea65e8386 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -1,7 +1,7 @@ //! Facilitates the management and generation of tarballs. //! //! Tarballs efficiently hold Rust compiler build artifacts and -//! capture a snapshot of each boostrap stage. +//! capture a snapshot of each bootstrap stage. //! In uplifting, a tarball from Stage N captures essential components //! to assemble Stage N + 1 compiler. diff --git a/src/bootstrap/src/utils/tests/mod.rs b/src/bootstrap/src/utils/tests/mod.rs new file mode 100644 index 000000000000..0791f7a6e207 --- /dev/null +++ b/src/bootstrap/src/utils/tests/mod.rs @@ -0,0 +1 @@ +mod shared_helpers_tests; diff --git a/src/bootstrap/src/utils/shared_helpers/tests.rs b/src/bootstrap/src/utils/tests/shared_helpers_tests.rs similarity index 69% rename from src/bootstrap/src/utils/shared_helpers/tests.rs rename to src/bootstrap/src/utils/tests/shared_helpers_tests.rs index da7924276f7c..6c47e7f24387 100644 --- a/src/bootstrap/src/utils/shared_helpers/tests.rs +++ b/src/bootstrap/src/utils/tests/shared_helpers_tests.rs @@ -1,4 +1,11 @@ -use super::parse_value_from_args; +//! The `shared_helpers` module can't have its own tests submodule, because +//! that would cause problems for the shim binaries that include it via +//! `#[path]`, so instead those unit tests live here. +//! +//! To prevent tidy from complaining about this file not being named `tests.rs`, +//! it lives inside a submodule directory named `tests`. + +use crate::utils::shared_helpers::parse_value_from_args; #[test] fn test_parse_value_from_args() { diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 2f35e6050262..508b7b40c01e 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -26,6 +26,12 @@ DEPLOY=1 ./src/ci/docker/run.sh x86_64-gnu while locally, to the `obj/$image_name` directory. This is primarily to prevent strange linker errors when using multiple Docker images. +For some Linux workflows (for example `x86_64-gnu-llvm-18-N`), the process is more involved. You will need to see which script is executed for the given workflow inside the [`jobs.yml`](../github-actions/jobs.yml) file and pass it through the `DOCKER_SCRIPT` environment variable. For example, to reproduce the `x86_64-gnu-llvm-18-3` workflow, you can run the following script: + +``` +DOCKER_SCRIPT=x86_64-gnu-llvm3.sh ./src/ci/docker/run.sh x86_64-gnu-llvm-18 +``` + ## Local Development Refer to the [dev guide](https://rustc-dev-guide.rust-lang.org/tests/docker.html) for more information on testing locally. diff --git a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile index 414bcc52484c..7e946df61631 100644 --- a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile @@ -50,6 +50,7 @@ COPY host-x86_64/dist-x86_64-linux/shared.sh /tmp/ # Need at least GCC 5.1 to compile LLVM nowadays COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/ +ENV GCC_VERSION=9.5.0 RUN ./build-gcc.sh && yum remove -y gcc gcc-c++ COPY scripts/cmake.sh /tmp/ diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index e857f38e68a8..bbb4fe216a55 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -44,12 +44,14 @@ RUN mkdir -p /rustroot/bin ENV PATH=/rustroot/bin:$PATH ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib32:/rustroot/lib ENV PKG_CONFIG_PATH=/rustroot/lib/pkgconfig +# Clang needs to access GCC headers to enable linker plugin LTO WORKDIR /tmp RUN mkdir /home/user COPY host-x86_64/dist-x86_64-linux/shared.sh /tmp/ # Need at least GCC 5.1 to compile LLVM nowadays COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/ +ENV GCC_VERSION=9.5.0 RUN ./build-gcc.sh && yum remove -y gcc gcc-c++ # LLVM 17 needs cmake 3.20 or higher. @@ -89,6 +91,7 @@ ENV RUST_CONFIGURE_ARGS \ --set rust.lto=thin \ --set rust.codegen-units=1 +# Note that `rust.debug` is set to true *only* for `opt-dist` ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \ ./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \ --host $HOSTS --target $HOSTS \ @@ -104,3 +107,7 @@ ENV DIST_SRC 1 ENV LIBCURL_NO_PKG_CONFIG 1 ENV DIST_REQUIRE_ALL_TOOLS 1 + +# FIXME: Without this, LLVMgold.so incorrectly resolves to the system +# libstdc++, instead of the one we build. +ENV LD_PRELOAD=/rustroot/lib64/libstdc++.so.6 diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh index 2e08c87f278c..3c8123d90de0 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh @@ -39,6 +39,7 @@ hide_output \ -DLLVM_INCLUDE_TESTS=OFF \ -DLLVM_INCLUDE_EXAMPLES=OFF \ -DLLVM_ENABLE_PROJECTS="clang;lld;compiler-rt;bolt" \ + -DLLVM_BINUTILS_INCDIR="/rustroot/lib/gcc/x86_64-pc-linux-gnu/$GCC_VERSION/plugin/include/" \ -DC_INCLUDE_DIRS="$INC" hide_output make -j$(nproc) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh index e939a5d7eac4..57d4d338a506 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh @@ -1,10 +1,11 @@ #!/usr/bin/env bash -set -ex +set -eux source shared.sh # Note: in the future when bumping to version 10.1.0, also take care of the sed block below. -GCC=9.5.0 +# This version is specified in the Dockerfile +GCC=$GCC_VERSION curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.xz | xzcat | tar xf - cd gcc-$GCC diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index a0adf60b6b2c..d1bc0519bc1e 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -76,8 +76,9 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then # Include cache version. Can be used to manually bust the Docker cache. echo "2" >> $hash_key - echo "Image input" + echo "::group::Image checksum input" cat $hash_key + echo "::endgroup::" cksum=$(sha512sum $hash_key | \ awk '{print $1}') diff --git a/src/ci/scripts/install-clang.sh b/src/ci/scripts/install-clang.sh index 6103aa61248a..5522095e3049 100755 --- a/src/ci/scripts/install-clang.sh +++ b/src/ci/scripts/install-clang.sh @@ -15,7 +15,7 @@ LLVM_VERSION="18.1.4" if isMacOS; then # FIXME: This is the latest pre-built version of LLVM that's available for - # x86_64 MacOS. We may want to consider bulding our own LLVM binaries + # x86_64 MacOS. We may want to consider building our own LLVM binaries # instead, or set `USE_XCODE_CLANG` like AArch64 does. LLVM_VERSION="15.0.7" diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 9743b3ba442a..f0c3720eae14 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -56,6 +56,7 @@ - [csky-unknown-linux-gnuabiv2\*](platform-support/csky-unknown-linux-gnuabiv2.md) - [hexagon-unknown-linux-musl](platform-support/hexagon-unknown-linux-musl.md) - [hexagon-unknown-none-elf](platform-support/hexagon-unknown-none-elf.md) + - [illumos](platform-support/illumos.md) - [loongarch\*-unknown-linux-\*](platform-support/loongarch-linux.md) - [loongarch\*-unknown-none\*](platform-support/loongarch-none.md) - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 00ab61051c3c..24e9a3c81210 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -32,8 +32,8 @@ All tier 1 targets with host tools support the full standard library. target | notes -------|------- -`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+) [`aarch64-apple-darwin`](platform-support/apple-darwin.md) | ARM64 macOS (11.0+, Big Sur+) +`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+) `i686-pc-windows-gnu` | 32-bit MinGW (Windows 10+, Windows Server 2016+) [^x86_32-floats-return-ABI] `i686-pc-windows-msvc` | 32-bit MSVC (Windows 10+, Windows Server 2016+) [^x86_32-floats-return-ABI] `i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+) [^x86_32-floats-return-ABI] @@ -102,7 +102,7 @@ target | notes [`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3) [`s390x-unknown-linux-gnu`](platform-support/s390x-unknown-linux-gnu.md) | S390x Linux (kernel 3.2, glibc 2.17) [`x86_64-unknown-freebsd`](platform-support/freebsd.md) | 64-bit amd64 FreeBSD -`x86_64-unknown-illumos` | illumos +[`x86_64-unknown-illumos`](platform-support/illumos.md) | illumos `x86_64-unknown-linux-musl` | 64-bit Linux with musl 1.2.3 [`x86_64-unknown-netbsd`](platform-support/netbsd.md) | NetBSD/amd64 @@ -139,12 +139,12 @@ target | std | notes [`aarch64-apple-ios`](platform-support/apple-ios.md) | ✓ | ARM64 iOS [`aarch64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | Mac Catalyst on ARM64 [`aarch64-apple-ios-sim`](platform-support/apple-ios.md) | ✓ | Apple iOS Simulator on ARM64 -[`aarch64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | ARM64 Fuchsia [`aarch64-linux-android`](platform-support/android.md) | ✓ | ARM64 Android [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ARM64 MinGW (Windows 10+), LLVM ABI +[`aarch64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | ARM64 Fuchsia [`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | ARM64 OpenHarmony -`aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat `aarch64-unknown-none` | * | Bare ARM64, hardfloat +`aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat [`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | ARM64 UEFI [`arm-linux-androideabi`](platform-support/android.md) | ✓ | Armv6 Android `arm-unknown-linux-musleabi` | ✓ | Armv6 Linux with musl 1.2.3 @@ -173,11 +173,11 @@ target | std | notes [`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64D ABI) [`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64S ABI) [`nvptx64-nvidia-cuda`](platform-support/nvptx64-nvidia-cuda.md) | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs] -[`riscv32imac-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAC ISA) [`riscv32i-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32I ISA) [`riscv32im-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IM ISA) -[`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) +[`riscv32imac-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAC ISA) [`riscv32imafc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAFC ISA) +[`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA) `sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4, glibc 2.23) @@ -194,16 +194,16 @@ target | std | notes [`wasm32-unknown-emscripten`](platform-support/wasm32-unknown-emscripten.md) | ✓ | WebAssembly via Emscripten [`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASIp1 -[`wasm32-wasip2`](platform-support/wasm32-wasip2.md) | ✓ | WebAssembly with WASIp2 [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads +[`wasm32-wasip2`](platform-support/wasm32-wasip2.md) | ✓ | WebAssembly with WASIp2 [`wasm32v1-none`](platform-support/wasm32v1-none.md) | * | WebAssembly limited to 1.0 features and no imports [`x86_64-apple-ios`](platform-support/apple-ios.md) | ✓ | 64-bit x86 iOS [`x86_64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | Mac Catalyst on x86_64 [`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX -[`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia [`x86_64-linux-android`](platform-support/android.md) | ✓ | 64-bit x86 Android [`x86_64-pc-solaris`](platform-support/solaris.md) | ✓ | 64-bit x86 Solaris 11.4 [`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | 64-bit x86 MinGW (Windows 10+), LLVM ABI +[`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27) [`x86_64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | x86_64 OpenHarmony [`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat @@ -245,34 +245,34 @@ host tools. target | std | host | notes -------|:---:|:----:|------- -[`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md) | ✓ | ✓ | ARM64e Apple Darwin -[`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS -[`arm64e-apple-tvos`](platform-support/arm64e-apple-tvos.md) | ✓ | | ARM64e Apple tvOS [`aarch64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | ARM64 tvOS [`aarch64-apple-tvos-sim`](platform-support/apple-tvos.md) | ✓ | | ARM64 tvOS Simulator -[`aarch64-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS -[`aarch64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS Simulator [`aarch64-apple-visionos`](platform-support/apple-visionos.md) | ✓ | | ARM64 Apple visionOS [`aarch64-apple-visionos-sim`](platform-support/apple-visionos.md) | ✓ | | ARM64 Apple visionOS Simulator +[`aarch64-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS +[`aarch64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS Simulator [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon -[`aarch64-unknown-teeos`](platform-support/aarch64-unknown-teeos.md) | ? | | ARM64 TEEOS | -[`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.0 RTOS | -[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS | [`aarch64-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | ARM64 FreeBSD [`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ | | ARM64 Hermit -`aarch64-unknown-illumos` | ✓ | ✓ | ARM64 illumos +[`aarch64-unknown-illumos`](platform-support/illumos.md) | ✓ | ✓ | ARM64 illumos `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) [`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD +[`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.0 RTOS | +[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS | [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD [`aarch64-unknown-redox`](platform-support/redox.md) | ✓ | | ARM64 Redox OS +[`aarch64-unknown-teeos`](platform-support/aarch64-unknown-teeos.md) | ? | | ARM64 TEEOS | [`aarch64-unknown-trusty`](platform-support/trusty.md) | ? | | `aarch64-uwp-windows-msvc` | ✓ | | [`aarch64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | ARM64 VxWorks OS -`aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) `aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian) +`aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) [`aarch64_be-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD (big-endian) [`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | Arm Apple WatchOS 64-bit with 32-bit pointers +[`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md) | ✓ | ✓ | ARM64e Apple Darwin +[`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS +[`arm64e-apple-tvos`](platform-support/arm64e-apple-tvos.md) | ✓ | | ARM64e Apple tvOS [`armeb-unknown-linux-gnueabi`](platform-support/armeb-unknown-linux-gnueabi.md) | ✓ | ? | Arm BE8 the default Arm big-endian architecture since [Armv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en). [`armv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Bare Armv4T `armv4t-unknown-linux-gnueabi` | ? | | Armv4T Linux @@ -283,9 +283,9 @@ target | std | host | notes [`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | Armv6k Nintendo 3DS, Horizon (Requires devkitARM toolchain) [`armv7-rtems-eabihf`](platform-support/armv7-rtems-eabihf.md) | ? | | RTEMS OS for ARM BSPs [`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ✓ | | Armv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain) +[`armv7-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | Armv7-A FreeBSD [`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | Armv7-A Linux with uClibc, softfloat [`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | Armv7-A Linux with uClibc, hardfloat -[`armv7-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | Armv7-A FreeBSD [`armv7-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv7-A NetBSD w/hard-float [`armv7-unknown-trusty`](platform-support/trusty.md) | ? | | [`armv7-wrs-vxworks-eabihf`](platform-support/vxworks.md) | ✓ | | Armv7-A for VxWorks @@ -300,8 +300,8 @@ target | std | host | notes `bpfel-unknown-none` | * | | BPF (little endian) `csky-unknown-linux-gnuabiv2` | ✓ | | C-SKY abiv2 Linux (little endian) `csky-unknown-linux-gnuabiv2hf` | ✓ | | C-SKY abiv2 Linux, hardfloat (little endian) -[`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | | Bare Hexagon (v60+, HVX) [`hexagon-unknown-linux-musl`](platform-support/hexagon-unknown-linux-musl.md) | ✓ | | Hexagon Linux with musl 1.2.3 +[`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | | Bare Hexagon (v60+, HVX) [`i386-apple-ios`](platform-support/apple-ios.md) | ✓ | | 32-bit x86 iOS [^x86_32-floats-return-ABI] [`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS [^x86_32-floats-return-ABI] [`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ | | 32-bit x86, restricted to Pentium @@ -325,48 +325,56 @@ target | std | host | notes `mips64-unknown-linux-muslabi64` | ✓ | | MIPS64 Linux, N64 ABI, musl 1.2.3 `mips64el-unknown-linux-gnuabi64` | ✓ | ✓ | MIPS64 (little endian) Linux, N64 ABI (kernel 4.4, glibc 2.23) `mips64el-unknown-linux-muslabi64` | ✓ | | MIPS64 (little endian) Linux, N64 ABI, musl 1.2.3 -`mipsel-unknown-linux-gnu` | ✓ | ✓ | MIPS (little endian) Linux (kernel 4.4, glibc 2.23) -`mipsel-unknown-linux-musl` | ✓ | | MIPS (little endian) Linux with musl 1.2.3 -[`mipsel-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | 32-bit MIPS (LE), requires mips32 cpu support `mipsel-sony-psp` | * | | MIPS (LE) Sony PlayStation Portable (PSP) [`mipsel-sony-psx`](platform-support/mipsel-sony-psx.md) | * | | MIPS (LE) Sony PlayStation 1 (PSX) +`mipsel-unknown-linux-gnu` | ✓ | ✓ | MIPS (little endian) Linux (kernel 4.4, glibc 2.23) +`mipsel-unknown-linux-musl` | ✓ | | MIPS (little endian) Linux with musl 1.2.3 `mipsel-unknown-linux-uclibc` | ✓ | | MIPS (LE) Linux with uClibc +[`mipsel-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | 32-bit MIPS (LE), requires mips32 cpu support `mipsel-unknown-none` | * | | Bare MIPS (LE) softfloat [`mipsisa32r6-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Big Endian [`mipsisa32r6el-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Little Endian [`mipsisa64r6-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ? | | 64-bit MIPS Release 6 Big Endian [`mipsisa64r6el-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ✓ | ✓ | 64-bit MIPS Release 6 Little Endian `msp430-none-elf` | * | | 16-bit MSP430 microcontrollers +[`powerpc-unknown-freebsd`](platform-support/freebsd.md) | ? | | PowerPC FreeBSD `powerpc-unknown-linux-gnuspe` | ✓ | | PowerPC SPE Linux `powerpc-unknown-linux-musl` | ? | | PowerPC Linux with musl 1.2.3 [`powerpc-unknown-linux-muslspe`](platform-support/powerpc-unknown-linux-muslspe.md) | ? | | PowerPC SPE Linux [`powerpc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD 32-bit powerpc systems [`powerpc-unknown-openbsd`](platform-support/powerpc-unknown-openbsd.md) | * | | -[`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ✓ | | [`powerpc-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | -[`powerpc64-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64 FreeBSD (ELFv2) -[`powerpc64le-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64LE FreeBSD -[`powerpc-unknown-freebsd`](platform-support/freebsd.md) | ? | | PowerPC FreeBSD -`powerpc64-unknown-linux-musl` | ? | | 64-bit PowerPC Linux with musl 1.2.3 -[`powerpc64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | -[`powerpc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/powerpc64 +[`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ✓ | | [`powerpc64-ibm-aix`](platform-support/aix.md) | ? | | 64-bit AIX (7.2 and newer) +[`powerpc64-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64 FreeBSD (ELFv2) +`powerpc64-unknown-linux-musl` | ? | | 64-bit PowerPC Linux with musl 1.2.3 +[`powerpc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/powerpc64 +[`powerpc64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | +[`powerpc64le-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64LE FreeBSD +[`riscv32-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | +[`riscv32e-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32E ISA) +[`riscv32em-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EM ISA) +[`riscv32emc-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EMC ISA) `riscv32gc-unknown-linux-gnu` | ✓ | | RISC-V Linux (kernel 5.4, glibc 2.33) `riscv32gc-unknown-linux-musl` | ? | | RISC-V Linux (kernel 5.4, musl 1.2.3 + RISCV32 support patches) [`riscv32im-risc0-zkvm-elf`](platform-support/riscv32im-risc0-zkvm-elf.md) | ? | | RISC Zero's zero-knowledge Virtual Machine (RV32IM ISA) [`riscv32ima-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32IMA ISA) -[`riscv32imac-unknown-xous-elf`](platform-support/riscv32imac-unknown-xous-elf.md) | ? | | RISC-V Xous (RV32IMAC ISA) -[`riscv32imc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF [`riscv32imac-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF +[`riscv32imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX +[`riscv32imac-unknown-xous-elf`](platform-support/riscv32imac-unknown-xous-elf.md) | ? | | RISC-V Xous (RV32IMAC ISA) [`riscv32imafc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF -[`riscv32-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | -[`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit -`riscv64gc-unknown-freebsd` | ? | | RISC-V FreeBSD -`riscv64gc-unknown-fuchsia` | ? | | RISC-V Fuchsia -[`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD -[`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64 +[`riscv32imafc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX +[`riscv32imc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF +[`riscv32imc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX [`riscv64-linux-android`](platform-support/android.md) | ? | | RISC-V 64-bit Android [`riscv64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | +`riscv64gc-unknown-freebsd` | ? | | RISC-V FreeBSD +`riscv64gc-unknown-fuchsia` | ? | | RISC-V Fuchsia +[`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit +[`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD +[`riscv64gc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX +[`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64 +[`riscv64imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX [`s390x-unknown-linux-musl`](platform-support/s390x-unknown-linux-musl.md) | ✓ | | S390x Linux (kernel 3.2, musl 1.2.3) `sparc-unknown-linux-gnu` | ✓ | | 32-bit SPARC Linux [`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * | | Bare 32-bit SPARC V7+ @@ -374,9 +382,16 @@ target | std | host | notes [`sparc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/sparc64 [`thumbv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Thumb-mode Bare Armv4T [`thumbv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * | | Thumb-mode Bare Armv5TE +[`thumbv6m-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv6M with NuttX `thumbv7a-pc-windows-msvc` | ✓ | | `thumbv7a-uwp-windows-msvc` | ✓ | | +[`thumbv7em-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7EM with NuttX +[`thumbv7em-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv7EM with NuttX, hardfloat +[`thumbv7m-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7M with NuttX `thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode Armv7-A Linux with NEON, musl 1.2.3 +[`thumbv8m.base-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv8M Baseline with NuttX +[`thumbv8m.main-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv8M Mainline with NuttX +[`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv8M Mainline with NuttX, hardfloat [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator @@ -384,9 +399,10 @@ target | std | host | notes [`x86_64-unikraft-linux-musl`](platform-support/unikraft-linux-musl.md) | ✓ | | 64-bit Unikraft with musl 1.2.3 `x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku -[`x86_64-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 64-bit GNU/Hurd [`x86_64-unknown-hermit`](platform-support/hermit.md) | ✓ | | x86_64 Hermit +[`x86_64-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 64-bit GNU/Hurd `x86_64-unknown-l4re-uclibc` | ? | | +[`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * | | 64-bit Linux with no libc [`x86_64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 64-bit OpenBSD [`x86_64-unknown-trusty`](platform-support/trusty.md) | ? | | `x86_64-uwp-windows-gnu` | ✓ | | @@ -394,27 +410,11 @@ target | std | host | notes [`x86_64-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 64-bit Windows 7 support [`x86_64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [`x86_64h-apple-darwin`](platform-support/x86_64h-apple-darwin.md) | ✓ | ✓ | macOS with late-gen Intel (at least Haswell) -[`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * | | 64-bit Linux with no libc -[`xtensa-esp32-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32 [`xtensa-esp32-espidf`](platform-support/esp-idf.md) | ✓ | | Xtensa ESP32 -[`xtensa-esp32s2-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32-S2 +[`xtensa-esp32-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32 [`xtensa-esp32s2-espidf`](platform-support/esp-idf.md) | ✓ | | Xtensa ESP32-S2 -[`xtensa-esp32s3-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32-S3 +[`xtensa-esp32s2-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32-S2 [`xtensa-esp32s3-espidf`](platform-support/esp-idf.md) | ✓ | | Xtensa ESP32-S3 -[`thumbv6m-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv6M with NuttX -[`thumbv7m-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7M with NuttX -[`thumbv7em-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7EM with NuttX -[`thumbv7em-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv7EM with NuttX, hardfloat -[`thumbv8m.base-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv8M Baseline with NuttX -[`thumbv8m.main-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv8M Mainline with NuttX -[`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv8M Mainline with NuttX, hardfloat -[`riscv32imc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX -[`riscv32imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX -[`riscv32imafc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX -[`riscv64imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX -[`riscv64gc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX -[`riscv32e-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32E ISA) -[`riscv32em-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EM ISA) -[`riscv32emc-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EMC ISA) +[`xtensa-esp32s3-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32-S3 [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets diff --git a/src/doc/rustc/src/platform-support/android.md b/src/doc/rustc/src/platform-support/android.md index 96499b0d8014..54e7ddca32aa 100644 --- a/src/doc/rustc/src/platform-support/android.md +++ b/src/doc/rustc/src/platform-support/android.md @@ -65,4 +65,4 @@ Currently the `riscv64-linux-android` target requires the following architecture ### aarch64-linux-android on Nightly compilers As soon as `-Zfixed-x18` compiler flag is supplied, the [`ShadowCallStack` sanitizer](https://releases.llvm.org/7.0.1/tools/clang/docs/ShadowCallStack.html) -instrumentation is also made avaiable by supplying the second compiler flag `-Zsanitizer=shadow-call-stack`. +instrumentation is also made available by supplying the second compiler flag `-Zsanitizer=shadow-call-stack`. diff --git a/src/doc/rustc/src/platform-support/illumos.md b/src/doc/rustc/src/platform-support/illumos.md new file mode 100644 index 000000000000..dd2ae90f6741 --- /dev/null +++ b/src/doc/rustc/src/platform-support/illumos.md @@ -0,0 +1,42 @@ +# `aarch64-unknown-illumos` and `x86_64-unknown-illumos` + +**Tier: 2/3** + +[illumos](https://www.illumos.org/), is a Unix operating system which provides next-generation features for downstream distributions, +including advanced system debugging, next generation filesystem, networking, and virtualization options. + +## Target maintainers + +- Joshua M. Clulow ([@jclulow](https://github.com/jclulow)) +- Patrick Mooney ([@pfmooney](https://github.com/pfmooney)) + +## Requirements + +The target supports host tools. + +The illumos target supports `std` and uses the standard ELF file format. + +`x86_64-unknown-illumos` is a tier 2 target with host tools. +`aarch64-unknown-illumos` is a tier 3 target. + +## Building the target + +These targets can be built by adding `aarch64-unknown-illumos` and +`x86_64-unknown-illumos` as targets in the rustc list. + +## Building Rust programs + +Rust ships pre-compiled artifacts for the `x86_64-unknown-illumos` target. +Rust does not ship pre-compiled artifacts for `aarch64-unknown-illumos`, +it requires building the target either as shown above or using `-Zbuild-std`. + +## Testing + +Tests can be run in the same way as a regular binary. + +## Cross-compilation toolchains and C code + +The target supports C code. + +The illumos project makes available [prebuilt sysroot artefacts](https://github.com/illumos/sysroot) which can be used for cross compilation. +The official Rust binaries are cross-compiled using these artefacts. diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md index 1acc0584be91..b57083980d27 100644 --- a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md +++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md @@ -122,7 +122,7 @@ limactl shell riscv Using [Docker (with BuildKit)](https://docs.docker.com/build/buildkit/) the [`riscv64/ubuntu`](https://hub.docker.com/r/riscv64/ubuntu) image can be used -to buiild or run `riscv64gc-unknown-linux-gnu` binaries. +to build or run `riscv64gc-unknown-linux-gnu` binaries. ```bash docker run --platform linux/riscv64 -ti --rm --mount "type=bind,src=$(pwd),dst=/checkout" riscv64/ubuntu bash diff --git a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md index 5608b5cb7781..965d6aea9318 100644 --- a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md +++ b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md @@ -14,6 +14,11 @@ This target is cross compiled and can be built from any host. This target has no support for host tools, std, or alloc. +One of the primary motivations of the target is to write a dynamic linker and libc in Rust. +For that, the target defaults to position-independent code and position-independent executables (PIE) by default. +PIE binaries need relocation at runtime. This is usually done by the dynamic linker or libc. +You can use `-Crelocation-model=static` to create a position-dependent binary that does not need relocation at runtime. + ## Building the target The target can be built by enabling it for a `rustc` build: diff --git a/src/doc/rustc/src/targets/custom.md b/src/doc/rustc/src/targets/custom.md index a332d24c9f1f..6c1494186a4e 100644 --- a/src/doc/rustc/src/targets/custom.md +++ b/src/doc/rustc/src/targets/custom.md @@ -21,10 +21,10 @@ To use a custom target, see the (unstable) [`build-std` feature](../../cargo/ref When `rustc` is given an option `--target=TARGET` (where `TARGET` is any string), it uses the following logic: 1. if `TARGET` is the name of a built-in target, use that 2. if `TARGET` is a path to a file, read that file as a json target -3. otherwise, search the colon-seperated list of directories found +3. otherwise, search the colon-separated list of directories found in the `RUST_TARGET_PATH` environment variable from left to right for a file named `TARGET.json`. -These steps are tried in order, so if there are multple potentially valid +These steps are tried in order, so if there are multiple potentially valid interpretations for a target, whichever is found first will take priority. If none of these methods find a target, an error is thrown. diff --git a/src/doc/rustdoc/src/write-documentation/documentation-tests.md b/src/doc/rustdoc/src/write-documentation/documentation-tests.md index e02c26bd42bd..b921f6778575 100644 --- a/src/doc/rustdoc/src/write-documentation/documentation-tests.md +++ b/src/doc/rustdoc/src/write-documentation/documentation-tests.md @@ -412,7 +412,7 @@ In some cases, doctests cannot be merged. For example, if you have: ``` The problem with this code is that, if you change any other doctests, it'll likely break when -runing `rustdoc --test`, making it tricky to maintain. +running `rustdoc --test`, making it tricky to maintain. This is where the `standalone_crate` attribute comes in: it tells `rustdoc` that a doctest should not be merged with the others. So the previous code should use it: diff --git a/src/doc/unstable-book/src/language-features/rustc-private.md b/src/doc/unstable-book/src/language-features/rustc-private.md index 97fce5980e40..3b83a3cf4df8 100644 --- a/src/doc/unstable-book/src/language-features/rustc-private.md +++ b/src/doc/unstable-book/src/language-features/rustc-private.md @@ -6,6 +6,9 @@ The tracking issue for this feature is: [#27812] ------------------------ -This feature allows access to unstable internal compiler crates. +This feature allows access to unstable internal compiler crates such as `rustc_driver`. -Additionally it changes the linking behavior of crates which have this feature enabled. It will prevent linking to a dylib if there's a static variant of it already statically linked into another dylib dependency. This is required to successfully link to `rustc_driver`. +The presence of this feature changes the way the linkage format for dylibs is calculated in a way +that is necessary for linking against dylibs that statically link `std` (such as `rustc_driver`). +This makes this feature "viral" in linkage; its use in a given crate makes its use required in +dependent crates which link to it (including integration tests, which are built as separate crates). diff --git a/src/etc/completions/x.fish b/src/etc/completions/x.fish index f0927183c071..49fe10a4ea22 100644 --- a/src/etc/completions/x.fish +++ b/src/etc/completions/x.fish @@ -319,6 +319,7 @@ complete -c x -n "__fish_x_using_subcommand test" -l bless -d 'whether to automa complete -c x -n "__fish_x_using_subcommand test" -l force-rerun -d 'rerun tests even if the inputs are unchanged' complete -c x -n "__fish_x_using_subcommand test" -l only-modified -d 'only run tests that result has been changed' complete -c x -n "__fish_x_using_subcommand test" -l rustfix-coverage -d 'enable this to generate a Rustfix coverage file, which is saved in `//rustfix_missing_coverage.txt`' +complete -c x -n "__fish_x_using_subcommand test" -l no-capture -d 'don\'t capture stdout/stderr of tests' complete -c x -n "__fish_x_using_subcommand test" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand test" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand test" -l include-default-paths -d 'include default paths in addition to the provided ones' diff --git a/src/etc/completions/x.ps1 b/src/etc/completions/x.ps1 index 7cbf0f0d13ce..fa833b6876ac 100644 --- a/src/etc/completions/x.ps1 +++ b/src/etc/completions/x.ps1 @@ -366,6 +366,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--force-rerun', '--force-rerun', [CompletionResultType]::ParameterName, 'rerun tests even if the inputs are unchanged') [CompletionResult]::new('--only-modified', '--only-modified', [CompletionResultType]::ParameterName, 'only run tests that result has been changed') [CompletionResult]::new('--rustfix-coverage', '--rustfix-coverage', [CompletionResultType]::ParameterName, 'enable this to generate a Rustfix coverage file, which is saved in `//rustfix_missing_coverage.txt`') + [CompletionResult]::new('--no-capture', '--no-capture', [CompletionResultType]::ParameterName, 'don''t capture stdout/stderr of tests') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index df31b0d644e7..07144ad22d1a 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -319,6 +319,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand test" -l bless -d 'whether to complete -c x.py -n "__fish_x.py_using_subcommand test" -l force-rerun -d 'rerun tests even if the inputs are unchanged' complete -c x.py -n "__fish_x.py_using_subcommand test" -l only-modified -d 'only run tests that result has been changed' complete -c x.py -n "__fish_x.py_using_subcommand test" -l rustfix-coverage -d 'enable this to generate a Rustfix coverage file, which is saved in `//rustfix_missing_coverage.txt`' +complete -c x.py -n "__fish_x.py_using_subcommand test" -l no-capture -d 'don\'t capture stdout/stderr of tests' complete -c x.py -n "__fish_x.py_using_subcommand test" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand test" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand test" -l include-default-paths -d 'include default paths in addition to the provided ones' diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index afbfb055abdb..7d5bd3c9632b 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -366,6 +366,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--force-rerun', '--force-rerun', [CompletionResultType]::ParameterName, 'rerun tests even if the inputs are unchanged') [CompletionResult]::new('--only-modified', '--only-modified', [CompletionResultType]::ParameterName, 'only run tests that result has been changed') [CompletionResult]::new('--rustfix-coverage', '--rustfix-coverage', [CompletionResultType]::ParameterName, 'enable this to generate a Rustfix coverage file, which is saved in `//rustfix_missing_coverage.txt`') + [CompletionResult]::new('--no-capture', '--no-capture', [CompletionResultType]::ParameterName, 'don''t capture stdout/stderr of tests') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh index ba7f2c9fb5d6..5c5e4ef0c158 100644 --- a/src/etc/completions/x.py.sh +++ b/src/etc/completions/x.py.sh @@ -3119,7 +3119,7 @@ _x.py() { return 0 ;; x.py__test) - opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh index 415fe09718c2..dd71ec00edfa 100644 --- a/src/etc/completions/x.py.zsh +++ b/src/etc/completions/x.py.zsh @@ -365,6 +365,7 @@ _arguments "${_arguments_options[@]}" : \ '--force-rerun[rerun tests even if the inputs are unchanged]' \ '--only-modified[only run tests that result has been changed]' \ '--rustfix-coverage[enable this to generate a Rustfix coverage file, which is saved in \`//rustfix_missing_coverage.txt\`]' \ +'--no-capture[don'\''t capture stdout/stderr of tests]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ diff --git a/src/etc/completions/x.sh b/src/etc/completions/x.sh index a4cf80acc30f..057af1ffc6d5 100644 --- a/src/etc/completions/x.sh +++ b/src/etc/completions/x.sh @@ -3119,7 +3119,7 @@ _x() { return 0 ;; x__test) - opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/src/etc/completions/x.zsh b/src/etc/completions/x.zsh index ee6f504f93e2..6215f9af8330 100644 --- a/src/etc/completions/x.zsh +++ b/src/etc/completions/x.zsh @@ -365,6 +365,7 @@ _arguments "${_arguments_options[@]}" : \ '--force-rerun[rerun tests even if the inputs are unchanged]' \ '--only-modified[only run tests that result has been changed]' \ '--rustfix-coverage[enable this to generate a Rustfix coverage file, which is saved in \`//rustfix_missing_coverage.txt\`]' \ +'--no-capture[don'\''t capture stdout/stderr of tests]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ diff --git a/src/etc/test-float-parse/README.md b/src/etc/test-float-parse/README.md index 21b20d0a072d..5e2c43d1cad6 100644 --- a/src/etc/test-float-parse/README.md +++ b/src/etc/test-float-parse/README.md @@ -3,7 +3,7 @@ These are tests designed to test decimal to float conversions (`dec2flt`) used by the standard library. -It consistes of a collection of test generators that each generate a set of +It consists of a collection of test generators that each generate a set of patterns intended to test a specific property. In addition, there are exhaustive tests (for <= `f32`) and fuzzers (for anything that can't be run exhaustively). diff --git a/src/etc/test-float-parse/src/lib.rs b/src/etc/test-float-parse/src/lib.rs index 71b1aa066710..3c71b0dc32e7 100644 --- a/src/etc/test-float-parse/src/lib.rs +++ b/src/etc/test-float-parse/src/lib.rs @@ -35,7 +35,7 @@ const DEFAULT_MAX_FAILURES: u64 = 20; /// Register exhaustive tests only for <= 32 bits. No more because it would take years. const MAX_BITS_FOR_EXHAUUSTIVE: u32 = 32; -/// If there are more tests than this threashold, the test will be defered until after all +/// If there are more tests than this threshold, the test will be deferred until after all /// others run (so as to avoid thread pool starvation). They also can be excluded with /// `--skip-huge`. const HUGE_TEST_CUTOFF: u64 = 5_000_000; @@ -109,7 +109,7 @@ pub fn run(cfg: Config, include: &[String], exclude: &[String]) -> ExitCode { ui::finish(&tests, elapsed, &cfg) } -/// Enumerate tests to run but don't actaully run them. +/// Enumerate tests to run but don't actually run them. pub fn register_tests(cfg: &Config) -> Vec { let mut tests = Vec::new(); @@ -120,7 +120,7 @@ pub fn register_tests(cfg: &Config) -> Vec { tests.sort_unstable_by_key(|t| (t.float_name, t.gen_name)); for i in 0..(tests.len() - 1) { if tests[i].gen_name == tests[i + 1].gen_name { - panic!("dupliate test name {}", tests[i].gen_name); + panic!("duplicate test name {}", tests[i].gen_name); } } @@ -295,7 +295,7 @@ enum Update { fail: CheckFailure, /// String for which parsing was attempted. input: Box, - /// The parsed & decomposed `FloatRes`, aleady stringified so we don't need generics here. + /// The parsed & decomposed `FloatRes`, already stringified so we don't need generics here. float_res: Box, }, /// Exited with an unexpected condition. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4d46f0e75c84..3c9e0914b59d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -268,7 +268,7 @@ fn clean_poly_trait_ref_with_constraints<'tcx>( ) } -fn clean_lifetime(lifetime: &hir::Lifetime, cx: &mut DocContext<'_>) -> Lifetime { +fn clean_lifetime(lifetime: &hir::Lifetime, cx: &DocContext<'_>) -> Lifetime { if let Some( rbv::ResolvedArg::EarlyBound(did) | rbv::ResolvedArg::LateBound(_, _, did) @@ -362,9 +362,9 @@ pub(crate) fn clean_predicate<'tcx>( let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { ty::ClauseKind::Trait(pred) => clean_poly_trait_predicate(bound_predicate.rebind(pred), cx), - ty::ClauseKind::RegionOutlives(pred) => clean_region_outlives_predicate(pred), + ty::ClauseKind::RegionOutlives(pred) => Some(clean_region_outlives_predicate(pred)), ty::ClauseKind::TypeOutlives(pred) => { - clean_type_outlives_predicate(bound_predicate.rebind(pred), cx) + Some(clean_type_outlives_predicate(bound_predicate.rebind(pred), cx)) } ty::ClauseKind::Projection(pred) => { Some(clean_projection_predicate(bound_predicate.rebind(pred), cx)) @@ -396,32 +396,30 @@ fn clean_poly_trait_predicate<'tcx>( }) } -fn clean_region_outlives_predicate( - pred: ty::RegionOutlivesPredicate<'_>, -) -> Option { +fn clean_region_outlives_predicate(pred: ty::RegionOutlivesPredicate<'_>) -> WherePredicate { let ty::OutlivesPredicate(a, b) = pred; - Some(WherePredicate::RegionPredicate { + WherePredicate::RegionPredicate { lifetime: clean_middle_region(a).expect("failed to clean lifetime"), bounds: vec![GenericBound::Outlives( clean_middle_region(b).expect("failed to clean bounds"), )], - }) + } } fn clean_type_outlives_predicate<'tcx>( pred: ty::Binder<'tcx, ty::TypeOutlivesPredicate<'tcx>>, cx: &mut DocContext<'tcx>, -) -> Option { +) -> WherePredicate { let ty::OutlivesPredicate(ty, lt) = pred.skip_binder(); - Some(WherePredicate::BoundPredicate { + WherePredicate::BoundPredicate { ty: clean_middle_ty(pred.rebind(ty), cx, None, None), bounds: vec![GenericBound::Outlives( clean_middle_region(lt).expect("failed to clean lifetimes"), )], bound_params: Vec::new(), - }) + } } fn clean_middle_term<'tcx>( @@ -894,7 +892,7 @@ fn clean_ty_generics<'tcx>( // Add back a `Sized` bound if there are no *trait* bounds remaining (incl. `?Sized`). // Since all potential trait bounds are at the front we can just check the first bound. - if bounds.first().map_or(true, |b| !b.is_trait_bound()) { + if bounds.first().is_none_or(|b| !b.is_trait_bound()) { bounds.insert(0, GenericBound::sized(cx)); } @@ -1811,7 +1809,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T } TyKind::Slice(ty) => Slice(Box::new(clean_ty(ty, cx))), TyKind::Pat(ty, pat) => Type::Pat(Box::new(clean_ty(ty, cx)), format!("{pat:?}").into()), - TyKind::Array(ty, ref const_arg) => { + TyKind::Array(ty, const_arg) => { // NOTE(min_const_generics): We can't use `const_eval_poly` for constants // as we currently do not supply the parent generics to anonymous constants // but do allow `ConstKind::Param`. @@ -1860,7 +1858,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T /// Returns `None` if the type could not be normalized fn normalize<'tcx>( - cx: &mut DocContext<'tcx>, + cx: &DocContext<'tcx>, ty: ty::Binder<'tcx, Ty<'tcx>>, ) -> Option>> { // HACK: low-churn fix for #79459 while we wait for a trait normalization fix @@ -2337,7 +2335,7 @@ fn clean_middle_opaque_bounds<'tcx>( // Add back a `Sized` bound if there are no *trait* bounds remaining (incl. `?Sized`). // Since all potential trait bounds are at the front we can just check the first bound. - if bounds.first().map_or(true, |b| !b.is_trait_bound()) { + if bounds.first().is_none_or(|b| !b.is_trait_bound()) { bounds.insert(0, GenericBound::sized(cx)); } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index e6e5123d0bba..009e9662933a 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -220,7 +220,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions } = interface::run_compiler(config, |compiler| { let krate = rustc_interface::passes::parse(&compiler.sess); - let collector = rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { + let collector = rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { let crate_name = tcx.crate_name(LOCAL_CRATE).to_string(); let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID); let opts = scrape_test_config(crate_name, crate_attrs, args_path); diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index a188bc8ebd91..7bcb9465948d 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -538,7 +538,7 @@ fn handle_attr(mod_attr_pending: &mut String, source_info: &mut SourceInfo, edit // If it's complete, then we can clear the pending content. mod_attr_pending.clear(); } else { - mod_attr_pending.push_str("\n"); + mod_attr_pending.push('\n'); } } diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index b63122565c42..e64baca974da 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -305,6 +305,7 @@ impl DocFolder for CacheBuilder<'_, '_> { | clean::MacroItem(..) | clean::ProcMacroItem(..) | clean::VariantItem(..) => { + use rustc_data_structures::fx::IndexEntry as Entry; if !self.cache.stripped_mod { // Re-exported items mean that the same id can show up twice // in the rustdoc ast that we're looking at. We know, @@ -313,15 +314,15 @@ impl DocFolder for CacheBuilder<'_, '_> { // paths map if there was already an entry present and we're // not a public item. let item_def_id = item.item_id.expect_def_id(); - if !self.cache.paths.contains_key(&item_def_id) - || self - .cache - .effective_visibilities - .is_directly_public(self.tcx, item_def_id) - { - self.cache - .paths - .insert(item_def_id, (self.cache.stack.clone(), item.type_())); + match self.cache.paths.entry(item_def_id) { + Entry::Vacant(entry) => { + entry.insert((self.cache.stack.clone(), item.type_())); + } + Entry::Occupied(mut entry) => { + if entry.get().0.len() > self.cache.stack.len() { + entry.insert((self.cache.stack.clone(), item.type_())); + } + } } } } @@ -413,7 +414,7 @@ impl DocFolder for CacheBuilder<'_, '_> { let impl_item = Impl { impl_item: item }; let impl_did = impl_item.def_id(); let trait_did = impl_item.trait_did(); - if trait_did.map_or(true, |d| self.cache.traits.contains_key(&d)) { + if trait_did.is_none_or(|d| self.cache.traits.contains_key(&d)) { for did in dids { if self.impl_ids.entry(did).or_default().insert(impl_did) { self.cache.impls.entry(did).or_default().push(impl_item.clone()); diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs index 48771571f8ff..88654ed32da9 100644 --- a/src/librustdoc/html/escape.rs +++ b/src/librustdoc/html/escape.rs @@ -104,10 +104,9 @@ impl fmt::Display for EscapeBodyTextWithWbr<'_> { continue; } let is_uppercase = || s.chars().any(|c| c.is_uppercase()); - let next_is_uppercase = - || pk.map_or(true, |(_, t)| t.chars().any(|c| c.is_uppercase())); - let next_is_underscore = || pk.map_or(true, |(_, t)| t.contains('_')); - let next_is_colon = || pk.map_or(true, |(_, t)| t.contains(':')); + let next_is_uppercase = || pk.is_none_or(|(_, t)| t.chars().any(|c| c.is_uppercase())); + let next_is_underscore = || pk.is_none_or(|(_, t)| t.contains('_')); + let next_is_colon = || pk.is_none_or(|(_, t)| t.contains(':')); // Check for CamelCase. // // `i - last > 3` avoids turning FmRadio into FmRadio, which is technically diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index aa8fdaaee4cb..7e835585b73e 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -480,7 +480,7 @@ impl<'a, I: Iterator>> Iterator for SpannedLinkReplacer< type Item = SpannedEvent<'a>; fn next(&mut self) -> Option { - let Some((mut event, range)) = self.iter.next() else { return None }; + let (mut event, range) = self.iter.next()?; self.inner.handle_event(&mut event); // Yield the modified event Some((event, range)) @@ -2039,7 +2039,7 @@ impl IdMap { let candidate = candidate.to_string(); if is_default_id(&candidate) { let id = format!("{}-{}", candidate, 1); - self.map.insert(candidate.into(), 2); + self.map.insert(candidate, 2); id } else { candidate @@ -2052,7 +2052,7 @@ impl IdMap { } }; - self.map.insert(id.clone().into(), 1); + self.map.insert(id.clone(), 1); id } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 2d5df75e7dc1..5d96dbc0ee65 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -748,7 +748,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { &shared.layout, &page, "", - scrape_examples_help(&shared), + scrape_examples_help(shared), &shared.style_files, ); shared.fs.write(scrape_examples_help_file, v)?; diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index dfdf2cd6ec32..9a9ce31caaa4 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1974,7 +1974,7 @@ fn render_impl( .opt_doc_value() .map(|dox| { Markdown { - content: &*dox, + content: &dox, links: &i.impl_item.links(cx), ids: &mut cx.id_map.borrow_mut(), error_codes: cx.shared.codes, diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 0fb77d38f165..e8230e63c0f6 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1420,7 +1420,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni ty: &'a clean::Type, ) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { display_fn(move |f| { - let v = ty.print(&self.cx); + let v = ty.print(self.cx); write!(f, "{v}") }) } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 583d0214a468..7f072aa7e2fc 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -312,15 +312,15 @@ fn from_clean_item(item: clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum { StructFieldItem(f) => ItemEnum::StructField(f.into_json(renderer)), EnumItem(e) => ItemEnum::Enum(e.into_json(renderer)), VariantItem(v) => ItemEnum::Variant(v.into_json(renderer)), - FunctionItem(f) => ItemEnum::Function(from_function(f, true, header.unwrap(), renderer)), + FunctionItem(f) => ItemEnum::Function(from_function(*f, true, header.unwrap(), renderer)), ForeignFunctionItem(f, _) => { - ItemEnum::Function(from_function(f, false, header.unwrap(), renderer)) + ItemEnum::Function(from_function(*f, false, header.unwrap(), renderer)) } TraitItem(t) => ItemEnum::Trait((*t).into_json(renderer)), TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_json(renderer)), - MethodItem(m, _) => ItemEnum::Function(from_function(m, true, header.unwrap(), renderer)), + MethodItem(m, _) => ItemEnum::Function(from_function(*m, true, header.unwrap(), renderer)), RequiredMethodItem(m) => { - ItemEnum::Function(from_function(m, false, header.unwrap(), renderer)) + ItemEnum::Function(from_function(*m, false, header.unwrap(), renderer)) } ImplItem(i) => ItemEnum::Impl((*i).into_json(renderer)), StaticItem(s) => ItemEnum::Static(convert_static(s, rustc_hir::Safety::Safe, renderer)), @@ -730,12 +730,11 @@ impl FromClean for Impl { } pub(crate) fn from_function( - function: Box, + clean::Function { decl, generics }: clean::Function, has_body: bool, header: rustc_hir::FnHeader, renderer: &JsonRenderer<'_>, ) -> Function { - let clean::Function { decl, generics } = *function; Function { sig: decl.into_json(renderer), generics: generics.into_json(renderer), diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index ff1c9c61720f..d74dcc98cb05 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -869,7 +869,7 @@ fn main_args( sess.dcx().fatal("Compilation failed, aborting rustdoc"); } - rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { + rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || { core::run_global_ctxt(tcx, show_coverage, render_options, output_format) }); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 3c1d0c35befa..a777b45b8070 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1977,7 +1977,7 @@ fn resolution_failure( } if !path_str.contains("::") { - if disambiguator.map_or(true, |d| d.ns() == MacroNS) + if disambiguator.is_none_or(|d| d.ns() == MacroNS) && collector .cx .tcx diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index 5638d4718902..01068af3e8c2 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -160,10 +160,10 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "needs-xray", "no-auto-check-cfg", "no-prefer-dynamic", + "normalize-stderr", "normalize-stderr-32bit", "normalize-stderr-64bit", - "normalize-stderr-test", - "normalize-stdout-test", + "normalize-stdout", "only-16bit", "only-32bit", "only-64bit", diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 91558d0c898b..48149e3b897e 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -12,7 +12,6 @@ use tracing::*; use crate::common::{Config, Debugger, FailMode, Mode, PassMode}; use crate::debuggers::{extract_cdb_version, extract_gdb_version}; use crate::header::auxiliary::{AuxProps, parse_and_update_aux}; -use crate::header::cfg::{MatchOutcome, parse_cfg_name_directive}; use crate::header::needs::CachedNeedsConditions; use crate::util::static_regex; @@ -472,11 +471,24 @@ impl TestProps { config.set_name_directive(ln, IGNORE_PASS, &mut self.ignore_pass); - if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stdout") { - self.normalize_stdout.push(rule); - } - if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stderr") { - self.normalize_stderr.push(rule); + if let Some(NormalizeRule { kind, regex, replacement }) = + config.parse_custom_normalization(ln) + { + let rule_tuple = (regex, replacement); + match kind { + NormalizeKind::Stdout => self.normalize_stdout.push(rule_tuple), + NormalizeKind::Stderr => self.normalize_stderr.push(rule_tuple), + NormalizeKind::Stderr32bit => { + if config.target_cfg().pointer_width == 32 { + self.normalize_stderr.push(rule_tuple); + } + } + NormalizeKind::Stderr64bit => { + if config.target_cfg().pointer_width == 64 { + self.normalize_stderr.push(rule_tuple); + } + } + } } if let Some(code) = config @@ -966,20 +978,26 @@ impl Config { } } - fn parse_custom_normalization(&self, line: &str, prefix: &str) -> Option<(String, String)> { - let parsed = parse_cfg_name_directive(self, line, prefix); - if parsed.outcome != MatchOutcome::Match { - return None; - } - let name = parsed.name.expect("successful match always has a name"); + fn parse_custom_normalization(&self, raw_directive: &str) -> Option { + // FIXME(Zalathar): Integrate name/value splitting into `DirectiveLine` + // instead of doing it here. + let (directive_name, raw_value) = raw_directive.split_once(':')?; - let Some((regex, replacement)) = parse_normalize_rule(line) else { + let kind = match directive_name { + "normalize-stdout" => NormalizeKind::Stdout, + "normalize-stderr" => NormalizeKind::Stderr, + "normalize-stderr-32bit" => NormalizeKind::Stderr32bit, + "normalize-stderr-64bit" => NormalizeKind::Stderr64bit, + _ => return None, + }; + + let Some((regex, replacement)) = parse_normalize_rule(raw_value) else { panic!( - "couldn't parse custom normalization rule: `{line}`\n\ - help: expected syntax is: `{prefix}-{name}: \"REGEX\" -> \"REPLACEMENT\"`" + "couldn't parse custom normalization rule: `{raw_directive}`\n\ + help: expected syntax is: `{directive_name}: \"REGEX\" -> \"REPLACEMENT\"`" ); }; - Some((regex, replacement)) + Some(NormalizeRule { kind, regex, replacement }) } fn parse_name_directive(&self, line: &str, directive: &str) -> bool { @@ -1105,27 +1123,42 @@ fn expand_variables(mut value: String, config: &Config) -> String { value } +struct NormalizeRule { + kind: NormalizeKind, + regex: String, + replacement: String, +} + +enum NormalizeKind { + Stdout, + Stderr, + Stderr32bit, + Stderr64bit, +} + /// Parses the regex and replacement values of a `//@ normalize-*` header, /// in the format: /// ```text -/// normalize-*: "REGEX" -> "REPLACEMENT" +/// "REGEX" -> "REPLACEMENT" /// ``` -fn parse_normalize_rule(header: &str) -> Option<(String, String)> { +fn parse_normalize_rule(raw_value: &str) -> Option<(String, String)> { // FIXME: Support escaped double-quotes in strings. let captures = static_regex!( r#"(?x) # (verbose mode regex) ^ - [^:\s]+:\s* # (header name followed by colon) + \s* # (leading whitespace) "(?[^"]*)" # "REGEX" \s+->\s+ # -> "(?[^"]*)" # "REPLACEMENT" $ "# ) - .captures(header)?; + .captures(raw_value)?; let regex = captures["regex"].to_owned(); let replacement = captures["replacement"].to_owned(); - // FIXME: Support escaped new-line in strings. + // A `\n` sequence in the replacement becomes an actual newline. + // FIXME: Do unescaping in a less ad-hoc way, and perhaps support escaped + // backslashes and double-quotes. let replacement = replacement.replace("\\n", "\n"); Some((regex, replacement)) } diff --git a/src/tools/compiletest/src/header/cfg.rs b/src/tools/compiletest/src/header/cfg.rs index 3ab552903dc6..3f7225195ce0 100644 --- a/src/tools/compiletest/src/header/cfg.rs +++ b/src/tools/compiletest/src/header/cfg.rs @@ -40,8 +40,8 @@ pub(super) fn handle_only(config: &Config, line: &str) -> IgnoreDecision { } /// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86` -/// or `normalize-stderr-32bit`. -pub(super) fn parse_cfg_name_directive<'a>( +/// or `only-windows`. +fn parse_cfg_name_directive<'a>( config: &Config, line: &'a str, prefix: &str, diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index cd7c6f8361ed..618b66dfd4cb 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -35,11 +35,14 @@ fn make_test_description( #[test] fn test_parse_normalize_rule() { - let good_data = &[( - r#"normalize-stderr-32bit: "something (32 bits)" -> "something ($WORD bits)""#, - "something (32 bits)", - "something ($WORD bits)", - )]; + let good_data = &[ + ( + r#""something (32 bits)" -> "something ($WORD bits)""#, + "something (32 bits)", + "something ($WORD bits)", + ), + (r#" " with whitespace" -> " replacement""#, " with whitespace", " replacement"), + ]; for &(input, expected_regex, expected_replacement) in good_data { let parsed = parse_normalize_rule(input); @@ -49,15 +52,15 @@ fn test_parse_normalize_rule() { } let bad_data = &[ - r#"normalize-stderr-32bit "something (32 bits)" -> "something ($WORD bits)""#, - r#"normalize-stderr-16bit: something (16 bits) -> something ($WORD bits)"#, - r#"normalize-stderr-32bit: something (32 bits) -> something ($WORD bits)"#, - r#"normalize-stderr-32bit: "something (32 bits) -> something ($WORD bits)"#, - r#"normalize-stderr-32bit: "something (32 bits)" -> "something ($WORD bits)"#, - r#"normalize-stderr-32bit: "something (32 bits)" -> "something ($WORD bits)"."#, + r#"something (11 bits) -> something ($WORD bits)"#, + r#"something (12 bits) -> something ($WORD bits)"#, + r#""something (13 bits) -> something ($WORD bits)"#, + r#""something (14 bits)" -> "something ($WORD bits)"#, + r#""something (15 bits)" -> "something ($WORD bits)"."#, ]; for &input in bad_data { + println!("- {input:?}"); let parsed = parse_normalize_rule(input); assert_eq!(parsed, None); } diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 250ef0794add..74d1f5637a8f 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -159,7 +159,9 @@ pub fn parse_config(args: Vec) -> Config { ) .optflag("", "force-rerun", "rerun tests even if the inputs are unchanged") .optflag("", "only-modified", "only run tests that result been modified") + // FIXME: Temporarily retained so we can point users to `--no-capture` .optflag("", "nocapture", "") + .optflag("", "no-capture", "don't capture stdout/stderr of tests") .optflag("", "profiler-runtime", "is the profiler runtime enabled for this target") .optflag("h", "help", "show this message") .reqopt("", "channel", "current Rust channel", "CHANNEL") @@ -288,6 +290,10 @@ pub fn parse_config(args: Vec) -> Config { ); }) }); + if matches.opt_present("nocapture") { + panic!("`--nocapture` is deprecated; please use `--no-capture`"); + } + Config { bless: matches.opt_present("bless"), compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")), @@ -385,7 +391,7 @@ pub fn parse_config(args: Vec) -> Config { target_cfgs: OnceLock::new(), builtin_cfg_names: OnceLock::new(), - nocapture: matches.opt_present("nocapture"), + nocapture: matches.opt_present("no-capture"), git_repository: matches.opt_str("git-repository").unwrap(), nightly_branch: matches.opt_str("nightly-branch").unwrap(), diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 108fde1c8995..7084c407a642 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -213,7 +213,7 @@ fn remove_and_create_dir_all(path: &Path) { fs::create_dir_all(path).unwrap(); } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] struct TestCx<'test> { config: &'test Config, props: &'test TestProps, @@ -2318,32 +2318,47 @@ impl<'test> TestCx<'test> { match output_kind { TestOutput::Compile => { if !self.props.dont_check_compiler_stdout { - errors += self.compare_output( + if self + .compare_output( + stdout_kind, + &normalized_stdout, + &proc_res.stdout, + &expected_stdout, + ) + .should_error() + { + errors += 1; + } + } + if !self.props.dont_check_compiler_stderr { + if self + .compare_output(stderr_kind, &normalized_stderr, &stderr, &expected_stderr) + .should_error() + { + errors += 1; + } + } + } + TestOutput::Run => { + if self + .compare_output( stdout_kind, &normalized_stdout, &proc_res.stdout, &expected_stdout, - ); + ) + .should_error() + { + errors += 1; } - if !self.props.dont_check_compiler_stderr { - errors += self.compare_output( - stderr_kind, - &normalized_stderr, - &stderr, - &expected_stderr, - ); + + if self + .compare_output(stderr_kind, &normalized_stderr, &stderr, &expected_stderr) + .should_error() + { + errors += 1; } } - TestOutput::Run => { - errors += self.compare_output( - stdout_kind, - &normalized_stdout, - &proc_res.stdout, - &expected_stdout, - ); - errors += - self.compare_output(stderr_kind, &normalized_stderr, &stderr, &expected_stderr); - } } errors } @@ -2576,7 +2591,14 @@ impl<'test> TestCx<'test> { actual: &str, actual_unnormalized: &str, expected: &str, - ) -> usize { + ) -> CompareOutcome { + let expected_path = + expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream); + + if self.config.bless && actual.is_empty() && expected_path.exists() { + self.delete_file(&expected_path); + } + let are_different = match (self.force_color_svg(), expected.find('\n'), actual.find('\n')) { // FIXME: We ignore the first line of SVG files // because the width parameter is non-deterministic. @@ -2584,7 +2606,7 @@ impl<'test> TestCx<'test> { _ => expected != actual, }; if !are_different { - return 0; + return CompareOutcome::Same; } // Wrapper tools set by `runner` might provide extra output on failure, @@ -2600,7 +2622,7 @@ impl<'test> TestCx<'test> { used.retain(|line| actual_lines.contains(line)); // check if `expected` contains a subset of the lines of `actual` if used.len() == expected_lines.len() && (expected.is_empty() == actual.is_empty()) { - return 0; + return CompareOutcome::Same; } if expected_lines.is_empty() { // if we have no lines to check, force a full overwite @@ -2626,9 +2648,6 @@ impl<'test> TestCx<'test> { } println!("Saved the actual {stream} to {actual_path:?}"); - let expected_path = - expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream); - if !self.config.bless { if expected.is_empty() { println!("normalized {}:\n{}\n", stream, actual); @@ -2651,15 +2670,17 @@ impl<'test> TestCx<'test> { self.delete_file(&old); } - if let Err(err) = fs::write(&expected_path, &actual) { - self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}")); + if !actual.is_empty() { + if let Err(err) = fs::write(&expected_path, &actual) { + self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}")); + } + println!("Blessing the {stream} of {test_name} in {expected_path:?}"); } - println!("Blessing the {stream} of {test_name} in {expected_path:?}"); } println!("\nThe actual {0} differed from the expected {0}.", stream); - if self.config.bless { 0 } else { 1 } + if self.config.bless { CompareOutcome::Blessed } else { CompareOutcome::Differed } } /// Returns whether to show the full stderr/stdout. @@ -2885,3 +2906,21 @@ enum AuxType { Dylib, ProcMacro, } + +/// Outcome of comparing a stream to a blessed file, +/// e.g. `.stderr` and `.fixed`. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +enum CompareOutcome { + /// Expected and actual outputs are the same + Same, + /// Outputs differed but were blessed + Blessed, + /// Outputs differed and an error should be emitted + Differed, +} + +impl CompareOutcome { + fn should_error(&self) -> bool { + matches!(self, CompareOutcome::Differed) + } +} diff --git a/src/tools/compiletest/src/runtest/coverage.rs b/src/tools/compiletest/src/runtest/coverage.rs index 030ca5ebb247..56fc5baf5f24 100644 --- a/src/tools/compiletest/src/runtest/coverage.rs +++ b/src/tools/compiletest/src/runtest/coverage.rs @@ -39,16 +39,16 @@ impl<'test> TestCx<'test> { let expected_coverage_dump = self.load_expected_output(kind); let actual_coverage_dump = self.normalize_output(&proc_res.stdout, &[]); - let coverage_dump_errors = self.compare_output( + let coverage_dump_compare_outcome = self.compare_output( kind, &actual_coverage_dump, &proc_res.stdout, &expected_coverage_dump, ); - if coverage_dump_errors > 0 { + if coverage_dump_compare_outcome.should_error() { self.fatal_proc_rec( - &format!("{coverage_dump_errors} errors occurred comparing coverage output."), + &format!("an error occurred comparing coverage output."), &proc_res, ); } @@ -139,16 +139,16 @@ impl<'test> TestCx<'test> { self.fatal_proc_rec(&err, &proc_res); }); - let coverage_errors = self.compare_output( + let coverage_dump_compare_outcome = self.compare_output( kind, &normalized_actual_coverage, &proc_res.stdout, &expected_coverage, ); - if coverage_errors > 0 { + if coverage_dump_compare_outcome.should_error() { self.fatal_proc_rec( - &format!("{} errors occurred comparing coverage output.", coverage_errors), + &format!("an error occurred comparing coverage output."), &proc_res, ); } diff --git a/src/tools/compiletest/src/runtest/debugger.rs b/src/tools/compiletest/src/runtest/debugger.rs index c15422fb6f68..d9e5c3fa0d8f 100644 --- a/src/tools/compiletest/src/runtest/debugger.rs +++ b/src/tools/compiletest/src/runtest/debugger.rs @@ -19,15 +19,9 @@ pub(super) struct DebuggerCommands { } impl DebuggerCommands { - pub fn parse_from( - file: &Path, - config: &Config, - debugger_prefixes: &[&str], - ) -> Result { - let directives = debugger_prefixes - .iter() - .map(|prefix| (format!("{prefix}-command"), format!("{prefix}-check"))) - .collect::>(); + pub fn parse_from(file: &Path, config: &Config, debugger_prefix: &str) -> Result { + let command_directive = format!("{debugger_prefix}-command"); + let check_directive = format!("{debugger_prefix}-check"); let mut breakpoint_lines = vec![]; let mut commands = vec![]; @@ -48,14 +42,11 @@ impl DebuggerCommands { continue; }; - for &(ref command_directive, ref check_directive) in &directives { - config - .parse_name_value_directive(&line, command_directive) - .map(|cmd| commands.push(cmd)); - - config - .parse_name_value_directive(&line, check_directive) - .map(|cmd| check_lines.push((line_no, cmd))); + if let Some(command) = config.parse_name_value_directive(&line, &command_directive) { + commands.push(command); + } + if let Some(pattern) = config.parse_name_value_directive(&line, &check_directive) { + check_lines.push((line_no, pattern)); } } diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index c621c22ac993..b236b0675690 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -59,14 +59,8 @@ impl TestCx<'_> { return; } - let prefixes = { - static PREFIXES: &[&str] = &["cdb", "cdbg"]; - // No "native rust support" variation for CDB yet. - PREFIXES - }; - // Parse debugger commands etc from test files - let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, prefixes) + let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, "cdb") .unwrap_or_else(|e| self.fatal(&e)); // https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-commands @@ -137,7 +131,7 @@ impl TestCx<'_> { } fn run_debuginfo_gdb_test_no_opt(&self) { - let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, &["gdb"]) + let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, "gdb") .unwrap_or_else(|e| self.fatal(&e)); let mut cmds = dbg_cmds.commands.join("\n"); @@ -403,7 +397,7 @@ impl TestCx<'_> { } // Parse debugger commands etc from test files - let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, &["lldb"]) + let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, "lldb") .unwrap_or_else(|e| self.fatal(&e)); // Write debugger script: diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs index 10528de427d0..0c6d46188e6f 100644 --- a/src/tools/compiletest/src/runtest/ui.rs +++ b/src/tools/compiletest/src/runtest/ui.rs @@ -100,7 +100,12 @@ impl TestCx<'_> { ) }); - errors += self.compare_output("fixed", &fixed_code, &fixed_code, &expected_fixed); + if self + .compare_output("fixed", &fixed_code, &fixed_code, &expected_fixed) + .should_error() + { + errors += 1; + } } else if !expected_fixed.is_empty() { panic!( "the `//@ run-rustfix` directive wasn't found but a `*.fixed` \ diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 833e41df5370..570b2c374c0e 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -8,7 +8,7 @@ //! //! Currently uses a combination of HTML parsing to //! extract the `href` and `id` attributes, -//! and regex search on the orignal markdown to handle intra-doc links. +//! and regex search on the original markdown to handle intra-doc links. //! //! These values are then translated to file URLs if possible and then the //! destination is asserted to exist. diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs index 89fdd2a01ebc..de154d771a0c 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs @@ -1,7 +1,7 @@ #![feature(core_intrinsics)] #![feature(rustc_attrs)] -use std::intrinsics::typed_swap; +use std::intrinsics::typed_swap_nonoverlapping; use std::ptr::addr_of_mut; fn invalid_array() { @@ -10,7 +10,7 @@ fn invalid_array() { unsafe { let a = addr_of_mut!(a).cast::<[bool; 100]>(); let b = addr_of_mut!(b).cast::<[bool; 100]>(); - typed_swap(a, b); //~ERROR: constructing invalid value + typed_swap_nonoverlapping(a, b); //~ERROR: constructing invalid value } } diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr index 20b20412e75a..5884d13a2adc 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: constructing invalid value at [0]: encountered 0x02, but expected a boolean --> tests/fail/intrinsics/typed-swap-invalid-array.rs:LL:CC | -LL | typed_swap(a, b); - | ^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered 0x02, but expected a boolean +LL | typed_swap_nonoverlapping(a, b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered 0x02, but expected a boolean | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr similarity index 83% rename from src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.stderr rename to src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr index 6062465f36a6..9804233c7fa8 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: constructing invalid value: encountered 0x02, but expected a boolean --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC | -LL | typed_swap(a, b); - | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x02, but expected a boolean +LL | typed_swap_nonoverlapping(a, b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x02, but expected a boolean | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr new file mode 100644 index 000000000000..54b21f155caa --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: constructing invalid value: encountered 0x03, but expected a boolean + --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC + | +LL | typed_swap_nonoverlapping(a, b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `invalid_scalar` at tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC +note: inside `main` + --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC + | +LL | invalid_scalar(); + | ^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs index 9d014a523f8f..f5f9c7efbe4a 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs @@ -1,16 +1,18 @@ +//@revisions: left right #![feature(core_intrinsics)] #![feature(rustc_attrs)] -use std::intrinsics::typed_swap; +use std::intrinsics::typed_swap_nonoverlapping; use std::ptr::addr_of_mut; fn invalid_scalar() { - let mut a = 1_u8; - let mut b = 2_u8; + // We run the test twice, with either the left or the right side being invalid. + let mut a = if cfg!(left) { 2_u8 } else { 1_u8 }; + let mut b = if cfg!(right) { 3_u8 } else { 1_u8 }; unsafe { let a = addr_of_mut!(a).cast::(); let b = addr_of_mut!(b).cast::(); - typed_swap(a, b); //~ERROR: constructing invalid value + typed_swap_nonoverlapping(a, b); //~ERROR: constructing invalid value } } diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs new file mode 100644 index 000000000000..e643091a02ae --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs @@ -0,0 +1,13 @@ +#![feature(core_intrinsics)] +#![feature(rustc_attrs)] + +use std::intrinsics::typed_swap_nonoverlapping; +use std::ptr::addr_of_mut; + +fn main() { + let mut a = 0_u8; + unsafe { + let a = addr_of_mut!(a); + typed_swap_nonoverlapping(a, a); //~ERROR: called on overlapping ranges + } +} diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr new file mode 100644 index 000000000000..6d578841fe5e --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: `copy_nonoverlapping` called on overlapping ranges + --> tests/fail/intrinsics/typed-swap-overlap.rs:LL:CC + | +LL | typed_swap_nonoverlapping(a, a); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `copy_nonoverlapping` called on overlapping ranges + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at tests/fail/intrinsics/typed-swap-overlap.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/nix-dev-shell/envrc-flake b/src/tools/nix-dev-shell/envrc-flake index 849ed1f4fc56..f3e5442b86b2 100644 --- a/src/tools/nix-dev-shell/envrc-flake +++ b/src/tools/nix-dev-shell/envrc-flake @@ -1,4 +1,4 @@ -# If you want to use this as an .envrc file to create a shell with necessery components +# If you want to use this as an .envrc file to create a shell with necessary components # to develop rustc, use the following command in the root of the rusr checkout: # # ln -s ./src/tools/nix-dev-shell/envrc-flake ./.envrc && nix flake update --flake ./src/tools/nix-dev-shell diff --git a/src/tools/nix-dev-shell/envrc-shell b/src/tools/nix-dev-shell/envrc-shell index d8f900fe86a6..4080d7d53840 100644 --- a/src/tools/nix-dev-shell/envrc-shell +++ b/src/tools/nix-dev-shell/envrc-shell @@ -1,4 +1,4 @@ -# If you want to use this as an .envrc file to create a shell with necessery components +# If you want to use this as an .envrc file to create a shell with necessary components # to develop rustc, use the following command in the root of the rusr checkout: # # ln -s ./src/tools/nix-dev-shell/envrc-shell ./.envrc diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index 68fb9895ecd4..1f98e820840f 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -96,9 +96,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "autocfg" @@ -161,9 +161,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.2.5" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" dependencies = [ "shlex", ] @@ -1209,9 +1209,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -1338,18 +1338,18 @@ checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" [[package]] name = "serde" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", @@ -1446,9 +1446,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.90" +version = "2.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" dependencies = [ "proc-macro2", "quote", @@ -1639,9 +1639,9 @@ checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "unicase" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" diff --git a/src/tools/rustc-perf-wrapper/src/main.rs b/src/tools/rustc-perf-wrapper/src/main.rs index 0b4c894e29d9..e6c885e23dee 100644 --- a/src/tools/rustc-perf-wrapper/src/main.rs +++ b/src/tools/rustc-perf-wrapper/src/main.rs @@ -1,5 +1,5 @@ use std::fs::create_dir_all; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::process::Command; use clap::Parser; @@ -169,7 +169,7 @@ fn execute_benchmark(cmd: &mut Command, compiler: &Path) { const MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR"); - let rustc_perf_dir = PathBuf::from(MANIFEST_DIR).join("../rustc-perf"); + let rustc_perf_dir = Path::new(MANIFEST_DIR).join("../rustc-perf"); // We need to set the working directory to `src/tools/perf`, so that it can find the directory // with compile-time benchmarks. diff --git a/src/tools/suggest-tests/src/static_suggestions.rs b/src/tools/suggest-tests/src/static_suggestions.rs index b216138cf9a5..d363d583b546 100644 --- a/src/tools/suggest-tests/src/static_suggestions.rs +++ b/src/tools/suggest-tests/src/static_suggestions.rs @@ -2,7 +2,7 @@ use std::sync::OnceLock; use crate::{Suggestion, sug}; -// FIXME: perhaps this could use `std::lazy` when it is stablizied +// FIXME: perhaps this could use `std::lazy` when it is stabilized macro_rules! static_suggestions { ($( [ $( $glob:expr ),* $(,)? ] => [ $( $suggestion:expr ),* $(,)? ] ),* $(,)? ) => { pub(crate) fn static_suggestions() -> &'static [(Vec<&'static str>, Vec)] diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index bc75787fb1ab..2f424a482b5b 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -6,7 +6,7 @@ autobins = false [dependencies] build_helper = { path = "../../build_helper" } -cargo_metadata = "0.18" +cargo_metadata = "0.19" regex = "1" miropt-test-tools = { path = "../miropt-test-tools" } walkdir = "2" diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 0e156b9d1ac9..b20d8678d0ea 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -1,9 +1,6 @@ -run-make/branch-protection-check-IBT/Makefile run-make/cat-and-grep-sanity-check/Makefile run-make/extern-fn-reachable/Makefile -run-make/incr-add-rust-src-component/Makefile run-make/jobserver-error/Makefile -run-make/libs-through-symlinks/Makefile run-make/split-debuginfo/Makefile run-make/symbol-mangling-hashed/Makefile run-make/translation/Makefile diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index beeb33b46ff2..1794d0fbca78 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -1,12 +1,16 @@ //! Checks the licenses of third-party dependencies. use std::collections::HashSet; -use std::fs::read_dir; +use std::fs::{File, read_dir}; +use std::io::Write; use std::path::Path; use build_helper::ci::CiEnv; use cargo_metadata::{Metadata, Package, PackageId}; +#[path = "../../../bootstrap/src/utils/proc_macro_deps.rs"] +mod proc_macro_deps; + /// These are licenses that are allowed for all crates, including the runtime, /// rustc, tools, etc. #[rustfmt::skip] @@ -564,9 +568,11 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ /// /// `root` is path to the directory with the root `Cargo.toml` (for the workspace). `cargo` is path /// to the cargo executable. -pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { +pub fn check(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) { let mut checked_runtime_licenses = false; + check_proc_macro_dep_list(root, cargo, bless, bad); + for &(workspace, exceptions, permitted_deps, submodules) in WORKSPACES { if has_missing_submodule(root, submodules) { continue; @@ -600,6 +606,71 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { assert!(checked_runtime_licenses); } +/// Ensure the list of proc-macro crate transitive dependencies is up to date +fn check_proc_macro_dep_list(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) { + let mut cmd = cargo_metadata::MetadataCommand::new(); + cmd.cargo_path(cargo) + .manifest_path(root.join("Cargo.toml")) + .features(cargo_metadata::CargoOpt::AllFeatures) + .other_options(vec!["--locked".to_owned()]); + let metadata = t!(cmd.exec()); + let is_proc_macro_pkg = |pkg: &Package| pkg.targets.iter().any(|target| target.is_proc_macro()); + + let mut proc_macro_deps = HashSet::new(); + for pkg in metadata.packages.iter().filter(|pkg| is_proc_macro_pkg(*pkg)) { + deps_of(&metadata, &pkg.id, &mut proc_macro_deps); + } + // Remove the proc-macro crates themselves + proc_macro_deps.retain(|pkg| !is_proc_macro_pkg(&metadata[pkg])); + let proc_macro_deps_iter = proc_macro_deps.into_iter().map(|dep| metadata[dep].name.clone()); + + if bless { + let mut proc_macro_deps: Vec<_> = proc_macro_deps_iter.collect(); + proc_macro_deps.sort(); + proc_macro_deps.dedup(); + let mut file = File::create(root.join("src/bootstrap/src/utils/proc_macro_deps.rs")) + .expect("`proc_macro_deps` should exist"); + writeln!( + &mut file, + "/// Do not update manually - use `./x.py test tidy --bless` +/// Holds all direct and indirect dependencies of proc-macro crates in tree. +/// See +pub static CRATES: &[&str] = &[ + // tidy-alphabetical-start" + ) + .unwrap(); + for dep in proc_macro_deps { + writeln!(&mut file, " {dep:?},").unwrap(); + } + writeln!( + &mut file, + " // tidy-alphabetical-end +];" + ) + .unwrap(); + } else { + let proc_macro_deps: HashSet<_> = proc_macro_deps_iter.collect(); + let expected = + proc_macro_deps::CRATES.iter().map(|s| s.to_string()).collect::>(); + let old_bad = *bad; + for missing in proc_macro_deps.difference(&expected) { + tidy_error!( + bad, + "proc-macro crate dependency `{missing}` is not registered in `src/bootstrap/src/utils/proc_macro_deps.rs`", + ); + } + for extra in expected.difference(&proc_macro_deps) { + tidy_error!( + bad, + "`{extra}` is not registered in `src/bootstrap/src/utils/proc_macro_deps.rs`, but is not a proc-macro crate dependency", + ); + } + if *bad != old_bad { + eprintln!("Run `./x.py test tidy --bless` to regenerate the list"); + } + } +} + /// Used to skip a check if a submodule is not checked out, and not in a CI environment. /// /// This helps prevent enforcing developers to fetch submodules for tidy. diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 40608952c0b7..13a558fea48e 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -95,7 +95,7 @@ fn main() { check!(target_specific_tests, &tests_path); // Checks that are done on the cargo workspace. - check!(deps, &root_path, &cargo); + check!(deps, &root_path, &cargo, bless); check!(extdeps, &root_path); // Checks over tests. diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 35cda17e1688..aefcd2bb0ccc 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -69,8 +69,7 @@ const ANNOTATIONS_TO_IGNORE: &[&str] = &[ "// gdb", "// lldb", "// cdb", - "// normalize-stderr-test", - "//@ normalize-stderr-test", + "//@ normalize-stderr", ]; fn generate_problems<'a>( @@ -198,8 +197,8 @@ fn should_ignore(line: &str) -> bool { // For `ui_test`-style UI test directives, also ignore // - `//@[rev] compile-flags` - // - `//@[rev] normalize-stderr-test` - || static_regex!("\\s*//@(\\[.*\\]) (compile-flags|normalize-stderr-test|error-pattern).*") + // - `//@[rev] normalize-stderr` + || static_regex!("\\s*//@(\\[.*\\]) (compile-flags|normalize-stderr|error-pattern).*") .is_match(line) // Matching for rustdoc tests commands. // It allows to prevent them emitting warnings like `line longer than 100 chars`. diff --git a/tests/codegen/const-array.rs b/tests/codegen/const-array.rs new file mode 100644 index 000000000000..f2b331c315dc --- /dev/null +++ b/tests/codegen/const-array.rs @@ -0,0 +1,15 @@ +//@ compile-flags: -O + +#![crate_type = "lib"] + +const LUT: [u8; 2] = [1, 1]; + +// CHECK-LABEL: @decode +#[no_mangle] +pub fn decode(i: u8) -> u8 { + // CHECK: start: + // CHECK-NEXT: icmp + // CHECK-NEXT: select + // CHECK-NEXT: ret + if i < 2 { LUT[i as usize] } else { 2 } +} diff --git a/tests/codegen/intrinsics/carrying_mul_add.rs b/tests/codegen/intrinsics/carrying_mul_add.rs new file mode 100644 index 000000000000..174c4077f09e --- /dev/null +++ b/tests/codegen/intrinsics/carrying_mul_add.rs @@ -0,0 +1,137 @@ +//@ revisions: RAW OPT +//@ compile-flags: -C opt-level=1 +//@[RAW] compile-flags: -C no-prepopulate-passes +//@[OPT] min-llvm-version: 19 + +#![crate_type = "lib"] +#![feature(core_intrinsics)] +#![feature(core_intrinsics_fallbacks)] + +// Note that LLVM seems to sometimes permute the order of arguments to mul and add, +// so these tests don't check the arguments in the optimized revision. + +use std::intrinsics::{carrying_mul_add, fallback}; + +// The fallbacks are emitted even when they're never used, but optimize out. + +// RAW: wide_mul_u128 +// OPT-NOT: wide_mul_u128 + +// CHECK-LABEL: @cma_u8 +#[no_mangle] +pub unsafe fn cma_u8(a: u8, b: u8, c: u8, d: u8) -> (u8, u8) { + // CHECK: [[A:%.+]] = zext i8 %a to i16 + // CHECK: [[B:%.+]] = zext i8 %b to i16 + // CHECK: [[C:%.+]] = zext i8 %c to i16 + // CHECK: [[D:%.+]] = zext i8 %d to i16 + // CHECK: [[AB:%.+]] = mul nuw i16 + // RAW-SAME: [[A]], [[B]] + // CHECK: [[ABC:%.+]] = add nuw i16 + // RAW-SAME: [[AB]], [[C]] + // CHECK: [[ABCD:%.+]] = add nuw i16 + // RAW-SAME: [[ABC]], [[D]] + // CHECK: [[LOW:%.+]] = trunc i16 [[ABCD]] to i8 + // CHECK: [[HIGHW:%.+]] = lshr i16 [[ABCD]], 8 + // RAW: [[HIGH:%.+]] = trunc i16 [[HIGHW]] to i8 + // OPT: [[HIGH:%.+]] = trunc nuw i16 [[HIGHW]] to i8 + // CHECK: [[PAIR0:%.+]] = insertvalue { i8, i8 } poison, i8 [[LOW]], 0 + // CHECK: [[PAIR1:%.+]] = insertvalue { i8, i8 } [[PAIR0]], i8 [[HIGH]], 1 + // OPT: ret { i8, i8 } [[PAIR1]] + carrying_mul_add(a, b, c, d) +} + +// CHECK-LABEL: @cma_u32 +#[no_mangle] +pub unsafe fn cma_u32(a: u32, b: u32, c: u32, d: u32) -> (u32, u32) { + // CHECK: [[A:%.+]] = zext i32 %a to i64 + // CHECK: [[B:%.+]] = zext i32 %b to i64 + // CHECK: [[C:%.+]] = zext i32 %c to i64 + // CHECK: [[D:%.+]] = zext i32 %d to i64 + // CHECK: [[AB:%.+]] = mul nuw i64 + // RAW-SAME: [[A]], [[B]] + // CHECK: [[ABC:%.+]] = add nuw i64 + // RAW-SAME: [[AB]], [[C]] + // CHECK: [[ABCD:%.+]] = add nuw i64 + // RAW-SAME: [[ABC]], [[D]] + // CHECK: [[LOW:%.+]] = trunc i64 [[ABCD]] to i32 + // CHECK: [[HIGHW:%.+]] = lshr i64 [[ABCD]], 32 + // RAW: [[HIGH:%.+]] = trunc i64 [[HIGHW]] to i32 + // OPT: [[HIGH:%.+]] = trunc nuw i64 [[HIGHW]] to i32 + // CHECK: [[PAIR0:%.+]] = insertvalue { i32, i32 } poison, i32 [[LOW]], 0 + // CHECK: [[PAIR1:%.+]] = insertvalue { i32, i32 } [[PAIR0]], i32 [[HIGH]], 1 + // OPT: ret { i32, i32 } [[PAIR1]] + carrying_mul_add(a, b, c, d) +} + +// CHECK-LABEL: @cma_u128 +// CHECK-SAME: sret{{.+}}dereferenceable(32){{.+}}%_0,{{.+}}%a,{{.+}}%b,{{.+}}%c,{{.+}}%d +#[no_mangle] +pub unsafe fn cma_u128(a: u128, b: u128, c: u128, d: u128) -> (u128, u128) { + // CHECK: [[A:%.+]] = zext i128 %a to i256 + // CHECK: [[B:%.+]] = zext i128 %b to i256 + // CHECK: [[C:%.+]] = zext i128 %c to i256 + // CHECK: [[D:%.+]] = zext i128 %d to i256 + // CHECK: [[AB:%.+]] = mul nuw i256 + // RAW-SAME: [[A]], [[B]] + // CHECK: [[ABC:%.+]] = add nuw i256 + // RAW-SAME: [[AB]], [[C]] + // CHECK: [[ABCD:%.+]] = add nuw i256 + // RAW-SAME: [[ABC]], [[D]] + // CHECK: [[LOW:%.+]] = trunc i256 [[ABCD]] to i128 + // CHECK: [[HIGHW:%.+]] = lshr i256 [[ABCD]], 128 + // RAW: [[HIGH:%.+]] = trunc i256 [[HIGHW]] to i128 + // OPT: [[HIGH:%.+]] = trunc nuw i256 [[HIGHW]] to i128 + // RAW: [[PAIR0:%.+]] = insertvalue { i128, i128 } poison, i128 [[LOW]], 0 + // RAW: [[PAIR1:%.+]] = insertvalue { i128, i128 } [[PAIR0]], i128 [[HIGH]], 1 + // OPT: store i128 [[LOW]], ptr %_0 + // OPT: [[P1:%.+]] = getelementptr inbounds i8, ptr %_0, {{i32|i64}} 16 + // OPT: store i128 [[HIGH]], ptr [[P1]] + // CHECK: ret void + carrying_mul_add(a, b, c, d) +} + +// CHECK-LABEL: @cma_i128 +// CHECK-SAME: sret{{.+}}dereferenceable(32){{.+}}%_0,{{.+}}%a,{{.+}}%b,{{.+}}%c,{{.+}}%d +#[no_mangle] +pub unsafe fn cma_i128(a: i128, b: i128, c: i128, d: i128) -> (u128, i128) { + // CHECK: [[A:%.+]] = sext i128 %a to i256 + // CHECK: [[B:%.+]] = sext i128 %b to i256 + // CHECK: [[C:%.+]] = sext i128 %c to i256 + // CHECK: [[D:%.+]] = sext i128 %d to i256 + // CHECK: [[AB:%.+]] = mul nsw i256 + // RAW-SAME: [[A]], [[B]] + // CHECK: [[ABC:%.+]] = add nsw i256 + // RAW-SAME: [[AB]], [[C]] + // CHECK: [[ABCD:%.+]] = add nsw i256 + // RAW-SAME: [[ABC]], [[D]] + // CHECK: [[LOW:%.+]] = trunc i256 [[ABCD]] to i128 + // CHECK: [[HIGHW:%.+]] = lshr i256 [[ABCD]], 128 + // RAW: [[HIGH:%.+]] = trunc i256 [[HIGHW]] to i128 + // OPT: [[HIGH:%.+]] = trunc nuw i256 [[HIGHW]] to i128 + // RAW: [[PAIR0:%.+]] = insertvalue { i128, i128 } poison, i128 [[LOW]], 0 + // RAW: [[PAIR1:%.+]] = insertvalue { i128, i128 } [[PAIR0]], i128 [[HIGH]], 1 + // OPT: store i128 [[LOW]], ptr %_0 + // OPT: [[P1:%.+]] = getelementptr inbounds i8, ptr %_0, {{i32|i64}} 16 + // OPT: store i128 [[HIGH]], ptr [[P1]] + // CHECK: ret void + carrying_mul_add(a, b, c, d) +} + +// CHECK-LABEL: @fallback_cma_u32 +#[no_mangle] +pub unsafe fn fallback_cma_u32(a: u32, b: u32, c: u32, d: u32) -> (u32, u32) { + // OPT-DAG: [[A:%.+]] = zext i32 %a to i64 + // OPT-DAG: [[B:%.+]] = zext i32 %b to i64 + // OPT-DAG: [[AB:%.+]] = mul nuw i64 + // OPT-DAG: [[C:%.+]] = zext i32 %c to i64 + // OPT-DAG: [[ABC:%.+]] = add nuw i64{{.+}}[[C]] + // OPT-DAG: [[D:%.+]] = zext i32 %d to i64 + // OPT-DAG: [[ABCD:%.+]] = add nuw i64{{.+}}[[D]] + // OPT-DAG: [[LOW:%.+]] = trunc i64 [[ABCD]] to i32 + // OPT-DAG: [[HIGHW:%.+]] = lshr i64 [[ABCD]], 32 + // OPT-DAG: [[HIGH:%.+]] = trunc nuw i64 [[HIGHW]] to i32 + // OPT-DAG: [[PAIR0:%.+]] = insertvalue { i32, i32 } poison, i32 [[LOW]], 0 + // OPT-DAG: [[PAIR1:%.+]] = insertvalue { i32, i32 } [[PAIR0]], i32 [[HIGH]], 1 + // OPT-DAG: ret { i32, i32 } [[PAIR1]] + fallback::CarryingMulAdd::carrying_mul_add(a, b, c, d) +} diff --git a/tests/codegen/intrinsics/typed_swap.rs b/tests/codegen/intrinsics/typed_swap.rs index e73931d1d547..6b55078407a4 100644 --- a/tests/codegen/intrinsics/typed_swap.rs +++ b/tests/codegen/intrinsics/typed_swap.rs @@ -8,14 +8,14 @@ #![crate_type = "lib"] #![feature(core_intrinsics)] -use std::intrinsics::typed_swap; +use std::intrinsics::typed_swap_nonoverlapping; // CHECK-LABEL: @swap_unit( #[no_mangle] pub unsafe fn swap_unit(x: &mut (), y: &mut ()) { // CHECK: start // CHECK-NEXT: ret void - typed_swap(x, y) + typed_swap_nonoverlapping(x, y) } // CHECK-LABEL: @swap_i32( @@ -32,7 +32,7 @@ pub unsafe fn swap_i32(x: &mut i32, y: &mut i32) { // OPT3: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %x, ptr align 4 %y, i64 4, i1 false) // CHECK: store i32 %[[TEMP]], ptr %y, align 4 // CHECK: ret void - typed_swap(x, y) + typed_swap_nonoverlapping(x, y) } // CHECK-LABEL: @swap_pair( @@ -47,7 +47,7 @@ pub unsafe fn swap_pair(x: &mut (i32, u32), y: &mut (i32, u32)) { // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %x, ptr align 4 %y, i64 8, i1 false) // CHECK: store i32 // CHECK: store i32 - typed_swap(x, y) + typed_swap_nonoverlapping(x, y) } // CHECK-LABEL: @swap_str( @@ -63,7 +63,7 @@ pub unsafe fn swap_str<'a>(x: &mut &'a str, y: &mut &'a str) { // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %x, ptr align 8 %y, i64 16, i1 false) // CHECK: store ptr // CHECK: store i64 - typed_swap(x, y) + typed_swap_nonoverlapping(x, y) } // OPT0-LABEL: @swap_string( @@ -73,5 +73,5 @@ pub unsafe fn swap_string(x: &mut String, y: &mut String) { // OPT0: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[TEMP]], ptr align 8 %x, i64 24, i1 false) // OPT0: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %x, ptr align 8 %y, i64 24, i1 false) // OPT0: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %y, ptr align 8 %[[TEMP]], i64 24, i1 false) - typed_swap(x, y) + typed_swap_nonoverlapping(x, y) } diff --git a/tests/codegen/range_to_inclusive.rs b/tests/codegen/range_to_inclusive.rs new file mode 100644 index 000000000000..f3001897f88d --- /dev/null +++ b/tests/codegen/range_to_inclusive.rs @@ -0,0 +1,28 @@ +//! Test that `RangeTo` and `RangeToInclusive` generate identical +//! (and optimal) code; #63646 +//@ compile-flags: -O -Zmerge-functions=disabled +#![crate_type = "lib"] + +#[no_mangle] +// CHECK-LABEL: range_to( +pub fn range_to(a: i32, mut b: i32) -> i32 { + // CHECK: %1 = and i32 %0, %a + // CHECK-NEXT: ret i32 %1 + for _ in 0..65 { + b &= a; + } + + b +} + +#[no_mangle] +// CHECK-LABEL: range_to_inclusive( +pub fn range_to_inclusive(a: i32, mut b: i32) -> i32 { + // CHECK: %1 = and i32 %0, %a + // CHECK-NEXT: ret i32 %1 + for _ in 0..=64 { + b &= a; + } + + b +} diff --git a/tests/codegen/slice-indexing.rs b/tests/codegen/slice-indexing.rs index 3d284148db22..75112bb0c24e 100644 --- a/tests/codegen/slice-indexing.rs +++ b/tests/codegen/slice-indexing.rs @@ -60,3 +60,40 @@ pub unsafe fn str_get_unchecked_mut_by_range(x: &mut str, r: Range) -> &m // CHECK: sub nuw i64 x.get_unchecked_mut(r) } + +// CHECK-LABEL: @slice_repeated_indexing( +#[no_mangle] +pub fn slice_repeated_indexing(dst: &mut [u8], offset: usize) { + let mut i = offset; + // CHECK: panic_bounds_check + dst[i] = 1; + i += 1; + // CHECK: panic_bounds_check + dst[i] = 2; + i += 1; + // CHECK: panic_bounds_check + dst[i] = 3; + i += 1; + // CHECK: panic_bounds_check + dst[i] = 4; +} + +// CHECK-LABEL: @slice_repeated_indexing_coalesced( +#[no_mangle] +pub fn slice_repeated_indexing_coalesced(dst: &mut [u8], offset: usize) { + let mut i = offset; + if i.checked_add(4).unwrap() <= dst.len() { + // CHECK-NOT: panic_bounds_check + dst[i] = 1; + i += 1; + // CHECK-NOT: panic_bounds_check + dst[i] = 2; + i += 1; + // CHECK-NOT: panic_bounds_check + dst[i] = 3; + i += 1; + // CHECK-NOT: panic_bounds_check + dst[i] = 4; + } + // CHECK: ret +} diff --git a/tests/crashes/128346.rs b/tests/crashes/128346.rs deleted file mode 100644 index 93d9c40a544e..000000000000 --- a/tests/crashes/128346.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: rust-lang/rust#128346 - -macro_rules! one_rep { - ( $($a:ident)* ) => { - A( - const ${concat($a, Z)}: i32 = 3; - )* - }; -} - -fn main() { - one_rep!(A B C); -} diff --git a/tests/run-make/branch-protection-check-IBT/Makefile b/tests/run-make/branch-protection-check-IBT/Makefile deleted file mode 100644 index ee0e034627f6..000000000000 --- a/tests/run-make/branch-protection-check-IBT/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# Check for GNU Property Note - -include ../tools.mk - -# How to run this -# python3 x.py test --target x86_64-unknown-linux-gnu tests/run-make/branch-protection-check-IBT/ - -# only-x86_64 - -# ignore-test -# FIXME(jieyouxu): This test never runs because the `ifeq` check on line 17 -# compares `x86` to `x86_64`, which always evaluates to false. -# When the test does run, the compilation does not include `.note.gnu.property`. -# See https://github.com/rust-lang/rust/pull/126720 for more information. - -all: -ifeq ($(filter x86,$(LLVM_COMPONENTS)),x86_64) - $(RUSTC) --target x86_64-unknown-linux-gnu -Z cf-protection=branch -L$(TMPDIR) -C link-args='-nostartfiles' -C save-temps ./main.rs -o $(TMPDIR)/rsmain - readelf -nW $(TMPDIR)/rsmain | $(CGREP) -e ".note.gnu.property" -endif - diff --git a/tests/run-make/branch-protection-check-IBT/_rmake.rs b/tests/run-make/branch-protection-check-IBT/_rmake.rs deleted file mode 100644 index 911514087856..000000000000 --- a/tests/run-make/branch-protection-check-IBT/_rmake.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Check for GNU Property Note - -// How to run this -// python3 x.py test --target x86_64-unknown-linux-gnu tests/run-make/branch-protection-check-IBT/ - -//@ only-x86_64 - -//@ ignore-test -// FIXME(jieyouxu): see the FIXME in the Makefile - -use run_make_support::{cwd, env_var, llvm_readobj, rustc}; - -fn main() { - let llvm_components = env_var("LLVM_COMPONENTS"); - if !format!(" {llvm_components} ").contains(" x86 ") { - return; - } - - rustc() - .input("main.rs") - .target("x86_64-unknown-linux-gnu") - .arg("-Zcf-protection=branch") - .arg(format!("-L{}", cwd().display())) - .arg("-Clink-args=-nostartfiles") - .arg("-Csave-temps") - .run(); - - llvm_readobj().arg("-nW").input("main").run().assert_stdout_contains(".note.gnu.property"); -} diff --git a/tests/run-make/branch-protection-check-IBT/main.rs b/tests/run-make/branch-protection-check-IBT/main.rs index ad379d6ea437..445b8795134c 100644 --- a/tests/run-make/branch-protection-check-IBT/main.rs +++ b/tests/run-make/branch-protection-check-IBT/main.rs @@ -1,3 +1,5 @@ -fn main() { - println!("hello world"); -} +#![feature(no_core)] +#![allow(internal_features)] +#![no_core] +#![no_std] +#![no_main] diff --git a/tests/run-make/branch-protection-check-IBT/rmake.rs b/tests/run-make/branch-protection-check-IBT/rmake.rs new file mode 100644 index 000000000000..73109df12ae9 --- /dev/null +++ b/tests/run-make/branch-protection-check-IBT/rmake.rs @@ -0,0 +1,53 @@ +// ignore-tidy-linelength +//! A basic smoke test to check for GNU Property Note to see that for `x86_64` targets when [`-Z +//! cf-protection=branch`][intel-cet-tracking-issue] is requested, that the +//! +//! ```text +//! NT_GNU_PROPERTY_TYPE_0 Properties: x86 feature: IBT +//! ``` +//! +//! Intel Indirect Branch Tracking (IBT) property is emitted. This was generated in +//! in order to address +//! . +//! +//! Note that the precompiled std currently is not compiled with `-Z cf-protection=branch`! +//! +//! In particular, it is expected that: +//! +//! > IBT to only be enabled for the process if `.note.gnu.property` indicates that the executable +//! > was compiled with IBT support and the linker to only tell that IBT is supported if all input +//! > object files indicate that they support IBT, which in turn requires the standard library to be +//! > compiled with IBT enabled. +//! +//! Note that Intel IBT (Indirect Branch Tracking) is not to be confused with Arm's BTI (Branch +//! Target Identification). See below for link to Intel IBT docs. +//! +//! ## Related links +//! +//! - [Tracking Issue for Intel Control Enforcement Technology (CET)][intel-cet-tracking-issue] +//! - Zulip question about this test: +//! +//! - Intel IBT docs: +//! +//! +//! [intel-cet-tracking-issue]: https://github.com/rust-lang/rust/issues/93754 + +//@ needs-llvm-components: x86 + +// FIXME(#93754): increase the test coverage of this test. +//@ only-x86_64-unknown-linux-gnu +//@ ignore-cross-compile + +use run_make_support::{bare_rustc, llvm_readobj}; + +fn main() { + // `main.rs` is `#![no_std]` to not pull in the currently not-compiled-with-IBT precompiled std. + bare_rustc() + .input("main.rs") + .target("x86_64-unknown-linux-gnu") + .arg("-Zcf-protection=branch") + .arg("-Clink-args=-nostartfiles") + .run(); + + llvm_readobj().arg("-nW").input("main").run().assert_stdout_contains(".note.gnu.property"); +} diff --git a/tests/run-make/incr-add-rust-src-component/Makefile b/tests/run-make/incr-add-rust-src-component/Makefile deleted file mode 100644 index fd09c2299f98..000000000000 --- a/tests/run-make/incr-add-rust-src-component/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# rust-lang/rust#70924: Test that if we add rust-src component in between two -# incremental compiles, the compiler does not ICE on the second. - -# This test uses `ln -s` rather than copying to save testing time, but its -# usage doesn't work on windows. So ignore windows. - -# ignore-windows - -SYSROOT:=$(shell $(RUSTC) --print sysroot) -FAKEROOT=$(TMPDIR)/fakeroot -INCR=$(TMPDIR)/incr - -# Make a local copy of the sysroot; then remove the rust-src part of it, if -# present, for the *first* build. Then put in a facsimile of the rust-src -# component for the second build, in order to expose the ICE from issue #70924. -# -# Note that it is much easier to just do `cp -a $(SYSROOT)/* $(FAKEROOT)` as a -# first step, but I am concerned that would be too expensive in a unit test -# compared to making symbolic links. -# -# Anyway, the pattern you'll see here is: For every prefix in -# root/lib/rustlib/src, link all of prefix parent content, then remove the -# prefix, then loop on the next prefix. This way, we basically create a copy of -# the context around root/lib/rustlib/src, and can freely add/remove the src -# component itself. -all: - mkdir $(FAKEROOT) - ln -s $(SYSROOT)/* $(FAKEROOT) - rm -f $(FAKEROOT)/lib - mkdir $(FAKEROOT)/lib - ln -s $(SYSROOT)/lib/* $(FAKEROOT)/lib - rm -f $(FAKEROOT)/lib/rustlib - mkdir $(FAKEROOT)/lib/rustlib - ln -s $(SYSROOT)/lib/rustlib/* $(FAKEROOT)/lib/rustlib - rm -f $(FAKEROOT)/lib/rustlib/src - mkdir $(FAKEROOT)/lib/rustlib/src - ln -s $(SYSROOT)/lib/rustlib/src/* $(FAKEROOT)/lib/rustlib/src - rm -f $(FAKEROOT)/lib/rustlib/src/rust - $(RUSTC) --sysroot $(FAKEROOT) -C incremental=$(INCR) main.rs - mkdir -p $(FAKEROOT)/lib/rustlib/src/rust/src/libstd - touch $(FAKEROOT)/lib/rustlib/src/rust/src/libstd/lib.rs - $(RUSTC) --sysroot $(FAKEROOT) -C incremental=$(INCR) main.rs diff --git a/tests/run-make/incr-add-rust-src-component/rmake.rs b/tests/run-make/incr-add-rust-src-component/rmake.rs new file mode 100644 index 000000000000..964f1410a964 --- /dev/null +++ b/tests/run-make/incr-add-rust-src-component/rmake.rs @@ -0,0 +1,131 @@ +//! Regression test for rust-lang/rust#70924. Check that if we add the `rust-src` component in +//! between two incremental compiles, that the compiler doesn't ICE on the second invocation. +//! +//! This test uses symbolic links to save testing time. +//! +//! The way this test works is that, for every prefix in `root/lib/rustlib/src`, link all of prefix +//! parent content, then remove the prefix, then loop on the next prefix. This way, we basically +//! create a copy of the context around `root/lib/rustlib/src`, and can freely add/remove the src +//! component itself. + +//@ ignore-cross-compile +// Reason: test needs to run. + +//@ needs-symlink +// Reason: test needs symlink to create stub directories and files. + +use std::path::Path; + +use run_make_support::rfs::read_dir_entries; +use run_make_support::{bare_rustc, path, rfs, run}; + +#[derive(Debug, Copy, Clone)] +struct Symlink<'a, 'b> { + src_dir: &'a Path, + dst_dir: &'b Path, +} + +fn shallow_symlink_dir<'a, 'b>(Symlink { src_dir, dst_dir }: Symlink<'a, 'b>) { + eprintln!( + "shallow_symlink_dir: src_dir={} -> dst_dir={}", + src_dir.display(), + dst_dir.display() + ); + + read_dir_entries(src_dir, |src_path| { + let src_metadata = rfs::symlink_metadata(src_path); + let filename = src_path.file_name().unwrap(); + if src_metadata.is_dir() { + rfs::symlink_dir(src_path, dst_dir.join(filename)); + } else if src_metadata.is_file() { + rfs::symlink_file(src_path, dst_dir.join(filename)); + } else if src_metadata.is_symlink() { + rfs::copy_symlink(src_path, dst_dir.join(filename)); + } + }); +} + +fn recreate_dir(path: &Path) { + rfs::recursive_remove(path); + rfs::create_dir(path); +} + +fn main() { + let sysroot = bare_rustc().print("sysroot").run().stdout_utf8(); + let sysroot = sysroot.trim(); + let sysroot = path(sysroot); + + let incr = path("incr"); + + let fakeroot = path("fakeroot"); + rfs::create_dir(&fakeroot); + + shallow_symlink_dir(Symlink { src_dir: &sysroot, dst_dir: &fakeroot }); + recreate_dir(&fakeroot.join("lib")); + + shallow_symlink_dir(Symlink { src_dir: &sysroot.join("lib"), dst_dir: &fakeroot.join("lib") }); + recreate_dir(&fakeroot.join("lib").join("rustlib")); + + shallow_symlink_dir(Symlink { + src_dir: &sysroot.join("lib").join("rustlib"), + dst_dir: &fakeroot.join("lib").join("rustlib"), + }); + recreate_dir(&fakeroot.join("lib").join("rustlib").join("src")); + + shallow_symlink_dir(Symlink { + src_dir: &sysroot.join("lib").join("rustlib").join("src"), + dst_dir: &fakeroot.join("lib").join("rustlib").join("src"), + }); + + rfs::recursive_remove(&fakeroot.join("lib").join("rustlib").join("src").join("rust")); + + let run_incr_rustc = || { + bare_rustc() + .sysroot(&fakeroot) + .arg("-C") + .arg(format!("incremental={}", incr.to_str().unwrap())) + .input("main.rs") + .run(); + }; + + // Run rustc w/ incremental once... + run_incr_rustc(); + + // NOTE: the Makefile version of this used `$SYSROOT/lib/rustlib/src/rust/src/libstd/lib.rs`, + // but that actually got moved around and reorganized over the years. As of Dec 2024, the + // rust-src component is more like (specific for our purposes): + // + // ``` + // $SYSROOT/lib/rustlib/src/rust/ + // library/std/src/lib.rs + // src/ + // ``` + rfs::create_dir_all( + &fakeroot + .join("lib") + .join("rustlib") + .join("src") + .join("rust") + .join("library") + .join("std") + .join("src"), + ); + rfs::write( + &fakeroot + .join("lib") + .join("rustlib") + .join("src") + .join("rust") + .join("library") + .join("std") + .join("src") + .join("lib.rs"), + b"", + ); + + // ... and a second time. + run_incr_rustc(); + + // Basic sanity check that the compiled binary can run. + run("main"); +} diff --git a/tests/run-make/libs-through-symlinks/Makefile b/tests/run-make/libs-through-symlinks/Makefile deleted file mode 100644 index c6ff566a0e86..000000000000 --- a/tests/run-make/libs-through-symlinks/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# ignore-windows - -# The option -n for the AIX ln command has a different purpose than it does -# on Linux. On Linux, the -n option is used to treat the destination path as -# normal file if it is a symbolic link to a directory, which is the default -# behavior of the AIX ln command. -ifeq ($(UNAME),AIX) -LN_FLAGS := -sf -else -LN_FLAGS := -nsf -endif - -NAME := $(shell $(RUSTC) --print file-names foo.rs) - -all: - mkdir -p $(TMPDIR)/outdir - $(RUSTC) foo.rs -o $(TMPDIR)/outdir/$(NAME) - ln $(LN_FLAGS) outdir/$(NAME) $(TMPDIR) - RUSTC_LOG=rustc_metadata::loader $(RUSTC) bar.rs diff --git a/tests/run-make/libs-through-symlinks/rmake.rs b/tests/run-make/libs-through-symlinks/rmake.rs new file mode 100644 index 000000000000..4bb3d05abb7a --- /dev/null +++ b/tests/run-make/libs-through-symlinks/rmake.rs @@ -0,0 +1,48 @@ +//! Regression test for [rustc doesn't handle relative symlinks to libraries +//! #13890](https://github.com/rust-lang/rust/issues/13890). +//! +//! This smoke test checks that for a given library search path `P`: +//! +//! - `rustc` is able to locate a library available via a symlink, where: +//! - the symlink is under the directory subtree of `P`, +//! - but the actual library is not (it's in a different directory subtree). +//! +//! For example: +//! +//! ```text +//! actual_dir/ +//! libfoo.rlib +//! symlink_dir/ # $CWD set; rustc -L . bar.rs that depends on foo +//! libfoo.rlib --> ../actual_dir/libfoo.rlib +//! ``` +//! +//! Previously, if `rustc` was invoked with CWD set to `symlink_dir/`, it would fail to traverse the +//! symlink to locate `actual_dir/libfoo.rlib`. This was originally fixed in +//! . + +//@ ignore-cross-compile + +use run_make_support::{bare_rustc, cwd, path, rfs, rust_lib_name}; + +fn main() { + let actual_lib_dir = path("actual_lib_dir"); + let symlink_lib_dir = path("symlink_lib_dir"); + rfs::create_dir_all(&actual_lib_dir); + rfs::create_dir_all(&symlink_lib_dir); + + // NOTE: `bare_rustc` is used because it does not introduce an implicit `-L .` library search + // flag. + bare_rustc().input("foo.rs").output(actual_lib_dir.join(rust_lib_name("foo"))).run(); + + rfs::symlink_file( + actual_lib_dir.join(rust_lib_name("foo")), + symlink_lib_dir.join(rust_lib_name("foo")), + ); + + // Make rustc's $CWD be in the directory containing the symlink-to-lib. + bare_rustc() + .current_dir(&symlink_lib_dir) + .library_search_path(".") + .input(cwd().join("bar.rs")) + .run(); +} diff --git a/tests/rustdoc-js-std/path-maxeditdistance.js b/tests/rustdoc-js-std/path-maxeditdistance.js index af71713f0558..fd12a0564966 100644 --- a/tests/rustdoc-js-std/path-maxeditdistance.js +++ b/tests/rustdoc-js-std/path-maxeditdistance.js @@ -17,10 +17,10 @@ const EXPECTED = [ { 'path': 'std::vec::IntoIter', 'name': 'into_iter' }, { 'path': 'std::vec::ExtractIf', 'name': 'into_iter' }, { 'path': 'std::vec::Splice', 'name': 'into_iter' }, - { 'path': 'std::collections::vec_deque::VecDeque', 'name': 'iter' }, - { 'path': 'std::collections::vec_deque::VecDeque', 'name': 'iter_mut' }, - { 'path': 'std::collections::vec_deque::VecDeque', 'name': 'from_iter' }, - { 'path': 'std::collections::vec_deque::VecDeque', 'name': 'into_iter' }, + { 'path': 'std::collections::VecDeque', 'name': 'iter' }, + { 'path': 'std::collections::VecDeque', 'name': 'iter_mut' }, + { 'path': 'std::collections::VecDeque', 'name': 'from_iter' }, + { 'path': 'std::collections::VecDeque', 'name': 'into_iter' }, ], }, { diff --git a/tests/rustdoc-js-std/path-ordering.js b/tests/rustdoc-js-std/path-ordering.js index 4bfc6256052c..4bec4827d519 100644 --- a/tests/rustdoc-js-std/path-ordering.js +++ b/tests/rustdoc-js-std/path-ordering.js @@ -3,17 +3,17 @@ const EXPECTED = [ query: 'hashset::insert', others: [ // ensure hashset::insert comes first - { 'path': 'std::collections::hash_set::HashSet', 'name': 'insert' }, - { 'path': 'std::collections::hash_set::HashSet', 'name': 'get_or_insert' }, - { 'path': 'std::collections::hash_set::HashSet', 'name': 'get_or_insert_with' }, + { 'path': 'std::collections::HashSet', 'name': 'insert' }, + { 'path': 'std::collections::HashSet', 'name': 'get_or_insert' }, + { 'path': 'std::collections::HashSet', 'name': 'get_or_insert_with' }, ], }, { query: 'hash::insert', others: [ // ensure hashset/hashmap::insert come first - { 'path': 'std::collections::hash_map::HashMap', 'name': 'insert' }, - { 'path': 'std::collections::hash_set::HashSet', 'name': 'insert' }, + { 'path': 'std::collections::HashMap', 'name': 'insert' }, + { 'path': 'std::collections::HashSet', 'name': 'insert' }, ], }, ]; diff --git a/tests/rustdoc-js-std/simd-type-signatures.js b/tests/rustdoc-js-std/simd-type-signatures.js index 4fc14e65ac42..fea34ff97f21 100644 --- a/tests/rustdoc-js-std/simd-type-signatures.js +++ b/tests/rustdoc-js-std/simd-type-signatures.js @@ -11,29 +11,29 @@ const EXPECTED = [ 'query': 'simd, simd -> simd', 'others': [ { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'simd_max', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_max' + 'href': '../std/simd/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_max' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'simd_min', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_min' + 'href': '../std/simd/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_min' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'saturating_add', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci16,+N%3E/method.saturating_add' + 'href': '../std/simd/struct.Simd.html#impl-SimdInt-for-Simd%3Ci16,+N%3E/method.saturating_add' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'saturating_sub', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci16,+N%3E/method.saturating_sub' + 'href': '../std/simd/struct.Simd.html#impl-SimdInt-for-Simd%3Ci16,+N%3E/method.saturating_sub' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'simd_clamp', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_clamp' + 'href': '../std/simd/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_clamp' }, ], }, @@ -41,29 +41,29 @@ const EXPECTED = [ 'query': 'simd, simd -> simd', 'others': [ { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'simd_max', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_max' + 'href': '../std/simd/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_max' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'simd_min', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_min' + 'href': '../std/simd/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_min' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'saturating_add', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci8,+N%3E/method.saturating_add' + 'href': '../std/simd/struct.Simd.html#impl-SimdInt-for-Simd%3Ci8,+N%3E/method.saturating_add' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'saturating_sub', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci8,+N%3E/method.saturating_sub' + 'href': '../std/simd/struct.Simd.html#impl-SimdInt-for-Simd%3Ci8,+N%3E/method.saturating_sub' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'simd_clamp', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_clamp' + 'href': '../std/simd/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_clamp' }, ], }, diff --git a/tests/rustdoc-ui/2024-doctests-checks.rs b/tests/rustdoc-ui/2024-doctests-checks.rs index f3e4e10f5714..0c3a11771f34 100644 --- a/tests/rustdoc-ui/2024-doctests-checks.rs +++ b/tests/rustdoc-ui/2024-doctests-checks.rs @@ -1,9 +1,9 @@ //@ check-pass //@ edition: 2024 //@ compile-flags: --test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" +//@ normalize-stdout: "tests/rustdoc-ui" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" /// ``` /// let x = 12; diff --git a/tests/rustdoc-ui/2024-doctests-crate-attribute.rs b/tests/rustdoc-ui/2024-doctests-crate-attribute.rs index a353fc7cc445..c9887cbc63ba 100644 --- a/tests/rustdoc-ui/2024-doctests-crate-attribute.rs +++ b/tests/rustdoc-ui/2024-doctests-crate-attribute.rs @@ -1,9 +1,9 @@ //@ check-pass //@ edition: 2024 //@ compile-flags: --test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" +//@ normalize-stdout: "tests/rustdoc-ui" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" /// This doctest is used to ensure that if a crate attribute is present, /// it will not be part of the merged doctests. diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs index 24cfd25ccadb..1a1cf6b9e75e 100644 --- a/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs +++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs @@ -5,8 +5,8 @@ // line arguments and is only run on windows. // //@ only-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args #[cfg(not(cmdline_set))] diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs b/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs index fe6a849b0c8b..8d9335f5add5 100644 --- a/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs +++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs @@ -6,8 +6,8 @@ // windows. // //@ ignore-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args #[cfg(not(cmdline_set))] diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs index 84c050d84e25..9cbbd505c57b 100644 --- a/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs +++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs @@ -5,9 +5,9 @@ // line arguments and is only run on windows. // //@ only-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " -//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args @{{src-base}}\argfile\commandline-argfile-badutf8.args @{{src-base}}\argfile\commandline-argfile-missing2.args #[cfg(not(cmdline_set))] diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs index f658ee34fbb0..f211a50892c5 100644 --- a/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs +++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs @@ -6,9 +6,9 @@ // windows. // //@ ignore-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " -//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args @{{src-base}}/argfile/commandline-argfile-badutf8.args @{{src-base}}/argfile/commandline-argfile-missing2.args #[cfg(not(cmdline_set))] diff --git a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs index c3da1fdd7cc6..1174e16dd53f 100644 --- a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs +++ b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +//@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" //! [struct@m!()] //~ WARN: unmatched disambiguator `struct` and suffix `!()` //! [struct@m!{}] diff --git a/tests/rustdoc-ui/doctest/block-doc-comment.rs b/tests/rustdoc-ui/doctest/block-doc-comment.rs index df953dc49bee..84bb5abb244a 100644 --- a/tests/rustdoc-ui/doctest/block-doc-comment.rs +++ b/tests/rustdoc-ui/doctest/block-doc-comment.rs @@ -1,6 +1,6 @@ //@ check-pass //@ compile-flags:--test -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // This test ensures that no code block is detected in the doc comments. diff --git a/tests/rustdoc-ui/doctest/cfg-test.rs b/tests/rustdoc-ui/doctest/cfg-test.rs index 573172349acb..340a2eec87a8 100644 --- a/tests/rustdoc-ui/doctest/cfg-test.rs +++ b/tests/rustdoc-ui/doctest/cfg-test.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test --test-args --test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // Crates like core have doctests gated on `cfg(not(test))` so we need to make // sure `cfg(test)` is not active when running `rustdoc --test`. diff --git a/tests/rustdoc-ui/doctest/check-cfg-test.rs b/tests/rustdoc-ui/doctest/check-cfg-test.rs index b3bff381d64a..39fdb3a5853f 100644 --- a/tests/rustdoc-ui/doctest/check-cfg-test.rs +++ b/tests/rustdoc-ui/doctest/check-cfg-test.rs @@ -1,8 +1,8 @@ //@ check-pass //@ compile-flags: --test --nocapture --check-cfg=cfg(feature,values("test")) -Z unstable-options -//@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stderr: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// The doctest will produce a warning because feature invalid is unexpected /// ``` diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs index 8cdd665ff69d..944939c8efe8 100644 --- a/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs +++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs @@ -1,8 +1,8 @@ //@ compile-flags:--test --test-args --test-threads=1 //@ failure-status: 101 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" //! ``` #![doc = "#![all\ diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs b/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs index 3689ebe166ad..2fbc8a215607 100644 --- a/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs +++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs @@ -4,9 +4,9 @@ //@ compile-flags:--test --test-args --test-threads=1 //@ failure-status: 101 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" /*! ```rust diff --git a/tests/rustdoc-ui/doctest/dead-code-2024.rs b/tests/rustdoc-ui/doctest/dead-code-2024.rs index 41459c5e6512..079d44570bba 100644 --- a/tests/rustdoc-ui/doctest/dead-code-2024.rs +++ b/tests/rustdoc-ui/doctest/dead-code-2024.rs @@ -2,8 +2,8 @@ //@ edition: 2024 //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 #![doc(test(attr(allow(unused_variables), deny(warnings))))] diff --git a/tests/rustdoc-ui/doctest/dead-code.rs b/tests/rustdoc-ui/doctest/dead-code.rs index cb9b4c28f6ce..1ea3e1d53ac2 100644 --- a/tests/rustdoc-ui/doctest/dead-code.rs +++ b/tests/rustdoc-ui/doctest/dead-code.rs @@ -1,8 +1,8 @@ // This test ensures that the doctest will not use `#[allow(unused)]`. //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 #![doc(test(attr(allow(unused_variables), deny(warnings))))] diff --git a/tests/rustdoc-ui/doctest/display-output.rs b/tests/rustdoc-ui/doctest/display-output.rs index 70d15ea6f8a5..d5de341b6962 100644 --- a/tests/rustdoc-ui/doctest/display-output.rs +++ b/tests/rustdoc-ui/doctest/display-output.rs @@ -3,8 +3,8 @@ //@ check-pass //@ edition:2018 //@ compile-flags:--test --test-args=--show-output -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// #![warn(unused)] diff --git a/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.rs b/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.rs index f95d6f82933a..135ecca7ffd9 100644 --- a/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.rs +++ b/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.rs @@ -1,7 +1,7 @@ // Regression test for #97440: Multiline inner attribute triggers ICE during doctest //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass //! ```rust diff --git a/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.rs b/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.rs index 8cafadfdc829..16adb3c6c547 100644 --- a/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.rs +++ b/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.rs @@ -1,6 +1,6 @@ //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass /// ``` diff --git a/tests/rustdoc-ui/doctest/doc-test-doctest-feature.rs b/tests/rustdoc-ui/doctest/doc-test-doctest-feature.rs index fca1f51ed216..9c2d200329a9 100644 --- a/tests/rustdoc-ui/doctest/doc-test-doctest-feature.rs +++ b/tests/rustdoc-ui/doctest/doc-test-doctest-feature.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // Make sure `cfg(doctest)` is set when finding doctests but not inside // the doctests. diff --git a/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.rs b/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.rs index 6d12d7af56ac..dd04adfe6179 100644 --- a/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.rs +++ b/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" #![feature(doc_cfg)] diff --git a/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.rs b/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.rs index b446492e4724..1f80e002ef5d 100644 --- a/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.rs +++ b/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.rs @@ -1,6 +1,6 @@ //@ compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass /// ``` diff --git a/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs b/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs index 58612b682a00..a47bac3daefe 100644 --- a/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs +++ b/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs @@ -1,7 +1,7 @@ //@ edition:2024 //@ compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 // https://github.com/rust-lang/rust/issues/130470 diff --git a/tests/rustdoc-ui/doctest/doctest-output.rs b/tests/rustdoc-ui/doctest/doctest-output.rs index 946bc550b12f..fb4ab0680001 100644 --- a/tests/rustdoc-ui/doctest/doctest-output.rs +++ b/tests/rustdoc-ui/doctest/doctest-output.rs @@ -5,8 +5,8 @@ //@[edition2024]edition:2015 //@[edition2024]aux-build:extern_macros.rs //@[edition2024]compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass //! ``` diff --git a/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.rs b/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.rs index 4d0e035f86e0..6f7b2672b564 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.rs @@ -2,8 +2,8 @@ // adapted to use that, and that normalize line can go away //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ```compile_fail diff --git a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs index b65ef4327058..508faadcf672 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs @@ -2,8 +2,8 @@ // adapted to use that, and that normalize line can go away //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// diff --git a/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.rs b/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.rs index 766d94861437..ded674bf18ae 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.rs @@ -2,8 +2,8 @@ // adapted to use that, and that normalize line can go away //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ```compile_fail,E0004 diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output-windows.rs b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.rs index cf0d8b9daa1c..3a08faf626f1 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-output-windows.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.rs @@ -7,8 +7,8 @@ //@ compile-flags:--test --test-args --test-threads=1 //@ rustc-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 // doctest fails at runtime diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output.rs b/tests/rustdoc-ui/doctest/failed-doctest-output.rs index 160796065f33..84c722688812 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-output.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-output.rs @@ -7,8 +7,8 @@ //@ compile-flags:--test --test-args --test-threads=1 //@ rustc-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 // doctest fails at runtime diff --git a/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.rs b/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.rs index 4fe513b40669..d8c43100d2fc 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.rs @@ -2,8 +2,8 @@ // adapted to use that, and that normalize line can go away //@ compile-flags:--test --edition 2021 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ```should_panic diff --git a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs index d057218688c4..793f86546610 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs @@ -3,8 +3,8 @@ //@ edition: 2024 //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ```should_panic diff --git a/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs index 754791361e8b..7dac64e6de42 100644 --- a/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs +++ b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs @@ -1,7 +1,7 @@ //@ edition: 2024 //@ compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass /// ```ignore (test) diff --git a/tests/rustdoc-ui/doctest/nested-main.rs b/tests/rustdoc-ui/doctest/nested-main.rs index e939ba81214c..d1b3bd6da40c 100644 --- a/tests/rustdoc-ui/doctest/nested-main.rs +++ b/tests/rustdoc-ui/doctest/nested-main.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // Regression test for . // It ensures that if a function called `main` is nested, it will not consider diff --git a/tests/rustdoc-ui/doctest/no-run-flag.rs b/tests/rustdoc-ui/doctest/no-run-flag.rs index 0f7a0a175f12..8f1381e07604 100644 --- a/tests/rustdoc-ui/doctest/no-run-flag.rs +++ b/tests/rustdoc-ui/doctest/no-run-flag.rs @@ -2,8 +2,8 @@ //@ check-pass //@ compile-flags:-Z unstable-options --test --no-run --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// let a = true; diff --git a/tests/rustdoc-ui/doctest/nocapture-fail.rs b/tests/rustdoc-ui/doctest/nocapture-fail.rs index db4062e84941..8c64a49f6500 100644 --- a/tests/rustdoc-ui/doctest/nocapture-fail.rs +++ b/tests/rustdoc-ui/doctest/nocapture-fail.rs @@ -1,8 +1,8 @@ //@ check-pass //@ compile-flags:--test -Zunstable-options --nocapture -//@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stderr: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ```compile_fail /// fn foo() { diff --git a/tests/rustdoc-ui/doctest/nocapture.rs b/tests/rustdoc-ui/doctest/nocapture.rs index 3b87dad49f95..c4360341864f 100644 --- a/tests/rustdoc-ui/doctest/nocapture.rs +++ b/tests/rustdoc-ui/doctest/nocapture.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test -Zunstable-options --nocapture -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// println!("hello!"); diff --git a/tests/rustdoc-ui/doctest/non-local-defs-impl.rs b/tests/rustdoc-ui/doctest/non-local-defs-impl.rs index b1ab5323a2bc..04fdd2855067 100644 --- a/tests/rustdoc-ui/doctest/non-local-defs-impl.rs +++ b/tests/rustdoc-ui/doctest/non-local-defs-impl.rs @@ -3,8 +3,8 @@ //@ failure-status: 101 //@ aux-build:pub_trait.rs //@ compile-flags: --test --test-args --test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" #![doc(test(attr(deny(non_local_definitions))))] #![doc(test(attr(allow(dead_code))))] diff --git a/tests/rustdoc-ui/doctest/non_local_defs.rs b/tests/rustdoc-ui/doctest/non_local_defs.rs index a2f66c392231..ce65ad2cf72c 100644 --- a/tests/rustdoc-ui/doctest/non_local_defs.rs +++ b/tests/rustdoc-ui/doctest/non_local_defs.rs @@ -1,8 +1,8 @@ //@ check-pass //@ compile-flags:--test --test-args --test-threads=1 --nocapture -Zunstable-options -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stderr: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //! ``` //! #[macro_export] diff --git a/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs index 5a1d4d0a60dd..5c9e2978e48a 100644 --- a/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs +++ b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs @@ -7,8 +7,8 @@ //@[edition2024]edition:2024 //@[edition2024]check-pass //@[edition2024]compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // https://github.com/rust-lang/rust/issues/132203 // This version, because it's edition2024, passes thanks to the new diff --git a/tests/rustdoc-ui/doctest/run-directory.rs b/tests/rustdoc-ui/doctest/run-directory.rs index 0e3a30ba4614..090bd19c4d90 100644 --- a/tests/rustdoc-ui/doctest/run-directory.rs +++ b/tests/rustdoc-ui/doctest/run-directory.rs @@ -4,8 +4,8 @@ //@ check-pass //@ [correct]compile-flags:--test --test-run-directory={{src-base}} //@ [incorrect]compile-flags:--test --test-run-directory={{src-base}}/coverage -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// assert_eq!( diff --git a/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs b/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs index 8519920e53be..8d8c60ede585 100644 --- a/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs +++ b/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs @@ -4,8 +4,8 @@ //@ check-pass //@ compile-flags: --test -Zunstable-options --doctest-compilation-args=--cfg=testcase_must_be_present //@ compile-flags: --doctest-compilation-args=--cfg=another -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// #[cfg(testcase_must_be_present)] diff --git a/tests/rustdoc-ui/doctest/rustflags.rs b/tests/rustdoc-ui/doctest/rustflags.rs index fa460e355472..9f1e6017ea15 100644 --- a/tests/rustdoc-ui/doctest/rustflags.rs +++ b/tests/rustdoc-ui/doctest/rustflags.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags: --test -Zunstable-options --doctest-compilation-args=--cfg=testcase_must_be_present -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// #[cfg(testcase_must_be_present)] diff --git a/tests/rustdoc-ui/doctest/standalone-warning-2024.rs b/tests/rustdoc-ui/doctest/standalone-warning-2024.rs index 35d1c738bb16..c53a8b48749c 100644 --- a/tests/rustdoc-ui/doctest/standalone-warning-2024.rs +++ b/tests/rustdoc-ui/doctest/standalone-warning-2024.rs @@ -2,9 +2,9 @@ //@ edition: 2024 //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" #![deny(warnings)] diff --git a/tests/rustdoc-ui/doctest/test-no_std.rs b/tests/rustdoc-ui/doctest/test-no_std.rs index b8af892552de..9abfa4a37286 100644 --- a/tests/rustdoc-ui/doctest/test-no_std.rs +++ b/tests/rustdoc-ui/doctest/test-no_std.rs @@ -1,6 +1,6 @@ //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass #![no_std] diff --git a/tests/rustdoc-ui/doctest/test-type.rs b/tests/rustdoc-ui/doctest/test-type.rs index 846a98a853b5..28c862fb69b6 100644 --- a/tests/rustdoc-ui/doctest/test-type.rs +++ b/tests/rustdoc-ui/doctest/test-type.rs @@ -1,7 +1,7 @@ //@ compile-flags: --test --test-args=--test-threads=1 //@ check-pass -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// let a = true; diff --git a/tests/rustdoc-ui/doctest/unparseable-doc-test.rs b/tests/rustdoc-ui/doctest/unparseable-doc-test.rs index 43acfa6de3f9..d90e152aadab 100644 --- a/tests/rustdoc-ui/doctest/unparseable-doc-test.rs +++ b/tests/rustdoc-ui/doctest/unparseable-doc-test.rs @@ -1,6 +1,6 @@ //@ compile-flags: --test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 //@ rustc-env: RUST_BACKTRACE=0 diff --git a/tests/rustdoc-ui/doctest/wrong-ast-2024.rs b/tests/rustdoc-ui/doctest/wrong-ast-2024.rs index a1455c01bc69..3b4fb3f34433 100644 --- a/tests/rustdoc-ui/doctest/wrong-ast-2024.rs +++ b/tests/rustdoc-ui/doctest/wrong-ast-2024.rs @@ -1,8 +1,8 @@ //@ edition: 2024 //@ compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" //@ failure-status: 101 /// ``` diff --git a/tests/rustdoc-ui/doctest/wrong-ast.rs b/tests/rustdoc-ui/doctest/wrong-ast.rs index 92286b33dcfb..be8f54175869 100644 --- a/tests/rustdoc-ui/doctest/wrong-ast.rs +++ b/tests/rustdoc-ui/doctest/wrong-ast.rs @@ -1,6 +1,6 @@ //@ compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ``` diff --git a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.rs b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.rs index dfa528acb263..032da8f53f0f 100644 --- a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.rs +++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test: "`.*`" -> "`DEF_ID`" -//@ normalize-stdout-test: "`.*`" -> "`DEF_ID`" +//@ normalize-stderr: "`.*`" -> "`DEF_ID`" +//@ normalize-stdout: "`.*`" -> "`DEF_ID`" //@ edition:2018 pub async fn f() -> impl std::fmt::Debug { diff --git a/tests/rustdoc-ui/ice-bug-report-url.rs b/tests/rustdoc-ui/ice-bug-report-url.rs index f270340e07e8..9260644e44f1 100644 --- a/tests/rustdoc-ui/ice-bug-report-url.rs +++ b/tests/rustdoc-ui/ice-bug-report-url.rs @@ -4,12 +4,12 @@ //@ error-pattern: aborting due to //@ error-pattern: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md -//@ normalize-stderr-test: "note: compiler flags.*\n\n" -> "" -//@ normalize-stderr-test: "note: rustc.*running on.*" -> "note: rustc {version} running on {platform}" -//@ normalize-stderr-test: "thread.*panicked at compiler.*" -> "" -//@ normalize-stderr-test: " +\d{1,}: .*\n" -> "" -//@ normalize-stderr-test: " + at .*\n" -> "" -//@ normalize-stderr-test: ".*note: Some details are omitted.*\n" -> "" +//@ normalize-stderr: "note: compiler flags.*\n\n" -> "" +//@ normalize-stderr: "note: rustc.*running on.*" -> "note: rustc {version} running on {platform}" +//@ normalize-stderr: "thread.*panicked at compiler.*" -> "" +//@ normalize-stderr: " +\d{1,}: .*\n" -> "" +//@ normalize-stderr: " + at .*\n" -> "" +//@ normalize-stderr: ".*note: Some details are omitted.*\n" -> "" fn wrong() //~^ ERROR expected one of diff --git a/tests/rustdoc-ui/intra-doc/email-address-localhost.rs b/tests/rustdoc-ui/intra-doc/email-address-localhost.rs index adef39527eb0..3faff8a3cca5 100644 --- a/tests/rustdoc-ui/intra-doc/email-address-localhost.rs +++ b/tests/rustdoc-ui/intra-doc/email-address-localhost.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +//@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" //@ check-pass #![deny(warnings)] diff --git a/tests/rustdoc-ui/intra-doc/unknown-disambiguator.rs b/tests/rustdoc-ui/intra-doc/unknown-disambiguator.rs index 68b818e32b35..86b31cb14d85 100644 --- a/tests/rustdoc-ui/intra-doc/unknown-disambiguator.rs +++ b/tests/rustdoc-ui/intra-doc/unknown-disambiguator.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +//@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" #![deny(warnings)] //! Linking to [foo@banana] and [`bar@banana!()`]. diff --git a/tests/rustdoc-ui/issues/issue-80992.rs b/tests/rustdoc-ui/issues/issue-80992.rs index 31cc8b78ecc4..c328ac53e538 100644 --- a/tests/rustdoc-ui/issues/issue-80992.rs +++ b/tests/rustdoc-ui/issues/issue-80992.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/issues" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/issues" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" pub fn test() -> Result<(), ()> { //! ```compile_fail diff --git a/tests/rustdoc-ui/issues/issue-81662-shortness.rs b/tests/rustdoc-ui/issues/issue-81662-shortness.rs index 7df63261ce7e..8719442c34f9 100644 --- a/tests/rustdoc-ui/issues/issue-81662-shortness.rs +++ b/tests/rustdoc-ui/issues/issue-81662-shortness.rs @@ -1,8 +1,8 @@ //@ compile-flags:--test --error-format=short //@ check-stdout //@ error-pattern:cannot find function `foo` -//@ normalize-stdout-test: "tests/rustdoc-ui/issues" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/issues" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ```rust diff --git a/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs b/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs index a7b1c734d7f5..35d2fda45850 100644 --- a/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs +++ b/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs @@ -6,5 +6,5 @@ // // ignore-tidy-linelength // -//@ normalize-stdout-test: "( +name default meaning\n +---- ------- -------\n)?( *[[:word:]:-]+ (allow |warn |deny |forbid ) [^\n]+\n)+" -> " $$NAMES $$LEVELS $$MEANINGS" -//@ normalize-stdout-test: " +name sub-lints\n +---- ---------\n( *[[:word:]:-]+ [^\n]+\n)+" -> " $$NAMES $$SUB_LINTS" +//@ normalize-stdout: "( +name default meaning\n +---- ------- -------\n)?( *[[:word:]:-]+ (allow |warn |deny |forbid ) [^\n]+\n)+" -> " $$NAMES $$LEVELS $$MEANINGS" +//@ normalize-stdout: " +name sub-lints\n +---- ---------\n( *[[:word:]:-]+ [^\n]+\n)+" -> " $$NAMES $$SUB_LINTS" diff --git a/tests/rustdoc-ui/issues/issue-91134.rs b/tests/rustdoc-ui/issues/issue-91134.rs index 6b1fec957eac..1c53ecfeb8b7 100644 --- a/tests/rustdoc-ui/issues/issue-91134.rs +++ b/tests/rustdoc-ui/issues/issue-91134.rs @@ -1,8 +1,8 @@ //@ compile-flags: --test --crate-name=empty_fn --extern=empty_fn --test-args=--test-threads=1 //@ aux-build:empty-fn.rs //@ check-pass -//@ normalize-stdout-test: "tests/rustdoc-ui/issues" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/issues" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ edition:2021 /// diff --git a/tests/rustdoc-ui/lints/check.rs b/tests/rustdoc-ui/lints/check.rs index 058c5d6c468f..61c9f1889529 100644 --- a/tests/rustdoc-ui/lints/check.rs +++ b/tests/rustdoc-ui/lints/check.rs @@ -1,6 +1,6 @@ //@ check-pass //@ compile-flags: -Z unstable-options --check -//@ normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +//@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" #![feature(rustdoc_missing_doc_code_examples)] //~^ WARN diff --git a/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs index 12d4892d36a8..6e631061e8ac 100644 --- a/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs +++ b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs @@ -1,5 +1,5 @@ //@ error-pattern: no documentation found -//@ normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +//@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" #![deny(rustdoc::missing_crate_level_docs)] //^~ NOTE defined here diff --git a/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs index 57c0c1af031b..72c3330709a7 100644 --- a/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs +++ b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs @@ -4,8 +4,8 @@ //@ failure-status: 101 //@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 //@ rustc-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ normalize-stdout-test: "exit (status|code): 101" -> "exit status: 101" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "exit (status|code): 101" -> "exit status: 101" // doctest fails at runtime /// ``` diff --git a/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs index 96a79e85f6be..c18a416d43f0 100644 --- a/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs +++ b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs @@ -4,7 +4,7 @@ //@ failure-status: 101 //@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 //@ rustc-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // doctest fails to compile /// ``` diff --git a/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs index 4c61c43578cd..6fa04ef77f32 100644 --- a/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs +++ b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs @@ -5,7 +5,7 @@ // adapted to use that, and that normalize line can go away //@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // doctest passes at runtime /// ``` diff --git a/tests/rustdoc-ui/track-diagnostics.rs b/tests/rustdoc-ui/track-diagnostics.rs index 403b8c789174..5c950a11082f 100644 --- a/tests/rustdoc-ui/track-diagnostics.rs +++ b/tests/rustdoc-ui/track-diagnostics.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" struct A; struct B; diff --git a/tests/rustdoc/inline_local/parent-path-is-better.rs b/tests/rustdoc/inline_local/parent-path-is-better.rs new file mode 100644 index 000000000000..086540d54441 --- /dev/null +++ b/tests/rustdoc/inline_local/parent-path-is-better.rs @@ -0,0 +1,40 @@ +//! Test case for [134702] +//! +//! [134702]: https://github.com/rust-lang/rust/issues/134702 +#![crate_name = "foo"] + +pub mod inside1 { + pub use self::inner::Inside1; + mod inner { + pub struct Inside1; + impl Inside1 { + pub fn stuff(self) {} + } + } +} + +pub mod inside2 { + pub use self::inner::Inside2; + mod inner { + pub struct Inside2; + impl Inside2 { + pub fn stuff(self) {} + } + } +} + +pub mod nested { + //! [Inside1] [Inside2] + //@ has foo/nested/index.html '//a[@href="../struct.Inside1.html"]' 'Inside1' + //@ has foo/nested/index.html '//a[@href="../struct.Inside2.html"]' 'Inside2' + //! [Inside1::stuff] [Inside2::stuff] + //@ has foo/nested/index.html '//a[@href="../struct.Inside1.html#method.stuff"]' 'Inside1::stuff' + //@ has foo/nested/index.html '//a[@href="../struct.Inside2.html#method.stuff"]' 'Inside2::stuff' + use crate::inside1::Inside1; + use crate::inside2::Inside2; +} + +#[doc(inline)] +pub use inside1::Inside1; +#[doc(inline)] +pub use inside2::Inside2; diff --git a/tests/rustdoc/intra-doc/pub-use.rs b/tests/rustdoc/intra-doc/pub-use.rs index 7c70adad7d96..5aeb3eb149ee 100644 --- a/tests/rustdoc/intra-doc/pub-use.rs +++ b/tests/rustdoc/intra-doc/pub-use.rs @@ -7,7 +7,7 @@ extern crate inner; /// [mod@std::env] [g] //@ has outer/index.html //@ has - '//a[@href="{{channel}}/std/env/index.html"]' "std::env" -//@ has - '//a[@href="fn.f.html"]' "g" +//@ has - '//a[@href="fn.g.html"]' "g" pub use f as g; // Make sure the documentation is actually correct by documenting an inlined re-export diff --git a/tests/ui-fulldeps/codegen-backend/hotplug.rs b/tests/ui-fulldeps/codegen-backend/hotplug.rs index dc0fb3f9efd0..917b20fcdb56 100644 --- a/tests/ui-fulldeps/codegen-backend/hotplug.rs +++ b/tests/ui-fulldeps/codegen-backend/hotplug.rs @@ -3,8 +3,8 @@ //@ ignore-stage1 (requires matching sysroot built with in-tree compiler) //@ aux-codegen-backend: the_backend.rs -//@ normalize-stdout-test: "libthe_backend.dylib" -> "libthe_backend.so" -//@ normalize-stdout-test: "the_backend.dll" -> "libthe_backend.so" +//@ normalize-stdout: "libthe_backend.dylib" -> "libthe_backend.so" +//@ normalize-stdout: "the_backend.dll" -> "libthe_backend.so" //@ revisions: normal dep bindep //@ compile-flags: --crate-type=lib diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs index 3361ebcef018..c1f5fe730c76 100644 --- a/tests/ui-fulldeps/fluent-messages/test.rs +++ b/tests/ui-fulldeps/fluent-messages/test.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "could not open Fluent resource:.*" -> "could not open Fluent resource: os-specific message" +//@ normalize-stderr: "could not open Fluent resource:.*" -> "could not open Fluent resource: os-specific message" #![feature(rustc_private)] #![crate_type = "lib"] diff --git a/tests/ui-fulldeps/missing-rustc-driver-error.rs b/tests/ui-fulldeps/missing-rustc-driver-error.rs index 23ca39363bcd..03ab5ce7b253 100644 --- a/tests/ui-fulldeps/missing-rustc-driver-error.rs +++ b/tests/ui-fulldeps/missing-rustc-driver-error.rs @@ -1,8 +1,8 @@ // Test that we get the following hint when trying to use a compiler crate without rustc_driver. //@ error-pattern: try adding `extern crate rustc_driver;` at the top level of this crate //@ compile-flags: --emit link -//@ normalize-stderr-test: ".*crate .* required.*\n\n" -> "" -//@ normalize-stderr-test: "aborting due to [0-9]+" -> "aborting due to NUMBER" +//@ normalize-stderr: ".*crate .* required.*\n\n" -> "" +//@ normalize-stderr: "aborting due to [0-9]+" -> "aborting due to NUMBER" #![feature(rustc_private)] diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index 94c7964392d1..2b41020d3071 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -77,6 +77,9 @@ static EXPRS: &[&str] = &[ // These mean different things. "if let _ = true && false {}", "if let _ = (true && false) {}", + // Parentheses to call a named field, but not an unnamed field. + "(self.fun)()", + "self.0()", // Conditions end at the first curly brace, so struct expressions need to be // parenthesized. Except in a match guard, where conditions end at arrow. "if let _ = (Struct {}) {}", @@ -108,6 +111,10 @@ static EXPRS: &[&str] = &[ "{ (match 2 {})() - 1 }", "{ (match 2 {})[0] - 1 }", "{ (loop {}) - 1 }", + "match 2 { _ => (loop {}) - 1 }", + // No eager statement boundary if followed by `.` or `?`. + "{ loop {}.to_string() - 1 }", + "match 2 { _ => loop {}.to_string() - 1 }", // Angle bracket is eagerly parsed as a path's generic argument list. "(2 as T) < U", "(2 as T) < V", // FIXME: no parentheses needed. diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs index 7921ede23c57..37f78a7777c4 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs @@ -1,7 +1,7 @@ //@ check-fail // Tests that a doc comment will not preclude a field from being considered a diagnostic argument -//@ normalize-stderr-test: "the following other types implement trait `IntoDiagArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" -//@ normalize-stderr-test: "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC" +//@ normalize-stderr: "the following other types implement trait `IntoDiagArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" +//@ normalize-stderr: "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC" // The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, // changing the output of this test. Since Subdiagnostic is strictly internal to the compiler diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 1577b68e748f..fa2d037064d2 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -1,7 +1,7 @@ //@ check-fail // Tests error conditions for specifying diagnostics using #[derive(Diagnostic)] -//@ normalize-stderr-test: "the following other types implement trait `IntoDiagArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" -//@ normalize-stderr-test: "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC" +//@ normalize-stderr: "the following other types implement trait `IntoDiagArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" +//@ normalize-stderr: "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC" // The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, // changing the output of this test. Since Diagnostic is strictly internal to the compiler diff --git a/tests/ui/abi/c-zst.rs b/tests/ui/abi/c-zst.rs index 69ebefa09acb..6b299ffadb7b 100644 --- a/tests/ui/abi/c-zst.rs +++ b/tests/ui/abi/c-zst.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" +//@ normalize-stderr: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" /*! C doesn't have zero-sized types... except it does. diff --git a/tests/ui/abi/debug.rs b/tests/ui/abi/debug.rs index 16d616027341..565743bf978e 100644 --- a/tests/ui/abi/debug.rs +++ b/tests/ui/abi/debug.rs @@ -1,9 +1,9 @@ -//@ normalize-stderr-test: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" -//@ normalize-stderr-test: "(size): Size\([48] bytes\)" -> "$1: $$SOME_SIZE" -//@ normalize-stderr-test: "(can_unwind): (true|false)" -> "$1: $$SOME_BOOL" -//@ normalize-stderr-test: "(valid_range): 0\.\.=(4294967295|18446744073709551615)" -> "$1: $$FULL" +//@ normalize-stderr: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" +//@ normalize-stderr: "(size): Size\([48] bytes\)" -> "$1: $$SOME_SIZE" +//@ normalize-stderr: "(can_unwind): (true|false)" -> "$1: $$SOME_BOOL" +//@ normalize-stderr: "(valid_range): 0\.\.=(4294967295|18446744073709551615)" -> "$1: $$FULL" // This pattern is prepared for when we account for alignment in the niche. -//@ normalize-stderr-test: "(valid_range): [1-9]\.\.=(429496729[0-9]|1844674407370955161[0-9])" -> "$1: $$NON_NULL" +//@ normalize-stderr: "(valid_range): [1-9]\.\.=(429496729[0-9]|1844674407370955161[0-9])" -> "$1: $$NON_NULL" // Some attributes are only computed for release builds: //@ compile-flags: -O #![feature(rustc_attrs)] diff --git a/tests/ui/abi/sysv64-zst.rs b/tests/ui/abi/sysv64-zst.rs index 6f4497e77a18..42ba1fb5f03a 100644 --- a/tests/ui/abi/sysv64-zst.rs +++ b/tests/ui/abi/sysv64-zst.rs @@ -1,5 +1,5 @@ //@ only-x86_64 -//@ normalize-stderr-test: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" +//@ normalize-stderr: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" #![feature(rustc_attrs)] #![crate_type = "lib"] diff --git a/tests/ui/abi/win64-zst.rs b/tests/ui/abi/win64-zst.rs index a2f7d19eb459..bc4e0e629eb4 100644 --- a/tests/ui/abi/win64-zst.rs +++ b/tests/ui/abi/win64-zst.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" +//@ normalize-stderr: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" //@ only-x86_64 //@ revisions: x86_64-linux diff --git a/tests/ui/argfile/commandline-argfile-missing-windows.rs b/tests/ui/argfile/commandline-argfile-missing-windows.rs index 24cfd25ccadb..1a1cf6b9e75e 100644 --- a/tests/ui/argfile/commandline-argfile-missing-windows.rs +++ b/tests/ui/argfile/commandline-argfile-missing-windows.rs @@ -5,8 +5,8 @@ // line arguments and is only run on windows. // //@ only-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args #[cfg(not(cmdline_set))] diff --git a/tests/ui/argfile/commandline-argfile-missing.rs b/tests/ui/argfile/commandline-argfile-missing.rs index fe6a849b0c8b..8d9335f5add5 100644 --- a/tests/ui/argfile/commandline-argfile-missing.rs +++ b/tests/ui/argfile/commandline-argfile-missing.rs @@ -6,8 +6,8 @@ // windows. // //@ ignore-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args #[cfg(not(cmdline_set))] diff --git a/tests/ui/argfile/commandline-argfile-multiple-windows.rs b/tests/ui/argfile/commandline-argfile-multiple-windows.rs index 84c050d84e25..9cbbd505c57b 100644 --- a/tests/ui/argfile/commandline-argfile-multiple-windows.rs +++ b/tests/ui/argfile/commandline-argfile-multiple-windows.rs @@ -5,9 +5,9 @@ // line arguments and is only run on windows. // //@ only-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " -//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args @{{src-base}}\argfile\commandline-argfile-badutf8.args @{{src-base}}\argfile\commandline-argfile-missing2.args #[cfg(not(cmdline_set))] diff --git a/tests/ui/argfile/commandline-argfile-multiple.rs b/tests/ui/argfile/commandline-argfile-multiple.rs index f658ee34fbb0..f211a50892c5 100644 --- a/tests/ui/argfile/commandline-argfile-multiple.rs +++ b/tests/ui/argfile/commandline-argfile-multiple.rs @@ -6,9 +6,9 @@ // windows. // //@ ignore-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " -//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args @{{src-base}}/argfile/commandline-argfile-badutf8.args @{{src-base}}/argfile/commandline-argfile-missing2.args #[cfg(not(cmdline_set))] diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr index cf5d8f614dda..7f8ed8985252 100644 --- a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr +++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr @@ -4,12 +4,12 @@ error[E0391]: cycle detected when computing predicates of `Foo` LL | struct Foo { | ^^^^^^^^^^ | -note: ...which requires computing inferred outlives predicates of `Foo`... +note: ...which requires computing inferred outlives-predicates of `Foo`... --> $DIR/cycle-iat-inside-of-adt.rs:7:1 | LL | struct Foo { | ^^^^^^^^^^ - = note: ...which requires computing the inferred outlives predicates for items in this crate... + = note: ...which requires computing the inferred outlives-predicates for items in this crate... note: ...which requires computing type of `Foo::bar`... --> $DIR/cycle-iat-inside-of-adt.rs:8:5 | diff --git a/tests/ui/associated-types/associated-types-eq-2.rs b/tests/ui/associated-types/associated-types-eq-2.rs index 88eb29810610..9d2860d1b309 100644 --- a/tests/ui/associated-types/associated-types-eq-2.rs +++ b/tests/ui/associated-types/associated-types-eq-2.rs @@ -33,7 +33,7 @@ fn baz(_x: &>::A) {} trait Tr2 { } -// Test for when wrongly specifed equality constraint's ident +// Test for when wrongly specified equality constraint's ident // matches some generic param's ident // (Note: E0229 is emitted only for the first erroneous equality // constraint (T2) not for any subequent ones (e.g. T3)) diff --git a/tests/ui/associated-types/associated-types-in-ambiguous-context.rs b/tests/ui/associated-types/associated-types-in-ambiguous-context.rs index 98bbff794ca4..3c0d66f8a0d2 100644 --- a/tests/ui/associated-types/associated-types-in-ambiguous-context.rs +++ b/tests/ui/associated-types/associated-types-in-ambiguous-context.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "and \d+ other candidates" -> "and N other candidates" +//@ normalize-stderr: "and \d+ other candidates" -> "and N other candidates" trait Get { type Value; diff --git a/tests/ui/associated-types/project-defer-unification.rs b/tests/ui/associated-types/project-defer-unification.rs index cec088496fd3..b51228ef4117 100644 --- a/tests/ui/associated-types/project-defer-unification.rs +++ b/tests/ui/associated-types/project-defer-unification.rs @@ -93,7 +93,7 @@ where Pix: Pixel + 'static, let mut indices: ImageBuffer<_,Vec<_>> = loop { }; for (pixel, idx) in image.pixels().zip(indices.pixels_mut()) { - // failured occurred here ^^ because we were requiring that we + // failure occurred here ^^ because we were requiring that we // could project Pixel or Subpixel from `T_indices` (type of // `indices`), but the type is insufficiently constrained // until we reach the return below. diff --git a/tests/ui/attributes/dump-preds.rs b/tests/ui/attributes/dump-preds.rs index ca38e23b237c..071a7baede52 100644 --- a/tests/ui/attributes/dump-preds.rs +++ b/tests/ui/attributes/dump-preds.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "DefId\(.+?\)" -> "DefId(..)" +//@ normalize-stderr: "DefId\(.+?\)" -> "DefId(..)" #![feature(rustc_attrs)] diff --git a/tests/ui/attributes/dump_def_parents.rs b/tests/ui/attributes/dump_def_parents.rs index 04a725f6c144..af117e4fa636 100644 --- a/tests/ui/attributes/dump_def_parents.rs +++ b/tests/ui/attributes/dump_def_parents.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "DefId\(.+?\)" -> "DefId(..)" +//@ normalize-stderr: "DefId\(.+?\)" -> "DefId(..)" #![feature(rustc_attrs)] fn bar() { diff --git a/tests/ui/attributes/extented-attribute-macro-error.rs b/tests/ui/attributes/extented-attribute-macro-error.rs index 5dcb38d7da9d..83060024dac9 100644 --- a/tests/ui/attributes/extented-attribute-macro-error.rs +++ b/tests/ui/attributes/extented-attribute-macro-error.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "couldn't read.*" -> "couldn't read the file" +//@ normalize-stderr: "couldn't read.*" -> "couldn't read the file" #![doc = include_str!("../not_existing_file.md")] struct Documented {} diff --git a/tests/crashes/133252.rs b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.rs similarity index 81% rename from tests/crashes/133252.rs rename to tests/ui/borrowck/implementation-not-general-enough-ice-133252.rs index 3cecf448287b..7ee16e62b9a7 100644 --- a/tests/crashes/133252.rs +++ b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.rs @@ -1,4 +1,4 @@ -//@ known-bug: #133252 +// Regression test for borrowck ICE #133252 //@ edition:2021 use std::future::Future; @@ -7,6 +7,8 @@ fn ice() -> impl Future { async { let not_static = 0; force_send(async_load(¬_static)); + //~^ ERROR implementation of `LoadQuery` is not general enough + //~| ERROR `not_static` does not live long enough loop {} } } @@ -41,3 +43,5 @@ impl Future for SimpleFuture { loop {} } } + +fn main() {} diff --git a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr new file mode 100644 index 000000000000..13c768dcbf63 --- /dev/null +++ b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr @@ -0,0 +1,34 @@ +error: implementation of `LoadQuery` is not general enough + --> $DIR/implementation-not-general-enough-ice-133252.rs:9:9 + | +LL | force_send(async_load(¬_static)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `LoadQuery` is not general enough + | + = note: `LoadQuery<'0>` would have to be implemented for the type `&u8`, for any lifetime `'0`... + = note: ...but `LoadQuery<'1>` is actually implemented for the type `&'1 u8`, for some specific lifetime `'1` + +error[E0597]: `not_static` does not live long enough + --> $DIR/implementation-not-general-enough-ice-133252.rs:9:31 + | +LL | async { + | - return type of async block is &(dyn Owned + '1) +LL | let not_static = 0; + | ---------- binding `not_static` declared here +LL | force_send(async_load(¬_static)); + | -----------^^^^^^^^^^^- + | | | + | | borrowed value does not live long enough + | argument requires that `not_static` is borrowed for `'1` +... +LL | } + | - `not_static` dropped here while still borrowed + | +note: due to current limitations in the borrow checker, this implies a `'static` lifetime + --> $DIR/implementation-not-general-enough-ice-133252.rs:16:18 + | +LL | fn force_send(_: T) {} + | ^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/check-cfg/and-more-diagnostic.rs b/tests/ui/check-cfg/and-more-diagnostic.rs index 82867f3b4354..977f55e8a6d1 100644 --- a/tests/ui/check-cfg/and-more-diagnostic.rs +++ b/tests/ui/check-cfg/and-more-diagnostic.rs @@ -4,8 +4,8 @@ //@ check-pass //@ no-auto-check-cfg //@ compile-flags: --check-cfg=cfg() -//@ normalize-stderr-test: "and \d+ more" -> "and X more" -//@ normalize-stderr-test: "`[a-zA-Z0-9_-]+`" -> "`xxx`" +//@ normalize-stderr: "and \d+ more" -> "and X more" +//@ normalize-stderr: "`[a-zA-Z0-9_-]+`" -> "`xxx`" fn main() { cfg!(target_feature = "zebra"); diff --git a/tests/ui/check-cfg/target_feature.rs b/tests/ui/check-cfg/target_feature.rs index 6028dae66c4d..3c0f1a3c2f62 100644 --- a/tests/ui/check-cfg/target_feature.rs +++ b/tests/ui/check-cfg/target_feature.rs @@ -10,7 +10,7 @@ //@ check-pass //@ no-auto-check-cfg //@ compile-flags: --check-cfg=cfg() -Zcheck-cfg-all-expected -//@ normalize-stderr-test: "`, `" -> "`\n`" +//@ normalize-stderr: "`, `" -> "`\n`" fn main() { cfg!(target_feature = "_UNEXPECTED_VALUE"); diff --git a/tests/ui/codegen/mismatched-data-layouts.rs b/tests/ui/codegen/mismatched-data-layouts.rs index 7d63895c65ba..955f917ee332 100644 --- a/tests/ui/codegen/mismatched-data-layouts.rs +++ b/tests/ui/codegen/mismatched-data-layouts.rs @@ -4,8 +4,8 @@ //@ needs-llvm-components: x86 //@ compile-flags: --crate-type=lib --target={{src-base}}/codegen/mismatched-data-layout.json -Z unstable-options //@ error-pattern: differs from LLVM target's -//@ normalize-stderr-test: "`, `[A-Za-z0-9-:]*`" -> "`, `normalized data layout`" -//@ normalize-stderr-test: "layout, `[A-Za-z0-9-:]*`" -> "layout, `normalized data layout`" +//@ normalize-stderr: "`, `[A-Za-z0-9-:]*`" -> "`, `normalized data layout`" +//@ normalize-stderr: "layout, `[A-Za-z0-9-:]*`" -> "layout, `normalized data layout`" #![feature(lang_items, no_core, auto_traits)] #![no_core] diff --git a/tests/ui/codegen/target-cpus.rs b/tests/ui/codegen/target-cpus.rs index 363915c6419b..f26203171f33 100644 --- a/tests/ui/codegen/target-cpus.rs +++ b/tests/ui/codegen/target-cpus.rs @@ -6,4 +6,4 @@ // output so that the stdout with LLVM-at-HEAD matches the output of the LLVM // versions currently used by default. // FIXME(#133919): Once Rust upgrades to LLVM 20, remove this. -//@ normalize-stdout-test: "(?m)^ *lime1\n" -> "" +//@ normalize-stdout: "(?m)^ *lime1\n" -> "" diff --git a/tests/ui/compiletest-self-test/normalize-with-revision.a.run.stderr b/tests/ui/compiletest-self-test/normalize-with-revision.a.run.stderr new file mode 100644 index 000000000000..3eb3f6b4e571 --- /dev/null +++ b/tests/ui/compiletest-self-test/normalize-with-revision.a.run.stderr @@ -0,0 +1,2 @@ +1st emitted line +second emitted line diff --git a/tests/ui/compiletest-self-test/normalize-with-revision.b.run.stderr b/tests/ui/compiletest-self-test/normalize-with-revision.b.run.stderr new file mode 100644 index 000000000000..8d9156480abf --- /dev/null +++ b/tests/ui/compiletest-self-test/normalize-with-revision.b.run.stderr @@ -0,0 +1,2 @@ +first emitted line +2nd emitted line diff --git a/tests/ui/compiletest-self-test/normalize-with-revision.rs b/tests/ui/compiletest-self-test/normalize-with-revision.rs new file mode 100644 index 000000000000..e1bbbb3eabb7 --- /dev/null +++ b/tests/ui/compiletest-self-test/normalize-with-revision.rs @@ -0,0 +1,20 @@ +//! Checks that `[rev] normalize-*` directives affect the specified revision, +//! and don't affect other revisions. +//! +//! This currently relies on the fact that `normalize-*` directives are +//! applied to run output, not just compiler output. If that ever changes, +//! this test might need to be adjusted. + +//@ edition: 2021 +//@ revisions: a b +//@ run-pass +//@ check-run-results + +//@ normalize-stderr: "output" -> "emitted" +//@[a] normalize-stderr: "first" -> "1st" +//@[b] normalize-stderr: "second" -> "2nd" + +fn main() { + eprintln!("first output line"); + eprintln!("second output line"); +} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs index 30851b49cdca..73357d208c04 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs @@ -1,9 +1,9 @@ //@ check-fail //@ known-bug: #97477 //@ failure-status: 101 -//@ normalize-stderr-test: "note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*\n" -> "" -//@ normalize-stderr-test: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr: "note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " //@ rustc-env:RUST_BACKTRACE=0 // This test used to cause an ICE in rustc_mir::interpret::step::eval_rvalue_into_place diff --git a/tests/ui/const-generics/transmute-fail.rs b/tests/ui/const-generics/transmute-fail.rs index 95c711605675..cf9064bd8f4b 100644 --- a/tests/ui/const-generics/transmute-fail.rs +++ b/tests/ui/const-generics/transmute-fail.rs @@ -1,6 +1,5 @@ // ignore-tidy-linelength -//@ normalize-stderr-32bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" -//@ normalize-stderr-64bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" +//@ normalize-stderr: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" #![feature(transmute_generic_consts)] diff --git a/tests/ui/const-generics/transmute-fail.stderr b/tests/ui/const-generics/transmute-fail.stderr index 638ce790345a..978a9744e88a 100644 --- a/tests/ui/const-generics/transmute-fail.stderr +++ b/tests/ui/const-generics/transmute-fail.stderr @@ -1,11 +1,11 @@ error: the constant `W` is not of type `usize` - --> $DIR/transmute-fail.rs:17:42 + --> $DIR/transmute-fail.rs:16:42 | LL | fn bar(v: [[u32; H]; W]) -> [[u32; W]; H] { | ^^^^^^^^^^^^^ expected `usize`, found `bool` error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:12:9 + --> $DIR/transmute-fail.rs:11:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -14,13 +14,13 @@ LL | std::mem::transmute(v) = note: target type: `[[u32; W + 1]; H]` (size can vary because of [u32; W + 1]) error: the constant `W` is not of type `usize` - --> $DIR/transmute-fail.rs:20:9 + --> $DIR/transmute-fail.rs:19:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:27:9 + --> $DIR/transmute-fail.rs:26:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | std::mem::transmute(v) = note: target type: `[u32; W * H * H]` (this type does not have a fixed size) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:34:9 + --> $DIR/transmute-fail.rs:33:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | std::mem::transmute(v) = note: target type: `[[[u32; 9999999]; 777777777]; 8888888]` (values of the type $REALLY_TOO_BIG are too big for the target architecture) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:40:14 + --> $DIR/transmute-fail.rs:39:14 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | unsafe { std::mem::transmute(v) } = note: target type: `[[[u32; 9999999]; 777777777]; 239]` (values of the type $REALLY_TOO_BIG are too big for the target architecture) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:46:9 + --> $DIR/transmute-fail.rs:45:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | std::mem::transmute(v) = note: target type: `[[u32; W]; H]` (size can vary because of [u32; W]) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:57:9 + --> $DIR/transmute-fail.rs:56:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | std::mem::transmute(v) = note: target type: `[u32; W * H]` (this type does not have a fixed size) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:64:9 + --> $DIR/transmute-fail.rs:63:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -74,7 +74,7 @@ LL | std::mem::transmute(v) = note: target type: `[[u32; W]; H]` (size can vary because of [u32; W]) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:73:9 + --> $DIR/transmute-fail.rs:72:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -83,7 +83,7 @@ LL | std::mem::transmute(v) = note: target type: `[u32; D * W * H]` (this type does not have a fixed size) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:82:9 + --> $DIR/transmute-fail.rs:81:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -92,7 +92,7 @@ LL | std::mem::transmute(v) = note: target type: `[[u32; D * W]; H]` (size can vary because of [u32; D * W]) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:89:9 + --> $DIR/transmute-fail.rs:88:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -101,7 +101,7 @@ LL | std::mem::transmute(v) = note: target type: `[u8; L * 2]` (this type does not have a fixed size) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:96:9 + --> $DIR/transmute-fail.rs:95:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -110,7 +110,7 @@ LL | std::mem::transmute(v) = note: target type: `[u16; L]` (this type does not have a fixed size) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:103:9 + --> $DIR/transmute-fail.rs:102:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -119,7 +119,7 @@ LL | std::mem::transmute(v) = note: target type: `[[u8; 1]; L]` (this type does not have a fixed size) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:112:9 + --> $DIR/transmute-fail.rs:111:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/const-ptr/forbidden_slices.rs b/tests/ui/const-ptr/forbidden_slices.rs index bc4993466eb1..59ea92c5ab38 100644 --- a/tests/ui/const-ptr/forbidden_slices.rs +++ b/tests/ui/const-ptr/forbidden_slices.rs @@ -1,6 +1,6 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature( slice_from_ptr_range, diff --git a/tests/ui/consts/const-eval/const-eval-query-stack.rs b/tests/ui/consts/const-eval/const-eval-query-stack.rs index c015c5e0c498..8de398787b41 100644 --- a/tests/ui/consts/const-eval/const-eval-query-stack.rs +++ b/tests/ui/consts/const-eval/const-eval-query-stack.rs @@ -1,16 +1,16 @@ //@ compile-flags: -Ztreat-err-as-bug=1 //@ failure-status: 101 //@ rustc-env:RUST_BACKTRACE=1 -//@ normalize-stderr-test: "\nerror: .*unexpectedly panicked.*\n\n" -> "" -//@ normalize-stderr-test: "note: we would appreciate a bug report.*\n\n" -> "" -//@ normalize-stderr-test: "note: compiler flags.*\n\n" -> "" -//@ normalize-stderr-test: "note: rustc.*running on.*\n\n" -> "" -//@ normalize-stderr-test: "thread.*panicked.*:\n.*\n" -> "" -//@ normalize-stderr-test: "stack backtrace:\n" -> "" -//@ normalize-stderr-test: "\s\d{1,}: .*\n" -> "" -//@ normalize-stderr-test: "\s at .*\n" -> "" -//@ normalize-stderr-test: ".*note: Some details.*\n" -> "" -//@ normalize-stderr-test: ".*omitted \d{1,} frame.*\n" -> "" +//@ normalize-stderr: "\nerror: .*unexpectedly panicked.*\n\n" -> "" +//@ normalize-stderr: "note: we would appreciate a bug report.*\n\n" -> "" +//@ normalize-stderr: "note: compiler flags.*\n\n" -> "" +//@ normalize-stderr: "note: rustc.*running on.*\n\n" -> "" +//@ normalize-stderr: "thread.*panicked.*:\n.*\n" -> "" +//@ normalize-stderr: "stack backtrace:\n" -> "" +//@ normalize-stderr: "\s\d{1,}: .*\n" -> "" +//@ normalize-stderr: "\s at .*\n" -> "" +//@ normalize-stderr: ".*note: Some details.*\n" -> "" +//@ normalize-stderr: ".*omitted \d{1,} frame.*\n" -> "" #![allow(unconditional_panic)] const X: i32 = 1 / 0; //~ERROR constant diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs index 3054e79770d9..509c872f6095 100644 --- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs +++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs @@ -2,9 +2,9 @@ #![feature(const_heap)] // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -//@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" use std::intrinsics; diff --git a/tests/ui/consts/const-eval/raw-bytes.rs b/tests/ui/consts/const-eval/raw-bytes.rs index 0df732df30e1..9187de563620 100644 --- a/tests/ui/consts/const-eval/raw-bytes.rs +++ b/tests/ui/consts/const-eval/raw-bytes.rs @@ -1,7 +1,7 @@ //@ stderr-per-bitwidth //@ ignore-endian-big // ignore-tidy-linelength -//@ normalize-stderr-test: "╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼" -> "╾ALLOC_ID$1╼" +//@ normalize-stderr: "╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼" -> "╾ALLOC_ID$1╼" #![allow(invalid_value)] #![feature(never_type, rustc_attrs, ptr_metadata, slice_from_ptr_range, const_slice_from_ptr_range)] diff --git a/tests/ui/consts/const-eval/ub-enum.rs b/tests/ui/consts/const-eval/ub-enum.rs index 728c1666deb6..11cd87023d17 100644 --- a/tests/ui/consts/const-eval/ub-enum.rs +++ b/tests/ui/consts/const-eval/ub-enum.rs @@ -1,7 +1,7 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -//@ normalize-stderr-test: "0x0+" -> "0x0" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "0x0+" -> "0x0" #![feature(never_type)] #![allow(invalid_value)] diff --git a/tests/ui/consts/const-eval/ub-nonnull.rs b/tests/ui/consts/const-eval/ub-nonnull.rs index 47d3ca97fda7..b8e312759b4c 100644 --- a/tests/ui/consts/const-eval/ub-nonnull.rs +++ b/tests/ui/consts/const-eval/ub-nonnull.rs @@ -1,6 +1,6 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP" #![allow(invalid_value)] // make sure we cannot allow away the errors tested here #![feature(rustc_attrs, ptr_metadata)] diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.rs b/tests/ui/consts/const-eval/ub-ref-ptr.rs index 44b25a6438ea..78d6fb5b65ba 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.rs +++ b/tests/ui/consts/const-eval/ub-ref-ptr.rs @@ -1,7 +1,7 @@ // ignore-tidy-linelength // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![allow(invalid_value)] use std::mem; diff --git a/tests/ui/consts/const-eval/ub-uninhabit.rs b/tests/ui/consts/const-eval/ub-uninhabit.rs index 0167de26e942..d0515a4e6f06 100644 --- a/tests/ui/consts/const-eval/ub-uninhabit.rs +++ b/tests/ui/consts/const-eval/ub-uninhabit.rs @@ -1,6 +1,6 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(core_intrinsics)] #![feature(never_type)] diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.rs b/tests/ui/consts/const-eval/ub-wide-ptr.rs index 991d4424dcf9..a071a44272b4 100644 --- a/tests/ui/consts/const-eval/ub-wide-ptr.rs +++ b/tests/ui/consts/const-eval/ub-wide-ptr.rs @@ -5,10 +5,10 @@ use std::{ptr, mem}; // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -//@ normalize-stderr-test: "offset \d+" -> "offset N" -//@ normalize-stderr-test: "size \d+" -> "size N" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "offset \d+" -> "offset N" +//@ normalize-stderr: "size \d+" -> "size N" /// A newtype wrapper to prevent MIR generation from inserting reborrows that would affect the error diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs b/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs index af7463e6574f..283c1224e013 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs @@ -1,6 +1,6 @@ -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "( 0x[0-9a-f][0-9a-f] │)? ([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> " HEX_DUMP" -//@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "( 0x[0-9a-f][0-9a-f] │)? ([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> " HEX_DUMP" +//@ normalize-stderr: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" use std::cell::UnsafeCell; use std::mem; diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs index 2539fcccb848..ac903fca20ae 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs @@ -1,6 +1,6 @@ -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "( 0x[0-9a-f][0-9a-f] │)? ([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> " HEX_DUMP" -//@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "( 0x[0-9a-f][0-9a-f] │)? ([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> " HEX_DUMP" +//@ normalize-stderr: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" use std::sync::Mutex; diff --git a/tests/ui/consts/const_refs_to_static_fail.rs b/tests/ui/consts/const_refs_to_static_fail.rs index 44e848ab6377..596ed50af385 100644 --- a/tests/ui/consts/const_refs_to_static_fail.rs +++ b/tests/ui/consts/const_refs_to_static_fail.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(sync_unsafe_cell)] diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.rs b/tests/ui/consts/const_refs_to_static_fail_invalid.rs index aa101cf9d8a6..3383a208345d 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.rs +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![allow(static_mut_refs)] fn invalid() { diff --git a/tests/ui/consts/dangling-alloc-id-ice.rs b/tests/ui/consts/dangling-alloc-id-ice.rs index da95d4d13476..8e9493c8d285 100644 --- a/tests/ui/consts/dangling-alloc-id-ice.rs +++ b/tests/ui/consts/dangling-alloc-id-ice.rs @@ -1,8 +1,8 @@ // https://github.com/rust-lang/rust/issues/55223 // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -//@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" union Foo<'a> { y: &'a (), diff --git a/tests/ui/consts/dangling-zst-ice-issue-126393.rs b/tests/ui/consts/dangling-zst-ice-issue-126393.rs index b56fcd235c7d..4beee913a978 100644 --- a/tests/ui/consts/dangling-zst-ice-issue-126393.rs +++ b/tests/ui/consts/dangling-zst-ice-issue-126393.rs @@ -1,7 +1,7 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -//@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" pub struct Wrapper; pub static MAGIC_FFI_REF: &'static Wrapper = unsafe { diff --git a/tests/ui/consts/error-is-freeze.rs b/tests/ui/consts/error-is-freeze.rs new file mode 100644 index 000000000000..fe27d029e663 --- /dev/null +++ b/tests/ui/consts/error-is-freeze.rs @@ -0,0 +1,14 @@ +// Make sure we treat the error type as freeze to suppress useless errors. + +struct MyStruct { + foo: Option, + //~^ ERROR cannot find type `UndefinedType` in this scope +} +impl MyStruct { + pub const EMPTY_REF: &'static Self = &Self::EMPTY; + pub const EMPTY: Self = Self { + foo: None, + }; +} + +fn main() {} diff --git a/tests/ui/consts/error-is-freeze.stderr b/tests/ui/consts/error-is-freeze.stderr new file mode 100644 index 000000000000..f3bfd1ea5e29 --- /dev/null +++ b/tests/ui/consts/error-is-freeze.stderr @@ -0,0 +1,14 @@ +error[E0412]: cannot find type `UndefinedType` in this scope + --> $DIR/error-is-freeze.rs:4:17 + | +LL | foo: Option, + | ^^^^^^^^^^^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | struct MyStruct { + | +++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/consts/issue-17718-const-bad-values.rs b/tests/ui/consts/issue-17718-const-bad-values.rs index fca6cb085379..c4de7b61f07d 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.rs +++ b/tests/ui/consts/issue-17718-const-bad-values.rs @@ -1,6 +1,5 @@ -//@ normalize-stderr-32bit: "\(size: \d+, align: \d+\)" -> "(size: $$PTR, align: $$PTR)" -//@ normalize-stderr-64bit: "\(size: \d+, align: \d+\)" -> "(size: $$PTR, align: $$PTR)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "\(size: \d+, align: \d+\)" -> "(size: $$PTR, align: $$PTR)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![allow(static_mut_refs)] diff --git a/tests/ui/consts/issue-17718-const-bad-values.stderr b/tests/ui/consts/issue-17718-const-bad-values.stderr index 102491e90bac..364fa7be5aae 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.stderr +++ b/tests/ui/consts/issue-17718-const-bad-values.stderr @@ -1,11 +1,11 @@ error[E0764]: mutable references are not allowed in the final value of constants - --> $DIR/issue-17718-const-bad-values.rs:7:34 + --> $DIR/issue-17718-const-bad-values.rs:6:34 | LL | const C1: &'static mut [usize] = &mut []; | ^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/issue-17718-const-bad-values.rs:11:1 + --> $DIR/issue-17718-const-bad-values.rs:10:1 | LL | const C2: &'static mut i32 = unsafe { &mut S }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` diff --git a/tests/ui/consts/issue-94371.rs b/tests/ui/consts/issue-94371.rs index ad9ee9a5a3ef..b2dd7053c1f9 100644 --- a/tests/ui/consts/issue-94371.rs +++ b/tests/ui/consts/issue-94371.rs @@ -1,7 +1,5 @@ //@ check-pass -#![feature(const_swap)] - #[repr(C)] struct Demo(u64, bool, u64, u32, u64, u64, u64); diff --git a/tests/ui/consts/issue-miri-1910.rs b/tests/ui/consts/issue-miri-1910.rs index a66cb6b66651..107d9742b92a 100644 --- a/tests/ui/consts/issue-miri-1910.rs +++ b/tests/ui/consts/issue-miri-1910.rs @@ -1,5 +1,5 @@ //@ error-pattern unable to turn pointer into raw bytes -//@ normalize-stderr-test: "alloc[0-9]+\+0x[a-z0-9]+" -> "ALLOC" +//@ normalize-stderr: "alloc[0-9]+\+0x[a-z0-9]+" -> "ALLOC" const C: () = unsafe { let foo = Some(&42 as *const i32); diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static.rs index 562595325733..a6691fa2a2f1 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.rs @@ -1,6 +1,6 @@ //@ compile-flags: -Zunleash-the-miri-inside-of-you -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs index facb21a04ef0..b33ebfb06be9 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs @@ -1,7 +1,7 @@ //@ compile-flags: -Zunleash-the-miri-inside-of-you //@ aux-build:static_cross_crate.rs -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(half_open_range_patterns_in_slices)] #![allow(static_mut_refs)] diff --git a/tests/ui/consts/miri_unleashed/mutable_references.rs b/tests/ui/consts/miri_unleashed/mutable_references.rs index a60058cc5c01..039d0fadfcc4 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references.rs +++ b/tests/ui/consts/miri_unleashed/mutable_references.rs @@ -1,6 +1,6 @@ //@ compile-flags: -Zunleash-the-miri-inside-of-you -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![allow(static_mut_refs)] use std::cell::UnsafeCell; diff --git a/tests/ui/consts/offset_from_ub.rs b/tests/ui/consts/offset_from_ub.rs index 7efc5dd3e28b..0232b03a813e 100644 --- a/tests/ui/consts/offset_from_ub.rs +++ b/tests/ui/consts/offset_from_ub.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "\d+ bytes" -> "$$BYTES bytes" +//@ normalize-stderr: "\d+ bytes" -> "$$BYTES bytes" #![feature(const_ptr_sub_ptr)] #![feature(core_intrinsics)] diff --git a/tests/ui/consts/offset_ub.rs b/tests/ui/consts/offset_ub.rs index 5026d9a27132..dda6dd388f28 100644 --- a/tests/ui/consts/offset_ub.rs +++ b/tests/ui/consts/offset_ub.rs @@ -1,8 +1,8 @@ use std::ptr; -//@ normalize-stderr-test: "0xf+" -> "0xf..f" -//@ normalize-stderr-test: "0x7f+" -> "0x7f..f" -//@ normalize-stderr-test: "\d+ bytes" -> "$$BYTES bytes" +//@ normalize-stderr: "0xf+" -> "0xf..f" +//@ normalize-stderr: "0x7f+" -> "0x7f..f" +//@ normalize-stderr: "\d+ bytes" -> "$$BYTES bytes" pub const BEFORE_START: *const u8 = unsafe { (&0u8 as *const u8).offset(-1) }; //~NOTE diff --git a/tests/ui/consts/overflowing-consts.rs b/tests/ui/consts/overflowing-consts.rs index 68282750dce2..5ff205ce58e6 100644 --- a/tests/ui/consts/overflowing-consts.rs +++ b/tests/ui/consts/overflowing-consts.rs @@ -6,8 +6,8 @@ //@ [opt]compile-flags: -O //@ [opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O //@ ignore-pass (test tests codegen-time behaviour) -//@ normalize-stderr-test: "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which" -//@ normalize-stderr-test: "shift right by `(64|32)_usize`, which" -> "shift right by `%BITS%`, which" +//@ normalize-stderr: "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which" +//@ normalize-stderr: "shift right by `(64|32)_usize`, which" -> "shift right by `%BITS%`, which" #[cfg(target_pointer_width = "32")] diff --git a/tests/ui/consts/qualif-indirect-mutation-fail.rs b/tests/ui/consts/qualif-indirect-mutation-fail.rs index c6e08a557c8a..0f59a86b7cc0 100644 --- a/tests/ui/consts/qualif-indirect-mutation-fail.rs +++ b/tests/ui/consts/qualif-indirect-mutation-fail.rs @@ -1,6 +1,5 @@ //@ compile-flags: --crate-type=lib #![feature(const_precise_live_drops)] -#![feature(const_swap)] // Mutable borrow of a field with drop impl. pub const fn f() { diff --git a/tests/ui/consts/qualif-indirect-mutation-fail.stderr b/tests/ui/consts/qualif-indirect-mutation-fail.stderr index f706b7cf699d..e76d7d3b6705 100644 --- a/tests/ui/consts/qualif-indirect-mutation-fail.stderr +++ b/tests/ui/consts/qualif-indirect-mutation-fail.stderr @@ -1,5 +1,5 @@ error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:13:9 + --> $DIR/qualif-indirect-mutation-fail.rs:12:9 | LL | let mut x = None; | ^^^^^ the destructor for this type cannot be evaluated in constants @@ -19,13 +19,13 @@ note: inside `std::ptr::drop_in_place:: - shim(Some(String))` note: inside `std::ptr::drop_in_place::> - shim(Some(Option))` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL note: inside `A1` - --> $DIR/qualif-indirect-mutation-fail.rs:19:1 + --> $DIR/qualif-indirect-mutation-fail.rs:18:1 | LL | }; | ^ error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:29:9 + --> $DIR/qualif-indirect-mutation-fail.rs:28:9 | LL | let _z = x; | ^^ the destructor for this type cannot be evaluated in constants @@ -44,13 +44,13 @@ note: inside `std::ptr::drop_in_place:: - shim(Some(String))` note: inside `std::ptr::drop_in_place::> - shim(Some(Option))` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL note: inside `A2` - --> $DIR/qualif-indirect-mutation-fail.rs:30:1 + --> $DIR/qualif-indirect-mutation-fail.rs:29:1 | LL | }; | ^ error[E0493]: destructor of `(u32, Option)` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:7:9 + --> $DIR/qualif-indirect-mutation-fail.rs:6:9 | LL | let mut a: (u32, Option) = (0, None); | ^^^^^ the destructor for this type cannot be evaluated in constant functions @@ -59,7 +59,7 @@ LL | } | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:34:9 + --> $DIR/qualif-indirect-mutation-fail.rs:33:9 | LL | let x: Option = None; | ^ the destructor for this type cannot be evaluated in constant functions @@ -68,7 +68,7 @@ LL | } | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:42:9 + --> $DIR/qualif-indirect-mutation-fail.rs:41:9 | LL | let _y = x; | ^^ the destructor for this type cannot be evaluated in constant functions @@ -76,7 +76,7 @@ LL | } | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:50:9 + --> $DIR/qualif-indirect-mutation-fail.rs:49:9 | LL | let mut y: Option = None; | ^^^^^ the destructor for this type cannot be evaluated in constant functions @@ -85,7 +85,7 @@ LL | } | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:47:9 + --> $DIR/qualif-indirect-mutation-fail.rs:46:9 | LL | let mut x: Option = None; | ^^^^^ the destructor for this type cannot be evaluated in constant functions @@ -94,7 +94,7 @@ LL | } | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:60:9 + --> $DIR/qualif-indirect-mutation-fail.rs:59:9 | LL | let y: Option = None; | ^ the destructor for this type cannot be evaluated in constant functions @@ -103,7 +103,7 @@ LL | } | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:57:9 + --> $DIR/qualif-indirect-mutation-fail.rs:56:9 | LL | let x: Option = None; | ^ the destructor for this type cannot be evaluated in constant functions diff --git a/tests/ui/consts/validate_never_arrays.rs b/tests/ui/consts/validate_never_arrays.rs index 7585a78a0d35..055bb1c69c89 100644 --- a/tests/ui/consts/validate_never_arrays.rs +++ b/tests/ui/consts/validate_never_arrays.rs @@ -1,6 +1,6 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(never_type)] const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior diff --git a/tests/ui/coroutine/static-not-unpin.rs b/tests/ui/coroutine/static-not-unpin.rs index b66a248654e9..9be7eca63cbb 100644 --- a/tests/ui/coroutine/static-not-unpin.rs +++ b/tests/ui/coroutine/static-not-unpin.rs @@ -5,7 +5,7 @@ #![feature(coroutines, stmt_expr_attributes)] -//@ normalize-stderr-test: "std::pin::Unpin" -> "std::marker::Unpin" +//@ normalize-stderr: "std::pin::Unpin" -> "std::marker::Unpin" use std::marker::Unpin; diff --git a/tests/ui/crate-loading/crateresolve1.rs b/tests/ui/crate-loading/crateresolve1.rs index 2fccb744e82c..9200b6a62314 100644 --- a/tests/ui/crate-loading/crateresolve1.rs +++ b/tests/ui/crate-loading/crateresolve1.rs @@ -2,9 +2,9 @@ //@ aux-build:crateresolve1-2.rs //@ aux-build:crateresolve1-3.rs -//@ normalize-stderr-test: "\.nll/" -> "/" -//@ normalize-stderr-test: "\\\?\\" -> "" -//@ normalize-stderr-test: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib" +//@ normalize-stderr: "\.nll/" -> "/" +//@ normalize-stderr: "\\\?\\" -> "" +//@ normalize-stderr: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib" // NOTE: This test is duplicated at `tests/ui/error-codes/E0464.rs`. diff --git a/tests/ui/crate-loading/crateresolve2.rs b/tests/ui/crate-loading/crateresolve2.rs index 159ce04c3c4a..bec692eb8d2b 100644 --- a/tests/ui/crate-loading/crateresolve2.rs +++ b/tests/ui/crate-loading/crateresolve2.rs @@ -4,8 +4,8 @@ //@ aux-build:crateresolve2-2.rs //@ aux-build:crateresolve2-3.rs -//@ normalize-stderr-test: "\.nll/" -> "/" -//@ normalize-stderr-test: "\\\?\\" -> "" +//@ normalize-stderr: "\.nll/" -> "/" +//@ normalize-stderr: "\\\?\\" -> "" extern crate crateresolve2; //~^ ERROR multiple candidates for `rmeta` dependency `crateresolve2` found diff --git a/tests/ui/crate-loading/invalid-rlib.rs b/tests/ui/crate-loading/invalid-rlib.rs index 0b401add8e49..6b4635262445 100644 --- a/tests/ui/crate-loading/invalid-rlib.rs +++ b/tests/ui/crate-loading/invalid-rlib.rs @@ -1,5 +1,5 @@ //@ compile-flags: --crate-type lib --extern foo={{src-base}}/crate-loading/auxiliary/libfoo.rlib -//@ normalize-stderr-test: "failed to mmap file '.*auxiliary/libfoo.rlib':.*" -> "failed to mmap file 'auxiliary/libfoo.rlib'" +//@ normalize-stderr: "failed to mmap file '.*auxiliary/libfoo.rlib':.*" -> "failed to mmap file 'auxiliary/libfoo.rlib'" // don't emit warn logging, it's basically the same as the errors and it's annoying to normalize //@ rustc-env:RUSTC_LOG=error //@ edition:2018 diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs index a1922c98ef6d..3bff44716985 100644 --- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs +++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs @@ -4,8 +4,6 @@ //@ compile-flags:-C debuginfo=2 //@ build-fail //@ error-pattern: too big for the target architecture -//@ normalize-stderr-64bit: "18446744073709551615" -> "SIZE" -//@ normalize-stderr-32bit: "4294967295" -> "SIZE" #![crate_type = "rlib"] diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs index 3456cd55b758..6a3f8f4c249c 100644 --- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs +++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs @@ -6,8 +6,6 @@ //@ compile-flags:-C debuginfo=2 //@ build-fail //@ error-pattern: too big for the target architecture -//@ normalize-stderr-64bit: "18446744073709551615" -> "SIZE" -//@ normalize-stderr-32bit: "4294967295" -> "SIZE" #![crate_type = "rlib"] diff --git a/tests/ui/diagnostic-width/E0271.rs b/tests/ui/diagnostic-width/E0271.rs index dedae4365e88..061ba45c2198 100644 --- a/tests/ui/diagnostic-width/E0271.rs +++ b/tests/ui/diagnostic-width/E0271.rs @@ -1,7 +1,7 @@ //@ revisions: ascii unicode //@[ascii] compile-flags: --diagnostic-width=40 //@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40 -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" trait Future { type Error; } diff --git a/tests/ui/diagnostic-width/long-E0308.rs b/tests/ui/diagnostic-width/long-E0308.rs index 695852f83ac0..939872260209 100644 --- a/tests/ui/diagnostic-width/long-E0308.rs +++ b/tests/ui/diagnostic-width/long-E0308.rs @@ -1,7 +1,7 @@ //@ revisions: ascii unicode //@[ascii] compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes //@[unicode] compile-flags: -Zunstable-options --json=diagnostic-unicode --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" mod a { // Force the "short path for unique types" machinery to trip up diff --git a/tests/ui/duplicate_entry_error.rs b/tests/ui/duplicate_entry_error.rs index e8b905a65f60..5a25802c6e78 100644 --- a/tests/ui/duplicate_entry_error.rs +++ b/tests/ui/duplicate_entry_error.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" +//@ normalize-stderr: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" // note-pattern: first defined in crate `std`. // Test for issue #31788 and E0152 diff --git a/tests/ui/error-codes/E0017.rs b/tests/ui/error-codes/E0017.rs index e103d3bf5b11..8c685aad0308 100644 --- a/tests/ui/error-codes/E0017.rs +++ b/tests/ui/error-codes/E0017.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test: "\(size: ., align: .\)" -> "" -//@ normalize-stderr-test: " +│ ╾─+╼" -> "" +//@ normalize-stderr: "\(size: ., align: .\)" -> "" +//@ normalize-stderr: " +│ ╾─+╼" -> "" static X: i32 = 1; const C: i32 = 2; diff --git a/tests/ui/error-codes/E0152.rs b/tests/ui/error-codes/E0152.rs index 44d462c27e68..565e92baf02e 100644 --- a/tests/ui/error-codes/E0152.rs +++ b/tests/ui/error-codes/E0152.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "loaded from .*liballoc-.*.rlib" -> "loaded from SYSROOT/liballoc-*.rlib" +//@ normalize-stderr: "loaded from .*liballoc-.*.rlib" -> "loaded from SYSROOT/liballoc-*.rlib" #![feature(lang_items)] #[lang = "owned_box"] diff --git a/tests/ui/error-codes/E0253.rs b/tests/ui/error-codes/E0253.rs index 284b16da8f22..8284f791c648 100644 --- a/tests/ui/error-codes/E0253.rs +++ b/tests/ui/error-codes/E0253.rs @@ -1,10 +1,10 @@ mod foo { pub trait MyTrait { - fn do_something(); + type SomeType; } } -use foo::MyTrait::do_something; +use foo::MyTrait::SomeType; //~^ ERROR E0253 fn main() {} diff --git a/tests/ui/error-codes/E0253.stderr b/tests/ui/error-codes/E0253.stderr index 4ee36b70fe51..954dbc816939 100644 --- a/tests/ui/error-codes/E0253.stderr +++ b/tests/ui/error-codes/E0253.stderr @@ -1,8 +1,8 @@ -error[E0253]: `do_something` is not directly importable +error[E0253]: `SomeType` is not directly importable --> $DIR/E0253.rs:7:5 | -LL | use foo::MyTrait::do_something; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly +LL | use foo::MyTrait::SomeType; + | ^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0275.rs b/tests/ui/error-codes/E0275.rs index 889d9d8be903..df7b606155eb 100644 --- a/tests/ui/error-codes/E0275.rs +++ b/tests/ui/error-codes/E0275.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" trait Foo {} struct Bar(T); diff --git a/tests/ui/error-codes/E0462.rs b/tests/ui/error-codes/E0462.rs index 2dd3b16394d5..12214331445f 100644 --- a/tests/ui/error-codes/E0462.rs +++ b/tests/ui/error-codes/E0462.rs @@ -1,8 +1,8 @@ //@ aux-build:found-staticlib.rs -//@ normalize-stderr-test: "\.nll/" -> "/" -//@ normalize-stderr-test: "\\\?\\" -> "" -//@ normalize-stderr-test: "(lib)?found_staticlib\.[a-z]+" -> "libfound_staticlib.somelib" +//@ normalize-stderr: "\.nll/" -> "/" +//@ normalize-stderr: "\\\?\\" -> "" +//@ normalize-stderr: "(lib)?found_staticlib\.[a-z]+" -> "libfound_staticlib.somelib" extern crate found_staticlib; //~ ERROR E0462 diff --git a/tests/ui/error-codes/E0464.rs b/tests/ui/error-codes/E0464.rs index 4ecf21996ccf..aaf4d3a8f500 100644 --- a/tests/ui/error-codes/E0464.rs +++ b/tests/ui/error-codes/E0464.rs @@ -2,9 +2,9 @@ //@ aux-build:crateresolve1-2.rs //@ aux-build:crateresolve1-3.rs -//@ normalize-stderr-test: "\.nll/" -> "/" -//@ normalize-stderr-test: "\\\?\\" -> "" -//@ normalize-stderr-test: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib" +//@ normalize-stderr: "\.nll/" -> "/" +//@ normalize-stderr: "\\\?\\" -> "" +//@ normalize-stderr: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib" // NOTE: This test is duplicated from `tests/ui/crate-loading/crateresolve1.rs`. diff --git a/tests/ui/error-codes/E0523.rs b/tests/ui/error-codes/E0523.rs index 4ecf21996ccf..aaf4d3a8f500 100644 --- a/tests/ui/error-codes/E0523.rs +++ b/tests/ui/error-codes/E0523.rs @@ -2,9 +2,9 @@ //@ aux-build:crateresolve1-2.rs //@ aux-build:crateresolve1-3.rs -//@ normalize-stderr-test: "\.nll/" -> "/" -//@ normalize-stderr-test: "\\\?\\" -> "" -//@ normalize-stderr-test: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib" +//@ normalize-stderr: "\.nll/" -> "/" +//@ normalize-stderr: "\\\?\\" -> "" +//@ normalize-stderr: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib" // NOTE: This test is duplicated from `tests/ui/crate-loading/crateresolve1.rs`. diff --git a/tests/ui/error-emitter/multiline-removal-suggestion.rs b/tests/ui/error-emitter/multiline-removal-suggestion.rs new file mode 100644 index 000000000000..72e9ea357c9e --- /dev/null +++ b/tests/ui/error-emitter/multiline-removal-suggestion.rs @@ -0,0 +1,58 @@ +// Make sure suggestion for removal of a span that covers multiple lines is properly highlighted. +//@ compile-flags: --error-format=human --color=always +//@ edition:2018 +//@ only-linux +// ignore-tidy-tab +// We use `\t` instead of spaces for indentation to ensure that the highlighting logic properly +// accounts for replaced characters (like we do for `\t` with ` `). The naïve way of highlighting +// could be counting chars of the original code, instead of operating on the code as it is being +// displayed. +use std::collections::{HashMap, HashSet}; +fn foo() -> Vec<(bool, HashSet)> { + let mut hm = HashMap::>>::new(); + hm.into_iter() + .map(|(is_true, ts)| { + ts.into_iter() + .map(|t| { + ( + is_true, + t, + ) + }).flatten() + }) + .flatten() + .collect() +} +fn bar() -> Vec<(bool, HashSet)> { + let mut hm = HashMap::>>::new(); + hm.into_iter() + .map(|(is_true, ts)| { + ts.into_iter() + .map(|t| (is_true, t)) + .flatten() + }) + .flatten() + .collect() +} +fn baz() -> Vec<(bool, HashSet)> { + let mut hm = HashMap::>>::new(); + hm.into_iter() + .map(|(is_true, ts)| { + ts.into_iter().map(|t| { + (is_true, t) + }).flatten() + }) + .flatten() + .collect() +} +fn bay() -> Vec<(bool, HashSet)> { + let mut hm = HashMap::>>::new(); + hm.into_iter() + .map(|(is_true, ts)| { + ts.into_iter() + .map(|t| (is_true, t)).flatten() + }) + .flatten() + .collect() +} +fn main() {} diff --git a/tests/ui/error-emitter/multiline-removal-suggestion.svg b/tests/ui/error-emitter/multiline-removal-suggestion.svg new file mode 100644 index 000000000000..95c7740f6995 --- /dev/null +++ b/tests/ui/error-emitter/multiline-removal-suggestion.svg @@ -0,0 +1,504 @@ + + + + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:21:8 + + | + + LL | }).flatten() + + | ^^^^^^^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `flatten` + + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + + help: consider removing this method call, as the receiver has type `std::vec::IntoIter<HashSet<u8>>` and `std::vec::IntoIter<HashSet<u8>>: Iterator` trivially holds + + | + + LL - ts.into_iter() + + LL - .map(|t| { + + LL - ( + + LL - is_true, + + LL - t, + + LL - ) + + LL - }).flatten() + + LL + ts.into_iter().flatten() + + | + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:13:2 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter() + + LL | | .map(|t| { + + ... | + + LL | | }).flatten() + + LL | | }) + + | |__________^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `Flatten` + + --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL + + + + error[E0599]: the method `collect` exists for struct `Flatten<Map<IntoIter<bool, Vec<HashSet<u8>>>, {closure@multiline-removal-suggestion.rs:14:8}>>`, but its trait bounds were not satisfied + + --> $DIR/multiline-removal-suggestion.rs:24:4 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter() + + LL | | .map(|t| { + + ... | + + LL | | .flatten() + + LL | | .collect() + + | | -^^^^^^^ method cannot be called due to unsatisfied trait bounds + + | |_________| + + | + + | + + = note: the following trait bounds were not satisfied: + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:16:10: 16:13}>> as IntoIterator>::IntoIter = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator` + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:16:10: 16:13}>> as IntoIterator>::Item = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator` + + `Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:16:10: 16:13}>>: IntoIterator` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator` + + `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator` + + which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator` + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:32:6 + + | + + LL | .flatten() + + | ^^^^^^^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `flatten` + + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + + help: consider removing this method call, as the receiver has type `std::vec::IntoIter<HashSet<u8>>` and `std::vec::IntoIter<HashSet<u8>>: Iterator` trivially holds + + | + + LL - ts.into_iter() + + LL - .map(|t| (is_true, t)) + + LL + ts.into_iter() + + | + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:28:2 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter() + + LL | | .map(|t| (is_true, t)) + + LL | | .flatten() + + LL | | }) + + | |__________^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `Flatten` + + --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL + + + + error[E0599]: the method `collect` exists for struct `Flatten<Map<IntoIter<bool, Vec<HashSet<u8>>>, {closure@multiline-removal-suggestion.rs:29:8}>>`, but its trait bounds were not satisfied + + --> $DIR/multiline-removal-suggestion.rs:35:4 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter() + + LL | | .map(|t| (is_true, t)) + + ... | + + LL | | .flatten() + + LL | | .collect() + + | | -^^^^^^^ method cannot be called due to unsatisfied trait bounds + + | |_________| + + | + + | + + = note: the following trait bounds were not satisfied: + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:31:10: 31:13}>> as IntoIterator>::IntoIter = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator` + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:31:10: 31:13}>> as IntoIterator>::Item = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator` + + `Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:31:10: 31:13}>>: IntoIterator` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator` + + `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator` + + which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator` + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:43:7 + + | + + LL | }).flatten() + + | ^^^^^^^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `flatten` + + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + + help: consider removing this method call, as the receiver has type `std::vec::IntoIter<HashSet<u8>>` and `std::vec::IntoIter<HashSet<u8>>: Iterator` trivially holds + + | + + LL - ts.into_iter().map(|t| { + + LL - (is_true, t) + + LL - }).flatten() + + LL + ts.into_iter().flatten() + + | + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:39:2 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter().map(|t| { + + LL | | (is_true, t) + + LL | | }).flatten() + + LL | | }) + + | |__________^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `Flatten` + + --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL + + + + error[E0599]: the method `collect` exists for struct `Flatten<Map<IntoIter<bool, Vec<HashSet<u8>>>, {closure@multiline-removal-suggestion.rs:40:8}>>`, but its trait bounds were not satisfied + + --> $DIR/multiline-removal-suggestion.rs:46:4 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter().map(|t| { + + LL | | (is_true, t) + + ... | + + LL | | .flatten() + + LL | | .collect() + + | | -^^^^^^^ method cannot be called due to unsatisfied trait bounds + + | |_________| + + | + + | + + = note: the following trait bounds were not satisfied: + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:41:23: 41:26}>> as IntoIterator>::IntoIter = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator` + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:41:23: 41:26}>> as IntoIterator>::Item = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator` + + `Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:41:23: 41:26}>>: IntoIterator` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator` + + `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator` + + which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator` + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:53:28 + + | + + LL | .map(|t| (is_true, t)).flatten() + + | ^^^^^^^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `flatten` + + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + + help: consider removing this method call, as the receiver has type `std::vec::IntoIter<HashSet<u8>>` and `std::vec::IntoIter<HashSet<u8>>: Iterator` trivially holds + + | + + LL - ts.into_iter() + + LL - .map(|t| (is_true, t)).flatten() + + LL + ts.into_iter().flatten() + + | + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:50:2 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter() + + LL | | .map(|t| (is_true, t)).flatten() + + LL | | }) + + | |__________^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `Flatten` + + --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL + + + + error[E0599]: the method `collect` exists for struct `Flatten<Map<IntoIter<bool, Vec<HashSet<u8>>>, {closure@multiline-removal-suggestion.rs:51:8}>>`, but its trait bounds were not satisfied + + --> $DIR/multiline-removal-suggestion.rs:56:4 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter() + + LL | | .map(|t| (is_true, t)).flatten() + + LL | | }) + + LL | | .flatten() + + LL | | .collect() + + | | -^^^^^^^ method cannot be called due to unsatisfied trait bounds + + | |_________| + + | + + | + + = note: the following trait bounds were not satisfied: + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:53:10: 53:13}>> as IntoIterator>::IntoIter = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator` + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:53:10: 53:13}>> as IntoIterator>::Item = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator` + + `Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:53:10: 53:13}>>: IntoIterator` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator` + + `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator` + + which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator` + + + + error: aborting due to 12 previous errors + + + + Some errors have detailed explanations: E0277, E0599. + + For more information about an error, try `rustc --explain E0277`. + + + + + + diff --git a/tests/ui/errors/remap-path-prefix-sysroot.rs b/tests/ui/errors/remap-path-prefix-sysroot.rs index 4cbb38709bea..7281e6da0944 100644 --- a/tests/ui/errors/remap-path-prefix-sysroot.rs +++ b/tests/ui/errors/remap-path-prefix-sysroot.rs @@ -8,7 +8,7 @@ // The $SRC_DIR*.rs:LL:COL normalisation doesn't kick in automatically // as the remapped revision will not begin with $SRC_DIR_REAL, // so we have to do it ourselves. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:COL" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:COL" use std::thread; struct Worker { diff --git a/tests/ui/errors/remap-path-prefix.rs b/tests/ui/errors/remap-path-prefix.rs index 6283a8737ff2..8809caa4d4f1 100644 --- a/tests/ui/errors/remap-path-prefix.rs +++ b/tests/ui/errors/remap-path-prefix.rs @@ -5,7 +5,7 @@ // no-remap-src-base: Manually remap, so the remapped path remains in .stderr file. // The remapped paths are not normalized by compiletest. -//@ normalize-stderr-test: "\\(errors)" -> "/$1" +//@ normalize-stderr: "\\(errors)" -> "/$1" // The remapped paths aren't recognized by compiletest, so we // cannot use line-specific patterns. diff --git a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs index bf060b3d1683..33d295f7ebe1 100644 --- a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs +++ b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs @@ -1,8 +1,8 @@ // test for ICE when casting extern "C" fn when it has a non-FFI-safe argument // issue: rust-lang/rust#52334 //@ check-pass -//@ normalize-stderr-test: "\[i8\]" -> "[i8 or u8 (arch dependant)]" -//@ normalize-stderr-test: "\[u8\]" -> "[i8 or u8 (arch dependant)]" +//@ normalize-stderr: "\[i8\]" -> "[i8 or u8 (arch dependant)]" +//@ normalize-stderr: "\[u8\]" -> "[i8 or u8 (arch dependant)]" type Foo = extern "C" fn(::std::ffi::CStr); //~^ WARN `extern` fn uses type diff --git a/tests/ui/extern/extern-types-field-offset.rs b/tests/ui/extern/extern-types-field-offset.rs index e9c4bb7b2304..75f3eab3e275 100644 --- a/tests/ui/extern/extern-types-field-offset.rs +++ b/tests/ui/extern/extern-types-field-offset.rs @@ -1,7 +1,7 @@ //@ run-fail //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +//@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" #![feature(extern_types)] extern "C" { diff --git a/tests/ui/extern/extern-types-size_of_val.rs b/tests/ui/extern/extern-types-size_of_val.rs index cc4d34e59fa9..399a5828ff3b 100644 --- a/tests/ui/extern/extern-types-size_of_val.rs +++ b/tests/ui/extern/extern-types-size_of_val.rs @@ -1,7 +1,7 @@ //@ run-fail //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +//@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" //@ revisions: size align #![feature(extern_types)] diff --git a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs new file mode 100644 index 000000000000..aec13fb02028 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs @@ -0,0 +1,63 @@ +//@ edition:2018 +use std::collections::HashMap; + +use A::{DEFAULT, new}; +//~^ ERROR `use` associated items of traits is unstable [E0658] +//~| ERROR `use` associated items of traits is unstable [E0658] +use Default::default; +//~^ ERROR `use` associated items of traits is unstable [E0658] + +struct S { + a: HashMap, +} + +impl S { + fn new() -> S { + S { a: default() } + } +} + +trait A: Sized { + const DEFAULT: Option = None; + fn new() -> Self; + fn do_something(&self); +} + +mod b { + use super::A::{self, DEFAULT, new}; + //~^ ERROR `use` associated items of traits is unstable [E0658] + //~| ERROR `use` associated items of traits is unstable [E0658] + + struct B(); + + impl A for B { + const DEFAULT: Option = Some(B()); + fn new() -> Self { + B() + } + + fn do_something(&self) {} + } + + fn f() { + let b: B = new(); + b.do_something(); + let c: B = DEFAULT.unwrap(); + } +} + +impl A for S { + fn new() -> Self { + S::new() + } + + fn do_something(&self) {} +} + +fn f() { + let s: S = new(); + s.do_something(); + let t: Option = DEFAULT; +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr new file mode 100644 index 000000000000..d342f5bd5512 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr @@ -0,0 +1,53 @@ +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:4:9 + | +LL | use A::{DEFAULT, new}; + | ^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:4:18 + | +LL | use A::{DEFAULT, new}; + | ^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:7:5 + | +LL | use Default::default; + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:27:26 + | +LL | use super::A::{self, DEFAULT, new}; + | ^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:27:35 + | +LL | use super::A::{self, DEFAULT, new}; + | ^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs index a884c94734a7..7b6ba9f7f169 100644 --- a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs +++ b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" fn id( f: &dyn Fn(u32), diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs index 799df8cae9fd..f880749ec835 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" // rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream` // should act as assertion that item does not borrow from its stream; diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs index 92e2e7f796ea..ff4c0cf24d69 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" // rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" // // Regression test for issue #70963 // The reported panic location should not be `<::core::macros::panic macros>`. diff --git a/tests/ui/hygiene/unpretty-debug.rs b/tests/ui/hygiene/unpretty-debug.rs index 8e05d60e2184..4d3d139deda3 100644 --- a/tests/ui/hygiene/unpretty-debug.rs +++ b/tests/ui/hygiene/unpretty-debug.rs @@ -2,7 +2,7 @@ //@ compile-flags: -Zunpretty=expanded,hygiene // Don't break whenever Symbol numbering changes -//@ normalize-stdout-test: "\d+#" -> "0#" +//@ normalize-stdout: "\d+#" -> "0#" // minimal junk #![feature(no_core)] diff --git a/tests/ui/hygiene/unpretty-debug.stdout b/tests/ui/hygiene/unpretty-debug.stdout index 1f620cef239f..e475cfac2fc1 100644 --- a/tests/ui/hygiene/unpretty-debug.stdout +++ b/tests/ui/hygiene/unpretty-debug.stdout @@ -2,7 +2,7 @@ //@ compile-flags: -Zunpretty=expanded,hygiene // Don't break whenever Symbol numbering changes -//@ normalize-stdout-test: "\d+#" -> "0#" +//@ normalize-stdout: "\d+#" -> "0#" // minimal junk #![feature /* 0#0 */(no_core)] diff --git a/tests/crashes/131050.rs b/tests/ui/impl-trait/auto-trait-contains-err.rs similarity index 89% rename from tests/crashes/131050.rs rename to tests/ui/impl-trait/auto-trait-contains-err.rs index 3e3a600ef3de..d7f094211d7d 100644 --- a/tests/crashes/131050.rs +++ b/tests/ui/impl-trait/auto-trait-contains-err.rs @@ -1,9 +1,9 @@ -//@ known-bug: #131050 //@ compile-flags: --edition=2021 use std::future::Future; fn invalid_future() -> impl Future {} +//~^ ERROR `()` is not a future fn create_complex_future() -> impl Future { async { &|| async { invalid_future().await } } @@ -21,3 +21,5 @@ where R: Send, { } + +fn main() {} diff --git a/tests/ui/impl-trait/auto-trait-contains-err.stderr b/tests/ui/impl-trait/auto-trait-contains-err.stderr new file mode 100644 index 000000000000..4da6b285ae15 --- /dev/null +++ b/tests/ui/impl-trait/auto-trait-contains-err.stderr @@ -0,0 +1,11 @@ +error[E0277]: `()` is not a future + --> $DIR/auto-trait-contains-err.rs:5:24 + | +LL | fn invalid_future() -> impl Future {} + | ^^^^^^^^^^^ `()` is not a future + | + = help: the trait `Future` is not implemented for `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs b/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs index 294b27e1dc18..766c37419cd8 100644 --- a/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs +++ b/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs @@ -2,7 +2,7 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@ compile-flags: -Zverbose-internals //@[next] compile-flags: -Znext-solver -//@ normalize-stderr-test: "DefId\([^\)]+\)" -> "DefId(..)" +//@ normalize-stderr: "DefId\([^\)]+\)" -> "DefId(..)" #![feature(rustc_attrs)] #![rustc_hidden_type_of_opaques] diff --git a/tests/ui/imports/import-trait-method.rs b/tests/ui/imports/import-trait-method.rs index 97dd68f1e76e..a24b3a136444 100644 --- a/tests/ui/imports/import-trait-method.rs +++ b/tests/ui/imports/import-trait-method.rs @@ -2,6 +2,6 @@ trait Foo { fn foo(); } -use Foo::foo; //~ ERROR not directly importable +use Foo::foo; //~ ERROR `use` associated items of traits is unstable [E0658] -fn main() { foo(); } +fn main() { foo(); } //~ ERROR type annotations needed diff --git a/tests/ui/imports/import-trait-method.stderr b/tests/ui/imports/import-trait-method.stderr index 9786eb52d354..8fe774111b96 100644 --- a/tests/ui/imports/import-trait-method.stderr +++ b/tests/ui/imports/import-trait-method.stderr @@ -1,9 +1,22 @@ -error[E0253]: `foo` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/import-trait-method.rs:5:5 | LL | use Foo::foo; - | ^^^^^^^^ cannot be imported directly + | ^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 1 previous error +error[E0283]: type annotations needed + --> $DIR/import-trait-method.rs:7:13 + | +LL | fn main() { foo(); } + | ^^^^^ cannot infer type + | + = note: cannot satisfy `_: Foo` -For more information about this error, try `rustc --explain E0253`. +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0283, E0658. +For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/include-macros/parent_dir.rs b/tests/ui/include-macros/parent_dir.rs index 5fadff77a37e..1dcf27324d1f 100644 --- a/tests/ui/include-macros/parent_dir.rs +++ b/tests/ui/include-macros/parent_dir.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "`: .*" -> "`: $$FILE_NOT_FOUND_MSG" +//@ normalize-stderr: "`: .*" -> "`: $$FILE_NOT_FOUND_MSG" fn main() { let _ = include_str!("include-macros/file.txt"); //~ ERROR couldn't read diff --git a/tests/ui/infinite/infinite-instantiation.rs b/tests/ui/infinite/infinite-instantiation.rs index ed6fe693ebf4..7e1bff6b1242 100644 --- a/tests/ui/infinite/infinite-instantiation.rs +++ b/tests/ui/infinite/infinite-instantiation.rs @@ -1,5 +1,5 @@ //@ build-fail -//@ normalize-stderr-test: ".nll/" -> "/" +//@ normalize-stderr: ".nll/" -> "/" trait ToOpt: Sized { fn to_option(&self) -> Option; diff --git a/tests/ui/intrinsics/not-overridden.rs b/tests/ui/intrinsics/not-overridden.rs index 16f8e9bcf6a7..b57b4e5bc06d 100644 --- a/tests/ui/intrinsics/not-overridden.rs +++ b/tests/ui/intrinsics/not-overridden.rs @@ -3,9 +3,9 @@ #![feature(intrinsics)] //@ build-fail //@ failure-status:101 -//@ normalize-stderr-test: ".*note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*:\n.*\n" -> "" -//@ normalize-stderr-test: "internal compiler error:.*: intrinsic const_deallocate " -> "" +//@ normalize-stderr: ".*note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*:\n.*\n" -> "" +//@ normalize-stderr: "internal compiler error:.*: intrinsic const_deallocate " -> "" //@ rustc-env:RUST_BACKTRACE=0 #[rustc_intrinsic] diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr b/tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr new file mode 100644 index 000000000000..0f8772024dfa --- /dev/null +++ b/tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr @@ -0,0 +1,2 @@ +error: unknown crate type: `` + diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr b/tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr new file mode 100644 index 000000000000..a4a974169964 --- /dev/null +++ b/tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr @@ -0,0 +1,2 @@ +error: unknown crate type: `proc_macro` + diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.rs b/tests/ui/invalid-compile-flags/crate-type-flag.rs new file mode 100644 index 000000000000..42bd72cbfbf5 --- /dev/null +++ b/tests/ui/invalid-compile-flags/crate-type-flag.rs @@ -0,0 +1,61 @@ +//! Check that `rustc`'s `--crate-type` flag accepts `--crate-type=` as well as the +//! multi-value version `--crate-type=,`. +//! +//! This test does not try to check if the output artifacts are valid. + +// FIXME(#132309): add a proper `supports-crate-type` directive. + +// Single valid crate types should pass +//@ revisions: lib rlib staticlib dylib cdylib bin proc_dash_macro + +//@[lib] compile-flags: --crate-type=lib +//@[lib] check-pass + +//@[rlib] compile-flags: --crate-type=rlib +//@[rlib] check-pass + +//@[staticlib] compile-flags: --crate-type=staticlib +//@[staticlib] check-pass + +//@[dylib] ignore-musl (dylibs are not supported) +//@[dylib] ignore-wasm (dylibs are not supported) +//@[dylib] compile-flags: --crate-type=dylib +//@[dylib] check-pass + +//@[cdylib] ignore-musl (cdylibs are not supported) +//@[cdylib] compile-flags: --crate-type=cdylib +//@[cdylib] check-pass + +//@[bin] compile-flags: --crate-type=bin +//@[bin] check-pass + +//@[proc_dash_macro] ignore-wasm (proc-macro is not supported) +//@[proc_dash_macro] compile-flags: --crate-type=proc-macro +//@[proc_dash_macro] check-pass + +//@ revisions: multivalue multivalue_combined + +//@[multivalue] compile-flags: --crate-type=lib,rlib,staticlib +//@[multivalue] check-pass + +//@[multivalue_combined] ignore-musl (dylibs are not supported) +//@[multivalue_combined] ignore-wasm (dylibs are not supported) +//@[multivalue_combined] compile-flags: --crate-type=lib,rlib,staticlib --crate-type=dylib +//@[multivalue_combined] check-pass + +// `proc-macro` is accepted, but `proc_macro` is not. +//@ revisions: proc_underscore_macro +//@[proc_underscore_macro] compile-flags: --crate-type=proc_macro +//@[proc_underscore_macro] error-pattern: "unknown crate type: `proc_macro`" + +// Empty `--crate-type` not accepted. +//@ revisions: empty_crate_type +//@[empty_crate_type] compile-flags: --crate-type= +//@[empty_crate_type] error-pattern: "unknown crate type: ``" + +// Random unknown crate type. Also check that we can handle non-ASCII. +//@ revisions: unknown +//@[unknown] compile-flags: --crate-type=🤡 +//@[unknown] error-pattern: "unknown crate type: `🤡`" + +fn main() {} diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr b/tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr new file mode 100644 index 000000000000..7fb0f09a1afb --- /dev/null +++ b/tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr @@ -0,0 +1,2 @@ +error: unknown crate type: `🤡` + diff --git a/tests/ui/invalid/invalid-debugger-visualizer-option.rs b/tests/ui/invalid/invalid-debugger-visualizer-option.rs index 16e5619e8e49..0f1cf15a6879 100644 --- a/tests/ui/invalid/invalid-debugger-visualizer-option.rs +++ b/tests/ui/invalid/invalid-debugger-visualizer-option.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test: "foo.random:.*\(" -> "foo.random: $$FILE_NOT_FOUND_MSG (" -//@ normalize-stderr-test: "os error \d+" -> "os error $$FILE_NOT_FOUND_CODE" +//@ normalize-stderr: "foo.random:.*\(" -> "foo.random: $$FILE_NOT_FOUND_MSG (" +//@ normalize-stderr: "os error \d+" -> "os error $$FILE_NOT_FOUND_CODE" #![debugger_visualizer(random_file = "../foo.random")] //~ ERROR invalid argument #![debugger_visualizer(natvis_file = "../foo.random")] //~ ERROR diff --git a/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs b/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs index a6deb8bab29c..7cae77eb67f4 100644 --- a/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs +++ b/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs @@ -19,10 +19,10 @@ //@ error-pattern: error // On Mac OS X, we get an error like the below -//@ normalize-stderr-test: "failed to write bytecode to ./does-not-exist/output.non_ice_error_on_worker_io_fail.*" -> "io error modifying ./does-not-exist/" +//@ normalize-stderr: "failed to write bytecode to ./does-not-exist/output.non_ice_error_on_worker_io_fail.*" -> "io error modifying ./does-not-exist/" // On Linux, we get an error like the below -//@ normalize-stderr-test: "couldn't create a temp dir.*" -> "io error modifying ./does-not-exist/" +//@ normalize-stderr: "couldn't create a temp dir.*" -> "io error modifying ./does-not-exist/" //@ ignore-windows - this is a unix-specific test //@ ignore-emscripten - the file-system issues do not replicate here diff --git a/tests/ui/issues/issue-20413.rs b/tests/ui/issues/issue-20413.rs index 0f602b32fabe..7766f3755993 100644 --- a/tests/ui/issues/issue-20413.rs +++ b/tests/ui/issues/issue-20413.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" trait Foo { fn answer(self); } diff --git a/tests/ui/issues/issue-21763.rs b/tests/ui/issues/issue-21763.rs index 1d0a0705cbbd..c1ed5d94f9b5 100644 --- a/tests/ui/issues/issue-21763.rs +++ b/tests/ui/issues/issue-21763.rs @@ -1,6 +1,6 @@ // Regression test for HashMap only impl'ing Send/Sync if its contents do -//@ normalize-stderr-test: "\S+[\\/]hashbrown\S+" -> "$$HASHBROWN_SRC_LOCATION" +//@ normalize-stderr: "\S+[\\/]hashbrown\S+" -> "$$HASHBROWN_SRC_LOCATION" use std::collections::HashMap; use std::rc::Rc; diff --git a/tests/ui/issues/issue-28625.rs b/tests/ui/issues/issue-28625.rs index 23f96d10bf26..54ed408e7488 100644 --- a/tests/ui/issues/issue-28625.rs +++ b/tests/ui/issues/issue-28625.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "\d+ bits" -> "N bits" +//@ normalize-stderr: "\d+ bits" -> "N bits" trait Bar { type Bar; diff --git a/tests/ui/issues/issue-32377.rs b/tests/ui/issues/issue-32377.rs index 3a4942deb834..6737f9820efd 100644 --- a/tests/ui/issues/issue-32377.rs +++ b/tests/ui/issues/issue-32377.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "\d+ bits" -> "N bits" +//@ normalize-stderr: "\d+ bits" -> "N bits" use std::mem; use std::marker::PhantomData; diff --git a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs index 96e2691164ba..edf4f2fce26a 100644 --- a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs +++ b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs @@ -1,5 +1,5 @@ //@ build-fail -//@ normalize-stderr-test: ".nll/" -> "/" +//@ normalize-stderr: ".nll/" -> "/" trait Mirror { type Image; diff --git a/tests/ui/issues/issue-67552.rs b/tests/ui/issues/issue-67552.rs index 26466bf838c4..343ae4f262fc 100644 --- a/tests/ui/issues/issue-67552.rs +++ b/tests/ui/issues/issue-67552.rs @@ -1,6 +1,6 @@ //@ build-fail //@ compile-flags: -Copt-level=0 -//@ normalize-stderr-test: ".nll/" -> "/" +//@ normalize-stderr: ".nll/" -> "/" fn main() { rec(Empty); diff --git a/tests/ui/issues/issue-8727.rs b/tests/ui/issues/issue-8727.rs index 4ef660003748..b824be7c12fe 100644 --- a/tests/ui/issues/issue-8727.rs +++ b/tests/ui/issues/issue-8727.rs @@ -2,7 +2,7 @@ // recursions. //@ build-fail -//@ normalize-stderr-test: ".nll/" -> "/" +//@ normalize-stderr: ".nll/" -> "/" fn generic() { //~ WARN function cannot return without recursing generic::>(); diff --git a/tests/ui/lang-items/duplicate.rs b/tests/ui/lang-items/duplicate.rs index 3aa7dd2b0bee..4594e9456a4c 100644 --- a/tests/ui/lang-items/duplicate.rs +++ b/tests/ui/lang-items/duplicate.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "loaded from .*libcore-.*.rlib" -> "loaded from SYSROOT/libcore-*.rlib" +//@ normalize-stderr: "loaded from .*libcore-.*.rlib" -> "loaded from SYSROOT/libcore-*.rlib" #![feature(lang_items)] #[lang = "sized"] diff --git a/tests/ui/layout/debug.rs b/tests/ui/layout/debug.rs index 166321798de3..5602c4e711f6 100644 --- a/tests/ui/layout/debug.rs +++ b/tests/ui/layout/debug.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" #![feature(never_type, rustc_attrs, type_alias_impl_trait, repr_simd)] #![crate_type = "lib"] diff --git a/tests/ui/layout/enum-scalar-pair-int-ptr.rs b/tests/ui/layout/enum-scalar-pair-int-ptr.rs index ebb3fdb1514c..60cada5e05a8 100644 --- a/tests/ui/layout/enum-scalar-pair-int-ptr.rs +++ b/tests/ui/layout/enum-scalar-pair-int-ptr.rs @@ -1,6 +1,6 @@ -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" -//@ normalize-stderr-test: "Int\(I[0-9]+," -> "Int(I?," -//@ normalize-stderr-test: "valid_range: 0..=[0-9]+" -> "valid_range: $$VALID_RANGE" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr: "Int\(I[0-9]+," -> "Int(I?," +//@ normalize-stderr: "valid_range: 0..=[0-9]+" -> "valid_range: $$VALID_RANGE" //! Enum layout tests related to scalar pairs with an int/ptr common primitive. diff --git a/tests/ui/layout/enum.rs b/tests/ui/layout/enum.rs index b58d390a2eff..005faf8ee508 100644 --- a/tests/ui/layout/enum.rs +++ b/tests/ui/layout/enum.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" //! Various enum layout tests. #![feature(rustc_attrs)] diff --git a/tests/ui/layout/ice-type-error-in-tail-124031.rs b/tests/ui/layout/ice-type-error-in-tail-124031.rs index ecd6f3d56f3f..ef5b27cd1952 100644 --- a/tests/ui/layout/ice-type-error-in-tail-124031.rs +++ b/tests/ui/layout/ice-type-error-in-tail-124031.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "\d+ bits" -> "$$BITS bits" +//@ normalize-stderr: "\d+ bits" -> "$$BITS bits" // Regression test for issue #124031 // Checks that we don't ICE when the tail diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs index 2c8179a63d80..328d204aa3cd 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" #![crate_type = "lib"] #![feature(rustc_attrs)] diff --git a/tests/ui/layout/issue-96185-overaligned-enum.rs b/tests/ui/layout/issue-96185-overaligned-enum.rs index 88863d14cb7f..341233a7890e 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.rs +++ b/tests/ui/layout/issue-96185-overaligned-enum.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" #![crate_type = "lib"] #![feature(rustc_attrs)] diff --git a/tests/ui/layout/struct.rs b/tests/ui/layout/struct.rs index 309624e667cc..5f652b3d570d 100644 --- a/tests/ui/layout/struct.rs +++ b/tests/ui/layout/struct.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" //! Various struct layout tests. #![feature(rustc_attrs)] diff --git a/tests/ui/layout/valid_range_oob.rs b/tests/ui/layout/valid_range_oob.rs index 38ab5cec7a66..df816e740663 100644 --- a/tests/ui/layout/valid_range_oob.rs +++ b/tests/ui/layout/valid_range_oob.rs @@ -1,6 +1,6 @@ //@ failure-status: 101 -//@ normalize-stderr-test: "note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr: "note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> "" //@ rustc-env:RUST_BACKTRACE=0 #![feature(rustc_attrs)] diff --git a/tests/ui/layout/zero-sized-array-enum-niche.rs b/tests/ui/layout/zero-sized-array-enum-niche.rs index 433db46b7a00..152f44bd8637 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.rs +++ b/tests/ui/layout/zero-sized-array-enum-niche.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" #![crate_type = "lib"] #![feature(rustc_attrs)] diff --git a/tests/ui/limits/huge-enum.rs b/tests/ui/limits/huge-enum.rs index 5664d0ba5166..66c5be20693d 100644 --- a/tests/ui/limits/huge-enum.rs +++ b/tests/ui/limits/huge-enum.rs @@ -1,6 +1,6 @@ //@ build-fail -//@ normalize-stderr-test: "std::option::Option<\[u32; \d+\]>" -> "TYPE" -//@ normalize-stderr-test: "\[u32; \d+\]" -> "TYPE" +//@ normalize-stderr: "std::option::Option<\[u32; \d+\]>" -> "TYPE" +//@ normalize-stderr: "\[u32; \d+\]" -> "TYPE" #[cfg(target_pointer_width = "32")] type BIG = Option<[u32; (1<<29)-1]>; diff --git a/tests/ui/limits/huge-struct.rs b/tests/ui/limits/huge-struct.rs index f7ce4f26db18..296147015bfe 100644 --- a/tests/ui/limits/huge-struct.rs +++ b/tests/ui/limits/huge-struct.rs @@ -1,9 +1,8 @@ // ignore-tidy-linelength //@ build-fail -//@ normalize-stderr-test: "S32" -> "SXX" -//@ normalize-stderr-test: "S1M" -> "SXX" -//@ normalize-stderr-32bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" -//@ normalize-stderr-64bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" +//@ normalize-stderr: "S32" -> "SXX" +//@ normalize-stderr: "S1M" -> "SXX" +//@ normalize-stderr: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" struct S32 { v0: T, diff --git a/tests/ui/limits/huge-struct.stderr b/tests/ui/limits/huge-struct.stderr index b10455ffd2dc..e03456f1c7b5 100644 --- a/tests/ui/limits/huge-struct.stderr +++ b/tests/ui/limits/huge-struct.stderr @@ -1,5 +1,5 @@ error: values of the type $REALLY_TOO_BIG are too big for the target architecture - --> $DIR/huge-struct.rs:48:9 + --> $DIR/huge-struct.rs:47:9 | LL | let fat: Option>>> = None; | ^^^ diff --git a/tests/ui/limits/issue-17913.rs b/tests/ui/limits/issue-17913.rs index 24fd3b542e6a..5407902daba5 100644 --- a/tests/ui/limits/issue-17913.rs +++ b/tests/ui/limits/issue-17913.rs @@ -1,5 +1,5 @@ //@ build-fail -//@ normalize-stderr-test: "\[&usize; \d+\]" -> "[&usize; usize::MAX]" +//@ normalize-stderr: "\[&usize; \d+\]" -> "[&usize; usize::MAX]" //@ error-pattern: too big for the target architecture #[cfg(target_pointer_width = "64")] diff --git a/tests/ui/limits/issue-55878.rs b/tests/ui/limits/issue-55878.rs index 81696e226fd0..db4a2724452a 100644 --- a/tests/ui/limits/issue-55878.rs +++ b/tests/ui/limits/issue-55878.rs @@ -1,6 +1,4 @@ //@ build-fail -//@ normalize-stderr-64bit: "18446744073709551615" -> "SIZE" -//@ normalize-stderr-32bit: "4294967295" -> "SIZE" //@ error-pattern: are too big for the target architecture fn main() { diff --git a/tests/ui/limits/issue-55878.stderr b/tests/ui/limits/issue-55878.stderr index 51c4837f4583..d2b5150c5561 100644 --- a/tests/ui/limits/issue-55878.stderr +++ b/tests/ui/limits/issue-55878.stderr @@ -6,7 +6,7 @@ error[E0080]: evaluation of constant value failed note: inside `std::mem::size_of::<[u8; usize::MAX]>` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL note: inside `main` - --> $DIR/issue-55878.rs:7:26 + --> $DIR/issue-55878.rs:5:26 | LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/link-native-libs/msvc-non-utf8-output.rs b/tests/ui/link-native-libs/msvc-non-utf8-output.rs index 659a832247a9..03b1f6516ab9 100644 --- a/tests/ui/link-native-libs/msvc-non-utf8-output.rs +++ b/tests/ui/link-native-libs/msvc-non-utf8-output.rs @@ -1,5 +1,5 @@ //@ build-fail //@ compile-flags:-C link-arg=⦺ⅈ⽯⭏⽽◃⡽⚞ //@ only-msvc -//@ normalize-stderr-test: "(?:.|\n)*(⦺ⅈ⽯⭏⽽◃⡽⚞)(?:.|\n)*" -> "$1" +//@ normalize-stderr: "(?:.|\n)*(⦺ⅈ⽯⭏⽽◃⡽⚞)(?:.|\n)*" -> "$1" pub fn main() {} diff --git a/tests/ui/lint/lint-overflowing-ops.rs b/tests/ui/lint/lint-overflowing-ops.rs index eec347010ad6..116460f11cc0 100644 --- a/tests/ui/lint/lint-overflowing-ops.rs +++ b/tests/ui/lint/lint-overflowing-ops.rs @@ -11,8 +11,8 @@ //@ [opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O -Z deduplicate-diagnostics=yes //@ build-fail //@ ignore-pass (test tests codegen-time behaviour) -//@ normalize-stderr-test: "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which" -//@ normalize-stderr-test: "shift right by `(64|32)_usize`, which" -> "shift right by `%BITS%`, which" +//@ normalize-stderr: "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which" +//@ normalize-stderr: "shift right by `(64|32)_usize`, which" -> "shift right by `%BITS%`, which" #![deny(arithmetic_overflow)] diff --git a/tests/ui/lto/lto-duplicate-symbols.rs b/tests/ui/lto/lto-duplicate-symbols.rs index 679d44baae78..27bdde418f85 100644 --- a/tests/ui/lto/lto-duplicate-symbols.rs +++ b/tests/ui/lto/lto-duplicate-symbols.rs @@ -4,7 +4,7 @@ //@ error-pattern:Linking globals named 'foo': symbol multiply defined! //@ compile-flags: -C lto //@ no-prefer-dynamic -//@ normalize-stderr-test: "lto-duplicate-symbols2\.lto_duplicate_symbols2\.[0-9a-zA-Z]+-cgu" -> "lto-duplicate-symbols2.lto_duplicate_symbols2.HASH-cgu" +//@ normalize-stderr: "lto-duplicate-symbols2\.lto_duplicate_symbols2\.[0-9a-zA-Z]+-cgu" -> "lto-duplicate-symbols2.lto_duplicate_symbols2.HASH-cgu" extern crate lto_duplicate_symbols1; extern crate lto_duplicate_symbols2; diff --git a/tests/ui/macros/macro-metavar-expr-concat/repetitions.rs b/tests/ui/macros/macro-metavar-expr-concat/repetitions.rs index 781443207ac1..52a7d5cd8a7e 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/repetitions.rs +++ b/tests/ui/macros/macro-metavar-expr-concat/repetitions.rs @@ -1,5 +1,3 @@ -//@ run-pass - #![feature(macro_metavar_expr_concat)] macro_rules! one_rep { @@ -10,9 +8,29 @@ macro_rules! one_rep { }; } +macro_rules! issue_128346 { + ( $($a:ident)* ) => { + A( + const ${concat($a, Z)}: i32 = 3; + //~^ ERROR invalid syntax + )* + }; +} + +macro_rules! issue_131393 { + ($t:ident $($en:ident)?) => { + read::<${concat($t, $en)}>() + //~^ ERROR invalid syntax + //~| ERROR invalid syntax + } +} + fn main() { one_rep!(A B C); assert_eq!(AZ, 3); assert_eq!(BZ, 3); assert_eq!(CZ, 3); + issue_128346!(A B C); + issue_131393!(u8); + issue_131393!(u16 le); } diff --git a/tests/ui/macros/macro-metavar-expr-concat/repetitions.stderr b/tests/ui/macros/macro-metavar-expr-concat/repetitions.stderr new file mode 100644 index 000000000000..c3006c4be5df --- /dev/null +++ b/tests/ui/macros/macro-metavar-expr-concat/repetitions.stderr @@ -0,0 +1,22 @@ +error: invalid syntax + --> $DIR/repetitions.rs:14:20 + | +LL | const ${concat($a, Z)}: i32 = 3; + | ^^^^^^^^^^^^^^^ + +error: invalid syntax + --> $DIR/repetitions.rs:22:17 + | +LL | read::<${concat($t, $en)}>() + | ^^^^^^^^^^^^^^^^^ + +error: invalid syntax + --> $DIR/repetitions.rs:22:17 + | +LL | read::<${concat($t, $en)}>() + | ^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/macros/macros-nonfatal-errors.rs b/tests/ui/macros/macros-nonfatal-errors.rs index 658455b1b5b8..79beffbe986e 100644 --- a/tests/ui/macros/macros-nonfatal-errors.rs +++ b/tests/ui/macros/macros-nonfatal-errors.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "`: .*" -> "`: $$FILE_NOT_FOUND_MSG" +//@ normalize-stderr: "`: .*" -> "`: $$FILE_NOT_FOUND_MSG" // test that errors in a (selection) of macros don't kill compilation // immediately, so that we get more errors listed at a time. diff --git a/tests/ui/methods/inherent-bound-in-probe.rs b/tests/ui/methods/inherent-bound-in-probe.rs index 265ef93425a2..9b9eb91559b3 100644 --- a/tests/ui/methods/inherent-bound-in-probe.rs +++ b/tests/ui/methods/inherent-bound-in-probe.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" // Fixes #110131 // diff --git a/tests/ui/mir/lint/storage-live.rs b/tests/ui/mir/lint/storage-live.rs index ded02150342d..3e0cc4ee0614 100644 --- a/tests/ui/mir/lint/storage-live.rs +++ b/tests/ui/mir/lint/storage-live.rs @@ -2,10 +2,10 @@ //@ failure-status: 101 //@ error-pattern: broken MIR in //@ error-pattern: StorageLive(_1) which already has storage here -//@ normalize-stderr-test: "note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*\n" -> "" -//@ normalize-stderr-test: "storage_live\[....\]" -> "storage_live[HASH]" -//@ normalize-stderr-test: "(delayed at [^:]+):\d+:\d+ - " -> "$1:LL:CC - " +//@ normalize-stderr: "note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr: "storage_live\[....\]" -> "storage_live[HASH]" +//@ normalize-stderr: "(delayed at [^:]+):\d+:\d+ - " -> "$1:LL:CC - " //@ rustc-env:RUST_BACKTRACE=0 #![feature(custom_mir, core_intrinsics)] diff --git a/tests/ui/modules/path-no-file-name.rs b/tests/ui/modules/path-no-file-name.rs index c36043686fcf..23127346e02a 100644 --- a/tests/ui/modules/path-no-file-name.rs +++ b/tests/ui/modules/path-no-file-name.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test: "\.:.*\(" -> ".: $$ACCESS_DENIED_MSG (" -//@ normalize-stderr-test: "os error \d+" -> "os error $$ACCESS_DENIED_CODE" +//@ normalize-stderr: "\.:.*\(" -> ".: $$ACCESS_DENIED_MSG (" +//@ normalize-stderr: "os error \d+" -> "os error $$ACCESS_DENIED_CODE" #[path = "."] mod m; //~ ERROR couldn't read diff --git a/tests/ui/packed/packed-struct-transmute.rs b/tests/ui/packed/packed-struct-transmute.rs index 0a887e3886d5..98feeea88714 100644 --- a/tests/ui/packed/packed-struct-transmute.rs +++ b/tests/ui/packed/packed-struct-transmute.rs @@ -3,7 +3,7 @@ // the error points to the start of the file, not the line with the // transmute -//@ normalize-stderr-test: "\d+ bits" -> "N bits" +//@ normalize-stderr: "\d+ bits" -> "N bits" //@ error-pattern: cannot transmute between types of different sizes, or dependently-sized types use std::mem; diff --git a/tests/ui/panic-handler/panic-handler-std.rs b/tests/ui/panic-handler/panic-handler-std.rs index 82e6de43a2ec..4eb05b5365fe 100644 --- a/tests/ui/panic-handler/panic-handler-std.rs +++ b/tests/ui/panic-handler/panic-handler-std.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" +//@ normalize-stderr: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" //@ error-pattern: found duplicate lang item `panic_impl` extern crate core; diff --git a/tests/ui/panics/default-backtrace-ice.rs b/tests/ui/panics/default-backtrace-ice.rs index 7953283f0281..c47f458f6e97 100644 --- a/tests/ui/panics/default-backtrace-ice.rs +++ b/tests/ui/panics/default-backtrace-ice.rs @@ -5,12 +5,12 @@ //@ error-pattern:__rust_begin_short_backtrace //@ failure-status:101 //@ ignore-msvc -//@ normalize-stderr-test: "note: .*" -> "" -//@ normalize-stderr-test: "thread 'rustc' .*" -> "" -//@ normalize-stderr-test: " +\d+:.*__rust_begin_short_backtrace.*" -> "(begin_short_backtrace)" -//@ normalize-stderr-test: " +\d+:.*__rust_end_short_backtrace.*" -> "(end_short_backtrace)" -//@ normalize-stderr-test: " +\d+:.*\n" -> "" -//@ normalize-stderr-test: " +at .*\n" -> "" +//@ normalize-stderr: "note: .*" -> "" +//@ normalize-stderr: "thread 'rustc' .*" -> "" +//@ normalize-stderr: " +\d+:.*__rust_begin_short_backtrace.*" -> "(begin_short_backtrace)" +//@ normalize-stderr: " +\d+:.*__rust_end_short_backtrace.*" -> "(end_short_backtrace)" +//@ normalize-stderr: " +\d+:.*\n" -> "" +//@ normalize-stderr: " +at .*\n" -> "" // // This test makes sure that full backtraces are used for ICEs when // RUST_BACKTRACE is not set. It does this by checking for the presence of diff --git a/tests/ui/panics/issue-47429-short-backtraces.rs b/tests/ui/panics/issue-47429-short-backtraces.rs index 0d216fdd6530..dff885af1b87 100644 --- a/tests/ui/panics/issue-47429-short-backtraces.rs +++ b/tests/ui/panics/issue-47429-short-backtraces.rs @@ -8,9 +8,11 @@ // This is needed to avoid test output differences across std being built with v0 symbols vs legacy // symbols. -//@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +//@ normalize-stderr: "begin_panic::<&str>" -> "begin_panic" +// This variant occurs on macOS with `rust.debuginfo-level = "line-tables-only"` (#133997) +//@ normalize-stderr: " begin_panic<&str>" -> " std::panicking::begin_panic" // And this is for differences between std with and without debuginfo. -//@ normalize-stderr-test: "\n +at [^\n]+" -> "" +//@ normalize-stderr: "\n +at [^\n]+" -> "" //@ ignore-msvc see #62897 and `backtrace-debuginfo.rs` test //@ ignore-android FIXME #17520 diff --git a/tests/ui/panics/issue-47429-short-backtraces.run.stderr b/tests/ui/panics/issue-47429-short-backtraces.run.stderr index 1078a2fbc902..6a22e0215fee 100644 --- a/tests/ui/panics/issue-47429-short-backtraces.run.stderr +++ b/tests/ui/panics/issue-47429-short-backtraces.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at $DIR/issue-47429-short-backtraces.rs:24:5: +thread 'main' panicked at $DIR/issue-47429-short-backtraces.rs:26:5: explicit panic stack backtrace: 0: std::panicking::begin_panic diff --git a/tests/ui/panics/panic-in-cleanup.rs b/tests/ui/panics/panic-in-cleanup.rs index c3639c7034eb..8cddeb37348d 100644 --- a/tests/ui/panics/panic-in-cleanup.rs +++ b/tests/ui/panics/panic-in-cleanup.rs @@ -2,9 +2,9 @@ //@ exec-env:RUST_BACKTRACE=0 //@ check-run-results //@ error-pattern: panic in a destructor during cleanup -//@ normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "" -//@ normalize-stderr-test: "\n +at [^\n]+" -> "" -//@ normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +//@ normalize-stderr: "\n +[0-9]+:[^\n]+" -> "" +//@ normalize-stderr: "\n +at [^\n]+" -> "" +//@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" //@ needs-unwind //@ ignore-emscripten "RuntimeError" junk in output //@ ignore-msvc SEH doesn't do panic-during-cleanup the same way as everyone else diff --git a/tests/ui/panics/panic-in-ffi.rs b/tests/ui/panics/panic-in-ffi.rs index c0ae1899f4c2..6068e4fdc59b 100644 --- a/tests/ui/panics/panic-in-ffi.rs +++ b/tests/ui/panics/panic-in-ffi.rs @@ -3,9 +3,9 @@ //@ check-run-results //@ error-pattern: panic in a function that cannot unwind //@ error-pattern: Noisy Drop -//@ normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "" -//@ normalize-stderr-test: "\n +at [^\n]+" -> "" -//@ normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +//@ normalize-stderr: "\n +[0-9]+:[^\n]+" -> "" +//@ normalize-stderr: "\n +at [^\n]+" -> "" +//@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" //@ needs-unwind //@ ignore-emscripten "RuntimeError" junk in output diff --git a/tests/ui/panics/panic-in-message-fmt.rs b/tests/ui/panics/panic-in-message-fmt.rs index e5bedf96b357..1e9bbaf45c54 100644 --- a/tests/ui/panics/panic-in-message-fmt.rs +++ b/tests/ui/panics/panic-in-message-fmt.rs @@ -4,9 +4,9 @@ //@ exec-env:RUST_BACKTRACE=0 //@ check-run-results //@ error-pattern: panicked while processing panic -//@ normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "" -//@ normalize-stderr-test: "\n +at [^\n]+" -> "" -//@ normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +//@ normalize-stderr: "\n +[0-9]+:[^\n]+" -> "" +//@ normalize-stderr: "\n +at [^\n]+" -> "" +//@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" //@ ignore-emscripten "RuntimeError" junk in output use std::fmt::{Display, self}; diff --git a/tests/ui/panics/panic-short-backtrace-windows-x86_64.rs b/tests/ui/panics/panic-short-backtrace-windows-x86_64.rs index 70c4a5aaf2b9..a56214b73bf0 100644 --- a/tests/ui/panics/panic-short-backtrace-windows-x86_64.rs +++ b/tests/ui/panics/panic-short-backtrace-windows-x86_64.rs @@ -17,7 +17,7 @@ // We need to normalize out frame 5 because without debug info, dbghelp.dll doesn't know where CGU // internal functions like `main` start or end and so it will return whatever symbol happens // to be located near the address. -//@ normalize-stderr-test: "5: .*" -> "5: some Rust fn" +//@ normalize-stderr: "5: .*" -> "5: some Rust fn" // Backtraces are pretty broken in general on i686-pc-windows-msvc (#62897). //@ only-x86_64-pc-windows-msvc diff --git a/tests/ui/panics/runtime-switch.rs b/tests/ui/panics/runtime-switch.rs index 10dce2509093..ffd038f95351 100644 --- a/tests/ui/panics/runtime-switch.rs +++ b/tests/ui/panics/runtime-switch.rs @@ -8,9 +8,11 @@ // This is needed to avoid test output differences across std being built with v0 symbols vs legacy // symbols. -//@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +//@ normalize-stderr: "begin_panic::<&str>" -> "begin_panic" +// This variant occurs on macOS with `rust.debuginfo-level = "line-tables-only"` (#133997) +//@ normalize-stderr: " begin_panic<&str>" -> " std::panicking::begin_panic" // And this is for differences between std with and without debuginfo. -//@ normalize-stderr-test: "\n +at [^\n]+" -> "" +//@ normalize-stderr: "\n +at [^\n]+" -> "" //@ ignore-msvc see #62897 and `backtrace-debuginfo.rs` test //@ ignore-android FIXME #17520 diff --git a/tests/ui/panics/runtime-switch.run.stderr b/tests/ui/panics/runtime-switch.run.stderr index abbb91eba60e..35be010d6be7 100644 --- a/tests/ui/panics/runtime-switch.run.stderr +++ b/tests/ui/panics/runtime-switch.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at $DIR/runtime-switch.rs:27:5: +thread 'main' panicked at $DIR/runtime-switch.rs:29:5: explicit panic stack backtrace: 0: std::panicking::begin_panic diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.rs b/tests/ui/panics/short-ice-remove-middle-frames-2.rs index c2f04cd122c7..48f60b141706 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames-2.rs +++ b/tests/ui/panics/short-ice-remove-middle-frames-2.rs @@ -11,9 +11,11 @@ //@ ignore-msvc the `__rust_{begin,end}_short_backtrace` symbols aren't reliable. // This is needed to avoid test output differences across std being built with v0 symbols vs legacy // symbols. -//@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +//@ normalize-stderr: "begin_panic::<&str>" -> "begin_panic" +// This variant occurs on macOS with `rust.debuginfo-level = "line-tables-only"` (#133997) +//@ normalize-stderr: " begin_panic<&str>" -> " std::panicking::begin_panic" // And this is for differences between std with and without debuginfo. -//@ normalize-stderr-test: "\n +at [^\n]+" -> "" +//@ normalize-stderr: "\n +at [^\n]+" -> "" /// This test case make sure that we can have multiple pairs of `__rust_{begin,end}_short_backtrace` diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr index 67577f3568e9..ab23ce780625 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr +++ b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:61:5: +thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:63:5: debug!!! stack backtrace: 0: std::panicking::begin_panic diff --git a/tests/ui/panics/short-ice-remove-middle-frames.rs b/tests/ui/panics/short-ice-remove-middle-frames.rs index c035e7e69bc6..216c51277995 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames.rs +++ b/tests/ui/panics/short-ice-remove-middle-frames.rs @@ -12,9 +12,11 @@ // This is needed to avoid test output differences across std being built with v0 symbols vs legacy // symbols. -//@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +//@ normalize-stderr: "begin_panic::<&str>" -> "begin_panic" +// This variant occurs on macOS with `rust.debuginfo-level = "line-tables-only"` (#133997) +//@ normalize-stderr: " begin_panic<&str>" -> " std::panicking::begin_panic" // And this is for differences between std with and without debuginfo. -//@ normalize-stderr-test: "\n +at [^\n]+" -> "" +//@ normalize-stderr: "\n +at [^\n]+" -> "" #[inline(never)] fn __rust_begin_short_backtrace T>(f: F) -> T { diff --git a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr index 63fa466ab24a..d2616911e3bf 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr +++ b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:57:5: +thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:59:5: debug!!! stack backtrace: 0: std::panicking::begin_panic diff --git a/tests/ui/parser/issues/issue-5806.rs b/tests/ui/parser/issues/issue-5806.rs index 3f1b7cda9316..dbd53a7adc43 100644 --- a/tests/ui/parser/issues/issue-5806.rs +++ b/tests/ui/parser/issues/issue-5806.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test: "parser:.*\(" -> "parser: $$ACCESS_DENIED_MSG (" -//@ normalize-stderr-test: "os error \d+" -> "os error $$ACCESS_DENIED_CODE" +//@ normalize-stderr: "parser:.*\(" -> "parser: $$ACCESS_DENIED_MSG (" +//@ normalize-stderr: "os error \d+" -> "os error $$ACCESS_DENIED_CODE" #[path = "../parser"] mod foo; //~ ERROR couldn't read diff --git a/tests/ui/parser/mod_file_with_path_attr.rs b/tests/ui/parser/mod_file_with_path_attr.rs index e2854f3cc8d9..ff964f750e29 100644 --- a/tests/ui/parser/mod_file_with_path_attr.rs +++ b/tests/ui/parser/mod_file_with_path_attr.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "not_a_real_file.rs:.*\(" -> "not_a_real_file.rs: $$FILE_NOT_FOUND_MSG (" +//@ normalize-stderr: "not_a_real_file.rs:.*\(" -> "not_a_real_file.rs: $$FILE_NOT_FOUND_MSG (" #[path = "not_a_real_file.rs"] mod m; //~ ERROR not_a_real_file.rs diff --git a/tests/ui/print-request/macos-target.rs b/tests/ui/print-request/macos-target.rs index af74babbed48..70122a525802 100644 --- a/tests/ui/print-request/macos-target.rs +++ b/tests/ui/print-request/macos-target.rs @@ -1,8 +1,8 @@ //@ only-apple //@ compile-flags: --print deployment-target -//@ normalize-stdout-test: "\w*_DEPLOYMENT_TARGET" -> "$$OS_DEPLOYMENT_TARGET" -//@ normalize-stdout-test: "\d+\." -> "$$CURRENT_MAJOR_VERSION." -//@ normalize-stdout-test: "\d+" -> "$$CURRENT_MINOR_VERSION" +//@ normalize-stdout: "\w*_DEPLOYMENT_TARGET" -> "$$OS_DEPLOYMENT_TARGET" +//@ normalize-stdout: "\d+\." -> "$$CURRENT_MAJOR_VERSION." +//@ normalize-stdout: "\d+" -> "$$CURRENT_MINOR_VERSION" //@ check-pass fn main() {} diff --git a/tests/ui/proc-macro/load-panic-backtrace.rs b/tests/ui/proc-macro/load-panic-backtrace.rs index 302bcaea75e6..848bdaf9f372 100644 --- a/tests/ui/proc-macro/load-panic-backtrace.rs +++ b/tests/ui/proc-macro/load-panic-backtrace.rs @@ -1,8 +1,8 @@ //@ proc-macro: test-macros.rs //@ compile-flags: -Z proc-macro-backtrace //@ rustc-env:RUST_BACKTRACE=0 -//@ normalize-stderr-test: "thread '.*' panicked " -> "" -//@ normalize-stderr-test: "note:.*RUST_BACKTRACE=1.*\n" -> "" +//@ normalize-stderr: "thread '.*' panicked " -> "" +//@ normalize-stderr: "note:.*RUST_BACKTRACE=1.*\n" -> "" //@ needs-unwind proc macro panics to report errors #[macro_use] diff --git a/tests/ui/proc-macro/meta-macro-hygiene.rs b/tests/ui/proc-macro/meta-macro-hygiene.rs index 9fbe9763b44d..afe0e1fb601a 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.rs +++ b/tests/ui/proc-macro/meta-macro-hygiene.rs @@ -4,9 +4,9 @@ //@ compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no //@ check-pass // ignore-tidy-linelength -//@ normalize-stdout-test: "\d+#" -> "0#" -//@ normalize-stdout-test: "expn\d{3,}" -> "expnNNN" -//@ normalize-stdout-test: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" +//@ normalize-stdout: "\d+#" -> "0#" +//@ normalize-stdout: "expn\d{3,}" -> "expnNNN" +//@ normalize-stdout: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" // // We don't care about symbol ids, so we set them all to 0 // in the stdout diff --git a/tests/ui/proc-macro/meta-macro-hygiene.stdout b/tests/ui/proc-macro/meta-macro-hygiene.stdout index ae02b24e1d0e..fae8446515af 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.stdout +++ b/tests/ui/proc-macro/meta-macro-hygiene.stdout @@ -8,9 +8,9 @@ Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro //@ compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no //@ check-pass // ignore-tidy-linelength -//@ normalize-stdout-test: "\d+#" -> "0#" -//@ normalize-stdout-test: "expn\d{3,}" -> "expnNNN" -//@ normalize-stdout-test: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" +//@ normalize-stdout: "\d+#" -> "0#" +//@ normalize-stdout: "expn\d{3,}" -> "expnNNN" +//@ normalize-stdout: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" // // We don't care about symbol ids, so we set them all to 0 // in the stdout diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.rs b/tests/ui/proc-macro/nonterminal-token-hygiene.rs index 76c71441c808..e2aedb245d07 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.rs +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.rs @@ -4,9 +4,9 @@ //@ compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene //@ compile-flags: -Z trim-diagnostic-paths=no // ignore-tidy-linelength -//@ normalize-stdout-test: "\d+#" -> "0#" -//@ normalize-stdout-test: "expn\d{3,}" -> "expnNNN" -//@ normalize-stdout-test: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" +//@ normalize-stdout: "\d+#" -> "0#" +//@ normalize-stdout: "expn\d{3,}" -> "expnNNN" +//@ normalize-stdout: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" //@ proc-macro: test-macros.rs #![feature(decl_macro)] diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout index 1ad140590281..e7dda7d3c160 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout @@ -28,9 +28,9 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ //@ compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene //@ compile-flags: -Z trim-diagnostic-paths=no // ignore-tidy-linelength -//@ normalize-stdout-test: "\d+#" -> "0#" -//@ normalize-stdout-test: "expn\d{3,}" -> "expnNNN" -//@ normalize-stdout-test: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" +//@ normalize-stdout: "\d+#" -> "0#" +//@ normalize-stdout: "expn\d{3,}" -> "expnNNN" +//@ normalize-stdout: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" //@ proc-macro: test-macros.rs #![feature /* 0#0 */(decl_macro)] diff --git a/tests/ui/process/println-with-broken-pipe.rs b/tests/ui/process/println-with-broken-pipe.rs index 4ac1f7c98cbd..d88c6dcc12b3 100644 --- a/tests/ui/process/println-with-broken-pipe.rs +++ b/tests/ui/process/println-with-broken-pipe.rs @@ -5,7 +5,7 @@ //@ ignore-fuchsia //@ ignore-horizon //@ ignore-android -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" //@ compile-flags: -Zon-broken-pipe=error // Test what the error message looks like when `println!()` panics because of diff --git a/tests/ui/recursion/issue-23122-2.rs b/tests/ui/recursion/issue-23122-2.rs index 2880b9564170..3e14fa92dd0f 100644 --- a/tests/ui/recursion/issue-23122-2.rs +++ b/tests/ui/recursion/issue-23122-2.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" trait Next { type Next: Next; } diff --git a/tests/ui/recursion/issue-83150.rs b/tests/ui/recursion/issue-83150.rs index e919a2d93096..ea1bef4fce39 100644 --- a/tests/ui/recursion/issue-83150.rs +++ b/tests/ui/recursion/issue-83150.rs @@ -1,7 +1,7 @@ //~ ERROR overflow evaluating the requirement `Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:13:24: 13:27}>: Iterator` //@ build-fail //@ compile-flags: -Copt-level=0 -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" fn main() { let mut iter = 0u8..1; diff --git a/tests/ui/recursion/recursion.rs b/tests/ui/recursion/recursion.rs index 074e9ed6947a..f3c633983b19 100644 --- a/tests/ui/recursion/recursion.rs +++ b/tests/ui/recursion/recursion.rs @@ -1,6 +1,6 @@ //@ build-fail //@ compile-flags:-C overflow-checks=off -//@ normalize-stderr-test: ".nll/" -> "/" +//@ normalize-stderr: ".nll/" -> "/" enum Nil {NilValue} struct Cons {head:isize, tail:T} diff --git a/tests/ui/regions/issue-102374.rs b/tests/ui/regions/issue-102374.rs index db2b38334b5d..d640c29b2f4c 100644 --- a/tests/ui/regions/issue-102374.rs +++ b/tests/ui/regions/issue-102374.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" use std::cell::Cell; #[rustfmt::skip] diff --git a/tests/ui/repr/repr-c-dead-variants.rs b/tests/ui/repr/repr-c-dead-variants.rs index cc080b2e59ad..3e8ae3d096d8 100644 --- a/tests/ui/repr/repr-c-dead-variants.rs +++ b/tests/ui/repr/repr-c-dead-variants.rs @@ -6,7 +6,7 @@ // See also: repr-c-int-dead-variants.rs -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" // This test depends on the value of the `c_enum_min_bits` target option. // As there's no way to actually check it from UI test, we only run this test on a subset of archs. diff --git a/tests/ui/repr/repr-c-int-dead-variants.rs b/tests/ui/repr/repr-c-int-dead-variants.rs index ed26174343a4..627569e080d4 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.rs +++ b/tests/ui/repr/repr-c-int-dead-variants.rs @@ -3,7 +3,7 @@ // See also: repr-c-dead-variants.rs -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" // A simple uninhabited type. enum Void {} diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.rs b/tests/ui/resolve/multiple_definitions_attribute_merging.rs index 7d649476ad2a..155abafdd9d9 100644 --- a/tests/ui/resolve/multiple_definitions_attribute_merging.rs +++ b/tests/ui/resolve/multiple_definitions_attribute_merging.rs @@ -4,9 +4,9 @@ //@known-bug: #120873 //@ failure-status: 101 -//@ normalize-stderr-test: "note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*\n" -> "" -//@ normalize-stderr-test: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr: "note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " //@ rustc-env:RUST_BACKTRACE=0 #[repr(packed)] diff --git a/tests/ui/resolve/proc_macro_generated_packed.rs b/tests/ui/resolve/proc_macro_generated_packed.rs index 8459fb79f1ed..0cba3c1616d7 100644 --- a/tests/ui/resolve/proc_macro_generated_packed.rs +++ b/tests/ui/resolve/proc_macro_generated_packed.rs @@ -4,9 +4,9 @@ //@proc-macro: proc_macro_generate_packed.rs //@known-bug: #120873 //@ failure-status: 101 -//@ normalize-stderr-test: "note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*\n" -> "" -//@ normalize-stderr-test: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr: "note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " //@ rustc-env:RUST_BACKTRACE=0 extern crate proc_macro_generate_packed; diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs index ea9d48e7859d..e69a45379352 100644 --- a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs +++ b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs @@ -2,12 +2,12 @@ //@ needs-dlltool //@ compile-flags: --crate-type lib --emit link -//@ normalize-stderr-test: "[^ ']*/dlltool.exe" -> "$$DLLTOOL" -//@ normalize-stderr-test: "[^ ]*/foo.dll_imports.def" -> "$$DEF_FILE" -//@ normalize-stderr-test: "[^ ]*/foo.dll_imports.lib" -> "$$LIB_FILE" -//@ normalize-stderr-test: "-m [^ ]*" -> "$$TARGET_MACHINE" -//@ normalize-stderr-test: "-f [^ ]*" -> "$$ASM_FLAGS" -//@ normalize-stderr-test: "--temp-prefix [^ ]*/foo.dll" -> "$$TEMP_PREFIX" +//@ normalize-stderr: "[^ ']*/dlltool.exe" -> "$$DLLTOOL" +//@ normalize-stderr: "[^ ]*/foo.dll_imports.def" -> "$$DEF_FILE" +//@ normalize-stderr: "[^ ]*/foo.dll_imports.lib" -> "$$LIB_FILE" +//@ normalize-stderr: "-m [^ ]*" -> "$$TARGET_MACHINE" +//@ normalize-stderr: "-f [^ ]*" -> "$$ASM_FLAGS" +//@ normalize-stderr: "--temp-prefix [^ ]*/foo.dll" -> "$$TEMP_PREFIX" #[link(name = "foo", kind = "raw-dylib")] extern "C" { // `@1` is an invalid name to export, as it usually indicates that something diff --git a/tests/ui/runtime/backtrace-debuginfo.rs b/tests/ui/runtime/backtrace-debuginfo.rs index 9c4b15e64f51..da747ded44ff 100644 --- a/tests/ui/runtime/backtrace-debuginfo.rs +++ b/tests/ui/runtime/backtrace-debuginfo.rs @@ -13,6 +13,10 @@ //@ ignore-sgx no processes //@ ignore-fuchsia Backtrace not symbolized, trace different line alignment +// FIXME(#117097): backtrace (possibly unwinding mechanism) seems to be different on at least +// `i686-mingw` (32-bit windows-gnu)? cc #128911. +//@ ignore-windows-gnu + use std::env; #[path = "backtrace-debuginfo-aux.rs"] mod aux; diff --git a/tests/ui/statics/mutable_memory_validation.rs b/tests/ui/statics/mutable_memory_validation.rs index 032b903f64e5..3bb572d38bc5 100644 --- a/tests/ui/statics/mutable_memory_validation.rs +++ b/tests/ui/statics/mutable_memory_validation.rs @@ -1,8 +1,8 @@ //issue: rust-lang/rust#122548 // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" use std::cell::UnsafeCell; diff --git a/tests/ui/structs/manual-default-impl-could-be-derived.rs b/tests/ui/structs/manual-default-impl-could-be-derived.rs new file mode 100644 index 000000000000..773b73899886 --- /dev/null +++ b/tests/ui/structs/manual-default-impl-could-be-derived.rs @@ -0,0 +1,194 @@ +// Warn when we encounter a manual `Default` impl that could be derived. +// Restricted only to types using `default_field_values`. +#![feature(default_field_values)] +#![allow(dead_code)] +#![deny(default_overrides_default_fields)] +struct S(i32); +fn s() -> S { S(1) } + +struct A { + x: S, + y: i32 = 1, +} + +impl Default for A { //~ ERROR default_overrides_default_fields + fn default() -> Self { + A { + y: 0, + x: s(), + } + } +} + +struct B { + x: S = S(3), + y: i32 = 1, +} + +impl Default for B { //~ ERROR default_overrides_default_fields + fn default() -> Self { + B { + x: s(), + y: 0, + } + } +} + +struct C { + x: S, + y: i32 = 1, + z: i32 = 1, +} + +impl Default for C { //~ ERROR default_overrides_default_fields + fn default() -> Self { + C { + x: s(), + y: 0, + .. + } + } +} + +struct D { + x: S, + y: i32 = 1, + z: i32 = 1, +} + +impl Default for D { //~ ERROR default_overrides_default_fields + fn default() -> Self { + D { + y: 0, + x: s(), + .. + } + } +} + +struct E { + x: S, + y: i32 = 1, + z: i32 = 1, +} + +impl Default for E { //~ ERROR default_overrides_default_fields + fn default() -> Self { + E { + y: 0, + z: 0, + x: s(), + } + } +} + +// Let's ensure that the span for `x` and the span for `y` don't overlap when suggesting their +// removal in favor of their default field values. +struct E2 { + x: S, + y: i32 = 1, + z: i32 = 1, +} + +impl Default for E2 { //~ ERROR default_overrides_default_fields + fn default() -> Self { + E2 { + x: s(), + y: i(), + z: 0, + } + } +} + +fn i() -> i32 { + 1 +} + +// Account for a `const fn` being the `Default::default()` of a field's type. +struct F { + x: G, + y: i32 = 1, +} + +impl Default for F { //~ ERROR default_overrides_default_fields + fn default() -> Self { + F { + x: g_const(), + y: 0, + } + } +} + +struct G; + +impl Default for G { // ok + fn default() -> Self { + g_const() + } +} + +const fn g_const() -> G { + G +} + +// Account for a `const fn` being used in `Default::default()`, even if the type doesn't use it as +// its own `Default`. We suggest setting the default field value in that case. +struct H { + x: I, + y: i32 = 1, +} + +impl Default for H { //~ ERROR default_overrides_default_fields + fn default() -> Self { + H { + x: i_const(), + y: 0, + } + } +} + +struct I; + +const fn i_const() -> I { + I +} + +// Account for a `const` and struct literal being the `Default::default()` of a field's type. +struct M { + x: N, + y: i32 = 1, + z: A, +} + +impl Default for M { // ok, `y` is not specified + fn default() -> Self { + M { + x: N_CONST, + z: A { + x: S(0), + y: 0, + }, + .. + } + } +} + +struct N; + +const N_CONST: N = N; + +struct O { + x: Option, + y: i32 = 1, +} + +impl Default for O { //~ ERROR default_overrides_default_fields + fn default() -> Self { + O { + x: None, + y: 1, + } + } +} + +fn main() {} diff --git a/tests/ui/structs/manual-default-impl-could-be-derived.stderr b/tests/ui/structs/manual-default-impl-could-be-derived.stderr new file mode 100644 index 000000000000..e8f607fac7ed --- /dev/null +++ b/tests/ui/structs/manual-default-impl-could-be-derived.stderr @@ -0,0 +1,144 @@ +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:14:1 + | +LL | / impl Default for A { +LL | | fn default() -> Self { +LL | | A { +LL | | y: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time +note: the lint level is defined here + --> $DIR/manual-default-impl-could-be-derived.rs:5:9 + | +LL | #![deny(default_overrides_default_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:28:1 + | +LL | / impl Default for B { +LL | | fn default() -> Self { +LL | | B { +LL | | x: s(), + | | --- this field has a default value +LL | | y: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: to avoid divergence in behavior between `Struct { .. }` and `::default()`, derive the `Default` + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:43:1 + | +LL | / impl Default for C { +LL | | fn default() -> Self { +LL | | C { +LL | | x: s(), +LL | | y: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:59:1 + | +LL | / impl Default for D { +LL | | fn default() -> Self { +LL | | D { +LL | | y: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:75:1 + | +LL | / impl Default for E { +LL | | fn default() -> Self { +LL | | E { +LL | | y: 0, + | | - this field has a default value +LL | | z: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:93:1 + | +LL | / impl Default for E2 { +LL | | fn default() -> Self { +LL | | E2 { +LL | | x: s(), +LL | | y: i(), + | | --- this field has a default value +LL | | z: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:113:1 + | +LL | / impl Default for F { +LL | | fn default() -> Self { +LL | | F { +LL | | x: g_const(), +LL | | y: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:141:1 + | +LL | / impl Default for H { +LL | | fn default() -> Self { +LL | | H { +LL | | x: i_const(), +LL | | y: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:185:1 + | +LL | / impl Default for O { +LL | | fn default() -> Self { +LL | | O { +LL | | x: None, +LL | | y: 1, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time + +error: aborting due to 9 previous errors + diff --git a/tests/ui/suggestions/fn-to-method.import_trait_associated_functions.stderr b/tests/ui/suggestions/fn-to-method.import_trait_associated_functions.stderr new file mode 100644 index 000000000000..593a90d728fa --- /dev/null +++ b/tests/ui/suggestions/fn-to-method.import_trait_associated_functions.stderr @@ -0,0 +1,39 @@ +error[E0425]: cannot find function `cmp` in this scope + --> $DIR/fn-to-method.rs:12:13 + | +LL | let x = cmp(&1, &2); + | ^^^ not found in this scope + | +help: consider importing one of these associated functions + | +LL + use std::cmp::Ord::cmp; + | +LL + use std::iter::Iterator::cmp; + | + +error[E0425]: cannot find function `len` in this scope + --> $DIR/fn-to-method.rs:16:13 + | +LL | let y = len([1, 2, 3]); + | ^^^ not found in this scope + | +help: consider importing this associated function + | +LL + use std::iter::ExactSizeIterator::len; + | + +error[E0425]: cannot find function `bar` in this scope + --> $DIR/fn-to-method.rs:20:13 + | +LL | let z = bar(Foo); + | ^^^ not found in this scope + | +help: use the `.` operator to call the method `bar` on `Foo` + | +LL - let z = bar(Foo); +LL + let z = Foo.bar(); + | + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/suggestions/fn-to-method.stderr b/tests/ui/suggestions/fn-to-method.normal.stderr similarity index 96% rename from tests/ui/suggestions/fn-to-method.stderr rename to tests/ui/suggestions/fn-to-method.normal.stderr index 36c17e60d357..502be79481ac 100644 --- a/tests/ui/suggestions/fn-to-method.stderr +++ b/tests/ui/suggestions/fn-to-method.normal.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find function `cmp` in this scope - --> $DIR/fn-to-method.rs:8:13 + --> $DIR/fn-to-method.rs:12:13 | LL | let x = cmp(&1, &2); | ^^^ not found in this scope @@ -10,7 +10,7 @@ LL | let x = (&1).cmp(&2); | ~ ~~~~~~~~~ error[E0425]: cannot find function `len` in this scope - --> $DIR/fn-to-method.rs:12:13 + --> $DIR/fn-to-method.rs:16:13 | LL | let y = len([1, 2, 3]); | ^^^ not found in this scope @@ -22,7 +22,7 @@ LL + let y = [1, 2, 3].len(); | error[E0425]: cannot find function `bar` in this scope - --> $DIR/fn-to-method.rs:16:13 + --> $DIR/fn-to-method.rs:20:13 | LL | let z = bar(Foo); | ^^^ not found in this scope diff --git a/tests/ui/suggestions/fn-to-method.rs b/tests/ui/suggestions/fn-to-method.rs index 9a35c3efc41b..619ac4446494 100644 --- a/tests/ui/suggestions/fn-to-method.rs +++ b/tests/ui/suggestions/fn-to-method.rs @@ -1,4 +1,8 @@ +//@ revisions: normal import_trait_associated_functions +#![cfg_attr(import_trait_associated_functions, feature(import_trait_associated_functions))] struct Foo; +//[import_trait_associated_functions]~^ HELP consider importing one of these associated functions +//[import_trait_associated_functions]~| HELP consider importing this associated function impl Foo { fn bar(self) {} @@ -7,11 +11,11 @@ impl Foo { fn main() { let x = cmp(&1, &2); //~^ ERROR cannot find function `cmp` in this scope - //~| HELP use the `.` operator to call the method `Ord::cmp` on `&{integer}` + //[normal]~| HELP use the `.` operator to call the method `Ord::cmp` on `&{integer}` let y = len([1, 2, 3]); //~^ ERROR cannot find function `len` in this scope - //~| HELP use the `.` operator to call the method `len` on `&[{integer}]` + //[normal]~| HELP use the `.` operator to call the method `len` on `&[{integer}]` let z = bar(Foo); //~^ ERROR cannot find function `bar` in this scope diff --git a/tests/ui/svh/changing-crates.rs b/tests/ui/svh/changing-crates.rs index 78075a5c75fa..39a6473c8d91 100644 --- a/tests/ui/svh/changing-crates.rs +++ b/tests/ui/svh/changing-crates.rs @@ -2,7 +2,7 @@ //@ aux-build:changing-crates-a1.rs //@ aux-build:changing-crates-b.rs //@ aux-build:changing-crates-a2.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on diff --git a/tests/ui/svh/svh-change-lit.rs b/tests/ui/svh/svh-change-lit.rs index 6ecdd9f2c084..66f739e144ef 100644 --- a/tests/ui/svh/svh-change-lit.rs +++ b/tests/ui/svh/svh-change-lit.rs @@ -2,7 +2,7 @@ //@ aux-build:svh-a-base.rs //@ aux-build:svh-b.rs //@ aux-build:svh-a-change-lit.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on diff --git a/tests/ui/svh/svh-change-significant-cfg.rs b/tests/ui/svh/svh-change-significant-cfg.rs index c03560ee5112..9e736788d138 100644 --- a/tests/ui/svh/svh-change-significant-cfg.rs +++ b/tests/ui/svh/svh-change-significant-cfg.rs @@ -2,7 +2,7 @@ //@ aux-build:svh-a-base.rs //@ aux-build:svh-b.rs //@ aux-build:svh-a-change-significant-cfg.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on diff --git a/tests/ui/svh/svh-change-trait-bound.rs b/tests/ui/svh/svh-change-trait-bound.rs index 4bbbf45a8866..1e0fa15b94a0 100644 --- a/tests/ui/svh/svh-change-trait-bound.rs +++ b/tests/ui/svh/svh-change-trait-bound.rs @@ -2,7 +2,7 @@ //@ aux-build:svh-a-base.rs //@ aux-build:svh-b.rs //@ aux-build:svh-a-change-trait-bound.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on diff --git a/tests/ui/svh/svh-change-type-arg.rs b/tests/ui/svh/svh-change-type-arg.rs index cdc5cf24272f..f275a38acc48 100644 --- a/tests/ui/svh/svh-change-type-arg.rs +++ b/tests/ui/svh/svh-change-type-arg.rs @@ -2,7 +2,7 @@ //@ aux-build:svh-a-base.rs //@ aux-build:svh-b.rs //@ aux-build:svh-a-change-type-arg.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on diff --git a/tests/ui/svh/svh-change-type-ret.rs b/tests/ui/svh/svh-change-type-ret.rs index f2a579fab630..76118dc9f696 100644 --- a/tests/ui/svh/svh-change-type-ret.rs +++ b/tests/ui/svh/svh-change-type-ret.rs @@ -2,7 +2,7 @@ //@ aux-build:svh-a-base.rs //@ aux-build:svh-b.rs //@ aux-build:svh-a-change-type-ret.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on diff --git a/tests/ui/svh/svh-change-type-static.rs b/tests/ui/svh/svh-change-type-static.rs index 489923ddecf5..6a658ca36dc9 100644 --- a/tests/ui/svh/svh-change-type-static.rs +++ b/tests/ui/svh/svh-change-type-static.rs @@ -2,7 +2,7 @@ //@ aux-build:svh-a-base.rs //@ aux-build:svh-b.rs //@ aux-build:svh-a-change-type-static.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on diff --git a/tests/ui/svh/svh-use-trait.rs b/tests/ui/svh/svh-use-trait.rs index 8ac4cc426054..4791bfb50066 100644 --- a/tests/ui/svh/svh-use-trait.rs +++ b/tests/ui/svh/svh-use-trait.rs @@ -2,7 +2,7 @@ //@ aux-build:svh-uta-base.rs //@ aux-build:svh-utb.rs //@ aux-build:svh-uta-change-use-trait.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" //! "svh-uta-trait.rs" is checking that we detect a //! change from `use foo::TraitB` to use `foo::TraitB` in the hash diff --git a/tests/ui/symbol-names/const-generics-demangling.rs b/tests/ui/symbol-names/const-generics-demangling.rs index 86f24f6af6ad..9c078d4192a9 100644 --- a/tests/ui/symbol-names/const-generics-demangling.rs +++ b/tests/ui/symbol-names/const-generics-demangling.rs @@ -3,8 +3,8 @@ //@ compile-flags: --crate-name=c //@[legacy]compile-flags: -C symbol-mangling-version=legacy -Z unstable-options //@ [v0]compile-flags: -C symbol-mangling-version=v0 -//@[legacy]normalize-stderr-test: "h[[:xdigit:]]{16}" -> "h[HASH]" -//@ [v0]normalize-stderr-test: "c\[.*?\]" -> "c[HASH]" +//@[legacy]normalize-stderr: "h[[:xdigit:]]{16}" -> "h[HASH]" +//@ [v0]normalize-stderr: "c\[.*?\]" -> "c[HASH]" #![feature(rustc_attrs)] pub struct Unsigned; diff --git a/tests/ui/symbol-names/const-generics-str-demangling.rs b/tests/ui/symbol-names/const-generics-str-demangling.rs index 87b1fdf8a479..94c3b4c44488 100644 --- a/tests/ui/symbol-names/const-generics-str-demangling.rs +++ b/tests/ui/symbol-names/const-generics-str-demangling.rs @@ -1,6 +1,6 @@ //@ build-fail //@ compile-flags: -C symbol-mangling-version=v0 --crate-name=c -//@ normalize-stderr-test: "c\[.*?\]" -> "c[HASH]" +//@ normalize-stderr: "c\[.*?\]" -> "c[HASH]" #![feature(adt_const_params, unsized_const_params, rustc_attrs)] #![allow(incomplete_features)] diff --git a/tests/ui/symbol-names/const-generics-structural-demangling.rs b/tests/ui/symbol-names/const-generics-structural-demangling.rs index 9f5f31177b38..06e3ce51fa6a 100644 --- a/tests/ui/symbol-names/const-generics-structural-demangling.rs +++ b/tests/ui/symbol-names/const-generics-structural-demangling.rs @@ -1,7 +1,7 @@ //@ build-fail //@ compile-flags: -C symbol-mangling-version=v0 --crate-name=c -//@ normalize-stderr-test: "c\[[0-9a-f]+\]" -> "c[HASH]" +//@ normalize-stderr: "c\[[0-9a-f]+\]" -> "c[HASH]" #![feature(adt_const_params, unsized_const_params, decl_macro, rustc_attrs)] #![allow(incomplete_features)] diff --git a/tests/ui/symbol-names/impl1.rs b/tests/ui/symbol-names/impl1.rs index 9aefca47447f..694cd89bd80f 100644 --- a/tests/ui/symbol-names/impl1.rs +++ b/tests/ui/symbol-names/impl1.rs @@ -2,7 +2,7 @@ //@ revisions: legacy v0 //@[legacy]compile-flags: -Z unstable-options -C symbol-mangling-version=legacy //@[v0]compile-flags: -C symbol-mangling-version=v0 -//@[legacy]normalize-stderr-test: "h[\w]{16}E?\)" -> ")" +//@[legacy]normalize-stderr: "h[\w]{16}E?\)" -> ")" #![feature(auto_traits, rustc_attrs)] #![allow(dead_code)] diff --git a/tests/ui/symbol-names/issue-75326.rs b/tests/ui/symbol-names/issue-75326.rs index a6aef3ddd7df..c60b872b0a23 100644 --- a/tests/ui/symbol-names/issue-75326.rs +++ b/tests/ui/symbol-names/issue-75326.rs @@ -2,7 +2,7 @@ //@ revisions: legacy v0 //@[legacy]compile-flags: -Z unstable-options -C symbol-mangling-version=legacy //@[v0]compile-flags: -C symbol-mangling-version=v0 -//@[legacy]normalize-stderr-test: "h[\w{16}]+" -> "SYMBOL_HASH" +//@[legacy]normalize-stderr: "h[\w{16}]+" -> "SYMBOL_HASH" #![feature(rustc_attrs)] diff --git a/tests/ui/symbol-names/trait-objects.rs b/tests/ui/symbol-names/trait-objects.rs index d3fa40d1f391..da48190285da 100644 --- a/tests/ui/symbol-names/trait-objects.rs +++ b/tests/ui/symbol-names/trait-objects.rs @@ -3,7 +3,7 @@ //@ build-fail //@ revisions: v0 //@[v0]compile-flags: -C symbol-mangling-version=v0 -//@[v0]normalize-stderr-test: "core\[.*?\]" -> "core[HASH]" +//@[v0]normalize-stderr: "core\[.*?\]" -> "core[HASH]" #![feature(rustc_attrs)] diff --git a/tests/ui/symbol-names/types.rs b/tests/ui/symbol-names/types.rs index 38735e1aa509..a4bbbaa02f27 100644 --- a/tests/ui/symbol-names/types.rs +++ b/tests/ui/symbol-names/types.rs @@ -4,8 +4,8 @@ //@ [legacy] compile-flags: -Csymbol-mangling-version=legacy //@ [verbose-legacy] compile-flags: -Csymbol-mangling-version=legacy -Zverbose-internals //@ [v0] compile-flags: -Csymbol-mangling-version=v0 -//@ normalize-stderr-test: "h[[:xdigit:]]{16}" -> "h[HASH]" -//@ [v0] normalize-stderr-test: "\[[[:xdigit:]]{16}\]" -> "[HASH]" +//@ normalize-stderr: "h[[:xdigit:]]{16}" -> "h[HASH]" +//@ [v0] normalize-stderr: "\[[[:xdigit:]]{16}\]" -> "[HASH]" #![feature(never_type)] #![feature(rustc_attrs)] diff --git a/tests/ui/test-attrs/terse.rs b/tests/ui/test-attrs/terse.rs index 74e189158570..6c3f29ed10f9 100644 --- a/tests/ui/test-attrs/terse.rs +++ b/tests/ui/test-attrs/terse.rs @@ -3,7 +3,7 @@ //@ run-flags: --test-threads=1 --quiet //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ ignore-emscripten no threads support //@ needs-unwind diff --git a/tests/ui/test-attrs/test-filter-multiple.rs b/tests/ui/test-attrs/test-filter-multiple.rs index c875929e6724..49211c61e18a 100644 --- a/tests/ui/test-attrs/test-filter-multiple.rs +++ b/tests/ui/test-attrs/test-filter-multiple.rs @@ -2,7 +2,7 @@ //@ compile-flags: --test //@ run-flags: --test-threads=1 test1 test2 //@ check-run-results -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ needs-threads #[test] diff --git a/tests/ui/test-attrs/test-panic-abort-nocapture.rs b/tests/ui/test-attrs/test-panic-abort-nocapture.rs index f3485d9c1fa9..4377ae1ac3bd 100644 --- a/tests/ui/test-attrs/test-panic-abort-nocapture.rs +++ b/tests/ui/test-attrs/test-panic-abort-nocapture.rs @@ -4,7 +4,7 @@ //@ run-fail //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ ignore-android #120567 //@ ignore-wasm no panic or subprocess support diff --git a/tests/ui/test-attrs/test-panic-abort.rs b/tests/ui/test-attrs/test-panic-abort.rs index 84740161a708..3d203e059a46 100644 --- a/tests/ui/test-attrs/test-panic-abort.rs +++ b/tests/ui/test-attrs/test-panic-abort.rs @@ -4,7 +4,7 @@ //@ run-fail //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ ignore-android #120567 //@ ignore-wasm no panic or subprocess support diff --git a/tests/ui/test-attrs/test-passed.rs b/tests/ui/test-attrs/test-passed.rs index 2a3fca7f002e..959470adcc42 100644 --- a/tests/ui/test-attrs/test-passed.rs +++ b/tests/ui/test-attrs/test-passed.rs @@ -3,7 +3,7 @@ //@ run-flags: --test-threads=1 //@ run-pass //@ check-run-results -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // Tests the output of the test harness with only passed tests. diff --git a/tests/ui/test-attrs/test-thread-capture.rs b/tests/ui/test-attrs/test-thread-capture.rs index 75ff4e0ece64..c56f87f2ddac 100644 --- a/tests/ui/test-attrs/test-thread-capture.rs +++ b/tests/ui/test-attrs/test-thread-capture.rs @@ -3,7 +3,7 @@ //@ run-flags: --test-threads=1 //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ ignore-emscripten no threads support //@ needs-unwind diff --git a/tests/ui/test-attrs/test-thread-nocapture.rs b/tests/ui/test-attrs/test-thread-nocapture.rs index 6a36ea8d7d19..5b82e9b27207 100644 --- a/tests/ui/test-attrs/test-thread-nocapture.rs +++ b/tests/ui/test-attrs/test-thread-nocapture.rs @@ -3,7 +3,7 @@ //@ run-flags: --test-threads=1 --nocapture //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ ignore-emscripten no threads support //@ needs-unwind diff --git a/tests/ui/test-attrs/test-type.rs b/tests/ui/test-attrs/test-type.rs index 1b71ead55b07..51a6b9245cc7 100644 --- a/tests/ui/test-attrs/test-type.rs +++ b/tests/ui/test-attrs/test-type.rs @@ -1,7 +1,7 @@ //@ compile-flags: --test -Zpanic-abort-tests //@ run-flags: --test-threads=1 //@ check-run-results -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ needs-threads //@ run-pass diff --git a/tests/ui/test-attrs/tests-listing-format-json.rs b/tests/ui/test-attrs/tests-listing-format-json.rs index b735a82c1662..9d57a6bc3834 100644 --- a/tests/ui/test-attrs/tests-listing-format-json.rs +++ b/tests/ui/test-attrs/tests-listing-format-json.rs @@ -4,8 +4,8 @@ //@ run-pass //@ check-run-results //@ only-nightly -//@ normalize-stdout-test: "fake-test-src-base/test-attrs/" -> "$$DIR/" -//@ normalize-stdout-test: "fake-test-src-base\\test-attrs\\" -> "$$DIR/" +//@ normalize-stdout: "fake-test-src-base/test-attrs/" -> "$$DIR/" +//@ normalize-stdout: "fake-test-src-base\\test-attrs\\" -> "$$DIR/" // Checks the listing of tests with --format json. diff --git a/tests/ui/thread-local/thread-local-static.rs b/tests/ui/thread-local/thread-local-static.rs index af30f5383661..422dac410023 100644 --- a/tests/ui/thread-local/thread-local-static.rs +++ b/tests/ui/thread-local/thread-local-static.rs @@ -1,7 +1,6 @@ //@ edition:2018 #![feature(thread_local)] -#![feature(const_swap)] #![allow(static_mut_refs)] #[thread_local] diff --git a/tests/ui/thread-local/thread-local-static.stderr b/tests/ui/thread-local/thread-local-static.stderr index 3bc1aec00c11..bb078b797487 100644 --- a/tests/ui/thread-local/thread-local-static.stderr +++ b/tests/ui/thread-local/thread-local-static.stderr @@ -1,5 +1,5 @@ error[E0133]: use of mutable static is unsafe and requires unsafe function or block - --> $DIR/thread-local-static.rs:10:28 + --> $DIR/thread-local-static.rs:9:28 | LL | std::mem::swap(x, &mut STATIC_VAR_2) | ^^^^^^^^^^^^ use of mutable static @@ -7,7 +7,7 @@ LL | std::mem::swap(x, &mut STATIC_VAR_2) = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error[E0625]: thread-local statics cannot be accessed at compile-time - --> $DIR/thread-local-static.rs:10:28 + --> $DIR/thread-local-static.rs:9:28 | LL | std::mem::swap(x, &mut STATIC_VAR_2) | ^^^^^^^^^^^^ diff --git a/tests/ui/track-diagnostics/track.rs b/tests/ui/track-diagnostics/track.rs index 5023f34e4c1b..9e81cb53fc11 100644 --- a/tests/ui/track-diagnostics/track.rs +++ b/tests/ui/track-diagnostics/track.rs @@ -5,13 +5,13 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" -//@ normalize-stderr-test: "note: rustc .+ running on .+" -> "note: rustc $$VERSION running on $$TARGET" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: "note: rustc .+ running on .+" -> "note: rustc $$VERSION running on $$TARGET" // The test becomes too flaky if we care about exact args. If `-Z ui-testing` // from compiletest and `-Z track-diagnostics` from `// compile-flags` at the // top of this file are present, then assume all args are present. -//@ normalize-stderr-test: "note: compiler flags: .*-Z ui-testing.*-Z track-diagnostics" -> "note: compiler flags: ... -Z ui-testing ... -Z track-diagnostics" +//@ normalize-stderr: "note: compiler flags: .*-Z ui-testing.*-Z track-diagnostics" -> "note: compiler flags: ... -Z ui-testing ... -Z track-diagnostics" fn main() { break rust diff --git a/tests/ui/track-diagnostics/track2.rs b/tests/ui/track-diagnostics/track2.rs index 7466e9246ce6..5805fd21220d 100644 --- a/tests/ui/track-diagnostics/track2.rs +++ b/tests/ui/track-diagnostics/track2.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" fn main() { let _moved @ _from = String::from("foo"); diff --git a/tests/ui/track-diagnostics/track3.rs b/tests/ui/track-diagnostics/track3.rs index 43ad1dff8b83..bac1fc7e184b 100644 --- a/tests/ui/track-diagnostics/track3.rs +++ b/tests/ui/track-diagnostics/track3.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" fn main() { let _unimported = Blah { field: u8 }; diff --git a/tests/ui/track-diagnostics/track4.rs b/tests/ui/track-diagnostics/track4.rs index bc76f6f14517..ec9e3efa481c 100644 --- a/tests/ui/track-diagnostics/track4.rs +++ b/tests/ui/track-diagnostics/track4.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" pub onion { Owo(u8), diff --git a/tests/ui/track-diagnostics/track5.rs b/tests/ui/track-diagnostics/track5.rs index bb82e9a62c8b..e72e3482ad38 100644 --- a/tests/ui/track-diagnostics/track5.rs +++ b/tests/ui/track-diagnostics/track5.rs @@ -3,6 +3,6 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" } diff --git a/tests/ui/track-diagnostics/track6.rs b/tests/ui/track-diagnostics/track6.rs index fc8df68e6d92..e4d124a22e49 100644 --- a/tests/ui/track-diagnostics/track6.rs +++ b/tests/ui/track-diagnostics/track6.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" pub trait Foo { diff --git a/tests/ui/traits/on_unimplemented_long_types.rs b/tests/ui/traits/on_unimplemented_long_types.rs index 60c3327902e1..98749b8db7ae 100644 --- a/tests/ui/traits/on_unimplemented_long_types.rs +++ b/tests/ui/traits/on_unimplemented_long_types.rs @@ -1,5 +1,5 @@ //@ compile-flags: --diagnostic-width=60 -Z write-long-types-to-disk=yes -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" pub fn foo() -> impl std::fmt::Display { //~^ ERROR doesn't implement `std::fmt::Display` diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs index ef0a5a7adcaf..d0418e75fab2 100644 --- a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs +++ b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs @@ -2,10 +2,10 @@ //@[next] compile-flags: -Znext-solver //@[next] failure-status: 101 //@[next] known-bug: unknown -//@[next] normalize-stderr-test: "note: .*\n\n" -> "" -//@[next] normalize-stderr-test: "thread 'rustc' panicked.*\n.*\n" -> "" -//@[next] normalize-stderr-test: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " -//@[next] normalize-stderr-test: "delayed at .*" -> "" +//@[next] normalize-stderr: "note: .*\n\n" -> "" +//@[next] normalize-stderr: "thread 'rustc' panicked.*\n.*\n" -> "" +//@[next] normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@[next] normalize-stderr: "delayed at .*" -> "" //@[next] rustc-env:RUST_BACKTRACE=0 //@ check-pass diff --git a/tests/ui/transmute/transmute-different-sizes.rs b/tests/ui/transmute/transmute-different-sizes.rs index b7fca2b32783..40197a6c53f0 100644 --- a/tests/ui/transmute/transmute-different-sizes.rs +++ b/tests/ui/transmute/transmute-different-sizes.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "\d+ bits" -> "N bits" +//@ normalize-stderr: "\d+ bits" -> "N bits" // Tests that `transmute` cannot be called on types of different size. diff --git a/tests/ui/transmute/transmute-fat-pointers.rs b/tests/ui/transmute/transmute-fat-pointers.rs index d1340c5e8604..f095b80dc2da 100644 --- a/tests/ui/transmute/transmute-fat-pointers.rs +++ b/tests/ui/transmute/transmute-fat-pointers.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "\d+ bits" -> "N bits" +//@ normalize-stderr: "\d+ bits" -> "N bits" // Tests that are conservative around thin/fat pointer mismatches. diff --git a/tests/ui/transmute/transmute-impl.rs b/tests/ui/transmute/transmute-impl.rs index 15d67483cc8d..84951a0ee603 100644 --- a/tests/ui/transmute/transmute-impl.rs +++ b/tests/ui/transmute/transmute-impl.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "\d+ bits" -> "N bits" +//@ normalize-stderr: "\d+ bits" -> "N bits" // Tests that are conservative around thin/fat pointer mismatches. diff --git a/tests/ui/treat-err-as-bug/err.rs b/tests/ui/treat-err-as-bug/err.rs index 82683cdffef6..9f0e293b4cb1 100644 --- a/tests/ui/treat-err-as-bug/err.rs +++ b/tests/ui/treat-err-as-bug/err.rs @@ -2,8 +2,8 @@ //@ failure-status: 101 //@ error-pattern: aborting due to `-Z treat-err-as-bug=1` //@ error-pattern: [eval_static_initializer] evaluating initializer of static `C` -//@ normalize-stderr-test: "note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*:\n.*\n" -> "" +//@ normalize-stderr: "note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*:\n.*\n" -> "" //@ rustc-env:RUST_BACKTRACE=0 #![crate_type = "rlib"] diff --git a/tests/ui/treat-err-as-bug/span_delayed_bug.rs b/tests/ui/treat-err-as-bug/span_delayed_bug.rs index 97b8e4a3ddac..296bdd7a12d9 100644 --- a/tests/ui/treat-err-as-bug/span_delayed_bug.rs +++ b/tests/ui/treat-err-as-bug/span_delayed_bug.rs @@ -2,8 +2,8 @@ //@ failure-status: 101 //@ error-pattern: aborting due to `-Z treat-err-as-bug=1` //@ error-pattern: [trigger_delayed_bug] triggering a delayed bug for testing incremental -//@ normalize-stderr-test: "note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*:\n.*\n" -> "" +//@ normalize-stderr: "note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*:\n.*\n" -> "" //@ rustc-env:RUST_BACKTRACE=0 #![feature(rustc_attrs)] diff --git a/tests/ui/type/pattern_types/range_patterns.rs b/tests/ui/type/pattern_types/range_patterns.rs index 7c25edb1c3fd..ff87444b49e3 100644 --- a/tests/ui/type/pattern_types/range_patterns.rs +++ b/tests/ui/type/pattern_types/range_patterns.rs @@ -2,7 +2,7 @@ #![feature(pattern_type_macro)] #![allow(incomplete_features)] -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" use std::pat::pattern_type; diff --git a/tests/ui/unknown-llvm-arg.rs b/tests/ui/unknown-llvm-arg.rs index 17908d36417c..a8fa55a220a5 100644 --- a/tests/ui/unknown-llvm-arg.rs +++ b/tests/ui/unknown-llvm-arg.rs @@ -1,6 +1,6 @@ //@ compile-flags: -Cllvm-args=-not-a-real-llvm-arg -//@ normalize-stderr-test: "--help" -> "-help" -//@ normalize-stderr-test: "\n(\n|.)*" -> "" +//@ normalize-stderr: "--help" -> "-help" +//@ normalize-stderr: "\n(\n|.)*" -> "" // I'm seeing "--help" locally, but "-help" in CI, so I'm normalizing it to just "-help". diff --git a/tests/ui/unpretty/avoid-crash.rs b/tests/ui/unpretty/avoid-crash.rs index e2bde8236220..7fcabfe6a8d4 100644 --- a/tests/ui/unpretty/avoid-crash.rs +++ b/tests/ui/unpretty/avoid-crash.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "error `.*`" -> "$$ERROR_MESSAGE" +//@ normalize-stderr: "error `.*`" -> "$$ERROR_MESSAGE" //@ compile-flags: -o. -Zunpretty=ast-tree fn main() {} diff --git a/tests/ui/unpretty/staged-api-invalid-path-108697.rs b/tests/ui/unpretty/staged-api-invalid-path-108697.rs index 1b6ef2491914..71bad213576c 100644 --- a/tests/ui/unpretty/staged-api-invalid-path-108697.rs +++ b/tests/ui/unpretty/staged-api-invalid-path-108697.rs @@ -2,7 +2,7 @@ // ICE: tcx.resolutions(()) is not supported for local crate -Zunpretty=mir // on invalid module path with staged_api //@ compile-flags: -Zunpretty=mir -//@ normalize-stderr-test: "The system cannot find the file specified." -> "No such file or directory" +//@ normalize-stderr: "The system cannot find the file specified." -> "No such file or directory" #![feature(staged_api)] #[path = "lol"] mod foo; diff --git a/tests/ui/use/import_trait_associated_functions-2015.rs b/tests/ui/use/import_trait_associated_functions-2015.rs new file mode 100644 index 000000000000..3177aeefb097 --- /dev/null +++ b/tests/ui/use/import_trait_associated_functions-2015.rs @@ -0,0 +1,61 @@ +//@ edition:2015 +//@ check-pass +#![feature(import_trait_associated_functions)] + +use std::collections::HashMap; + +use A::{DEFAULT, new}; +use std::default::Default::default; + +struct S { + a: HashMap, +} + +impl S { + fn new() -> S { + S { a: default() } + } +} + +trait A: Sized { + const DEFAULT: Option = None; + fn new() -> Self; + fn do_something(&self); +} + +mod b { + use super::A::{self, DEFAULT, new}; + + struct B(); + + impl A for B { + const DEFAULT: Option = Some(B()); + fn new() -> Self { + B() + } + + fn do_something(&self) {} + } + + fn f() { + let b: B = new(); + b.do_something(); + let c: B = DEFAULT.unwrap(); + } +} + +impl A for S { + fn new() -> Self { + S::new() + } + + fn do_something(&self) {} +} + +fn f() { + let s: S = new(); + s.do_something(); + let t: Option = DEFAULT; +} + +fn main() {} diff --git a/tests/ui/use/import_trait_associated_functions.rs b/tests/ui/use/import_trait_associated_functions.rs new file mode 100644 index 000000000000..4dc473404dbd --- /dev/null +++ b/tests/ui/use/import_trait_associated_functions.rs @@ -0,0 +1,61 @@ +//@ edition:2018 +//@ check-pass +#![feature(import_trait_associated_functions)] + +use std::collections::HashMap; + +use A::{DEFAULT, new}; +use Default::default; + +struct S { + a: HashMap, +} + +impl S { + fn new() -> S { + S { a: default() } + } +} + +trait A: Sized { + const DEFAULT: Option = None; + fn new() -> Self; + fn do_something(&self); +} + +mod b { + use super::A::{self, DEFAULT, new}; + + struct B(); + + impl A for B { + const DEFAULT: Option = Some(B()); + fn new() -> Self { + B() + } + + fn do_something(&self) {} + } + + fn f() { + let b: B = new(); + b.do_something(); + let c: B = DEFAULT.unwrap(); + } +} + +impl A for S { + fn new() -> Self { + S::new() + } + + fn do_something(&self) {} +} + +fn f() { + let s: S = new(); + s.do_something(); + let t: Option = DEFAULT; +} + +fn main() {} diff --git a/tests/ui/use/use-from-trait-xc.rs b/tests/ui/use/use-from-trait-xc.rs index b7b9c834b327..b030892aa269 100644 --- a/tests/ui/use/use-from-trait-xc.rs +++ b/tests/ui/use/use-from-trait-xc.rs @@ -3,13 +3,13 @@ extern crate use_from_trait_xc; use use_from_trait_xc::Trait::foo; -//~^ ERROR `foo` is not directly importable +//~^ ERROR `use` associated items of traits is unstable [E0658] use use_from_trait_xc::Trait::Assoc; //~^ ERROR `Assoc` is not directly importable use use_from_trait_xc::Trait::CONST; -//~^ ERROR `CONST` is not directly importable +//~^ ERROR `use` associated items of traits is unstable [E0658] use use_from_trait_xc::Foo::new; //~ ERROR struct `Foo` is private //~^ ERROR unresolved import `use_from_trait_xc::Foo` diff --git a/tests/ui/use/use-from-trait-xc.stderr b/tests/ui/use/use-from-trait-xc.stderr index 4c4c2f6225f1..0f8440aa5307 100644 --- a/tests/ui/use/use-from-trait-xc.stderr +++ b/tests/ui/use/use-from-trait-xc.stderr @@ -1,8 +1,12 @@ -error[E0253]: `foo` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait-xc.rs:5:5 | LL | use use_from_trait_xc::Trait::foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0253]: `Assoc` is not directly importable --> $DIR/use-from-trait-xc.rs:8:5 @@ -10,11 +14,15 @@ error[E0253]: `Assoc` is not directly importable LL | use use_from_trait_xc::Trait::Assoc; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly -error[E0253]: `CONST` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait-xc.rs:11:5 | LL | use use_from_trait_xc::Trait::CONST; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0432]: unresolved import `use_from_trait_xc::Foo` --> $DIR/use-from-trait-xc.rs:14:24 @@ -66,5 +74,5 @@ LL | struct Foo; error: aborting due to 9 previous errors -Some errors have detailed explanations: E0253, E0432, E0603. +Some errors have detailed explanations: E0253, E0432, E0603, E0658. For more information about an error, try `rustc --explain E0253`. diff --git a/tests/ui/use/use-from-trait.rs b/tests/ui/use/use-from-trait.rs index eab4bb6e3b5b..89b7aaa4ba38 100644 --- a/tests/ui/use/use-from-trait.rs +++ b/tests/ui/use/use-from-trait.rs @@ -1,6 +1,6 @@ -use Trait::foo; //~ ERROR `foo` is not directly importable +use Trait::foo; //~ ERROR `use` associated items of traits is unstable [E0658] use Trait::Assoc; //~ ERROR `Assoc` is not directly importable -use Trait::C; //~ ERROR `C` is not directly importable +use Trait::C; //~ ERROR `use` associated items of traits is unstable [E0658] use Foo::new; //~ ERROR unresolved import `Foo` [E0432] diff --git a/tests/ui/use/use-from-trait.stderr b/tests/ui/use/use-from-trait.stderr index a5b0e356b34c..2dd78a354529 100644 --- a/tests/ui/use/use-from-trait.stderr +++ b/tests/ui/use/use-from-trait.stderr @@ -1,8 +1,12 @@ -error[E0253]: `foo` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait.rs:1:5 | LL | use Trait::foo; - | ^^^^^^^^^^ cannot be imported directly + | ^^^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0253]: `Assoc` is not directly importable --> $DIR/use-from-trait.rs:2:5 @@ -10,11 +14,15 @@ error[E0253]: `Assoc` is not directly importable LL | use Trait::Assoc; | ^^^^^^^^^^^^ cannot be imported directly -error[E0253]: `C` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait.rs:3:5 | LL | use Trait::C; - | ^^^^^^^^ cannot be imported directly + | ^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0432]: unresolved import `Foo` --> $DIR/use-from-trait.rs:5:5 @@ -30,5 +38,5 @@ LL | use Foo::C2; error: aborting due to 5 previous errors -Some errors have detailed explanations: E0253, E0432. +Some errors have detailed explanations: E0253, E0432, E0658. For more information about an error, try `rustc --explain E0253`. diff --git a/triagebot.toml b/triagebot.toml index da652ef70420..730ae265ae7a 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -997,6 +997,7 @@ users_on_vacation = [ "jyn514", "celinval", "nnethercote", + "spastorino", "workingjubilee", ] @@ -1046,6 +1047,7 @@ bootstrap = [ "@onur-ozkan", "@kobzol", "@jieyouxu", + "@clubby789", ] infra-ci = [ "@Mark-Simulacrum",