diff options
Diffstat (limited to 'src')
191 files changed, 2333 insertions, 788 deletions
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index dab58fccf5e..68fa42ee9e6 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -155,7 +155,7 @@ impl Step for Std { // When using `download-rustc`, we already have artifacts for the host available. Don't // recompile them. - if builder.download_rustc() && builder.is_builder_target(target) + if builder.download_rustc() && builder.config.is_host_target(target) // NOTE: the beta compiler may generate different artifacts than the downloaded compiler, so // its artifacts can't be reused. && compiler.stage != 0 @@ -229,7 +229,7 @@ impl Step for Std { // The LLD wrappers and `rust-lld` are self-contained linking components that can be // necessary to link the stdlib on some targets. We'll also need to copy these binaries to // the `stage0-sysroot` to ensure the linker is found when bootstrapping on such a target. - if compiler.stage == 0 && builder.is_builder_target(compiler.host) { + if compiler.stage == 0 && builder.config.is_host_target(compiler.host) { trace!( "(build == host) copying linking components to `stage0-sysroot` for bootstrapping" ); @@ -1194,8 +1194,7 @@ pub fn rustc_cargo( let enzyme_dir = builder.build.out.join(arch).join("enzyme").join("lib"); cargo.rustflag("-L").rustflag(enzyme_dir.to_str().expect("Invalid path")); - if !builder.config.dry_run() { - let llvm_config = builder.llvm_config(builder.config.build).unwrap(); + if let Some(llvm_config) = builder.llvm_config(builder.config.build) { let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config); cargo.rustflag("-l").rustflag(&format!("Enzyme-{llvm_version_major}")); } @@ -1374,7 +1373,7 @@ pub fn rustc_cargo_env( /// Pass down configuration from the LLVM build into the build of /// rustc_llvm and rustc_codegen_llvm. fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) { - if builder.is_rust_llvm(target) { + if builder.config.is_rust_llvm(target) { cargo.env("LLVM_RUSTLLVM", "1"); } if builder.config.llvm_enzyme { @@ -2182,7 +2181,7 @@ impl Step for Assemble { debug!("copying codegen backends to sysroot"); copy_codegen_backends_to_sysroot(builder, build_compiler, target_compiler); - if builder.config.lld_enabled { + if builder.config.lld_enabled && !builder.config.is_system_llvm(target_compiler.host) { builder.ensure(crate::core::build_steps::tool::LldWrapper { build_compiler, target_compiler, @@ -2532,7 +2531,9 @@ pub fn strip_debug(builder: &Builder<'_>, target: TargetSelection, path: &Path) // FIXME: to make things simpler for now, limit this to the host and target where we know // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not // cross-compiling. Expand this to other appropriate targets in the future. - if target != "x86_64-unknown-linux-gnu" || !builder.is_builder_target(target) || !path.exists() + if target != "x86_64-unknown-linux-gnu" + || !builder.config.is_host_target(target) + || !path.exists() { return; } diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 83f71aeed72..ed90ede7936 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -612,7 +612,7 @@ impl Step for DebuggerScripts { fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool { // The only true set of target libraries came from the build triple, so // let's reduce redundant work by only producing archives from that host. - if !builder.is_builder_target(compiler.host) { + if !builder.config.is_host_target(compiler.host) { builder.info("\tskipping, not a build host"); true } else { @@ -671,7 +671,8 @@ fn copy_target_libs( &self_contained_dst.join(path.file_name().unwrap()), FileType::NativeLibrary, ); - } else if dependency_type == DependencyType::Target || builder.is_builder_target(target) { + } else if dependency_type == DependencyType::Target || builder.config.is_host_target(target) + { builder.copy_link(&path, &dst.join(path.file_name().unwrap()), FileType::NativeLibrary); } } @@ -824,7 +825,7 @@ impl Step for Analysis { fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { let compiler = self.compiler; let target = self.target; - if !builder.is_builder_target(compiler.host) { + if !builder.config.is_host_target(compiler.host) { return None; } @@ -2118,7 +2119,7 @@ fn maybe_install_llvm( // // If the LLVM is coming from ourselves (just from CI) though, we // still want to install it, as it otherwise won't be available. - if builder.is_system_llvm(target) { + if builder.config.is_system_llvm(target) { trace!("system LLVM requested, no install"); return false; } diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 6e84b83d17d..6f6839ad15b 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -485,7 +485,7 @@ impl Step for Llvm { } // https://llvm.org/docs/HowToCrossCompileLLVM.html - if !builder.is_builder_target(target) { + if !builder.config.is_host_target(target) { let LlvmResult { llvm_config, .. } = builder.ensure(Llvm { target: builder.config.build }); if !builder.config.dry_run() { @@ -637,7 +637,7 @@ fn configure_cmake( } cfg.target(&target.triple).host(&builder.config.build.triple); - if !builder.is_builder_target(target) { + if !builder.config.is_host_target(target) { cfg.define("CMAKE_CROSSCOMPILING", "True"); // NOTE: Ideally, we wouldn't have to do this, and `cmake-rs` would just handle it for us. @@ -1098,7 +1098,7 @@ impl Step for Lld { .define("LLVM_CMAKE_DIR", llvm_cmake_dir) .define("LLVM_INCLUDE_TESTS", "OFF"); - if !builder.is_builder_target(target) { + if !builder.config.is_host_target(target) { // Use the host llvm-tblgen binary. cfg.define( "LLVM_TABLEGEN_EXE", diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 80d92135dd3..83083e12ef1 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -584,6 +584,7 @@ Select which editor you would like to set up [default: None]: "; "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0", "d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45", "b5dd299b93dca3ceeb9b335f929293cb3d4bf4977866fbe7ceeac2a8a9f99088", + "631c837b0e98ae35fd48b0e5f743b1ca60adadf2d0a2b23566ba25df372cf1a9", ], EditorKind::Helix => &[ "2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233", @@ -602,10 +603,12 @@ Select which editor you would like to set up [default: None]: "; "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4", "c394386e6133bbf29ffd32c8af0bb3d4aac354cba9ee051f29612aa9350f8f8d", "e53e9129ca5ee5dcbd6ec8b68c2d87376474eb154992deba3c6d9ab1703e0717", + "f954316090936c7e590c253ca9d524008375882fa13c5b41d7e2547a896ff893", ], EditorKind::Zed => &[ "bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c", "a5380cf5dd9328731aecc5dfb240d16dac46ed272126b9728006151ef42f5909", + "2e96bf0d443852b12f016c8fc9840ab3d0a2b4fe0b0fb3a157e8d74d5e7e0e26", ], } } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index b1a3bba0887..096f7de6597 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1894,7 +1894,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the .arg(llvm_components.trim()); llvm_components_passed = true; } - if !builder.is_rust_llvm(target) { + if !builder.config.is_rust_llvm(target) { cmd.arg("--system-llvm"); } @@ -2668,7 +2668,7 @@ impl Step for Crate { cargo } else { // Also prepare a sysroot for the target. - if !builder.is_builder_target(target) { + if !builder.config.is_host_target(target) { builder.ensure(compile::Std::new(compiler, target).force_recompile(true)); builder.ensure(RemoteCopyLibs { compiler, target }); } diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index fd3b28e4e6a..5de824ebab2 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1107,8 +1107,8 @@ fn test_is_builder_target() { let build = Build::new(config); let builder = Builder::new(&build); - assert!(builder.is_builder_target(target1)); - assert!(!builder.is_builder_target(target2)); + assert!(builder.config.is_host_target(target1)); + assert!(!builder.config.is_host_target(target2)); } } diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 2266e61bf60..43b62789536 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -6,6 +6,7 @@ use std::cell::{Cell, RefCell}; use std::collections::{BTreeSet, HashMap, HashSet}; use std::fmt::{self, Display}; +use std::hash::Hash; use std::io::IsTerminal; use std::path::{Path, PathBuf, absolute}; use std::process::Command; @@ -701,6 +702,7 @@ pub(crate) struct TomlConfig { target: Option<HashMap<String, TomlTarget>>, dist: Option<Dist>, profile: Option<String>, + include: Option<Vec<PathBuf>>, } /// This enum is used for deserializing change IDs from TOML, allowing both numeric values and the string `"ignore"`. @@ -747,27 +749,35 @@ enum ReplaceOpt { } trait Merge { - fn merge(&mut self, other: Self, replace: ReplaceOpt); + fn merge( + &mut self, + parent_config_path: Option<PathBuf>, + included_extensions: &mut HashSet<PathBuf>, + other: Self, + replace: ReplaceOpt, + ); } impl Merge for TomlConfig { fn merge( &mut self, - TomlConfig { build, install, llvm, gcc, rust, dist, target, profile, change_id }: Self, + parent_config_path: Option<PathBuf>, + included_extensions: &mut HashSet<PathBuf>, + TomlConfig { build, install, llvm, gcc, rust, dist, target, profile, change_id, include }: Self, replace: ReplaceOpt, ) { fn do_merge<T: Merge>(x: &mut Option<T>, y: Option<T>, replace: ReplaceOpt) { if let Some(new) = y { if let Some(original) = x { - original.merge(new, replace); + original.merge(None, &mut Default::default(), new, replace); } else { *x = Some(new); } } } - self.change_id.inner.merge(change_id.inner, replace); - self.profile.merge(profile, replace); + self.change_id.inner.merge(None, &mut Default::default(), change_id.inner, replace); + self.profile.merge(None, &mut Default::default(), profile, replace); do_merge(&mut self.build, build, replace); do_merge(&mut self.install, install, replace); @@ -782,13 +792,50 @@ impl Merge for TomlConfig { (Some(original_target), Some(new_target)) => { for (triple, new) in new_target { if let Some(original) = original_target.get_mut(&triple) { - original.merge(new, replace); + original.merge(None, &mut Default::default(), new, replace); } else { original_target.insert(triple, new); } } } } + + let parent_dir = parent_config_path + .as_ref() + .and_then(|p| p.parent().map(ToOwned::to_owned)) + .unwrap_or_default(); + + // `include` handled later since we ignore duplicates using `ReplaceOpt::IgnoreDuplicate` to + // keep the upper-level configuration to take precedence. + for include_path in include.clone().unwrap_or_default().iter().rev() { + let include_path = parent_dir.join(include_path); + let include_path = include_path.canonicalize().unwrap_or_else(|e| { + eprintln!("ERROR: Failed to canonicalize '{}' path: {e}", include_path.display()); + exit!(2); + }); + + let included_toml = Config::get_toml_inner(&include_path).unwrap_or_else(|e| { + eprintln!("ERROR: Failed to parse '{}': {e}", include_path.display()); + exit!(2); + }); + + assert!( + included_extensions.insert(include_path.clone()), + "Cyclic inclusion detected: '{}' is being included again before its previous inclusion was fully processed.", + include_path.display() + ); + + self.merge( + Some(include_path.clone()), + included_extensions, + included_toml, + // Ensures that parent configuration always takes precedence + // over child configurations. + ReplaceOpt::IgnoreDuplicate, + ); + + included_extensions.remove(&include_path); + } } } @@ -803,7 +850,13 @@ macro_rules! define_config { } impl Merge for $name { - fn merge(&mut self, other: Self, replace: ReplaceOpt) { + fn merge( + &mut self, + _parent_config_path: Option<PathBuf>, + _included_extensions: &mut HashSet<PathBuf>, + other: Self, + replace: ReplaceOpt + ) { $( match replace { ReplaceOpt::IgnoreDuplicate => { @@ -903,7 +956,13 @@ macro_rules! define_config { } impl<T> Merge for Option<T> { - fn merge(&mut self, other: Self, replace: ReplaceOpt) { + fn merge( + &mut self, + _parent_config_path: Option<PathBuf>, + _included_extensions: &mut HashSet<PathBuf>, + other: Self, + replace: ReplaceOpt, + ) { match replace { ReplaceOpt::IgnoreDuplicate => { if self.is_none() { @@ -1363,13 +1422,15 @@ impl Config { Self::get_toml(&builder_config_path) } - #[cfg(test)] - pub(crate) fn get_toml(_: &Path) -> Result<TomlConfig, toml::de::Error> { - Ok(TomlConfig::default()) + pub(crate) fn get_toml(file: &Path) -> Result<TomlConfig, toml::de::Error> { + #[cfg(test)] + return Ok(TomlConfig::default()); + + #[cfg(not(test))] + Self::get_toml_inner(file) } - #[cfg(not(test))] - pub(crate) fn get_toml(file: &Path) -> Result<TomlConfig, toml::de::Error> { + fn get_toml_inner(file: &Path) -> Result<TomlConfig, toml::de::Error> { let contents = t!(fs::read_to_string(file), format!("config file {} not found", file.display())); // Deserialize to Value and then TomlConfig to prevent the Deserialize impl of @@ -1548,7 +1609,8 @@ impl Config { // but not if `bootstrap.toml` hasn't been created. let mut toml = if !using_default_path || toml_path.exists() { config.config = Some(if cfg!(not(test)) { - toml_path.canonicalize().unwrap() + toml_path = toml_path.canonicalize().unwrap(); + toml_path.clone() } else { toml_path.clone() }); @@ -1576,6 +1638,26 @@ impl Config { toml.profile = Some("dist".into()); } + // Reverse the list to ensure the last added config extension remains the most dominant. + // For example, given ["a.toml", "b.toml"], "b.toml" should take precedence over "a.toml". + // + // This must be handled before applying the `profile` since `include`s should always take + // precedence over `profile`s. + for include_path in toml.include.clone().unwrap_or_default().iter().rev() { + let include_path = toml_path.parent().unwrap().join(include_path); + + let included_toml = get_toml(&include_path).unwrap_or_else(|e| { + eprintln!("ERROR: Failed to parse '{}': {e}", include_path.display()); + exit!(2); + }); + toml.merge( + Some(include_path), + &mut Default::default(), + included_toml, + ReplaceOpt::IgnoreDuplicate, + ); + } + if let Some(include) = &toml.profile { // Allows creating alias for profile names, allowing // profiles to be renamed while maintaining back compatibility @@ -1597,7 +1679,12 @@ impl Config { ); exit!(2); }); - toml.merge(included_toml, ReplaceOpt::IgnoreDuplicate); + toml.merge( + Some(include_path), + &mut Default::default(), + included_toml, + ReplaceOpt::IgnoreDuplicate, + ); } let mut override_toml = TomlConfig::default(); @@ -1608,7 +1695,12 @@ impl Config { let mut err = match get_table(option) { Ok(v) => { - override_toml.merge(v, ReplaceOpt::ErrorOnDuplicate); + override_toml.merge( + None, + &mut Default::default(), + v, + ReplaceOpt::ErrorOnDuplicate, + ); continue; } Err(e) => e, @@ -1619,7 +1711,12 @@ impl Config { if !value.contains('"') { match get_table(&format!(r#"{key}="{value}""#)) { Ok(v) => { - override_toml.merge(v, ReplaceOpt::ErrorOnDuplicate); + override_toml.merge( + None, + &mut Default::default(), + v, + ReplaceOpt::ErrorOnDuplicate, + ); continue; } Err(e) => err = e, @@ -1629,7 +1726,7 @@ impl Config { eprintln!("failed to parse override `{option}`: `{err}"); exit!(2) } - toml.merge(override_toml, ReplaceOpt::Override); + toml.merge(None, &mut Default::default(), override_toml, ReplaceOpt::Override); config.change_id = toml.change_id.inner; @@ -2397,6 +2494,12 @@ impl Config { ); } + if config.lld_enabled && config.is_system_llvm(config.build) { + eprintln!( + "Warning: LLD is enabled when using external llvm-config. LLD will not be built and copied to the sysroot." + ); + } + let default_std_features = BTreeSet::from([String::from("panic-unwind")]); config.rust_std_features = std_features.unwrap_or(default_std_features); @@ -3240,6 +3343,42 @@ impl Config { Some(commit.to_string()) } + + /// Checks if the given target is the same as the host target. + pub fn is_host_target(&self, target: TargetSelection) -> bool { + self.build == target + } + + /// Returns `true` if this is an external version of LLVM not managed by bootstrap. + /// In particular, we expect llvm sources to be available when this is false. + /// + /// NOTE: this is not the same as `!is_rust_llvm` when `llvm_has_patches` is set. + pub fn is_system_llvm(&self, target: TargetSelection) -> bool { + match self.target_config.get(&target) { + Some(Target { llvm_config: Some(_), .. }) => { + let ci_llvm = self.llvm_from_ci && self.is_host_target(target); + !ci_llvm + } + // We're building from the in-tree src/llvm-project sources. + Some(Target { llvm_config: None, .. }) => false, + None => false, + } + } + + /// Returns `true` if this is our custom, patched, version of LLVM. + /// + /// This does not necessarily imply that we're managing the `llvm-project` submodule. + pub fn is_rust_llvm(&self, target: TargetSelection) -> bool { + match self.target_config.get(&target) { + // We're using a user-controlled version of LLVM. The user has explicitly told us whether the version has our patches. + // (They might be wrong, but that's not a supported use-case.) + // In particular, this tries to support `submodules = false` and `patches = false`, for using a newer version of LLVM that's not through `rust-lang/llvm-project`. + Some(Target { llvm_has_rust_patches: Some(patched), .. }) => *patched, + // The user hasn't promised the patches match. + // This only has our patches if it's downloaded from CI or built from source. + _ => !self.is_system_llvm(target), + } + } } /// Compares the current `Llvm` options against those in the CI LLVM builder and detects any incompatible options. diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index d8002ba8467..c8a12c9072c 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -1,8 +1,8 @@ use std::collections::BTreeSet; -use std::env; use std::fs::{File, remove_file}; use std::io::Write; -use std::path::Path; +use std::path::{Path, PathBuf}; +use std::{env, fs}; use build_helper::ci::CiEnv; use clap::CommandFactory; @@ -23,6 +23,27 @@ pub(crate) fn parse(config: &str) -> Config { ) } +fn get_toml(file: &Path) -> Result<TomlConfig, toml::de::Error> { + let contents = std::fs::read_to_string(file).unwrap(); + toml::from_str(&contents).and_then(|table: toml::Value| TomlConfig::deserialize(table)) +} + +/// Helps with debugging by using consistent test-specific directories instead of +/// random temporary directories. +fn prepare_test_specific_dir() -> PathBuf { + let current = std::thread::current(); + // Replace "::" with "_" to make it safe for directory names on Windows systems + let test_path = current.name().unwrap().replace("::", "_"); + + let testdir = parse("").tempdir().join(test_path); + + // clean up any old test files + let _ = fs::remove_dir_all(&testdir); + let _ = fs::create_dir_all(&testdir); + + testdir +} + #[test] fn download_ci_llvm() { let config = parse("llvm.download-ci-llvm = false"); @@ -539,3 +560,189 @@ fn test_ci_flag() { let config = Config::parse_inner(Flags::parse(&["check".into()]), |&_| toml::from_str("")); assert_eq!(config.is_running_on_ci, CiEnv::is_ci()); } + +#[test] +fn test_precedence_of_includes() { + let testdir = prepare_test_specific_dir(); + + let root_config = testdir.join("config.toml"); + let root_config_content = br#" + include = ["./extension.toml"] + + [llvm] + link-jobs = 2 + "#; + File::create(&root_config).unwrap().write_all(root_config_content).unwrap(); + + let extension = testdir.join("extension.toml"); + let extension_content = br#" + change-id=543 + include = ["./extension2.toml"] + "#; + File::create(extension).unwrap().write_all(extension_content).unwrap(); + + let extension = testdir.join("extension2.toml"); + let extension_content = br#" + change-id=742 + + [llvm] + link-jobs = 10 + + [build] + description = "Some creative description" + "#; + File::create(extension).unwrap().write_all(extension_content).unwrap(); + + let config = Config::parse_inner( + Flags::parse(&["check".to_owned(), format!("--config={}", root_config.to_str().unwrap())]), + get_toml, + ); + + assert_eq!(config.change_id.unwrap(), ChangeId::Id(543)); + assert_eq!(config.llvm_link_jobs.unwrap(), 2); + assert_eq!(config.description.unwrap(), "Some creative description"); +} + +#[test] +#[should_panic(expected = "Cyclic inclusion detected")] +fn test_cyclic_include_direct() { + let testdir = prepare_test_specific_dir(); + + let root_config = testdir.join("config.toml"); + let root_config_content = br#" + include = ["./extension.toml"] + "#; + File::create(&root_config).unwrap().write_all(root_config_content).unwrap(); + + let extension = testdir.join("extension.toml"); + let extension_content = br#" + include = ["./config.toml"] + "#; + File::create(extension).unwrap().write_all(extension_content).unwrap(); + + let config = Config::parse_inner( + Flags::parse(&["check".to_owned(), format!("--config={}", root_config.to_str().unwrap())]), + get_toml, + ); +} + +#[test] +#[should_panic(expected = "Cyclic inclusion detected")] +fn test_cyclic_include_indirect() { + let testdir = prepare_test_specific_dir(); + + let root_config = testdir.join("config.toml"); + let root_config_content = br#" + include = ["./extension.toml"] + "#; + File::create(&root_config).unwrap().write_all(root_config_content).unwrap(); + + let extension = testdir.join("extension.toml"); + let extension_content = br#" + include = ["./extension2.toml"] + "#; + File::create(extension).unwrap().write_all(extension_content).unwrap(); + + let extension = testdir.join("extension2.toml"); + let extension_content = br#" + include = ["./extension3.toml"] + "#; + File::create(extension).unwrap().write_all(extension_content).unwrap(); + + let extension = testdir.join("extension3.toml"); + let extension_content = br#" + include = ["./extension.toml"] + "#; + File::create(extension).unwrap().write_all(extension_content).unwrap(); + + let config = Config::parse_inner( + Flags::parse(&["check".to_owned(), format!("--config={}", root_config.to_str().unwrap())]), + get_toml, + ); +} + +#[test] +fn test_include_absolute_paths() { + let testdir = prepare_test_specific_dir(); + + let extension = testdir.join("extension.toml"); + File::create(&extension).unwrap().write_all(&[]).unwrap(); + + let root_config = testdir.join("config.toml"); + let extension_absolute_path = + extension.canonicalize().unwrap().to_str().unwrap().replace('\\', r"\\"); + let root_config_content = format!(r#"include = ["{}"]"#, extension_absolute_path); + File::create(&root_config).unwrap().write_all(root_config_content.as_bytes()).unwrap(); + + let config = Config::parse_inner( + Flags::parse(&["check".to_owned(), format!("--config={}", root_config.to_str().unwrap())]), + get_toml, + ); +} + +#[test] +fn test_include_relative_paths() { + let testdir = prepare_test_specific_dir(); + + let _ = fs::create_dir_all(&testdir.join("subdir/another_subdir")); + + let root_config = testdir.join("config.toml"); + let root_config_content = br#" + include = ["./subdir/extension.toml"] + "#; + File::create(&root_config).unwrap().write_all(root_config_content).unwrap(); + + let extension = testdir.join("subdir/extension.toml"); + let extension_content = br#" + include = ["../extension2.toml"] + "#; + File::create(extension).unwrap().write_all(extension_content).unwrap(); + + let extension = testdir.join("extension2.toml"); + let extension_content = br#" + include = ["./subdir/another_subdir/extension3.toml"] + "#; + File::create(extension).unwrap().write_all(extension_content).unwrap(); + + let extension = testdir.join("subdir/another_subdir/extension3.toml"); + let extension_content = br#" + include = ["../../extension4.toml"] + "#; + File::create(extension).unwrap().write_all(extension_content).unwrap(); + + let extension = testdir.join("extension4.toml"); + File::create(extension).unwrap().write_all(&[]).unwrap(); + + let config = Config::parse_inner( + Flags::parse(&["check".to_owned(), format!("--config={}", root_config.to_str().unwrap())]), + get_toml, + ); +} + +#[test] +fn test_include_precedence_over_profile() { + let testdir = prepare_test_specific_dir(); + + let root_config = testdir.join("config.toml"); + let root_config_content = br#" + profile = "dist" + include = ["./extension.toml"] + "#; + File::create(&root_config).unwrap().write_all(root_config_content).unwrap(); + + let extension = testdir.join("extension.toml"); + let extension_content = br#" + [rust] + channel = "dev" + "#; + File::create(extension).unwrap().write_all(extension_content).unwrap(); + + let config = Config::parse_inner( + Flags::parse(&["check".to_owned(), format!("--config={}", root_config.to_str().unwrap())]), + get_toml, + ); + + // "dist" profile would normally set the channel to "auto-detect", but includes should + // override profile settings, so we expect this to be "dev" here. + assert_eq!(config.channel, "dev"); +} diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 9e4a72bc9c3..eb0bf1d166a 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -326,7 +326,7 @@ than building it. if target.contains("musl") && !target.contains("unikraft") { // If this is a native target (host is also musl) and no musl-root is given, // fall back to the system toolchain in /usr before giving up - if build.musl_root(*target).is_none() && build.is_builder_target(*target) { + if build.musl_root(*target).is_none() && build.config.is_host_target(*target) { let target = build.config.target_config.entry(*target).or_default(); target.musl_root = Some("/usr".into()); } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 1a513a240e1..88d181532a7 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -35,7 +35,7 @@ use utils::channel::GitInfo; use crate::core::builder; use crate::core::builder::Kind; -use crate::core::config::{DryRun, LldMode, LlvmLibunwind, Target, TargetSelection, flags}; +use crate::core::config::{DryRun, LldMode, LlvmLibunwind, TargetSelection, flags}; use crate::utils::exec::{BehaviorOnFailure, BootstrapCommand, CommandOutput, OutputMode, command}; use crate::utils::helpers::{ self, dir_is_empty, exe, libdir, output, set_file_times, split_debuginfo, symlink_dir, @@ -803,7 +803,7 @@ impl Build { /// Note that if LLVM is configured externally then the directory returned /// will likely be empty. fn llvm_out(&self, target: TargetSelection) -> PathBuf { - if self.config.llvm_from_ci && self.is_builder_target(target) { + if self.config.llvm_from_ci && self.config.is_host_target(target) { self.config.ci_llvm_root() } else { self.out.join(target).join("llvm") @@ -851,37 +851,6 @@ impl Build { if self.config.vendor { Some(self.src.join(VENDOR_DIR)) } else { None } } - /// Returns `true` if this is an external version of LLVM not managed by bootstrap. - /// In particular, we expect llvm sources to be available when this is false. - /// - /// NOTE: this is not the same as `!is_rust_llvm` when `llvm_has_patches` is set. - fn is_system_llvm(&self, target: TargetSelection) -> bool { - match self.config.target_config.get(&target) { - Some(Target { llvm_config: Some(_), .. }) => { - let ci_llvm = self.config.llvm_from_ci && self.is_builder_target(target); - !ci_llvm - } - // We're building from the in-tree src/llvm-project sources. - Some(Target { llvm_config: None, .. }) => false, - None => false, - } - } - - /// Returns `true` if this is our custom, patched, version of LLVM. - /// - /// This does not necessarily imply that we're managing the `llvm-project` submodule. - fn is_rust_llvm(&self, target: TargetSelection) -> bool { - match self.config.target_config.get(&target) { - // We're using a user-controlled version of LLVM. The user has explicitly told us whether the version has our patches. - // (They might be wrong, but that's not a supported use-case.) - // In particular, this tries to support `submodules = false` and `patches = false`, for using a newer version of LLVM that's not through `rust-lang/llvm-project`. - Some(Target { llvm_has_rust_patches: Some(patched), .. }) => *patched, - // The user hasn't promised the patches match. - // This only has our patches if it's downloaded from CI or built from source. - _ => !self.is_system_llvm(target), - } - } - /// Returns the path to `FileCheck` binary for the specified target fn llvm_filecheck(&self, target: TargetSelection) -> PathBuf { let target_config = self.config.target_config.get(&target); @@ -1356,7 +1325,7 @@ Executed at: {executed_at}"#, // need to use CXX compiler as linker to resolve the exception functions // that are only existed in CXX libraries Some(self.cxx.borrow()[&target].path().into()) - } else if !self.is_builder_target(target) + } else if !self.config.is_host_target(target) && helpers::use_host_linker(target) && !target.is_msvc() { @@ -2025,11 +1994,6 @@ to download LLVM rather than building it. stream.reset().unwrap(); result } - - /// Checks if the given target is the same as the builder target. - fn is_builder_target(&self, target: TargetSelection) -> bool { - self.config.build == target - } } #[cfg(unix)] diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 48b6f77e8a5..3f1885a425f 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -396,4 +396,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "Added a new option `build.compiletest-use-stage0-libtest` to force `compiletest` to use the stage 0 libtest.", }, + ChangeInfo { + change_id: 138934, + severity: ChangeSeverity::Info, + summary: "Added new option `include` to create config extensions.", + }, ]; diff --git a/src/ci/citool/Cargo.lock b/src/ci/citool/Cargo.lock index 2fe219f368b..43321d12caf 100644 --- a/src/ci/citool/Cargo.lock +++ b/src/ci/citool/Cargo.lock @@ -65,12 +65,63 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] +name = "askama" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4744ed2eef2645831b441d8f5459689ade2ab27c854488fbab1fbe94fce1a7" +dependencies = [ + "askama_derive", + "itoa", + "percent-encoding", + "serde", + "serde_json", +] + +[[package]] +name = "askama_derive" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d661e0f57be36a5c14c48f78d09011e67e0cb618f269cca9f2fd8d15b68c46ac" +dependencies = [ + "askama_parser", + "basic-toml", + "memchr", + "proc-macro2", + "quote", + "rustc-hash", + "serde", + "serde_derive", + "syn", +] + +[[package]] +name = "askama_parser" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf315ce6524c857bb129ff794935cf6d42c82a6cff60526fe2a63593de4d0d4f" +dependencies = [ + "memchr", + "serde", + "serde_derive", + "winnow", +] + +[[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] +name = "basic-toml" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a" +dependencies = [ + "serde", +] + +[[package]] name = "build_helper" version = "0.1.0" dependencies = [ @@ -104,6 +155,7 @@ name = "citool" version = "0.1.0" dependencies = [ "anyhow", + "askama", "build_helper", "clap", "csv", @@ -647,6 +699,12 @@ dependencies = [ ] [[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] name = "rustls" version = "0.23.23" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1027,6 +1085,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] +name = "winnow" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" +dependencies = [ + "memchr", +] + +[[package]] name = "write16" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml index f18436a1263..0e2aba3b9e3 100644 --- a/src/ci/citool/Cargo.toml +++ b/src/ci/citool/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] anyhow = "1" +askama = "0.13" clap = { version = "4.5", features = ["derive"] } csv = "1" diff = "0.1" diff --git a/src/ci/citool/src/analysis.rs b/src/ci/citool/src/analysis.rs index 9fc7c309bfb..62974be2dbe 100644 --- a/src/ci/citool/src/analysis.rs +++ b/src/ci/citool/src/analysis.rs @@ -8,9 +8,9 @@ use build_helper::metrics::{ }; use crate::github::JobInfoResolver; -use crate::metrics; use crate::metrics::{JobMetrics, JobName, get_test_suites}; use crate::utils::{output_details, pluralize}; +use crate::{metrics, utils}; /// Outputs durations of individual bootstrap steps from the gathered bootstrap invocations, /// and also a table with summarized information about executed tests. @@ -394,18 +394,17 @@ fn aggregate_tests(metrics: &JsonRoot) -> TestSuiteData { // Poor man's detection of doctests based on the "(line XYZ)" suffix let is_doctest = matches!(suite.metadata, TestSuiteMetadata::CargoPackage { .. }) && test.name.contains("(line"); - let test_entry = Test { name: generate_test_name(&test.name), stage, is_doctest }; + let test_entry = Test { + name: utils::normalize_path_delimiters(&test.name).to_string(), + stage, + is_doctest, + }; tests.insert(test_entry, test.outcome.clone()); } } TestSuiteData { tests } } -/// Normalizes Windows-style path delimiters to Unix-style paths. -fn generate_test_name(name: &str) -> String { - name.replace('\\', "/") -} - /// Prints test changes in Markdown format to stdout. fn report_test_diffs( diff: AggregatedTestDiffs, diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index a1956da352f..87ce09cfb23 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -4,6 +4,7 @@ mod datadog; mod github; mod jobs; mod metrics; +mod test_dashboard; mod utils; use std::collections::{BTreeMap, HashMap}; @@ -22,7 +23,8 @@ use crate::datadog::upload_datadog_metric; use crate::github::JobInfoResolver; use crate::jobs::RunType; use crate::metrics::{JobMetrics, download_auto_job_metrics, download_job_metrics, load_metrics}; -use crate::utils::load_env_var; +use crate::test_dashboard::generate_test_dashboard; +use crate::utils::{load_env_var, output_details}; const CI_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/.."); const DOCKER_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docker"); @@ -180,12 +182,26 @@ fn postprocess_metrics( } fn post_merge_report(db: JobDatabase, current: String, parent: String) -> anyhow::Result<()> { - let metrics = download_auto_job_metrics(&db, &parent, ¤t)?; + let metrics = download_auto_job_metrics(&db, Some(&parent), ¤t)?; println!("\nComparing {parent} (parent) -> {current} (this PR)\n"); let mut job_info_resolver = JobInfoResolver::new(); output_test_diffs(&metrics, &mut job_info_resolver); + + output_details("Test dashboard", || { + println!( + r#"Run + +```bash +cargo run --manifest-path src/ci/citool/Cargo.toml -- \ + test-dashboard {current} --output-dir test-dashboard +``` +And then open `test-dashboard/index.html` in your browser to see an overview of all executed tests. +"# + ); + }); + output_largest_duration_changes(&metrics, &mut job_info_resolver); Ok(()) @@ -234,6 +250,14 @@ enum Args { /// Current commit that will be compared to `parent`. current: String, }, + /// Generate a directory containing a HTML dashboard of test results from a CI run. + TestDashboard { + /// Commit SHA that was tested on CI to analyze. + current: String, + /// Output path for the HTML directory. + #[clap(long)] + output_dir: PathBuf, + }, } #[derive(clap::ValueEnum, Clone)] @@ -275,7 +299,11 @@ fn main() -> anyhow::Result<()> { postprocess_metrics(metrics_path, parent, job_name)?; } Args::PostMergeReport { current, parent } => { - post_merge_report(load_db(default_jobs_file)?, current, parent)?; + post_merge_report(load_db(&default_jobs_file)?, current, parent)?; + } + Args::TestDashboard { current, output_dir } => { + let db = load_db(&default_jobs_file)?; + generate_test_dashboard(db, ¤t, &output_dir)?; } } diff --git a/src/ci/citool/src/metrics.rs b/src/ci/citool/src/metrics.rs index a816fb3c4f1..3d8b1ad84cf 100644 --- a/src/ci/citool/src/metrics.rs +++ b/src/ci/citool/src/metrics.rs @@ -46,24 +46,25 @@ pub struct JobMetrics { /// `parent` and `current` should be commit SHAs. pub fn download_auto_job_metrics( job_db: &JobDatabase, - parent: &str, + parent: Option<&str>, current: &str, ) -> anyhow::Result<HashMap<JobName, JobMetrics>> { let mut jobs = HashMap::default(); for job in &job_db.auto_jobs { eprintln!("Downloading metrics of job {}", job.name); - let metrics_parent = match download_job_metrics(&job.name, parent) { - Ok(metrics) => Some(metrics), - Err(error) => { - eprintln!( - r#"Did not find metrics for job `{}` at `{parent}`: {error:?}. + let metrics_parent = + parent.and_then(|parent| match download_job_metrics(&job.name, parent) { + Ok(metrics) => Some(metrics), + Err(error) => { + eprintln!( + r#"Did not find metrics for job `{}` at `{parent}`: {error:?}. Maybe it was newly added?"#, - job.name - ); - None - } - }; + job.name + ); + None + } + }); let metrics_current = download_job_metrics(&job.name, current)?; jobs.insert( job.name.clone(), diff --git a/src/ci/citool/src/test_dashboard.rs b/src/ci/citool/src/test_dashboard.rs new file mode 100644 index 00000000000..8fbd0d3f200 --- /dev/null +++ b/src/ci/citool/src/test_dashboard.rs @@ -0,0 +1,216 @@ +use std::collections::{BTreeMap, HashMap}; +use std::fs::File; +use std::io::BufWriter; +use std::path::{Path, PathBuf}; + +use askama::Template; +use build_helper::metrics::{TestOutcome, TestSuiteMetadata}; + +use crate::jobs::JobDatabase; +use crate::metrics::{JobMetrics, JobName, download_auto_job_metrics, get_test_suites}; +use crate::utils::normalize_path_delimiters; + +/// Generate a set of HTML files into a directory that contain a dashboard of test results. +pub fn generate_test_dashboard( + db: JobDatabase, + current: &str, + output_dir: &Path, +) -> anyhow::Result<()> { + let metrics = download_auto_job_metrics(&db, None, current)?; + let suites = gather_test_suites(&metrics); + + std::fs::create_dir_all(output_dir)?; + + let test_count = suites.test_count(); + write_page(output_dir, "index.html", &TestSuitesPage { suites, test_count })?; + + Ok(()) +} + +fn write_page<T: Template>(dir: &Path, name: &str, template: &T) -> anyhow::Result<()> { + let mut file = BufWriter::new(File::create(dir.join(name))?); + Template::write_into(template, &mut file)?; + Ok(()) +} + +fn gather_test_suites(job_metrics: &HashMap<JobName, JobMetrics>) -> TestSuites { + struct CoarseTestSuite<'a> { + tests: BTreeMap<String, Test<'a>>, + } + + let mut suites: HashMap<String, CoarseTestSuite> = HashMap::new(); + + // First, gather tests from all jobs, stages and targets, and aggregate them per suite + // Only work with compiletest suites. + for (job, metrics) in job_metrics { + let test_suites = get_test_suites(&metrics.current); + for suite in test_suites { + let (suite_name, stage, target) = match &suite.metadata { + TestSuiteMetadata::CargoPackage { .. } => { + continue; + } + TestSuiteMetadata::Compiletest { suite, stage, target, .. } => { + (suite.clone(), *stage, target) + } + }; + let suite_entry = suites + .entry(suite_name.clone()) + .or_insert_with(|| CoarseTestSuite { tests: Default::default() }); + let test_metadata = TestMetadata { job, stage, target }; + + for test in &suite.tests { + let test_name = normalize_test_name(&test.name, &suite_name); + let (test_name, variant_name) = match test_name.rsplit_once('#') { + Some((name, variant)) => (name.to_string(), variant.to_string()), + None => (test_name, "".to_string()), + }; + let test_entry = suite_entry + .tests + .entry(test_name.clone()) + .or_insert_with(|| Test { revisions: Default::default() }); + let variant_entry = test_entry + .revisions + .entry(variant_name) + .or_insert_with(|| TestResults { passed: vec![], ignored: vec![] }); + + match test.outcome { + TestOutcome::Passed => { + variant_entry.passed.push(test_metadata); + } + TestOutcome::Ignored { ignore_reason: _ } => { + variant_entry.ignored.push(test_metadata); + } + TestOutcome::Failed => { + eprintln!("Warning: failed test {test_name}"); + } + } + } + } + } + + // Then, split the suites per directory + let mut suites = suites.into_iter().collect::<Vec<_>>(); + suites.sort_by(|a, b| a.0.cmp(&b.0)); + + let suites = suites + .into_iter() + .map(|(suite_name, suite)| TestSuite { group: build_test_group(&suite_name, suite.tests) }) + .collect(); + + TestSuites { suites } +} + +/// Recursively expand a test group based on filesystem hierarchy. +fn build_test_group<'a>(name: &str, tests: BTreeMap<String, Test<'a>>) -> TestGroup<'a> { + let mut root_tests = vec![]; + let mut subdirs: BTreeMap<String, BTreeMap<String, Test<'a>>> = Default::default(); + + // Split tests into root tests and tests located in subdirectories + for (name, test) in tests { + let mut components = Path::new(&name).components().peekable(); + let subdir = components.next().unwrap(); + + if components.peek().is_none() { + // This is a root test + root_tests.push((name, test)); + } else { + // This is a test in a nested directory + let subdir_tests = + subdirs.entry(subdir.as_os_str().to_str().unwrap().to_string()).or_default(); + let test_name = + components.into_iter().collect::<PathBuf>().to_str().unwrap().to_string(); + subdir_tests.insert(test_name, test); + } + } + let dirs = subdirs + .into_iter() + .map(|(name, tests)| { + let group = build_test_group(&name, tests); + (name, group) + }) + .collect(); + + TestGroup { name: name.to_string(), root_tests, groups: dirs } +} + +/// Compiletest tests start with `[suite] tests/[suite]/a/b/c...`. +/// Remove the `[suite] tests/[suite]/` prefix so that we can find the filesystem path. +/// Also normalizes path delimiters. +fn normalize_test_name(name: &str, suite_name: &str) -> String { + let name = normalize_path_delimiters(name); + let name = name.as_ref(); + let name = name.strip_prefix(&format!("[{suite_name}]")).unwrap_or(name).trim(); + let name = name.strip_prefix("tests/").unwrap_or(name); + let name = name.strip_prefix(suite_name).unwrap_or(name); + name.trim_start_matches("/").to_string() +} + +struct TestSuites<'a> { + suites: Vec<TestSuite<'a>>, +} + +impl<'a> TestSuites<'a> { + fn test_count(&self) -> u64 { + self.suites.iter().map(|suite| suite.group.test_count()).sum::<u64>() + } +} + +struct TestSuite<'a> { + group: TestGroup<'a>, +} + +struct TestResults<'a> { + passed: Vec<TestMetadata<'a>>, + ignored: Vec<TestMetadata<'a>>, +} + +struct Test<'a> { + revisions: BTreeMap<String, TestResults<'a>>, +} + +impl<'a> Test<'a> { + /// If this is a test without revisions, it will have a single entry in `revisions` with + /// an empty string as the revision name. + fn single_test(&self) -> Option<&TestResults<'a>> { + if self.revisions.len() == 1 { + self.revisions.iter().next().take_if(|e| e.0.is_empty()).map(|e| e.1) + } else { + None + } + } +} + +#[derive(Clone, Copy)] +#[allow(dead_code)] +struct TestMetadata<'a> { + job: &'a str, + stage: u32, + target: &'a str, +} + +// We have to use a template for the TestGroup instead of a macro, because +// macros cannot be recursive in askama at the moment. +#[derive(Template)] +#[template(path = "test_group.askama")] +/// Represents a group of tests +struct TestGroup<'a> { + name: String, + /// Tests located directly in this directory + root_tests: Vec<(String, Test<'a>)>, + /// Nested directories with additional tests + groups: Vec<(String, TestGroup<'a>)>, +} + +impl<'a> TestGroup<'a> { + fn test_count(&self) -> u64 { + let root = self.root_tests.len() as u64; + self.groups.iter().map(|(_, group)| group.test_count()).sum::<u64>() + root + } +} + +#[derive(Template)] +#[template(path = "test_suites.askama")] +struct TestSuitesPage<'a> { + suites: TestSuites<'a>, + test_count: u64, +} diff --git a/src/ci/citool/src/utils.rs b/src/ci/citool/src/utils.rs index a4c6ff85ef7..0367d349a1e 100644 --- a/src/ci/citool/src/utils.rs +++ b/src/ci/citool/src/utils.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::path::Path; use anyhow::Context; @@ -28,3 +29,8 @@ where func(); println!("</details>\n"); } + +/// Normalizes Windows-style path delimiters to Unix-style paths. +pub fn normalize_path_delimiters(name: &str) -> Cow<str> { + if name.contains("\\") { name.replace('\\', "/").into() } else { name.into() } +} diff --git a/src/ci/citool/templates/layout.askama b/src/ci/citool/templates/layout.askama new file mode 100644 index 00000000000..3b3b6f23741 --- /dev/null +++ b/src/ci/citool/templates/layout.askama @@ -0,0 +1,22 @@ +<html> +<head> + <meta charset="UTF-8"> + <title>Rust CI Test Dashboard</title> + <style> + body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + line-height: 1.6; + max-width: 1500px; + margin: 0 auto; + padding: 20px; + background: #F5F5F5; + } + {% block styles %}{% endblock %} + </style> +</head> + +<body> +{% block content %}{% endblock %} +{% block scripts %}{% endblock %} +</body> +</html> diff --git a/src/ci/citool/templates/test_group.askama b/src/ci/citool/templates/test_group.askama new file mode 100644 index 00000000000..95731103f3b --- /dev/null +++ b/src/ci/citool/templates/test_group.askama @@ -0,0 +1,42 @@ +{% macro test_result(r) -%} +passed: {{ r.passed.len() }}, ignored: {{ r.ignored.len() }} +{%- endmacro %} + +<li> +<details> +<summary>{{ name }} ({{ test_count() }} test{{ test_count() | pluralize }}{% if !root_tests.is_empty() && root_tests.len() as u64 != test_count() -%} + , {{ root_tests.len() }} root test{{ root_tests.len() | pluralize }} +{%- endif %}{% if !groups.is_empty() -%} + , {{ groups.len() }} subdir{{ groups.len() | pluralize }} +{%- endif %}) +</summary> + +{% if !groups.is_empty() %} +<ul> + {% for (dir_name, subgroup) in groups %} + {{ subgroup|safe }} + {% endfor %} +</ul> +{% endif %} + +{% if !root_tests.is_empty() %} +<ul> + {% for (name, test) in root_tests %} + <li> + {% if let Some(result) = test.single_test() %} + <b>{{ name }}</b> ({% call test_result(result) %}) + {% else %} + <b>{{ name }}</b> ({{ test.revisions.len() }} revision{{ test.revisions.len() | pluralize }}) + <ul> + {% for (revision, result) in test.revisions %} + <li>#<i>{{ revision }}</i> ({% call test_result(result) %})</li> + {% endfor %} + </ul> + {% endif %} + </li> + {% endfor %} +</ul> +{% endif %} + +</details> +</li> diff --git a/src/ci/citool/templates/test_suites.askama b/src/ci/citool/templates/test_suites.askama new file mode 100644 index 00000000000..4997f6a3f1c --- /dev/null +++ b/src/ci/citool/templates/test_suites.askama @@ -0,0 +1,108 @@ +{% extends "layout.askama" %} + +{% block content %} +<h1>Rust CI test dashboard</h1> +<div> +Here's how to interpret the "passed" and "ignored" counts: +the count includes all combinations of "stage" x "target" x "CI job where the test was executed or ignored". +</div> +<div class="test-suites"> + <div class="summary"> + <div> + <div class="test-count">Total tests: {{ test_count }}</div> + <div> + To find tests that haven't been executed anywhere, click on "Open all" and search for "passed: 0". + </div> + </div> + <div> + <button onclick="openAll()">Open all</button> + <button onclick="closeAll()">Close all</button> + </div> + </div> + + <ul> + {% for suite in suites.suites %} + {{ suite.group|safe }} + {% endfor %} + </ul> +</div> +{% endblock %} + +{% block styles %} +h1 { + text-align: center; + color: #333333; + margin-bottom: 30px; +} + +.summary { + display: flex; + justify-content: space-between; +} + +.test-count { + font-size: 1.2em; +} + +.test-suites { + background: white; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + padding: 20px; +} + +ul { + padding-left: 0; +} + +li { + list-style: none; + padding-left: 20px; +} +summary { + margin-bottom: 5px; + padding: 6px; + background-color: #F4F4F4; + border: 1px solid #ddd; + border-radius: 4px; + cursor: pointer; +} +summary:hover { + background-color: #CFCFCF; +} + +/* Style the disclosure triangles */ +details > summary { + list-style: none; + position: relative; +} + +details > summary::before { + content: "▶"; + position: absolute; + left: -15px; + transform: rotate(0); + transition: transform 0.2s; +} + +details[open] > summary::before { + transform: rotate(90deg); +} +{% endblock %} + +{% block scripts %} +<script type="text/javascript"> +function openAll() { + const details = document.getElementsByTagName("details"); + for (const elem of details) { + elem.open = true; + } +} +function closeAll() { + const details = document.getElementsByTagName("details"); + for (const elem of details) { + elem.open = false; + } +} +</script> +{% endblock %} diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md index 6a25a91f56a..9f468b933d7 100644 --- a/src/doc/rustc-dev-guide/README.md +++ b/src/doc/rustc-dev-guide/README.md @@ -43,13 +43,13 @@ rustdocs][rustdocs]. To build a local static HTML site, install [`mdbook`](https://github.com/rust-lang/mdBook) with: ``` -> cargo install mdbook mdbook-linkcheck2 mdbook-toc mdbook-mermaid +cargo install mdbook mdbook-linkcheck2 mdbook-toc mdbook-mermaid ``` and execute the following command in the root of the repository: ``` -> mdbook build --open +mdbook build --open ``` The build files are found in the `book/html` directory. @@ -61,8 +61,8 @@ checking is **not** run by default locally, though it is in CI. To enable it locally, set the environment variable `ENABLE_LINKCHECK=1` like in the following example. -```console -$ ENABLE_LINKCHECK=1 mdbook serve +``` +ENABLE_LINKCHECK=1 mdbook serve ``` ### Table of Contents @@ -86,14 +86,14 @@ Older versions of `josh-proxy` may not round trip commits losslessly so it is im 1) Checkout a new branch that will be used to create a PR into `rust-lang/rustc-dev-guide` 2) Run the pull command ``` - $ cargo run --manifest-path josh-sync/Cargo.toml rustc-pull + cargo run --manifest-path josh-sync/Cargo.toml rustc-pull ``` 3) Push the branch to your fork and create a PR into `rustc-dev-guide` ### Push changes from this repository into `rust-lang/rust` 1) Run the push command to create a branch named `<branch-name>` in a `rustc` fork under the `<gh-username>` account ``` - $ cargo run --manifest-path josh-sync/Cargo.toml rustc-push <branch-name> <gh-username> + cargo run --manifest-path josh-sync/Cargo.toml rustc-push <branch-name> <gh-username> ``` 2) Create a PR from `<branch-name>` into `rust-lang/rust` @@ -106,5 +106,5 @@ You may observe "Nothing to pull" even if you *know* rustc-pull has something to To minimize the likelihood of this happening, you may wish to keep a separate *minimal* git config that *only* has `[user]` entries from global git config, then repoint system git to use the minimal git config instead. E.g. ``` -$ GIT_CONFIG_GLOBAL=/path/to/minimal/gitconfig GIT_CONFIG_SYSTEM='' cargo +stable run --manifest-path josh-sync/Cargo.toml -- rustc-pull +GIT_CONFIG_GLOBAL=/path/to/minimal/gitconfig GIT_CONFIG_SYSTEM='' cargo +stable run --manifest-path josh-sync/Cargo.toml -- rustc-pull ``` diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index a6f29510879..dc52e0928cc 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -25a615bf829b9f6d6f22da537e3851043f92e5f2 +b8005bff3248cfc6e327faf4fa631ac49bb49ba9 diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index 95a3cd7c790..68112d06167 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -10,9 +10,9 @@ - [How to build and run the compiler](./building/how-to-build-and-run.md) - [Quickstart](./building/quickstart.md) - [Prerequisites](./building/prerequisites.md) - - [Suggested Workflows](./building/suggested.md) + - [Suggested workflows](./building/suggested.md) - [Distribution artifacts](./building/build-install-distribution-artifacts.md) - - [Building Documentation](./building/compiler-documenting.md) + - [Building documentation](./building/compiler-documenting.md) - [Rustdoc overview](./rustdoc.md) - [Adding a new target](./building/new-target.md) - [Optimized build](./building/optimized-build.md) @@ -42,11 +42,11 @@ - [with the linux perf tool](./profiling/with_perf.md) - [with Windows Performance Analyzer](./profiling/wpa_profiling.md) - [with the Rust benchmark suite](./profiling/with_rustc_perf.md) -- [crates.io Dependencies](./crates-io.md) +- [crates.io dependencies](./crates-io.md) # Contributing to Rust -- [Contribution Procedures](./contributing.md) +- [Contribution procedures](./contributing.md) - [About the compiler team](./compiler-team.md) - [Using Git](./git.md) - [Mastering @rustbot](./rustbot.md) @@ -56,7 +56,7 @@ - [Stabilizing Features](./stabilization_guide.md) - [Feature Gates](./feature-gates.md) - [Coding conventions](./conventions.md) -- [Procedures for Breaking Changes](./bug-fix-procedure.md) +- [Procedures for breaking changes](./bug-fix-procedure.md) - [Using external repositories](./external-repos.md) - [Fuzzing](./fuzzing.md) - [Notification groups](notification-groups/about.md) @@ -81,6 +81,7 @@ - [How Bootstrap does it](./building/bootstrapping/how-bootstrap-does-it.md) - [Writing tools in Bootstrap](./building/bootstrapping/writing-tools-in-bootstrap.md) - [Debugging bootstrap](./building/bootstrapping/debugging-bootstrap.md) +- [cfg(bootstrap) in dependencies](./building/bootstrapping/bootstrap-in-dependencies.md) # High-level Compiler Architecture @@ -88,29 +89,35 @@ - [Overview of the compiler](./overview.md) - [The compiler source code](./compiler-src.md) - [Queries: demand-driven compilation](./query.md) - - [The Query Evaluation Model in Detail](./queries/query-evaluation-model-in-detail.md) + - [The Query Evaluation Model in detail](./queries/query-evaluation-model-in-detail.md) - [Incremental compilation](./queries/incremental-compilation.md) - - [Incremental compilation In Detail](./queries/incremental-compilation-in-detail.md) - - [Debugging and Testing](./incrcomp-debugging.md) + - [Incremental compilation in detail](./queries/incremental-compilation-in-detail.md) + - [Debugging and testing](./incrcomp-debugging.md) - [Salsa](./queries/salsa.md) -- [Memory Management in Rustc](./memory.md) -- [Serialization in Rustc](./serialization.md) -- [Parallel Compilation](./parallel-rustc.md) +- [Memory management in rustc](./memory.md) +- [Serialization in rustc](./serialization.md) +- [Parallel compilation](./parallel-rustc.md) - [Rustdoc internals](./rustdoc-internals.md) - [Search](./rustdoc-internals/search.md) - [The `rustdoc` test suite](./rustdoc-internals/rustdoc-test-suite.md) +- [Autodiff internals](./autodiff/internals.md) + - [Installation](./autodiff/installation.md) + - [How to debug](./autodiff/debugging.md) + - [Autodiff flags](./autodiff/flags.md) + - [Current limitations](./autodiff/limitations.md) + # Source Code Representation - [Prologue](./part-3-intro.md) - [Syntax and the AST](./syntax-intro.md) - - [Lexing and Parsing](./the-parser.md) + - [Lexing and parsing](./the-parser.md) - [Macro expansion](./macro-expansion.md) - [Name resolution](./name-resolution.md) - [Attributes](./attributes.md) - - [`#[test]` Implementation](./test-implementation.md) - - [Panic Implementation](./panic-implementation.md) - - [AST Validation](./ast-validation.md) - - [Feature Gate Checking](./feature-gate-ck.md) + - [`#[test]` implementation](./test-implementation.md) + - [Panic implementation](./panic-implementation.md) + - [AST validation](./ast-validation.md) + - [Feature gate checking](./feature-gate-ck.md) - [Lang Items](./lang-items.md) - [The HIR (High-level IR)](./hir.md) - [Lowering AST to HIR](./ast-lowering.md) @@ -129,7 +136,7 @@ - [Example: Type checking](./rustc-driver/interacting-with-the-ast.md) - [Example: Getting diagnostics](./rustc-driver/getting-diagnostics.md) - [Remarks on perma-unstable features](./rustc-driver/remarks-on-perma-unstable-features.md) -- [Errors and Lints](diagnostics.md) +- [Errors and lints](diagnostics.md) - [Diagnostic and subdiagnostic structs](./diagnostics/diagnostic-structs.md) - [Translation](./diagnostics/translation.md) - [`LintStore`](./diagnostics/lintstore.md) @@ -175,14 +182,14 @@ - [Type checking](./type-checking.md) - [Method Lookup](./method-lookup.md) - [Variance](./variance.md) - - [Coherence Checking](./coherence.md) - - [Opaque Types](./opaque-types-type-alias-impl-trait.md) + - [Coherence checking](./coherence.md) + - [Opaque types](./opaque-types-type-alias-impl-trait.md) - [Inference details](./opaque-types-impl-trait-inference.md) - [Return Position Impl Trait In Trait](./return-position-impl-trait-in-trait.md) - [Region inference restrictions][opaque-infer] - [Const condition checking](./effects.md) - [Pattern and Exhaustiveness Checking](./pat-exhaustive-checking.md) -- [Unsafety Checking](./unsafety-checking.md) +- [Unsafety checking](./unsafety-checking.md) - [MIR dataflow](./mir/dataflow.md) - [Drop elaboration](./mir/drop-elaboration.md) - [The borrow checker](./borrow_check.md) diff --git a/src/doc/rustc-dev-guide/src/about-this-guide.md b/src/doc/rustc-dev-guide/src/about-this-guide.md index 781a5c51bf7..057e4a4ccee 100644 --- a/src/doc/rustc-dev-guide/src/about-this-guide.md +++ b/src/doc/rustc-dev-guide/src/about-this-guide.md @@ -3,33 +3,41 @@ This guide is meant to help document how rustc – the Rust compiler – works, as well as to help new contributors get involved in rustc development. -There are seven parts to this guide: +There are several parts to this guide: -1. [Building `rustc`][p1]: +1. [Building and debugging `rustc`][p1]: Contains information that should be useful no matter how you are contributing, about building, debugging, profiling, etc. -2. [Contributing to `rustc`][p2]: +1. [Contributing to Rust][p2]: Contains information that should be useful no matter how you are contributing, about procedures for contribution, using git and Github, stabilizing features, etc. -3. [High-Level Compiler Architecture][p3]: +1. [Bootstrapping][p3]: + Describes how the Rust compiler builds itself using previous versions, including + an introduction to the bootstrap process and debugging methods. +1. [High-level Compiler Architecture][p4]: Discusses the high-level architecture of the compiler and stages of the compile process. -4. [Source Code Representation][p4]: +1. [Source Code Representation][p5]: Describes the process of taking raw source code from the user and transforming it into various forms that the compiler can work with easily. -5. [Analysis][p5]: - discusses the analyses that the compiler uses to check various properties of the code +1. [Supporting Infrastructure][p6]: + Covers command-line argument conventions, compiler entry points like rustc_driver and + rustc_interface, and the design and implementation of errors and lints. +1. [Analysis][p7]: + Discusses the analyses that the compiler uses to check various properties of the code and inform later stages of the compile process (e.g., type checking). -6. [From MIR to Binaries][p6]: How linked executable machine code is generated. -7. [Appendices][p7] at the end with useful reference information. +1. [MIR to Binaries][p8]: How linked executable machine code is generated. +1. [Appendices][p9] at the end with useful reference information. There are a few of these with different information, including a glossary. [p1]: ./building/how-to-build-and-run.html [p2]: ./contributing.md -[p3]: ./part-2-intro.md -[p4]: ./part-3-intro.md -[p5]: ./part-4-intro.md -[p6]: ./part-5-intro.md -[p7]: ./appendix/background.md +[p3]: ./building/bootstrapping/intro.md +[p4]: ./part-2-intro.md +[p5]: ./part-3-intro.md +[p6]: ./cli.md +[p7]: ./part-4-intro.md +[p8]: ./part-5-intro.md +[p9]: ./appendix/background.md ### Constant change diff --git a/src/doc/rustc-dev-guide/src/ast-validation.md b/src/doc/rustc-dev-guide/src/ast-validation.md index fa0f1d954f8..8f10bbecf21 100644 --- a/src/doc/rustc-dev-guide/src/ast-validation.md +++ b/src/doc/rustc-dev-guide/src/ast-validation.md @@ -1,4 +1,4 @@ -# AST Validation +# AST validation _AST validation_ is a separate AST pass that visits each item in the tree and performs simple checks. This pass diff --git a/src/doc/rustc-dev-guide/src/autodiff/debugging.md b/src/doc/rustc-dev-guide/src/autodiff/debugging.md new file mode 100644 index 00000000000..bd46a66fade --- /dev/null +++ b/src/doc/rustc-dev-guide/src/autodiff/debugging.md @@ -0,0 +1,113 @@ +# Reporting backend crashes + +If after a compilation failure you are greeted by a large amount of llvm-ir code, then our enzyme backend likely failed to compile your code. These cases are harder to debug, so your help is highly appreciated. Please also keep in mind that release builds are usually much more likely to work at the moment. + +The final goal here is to reproduce your bug in the enzyme [compiler explorer](https://enzyme.mit.edu/explorer/), in order to create a bug report in the [Enzyme](https://github.com/enzymead/enzyme/issues) repository. + +We have an `autodiff` flag which you can pass to `rustflags` to help with this. it will print the whole llvm-ir module, along with some `__enzyme_fwddiff` or `__enzyme_autodiff` calls. A potential workflow on linux could look like: + +## Controlling llvm-ir generation + +Before generating the llvm-ir, keep in mind two techniques that can help ensure the relevant rust code is visible for debugging: + +- **`std::hint::black_box`**: wrap rust variables or expressions in `std::hint::black_box()` to prevent rust and llvm from optimizing them away. This is useful when you need to inspect or manually manipulate specific values in the llvm-ir. +- **`extern "rust"` or `extern "c"`**: if you want to see how a specific function declaration is lowered to llvm-ir, you can declare it as `extern "rust"` or `extern "c"`. You can also look for existing `__enzyme_autodiff` or similar declarations within the generated module for examples. + +## 1) Generate an llvm-ir reproducer + +```sh +rustflags="-z autodiff=enable,printmodbefore" cargo +enzyme build --release &> out.ll +``` + +This also captures a few warnings and info messages above and below your module. open out.ll and remove every line above `; moduleid = <somehash>`. Now look at the end of the file and remove everything that's not part of llvm-ir, i.e. remove errors and warnings. The last line of your llvm-ir should now start with `!<somenumber> = `, i.e. `!40831 = !{i32 0, i32 1037508, i32 1037538, i32 1037559}` or `!43760 = !dilocation(line: 297, column: 5, scope: !43746)`. + +The actual numbers will depend on your code. + +## 2) Check your llvm-ir reproducer + +To confirm that your previous step worked, we will use llvm's `opt` tool. find your path to the opt binary, with a path similar to `<some_dir>/rust/build/<x86/arm/...-target-tripple>/build/bin/opt`. also find `llvmenzyme-19.<so/dll/dylib>` path, similar to `/rust/build/target-tripple/enzyme/build/enzyme/llvmenzyme-19`. Please keep in mind that llvm frequently updates it's llvm backend, so the version number might be higher (20, 21, ...). Once you have both, run the following command: + +```sh +<path/to/opt> out.ll -load-pass-plugin=/path/to/llvmenzyme-19.so -passes="enzyme" -s +``` + +If the previous step succeeded, you are going to see the same error that you saw when compiling your rust code with cargo. + +If you fail to get the same error, please open an issue in the rust repository. If you succeed, congrats! the file is still huge, so let's automatically minimize it. + +## 3) Minimize your llvm-ir reproducer + +First find your `llvm-extract` binary, it's in the same folder as your opt binary. then run: + +```sh +<path/to/llvm-extract> -s --func=<name> --recursive --rfunc="enzyme_autodiff*" --rfunc="enzyme_fwddiff*" --rfunc=<fnc_called_by_enzyme> out.ll -o mwe.ll +``` + +This command creates `mwe.ll`, a minimal working example. + +Please adjust the name passed with the last `--func` flag. You can either apply the `#[no_mangle]` attribute to the function you differentiate, then you can replace it with the rust name. otherwise you will need to look up the mangled function name. To do that, open `out.ll` and search for `__enzyme_fwddiff` or `__enzyme_autodiff`. the first string in that function call is the name of your function. example: + +```llvm-ir +define double @enzyme_opt_helper_0(ptr %0, i64 %1, double %2) { + %4 = call double (...) @__enzyme_fwddiff(ptr @_zn2ad3_f217h3b3b1800bd39fde3e, metadata !"enzyme_const", ptr %0, metadata !"enzyme_const", i64 %1, metadata !"enzyme_dup", double %2, double %2) + ret double %4 +} +``` + +Here, `_zn2ad3_f217h3b3b1800bd39fde3e` is the correct name. make sure to not copy the leading `@`. redo step 2) by running the `opt` command again, but this time passing `mwe.ll` as the input file instead of `out.ll`. Check if this minimized example still reproduces the crash. + +## 4) (Optional) Minimize your llvm-ir reproducer further. + +After the previous step you should have an `mwe.ll` file with ~5k loc. let's try to get it down to 50. find your `llvm-reduce` binary next to `opt` and `llvm-extract`. Copy the first line of your error message, an example could be: + +```sh +opt: /home/manuel/prog/rust/src/llvm-project/llvm/lib/ir/instructions.cpp:686: void llvm::callinst::init(llvm::functiontype*, llvm::value*, llvm::arrayref<llvm::value*>, llvm::arrayref<llvm::operandbundledeft<llvm::value*> >, const llvm::twine&): assertion `(args.size() == fty->getnumparams() || (fty->isvararg() && args.size() > fty->getnumparams())) && "calling a function with bad signature!"' failed. +``` + +If you just get a `segfault` there is no sensible error message and not much to do automatically, so continue to 5). +otherwise, create a `script.sh` file containing + +```sh +#!/bin/bash +<path/to/your/opt> $1 -load-pass-plugin=/path/to/llvmenzyme-19.so -passes="enzyme" \ + |& grep "/some/path.cpp:686: void llvm::callinst::init" +``` + +Experiment a bit with which error message you pass to grep. it should be long enough to make sure that the error is unique. However, for longer errors including `(` or `)` you will need to escape them correctly which can become annoying. Run + +```sh +<path/to/llvm-reduce> --test=script.sh mwe.ll +``` + +If you see `input isn't interesting! verify interesting-ness test`, you got the error message in script.sh wrong, you need to make sure that grep matches your actual error. If all works out, you will see a lot of iterations, ending with a new `reduced.ll` file. Verify with `opt` that you still get the same error. + +### Advanced debugging: manual llvm-ir investigation + +Once you have a minimized reproducer (`mwe.ll` or `reduced.ll`), you can delve deeper: + +- **manual editing:** try manually rewriting the llvm-ir. for certain issues, like those involving indirect calls, you might investigate enzyme-specific intrinsics like `__enzyme_virtualreverse`. Understanding how to use these might require consulting enzyme's documentation or source code. +- **enzyme test cases:** look for relevant test cases within the [enzyme repository](https://github.com/enzymead/enzyme/tree/main/enzyme/test) that might demonstrate the correct usage of features or intrinsics related to your problem. + +## 5) Report your bug. + +Afterwards, you should be able to copy and paste your `mwe.ll` (or `reduced.ll`) example into our [compiler explorer](https://enzyme.mit.edu/explorer/). + +- Select `llvm ir` as language and `opt 20` as compiler. +- Replace the field to the right of your compiler with `-passes="enzyme"`, if it is not already set. +- Hopefully, you will see once again your now familiar error. +- Please use the share button to copy links to them. +- Please create an issue on [https://github.com/enzymead/enzyme/issues](https://github.com/enzymead/enzyme/issues) and share `mwe.ll` and (if you have it) `reduced.ll`, as well as links to the compiler explorer. Please feel free to also add your rust code or a link to it. + +#### Documenting findings + +some enzyme errors, like `"attempting to call an indirect active function whose runtime value is inactive"`, have historically caused confusion. If you investigate such an issue, even if you don't find a complete solution, please consider documenting your findings. If the insights are general to enzyme and not specific to its rust usage, contributing them to the main [enzyme documentation](https://github.com/enzymead/www) is often the best first step. You can also mention your findings in the relevant enzyme github issue or propose updates to these docs if appropriate. This helps prevent others from starting from scratch. + +With a clear reproducer and documentation, hopefully an enzyme developer will be able to fix your bug. Once that happens, the enzyme submodule inside the rust compiler will be updated, which should allow you to differentiate your rust code. Thanks for helping us to improve rust-ad. + +# Minimize rust code + +Beyond having a minimal llvm-ir reproducer, it is also helpful to have a minimal rust reproducer without dependencies. This allows us to add it as a test case to ci once we fix it, which avoids regressions for the future. + +There are a few solutions to help you with minimizing the rust reproducer. This is probably the most simple automated approach: [cargo-minimize](https://github.com/nilstrieb/cargo-minimize). + +Otherwise we have various alternatives, including [`treereduce`](https://github.com/langston-barrett/treereduce), [`halfempty`](https://github.com/googleprojectzero/halfempty), or [`picireny`](https://github.com/renatahodovan/picireny), potentially also [`creduce`](https://github.com/csmith-project/creduce). diff --git a/src/doc/rustc-dev-guide/src/autodiff/flags.md b/src/doc/rustc-dev-guide/src/autodiff/flags.md new file mode 100644 index 00000000000..946ae1d03ae --- /dev/null +++ b/src/doc/rustc-dev-guide/src/autodiff/flags.md @@ -0,0 +1,42 @@ +# Supported `RUSTFLAGS` + +To support you while debugging or profiling, we have added support for an experimental `-Z autodiff` rustc flag (which can be passed to cargo via `RUSTFLAGS`), which allow changing the behaviour of Enzyme, without recompiling rustc. We currently support the following values for `autodiff`. + +### Debug Flags + +```text +PrintTA // Print TypeAnalysis information +PrintAA // Print ActivityAnalysis information +Print // Print differentiated functions while they are being generated and optimized +PrintPerf // Print AD related Performance warnings +PrintModBefore // Print the whole LLVM-IR module directly before running AD +PrintModAfter // Print the whole LLVM-IR module after running AD, before optimizations +PrintModFinal // Print the whole LLVM-IR module after running optimizations and AD +LooseTypes // Risk incorrect derivatives instead of aborting when missing Type Info +``` + +<div class="warning"> +`LooseTypes` is often helpful to get rid of Enzyme errors stating `Can not deduce type of <X>` and to be able to run some code. But please keep in mind that this flag absolutely has the chance to cause incorrect gradients. Even worse, the gradients might be correct for certain input values, but not for others. So please create issues about such bugs and only use this flag temporarily while you wait for your bug to be fixed. +</div> + +### Benchmark flags + +For performance experiments and benchmarking we also support + +```text +NoPostopt // We won't optimize the LLVM-IR Module after AD +RuntimeActivity // Enables the runtime activity feature from Enzyme +Inline // Instructs Enzyme to maximize inlining as far as possible, beyond LLVM's default +``` + +You can combine multiple `autodiff` values using a comma as separator: + +```bash +RUSTFLAGS="-Z autodiff=Enable,LooseTypes,PrintPerf" cargo +enzyme build +``` + +Using `-Zautodiff=Enable` will allow using autodiff and update your normal rustc compilation pipeline: + +1. Run your selected compilation pipeline. If you selected a release build, we will disable vectorization and loop unrolling. +2. Differentiate your functions. +3. Run your selected compilation pipeline again on the whole module. This time we do not disable vectorization or loop unrolling. diff --git a/src/doc/rustc-dev-guide/src/autodiff/installation.md b/src/doc/rustc-dev-guide/src/autodiff/installation.md new file mode 100644 index 00000000000..dbea9dbe144 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/autodiff/installation.md @@ -0,0 +1,86 @@ +# Installation + +In the near future, `std::autodiff` should become available in nightly builds for users. As a contribute however, you will still need to build rustc from source. Please be aware that the msvc target is not supported at the moment, all other tier 1 targets should work. Please open an issue if you encounter any problems on a supported tier 1 target, or if you succesfully build this project on a tier2/tier3 target. + +## Build instructions + +First you need to clone and configure the Rust repository: +```bash +git clone --depth=1 git@github.com:rust-lang/rust.git +cd rust +./configure --enable-llvm-link-shared --enable-llvm-plugins --enable-llvm-enzyme --release-channel=nightly --enable-llvm-assertions --enable-clang --enable-lld --enable-option-checking --enable-ninja --disable-docs +``` + +Afterwards you can build rustc using: +```bash +./x.py build --stage 1 library +``` + +Afterwards rustc toolchain link will allow you to use it through cargo: +``` +rustup toolchain link enzyme build/host/stage1 +rustup toolchain install nightly # enables -Z unstable-options +``` + +You can then run our test cases: + +```bash +./x.py test --stage 1 library tests/ui/autodiff +./x.py test --stage 1 library tests/codegen/autodiff +./x.py test --stage 1 library tests/pretty/autodiff* +``` + +Autodiff is still experimental, so if you want to use it in your own projects, you will need to add `lto="fat"` to your Cargo.toml +and use `RUSTFLAGS="-Zautodiff=Enable" cargo +enzyme` instead of `cargo` or `cargo +nightly`. + +## Compiler Explorer and dist builds + +Our compiler explorer instance can be updated to a newer rustc in a similar way. First, prepare a docker instance. +```bash +docker run -it ubuntu:22.04 +export CC=clang CXX=clang++ +apt update +apt install wget vim python3 git curl libssl-dev pkg-config lld ninja-build cmake clang build-essential +``` +Then build rustc in a slightly altered way: +```bash +git clone --depth=1 https://github.com/EnzymeAD/rust.git +cd rust +./configure --enable-llvm-link-shared --enable-llvm-plugins --enable-llvm-enzyme --release-channel=nightly --enable-llvm-assertions --enable-clang --enable-lld --enable-option-checking --enable-ninja --disable-docs +./x dist +``` +We then copy the tarball to our host. The dockerid is the newest entry under `docker ps -a`. +```bash +docker cp <dockerid>:/rust/build/dist/rust-nightly-x86_64-unknown-linux-gnu.tar.gz rust-nightly-x86_64-unknown-linux-gnu.tar.gz +``` +Afterwards we can create a new (pre-release) tag on the EnzymeAD/rust repository and make a PR against the EnzymeAD/enzyme-explorer repository to update the tag. +Remember to ping `tgymnich` on the PR to run his update script. + + +## Build instruction for Enzyme itself + +Following the Rust build instruction above will build LLVMEnzyme, LLDEnzyme, and ClangEnzyme along with the Rust compiler. +We recommend that approach, if you just want to use any of them and have no experience with cmake. +However, if you prefer to just build Enzyme without Rust, then these instructions might help. + +```bash +git clone --depth=1 git@github.com:llvm/llvm-project.git +cd llvm-project +mkdir build +cd build +cmake -G Ninja ../llvm -DLLVM_TARGETS_TO_BUILD="host" -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_ENABLE_RUNTIMES="openmp" -DLLVM_ENABLE_PLUGINS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=. +ninja +ninja install +``` +This gives you a working LLVM build, now we can continue with building Enzyme. +Leave the `llvm-project` folder, and execute the following commands: +```bash +git clone git@github.com:EnzymeAD/Enzyme.git +cd Enzyme/enzyme +mkdir build +cd build +cmake .. -G Ninja -DLLVM_DIR=<YourLocalPath>/llvm-project/build/lib/cmake/llvm/ -DLLVM_EXTERNAL_LIT=<YourLocalPath>/llvm-project/llvm/utils/lit/lit.py -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=YES -DBUILD_SHARED_LIBS=ON +ninja +``` +This will build Enzyme, and you can find it in `Enzyme/enzyme/build/lib/<LLD/Clang/LLVM>Enzyme.so`. (Endings might differ based on your OS). + diff --git a/src/doc/rustc-dev-guide/src/autodiff/internals.md b/src/doc/rustc-dev-guide/src/autodiff/internals.md new file mode 100644 index 00000000000..0093ef044c8 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/autodiff/internals.md @@ -0,0 +1,27 @@ +The `std::autodiff` module in Rust allows differentiable programming: + +```rust +#![feature(autodiff)] +use std::autodiff::autodiff; + +// f(x) = x * x, f'(x) = 2.0 * x +// bar therefore returns (x * x, 2.0 * x) +#[autodiff(bar, Reverse, Active, Active)] +fn foo(x: f32) -> f32 { x * x } + +fn main() { + assert_eq!(bar(3.0, 1.0), (9.0, 6.0)); + assert_eq!(bar(4.0, 1.0), (16.0, 8.0)); +} +``` + +The detailed documentation for the `std::autodiff` module is available at [std::autodiff](https://doc.rust-lang.org/std/autodiff/index.html). + +Differentiable programing is used in various fields like numerical computing, [solid mechanics][ratel], [computational chemistry][molpipx], [fluid dynamics][waterlily] or for Neural Network training via Backpropagation, [ODE solver][diffsol], [differentiable rendering][libigl], [quantum computing][catalyst], and climate simulations. + +[ratel]: https://gitlab.com/micromorph/ratel +[molpipx]: https://arxiv.org/abs/2411.17011v +[waterlily]: https://github.com/WaterLily-jl/WaterLily.jl +[diffsol]: https://github.com/martinjrobins/diffsol +[libigl]: https://github.com/alecjacobson/libigl-enzyme-example?tab=readme-ov-file#run +[catalyst]: https://github.com/PennyLaneAI/catalyst diff --git a/src/doc/rustc-dev-guide/src/autodiff/limitations.md b/src/doc/rustc-dev-guide/src/autodiff/limitations.md new file mode 100644 index 00000000000..90afbd51f3f --- /dev/null +++ b/src/doc/rustc-dev-guide/src/autodiff/limitations.md @@ -0,0 +1,27 @@ +# Current limitations + +## Safety and Soundness + +Enzyme currently assumes that the user passes shadow arguments (`dx`, `dy`, ...) of appropriate size. Under Reverse Mode, we additionally assume that shadow arguments are mutable. In Reverse Mode we adjust the outermost pointer or reference to be mutable. Therefore `&f32` will receive the shadow type `&mut f32`. However, we do not check length for other types than slices (e.g. enums, Vec). We also do not enforce mutability of inner references, but will warn if we recognize them. We do intend to add additional checks over time. + +## ABI adjustments + +In some cases, a function parameter might get lowered in a way that we currently don't handle correctly, leading to a compile time type mismatch in the `rustc_codegen_llvm` backend. Here are some [examples](https://github.com/EnzymeAD/rust/issues/105). + +## Compile Times + +Enzyme will often achieve excellent runtime performance, but might increase your compile time by a large factor. For Rust, we already have made significant improvements and have a list of further improvements planed - please reach out if you have time to help here. + +### Type Analysis + +Most of the times, Type Analysis (TA) is the reason of large (>5x) compile time increases when using Enzyme. This poster explains why we need to run Type Analysis in the bottom left part: [Poster Link](https://c.wsmoses.com/posters/Enzyme-llvmdev.pdf). + +We intend to increase the number of locations where we pass down Type information based on Rust types, which in turn will reduce the number of locations where Enzyme has to run Type Analysis, which will help compile times. + +### Duplicated Optimizations + +The key reason for Enzyme offering often excellent performance is that Enzyme differentiates already optimized LLVM-IR. However, we also (have to) run LLVM's optimization pipeline after differentiating, to make sure that the code which Enzyme generates is optimized properly. As a result you should have excellent runtime performance (please fill an issue if not), but at a compile time cost for running optimizations twice. + +### Fat-LTO + +The usage of `#[autodiff(...)]` currently requires compiling your project with Fat-LTO. We technically only need LTO if the function being differentiated calls functions in other compilation units. Therefore, other solutions are possible, but this is the most simple one to get started. diff --git a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md index e6a16df6d2a..8e6725c54ef 100644 --- a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md +++ b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md @@ -1,4 +1,4 @@ -# Procedures for Breaking Changes +# Procedures for breaking changes <!-- toc --> diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping/bootstrap-in-dependencies.md b/src/doc/rustc-dev-guide/src/building/bootstrapping/bootstrap-in-dependencies.md new file mode 100644 index 00000000000..68c5c2386bd --- /dev/null +++ b/src/doc/rustc-dev-guide/src/building/bootstrapping/bootstrap-in-dependencies.md @@ -0,0 +1,53 @@ +# `cfg(bootstrap)` in compiler dependencies + +The rust compiler uses some external crates that can run into cyclic dependencies with the compiler itself: the compiler needs an updated crate to build, but the crate needs an updated compiler. This page describes how `#[cfg(bootstrap)]` can be used to break this cycle. + +## Enabling `#[cfg(bootstrap)]` + +Usually the use of `#[cfg(bootstrap)]` in an external crate causes a warning: + +``` +warning: unexpected `cfg` condition name: `bootstrap` + --> src/main.rs:1:7 + | +1 | #[cfg(bootstrap)] + | ^^^^^^^^^ + | + = help: expected names are: `docsrs`, `feature`, and `test` and 31 more + = help: consider using a Cargo feature instead + = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint: + [lints.rust] + unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] } + = help: or consider adding `println!("cargo::rustc-check-cfg=cfg(bootstrap)");` to the top of the `build.rs` + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default +``` + +This warning can be silenced by adding these lines to the project's `Cargo.toml`: + +```toml +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] } +``` + +Now `#[cfg(bootstrap)]` can be used in the crate just like it can be in the compiler: when the bootstrap compiler is used, code annotated with `#[cfg(bootstrap)]` is compiled, otherwise code annotated with `#[cfg(not(bootstrap))]` is compiled. + +## The update dance + +As a concrete example we'll use a change where the `#[naked]` attribute was made into an unsafe attribute, which caused a cyclic dependency with the `compiler-builtins` crate. + +### Step 1: accept the new behavior in the compiler ([#139797](https://github.com/rust-lang/rust/pull/139797)) + +In this example it is possible to accept both the old and new behavior at the same time by disabling an error. + +### Step 2: update the crate ([#821](https://github.com/rust-lang/compiler-builtins/pull/821)) + +Now in the crate, use `#[cfg(bootstrap)]` to use the old behavior, or `#[cfg(not(bootstrap))]` to use the new behavior. + +### Step 3: update the crate version used by the compiler ([#139934](https://github.com/rust-lang/rust/pull/139934)) + +For `compiler-builtins` this meant a version bump, in other cases it may be a git submodule update. + +### Step 4: remove the old behavior from the compiler ([#139753](https://github.com/rust-lang/rust/pull/139753)) + +The updated crate can now be used. In this example that meant that the old behavior could be removed. diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md index 43ff2ba726f..f8a28b7f2e9 100644 --- a/src/doc/rustc-dev-guide/src/building/suggested.md +++ b/src/doc/rustc-dev-guide/src/building/suggested.md @@ -1,4 +1,4 @@ -# Suggested Workflows +# Suggested workflows The full bootstrapping process takes quite a while. Here are some suggestions to make your life easier. @@ -20,6 +20,43 @@ your `.git/hooks` folder as `pre-push` (without the `.sh` extension!). You can also install the hook as a step of running `./x setup`! +## Config extensions + +When working on different tasks, you might need to switch between different bootstrap configurations. +Sometimes you may want to keep an old configuration for future use. But saving raw config values in +random files and manually copying and pasting them can quickly become messy, especially if you have a +long history of different configurations. + +To simplify managing multiple configurations, you can create config extensions. + +For example, you can create a simple config file named `cross.toml`: + +```toml +[build] +build = "x86_64-unknown-linux-gnu" +host = ["i686-unknown-linux-gnu"] +target = ["i686-unknown-linux-gnu"] + + +[llvm] +download-ci-llvm = false + +[target.x86_64-unknown-linux-gnu] +llvm-config = "/path/to/llvm-19/bin/llvm-config" +``` + +Then, include this in your `bootstrap.toml`: + +```toml +include = ["cross.toml"] +``` + +You can also include extensions within extensions recursively. + +**Note:** In the `include` field, the overriding logic follows a right-to-left order. For example, +in `include = ["a.toml", "b.toml"]`, extension `b.toml` overrides `a.toml`. Also, parent extensions +always overrides the inner ones. + ## Configuring `rust-analyzer` for `rustc` ### Project-local rust-analyzer setup diff --git a/src/doc/rustc-dev-guide/src/coherence.md b/src/doc/rustc-dev-guide/src/coherence.md index b3af101fb87..73f9213bf40 100644 --- a/src/doc/rustc-dev-guide/src/coherence.md +++ b/src/doc/rustc-dev-guide/src/coherence.md @@ -1,4 +1,3 @@ - # Coherence > NOTE: this is based on [notes by @lcnr](https://github.com/rust-lang/rust/pull/121848) diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 09a7f912b98..0575de642ee 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -1,4 +1,4 @@ -# Contribution Procedures +# Contribution procedures <!-- toc --> @@ -150,6 +150,20 @@ when contributing to Rust under [the git section](./git.md). [t-compiler]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler [triagebot]: https://github.com/rust-lang/rust/blob/master/triagebot.toml +### Keeping your branch up-to-date + +The CI in rust-lang/rust applies your patches directly against the current master, +not against the commit your branch is based on. This can lead to unexpected failures +if your branch is outdated, even when there are no explicit merge conflicts. + +Before submitting or updating a PR, make sure to update your branch +as mentioned [here](git.md#keeping-things-up-to-date) if it's significantly +behind the master branch (e.g., more than 100 commits behind). +This fetches the latest master branch and rebases your changes on top of it, +ensuring your PR is tested against the latest code. + +After rebasing, it's recommended to [run the relevant tests locally](tests/intro.md) to catch any issues before CI runs. + ### r? All pull requests are reviewed by another person. We have a bot, @@ -346,7 +360,7 @@ function in the same way as other pull requests. [`src/doc`]: https://github.com/rust-lang/rust/tree/master/src/doc [std-root]: https://github.com/rust-lang/rust/blob/master/library/std/src/lib.rs#L1 -To find documentation-related issues, sort by the [A-docs label]. +To find documentation-related issues, use the [A-docs label]. You can find documentation style guidelines in [RFC 1574]. @@ -373,7 +387,7 @@ Just a few things to keep in mind: There is no strict limit on line lengths; let the sentence or part of the sentence flow to its proper end on the same line. - When contributing text to the guide, please contextualize the information with some time period - and/or a reason so that the reader knows how much to trust or mistrust the information. + and/or a reason so that the reader knows how much to trust the information. Aim to provide a reasonable amount of context, possibly including but not limited to: - A reason for why the data may be out of date other than "change", @@ -387,28 +401,28 @@ Just a few things to keep in mind: - jan 2021 - january 2021 - There is a CI action (in `~/.github/workflows/date-check.yml`) - that generates a monthly showing those that are over 6 months old + There is a CI action (in `.github/workflows/date-check.yml`) + that generates a monthly report showing those that are over 6 months old ([example](https://github.com/rust-lang/rustc-dev-guide/issues/2052)). For the action to pick the date, add a special annotation before specifying the date: ```md - <!-- date-check --> Sep 2024 + <!-- date-check --> Apr 2025 ``` Example: ```md - As of <!-- date-check --> Sep 2024, the foo did the bar. + As of <!-- date-check --> Apr 2025, the foo did the bar. ``` For cases where the date should not be part of the visible rendered output, use the following instead: ```md - <!-- date-check: Sep 2024 --> + <!-- date-check: Apr 2025 --> ``` - A link to a relevant WG, tracking issue, `rustc` rustdoc page, or similar, that may provide diff --git a/src/doc/rustc-dev-guide/src/conventions.md b/src/doc/rustc-dev-guide/src/conventions.md index 0e624a4566d..4356cf246f8 100644 --- a/src/doc/rustc-dev-guide/src/conventions.md +++ b/src/doc/rustc-dev-guide/src/conventions.md @@ -1,3 +1,5 @@ +# Coding conventions + This file offers some tips on the coding conventions for rustc. This chapter covers [formatting](#formatting), [coding for correctness](#cc), [using crates from crates.io](#cio), and some tips on @@ -5,7 +7,7 @@ chapter covers [formatting](#formatting), [coding for correctness](#cc), <a id="formatting"></a> -# Formatting and the tidy script +## Formatting and the tidy script rustc is moving towards the [Rust standard coding style][fmt]. @@ -20,44 +22,42 @@ Formatting is checked by the `tidy` script. It runs automatically when you do `./x test` and can be run in isolation with `./x fmt --check`. If you want to use format-on-save in your editor, the pinned version of -`rustfmt` is built under `build/<target>/stage0/bin/rustfmt`. You'll have to -pass the <!-- date-check: nov 2022 --> `--edition=2021` argument yourself when calling -`rustfmt` directly. +`rustfmt` is built under `build/<target>/stage0/bin/rustfmt`. [fmt]: https://github.com/rust-dev-tools/fmt-rfcs - [`rustfmt`]:https://github.com/rust-lang/rustfmt -## Formatting C++ code +### Formatting C++ code The compiler contains some C++ code for interfacing with parts of LLVM that don't have a stable C API. When modifying that code, use this command to format it: -```sh -./x test tidy --extra-checks=cpp:fmt --bless +```console +./x test tidy --extra-checks cpp:fmt --bless ``` This uses a pinned version of `clang-format`, to avoid relying on the local environment. -## Formatting and linting Python code +### Formatting and linting Python code The Rust repository contains quite a lot of Python code. We try to keep -it both linted and formatted by the [ruff][ruff] tool. +it both linted and formatted by the [ruff] tool. When modifying Python code, use this command to format it: -```sh -./x test tidy --extra-checks=py:fmt --bless + +```console +./x test tidy --extra-checks py:fmt --bless ``` -and the following command to run lints: -```sh -./x test tidy --extra-checks=py:lint +And, the following command to run lints: + +```console +./x test tidy --extra-checks py:lint ``` -This uses a pinned version of `ruff`, to avoid relying on the local -environment. +These use a pinned version of `ruff`, to avoid relying on the local environment. [ruff]: https://github.com/astral-sh/ruff @@ -65,7 +65,7 @@ environment. <!-- REUSE-IgnoreStart --> <!-- Prevent REUSE from interpreting the heading as a copyright notice --> -## Copyright notice +### Copyright notice <!-- REUSE-IgnoreEnd --> In the past, files began with a copyright and license notice. Please **omit** @@ -75,41 +75,42 @@ MIT/Apache-2.0). All of the copyright notices should be gone by now, but if you come across one in the rust-lang/rust repo, feel free to open a PR to remove it. -## Line length +### Line length Lines should be at most 100 characters. It's even better if you can keep things to 80. -**Ignoring the line length limit.** Sometimes – in particular for -tests – it can be necessary to exempt yourself from this limit. In -that case, you can add a comment towards the top of the file like so: +Sometimes, and particularly for tests, it can be necessary to exempt yourself from this limit. +In that case, you can add a comment towards the top of the file like so: ```rust // ignore-tidy-linelength ``` -## Tabs vs spaces +### Tabs vs spaces -Prefer 4-space indent. +Prefer 4-space indents. <a id="cc"></a> -# Coding for correctness +## Coding for correctness Beyond formatting, there are a few other tips that are worth following. -## Prefer exhaustive matches +### Prefer exhaustive matches Using `_` in a match is convenient, but it means that when new variants are added to the enum, they may not get handled correctly. Ask yourself: if a new variant were added to this enum, what's the chance that it would want to use the `_` code, versus having some other treatment? Unless the answer is "low", then prefer an -exhaustive match. (The same advice applies to `if let` and `while -let`, which are effectively tests for a single variant.) +exhaustive match. + +The same advice applies to `if let` and `while let`, +which are effectively tests for a single variant. -## Use "TODO" comments for things you don't want to forget +### Use "TODO" comments for things you don't want to forget As a useful tool to yourself, you can insert a `// TODO` comment for something that you want to get back to before you land your PR: @@ -136,13 +137,13 @@ if foo { <a id="cio"></a> -# Using crates from crates.io +## Using crates from crates.io See the [crates.io dependencies][crates] section. <a id="er"></a> -# How to structure your PR +## How to structure your PR How you prepare the commits in your PR can make a big difference for the reviewer. Here are some tips. @@ -172,7 +173,7 @@ require that every intermediate commit successfully builds – we only expect to be able to bisect at a PR level. However, if you *can* make individual commits build, that is always helpful. -# Naming conventions +## Naming conventions Apart from normal Rust style/naming conventions, there are also some specific to the compiler. diff --git a/src/doc/rustc-dev-guide/src/crates-io.md b/src/doc/rustc-dev-guide/src/crates-io.md index 403d61a81da..4431585a2f0 100644 --- a/src/doc/rustc-dev-guide/src/crates-io.md +++ b/src/doc/rustc-dev-guide/src/crates-io.md @@ -1,4 +1,4 @@ -# crates.io Dependencies +# crates.io dependencies The Rust compiler supports building with some dependencies from `crates.io`. Examples are `log` and `env_logger`. diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md index 6f72ea902f5..2f8f4b0ab8a 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics.md +++ b/src/doc/rustc-dev-guide/src/diagnostics.md @@ -1,4 +1,4 @@ -# Errors and Lints +# Errors and lints <!-- toc --> @@ -772,7 +772,7 @@ store.register_renamed("single_use_lifetime", "single_use_lifetimes"); [`store.register_removed`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LintStore.html#method.register_removed [`rustc_lint::register_builtins`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/fn.register_builtins.html -### Lint Groups +### Lint groups Lints can be turned on in groups. These groups are declared in the [`register_builtins`][rbuiltins] function in [`rustc_lint::lib`][builtin]. The diff --git a/src/doc/rustc-dev-guide/src/feature-gates.md b/src/doc/rustc-dev-guide/src/feature-gates.md index 24ce9bb71bf..9806f73c483 100644 --- a/src/doc/rustc-dev-guide/src/feature-gates.md +++ b/src/doc/rustc-dev-guide/src/feature-gates.md @@ -1,4 +1,4 @@ -# Feature Gates +# Feature gates This chapter is intended to provide basic help for adding, removing, and modifying feature gates. diff --git a/src/doc/rustc-dev-guide/src/hir.md b/src/doc/rustc-dev-guide/src/hir.md index 65779f3129d..0c1c9941572 100644 --- a/src/doc/rustc-dev-guide/src/hir.md +++ b/src/doc/rustc-dev-guide/src/hir.md @@ -144,7 +144,7 @@ that `n` must be some HIR expression, you can do Finally, you can find the parents of nodes, via calls like [`tcx.parent_hir_node(n)`][parent_hir_node]. -[get_parent_item]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.parent_hir_node +[parent_hir_node]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.parent_hir_node ## HIR Bodies diff --git a/src/doc/rustc-dev-guide/src/incrcomp-debugging.md b/src/doc/rustc-dev-guide/src/incrcomp-debugging.md index 7045d3fa39d..a548215cf0c 100644 --- a/src/doc/rustc-dev-guide/src/incrcomp-debugging.md +++ b/src/doc/rustc-dev-guide/src/incrcomp-debugging.md @@ -1,4 +1,4 @@ -# Debugging and Testing Dependencies +# Debugging and testing dependencies ## Testing the dependency graph diff --git a/src/doc/rustc-dev-guide/src/memory.md b/src/doc/rustc-dev-guide/src/memory.md index 1e030ff45a7..eeb4a813980 100644 --- a/src/doc/rustc-dev-guide/src/memory.md +++ b/src/doc/rustc-dev-guide/src/memory.md @@ -1,4 +1,4 @@ -# Memory Management in Rustc +# Memory management in rustc Generally rustc tries to be pretty careful how it manages memory. The compiler allocates _a lot_ of data structures throughout compilation, diff --git a/src/doc/rustc-dev-guide/src/panic-implementation.md b/src/doc/rustc-dev-guide/src/panic-implementation.md index f3587428667..468190ffccd 100644 --- a/src/doc/rustc-dev-guide/src/panic-implementation.md +++ b/src/doc/rustc-dev-guide/src/panic-implementation.md @@ -1,4 +1,4 @@ -# Panicking in rust +# Panicking in Rust <!-- toc --> diff --git a/src/doc/rustc-dev-guide/src/parallel-rustc.md b/src/doc/rustc-dev-guide/src/parallel-rustc.md index 690fb19c9f5..ce69b66c2da 100644 --- a/src/doc/rustc-dev-guide/src/parallel-rustc.md +++ b/src/doc/rustc-dev-guide/src/parallel-rustc.md @@ -1,4 +1,4 @@ -# Parallel Compilation +# Parallel compilation <div class="warning"> As of <!-- date-check --> November 2024, @@ -28,7 +28,7 @@ The following sections are kept for now but are quite outdated. [codegen]: backend/codegen.md -## Code Generation +## Code generation During monomorphization the compiler splits up all the code to be generated into smaller chunks called _codegen units_. These are then generated by @@ -38,7 +38,7 @@ occurs in the [`rustc_codegen_ssa::base`] module. [`rustc_codegen_ssa::base`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/base/index.html -## Data Structures +## Data structures The underlying thread-safe data-structures used in the parallel compiler can be found in the [`rustc_data_structures::sync`] module. These data structures @@ -83,7 +83,7 @@ can be accessed directly through `Deref::deref`. [`rustc_data_structures::sync::worker_local`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_data_structures/sync/worker_local/index.html [`WorkerLocal`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_data_structures/sync/worker_local/struct.WorkerLocal.html -## Parallel Iterator +## Parallel iterator The parallel iterators provided by the [`rayon`] crate are easy ways to implement parallelism. In the current implementation of the parallel compiler @@ -124,7 +124,7 @@ the parallel iterator function has been used are as follows: There are still many loops that have the potential to use parallel iterators. -## Query System +## Query system The query model has some properties that make it actually feasible to evaluate multiple queries in parallel without too much effort: diff --git a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md index 4133b196c0a..03c822d4fee 100644 --- a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md +++ b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md @@ -1,4 +1,4 @@ -# Incremental Compilation In Detail +# Incremental Compilation in detail <!-- toc --> diff --git a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md index f7f204bf79d..444e20bc580 100644 --- a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md +++ b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md @@ -1,4 +1,4 @@ -# The Query Evaluation Model in Detail +# The Query Evaluation Model in detail <!-- toc --> diff --git a/src/doc/rustc-dev-guide/src/serialization.md b/src/doc/rustc-dev-guide/src/serialization.md index 0ff04990128..670a37ffb0a 100644 --- a/src/doc/rustc-dev-guide/src/serialization.md +++ b/src/doc/rustc-dev-guide/src/serialization.md @@ -1,4 +1,4 @@ -# Serialization in Rustc +# Serialization in rustc rustc has to [serialize] and deserialize various data during compilation. Specifically: diff --git a/src/doc/rustc-dev-guide/src/test-implementation.md b/src/doc/rustc-dev-guide/src/test-implementation.md index bee783c0fa6..e906dd29f25 100644 --- a/src/doc/rustc-dev-guide/src/test-implementation.md +++ b/src/doc/rustc-dev-guide/src/test-implementation.md @@ -83,7 +83,7 @@ with your hand-written one, it will not share a [Symbol][Symbol]. This technique prevents name collision during code generation and is the foundation of Rust's [`macro`] hygiene. -## Step 2: Harness Generation +## Step 2: Harness generation Now that our tests are accessible from the root of our crate, we need to do something with them using [`rustc_ast`][ast] generates a module like so: @@ -106,7 +106,7 @@ called [`test`][test] that is part of Rust core, that implements all of the runtime for testing. [`test`][test]'s interface is unstable, so the only stable way to interact with it is through the `#[test]` macro. -## Step 3: Test Object Generation +## Step 3: Test object generation If you've written tests in Rust before, you may be familiar with some of the optional attributes available on test functions. For example, a test can be diff --git a/src/doc/rustc-dev-guide/src/tests/ecosystem.md b/src/doc/rustc-dev-guide/src/tests/ecosystem.md index f4b93492e00..eee07dd079b 100644 --- a/src/doc/rustc-dev-guide/src/tests/ecosystem.md +++ b/src/doc/rustc-dev-guide/src/tests/ecosystem.md @@ -15,9 +15,11 @@ CI. See the [Crater chapter](crater.md) for more details. `cargotest` is a small tool which runs `cargo test` on a few sample projects (such as `servo`, `ripgrep`, `tokei`, etc.). This runs as part of CI and ensures -there aren't any significant regressions. +there aren't any significant regressions: -> Example: `./x test src/tools/cargotest` +```console +./x test src/tools/cargotest +``` ### Large OSS Project builders diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md index 3243a3535ac..6232c8bcc0a 100644 --- a/src/doc/rustc-dev-guide/src/tests/ui.md +++ b/src/doc/rustc-dev-guide/src/tests/ui.md @@ -303,7 +303,7 @@ It should be preferred to using `error-pattern`, which is imprecise and non-exha ### `error-pattern` The `error-pattern` [directive](directives.md) can be used for runtime messages, which don't -have a specific span, or in exceptional cases for compile time messages. +have a specific span, or in exceptional cases, for compile time messages. Let's think about this test: @@ -316,7 +316,7 @@ fn main() { } ``` -We want to ensure this shows "index out of bounds" but we cannot use the `ERROR` +We want to ensure this shows "index out of bounds", but we cannot use the `ERROR` annotation since the runtime error doesn't have any span. Then it's time to use the `error-pattern` directive: @@ -333,18 +333,19 @@ fn main() { Use of `error-pattern` is not recommended in general. For strict testing of compile time output, try to use the line annotations `//~` as much as -possible, including `//~?` annotations for diagnostics without span. +possible, including `//~?` annotations for diagnostics without spans. If the compile time output is target dependent or too verbose, use directive `//@ dont-require-annotations: <diagnostic-kind>` to make the line annotation checking -non-exhaustive, some of the compiler messages can stay uncovered by annotations in this mode. +non-exhaustive. +Some of the compiler messages can stay uncovered by annotations in this mode. -For checking runtime output `//@ check-run-results` may be preferable. +For checking runtime output, `//@ check-run-results` may be preferable. Only use `error-pattern` if none of the above works. Line annotations `//~` are still checked in tests using `error-pattern`. -In exceptional cases use `//@ compile-flags: --error-format=human` to opt out of these checks. +In exceptional cases, use `//@ compile-flags: --error-format=human` to opt out of these checks. ### Diagnostic kinds (error levels) @@ -596,4 +597,27 @@ with "user-facing" Rust alone. Indeed, one could say that this slightly abuses the term "UI" (*user* interface) and turns such UI tests from black-box tests into white-box ones. Use them carefully and sparingly. -[compiler debugging]: ../compiler-debugging.md#rustc_test-attributes +[compiler debugging]: ../compiler-debugging.md#rustc_-test-attributes + +## UI test mode preset lint levels + +By default, test suites under UI test mode (`tests/ui`, `tests/ui-fulldeps`, +but not `tests/rustdoc-ui`) will specify + +- `-A unused` +- `-A internal_features` + +If: + +- The ui test's pass mode is below `run` (i.e. check or build). +- No compare modes are specified. + +Since they can be very noisy in ui tests. + +You can override them with `compile-flags` lint level flags or +in-source lint level attributes as required. + +Note that the `rustfix` version will *not* have `-A unused` passed, +meaning that you may have to `#[allow(unused)]` to suppress `unused` +lints on the rustfix'd file (because we might be testing rustfix +on `unused` lints themselves). diff --git a/src/doc/rustc-dev-guide/src/the-parser.md b/src/doc/rustc-dev-guide/src/the-parser.md index 60a71ae3873..601a81e2e48 100644 --- a/src/doc/rustc-dev-guide/src/the-parser.md +++ b/src/doc/rustc-dev-guide/src/the-parser.md @@ -1,4 +1,4 @@ -# Lexing and Parsing +# Lexing and parsing The very first thing the compiler does is take the program (in UTF-8 Unicode text) and turn it into a data format the compiler can work with more conveniently than strings. @@ -59,7 +59,7 @@ Note that while parsing, we may encounter macro definitions or invocations. We set these aside to be expanded (see [Macro Expansion](./macro-expansion.md)). Expansion itself may require parsing the output of a macro, which may reveal more macros to be expanded, and so on. -## More on Lexical Analysis +## More on lexical analysis Code for lexical analysis is split between two crates: diff --git a/src/doc/rustc-dev-guide/src/unsafety-checking.md b/src/doc/rustc-dev-guide/src/unsafety-checking.md index 1130878944d..fbc19d8961c 100644 --- a/src/doc/rustc-dev-guide/src/unsafety-checking.md +++ b/src/doc/rustc-dev-guide/src/unsafety-checking.md @@ -1,4 +1,4 @@ -# Unsafety Checking +# Unsafety checking Certain expressions in Rust can violate memory safety and as such need to be inside an `unsafe` block or function. The compiler will also warn if an unsafe diff --git a/src/doc/rustc-dev-guide/src/walkthrough.md b/src/doc/rustc-dev-guide/src/walkthrough.md index 6e07ceb7d73..48b3f8bb15d 100644 --- a/src/doc/rustc-dev-guide/src/walkthrough.md +++ b/src/doc/rustc-dev-guide/src/walkthrough.md @@ -221,7 +221,7 @@ There are a couple of things that may happen for some PRs during the review proc some merge conflicts with other PRs that happen to get merged first. You should fix these merge conflicts using the normal git procedures. -[crater]: ./tests/intro.html#crater +[crater]: ./tests/crater.html If you are not doing a new feature or something like that (e.g. if you are fixing a bug), then that's it! Thanks for your contribution :) diff --git a/src/doc/rustc-dev-guide/triagebot.toml b/src/doc/rustc-dev-guide/triagebot.toml index 12aa0b7b8ff..6232dbf05fd 100644 --- a/src/doc/rustc-dev-guide/triagebot.toml +++ b/src/doc/rustc-dev-guide/triagebot.toml @@ -7,5 +7,9 @@ allow-unauthenticated = [ "blocked", ] +[no-mentions] + +[canonicalize-issue-links] + # Automatically close and reopen PRs made by bots to run CI on them [bot-pull-requests] diff --git a/src/doc/rustc/src/exploit-mitigations.md b/src/doc/rustc/src/exploit-mitigations.md index d4e2fc52e97..f8bafe03214 100644 --- a/src/doc/rustc/src/exploit-mitigations.md +++ b/src/doc/rustc/src/exploit-mitigations.md @@ -42,8 +42,7 @@ understood within a given context. This section documents the exploit mitigations applicable to the Rust compiler when building programs for the Linux operating system on the AMD64 architecture -and equivalent.<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" -class="footnote">1</a></sup> All examples in this section were built using +and equivalent.[^all-targets] All examples in this section were built using nightly builds of the Rust compiler on Debian testing. The Rust Programming Language currently has no specification. The Rust compiler @@ -67,11 +66,8 @@ equivalent. | Forward-edge control flow protection | Yes | Nightly | | Backward-edge control flow protection (e.g., shadow and safe stack) | Yes | Nightly | -<small id="fn:1">1\. See -<https://github.com/rust-lang/rust/tree/master/compiler/rustc_target/src/spec> -for a list of targets and their default options. <a href="#fnref:1" -class="reversefootnote" role="doc-backlink">↩</a></small> - +[^all-targets]: See <https://github.com/rust-lang/rust/tree/master/compiler/rustc_target/src/spec> + for a list of targets and their default options. ### Position-independent executable @@ -141,18 +137,15 @@ Integer overflow checks are enabled when debug assertions are enabled (see Fig. 3), and disabled when debug assertions are disabled (see Fig. 4). To enable integer overflow checks independently, use the option to control integer overflow checks, scoped attributes, or explicit checking methods such as -`checked_add`<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" -class="footnote">2</a></sup>. +`checked_add`[^checked-methods]. It is recommended that explicit wrapping methods such as `wrapping_add` be used when wrapping semantics are intended, and that explicit checking and wrapping methods always be used when using Unsafe Rust. -<small id="fn:2">2\. See [the `u32` docs](../std/primitive.u32.html) for more -information on the checked, overflowing, saturating, and wrapping methods -(using u32 as an example). <a href="#fnref:2" class="reversefootnote" -role="doc-backlink">↩</a></small> - +[^checked-methods]: See [the `u32` docs](../std/primitive.u32.html) for more + information on the checked, overflowing, saturating, and wrapping methods + (using u32 as an example). ### Non-executable memory regions @@ -180,17 +173,14 @@ binary. The presence of an element of type `PT_GNU_STACK` in the program header table with the `PF_X` (i.e., executable) flag unset indicates non-executable memory -regions<sup id="fnref:3" role="doc-noteref"><a href="#fn:3" -class="footnote">3</a></sup> are enabled for a given binary (see Fig. 5). +regions[^other-regions] are enabled for a given binary (see Fig. 5). Conversely, the presence of an element of type `PT_GNU_STACK` in the program header table with the `PF_X` flag set or the absence of an element of type `PT_GNU_STACK` in the program header table indicates non-executable memory regions are not enabled for a given binary. -<small id="fn:3">3\. See the Appendix section for more information on why it -affects other memory regions besides the stack. <a href="#fnref:3" -class="reversefootnote" role="doc-backlink">↩</a></small> - +[^other-regions]: See the [Appendix section](#appendix) for more information + on why it affects other memory regions besides the stack. ### Stack clashing protection @@ -270,8 +260,7 @@ $ readelf -d target/release/hello-rust | grep BIND_NOW Fig. 10. Checking if immediate binding is enabled for a given binary. The presence of an element with the `DT_BIND_NOW` tag and the `DF_BIND_NOW` -flag<sup id="fnref:4" role="doc-noteref"><a href="#fn:4" -class="footnote">4</a></sup> in the dynamic section indicates immediate binding +flag[^bind-now] in the dynamic section indicates immediate binding is enabled for a given binary (see Fig. 10). Conversely, the absence of an element with the `DT_BIND_NOW` tag and the `DF_BIND_NOW` flag in the dynamic section indicates immediate binding is not enabled for a given binary. @@ -281,9 +270,7 @@ table and of an element with the `DT_BIND_NOW` tag and the `DF_BIND_NOW` flag in the dynamic section indicates full RELRO is enabled for a given binary (see Figs. 9–10). -<small id="fn:4">4\. And the `DF_1_NOW` flag for some link editors. <a -href="#fnref:4" class="reversefootnote" role="doc-backlink">↩</a></small> - +[^bind-now]: And the `DF_1_NOW` flag for some link editors. ### Heap corruption protection @@ -303,8 +290,7 @@ Rust’s default allocator has historically been [jemalloc](http://jemalloc.net/), and it has long been the cause of issues and the subject of much discussion[32]–[38]. Consequently, it has been removed as the default allocator in favor of the operating system’s standard C library -default allocator<sup id="fnref:5" role="doc-noteref"><a href="#fn:5" -class="footnote">5</a></sup> since version 1.32.0 (2019-01-17)[39]. +default allocator[^linx-allocator] since version 1.32.0 (2019-01-17)[39]. ```rust,no_run fn main() { @@ -343,11 +329,9 @@ Fig. 13. Build and execution of hello-rust-heap with debug assertions disabled Heap corruption checks are performed when using the default allocator (i.e., the GNU Allocator) (see Figs. 12–13). -<small id="fn:5">5\. Linux's standard C library default allocator is the GNU -Allocator, which is derived from ptmalloc (pthreads malloc) by Wolfram Gloger, -which in turn is derived from dlmalloc (Doug Lea malloc) by Doug Lea. <a -href="#fnref:5" class="reversefootnote" role="doc-backlink">↩</a></small> - +[^linx-allocator]: Linux's standard C library default allocator is the GNU + Allocator, which is derived from ptmalloc (pthreads malloc) by Wolfram Gloger, + which in turn is derived from dlmalloc (Doug Lea malloc) by Doug Lea. ### Stack smashing protection @@ -385,8 +369,7 @@ commercially available [grsecurity/PaX Reuse Attack Protector (RAP)](https://grsecurity.net/rap_faq). The Rust compiler supports forward-edge control flow protection on nightly -builds[41]-[42] <sup id="fnref:6" role="doc-noteref"><a href="#fn:6" -class="footnote">6</a></sup>. +builds[41]-[42] [^win-cfg]. ```text $ readelf -s -W target/release/hello-rust | grep "\.cfi" @@ -401,10 +384,8 @@ of symbols suffixed with ".cfi" or the `__cfi_init` symbol (and references to `__cfi_check`) indicates that LLVM CFI is not enabled for a given binary (see Fig. 15). -<small id="fn:6">6\. It also supports Control Flow Guard (CFG) on Windows (see -<https://github.com/rust-lang/rust/issues/68793>). <a href="#fnref:6" -class="reversefootnote" role="doc-backlink">↩</a></small> - +[^win-cfg]: It also supports Control Flow Guard (CFG) on Windows (see + <https://github.com/rust-lang/rust/issues/68793>). ### Backward-edge control flow protection @@ -431,8 +412,7 @@ Newer processors provide hardware assistance for backward-edge control flow protection, such as ARM Pointer Authentication, and Intel Shadow Stack as part of Intel CET. -The Rust compiler supports shadow stack for the AArch64 architecture<sup -id="fnref:7" role="doc-noteref"><a href="#fn:7" class="footnote">7</a></sup>on +The Rust compiler supports shadow stack for the AArch64 architecture[^amd64-shadow] on nightly builds[43]-[44], and also supports safe stack on nightly builds[45]-[46]. @@ -447,9 +427,8 @@ enabled for a given binary. Conversely, the absence of the `__safestack_init` symbol indicates that LLVM SafeStack is not enabled for a given binary (see Fig. 16). -<small id="fn:7">7\. The shadow stack implementation for the AMD64 architecture -and equivalent in LLVM was removed due to performance and security issues. <a -href="#fnref:7" class="reversefootnote" role="doc-backlink">↩</a></small> +[^amd64-shadow]: The shadow stack implementation for the AMD64 architecture + and equivalent in LLVM was removed due to performance and security issues. ## Appendix diff --git a/src/doc/rustc/src/platform-support/TEMPLATE.md b/src/doc/rustc/src/platform-support/TEMPLATE.md index 96c79973a16..f523237ab06 100644 --- a/src/doc/rustc/src/platform-support/TEMPLATE.md +++ b/src/doc/rustc/src/platform-support/TEMPLATE.md @@ -6,7 +6,8 @@ One-sentence description of the target (e.g. CPU, OS) ## Target maintainers -- Some Person, https://github.com/... +[@Ghost](https://github.com/Ghost) +[@octocat](https://github.com/octocat) ## Requirements diff --git a/src/doc/rustc/src/platform-support/aarch64-nintendo-switch-freestanding.md b/src/doc/rustc/src/platform-support/aarch64-nintendo-switch-freestanding.md index 308e1fe2f92..6951d7f23f8 100644 --- a/src/doc/rustc/src/platform-support/aarch64-nintendo-switch-freestanding.md +++ b/src/doc/rustc/src/platform-support/aarch64-nintendo-switch-freestanding.md @@ -4,10 +4,10 @@ Nintendo Switch with pure-Rust toolchain. -## Designated Developers +## Target Maintainers -* [@leo60228](https://github.com/leo60228) -* [@jam1garner](https://github.com/jam1garner) +[@leo60228](https://github.com/leo60228) +[@jam1garner](https://github.com/jam1garner) ## Requirements diff --git a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md index e2f2379ec44..be11d0cdd10 100644 --- a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md +++ b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md @@ -20,8 +20,8 @@ TEEOS is open source in progress. [MORE about](https://gitee.com/opentrustee-gro ## Target maintainers -- Petrochenkov Vadim -- Sword-Destiny +[@petrochenkov](https://github.com/petrochenkov) +[@Sword-Destiny](https://github.com/Sword-Destiny) ## Setup We use OpenHarmony SDK for TEEOS. diff --git a/src/doc/rustc/src/platform-support/aix.md b/src/doc/rustc/src/platform-support/aix.md index 5a198062b95..3002a5c4b2c 100644 --- a/src/doc/rustc/src/platform-support/aix.md +++ b/src/doc/rustc/src/platform-support/aix.md @@ -6,8 +6,8 @@ Rust for AIX operating system, currently only 64-bit PowerPC is supported. ## Target maintainers -- David Tenty `daltenty@ibm.com`, https://github.com/daltenty -- Chris Cambly, `ccambly@ca.ibm.com`, https://github.com/gilamn5tr +[@daltenty](https://github.com/daltenty) +[@gilamn5tr](https://github.com/gilamn5tr) ## Requirements diff --git a/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md b/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md index 0b2f798e66d..16152dd2dad 100644 --- a/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md +++ b/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md @@ -6,7 +6,7 @@ AMD GPU target for compute/HSA (Heterogeneous System Architecture). ## Target maintainers -- [@Flakebi](https://github.com/Flakebi) +[@Flakebi](https://github.com/Flakebi) ## Requirements diff --git a/src/doc/rustc/src/platform-support/android.md b/src/doc/rustc/src/platform-support/android.md index 54e7ddca32a..a54288f8f05 100644 --- a/src/doc/rustc/src/platform-support/android.md +++ b/src/doc/rustc/src/platform-support/android.md @@ -8,9 +8,9 @@ ## Target maintainers -- Chris Wailes ([@chriswailes](https://github.com/chriswailes)) -- Matthew Maurer ([@maurer](https://github.com/maurer)) -- Martin Geisler ([@mgeisler](https://github.com/mgeisler)) +[@chriswailes](https://github.com/chriswailes) +[@maurer](https://github.com/maurer) +[@mgeisler](https://github.com/mgeisler) ## Requirements diff --git a/src/doc/rustc/src/platform-support/apple-darwin.md b/src/doc/rustc/src/platform-support/apple-darwin.md index 22c54d04b1e..e41aee9bdb2 100644 --- a/src/doc/rustc/src/platform-support/apple-darwin.md +++ b/src/doc/rustc/src/platform-support/apple-darwin.md @@ -9,8 +9,8 @@ Apple macOS targets. ## Target maintainers -- [@thomcc](https://github.com/thomcc) -- [@madsmtm](https://github.com/madsmtm) +[@thomcc](https://github.com/thomcc) +[@madsmtm](https://github.com/madsmtm) ## Requirements diff --git a/src/doc/rustc/src/platform-support/apple-ios-macabi.md b/src/doc/rustc/src/platform-support/apple-ios-macabi.md index 79966d908d8..d4b71dbd4f4 100644 --- a/src/doc/rustc/src/platform-support/apple-ios-macabi.md +++ b/src/doc/rustc/src/platform-support/apple-ios-macabi.md @@ -9,9 +9,9 @@ Apple Mac Catalyst targets. ## Target maintainers -- [@badboy](https://github.com/badboy) -- [@BlackHoleFox](https://github.com/BlackHoleFox) -- [@madsmtm](https://github.com/madsmtm) +[@badboy](https://github.com/badboy) +[@BlackHoleFox](https://github.com/BlackHoleFox) +[@madsmtm](https://github.com/madsmtm) ## Requirements diff --git a/src/doc/rustc/src/platform-support/apple-ios.md b/src/doc/rustc/src/platform-support/apple-ios.md index 7f5dc361c49..64325554ab6 100644 --- a/src/doc/rustc/src/platform-support/apple-ios.md +++ b/src/doc/rustc/src/platform-support/apple-ios.md @@ -15,9 +15,9 @@ Apple iOS / iPadOS targets. ## Target maintainers -- [@badboy](https://github.com/badboy) -- [@deg4uss3r](https://github.com/deg4uss3r) -- [@madsmtm](https://github.com/madsmtm) +[@badboy](https://github.com/badboy) +[@deg4uss3r](https://github.com/deg4uss3r) +[@madsmtm](https://github.com/madsmtm) ## Requirements diff --git a/src/doc/rustc/src/platform-support/apple-tvos.md b/src/doc/rustc/src/platform-support/apple-tvos.md index fc46db20074..193d6466612 100644 --- a/src/doc/rustc/src/platform-support/apple-tvos.md +++ b/src/doc/rustc/src/platform-support/apple-tvos.md @@ -10,8 +10,8 @@ Apple tvOS targets. ## Target maintainers -- [@thomcc](https://github.com/thomcc) -- [@madsmtm](https://github.com/madsmtm) +[@thomcc](https://github.com/thomcc) +[@madsmtm](https://github.com/madsmtm) ## Requirements diff --git a/src/doc/rustc/src/platform-support/apple-visionos.md b/src/doc/rustc/src/platform-support/apple-visionos.md index 7cf9549227d..ed96912da7a 100644 --- a/src/doc/rustc/src/platform-support/apple-visionos.md +++ b/src/doc/rustc/src/platform-support/apple-visionos.md @@ -9,8 +9,8 @@ Apple visionOS / xrOS targets. ## Target maintainers -- [@agg23](https://github.com/agg23) -- [@madsmtm](https://github.com/madsmtm) +[@agg23](https://github.com/agg23) +[@madsmtm](https://github.com/madsmtm) ## Requirements diff --git a/src/doc/rustc/src/platform-support/apple-watchos.md b/src/doc/rustc/src/platform-support/apple-watchos.md index 7b12d9ebfd4..6ac09d0d1e5 100644 --- a/src/doc/rustc/src/platform-support/apple-watchos.md +++ b/src/doc/rustc/src/platform-support/apple-watchos.md @@ -12,10 +12,10 @@ Apple watchOS targets. ## Target maintainers -- [@deg4uss3r](https://github.com/deg4uss3r) -- [@vladimir-ea](https://github.com/vladimir-ea) -- [@leohowell](https://github.com/leohowell) -- [@madsmtm](https://github.com/madsmtm) +[@deg4uss3r](https://github.com/deg4uss3r) +[@vladimir-ea](https://github.com/vladimir-ea) +[@leohowell](https://github.com/leohowell) +[@madsmtm](https://github.com/madsmtm) ## Requirements diff --git a/src/doc/rustc/src/platform-support/arm64e-apple-darwin.md b/src/doc/rustc/src/platform-support/arm64e-apple-darwin.md index 3200b7ae1b6..2043b342105 100644 --- a/src/doc/rustc/src/platform-support/arm64e-apple-darwin.md +++ b/src/doc/rustc/src/platform-support/arm64e-apple-darwin.md @@ -6,7 +6,7 @@ ARM64e macOS (11.0+, Big Sur+) ## Target maintainers -- Artyom Tetyukhin ([@arttet](https://github.com/arttet)) +[@arttet](https://github.com/arttet) ## Requirements diff --git a/src/doc/rustc/src/platform-support/arm64e-apple-ios.md b/src/doc/rustc/src/platform-support/arm64e-apple-ios.md index aa99276a68f..a2b09e07728 100644 --- a/src/doc/rustc/src/platform-support/arm64e-apple-ios.md +++ b/src/doc/rustc/src/platform-support/arm64e-apple-ios.md @@ -6,7 +6,7 @@ ARM64e iOS (14.0+) ## Target maintainers -- Artyom Tetyukhin ([@arttet](https://github.com/arttet)) +[@arttet](https://github.com/arttet) ## Requirements diff --git a/src/doc/rustc/src/platform-support/arm64e-apple-tvos.md b/src/doc/rustc/src/platform-support/arm64e-apple-tvos.md index 332ea750f20..36588c5a964 100644 --- a/src/doc/rustc/src/platform-support/arm64e-apple-tvos.md +++ b/src/doc/rustc/src/platform-support/arm64e-apple-tvos.md @@ -6,7 +6,7 @@ ARM64e tvOS (10.0+) ## Target maintainers -- Artyom Tetyukhin ([@arttet](https://github.com/arttet)) +[@arttet](https://github.com/arttet) ## Requirements diff --git a/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md b/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md index 67903ae6401..d02043b2ae9 100644 --- a/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md +++ b/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md @@ -7,7 +7,7 @@ applications on AArch64 Windows 11. See <https://learn.microsoft.com/en-us/windo ## Target maintainers -- [@dpaoliello](https://github.com/dpaoliello) +[@dpaoliello](https://github.com/dpaoliello) ## Requirements diff --git a/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md b/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md index 3a5b5a38017..7c1c5db7076 100644 --- a/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md +++ b/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md @@ -10,7 +10,8 @@ BE8 architecture retains the same little-endian ordered code-stream used by conv BE8 architecture is the default big-endian architecture for Arm since [Armv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en). It's predecessor, used for Armv4 and Armv5 devices was [BE32](https://developer.arm.com/documentation/dui0474/j/linker-command-line-options/--be32). On Armv6 architecture, endianness can be configured via [system registers](https://developer.arm.com/documentation/ddi0290/g/unaligned-and-mixed-endian-data-access-support/mixed-endian-access-support/interaction-between-the-bus-protocol-and-the-core-endianness). However, BE32 was withdrawn for [Armv7](https://developer.arm.com/documentation/ddi0406/cb/Appendixes/Deprecated-and-Obsolete-Features/Obsolete-features/Support-for-BE-32-endianness-model) onwards. ## Target Maintainers -* [@WorksButNotTested](https://github.com/WorksButNotTested) + +[@WorksButNotTested](https://github.com/WorksButNotTested) ## Requirements The target is cross-compiled. This target supports `std` in the normal way (indeed only nominal changes are required from the standard Arm configuration). diff --git a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md index 0c5129d0efb..56f919e2a12 100644 --- a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md @@ -11,8 +11,8 @@ overall performance. ## Target Maintainers -* [@Lokathor](https://github.com/lokathor) -* [@corwinkuiper](https://github.com/corwinkuiper) +[@Lokathor](https://github.com/lokathor) +[@corwinkuiper](https://github.com/corwinkuiper) ## Testing diff --git a/src/doc/rustc/src/platform-support/armv5te-none-eabi.md b/src/doc/rustc/src/platform-support/armv5te-none-eabi.md index 41621e070bb..22287972b7e 100644 --- a/src/doc/rustc/src/platform-support/armv5te-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv5te-none-eabi.md @@ -13,7 +13,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all ## Target Maintainers -* [@QuinnPainter](https://github.com/QuinnPainter) +[@QuinnPainter](https://github.com/QuinnPainter) ## Testing diff --git a/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md index a085aef2d04..e4a0f75b8ce 100644 --- a/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md +++ b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md @@ -13,9 +13,9 @@ from nor used with any official Nintendo SDK. This target is maintained by members of the [@rust3ds](https://github.com/rust3ds) organization: -- [@Meziu](https://github.com/Meziu) -- [@AzureMarker](https://github.com/AzureMarker) -- [@ian-h-chamberlain](https://github.com/ian-h-chamberlain) +[@Meziu](https://github.com/Meziu) +[@AzureMarker](https://github.com/AzureMarker) +[@ian-h-chamberlain](https://github.com/ian-h-chamberlain) ## Requirements diff --git a/src/doc/rustc/src/platform-support/armv7-rtems-eabihf.md b/src/doc/rustc/src/platform-support/armv7-rtems-eabihf.md index 2791c21ee45..feac3c1edc7 100644 --- a/src/doc/rustc/src/platform-support/armv7-rtems-eabihf.md +++ b/src/doc/rustc/src/platform-support/armv7-rtems-eabihf.md @@ -6,13 +6,13 @@ ARM targets for the [RTEMS realtime operating system](https://www.rtems.org) us ## Target maintainers -- [@thesummer](https://github.com/thesummer) +[@thesummer](https://github.com/thesummer) ## Requirements The target does not support host tools. Only cross-compilation is possible. The cross-compiler toolchain can be obtained by following the installation instructions -of the [RTEMS Documentation](https://docs.rtems.org/branches/master/user/index.html). Additionally to the cross-compiler also a compiled BSP +of the [RTEMS Documentation](https://docs.rtems.org/docs/main/user/index.html). Additionally to the cross-compiler also a compiled BSP for a board fitting the architecture needs to be available on the host. Currently tested has been the BSP `xilinx_zynq_a9_qemu` of RTEMS 6. @@ -49,4 +49,4 @@ While basic execution of the unit test harness seems to work. However, running t ## Cross-compilation toolchains and C code Compatible C-code can be built with the RTEMS cross-compiler toolchain `arm-rtems6-gcc`. -For more information how to build the toolchain, RTEMS itself and RTEMS applications please have a look at the [RTEMS Documentation](https://docs.rtems.org/branches/master/user/index.html). +For more information how to build the toolchain, RTEMS itself and RTEMS applications please have a look at the [RTEMS Documentation](https://docs.rtems.org/docs/main/user/index.html). diff --git a/src/doc/rustc/src/platform-support/armv7-sony-vita-newlibeabihf.md b/src/doc/rustc/src/platform-support/armv7-sony-vita-newlibeabihf.md index e1473bd966c..814f301d8b2 100644 --- a/src/doc/rustc/src/platform-support/armv7-sony-vita-newlibeabihf.md +++ b/src/doc/rustc/src/platform-support/armv7-sony-vita-newlibeabihf.md @@ -9,9 +9,9 @@ from nor used with any official Sony SDK. ## Target maintainers -* [@nikarh](https://github.com/nikarh) -* [@pheki](https://github.com/pheki) -* [@ZetaNumbers](https://github.com/ZetaNumbers) +[@nikarh](https://github.com/nikarh) +[@pheki](https://github.com/pheki) +[@zetanumbers](https://github.com/zetanumbers) ## Requirements diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md index f22a20835c1..e553c49589d 100644 --- a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md +++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md @@ -6,7 +6,7 @@ This target supports Armv7-A softfloat CPUs and uses the uclibc-ng standard libr ## Target maintainers -* [@lancethepants](https://github.com/lancethepants) +[@lancethepants](https://github.com/lancethepants) ## Requirements diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md index f687f6f0695..91f3ea886cc 100644 --- a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md +++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md @@ -4,9 +4,9 @@ This tier supports the Armv7-A processor running a Linux kernel and uClibc-ng standard library. It provides full support for rust and the rust standard library. -## Designated Developers +## Target Maintainers -* [@skrap](https://github.com/skrap) +[@skrap](https://github.com/skrap) ## Requirements diff --git a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md index 5f0dc6a7115..88b2689dcf0 100644 --- a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md @@ -16,7 +16,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all ## Target maintainers -- [Chris Copeland](https://github.com/chrisnc), `chris@chrisnc.net` +[@chrisnc](https://github.com/chrisnc) ## Requirements diff --git a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md index 6f80a06020f..569d8802ebe 100644 --- a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md +++ b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md @@ -16,7 +16,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all ## Target maintainers -- [Chris Copeland](https://github.com/chrisnc), `chris@chrisnc.net` +[@chrisnc](https://github.com/chrisnc) ## Requirements diff --git a/src/doc/rustc/src/platform-support/avr-none.md b/src/doc/rustc/src/platform-support/avr-none.md index 9c1836222c1..5218f19adf3 100644 --- a/src/doc/rustc/src/platform-support/avr-none.md +++ b/src/doc/rustc/src/platform-support/avr-none.md @@ -6,7 +6,7 @@ Series of microcontrollers from Atmel: ATmega8, ATmega328p etc. ## Target maintainers -- [Patryk Wychowaniec](https://github.com/Patryk27) <pwychowaniec@pm.me> +[@Patryk27](https://github.com/Patryk27) ## Requirements diff --git a/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md b/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md index f749b37aa7a..e69d606ccd2 100644 --- a/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md +++ b/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md @@ -22,7 +22,7 @@ other links: ## Target maintainers -* [@Dirreke](https://github.com/Dirreke) +[@Dirreke](https://github.com/Dirreke) ## Requirements diff --git a/src/doc/rustc/src/platform-support/esp-idf.md b/src/doc/rustc/src/platform-support/esp-idf.md index 91d7d66627d..baf42ab29a6 100644 --- a/src/doc/rustc/src/platform-support/esp-idf.md +++ b/src/doc/rustc/src/platform-support/esp-idf.md @@ -6,9 +6,9 @@ Targets for the [ESP-IDF](https://github.com/espressif/esp-idf) development fram ## Target maintainers -- Ivan Markov [@ivmarkov](https://github.com/ivmarkov) -- Scott Mabin [@MabezDev](https://github.com/MabezDev) -- Sergio Gasquez [@SergioGasquez](https://github.com/SergioGasquez) +[@ivmarkov](https://github.com/ivmarkov) +[@MabezDev](https://github.com/MabezDev) +[@SergioGasquez](https://github.com/SergioGasquez) ## Requirements diff --git a/src/doc/rustc/src/platform-support/freebsd.md b/src/doc/rustc/src/platform-support/freebsd.md index 9d34d364920..9d7218b258e 100644 --- a/src/doc/rustc/src/platform-support/freebsd.md +++ b/src/doc/rustc/src/platform-support/freebsd.md @@ -6,8 +6,8 @@ ## Target maintainers -- Alan Somers `asomers@FreeBSD.org`, https://github.com/asomers -- Mikael Urankar `mikael@FreeBSD.org`, https://github.com/MikaelUrankar +[@asomers](https://github.com/asomers) +[@MikaelUrankar](https://github.com/MikaelUrankar) ## Requirements diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md index bed5b81adc5..e2befc5d995 100644 --- a/src/doc/rustc/src/platform-support/fuchsia.md +++ b/src/doc/rustc/src/platform-support/fuchsia.md @@ -7,9 +7,11 @@ updatable, and performant. ## Target maintainers -See [`fuchsia.toml`] in the `team` repository for current target maintainers. +[@erickt](https://github.com/erickt) +[@Nashenas88](https://github.com/Nashenas88) -[`fuchsia.toml`]: https://github.com/rust-lang/team/blob/master/teams/fuchsia.toml +The up-to-date list can be also found via the +[fuchsia marker team](https://github.com/rust-lang/team/blob/master/teams/fuchsia.toml). ## Table of contents diff --git a/src/doc/rustc/src/platform-support/hermit.md b/src/doc/rustc/src/platform-support/hermit.md index df7bc495fce..069c253bd38 100644 --- a/src/doc/rustc/src/platform-support/hermit.md +++ b/src/doc/rustc/src/platform-support/hermit.md @@ -14,8 +14,8 @@ Target triplets available so far: ## Target maintainers -- Stefan Lankes ([@stlankes](https://github.com/stlankes)) -- Martin Kröning ([@mkroening](https://github.com/mkroening)) +[@stlankes](https://github.com/stlankes) +[@mkroening](https://github.com/mkroening) ## Requirements diff --git a/src/doc/rustc/src/platform-support/hexagon-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/hexagon-unknown-linux-musl.md index cfd2b2bac9c..be6e17883f4 100644 --- a/src/doc/rustc/src/platform-support/hexagon-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/hexagon-unknown-linux-musl.md @@ -11,7 +11,7 @@ DSP architecture. ## Target maintainers -- [Brian Cain](https://github.com/androm3da), `bcain@quicinc.com` +[@androm3da](https://github.com/androm3da) ## Requirements The target is cross-compiled. This target supports `std`. By default, code diff --git a/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md b/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md index c7726eacaf4..b07b0bb08d6 100644 --- a/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md +++ b/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md @@ -10,7 +10,7 @@ Rust for baremetal Hexagon DSPs. ## Target maintainers -- [Brian Cain](https://github.com/androm3da), `bcain@quicinc.com` +[@androm3da](https://github.com/androm3da) ## Requirements diff --git a/src/doc/rustc/src/platform-support/hurd.md b/src/doc/rustc/src/platform-support/hurd.md index 2521f79dc5e..6ecde1db511 100644 --- a/src/doc/rustc/src/platform-support/hurd.md +++ b/src/doc/rustc/src/platform-support/hurd.md @@ -6,7 +6,7 @@ ## Target maintainers -- Samuel Thibault, `samuel.thibault@ens-lyon.org`, https://github.com/sthibaul/ +[@sthibaul](https://github.com/sthibaul) ## Requirements diff --git a/src/doc/rustc/src/platform-support/i686-apple-darwin.md b/src/doc/rustc/src/platform-support/i686-apple-darwin.md index abb64dcc986..5f18a5e271a 100644 --- a/src/doc/rustc/src/platform-support/i686-apple-darwin.md +++ b/src/doc/rustc/src/platform-support/i686-apple-darwin.md @@ -4,8 +4,8 @@ Apple macOS on 32-bit x86. ## Target maintainers -- [@thomcc](https://github.com/thomcc) -- [@madsmtm](https://github.com/madsmtm) +[@thomcc](https://github.com/thomcc) +[@madsmtm](https://github.com/madsmtm) ## Requirements diff --git a/src/doc/rustc/src/platform-support/illumos.md b/src/doc/rustc/src/platform-support/illumos.md index dd2ae90f674..c03238269d3 100644 --- a/src/doc/rustc/src/platform-support/illumos.md +++ b/src/doc/rustc/src/platform-support/illumos.md @@ -7,8 +7,8 @@ including advanced system debugging, next generation filesystem, networking, and ## Target maintainers -- Joshua M. Clulow ([@jclulow](https://github.com/jclulow)) -- Patrick Mooney ([@pfmooney](https://github.com/pfmooney)) +[@jclulow](https://github.com/jclulow) +[@pfmooney](https://github.com/pfmooney) ## Requirements diff --git a/src/doc/rustc/src/platform-support/kmc-solid.md b/src/doc/rustc/src/platform-support/kmc-solid.md index 44f47927286..838662a3741 100644 --- a/src/doc/rustc/src/platform-support/kmc-solid.md +++ b/src/doc/rustc/src/platform-support/kmc-solid.md @@ -14,9 +14,9 @@ The target names follow this format: `$ARCH-kmc-solid_$KERNEL-$ABI`, where `$ARC | `armv7a-kmc-solid_asp3-eabi` | `arm` | `kmc` | `solid_asp3` | | `armv7a-kmc-solid_asp3-eabihf` | `arm` | `kmc` | `solid_asp3` | -## Designated Developers +## Target Maintainers -- [@kawadakk](https://github.com/kawadakk) +[@kawadakk](https://github.com/kawadakk) ## Requirements diff --git a/src/doc/rustc/src/platform-support/loongarch-linux.md b/src/doc/rustc/src/platform-support/loongarch-linux.md index 2c9f712ce82..817d3a89230 100644 --- a/src/doc/rustc/src/platform-support/loongarch-linux.md +++ b/src/doc/rustc/src/platform-support/loongarch-linux.md @@ -22,10 +22,10 @@ Reference material: ## Target maintainers -- [WANG Rui](https://github.com/heiher) `wangrui@loongson.cn` -- [ZHAI Xiang](https://github.com/xiangzhai) `zhaixiang@loongson.cn` -- [ZHAI Xiaojuan](https://github.com/zhaixiaojuan) `zhaixiaojuan@loongson.cn` -- [WANG Xuerui](https://github.com/xen0n) `git@xen0n.name` +[@heiher](https://github.com/heiher) +[@xiangzhai](https://github.com/xiangzhai) +[@zhaixiaojuan](https://github.com/zhaixiaojuan) +[@xen0n](https://github.com/xen0n) ## Requirements diff --git a/src/doc/rustc/src/platform-support/loongarch-none.md b/src/doc/rustc/src/platform-support/loongarch-none.md index 6c5d8669830..a2bd6e5734c 100644 --- a/src/doc/rustc/src/platform-support/loongarch-none.md +++ b/src/doc/rustc/src/platform-support/loongarch-none.md @@ -11,8 +11,8 @@ Freestanding/bare-metal LoongArch64 binaries in ELF format: firmware, kernels, e ## Target maintainers -- [WANG Rui](https://github.com/heiher) `wangrui@loongson.cn` -- [WANG Xuerui](https://github.com/xen0n) `git@xen0n.name` +[@heiher](https://github.com/heiher) +[@xen0n](https://github.com/xen0n) ## Requirements diff --git a/src/doc/rustc/src/platform-support/m68k-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/m68k-unknown-linux-gnu.md index b18a125f3b0..1efea86df92 100644 --- a/src/doc/rustc/src/platform-support/m68k-unknown-linux-gnu.md +++ b/src/doc/rustc/src/platform-support/m68k-unknown-linux-gnu.md @@ -4,10 +4,10 @@ Motorola 680x0 Linux -## Designated Developers +## Target Maintainers -* [@glaubitz](https://github.com/glaubitz) -* [@ricky26](https://github.com/ricky26) +[@glaubitz](https://github.com/glaubitz) +[@ricky26](https://github.com/ricky26) ## Requirements diff --git a/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md b/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md index 92780cb5a5c..e390ba0aee9 100644 --- a/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md +++ b/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md @@ -4,9 +4,9 @@ Bare metal Motorola 680x0 -## Designated Developers +## Target Maintainers -* [@knickish](https://github.com/knickish) +[@knickish](https://github.com/knickish) ## Requirements diff --git a/src/doc/rustc/src/platform-support/mips-mti-none-elf.md b/src/doc/rustc/src/platform-support/mips-mti-none-elf.md index 731f0a8c42f..c060ebf7c7e 100644 --- a/src/doc/rustc/src/platform-support/mips-mti-none-elf.md +++ b/src/doc/rustc/src/platform-support/mips-mti-none-elf.md @@ -9,7 +9,7 @@ MIPS32r2 baremetal softfloat, Big Endian or Little Endian. ## Target maintainers -- YunQiang Su, `syq@debian.org`, https://github.com/wzssyqa +[@wzssyqa](https://github.com/wzssyqa) ## Background diff --git a/src/doc/rustc/src/platform-support/mips-release-6.md b/src/doc/rustc/src/platform-support/mips-release-6.md index b779477996d..77f495751c1 100644 --- a/src/doc/rustc/src/platform-support/mips-release-6.md +++ b/src/doc/rustc/src/platform-support/mips-release-6.md @@ -16,10 +16,10 @@ The target name follow this format: `<machine>-<vendor>-<os><abi_suffix>`, where ## Target Maintainers -- [Xuan Chen](https://github.com/chenx97) <henry.chen@oss.cipunited.com> -- [Walter Ji](https://github.com/709924470) <walter.ji@oss.cipunited.com> -- [Xinhui Yang](https://github.com/Cyanoxygen) <cyan@oss.cipunited.com> -- [Lain Yang](https://github.com/Fearyncess) <lain.yang@oss.cipunited.com> +[@chenx97](https://github.com/chenx97) +[@709924470](https://github.com/709924470) +[@Cyanoxygen](https://github.com/Cyanoxygen) +[@Fearyncess](https://github.com/Fearyncess) ## Requirements diff --git a/src/doc/rustc/src/platform-support/mips64-openwrt-linux-musl.md b/src/doc/rustc/src/platform-support/mips64-openwrt-linux-musl.md index 07470eef051..2ad33c9e20d 100644 --- a/src/doc/rustc/src/platform-support/mips64-openwrt-linux-musl.md +++ b/src/doc/rustc/src/platform-support/mips64-openwrt-linux-musl.md @@ -2,7 +2,8 @@ **Tier: 3** ## Target maintainers -- Donald Hoskins `grommish@gmail.com`, https://github.com/Itus-Shield + +[@Itus-Shield](https://github.com/Itus-Shield) ## Requirements This target is cross-compiled. There is no support for `std`. There is no diff --git a/src/doc/rustc/src/platform-support/mipsel-sony-psx.md b/src/doc/rustc/src/platform-support/mipsel-sony-psx.md index 589100e8888..2343df227f5 100644 --- a/src/doc/rustc/src/platform-support/mipsel-sony-psx.md +++ b/src/doc/rustc/src/platform-support/mipsel-sony-psx.md @@ -6,7 +6,7 @@ Sony PlayStation 1 (psx) ## Designated Developer -* [@ayrtonm](https://github.com/ayrtonm) +[@ayrtonm](https://github.com/ayrtonm) ## Requirements diff --git a/src/doc/rustc/src/platform-support/mipsel-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/mipsel-unknown-linux-gnu.md index b1ee8728c02..eed0ce4437a 100644 --- a/src/doc/rustc/src/platform-support/mipsel-unknown-linux-gnu.md +++ b/src/doc/rustc/src/platform-support/mipsel-unknown-linux-gnu.md @@ -6,7 +6,7 @@ Little-endian 32 bit MIPS for Linux with `glibc. ## Target maintainers -- [@LukasWoodtli](https://github.com/LukasWoodtli) +[@LukasWoodtli](https://github.com/LukasWoodtli) ## Requirements diff --git a/src/doc/rustc/src/platform-support/netbsd.md b/src/doc/rustc/src/platform-support/netbsd.md index 5c2ce0ee900..9040ef637be 100644 --- a/src/doc/rustc/src/platform-support/netbsd.md +++ b/src/doc/rustc/src/platform-support/netbsd.md @@ -31,9 +31,12 @@ are built for NetBSD 9.x, although some exceptions exist (some are built for NetBSD 8.x but also work on newer OS versions). -## Designated Developers +## Target Maintainers + +[@he32](https://github.com/he32) + +Further contacts: -- [@he32](https://github.com/he32), `he@NetBSD.org` - [NetBSD/pkgsrc-wip's rust](https://github.com/NetBSD/pkgsrc-wip/blob/master/rust185/Makefile) maintainer (see MAINTAINER variable). This package is part of "pkgsrc work-in-progress" and is used for deployment and testing of new versions of rust - [NetBSD's pkgsrc lang/rust](https://github.com/NetBSD/pkgsrc/tree/trunk/lang/rust) for the "proper" package in pkgsrc. - [NetBSD's pkgsrc lang/rust-bin](https://github.com/NetBSD/pkgsrc/tree/trunk/lang/rust-bin) which re-uses the bootstrap kit as a binary distribution and therefore avoids the rather protracted native build time of rust itself @@ -46,7 +49,7 @@ bug reporting system. The `x86_64-unknown-netbsd` artifacts is being distributed by the rust project. -The other targets are built by the designated developers (see above), +The other targets are built by the target maintainers (see above), and the targets are initially cross-compiled, but many if not most of them are also built natively as part of testing. diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index e097d32277d..9f8960899c1 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -13,10 +13,10 @@ and [QNX][qnx.com]. ## Target maintainers -- Florian Bartels, `Florian.Bartels@elektrobit.com`, https://github.com/flba-eb -- Tristan Roach, `TRoach@blackberry.com`, https://github.com/gh-tr -- Jonathan Pallant `Jonathan.Pallant@ferrous-systems.com`, https://github.com/jonathanpallant -- Jorge Aparicio `Jorge.Aparicio@ferrous-systems.com`, https://github.com/japaric +[@flba-eb](https://github.com/flba-eb) +[@gh-tr](https://github.com/gh-tr) +[@jonathanpallant](https://github.com/jonathanpallant) +[@japaric](https://github.com/japaric) ## Requirements diff --git a/src/doc/rustc/src/platform-support/nuttx.md b/src/doc/rustc/src/platform-support/nuttx.md index f76fe0887b5..df3f4e7b394 100644 --- a/src/doc/rustc/src/platform-support/nuttx.md +++ b/src/doc/rustc/src/platform-support/nuttx.md @@ -12,7 +12,7 @@ For brevity, many parts of the documentation will refer to Apache NuttX as simpl ## Target maintainers -- Qi Huang [@no1wudi](https://github.com/no1wudi) +[@no1wudi](https://github.com/no1wudi) ## Requirements diff --git a/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md b/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md index ab8641ff69a..106ec562bfc 100644 --- a/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md +++ b/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md @@ -7,8 +7,8 @@ platform. ## Target maintainers -- Riccardo D'Ambrosio, https://github.com/RDambrosio016 -- Kjetil Kjeka, https://github.com/kjetilkjeka +[@RDambrosio016](https://github.com/RDambrosio016) +[@kjetilkjeka](https://github.com/kjetilkjeka) <!-- FIXME: fill this out diff --git a/src/doc/rustc/src/platform-support/openbsd.md b/src/doc/rustc/src/platform-support/openbsd.md index 4ce80157dbf..e6fb23ca9ee 100644 --- a/src/doc/rustc/src/platform-support/openbsd.md +++ b/src/doc/rustc/src/platform-support/openbsd.md @@ -20,9 +20,12 @@ The target names follow this format: `$ARCH-unknown-openbsd`, where `$ARCH` spec Note that all OS versions are *major* even if using X.Y notation (`6.8` and `6.9` are different major versions) and could be binary incompatibles (with breaking changes). -## Designated Developers +## Target Maintainers + +[@semarie](https://github.com/semarie) + +Further contacts: -- [@semarie](https://github.com/semarie), `semarie@openbsd.org` - [lang/rust](https://cvsweb.openbsd.org/cgi-bin/cvsweb/ports/lang/rust/Makefile?rev=HEAD&content-type=text/x-cvsweb-markup) maintainer (see MAINTAINER variable) Fallback to ports@openbsd.org, OpenBSD third parties public mailing-list (with openbsd developers readers) diff --git a/src/doc/rustc/src/platform-support/openharmony.md b/src/doc/rustc/src/platform-support/openharmony.md index ab50cbcdf97..3acdc3707a8 100644 --- a/src/doc/rustc/src/platform-support/openharmony.md +++ b/src/doc/rustc/src/platform-support/openharmony.md @@ -15,8 +15,8 @@ system. ## Target maintainers -- Amanieu d'Antras ([@Amanieu](https://github.com/Amanieu)) -- Lu Binglun ([@lubinglun](https://github.com/lubinglun)) +[@Amanieu](https://github.com/Amanieu) +[@lubinglun](https://github.com/lubinglun) ## Requirements diff --git a/src/doc/rustc/src/platform-support/powerpc-unknown-linux-muslspe.md b/src/doc/rustc/src/platform-support/powerpc-unknown-linux-muslspe.md index 6b62e9ddba1..721e7bd3b54 100644 --- a/src/doc/rustc/src/platform-support/powerpc-unknown-linux-muslspe.md +++ b/src/doc/rustc/src/platform-support/powerpc-unknown-linux-muslspe.md @@ -9,7 +9,7 @@ See also [platform support documentation of `powerpc-unknown-linux-gnuspe`](powe ## Target maintainers -- [@BKPepe](https://github.com/BKPepe) +[@BKPepe](https://github.com/BKPepe) ## Requirements diff --git a/src/doc/rustc/src/platform-support/powerpc64-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/powerpc64-unknown-linux-musl.md index 0f78dcc089c..7213e54d5a1 100644 --- a/src/doc/rustc/src/platform-support/powerpc64-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/powerpc64-unknown-linux-musl.md @@ -7,9 +7,9 @@ This target uses the ELF v2 ABI. ## Target maintainers -- [@Gelbpunkt](https://github.com/Gelbpunkt) -- [@famfo](https://github.com/famfo) -- [@neuschaefer](https://github.com/neuschaefer) +[@Gelbpunkt](https://github.com/Gelbpunkt) +[@famfo](https://github.com/famfo) +[@neuschaefer](https://github.com/neuschaefer) ## Requirements diff --git a/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-gnu.md index 6cb34b2a777..78c3e680fc3 100644 --- a/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-gnu.md +++ b/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-gnu.md @@ -6,8 +6,8 @@ Target for 64-bit little endian PowerPC Linux programs ## Target maintainers -- David Tenty `daltenty@ibm.com`, https://github.com/daltenty -- Chris Cambly, `ccambly@ca.ibm.com`, https://github.com/gilamn5tr +[@daltenty](https://github.com/daltenty) +[@gilamn5tr](https://github.com/gilamn5tr) ## Requirements diff --git a/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-musl.md index e1e3d6d31c0..0808840065a 100644 --- a/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-musl.md @@ -6,9 +6,9 @@ Target for 64-bit little endian PowerPC Linux programs using musl libc. ## Target maintainers -- [@Gelbpunkt](https://github.com/Gelbpunkt) -- [@famfo](https://github.com/famfo) -- [@neuschaefer](https://github.com/neuschaefer) +[@Gelbpunkt](https://github.com/Gelbpunkt) +[@famfo](https://github.com/famfo) +[@neuschaefer](https://github.com/neuschaefer) ## Requirements diff --git a/src/doc/rustc/src/platform-support/redox.md b/src/doc/rustc/src/platform-support/redox.md index c1a96f1cfc4..fc36a551c86 100644 --- a/src/doc/rustc/src/platform-support/redox.md +++ b/src/doc/rustc/src/platform-support/redox.md @@ -13,7 +13,7 @@ Target triplets available so far: ## Target maintainers -- Jeremy Soller ([@jackpot51](https://github.com/jackpot51)) +[@jackpot51](https://github.com/jackpot51) ## Requirements diff --git a/src/doc/rustc/src/platform-support/riscv32e-unknown-none-elf.md b/src/doc/rustc/src/platform-support/riscv32e-unknown-none-elf.md index 69f08774f83..d33bf37e1f9 100644 --- a/src/doc/rustc/src/platform-support/riscv32e-unknown-none-elf.md +++ b/src/doc/rustc/src/platform-support/riscv32e-unknown-none-elf.md @@ -6,7 +6,7 @@ Bare-metal target for RISC-V CPUs with the RV32E, RV32EM and RV32EMC ISAs. ## Target maintainers -* Henri Lunnikivi, <henri.lunnikivi@gmail.com>, [@hegza](https://github.com/hegza) +[@hegza](https://github.com/hegza) ## Requirements diff --git a/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md b/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md index 79455b0fbc4..09b42da26e7 100644 --- a/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md +++ b/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md @@ -6,9 +6,9 @@ RISC Zero's Zero Knowledge Virtual Machine (zkVM) implementing the RV32IM instru ## Target maintainers -- Frank Laub, `frank@risczero.com`, https://github.com/flaub -- Jeremy Bruestle, `jeremy@risczero.com`, https://github.com/jbruestle -- Erik Kaneda, `erik@risczero.com`, https://github.com/SchmErik +[@flaub](https://github.com/flaub) +[@jbruestle](https://github.com/jbruestle) +[@SchmErik](https://github.com/SchmErik) ## Background diff --git a/src/doc/rustc/src/platform-support/riscv32imac-unknown-xous-elf.md b/src/doc/rustc/src/platform-support/riscv32imac-unknown-xous-elf.md index 12928edfcac..cbfb2e2d2b6 100644 --- a/src/doc/rustc/src/platform-support/riscv32imac-unknown-xous-elf.md +++ b/src/doc/rustc/src/platform-support/riscv32imac-unknown-xous-elf.md @@ -6,7 +6,7 @@ Xous microkernel, message-based operating system that powers devices such as Pre ## Target maintainers -- [@xobs](https://github.com/xobs) +[@xobs](https://github.com/xobs) ## Requirements diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md index 1ab867fe71e..d62a65b2190 100644 --- a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md +++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md @@ -7,10 +7,10 @@ RISC-V targets using the *RV64I* base instruction set with the *G* collection of ## Target maintainers -- Kito Cheng, <kito.cheng@gmail.com>, [@kito-cheng](https://github.com/kito-cheng) -- Michael Maitland, <michaeltmaitland@gmail.com>, [@michaelmaitland](https://github.com/michaelmaitland) -- Robin Randhawa, <robin.randhawa@sifive.com>, [@robin-randhawa-sifive](https://github.com/robin-randhawa-sifive) -- Craig Topper, <craig.topper@sifive.com>, [@topperc](https://github.com/topperc) +[@kito-cheng](https://github.com/kito-cheng) +[@michaelmaitland](https://github.com/michaelmaitland) +[@robin-randhawa-sifive](https://github.com/robin-randhawa-sifive) +[@topperc](https://github.com/topperc) ## Requirements diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md index 5e6275d6979..2e88b5aa813 100644 --- a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md @@ -6,8 +6,8 @@ Target for RISC-V Linux programs using musl libc. ## Target maintainers -- [@Amanieu](https://github.com/Amanieu) -- [@kraj](https://github.com/kraj) +[@Amanieu](https://github.com/Amanieu) +[@kraj](https://github.com/kraj) ## Requirements diff --git a/src/doc/rustc/src/platform-support/s390x-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/s390x-unknown-linux-gnu.md index 1aa2704cf95..77bdabf4f71 100644 --- a/src/doc/rustc/src/platform-support/s390x-unknown-linux-gnu.md +++ b/src/doc/rustc/src/platform-support/s390x-unknown-linux-gnu.md @@ -6,8 +6,8 @@ IBM z/Architecture (s390x) targets (including IBM Z and LinuxONE) running Linux. ## Target maintainers -- Ulrich Weigand, <ulrich.weigand@de.ibm.com>, [@uweigand](https://github.com/uweigand) -- Josh Stone, <jistone@redhat.com>, [@cuviper](https://github.com/cuviper) +[@uweigand](https://github.com/uweigand) +[@cuviper](https://github.com/cuviper) ## Requirements diff --git a/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md index 3c334620cfc..c604b487c2c 100644 --- a/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md @@ -6,7 +6,7 @@ IBM z/Architecture (s390x) targets (including IBM Z and LinuxONE) running Linux. ## Target maintainers -- Ulrich Weigand, <ulrich.weigand@de.ibm.com>, [@uweigand](https://github.com/uweigand) +[@uweigand](https://github.com/uweigand) ## Requirements diff --git a/src/doc/rustc/src/platform-support/solaris.md b/src/doc/rustc/src/platform-support/solaris.md index 1e0a241f840..0452d76f6c2 100644 --- a/src/doc/rustc/src/platform-support/solaris.md +++ b/src/doc/rustc/src/platform-support/solaris.md @@ -7,7 +7,7 @@ Rust for Solaris operating system. ## Target maintainers -- Petr Sumbera `sumbera@volny.cz`, https://github.com/psumbera +[@psumbera](https://github.com/psumbera) ## Requirements diff --git a/src/doc/rustc/src/platform-support/sparc-unknown-none-elf.md b/src/doc/rustc/src/platform-support/sparc-unknown-none-elf.md index c19b7d7681a..f341914fb5b 100644 --- a/src/doc/rustc/src/platform-support/sparc-unknown-none-elf.md +++ b/src/doc/rustc/src/platform-support/sparc-unknown-none-elf.md @@ -10,7 +10,7 @@ Rust for bare-metal 32-bit SPARC V7 and V8 systems, e.g. the Gaisler LEON3. ## Target maintainers -- Jonathan Pallant, <jonathan.pallant@ferrous-systems.com>, https://ferrous-systems.com +[@jonathanpallant](https://github.com/jonathanpallant) ## Requirements diff --git a/src/doc/rustc/src/platform-support/trusty.md b/src/doc/rustc/src/platform-support/trusty.md index 73fcbbdddca..2aa599594a8 100644 --- a/src/doc/rustc/src/platform-support/trusty.md +++ b/src/doc/rustc/src/platform-support/trusty.md @@ -7,10 +7,8 @@ Environment (TEE) for Android. ## Target maintainers -- Nicole LeGare (@randomPoison) -- Andrei Homescu (@ahomescu) -- Chris Wailes (chriswailes@google.com) -- As a fallback trusty-dev-team@google.com can be contacted +[@randomPoison](https://github.com/randomPoison) +[@ahomescu](https://github.com/ahomescu) ## Requirements diff --git a/src/doc/rustc/src/platform-support/unikraft-linux-musl.md b/src/doc/rustc/src/platform-support/unikraft-linux-musl.md index b40e99825e5..4a4080eba9b 100644 --- a/src/doc/rustc/src/platform-support/unikraft-linux-musl.md +++ b/src/doc/rustc/src/platform-support/unikraft-linux-musl.md @@ -12,7 +12,7 @@ Target triplets available so far: ## Target maintainers -- Martin Kröning ([@mkroening](https://github.com/mkroening)) +[@mkroening](https://github.com/mkroening) ## Requirements diff --git a/src/doc/rustc/src/platform-support/unknown-uefi.md b/src/doc/rustc/src/platform-support/unknown-uefi.md index e9979cc912c..9587590d12d 100644 --- a/src/doc/rustc/src/platform-support/unknown-uefi.md +++ b/src/doc/rustc/src/platform-support/unknown-uefi.md @@ -13,8 +13,8 @@ Available targets: ## Target maintainers -- David Rheinsberg ([@dvdhrm](https://github.com/dvdhrm)) -- Nicholas Bishop ([@nicholasbishop](https://github.com/nicholasbishop)) +[@dvdhrm](https://github.com/dvdhrm) +[@nicholasbishop](https://github.com/nicholasbishop) ## Requirements diff --git a/src/doc/rustc/src/platform-support/uwp-windows-msvc.md b/src/doc/rustc/src/platform-support/uwp-windows-msvc.md index ce2ebb686fa..7ee6b41dbd1 100644 --- a/src/doc/rustc/src/platform-support/uwp-windows-msvc.md +++ b/src/doc/rustc/src/platform-support/uwp-windows-msvc.md @@ -6,7 +6,7 @@ Windows targets for Universal Windows Platform (UWP) applications, using MSVC to ## Target maintainers -- [@bdbai](https://github.com/bdbai) +[@bdbai](https://github.com/bdbai) ## Requirements diff --git a/src/doc/rustc/src/platform-support/vxworks.md b/src/doc/rustc/src/platform-support/vxworks.md index a2b91f3769d..3fccee80722 100644 --- a/src/doc/rustc/src/platform-support/vxworks.md +++ b/src/doc/rustc/src/platform-support/vxworks.md @@ -19,7 +19,7 @@ Target triplets available: ## Target maintainers -- B I Mohammed Abbas ([@biabbas](https://github.com/biabbas)) +[@biabbas](https://github.com/biabbas) ## Requirements diff --git a/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md b/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md index 6949c657db8..a9ff1ebd104 100644 --- a/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md +++ b/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md @@ -36,8 +36,8 @@ If you are only targeting the web and need to access web APIs, the ## Target maintainers -- Hood Chatham, https://github.com/hoodmane -- Juniper Tyree, https://github.com/juntyr +[@hoodmane](https://github.com/hoodmane) +[@juntyr](https://github.com/juntyr) ## Requirements diff --git a/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md index 150f69e03c6..b67f49c3a38 100644 --- a/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md +++ b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md @@ -34,7 +34,7 @@ was not maintained at that time. This means that the list below is not exhaustive, and there are more interested parties in this target. That being said, those interested in maintaining this target are: -- Alex Crichton, https://github.com/alexcrichton +[@alexcrichton](https://github.com/alexcrichton) ## Requirements diff --git a/src/doc/rustc/src/platform-support/wasm32-wali-linux.md b/src/doc/rustc/src/platform-support/wasm32-wali-linux.md index 0c46ea2c01d..3213e2b0c8f 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wali-linux.md +++ b/src/doc/rustc/src/platform-support/wasm32-wali-linux.md @@ -10,7 +10,7 @@ From the wider Wasm ecosystem perspective, implementing WALI within engines allo ## Target maintainers -- Arjun Ramesh [@arjunr2](https://github.com/arjunr2) +[@arjunr2](https://github.com/arjunr2) ## Requirements diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md index af20b62b9f6..6c8bf21ec19 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md @@ -18,10 +18,10 @@ with native multi threading capabilities. ## Target maintainers -- Georgii Rylov, https://github.com/g0djan -- Alex Crichton, https://github.com/alexcrichton -- Andrew Brown, https://github.com/abrown -- Marcin Kolny, https://github.com/loganek +[@g0djan](https://github.com/g0djan) +[@alexcrichton](https://github.com/alexcrichton) +[@abrown](https://github.com/abrown) +[@loganek](https://github.com/loganek) ## Requirements diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1.md b/src/doc/rustc/src/platform-support/wasm32-wasip1.md index e5e8d554ecf..4f065a554cf 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1.md @@ -43,7 +43,7 @@ exhaustive and there are more interested parties in this target. That being said since when this document was last updated those interested in maintaining this target are: -- Alex Crichton, https://github.com/alexcrichton +[@alexcrichton](https://github.com/alexcrichton) ## Requirements diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip2.md b/src/doc/rustc/src/platform-support/wasm32-wasip2.md index 40049ecfa5f..dea33e62f2b 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip2.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip2.md @@ -13,8 +13,8 @@ WebAssembly binaries with native host capabilities. ## Target maintainers -- Alex Crichton, https://github.com/alexcrichton -- Ryan Levick, https://github.com/rylev +[@alexcrichton](https://github.com/alexcrichton) +[@rylev](https://github.com/rylev) ## Requirements diff --git a/src/doc/rustc/src/platform-support/wasm32v1-none.md b/src/doc/rustc/src/platform-support/wasm32v1-none.md index 46f89c20113..51b00de5e57 100644 --- a/src/doc/rustc/src/platform-support/wasm32v1-none.md +++ b/src/doc/rustc/src/platform-support/wasm32v1-none.md @@ -19,8 +19,8 @@ The target is very similar to [`wasm32-unknown-unknown`](./wasm32-unknown-unknow ## Target maintainers -- Alex Crichton, https://github.com/alexcrichton -- Graydon Hoare, https://github.com/graydon +[@alexcrichton](https://github.com/alexcrichton) +[@graydon](https://github.com/graydon) ## Requirements diff --git a/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md b/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md index 157fff419d3..cc21da11f4d 100644 --- a/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md +++ b/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md @@ -9,7 +9,7 @@ WebAssembly proposal. ## Target maintainers -- Alex Crichton, https://github.com/alexcrichton +[@alexcrichton](https://github.com/alexcrichton) ## Requirements diff --git a/src/doc/rustc/src/platform-support/win7-windows-gnu.md b/src/doc/rustc/src/platform-support/win7-windows-gnu.md index 3a819b0a4e2..1311117dc7c 100644 --- a/src/doc/rustc/src/platform-support/win7-windows-gnu.md +++ b/src/doc/rustc/src/platform-support/win7-windows-gnu.md @@ -10,7 +10,7 @@ Target triples: ## Target maintainers -- @tbu- +[@tbu-](https://github.com/tbu-) ## Requirements diff --git a/src/doc/rustc/src/platform-support/win7-windows-msvc.md b/src/doc/rustc/src/platform-support/win7-windows-msvc.md index cbbb44b47aa..56fe0f64016 100644 --- a/src/doc/rustc/src/platform-support/win7-windows-msvc.md +++ b/src/doc/rustc/src/platform-support/win7-windows-msvc.md @@ -10,7 +10,7 @@ Target triples: ## Target maintainers -- @roblabla +[@roblabla](https://github.com/roblabla) ## Requirements diff --git a/src/doc/rustc/src/platform-support/windows-gnullvm.md b/src/doc/rustc/src/platform-support/windows-gnullvm.md index 1ff559fe960..f3dc73165ac 100644 --- a/src/doc/rustc/src/platform-support/windows-gnullvm.md +++ b/src/doc/rustc/src/platform-support/windows-gnullvm.md @@ -11,8 +11,8 @@ Target triples available so far: ## Target maintainers -- [@mati865](https://github.com/mati865) -- [@thomcc](https://github.com/thomcc) +[@mati865](https://github.com/mati865) +[@thomcc](https://github.com/thomcc) ## Requirements diff --git a/src/doc/rustc/src/platform-support/x86_64-fortanix-unknown-sgx.md b/src/doc/rustc/src/platform-support/x86_64-fortanix-unknown-sgx.md index 33e1c44e6d3..e52ad1ce828 100644 --- a/src/doc/rustc/src/platform-support/x86_64-fortanix-unknown-sgx.md +++ b/src/doc/rustc/src/platform-support/x86_64-fortanix-unknown-sgx.md @@ -9,11 +9,13 @@ based on the ABI defined by Fortanix for the [Enclave Development Platform ## Target maintainers -The [EDP team](mailto:edp.maintainers@fortanix.com) at Fortanix. +[@jethrogb](https://github.com/jethrogb) +[@raoulstrackx](https://github.com/raoulstrackx) +[@mzohreva](https://github.com/mzohreva) + +Further contacts: -- Jethro Beekman [@jethrogb](https://github.com/jethrogb) -- Raoul Strackx [@raoulstrackx](https://github.com/raoulstrackx) -- Mohsen Zohrevandi [@mzohreva](https://github.com/mzohreva) +The [EDP team](mailto:edp.maintainers@fortanix.com) at Fortanix. ## Requirements diff --git a/src/doc/rustc/src/platform-support/x86_64-pc-cygwin.md b/src/doc/rustc/src/platform-support/x86_64-pc-cygwin.md index a8fc4f181d8..60aaa371bbc 100644 --- a/src/doc/rustc/src/platform-support/x86_64-pc-cygwin.md +++ b/src/doc/rustc/src/platform-support/x86_64-pc-cygwin.md @@ -10,7 +10,7 @@ Cygwin is only intended as an emulation layer for Unix-only programs which do no ## Target maintainers -- [Berrysoft](https://github.com/Berrysoft) +[@Berrysoft](https://github.com/Berrysoft) ## Requirements diff --git a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md index 965d6aea931..ec16c181fe1 100644 --- a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md +++ b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md @@ -6,7 +6,7 @@ Freestanding x86-64 linux binary with no dependency on libc. ## Target maintainers -- [morr0ne](https://github.com/morr0ne/) +[@morr0ne](https://github.com/morr0ne) ## Requirements diff --git a/src/doc/rustc/src/platform-support/x86_64-unknown-none.md b/src/doc/rustc/src/platform-support/x86_64-unknown-none.md index 3b8aae3a389..c8db5dc846f 100644 --- a/src/doc/rustc/src/platform-support/x86_64-unknown-none.md +++ b/src/doc/rustc/src/platform-support/x86_64-unknown-none.md @@ -6,8 +6,8 @@ Freestanding/bare-metal x86-64 binaries in ELF format: firmware, kernels, etc. ## Target maintainers -- Harald Hoyer `harald@profian.com`, https://github.com/haraldh -- Mike Leany, https://github.com/mikeleany +[@haraldh](https://github.com/haraldh) +[@mikeleany](https://github.com/mikeleany) ## Requirements diff --git a/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md b/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md index 545fffb84f9..4ffbe4baeb8 100644 --- a/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md +++ b/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md @@ -8,7 +8,7 @@ Target for macOS on late-generation `x86_64` Apple chips, usable as the ## Target maintainers -- Thom Chiovoloni `thom@shift.click` <https://github.com/thomcc> +[@thomcc](https://github.com/thomcc) ## Requirements diff --git a/src/doc/rustc/src/platform-support/xtensa.md b/src/doc/rustc/src/platform-support/xtensa.md index 332b8ee9c15..1189d27c95d 100644 --- a/src/doc/rustc/src/platform-support/xtensa.md +++ b/src/doc/rustc/src/platform-support/xtensa.md @@ -6,8 +6,8 @@ Targets for Xtensa CPUs. ## Target maintainers -- Scott Mabin [@MabezDev](https://github.com/MabezDev) -- Sergio Gasquez [@SergioGasquez](https://github.com/SergioGasquez) +[@MabezDev](https://github.com/MabezDev) +[@SergioGasquez](https://github.com/SergioGasquez) ## Requirements diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index 4679acf0a6a..2f9d4d22e5a 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -245,36 +245,31 @@ See the [Clang ControlFlowIntegrity documentation][clang-cfi] for more details. ## Example 1: Redirecting control flow using an indirect branch/call to an invalid destination ```rust,ignore (making doc tests pass cross-platform is hard) -#![feature(naked_functions)] - -use std::arch::asm; +use std::arch::naked_asm; use std::mem; fn add_one(x: i32) -> i32 { x + 1 } -#[naked] +#[unsafe(naked)] pub extern "C" fn add_two(x: i32) { // x + 2 preceded by a landing pad/nop block - unsafe { - asm!( - " - nop - nop - nop - nop - nop - nop - nop - nop - nop - lea eax, [rdi+2] - ret - ", - options(noreturn) - ); - } + naked_asm!( + " + nop + nop + nop + nop + nop + nop + nop + nop + nop + lea eax, [rdi+2] + ret + " + ); } fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 { diff --git a/src/doc/unstable-book/src/language-features/box-patterns.md b/src/doc/unstable-book/src/language-features/box-patterns.md index a1ac09633b7..c8a15b8477e 100644 --- a/src/doc/unstable-book/src/language-features/box-patterns.md +++ b/src/doc/unstable-book/src/language-features/box-patterns.md @@ -6,6 +6,8 @@ The tracking issue for this feature is: [#29641] ------------------------ +> **Note**: This feature will be superseded by [`deref_patterns`] in the future. + Box patterns let you match on `Box<T>`s: @@ -28,3 +30,5 @@ fn main() { } } ``` + +[`deref_patterns`]: ./deref-patterns.md diff --git a/src/doc/unstable-book/src/language-features/deref-patterns.md b/src/doc/unstable-book/src/language-features/deref-patterns.md new file mode 100644 index 00000000000..d0102a665b0 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/deref-patterns.md @@ -0,0 +1,57 @@ +# `deref_patterns` + +The tracking issue for this feature is: [#87121] + +[#87121]: https://github.com/rust-lang/rust/issues/87121 + +------------------------ + +> **Note**: This feature is incomplete. In the future, it is meant to supersede +> [`box_patterns`](./box-patterns.md) and [`string_deref_patterns`](./string-deref-patterns.md). + +This feature permits pattern matching on [smart pointers in the standard library] through their +`Deref` target types, either implicitly or with explicit `deref!(_)` patterns (the syntax of which +is currently a placeholder). + +```rust +#![feature(deref_patterns)] +#![allow(incomplete_features)] + +let mut v = vec![Box::new(Some(0))]; + +// Implicit dereferences are inserted when a pattern can match against the +// result of repeatedly dereferencing but can't match against a smart +// pointer itself. This works alongside match ergonomics for references. +if let [Some(x)] = &mut v { + *x += 1; +} + +// Explicit `deref!(_)` patterns may instead be used when finer control is +// needed, e.g. to dereference only a single smart pointer, or to bind the +// the result of dereferencing to a variable. +if let deref!([deref!(opt_x @ Some(1))]) = &mut v { + opt_x.as_mut().map(|x| *x += 1); +} + +assert_eq!(v, [Box::new(Some(2))]); +``` + +Without this feature, it may be necessary to introduce temporaries to represent dereferenced places +when matching on nested structures: + +```rust +let mut v = vec![Box::new(Some(0))]; +if let [b] = &mut *v { + if let Some(x) = &mut **b { + *x += 1; + } +} +if let [b] = &mut *v { + if let opt_x @ Some(1) = &mut **b { + opt_x.as_mut().map(|x| *x += 1); + } +} +assert_eq!(v, [Box::new(Some(2))]); +``` + +[smart pointers in the standard library]: https://doc.rust-lang.org/std/ops/trait.DerefPure.html#implementors diff --git a/src/doc/unstable-book/src/language-features/string-deref-patterns.md b/src/doc/unstable-book/src/language-features/string-deref-patterns.md index 3723830751e..366bb15d4ea 100644 --- a/src/doc/unstable-book/src/language-features/string-deref-patterns.md +++ b/src/doc/unstable-book/src/language-features/string-deref-patterns.md @@ -6,6 +6,8 @@ The tracking issue for this feature is: [#87121] ------------------------ +> **Note**: This feature will be superseded by [`deref_patterns`] in the future. + This feature permits pattern matching `String` to `&str` through [its `Deref` implementation]. ```rust @@ -42,4 +44,5 @@ pub fn is_it_the_answer(value: Value) -> bool { } ``` +[`deref_patterns`]: ./deref-patterns.md [its `Deref` implementation]: https://doc.rust-lang.org/std/string/struct.String.html#impl-Deref-for-String diff --git a/src/etc/natvis/libcore.natvis b/src/etc/natvis/libcore.natvis index 8a441cf2093..8fe87a99989 100644 --- a/src/etc/natvis/libcore.natvis +++ b/src/etc/natvis/libcore.natvis @@ -69,9 +69,9 @@ </Type> <Type Name="core::pin::Pin<*>"> - <DisplayString>Pin({(void*)__pointer}: {__pointer})</DisplayString> + <DisplayString>Pin({(void*)pointer}: {pointer})</DisplayString> <Expand> - <ExpandedItem>__pointer</ExpandedItem> + <ExpandedItem>pointer</ExpandedItem> </Expand> </Type> diff --git a/src/etc/rust_analyzer_eglot.el b/src/etc/rust_analyzer_eglot.el index 6b40371d9af..90bd38aa894 100644 --- a/src/etc/rust_analyzer_eglot.el +++ b/src/etc/rust_analyzer_eglot.el @@ -8,10 +8,11 @@ "check" "--json-output"]) :linkedProjects ["Cargo.toml" - "src/bootstrap/Cargo.toml" - "src/tools/rust-analyzer/Cargo.toml" "compiler/rustc_codegen_cranelift/Cargo.toml" - "compiler/rustc_codegen_gcc/Cargo.toml"] + "compiler/rustc_codegen_gcc/Cargo.toml" + "library/Cargo.toml" + "src/bootstrap/Cargo.toml" + "src/tools/rust-analyzer/Cargo.toml"] :rustfmt ( :overrideCommand ["build/host/rustfmt/bin/rustfmt" "--edition=2021"]) :procMacro ( :server "build/host/stage0/libexec/rust-analyzer-proc-macro-srv" diff --git a/src/etc/rust_analyzer_settings.json b/src/etc/rust_analyzer_settings.json index da7d326a512..5ce886a9b65 100644 --- a/src/etc/rust_analyzer_settings.json +++ b/src/etc/rust_analyzer_settings.json @@ -9,11 +9,11 @@ ], "rust-analyzer.linkedProjects": [ "Cargo.toml", + "compiler/rustc_codegen_cranelift/Cargo.toml", + "compiler/rustc_codegen_gcc/Cargo.toml", "library/Cargo.toml", "src/bootstrap/Cargo.toml", - "src/tools/rust-analyzer/Cargo.toml", - "compiler/rustc_codegen_cranelift/Cargo.toml", - "compiler/rustc_codegen_gcc/Cargo.toml" + "src/tools/rust-analyzer/Cargo.toml" ], "rust-analyzer.rustfmt.overrideCommand": [ "${workspaceFolder}/build/host/rustfmt/bin/rustfmt", @@ -36,5 +36,10 @@ }, "rust-analyzer.server.extraEnv": { "RUSTUP_TOOLCHAIN": "nightly" + }, + "files.associations": { + "*.fixed": "rust", + "*.pp": "rust", + "*.mir": "rust" } } diff --git a/src/etc/rust_analyzer_zed.json b/src/etc/rust_analyzer_zed.json index abc6ddbc213..3461ff887d9 100644 --- a/src/etc/rust_analyzer_zed.json +++ b/src/etc/rust_analyzer_zed.json @@ -21,15 +21,15 @@ }, "linkedProjects": [ "Cargo.toml", + "compiler/rustc_codegen_cranelift/Cargo.toml", + "compiler/rustc_codegen_gcc/Cargo.toml", "library/Cargo.toml", "src/bootstrap/Cargo.toml", - "src/tools/rust-analyzer/Cargo.toml", - "compiler/rustc_codegen_cranelift/Cargo.toml", - "compiler/rustc_codegen_gcc/Cargo.toml" + "src/tools/rust-analyzer/Cargo.toml" ], "procMacro": { - "enable": true, - "server": "${workspaceFolder}/build/host/stage0/libexec/rust-analyzer-proc-macro-srv" + "enable": true, + "server": "${workspaceFolder}/build/host/stage0/libexec/rust-analyzer-proc-macro-srv" }, "rustc": { "source": "./Cargo.toml" @@ -47,5 +47,8 @@ } } } + }, + "file_types": { + "Rust": ["fixed", "pp", "mir"] } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index fe9dc9a9e21..6ecb67c776c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1052,7 +1052,7 @@ fn clean_fn_or_proc_macro<'tcx>( match macro_kind { Some(kind) => clean_proc_macro(item, name, kind, cx), None => { - let mut func = clean_function(cx, sig, generics, FunctionArgs::Body(body_id)); + let mut func = clean_function(cx, sig, generics, ParamsSrc::Body(body_id)); clean_fn_decl_legacy_const_generics(&mut func, attrs); FunctionItem(func) } @@ -1071,16 +1071,11 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[hir::Attrib for (pos, literal) in meta_item_list.iter().filter_map(|meta| meta.lit()).enumerate() { match literal.kind { ast::LitKind::Int(a, _) => { - let param = func.generics.params.remove(0); - if let GenericParamDef { - name, - kind: GenericParamDefKind::Const { ty, .. }, - .. - } = param - { - func.decl.inputs.values.insert( + let GenericParamDef { name, kind, .. } = func.generics.params.remove(0); + if let GenericParamDefKind::Const { ty, .. } = kind { + func.decl.inputs.insert( a.get() as _, - Argument { name: Some(name), type_: *ty, is_const: true }, + Parameter { name: Some(name), type_: *ty, is_const: true }, ); } else { panic!("unexpected non const in position {pos}"); @@ -1092,7 +1087,7 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[hir::Attrib } } -enum FunctionArgs<'tcx> { +enum ParamsSrc<'tcx> { Body(hir::BodyId), Idents(&'tcx [Option<Ident>]), } @@ -1101,86 +1096,62 @@ fn clean_function<'tcx>( cx: &mut DocContext<'tcx>, sig: &hir::FnSig<'tcx>, generics: &hir::Generics<'tcx>, - args: FunctionArgs<'tcx>, + params: ParamsSrc<'tcx>, ) -> Box<Function> { let (generics, decl) = enter_impl_trait(cx, |cx| { - // NOTE: generics must be cleaned before args + // NOTE: Generics must be cleaned before params. let generics = clean_generics(generics, cx); - let args = match args { - FunctionArgs::Body(body_id) => { - clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id) - } - FunctionArgs::Idents(idents) => { - clean_args_from_types_and_names(cx, sig.decl.inputs, idents) - } + let params = match params { + ParamsSrc::Body(body_id) => clean_params_via_body(cx, sig.decl.inputs, body_id), + // Let's not perpetuate anon params from Rust 2015; use `_` for them. + ParamsSrc::Idents(idents) => clean_params(cx, sig.decl.inputs, idents, |ident| { + Some(ident.map_or(kw::Underscore, |ident| ident.name)) + }), }; - let decl = clean_fn_decl_with_args(cx, sig.decl, Some(&sig.header), args); + let decl = clean_fn_decl_with_params(cx, sig.decl, Some(&sig.header), params); (generics, decl) }); Box::new(Function { decl, generics }) } -fn clean_args_from_types_and_names<'tcx>( +fn clean_params<'tcx>( cx: &mut DocContext<'tcx>, types: &[hir::Ty<'tcx>], idents: &[Option<Ident>], -) -> Arguments { - fn nonempty_name(ident: &Option<Ident>) -> Option<Symbol> { - if let Some(ident) = ident - && ident.name != kw::Underscore - { - Some(ident.name) - } else { - None - } - } - - // If at least one argument has a name, use `_` as the name of unnamed - // arguments. Otherwise omit argument names. - let default_name = if idents.iter().any(|ident| nonempty_name(ident).is_some()) { - Some(kw::Underscore) - } else { - None - }; - - Arguments { - values: types - .iter() - .enumerate() - .map(|(i, ty)| Argument { - type_: clean_ty(ty, cx), - name: idents.get(i).and_then(nonempty_name).or(default_name), - is_const: false, - }) - .collect(), - } + postprocess: impl Fn(Option<Ident>) -> Option<Symbol>, +) -> Vec<Parameter> { + types + .iter() + .enumerate() + .map(|(i, ty)| Parameter { + name: postprocess(idents[i]), + type_: clean_ty(ty, cx), + is_const: false, + }) + .collect() } -fn clean_args_from_types_and_body_id<'tcx>( +fn clean_params_via_body<'tcx>( cx: &mut DocContext<'tcx>, types: &[hir::Ty<'tcx>], body_id: hir::BodyId, -) -> Arguments { - let body = cx.tcx.hir_body(body_id); - - Arguments { - values: types - .iter() - .zip(body.params) - .map(|(ty, param)| Argument { - name: Some(name_from_pat(param.pat)), - type_: clean_ty(ty, cx), - is_const: false, - }) - .collect(), - } +) -> Vec<Parameter> { + types + .iter() + .zip(cx.tcx.hir_body(body_id).params) + .map(|(ty, param)| Parameter { + name: Some(name_from_pat(param.pat)), + type_: clean_ty(ty, cx), + is_const: false, + }) + .collect() } -fn clean_fn_decl_with_args<'tcx>( +fn clean_fn_decl_with_params<'tcx>( cx: &mut DocContext<'tcx>, decl: &hir::FnDecl<'tcx>, header: Option<&hir::FnHeader>, - args: Arguments, + params: Vec<Parameter>, ) -> FnDecl { let mut output = match decl.output { hir::FnRetTy::Return(typ) => clean_ty(typ, cx), @@ -1191,7 +1162,7 @@ fn clean_fn_decl_with_args<'tcx>( { output = output.sugared_async_return_type(); } - FnDecl { inputs: args, output, c_variadic: decl.c_variadic } + FnDecl { inputs: params, output, c_variadic: decl.c_variadic } } fn clean_poly_fn_sig<'tcx>( @@ -1199,10 +1170,6 @@ fn clean_poly_fn_sig<'tcx>( did: Option<DefId>, sig: ty::PolyFnSig<'tcx>, ) -> FnDecl { - let mut names = did.map_or(&[] as &[_], |did| cx.tcx.fn_arg_idents(did)).iter(); - - // We assume all empty tuples are default return type. This theoretically can discard `-> ()`, - // but shouldn't change any code meaning. let mut output = clean_middle_ty(sig.output(), cx, None, None); // If the return type isn't an `impl Trait`, we can safely assume that this @@ -1215,25 +1182,25 @@ fn clean_poly_fn_sig<'tcx>( output = output.sugared_async_return_type(); } - FnDecl { - output, - c_variadic: sig.skip_binder().c_variadic, - inputs: Arguments { - values: sig - .inputs() - .iter() - .map(|t| Argument { - type_: clean_middle_ty(t.map_bound(|t| *t), cx, None, None), - name: Some(if let Some(Some(ident)) = names.next() { - ident.name - } else { - kw::Underscore - }), - is_const: false, - }) - .collect(), - }, - } + let mut idents = did.map(|did| cx.tcx.fn_arg_idents(did)).unwrap_or_default().iter().copied(); + + // If this comes from a fn item, let's not perpetuate anon params from Rust 2015; use `_` for them. + // If this comes from a fn ptr ty, we just keep params unnamed since it's more conventional stylistically. + // Since the param name is not part of the semantic type, these params never bear a name unlike + // in the HIR case, thus we can't peform any fancy fallback logic unlike `clean_bare_fn_ty`. + let fallback = did.map(|_| kw::Underscore); + + let params = sig + .inputs() + .iter() + .map(|ty| Parameter { + name: idents.next().flatten().map(|ident| ident.name).or(fallback), + type_: clean_middle_ty(ty.map_bound(|ty| *ty), cx, None, None), + is_const: false, + }) + .collect(); + + FnDecl { inputs: params, output, c_variadic: sig.skip_binder().c_variadic } } fn clean_trait_ref<'tcx>(trait_ref: &hir::TraitRef<'tcx>, cx: &mut DocContext<'tcx>) -> Path { @@ -1273,11 +1240,11 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext RequiredAssocConstItem(generics, Box::new(clean_ty(ty, cx))) } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { - let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Body(body)); + let m = clean_function(cx, sig, trait_item.generics, ParamsSrc::Body(body)); MethodItem(m, None) } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(idents)) => { - let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Idents(idents)); + let m = clean_function(cx, sig, trait_item.generics, ParamsSrc::Idents(idents)); RequiredMethodItem(m) } hir::TraitItemKind::Type(bounds, Some(default)) => { @@ -1318,7 +1285,7 @@ pub(crate) fn clean_impl_item<'tcx>( type_: clean_ty(ty, cx), })), hir::ImplItemKind::Fn(ref sig, body) => { - let m = clean_function(cx, sig, impl_.generics, FunctionArgs::Body(body)); + let m = clean_function(cx, sig, impl_.generics, ParamsSrc::Body(body)); let defaultness = cx.tcx.defaultness(impl_.owner_id); MethodItem(m, Some(defaultness)) } @@ -1390,14 +1357,14 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo } ty::AssocItemContainer::Trait => tcx.types.self_param, }; - let self_arg_ty = + let self_param_ty = tcx.fn_sig(assoc_item.def_id).instantiate_identity().input(0).skip_binder(); - if self_arg_ty == self_ty { - item.decl.inputs.values[0].type_ = SelfTy; - } else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() + if self_param_ty == self_ty { + item.decl.inputs[0].type_ = SelfTy; + } else if let ty::Ref(_, ty, _) = *self_param_ty.kind() && ty == self_ty { - match item.decl.inputs.values[0].type_ { + match item.decl.inputs[0].type_ { BorrowedRef { ref mut type_, .. } => **type_ = SelfTy, _ => unreachable!(), } @@ -2611,15 +2578,25 @@ fn clean_bare_fn_ty<'tcx>( cx: &mut DocContext<'tcx>, ) -> BareFunctionDecl { let (generic_params, decl) = enter_impl_trait(cx, |cx| { - // NOTE: generics must be cleaned before args + // NOTE: Generics must be cleaned before params. let generic_params = bare_fn .generic_params .iter() .filter(|p| !is_elided_lifetime(p)) .map(|x| clean_generic_param(cx, None, x)) .collect(); - let args = clean_args_from_types_and_names(cx, bare_fn.decl.inputs, bare_fn.param_idents); - let decl = clean_fn_decl_with_args(cx, bare_fn.decl, None, args); + // Since it's more conventional stylistically, elide the name of all params called `_` + // unless there's at least one interestingly named param in which case don't elide any + // name since mixing named and unnamed params is less legible. + let filter = |ident: Option<Ident>| { + ident.map(|ident| ident.name).filter(|&ident| ident != kw::Underscore) + }; + let fallback = + bare_fn.param_idents.iter().copied().find_map(filter).map(|_| kw::Underscore); + let params = clean_params(cx, bare_fn.decl.inputs, bare_fn.param_idents, |ident| { + filter(ident).or(fallback) + }); + let decl = clean_fn_decl_with_params(cx, bare_fn.decl, None, params); (generic_params, decl) }); BareFunctionDecl { safety: bare_fn.safety, abi: bare_fn.abi, decl, generic_params } @@ -2629,7 +2606,6 @@ fn clean_unsafe_binder_ty<'tcx>( unsafe_binder_ty: &hir::UnsafeBinderTy<'tcx>, cx: &mut DocContext<'tcx>, ) -> UnsafeBinderTy { - // NOTE: generics must be cleaned before args let generic_params = unsafe_binder_ty .generic_params .iter() @@ -2797,10 +2773,35 @@ fn clean_maybe_renamed_item<'tcx>( ) -> Vec<Item> { use hir::ItemKind; - let def_id = item.owner_id.to_def_id(); - let mut name = if renamed.is_some() { renamed } else { cx.tcx.hir_opt_name(item.hir_id()) }; + fn get_name( + cx: &DocContext<'_>, + item: &hir::Item<'_>, + renamed: Option<Symbol>, + ) -> Option<Symbol> { + renamed.or_else(|| cx.tcx.hir_opt_name(item.hir_id())) + } + let def_id = item.owner_id.to_def_id(); cx.with_param_env(def_id, |cx| { + // These kinds of item either don't need a `name` or accept a `None` one so we handle them + // before. + match item.kind { + ItemKind::Impl(impl_) => return clean_impl(impl_, item.owner_id.def_id, cx), + ItemKind::Use(path, kind) => { + return clean_use_statement( + item, + get_name(cx, item, renamed), + path, + kind, + cx, + &mut FxHashSet::default(), + ); + } + _ => {} + } + + let mut name = get_name(cx, item, renamed).unwrap(); + let kind = match item.kind { ItemKind::Static(_, ty, mutability, body_id) => StaticItem(Static { type_: Box::new(clean_ty(ty, cx)), @@ -2839,7 +2840,7 @@ fn clean_maybe_renamed_item<'tcx>( item_type: Some(type_), })), item.owner_id.def_id.to_def_id(), - name.unwrap(), + name, import_id, renamed, )); @@ -2862,17 +2863,14 @@ fn clean_maybe_renamed_item<'tcx>( generics: clean_generics(generics, cx), fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(), }), - ItemKind::Impl(impl_) => return clean_impl(impl_, item.owner_id.def_id, cx), ItemKind::Macro(_, macro_def, MacroKind::Bang) => MacroItem(Macro { - source: display_macro_source(cx, name.unwrap(), macro_def), + source: display_macro_source(cx, name, macro_def), macro_rules: macro_def.macro_rules, }), - ItemKind::Macro(_, _, macro_kind) => { - clean_proc_macro(item, name.as_mut().unwrap(), macro_kind, cx) - } + ItemKind::Macro(_, _, macro_kind) => clean_proc_macro(item, &mut name, macro_kind, cx), // proc macros can have a name set by attributes ItemKind::Fn { ref sig, generics, body: body_id, .. } => { - clean_fn_or_proc_macro(item, sig, generics, body_id, name.as_mut().unwrap(), cx) + clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx) } ItemKind::Trait(_, _, _, generics, bounds, item_ids) => { let items = item_ids @@ -2888,10 +2886,7 @@ fn clean_maybe_renamed_item<'tcx>( })) } ItemKind::ExternCrate(orig_name, _) => { - return clean_extern_crate(item, name.unwrap(), orig_name, cx); - } - ItemKind::Use(path, kind) => { - return clean_use_statement(item, name, path, kind, cx, &mut FxHashSet::default()); + return clean_extern_crate(item, name, orig_name, cx); } _ => span_bug!(item.span, "not yet converted"), }; @@ -2900,7 +2895,7 @@ fn clean_maybe_renamed_item<'tcx>( cx, kind, item.owner_id.def_id.to_def_id(), - name.unwrap(), + name, import_id, renamed, )] @@ -3155,7 +3150,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>( cx.with_param_env(def_id, |cx| { let kind = match item.kind { hir::ForeignItemKind::Fn(sig, idents, generics) => ForeignFunctionItem( - clean_function(cx, &sig, generics, FunctionArgs::Idents(idents)), + clean_function(cx, &sig, generics, ParamsSrc::Idents(idents)), sig.header.safety(), ), hir::ForeignItemKind::Static(ty, mutability, safety) => ForeignStaticItem( diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs index 31f9c284d7d..fc99dd08b78 100644 --- a/src/librustdoc/clean/render_macro_matchers.rs +++ b/src/librustdoc/clean/render_macro_matchers.rs @@ -96,7 +96,7 @@ fn print_tt(printer: &mut Printer<'_>, tt: &TokenTree) { } } TokenTree::Delimited(_span, _spacing, delim, tts) => { - let open_delim = printer.token_kind_to_string(&token::OpenDelim(*delim)); + let open_delim = printer.token_kind_to_string(&delim.as_open_token_kind()); printer.word(open_delim); if !tts.is_empty() { if *delim == Delimiter::Brace { @@ -107,7 +107,7 @@ fn print_tt(printer: &mut Printer<'_>, tt: &TokenTree) { printer.space(); } } - let close_delim = printer.token_kind_to_string(&token::CloseDelim(*delim)); + let close_delim = printer.token_kind_to_string(&delim.as_close_token_kind()); printer.word(close_delim); } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index f58cdfc6b5e..bbe11bf56af 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -788,7 +788,7 @@ impl Item { } _ => Some(rustc_hir_pretty::attribute_to_string(&tcx, attr)), } - } else if ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) { + } else if attr.has_any_name(ALLOWED_ATTRIBUTES) { Some( rustc_hir_pretty::attribute_to_string(&tcx, attr) .replace("\\\n", "") @@ -1407,32 +1407,28 @@ pub(crate) struct Function { #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub(crate) struct FnDecl { - pub(crate) inputs: Arguments, + pub(crate) inputs: Vec<Parameter>, pub(crate) output: Type, pub(crate) c_variadic: bool, } impl FnDecl { pub(crate) fn receiver_type(&self) -> Option<&Type> { - self.inputs.values.first().and_then(|v| v.to_receiver()) + self.inputs.first().and_then(|v| v.to_receiver()) } } +/// A function parameter. #[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub(crate) struct Arguments { - pub(crate) values: Vec<Argument>, -} - -#[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub(crate) struct Argument { - pub(crate) type_: Type, +pub(crate) struct Parameter { pub(crate) name: Option<Symbol>, + pub(crate) type_: Type, /// This field is used to represent "const" arguments from the `rustc_legacy_const_generics` /// feature. More information in <https://github.com/rust-lang/rust/issues/83167>. pub(crate) is_const: bool, } -impl Argument { +impl Parameter { pub(crate) fn to_receiver(&self) -> Option<&Type> { if self.name == Some(kw::SelfLower) { Some(&self.type_) } else { None } } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 8ee08edec19..af7986d030e 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -303,13 +303,12 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { debug!("trying to get a name from pattern: {p:?}"); Symbol::intern(&match &p.kind { - // FIXME(never_patterns): does this make sense? - PatKind::Missing => unreachable!(), - PatKind::Wild - | PatKind::Err(_) + PatKind::Err(_) + | PatKind::Missing // Let's not perpetuate anon params from Rust 2015; use `_` for them. | PatKind::Never + | PatKind::Range(..) | PatKind::Struct(..) - | PatKind::Range(..) => { + | PatKind::Wild => { return kw::Underscore; } PatKind::Binding(_, _, ident, _) => return ident.name, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 41688b41c6e..9d1c9ff00b1 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -412,9 +412,7 @@ pub(crate) fn run_global_ctxt( // Process all of the crate attributes, extracting plugin metadata along // with the passes which we are supposed to run. for attr in krate.module.attrs.lists(sym::doc) { - let name = attr.name_or_empty(); - - if attr.is_word() && name == sym::document_private_items { + if attr.is_word() && attr.has_name(sym::document_private_items) { ctxt.render_options.document_private = true; } } diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index 4edd5433de6..d5c965f7053 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -345,7 +345,7 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn fn check_item(item: &ast::Item, info: &mut ParseSourceInfo, crate_name: &Option<&str>) -> bool { let mut is_extern_crate = false; if !info.has_global_allocator - && item.attrs.iter().any(|attr| attr.name_or_empty() == sym::global_allocator) + && item.attrs.iter().any(|attr| attr.has_name(sym::global_allocator)) { info.has_global_allocator = true; } @@ -377,7 +377,7 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn } let mut prev_span_hi = 0; - let not_crate_attrs = [sym::forbid, sym::allow, sym::warn, sym::deny, sym::expect]; + let not_crate_attrs = &[sym::forbid, sym::allow, sym::warn, sym::deny, sym::expect]; let parsed = parser.parse_item(rustc_parse::parser::ForceCollect::No); let result = match parsed { @@ -386,17 +386,13 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn && let Some(ref body) = fn_item.body => { for attr in &item.attrs { - let attr_name = attr.name_or_empty(); - - if attr.style == AttrStyle::Outer || not_crate_attrs.contains(&attr_name) { + if attr.style == AttrStyle::Outer || attr.has_any_name(not_crate_attrs) { // There is one exception to these attributes: // `#![allow(internal_features)]`. If this attribute is used, we need to // consider it only as a crate-level attribute. - if attr_name == sym::allow + if attr.has_name(sym::allow) && let Some(list) = attr.meta_item_list() - && list.iter().any(|sub_attr| { - sub_attr.name_or_empty().as_str() == "internal_features" - }) + && list.iter().any(|sub_attr| sub_attr.has_name(sym::internal_features)) { push_to_s(&mut info.crate_attrs, source, attr.span, &mut prev_span_hi); } else { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 9ac328f7495..299fd6b9adb 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1186,8 +1186,8 @@ impl clean::Impl { { primitive_link(f, PrimitiveType::Array, format_args!("[{name}; N]"), cx)?; } else if let clean::BareFunction(bare_fn) = &type_ - && let [clean::Argument { type_: clean::Type::Generic(name), .. }] = - &bare_fn.decl.inputs.values[..] + && let [clean::Parameter { type_: clean::Type::Generic(name), .. }] = + &bare_fn.decl.inputs[..] && (self.kind.is_fake_variadic() || self.kind.is_auto()) { // Hardcoded anchor library/core/src/primitive_docs.rs @@ -1234,22 +1234,20 @@ impl clean::Impl { } } -impl clean::Arguments { - pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { - fmt::from_fn(move |f| { - self.values - .iter() - .map(|input| { - fmt::from_fn(|f| { - if let Some(name) = input.name { - write!(f, "{}: ", name)?; - } - input.type_.print(cx).fmt(f) - }) +pub(crate) fn print_params(params: &[clean::Parameter], cx: &Context<'_>) -> impl Display { + fmt::from_fn(move |f| { + params + .iter() + .map(|param| { + fmt::from_fn(|f| { + if let Some(name) = param.name { + write!(f, "{}: ", name)?; + } + param.type_.print(cx).fmt(f) }) - .joined(", ", f) - }) - } + }) + .joined(", ", f) + }) } // Implements Write but only counts the bytes "written". @@ -1281,16 +1279,16 @@ impl clean::FnDecl { if f.alternate() { write!( f, - "({args:#}{ellipsis}){arrow:#}", - args = self.inputs.print(cx), + "({params:#}{ellipsis}){arrow:#}", + params = print_params(&self.inputs, cx), ellipsis = ellipsis, arrow = self.print_output(cx) ) } else { write!( f, - "({args}{ellipsis}){arrow}", - args = self.inputs.print(cx), + "({params}{ellipsis}){arrow}", + params = print_params(&self.inputs, cx), ellipsis = ellipsis, arrow = self.print_output(cx) ) @@ -1336,14 +1334,14 @@ impl clean::FnDecl { write!(f, "(")?; if let Some(n) = line_wrapping_indent - && !self.inputs.values.is_empty() + && !self.inputs.is_empty() { write!(f, "\n{}", Indent(n + 4))?; } - let last_input_index = self.inputs.values.len().checked_sub(1); - for (i, input) in self.inputs.values.iter().enumerate() { - if let Some(selfty) = input.to_receiver() { + let last_input_index = self.inputs.len().checked_sub(1); + for (i, param) in self.inputs.iter().enumerate() { + if let Some(selfty) = param.to_receiver() { match selfty { clean::SelfTy => { write!(f, "self")?; @@ -1361,13 +1359,13 @@ impl clean::FnDecl { } } } else { - if input.is_const { + if param.is_const { write!(f, "const ")?; } - if let Some(name) = input.name { + if let Some(name) = param.name { write!(f, "{}: ", name)?; } - input.type_.print(cx).fmt(f)?; + param.type_.print(cx).fmt(f)?; } match (line_wrapping_indent, last_input_index) { (_, None) => (), diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 596ac665fc3..f22935df96c 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -521,23 +521,23 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { // Crawl the crate attributes looking for attributes which control how we're // going to emit HTML for attr in krate.module.attrs.lists(sym::doc) { - match (attr.name_or_empty(), attr.value_str()) { - (sym::html_favicon_url, Some(s)) => { + match (attr.name(), attr.value_str()) { + (Some(sym::html_favicon_url), Some(s)) => { layout.favicon = s.to_string(); } - (sym::html_logo_url, Some(s)) => { + (Some(sym::html_logo_url), Some(s)) => { layout.logo = s.to_string(); } - (sym::html_playground_url, Some(s)) => { + (Some(sym::html_playground_url), Some(s)) => { playground = Some(markdown::Playground { crate_name: Some(krate.name(tcx)), url: s.to_string(), }); } - (sym::issue_tracker_base_url, Some(s)) => { + (Some(sym::issue_tracker_base_url), Some(s)) => { issue_tracker_base_url = Some(s.to_string()); } - (sym::html_no_source, None) if attr.is_word() => { + (Some(sym::html_no_source), None) if attr.is_word() => { include_sources = false; } _ => {} diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 1360ab94cb1..aff8684ee3a 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -1112,7 +1112,7 @@ fn simplify_fn_type<'a, 'tcx>( } Type::BareFunction(ref bf) => { let mut ty_generics = Vec::new(); - for ty in bf.decl.inputs.values.iter().map(|arg| &arg.type_) { + for ty in bf.decl.inputs.iter().map(|arg| &arg.type_) { simplify_fn_type( self_, generics, @@ -1418,15 +1418,15 @@ fn get_fn_inputs_and_outputs( (None, &func.generics) }; - let mut arg_types = Vec::new(); - for arg in decl.inputs.values.iter() { + let mut param_types = Vec::new(); + for param in decl.inputs.iter() { simplify_fn_type( self_, generics, - &arg.type_, + ¶m.type_, tcx, 0, - &mut arg_types, + &mut param_types, &mut rgen, false, cache, @@ -1439,7 +1439,7 @@ fn get_fn_inputs_and_outputs( let mut simplified_params = rgen.into_iter().collect::<Vec<_>>(); simplified_params.sort_by_key(|(_, (idx, _))| -idx); ( - arg_types, + param_types, ret_types, simplified_params .iter() diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 74d23b3143f..a6dd06b76ea 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -585,7 +585,7 @@ img { margin-left: -140px; border-left: none; } -.sidebar-resizer.active:before { +.sidebar-resizer.active::before { border-left: solid 2px var(--sidebar-resizer-active); display: block; height: 100%; @@ -2044,7 +2044,7 @@ button#toggle-all-docs:hover, button#toggle-all-docs:focus-visible { text-decoration: none; } -#settings-menu > a:before { +#settings-menu > a::before { /* Wheel <https://www.svgrepo.com/svg/384069/settings-cog-gear> */ content: url('data:image/svg+xml,<svg width="18" height="18" viewBox="0 0 12 12" \ enable-background="new 0 0 12 12" xmlns="http://www.w3.org/2000/svg">\ @@ -2064,7 +2064,7 @@ button#toggle-all-docs:hover, button#toggle-all-docs:focus-visible { filter: var(--settings-menu-filter); } -button#toggle-all-docs:before { +button#toggle-all-docs::before { /* Custom arrow icon */ content: url('data:image/svg+xml,<svg width="18" height="18" viewBox="0 0 12 12" \ enable-background="new 0 0 12 12" xmlns="http://www.w3.org/2000/svg">\ @@ -2074,14 +2074,14 @@ button#toggle-all-docs:before { filter: var(--settings-menu-filter); } -button#toggle-all-docs.will-expand:before { +button#toggle-all-docs.will-expand::before { /* Custom arrow icon */ content: url('data:image/svg+xml,<svg width="18" height="18" viewBox="0 0 12 12" \ enable-background="new 0 0 12 12" xmlns="http://www.w3.org/2000/svg">\ <path d="M2,5l4,-4l4,4M2,7l4,4l4,-4" stroke="black" fill="none" stroke-width="2px"/></svg>'); } -#help-button > a:before { +#help-button > a::before { /* Question mark with circle */ content: url('data:image/svg+xml,<svg width="18" height="18" viewBox="0 0 12 12" \ enable-background="new 0 0 12 12" xmlns="http://www.w3.org/2000/svg" fill="none">\ @@ -2093,17 +2093,17 @@ button#toggle-all-docs.will-expand:before { filter: var(--settings-menu-filter); } -button#toggle-all-docs:before, -#help-button > a:before, -#settings-menu > a:before { +button#toggle-all-docs::before, +#help-button > a::before, +#settings-menu > a::before { filter: var(--settings-menu-filter); margin: 8px; } @media not (pointer: coarse) { - button#toggle-all-docs:hover:before, - #help-button > a:hover:before, - #settings-menu > a:hover:before { + button#toggle-all-docs:hover::before, + #help-button > a:hover::before, + #settings-menu > a:hover::before { filter: var(--settings-menu-hover-filter); } } @@ -2125,7 +2125,7 @@ rustdoc-toolbar span.label { padding-bottom: 4px; } -#sidebar-button > a:before { +#sidebar-button > a::before { /* sidebar resizer image */ content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" \ fill="none" stroke="black">\ @@ -2400,21 +2400,21 @@ However, it's not needed with smaller screen width because the doc/code block is /* sidebar button opens modal use hamburger button */ -.src #sidebar-button > a:before, .sidebar-menu-toggle:before { +.src #sidebar-button > a::before, .sidebar-menu-toggle::before { /* hamburger button image */ content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" \ viewBox="0 0 22 22" fill="none" stroke="black">\ <path d="M3,5h16M3,11h16M3,17h16" stroke-width="2.75"/></svg>'); opacity: 0.75; } -.sidebar-menu-toggle:hover:before, -.sidebar-menu-toggle:active:before, -.sidebar-menu-toggle:focus:before { +.sidebar-menu-toggle:hover::before, +.sidebar-menu-toggle:active::before, +.sidebar-menu-toggle:focus::before { opacity: 1; } /* src sidebar button opens a folder view */ -.src #sidebar-button > a:before { +.src #sidebar-button > a::before { /* folder image */ content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" \ viewBox="0 0 22 22" fill="none" stroke="black">\ @@ -2599,7 +2599,7 @@ in src-script.js and main.js } /* sidebar button becomes topbar button */ - #sidebar-button > a:before { + #sidebar-button > a::before { content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" \ viewBox="0 0 22 22" fill="none" stroke="black">\ <rect x="1" y="1" width="20" height="20" ry="1.5" stroke-width="1.5" stroke="%23777"/>\ @@ -2608,7 +2608,7 @@ in src-script.js and main.js width: 22px; height: 22px; } - .sidebar-menu-toggle:before { + .sidebar-menu-toggle::before { filter: var(--mobile-sidebar-menu-filter); } .sidebar-menu-toggle:hover { @@ -3287,7 +3287,7 @@ Original by Dempfi (https://github.com/dempfi/ayu) } :root[data-theme="ayu"] #settings-menu > a img, -:root[data-theme="ayu"] #sidebar-button > a:before { +:root[data-theme="ayu"] #sidebar-button > a::before { filter: invert(100); } /* End theme: ayu */ diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 5d85a4676b7..f446c9fbbd8 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -84,8 +84,8 @@ impl JsonRenderer<'_> { let lo = span.lo(self.sess()); Some(Span { filename: local_path, - begin: (lo.line, lo.col.to_usize()), - end: (hi.line, hi.col.to_usize()), + begin: (lo.line, lo.col.to_usize() + 1), + end: (hi.line, hi.col.to_usize() + 1), }) } else { None @@ -609,11 +609,12 @@ impl FromClean<clean::FnDecl> for FunctionSignature { let clean::FnDecl { inputs, output, c_variadic } = decl; FunctionSignature { inputs: inputs - .values .into_iter() - // `_` is the most sensible name for missing param names. - .map(|arg| { - (arg.name.unwrap_or(kw::Underscore).to_string(), arg.type_.into_json(renderer)) + .map(|param| { + // `_` is the most sensible name for missing param names. + let name = param.name.unwrap_or(kw::Underscore).to_string(); + let type_ = param.type_.into_json(renderer); + (name, type_) }) .collect(), output: if output.is_unit() { None } else { Some(output.into_json(renderer)) }, diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index ba27eed7c11..131a12ce228 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -14,6 +14,7 @@ use std::io::{BufWriter, Write, stdout}; use std::path::PathBuf; use std::rc::Rc; +use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; @@ -123,6 +124,58 @@ impl<'tcx> JsonRenderer<'tcx> { } } +fn target(sess: &rustc_session::Session) -> types::Target { + // Build a set of which features are enabled on this target + let globally_enabled_features: FxHashSet<&str> = + sess.unstable_target_features.iter().map(|name| name.as_str()).collect(); + + // Build a map of target feature stability by feature name + use rustc_target::target_features::Stability; + let feature_stability: FxHashMap<&str, Stability> = sess + .target + .rust_target_features() + .into_iter() + .copied() + .map(|(name, stability, _)| (name, stability)) + .collect(); + + types::Target { + triple: sess.opts.target_triple.tuple().into(), + target_features: sess + .target + .rust_target_features() + .into_iter() + .copied() + .filter(|(_, stability, _)| { + // Describe only target features which the user can toggle + stability.toggle_allowed().is_ok() + }) + .map(|(name, stability, implied_features)| { + types::TargetFeature { + name: name.into(), + unstable_feature_gate: match stability { + Stability::Unstable(feature_gate) => Some(feature_gate.as_str().into()), + _ => None, + }, + implies_features: implied_features + .into_iter() + .copied() + .filter(|name| { + // Imply only target features which the user can toggle + feature_stability + .get(name) + .map(|stability| stability.toggle_allowed().is_ok()) + .unwrap_or(false) + }) + .map(String::from) + .collect(), + globally_enabled: globally_enabled_features.contains(name), + } + }) + .collect(), + } +} + impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { fn descr() -> &'static str { "json" @@ -248,6 +301,12 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { let e = ExternalCrate { crate_num: LOCAL_CRATE }; let index = (*self.index).clone().into_inner(); + // Note that tcx.rust_target_features is inappropriate here because rustdoc tries to run for + // multiple targets: https://github.com/rust-lang/rust/pull/137632 + // + // We want to describe a single target, so pass tcx.sess rather than tcx. + let target = target(self.tcx.sess); + debug!("Constructing Output"); let output_crate = types::Crate { root: self.id_from_item_default(e.def_id().into()), @@ -288,6 +347,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { ) }) .collect(), + target, format_version: types::FORMAT_VERSION, }; if let Some(ref out_dir) = self.out_dir { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 297597b3dea..36f5889dcf4 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -59,7 +59,12 @@ fn filter_assoc_items_by_name_and_namespace( ident: Ident, ns: Namespace, ) -> impl Iterator<Item = &ty::AssocItem> { - tcx.associated_items(assoc_items_of).filter_by_name_unhygienic(ident.name).filter(move |item| { + let iter: Box<dyn Iterator<Item = &ty::AssocItem>> = if !ident.name.is_empty() { + Box::new(tcx.associated_items(assoc_items_of).filter_by_name_unhygienic(ident.name)) + } else { + Box::new([].iter()) + }; + iter.filter(move |item| { item.namespace() == ns && tcx.hygienic_eq(ident, item.ident(tcx), assoc_items_of) }) } diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 137fe4c4c35..64223b5b758 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -30,7 +30,7 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc /// This integer is incremented with every breaking change to the API, /// and is returned along with the JSON blob as [`Crate::format_version`]. /// Consuming code should assert that this value matches the format version(s) that it supports. -pub const FORMAT_VERSION: u32 = 43; +pub const FORMAT_VERSION: u32 = 45; /// The root of the emitted JSON blob. /// @@ -52,11 +52,67 @@ pub struct Crate { pub paths: HashMap<Id, ItemSummary>, /// Maps `crate_id` of items to a crate name and html_root_url if it exists. pub external_crates: HashMap<u32, ExternalCrate>, + /// Information about the target for which this documentation was generated + pub target: Target, /// A single version number to be used in the future when making backwards incompatible changes /// to the JSON output. pub format_version: u32, } +/// Information about a target +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct Target { + /// The target triple for which this documentation was generated + pub triple: String, + /// A list of features valid for use in `#[target_feature]` attributes + /// for the target where this rustdoc JSON was generated. + pub target_features: Vec<TargetFeature>, +} + +/// Information about a target feature. +/// +/// Rust target features are used to influence code generation, especially around selecting +/// instructions which are not universally supported by the target architecture. +/// +/// Target features are commonly enabled by the [`#[target_feature]` attribute][1] to influence code +/// generation for a particular function, and less commonly enabled by compiler options like +/// `-Ctarget-feature` or `-Ctarget-cpu`. Targets themselves automatically enable certain target +/// features by default, for example because the target's ABI specification requires saving specific +/// registers which only exist in an architectural extension. +/// +/// Target features can imply other target features: for example, x86-64 `avx2` implies `avx`, and +/// aarch64 `sve2` implies `sve`, since both of these architectural extensions depend on their +/// predecessors. +/// +/// Target features can be probed at compile time by [`#[cfg(target_feature)]`][2] or `cfg!(…)` +/// conditional compilation to determine whether a target feature is enabled in a particular +/// context. +/// +/// [1]: https://doc.rust-lang.org/stable/reference/attributes/codegen.html#the-target_feature-attribute +/// [2]: https://doc.rust-lang.org/reference/conditional-compilation.html#target_feature +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct TargetFeature { + /// The name of this target feature. + pub name: String, + /// Other target features which are implied by this target feature, if any. + pub implies_features: Vec<String>, + /// If this target feature is unstable, the name of the associated language feature gate. + pub unstable_feature_gate: Option<String>, + /// Whether this feature is globally enabled for this compilation session. + /// + /// Target features can be globally enabled implicitly as a result of the target's definition. + /// For example, x86-64 hardware floating point ABIs require saving x87 and SSE2 registers, + /// which in turn requires globally enabling the `x87` and `sse2` target features so that the + /// generated machine code conforms to the target's ABI. + /// + /// Target features can also be globally enabled explicitly as a result of compiler flags like + /// [`-Ctarget-feature`][1] or [`-Ctarget-cpu`][2]. + /// + /// [1]: https://doc.rust-lang.org/beta/rustc/codegen-options/index.html#target-feature + /// [2]: https://doc.rust-lang.org/beta/rustc/codegen-options/index.html#target-cpu + pub globally_enabled: bool, +} + /// Metadata of a crate, either the same crate on which `rustdoc` was invoked, or its dependency. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct ExternalCrate { @@ -149,9 +205,9 @@ pub struct Item { pub struct Span { /// The path to the source file for this span relative to the path `rustdoc` was invoked with. pub filename: PathBuf, - /// Zero indexed Line and Column of the first character of the `Span` + /// One indexed Line and Column of the first character of the `Span`. pub begin: (usize, usize), - /// Zero indexed Line and Column of the last character of the `Span` + /// One indexed Line and Column of the last character of the `Span`. pub end: (usize, usize), } diff --git a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs index 8f1a1ee76c6..96d3f7196c0 100644 --- a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs +++ b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs @@ -179,7 +179,7 @@ fn find_first_mismatch(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option<(Span, Mut }; if let Some(adjustments) = cx.typeck_results().pat_adjustments().get(adjust_pat.hir_id) { if let [first, ..] = **adjustments { - if let ty::Ref(.., mutability) = *first.kind() { + if let ty::Ref(.., mutability) = *first.source.kind() { let level = if p.hir_id == pat.hir_id { Level::Top } else { diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 9f450d654d5..f715fc86e4e 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -2363,14 +2363,14 @@ pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool { cx.tcx .hir_attrs(hir::CRATE_HIR_ID) .iter() - .any(|attr| attr.name_or_empty() == sym::no_std) + .any(|attr| attr.has_name(sym::no_std)) } pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool { cx.tcx .hir_attrs(hir::CRATE_HIR_ID) .iter() - .any(|attr| attr.name_or_empty() == sym::no_core) + .any(|attr| attr.has_name(sym::no_core)) } /// Check if parent of a hir node is a trait implementation block. diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index 44c52c8c766..1449e9af19a 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -178,6 +178,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-32bit", "only-64bit", "only-aarch64", + "only-aarch64-apple-darwin", "only-aarch64-unknown-linux-gnu", "only-apple", "only-arm", @@ -191,6 +192,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-gnu", "only-i686-pc-windows-gnu", "only-i686-pc-windows-msvc", + "only-i686-unknown-linux-gnu", "only-ios", "only-linux", "only-loongarch64", @@ -222,6 +224,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-windows-msvc", "only-x86", "only-x86_64", + "only-x86_64-apple-darwin", "only-x86_64-fortanix-unknown-sgx", "only-x86_64-pc-windows-gnu", "only-x86_64-pc-windows-msvc", diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index d11f5c1a3a6..cc09463c358 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1395,14 +1395,6 @@ impl<'test> TestCx<'test> { matches!(self.config.suite.as_str(), "rustdoc-ui" | "rustdoc-js" | "rustdoc-json") } - fn get_mir_dump_dir(&self) -> Utf8PathBuf { - let mut mir_dump_dir = self.config.build_test_suite_root.clone(); - debug!("input_file: {}", self.testpaths.file); - mir_dump_dir.push(&self.testpaths.relative_dir); - mir_dump_dir.push(self.testpaths.file.file_stem().unwrap()); - mir_dump_dir - } - fn make_compile_args( &self, input_file: &Utf8Path, @@ -1511,10 +1503,7 @@ impl<'test> TestCx<'test> { } let set_mir_dump_dir = |rustc: &mut Command| { - let mir_dump_dir = self.get_mir_dump_dir(); - remove_and_create_dir_all(&mir_dump_dir).unwrap_or_else(|e| { - panic!("failed to remove and recreate output directory `{mir_dump_dir}`: {e}") - }); + let mir_dump_dir = self.output_base_dir(); let mut dir_opt = "-Zdump-mir-dir=".to_string(); dir_opt.push_str(mir_dump_dir.as_str()); debug!("dir_opt: {:?}", dir_opt); diff --git a/src/tools/compiletest/src/runtest/mir_opt.rs b/src/tools/compiletest/src/runtest/mir_opt.rs index ded6a68fe58..efdb131bf14 100644 --- a/src/tools/compiletest/src/runtest/mir_opt.rs +++ b/src/tools/compiletest/src/runtest/mir_opt.rs @@ -56,7 +56,7 @@ impl TestCx<'_> { self.diff_mir_files(from_file.into(), after.into()) } else { let mut output_file = Utf8PathBuf::new(); - output_file.push(self.get_mir_dump_dir()); + output_file.push(self.output_base_dir()); output_file.push(&from_file); debug!("comparing the contents of: {} with {:?}", output_file, expected_file); if !output_file.exists() { @@ -100,7 +100,7 @@ impl TestCx<'_> { fn diff_mir_files(&self, before: Utf8PathBuf, after: Utf8PathBuf) -> String { let to_full_path = |path: Utf8PathBuf| { - let full = self.get_mir_dump_dir().join(&path); + let full = self.output_base_dir().join(&path); if !full.exists() { panic!( "the mir dump file for {} does not exist (requested in {})", diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs index 54249fbd9ae..65ad38da98b 100644 --- a/src/tools/jsondocck/src/main.rs +++ b/src/tools/jsondocck/src/main.rs @@ -154,9 +154,10 @@ impl CommandKind { static LINE_PATTERN: LazyLock<Regex> = LazyLock::new(|| { RegexBuilder::new( r#" + ^\s* //@\s+ (?P<negated>!?) - (?P<cmd>[A-Za-z]+(?:-[A-Za-z]+)*) + (?P<cmd>[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*) (?P<args>.*)$ "#, ) diff --git a/src/tools/jsondoclint/src/validator/tests.rs b/src/tools/jsondoclint/src/validator/tests.rs index 28deb7e7cee..dd0b4ac5601 100644 --- a/src/tools/jsondoclint/src/validator/tests.rs +++ b/src/tools/jsondoclint/src/validator/tests.rs @@ -42,6 +42,7 @@ fn errors_on_missing_links() { )]), paths: FxHashMap::default(), external_crates: FxHashMap::default(), + target: rustdoc_json_types::Target { triple: "".to_string(), target_features: vec![] }, format_version: rustdoc_json_types::FORMAT_VERSION, }; @@ -112,6 +113,7 @@ fn errors_on_local_in_paths_and_not_index() { }, )]), external_crates: FxHashMap::default(), + target: rustdoc_json_types::Target { triple: "".to_string(), target_features: vec![] }, format_version: rustdoc_json_types::FORMAT_VERSION, }; @@ -216,6 +218,7 @@ fn errors_on_missing_path() { ItemSummary { crate_id: 0, path: vec!["foo".to_owned()], kind: ItemKind::Module }, )]), external_crates: FxHashMap::default(), + target: rustdoc_json_types::Target { triple: "".to_string(), target_features: vec![] }, format_version: rustdoc_json_types::FORMAT_VERSION, }; @@ -259,6 +262,7 @@ fn checks_local_crate_id_is_correct() { )]), paths: FxHashMap::default(), external_crates: FxHashMap::default(), + target: rustdoc_json_types::Target { triple: "".to_string(), target_features: vec![] }, format_version: FORMAT_VERSION, }; check(&krate, &[]); diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index b4098ca0750..1af3d1abc64 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -1382,6 +1382,11 @@ pub(crate) fn bool_to_simd_element(b: bool, size: Size) -> Scalar { } pub(crate) fn simd_element_to_bool(elem: ImmTy<'_>) -> InterpResult<'_, bool> { + assert!( + matches!(elem.layout.ty.kind(), ty::Int(_) | ty::Uint(_)), + "SIMD mask element type must be an integer, but this is `{}`", + elem.layout.ty + ); let val = elem.to_scalar().to_int(elem.layout.size)?; interp_ok(match val { 0 => false, diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 5921ba86639..b6b2684dc6d 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -169,7 +169,7 @@ pub const MIRI_DEFAULT_ARGS: &[&str] = &[ "-Zalways-encode-mir", "-Zextra-const-ub-checks", "-Zmir-emit-retag", - "-Zmir-keep-place-mention", + "-Zmir-preserve-ub", "-Zmir-opt-level=0", "-Zmir-enable-passes=-CheckAlignment,-CheckNull", // Deduplicating diagnostics means we miss events when tracking what happens during an diff --git a/src/tools/miri/tests/fail/panic/tls_macro_const_drop_panic.stderr b/src/tools/miri/tests/fail/panic/tls_macro_const_drop_panic.stderr index aadb9976609..1dcdb4a3996 100644 --- a/src/tools/miri/tests/fail/panic/tls_macro_const_drop_panic.stderr +++ b/src/tools/miri/tests/fail/panic/tls_macro_const_drop_panic.stderr @@ -1,7 +1,7 @@ thread $NAME panicked at tests/fail/panic/tls_macro_const_drop_panic.rs:LL:CC: ow -fatal runtime error: thread local panicked on drop +fatal runtime error: thread local panicked on drop, aborting error: abnormal termination: the program aborted execution error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr index 546ee7e1ed2..7e4907abd93 100644 --- a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr +++ b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr @@ -1,7 +1,7 @@ thread $NAME panicked at tests/fail/panic/tls_macro_drop_panic.rs:LL:CC: ow -fatal runtime error: thread local panicked on drop +fatal runtime error: thread local panicked on drop, aborting error: abnormal termination: the program aborted execution error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/read_from_trivial_switch.rs b/src/tools/miri/tests/fail/read_from_trivial_switch.rs new file mode 100644 index 00000000000..d34b1cd5820 --- /dev/null +++ b/src/tools/miri/tests/fail/read_from_trivial_switch.rs @@ -0,0 +1,14 @@ +// Ensure that we don't optimize out `SwitchInt` reads even if that terminator +// branches to the same basic block on every target, since the operand may have +// side-effects that affect analysis of the MIR. +// +// See <https://github.com/rust-lang/miri/issues/4237>. + +use std::mem::MaybeUninit; + +fn main() { + let uninit: MaybeUninit<i32> = MaybeUninit::uninit(); + let bad_ref: &i32 = unsafe { uninit.assume_init_ref() }; + let &(0 | _) = bad_ref; + //~^ ERROR: Undefined Behavior: using uninitialized data, but this operation requires initialized memory +} diff --git a/src/tools/miri/tests/fail/read_from_trivial_switch.stderr b/src/tools/miri/tests/fail/read_from_trivial_switch.stderr new file mode 100644 index 00000000000..6b3d4539b96 --- /dev/null +++ b/src/tools/miri/tests/fail/read_from_trivial_switch.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory + --> tests/fail/read_from_trivial_switch.rs:LL:CC + | +LL | let &(0 | _) = bad_ref; + | ^^^^^^^^ using uninitialized data, but this operation requires initialized memory + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at tests/fail/read_from_trivial_switch.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/pass/issues/issue-139553.rs b/src/tools/miri/tests/pass/issues/issue-139553.rs new file mode 100644 index 00000000000..119d589d1ea --- /dev/null +++ b/src/tools/miri/tests/pass/issues/issue-139553.rs @@ -0,0 +1,45 @@ +//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-compare-exchange-weak-failure-rate=0 +use std::sync::mpsc::channel; +use std::thread; + +/// This test aims to trigger a race condition that causes a double free in the unbounded channel +/// implementation. The test relies on a particular thread scheduling to happen as annotated by the +/// comments below. +fn main() { + let (s1, r) = channel::<u64>(); + let s2 = s1.clone(); + + let t1 = thread::spawn(move || { + // 1. The first action executed is an attempt to send the first value in the channel. This + // will begin to initialize the channel but will stop at a critical momement as + // indicated by the `yield_now()` call in the `start_send` method of the implementation. + let _ = s1.send(42); + // 4. The sender is re-scheduled and it finishes the initialization of the channel by + // setting head.block to the same value as tail.block. It then proceeds to publish its + // value but observes that the channel has already disconnected (due to the concurrent + // call of `discard_all_messages`) and aborts the send. + }); + std::thread::yield_now(); + + // 2. A second sender attempts to send a value while the channel is in a half-initialized + // state. Here, half-initialized means that the `tail.block` pointer points to a valid block + // but `head.block` is still null. This condition is ensured by the yield of step 1. When + // this call returns the channel state has tail.index != head.index, tail.block != NULL, and + // head.block = NULL. + s2.send(42).unwrap(); + // 3. This thread continues with dropping the one and only receiver. When all receivers are + // gone `discard_all_messages` will attempt to drop all currently sent values and + // de-allocate all the blocks. If `tail.block != NULL` but `head.block = NULL` the + // implementation waits for the initializing sender to finish by spinning/yielding. + drop(r); + // 5. This thread is rescheduled and `discard_all_messages` observes the head.block pointer set + // by step 4 and proceeds with deallocation. In the problematic version of the code + // `head.block` is simply read via an `Acquire` load and not swapped with NULL. After this + // call returns the channel state has tail.index = head.index, tail.block = NULL, and + // head.block != NULL. + t1.join().unwrap(); + // 6. The last sender (s2) is dropped here which also attempts to cleanup any data in the + // channel. It observes `tail.index = head.index` and so it doesn't attempt to cleanup any + // messages but it also observes that `head.block != NULL` and attempts to deallocate it. + // This is however already deallocated by `discard_all_messages`, leading to a double free. +} diff --git a/src/tools/nix-dev-shell/flake.nix b/src/tools/nix-dev-shell/flake.nix index 1b838bd2f7b..b8287de5fcf 100644 --- a/src/tools/nix-dev-shell/flake.nix +++ b/src/tools/nix-dev-shell/flake.nix @@ -1,32 +1,24 @@ { description = "rustc dev shell"; - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - flake-utils.url = "github:numtide/flake-utils"; - }; + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - outputs = { self, nixpkgs, flake-utils, ... }: - flake-utils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { inherit system; }; - x = import ./x { inherit pkgs; }; - in - { - devShells.default = with pkgs; mkShell { - name = "rustc-dev-shell"; - nativeBuildInputs = with pkgs; [ - binutils cmake ninja pkg-config python3 git curl cacert patchelf nix - ]; - buildInputs = with pkgs; [ - openssl glibc.out glibc.static x - ]; - # Avoid creating text files for ICEs. - RUSTC_ICE = "0"; - # Provide `libstdc++.so.6` for the self-contained lld. - # Provide `libz.so.1`. - LD_LIBRARY_PATH = "${with pkgs; lib.makeLibraryPath [stdenv.cc.cc.lib zlib]}"; - }; - } - ); + outputs = + { + self, + nixpkgs, + }: + let + inherit (nixpkgs) lib; + forEachSystem = lib.genAttrs lib.systems.flakeExposed; + in + { + devShells = forEachSystem (system: { + default = nixpkgs.legacyPackages.${system}.callPackage ./shell.nix { }; + }); + + packages = forEachSystem (system: { + default = nixpkgs.legacyPackages.${system}.callPackage ./x { }; + }); + }; } diff --git a/src/tools/nix-dev-shell/shell.nix b/src/tools/nix-dev-shell/shell.nix index a3f5969bd81..0adbacf7e8d 100644 --- a/src/tools/nix-dev-shell/shell.nix +++ b/src/tools/nix-dev-shell/shell.nix @@ -1,18 +1,26 @@ -{ pkgs ? import <nixpkgs> {} }: -let - x = import ./x { inherit pkgs; }; +{ + pkgs ? import <nixpkgs> { }, +}: +let + inherit (pkgs.lib) lists attrsets; + + x = pkgs.callPackage ./x { }; + inherit (x.passthru) cacert env; in pkgs.mkShell { - name = "rustc"; - nativeBuildInputs = with pkgs; [ - binutils cmake ninja pkg-config python3 git curl cacert patchelf nix - ]; - buildInputs = with pkgs; [ - openssl glibc.out glibc.static x - ]; - # Avoid creating text files for ICEs. - RUSTC_ICE = "0"; - # Provide `libstdc++.so.6` for the self-contained lld. - # Provide `libz.so.1` - LD_LIBRARY_PATH = "${with pkgs; lib.makeLibraryPath [stdenv.cc.cc.lib zlib]}"; + name = "rustc-shell"; + + inputsFrom = [ x ]; + packages = [ + pkgs.git + pkgs.nix + x + # Get the runtime deps of the x wrapper + ] ++ lists.flatten (attrsets.attrValues env); + + env = { + # Avoid creating text files for ICEs. + RUSTC_ICE = 0; + SSL_CERT_FILE = cacert; + }; } diff --git a/src/tools/nix-dev-shell/x/default.nix b/src/tools/nix-dev-shell/x/default.nix index e6dfbad6f19..422c1c4a2ae 100644 --- a/src/tools/nix-dev-shell/x/default.nix +++ b/src/tools/nix-dev-shell/x/default.nix @@ -1,22 +1,83 @@ { - pkgs ? import <nixpkgs> { }, + pkgs, + lib, + stdenv, + rustc, + python3, + makeBinaryWrapper, + # Bootstrap + curl, + pkg-config, + libiconv, + openssl, + patchelf, + cacert, + zlib, + # LLVM Deps + ninja, + cmake, + glibc, }: -pkgs.stdenv.mkDerivation { - name = "x"; +stdenv.mkDerivation (self: { + strictDeps = true; + name = "x-none"; + + outputs = [ + "out" + "unwrapped" + ]; src = ./x.rs; dontUnpack = true; - nativeBuildInputs = with pkgs; [ rustc ]; + nativeBuildInputs = [ + rustc + makeBinaryWrapper + ]; + env.PYTHON = python3.interpreter; buildPhase = '' - PYTHON=${pkgs.lib.getExe pkgs.python3} rustc -Copt-level=3 --crate-name x $src --out-dir $out/bin + rustc -Copt-level=3 --crate-name x $src --out-dir $unwrapped/bin ''; - meta = with pkgs.lib; { + installPhase = + let + inherit (self.passthru) cacert env; + in + '' + makeWrapper $unwrapped/bin/x $out/bin/x \ + --set-default SSL_CERT_FILE ${cacert} \ + --prefix CPATH ";" "${lib.makeSearchPath "include" env.cpath}" \ + --prefix PATH : ${lib.makeBinPath env.path} \ + --prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath env.ldLib} + ''; + + # For accessing them in the devshell + passthru = { + env = { + cpath = [ libiconv ]; + path = [ + python3 + patchelf + curl + pkg-config + cmake + ninja + stdenv.cc + ]; + ldLib = [ + openssl + zlib + stdenv.cc.cc.lib + ]; + }; + cacert = "${cacert}/etc/ssl/certs/ca-bundle.crt"; + }; + + meta = { description = "Helper for rust-lang/rust x.py"; homepage = "https://github.com/rust-lang/rust/blob/master/src/tools/x"; - license = licenses.mit; + license = lib.licenses.mit; mainProgram = "x"; }; -} +}) diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index f9beffec750..15ed03ad5c2 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -14,9 +14,5 @@ build_helper = { path = "../../build_helper" } serde_json = "1.0" libc = "0.2" -# FIXME(#137532): replace `os_pipe` with `anonymous_pipe` once it stabilizes and -# reaches beta. -os_pipe = "1.2.1" - [lib] crate-type = ["lib", "dylib"] diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index c75d500d2f0..f37b38ac0b1 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -41,8 +41,6 @@ pub use bstr; pub use gimli; pub use libc; pub use object; -// FIXME(#137532): replace with std `anonymous_pipe` once it stabilizes and reaches beta. -pub use os_pipe; pub use regex; pub use serde_json; pub use similar; diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index c14372dd6ae..fb584103df5 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -139,9 +139,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.11.3" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" dependencies = [ "memchr", "regex-automata", @@ -156,9 +156,9 @@ checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "cc" -version = "1.2.18" +version = "1.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525046617d8376e3db1deffb079e91cef90a89fc3ca5c185bbf8c9ecdd15cd5c" +checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362" dependencies = [ "shlex", ] @@ -185,9 +185,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.35" +version = "4.5.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" +checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04" dependencies = [ "clap_builder", "clap_derive", @@ -195,9 +195,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.35" +version = "4.5.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" +checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5" dependencies = [ "anstream", "anstyle", @@ -775,9 +775,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c102670231191d07d37a35af3eb77f1f0dbf7a71be51a962dcd57ea607be7260" +checksum = "1f33145a5cbea837164362c7bd596106eb7c5198f97d1ba6f6ebb3223952e488" dependencies = [ "jiff-static", "log", @@ -788,9 +788,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cdde31a9d349f1b1f51a0b3714a5940ac022976f4b49485fc04be052b183b4c" +checksum = "43ce13c40ec6956157a3635d97a1ee2df323b263f09ea14165131289cb0f5c19" dependencies = [ "proc-macro2", "quote", @@ -840,9 +840,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "litemap" @@ -2022,9 +2022,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" dependencies = [ "memchr", ] diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs index 1e16aace304..0ff0aad7a2d 100644 --- a/src/tools/rustfmt/src/macros.rs +++ b/src/tools/rustfmt/src/macros.rs @@ -722,7 +722,7 @@ fn last_tok(tt: &TokenTree) -> Token { match *tt { TokenTree::Token(ref t, _) => t.clone(), TokenTree::Delimited(delim_span, _, delim, _) => Token { - kind: TokenKind::CloseDelim(delim), + kind: delim.as_open_token_kind(), span: delim_span.close, }, } @@ -1124,8 +1124,14 @@ fn next_space(tok: &TokenKind) -> SpaceState { TokenKind::PathSep | TokenKind::Pound | TokenKind::Dollar - | TokenKind::OpenDelim(_) - | TokenKind::CloseDelim(_) => SpaceState::Never, + | TokenKind::OpenParen + | TokenKind::CloseParen + | TokenKind::OpenBrace + | TokenKind::CloseBrace + | TokenKind::OpenBracket + | TokenKind::CloseBracket + | TokenKind::OpenInvisible(_) + | TokenKind::CloseInvisible(_) => SpaceState::Never, TokenKind::Literal(..) | TokenKind::Ident(..) | TokenKind::Lifetime(..) => { SpaceState::Ident diff --git a/src/tools/rustfmt/src/parse/macros/cfg_if.rs b/src/tools/rustfmt/src/parse/macros/cfg_if.rs index 0b7b6c4d361..30b83373c17 100644 --- a/src/tools/rustfmt/src/parse/macros/cfg_if.rs +++ b/src/tools/rustfmt/src/parse/macros/cfg_if.rs @@ -1,7 +1,7 @@ use std::panic::{AssertUnwindSafe, catch_unwind}; use rustc_ast::ast; -use rustc_ast::token::{Delimiter, TokenKind}; +use rustc_ast::token::TokenKind; use rustc_parse::exp; use rustc_parse::parser::ForceCollect; use rustc_span::symbol::kw; @@ -60,9 +60,7 @@ fn parse_cfg_if_inner<'a>( return Err("Expected an opening brace"); } - while parser.token != TokenKind::CloseDelim(Delimiter::Brace) - && parser.token.kind != TokenKind::Eof - { + while parser.token != TokenKind::CloseBrace && parser.token.kind != TokenKind::Eof { let item = match parser.parse_item(ForceCollect::No) { Ok(Some(item_ptr)) => item_ptr.into_inner(), Ok(None) => continue, diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index d2ae9b1f6ef..f1ce3ccda04 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -1397,7 +1397,6 @@ ui/issues/auxiliary/issue-13620-1.rs ui/issues/auxiliary/issue-13620-2.rs ui/issues/auxiliary/issue-14344-1.rs ui/issues/auxiliary/issue-14344-2.rs -ui/issues/auxiliary/issue-14421.rs ui/issues/auxiliary/issue-14422.rs ui/issues/auxiliary/issue-15562.rs ui/issues/auxiliary/issue-16643.rs @@ -1564,7 +1563,6 @@ ui/issues/issue-14366.rs ui/issues/issue-14382.rs ui/issues/issue-14393.rs ui/issues/issue-14399.rs -ui/issues/issue-14421.rs ui/issues/issue-14422.rs ui/issues/issue-14541.rs ui/issues/issue-14721.rs @@ -1629,7 +1627,6 @@ ui/issues/issue-16774.rs ui/issues/issue-16783.rs ui/issues/issue-16819.rs ui/issues/issue-16922-rpass.rs -ui/issues/issue-16939.rs ui/issues/issue-16966.rs ui/issues/issue-16994.rs ui/issues/issue-17001.rs @@ -1867,7 +1864,6 @@ ui/issues/issue-23550.rs ui/issues/issue-23589.rs ui/issues/issue-23699.rs ui/issues/issue-2380-b.rs -ui/issues/issue-23808.rs ui/issues/issue-2383.rs ui/issues/issue-23891.rs ui/issues/issue-23898.rs @@ -2607,7 +2603,6 @@ ui/issues/issue-9249.rs ui/issues/issue-9259.rs ui/issues/issue-92741.rs ui/issues/issue-9446.rs -ui/issues/issue-9719.rs ui/issues/issue-9725.rs ui/issues/issue-9737.rs ui/issues/issue-9814.rs @@ -3138,7 +3133,6 @@ ui/nll/user-annotations/issue-55241.rs ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs ui/numbers-arithmetic/issue-8460.rs -ui/on-unimplemented/issue-104140.rs ui/or-patterns/issue-64879-trailing-before-guard.rs ui/or-patterns/issue-67514-irrefutable-param.rs ui/or-patterns/issue-68785-irrefutable-param-with-at.rs diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 61728d0553f..2e069af23d6 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -17,7 +17,7 @@ use ignore::Walk; const ENTRY_LIMIT: u32 = 901; // FIXME: The following limits should be reduced eventually. -const ISSUES_ENTRY_LIMIT: u32 = 1631; +const ISSUES_ENTRY_LIMIT: u32 = 1626; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ "rs", // test source files |
