From 59c77c43d941dd621701d8e452928846af934497 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sat, 17 Jan 2026 10:14:47 +0000 Subject: [PATCH 01/10] use clap on tidy Current tidy parses paths and options manually, and parsing is spreading multple files. This commit introduces a parser using clap to clean and centralize it. --- Cargo.lock | 9 +- src/tools/tidy/Cargo.toml | 1 + src/tools/tidy/src/alphabetical/tests.rs | 2 +- src/tools/tidy/src/arg_parser.rs | 92 +++++++++++++ src/tools/tidy/src/arg_parser/tests.rs | 162 +++++++++++++++++++++++ src/tools/tidy/src/diagnostics.rs | 12 +- src/tools/tidy/src/extra_checks/mod.rs | 12 +- src/tools/tidy/src/lib.rs | 1 + src/tools/tidy/src/main.rs | 39 +++--- 9 files changed, 284 insertions(+), 46 deletions(-) create mode 100644 src/tools/tidy/src/arg_parser.rs create mode 100644 src/tools/tidy/src/arg_parser/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 01300d56cff9c..f279ad6cae9dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -580,9 +580,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.51" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" +checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" dependencies = [ "clap_builder", "clap_derive", @@ -600,9 +600,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.51" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" +checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" dependencies = [ "anstream", "anstyle", @@ -5622,6 +5622,7 @@ version = "0.1.0" dependencies = [ "build_helper", "cargo_metadata 0.21.0", + "clap", "fluent-syntax", "globset", "ignore", diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index cbf27ea87a076..d5433080efc08 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -20,6 +20,7 @@ fluent-syntax = "0.12" similar = "2.5.0" toml = "0.7.8" tempfile = "3.15.0" +clap = "4.5.54" [features] build-metrics = ["dep:serde"] diff --git a/src/tools/tidy/src/alphabetical/tests.rs b/src/tools/tidy/src/alphabetical/tests.rs index 4a1d263f1a4f3..5fa0dd751b647 100644 --- a/src/tools/tidy/src/alphabetical/tests.rs +++ b/src/tools/tidy/src/alphabetical/tests.rs @@ -37,7 +37,7 @@ fn bless_test(before: &str, after: &str) { let temp_path = tempfile::Builder::new().tempfile().unwrap().into_temp_path(); std::fs::write(&temp_path, before).unwrap(); - let tidy_ctx = TidyCtx::new(Path::new("/"), false, TidyFlags::new(&["--bless".to_owned()])); + let tidy_ctx = TidyCtx::new(Path::new("/"), false, TidyFlags::new(true)); let mut check = tidy_ctx.start_check("alphabetical-test"); check_lines(&temp_path, before, &tidy_ctx, &mut check); diff --git a/src/tools/tidy/src/arg_parser.rs b/src/tools/tidy/src/arg_parser.rs new file mode 100644 index 0000000000000..ca7ee04da8fb7 --- /dev/null +++ b/src/tools/tidy/src/arg_parser.rs @@ -0,0 +1,92 @@ +use std::num::NonZeroUsize; +use std::path::PathBuf; + +use clap::{Arg, ArgAction, ArgMatches, Command, value_parser}; + +#[cfg(test)] +mod tests; + +#[derive(Debug, Clone)] +pub struct TidyArgParser { + pub root_path: PathBuf, + pub cargo: PathBuf, + pub output_directory: PathBuf, + pub concurrency: NonZeroUsize, + pub npm: PathBuf, + pub verbose: bool, + pub bless: bool, + pub extra_checks: Option>, + pub pos_args: Vec, +} + +impl TidyArgParser { + fn command() -> Command { + Command::new("rust-tidy") + .arg( + Arg::new("root_path") + .help("path of the root directory") + .required(true) + .value_parser(value_parser!(PathBuf)), + ) + .arg( + Arg::new("cargo") + .help("path of cargo") + .required(true) + .value_parser(value_parser!(PathBuf)), + ) + .arg( + Arg::new("output_directory") + .help("path of output directory") + .required(true) + .value_parser(value_parser!(PathBuf)), + ) + .arg(Arg::new("concurrency").required(true).value_parser(value_parser!(NonZeroUsize))) + .arg( + Arg::new("npm") + .help("path of npm") + .required(true) + .value_parser(value_parser!(PathBuf)), + ) + .arg(Arg::new("verbose").help("verbose").long("verbose").action(ArgAction::SetTrue)) + .arg(Arg::new("bless").help("bless").long("bless").action(ArgAction::SetTrue)) + .arg( + Arg::new("extra_checks") + .help("extra checks") + .long("extra-checks") + .value_delimiter(',') + .action(ArgAction::Append), + ) + .arg(Arg::new("pos_args").help("for extra checks. you can specify configs and target files for external check tools").action(ArgAction::Append).last(true)) + } + + fn build(matches: ArgMatches) -> Self { + let mut tidy_flags = Self { + root_path: matches.get_one::("root_path").unwrap().clone(), + cargo: matches.get_one::("cargo").unwrap().clone(), + output_directory: matches.get_one::("output_directory").unwrap().clone(), + concurrency: *matches.get_one::("concurrency").unwrap(), + npm: matches.get_one::("npm").unwrap().clone(), + verbose: *matches.get_one::("verbose").unwrap(), + bless: *matches.get_one::("bless").unwrap(), + extra_checks: None, + pos_args: vec![], + }; + + if let Some(extra_checks) = matches.get_many::("extra_checks") { + tidy_flags.extra_checks = Some(extra_checks.map(|s| s.to_string()).collect::>()); + } + + tidy_flags.pos_args = matches + .get_many::("pos_args") + .unwrap_or_default() + .map(|v| v.to_string()) + .collect::>(); + + tidy_flags + } + + pub fn parse() -> Self { + let matches = Self::command().get_matches(); + Self::build(matches) + } +} diff --git a/src/tools/tidy/src/arg_parser/tests.rs b/src/tools/tidy/src/arg_parser/tests.rs new file mode 100644 index 0000000000000..856e80279e27a --- /dev/null +++ b/src/tools/tidy/src/arg_parser/tests.rs @@ -0,0 +1,162 @@ +use std::path::PathBuf; + +use crate::arg_parser::TidyArgParser; + +#[test] +fn test_tidy_parser() { + let args = vec![ + "rust-tidy", + "/home/user/rust", // Root dir + "/home/user/rust/build/x86_64-unknown-linux-gnu/stage0/bin/cargo", // Cardo location + "/home/user/rust/build", // Build dir + "16", // Number of concurrency + "/home/user/rust/build/misc-tools/bin/yarn", // Yarn location + "--verbose", + "--bless", + "--extra-checks", + "if-installed:auto:js,auto:if-installed:py,if-installed:auto:cpp,if-installed:auto:spellcheck", + "--", // pos_args + "some-file", + "some-file2", + ]; + let cmd = TidyArgParser::command(); + let parsed_args = TidyArgParser::build(cmd.get_matches_from(args)); + + assert_eq!(parsed_args.root_path, PathBuf::from("/home/user/rust")); + assert_eq!( + parsed_args.cargo, + PathBuf::from("/home/user/rust/build/x86_64-unknown-linux-gnu/stage0/bin/cargo") + ); + assert_eq!(parsed_args.output_directory, PathBuf::from("/home/user/rust/build")); + assert_eq!(parsed_args.concurrency.get(), 16); + assert_eq!(parsed_args.npm, PathBuf::from("/home/user/rust/build/misc-tools/bin/yarn")); + assert!(parsed_args.verbose); + assert!(parsed_args.bless); + assert_eq!( + parsed_args.extra_checks, + Some(vec![ + "if-installed:auto:js".to_string(), + "auto:if-installed:py".to_string(), + "if-installed:auto:cpp".to_string(), + "if-installed:auto:spellcheck".to_string(), + ]) + ); + assert_eq!(parsed_args.pos_args, vec!["some-file".to_string(), "some-file2".to_string()]); +} + +// The parser can take required args any order +#[test] +fn test_tidy_parser_any_order() { + let args = vec![ + "rust-tidy", + "--npm-path", + "yarn", + "--concurrency", + "16", + "--output-dir", + "/home/user/rust/build", + "--cargo-path", + "/home/user/rust/build/x86_64-unknown-linux-gnu/stage0/bin/cargo", + "--root-path", + "/home/user/rust", + ]; + let cmd = TidyArgParser::command(); + let parsed_args = TidyArgParser::build(cmd.get_matches_from(args)); + + assert_eq!(parsed_args.root_path, PathBuf::from("/home/user/rust")); + assert_eq!( + parsed_args.cargo, + PathBuf::from("/home/user/rust/build/x86_64-unknown-linux-gnu/stage0/bin/cargo") + ); + assert_eq!(parsed_args.output_directory, PathBuf::from("/home/user/rust/build")); + assert_eq!(parsed_args.concurrency.get(), 16); + assert_eq!(parsed_args.npm, PathBuf::from("yarn")); +} + +// --root-path is required +#[test] +fn test_tidy_parser_missing_root_path() { + let args = vec![ + "rust-tidy", + "--npm-path", + "yarn", + "--concurrency", + "16", + "--output-dir", + "/home/user/rust/build", + "--cargo-path", + "/home/user/rust/build/x86_64-unknown-linux-gnu/stage0/bin/cargo", + ]; + let cmd = TidyArgParser::command(); + assert!(cmd.try_get_matches_from(args).is_err()); +} + +// --cargo-path is required +#[test] +fn test_tidy_parser_missing_cargo_path() { + let args = vec![ + "rust-tidy", + "--npm-path", + "yarn", + "--concurrency", + "16", + "--output-dir", + "/home/user/rust/build", + "--root-path", + "/home/user/rust", + ]; + let cmd = TidyArgParser::command(); + assert!(cmd.try_get_matches_from(args).is_err()); +} + +// --output-dir is required +#[test] +fn test_tidy_parser_missing_output_dir() { + let args = vec![ + "rust-tidy", + "--npm-path", + "yarn", + "--concurrency", + "16", + "--cargo-path", + "/home/user/rust/build/x86_64-unknown-linux-gnu/stage0/bin/cargo", + "--root-path", + "/home/user/rust", + ]; + let cmd = TidyArgParser::command(); + assert!(cmd.try_get_matches_from(args).is_err()); +} + +// --concurrency is required +#[test] +fn test_tidy_parser_missing_concurrency() { + let args = vec![ + "rust-tidy", + "--npm-path", + "yarn", + "--output-dir", + "/home/user/rust/build", + "--cargo-path", + "/home/user/rust/build/x86_64-unknown-linux-gnu/stage0/bin/cargo", + "--root-path", + "/home/user/rust", + ]; + let cmd = TidyArgParser::command(); + assert!(cmd.try_get_matches_from(args).is_err()); +} + +// --npm-path is required +#[test] +fn test_tidy_parser_missing_npm_path() { + let args = vec![ + "rust-tidy", + "--concurrency", + "16", + "--output-dir", + "/home/user/rust/build", + "--cargo-path", + "/home/user/rust/build/x86_64-unknown-linux-gnu/stage0/bin/cargo", + ]; + let cmd = TidyArgParser::command(); + assert!(cmd.try_get_matches_from(args).is_err()); +} diff --git a/src/tools/tidy/src/diagnostics.rs b/src/tools/tidy/src/diagnostics.rs index 6f53f2fff1a48..4e6c316f5e18e 100644 --- a/src/tools/tidy/src/diagnostics.rs +++ b/src/tools/tidy/src/diagnostics.rs @@ -14,16 +14,8 @@ pub struct TidyFlags { } impl TidyFlags { - pub fn new(cfg_args: &[String]) -> Self { - let mut flags = Self::default(); - - for arg in cfg_args { - match arg.as_str() { - "--bless" => flags.bless = true, - _ => continue, - } - } - flags + pub fn new(bless: bool) -> Self { + Self { bless } } } diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs index 1c81a485608ae..6272e00591d78 100644 --- a/src/tools/tidy/src/extra_checks/mod.rs +++ b/src/tools/tidy/src/extra_checks/mod.rs @@ -58,8 +58,8 @@ pub fn check( tools_path: &Path, npm: &Path, cargo: &Path, - extra_checks: Option<&str>, - pos_args: &[String], + extra_checks: Option>, + pos_args: Vec, tidy_ctx: TidyCtx, ) { let mut check = tidy_ctx.start_check("extra_checks"); @@ -88,8 +88,8 @@ fn check_impl( tools_path: &Path, npm: &Path, cargo: &Path, - extra_checks: Option<&str>, - pos_args: &[String], + extra_checks: Option>, + pos_args: Vec, tidy_ctx: &TidyCtx, ) -> Result<(), Error> { let show_diff = @@ -99,9 +99,7 @@ fn check_impl( // Split comma-separated args up let mut lint_args = match extra_checks { Some(s) => s - .strip_prefix("--extra-checks=") - .unwrap() - .split(',') + .iter() .map(|s| { if s == "spellcheck:fix" { eprintln!("warning: `spellcheck:fix` is no longer valid, use `--extra-checks=spellcheck --bless`"); diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 425f43e42b7f8..19a9fa80d9f04 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -157,6 +157,7 @@ pub fn files_modified(ci_info: &CiInfo, pred: impl Fn(&str) -> bool) -> bool { } pub mod alphabetical; +pub mod arg_parser; pub mod bins; pub mod debug_artifacts; pub mod deps; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 94c24f11ed12f..457fbe93e6d22 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -5,12 +5,10 @@ //! builders. The tidy checks can be executed with `./x.py test tidy`. use std::collections::VecDeque; -use std::num::NonZeroUsize; -use std::path::PathBuf; -use std::str::FromStr; use std::thread::{self, ScopedJoinHandle, scope}; use std::{env, process}; +use tidy::arg_parser::TidyArgParser; use tidy::diagnostics::{COLOR_ERROR, COLOR_SUCCESS, TidyCtx, TidyFlags, output_message}; use tidy::*; @@ -22,14 +20,13 @@ fn main() { env::set_var("RUSTC_BOOTSTRAP", "1"); } - let root_path: PathBuf = env::args_os().nth(1).expect("need path to root of repo").into(); - let cargo: PathBuf = env::args_os().nth(2).expect("need path to cargo").into(); - let output_directory: PathBuf = - env::args_os().nth(3).expect("need path to output directory").into(); - let concurrency: NonZeroUsize = - FromStr::from_str(&env::args().nth(4).expect("need concurrency")) - .expect("concurrency must be a number"); - let npm: PathBuf = env::args_os().nth(5).expect("need name/path of npm command").into(); + let parsed_args = TidyArgParser::parse(); + + let root_path = parsed_args.root_path; + let cargo = parsed_args.cargo; + let output_directory = parsed_args.output_directory; + let concurrency = parsed_args.concurrency.get(); + let npm = parsed_args.npm; let root_manifest = root_path.join("Cargo.toml"); let src_path = root_path.join("src"); @@ -40,17 +37,12 @@ fn main() { let tools_path = src_path.join("tools"); let crashes_path = tests_path.join("crashes"); - let args: Vec = env::args().skip(1).collect(); - let (cfg_args, pos_args) = match args.iter().position(|arg| arg == "--") { - Some(pos) => (&args[..pos], &args[pos + 1..]), - None => (&args[..], [].as_slice()), - }; - let verbose = cfg_args.iter().any(|s| *s == "--verbose"); - let extra_checks = - cfg_args.iter().find(|s| s.starts_with("--extra-checks=")).map(String::as_str); + let verbose = parsed_args.verbose; + let bless = parsed_args.bless; + let extra_checks = parsed_args.extra_checks; + let pos_args = parsed_args.pos_args; - let tidy_flags = TidyFlags::new(cfg_args); - let tidy_ctx = TidyCtx::new(&root_path, verbose, tidy_flags); + let tidy_ctx = TidyCtx::new(&root_path, verbose, TidyFlags::new(bless)); let ci_info = CiInfo::new(tidy_ctx.clone()); let drain_handles = |handles: &mut VecDeque>| { @@ -61,14 +53,13 @@ fn main() { } } - while handles.len() >= concurrency.get() { + while handles.len() >= concurrency { handles.pop_front().unwrap().join().unwrap(); } }; scope(|s| { - let mut handles: VecDeque> = - VecDeque::with_capacity(concurrency.get()); + let mut handles: VecDeque> = VecDeque::with_capacity(concurrency); macro_rules! check { ($p:ident) => { From 14858732330380e488ffb406d4a537bf133d90f9 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sun, 25 Jan 2026 10:13:48 +0000 Subject: [PATCH 02/10] set long variants for required args Currently some required arguments (like path of the root dir) are ordered, but it causes an user (mainly bootstrap) needs to remember the order. This commit introduces long arguments (e.g., --root-path) for required args. --- src/bootstrap/src/core/build_steps/test.rs | 12 ++++++------ src/tools/tidy/src/arg_parser.rs | 14 ++++++++++++-- src/tools/tidy/src/arg_parser/tests.rs | 20 +++++++++++++------- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 52b38421eec22..ca70a7758d581 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1293,19 +1293,19 @@ impl Step for Tidy { /// for the `dev` or `nightly` channels. fn run(self, builder: &Builder<'_>) { let mut cmd = builder.tool_cmd(Tool::Tidy); - cmd.arg(&builder.src); - cmd.arg(&builder.initial_cargo); - cmd.arg(&builder.out); + cmd.arg(format!("--root-path={}", &builder.src.display())); + cmd.arg(format!("--cargo-path={}", &builder.initial_cargo.display())); + cmd.arg(format!("--output-dir={}", &builder.out.display())); // Tidy is heavily IO constrained. Still respect `-j`, but use a higher limit if `jobs` hasn't been configured. let jobs = builder.config.jobs.unwrap_or_else(|| { 8 * std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32 }); - cmd.arg(jobs.to_string()); + cmd.arg(format!("--concurrency={jobs}")); // pass the path to the yarn command used for installing js deps. if let Some(yarn) = &builder.config.yarn { - cmd.arg(yarn); + cmd.arg(format!("--npm-path={}", yarn.display())); } else { - cmd.arg("yarn"); + cmd.arg("--npm-path=yarn"); } if builder.is_verbose() { cmd.arg("--verbose"); diff --git a/src/tools/tidy/src/arg_parser.rs b/src/tools/tidy/src/arg_parser.rs index ca7ee04da8fb7..8041f739308d4 100644 --- a/src/tools/tidy/src/arg_parser.rs +++ b/src/tools/tidy/src/arg_parser.rs @@ -25,30 +25,40 @@ impl TidyArgParser { .arg( Arg::new("root_path") .help("path of the root directory") + .long("root-path") .required(true) .value_parser(value_parser!(PathBuf)), ) .arg( Arg::new("cargo") .help("path of cargo") + .long("cargo-path") .required(true) .value_parser(value_parser!(PathBuf)), ) .arg( Arg::new("output_directory") .help("path of output directory") + .long("output-dir") .required(true) .value_parser(value_parser!(PathBuf)), ) - .arg(Arg::new("concurrency").required(true).value_parser(value_parser!(NonZeroUsize))) + .arg( + Arg::new("concurrency") + .help("number of threads working concurrently") + .long("concurrency") + .required(true) + .value_parser(value_parser!(NonZeroUsize)), + ) .arg( Arg::new("npm") .help("path of npm") + .long("npm-path") .required(true) .value_parser(value_parser!(PathBuf)), ) .arg(Arg::new("verbose").help("verbose").long("verbose").action(ArgAction::SetTrue)) - .arg(Arg::new("bless").help("bless").long("bless").action(ArgAction::SetTrue)) + .arg(Arg::new("bless").help("target files are modified").long("bless").action(ArgAction::SetTrue)) .arg( Arg::new("extra_checks") .help("extra checks") diff --git a/src/tools/tidy/src/arg_parser/tests.rs b/src/tools/tidy/src/arg_parser/tests.rs index 856e80279e27a..c5e7aed21c1a0 100644 --- a/src/tools/tidy/src/arg_parser/tests.rs +++ b/src/tools/tidy/src/arg_parser/tests.rs @@ -2,15 +2,21 @@ use std::path::PathBuf; use crate::arg_parser::TidyArgParser; +// Test all arguments #[test] -fn test_tidy_parser() { +fn test_tidy_parser_full() { let args = vec![ "rust-tidy", - "/home/user/rust", // Root dir - "/home/user/rust/build/x86_64-unknown-linux-gnu/stage0/bin/cargo", // Cardo location - "/home/user/rust/build", // Build dir - "16", // Number of concurrency - "/home/user/rust/build/misc-tools/bin/yarn", // Yarn location + "--root-path", + "/home/user/rust", + "--cargo-path", + "/home/user/rust/build/x86_64-unknown-linux-gnu/stage0/bin/cargo", + "--output-dir", + "/home/user/rust/build", + "--concurrency", + "16", + "--npm-path", + "yarn", "--verbose", "--bless", "--extra-checks", @@ -29,7 +35,7 @@ fn test_tidy_parser() { ); assert_eq!(parsed_args.output_directory, PathBuf::from("/home/user/rust/build")); assert_eq!(parsed_args.concurrency.get(), 16); - assert_eq!(parsed_args.npm, PathBuf::from("/home/user/rust/build/misc-tools/bin/yarn")); + assert_eq!(parsed_args.npm, PathBuf::from("yarn")); assert!(parsed_args.verbose); assert!(parsed_args.bless); assert_eq!( From 4ae5b43b0f8c7bb4b579ea8e5e34dd928ffe87a2 Mon Sep 17 00:00:00 2001 From: Frank King Date: Fri, 30 Jan 2026 11:04:04 +0800 Subject: [PATCH 03/10] refactor: remove `Ty::pinned_ref` in favor of `Ty::maybe_pinned_ref` Also returns the `Region` of the reference type. --- compiler/rustc_hir_typeck/src/pat.rs | 2 +- compiler/rustc_middle/src/ty/sty.rs | 22 +++++++------------- compiler/rustc_pattern_analysis/src/rustc.rs | 8 +++---- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index b56ab6dcb4ab2..f054145dc7e9a 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2841,7 +2841,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // the bad interactions of the given hack detailed in (note_1). debug!("check_pat_ref: expected={:?}", expected); match expected.maybe_pinned_ref() { - Some((r_ty, r_pinned, r_mutbl)) + Some((r_ty, r_pinned, r_mutbl, _)) if ((ref_pat_matches_mut_ref && r_mutbl >= pat_mutbl) || r_mutbl == pat_mutbl) && pat_pinned == r_pinned => diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 4c5bd85e6b726..4be30d8b6c918 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1336,25 +1336,17 @@ impl<'tcx> Ty<'tcx> { } } - pub fn pinned_ref(self) -> Option<(Ty<'tcx>, ty::Mutability)> { - if let Adt(def, args) = self.kind() - && def.is_pin() - && let &ty::Ref(_, ty, mutbl) = args.type_at(0).kind() - { - return Some((ty, mutbl)); - } - None - } - - pub fn maybe_pinned_ref(self) -> Option<(Ty<'tcx>, ty::Pinnedness, ty::Mutability)> { - match *self.kind() { + pub fn maybe_pinned_ref( + self, + ) -> Option<(Ty<'tcx>, ty::Pinnedness, ty::Mutability, Region<'tcx>)> { + match self.kind() { Adt(def, args) if def.is_pin() - && let ty::Ref(_, ty, mutbl) = *args.type_at(0).kind() => + && let &ty::Ref(region, ty, mutbl) = args.type_at(0).kind() => { - Some((ty, ty::Pinnedness::Pinned, mutbl)) + Some((ty, ty::Pinnedness::Pinned, mutbl, region)) } - ty::Ref(_, ty, mutbl) => Some((ty, ty::Pinnedness::Not, mutbl)), + &Ref(region, ty, mutbl) => Some((ty, ty::Pinnedness::Not, mutbl, region)), _ => None, } } diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 3e97842b7f395..dc38f2d8bc70f 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -4,8 +4,8 @@ use std::iter::once; use rustc_abi::{FIRST_VARIANT, FieldIdx, Integer, VariantIdx}; use rustc_arena::DroplessArena; +use rustc_hir::HirId; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir, HirId}; use rustc_index::{Idx, IndexVec}; use rustc_middle::middle::stability::EvalResult; use rustc_middle::thir::{self, Pat, PatKind, PatRange, PatRangeBoundary}; @@ -471,9 +471,9 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { PatKind::Deref { pin, subpattern } => { fields = vec![self.lower_pat(subpattern).at_index(0)]; arity = 1; - ctor = match pin { - hir::Pinnedness::Not if ty.is_ref() => Ref, - hir::Pinnedness::Pinned if let Some((inner_ty, _)) = ty.pinned_ref() => { + ctor = match (pin, ty.maybe_pinned_ref()) { + (ty::Pinnedness::Not, Some((_, ty::Pinnedness::Not, _, _))) => Ref, + (ty::Pinnedness::Pinned, Some((inner_ty, ty::Pinnedness::Pinned, _, _))) => { self.internal_state.has_lowered_deref_pat.set(true); DerefPattern(RevealedTy(inner_ty)) } From 9cdcd0c3fa2ec52547d196101d350c5f2e50ead6 Mon Sep 17 00:00:00 2001 From: ritik chahar Date: Sat, 31 Jan 2026 10:15:19 +0530 Subject: [PATCH 04/10] Document enum types used as values for E0423 --- compiler/rustc_error_codes/src/error_codes/E0423.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/compiler/rustc_error_codes/src/error_codes/E0423.md b/compiler/rustc_error_codes/src/error_codes/E0423.md index a98ada17a469c..eb5243b598471 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0423.md +++ b/compiler/rustc_error_codes/src/error_codes/E0423.md @@ -44,3 +44,16 @@ fn h1() -> i32 { // did you mean `a::I`? } ``` + + + +### Enum types used as values + +Enums are types and cannot be used directly as values. + +```compile_fail,E0423 +fn main() { + let x = Option::; + //~^ ERROR expected value, found enum `Option` +} +``` \ No newline at end of file From daaff44cbc25c35fbe59878bef315252fbba8a62 Mon Sep 17 00:00:00 2001 From: ritik chahar Date: Sat, 31 Jan 2026 10:46:58 +0530 Subject: [PATCH 05/10] Fix tidy formatting manually for E0423.md --- compiler/rustc_error_codes/src/error_codes/E0423.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0423.md b/compiler/rustc_error_codes/src/error_codes/E0423.md index eb5243b598471..4af17b1221b9c 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0423.md +++ b/compiler/rustc_error_codes/src/error_codes/E0423.md @@ -45,15 +45,13 @@ fn h1() -> i32 { } ``` - - ### Enum types used as values Enums are types and cannot be used directly as values. ```compile_fail,E0423 -fn main() { +fn main(){ let x = Option::; - //~^ ERROR expected value, found enum `Option` + //~^ ERROR expected value,found enum `Option` } -``` \ No newline at end of file +``` From 54f88be3cd4b8e7a3f4cae9ad495d047bfb51d33 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 31 Jan 2026 07:07:53 +0000 Subject: [PATCH 06/10] Revert "Enable `outline-atomics` by default on AArch64 FreeBSD" This reverts commit 383053e01602a1a754a170d7c201cc43fff87739. --- .../rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs index 47775f9684008..69a65e6b0f024 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: Arch::AArch64, options: TargetOptions { - features: "+v8a,+outline-atomics".into(), + features: "+v8a".into(), max_atomic_width: Some(128), stack_probes: StackProbeType::Inline, supported_sanitizers: SanitizerSet::ADDRESS From 63e16520a245d69dae38428aede40303dfc0e410 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 31 Jan 2026 07:07:59 +0000 Subject: [PATCH 07/10] Revert "Enable `outline-atomics` by default on AArch64 OpenBSD" This reverts commit 66c150c1fa29d15e1c5c06dfe708c8443faf42c3. --- .../rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs index 14a2f007f1e8c..e5e40cb38b911 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: Arch::AArch64, options: TargetOptions { - features: "+v8a,+outline-atomics".into(), + features: "+v8a".into(), max_atomic_width: Some(128), stack_probes: StackProbeType::Inline, ..base::openbsd::opts() From a9da102e20153c03e963c3cdf5160cde7c7d81af Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 31 Jan 2026 07:08:05 +0000 Subject: [PATCH 08/10] Revert "Enable `outline-atomics` by default on AArch64 Fuchsia" This reverts commit 21525f862d621bbeb9a131f3631111c402e1a447. --- .../rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs index 8a07f98075a89..6489e2bda8091 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs @@ -5,7 +5,7 @@ use crate::spec::{ pub(crate) fn target() -> Target { let mut base = base::fuchsia::opts(); base.cpu = "generic".into(); - base.features = "+v8a,+crc,+aes,+sha2,+neon,+outline-atomics".into(); + base.features = "+v8a,+crc,+aes,+sha2,+neon".into(); base.max_atomic_width = Some(128); base.stack_probes = StackProbeType::Inline; base.supported_sanitizers = SanitizerSet::ADDRESS From 1173034b7bd007d68931cf58cb656deec8af994d Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 31 Jan 2026 07:08:11 +0000 Subject: [PATCH 09/10] Revert "Enable `outline-atomics` by default on AArch64 Android" This reverts commit c45590397843909a1f36d4fd9d89cfc1e7551652. --- compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs index d1810b6fa4860..3b158c13521ea 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { max_atomic_width: Some(128), // As documented in https://developer.android.com/ndk/guides/cpu-features.html // the neon (ASIMD) and FP must exist on all android aarch64 targets. - features: "+v8a,+neon,+outline-atomics".into(), + features: "+v8a,+neon".into(), // the AAPCS64 expects use of non-leaf frame pointers per // https://github.com/ARM-software/abi-aa/blob/4492d1570eb70c8fd146623e0db65b2d241f12e7/aapcs64/aapcs64.rst#the-frame-pointer // and we tend to encounter interesting bugs in AArch64 unwinding code if we do not From 9fb68d60efc842614a5ce63eb4d8ecfa6f7deee3 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 31 Jan 2026 07:08:17 +0000 Subject: [PATCH 10/10] Revert "Enable `outline-atomics` by default on AArch64 Windows platforms" This reverts commit 1ed1b6e2674e0884479042ae1b6aac431f1c217c. --- .../rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs | 2 +- .../rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs index db3cf83ddc999..ce17280b153d6 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs @@ -3,7 +3,7 @@ use crate::spec::{Arch, Cc, FramePointer, LinkerFlavor, Lld, Target, TargetMetad pub(crate) fn target() -> Target { let mut base = base::windows_gnullvm::opts(); base.max_atomic_width = Some(128); - base.features = "+v8a,+neon,+outline-atomics".into(); + base.features = "+v8a,+neon".into(); base.linker = Some("aarch64-w64-mingw32-clang".into()); base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "arm64pe"]); diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs index e9f7f51a7a35b..0d06bec21f4a4 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs @@ -3,7 +3,7 @@ use crate::spec::{Arch, FramePointer, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_msvc::opts(); base.max_atomic_width = Some(128); - base.features = "+v8a,+neon,+outline-atomics".into(); + base.features = "+v8a,+neon".into(); // Microsoft recommends enabling frame pointers on Arm64 Windows. // From https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#integer-registers