From ae174cf351beece10b20a614497e3853058fdb53 Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Mon, 7 Sep 2026 11:15:39 -0700 Subject: [PATCH 1/9] Make `std::fs::{File, ReadDir, DirEntry}` always `needs_drop` even when unsupported. This eliminates the portability hazard (and inconsistent linting of `clippy::drop_non_drop`) of types having destructors on some platforms and not others. It is arguably a breaking change, but a breaking change that would also be required if any of these platforms later gains filesystem support. An alternative to this change would be to implement `Drop` on the `std::fs` types instead of the `std::sys` types. That would be more reliable, but would be more of a public API change since `T: Drop` bounds are unfortunately possible. --- library/std/src/sys/fs/unsupported.rs | 19 +++++++++++++++++++ library/std/src/sys/fs/vexos.rs | 7 +++++++ 2 files changed, 26 insertions(+) diff --git a/library/std/src/sys/fs/unsupported.rs b/library/std/src/sys/fs/unsupported.rs index 512af27401dfe..b0ad9a9c96dc8 100644 --- a/library/std/src/sys/fs/unsupported.rs +++ b/library/std/src/sys/fs/unsupported.rs @@ -29,6 +29,25 @@ pub struct FileType(!); #[derive(Debug)] pub struct DirBuilder {} +// Dummy Drops so that `needs_drop::()` etc. is true independent of platform, +// avoiding a portability hazard. +// The types not listed here are pure data and don’t implement Drop even when real. +impl Drop for File { + fn drop(&mut self) { + self.0 + } +} +impl Drop for ReadDir { + fn drop(&mut self) { + self.0 + } +} +impl Drop for DirEntry { + fn drop(&mut self) { + self.0 + } +} + impl FileAttr { pub fn size(&self) -> u64 { self.0 diff --git a/library/std/src/sys/fs/vexos.rs b/library/std/src/sys/fs/vexos.rs index 1357787c44c77..c2417627c0b9d 100644 --- a/library/std/src/sys/fs/vexos.rs +++ b/library/std/src/sys/fs/vexos.rs @@ -477,6 +477,13 @@ impl Drop for File { } } +impl Drop for ReadDir { + fn drop(&mut self) { + // Dummy Drop so that `needs_drop::()` is true independent of platform. + self.0 + } +} + pub fn readdir(_p: &Path) -> io::Result { // While there *is* a userspace function for reading file directories, // the necessary implementation cannot currently be done cleanly, as From 9da36d0ca22939409424266e55df40706db5fcdc Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 5 Oct 2026 17:37:30 +0200 Subject: [PATCH 2/9] Collect all limit attributes during TyCtxt creation --- compiler/rustc_interface/src/limits.rs | 53 +++++++++++++------ compiler/rustc_interface/src/passes.rs | 27 +++------- compiler/rustc_middle/src/queries.rs | 1 + .../feature-gate-large-assignments.rs | 1 + .../feature-gate-large-assignments.stderr | 13 ++++- .../feature-gate-pattern-complexity-limit.rs | 4 ++ ...ature-gate-pattern-complexity-limit.stderr | 13 ++++- 7 files changed, 74 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_interface/src/limits.rs b/compiler/rustc_interface/src/limits.rs index a0791bb22df6d..a97aef1a66058 100644 --- a/compiler/rustc_interface/src/limits.rs +++ b/compiler/rustc_interface/src/limits.rs @@ -8,28 +8,51 @@ //! Users can override these limits via an attribute on the crate like //! `#![recursion_limit="22"]`. This pass just looks for those attributes. +use rustc_ast::{self as ast, DUMMY_NODE_ID}; +use rustc_attr_ir::target::Target; use rustc_attr_ir::{Attribute, find_attr}; -use rustc_middle::query::Providers; +use rustc_attr_parsing::{AttributeParser, ShouldEmit}; +use rustc_feature::Features; use rustc_session::{Limits, Session}; +use rustc_span::{DUMMY_SP, sym}; use rustc_structures::Limit; -pub(crate) fn provide(providers: &mut Providers) { - providers.limits = |tcx, ()| { - let attrs = tcx.hir_krate_attrs(); - Limits { - recursion_limit: get_recursion_limit(tcx.hir_krate_attrs(), tcx.sess), - move_size_limit: find_attr!(attrs, MoveSizeLimit { limit } => *limit) - .unwrap_or(Limit::new(tcx.sess.opts.unstable_opts.move_size_limit.unwrap_or(0))), - type_length_limit: find_attr!(attrs, TypeLengthLimit { limit } => *limit) - .unwrap_or(Limit::new(2usize.pow(24))), - pattern_complexity_limit: find_attr!(attrs, PatternComplexityLimit { limit } => *limit) - .unwrap_or(Limit::unlimited()), - } +pub fn get_limits(krate_attrs: &[ast::Attribute], sess: &Session, features: &Features) -> Limits { + let attrs = AttributeParser::parse_limited_all( + sess, + &krate_attrs, + Some(&|attr| { + attr.has_any_name(&[ + sym::recursion_limit, + sym::move_size_limit, + sym::type_length_limit, + sym::pattern_complexity_limit, + ]) + }), + Target::Crate, + DUMMY_SP, + DUMMY_NODE_ID, + Some(features), + // errors are fatal here, but lints aren't. + // If things aren't fatal we continue, and will parse this again. + // That makes the same lint trigger again. + // So, no lints here to avoid duplicates. + ShouldEmit::EarlyFatal { also_emit_lints: false }, + None, + ); + let attrs = &attrs; + Limits { + recursion_limit: get_recursion_limit(attrs, sess), + move_size_limit: find_attr!(attrs, MoveSizeLimit { limit } => *limit) + .unwrap_or(Limit::new(sess.opts.unstable_opts.move_size_limit.unwrap_or(0))), + type_length_limit: find_attr!(attrs, TypeLengthLimit { limit } => *limit) + .unwrap_or(Limit::new(2usize.pow(24))), + pattern_complexity_limit: find_attr!(attrs, PatternComplexityLimit { limit } => *limit) + .unwrap_or(Limit::unlimited()), } } -// This one is separate because it must be read prior to macro expansion. -pub(crate) fn get_recursion_limit(attrs: &[Attribute], sess: &Session) -> Limit { +fn get_recursion_limit(attrs: &[Attribute], sess: &Session) -> Limit { let limit_from_crate = find_attr!(attrs, RecursionLimit { limit } => limit.0).unwrap_or(128); Limit::new( sess.opts diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 8975f01de5216..b828a609bc02a 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -44,7 +44,7 @@ use rustc_session::{IncrCompSession, Session}; use rustc_span::{ DUMMY_SP, ErrorGuaranteed, ExpnKind, SourceFileHash, SourceFileHashAlgorithm, Span, Symbol, sym, }; -use rustc_structures::{CrateType, Limit}; +use rustc_structures::CrateType; use rustc_trait_selection::{solve, traits}; use tracing::{info, instrument}; @@ -199,7 +199,7 @@ fn configure_and_expand( } // Create the config for macro expansion - let recursion_limit = get_recursion_limit(pre_configured_attrs, sess); + let recursion_limit = tcx.recursion_limit(); let cfg = rustc_expand::expand::ExpansionConfig { crate_name, features, @@ -899,7 +899,6 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock = LazyLock::new(|| { providers.queries.env_var_os = env_var_os; providers.queries.proc_macro_decls_static = |tcx, _| tcx.hir_crate_items(()).proc_macro_decls(); rustc_ast_lowering::provide(&mut providers.queries); - limits::provide(&mut providers.queries); rustc_expand_queries::provide(&mut providers.queries); rustc_const_eval::provide(providers); rustc_middle::hir::provide(&mut providers.queries); @@ -1026,11 +1025,13 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( feed.crate_name(crate_name); let feed = tcx.feed_unit_query(); - feed.features_query(tcx.arena.alloc(rustc_expand::config::features( + let features = tcx.arena.alloc(rustc_expand::config::features( tcx.sess, &pre_configured_attrs, crate_name, - ))); + )); + feed.features_query(features); + feed.limits(limits::get_limits(&pre_configured_attrs, tcx.sess, features)); feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs)))); feed.output_filenames(Arc::new(outputs)); @@ -1512,19 +1513,3 @@ pub fn collect_crate_types( fn default_output_for_target(sess: &Session) -> CrateType { if !sess.target.executables { CrateType::StaticLib } else { CrateType::Executable } } - -fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit { - let attr = AttributeParser::parse_limited_sym_should_emit( - sess, - &krate_attrs, - &[sym::recursion_limit], - DUMMY_SP, - None, - // errors are fatal here, but lints aren't. - // If things aren't fatal we continue, and will parse this again. - // That makes the same lint trigger again. - // So, no lints here to avoid duplicates. - ShouldEmit::EarlyFatal { also_emit_lints: false }, - ); - crate::limits::get_recursion_limit(attr.as_slice(), sess) -} diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index d0429df43d1dd..4632c3ca1fc12 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -2721,6 +2721,7 @@ rustc_queries! { } query limits(key: ()) -> Limits { + feedable desc { "looking up limits" } } diff --git a/tests/ui/feature-gates/feature-gate-large-assignments.rs b/tests/ui/feature-gates/feature-gate-large-assignments.rs index 3c284ca3cafbd..dc37b8735410b 100644 --- a/tests/ui/feature-gates/feature-gate-large-assignments.rs +++ b/tests/ui/feature-gates/feature-gate-large-assignments.rs @@ -1,5 +1,6 @@ // check that `move_size_limit` is feature-gated #![move_size_limit = "42"] //~ ERROR the `move_size_limit` attribute is an experimental feature +//~^ ERROR the `move_size_limit` attribute is an experimental feature fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-large-assignments.stderr b/tests/ui/feature-gates/feature-gate-large-assignments.stderr index 350afcc0d63ad..6ec13a4f5342e 100644 --- a/tests/ui/feature-gates/feature-gate-large-assignments.stderr +++ b/tests/ui/feature-gates/feature-gate-large-assignments.stderr @@ -8,6 +8,17 @@ LL | #![move_size_limit = "42"] = help: add `#![feature(large_assignments)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 1 previous error +error[E0658]: the `move_size_limit` attribute is an experimental feature + --> $DIR/feature-gate-large-assignments.rs:3:4 + | +LL | #![move_size_limit = "42"] + | ^^^^^^^^^^^^^^^ + | + = note: see issue #83518 for more information + = help: add `#![feature(large_assignments)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-pattern-complexity-limit.rs b/tests/ui/feature-gates/feature-gate-pattern-complexity-limit.rs index 972312a497fa2..5a04749132ce2 100644 --- a/tests/ui/feature-gates/feature-gate-pattern-complexity-limit.rs +++ b/tests/ui/feature-gates/feature-gate-pattern-complexity-limit.rs @@ -2,7 +2,11 @@ #![pattern_complexity_limit = "42"] //~^ ERROR: use of an internal attribute [E0658] +//~| ERROR: use of an internal attribute [E0658] //~| NOTE the `pattern_complexity_limit` attribute is an internal implementation detail that will never be stable //~| NOTE: the `pattern_complexity_limit` attribute is used for rustc unit tests +//~| NOTE the `pattern_complexity_limit` attribute is an internal implementation detail that will never be stable +//~| NOTE: the `pattern_complexity_limit` attribute is used for rustc unit tests +//~| NOTE: duplicate diagnostic fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-pattern-complexity-limit.stderr b/tests/ui/feature-gates/feature-gate-pattern-complexity-limit.stderr index 7faf38d842e7f..82c57be8ec4e4 100644 --- a/tests/ui/feature-gates/feature-gate-pattern-complexity-limit.stderr +++ b/tests/ui/feature-gates/feature-gate-pattern-complexity-limit.stderr @@ -8,6 +8,17 @@ LL | #![pattern_complexity_limit = "42"] = note: the `pattern_complexity_limit` attribute is an internal implementation detail that will never be stable = note: the `pattern_complexity_limit` attribute is used for rustc unit tests -error: aborting due to 1 previous error +error[E0658]: use of an internal attribute + --> $DIR/feature-gate-pattern-complexity-limit.rs:3:4 + | +LL | #![pattern_complexity_limit = "42"] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable + = note: the `pattern_complexity_limit` attribute is an internal implementation detail that will never be stable + = note: the `pattern_complexity_limit` attribute is used for rustc unit tests + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. From ac009afffb35abcd8a0f528499a961873f4e8cba Mon Sep 17 00:00:00 2001 From: Yilin Chen <1479826151@qq.com> Date: Tue, 13 Oct 2026 11:30:06 +0800 Subject: [PATCH 3/9] make the safety documentation consistent in task::LocalWaker --- library/core/src/task/wake.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 1dbd11426e57e..635917ea6973b 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -843,9 +843,10 @@ impl LocalWaker { /// Creates a new `LocalWaker` from [`RawWaker`]. /// + /// # Safety + /// /// The behavior of the returned `LocalWaker` is undefined if the contract defined /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld. - /// Therefore this method is unsafe. #[inline] #[must_use] #[unstable(feature = "local_waker", issue = "118959")] From 9a6401d330d255a3ff85d7037dc614e2ecff42fa Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Thu, 15 Oct 2026 08:19:52 -0400 Subject: [PATCH 4/9] Add missing full stop --- library/core/src/hash/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index f1a93a880e7f4..dbec6035e5217 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -436,7 +436,7 @@ pub trait Hasher { /// writing its contents to this `Hasher`. That way /// `(collection![1, 2, 3], collection![4, 5])` and /// `(collection![1, 2], collection![3, 4, 5])` will provide different - /// sequences of values to the `Hasher` + /// sequences of values to the `Hasher`. /// /// The `impl Hash for [T]` includes a call to this method, so if you're /// hashing a slice (or array or vector) via its `Hash::hash` method, From ec9a24815acda76536120e8aabacaeb710ab7b4c Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Thu, 15 Oct 2026 18:48:54 +0200 Subject: [PATCH 5/9] core: hint: fix `unlikely`'s example polarity typo The line did not seem to get updated when the example was likely copy-pasted from the `likely()` one. Thus fix it. Signed-off-by: Miguel Ojeda --- library/core/src/hint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 616bdd9a97b7c..247e1430de3ed 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -704,7 +704,7 @@ pub const fn likely(b: bool) -> bool { /// // Use outside of a branch condition may still influence a nearby branch /// let cond = unlikely(x != 0); /// if cond { -/// println!("this branch is likely to be taken"); +/// println!("this branch is unlikely to be taken"); /// } /// } /// ``` From fd920982ac3a7d526306756bc334112767630082 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Fri, 16 Oct 2026 15:17:43 +0800 Subject: [PATCH 6/9] Add ui test for issue 164169 --- ...-loop-explain-borrow-error-issue-164169.rs | 31 +++++++++++++++++++ ...p-explain-borrow-error-issue-164169.stderr | 24 ++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.rs create mode 100644 tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.stderr diff --git a/tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.rs b/tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.rs new file mode 100644 index 0000000000000..447c00393884f --- /dev/null +++ b/tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.rs @@ -0,0 +1,31 @@ +//@ check-fail + +use std::path::PathBuf; + +type Test = Option<(PathBuf, Vec)>; + +fn test1(backend: &mut Vec) -> Result<(), String> { + let mut backend2 = Vec::new(); + for b in backend { + backend2.push(match b { + None => None, + Some((file, bytes)) => Some((file.as_path(), bytes)), + }); + } + + loop { + test2(&mut backend2)?; //~ ERROR E0499 + } +} + +fn test2<'a, P, C>(disks: &'a mut [Option<(P, &'a mut Vec)>]) -> Result { + todo!() +} + +fn test3<'a, P, C>(disks: &'a mut [Option<(P, &'a mut Vec)>]) -> Result { + loop { + test2(disks)?; //~ ERROR E0499 + } +} + +fn main() {} diff --git a/tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.stderr b/tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.stderr new file mode 100644 index 0000000000000..4084ed7e13680 --- /dev/null +++ b/tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.stderr @@ -0,0 +1,24 @@ +error[E0499]: cannot borrow `backend2` as mutable more than once at a time + --> $DIR/wrong-loop-explain-borrow-error-issue-164169.rs:17:15 + | +LL | backend2.push(match b { + | -------- first borrow used here, in later iteration of loop +... +LL | test2(&mut backend2)?; + | ^^^^^^^^^^^^^ `backend2` was mutably borrowed here in the previous iteration of the loop + +error[E0499]: cannot borrow `*disks` as mutable more than once at a time + --> $DIR/wrong-loop-explain-borrow-error-issue-164169.rs:27:15 + | +LL | fn test3<'a, P, C>(disks: &'a mut [Option<(P, &'a mut Vec)>]) -> Result { + | -- lifetime `'a` defined here +LL | loop { +LL | test2(disks)?; + | ------^^^^^- + | | | + | | `*disks` was mutably borrowed here in the previous iteration of the loop + | argument requires that `*disks` is borrowed for `'a` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0499`. From ad1fd473c5db072c80c793fcab135aaf6e21659c Mon Sep 17 00:00:00 2001 From: xizheyin Date: Fri, 16 Oct 2026 16:22:02 +0800 Subject: [PATCH 7/9] skip wrong loops when explaining borrow errors --- .../rustc_borrowck/src/diagnostics/explain_borrow.rs | 2 +- .../rustc_borrowck/src/region_infer/region_context.rs | 11 +++++++---- .../wrong-loop-explain-borrow-error-issue-164169.rs | 2 +- ...rong-loop-explain-borrow-error-issue-164169.stderr | 8 ++++---- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 706a60d84f402..bdd22ab7a2524 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -610,7 +610,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { // loop iteration. In this case, try using the loop terminator location in // `find_sub_region_live_at`. if let Some(loop_terminator_location) = - regioncx.find_loop_terminator_location(borrow.region, body) + regioncx.find_loop_terminator_location(borrow.region, body, location) { region_sub = self .regioncx diff --git a/compiler/rustc_borrowck/src/region_infer/region_context.rs b/compiler/rustc_borrowck/src/region_infer/region_context.rs index 327acb7da3fb8..6f29c42eed249 100644 --- a/compiler/rustc_borrowck/src/region_infer/region_context.rs +++ b/compiler/rustc_borrowck/src/region_infer/region_context.rs @@ -816,16 +816,19 @@ impl<'tcx> RegionInferenceContextInner<'tcx> { &self, r: RegionVid, body: &Body<'_>, + from_location: Location, ) -> Option { let scc = self.constraint_sccs.scc(r); let locations = self.scc_values.locations_outlived_by(scc); for location in locations { - let bb = &body[location.block]; - if let Some(terminator) = &bb.terminator + if from_location.is_predecessor_of(location, body) { + let bb = &body[location.block]; + if let Some(terminator) = &bb.terminator // terminator of a loop should be TerminatorKind::FalseUnwind && let TerminatorKind::FalseUnwind { .. } = terminator.kind - { - return Some(location); + { + return Some(location); + } } } None diff --git a/tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.rs b/tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.rs index 447c00393884f..82599a84df661 100644 --- a/tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.rs +++ b/tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.rs @@ -1,5 +1,5 @@ //@ check-fail - +//@ forbid-output: backend2.push( use std::path::PathBuf; type Test = Option<(PathBuf, Vec)>; diff --git a/tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.stderr b/tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.stderr index 4084ed7e13680..92026d3aedec8 100644 --- a/tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.stderr +++ b/tests/ui/borrowck/wrong-loop-explain-borrow-error-issue-164169.stderr @@ -1,11 +1,11 @@ error[E0499]: cannot borrow `backend2` as mutable more than once at a time --> $DIR/wrong-loop-explain-borrow-error-issue-164169.rs:17:15 | -LL | backend2.push(match b { - | -------- first borrow used here, in later iteration of loop -... LL | test2(&mut backend2)?; - | ^^^^^^^^^^^^^ `backend2` was mutably borrowed here in the previous iteration of the loop + | ^^^^^^^^^^^^^ + | | + | `backend2` was mutably borrowed here in the previous iteration of the loop + | first borrow used here, in later iteration of loop error[E0499]: cannot borrow `*disks` as mutable more than once at a time --> $DIR/wrong-loop-explain-borrow-error-issue-164169.rs:27:15 From 8c284bdf468db1345149ae419f9dddf71ba7037e Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 9 Oct 2026 13:24:24 +0800 Subject: [PATCH 8/9] Fix test pattern column placement and alignment There's some inconsistent formatting, and also patterns in the wrong column when the columns are intended to be * Has sign/zero extension attribute, versus * No sign/zero extension attribute. This is a precursor commit to make things less confusing. The test is still weak for return attributes. --- .../some-abis-do-extend-params-to-32-bits.rs | 100 +++++++++--------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs b/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs index 79be3bd5f57b4..3b2060b2bbde5 100644 --- a/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs +++ b/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs @@ -39,8 +39,8 @@ use minicore::*; // x86_64-uefi: void @c_arg_bool(i1 zeroext %_a) // i686: void @c_arg_bool(i1 zeroext %_a) // aarch64-apple: void @c_arg_bool(i1 zeroext %_a) -// aarch64-windows: void @c_arg_bool(i1 %_a) -// aarch64-linux: void @c_arg_bool(i1 %_a) +// aarch64-windows: void @c_arg_bool(i1 %_a) +// aarch64-linux: void @c_arg_bool(i1 %_a) // arm: void @c_arg_bool(i1 zeroext %_a) // riscv: void @c_arg_bool(i1 zeroext %_a) #[no_mangle] @@ -50,8 +50,8 @@ pub extern "C" fn c_arg_bool(_a: bool) {} // x86_64-uefi: void @c_arg_u8(i8 zeroext %_a) // i686: void @c_arg_u8(i8 zeroext %_a) // aarch64-apple: void @c_arg_u8(i8 zeroext %_a) -// aarch64-windows: void @c_arg_u8(i8 %_a) -// aarch64-linux: void @c_arg_u8(i8 %_a) +// aarch64-windows: void @c_arg_u8(i8 %_a) +// aarch64-linux: void @c_arg_u8(i8 %_a) // arm: void @c_arg_u8(i8 zeroext %_a) // riscv: void @c_arg_u8(i8 zeroext %_a) #[no_mangle] @@ -68,25 +68,25 @@ pub extern "C" fn c_arg_u8(_a: u8) {} #[no_mangle] pub extern "C" fn c_arg_u16(_a: u16) {} -// x86_64-linux: void @c_arg_u32(i32 %_a) -// x86_64-uefi: void @c_arg_u32(i32 %_a) -// i686: void @c_arg_u32(i32 %_a) -// aarch64-apple: void @c_arg_u32(i32 %_a) +// x86_64-linux: void @c_arg_u32(i32 %_a) +// x86_64-uefi: void @c_arg_u32(i32 %_a) +// i686: void @c_arg_u32(i32 %_a) +// aarch64-apple: void @c_arg_u32(i32 %_a) // aarch64-windows: void @c_arg_u32(i32 %_a) // aarch64-linux: void @c_arg_u32(i32 %_a) -// arm: void @c_arg_u32(i32 %_a) +// arm: void @c_arg_u32(i32 %_a) // riscv: void @c_arg_u32(i32 signext %_a) #[no_mangle] pub extern "C" fn c_arg_u32(_a: u32) {} -// x86_64-linux: void @c_arg_u64(i64 %_a) -// x86_64-uefi: void @c_arg_u64(i64 %_a) -// i686: void @c_arg_u64(i64 %_a) -// aarch64-apple: void @c_arg_u64(i64 %_a) +// x86_64-linux: void @c_arg_u64(i64 %_a) +// x86_64-uefi: void @c_arg_u64(i64 %_a) +// i686: void @c_arg_u64(i64 %_a) +// aarch64-apple: void @c_arg_u64(i64 %_a) // aarch64-windows: void @c_arg_u64(i64 %_a) // aarch64-linux: void @c_arg_u64(i64 %_a) -// arm: void @c_arg_u64(i64 %_a) -// riscv: void @c_arg_u64(i64 %_a) +// arm: void @c_arg_u64(i64 %_a) +// riscv: void @c_arg_u64(i64 %_a) #[no_mangle] pub extern "C" fn c_arg_u64(_a: u64) {} @@ -94,8 +94,8 @@ pub extern "C" fn c_arg_u64(_a: u64) {} // x86_64-uefi: void @c_arg_i8(i8 signext %_a) // i686: void @c_arg_i8(i8 signext %_a) // aarch64-apple: void @c_arg_i8(i8 signext %_a) -// aarch64-windows: void @c_arg_i8(i8 %_a) -// aarch64-linux: void @c_arg_i8(i8 %_a) +// aarch64-windows: void @c_arg_i8(i8 %_a) +// aarch64-linux: void @c_arg_i8(i8 %_a) // arm: void @c_arg_i8(i8 signext %_a) // riscv: void @c_arg_i8(i8 signext %_a) #[no_mangle] @@ -112,25 +112,25 @@ pub extern "C" fn c_arg_i8(_a: i8) {} #[no_mangle] pub extern "C" fn c_arg_i16(_a: i16) {} -// x86_64-linux: void @c_arg_i32(i32 %_a) -// x86_64-uefi: void @c_arg_i32(i32 %_a) -// i686: void @c_arg_i32(i32 %_a) -// aarch64-apple: void @c_arg_i32(i32 %_a) +// x86_64-linux: void @c_arg_i32(i32 %_a) +// x86_64-uefi: void @c_arg_i32(i32 %_a) +// i686: void @c_arg_i32(i32 %_a) +// aarch64-apple: void @c_arg_i32(i32 %_a) // aarch64-windows: void @c_arg_i32(i32 %_a) // aarch64-linux: void @c_arg_i32(i32 %_a) -// arm: void @c_arg_i32(i32 %_a) +// arm: void @c_arg_i32(i32 %_a) // riscv: void @c_arg_i32(i32 signext %_a) #[no_mangle] pub extern "C" fn c_arg_i32(_a: i32) {} -// x86_64-linux: void @c_arg_i64(i64 %_a) -// x86_64-uefi: void @c_arg_i64(i64 %_a) -// i686: void @c_arg_i64(i64 %_a) -// aarch64-apple: void @c_arg_i64(i64 %_a) +// x86_64-linux: void @c_arg_i64(i64 %_a) +// x86_64-uefi: void @c_arg_i64(i64 %_a) +// i686: void @c_arg_i64(i64 %_a) +// aarch64-apple: void @c_arg_i64(i64 %_a) // aarch64-windows: void @c_arg_i64(i64 %_a) // aarch64-linux: void @c_arg_i64(i64 %_a) -// arm: void @c_arg_i64(i64 %_a) -// riscv: void @c_arg_i64(i64 %_a) +// arm: void @c_arg_i64(i64 %_a) +// riscv: void @c_arg_i64(i64 %_a) #[no_mangle] pub extern "C" fn c_arg_i64(_a: i64) {} @@ -173,27 +173,27 @@ pub extern "C" fn c_ret_u16() -> u16 { 0 } -// x86_64-linux: i32 @c_ret_u32() -// x86_64-uefi: i32 @c_ret_u32() -// i686: i32 @c_ret_u32() -// aarch64-apple: i32 @c_ret_u32() +// x86_64-linux: i32 @c_ret_u32() +// x86_64-uefi: i32 @c_ret_u32() +// i686: i32 @c_ret_u32() +// aarch64-apple: i32 @c_ret_u32() // aarch64-windows: i32 @c_ret_u32() // aarch64-linux: i32 @c_ret_u32() -// arm: i32 @c_ret_u32() +// arm: i32 @c_ret_u32() // riscv: signext i32 @c_ret_u32() #[no_mangle] pub extern "C" fn c_ret_u32() -> u32 { 0 } -// x86_64-linux: i64 @c_ret_u64() -// x86_64-uefi: i64 @c_ret_u64() -// i686: i64 @c_ret_u64() -// aarch64-apple: i64 @c_ret_u64() +// x86_64-linux: i64 @c_ret_u64() +// x86_64-uefi: i64 @c_ret_u64() +// i686: i64 @c_ret_u64() +// aarch64-apple: i64 @c_ret_u64() // aarch64-windows: i64 @c_ret_u64() // aarch64-linux: i64 @c_ret_u64() -// arm: i64 @c_ret_u64() -// riscv: i64 @c_ret_u64() +// arm: i64 @c_ret_u64() +// riscv: i64 @c_ret_u64() #[no_mangle] pub extern "C" fn c_ret_u64() -> u64 { 0 @@ -225,27 +225,27 @@ pub extern "C" fn c_ret_i16() -> i16 { 0 } -// x86_64-linux: i32 @c_ret_i32() -// x86_64-uefi: i32 @c_ret_i32() -// i686: i32 @c_ret_i32() -// aarch64-apple: i32 @c_ret_i32() +// x86_64-linux: i32 @c_ret_i32() +// x86_64-uefi: i32 @c_ret_i32() +// i686: i32 @c_ret_i32() +// aarch64-apple: i32 @c_ret_i32() // aarch64-windows: i32 @c_ret_i32() // aarch64-linux: i32 @c_ret_i32() -// arm: i32 @c_ret_i32() +// arm: i32 @c_ret_i32() // riscv: signext i32 @c_ret_i32() #[no_mangle] pub extern "C" fn c_ret_i32() -> i32 { 0 } -// x86_64-linux: i64 @c_ret_i64() -// x86_64-uefi: i64 @c_ret_i64() -// i686: i64 @c_ret_i64() -// aarch64-apple: i64 @c_ret_i64() +// x86_64-linux: i64 @c_ret_i64() +// x86_64-uefi: i64 @c_ret_i64() +// i686: i64 @c_ret_i64() +// aarch64-apple: i64 @c_ret_i64() // aarch64-windows: i64 @c_ret_i64() // aarch64-linux: i64 @c_ret_i64() -// arm: i64 @c_ret_i64() -// riscv: i64 @c_ret_i64() +// arm: i64 @c_ret_i64() +// riscv: i64 @c_ret_i64() #[no_mangle] pub extern "C" fn c_ret_i64() -> i64 { 0 From b02b1775b63c15fc62a1cbf69ad0f51fb94275a1 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 9 Oct 2026 13:31:31 +0800 Subject: [PATCH 9/9] Tighten patterns to actually check for absence of return attribute The patterns in `tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs` were previously too weak as they matched a substring. Previously, the test uses a pattern like ``` i32 @c_ret_u32() ``` with the intention to check for absence of `zeroext` or `signext` when the attribute is not expected. However, this is a substring pattern match, so the pattern would actually match ``` zeroext i32 @c_ret_u32() ``` which is the very attribute the test wants to check the *absence* of. To fix this, use a stronger pattern ``` define {{(dso_local )?}}i32 @c_ret_u32() ``` that will not match against the presence of `zeroext`/`signext` return attributes. --- .../some-abis-do-extend-params-to-32-bits.rs | 94 ++++++++++--------- 1 file changed, 50 insertions(+), 44 deletions(-) diff --git a/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs b/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs index 3b2060b2bbde5..fa4f1cc969f89 100644 --- a/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs +++ b/tests/codegen-llvm/some-abis-do-extend-params-to-32-bits.rs @@ -33,6 +33,12 @@ use minicore::*; // The patterns in this file are written in the style of a table to make the // uniformities and distinctions more apparent. // +// NB: to check for **absence** of a return attribute, use a pattern +// `define {{(dso_local )?}}i1 @c_ret_bool()` and not just +// `i1 @c_ret_bool()`. Checking for `zeroext` in the substring +// `i1 @c_ret_bool()` will match `zeroext i1 @c_ret_bool()`, which is the +// opposite of your intention. +// // ZERO/SIGN-EXTENDING TO 32 BITS NON-EXTENDING // ============================== ======================= // x86_64-linux: void @c_arg_bool(i1 zeroext %_a) @@ -138,8 +144,8 @@ pub extern "C" fn c_arg_i64(_a: i64) {} // x86_64-uefi: zeroext i1 @c_ret_bool() // i686: zeroext i1 @c_ret_bool() // aarch64-apple: zeroext i1 @c_ret_bool() -// aarch64-windows: i1 @c_ret_bool() -// aarch64-linux: i1 @c_ret_bool() +// aarch64-windows: define {{(dso_local )?}}i1 @c_ret_bool() +// aarch64-linux: define {{(dso_local )?}}i1 @c_ret_bool() // arm: zeroext i1 @c_ret_bool() // riscv: zeroext i1 @c_ret_bool() #[no_mangle] @@ -147,12 +153,12 @@ pub extern "C" fn c_ret_bool() -> bool { false } -// x86_64-linux: i8 @c_ret_u8() +// x86_64-linux: define {{(dso_local )?}}i8 @c_ret_u8() // x86_64-uefi: zeroext i8 @c_ret_u8() // i686: zeroext i8 @c_ret_u8() // aarch64-apple: zeroext i8 @c_ret_u8() -// aarch64-windows: i8 @c_ret_u8() -// aarch64-linux: i8 @c_ret_u8() +// aarch64-windows: define {{(dso_local )?}}i8 @c_ret_u8() +// aarch64-linux: define {{(dso_local )?}}i8 @c_ret_u8() // arm: zeroext i8 @c_ret_u8() // riscv: zeroext i8 @c_ret_u8() #[no_mangle] @@ -160,12 +166,12 @@ pub extern "C" fn c_ret_u8() -> u8 { 0 } -// x86_64-linux: i16 @c_ret_u16() +// x86_64-linux: define {{(dso_local )?}}i16 @c_ret_u16() // x86_64-uefi: zeroext i16 @c_ret_u16() // i686: zeroext i16 @c_ret_u16() // aarch64-apple: zeroext i16 @c_ret_u16() -// aarch64-windows: i16 @c_ret_u16() -// aarch64-linux: i16 @c_ret_u16() +// aarch64-windows: define {{(dso_local )?}}i16 @c_ret_u16() +// aarch64-linux: define {{(dso_local )?}}i16 @c_ret_u16() // arm: zeroext i16 @c_ret_u16() // riscv: zeroext i16 @c_ret_u16() #[no_mangle] @@ -173,38 +179,38 @@ pub extern "C" fn c_ret_u16() -> u16 { 0 } -// x86_64-linux: i32 @c_ret_u32() -// x86_64-uefi: i32 @c_ret_u32() -// i686: i32 @c_ret_u32() -// aarch64-apple: i32 @c_ret_u32() -// aarch64-windows: i32 @c_ret_u32() -// aarch64-linux: i32 @c_ret_u32() -// arm: i32 @c_ret_u32() +// x86_64-linux: define {{(dso_local )?}}i32 @c_ret_u32() +// x86_64-uefi: define {{(dso_local )?}}i32 @c_ret_u32() +// i686: define {{(dso_local )?}}i32 @c_ret_u32() +// aarch64-apple: define {{(dso_local )?}}i32 @c_ret_u32() +// aarch64-windows: define {{(dso_local )?}}i32 @c_ret_u32() +// aarch64-linux: define {{(dso_local )?}}i32 @c_ret_u32() +// arm: define {{(dso_local )?}}i32 @c_ret_u32() // riscv: signext i32 @c_ret_u32() #[no_mangle] pub extern "C" fn c_ret_u32() -> u32 { 0 } -// x86_64-linux: i64 @c_ret_u64() -// x86_64-uefi: i64 @c_ret_u64() -// i686: i64 @c_ret_u64() -// aarch64-apple: i64 @c_ret_u64() -// aarch64-windows: i64 @c_ret_u64() -// aarch64-linux: i64 @c_ret_u64() -// arm: i64 @c_ret_u64() -// riscv: i64 @c_ret_u64() +// x86_64-linux: define {{(dso_local )?}}i64 @c_ret_u64() +// x86_64-uefi: define {{(dso_local )?}}i64 @c_ret_u64() +// i686: define {{(dso_local )?}}i64 @c_ret_u64() +// aarch64-apple: define {{(dso_local )?}}i64 @c_ret_u64() +// aarch64-windows: define {{(dso_local )?}}i64 @c_ret_u64() +// aarch64-linux: define {{(dso_local )?}}i64 @c_ret_u64() +// arm: define {{(dso_local )?}}i64 @c_ret_u64() +// riscv: define {{(dso_local )?}}i64 @c_ret_u64() #[no_mangle] pub extern "C" fn c_ret_u64() -> u64 { 0 } -// x86_64-linux: i8 @c_ret_i8() +// x86_64-linux: define {{(dso_local )?}}i8 @c_ret_i8() // x86_64-uefi: signext i8 @c_ret_i8() // i686: signext i8 @c_ret_i8() // aarch64-apple: signext i8 @c_ret_i8() -// aarch64-windows: i8 @c_ret_i8() -// aarch64-linux: i8 @c_ret_i8() +// aarch64-windows: define {{(dso_local )?}}i8 @c_ret_i8() +// aarch64-linux: define {{(dso_local )?}}i8 @c_ret_i8() // arm: signext i8 @c_ret_i8() // riscv: signext i8 @c_ret_i8() #[no_mangle] @@ -212,12 +218,12 @@ pub extern "C" fn c_ret_i8() -> i8 { 0 } -// x86_64-linux: i16 @c_ret_i16() +// x86_64-linux: define {{(dso_local )?}}i16 @c_ret_i16() // x86_64-uefi: signext i16 @c_ret_i16() // i686: signext i16 @c_ret_i16() // aarch64-apple: signext i16 @c_ret_i16() -// aarch64-windows: i16 @c_ret_i16() -// aarch64-linux: i16 @c_ret_i16() +// aarch64-windows: define {{(dso_local )?}}i16 @c_ret_i16() +// aarch64-linux: define {{(dso_local )?}}i16 @c_ret_i16() // arm: signext i16 @c_ret_i16() // riscv: signext i16 @c_ret_i16() #[no_mangle] @@ -225,27 +231,27 @@ pub extern "C" fn c_ret_i16() -> i16 { 0 } -// x86_64-linux: i32 @c_ret_i32() -// x86_64-uefi: i32 @c_ret_i32() -// i686: i32 @c_ret_i32() -// aarch64-apple: i32 @c_ret_i32() -// aarch64-windows: i32 @c_ret_i32() -// aarch64-linux: i32 @c_ret_i32() -// arm: i32 @c_ret_i32() +// x86_64-linux: define {{(dso_local )?}}i32 @c_ret_i32() +// x86_64-uefi: define {{(dso_local )?}}i32 @c_ret_i32() +// i686: define {{(dso_local )?}}i32 @c_ret_i32() +// aarch64-apple: define {{(dso_local )?}}i32 @c_ret_i32() +// aarch64-windows: define {{(dso_local )?}}i32 @c_ret_i32() +// aarch64-linux: define {{(dso_local )?}}i32 @c_ret_i32() +// arm: define {{(dso_local )?}}i32 @c_ret_i32() // riscv: signext i32 @c_ret_i32() #[no_mangle] pub extern "C" fn c_ret_i32() -> i32 { 0 } -// x86_64-linux: i64 @c_ret_i64() -// x86_64-uefi: i64 @c_ret_i64() -// i686: i64 @c_ret_i64() -// aarch64-apple: i64 @c_ret_i64() -// aarch64-windows: i64 @c_ret_i64() -// aarch64-linux: i64 @c_ret_i64() -// arm: i64 @c_ret_i64() -// riscv: i64 @c_ret_i64() +// x86_64-linux: define {{(dso_local )?}}i64 @c_ret_i64() +// x86_64-uefi: define {{(dso_local )?}}i64 @c_ret_i64() +// i686: define {{(dso_local )?}}i64 @c_ret_i64() +// aarch64-apple: define {{(dso_local )?}}i64 @c_ret_i64() +// aarch64-windows: define {{(dso_local )?}}i64 @c_ret_i64() +// aarch64-linux: define {{(dso_local )?}}i64 @c_ret_i64() +// arm: define {{(dso_local )?}}i64 @c_ret_i64() +// riscv: define {{(dso_local )?}}i64 @c_ret_i64() #[no_mangle] pub extern "C" fn c_ret_i64() -> i64 { 0