From 1cac5fa5f9f371db4789ea928e1d2769d4cd921b Mon Sep 17 00:00:00 2001 From: jyn Date: Thu, 13 Feb 2025 10:14:06 -0500 Subject: [PATCH 01/35] Look for `python3` first on MacOS, not `py` `py` is not installed by default *and* trying to run it results in a popup asking if you want to install it. `python3` is installed by default. This hopefully should not be too disruptive to people on Windows, since they should be going through `x.ps1` instead anyway. Just in case, I've added a check for Cygwin and Msys (i'm not sure how else you'd get a bash shell on windows). --- x | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/x b/x index e656d37c1e455..551cfe6efbf33 100755 --- a/x +++ b/x @@ -25,7 +25,13 @@ xpy=$(dirname "$(realpath "$0")")/x.py # On Windows, `py -3` sometimes works. We need to try it first because `python3` # sometimes tries to launch the app store on Windows. -for SEARCH_PYTHON in py python3 python python2; do +# On MacOS, `py` tries to install "Developer command line tools". Try `python3` first. +# NOTE: running `bash -c ./x` from Windows doesn't set OSTYPE. +case ${OSTYPE:-} in + cygwin*|msys*) SEARCH="py python3 python python2";; + *) SEARCH="python3 python py python2";; +esac +for SEARCH_PYTHON in $SEARCH; do if python=$(command -v $SEARCH_PYTHON) && [ -x "$python" ]; then if [ $SEARCH_PYTHON = py ]; then extra_arg="-3" From 477a2eeb3dd5a430bb3845c8f8041ff369232967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 19 Feb 2025 02:00:02 +0800 Subject: [PATCH 02/35] std::fs: slightly reformat `remove_dir_all` error docs To make the error cases easier to spot on a quick glance. --- library/std/src/fs.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 6001a2e2f391f..2b3a84d0a12c2 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -2841,9 +2841,11 @@ pub fn remove_dir>(path: P) -> io::Result<()> { /// /// See [`fs::remove_file`] and [`fs::remove_dir`]. /// -/// `remove_dir_all` will fail if `remove_dir` or `remove_file` fail on any constituent paths, including the root `path`. -/// As a result, the directory you are deleting must exist, meaning that this function is not idempotent. -/// Additionally, `remove_dir_all` will also fail if the `path` is not a directory. +/// [`remove_dir_all`] will fail if [`remove_dir`] or [`remove_file`] fail on *any* constituent +/// paths, *including* the root `path`. Consequently, +/// +/// - The directory you are deleting *must* exist, meaning that this function is *not idempotent*. +/// - [`remove_dir_all`] will fail if the `path` is *not* a directory. /// /// Consider ignoring the error if validating the removal is not required for your use case. /// From 2c752bcf559975995eb8086a7fa6a7f9b5ba0de8 Mon Sep 17 00:00:00 2001 From: Arlo Siemsen Date: Thu, 20 Feb 2025 11:47:14 -0600 Subject: [PATCH 03/35] Undeprecate env::home_dir --- library/std/src/env.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/library/std/src/env.rs b/library/std/src/env.rs index adbd68896241c..5a931b077cdb0 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -641,11 +641,6 @@ impl Error for JoinPathsError { /// None => println!("Impossible to get your home dir!"), /// } /// ``` -#[deprecated( - since = "1.29.0", - note = "This function's behavior may be unexpected on Windows. \ - Consider using a crate from crates.io instead." -)] #[must_use] #[stable(feature = "env", since = "1.0.0")] pub fn home_dir() -> Option { From 9323ba54d3b35aeaf55a9596a29682c7173cf4d2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 20 Feb 2025 03:04:13 +0000 Subject: [PATCH 04/35] Remove MaybeForgetReturn suggestion --- compiler/rustc_errors/src/lib.rs | 1 - .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 5 -- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 60 +------------------ .../src/error_reporting/traits/ambiguity.rs | 8 +-- ...suggest-add-return-to-coerce-ret-ty.stderr | 8 --- .../return/tail-expr-as-potential-return.rs | 1 - .../tail-expr-as-potential-return.stderr | 4 -- 7 files changed, 4 insertions(+), 83 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 6fce1fade2664..9df306bb63540 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -599,7 +599,6 @@ pub enum StashKey { MaybeFruTypo, CallAssocMethod, AssociatedTypeSuggestion, - MaybeForgetReturn, /// Query cycle detected, stashing in favor of a better error. Cycle, UndeterminedMacroResolution, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 2d7d80e39bc31..5bd190cda9503 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -666,12 +666,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !errors.is_empty() { self.adjust_fulfillment_errors_for_expr_obligation(&mut errors); - let errors_causecode = errors - .iter() - .map(|e| (e.obligation.cause.span, e.root_obligation.cause.code().clone())) - .collect::>(); self.err_ctxt().report_fulfillment_errors(errors); - self.collect_unused_stmts_for_coerce_return_ty(errors_causecode); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index cf61659479b13..f1b60fabfefd9 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -3,9 +3,7 @@ use std::{fmt, iter, mem}; use itertools::Itertools; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::codes::*; -use rustc_errors::{ - Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, a_or_an, listify, pluralize, -}; +use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, a_or_an, listify, pluralize}; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; @@ -2167,62 +2165,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub(super) fn collect_unused_stmts_for_coerce_return_ty( - &self, - errors_causecode: Vec<(Span, ObligationCauseCode<'tcx>)>, - ) { - for (span, code) in errors_causecode { - self.dcx().try_steal_modify_and_emit_err(span, StashKey::MaybeForgetReturn, |err| { - if let Some(fn_sig) = self.body_fn_sig() - && let ObligationCauseCode::WhereClauseInExpr(_, _, binding_hir_id, ..) = code - && !fn_sig.output().is_unit() - { - let mut block_num = 0; - let mut found_semi = false; - for (hir_id, node) in self.tcx.hir_parent_iter(binding_hir_id) { - // Don't proceed into parent bodies - if hir_id.owner != binding_hir_id.owner { - break; - } - match node { - hir::Node::Stmt(stmt) => { - if let hir::StmtKind::Semi(expr) = stmt.kind { - let expr_ty = self.typeck_results.borrow().expr_ty(expr); - let return_ty = fn_sig.output(); - if !matches!(expr.kind, hir::ExprKind::Ret(..)) - && self.may_coerce(expr_ty, return_ty) - { - found_semi = true; - } - } - } - hir::Node::Block(_block) => { - if found_semi { - block_num += 1; - } - } - hir::Node::Item(item) => { - if let hir::ItemKind::Fn { .. } = item.kind { - break; - } - } - _ => {} - } - } - if block_num > 1 && found_semi { - err.span_suggestion_verbose( - // use the span of the *whole* expr - self.tcx.hir().span(binding_hir_id).shrink_to_lo(), - "you might have meant to return this to infer its type parameters", - "return ", - Applicability::MaybeIncorrect, - ); - } - } - }); - } - } - /// Given a vector of fulfillment errors, try to adjust the spans of the /// errors to more accurately point at the cause of the failure. /// diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index f15f1b78b5282..d673e5672a00b 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -1,8 +1,6 @@ use std::ops::ControlFlow; -use rustc_errors::{ - Applicability, Diag, E0283, E0284, E0790, MultiSpan, StashKey, struct_span_code_err, -}; +use rustc_errors::{Applicability, Diag, E0283, E0284, E0790, MultiSpan, struct_span_code_err}; use rustc_hir as hir; use rustc_hir::LangItem; use rustc_hir::def::{DefKind, Res}; @@ -197,7 +195,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // be ignoring the fact that we don't KNOW the type works // out. Though even that would probably be harmless, given that // we're only talking about builtin traits, which are known to be - // inhabited. We used to check for `self.tcx.sess.has_errors()` to + // inhabited. We used to check for `self.tainted_by_errors()` to // avoid inundating the user with unnecessary errors, but we now // check upstream for type errors and don't add the obligations to // begin with in those cases. @@ -211,7 +209,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { TypeAnnotationNeeded::E0282, false, ); - return err.stash(span, StashKey::MaybeForgetReturn).unwrap(); + return err.emit(); } Some(e) => return e, } diff --git a/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr b/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr index 1fea73529a8a2..c61ca699b0d35 100644 --- a/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr +++ b/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr @@ -8,10 +8,6 @@ help: consider specifying the generic arguments | LL | Err::(MyError); | ++++++++++++++ -help: you might have meant to return this to infer its type parameters - | -LL | return Err(MyError); - | ++++++ error[E0282]: type annotations needed --> $DIR/issue-86094-suggest-add-return-to-coerce-ret-ty.rs:14:9 @@ -23,10 +19,6 @@ help: consider specifying the generic arguments | LL | Ok::<(), E>(()); | +++++++++ -help: you might have meant to return this to infer its type parameters - | -LL | return Ok(()); - | ++++++ error[E0308]: mismatched types --> $DIR/issue-86094-suggest-add-return-to-coerce-ret-ty.rs:21:20 diff --git a/tests/ui/return/tail-expr-as-potential-return.rs b/tests/ui/return/tail-expr-as-potential-return.rs index 11ecddb049b57..2e638f1897c22 100644 --- a/tests/ui/return/tail-expr-as-potential-return.rs +++ b/tests/ui/return/tail-expr-as-potential-return.rs @@ -60,7 +60,6 @@ fn method() -> Option { Receiver.generic(); //~^ ERROR type annotations needed //~| HELP consider specifying the generic argument - //~| HELP you might have meant to return this to infer its type parameters } None diff --git a/tests/ui/return/tail-expr-as-potential-return.stderr b/tests/ui/return/tail-expr-as-potential-return.stderr index 756de2b5a1668..8105b2df3fea6 100644 --- a/tests/ui/return/tail-expr-as-potential-return.stderr +++ b/tests/ui/return/tail-expr-as-potential-return.stderr @@ -57,10 +57,6 @@ help: consider specifying the generic argument | LL | Receiver.generic::(); | +++++ -help: you might have meant to return this to infer its type parameters - | -LL | return Receiver.generic(); - | ++++++ error: aborting due to 4 previous errors From ef337a6599145766fc73b2896c6ff3e0fef65b0b Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 9 Feb 2025 06:08:59 +0000 Subject: [PATCH 05/35] Make `ptr_cast_add_auto_to_object` lint into hard error In Rust 1.81, we added a FCW lint (including linting in dependencies) against pointer casts that add an auto trait to dyn bounds. This was part of work making casts of pointers involving trait objects stricter which was needed to restabilize trait upcasting. We considered just making this a hard error at the time, but opted against it due to breakage found by crater. This breakage was mostly due to the `anymap` crate which has been a persistent problem for us. It's now a year later, and the fact that this is not yet a hard error is giving us pause about stabilizing arbitrary self types and `derive(CoercePointee)`. So let's now make a hard error of this. --- .../src/error_codes/E0804.md | 41 ++++++++++++++ compiler/rustc_error_codes/src/lib.rs | 1 + compiler/rustc_hir_typeck/messages.ftl | 9 ++-- compiler/rustc_hir_typeck/src/cast.rs | 28 +++++----- compiler/rustc_hir_typeck/src/errors.rs | 9 +++- compiler/rustc_lint/src/lib.rs | 5 ++ compiler/rustc_lint_defs/src/builtin.rs | 53 ------------------- tests/ui/cast/ptr-to-trait-obj-add-auto.rs | 14 ++--- .../ui/cast/ptr-to-trait-obj-add-auto.stderr | 44 ++++----------- tests/ui/lint/removed-lints/README.md | 4 ++ .../ptr_cast_add_auto_to_object.rs | 5 ++ .../ptr_cast_add_auto_to_object.stderr | 10 ++++ 12 files changed, 110 insertions(+), 113 deletions(-) create mode 100644 compiler/rustc_error_codes/src/error_codes/E0804.md create mode 100644 tests/ui/lint/removed-lints/README.md create mode 100644 tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs create mode 100644 tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr diff --git a/compiler/rustc_error_codes/src/error_codes/E0804.md b/compiler/rustc_error_codes/src/error_codes/E0804.md new file mode 100644 index 0000000000000..9a6937c0b52e0 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0804.md @@ -0,0 +1,41 @@ +An auto trait cannot be added to the bounds of a `dyn Trait` type via +a pointer cast. + +Erroneous code example: + +```rust,edition2021,compile_fail,E0804 +let ptr: *const dyn core::any::Any = &(); +_ = ptr as *const (dyn core::any::Any + Send); +``` + +Adding an auto trait can make the vtable invalid, potentially causing +UB in safe code afterwards. For example: + +```rust,edition2021,no_run +use core::{mem::transmute, ptr::NonNull}; + +trait Trait { + fn f(&self) + where + Self: Send; +} + +impl Trait for NonNull<()> { + fn f(&self) { + unreachable!() + } +} + +fn main() { + let unsend: &dyn Trait = &NonNull::dangling(); + let bad: &(dyn Trait + Send) = unsafe { transmute(unsend) }; + // This crashes, since the vtable for `NonNull as dyn Trait` does + // not have an entry for `Trait::f`. + bad.f(); +} +``` + +To fix this error, you can use `transmute` rather than pointer casts, +but you must ensure that the vtable is valid for the pointer's type +before calling a method on the trait object or allowing other code to +do so. diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index 098ca42be2b44..d53d5678832b7 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -547,6 +547,7 @@ E0800: 0800, E0801: 0801, E0802: 0802, E0803: 0803, +E0804: 0804, ); ) } diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index a994b31aeb437..c9dea60ba9fe5 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -154,10 +154,13 @@ hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function .suggestion = cast the value to `{$cast_ty}` .teach_help = certain types, like `{$ty}`, must be casted before passing them to a variadic function, because of arcane ABI rules dictated by the C standard -hir_typeck_ptr_cast_add_auto_to_object = adding {$traits_len -> - [1] an auto trait {$traits} +hir_typeck_ptr_cast_add_auto_to_object = cannot add {$traits_len -> + [1] auto trait {$traits} *[other] auto traits {$traits} -} to a trait object in a pointer cast may cause UB later on +} to dyn bound via pointer cast + .note = this could allow UB elsewhere + .help = use `transmute` if you're sure this is sound + .label = unsupported cast hir_typeck_remove_semi_for_coerce = you might have meant to return the `match` expression hir_typeck_remove_semi_for_coerce_expr = this could be implicitly returned but it is a statement, not a tail expression diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index f5f6ada12c3cc..02a44d58a406a 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -936,23 +936,19 @@ impl<'a, 'tcx> CastCheck<'tcx> { .collect::>(); if !added.is_empty() { - tcx.emit_node_span_lint( - lint::builtin::PTR_CAST_ADD_AUTO_TO_OBJECT, - self.expr.hir_id, - self.span, - errors::PtrCastAddAutoToObject { - traits_len: added.len(), - traits: { - let mut traits: Vec<_> = added - .into_iter() - .map(|trait_did| tcx.def_path_str(trait_did)) - .collect(); - - traits.sort(); - traits.into() - }, + tcx.dcx().emit_err(errors::PtrCastAddAutoToObject { + span: self.span, + traits_len: added.len(), + traits: { + let mut traits: Vec<_> = added + .into_iter() + .map(|trait_did| tcx.def_path_str(trait_did)) + .collect(); + + traits.sort(); + traits.into() }, - ) + }); } Ok(CastKind::PtrPtrCast) diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 1bf8aa4f78d4d..f2ca7d2220389 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -373,9 +373,14 @@ pub(crate) struct LossyProvenanceInt2Ptr<'tcx> { pub sugg: LossyProvenanceInt2PtrSuggestion, } -#[derive(LintDiagnostic)] -#[diag(hir_typeck_ptr_cast_add_auto_to_object)] +#[derive(Diagnostic)] +#[diag(hir_typeck_ptr_cast_add_auto_to_object, code = E0804)] +#[note] +#[help] pub(crate) struct PtrCastAddAutoToObject { + #[primary_span] + #[label] + pub span: Span, pub traits_len: usize, pub traits: DiagSymbolList, } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index c8de5e877531e..1dc487d3511cb 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -601,6 +601,11 @@ fn register_builtins(store: &mut LintStore) { "converted into hard error, \ see for more information", ); + store.register_removed( + "ptr_cast_add_auto_to_object", + "converted into hard error, see issue #127323 \ + for more information", + ); } fn register_internals(store: &mut LintStore) { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 10bf4ec77ed93..42e288976f9ef 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -80,7 +80,6 @@ declare_lint_pass! { PRIVATE_BOUNDS, PRIVATE_INTERFACES, PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, - PTR_CAST_ADD_AUTO_TO_OBJECT, PTR_TO_INTEGER_TRANSMUTE_IN_CONSTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE, REDUNDANT_IMPORTS, @@ -4827,58 +4826,6 @@ declare_lint! { }; } -declare_lint! { - /// The `ptr_cast_add_auto_to_object` lint detects casts of raw pointers to trait - /// objects, which add auto traits. - /// - /// ### Example - /// - /// ```rust,edition2021,compile_fail - /// let ptr: *const dyn core::any::Any = &(); - /// _ = ptr as *const dyn core::any::Any + Send; - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// Adding an auto trait can make the vtable invalid, potentially causing - /// UB in safe code afterwards. For example: - /// - /// ```ignore (causes a warning) - /// #![feature(arbitrary_self_types)] - /// - /// trait Trait { - /// fn f(self: *const Self) - /// where - /// Self: Send; - /// } - /// - /// impl Trait for *const () { - /// fn f(self: *const Self) { - /// unreachable!() - /// } - /// } - /// - /// fn main() { - /// let unsend: *const () = &(); - /// let unsend: *const dyn Trait = &unsend; - /// let send_bad: *const (dyn Trait + Send) = unsend as _; - /// send_bad.f(); // this crashes, since vtable for `*const ()` does not have an entry for `f` - /// } - /// ``` - /// - /// Generally you must ensure that vtable is right for the pointer's type, - /// before passing the pointer to safe code. - pub PTR_CAST_ADD_AUTO_TO_OBJECT, - Warn, - "detects `as` casts from pointers to `dyn Trait` to pointers to `dyn Trait + Auto`", - @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, - reference: "issue #127323 ", - }; -} - declare_lint! { /// The `out_of_scope_macro_calls` lint detects `macro_rules` called when they are not in scope, /// above their definition, which may happen in key-value attributes. diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs index 46e72ea08779c..3a1e667d03a4f 100644 --- a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs @@ -1,18 +1,20 @@ -//@ check-pass - trait Trait<'a> {} fn add_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send) { x as _ - //~^ warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on - //~| warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //~^ ERROR cannot add auto trait `Send` to dyn bound via pointer cast + //~| NOTE unsupported cast + //~| NOTE this could allow UB elsewhere + //~| HELP use `transmute` if you're sure this is sound } // (to test diagnostic list formatting) fn add_multiple_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send + Sync + Unpin) { x as _ - //~^ warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on - //~| warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //~^ ERROR cannot add auto traits `Send`, `Sync`, and `Unpin` to dyn bound via pointer cast + //~| NOTE unsupported cast + //~| NOTE this could allow UB elsewhere + //~| HELP use `transmute` if you're sure this is sound } fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr index e5ef8bf76b447..b64ca9b32bf5d 100644 --- a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr @@ -1,43 +1,21 @@ -warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on - --> $DIR/ptr-to-trait-obj-add-auto.rs:6:5 +error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast + --> $DIR/ptr-to-trait-obj-add-auto.rs:4:5 | LL | x as _ - | ^^^^^^ + | ^^^^^^ unsupported cast | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #127323 - = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default + = note: this could allow UB elsewhere + = help: use `transmute` if you're sure this is sound -warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on +error[E0804]: cannot add auto traits `Send`, `Sync`, and `Unpin` to dyn bound via pointer cast --> $DIR/ptr-to-trait-obj-add-auto.rs:13:5 | LL | x as _ - | ^^^^^^ + | ^^^^^^ unsupported cast | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #127323 + = note: this could allow UB elsewhere + = help: use `transmute` if you're sure this is sound -warning: 2 warnings emitted - -Future incompatibility report: Future breakage diagnostic: -warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on - --> $DIR/ptr-to-trait-obj-add-auto.rs:6:5 - | -LL | x as _ - | ^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #127323 - = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default - -Future breakage diagnostic: -warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on - --> $DIR/ptr-to-trait-obj-add-auto.rs:13:5 - | -LL | x as _ - | ^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #127323 - = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0804`. diff --git a/tests/ui/lint/removed-lints/README.md b/tests/ui/lint/removed-lints/README.md new file mode 100644 index 0000000000000..abe7ee04115c3 --- /dev/null +++ b/tests/ui/lint/removed-lints/README.md @@ -0,0 +1,4 @@ +# Removed lints + +This directory contains tests to confirm that lints that have been +removed do not cause errors and produce the appropriate warnings. diff --git a/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs new file mode 100644 index 0000000000000..7fb635487ff2e --- /dev/null +++ b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs @@ -0,0 +1,5 @@ +//@ check-pass + +#![deny(ptr_cast_add_auto_to_object)] +//~^ WARN lint `ptr_cast_add_auto_to_object` has been removed +fn main() {} diff --git a/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr new file mode 100644 index 0000000000000..36b5e847d807c --- /dev/null +++ b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr @@ -0,0 +1,10 @@ +warning: lint `ptr_cast_add_auto_to_object` has been removed: converted into hard error, see issue #127323 for more information + --> $DIR/ptr_cast_add_auto_to_object.rs:3:9 + | +LL | #![deny(ptr_cast_add_auto_to_object)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(renamed_and_removed_lints)]` on by default + +warning: 1 warning emitted + From a7bd4a309c2d154ab4bafee9b575d4196b5d3222 Mon Sep 17 00:00:00 2001 From: beetrees Date: Tue, 25 Feb 2025 22:26:52 +0000 Subject: [PATCH 06/35] Add DWARF test case for non-C-like `repr128` enums --- tests/run-make/repr128-dwarf/main.rs | 25 ++++++ tests/run-make/repr128-dwarf/rmake.rs | 115 +++++++++++++++++++++----- 2 files changed, 119 insertions(+), 21 deletions(-) diff --git a/tests/run-make/repr128-dwarf/main.rs b/tests/run-make/repr128-dwarf/main.rs index 57923a8386db9..9842ab4a3426f 100644 --- a/tests/run-make/repr128-dwarf/main.rs +++ b/tests/run-make/repr128-dwarf/main.rs @@ -19,8 +19,33 @@ pub enum I128Enum { I128D = i128::MAX.to_le(), } +#[cfg(not(old_llvm))] +#[repr(u128)] +pub enum U128VariantEnum { + VariantU128A(u8) = 0_u128.to_le(), + VariantU128B = 1_u128.to_le(), + VariantU128C = (u64::MAX as u128 + 1).to_le(), + VariantU128D = u128::MAX.to_le(), +} + +#[cfg(not(old_llvm))] +#[repr(i128)] +pub enum I128VariantEnum { + VariantI128A(u8) = 0_i128.to_le(), + VariantI128B = (-1_i128).to_le(), + VariantI128C = i128::MIN.to_le(), + VariantI128D = i128::MAX.to_le(), +} + pub fn f(_: U128Enum, _: I128Enum) {} +#[cfg(not(old_llvm))] +pub fn g(_: U128VariantEnum, _: I128VariantEnum) {} + fn main() { f(U128Enum::U128A, I128Enum::I128A); + #[cfg(not(old_llvm))] + { + g(U128VariantEnum::VariantU128A(1), I128VariantEnum::VariantI128A(2)); + } } diff --git a/tests/run-make/repr128-dwarf/rmake.rs b/tests/run-make/repr128-dwarf/rmake.rs index 2fd54c186b934..15eb186717f6d 100644 --- a/tests/run-make/repr128-dwarf/rmake.rs +++ b/tests/run-make/repr128-dwarf/rmake.rs @@ -5,13 +5,32 @@ use std::collections::HashMap; use std::path::PathBuf; use std::rc::Rc; +use gimli::read::DebuggingInformationEntry; use gimli::{AttributeValue, EndianRcSlice, Reader, RunTimeEndian}; use object::{Object, ObjectSection}; use run_make_support::{gimli, object, rfs, rustc}; fn main() { + // Before LLVM 20, 128-bit enums with variants didn't emit debuginfo correctly. + // This check can be removed once Rust no longer supports LLVM 18 and 19. + let llvm_version = rustc() + .verbose() + .arg("--version") + .run() + .stdout_utf8() + .lines() + .filter_map(|line| line.strip_prefix("LLVM version: ")) + .map(|version| version.split(".").next().unwrap().parse::().unwrap()) + .next() + .unwrap(); + let is_old_llvm = llvm_version < 20; + let output = PathBuf::from("repr128"); - rustc().input("main.rs").output(&output).arg("-Cdebuginfo=2").run(); + let mut rustc = rustc(); + if is_old_llvm { + rustc.cfg("old_llvm"); + } + rustc.input("main.rs").output(&output).arg("-Cdebuginfo=2").run(); // Mach-O uses packed debug info let dsym_location = output .with_extension("dSYM") @@ -29,7 +48,8 @@ fn main() { }) .unwrap(); let mut iter = dwarf.units(); - let mut still_to_find = HashMap::from([ + + let mut enumerators_to_find = HashMap::from([ ("U128A", 0_u128), ("U128B", 1_u128), ("U128C", u64::MAX as u128 + 1), @@ -39,35 +59,88 @@ fn main() { ("I128C", i128::MIN as u128), ("I128D", i128::MAX as u128), ]); + let mut variants_to_find = HashMap::from([ + ("VariantU128A", 0_u128), + ("VariantU128B", 1_u128), + ("VariantU128C", u64::MAX as u128 + 1), + ("VariantU128D", u128::MAX), + ("VariantI128A", 0_i128 as u128), + ("VariantI128B", (-1_i128) as u128), + ("VariantI128C", i128::MIN as u128), + ("VariantI128D", i128::MAX as u128), + ]); + while let Some(header) = iter.next().unwrap() { let unit = dwarf.unit(header).unwrap(); let mut cursor = unit.entries(); + + let get_name = |entry: &DebuggingInformationEntry<'_, '_, _>| { + let name = dwarf + .attr_string( + &unit, + entry.attr(gimli::constants::DW_AT_name).unwrap().unwrap().value(), + ) + .unwrap(); + name.to_string().unwrap().to_string() + }; + while let Some((_, entry)) = cursor.next_dfs().unwrap() { - if entry.tag() == gimli::constants::DW_TAG_enumerator { - let name = dwarf - .attr_string( - &unit, - entry.attr(gimli::constants::DW_AT_name).unwrap().unwrap().value(), - ) - .unwrap(); - let name = name.to_string().unwrap(); - if let Some(expected) = still_to_find.remove(name.as_ref()) { - match entry.attr(gimli::constants::DW_AT_const_value).unwrap().unwrap().value() + match entry.tag() { + gimli::constants::DW_TAG_variant if !is_old_llvm => { + let value = match entry + .attr(gimli::constants::DW_AT_discr_value) + .unwrap() + .unwrap() + .value() { - AttributeValue::Block(value) => { - assert_eq!( - value.to_slice().unwrap(), - expected.to_le_bytes().as_slice(), - "{name}" - ); + AttributeValue::Block(value) => value.to_slice().unwrap().to_vec(), + value => panic!("unexpected DW_AT_discr_value of {value:?}"), + }; + // The `DW_TAG_member` that is a child of `DW_TAG_variant` will contain the + // variant's name. + let Some((1, child_entry)) = cursor.next_dfs().unwrap() else { + panic!("Missing child of DW_TAG_variant"); + }; + assert_eq!(child_entry.tag(), gimli::constants::DW_TAG_member); + let name = get_name(child_entry); + if let Some(expected) = variants_to_find.remove(name.as_str()) { + // This test uses LE byte order is used for consistent values across + // architectures. + assert_eq!(value.as_slice(), expected.to_le_bytes().as_slice(), "{name}"); + } + } + + gimli::constants::DW_TAG_enumerator => { + let name = get_name(entry); + if let Some(expected) = enumerators_to_find.remove(name.as_str()) { + match entry + .attr(gimli::constants::DW_AT_const_value) + .unwrap() + .unwrap() + .value() + { + AttributeValue::Block(value) => { + // This test uses LE byte order is used for consistent values across + // architectures. + assert_eq!( + value.to_slice().unwrap(), + expected.to_le_bytes().as_slice(), + "{name}" + ); + } + value => panic!("{name}: unexpected DW_AT_const_value of {value:?}"), } - value => panic!("{name}: unexpected DW_AT_const_value of {value:?}"), } } + + _ => {} } } } - if !still_to_find.is_empty() { - panic!("Didn't find debug entries for {still_to_find:?}"); + if !enumerators_to_find.is_empty() { + panic!("Didn't find debug enumerator entries for {enumerators_to_find:?}"); + } + if !is_old_llvm && !variants_to_find.is_empty() { + panic!("Didn't find debug variant entries for {variants_to_find:?}"); } } From b2bb7cc8ae45e8852e4b76fa10408a1eed626412 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Thu, 27 Feb 2025 19:06:06 -0800 Subject: [PATCH 07/35] Fix char count in Display for ByteStr --- library/core/src/bstr.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/core/src/bstr.rs b/library/core/src/bstr.rs index 74e07f3d242cd..ae84fd8adb61c 100644 --- a/library/core/src/bstr.rs +++ b/library/core/src/bstr.rs @@ -151,7 +151,9 @@ impl fmt::Display for ByteStr { }; let nchars: usize = self .utf8_chunks() - .map(|chunk| chunk.valid().len() + if chunk.invalid().is_empty() { 0 } else { 1 }) + .map(|chunk| { + chunk.valid().chars().count() + if chunk.invalid().is_empty() { 0 } else { 1 } + }) .sum(); let padding = f.width().unwrap_or(0).saturating_sub(nchars); let fill = f.fill(); From 41dd80aeaa706c169df62bdf16033b61b914cb87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 26 Feb 2025 14:29:19 +0100 Subject: [PATCH 08/35] add test to reproduce #137662 (using ty decl macro fragment in an attr) and fix it --- compiler/rustc_attr_parsing/src/parser.rs | 9 +++++++++ .../attributes/decl_macro_ty_in_attr_macro.rs | 20 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 tests/ui/attributes/decl_macro_ty_in_attr_macro.rs diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index b6d66af4466e2..6c2448b751283 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -473,6 +473,15 @@ impl<'a> MetaItemListParserContext<'a> { { self.inside_delimiters.next(); return Some(MetaItemOrLitParser::Lit(lit)); + } else if let Some(TokenTree::Delimited(.., Delimiter::Invisible(_), inner_tokens)) = + self.inside_delimiters.peek() + { + self.inside_delimiters.next(); + return MetaItemListParserContext { + inside_delimiters: inner_tokens.iter().peekable(), + dcx: self.dcx, + } + .next(); } // or a path. diff --git a/tests/ui/attributes/decl_macro_ty_in_attr_macro.rs b/tests/ui/attributes/decl_macro_ty_in_attr_macro.rs new file mode 100644 index 0000000000000..e633c08be3ad2 --- /dev/null +++ b/tests/ui/attributes/decl_macro_ty_in_attr_macro.rs @@ -0,0 +1,20 @@ +// tests for #137662: using a ty or (or most other) fragment inside an attr macro wouldn't work +// because of a missing code path. With $repr: tt it did work. +//@ check-pass + +macro_rules! foo { + { + $repr:ty + } => { + #[repr($repr)] + pub enum Foo { + Bar = 0i32, + } + } +} + +foo! { + i32 +} + +fn main() {} From 476b0980f22f4a4de2102f2994da39600fc4546d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 28 Feb 2025 16:30:59 +0100 Subject: [PATCH 09/35] adjust Layout debug printing to match the internal field names --- compiler/rustc_abi/src/lib.rs | 2 +- tests/ui/abi/c-zst.aarch64-darwin.stderr | 4 +- tests/ui/abi/c-zst.powerpc-linux.stderr | 4 +- tests/ui/abi/c-zst.s390x-linux.stderr | 4 +- tests/ui/abi/c-zst.sparc64-linux.stderr | 4 +- tests/ui/abi/c-zst.x86_64-linux.stderr | 4 +- .../ui/abi/c-zst.x86_64-pc-windows-gnu.stderr | 4 +- tests/ui/abi/debug.stderr | 48 +++++++++---------- tests/ui/abi/sysv64-zst.stderr | 4 +- tests/ui/layout/debug.stderr | 36 +++++++------- tests/ui/layout/hexagon-enum.stderr | 20 ++++---- ...-scalarpair-payload-might-be-uninit.stderr | 34 ++++++------- .../issue-96185-overaligned-enum.stderr | 12 ++--- tests/ui/layout/thumb-enum.stderr | 20 ++++---- .../layout/zero-sized-array-enum-niche.stderr | 26 +++++----- ...-variants.aarch64-unknown-linux-gnu.stderr | 16 +++---- ...-c-dead-variants.armebv7r-none-eabi.stderr | 16 +++---- ...-dead-variants.i686-pc-windows-msvc.stderr | 16 +++---- ...d-variants.x86_64-unknown-linux-gnu.stderr | 16 +++---- tests/ui/repr/repr-c-int-dead-variants.stderr | 16 +++---- .../type/pattern_types/range_patterns.stderr | 18 +++---- 21 files changed, 162 insertions(+), 162 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 81e4e255f3799..b91dedfe2005f 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1812,7 +1812,7 @@ where f.debug_struct("Layout") .field("size", size) .field("align", align) - .field("abi", backend_repr) + .field("backend_repr", backend_repr) .field("fields", fields) .field("largest_niche", largest_niche) .field("uninhabited", uninhabited) diff --git a/tests/ui/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr index 57cc48aa9cf47..48fa2bf29bc40 100644 --- a/tests/ui/abi/c-zst.aarch64-darwin.stderr +++ b/tests/ui/abi/c-zst.aarch64-darwin.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -38,7 +38,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr index 6738017673003..bfdf94c99007c 100644 --- a/tests/ui/abi/c-zst.powerpc-linux.stderr +++ b/tests/ui/abi/c-zst.powerpc-linux.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -49,7 +49,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr index 6738017673003..bfdf94c99007c 100644 --- a/tests/ui/abi/c-zst.s390x-linux.stderr +++ b/tests/ui/abi/c-zst.s390x-linux.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -49,7 +49,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr index 6738017673003..bfdf94c99007c 100644 --- a/tests/ui/abi/c-zst.sparc64-linux.stderr +++ b/tests/ui/abi/c-zst.sparc64-linux.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -49,7 +49,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/abi/c-zst.x86_64-linux.stderr b/tests/ui/abi/c-zst.x86_64-linux.stderr index 57cc48aa9cf47..48fa2bf29bc40 100644 --- a/tests/ui/abi/c-zst.x86_64-linux.stderr +++ b/tests/ui/abi/c-zst.x86_64-linux.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -38,7 +38,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr index 6738017673003..bfdf94c99007c 100644 --- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr +++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -49,7 +49,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr index 5f73ff7d6bd58..2239ba0e5880a 100644 --- a/tests/ui/abi/debug.stderr +++ b/tests/ui/abi/debug.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(test) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -48,7 +48,7 @@ error: fn_abi_of(test) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -107,7 +107,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -155,7 +155,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -205,7 +205,7 @@ error: fn_abi_of(test_generic) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Pointer( AddressSpace( @@ -245,7 +245,7 @@ error: fn_abi_of(test_generic) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -292,7 +292,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -331,7 +331,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -366,7 +366,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -405,7 +405,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -446,7 +446,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Array { @@ -486,7 +486,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -521,7 +521,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Array { @@ -561,7 +561,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -602,7 +602,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Float( F32, @@ -640,7 +640,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -675,7 +675,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -714,7 +714,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -755,7 +755,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -794,7 +794,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -829,7 +829,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -868,7 +868,7 @@ error: ABIs are not compatible abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -923,7 +923,7 @@ error: fn_abi_of(assoc_test) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Pointer( AddressSpace( @@ -975,7 +975,7 @@ error: fn_abi_of(assoc_test) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/abi/sysv64-zst.stderr b/tests/ui/abi/sysv64-zst.stderr index ec85030c10686..59d7b00441790 100644 --- a/tests/ui/abi/sysv64-zst.stderr +++ b/tests/ui/abi/sysv64-zst.stderr @@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -38,7 +38,7 @@ error: fn_abi_of(pass_zst) = FnAbi { abi: $SOME_ALIGN, pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index 07cad7766920f..80b35ff6ad49e 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -10,7 +10,7 @@ error: layout_of(E) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -49,7 +49,7 @@ error: layout_of(E) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -71,7 +71,7 @@ error: layout_of(E) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -112,7 +112,7 @@ error: layout_of(S) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -160,7 +160,7 @@ error: layout_of(U) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -186,7 +186,7 @@ error: layout_of(Result) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -238,7 +238,7 @@ error: layout_of(Result) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -277,7 +277,7 @@ error: layout_of(Result) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -327,7 +327,7 @@ error: layout_of(i32) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -357,7 +357,7 @@ error: layout_of(V) = Layout { abi: Align(2 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -383,7 +383,7 @@ error: layout_of(W) = Layout { abi: Align(2 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -409,7 +409,7 @@ error: layout_of(Y) = Layout { abi: Align(2 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -435,7 +435,7 @@ error: layout_of(P1) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -461,7 +461,7 @@ error: layout_of(P2) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -487,7 +487,7 @@ error: layout_of(P3) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -513,7 +513,7 @@ error: layout_of(P4) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Union( @@ -539,7 +539,7 @@ error: layout_of(P5) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Union { value: Int( I8, @@ -570,7 +570,7 @@ error: layout_of(MaybeUninit) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Union { value: Int( I8, diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index 90c06ba1f834e..1cd4efbcdad38 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -4,7 +4,7 @@ error: layout_of(A) = Layout { abi: Align(1 bytes), pref: Align(1 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -49,7 +49,7 @@ error: layout_of(A) = Layout { abi: Align(1 bytes), pref: Align(1 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -82,7 +82,7 @@ error: layout_of(B) = Layout { abi: Align(1 bytes), pref: Align(1 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -127,7 +127,7 @@ error: layout_of(B) = Layout { abi: Align(1 bytes), pref: Align(1 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -160,7 +160,7 @@ error: layout_of(C) = Layout { abi: Align(2 bytes), pref: Align(2 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I16, @@ -205,7 +205,7 @@ error: layout_of(C) = Layout { abi: Align(2 bytes), pref: Align(2 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -238,7 +238,7 @@ error: layout_of(P) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -283,7 +283,7 @@ error: layout_of(P) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -316,7 +316,7 @@ error: layout_of(T) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -361,7 +361,7 @@ error: layout_of(T) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index 3bdb9c5c143e4..ef7f0cd2d1c34 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -4,7 +4,7 @@ error: layout_of(MissingPayloadField) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -55,7 +55,7 @@ error: layout_of(MissingPayloadField) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -93,7 +93,7 @@ error: layout_of(MissingPayloadField) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -126,7 +126,7 @@ error: layout_of(CommonPayloadField) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -178,7 +178,7 @@ error: layout_of(CommonPayloadField) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -217,7 +217,7 @@ error: layout_of(CommonPayloadField) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -267,7 +267,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -318,7 +318,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -356,7 +356,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -405,7 +405,7 @@ error: layout_of(NicheFirst) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -460,7 +460,7 @@ error: layout_of(NicheFirst) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -510,7 +510,7 @@ error: layout_of(NicheFirst) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -532,7 +532,7 @@ error: layout_of(NicheFirst) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -565,7 +565,7 @@ error: layout_of(NicheSecond) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -620,7 +620,7 @@ error: layout_of(NicheSecond) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -670,7 +670,7 @@ error: layout_of(NicheSecond) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -692,7 +692,7 @@ error: layout_of(NicheSecond) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr index 1d4e443644826..a9081afc50944 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -4,7 +4,7 @@ error: layout_of(Aligned1) = Layout { abi: Align(8 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -43,7 +43,7 @@ error: layout_of(Aligned1) = Layout { abi: Align(8 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -67,7 +67,7 @@ error: layout_of(Aligned1) = Layout { abi: Align(8 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -104,7 +104,7 @@ error: layout_of(Aligned2) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -149,7 +149,7 @@ error: layout_of(Aligned2) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -173,7 +173,7 @@ error: layout_of(Aligned2) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index 0c34331856474..c1defe720db9c 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -4,7 +4,7 @@ error: layout_of(A) = Layout { abi: Align(1 bytes), pref: Align(4 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -49,7 +49,7 @@ error: layout_of(A) = Layout { abi: Align(1 bytes), pref: Align(4 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -82,7 +82,7 @@ error: layout_of(B) = Layout { abi: Align(1 bytes), pref: Align(4 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -127,7 +127,7 @@ error: layout_of(B) = Layout { abi: Align(1 bytes), pref: Align(4 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -160,7 +160,7 @@ error: layout_of(C) = Layout { abi: Align(2 bytes), pref: Align(4 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I16, @@ -205,7 +205,7 @@ error: layout_of(C) = Layout { abi: Align(2 bytes), pref: Align(4 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -238,7 +238,7 @@ error: layout_of(P) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -283,7 +283,7 @@ error: layout_of(P) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -316,7 +316,7 @@ error: layout_of(T) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -361,7 +361,7 @@ error: layout_of(T) = Layout { abi: Align(4 bytes), pref: Align(4 bytes), }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index 33d2eede22090..1ba184bdacefb 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -4,7 +4,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -43,7 +43,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -69,7 +69,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -115,7 +115,7 @@ error: layout_of(MultipleAlignments) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -154,7 +154,7 @@ error: layout_of(MultipleAlignments) = Layout { abi: Align(2 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -180,7 +180,7 @@ error: layout_of(MultipleAlignments) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -206,7 +206,7 @@ error: layout_of(MultipleAlignments) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -252,7 +252,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -291,7 +291,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -317,7 +317,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -363,7 +363,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -406,7 +406,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { abi: Align(4 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -432,7 +432,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { abi: Align(1 bytes), pref: $PREF_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index 204db30786ee3..5ae5aeb7d2c3b 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -4,7 +4,7 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -49,7 +49,7 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -92,7 +92,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -143,7 +143,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -181,7 +181,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -230,7 +230,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -269,7 +269,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -299,7 +299,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index 1fab00bf50c49..a325cb8d71ffe 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -4,7 +4,7 @@ error: layout_of(Univariant) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -49,7 +49,7 @@ error: layout_of(Univariant) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -92,7 +92,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -143,7 +143,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -181,7 +181,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -230,7 +230,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -269,7 +269,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -299,7 +299,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index 204db30786ee3..5ae5aeb7d2c3b 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -4,7 +4,7 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -49,7 +49,7 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -92,7 +92,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -143,7 +143,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -181,7 +181,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -230,7 +230,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -269,7 +269,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -299,7 +299,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index 204db30786ee3..5ae5aeb7d2c3b 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -4,7 +4,7 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -49,7 +49,7 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -92,7 +92,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -143,7 +143,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -181,7 +181,7 @@ error: layout_of(TwoVariants) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I32, @@ -230,7 +230,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -269,7 +269,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -299,7 +299,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr index f852212deb908..f63574182c25f 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -4,7 +4,7 @@ error: layout_of(UnivariantU8) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -49,7 +49,7 @@ error: layout_of(UnivariantU8) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I8, @@ -92,7 +92,7 @@ error: layout_of(TwoVariantsU8) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -143,7 +143,7 @@ error: layout_of(TwoVariantsU8) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -181,7 +181,7 @@ error: layout_of(TwoVariantsU8) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: ScalarPair( + backend_repr: ScalarPair( Initialized { value: Int( I8, @@ -230,7 +230,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -269,7 +269,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -299,7 +299,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index 690592ba0b8da..7eda50fd12116 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -4,7 +4,7 @@ error: layout_of(NonZero) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -50,7 +50,7 @@ error: layout_of((u32) is 1..=) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -89,7 +89,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -129,7 +129,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -151,7 +151,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -203,7 +203,7 @@ error: layout_of(Option>) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -243,7 +243,7 @@ error: layout_of(Option>) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Memory { + backend_repr: Memory { sized: true, }, fields: Arbitrary { @@ -265,7 +265,7 @@ error: layout_of(Option>) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, @@ -317,7 +317,7 @@ error: layout_of(NonZeroU32New) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Scalar( + backend_repr: Scalar( Initialized { value: Int( I32, From 91034adf30b3055e489d59f4483ed5def9cc9f19 Mon Sep 17 00:00:00 2001 From: Jack Wrenn Date: Fri, 28 Feb 2025 16:32:06 +0000 Subject: [PATCH 10/35] Do not require that unsafe fields lack drop glue Instead, we adopt the position that introducing an `unsafe` field itself carries a safety invariant: that if you assign an invariant to that field weaker than what the field's destructor requires, you must ensure that field is in a droppable state in your destructor. See: - https://github.com/rust-lang/rfcs/pull/3458#discussion_r1971676100 - https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/unsafe.20fields.20RFC/near/502113897 --- compiler/rustc_hir_analysis/messages.ftl | 7 ---- .../rustc_hir_analysis/src/check/check.rs | 32 ------------------- compiler/rustc_hir_analysis/src/errors.rs | 23 ------------- library/core/src/marker.rs | 4 +-- tests/ui/unsafe-fields/unsafe-fields.rs | 2 +- tests/ui/unsafe-fields/unsafe-fields.stderr | 17 ++-------- 6 files changed, 5 insertions(+), 80 deletions(-) diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 3f75cce009225..fe2254faf61e8 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -278,13 +278,6 @@ hir_analysis_invalid_union_field = hir_analysis_invalid_union_field_sugg = wrap the field type in `ManuallyDrop<...>` -hir_analysis_invalid_unsafe_field = - field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be unsafe - .note = unsafe fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>` - -hir_analysis_invalid_unsafe_field_sugg = - wrap the field type in `ManuallyDrop<...>` - hir_analysis_late_bound_const_in_apit = `impl Trait` can only mention const parameters from an fn or impl .label = const parameter declared here diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index f2331f3fd8e13..25dc6b7954b21 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -70,7 +70,6 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) { check_transparent(tcx, def); check_packed(tcx, span, def); - check_unsafe_fields(tcx, def_id); } fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) { @@ -144,36 +143,6 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b true } -/// Check that the unsafe fields do not need dropping. -fn check_unsafe_fields(tcx: TyCtxt<'_>, item_def_id: LocalDefId) { - let span = tcx.def_span(item_def_id); - let def = tcx.adt_def(item_def_id); - - let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id); - let args = ty::GenericArgs::identity_for_item(tcx, item_def_id); - - for field in def.all_fields() { - if !field.safety.is_unsafe() { - continue; - } - - if !allowed_union_or_unsafe_field(tcx, field.ty(tcx, args), typing_env, span) { - let hir::Node::Field(field) = tcx.hir_node_by_def_id(field.did.expect_local()) else { - unreachable!("field has to correspond to hir field") - }; - let ty_span = field.ty.span; - tcx.dcx().emit_err(errors::InvalidUnsafeField { - field_span: field.span, - sugg: errors::InvalidUnsafeFieldSuggestion { - lo: ty_span.shrink_to_lo(), - hi: ty_span.shrink_to_hi(), - }, - note: (), - }); - } - } -} - /// Check that a `static` is inhabited. fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { // Make sure statics are inhabited. @@ -1517,7 +1486,6 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) { detect_discriminant_duplicate(tcx, def); check_transparent(tcx, def); - check_unsafe_fields(tcx, def_id); } /// Part of enum check. Given the discriminants of an enum, errors if two or more discriminants are equal diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 852533ff5c954..d000314974ce2 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -710,17 +710,6 @@ pub(crate) struct InvalidUnionField { pub note: (), } -#[derive(Diagnostic)] -#[diag(hir_analysis_invalid_unsafe_field, code = E0740)] -pub(crate) struct InvalidUnsafeField { - #[primary_span] - pub field_span: Span, - #[subdiagnostic] - pub sugg: InvalidUnsafeFieldSuggestion, - #[note] - pub note: (), -} - #[derive(Diagnostic)] #[diag(hir_analysis_return_type_notation_on_non_rpitit)] pub(crate) struct ReturnTypeNotationOnNonRpitit<'tcx> { @@ -742,18 +731,6 @@ pub(crate) struct InvalidUnionFieldSuggestion { pub hi: Span, } -#[derive(Subdiagnostic)] -#[multipart_suggestion( - hir_analysis_invalid_unsafe_field_sugg, - applicability = "machine-applicable" -)] -pub(crate) struct InvalidUnsafeFieldSuggestion { - #[suggestion_part(code = "std::mem::ManuallyDrop<")] - pub lo: Span, - #[suggestion_part(code = ">")] - pub hi: Span, -} - #[derive(Diagnostic)] #[diag(hir_analysis_return_type_notation_equality_bound)] pub(crate) struct ReturnTypeNotationEqualityBound { diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index b0571bf7247af..e2dd813981d04 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -453,8 +453,8 @@ impl Copy for ! {} #[stable(feature = "rust1", since = "1.0.0")] impl Copy for &T {} -/// Marker trait for the types that are allowed in union fields, unsafe fields, -/// and unsafe binder types. +/// Marker trait for the types that are allowed in union fields and unsafe +/// binder types. /// /// Implemented for: /// * `&T`, `&mut T` for all `T`, diff --git a/tests/ui/unsafe-fields/unsafe-fields.rs b/tests/ui/unsafe-fields/unsafe-fields.rs index 637471582d7e4..cb86479bb20d3 100644 --- a/tests/ui/unsafe-fields/unsafe-fields.rs +++ b/tests/ui/unsafe-fields/unsafe-fields.rs @@ -17,7 +17,7 @@ fn f(a: A) { } struct WithInvalidUnsafeField { - unsafe unsafe_noncopy_field: Vec, //~ ERROR + unsafe unsafe_noncopy_field: Vec, } struct WithManuallyDropUnsafeField { diff --git a/tests/ui/unsafe-fields/unsafe-fields.stderr b/tests/ui/unsafe-fields/unsafe-fields.stderr index a1c5d2b44cdf1..d0e2dc16a13d5 100644 --- a/tests/ui/unsafe-fields/unsafe-fields.stderr +++ b/tests/ui/unsafe-fields/unsafe-fields.stderr @@ -1,15 +1,3 @@ -error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be unsafe - --> $DIR/unsafe-fields.rs:20:5 - | -LL | unsafe unsafe_noncopy_field: Vec, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: unsafe fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>` -help: wrap the field type in `ManuallyDrop<...>` - | -LL | unsafe unsafe_noncopy_field: std::mem::ManuallyDrop>, - | +++++++++++++++++++++++ + - error[E0133]: use of unsafe field is unsafe and requires unsafe block --> $DIR/unsafe-fields.rs:15:30 | @@ -69,7 +57,6 @@ LL | &raw const self.unsafe_field | = note: unsafe fields may carry library invariants -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0133, E0740. -For more information about an error, try `rustc --explain E0133`. +For more information about this error, try `rustc --explain E0133`. From 3998690a68d0346bc31870595e7ca6cf8540a989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 5 Feb 2025 21:15:04 +0800 Subject: [PATCH 11/35] compiletest: remove legacy `Makefile`-based `run-make` support --- src/tools/compiletest/src/header.rs | 16 +- src/tools/compiletest/src/header/tests.rs | 9 - src/tools/compiletest/src/lib.rs | 43 ++--- src/tools/compiletest/src/runtest/run_make.rs | 164 ------------------ 4 files changed, 18 insertions(+), 214 deletions(-) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 53ee901b8bc48..7675e13990d6c 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -709,11 +709,11 @@ impl TestProps { /// returns a struct containing various parts of the directive. fn line_directive<'line>( line_number: usize, - comment: &str, original_line: &'line str, ) -> Option> { // Ignore lines that don't start with the comment prefix. - let after_comment = original_line.trim_start().strip_prefix(comment)?.trim_start(); + let after_comment = + original_line.trim_start().strip_prefix(COMPILETEST_DIRECTIVE_PREFIX)?.trim_start(); let revision; let raw_directive; @@ -722,7 +722,7 @@ fn line_directive<'line>( // A comment like `//@[foo]` only applies to revision `foo`. let Some((line_revision, after_close_bracket)) = after_open_bracket.split_once(']') else { panic!( - "malformed condition directive: expected `{comment}[foo]`, found `{original_line}`" + "malformed condition directive: expected `{COMPILETEST_DIRECTIVE_PREFIX}[foo]`, found `{original_line}`" ) }; @@ -836,6 +836,8 @@ pub(crate) fn check_directive<'a>( CheckDirectiveResult { is_known_directive: is_known(&directive_name), trailing_directive } } +const COMPILETEST_DIRECTIVE_PREFIX: &str = "//@"; + fn iter_header( mode: Mode, _suite: &str, @@ -849,8 +851,7 @@ fn iter_header( } // Coverage tests in coverage-run mode always have these extra directives, without needing to - // specify them manually in every test file. (Some of the comments below have been copied over - // from the old `tests/run-make/coverage-reports/Makefile`, which no longer exists.) + // specify them manually in every test file. // // FIXME(jieyouxu): I feel like there's a better way to do this, leaving for later. if mode == Mode::CoverageRun { @@ -867,9 +868,6 @@ fn iter_header( } } - // NOTE(jieyouxu): once we get rid of `Makefile`s we can unconditionally check for `//@`. - let comment = if testfile.extension().is_some_and(|e| e == "rs") { "//@" } else { "#" }; - let mut rdr = BufReader::with_capacity(1024, rdr); let mut ln = String::new(); let mut line_number = 0; @@ -882,7 +880,7 @@ fn iter_header( } let ln = ln.trim(); - let Some(directive_line) = line_directive(line_number, comment, ln) else { + let Some(directive_line) = line_directive(line_number, ln) else { continue; }; diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index d7079fdeee6c3..007318be7cc39 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -239,11 +239,6 @@ fn check_ignore(config: &Config, contents: &str) -> bool { d.ignore } -fn parse_makefile(config: &Config, contents: &str) -> EarlyProps { - let bytes = contents.as_bytes(); - EarlyProps::from_reader(config, Path::new("Makefile"), bytes) -} - #[test] fn should_fail() { let config: Config = cfg().build(); @@ -261,10 +256,6 @@ fn revisions() { let config: Config = cfg().build(); assert_eq!(parse_rs(&config, "//@ revisions: a b c").revisions, vec!["a", "b", "c"],); - assert_eq!( - parse_makefile(&config, "# revisions: hello there").revisions, - vec!["hello", "there"], - ); } #[test] diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 9dff7047bc4ab..30b8e269e6254 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -21,7 +21,7 @@ pub mod util; use core::panic; use std::collections::HashSet; -use std::ffi::{OsStr, OsString}; +use std::ffi::OsString; use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; @@ -268,12 +268,8 @@ pub fn parse_config(args: Vec) -> Config { let path = Path::new(f); let mut iter = path.iter().skip(1); - // We skip the test folder and check if the user passed `rmake.rs` or `Makefile`. - if iter - .next() - .is_some_and(|s| s == OsStr::new("rmake.rs") || s == OsStr::new("Makefile")) - && iter.next().is_none() - { + // We skip the test folder and check if the user passed `rmake.rs`. + if iter.next().is_some_and(|s| s == "rmake.rs") && iter.next().is_none() { path.parent().unwrap().to_str().unwrap().to_string() } else { f.to_string() @@ -776,16 +772,9 @@ fn collect_tests_from_dir( return Ok(()); } - // For run-make tests, a "test file" is actually a directory that contains - // an `rmake.rs` or `Makefile`" + // For run-make tests, a "test file" is actually a directory that contains an `rmake.rs`. if cx.config.mode == Mode::RunMake { - if dir.join("Makefile").exists() && dir.join("rmake.rs").exists() { - return Err(io::Error::other( - "run-make tests cannot have both `Makefile` and `rmake.rs`", - )); - } - - if dir.join("Makefile").exists() || dir.join("rmake.rs").exists() { + if dir.join("rmake.rs").exists() { let paths = TestPaths { file: dir.to_path_buf(), relative_dir: relative_dir_path.parent().unwrap().to_path_buf(), @@ -854,24 +843,14 @@ pub fn is_test(file_name: &OsString) -> bool { !invalid_prefixes.iter().any(|p| file_name.starts_with(p)) } -/// For a single test file, creates one or more test structures (one per revision) -/// that can be handed over to libtest to run, possibly in parallel. +/// For a single test file, creates one or more test structures (one per revision) that can be +/// handed over to libtest to run, possibly in parallel. fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &TestPaths) { - // For run-make tests, each "test file" is actually a _directory_ containing - // an `rmake.rs` or `Makefile`. But for the purposes of directive parsing, - // we want to look at that recipe file, not the directory itself. + // For run-make tests, each "test file" is actually a _directory_ containing an `rmake.rs`. But + // for the purposes of directive parsing, we want to look at that recipe file, not the directory + // itself. let test_path = if cx.config.mode == Mode::RunMake { - if testpaths.file.join("rmake.rs").exists() && testpaths.file.join("Makefile").exists() { - panic!("run-make tests cannot have both `rmake.rs` and `Makefile`"); - } - - if testpaths.file.join("rmake.rs").exists() { - // Parse directives in rmake.rs. - testpaths.file.join("rmake.rs") - } else { - // Parse directives in the Makefile. - testpaths.file.join("Makefile") - } + testpaths.file.join("rmake.rs") } else { PathBuf::from(&testpaths.file) }; diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 9bb3993223e21..b237fac38f6b7 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -9,168 +9,6 @@ use crate::util::{copy_dir_all, dylib_env_var}; impl TestCx<'_> { pub(super) fn run_rmake_test(&self) { - let test_dir = &self.testpaths.file; - if test_dir.join("rmake.rs").exists() { - self.run_rmake_v2_test(); - } else if test_dir.join("Makefile").exists() { - self.run_rmake_legacy_test(); - } else { - self.fatal("failed to find either `rmake.rs` or `Makefile`") - } - } - - fn run_rmake_legacy_test(&self) { - let cwd = env::current_dir().unwrap(); - - // FIXME(Zalathar): This should probably be `output_base_dir` to avoid - // an unnecessary extra subdirectory, but since legacy Makefile tests - // are hopefully going away, it seems safer to leave this perilous code - // as-is until it can all be deleted. - let tmpdir = cwd.join(self.output_base_name()); - ignore_not_found(|| recursive_remove(&tmpdir)).unwrap(); - - fs::create_dir_all(&tmpdir).unwrap(); - - let host = &self.config.host; - let make = if host.contains("dragonfly") - || host.contains("freebsd") - || host.contains("netbsd") - || host.contains("openbsd") - || host.contains("aix") - { - "gmake" - } else { - "make" - }; - - let mut cmd = Command::new(make); - cmd.current_dir(&self.testpaths.file) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .env("TARGET", &self.config.target) - .env("PYTHON", &self.config.python) - .env("S", &self.config.src_root) - .env("RUST_BUILD_STAGE", &self.config.stage_id) - .env("RUSTC", cwd.join(&self.config.rustc_path)) - .env("TMPDIR", &tmpdir) - .env("LD_LIB_PATH_ENVVAR", dylib_env_var()) - .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path)) - .env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path)) - .env("LLVM_COMPONENTS", &self.config.llvm_components) - // We for sure don't want these tests to run in parallel, so make - // sure they don't have access to these vars if we run via `make` - // at the top level - .env_remove("MAKEFLAGS") - .env_remove("MFLAGS") - .env_remove("CARGO_MAKEFLAGS"); - - if let Some(ref cargo) = self.config.cargo_path { - cmd.env("CARGO", cwd.join(cargo)); - } - - if let Some(ref rustdoc) = self.config.rustdoc_path { - cmd.env("RUSTDOC", cwd.join(rustdoc)); - } - - if let Some(ref node) = self.config.nodejs { - cmd.env("NODE", node); - } - - if let Some(ref linker) = self.config.target_linker { - cmd.env("RUSTC_LINKER", linker); - } - - if let Some(ref clang) = self.config.run_clang_based_tests_with { - cmd.env("CLANG", clang); - } - - if let Some(ref filecheck) = self.config.llvm_filecheck { - cmd.env("LLVM_FILECHECK", filecheck); - } - - if let Some(ref llvm_bin_dir) = self.config.llvm_bin_dir { - cmd.env("LLVM_BIN_DIR", llvm_bin_dir); - } - - if let Some(ref remote_test_client) = self.config.remote_test_client { - cmd.env("REMOTE_TEST_CLIENT", remote_test_client); - } - - // We don't want RUSTFLAGS set from the outside to interfere with - // compiler flags set in the test cases: - cmd.env_remove("RUSTFLAGS"); - - // Use dynamic musl for tests because static doesn't allow creating dylibs - if self.config.host.contains("musl") { - cmd.env("RUSTFLAGS", "-Ctarget-feature=-crt-static").env("IS_MUSL_HOST", "1"); - } - - if self.config.bless { - cmd.env("RUSTC_BLESS_TEST", "--bless"); - // Assume this option is active if the environment variable is "defined", with _any_ value. - // As an example, a `Makefile` can use this option by: - // - // ifdef RUSTC_BLESS_TEST - // cp "$(TMPDIR)"/actual_something.ext expected_something.ext - // else - // $(DIFF) expected_something.ext "$(TMPDIR)"/actual_something.ext - // endif - } - - if self.config.target.contains("msvc") && !self.config.cc.is_empty() { - // We need to pass a path to `lib.exe`, so assume that `cc` is `cl.exe` - // and that `lib.exe` lives next to it. - let lib = Path::new(&self.config.cc).parent().unwrap().join("lib.exe"); - - // MSYS doesn't like passing flags of the form `/foo` as it thinks it's - // a path and instead passes `C:\msys64\foo`, so convert all - // `/`-arguments to MSVC here to `-` arguments. - let cflags = self - .config - .cflags - .split(' ') - .map(|s| s.replace("/", "-")) - .collect::>() - .join(" "); - let cxxflags = self - .config - .cxxflags - .split(' ') - .map(|s| s.replace("/", "-")) - .collect::>() - .join(" "); - - cmd.env("IS_MSVC", "1") - .env("IS_WINDOWS", "1") - .env("MSVC_LIB", format!("'{}' -nologo", lib.display())) - .env("MSVC_LIB_PATH", format!("{}", lib.display())) - .env("CC", format!("'{}' {}", self.config.cc, cflags)) - .env("CXX", format!("'{}' {}", &self.config.cxx, cxxflags)); - } else { - cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags)) - .env("CXX", format!("{} {}", self.config.cxx, self.config.cxxflags)) - .env("AR", &self.config.ar); - - if self.config.target.contains("windows") { - cmd.env("IS_WINDOWS", "1"); - } - } - - let (output, truncated) = - self.read2_abbreviated(cmd.spawn().expect("failed to spawn `make`")); - if !output.status.success() { - let res = ProcRes { - status: output.status, - stdout: String::from_utf8_lossy(&output.stdout).into_owned(), - stderr: String::from_utf8_lossy(&output.stderr).into_owned(), - truncated, - cmdline: format!("{:?}", cmd), - }; - self.fatal_proc_rec("make failed", &res); - } - } - - fn run_rmake_v2_test(&self) { // For `run-make` V2, we need to perform 2 steps to build and run a `run-make` V2 recipe // (`rmake.rs`) to run the actual tests. The support library is already built as a tool rust // library and is available under `build/$TARGET/stageN-tools-bin/librun_make_support.rlib`. @@ -191,8 +29,6 @@ impl TestCx<'_> { // recipes to `remove_dir_all($TMPDIR)` without running into issues related trying to remove // a currently running executable because the recipe executable is not under the // `rmake_out/` directory. - // - // This setup intentionally diverges from legacy Makefile run-make tests. let base_dir = self.output_base_dir(); ignore_not_found(|| recursive_remove(&base_dir)).unwrap(); From 413b824e5b41180b1503a081daf8f23927678add Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 5 Feb 2025 21:43:20 +0800 Subject: [PATCH 12/35] run-make: remove `tools.mk` It has served us well, but it's time to retire the `Makefile` support file since this is no longer needed. --- tests/run-make/tools.mk | 209 ---------------------------------------- 1 file changed, 209 deletions(-) delete mode 100644 tests/run-make/tools.mk diff --git a/tests/run-make/tools.mk b/tests/run-make/tools.mk deleted file mode 100644 index b1e872a202af5..0000000000000 --- a/tests/run-make/tools.mk +++ /dev/null @@ -1,209 +0,0 @@ -# These deliberately use `=` and not `:=` so that client makefiles can -# augment HOST_RPATH_DIR / TARGET_RPATH_DIR. -HOST_RPATH_ENV = \ - $(LD_LIB_PATH_ENVVAR)="$(TMPDIR):$(HOST_RPATH_DIR):$($(LD_LIB_PATH_ENVVAR))" -TARGET_RPATH_ENV = \ - $(LD_LIB_PATH_ENVVAR)="$(TMPDIR):$(TARGET_RPATH_DIR):$($(LD_LIB_PATH_ENVVAR))" - -RUSTC_ORIGINAL := $(RUSTC) -BARE_RUSTC := $(HOST_RPATH_ENV) '$(RUSTC)' -BARE_RUSTDOC := $(HOST_RPATH_ENV) '$(RUSTDOC)' -RUSTC := $(BARE_RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR) $(RUSTFLAGS) -Ainternal_features -RUSTDOC := $(BARE_RUSTDOC) -L $(TARGET_RPATH_DIR) -ifdef RUSTC_LINKER -RUSTC := $(RUSTC) -Clinker='$(RUSTC_LINKER)' -RUSTDOC := $(RUSTDOC) -Clinker='$(RUSTC_LINKER)' -endif -#CC := $(CC) -L $(TMPDIR) -HTMLDOCCK := '$(PYTHON)' '$(S)/src/etc/htmldocck.py' -CGREP := "$(S)/src/etc/cat-and-grep.sh" - -# diff with common flags for multi-platform diffs against text output -DIFF := diff -u --strip-trailing-cr - -# With RUSTC_TEST_OP you can elegantly support blessing of run-make tests. Do -# like this in a Makefile recipe: -# -# "$(TMPDIR)"/your-test > "$(TMPDIR)"/your-test.run.stdout -# $(RUSTC_TEST_OP) "$(TMPDIR)"/your-test.run.stdout your-test.run.stdout -# -# When running the test normally with -# -# ./x test tests/run-make/your-test -# -# the actual output will be diffed against the expected output. When running in -# bless-mode with -# -# ./x test --bless tests/run-make/your-test -# -# the actual output will be blessed as the expected output. -ifdef RUSTC_BLESS_TEST - RUSTC_TEST_OP = cp -else - RUSTC_TEST_OP = $(DIFF) -endif - -# Some of the Rust CI platforms use `/bin/dash` to run `shell` script in -# Makefiles. Other platforms, including many developer platforms, default to -# `/bin/bash`. (In many cases, `make` is actually using `/bin/sh`, but `sh` -# is configured to execute one or the other shell binary). `dash` features -# support only a small subset of `bash` features, so `dash` can be thought of as -# the lowest common denominator, and tests should be validated against `dash` -# whenever possible. Most developer platforms include `/bin/dash`, but to ensure -# tests still work when `/bin/dash`, if not available, this `SHELL` override is -# conditional: -ifndef IS_WINDOWS # dash interprets backslashes in executable paths incorrectly -ifneq (,$(wildcard /bin/dash)) -SHELL := /bin/dash -endif -endif - -# This is the name of the binary we will generate and run; use this -# e.g. for `$(CC) -o $(RUN_BINFILE)`. -RUN_BINFILE = $(TMPDIR)/$(1) - -# Invoke the generated binary on the remote machine if compiletest was -# configured to use a remote test device, otherwise run it on the current host. -ifdef REMOTE_TEST_CLIENT -# FIXME: if a test requires additional files, this will need to be changed to -# also push them (by changing the 0 to the number of additional files, and -# providing the path of the additional files as the last arguments). -EXECUTE = $(REMOTE_TEST_CLIENT) run 0 $(RUN_BINFILE) -else -EXECUTE = $(RUN_BINFILE) -endif - -# RUN and FAIL are basic way we will invoke the generated binary. On -# non-windows platforms, they set the LD_LIBRARY_PATH environment -# variable before running the binary. - -RLIB_GLOB = lib$(1)*.rlib -BIN = $(1) - -UNAME = $(shell uname) - -ifeq ($(UNAME),Darwin) -RUN = $(TARGET_RPATH_ENV) $(EXECUTE) -FAIL = $(TARGET_RPATH_ENV) $(EXECUTE) && exit 1 || exit 0 -DYLIB_GLOB = lib$(1)*.dylib -DYLIB = $(TMPDIR)/lib$(1).dylib -STATICLIB = $(TMPDIR)/lib$(1).a -STATICLIB_GLOB = lib$(1)*.a -else -ifdef IS_WINDOWS -RUN = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(EXECUTE) -FAIL = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(EXECUTE) && exit 1 || exit 0 -DYLIB_GLOB = $(1)*.dll -DYLIB = $(TMPDIR)/$(1).dll -ifdef IS_MSVC -STATICLIB = $(TMPDIR)/$(1).lib -STATICLIB_GLOB = $(1)*.lib -else -IMPLIB = $(TMPDIR)/lib$(1).dll.a -STATICLIB = $(TMPDIR)/lib$(1).a -STATICLIB_GLOB = lib$(1)*.a -endif -BIN = $(1).exe -LLVM_FILECHECK := $(shell cygpath -u "$(LLVM_FILECHECK)") -else -RUN = $(TARGET_RPATH_ENV) $(EXECUTE) -FAIL = $(TARGET_RPATH_ENV) $(EXECUTE) && exit 1 || exit 0 -DYLIB_GLOB = lib$(1)*.so -DYLIB = $(TMPDIR)/lib$(1).so -STATICLIB = $(TMPDIR)/lib$(1).a -STATICLIB_GLOB = lib$(1)*.a -endif -endif - -ifdef IS_MSVC -COMPILE_OBJ = $(CC) -c -Fo:`cygpath -w $(1)` $(2) -COMPILE_OBJ_CXX = $(CXX) -EHs -c -Fo:`cygpath -w $(1)` $(2) -NATIVE_STATICLIB_FILE = $(1).lib -NATIVE_STATICLIB = $(TMPDIR)/$(call NATIVE_STATICLIB_FILE,$(1)) -OUT_EXE=-Fe:`cygpath -w $(TMPDIR)/$(call BIN,$(1))` \ - -Fo:`cygpath -w $(TMPDIR)/$(1).obj` -else -COMPILE_OBJ = $(CC) -v -c -o $(1) $(2) -COMPILE_OBJ_CXX = $(CXX) -c -o $(1) $(2) -NATIVE_STATICLIB_FILE = lib$(1).a -NATIVE_STATICLIB = $(call STATICLIB,$(1)) -OUT_EXE=-o $(TMPDIR)/$(1) -endif - - -# Extra flags needed to compile a working executable with the standard library -ifdef IS_WINDOWS -ifdef IS_MSVC - EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib bcrypt.lib ntdll.lib synchronization.lib -else - EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt -lntdll -lsynchronization - EXTRACXXFLAGS := -lstdc++ - # So this is a bit hacky: we can't use the DLL version of libstdc++ because - # it pulls in the DLL version of libgcc, which means that we end up with 2 - # instances of the DW2 unwinding implementation. This is a problem on - # i686-pc-windows-gnu because each module (DLL/EXE) needs to register its - # unwind information with the unwinding implementation, and libstdc++'s - # __cxa_throw won't see the unwinding info we registered with our statically - # linked libgcc. - # - # Now, simply statically linking libstdc++ would fix this problem, except - # that it is compiled with the expectation that pthreads is dynamically - # linked as a DLL and will fail to link with a statically linked libpthread. - # - # So we end up with the following hack: we link use static:-bundle to only - # link the parts of libstdc++ that we actually use, which doesn't include - # the dependency on the pthreads DLL. - EXTRARSCXXFLAGS := -l static:-bundle=stdc++ -endif -else -ifeq ($(UNAME),Darwin) - EXTRACFLAGS := -lresolv - EXTRACXXFLAGS := -lc++ - EXTRARSCXXFLAGS := -lc++ -else -ifeq ($(UNAME),FreeBSD) - EXTRACFLAGS := -lm -lpthread -lgcc_s -else -ifeq ($(UNAME),SunOS) - EXTRACFLAGS := -lm -lpthread -lposix4 -lsocket -lresolv -else -ifeq ($(UNAME),OpenBSD) - EXTRACFLAGS := -lm -lpthread -lc++abi - RUSTC := $(RUSTC) -C linker="$(word 1,$(CC:ccache=))" -else - EXTRACFLAGS := -lm -lrt -ldl -lpthread - EXTRACXXFLAGS := -lstdc++ - EXTRARSCXXFLAGS := -lstdc++ -endif -endif -endif -endif -endif - -REMOVE_DYLIBS = rm $(TMPDIR)/$(call DYLIB_GLOB,$(1)) -REMOVE_RLIBS = rm $(TMPDIR)/$(call RLIB_GLOB,$(1)) - -%.a: %.o - $(AR) crus $@ $< -ifdef IS_MSVC -%.lib: lib%.o - $(MSVC_LIB) -out:`cygpath -w $@` $< -else -%.lib: lib%.o - $(AR) crus $@ $< -endif -%.dylib: %.o - $(CC) -dynamiclib -Wl,-dylib -o $@ $< -%.so: %.o - $(CC) -o $@ $< -shared - -ifdef IS_MSVC -%.dll: lib%.o - $(CC) $< -link -dll -out:`cygpath -w $@` -else -%.dll: lib%.o - $(CC) -o $@ $< -shared -Wl,--out-implib=$@.a -endif - -$(TMPDIR)/lib%.o: %.c - $(call COMPILE_OBJ,$@,$<) From 9b17c98d766f98766494230e65a5ab39c8656d6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 5 Feb 2025 21:35:25 +0800 Subject: [PATCH 13/35] run-make: update test suite README --- tests/run-make/README.md | 36 +++++++----------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/tests/run-make/README.md b/tests/run-make/README.md index 4035990347389..5cdd2fdc523cf 100644 --- a/tests/run-make/README.md +++ b/tests/run-make/README.md @@ -1,32 +1,17 @@ # The `run-make` test suite -The `run-make` test suite contains tests which are the most flexible out of all -the [rust-lang/rust](https://github.com/rust-lang/rust) test suites. `run-make` -tests can basically contain arbitrary code, and are supported by the -[`run_make_support`] library. +The `run-make` test suite contains tests which are the most flexible out of all the [rust-lang/rust](https://github.com/rust-lang/rust) test suites. `run-make` tests can basically contain arbitrary code, and are supported by the [`run_make_support`] library. ## Infrastructure -There are two kinds of run-make tests: +A `run-make` test is a test recipe source file `rmake.rs` accompanied by its parent directory (e.g. `tests/run-make/foo/rmake.rs` is the `foo` `run-make` test). -1. The new `rmake.rs` version: this allows run-make tests to be written in Rust - (with `rmake.rs` as the main test file). -2. The legacy `Makefile` version: this is what run-make tests were written with - before support for `rmake.rs` was introduced. +The implementation for collecting and building the `rmake.rs` recipes are in [`src/tools/compiletest/src/runtest.rs`](../../src/tools/compiletest/src/runtest.rs), in `run_rmake_test`. -The implementation for collecting and building the `rmake.rs` recipes (or -`Makefile`s) are in -[`src/tools/compiletest/src/runtest.rs`](../../src/tools/compiletest/src/runtest.rs), -in `run_rmake_v2_test` and `run_rmake_legacy_test`. - -### Rust-based `run-make` tests: `rmake.rs` - -The setup for the `rmake.rs` version is a 3-stage process: +The setup for the `rmake.rs` can be summarized as a 3-stage process: 1. First, we build the [`run_make_support`] library in bootstrap as a tool lib. -2. Then, we compile the `rmake.rs` "recipe" linking the support library and its - dependencies in, and provide a bunch of env vars. We setup a directory - structure within `build//test/run-make/` +2. Then, we compile the `rmake.rs` "recipe" linking the support library and its dependencies in, and provide a bunch of env vars. We setup a directory structure within `build//test/run-make/` ``` / @@ -34,15 +19,8 @@ The setup for the `rmake.rs` version is a 3-stage process: rmake_out/ # sources from test sources copied over ``` - and copy non-`rmake.rs` input support files over to `rmake_out/`. The - support library is made available as an [*extern prelude*][extern_prelude]. -3. Finally, we run the recipe binary and set `rmake_out/` as the working - directory. + and copy non-`rmake.rs` input support files over to `rmake_out/`. The support library is made available as an [*extern prelude*][extern_prelude]. +3. Finally, we run the recipe binary and set `rmake_out/` as the working directory. [`run_make_support`]: ../../src/tools/run-make-support [extern_prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude - -### Formatting - -Note that files under `tests/` are not formatted by `./x fmt`, -use `rustfmt tests/path/to/file.rs` to format a specific file if desired. From ed168e7b2bd98b7f044938ab88b791cdee73d85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sun, 2 Mar 2025 05:21:23 +0800 Subject: [PATCH 14/35] run-make-support: remove outdated comments --- .../run-make-support/src/artifact_names.rs | 17 ------ .../src/external_deps/c_cxx_compiler/cc.rs | 11 ---- .../external_deps/c_cxx_compiler/extras.rs | 55 ------------------- .../src/external_deps/rustc.rs | 25 --------- 4 files changed, 108 deletions(-) diff --git a/src/tools/run-make-support/src/artifact_names.rs b/src/tools/run-make-support/src/artifact_names.rs index 0d7b5cb98388e..8968f831542e6 100644 --- a/src/tools/run-make-support/src/artifact_names.rs +++ b/src/tools/run-make-support/src/artifact_names.rs @@ -8,23 +8,6 @@ use crate::targets::is_msvc; /// Construct the static library name based on the target. #[must_use] pub fn static_lib_name(name: &str) -> String { - // See tools.mk (irrelevant lines omitted): - // - // ```makefile - // ifeq ($(UNAME),Darwin) - // STATICLIB = $(TMPDIR)/lib$(1).a - // else - // ifdef IS_WINDOWS - // ifdef IS_MSVC - // STATICLIB = $(TMPDIR)/$(1).lib - // else - // STATICLIB = $(TMPDIR)/lib$(1).a - // endif - // else - // STATICLIB = $(TMPDIR)/lib$(1).a - // endif - // endif - // ``` assert!(!name.contains(char::is_whitespace), "static library name cannot contain whitespace"); if is_msvc() { format!("{name}.lib") } else { format!("lib{name}.a") } diff --git a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs index becb91ae989cc..0e6d6ea6075d2 100644 --- a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs +++ b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs @@ -80,17 +80,6 @@ impl Cc { /// Specify `-o` or `-Fe`/`-Fo` depending on platform/compiler. pub fn out_exe(&mut self, name: &str) -> &mut Self { - // Ref: tools.mk (irrelevant lines omitted): - // - // ```makefile - // ifdef IS_MSVC - // OUT_EXE=-Fe:`cygpath -w $(TMPDIR)/$(call BIN,$(1))` \ - // -Fo:`cygpath -w $(TMPDIR)/$(1).obj` - // else - // OUT_EXE=-o $(TMPDIR)/$(1) - // endif - // ``` - let mut path = std::path::PathBuf::from(name); if is_msvc() { diff --git a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs index 49210d75e063f..ca6ab3275c4d6 100644 --- a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs +++ b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs @@ -2,36 +2,6 @@ use crate::{is_msvc, is_windows, uname}; /// `EXTRACFLAGS` pub fn extra_c_flags() -> Vec<&'static str> { - // Adapted from tools.mk (trimmed): - // - // ```makefile - // ifdef IS_WINDOWS - // ifdef IS_MSVC - // EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib bcrypt.lib ntdll.lib synchronization.lib - // else - // EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt -lntdll -lsynchronization - // endif - // else - // ifeq ($(UNAME),Darwin) - // EXTRACFLAGS := -lresolv - // else - // ifeq ($(UNAME),FreeBSD) - // EXTRACFLAGS := -lm -lpthread -lgcc_s - // else - // ifeq ($(UNAME),SunOS) - // EXTRACFLAGS := -lm -lpthread -lposix4 -lsocket -lresolv - // else - // ifeq ($(UNAME),OpenBSD) - // EXTRACFLAGS := -lm -lpthread -lc++abi - // else - // EXTRACFLAGS := -lm -lrt -ldl -lpthread - // endif - // endif - // endif - // endif - // endif - // ``` - if is_windows() { if is_msvc() { vec![ @@ -60,31 +30,6 @@ pub fn extra_c_flags() -> Vec<&'static str> { /// `EXTRACXXFLAGS` pub fn extra_cxx_flags() -> Vec<&'static str> { - // Adapted from tools.mk (trimmed): - // - // ```makefile - // ifdef IS_WINDOWS - // ifdef IS_MSVC - // else - // EXTRACXXFLAGS := -lstdc++ - // endif - // else - // ifeq ($(UNAME),Darwin) - // EXTRACXXFLAGS := -lc++ - // else - // ifeq ($(UNAME),FreeBSD) - // else - // ifeq ($(UNAME),SunOS) - // else - // ifeq ($(UNAME),OpenBSD) - // else - // EXTRACXXFLAGS := -lstdc++ - // endif - // endif - // endif - // endif - // endif - // ``` if is_windows() { if is_msvc() { vec![] } else { vec!["-lstdc++"] } } else { diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs index 710ba025830a8..07db42027f0ab 100644 --- a/src/tools/run-make-support/src/external_deps/rustc.rs +++ b/src/tools/run-make-support/src/external_deps/rustc.rs @@ -365,31 +365,6 @@ impl Rustc { /// `EXTRARSCXXFLAGS` pub fn extra_rs_cxx_flags(&mut self) -> &mut Self { - // Adapted from tools.mk (trimmed): - // - // ```makefile - // ifdef IS_WINDOWS - // ifdef IS_MSVC - // else - // EXTRARSCXXFLAGS := -lstatic:-bundle=stdc++ - // endif - // else - // ifeq ($(UNAME),Darwin) - // EXTRARSCXXFLAGS := -lc++ - // else - // ifeq ($(UNAME),FreeBSD) - // else - // ifeq ($(UNAME),SunOS) - // else - // ifeq ($(UNAME),OpenBSD) - // else - // EXTRARSCXXFLAGS := -lstdc++ - // endif - // endif - // endif - // endif - // endif - // ``` if is_windows() { // So this is a bit hacky: we can't use the DLL version of libstdc++ because // it pulls in the DLL version of libgcc, which means that we end up with 2 From efec638308362313fe8c7541cb8f10e6b9a7fe4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 5 Feb 2025 21:48:48 +0800 Subject: [PATCH 15/35] tidy: remove legacy `Makefile` checks --- .../tidy/src/allowed_run_make_makefiles.txt | 0 src/tools/tidy/src/lib.rs | 1 - src/tools/tidy/src/main.rs | 2 - src/tools/tidy/src/run_make_tests.rs | 104 ------------------ 4 files changed, 107 deletions(-) delete mode 100644 src/tools/tidy/src/allowed_run_make_makefiles.txt delete mode 100644 src/tools/tidy/src/run_make_tests.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 1e7eb82b83e98..9f6d563166e2b 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -79,7 +79,6 @@ pub(crate) mod iter_header; pub mod known_bug; pub mod mir_opt_tests; pub mod pal; -pub mod run_make_tests; pub mod rustdoc_css_themes; pub mod rustdoc_gui_tests; pub mod rustdoc_templates; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 13a558fea48ea..1d8514ef4c9c4 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -103,8 +103,6 @@ fn main() { check!(tests_revision_unpaired_stdout_stderr, &tests_path); check!(debug_artifacts, &tests_path); check!(ui_tests, &root_path, bless); - // FIXME(jieyouxu): remove this check once all run-make tests are ported over to rmake.rs. - check!(run_make_tests, &tests_path, &src_path, bless); check!(mir_opt_tests, &tests_path, bless); check!(rustdoc_gui_tests, &tests_path); check!(rustdoc_css_themes, &librustdoc_path); diff --git a/src/tools/tidy/src/run_make_tests.rs b/src/tools/tidy/src/run_make_tests.rs deleted file mode 100644 index 8d1767878378c..0000000000000 --- a/src/tools/tidy/src/run_make_tests.rs +++ /dev/null @@ -1,104 +0,0 @@ -//! Tidy check to ensure that no new Makefiles are added under `tests/run-make/`. - -use std::collections::BTreeSet; -use std::fs::File; -use std::io::Write; -use std::path::{Path, PathBuf}; - -pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) { - let mut is_sorted = true; - - let allowed_makefiles = { - let mut total_lines = 0; - let mut prev_line = ""; - let allowed_makefiles: BTreeSet<&str> = include_str!("allowed_run_make_makefiles.txt") - .lines() - .map(|line| { - total_lines += 1; - - if prev_line > line { - is_sorted = false; - } - - prev_line = line; - - line - }) - .collect(); - - if !is_sorted && !bless { - tidy_error!( - bad, - "`src/tools/tidy/src/allowed_run_make_makefiles.txt` is not in order, likely \ - because you modified it manually, please only update it with command \ - `x test tidy --bless`" - ); - } - if allowed_makefiles.len() != total_lines { - tidy_error!( - bad, - "`src/tools/tidy/src/allowed_run_make_makefiles.txt` contains duplicate entries, \ - likely because you modified it manually, please only update it with command \ - `x test tidy --bless`" - ); - } - - allowed_makefiles - }; - - let mut remaining_makefiles = allowed_makefiles.clone(); - - crate::walk::walk_no_read( - &[tests_path.join("run-make").as_ref()], - |_, _| false, - &mut |entry| { - if entry.file_type().map_or(true, |t| t.is_dir()) { - return; - } - - if entry.file_name().to_str().map_or(true, |f| f != "Makefile") { - return; - } - - let makefile_path = entry.path().strip_prefix(&tests_path).unwrap(); - let makefile_path = makefile_path.to_str().unwrap().replace('\\', "/"); - - if !remaining_makefiles.remove(makefile_path.as_str()) { - tidy_error!( - bad, - "found run-make Makefile not permitted in \ - `src/tools/tidy/src/allowed_run_make_makefiles.txt`, please write new run-make \ - tests with `rmake.rs` instead: {}", - entry.path().display() - ); - } - }, - ); - - // If there are any expected Makefiles remaining, they were moved or deleted. - // Our data must remain up to date, so they must be removed from - // `src/tools/tidy/src/allowed_run_make_makefiles.txt`. - // This can be done automatically on --bless, or else a tidy error will be issued. - if bless && (!remaining_makefiles.is_empty() || !is_sorted) { - let tidy_src = src_path.join("tools").join("tidy").join("src"); - let org_file_path = tidy_src.join("allowed_run_make_makefiles.txt"); - let temp_file_path = tidy_src.join("blessed_allowed_run_make_makefiles.txt"); - let mut temp_file = t!(File::create_new(&temp_file_path)); - for file in allowed_makefiles.difference(&remaining_makefiles) { - t!(writeln!(temp_file, "{file}")); - } - t!(std::fs::rename(&temp_file_path, &org_file_path)); - } else { - for file in remaining_makefiles { - let mut p = PathBuf::from(tests_path); - p.push(file); - tidy_error!( - bad, - "Makefile `{}` no longer exists and should be removed from the exclusions in \ - `src/tools/tidy/src/allowed_run_make_makefiles.txt`, you can run `x test tidy --bless` to update \ - the allow list", - p.display() - ); - } - } -} From b0d6a8426caf94ed0f822208a55270776149a576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 5 Feb 2025 21:40:57 +0800 Subject: [PATCH 16/35] rustc-dev-guide: remove mentions of legacy `Makefile` run-make infra And remove outdated requirements to run `run-make` tests on Windows. --- .../rustc-dev-guide/src/tests/compiletest.md | 30 +------------------ .../rustc-dev-guide/src/tests/directives.md | 7 +---- src/doc/rustc-dev-guide/src/tests/running.md | 25 ---------------- 3 files changed, 2 insertions(+), 60 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index 459c082906eba..2905e470fabd3 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -74,8 +74,7 @@ The following test suites are available, with links for more information: ### General purpose test suite -[`run-make`](#run-make-tests) are general purpose tests using Rust programs (or -Makefiles (legacy)). +[`run-make`](#run-make-tests) are general purpose tests using Rust programs. ### Rustdoc test suites @@ -396,14 +395,6 @@ your test, causing separate files to be generated for 32bit and 64bit systems. ### `run-make` tests -> **Note on phasing out `Makefile`s** -> -> We are planning to migrate all existing Makefile-based `run-make` tests -> to Rust programs. You should not be adding new Makefile-based `run-make` -> tests. -> -> See . - The tests in [`tests/run-make`] are general-purpose tests using Rust *recipes*, which are small programs (`rmake.rs`) allowing arbitrary Rust code such as `rustc` invocations, and is supported by a [`run_make_support`] library. Using @@ -424,11 +415,6 @@ Compiletest directives like `//@ only-` or `//@ ignore-` are supported in `rmake.rs`, like in UI tests. However, revisions or building auxiliary via directives are not currently supported. -Two `run-make` tests are ported over to Rust recipes as examples: - -- -- - #### Quickly check if `rmake.rs` tests can be compiled You can quickly check if `rmake.rs` tests can be compiled without having to @@ -481,20 +467,6 @@ Then add a corresponding entry to `"rust-analyzer.linkedProjects"` ], ``` -#### Using Makefiles (legacy) - -
-You should avoid writing new Makefile-based `run-make` tests. -
- -Each test should be in a separate directory with a `Makefile` indicating the -commands to run. - -There is a [`tools.mk`] Makefile which you can include which provides a bunch of -utilities to make it easier to run commands and compare outputs. Take a look at -some of the other tests for some examples on how to get started. - -[`tools.mk`]: https://github.com/rust-lang/rust/blob/master/tests/run-make/tools.mk [`tests/run-make`]: https://github.com/rust-lang/rust/tree/master/tests/run-make [`run_make_support`]: https://github.com/rust-lang/rust/tree/master/src/tools/run-make-support diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index 00bb2bc4dbb1e..c72c7d7d87eb2 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -6,10 +6,7 @@ FIXME(jieyouxu) completely revise this chapter. --> -Directives are special comments that tell compiletest how to build and interpret -a test. They must appear before the Rust source in the test. They may also -appear in `rmake.rs` or legacy Makefiles for [run-make -tests](compiletest.md#run-make-tests). +Directives are special comments that tell compiletest how to build and interpret a test. They must appear before the Rust source in the test. They may also appear in `rmake.rs` [run-make tests](compiletest.md#run-make-tests). They are normally put after the short comment that explains the point of this test. Compiletest test suites use `//@` to signal that a comment is a directive. @@ -221,8 +218,6 @@ The following directives will check LLVM support: [`aarch64-gnu-debug`]), which only runs a subset of `run-make` tests. Other tests with this directive will not run at all, which is usually not what you want. - - Notably, the [`aarch64-gnu-debug`] CI job *currently* only runs `run-make` - tests which additionally contain `clang` in their test name. See also [Debuginfo tests](compiletest.md#debuginfo-tests) for directives for ignoring debuggers. diff --git a/src/doc/rustc-dev-guide/src/tests/running.md b/src/doc/rustc-dev-guide/src/tests/running.md index 6ce65092389bd..9ddf0afee0c77 100644 --- a/src/doc/rustc-dev-guide/src/tests/running.md +++ b/src/doc/rustc-dev-guide/src/tests/running.md @@ -238,30 +238,6 @@ This is much faster, but doesn't always work. For example, some tests include directives that specify specific compiler flags, or which rely on other crates, and they may not run the same without those options. -## Running `run-make` tests - -### Windows - -Running the `run-make` test suite on Windows is a currently bit more involved. -There are numerous prerequisites and environmental requirements: - -- Install msys2: -- Specify `MSYS2_PATH_TYPE=inherit` in `msys2.ini` in the msys2 installation directory, run the - following with `MSYS2 MSYS`: - - `pacman -Syuu` - - `pacman -S make` - - `pacman -S diffutils` - - `pacman -S binutils` - - `./x test run-make` (`./x test tests/run-make` doesn't work) - -There is [on-going work][port-run-make] to not rely on `Makefile`s in the -run-make test suite. Once this work is completed, you can run the entire -`run-make` test suite on native Windows inside `cmd` or `PowerShell` without -needing to install and use MSYS2. As of Oct 2024, it is -already possible to run the vast majority of the `run-make` test suite outside -of MSYS2, but there will be failures for the tests that still use `Makefile`s -due to not finding `make`. - ## Running tests on a remote machine Tests may be run on a remote machine (e.g. to test builds for a different @@ -406,4 +382,3 @@ If you encounter bugs or problems, don't hesitate to open issues on the repository](https://github.com/rust-lang/rustc_codegen_gcc/). [`tests/ui`]: https://github.com/rust-lang/rust/tree/master/tests/ui -[port-run-make]: https://github.com/rust-lang/rust/issues/121876 From 95b030f671bdc9652626a7a8490f42027973dfac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 5 Feb 2025 21:52:30 +0800 Subject: [PATCH 17/35] triagebot: stop backlinking to the test porting tracking issue No longer needed. --- triagebot.toml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index f9eb09ff34381..31683bc67e8de 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -834,13 +834,7 @@ message = "Some changes occurred in GUI tests." cc = ["@GuillaumeGomez"] [mentions."tests/run-make/"] -message = """ -This PR modifies `tests/run-make/`. If this PR is trying to port a Makefile -run-make test to use rmake.rs, please update the -[run-make port tracking issue](https://github.com/rust-lang/rust/issues/121876) -so we can track our progress. You can either modify the tracking issue -directly, or you can comment on the tracking issue and link this PR. -""" +message = "This PR modifies `run-make` tests." cc = ["@jieyouxu"] [mentions."src/rustdoc-json-types"] From 7e0a2fcb1b4c8026948212140d7d58b8ed87fa38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 11 Feb 2025 20:21:02 +0800 Subject: [PATCH 18/35] compiletest: change `TEST_BUILD_DIR` to maximally normalize This is to make test stderr insensitive to compare-mode / debugger that changes the test build dir output name. Previously, this normalized paths up to test-suite-specific build root, e.g. `/path/to/build/test/ui/`. Now, this normalizes up to test-specific build root, e.g. `/path/to/build/test/ui/subdir/$name.$revision.$mode.$debugger/`. --- src/tools/compiletest/src/runtest.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index f36d43b211fff..6e250ca12c937 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2412,8 +2412,9 @@ impl<'test> TestCx<'test> { let rust_src_dir = rust_src_dir.read_link().unwrap_or(rust_src_dir.to_path_buf()); normalize_path(&rust_src_dir.join("library"), "$SRC_DIR_REAL"); - // eg. /home/user/rust/build/x86_64-unknown-linux-gnu/test/ui - normalize_path(&self.config.build_test_suite_root, "$TEST_BUILD_DIR"); + // eg. + // /home/user/rust/build/x86_64-unknown-linux-gnu/test/ui//$name.$revision.$mode/ + normalize_path(&self.output_base_dir(), "$TEST_BUILD_DIR"); // eg. /home/user/rust/build normalize_path(&self.config.build_root, "$BUILD_DIR"); @@ -2434,6 +2435,18 @@ impl<'test> TestCx<'test> { .into_owned(); normalized = Self::normalize_platform_differences(&normalized); + + // Normalize long type name hash. + normalized = + static_regex!(r"\$TEST_BUILD_DIR/(?P[^\.]+).long-type-(?P\d+).txt") + .replace_all(&normalized, |caps: &Captures<'_>| { + format!( + "$TEST_BUILD_DIR/{filename}.long-type-$LONG_TYPE_HASH.txt", + filename = &caps["filename"] + ) + }) + .into_owned(); + normalized = normalized.replace("\t", "\\t"); // makes tabs visible // Remove test annotations like `//~ ERROR text` from the output, From 83429144fc43960368a25f0190d333f927805952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 11 Feb 2025 20:38:58 +0800 Subject: [PATCH 19/35] tests: remove explicit long type filename hash normalization from some ui tests --- tests/ui/diagnostic-width/E0271.ascii.stderr | 6 +++--- tests/ui/diagnostic-width/E0271.rs | 1 - tests/ui/diagnostic-width/E0271.unicode.stderr | 6 +++--- tests/ui/diagnostic-width/binop.rs | 2 -- tests/ui/diagnostic-width/binop.stderr | 8 ++++---- .../diagnostic-width/long-E0308.ascii.stderr | 16 ++++++++-------- tests/ui/diagnostic-width/long-E0308.rs | 3 --- .../diagnostic-width/long-E0308.unicode.stderr | 16 ++++++++-------- tests/ui/diagnostic-width/long-E0529.rs | 3 +-- tests/ui/diagnostic-width/long-E0529.stderr | 4 ++-- tests/ui/diagnostic-width/long-E0609.rs | 3 +-- tests/ui/diagnostic-width/long-E0609.stderr | 4 ++-- tests/ui/diagnostic-width/long-E0614.rs | 3 +-- tests/ui/diagnostic-width/long-E0614.stderr | 4 ++-- tests/ui/diagnostic-width/long-E0618.rs | 3 +-- tests/ui/diagnostic-width/long-E0618.stderr | 4 ++-- tests/ui/diagnostic-width/long-e0277.rs | 2 -- tests/ui/diagnostic-width/long-e0277.stderr | 8 ++++---- .../ui/diagnostic-width/non-copy-type-moved.rs | 2 -- .../non-copy-type-moved.stderr | 4 ++-- .../secondary-label-with-long-type.rs | 2 -- .../secondary-label-with-long-type.stderr | 4 ++-- tests/ui/error-codes/E0275.rs | 1 - tests/ui/error-codes/E0275.stderr | 4 ++-- .../trait-bounds/hang-on-deeply-nested-dyn.rs | 2 -- .../hang-on-deeply-nested-dyn.stderr | 2 +- .../trait-bounds/hrtb-doesnt-borrow-self-1.rs | 2 -- .../hrtb-doesnt-borrow-self-1.stderr | 14 +++++++------- .../trait-bounds/hrtb-doesnt-borrow-self-2.rs | 2 -- .../hrtb-doesnt-borrow-self-2.stderr | 14 +++++++------- ...ite-instantiation-struct-tail-ice-114484.rs | 3 --- ...instantiation-struct-tail-ice-114484.stderr | 10 +++++----- tests/ui/infinite/infinite-instantiation.rs | 2 -- .../ui/infinite/infinite-instantiation.stderr | 6 +++--- tests/ui/issues/issue-20413.rs | 1 - tests/ui/issues/issue-20413.stderr | 18 +++++++++--------- .../issue-37311.rs | 2 -- .../issue-37311.stderr | 6 +++--- tests/ui/issues/issue-67552.rs | 2 -- tests/ui/issues/issue-67552.stderr | 6 +++--- tests/ui/issues/issue-8727.rs | 2 -- tests/ui/issues/issue-8727.stderr | 8 ++++---- tests/ui/methods/inherent-bound-in-probe.rs | 2 -- .../ui/methods/inherent-bound-in-probe.stderr | 8 ++++---- tests/ui/recursion/issue-23122-2.rs | 1 - tests/ui/recursion/issue-23122-2.stderr | 4 ++-- tests/ui/recursion/issue-83150.rs | 3 +-- tests/ui/recursion/issue-83150.stderr | 8 ++++---- tests/ui/recursion/recursion.rs | 2 -- tests/ui/recursion/recursion.stderr | 6 +++--- tests/ui/regions/issue-102374.rs | 1 - tests/ui/regions/issue-102374.stderr | 2 +- tests/ui/traits/on_unimplemented_long_types.rs | 2 -- .../traits/on_unimplemented_long_types.stderr | 4 ++-- tests/ui/type_length_limit.rs | 3 --- tests/ui/type_length_limit.stderr | 4 ++-- 56 files changed, 109 insertions(+), 156 deletions(-) diff --git a/tests/ui/diagnostic-width/E0271.ascii.stderr b/tests/ui/diagnostic-width/E0271.ascii.stderr index 9a9c12a938f68..ad5f53e44beab 100644 --- a/tests/ui/diagnostic-width/E0271.ascii.stderr +++ b/tests/ui/diagnostic-width/E0271.ascii.stderr @@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving ` as Future>::Error == Foo` - --> $DIR/E0271.rs:20:5 + --> $DIR/E0271.rs:19:5 | LL | / Box::new( LL | | Ok::<_, ()>( @@ -10,12 +10,12 @@ LL | | ) | |_____^ type mismatch resolving ` as Future>::Error == Foo` | note: expected this to be `Foo` - --> $DIR/E0271.rs:10:18 + --> $DIR/E0271.rs:9:18 | LL | type Error = E; | ^ = note: required for the cast from `Box>` to `Box<...>` - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/E0271.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/E0271.rs b/tests/ui/diagnostic-width/E0271.rs index 0618772104143..522bfb5b93fee 100644 --- a/tests/ui/diagnostic-width/E0271.rs +++ b/tests/ui/diagnostic-width/E0271.rs @@ -1,7 +1,6 @@ //@ revisions: ascii unicode //@[ascii] compile-flags: --diagnostic-width=40 -Zwrite-long-types-to-disk=yes //@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40 -Zwrite-long-types-to-disk=yes -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" trait Future { type Error; } diff --git a/tests/ui/diagnostic-width/E0271.unicode.stderr b/tests/ui/diagnostic-width/E0271.unicode.stderr index 9c3deae66608c..91adf83410163 100644 --- a/tests/ui/diagnostic-width/E0271.unicode.stderr +++ b/tests/ui/diagnostic-width/E0271.unicode.stderr @@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving ` as Future>::Error == Foo` - ╭▸ $DIR/E0271.rs:20:5 + ╭▸ $DIR/E0271.rs:19:5 │ LL │ ┏ Box::new( LL │ ┃ Ok::<_, ()>( @@ -10,12 +10,12 @@ LL │ ┃ ) │ ┗━━━━━┛ type mismatch resolving ` as Future>::Error == Foo` ╰╴ note: expected this to be `Foo` - ╭▸ $DIR/E0271.rs:10:18 + ╭▸ $DIR/E0271.rs:9:18 │ LL │ type Error = E; │ ━ ├ note: required for the cast from `Box>` to `Box<...>` - ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/E0271.long-type-$LONG_TYPE_HASH.txt' ╰ note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/binop.rs b/tests/ui/diagnostic-width/binop.rs index 60ba40b8047f9..9e4e837f38698 100644 --- a/tests/ui/diagnostic-width/binop.rs +++ b/tests/ui/diagnostic-width/binop.rs @@ -1,6 +1,4 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" type A = (i32, i32, i32, i32); type B = (A, A, A, A); type C = (B, B, B, B); diff --git a/tests/ui/diagnostic-width/binop.stderr b/tests/ui/diagnostic-width/binop.stderr index fd69129c33e44..92723df5a9b35 100644 --- a/tests/ui/diagnostic-width/binop.stderr +++ b/tests/ui/diagnostic-width/binop.stderr @@ -1,21 +1,21 @@ error[E0369]: cannot add `(..., ..., ..., ...)` to `(..., ..., ..., ...)` - --> $DIR/binop.rs:10:7 + --> $DIR/binop.rs:8:7 | LL | x + x; | - ^ - (..., ..., ..., ...) | | | (..., ..., ..., ...) | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/binop.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error[E0600]: cannot apply unary operator `!` to type `(..., ..., ..., ...)` - --> $DIR/binop.rs:14:5 + --> $DIR/binop.rs:12:5 | LL | !x; | ^^ cannot apply unary operator `!` | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/binop.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 2 previous errors diff --git a/tests/ui/diagnostic-width/long-E0308.ascii.stderr b/tests/ui/diagnostic-width/long-E0308.ascii.stderr index 83da558618870..d1fdd6c443352 100644 --- a/tests/ui/diagnostic-width/long-E0308.ascii.stderr +++ b/tests/ui/diagnostic-width/long-E0308.ascii.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/long-E0308.rs:48:9 + --> $DIR/long-E0308.rs:45:9 | LL | let x: Atype< | _____________- @@ -20,11 +20,11 @@ LL | | )))))))))))))))))))))))))))))); | = note: expected struct `Atype, i32>` found enum `Result, _>` - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - --> $DIR/long-E0308.rs:61:26 + --> $DIR/long-E0308.rs:58:26 | LL | ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O... | __________________________^ @@ -36,11 +36,11 @@ LL | | )))))))))))))))))))))))); | = note: expected enum `Option, _>>` found enum `Result, _>` - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - --> $DIR/long-E0308.rs:92:9 + --> $DIR/long-E0308.rs:89:9 | LL | let x: Atype< | ____________- @@ -56,11 +56,11 @@ LL | | > = (); | = note: expected struct `Atype, i32>` found unit type `()` - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - --> $DIR/long-E0308.rs:95:17 + --> $DIR/long-E0308.rs:92:17 | LL | let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O... | ____________--___^ @@ -74,7 +74,7 @@ LL | | )))))))))))))))))))))))); | = note: expected unit type `()` found enum `Result, _>` - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 4 previous errors diff --git a/tests/ui/diagnostic-width/long-E0308.rs b/tests/ui/diagnostic-width/long-E0308.rs index 26383d9418dd8..94e525e387efb 100644 --- a/tests/ui/diagnostic-width/long-E0308.rs +++ b/tests/ui/diagnostic-width/long-E0308.rs @@ -2,9 +2,6 @@ //@[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 -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" - mod a { // Force the "short path for unique types" machinery to trip up pub struct Atype; diff --git a/tests/ui/diagnostic-width/long-E0308.unicode.stderr b/tests/ui/diagnostic-width/long-E0308.unicode.stderr index 54abf576dbd07..69e5ca100671e 100644 --- a/tests/ui/diagnostic-width/long-E0308.unicode.stderr +++ b/tests/ui/diagnostic-width/long-E0308.unicode.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - ╭▸ $DIR/long-E0308.rs:48:9 + ╭▸ $DIR/long-E0308.rs:45:9 │ LL │ let x: Atype< │ ┌─────────────┘ @@ -20,11 +20,11 @@ LL │ ┃ )))))))))))))))))))))))))))))); │ ├ note: expected struct `Atype, i32>` │ found enum `Result, _>` - ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' ╰ note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - ╭▸ $DIR/long-E0308.rs:61:26 + ╭▸ $DIR/long-E0308.rs:58:26 │ LL │ ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(… │ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━┛ @@ -36,11 +36,11 @@ LL │ ┃ )))))))))))))))))))))))); │ ├ note: expected enum `Option, _>>` │ found enum `Result, _>` - ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' ╰ note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - ╭▸ $DIR/long-E0308.rs:92:9 + ╭▸ $DIR/long-E0308.rs:89:9 │ LL │ let x: Atype< │ ┌────────────┘ @@ -56,11 +56,11 @@ LL │ │ > = (); │ ├ note: expected struct `Atype, i32>` │ found unit type `()` - ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' ╰ note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types - ╭▸ $DIR/long-E0308.rs:95:17 + ╭▸ $DIR/long-E0308.rs:92:17 │ LL │ let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(… │ ┏━━━━━━━━━━━━┬─━━━┛ @@ -74,7 +74,7 @@ LL │ ┃ )))))))))))))))))))))))); │ ├ note: expected unit type `()` │ found enum `Result, _>` - ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' ╰ note: consider using `--verbose` to print the full type name to the console error: aborting due to 4 previous errors diff --git a/tests/ui/diagnostic-width/long-E0529.rs b/tests/ui/diagnostic-width/long-E0529.rs index 3ebc4f5f8c825..759a902da7e63 100644 --- a/tests/ui/diagnostic-width/long-E0529.rs +++ b/tests/ui/diagnostic-width/long-E0529.rs @@ -1,6 +1,5 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" + type A = (i32, i32, i32, i32); type B = (A, A, A, A); type C = (B, B, B, B); diff --git a/tests/ui/diagnostic-width/long-E0529.stderr b/tests/ui/diagnostic-width/long-E0529.stderr index da03e5fab2ca2..bf3144cc9b67b 100644 --- a/tests/ui/diagnostic-width/long-E0529.stderr +++ b/tests/ui/diagnostic-width/long-E0529.stderr @@ -1,10 +1,10 @@ error[E0529]: expected an array or slice, found `(..., ..., ..., ...)` - --> $DIR/long-E0529.rs:10:9 + --> $DIR/long-E0529.rs:9:9 | LL | let [] = x; | ^^ pattern cannot match with input type `(..., ..., ..., ...)` | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0529.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/long-E0609.rs b/tests/ui/diagnostic-width/long-E0609.rs index 39442bdeae03a..a26d16ad12e78 100644 --- a/tests/ui/diagnostic-width/long-E0609.rs +++ b/tests/ui/diagnostic-width/long-E0609.rs @@ -1,6 +1,5 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" + type A = (i32, i32, i32, i32); type B = (A, A, A, A); type C = (B, B, B, B); diff --git a/tests/ui/diagnostic-width/long-E0609.stderr b/tests/ui/diagnostic-width/long-E0609.stderr index 6815caa6b6ba1..36ef85457468e 100644 --- a/tests/ui/diagnostic-width/long-E0609.stderr +++ b/tests/ui/diagnostic-width/long-E0609.stderr @@ -1,10 +1,10 @@ error[E0609]: no field `field` on type `(..., ..., ..., ...)` - --> $DIR/long-E0609.rs:10:7 + --> $DIR/long-E0609.rs:9:7 | LL | x.field; | ^^^^^ unknown field | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0609.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/long-E0614.rs b/tests/ui/diagnostic-width/long-E0614.rs index 0b78444a00d24..5e8b3324dd17d 100644 --- a/tests/ui/diagnostic-width/long-E0614.rs +++ b/tests/ui/diagnostic-width/long-E0614.rs @@ -1,6 +1,5 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" + type A = (i32, i32, i32, i32); type B = (A, A, A, A); type C = (B, B, B, B); diff --git a/tests/ui/diagnostic-width/long-E0614.stderr b/tests/ui/diagnostic-width/long-E0614.stderr index 1c16ff617faa2..18da20da9453e 100644 --- a/tests/ui/diagnostic-width/long-E0614.stderr +++ b/tests/ui/diagnostic-width/long-E0614.stderr @@ -1,10 +1,10 @@ error[E0614]: type `(..., ..., ..., ...)` cannot be dereferenced - --> $DIR/long-E0614.rs:10:5 + --> $DIR/long-E0614.rs:9:5 | LL | *x; | ^^ can't be dereferenced | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0614.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/long-E0618.rs b/tests/ui/diagnostic-width/long-E0618.rs index f8626ab9455e2..b499bedc394a5 100644 --- a/tests/ui/diagnostic-width/long-E0618.rs +++ b/tests/ui/diagnostic-width/long-E0618.rs @@ -1,6 +1,5 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" + type A = (i32, i32, i32, i32); type B = (A, A, A, A); type C = (B, B, B, B); diff --git a/tests/ui/diagnostic-width/long-E0618.stderr b/tests/ui/diagnostic-width/long-E0618.stderr index f0838cbddcc64..05bf999c1422a 100644 --- a/tests/ui/diagnostic-width/long-E0618.stderr +++ b/tests/ui/diagnostic-width/long-E0618.stderr @@ -1,5 +1,5 @@ error[E0618]: expected function, found `(..., ..., ..., ...)` - --> $DIR/long-E0618.rs:10:5 + --> $DIR/long-E0618.rs:9:5 | LL | fn foo(x: D) { | - `x` has type `(..., ..., ..., ...)` @@ -8,7 +8,7 @@ LL | x(); | | | call expression requires function | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0618.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/long-e0277.rs b/tests/ui/diagnostic-width/long-e0277.rs index 9b3bd8bb72896..369fd8daea78c 100644 --- a/tests/ui/diagnostic-width/long-e0277.rs +++ b/tests/ui/diagnostic-width/long-e0277.rs @@ -1,6 +1,4 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" type A = (i32, i32, i32, i32); type B = (A, A, A, A); type C = (B, B, B, B); diff --git a/tests/ui/diagnostic-width/long-e0277.stderr b/tests/ui/diagnostic-width/long-e0277.stderr index a57270df7e252..ff8971511653c 100644 --- a/tests/ui/diagnostic-width/long-e0277.stderr +++ b/tests/ui/diagnostic-width/long-e0277.stderr @@ -1,21 +1,21 @@ error[E0277]: the trait bound `(..., ..., ..., ...): Trait` is not satisfied - --> $DIR/long-e0277.rs:14:21 + --> $DIR/long-e0277.rs:12:21 | LL | require_trait::(); | ^ unsatisfied trait bound | = help: the trait `Trait` is not implemented for `(..., ..., ..., ...)` help: this trait has no implementations, consider adding one - --> $DIR/long-e0277.rs:9:1 + --> $DIR/long-e0277.rs:7:1 | LL | trait Trait {} | ^^^^^^^^^^^ note: required by a bound in `require_trait` - --> $DIR/long-e0277.rs:11:21 + --> $DIR/long-e0277.rs:9:21 | LL | fn require_trait() {} | ^^^^^ required by this bound in `require_trait` - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-e0277.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/non-copy-type-moved.rs b/tests/ui/diagnostic-width/non-copy-type-moved.rs index a220c62775eb8..845457f7e30fb 100644 --- a/tests/ui/diagnostic-width/non-copy-type-moved.rs +++ b/tests/ui/diagnostic-width/non-copy-type-moved.rs @@ -1,6 +1,4 @@ //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" type A = (String, String, String, String); type B = (A, A, A, A); diff --git a/tests/ui/diagnostic-width/non-copy-type-moved.stderr b/tests/ui/diagnostic-width/non-copy-type-moved.stderr index 254542c7b3908..16c01c858b7d0 100644 --- a/tests/ui/diagnostic-width/non-copy-type-moved.stderr +++ b/tests/ui/diagnostic-width/non-copy-type-moved.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `x` - --> $DIR/non-copy-type-moved.rs:16:14 + --> $DIR/non-copy-type-moved.rs:14:14 | LL | fn foo(x: D) { | - move occurs because `x` has type `(..., ..., ..., ...)`, which does not implement the `Copy` trait @@ -8,7 +8,7 @@ LL | let _a = x; LL | let _b = x; | ^ value used here after move | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/non-copy-type-moved.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console help: consider cloning the value if the performance cost is acceptable | diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs index c8845af318357..13fe967ba5f8c 100644 --- a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs +++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs @@ -1,6 +1,4 @@ //@ compile-flags: --diagnostic-width=100 -Zwrite-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" type A = (i32, i32, i32, i32); type B = (A, A, A, A); diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr index a95e17091489e..a99657ca113ff 100644 --- a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr +++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/secondary-label-with-long-type.rs:11:9 + --> $DIR/secondary-label-with-long-type.rs:9:9 | LL | let () = x; | ^^ - this expression has type `((..., ..., ..., ...), ..., ..., ...)` @@ -8,7 +8,7 @@ LL | let () = x; | = note: expected tuple `((..., ..., ..., ...), ..., ..., ...)` found unit type `()` - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/secondary-label-with-long-type.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0275.rs b/tests/ui/error-codes/E0275.rs index df7b606155eb4..28a9676f03e39 100644 --- a/tests/ui/error-codes/E0275.rs +++ b/tests/ui/error-codes/E0275.rs @@ -1,4 +1,3 @@ -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" trait Foo {} struct Bar(T); diff --git a/tests/ui/error-codes/E0275.stderr b/tests/ui/error-codes/E0275.stderr index b507540834060..3b31c87320ae9 100644 --- a/tests/ui/error-codes/E0275.stderr +++ b/tests/ui/error-codes/E0275.stderr @@ -1,12 +1,12 @@ error[E0275]: overflow evaluating the requirement `Bar>>>>>>: Foo` - --> $DIR/E0275.rs:6:33 + --> $DIR/E0275.rs:5:33 | LL | impl Foo for T where Bar: Foo {} | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`) note: required for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo` - --> $DIR/E0275.rs:6:9 + --> $DIR/E0275.rs:5:9 | LL | impl Foo for T where Bar: Foo {} | ^^^ ^ --- unsatisfied trait bound introduced here 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 7b6ba9f7f1695..e22a49d039935 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,5 +1,3 @@ -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" - fn id( f: &dyn Fn(u32), ) -> &dyn Fn( diff --git a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr index be2eca3e61ad9..00a5948bdd472 100644 --- a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr +++ b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/hang-on-deeply-nested-dyn.rs:12:5 + --> $DIR/hang-on-deeply-nested-dyn.rs:10:5 | LL | ) -> &dyn Fn( | ______- 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 f880749ec8352..ff6f4861e1443 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,5 +1,3 @@ -//@ 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; // but an earlier buggy rustc allowed `.map(|x: &_| x)` which does diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr index ae364de8cc061..240e1c3dde1a1 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr @@ -1,5 +1,5 @@ -error[E0599]: the method `filterx` exists for struct `Map`, but its trait bounds were not satisfied - --> $DIR/hrtb-doesnt-borrow-self-1.rs:116:22 +error[E0599]: the method `filterx` exists for struct `Map`, but its trait bounds were not satisfied + --> $DIR/hrtb-doesnt-borrow-self-1.rs:114:22 | LL | pub struct Map { | -------------------- method `filterx` not found for this struct because it doesn't satisfy `_: StreamExt` @@ -8,16 +8,16 @@ LL | let filter = map.filterx(|x: &_| true); | ^^^^^^^ method cannot be called due to unsatisfied trait bounds | note: the following trait bounds were not satisfied: - `&'a mut &Map: Stream` - `&'a mut &mut Map: Stream` - `&'a mut Map: Stream` - --> $DIR/hrtb-doesnt-borrow-self-1.rs:98:50 + `&'a mut &Map: Stream` + `&'a mut &mut Map: Stream` + `&'a mut Map: Stream` + --> $DIR/hrtb-doesnt-borrow-self-1.rs:96:50 | LL | impl StreamExt for T where for<'a> &'a mut T: Stream {} | --------- - ^^^^^^ unsatisfied trait bound introduced here = help: items from traits can only be used if the trait is implemented and in scope note: `StreamExt` defines an item `filterx`, perhaps you need to implement it - --> $DIR/hrtb-doesnt-borrow-self-1.rs:66:1 + --> $DIR/hrtb-doesnt-borrow-self-1.rs:64:1 | LL | pub trait StreamExt | ^^^^^^^^^^^^^^^^^^^ 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 ff4c0cf24d69f..d8a1f3fa69e4b 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,5 +1,3 @@ -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" - // rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream &u64 {identity::}>, {closure@hrtb-doesnt-borrow-self-2.rs:111:30}>`, but its trait bounds were not satisfied - --> $DIR/hrtb-doesnt-borrow-self-2.rs:112:24 +error[E0599]: the method `countx` exists for struct `Filter &u64 {identity::}>, {closure@hrtb-doesnt-borrow-self-2.rs:109:30}>`, but its trait bounds were not satisfied + --> $DIR/hrtb-doesnt-borrow-self-2.rs:110:24 | LL | pub struct Filter { | ----------------------- method `countx` not found for this struct because it doesn't satisfy `_: StreamExt` @@ -8,16 +8,16 @@ LL | let count = filter.countx(); | ^^^^^^ method cannot be called due to unsatisfied trait bounds | note: the following trait bounds were not satisfied: - `&'a mut &Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:111:30: 111:37}>: Stream` - `&'a mut &mut Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:111:30: 111:37}>: Stream` - `&'a mut Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:111:30: 111:37}>: Stream` - --> $DIR/hrtb-doesnt-borrow-self-2.rs:98:50 + `&'a mut &Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:109:30: 109:37}>: Stream` + `&'a mut &mut Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:109:30: 109:37}>: Stream` + `&'a mut Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:109:30: 109:37}>: Stream` + --> $DIR/hrtb-doesnt-borrow-self-2.rs:96:50 | LL | impl StreamExt for T where for<'a> &'a mut T: Stream {} | --------- - ^^^^^^ unsatisfied trait bound introduced here = help: items from traits can only be used if the trait is implemented and in scope note: `StreamExt` defines an item `countx`, perhaps you need to implement it - --> $DIR/hrtb-doesnt-borrow-self-2.rs:66:1 + --> $DIR/hrtb-doesnt-borrow-self-2.rs:64:1 | LL | pub trait StreamExt | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs index 62fc079d9d974..e28b8f373dabb 100644 --- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs +++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs @@ -3,9 +3,6 @@ //@ error-pattern: reached the recursion limit while instantiating //@ error-pattern: reached the recursion limit finding the struct tail -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" - // Regression test for #114484: This used to ICE during monomorphization, because we treated // ` as Pointee>::Metadata` as a rigid projection after reaching the recursion // limit when finding the struct tail. diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr index b67e000bf74a8..475e26fd0f066 100644 --- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr +++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr @@ -18,7 +18,7 @@ error: reached the recursion limit finding the struct tail for `[u8; 256]` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: the above error was encountered while instantiating `fn virtualize_my_trait::, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>` - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:29:18 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18 | LL | unsafe { virtualize_my_trait(L, self) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,7 +43,7 @@ error: reached the recursion limit finding the struct tail for `SomeData<256>` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: the above error was encountered while instantiating `fn virtualize_my_trait::, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>` - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:29:18 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18 | LL | unsafe { virtualize_my_trait(L, self) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ error: reached the recursion limit finding the struct tail for `VirtualWrapper, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>` - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:29:18 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18 | LL | unsafe { virtualize_my_trait(L, self) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -76,11 +76,11 @@ LL | unsafe { virtualize_my_trait(L, self) } error: reached the recursion limit while instantiating `, 1>, 1>, 1>, 1> as MyTrait>::virtualize` | note: ` as MyTrait>::virtualize` defined here - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:28:5 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:25:5 | LL | fn virtualize(&self) -> &dyn MyTrait { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/infinite-instantiation-struct-tail-ice-114484.long-type.txt' error: aborting due to 13 previous errors diff --git a/tests/ui/infinite/infinite-instantiation.rs b/tests/ui/infinite/infinite-instantiation.rs index d5cb8e79592f1..7898cc1ffc106 100644 --- a/tests/ui/infinite/infinite-instantiation.rs +++ b/tests/ui/infinite/infinite-instantiation.rs @@ -1,6 +1,4 @@ //@ build-fail -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" trait ToOpt: Sized { fn to_option(&self) -> Option; diff --git a/tests/ui/infinite/infinite-instantiation.stderr b/tests/ui/infinite/infinite-instantiation.stderr index 71c745cf5eb8b..d7a4a49961a64 100644 --- a/tests/ui/infinite/infinite-instantiation.stderr +++ b/tests/ui/infinite/infinite-instantiation.stderr @@ -1,15 +1,15 @@ error: reached the recursion limit while instantiating `function::>>>>>` - --> $DIR/infinite-instantiation.rs:23:9 + --> $DIR/infinite-instantiation.rs:21:9 | LL | function(counter - 1, t.to_option()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `function` defined here - --> $DIR/infinite-instantiation.rs:21:1 + --> $DIR/infinite-instantiation.rs:19:1 | LL | fn function(counter: usize, t: T) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/infinite-instantiation.long-type.txt' error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-20413.rs b/tests/ui/issues/issue-20413.rs index 7766f3755993b..138a235e675e3 100644 --- a/tests/ui/issues/issue-20413.rs +++ b/tests/ui/issues/issue-20413.rs @@ -1,4 +1,3 @@ -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" trait Foo { fn answer(self); } diff --git a/tests/ui/issues/issue-20413.stderr b/tests/ui/issues/issue-20413.stderr index 5d442eb989851..42f3cd2d06274 100644 --- a/tests/ui/issues/issue-20413.stderr +++ b/tests/ui/issues/issue-20413.stderr @@ -1,5 +1,5 @@ error[E0392]: type parameter `T` is never used - --> $DIR/issue-20413.rs:6:15 + --> $DIR/issue-20413.rs:5:15 | LL | struct NoData; | ^ unused type parameter @@ -8,14 +8,14 @@ LL | struct NoData; = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead error[E0275]: overflow evaluating the requirement `NoData>>>>>>: Foo` - --> $DIR/issue-20413.rs:9:36 + --> $DIR/issue-20413.rs:8:36 | LL | impl Foo for T where NoData: Foo { | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) note: required for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo` - --> $DIR/issue-20413.rs:9:9 + --> $DIR/issue-20413.rs:8:9 | LL | impl Foo for T where NoData: Foo { | ^^^ ^ --- unsatisfied trait bound introduced here @@ -23,19 +23,19 @@ LL | impl Foo for T where NoData: Foo { = note: required for `NoData` to implement `Foo` error[E0275]: overflow evaluating the requirement `AlmostNoData>>>>>>: Bar` - --> $DIR/issue-20413.rs:28:42 + --> $DIR/issue-20413.rs:27:42 | LL | impl Bar for T where EvenLessData: Baz { | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) note: required for `EvenLessData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz` - --> $DIR/issue-20413.rs:35:9 + --> $DIR/issue-20413.rs:34:9 | LL | impl Baz for T where AlmostNoData: Bar { | ^^^ ^ --- unsatisfied trait bound introduced here note: required for `AlmostNoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar` - --> $DIR/issue-20413.rs:28:9 + --> $DIR/issue-20413.rs:27:9 | LL | impl Bar for T where EvenLessData: Baz { | ^^^ ^ --- unsatisfied trait bound introduced here @@ -43,19 +43,19 @@ LL | impl Bar for T where EvenLessData: Baz { = note: required for `EvenLessData` to implement `Baz` error[E0275]: overflow evaluating the requirement `EvenLessData>>>>>>: Baz` - --> $DIR/issue-20413.rs:35:42 + --> $DIR/issue-20413.rs:34:42 | LL | impl Baz for T where AlmostNoData: Bar { | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) note: required for `AlmostNoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar` - --> $DIR/issue-20413.rs:28:9 + --> $DIR/issue-20413.rs:27:9 | LL | impl Bar for T where EvenLessData: Baz { | ^^^ ^ --- unsatisfied trait bound introduced here note: required for `EvenLessData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz` - --> $DIR/issue-20413.rs:35:9 + --> $DIR/issue-20413.rs:34:9 | LL | impl Baz for T where AlmostNoData: Bar { | ^^^ ^ --- unsatisfied trait bound introduced here 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 ebaf244ac9c24..05adde4520442 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,6 +1,4 @@ //@ build-fail -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" trait Mirror { type Image; diff --git a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr index fbbf80021bee9..945fa605e140c 100644 --- a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr +++ b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr @@ -1,15 +1,15 @@ error: reached the recursion limit while instantiating `<(&(&(..., ...), ...), ...) as Foo>::recurse` - --> $DIR/issue-37311.rs:18:9 + --> $DIR/issue-37311.rs:16:9 | LL | (self, self).recurse(); | ^^^^^^^^^^^^^^^^^^^^^^ | note: `::recurse` defined here - --> $DIR/issue-37311.rs:17:5 + --> $DIR/issue-37311.rs:15:5 | LL | fn recurse(&self) { | ^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/issue-37311.long-type.txt' error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-67552.rs b/tests/ui/issues/issue-67552.rs index 8c7e95bd2e3e7..53f0e931d60bc 100644 --- a/tests/ui/issues/issue-67552.rs +++ b/tests/ui/issues/issue-67552.rs @@ -1,7 +1,5 @@ //@ build-fail //@ compile-flags: -Copt-level=0 -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" fn main() { rec(Empty); diff --git a/tests/ui/issues/issue-67552.stderr b/tests/ui/issues/issue-67552.stderr index f94cd78c87011..def0a29f3e51e 100644 --- a/tests/ui/issues/issue-67552.stderr +++ b/tests/ui/issues/issue-67552.stderr @@ -1,17 +1,17 @@ error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut ...>` - --> $DIR/issue-67552.rs:30:9 + --> $DIR/issue-67552.rs:28:9 | LL | rec(identity(&mut it)) | ^^^^^^^^^^^^^^^^^^^^^^ | note: `rec` defined here - --> $DIR/issue-67552.rs:23:1 + --> $DIR/issue-67552.rs:21:1 | LL | / fn rec(mut it: T) LL | | where LL | | T: Iterator, | |________________^ - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/issue-67552.long-type.txt' error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-8727.rs b/tests/ui/issues/issue-8727.rs index 7767729109eac..1883287f1407c 100644 --- a/tests/ui/issues/issue-8727.rs +++ b/tests/ui/issues/issue-8727.rs @@ -2,8 +2,6 @@ // recursions. //@ build-fail -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" fn generic() { //~ WARN function cannot return without recursing generic::>(); diff --git a/tests/ui/issues/issue-8727.stderr b/tests/ui/issues/issue-8727.stderr index 22286eb8d7be0..04158962a0101 100644 --- a/tests/ui/issues/issue-8727.stderr +++ b/tests/ui/issues/issue-8727.stderr @@ -1,5 +1,5 @@ warning: function cannot return without recursing - --> $DIR/issue-8727.rs:8:1 + --> $DIR/issue-8727.rs:6:1 | LL | fn generic() { | ^^^^^^^^^^^^^^^ cannot return without recursing @@ -10,17 +10,17 @@ LL | generic::>(); = note: `#[warn(unconditional_recursion)]` on by default error: reached the recursion limit while instantiating `generic::>>>>>` - --> $DIR/issue-8727.rs:9:5 + --> $DIR/issue-8727.rs:7:5 | LL | generic::>(); | ^^^^^^^^^^^^^^^^^^^^^^ | note: `generic` defined here - --> $DIR/issue-8727.rs:8:1 + --> $DIR/issue-8727.rs:6:1 | LL | fn generic() { | ^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/issue-8727.long-type.txt' error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/methods/inherent-bound-in-probe.rs b/tests/ui/methods/inherent-bound-in-probe.rs index 9b9eb91559b3a..4add93e808d22 100644 --- a/tests/ui/methods/inherent-bound-in-probe.rs +++ b/tests/ui/methods/inherent-bound-in-probe.rs @@ -1,5 +1,3 @@ -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" - // Fixes #110131 // // The issue is that we were constructing an `ImplDerived` cause code for the diff --git a/tests/ui/methods/inherent-bound-in-probe.stderr b/tests/ui/methods/inherent-bound-in-probe.stderr index 433ef02a2aa4c..77aed390c9ace 100644 --- a/tests/ui/methods/inherent-bound-in-probe.stderr +++ b/tests/ui/methods/inherent-bound-in-probe.stderr @@ -1,5 +1,5 @@ error[E0277]: `Helper<'a, T>` is not an iterator - --> $DIR/inherent-bound-in-probe.rs:40:21 + --> $DIR/inherent-bound-in-probe.rs:38:21 | LL | type IntoIter = Helper<'a, T>; | ^^^^^^^^^^^^^ `Helper<'a, T>` is not an iterator @@ -9,14 +9,14 @@ note: required by a bound in `std::iter::IntoIterator::IntoIter` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL error[E0275]: overflow evaluating the requirement `&_: IntoIterator` - --> $DIR/inherent-bound-in-probe.rs:44:9 + --> $DIR/inherent-bound-in-probe.rs:42:9 | LL | Helper::new(&self.0) | ^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_bound_in_probe`) note: required for `&BitReaderWrapper<_>` to implement `IntoIterator` - --> $DIR/inherent-bound-in-probe.rs:34:13 + --> $DIR/inherent-bound-in-probe.rs:32:13 | LL | impl<'a, T> IntoIterator for &'a BitReaderWrapper | ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | &'a T: IntoIterator, = note: 126 redundant requirements hidden = note: required for `&BitReaderWrapper>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `IntoIterator` note: required by a bound in `Helper` - --> $DIR/inherent-bound-in-probe.rs:18:12 + --> $DIR/inherent-bound-in-probe.rs:16:12 | LL | struct Helper<'a, T> | ------ required by a bound in this struct diff --git a/tests/ui/recursion/issue-23122-2.rs b/tests/ui/recursion/issue-23122-2.rs index 3e14fa92dd0f5..95e1f60d8b029 100644 --- a/tests/ui/recursion/issue-23122-2.rs +++ b/tests/ui/recursion/issue-23122-2.rs @@ -1,4 +1,3 @@ -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" trait Next { type Next: Next; } diff --git a/tests/ui/recursion/issue-23122-2.stderr b/tests/ui/recursion/issue-23122-2.stderr index 10463ab2c33fe..c5774cc188829 100644 --- a/tests/ui/recursion/issue-23122-2.stderr +++ b/tests/ui/recursion/issue-23122-2.stderr @@ -1,12 +1,12 @@ error[E0275]: overflow evaluating the requirement `<<<<<<<... as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized` - --> $DIR/issue-23122-2.rs:11:17 + --> $DIR/issue-23122-2.rs:10:17 | LL | type Next = as Next>::Next; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`) note: required for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next` - --> $DIR/issue-23122-2.rs:10:15 + --> $DIR/issue-23122-2.rs:9:15 | LL | impl Next for GetNext { | - ^^^^ ^^^^^^^^^^ diff --git a/tests/ui/recursion/issue-83150.rs b/tests/ui/recursion/issue-83150.rs index ea1bef4fce391..b720c168187b8 100644 --- a/tests/ui/recursion/issue-83150.rs +++ b/tests/ui/recursion/issue-83150.rs @@ -1,7 +1,6 @@ -//~ ERROR overflow evaluating the requirement `Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:13:24: 13:27}>: Iterator` +//~ ERROR overflow evaluating the requirement `Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: Iterator` //@ build-fail //@ compile-flags: -Copt-level=0 -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" fn main() { let mut iter = 0u8..1; diff --git a/tests/ui/recursion/issue-83150.stderr b/tests/ui/recursion/issue-83150.stderr index 92a39a44e4fa2..600922f1e57a7 100644 --- a/tests/ui/recursion/issue-83150.stderr +++ b/tests/ui/recursion/issue-83150.stderr @@ -1,5 +1,5 @@ warning: function cannot return without recursing - --> $DIR/issue-83150.rs:11:1 + --> $DIR/issue-83150.rs:10:1 | LL | fn func>(iter: &mut T) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing @@ -10,12 +10,12 @@ LL | func(&mut iter.map(|x| x + 1)) = help: a `loop` may express intention better if this is on purpose = note: `#[warn(unconditional_recursion)]` on by default -error[E0275]: overflow evaluating the requirement `Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:13:24: 13:27}>: Iterator` +error[E0275]: overflow evaluating the requirement `Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: Iterator` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`) - = note: required for `&mut Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:13:24: 13:27}>` to implement `Iterator` + = note: required for `&mut Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:12:24: 12:27}>` to implement `Iterator` = note: 65 redundant requirements hidden - = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>` to implement `Iterator` + = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>` to implement `Iterator` error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/recursion/recursion.rs b/tests/ui/recursion/recursion.rs index ce56fe974b7c6..5cd4012a9d2d9 100644 --- a/tests/ui/recursion/recursion.rs +++ b/tests/ui/recursion/recursion.rs @@ -1,7 +1,5 @@ //@ build-fail //@ compile-flags:-C overflow-checks=off -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" enum Nil {NilValue} struct Cons {head:isize, tail:T} diff --git a/tests/ui/recursion/recursion.stderr b/tests/ui/recursion/recursion.stderr index cb9f67ba7418d..f959805defc64 100644 --- a/tests/ui/recursion/recursion.stderr +++ b/tests/ui/recursion/recursion.stderr @@ -1,15 +1,15 @@ error: reached the recursion limit while instantiating `test::>>>>>` - --> $DIR/recursion.rs:19:11 + --> $DIR/recursion.rs:17:11 | LL | _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: `test` defined here - --> $DIR/recursion.rs:17:1 + --> $DIR/recursion.rs:15:1 | LL | fn test (n:isize, i:isize, first:T, second:T) ->isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/recursion.long-type.txt' error: aborting due to 1 previous error diff --git a/tests/ui/regions/issue-102374.rs b/tests/ui/regions/issue-102374.rs index d640c29b2f4cb..e0a1164211a2c 100644 --- a/tests/ui/regions/issue-102374.rs +++ b/tests/ui/regions/issue-102374.rs @@ -1,4 +1,3 @@ -//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" use std::cell::Cell; #[rustfmt::skip] diff --git a/tests/ui/regions/issue-102374.stderr b/tests/ui/regions/issue-102374.stderr index e07dca0c7ee23..5416125d1c7b7 100644 --- a/tests/ui/regions/issue-102374.stderr +++ b/tests/ui/regions/issue-102374.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-102374.rs:17:5 + --> $DIR/issue-102374.rs:16:5 | LL | ) -> i32 { | --- expected `i32` because of return type diff --git a/tests/ui/traits/on_unimplemented_long_types.rs b/tests/ui/traits/on_unimplemented_long_types.rs index c652b71e51acd..d6c3e8ef75faa 100644 --- a/tests/ui/traits/on_unimplemented_long_types.rs +++ b/tests/ui/traits/on_unimplemented_long_types.rs @@ -1,6 +1,4 @@ //@ compile-flags: --diagnostic-width=60 -Z write-long-types-to-disk=yes -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" pub fn foo() -> impl std::fmt::Display { //~^ ERROR doesn't implement `std::fmt::Display` diff --git a/tests/ui/traits/on_unimplemented_long_types.stderr b/tests/ui/traits/on_unimplemented_long_types.stderr index 2705d7c501ec6..1628466e0818f 100644 --- a/tests/ui/traits/on_unimplemented_long_types.stderr +++ b/tests/ui/traits/on_unimplemented_long_types.stderr @@ -1,5 +1,5 @@ error[E0277]: `Option>>` doesn't implement `std::fmt::Display` - --> $DIR/on_unimplemented_long_types.rs:5:17 + --> $DIR/on_unimplemented_long_types.rs:3:17 | LL | pub fn foo() -> impl std::fmt::Display { | ^^^^^^^^^^^^^^^^^^^^^^ `Option>>` cannot be formatted with the default formatter @@ -15,7 +15,7 @@ LL | | ))))))))))) | = help: the trait `std::fmt::Display` is not implemented for `Option>>` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/on_unimplemented_long_types.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/type_length_limit.rs b/tests/ui/type_length_limit.rs index b629455aced7e..87f5ffd76d7a6 100644 --- a/tests/ui/type_length_limit.rs +++ b/tests/ui/type_length_limit.rs @@ -2,9 +2,6 @@ //@ compile-flags: -Copt-level=0 -Zenforce-type-length-limit //~^^ ERROR reached the type-length limit -// The regex below normalizes the long type file name to make it suitable for compare-modes. -//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'" - // Test that the type length limit can be changed. // The exact type depends on optimizations, so disable them. diff --git a/tests/ui/type_length_limit.stderr b/tests/ui/type_length_limit.stderr index d913b661c6f07..198d133c08c88 100644 --- a/tests/ui/type_length_limit.stderr +++ b/tests/ui/type_length_limit.stderr @@ -1,11 +1,11 @@ error: reached the type-length limit while instantiating `std::mem::drop::>` - --> $DIR/type_length_limit.rs:35:5 + --> $DIR/type_length_limit.rs:32:5 | LL | drop::>(None); | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding a `#![type_length_limit="4010"]` attribute to your crate - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit.long-type.txt' error: reached the type-length limit while instantiating `<{closure@rt::lang_start<()>::{closure#0}} as FnMut<()>>::call_mut` | From 12cd0f11f0ff3408781f673fd903859ac412c71c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 11 Feb 2025 20:59:35 +0800 Subject: [PATCH 20/35] tests: rebless some tests as a side-effect of `TEST_BUILD_DIR` changes --- tests/ui/crate-loading/crateresolve1.stderr | 6 +++--- tests/ui/crate-loading/crateresolve2.stderr | 6 +++--- tests/ui/error-codes/E0462.stderr | 2 +- tests/ui/error-codes/E0464.stderr | 6 +++--- tests/ui/error-codes/E0523.stderr | 6 +++--- tests/ui/json/json-multiple.stderr | 2 +- tests/ui/json/json-options.stderr | 2 +- tests/ui/rmeta/emit-artifact-notifications.stderr | 2 +- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/ui/crate-loading/crateresolve1.stderr b/tests/ui/crate-loading/crateresolve1.stderr index 47131a96bf43b..b17330fb9d945 100644 --- a/tests/ui/crate-loading/crateresolve1.stderr +++ b/tests/ui/crate-loading/crateresolve1.stderr @@ -4,9 +4,9 @@ error[E0464]: multiple candidates for `rlib` dependency `crateresolve1` found LL | extern crate crateresolve1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: candidate #1: $TEST_BUILD_DIR/crate-loading/crateresolve1/auxiliary/libcrateresolve1-1.somelib - = note: candidate #2: $TEST_BUILD_DIR/crate-loading/crateresolve1/auxiliary/libcrateresolve1-2.somelib - = note: candidate #3: $TEST_BUILD_DIR/crate-loading/crateresolve1/auxiliary/libcrateresolve1-3.somelib + = note: candidate #1: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-1.somelib + = note: candidate #2: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-2.somelib + = note: candidate #3: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-3.somelib error: aborting due to 1 previous error diff --git a/tests/ui/crate-loading/crateresolve2.stderr b/tests/ui/crate-loading/crateresolve2.stderr index 3dc89dabde6d5..0c488f3fd0700 100644 --- a/tests/ui/crate-loading/crateresolve2.stderr +++ b/tests/ui/crate-loading/crateresolve2.stderr @@ -4,9 +4,9 @@ error[E0464]: multiple candidates for `rmeta` dependency `crateresolve2` found LL | extern crate crateresolve2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: candidate #1: $TEST_BUILD_DIR/crate-loading/crateresolve2/auxiliary/libcrateresolve2-1.rmeta - = note: candidate #2: $TEST_BUILD_DIR/crate-loading/crateresolve2/auxiliary/libcrateresolve2-2.rmeta - = note: candidate #3: $TEST_BUILD_DIR/crate-loading/crateresolve2/auxiliary/libcrateresolve2-3.rmeta + = note: candidate #1: $TEST_BUILD_DIR/auxiliary/libcrateresolve2-1.rmeta + = note: candidate #2: $TEST_BUILD_DIR/auxiliary/libcrateresolve2-2.rmeta + = note: candidate #3: $TEST_BUILD_DIR/auxiliary/libcrateresolve2-3.rmeta error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0462.stderr b/tests/ui/error-codes/E0462.stderr index 18f20d79385e3..be32001fad46f 100644 --- a/tests/ui/error-codes/E0462.stderr +++ b/tests/ui/error-codes/E0462.stderr @@ -5,7 +5,7 @@ LL | extern crate found_staticlib; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the following crate versions were found: - crate `found_staticlib`: $TEST_BUILD_DIR/error-codes/E0462/auxiliary/libfound_staticlib.somelib + crate `found_staticlib`: $TEST_BUILD_DIR/auxiliary/libfound_staticlib.somelib = help: please recompile that crate using --crate-type lib error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0464.stderr b/tests/ui/error-codes/E0464.stderr index edb0b1cf41e1a..ec18978a59ac5 100644 --- a/tests/ui/error-codes/E0464.stderr +++ b/tests/ui/error-codes/E0464.stderr @@ -4,9 +4,9 @@ error[E0464]: multiple candidates for `rlib` dependency `crateresolve1` found LL | extern crate crateresolve1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: candidate #1: $TEST_BUILD_DIR/error-codes/E0464/auxiliary/libcrateresolve1-1.somelib - = note: candidate #2: $TEST_BUILD_DIR/error-codes/E0464/auxiliary/libcrateresolve1-2.somelib - = note: candidate #3: $TEST_BUILD_DIR/error-codes/E0464/auxiliary/libcrateresolve1-3.somelib + = note: candidate #1: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-1.somelib + = note: candidate #2: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-2.somelib + = note: candidate #3: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-3.somelib error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0523.stderr b/tests/ui/error-codes/E0523.stderr index c6e65b55e2b30..f4072d6910444 100644 --- a/tests/ui/error-codes/E0523.stderr +++ b/tests/ui/error-codes/E0523.stderr @@ -4,9 +4,9 @@ error[E0464]: multiple candidates for `rlib` dependency `crateresolve1` found LL | extern crate crateresolve1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: candidate #1: $TEST_BUILD_DIR/error-codes/E0523/auxiliary/libcrateresolve1-1.somelib - = note: candidate #2: $TEST_BUILD_DIR/error-codes/E0523/auxiliary/libcrateresolve1-2.somelib - = note: candidate #3: $TEST_BUILD_DIR/error-codes/E0523/auxiliary/libcrateresolve1-3.somelib + = note: candidate #1: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-1.somelib + = note: candidate #2: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-2.somelib + = note: candidate #3: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-3.somelib error: aborting due to 1 previous error diff --git a/tests/ui/json/json-multiple.stderr b/tests/ui/json/json-multiple.stderr index 7689fb94a6c8d..e285817cffb93 100644 --- a/tests/ui/json/json-multiple.stderr +++ b/tests/ui/json/json-multiple.stderr @@ -1 +1 @@ -{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/json/json-multiple/libjson_multiple.rlib","emit":"link"} +{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/libjson_multiple.rlib","emit":"link"} diff --git a/tests/ui/json/json-options.stderr b/tests/ui/json/json-options.stderr index 668fc18097f0d..fff4ec9a6df14 100644 --- a/tests/ui/json/json-options.stderr +++ b/tests/ui/json/json-options.stderr @@ -1 +1 @@ -{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/json/json-options/libjson_options.rlib","emit":"link"} +{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/libjson_options.rlib","emit":"link"} diff --git a/tests/ui/rmeta/emit-artifact-notifications.stderr b/tests/ui/rmeta/emit-artifact-notifications.stderr index 4f68a2d74ed31..c002be7bcff05 100644 --- a/tests/ui/rmeta/emit-artifact-notifications.stderr +++ b/tests/ui/rmeta/emit-artifact-notifications.stderr @@ -1 +1 @@ -{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/rmeta/emit-artifact-notifications/libemit_artifact_notifications.rmeta","emit":"metadata"} +{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/libemit_artifact_notifications.rmeta","emit":"metadata"} From 4f2a3dc196ff80f0fb535636296c4be5489ecd8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 11 Feb 2025 21:43:19 +0800 Subject: [PATCH 21/35] tests: manually rebless `tests/ui-fulldeps/codegen-backend/hotplug.rs` --- tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout | 4 ++-- tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout b/tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout index 4d58fd503d0a6..5cf39ca3165d7 100644 --- a/tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout +++ b/tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout @@ -1,4 +1,4 @@ -$TEST_BUILD_DIR/codegen-backend/hotplug.bindep/libhotplug.rlib: $DIR/hotplug.rs $TEST_BUILD_DIR/codegen-backend/hotplug.bindep/auxiliary/libthe_backend.so +$TEST_BUILD_DIR/libhotplug.rlib: $DIR/hotplug.rs $TEST_BUILD_DIR/auxiliary/libthe_backend.so $DIR/hotplug.rs: -$TEST_BUILD_DIR/codegen-backend/hotplug.bindep/auxiliary/libthe_backend.so: +$TEST_BUILD_DIR/auxiliary/libthe_backend.so: diff --git a/tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout b/tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout index 48b7534d8faf7..717439f14e1d6 100644 --- a/tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout +++ b/tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout @@ -1,3 +1,3 @@ -$TEST_BUILD_DIR/codegen-backend/hotplug.dep/libhotplug.rlib: $DIR/hotplug.rs +$TEST_BUILD_DIR/libhotplug.rlib: $DIR/hotplug.rs $DIR/hotplug.rs: From 133705c402941c0825fe658a932289847478cf9f Mon Sep 17 00:00:00 2001 From: xizheyin Date: Thu, 27 Feb 2025 20:54:26 +0800 Subject: [PATCH 22/35] [rustdoc] hide item that is not marked as doc(inline) and whose src is doc(hidden) Signed-off-by: xizheyin --- src/librustdoc/passes/strip_hidden.rs | 22 +++++++++++++++++-- tests/rustdoc/doc-hidden-reexports-109449.rs | 18 +++++++-------- tests/rustdoc/doc-hidden-source.rs | 16 ++++++++++++++ tests/rustdoc/inline_cross/inline_hidden.rs | 4 ++-- tests/rustdoc/reexport-attr-merge.rs | 4 ++-- .../reexport-doc-hidden-inside-private.rs | 4 ++-- tests/rustdoc/reexport-doc-hidden.rs | 4 ++-- tests/rustdoc/reexport-hidden-macro.rs | 2 +- tests/rustdoc/reexport-of-doc-hidden.rs | 12 +++++----- 9 files changed, 60 insertions(+), 26 deletions(-) create mode 100644 tests/rustdoc/doc-hidden-source.rs diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index a71bb62e56c74..bcdca862862d4 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -7,9 +7,8 @@ use rustc_middle::ty::TyCtxt; use rustc_span::symbol::sym; use tracing::debug; -use crate::clean; use crate::clean::utils::inherits_doc_hidden; -use crate::clean::{Item, ItemIdSet}; +use crate::clean::{self, Item, ItemIdSet, reexport_chain}; use crate::core::DocContext; use crate::fold::{DocFolder, strip_item}; use crate::passes::{ImplStripper, Pass}; @@ -89,6 +88,25 @@ impl Stripper<'_, '_> { impl DocFolder for Stripper<'_, '_> { fn fold_item(&mut self, i: Item) -> Option { let has_doc_hidden = i.is_doc_hidden(); + + if let clean::ImportItem(clean::Import { source, .. }) = &i.kind + && let Some(source_did) = source.did + && let Some(import_def_id) = i.def_id().and_then(|def_id| def_id.as_local()) + { + let reexports = reexport_chain(self.tcx, import_def_id, source_did); + + // Check if any reexport in the chain has a hidden source + let has_hidden_source = reexports + .iter() + .filter_map(|reexport| reexport.id()) + .any(|reexport_did| self.tcx.is_doc_hidden(reexport_did)) + || self.tcx.is_doc_hidden(source_did); + + if has_hidden_source { + return None; + } + } + let is_impl_or_exported_macro = match i.kind { clean::ImplItem(..) => true, // If the macro has the `#[macro_export]` attribute, it means it's accessible at the diff --git a/tests/rustdoc/doc-hidden-reexports-109449.rs b/tests/rustdoc/doc-hidden-reexports-109449.rs index 8f195544120af..78b9214300a95 100644 --- a/tests/rustdoc/doc-hidden-reexports-109449.rs +++ b/tests/rustdoc/doc-hidden-reexports-109449.rs @@ -26,21 +26,21 @@ pub mod single_reexport { //@ has 'foo/single_reexport/index.html' // First we check that we have 4 type aliases. - //@ count - '//*[@id="main-content"]/*[@class="item-table reexports"]//code' 4 + //@ count - '//*[@id="main-content"]/*[@class="item-table reexports"]//code' 0 // Then we check that we have the correct link for each re-export. //@ !has - '//*[@href="struct.Foo.html"]' 'Foo' - //@ has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;' + //@ !has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;' pub use crate::private_module::Public as Foo; //@ !has - '//*[@href="type.Foo2.html"]' 'Foo2' - //@ has - '//*[@id="reexport.Foo2"]/code' 'pub use crate::private_module::Bar as Foo2;' + //@ !has - '//*[@id="reexport.Foo2"]/code' 'pub use crate::private_module::Bar as Foo2;' pub use crate::private_module::Bar as Foo2; //@ !has - '//*[@href="type.Yo.html"]' 'Yo' - //@ has - '//*[@id="reexport.Yo"]/code' 'pub use crate::Bar3 as Yo;' + //@ !has - '//*[@id="reexport.Yo"]/code' 'pub use crate::Bar3 as Yo;' pub use crate::Bar3 as Yo; //@ !has - '//*[@href="struct.Yo2.html"]' 'Yo2' - //@ has - '//*[@id="reexport.Yo2"]/code' 'pub use crate::FooFoo as Yo2;' + //@ !has - '//*[@id="reexport.Yo2"]/code' 'pub use crate::FooFoo as Yo2;' pub use crate::FooFoo as Yo2; // Checking that each file is also created as expected. @@ -70,19 +70,19 @@ pub mod single_reexport_no_inline { //@ has - '//*[@id="main-content"]/*[@class="section-header"]' 'Re-exports' // Now we check that we don't have links to the items, just `pub use`. - //@ has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Public as XFoo;' + //@ !has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Public as XFoo;' //@ !has - '//*[@id="main-content"]//a' 'XFoo' #[doc(no_inline)] pub use crate::private_module::Public as XFoo; - //@ has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Bar as Foo2;' + //@ !has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Bar as Foo2;' //@ !has - '//*[@id="main-content"]//a' 'Foo2' #[doc(no_inline)] pub use crate::private_module::Bar as Foo2; - //@ has - '//*[@id="main-content"]//*' 'pub use crate::Bar3 as Yo;' + //@ !has - '//*[@id="main-content"]//*' 'pub use crate::Bar3 as Yo;' //@ !has - '//*[@id="main-content"]//a' 'Yo' #[doc(no_inline)] pub use crate::Bar3 as Yo; - //@ has - '//*[@id="main-content"]//*' 'pub use crate::FooFoo as Yo2;' + //@ !has - '//*[@id="main-content"]//*' 'pub use crate::FooFoo as Yo2;' //@ !has - '//*[@id="main-content"]//a' 'Yo2' #[doc(no_inline)] pub use crate::FooFoo as Yo2; diff --git a/tests/rustdoc/doc-hidden-source.rs b/tests/rustdoc/doc-hidden-source.rs new file mode 100644 index 0000000000000..b6bc622dd584f --- /dev/null +++ b/tests/rustdoc/doc-hidden-source.rs @@ -0,0 +1,16 @@ +// Test for . + +#![crate_name = "foo"] + +//@ has 'foo/index.html' +//@ !has - '//*[@id="main-content"]//*[@class="struct"]' 'Bar' +#[doc(hidden)] +pub struct Bar; + +//@ !has - '//*' 'pub use crate::Bar as A;' +pub use crate::Bar as A; +//@ !has - '//*' 'pub use crate::A as B;' +pub use crate::A as B; +//@ has - '//dt/a[@class="struct"]' 'C' +#[doc(inline)] +pub use crate::Bar as C; diff --git a/tests/rustdoc/inline_cross/inline_hidden.rs b/tests/rustdoc/inline_cross/inline_hidden.rs index 49ca2db6a2245..f6727de2cc67f 100644 --- a/tests/rustdoc/inline_cross/inline_hidden.rs +++ b/tests/rustdoc/inline_cross/inline_hidden.rs @@ -6,7 +6,7 @@ extern crate rustdoc_hidden; //@ has inline_hidden/index.html // Ensures this item is not inlined. -//@ has - '//*[@id="reexport.Foo"]/code' 'pub use rustdoc_hidden::Foo;' +//@ !has - '//*[@id="reexport.Foo"]/code' 'pub use rustdoc_hidden::Foo;' #[doc(no_inline)] pub use rustdoc_hidden::Foo; @@ -16,7 +16,7 @@ pub use rustdoc_hidden::Foo; pub use rustdoc_hidden::Foo as Inlined; // Even with this import, we should not see `Foo`. -//@ count - '//dt' 4 +//@ count - '//dt' 3 //@ has - '//dt/a[@class="struct"]' 'Bar' //@ has - '//dt/a[@class="fn"]' 'foo' pub use rustdoc_hidden::*; diff --git a/tests/rustdoc/reexport-attr-merge.rs b/tests/rustdoc/reexport-attr-merge.rs index e4a406c3845ad..aef302eb0b29a 100644 --- a/tests/rustdoc/reexport-attr-merge.rs +++ b/tests/rustdoc/reexport-attr-merge.rs @@ -18,7 +18,7 @@ pub use Foo1 as Foo2; // First we ensure that only the reexport `Bar2` and the inlined struct `Bar` // are inlined. -//@ count - '//a[@class="struct"]' 2 +//@ count - '//a[@class="struct"]' 1 // Then we check that `cfg` is displayed for base item, but not for intermediate re-exports. //@ has - '//*[@class="stab portability"]' 'foo' //@ !has - '//*[@class="stab portability"]' 'bar' @@ -29,5 +29,5 @@ pub use Foo2 as Bar; // This one should appear but `Bar2` won't be linked because there is no // `#[doc(inline)]`. -//@ has - '//*[@id="reexport.Bar2"]' 'pub use Foo2 as Bar2;' +//@ !has - '//*[@id="reexport.Bar2"]' 'pub use Foo2 as Bar2;' pub use Foo2 as Bar2; diff --git a/tests/rustdoc/reexport-doc-hidden-inside-private.rs b/tests/rustdoc/reexport-doc-hidden-inside-private.rs index 8e194ef74fb82..bae2aa78ec7a3 100644 --- a/tests/rustdoc/reexport-doc-hidden-inside-private.rs +++ b/tests/rustdoc/reexport-doc-hidden-inside-private.rs @@ -9,8 +9,8 @@ mod private_module { } //@ has 'foo/index.html' -//@ has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;' +//@ !has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;' pub use crate::private_module::Public as Foo; // Glob re-exports with no visible items should not be displayed. -//@ count - '//*[@class="item-table reexports"]/dt' 1 +//@ count - '//*[@class="item-table reexports"]/dt' 0 pub use crate::private_module::*; diff --git a/tests/rustdoc/reexport-doc-hidden.rs b/tests/rustdoc/reexport-doc-hidden.rs index b912362f2987a..1468e9ad957f7 100644 --- a/tests/rustdoc/reexport-doc-hidden.rs +++ b/tests/rustdoc/reexport-doc-hidden.rs @@ -8,7 +8,7 @@ pub type Type = u32; //@ has 'foo/index.html' -//@ has - '//*[@id="reexport.Type2"]/code' 'pub use crate::Type as Type2;' +//@ !has - '//*[@id="reexport.Type2"]/code' 'pub use crate::Type as Type2;' pub use crate::Type as Type2; //@ count - '//*[@id="reexport.Type3"]' 0 @@ -21,5 +21,5 @@ macro_rules! foo { () => {}; } -//@ has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' +//@ !has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' pub use crate::foo as Macro; diff --git a/tests/rustdoc/reexport-hidden-macro.rs b/tests/rustdoc/reexport-hidden-macro.rs index 9b83bca3906d2..7345149c64522 100644 --- a/tests/rustdoc/reexport-hidden-macro.rs +++ b/tests/rustdoc/reexport-hidden-macro.rs @@ -5,7 +5,7 @@ //@ has 'foo/index.html' //@ has - '//*[@id="main-content"]//a[@href="macro.Macro2.html"]' 'Macro2' -//@ has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' +//@ !has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' //@ has 'foo/macro.Macro2.html' //@ has - '//*[@class="docblock"]' 'Displayed' diff --git a/tests/rustdoc/reexport-of-doc-hidden.rs b/tests/rustdoc/reexport-of-doc-hidden.rs index 21511bc2aea99..e901d0ff8a2bc 100644 --- a/tests/rustdoc/reexport-of-doc-hidden.rs +++ b/tests/rustdoc/reexport-of-doc-hidden.rs @@ -12,13 +12,13 @@ macro_rules! foo { } //@ has 'foo/index.html' -//@ has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' +//@ !has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' pub use crate::foo as Macro; -//@ has - '//*[@id="reexport.Macro2"]/code' 'pub use crate::foo as Macro2;' +//@ !has - '//*[@id="reexport.Macro2"]/code' 'pub use crate::foo as Macro2;' pub use crate::foo as Macro2; -//@ has - '//*[@id="reexport.Boo"]/code' 'pub use crate::Bar as Boo;' +//@ !has - '//*[@id="reexport.Boo"]/code' 'pub use crate::Bar as Boo;' pub use crate::Bar as Boo; -//@ has - '//*[@id="reexport.Boo2"]/code' 'pub use crate::Bar as Boo2;' +//@ !has - '//*[@id="reexport.Boo2"]/code' 'pub use crate::Bar as Boo2;' pub use crate::Bar as Boo2; pub fn fofo() {} @@ -30,9 +30,9 @@ pub use crate::fofo as f2; pub mod sub { //@ has 'foo/sub/index.html' - //@ has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' + //@ !has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;' pub use crate::foo as Macro; - //@ has - '//*[@id="reexport.Macro2"]/code' 'pub use crate::foo as Macro2;' + //@ !has - '//*[@id="reexport.Macro2"]/code' 'pub use crate::foo as Macro2;' pub use crate::foo as Macro2; //@ has - '//*[@id="reexport.f1"]/code' 'pub use crate::fofo as f1;' From a23566a57e4d53a35827becc2f65ce27951276c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 28 Feb 2025 21:39:25 +0000 Subject: [PATCH 23/35] Provide more context on resolve error caused from incorrect RTN When encountering a resolve E0575 error for an associated method (when a type was expected), see if it could have been an intended return type notation bound. ``` error[E0575]: expected associated type, found associated function `Trait::method` --> $DIR/bad-inputs-and-output.rs:31:36 | LL | fn foo_qualified() where ::method(i32): Send {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ not a associated type | help: you might have meant to use the return type notation syntax | LL - fn foo_qualified() where ::method(i32): Send {} LL + fn foo_qualified() where T::method(..): Send {} | ``` --- compiler/rustc_ast_lowering/src/lib.rs | 1 - compiler/rustc_ast_lowering/src/path.rs | 1 - compiler/rustc_resolve/src/late.rs | 18 +++++++-- .../rustc_resolve/src/late/diagnostics.rs | 39 +++++++++++++++++- .../bad-inputs-and-output.fixed | 40 +++++++++++++++++++ .../bad-inputs-and-output.rs | 3 +- .../bad-inputs-and-output.stderr | 38 +++++++++++++----- 7 files changed, 123 insertions(+), 17 deletions(-) create mode 100644 tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.fixed diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 13edcc10c9e2a..2e175405da219 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -926,7 +926,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { if let Some(first_char) = constraint.ident.as_str().chars().next() && first_char.is_ascii_lowercase() { - tracing::info!(?data, ?data.inputs); let err = match (&data.inputs[..], &data.output) { ([_, ..], FnRetTy::Default(_)) => { errors::BadReturnTypeNotation::Inputs { span: data.inputs_span } diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 6b6244b05aa9b..d00c797755f3f 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -268,7 +268,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } GenericArgs::Parenthesized(data) => match generic_args_mode { GenericArgsMode::ReturnTypeNotation => { - tracing::info!(?data, ?data.inputs); let err = match (&data.inputs[..], &data.output) { ([_, ..], FnRetTy::Default(_)) => { BadReturnTypeNotation::Inputs { span: data.inputs_span } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f119ed55e7d1b..50bc2feb477dc 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -623,7 +623,7 @@ pub(crate) struct UnnecessaryQualification<'ra> { pub removal_span: Span, } -#[derive(Default)] +#[derive(Default, Debug)] struct DiagMetadata<'ast> { /// The current trait's associated items' ident, used for diagnostic suggestions. current_trait_assoc_items: Option<&'ast [P]>, @@ -3146,6 +3146,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { PathSource::Trait(AliasPossibility::No), Finalize::new(trait_ref.ref_id, trait_ref.path.span), RecordPartialRes::Yes, + None, ); self.diag_metadata.currently_processing_impl_trait = None; if let Some(def_id) = res.expect_full_res().opt_def_id() { @@ -4072,6 +4073,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { source, Finalize::new(id, path.span), RecordPartialRes::Yes, + None, ); } @@ -4083,14 +4085,21 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { source: PathSource<'ast>, finalize: Finalize, record_partial_res: RecordPartialRes, + parent_qself: Option<&QSelf>, ) -> PartialRes { let ns = source.namespace(); let Finalize { node_id, path_span, .. } = finalize; let report_errors = |this: &mut Self, res: Option| { if this.should_report_errs() { - let (err, candidates) = - this.smart_resolve_report_errors(path, None, path_span, source, res); + let (err, candidates) = this.smart_resolve_report_errors( + path, + None, + path_span, + source, + res, + parent_qself, + ); let def_id = this.parent_scope.module.nearest_parent_mod(); let instead = res.is_some(); @@ -4159,6 +4168,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { path_span, PathSource::Type, None, + parent_qself, ); // There are two different error messages user might receive at @@ -4436,6 +4446,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { PathSource::Trait(AliasPossibility::No), Finalize::new(finalize.node_id, qself.path_span), RecordPartialRes::No, + Some(&qself), ); if trait_res.expect_full_res() == Res::Err { @@ -4460,6 +4471,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { PathSource::TraitItem(ns), Finalize::with_root_span(finalize.node_id, finalize.path_span, qself.path_span), RecordPartialRes::No, + Some(&qself), ); // The remaining segments (the `C` in our example) will diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 0e14e7671b176..035f9abda86e6 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -35,7 +35,7 @@ use super::NoConstantGenericsReason; use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion}; use crate::late::{ AliasPossibility, LateResolutionVisitor, LifetimeBinderKind, LifetimeRes, LifetimeRibKind, - LifetimeUseSet, RibKind, + LifetimeUseSet, QSelf, RibKind, }; use crate::ty::fast_reject::SimplifiedType; use crate::{ @@ -421,6 +421,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { span: Span, source: PathSource<'_>, res: Option, + qself: Option<&QSelf>, ) -> (Diag<'tcx>, Vec) { debug!(?res, ?source); let base_error = self.make_base_error(path, span, source, res); @@ -453,6 +454,15 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { self.suggest_self_or_self_ref(&mut err, path, span); self.detect_assoc_type_constraint_meant_as_path(&mut err, &base_error); + self.detect_rtn_with_fully_qualified_path( + &mut err, + path, + following_seg, + span, + source, + res, + qself, + ); if self.suggest_self_ty(&mut err, source, path, span) || self.suggest_self_value(&mut err, source, path, span) { @@ -501,6 +511,33 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { (err, candidates) } + fn detect_rtn_with_fully_qualified_path( + &self, + err: &mut Diag<'_>, + path: &[Segment], + following_seg: Option<&Segment>, + span: Span, + source: PathSource<'_>, + res: Option, + qself: Option<&QSelf>, + ) { + if let Some(Res::Def(DefKind::AssocFn, _)) = res + && let PathSource::TraitItem(TypeNS) = source + && let None = following_seg + && let Some(qself) = qself + && let TyKind::Path(None, ty_path) = &qself.ty.kind + && ty_path.segments.len() == 1 + && self.diag_metadata.current_where_predicate.is_some() + { + err.span_suggestion_verbose( + span, + "you might have meant to use the return type notation syntax", + format!("{}::{}(..)", ty_path.segments[0].ident, path[path.len() - 1].ident), + Applicability::MaybeIncorrect, + ); + } + } + fn detect_assoc_type_constraint_meant_as_path( &self, err: &mut Diag<'_>, diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.fixed b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.fixed new file mode 100644 index 0000000000000..7af986267aa67 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.fixed @@ -0,0 +1,40 @@ +//@ edition: 2021 +//@ run-rustfix +#![feature(return_type_notation)] +#![allow(dead_code)] + +trait Trait { + async fn method() {} +} + +fn foo>() {} +//~^ ERROR argument types not allowed with return type notation + +fn bar>() {} +//~^ ERROR return type not allowed with return type notation + +fn baz>() {} +//~^ ERROR return type notation arguments must be elided with `..` + +fn foo_path() where T::method(..): Send {} +//~^ ERROR argument types not allowed with return type notation + +fn bar_path() where T::method(..): Send {} +//~^ ERROR return type not allowed with return type notation + +fn bay_path() where T::method(..): Send {} +//~^ ERROR return type not allowed with return type notation + +fn baz_path() where T::method(..): Send {} +//~^ ERROR return type notation arguments must be elided with `..` + +fn foo_qualified() where T::method(..): Send {} +//~^ ERROR expected associated type + +fn bar_qualified() where T::method(..): Send {} +//~^ ERROR expected associated type + +fn baz_qualified() where T::method(..): Send {} +//~^ ERROR expected associated type + +fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs index 90fd2c2b4f326..983836e6433f0 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs @@ -1,6 +1,7 @@ //@ edition: 2021 - +//@ run-rustfix #![feature(return_type_notation)] +#![allow(dead_code)] trait Trait { async fn method() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr index bd02b7d6534a9..e1245a04c7f7d 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr @@ -1,5 +1,5 @@ error: return type not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:24:45 + --> $DIR/bad-inputs-and-output.rs:25:45 | LL | fn bay_path() where T::method(..) -> (): Send {} | ^^^^^ @@ -11,25 +11,43 @@ LL + fn bay_path() where T::method(..): Send {} | error[E0575]: expected associated type, found associated function `Trait::method` - --> $DIR/bad-inputs-and-output.rs:30:36 + --> $DIR/bad-inputs-and-output.rs:31:36 | LL | fn foo_qualified() where ::method(i32): Send {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ not a associated type + | +help: you might have meant to use the return type notation syntax + | +LL - fn foo_qualified() where ::method(i32): Send {} +LL + fn foo_qualified() where T::method(..): Send {} + | error[E0575]: expected associated type, found associated function `Trait::method` - --> $DIR/bad-inputs-and-output.rs:33:36 + --> $DIR/bad-inputs-and-output.rs:34:36 | LL | fn bar_qualified() where ::method() -> (): Send {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a associated type + | +help: you might have meant to use the return type notation syntax + | +LL - fn bar_qualified() where ::method() -> (): Send {} +LL + fn bar_qualified() where T::method(..): Send {} + | error[E0575]: expected associated type, found associated function `Trait::method` - --> $DIR/bad-inputs-and-output.rs:36:36 + --> $DIR/bad-inputs-and-output.rs:37:36 | LL | fn baz_qualified() where ::method(): Send {} | ^^^^^^^^^^^^^^^^^^^^^^ not a associated type + | +help: you might have meant to use the return type notation syntax + | +LL - fn baz_qualified() where ::method(): Send {} +LL + fn baz_qualified() where T::method(..): Send {} + | error: argument types not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:9:23 + --> $DIR/bad-inputs-and-output.rs:10:23 | LL | fn foo>() {} | ^^^^^ @@ -41,7 +59,7 @@ LL + fn foo>() {} | error: return type not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:12:25 + --> $DIR/bad-inputs-and-output.rs:13:25 | LL | fn bar (): Send>>() {} | ^^^^^^ @@ -53,7 +71,7 @@ LL + fn bar>() {} | error: return type notation arguments must be elided with `..` - --> $DIR/bad-inputs-and-output.rs:15:23 + --> $DIR/bad-inputs-and-output.rs:16:23 | LL | fn baz>() {} | ^^ @@ -64,7 +82,7 @@ LL | fn baz>() {} | ++ error: argument types not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:18:40 + --> $DIR/bad-inputs-and-output.rs:19:40 | LL | fn foo_path() where T::method(i32): Send {} | ^^^^^ @@ -76,7 +94,7 @@ LL + fn foo_path() where T::method(..): Send {} | error: return type not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:21:42 + --> $DIR/bad-inputs-and-output.rs:22:42 | LL | fn bar_path() where T::method() -> (): Send {} | ^^^^^^ @@ -88,7 +106,7 @@ LL + fn bar_path() where T::method(..): Send {} | error: return type notation arguments must be elided with `..` - --> $DIR/bad-inputs-and-output.rs:27:40 + --> $DIR/bad-inputs-and-output.rs:28:40 | LL | fn baz_path() where T::method(): Send {} | ^^ From ab31129956869f6dfc25417230061bad72de9081 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 24 Feb 2025 20:10:37 +0000 Subject: [PATCH 24/35] Point of macro expansion from call expr if it involves macro var --- .../rustc_hir_typeck/src/method/suggest.rs | 23 ++++++++++++++++--- compiler/rustc_span/src/lib.rs | 23 +++++++++++++++++++ .../ui/methods/ident-from-macro-expansion.rs | 18 +++++++++++++++ .../methods/ident-from-macro-expansion.stderr | 21 +++++++++++++++++ 4 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 tests/ui/methods/ident-from-macro-expansion.rs create mode 100644 tests/ui/methods/ident-from-macro-expansion.stderr diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 18218a7a0a641..41bd3933feec9 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -158,7 +158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.typeck_results.borrow_mut().used_trait_imports.insert(import_id); } - let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) { + let (span, expr_span, source, item_name, args) = match self.tcx.hir_node(call_id) { hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::MethodCall(segment, rcvr, args, _), span, @@ -194,6 +194,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { node => unreachable!("{node:?}"), }; + // Try to get the span of the identifier within the expression's syntax context (if that's different). + let within_macro_span = span.within_macro(expr_span); + // Avoid suggestions when we don't know what's going on. if let Err(guar) = rcvr_ty.error_reported() { return guar; @@ -207,10 +210,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_id, source, args, - sugg_span, + expr_span, &mut no_match_data, expected, trait_missing_method, + within_macro_span, ), MethodError::Ambiguity(mut sources) => { @@ -221,6 +225,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "multiple applicable items in scope" ); err.span_label(item_name.span, format!("multiple `{item_name}` found")); + if let Some(within_macro_span) = within_macro_span { + err.span_label(within_macro_span, "due to this macro variable"); + } self.note_candidates_on_method_error( rcvr_ty, @@ -230,7 +237,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, &mut err, &mut sources, - Some(sugg_span), + Some(expr_span), ); err.emit() } @@ -252,6 +259,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .span_if_local(def_id) .unwrap_or_else(|| self.tcx.def_span(def_id)); err.span_label(sp, format!("private {kind} defined here")); + if let Some(within_macro_span) = within_macro_span { + err.span_label(within_macro_span, "due to this macro variable"); + } self.suggest_valid_traits(&mut err, item_name, out_of_scope_traits, true); err.emit() } @@ -268,6 +278,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !needs_mut { err.span_label(bound_span, "this has a `Sized` requirement"); } + if let Some(within_macro_span) = within_macro_span { + err.span_label(within_macro_span, "due to this macro variable"); + } if !candidates.is_empty() { let help = format!( "{an}other candidate{s} {were} found in the following trait{s}", @@ -581,6 +594,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { no_match_data: &mut NoMatchData<'tcx>, expected: Expectation<'tcx>, trait_missing_method: bool, + within_macro_span: Option, ) -> ErrorGuaranteed { let mode = no_match_data.mode; let tcx = self.tcx; @@ -721,6 +735,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if tcx.sess.source_map().is_multiline(sugg_span) { err.span_label(sugg_span.with_hi(span.lo()), ""); } + if let Some(within_macro_span) = within_macro_span { + err.span_label(within_macro_span, "due to this macro variable"); + } if short_ty_str.len() < ty_str.len() && ty_str.len() > 10 { ty_str = short_ty_str; diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index bca9323a50d4c..d23e1825e6ea2 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1057,6 +1057,29 @@ impl Span { } } + /// Returns the `Span` within the syntax context of "within". This is useful when + /// "self" is an expansion from a macro variable, since this can be used for + /// providing extra macro expansion context for certain errors. + /// + /// ```text + /// macro_rules! m { + /// ($ident:ident) => { ($ident,) } + /// } + /// + /// m!(outer_ident); + /// ``` + /// + /// If "self" is the span of the outer_ident, and "within" is the span of the `($ident,)` + /// expr, then this will return the span of the `$ident` macro variable. + pub fn within_macro(self, within: Span) -> Option { + match Span::prepare_to_combine(self, within) { + Ok((self_, _, parent)) if self_.lo != self.lo() && self.hi() != self_.hi => { + Some(Span::new(self_.lo, self_.hi, self_.ctxt, parent)) + } + _ => None, + } + } + pub fn from_inner(self, inner: InnerSpan) -> Span { let span = self.data(); Span::new( diff --git a/tests/ui/methods/ident-from-macro-expansion.rs b/tests/ui/methods/ident-from-macro-expansion.rs new file mode 100644 index 0000000000000..38d2fee0e53c0 --- /dev/null +++ b/tests/ui/methods/ident-from-macro-expansion.rs @@ -0,0 +1,18 @@ +macro_rules! dot { + ($id:ident) => { + ().$id(); + } +} + +macro_rules! dispatch { + ($id:ident) => { + <()>::$id(); + } +} + +fn main() { + dot!(hello); + //~^ ERROR no method named `hello` found for unit type `()` in the current scope + dispatch!(hello); + //~^ ERROR no function or associated item named `hello` found for unit type `()` in the current scope +} diff --git a/tests/ui/methods/ident-from-macro-expansion.stderr b/tests/ui/methods/ident-from-macro-expansion.stderr new file mode 100644 index 0000000000000..b596ce29f6fee --- /dev/null +++ b/tests/ui/methods/ident-from-macro-expansion.stderr @@ -0,0 +1,21 @@ +error[E0599]: no method named `hello` found for unit type `()` in the current scope + --> $DIR/ident-from-macro-expansion.rs:14:10 + | +LL | ().$id(); + | --- due to this macro variable +... +LL | dot!(hello); + | ^^^^^ method not found in `()` + +error[E0599]: no function or associated item named `hello` found for unit type `()` in the current scope + --> $DIR/ident-from-macro-expansion.rs:16:15 + | +LL | <()>::$id(); + | --- due to this macro variable +... +LL | dispatch!(hello); + | ^^^^^ function or associated item not found in `()` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. From e4dfca8ac240d517e5d7008333fd7d3367d0176f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 24 Feb 2025 20:20:54 +0000 Subject: [PATCH 25/35] Point out macro expansion ident in resolver errors too --- compiler/rustc_hir_typeck/src/method/suggest.rs | 3 ++- compiler/rustc_resolve/src/late/diagnostics.rs | 6 ++++++ tests/ui/hygiene/generate-mod.stderr | 6 ++++++ tests/ui/hygiene/globs.stderr | 6 ++++++ tests/ui/macros/macro-parameter-span.stderr | 3 +++ tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr | 3 +++ 6 files changed, 26 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 41bd3933feec9..09e1390cc3ecd 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -194,7 +194,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { node => unreachable!("{node:?}"), }; - // Try to get the span of the identifier within the expression's syntax context (if that's different). + // Try to get the span of the identifier within the expression's syntax context + // (if that's different). let within_macro_span = span.within_macro(expr_span); // Avoid suggestions when we don't know what's going on. diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 0e14e7671b176..c86305e23d1d7 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -429,6 +429,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let mut err = self.r.dcx().struct_span_err(base_error.span, base_error.msg.clone()); err.code(code); + // Try to get the span of the identifier within the path's syntax context + // (if that's different). + if let Some(within_macro_span) = base_error.span.within_macro(span) { + err.span_label(within_macro_span, "within this macro"); + } + self.detect_missing_binding_available_from_pattern(&mut err, path, following_seg); self.suggest_at_operator_in_slice_pat_with_range(&mut err, path); self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span); diff --git a/tests/ui/hygiene/generate-mod.stderr b/tests/ui/hygiene/generate-mod.stderr index 32a2e145ca942..58b9c642dabe3 100644 --- a/tests/ui/hygiene/generate-mod.stderr +++ b/tests/ui/hygiene/generate-mod.stderr @@ -1,12 +1,18 @@ error[E0412]: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:35:13 | +LL | type A = $FromOutside; + | ------------ due to this macro variable +... LL | genmod!(FromOutside, Outer); | ^^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `Outer` in this scope --> $DIR/generate-mod.rs:35:26 | +LL | struct $Outer; + | ------ due to this macro variable +... LL | genmod!(FromOutside, Outer); | ^^^^^ not found in this scope diff --git a/tests/ui/hygiene/globs.stderr b/tests/ui/hygiene/globs.stderr index 3f7a0ae7efa1b..31f25b182f1f5 100644 --- a/tests/ui/hygiene/globs.stderr +++ b/tests/ui/hygiene/globs.stderr @@ -50,6 +50,9 @@ error[E0425]: cannot find function `f` in this scope LL | n!(f); | ----- in this macro invocation ... +LL | $j(); + | -- due to this macro variable +... LL | n!(f); | ^ not found in this scope | @@ -63,6 +66,9 @@ error[E0425]: cannot find function `f` in this scope LL | n!(f); | ----- in this macro invocation ... +LL | $j(); + | -- due to this macro variable +... LL | f | ^ not found in this scope | diff --git a/tests/ui/macros/macro-parameter-span.stderr b/tests/ui/macros/macro-parameter-span.stderr index 247750a8ad705..44c8c56dff999 100644 --- a/tests/ui/macros/macro-parameter-span.stderr +++ b/tests/ui/macros/macro-parameter-span.stderr @@ -1,6 +1,9 @@ error[E0425]: cannot find value `x` in this scope --> $DIR/macro-parameter-span.rs:11:9 | +LL | $id + | --- due to this macro variable +... LL | x | ^ not found in this scope diff --git a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr index ce7694ecb1da3..d9646760cea92 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr +++ b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr @@ -338,6 +338,9 @@ LL | no_curly__no_rhs_dollar__no_round!(a); error[E0425]: cannot find value `a` in this scope --> $DIR/syntax-errors.rs:152:37 | +LL | ( $i:ident ) => { count($i) }; + | -- due to this macro variable +... LL | no_curly__rhs_dollar__no_round!(a); | ^ not found in this scope From 06072468fe8de249a39d2fcc42cea51db2649a80 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 24 Feb 2025 20:36:15 +0000 Subject: [PATCH 26/35] Fix associated type errors too --- compiler/rustc_hir_analysis/messages.ftl | 2 ++ compiler/rustc_hir_analysis/src/errors.rs | 2 ++ .../src/hir_ty_lowering/errors.rs | 3 +++ .../ident-from-macro-expansion.rs | 23 +++++++++++++++++++ .../ident-from-macro-expansion.stderr | 22 ++++++++++++++++++ 5 files changed, 52 insertions(+) create mode 100644 tests/ui/associated-types/ident-from-macro-expansion.rs create mode 100644 tests/ui/associated-types/ident-from-macro-expansion.stderr diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 3f75cce009225..c2a6b5a890ec1 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -620,6 +620,8 @@ hir_analysis_variances_of = {$variances} hir_analysis_where_clause_on_main = `main` function is not allowed to have a `where` clause .label = `main` cannot have a `where` clause +hir_analysis_within_macro = due to this macro variable + hir_analysis_wrong_number_of_generic_arguments_to_intrinsic = intrinsic has wrong number of {$descr} parameters: found {$found}, expected {$expected} .label = expected {$expected} {$descr} {$expected -> diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 852533ff5c954..78b28048c8b07 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -84,6 +84,8 @@ pub(crate) struct AssocItemNotFound<'a> { pub label: Option>, #[subdiagnostic] pub sugg: Option>, + #[label(hir_analysis_within_macro)] + pub within_macro_span: Option, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 922578792ba8b..156ddb8f2aaba 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -151,6 +151,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { qself: &qself_str, label: None, sugg: None, + // Try to get the span of the identifier within the path's syntax context + // (if that's different). + within_macro_span: assoc_name.span.within_macro(span), }; if is_dummy { diff --git a/tests/ui/associated-types/ident-from-macro-expansion.rs b/tests/ui/associated-types/ident-from-macro-expansion.rs new file mode 100644 index 0000000000000..6aabe4571406c --- /dev/null +++ b/tests/ui/associated-types/ident-from-macro-expansion.rs @@ -0,0 +1,23 @@ +trait Trait {} +impl Trait for () {} + +macro_rules! fully_qualified { + ($id:ident) => { + <() as Trait>::$id + } +} + +macro_rules! type_dependent { + ($t:ident, $id:ident) => { + T::$id + } +} + +fn t() { + let x: fully_qualified!(Assoc); + //~^ ERROR cannot find associated type `Assoc` in trait `Trait` + let x: type_dependent!(T, Assoc); + //~^ ERROR associated type `Assoc` not found for `T` +} + +fn main() {} diff --git a/tests/ui/associated-types/ident-from-macro-expansion.stderr b/tests/ui/associated-types/ident-from-macro-expansion.stderr new file mode 100644 index 0000000000000..dabf13c2c1726 --- /dev/null +++ b/tests/ui/associated-types/ident-from-macro-expansion.stderr @@ -0,0 +1,22 @@ +error[E0576]: cannot find associated type `Assoc` in trait `Trait` + --> $DIR/ident-from-macro-expansion.rs:17:29 + | +LL | <() as Trait>::$id + | --- due to this macro variable +... +LL | let x: fully_qualified!(Assoc); + | ^^^^^ not found in `Trait` + +error[E0220]: associated type `Assoc` not found for `T` + --> $DIR/ident-from-macro-expansion.rs:19:31 + | +LL | T::$id + | --- due to this macro variable +... +LL | let x: type_dependent!(T, Assoc); + | ^^^^^ associated type `Assoc` not found + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0220, E0576. +For more information about an error, try `rustc --explain E0220`. From 4fdc1b5f6c88de001768822016603a2c48b4da8d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 23 Feb 2025 22:54:36 +0000 Subject: [PATCH 27/35] Construct MIR error body for global_asm correctly --- compiler/rustc_mir_build/src/builder/mod.rs | 3 ++- tests/ui/asm/global-asm-with-error.rs | 9 +++++++++ tests/ui/asm/global-asm-with-error.stderr | 9 +++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 tests/ui/asm/global-asm-with-error.rs create mode 100644 tests/ui/asm/global-asm-with-error.stderr diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 949559549345f..dc869b885a038 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -612,7 +612,8 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) - | DefKind::AssocConst | DefKind::AnonConst | DefKind::InlineConst - | DefKind::Static { .. } => (vec![], tcx.type_of(def_id).instantiate_identity(), None), + | DefKind::Static { .. } + | DefKind::GlobalAsm => (vec![], tcx.type_of(def_id).instantiate_identity(), None), DefKind::Ctor(..) | DefKind::Fn | DefKind::AssocFn => { let sig = tcx.liberate_late_bound_regions( def_id.to_def_id(), diff --git a/tests/ui/asm/global-asm-with-error.rs b/tests/ui/asm/global-asm-with-error.rs new file mode 100644 index 0000000000000..84e95c587ef36 --- /dev/null +++ b/tests/ui/asm/global-asm-with-error.rs @@ -0,0 +1,9 @@ +// Ensure that we don't ICE when constructing the fake MIR body for a global +// asm when the body has errors. See #137470. + +use std::arch::global_asm; + +global_asm!("/* {} */", sym a); +//~^ ERROR cannot find value `a` in this scope + +fn main() {} diff --git a/tests/ui/asm/global-asm-with-error.stderr b/tests/ui/asm/global-asm-with-error.stderr new file mode 100644 index 0000000000000..6c07a9f020da8 --- /dev/null +++ b/tests/ui/asm/global-asm-with-error.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `a` in this scope + --> $DIR/global-asm-with-error.rs:6:29 + | +LL | global_asm!("/* {} */", sym a); + | ^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. From dc9d559f42b216a91ca2b45729b2f6d48b47e44f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 23 Feb 2025 23:01:04 +0000 Subject: [PATCH 28/35] Exclude global_asm from mir_keys --- compiler/rustc_mir_transform/src/lib.rs | 4 ++++ .../asm/global-asm-isnt-really-a-mir-body.rs | 23 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/ui/asm/global-asm-isnt-really-a-mir-body.rs diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 04c9375b83176..4168557e12cae 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -316,6 +316,10 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { // All body-owners have MIR associated with them. let mut set: FxIndexSet<_> = tcx.hir_body_owners().collect(); + // Remove the fake bodies for `global_asm!`, since they're not useful + // to be emitted (`--emit=mir`) or encoded (in metadata). + set.retain(|&def_id| !matches!(tcx.def_kind(def_id), DefKind::GlobalAsm)); + // Coroutine-closures (e.g. async closures) have an additional by-move MIR // body that isn't in the HIR. for body_owner in tcx.hir_body_owners() { diff --git a/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs b/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs new file mode 100644 index 0000000000000..0b0f0319ad940 --- /dev/null +++ b/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs @@ -0,0 +1,23 @@ +//@ revisions: emit_mir instrument cfi + +// Make sure we don't try to emit MIR for it. +//@[emit_mir] compile-flags: --emit=mir + +// Make sure we don't try to instrument it. +//@[instrument] compile-flags: -Cinstrument-coverage -Zno-profiler-runtime +//@[instrument] only-linux + +// Make sure we don't try to CFI encode it. +//@[cfi] compile-flags: -Zsanitizer=cfi -Ccodegen-units=1 -Clto -Clink-dead-code=true +//@[cfi] needs-sanitizer-cfi +//@[cfi] no-prefer-dynamic + +//@ build-pass + +use std::arch::global_asm; + +fn foo() {} + +global_asm!("/* {} */", sym foo); + +fn main() {} From 09e584671b439dc8a9d57cc900cc26668a69ddea Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 24 Feb 2025 21:37:01 +0000 Subject: [PATCH 29/35] Also note struct access, and fix macro expansion from foreign crates --- .../src/hir_ty_lowering/errors.rs | 2 +- compiler/rustc_hir_typeck/src/expr.rs | 35 ++++++++++++------- .../rustc_hir_typeck/src/method/suggest.rs | 2 +- .../rustc_resolve/src/late/diagnostics.rs | 6 ++-- compiler/rustc_span/src/lib.rs | 12 +++++-- .../ui/structs/ident-from-macro-expansion.rs | 19 ++++++++++ .../structs/ident-from-macro-expansion.stderr | 14 ++++++++ 7 files changed, 72 insertions(+), 18 deletions(-) create mode 100644 tests/ui/structs/ident-from-macro-expansion.rs create mode 100644 tests/ui/structs/ident-from-macro-expansion.stderr diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 156ddb8f2aaba..6b9c1c0b309af 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -153,7 +153,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { sugg: None, // Try to get the span of the identifier within the path's syntax context // (if that's different). - within_macro_span: assoc_name.span.within_macro(span), + within_macro_span: assoc_name.span.within_macro(span, tcx.sess.source_map()), }; if is_dummy { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index dec1779d92ca4..7f67e524fc4a8 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3069,7 +3069,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, base_ty={:?}", ident, base, expr, base_ty ); - let mut err = self.no_such_field_err(ident, base_ty, base.hir_id); + let mut err = self.no_such_field_err(ident, base_ty, expr); match *base_ty.peel_refs().kind() { ty::Array(_, len) => { @@ -3282,18 +3282,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - fn no_such_field_err(&self, field: Ident, expr_t: Ty<'tcx>, id: HirId) -> Diag<'_> { + fn no_such_field_err( + &self, + field: Ident, + base_ty: Ty<'tcx>, + expr: &hir::Expr<'tcx>, + ) -> Diag<'_> { let span = field.span; - debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t); + debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, base_ty); - let mut err = self.dcx().create_err(NoFieldOnType { span, ty: expr_t, field }); - if expr_t.references_error() { + let mut err = self.dcx().create_err(NoFieldOnType { span, ty: base_ty, field }); + if base_ty.references_error() { err.downgrade_to_delayed_bug(); } + if let Some(within_macro_span) = span.within_macro(expr.span, self.tcx.sess.source_map()) { + err.span_label(within_macro_span, "due to this macro variable"); + } + // try to add a suggestion in case the field is a nested field of a field of the Adt - let mod_id = self.tcx.parent_module(id).to_def_id(); - let (ty, unwrap) = if let ty::Adt(def, args) = expr_t.kind() + let mod_id = self.tcx.parent_module(expr.hir_id).to_def_id(); + let (ty, unwrap) = if let ty::Adt(def, args) = base_ty.kind() && (self.tcx.is_diagnostic_item(sym::Result, def.did()) || self.tcx.is_diagnostic_item(sym::Option, def.did())) && let Some(arg) = args.get(0) @@ -3301,10 +3310,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { (ty, "unwrap().") } else { - (expr_t, "") + (base_ty, "") }; for (found_fields, args) in - self.get_field_candidates_considering_privacy_for_diag(span, ty, mod_id, id) + self.get_field_candidates_considering_privacy_for_diag(span, ty, mod_id, expr.hir_id) { let field_names = found_fields.iter().map(|field| field.name).collect::>(); let mut candidate_fields: Vec<_> = found_fields @@ -3317,7 +3326,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { args, vec![], mod_id, - id, + expr.hir_id, ) }) .map(|mut field_path| { @@ -3328,7 +3337,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { candidate_fields.sort(); let len = candidate_fields.len(); - if len > 0 { + // Don't suggest `.field` if the base expr is from a different + // syntax context than the field. + if len > 0 && expr.span.eq_ctxt(field.span) { err.span_suggestions( field.span.shrink_to_lo(), format!( @@ -3963,7 +3974,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => (), }; - self.no_such_field_err(field, container, expr.hir_id).emit(); + self.no_such_field_err(field, container, expr).emit(); break; } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 09e1390cc3ecd..cb1e89fb9e593 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -196,7 +196,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Try to get the span of the identifier within the expression's syntax context // (if that's different). - let within_macro_span = span.within_macro(expr_span); + let within_macro_span = span.within_macro(expr_span, self.tcx.sess.source_map()); // Avoid suggestions when we don't know what's going on. if let Err(guar) = rcvr_ty.error_reported() { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index c86305e23d1d7..47b21f86641ba 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -431,8 +431,10 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // Try to get the span of the identifier within the path's syntax context // (if that's different). - if let Some(within_macro_span) = base_error.span.within_macro(span) { - err.span_label(within_macro_span, "within this macro"); + if let Some(within_macro_span) = + base_error.span.within_macro(span, self.r.tcx.sess.source_map()) + { + err.span_label(within_macro_span, "due to this macro variable"); } self.detect_missing_binding_available_from_pattern(&mut err, path, following_seg); diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index d23e1825e6ea2..798e186a94b1a 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1071,9 +1071,17 @@ impl Span { /// /// If "self" is the span of the outer_ident, and "within" is the span of the `($ident,)` /// expr, then this will return the span of the `$ident` macro variable. - pub fn within_macro(self, within: Span) -> Option { + pub fn within_macro(self, within: Span, sm: &SourceMap) -> Option { match Span::prepare_to_combine(self, within) { - Ok((self_, _, parent)) if self_.lo != self.lo() && self.hi() != self_.hi => { + // Only return something if it doesn't overlap with the original span, + // and the span isn't "imported" (i.e. from unavailable sources). + // FIXME: This does limit the usefulness of the error when the macro is + // from a foreign crate; we could also take into account `-Zmacro-backtrace`, + // which doesn't redact this span (but that would mean passing in even more + // args to this function, lol). + Ok((self_, _, parent)) + if self_.hi < self.lo() || self.hi() < self_.lo && !sm.is_imported(within) => + { Some(Span::new(self_.lo, self_.hi, self_.ctxt, parent)) } _ => None, diff --git a/tests/ui/structs/ident-from-macro-expansion.rs b/tests/ui/structs/ident-from-macro-expansion.rs new file mode 100644 index 0000000000000..56d31a4256168 --- /dev/null +++ b/tests/ui/structs/ident-from-macro-expansion.rs @@ -0,0 +1,19 @@ +struct Foo { + inner: Inner, +} + +struct Inner { + y: i32, +} + +macro_rules! access { + ($expr:expr, $ident:ident) => { + $expr.$ident + } +} + +fn main() { + let k = Foo { inner: Inner { y: 0 } }; + access!(k, y); + //~^ ERROR no field `y` on type `Foo` +} diff --git a/tests/ui/structs/ident-from-macro-expansion.stderr b/tests/ui/structs/ident-from-macro-expansion.stderr new file mode 100644 index 0000000000000..be2ab7c2e9966 --- /dev/null +++ b/tests/ui/structs/ident-from-macro-expansion.stderr @@ -0,0 +1,14 @@ +error[E0609]: no field `y` on type `Foo` + --> $DIR/ident-from-macro-expansion.rs:17:16 + | +LL | $expr.$ident + | ------ due to this macro variable +... +LL | access!(k, y); + | ^ unknown field + | + = note: available field is: `inner` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0609`. From 69c46515edc86dea961e1565ee2b34311ddaeb35 Mon Sep 17 00:00:00 2001 From: MarcoIeni <11428655+MarcoIeni@users.noreply.github.com> Date: Tue, 4 Mar 2025 10:01:00 +0100 Subject: [PATCH 30/35] ci: use ubuntu 24 on arm large runner --- src/ci/github-actions/jobs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 1504e5c60ce7e..69a39b6eec2f7 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -54,7 +54,7 @@ runners: <<: *base-job - &job-aarch64-linux-8c - os: ubuntu-22.04-arm64-8core-32gb + os: ubuntu-24.04-arm64-8core-32gb <<: *base-job envs: env-x86_64-apple-tests: &env-x86_64-apple-tests From da3e73654f311869c052f218e37871a2f4381c85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Fri, 28 Feb 2025 20:54:10 +0100 Subject: [PATCH 31/35] Clarify why InhabitedPredicate::instantiate_opt exists At first glance, the extra casework seems pointless and needlessly error-prone. Clarify that there is a reason for it being there. --- .../rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index 505c7278176f3..86ef07dff5f29 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -236,6 +236,11 @@ impl<'tcx> InhabitedPredicate<'tcx> { self.instantiate_opt(tcx, args).unwrap_or(self) } + /// Same as [`Self::instantiate`], but if there is no generics to + /// instantiate, returns `None`. This is useful because it lets us avoid + /// allocating a recursive copy of everything when the result is unchanged. + /// + /// Only used to implement `instantiate` itself. fn instantiate_opt(self, tcx: TyCtxt<'tcx>, args: ty::GenericArgsRef<'tcx>) -> Option { match self { Self::ConstIsZero(c) => { From a3d63fb0d488e4db52e0fe672f0cf2040840f2e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Mon, 3 Mar 2025 23:52:22 +0100 Subject: [PATCH 32/35] InhabitedPredicate: avoid using a wildcard branch This is error-prone. Explicitly write down which cases don't need anything substituted. Turn the `OpaqueType` case, which currently seems to be unreachable, into a `bug!`. --- .../rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index 86ef07dff5f29..953ad62be0a86 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -265,7 +265,10 @@ impl<'tcx> InhabitedPredicate<'tcx> { Some(InhabitedPredicate::True) => Some(InhabitedPredicate::True), Some(a) => Some(a.or(tcx, b.instantiate_opt(tcx, args).unwrap_or(b))), }, - _ => None, + Self::True | Self::False | Self::NotInModule(_) => None, + Self::OpaqueType(_) => { + bug!("unexpected OpaqueType in InhabitedPredicate"); + } } } } From c392cf7690e08a56ff1fcea67b81b89bbc976045 Mon Sep 17 00:00:00 2001 From: pcorwin Date: Sun, 9 Feb 2025 22:00:31 -0500 Subject: [PATCH 33/35] Added documentation for flushing --- library/std/src/io/stdio.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 318c350822168..90ed49ff663e6 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -574,6 +574,11 @@ impl fmt::Debug for StdinLock<'_> { /// output stream. Access is also synchronized via a lock and explicit control /// over locking is available via the [`lock`] method. /// +/// By default, the handle is line-buffered when connected to a terminal, meaning +/// it flushes automatically when a newline (`\n`) is encountered. For immediate +/// output, you can manually call the [`flush`] method. When the handle goes out +/// of scope, the buffer is automatically flushed. +/// /// Created by the [`io::stdout`] method. /// /// ### Note: Windows Portability Considerations @@ -589,6 +594,7 @@ impl fmt::Debug for StdinLock<'_> { /// standard library or via raw Windows API calls, will fail. /// /// [`lock`]: Stdout::lock +/// [`flush`]: Write::flush /// [`io::stdout`]: stdout #[stable(feature = "rust1", since = "1.0.0")] pub struct Stdout { @@ -603,6 +609,11 @@ pub struct Stdout { /// This handle implements the [`Write`] trait, and is constructed via /// the [`Stdout::lock`] method. See its documentation for more. /// +/// By default, the handle is line-buffered when connected to a terminal, meaning +/// it flushes automatically when a newline (`\n`) is encountered. For immediate +/// output, you can manually call the [`flush`] method. When the handle goes out +/// of scope, the buffer is automatically flushed. +/// /// ### Note: Windows Portability Considerations /// /// When operating in a console, the Windows implementation of this stream does not support @@ -614,6 +625,8 @@ pub struct Stdout { /// the contained handle will be null. In such cases, the standard library's `Read` and /// `Write` will do nothing and silently succeed. All other I/O operations, via the /// standard library or via raw Windows API calls, will fail. +/// +/// [`flush`]: Write::flush #[must_use = "if unused stdout will immediately unlock"] #[stable(feature = "rust1", since = "1.0.0")] pub struct StdoutLock<'a> { @@ -628,6 +641,11 @@ static STDOUT: OnceLock>>> = OnceLoc /// is synchronized via a mutex. If you need more explicit control over /// locking, see the [`Stdout::lock`] method. /// +/// By default, the handle is line-buffered when connected to a terminal, meaning +/// it flushes automatically when a newline (`\n`) is encountered. For immediate +/// output, you can manually call the [`flush`] method. When the handle goes out +/// of scope, the buffer is automatically flushed. +/// /// ### Note: Windows Portability Considerations /// /// When operating in a console, the Windows implementation of this stream does not support @@ -668,6 +686,22 @@ static STDOUT: OnceLock>>> = OnceLoc /// Ok(()) /// } /// ``` +/// +/// Ensuring output is flushed immediately: +/// +/// ```no_run +/// use std::io::{self, Write}; +/// +/// fn main() -> io::Result<()> { +/// let mut stdout = io::stdout(); +/// stdout.write_all(b"hello, ")?; +/// stdout.flush()?; // Manual flush +/// stdout.write_all(b"world!\n")?; // Automatically flushed +/// Ok(()) +/// } +/// ``` +/// +/// [`flush`]: Write::flush #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "io_stdout")] From 3d62b279ddc2095b94aa5921540b27f3003365ff Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 28 Feb 2025 01:28:32 +0000 Subject: [PATCH 34/35] Ensure that negative auto impls are always applicable --- compiler/rustc_data_structures/src/marker.rs | 10 +- .../check/{dropck.rs => always_applicable.rs} | 149 +++++++++++++----- compiler/rustc_hir_analysis/src/check/mod.rs | 6 +- .../rustc_hir_analysis/src/coherence/mod.rs | 26 +-- compiler/rustc_middle/src/traits/mod.rs | 4 +- .../src/error_reporting/traits/suggestions.rs | 2 +- library/core/src/convert/mod.rs | 1 - ...herence-conflicting-negative-trait-impl.rs | 8 +- ...nce-conflicting-negative-trait-impl.stderr | 31 +++- ...mpl-trait-for-marker-trait-negative.stderr | 20 +-- tests/ui/coherence/coherence-orphan.rs | 5 +- .../coherence-overlap-negative-impls.rs | 4 +- .../coherence-overlap-negative-impls.stderr | 16 ++ tests/ui/issues/issue-106755.rs | 5 +- tests/ui/issues/issue-106755.stderr | 31 +++- .../specialization/defaultimpl/validation.rs | 15 +- .../defaultimpl/validation.stderr | 28 ++-- .../specialization-overlap-negative.rs | 4 +- .../specialization-overlap-negative.stderr | 17 +- 19 files changed, 275 insertions(+), 107 deletions(-) rename compiler/rustc_hir_analysis/src/check/{dropck.rs => always_applicable.rs} (62%) create mode 100644 tests/ui/coherence/coherence-overlap-negative-impls.stderr diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index 6ae97222f77fd..4cacc269709a9 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -1,3 +1,5 @@ +use std::alloc::Allocator; + #[rustc_on_unimplemented(message = "`{Self}` doesn't implement `DynSend`. \ Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Send`")] // This is an auto trait for types which can be sent across threads if `sync::is_dyn_thread_safe()` @@ -28,8 +30,8 @@ impls_dyn_send_neg!( [*const T where T: ?Sized] [*mut T where T: ?Sized] [std::ptr::NonNull where T: ?Sized] - [std::rc::Rc where T: ?Sized] - [std::rc::Weak where T: ?Sized] + [std::rc::Rc where T: ?Sized, A: Allocator] + [std::rc::Weak where T: ?Sized, A: Allocator] [std::sync::MutexGuard<'_, T> where T: ?Sized] [std::sync::RwLockReadGuard<'_, T> where T: ?Sized] [std::sync::RwLockWriteGuard<'_, T> where T: ?Sized] @@ -96,8 +98,8 @@ impls_dyn_sync_neg!( [std::cell::RefCell where T: ?Sized] [std::cell::UnsafeCell where T: ?Sized] [std::ptr::NonNull where T: ?Sized] - [std::rc::Rc where T: ?Sized] - [std::rc::Weak where T: ?Sized] + [std::rc::Rc where T: ?Sized, A: Allocator] + [std::rc::Weak where T: ?Sized, A: Allocator] [std::cell::OnceCell where T] [std::sync::mpsc::Receiver where T] [std::sync::mpsc::Sender where T] diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs similarity index 62% rename from compiler/rustc_hir_analysis/src/check/dropck.rs rename to compiler/rustc_hir_analysis/src/check/always_applicable.rs index d7dfe482da449..64377ffa34761 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/always_applicable.rs @@ -1,8 +1,15 @@ +//! This module contains methods that assist in checking that impls are general +//! enough, i.e. that they always apply to every valid instantaiton of the ADT +//! they're implemented for. +//! +//! This is necessary for `Drop` and negative impls to be well-formed. + use rustc_data_structures::fx::FxHashSet; use rustc_errors::codes::*; use rustc_errors::{ErrorGuaranteed, struct_span_code_err}; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_infer::traits::{ObligationCause, ObligationCauseCode}; +use rustc_middle::span_bug; use rustc_middle::ty::util::CheckRegions; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypingMode}; use rustc_trait_selection::regions::InferCtxtRegionExt; @@ -27,11 +34,12 @@ use crate::hir::def_id::{DefId, LocalDefId}; /// 3. Any bounds on the generic parameters must be reflected in the /// struct/enum definition for the nominal type itself (i.e. /// cannot do `struct S; impl Drop for S { ... }`). -/// pub(crate) fn check_drop_impl( tcx: TyCtxt<'_>, drop_impl_did: DefId, ) -> Result<(), ErrorGuaranteed> { + let drop_impl_did = drop_impl_did.expect_local(); + match tcx.impl_polarity(drop_impl_did) { ty::ImplPolarity::Positive => {} ty::ImplPolarity::Negative => { @@ -45,55 +53,107 @@ pub(crate) fn check_drop_impl( })); } } - let dtor_self_type = tcx.type_of(drop_impl_did).instantiate_identity(); - match dtor_self_type.kind() { + + tcx.ensure_ok().orphan_check_impl(drop_impl_did)?; + + let dtor_impl_trait_ref = tcx.impl_trait_ref(drop_impl_did).unwrap().instantiate_identity(); + + match dtor_impl_trait_ref.self_ty().kind() { ty::Adt(adt_def, adt_to_impl_args) => { - ensure_drop_params_and_item_params_correspond( + ensure_impl_params_and_item_params_correspond( tcx, - drop_impl_did.expect_local(), + drop_impl_did, adt_def.did(), adt_to_impl_args, )?; - ensure_drop_predicates_are_implied_by_item_defn( + ensure_impl_predicates_are_implied_by_item_defn( tcx, - drop_impl_did.expect_local(), - adt_def.did().expect_local(), + drop_impl_did, + adt_def.did(), adt_to_impl_args, ) } _ => { - // Destructors only work on nominal types. This was - // already checked by coherence, but compilation may - // not have been terminated. - let span = tcx.def_span(drop_impl_did); - let reported = tcx.dcx().span_delayed_bug( - span, - format!("should have been rejected by coherence check: {dtor_self_type}"), - ); - Err(reported) + span_bug!(tcx.def_span(drop_impl_did), "incoherent impl of Drop"); } } } -fn ensure_drop_params_and_item_params_correspond<'tcx>( +pub(crate) fn check_negative_auto_trait_impl<'tcx>( tcx: TyCtxt<'tcx>, - drop_impl_did: LocalDefId, - self_type_did: DefId, + impl_def_id: LocalDefId, + impl_trait_ref: ty::TraitRef<'tcx>, + polarity: ty::ImplPolarity, +) -> Result<(), ErrorGuaranteed> { + let ty::ImplPolarity::Negative = polarity else { + return Ok(()); + }; + + if !tcx.trait_is_auto(impl_trait_ref.def_id) { + return Ok(()); + } + + if tcx.defaultness(impl_def_id).is_default() { + tcx.dcx().span_delayed_bug(tcx.def_span(impl_def_id), "default impl cannot be negative"); + } + + tcx.ensure_ok().orphan_check_impl(impl_def_id)?; + + match impl_trait_ref.self_ty().kind() { + ty::Adt(adt_def, adt_to_impl_args) => { + ensure_impl_params_and_item_params_correspond( + tcx, + impl_def_id, + adt_def.did(), + adt_to_impl_args, + )?; + + ensure_impl_predicates_are_implied_by_item_defn( + tcx, + impl_def_id, + adt_def.did(), + adt_to_impl_args, + ) + } + _ => { + if tcx.features().auto_traits() { + // NOTE: We ignore the applicability check for negative auto impls + // defined in libcore. In the (almost impossible) future where we + // stabilize auto impls, then the proper applicability check MUST + // be implemented here to handle non-ADT rigid types. + Ok(()) + } else { + span_bug!(tcx.def_span(impl_def_id), "incoherent impl of negative auto trait"); + } + } + } +} + +fn ensure_impl_params_and_item_params_correspond<'tcx>( + tcx: TyCtxt<'tcx>, + impl_def_id: LocalDefId, + adt_def_id: DefId, adt_to_impl_args: GenericArgsRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_args, CheckRegions::OnlyParam) else { return Ok(()); }; - let drop_impl_span = tcx.def_span(drop_impl_did); - let item_span = tcx.def_span(self_type_did); - let self_descr = tcx.def_descr(self_type_did); + let drop_impl_span = tcx.def_span(impl_def_id); + let item_span = tcx.def_span(adt_def_id); + let self_descr = tcx.def_descr(adt_def_id); + let polarity = match tcx.impl_polarity(impl_def_id) { + ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "", + ty::ImplPolarity::Negative => "!", + }; + let trait_name = tcx + .item_name(tcx.trait_id_of_impl(impl_def_id.to_def_id()).expect("expected impl of trait")); let mut err = struct_span_code_err!( tcx.dcx(), drop_impl_span, E0366, - "`Drop` impls cannot be specialized" + "`{polarity}{trait_name}` impls cannot be specialized", ); match arg { ty::util::NotUniqueParam::DuplicateParam(arg) => { @@ -116,17 +176,22 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( /// Confirms that all predicates defined on the `Drop` impl (`drop_impl_def_id`) are able to be /// proven from within `adt_def_id`'s environment. I.e. all the predicates on the impl are /// implied by the ADT being well formed. -fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( +fn ensure_impl_predicates_are_implied_by_item_defn<'tcx>( tcx: TyCtxt<'tcx>, - drop_impl_def_id: LocalDefId, - adt_def_id: LocalDefId, + impl_def_id: LocalDefId, + adt_def_id: DefId, adt_to_impl_args: GenericArgsRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let ocx = ObligationCtxt::new_with_diagnostics(&infcx); - let impl_span = tcx.def_span(drop_impl_def_id.to_def_id()); - + let impl_span = tcx.def_span(impl_def_id.to_def_id()); + let trait_name = tcx + .item_name(tcx.trait_id_of_impl(impl_def_id.to_def_id()).expect("expected impl of trait")); + let polarity = match tcx.impl_polarity(impl_def_id) { + ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "", + ty::ImplPolarity::Negative => "!", + }; // Take the param-env of the adt and instantiate the args that show up in // the implementation's self type. This gives us the assumptions that the // self ty of the implementation is allowed to know just from it being a @@ -145,17 +210,21 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( let adt_env = ty::EarlyBinder::bind(tcx.param_env(adt_def_id)).instantiate(tcx, adt_to_impl_args); - let fresh_impl_args = infcx.fresh_args_for_item(impl_span, drop_impl_def_id.to_def_id()); + let fresh_impl_args = infcx.fresh_args_for_item(impl_span, impl_def_id.to_def_id()); let fresh_adt_ty = - tcx.impl_trait_ref(drop_impl_def_id).unwrap().instantiate(tcx, fresh_impl_args).self_ty(); + tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(tcx, fresh_impl_args).self_ty(); ocx.eq(&ObligationCause::dummy_with_span(impl_span), adt_env, fresh_adt_ty, impl_adt_ty) - .unwrap(); + .expect("equating fully generic trait ref should never fail"); - for (clause, span) in tcx.predicates_of(drop_impl_def_id).instantiate(tcx, fresh_impl_args) { - let normalize_cause = traits::ObligationCause::misc(span, adt_def_id); + for (clause, span) in tcx.predicates_of(impl_def_id).instantiate(tcx, fresh_impl_args) { + let normalize_cause = traits::ObligationCause::misc(span, impl_def_id); let pred = ocx.normalize(&normalize_cause, adt_env, clause); - let cause = traits::ObligationCause::new(span, adt_def_id, ObligationCauseCode::DropImpl); + let cause = traits::ObligationCause::new( + span, + impl_def_id, + ObligationCauseCode::AlwaysApplicableImpl, + ); ocx.register_obligation(traits::Obligation::new(tcx, cause, adt_env, pred)); } @@ -173,13 +242,13 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( let root_predicate = error.root_obligation.predicate; if root_predicates.insert(root_predicate) { let item_span = tcx.def_span(adt_def_id); - let self_descr = tcx.def_descr(adt_def_id.to_def_id()); + let self_descr = tcx.def_descr(adt_def_id); guar = Some( struct_span_code_err!( tcx.dcx(), error.root_obligation.cause.span, E0367, - "`Drop` impl requires `{root_predicate}` \ + "`{polarity}{trait_name}` impl requires `{root_predicate}` \ but the {self_descr} it is implemented for does not", ) .with_span_note(item_span, "the implementor must specify the same requirement") @@ -190,12 +259,12 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( return Err(guar.unwrap()); } - let errors = ocx.infcx.resolve_regions(adt_def_id, adt_env, []); + let errors = ocx.infcx.resolve_regions(impl_def_id, adt_env, []); if !errors.is_empty() { let mut guar = None; for error in errors { let item_span = tcx.def_span(adt_def_id); - let self_descr = tcx.def_descr(adt_def_id.to_def_id()); + let self_descr = tcx.def_descr(adt_def_id); let outlives = match error { RegionResolutionError::ConcreteFailure(_, a, b) => format!("{b}: {a}"), RegionResolutionError::GenericBoundFailure(_, generic, r) => { @@ -212,7 +281,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( tcx.dcx(), error.origin().span(), E0367, - "`Drop` impl requires `{outlives}` \ + "`{polarity}{trait_name}` impl requires `{outlives}` \ but the {self_descr} it is implemented for does not", ) .with_span_note(item_span, "the implementor must specify the same requirement") diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 1c5455710db8a..d72d5b4fa19d4 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -62,9 +62,9 @@ a type parameter). */ +pub mod always_applicable; mod check; mod compare_impl_item; -pub mod dropck; mod entry; pub mod intrinsic; pub mod intrinsicck; @@ -113,11 +113,11 @@ pub fn provide(providers: &mut Providers) { } fn adt_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { - tcx.calculate_dtor(def_id.to_def_id(), dropck::check_drop_impl) + tcx.calculate_dtor(def_id.to_def_id(), always_applicable::check_drop_impl) } fn adt_async_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { - tcx.calculate_async_dtor(def_id.to_def_id(), dropck::check_drop_impl) + tcx.calculate_async_dtor(def_id.to_def_id(), always_applicable::check_drop_impl) } /// Given a `DefId` for an opaque type in return position, find its parent item's return diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 0245d4c9fe4b6..b5c6c2f386192 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -16,6 +16,7 @@ use rustc_span::{ErrorGuaranteed, sym}; use rustc_type_ir::elaborate; use tracing::debug; +use crate::check::always_applicable; use crate::errors; mod builtin; @@ -24,11 +25,12 @@ mod inherent_impls_overlap; mod orphan; mod unsafety; -fn check_impl( - tcx: TyCtxt<'_>, +fn check_impl<'tcx>( + tcx: TyCtxt<'tcx>, impl_def_id: LocalDefId, - trait_ref: ty::TraitRef<'_>, - trait_def: &ty::TraitDef, + trait_ref: ty::TraitRef<'tcx>, + trait_def: &'tcx ty::TraitDef, + polarity: ty::ImplPolarity, ) -> Result<(), ErrorGuaranteed> { debug!( "(checking implementation) adding impl for trait '{:?}', item '{}'", @@ -44,6 +46,12 @@ fn check_impl( enforce_trait_manually_implementable(tcx, impl_def_id, trait_ref.def_id, trait_def) .and(enforce_empty_impls_for_marker_traits(tcx, impl_def_id, trait_ref.def_id, trait_def)) + .and(always_applicable::check_negative_auto_trait_impl( + tcx, + impl_def_id, + trait_ref, + polarity, + )) } fn enforce_trait_manually_implementable( @@ -154,16 +162,16 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> let mut res = tcx.ensure_ok().specialization_graph_of(def_id); for &impl_def_id in impls { - let trait_header = tcx.impl_trait_header(impl_def_id).unwrap(); - let trait_ref = trait_header.trait_ref.instantiate_identity(); + let impl_header = tcx.impl_trait_header(impl_def_id).unwrap(); + let trait_ref = impl_header.trait_ref.instantiate_identity(); let trait_def = tcx.trait_def(trait_ref.def_id); res = res - .and(check_impl(tcx, impl_def_id, trait_ref, trait_def)) + .and(check_impl(tcx, impl_def_id, trait_ref, trait_def, impl_header.polarity)) .and(check_object_overlap(tcx, impl_def_id, trait_ref)) - .and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def)) + .and(unsafety::check_item(tcx, impl_def_id, impl_header, trait_def)) .and(tcx.ensure_ok().orphan_check_impl(impl_def_id)) - .and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header)); + .and(builtin::check_trait(tcx, def_id, impl_def_id, impl_header)); } res diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index d033ecc75dbe5..af38748d5b2a6 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -397,9 +397,9 @@ pub enum ObligationCauseCode<'tcx> { RustCall, - /// Obligations to prove that a `std::ops::Drop` impl is not stronger than + /// Obligations to prove that a `Drop` or negative auto trait impl is not stronger than /// the ADT it's being implemented for. - DropImpl, + AlwaysApplicableImpl, /// Requirement for a `const N: Ty` to implement `Ty: ConstParamTy` ConstParam(Ty<'tcx>), diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index b85c18c53121f..0178400414cb2 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -2695,7 +2695,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { | ObligationCauseCode::LetElse | ObligationCauseCode::BinOp { .. } | ObligationCauseCode::AscribeUserTypeProvePredicate(..) - | ObligationCauseCode::DropImpl + | ObligationCauseCode::AlwaysApplicableImpl | ObligationCauseCode::ConstParam(_) | ObligationCauseCode::ReferenceOutlivesReferent(..) | ObligationCauseCode::ObjectTypeBound(..) => {} diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index e468f4f0f7e66..43fd54f881dae 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -778,7 +778,6 @@ impl From for T { /// /// [#64715]: https://github.com/rust-lang/rust/issues/64715 #[stable(feature = "convert_infallible", since = "1.34.0")] -#[allow(unused_attributes)] // FIXME(#58633): do a principled fix instead. #[rustc_reservation_impl = "permitting this impl would forbid us from adding \ `impl From for T` later; see rust-lang/rust#64715 for details"] impl From for T { diff --git a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs index 24b878927530c..15ca0577e4acb 100644 --- a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs +++ b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs @@ -8,10 +8,14 @@ struct TestType(::std::marker::PhantomData); unsafe impl Send for TestType {} -impl !Send for TestType {} //~ ERROR found both positive and negative implementation +impl !Send for TestType {} +//~^ ERROR found both positive and negative implementation +//~| ERROR `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not -unsafe impl Send for TestType {} //~ ERROR conflicting implementations +unsafe impl Send for TestType {} +//~^ ERROR conflicting implementations impl !Send for TestType {} +//~^ ERROR `!Send` impls cannot be specialized fn main() {} diff --git a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr index 2463f38a92251..c6aed150201d8 100644 --- a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr +++ b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr @@ -8,7 +8,7 @@ LL | impl !Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>` - --> $DIR/coherence-conflicting-negative-trait-impl.rs:13:1 + --> $DIR/coherence-conflicting-negative-trait-impl.rs:15:1 | LL | unsafe impl Send for TestType {} | ------------------------------------------------------ first implementation here @@ -16,7 +16,32 @@ LL | unsafe impl Send for TestType {} LL | unsafe impl Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>` -error: aborting due to 2 previous errors +error[E0367]: `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not + --> $DIR/coherence-conflicting-negative-trait-impl.rs:11:9 + | +LL | impl !Send for TestType {} + | ^^^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/coherence-conflicting-negative-trait-impl.rs:7:1 + | +LL | struct TestType(::std::marker::PhantomData); + | ^^^^^^^^^^^^^^^^^^ + +error[E0366]: `!Send` impls cannot be specialized + --> $DIR/coherence-conflicting-negative-trait-impl.rs:18:1 + | +LL | impl !Send for TestType {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `i32` is not a generic parameter +note: use the same sequence of generic lifetime, type and const parameters as the struct definition + --> $DIR/coherence-conflicting-negative-trait-impl.rs:7:1 + | +LL | struct TestType(::std::marker::PhantomData); + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0119, E0751. +Some errors have detailed explanations: E0119, E0366, E0367, E0751. For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr b/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr index 77d1bdee5acf1..bc81dd6f286dd 100644 --- a/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr +++ b/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr @@ -1,9 +1,3 @@ -error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1` - --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1 - | -LL | impl !Marker1 for dyn Object + Marker2 {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1` - error[E0321]: traits with a default impl, like `Marker1`, cannot be implemented for trait object `(dyn Object + Marker2 + 'static)` --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1 | @@ -12,11 +6,11 @@ LL | impl !Marker1 for dyn Object + Marker2 {} | = note: a trait object implements `Marker1` if and only if `Marker1` is one of the trait object's trait bounds -error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2` - --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:18:1 +error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1` + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1 | -LL | impl !Marker2 for dyn Object + Marker2 {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2` +LL | impl !Marker1 for dyn Object + Marker2 {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1` error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + Marker2 + 'static)` --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:18:1 @@ -26,6 +20,12 @@ LL | impl !Marker2 for dyn Object + Marker2 {} | = note: a trait object implements `Marker2` if and only if `Marker2` is one of the trait object's trait bounds +error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2` + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:18:1 + | +LL | impl !Marker2 for dyn Object + Marker2 {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2` + error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + 'static)` --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:26:1 | diff --git a/tests/ui/coherence/coherence-orphan.rs b/tests/ui/coherence/coherence-orphan.rs index aee6647a78819..665fa15c56e53 100644 --- a/tests/ui/coherence/coherence-orphan.rs +++ b/tests/ui/coherence/coherence-orphan.rs @@ -8,12 +8,13 @@ use lib::TheTrait; struct TheType; impl TheTrait for isize {} -//~^ ERROR E0117 +//~^ ERROR only traits defined in the current crate can be implemented for primitive types impl TheTrait for isize {} impl TheTrait for TheType {} -impl !Send for Vec {} //~ ERROR E0117 +impl !Send for Vec {} +//~^ ERROR only traits defined in the current crate can be implemented for types defined outside of the crate fn main() {} diff --git a/tests/ui/coherence/coherence-overlap-negative-impls.rs b/tests/ui/coherence/coherence-overlap-negative-impls.rs index ffcd56817e5c2..ba90a37cb2aab 100644 --- a/tests/ui/coherence/coherence-overlap-negative-impls.rs +++ b/tests/ui/coherence/coherence-overlap-negative-impls.rs @@ -1,6 +1,3 @@ -//@ check-pass -//@ known-bug: #74629 - // Should fail. The `0` and `1` impls overlap, violating coherence. Eg, with // `T = Test, F = ()`, all bounds are true, making both impls applicable. // `Test: Fold`, `Test: Fold<()>` are true because of `2`. @@ -39,6 +36,7 @@ mod private { pub auto trait NotNil {} impl !NotNil for Is {} + //~^ ERROR `!NotNil` impls cannot be specialized } fn main() {} diff --git a/tests/ui/coherence/coherence-overlap-negative-impls.stderr b/tests/ui/coherence/coherence-overlap-negative-impls.stderr new file mode 100644 index 0000000000000..fe22cf61b753c --- /dev/null +++ b/tests/ui/coherence/coherence-overlap-negative-impls.stderr @@ -0,0 +1,16 @@ +error[E0366]: `!NotNil` impls cannot be specialized + --> $DIR/coherence-overlap-negative-impls.rs:38:5 + | +LL | impl !NotNil for Is {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Nil` is not a generic parameter +note: use the same sequence of generic lifetime, type and const parameters as the struct definition + --> $DIR/coherence-overlap-negative-impls.rs:35:5 + | +LL | pub struct Is(T); + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0366`. diff --git a/tests/ui/issues/issue-106755.rs b/tests/ui/issues/issue-106755.rs index 689b1d885ae60..d7e7122ebda16 100644 --- a/tests/ui/issues/issue-106755.rs +++ b/tests/ui/issues/issue-106755.rs @@ -10,10 +10,13 @@ struct TestType(::std::marker::PhantomData); unsafe impl Send for TestType {} -impl !Send for TestType {} //~ ERROR found both positive and negative implementation +impl !Send for TestType {} +//~^ ERROR found both positive and negative implementation +//~| ERROR `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not unsafe impl Send for TestType {} //~ ERROR conflicting implementations impl !Send for TestType {} +//~^ ERROR `!Send` impls cannot be specialized fn main() {} diff --git a/tests/ui/issues/issue-106755.stderr b/tests/ui/issues/issue-106755.stderr index 543970340620d..da6b8c5c56325 100644 --- a/tests/ui/issues/issue-106755.stderr +++ b/tests/ui/issues/issue-106755.stderr @@ -8,7 +8,7 @@ LL | impl !Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>` - --> $DIR/issue-106755.rs:15:1 + --> $DIR/issue-106755.rs:17:1 | LL | unsafe impl Send for TestType {} | ------------------------------------------------------ first implementation here @@ -16,7 +16,32 @@ LL | unsafe impl Send for TestType {} LL | unsafe impl Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>` -error: aborting due to 2 previous errors +error[E0367]: `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not + --> $DIR/issue-106755.rs:13:9 + | +LL | impl !Send for TestType {} + | ^^^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/issue-106755.rs:9:1 + | +LL | struct TestType(::std::marker::PhantomData); + | ^^^^^^^^^^^^^^^^^^ + +error[E0366]: `!Send` impls cannot be specialized + --> $DIR/issue-106755.rs:19:1 + | +LL | impl !Send for TestType {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `i32` is not a generic parameter +note: use the same sequence of generic lifetime, type and const parameters as the struct definition + --> $DIR/issue-106755.rs:9:1 + | +LL | struct TestType(::std::marker::PhantomData); + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0119, E0751. +Some errors have detailed explanations: E0119, E0366, E0367, E0751. For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/defaultimpl/validation.rs b/tests/ui/specialization/defaultimpl/validation.rs index 4049c4ea14c5b..14771be8982dd 100644 --- a/tests/ui/specialization/defaultimpl/validation.rs +++ b/tests/ui/specialization/defaultimpl/validation.rs @@ -6,12 +6,17 @@ struct Z; default impl S {} //~ ERROR inherent impls cannot be `default` -default unsafe impl Send for S {} //~ ERROR impls of auto traits cannot be default -//~^ ERROR `S` cannot be sent between threads safely -default impl !Send for Z {} //~ ERROR impls of auto traits cannot be default - //~^ ERROR negative impls cannot be default impls +default unsafe impl Send for S {} +//~^ ERROR impls of auto traits cannot be default + +default impl !Send for Z {} +//~^ ERROR impls of auto traits cannot be default +//~| ERROR negative impls cannot be default impls +//~| ERROR `!Send` impl requires `Z: Send` but the struct it is implemented for does not trait Tr {} -default impl !Tr for S {} //~ ERROR negative impls cannot be default impls + +default impl !Tr for S {} +//~^ ERROR negative impls cannot be default impls fn main() {} diff --git a/tests/ui/specialization/defaultimpl/validation.stderr b/tests/ui/specialization/defaultimpl/validation.stderr index f56f16162a27f..d034386b842f3 100644 --- a/tests/ui/specialization/defaultimpl/validation.stderr +++ b/tests/ui/specialization/defaultimpl/validation.stderr @@ -26,22 +26,20 @@ LL | default unsafe impl Send for S {} | | | default because of this -error[E0277]: `S` cannot be sent between threads safely - --> $DIR/validation.rs:9:1 +error[E0367]: `!Send` impl requires `Z: Send` but the struct it is implemented for does not + --> $DIR/validation.rs:12:1 | -LL | default unsafe impl Send for S {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `S` cannot be sent between threads safely - | - = help: the trait `Send` is not implemented for `S` - = help: the trait `Send` is implemented for `S` - = help: see issue #48214 -help: add `#![feature(trivial_bounds)]` to the crate attributes to enable +LL | default impl !Send for Z {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ | -LL + #![feature(trivial_bounds)] +note: the implementor must specify the same requirement + --> $DIR/validation.rs:5:1 | +LL | struct Z; + | ^^^^^^^^ error: impls of auto traits cannot be default - --> $DIR/validation.rs:11:15 + --> $DIR/validation.rs:12:15 | LL | default impl !Send for Z {} | ------- ^^^^ auto trait @@ -49,18 +47,18 @@ LL | default impl !Send for Z {} | default because of this error[E0750]: negative impls cannot be default impls - --> $DIR/validation.rs:11:1 + --> $DIR/validation.rs:12:1 | LL | default impl !Send for Z {} | ^^^^^^^ ^ error[E0750]: negative impls cannot be default impls - --> $DIR/validation.rs:15:1 + --> $DIR/validation.rs:19:1 | LL | default impl !Tr for S {} | ^^^^^^^ ^ error: aborting due to 6 previous errors; 1 warning emitted -Some errors have detailed explanations: E0277, E0750. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0367, E0750. +For more information about an error, try `rustc --explain E0367`. diff --git a/tests/ui/specialization/specialization-overlap-negative.rs b/tests/ui/specialization/specialization-overlap-negative.rs index 550d370829539..244f21c7ba905 100644 --- a/tests/ui/specialization/specialization-overlap-negative.rs +++ b/tests/ui/specialization/specialization-overlap-negative.rs @@ -6,6 +6,8 @@ trait MyTrait {} struct TestType(::std::marker::PhantomData); unsafe impl Send for TestType {} -impl !Send for TestType {} //~ ERROR E0751 +impl !Send for TestType {} +//~^ ERROR found both positive and negative implementation of trait `Send` for type `TestType<_>` +//~| ERROR `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not fn main() {} diff --git a/tests/ui/specialization/specialization-overlap-negative.stderr b/tests/ui/specialization/specialization-overlap-negative.stderr index a8e99953e2b65..4874e897726fc 100644 --- a/tests/ui/specialization/specialization-overlap-negative.stderr +++ b/tests/ui/specialization/specialization-overlap-negative.stderr @@ -16,6 +16,19 @@ LL | unsafe impl Send for TestType {} LL | impl !Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here -error: aborting due to 1 previous error; 1 warning emitted +error[E0367]: `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not + --> $DIR/specialization-overlap-negative.rs:9:9 + | +LL | impl !Send for TestType {} + | ^^^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/specialization-overlap-negative.rs:6:1 + | +LL | struct TestType(::std::marker::PhantomData); + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0751`. +Some errors have detailed explanations: E0367, E0751. +For more information about an error, try `rustc --explain E0367`. From 05a80608b36f71f49e6cc8d586f54c023264ac12 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 28 Feb 2025 02:43:12 +0000 Subject: [PATCH 35/35] Make rustdoc tests use always applicable negative auto impls --- .../src/check/always_applicable.rs | 4 +- tests/rustdoc/impl-parts-crosscrate.rs | 2 +- tests/rustdoc/impl-parts.rs | 2 +- .../coherence-overlap-negative-impls.rs | 42 --------------- .../coherence-overlap-negative-impls.stderr | 16 ------ .../negated-auto-traits-validity-error.rs | 22 ++++++++ .../negated-auto-traits-validity-error.stderr | 54 +++++++++++++++++++ .../negated-auto-traits-validity.rs | 22 ++++++++ 8 files changed, 102 insertions(+), 62 deletions(-) delete mode 100644 tests/ui/coherence/coherence-overlap-negative-impls.rs delete mode 100644 tests/ui/coherence/coherence-overlap-negative-impls.stderr create mode 100644 tests/ui/traits/negative-impls/negated-auto-traits-validity-error.rs create mode 100644 tests/ui/traits/negative-impls/negated-auto-traits-validity-error.stderr create mode 100644 tests/ui/traits/negative-impls/negated-auto-traits-validity.rs diff --git a/compiler/rustc_hir_analysis/src/check/always_applicable.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs index 64377ffa34761..ba5b61d3fce0b 100644 --- a/compiler/rustc_hir_analysis/src/check/always_applicable.rs +++ b/compiler/rustc_hir_analysis/src/check/always_applicable.rs @@ -140,7 +140,7 @@ fn ensure_impl_params_and_item_params_correspond<'tcx>( return Ok(()); }; - let drop_impl_span = tcx.def_span(impl_def_id); + let impl_span = tcx.def_span(impl_def_id); let item_span = tcx.def_span(adt_def_id); let self_descr = tcx.def_descr(adt_def_id); let polarity = match tcx.impl_polarity(impl_def_id) { @@ -151,7 +151,7 @@ fn ensure_impl_params_and_item_params_correspond<'tcx>( .item_name(tcx.trait_id_of_impl(impl_def_id.to_def_id()).expect("expected impl of trait")); let mut err = struct_span_code_err!( tcx.dcx(), - drop_impl_span, + impl_span, E0366, "`{polarity}{trait_name}` impls cannot be specialized", ); diff --git a/tests/rustdoc/impl-parts-crosscrate.rs b/tests/rustdoc/impl-parts-crosscrate.rs index 49752ab75d512..631c8bb3eb318 100644 --- a/tests/rustdoc/impl-parts-crosscrate.rs +++ b/tests/rustdoc/impl-parts-crosscrate.rs @@ -5,7 +5,7 @@ extern crate rustdoc_impl_parts_crosscrate; -pub struct Bar { t: T } +pub struct Bar { t: T } // The output file is html embedded in javascript, so the html tags // aren't stripped by the processing script and we can't check for the diff --git a/tests/rustdoc/impl-parts.rs b/tests/rustdoc/impl-parts.rs index 820f51008a40c..4f281bfd63c83 100644 --- a/tests/rustdoc/impl-parts.rs +++ b/tests/rustdoc/impl-parts.rs @@ -3,7 +3,7 @@ pub auto trait AnAutoTrait {} -pub struct Foo { field: T } +pub struct Foo { field: T } //@ has impl_parts/struct.Foo.html '//*[@class="impl"]//h3[@class="code-header"]' \ // "impl !AnAutoTrait for Foowhere T: Sync + Clone," diff --git a/tests/ui/coherence/coherence-overlap-negative-impls.rs b/tests/ui/coherence/coherence-overlap-negative-impls.rs deleted file mode 100644 index ba90a37cb2aab..0000000000000 --- a/tests/ui/coherence/coherence-overlap-negative-impls.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Should fail. The `0` and `1` impls overlap, violating coherence. Eg, with -// `T = Test, F = ()`, all bounds are true, making both impls applicable. -// `Test: Fold`, `Test: Fold<()>` are true because of `2`. -// `Is: NotNil` is true because of `auto trait` and lack of negative impl. - -#![feature(negative_impls)] -#![feature(auto_traits)] - -struct Nil; -struct Cons(H); -struct Test; - -trait Fold {} - -impl Fold for Cons -// 0 -where - T: Fold, -{ -} - -impl Fold for Cons -// 1 -where - T: Fold, - private::Is: private::NotNil, -{ -} - -impl Fold for Test {} // 2 - -mod private { - use crate::Nil; - - pub struct Is(T); - pub auto trait NotNil {} - - impl !NotNil for Is {} - //~^ ERROR `!NotNil` impls cannot be specialized -} - -fn main() {} diff --git a/tests/ui/coherence/coherence-overlap-negative-impls.stderr b/tests/ui/coherence/coherence-overlap-negative-impls.stderr deleted file mode 100644 index fe22cf61b753c..0000000000000 --- a/tests/ui/coherence/coherence-overlap-negative-impls.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0366]: `!NotNil` impls cannot be specialized - --> $DIR/coherence-overlap-negative-impls.rs:38:5 - | -LL | impl !NotNil for Is {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `Nil` is not a generic parameter -note: use the same sequence of generic lifetime, type and const parameters as the struct definition - --> $DIR/coherence-overlap-negative-impls.rs:35:5 - | -LL | pub struct Is(T); - | ^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0366`. diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.rs b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.rs new file mode 100644 index 0000000000000..cd675a5efd162 --- /dev/null +++ b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.rs @@ -0,0 +1,22 @@ +#![feature(auto_traits, negative_impls)] + +auto trait Foo {} + +struct AdditionalLt<'a, T>(&'a (), T); +impl<'a, T: 'a> !Foo for AdditionalLt<'a, T> {} +//~^ ERROR `!Foo` impl requires `T: 'a` but the struct it is implemented for does not + +struct AdditionalBound(T); +trait Bound {} +impl !Foo for AdditionalBound {} +//~^ ERROR `!Foo` impl requires `T: Bound` but the struct it is implemented for does not + +struct TwoParam(T, U); +impl !Foo for TwoParam {} +//~^ ERROR `!Foo` impls cannot be specialized + +struct ConcreteParam(T); +impl !Foo for ConcreteParam {} +//~^ ERROR `!Foo` impls cannot be specialized + +fn main() {} diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.stderr b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.stderr new file mode 100644 index 0000000000000..ef783e9015592 --- /dev/null +++ b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.stderr @@ -0,0 +1,54 @@ +error[E0367]: `!Foo` impl requires `T: 'a` but the struct it is implemented for does not + --> $DIR/negated-auto-traits-validity-error.rs:6:13 + | +LL | impl<'a, T: 'a> !Foo for AdditionalLt<'a, T> {} + | ^^ + | +note: the implementor must specify the same requirement + --> $DIR/negated-auto-traits-validity-error.rs:5:1 + | +LL | struct AdditionalLt<'a, T>(&'a (), T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0367]: `!Foo` impl requires `T: Bound` but the struct it is implemented for does not + --> $DIR/negated-auto-traits-validity-error.rs:11:9 + | +LL | impl !Foo for AdditionalBound {} + | ^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/negated-auto-traits-validity-error.rs:9:1 + | +LL | struct AdditionalBound(T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0366]: `!Foo` impls cannot be specialized + --> $DIR/negated-auto-traits-validity-error.rs:15:1 + | +LL | impl !Foo for TwoParam {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `T` is mentioned multiple times +note: use the same sequence of generic lifetime, type and const parameters as the struct definition + --> $DIR/negated-auto-traits-validity-error.rs:14:1 + | +LL | struct TwoParam(T, U); + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0366]: `!Foo` impls cannot be specialized + --> $DIR/negated-auto-traits-validity-error.rs:19:1 + | +LL | impl !Foo for ConcreteParam {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `i32` is not a generic parameter +note: use the same sequence of generic lifetime, type and const parameters as the struct definition + --> $DIR/negated-auto-traits-validity-error.rs:18:1 + | +LL | struct ConcreteParam(T); + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0366, E0367. +For more information about an error, try `rustc --explain E0366`. diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-validity.rs b/tests/ui/traits/negative-impls/negated-auto-traits-validity.rs new file mode 100644 index 0000000000000..76996b5593e60 --- /dev/null +++ b/tests/ui/traits/negative-impls/negated-auto-traits-validity.rs @@ -0,0 +1,22 @@ +//@ check-pass + +#![feature(auto_traits, negative_impls)] + +auto trait Foo {} +auto trait Bar {} + +struct NeedsOutlives<'a, T>(&'a T); + +impl<'a, T: 'a> !Foo for NeedsOutlives<'a, T> {} + +// Leaving out the lifetime bound +impl<'a, T> !Bar for NeedsOutlives<'a, T> {} + +struct NeedsSend(T); + +impl !Foo for NeedsSend {} + +// Leaving off the trait bound +impl !Bar for NeedsSend {} + +fn main() {}