From 6b68921ca0d25690e9d7d3b5d6f442fb1bda1fcc Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 6 Aug 2022 18:04:52 +0300 Subject: [PATCH 01/18] Change implementation of `-Z gcc-ld` and `lld-wrapper` again --- compiler/rustc_codegen_ssa/src/back/link.rs | 32 ++++++++++--------- src/bootstrap/compile.rs | 4 ++- src/bootstrap/dist.rs | 7 +++-- src/bootstrap/lib.rs | 3 ++ src/tools/lld-wrapper/src/main.rs | 35 +++++++++++---------- 5 files changed, 48 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 63207803e327f..085057c3bf3fa 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2777,20 +2777,24 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { if let LinkerFlavor::Gcc = flavor { match ld_impl { LdImpl::Lld => { - let tools_path = sess.get_tools_search_paths(false); - let gcc_ld_dir = tools_path - .into_iter() - .map(|p| p.join("gcc-ld")) - .find(|p| { - p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }).exists() - }) - .unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found")); - cmd.arg({ - let mut arg = OsString::from("-B"); - arg.push(gcc_ld_dir); - arg - }); - cmd.arg(format!("-Wl,-rustc-lld-flavor={}", sess.target.lld_flavor.as_str())); + // Implement the "self-contained" part of -Zgcc-ld + // by adding rustc distribution directories to the tool search path. + for path in sess.get_tools_search_paths(false) { + cmd.arg({ + let mut arg = OsString::from("-B"); + arg.push(path.join("gcc-ld")); + arg + }); + } + // Implement the "linker flavor" part of -Zgcc-ld + // by asking cc to use some kind of lld. + cmd.arg("-fuse-ld=lld"); + if sess.target.lld_flavor != LldFlavor::Ld { + // Tell clang to use a non-default LLD flavor. + // Gcc doesn't understand the target option, but we currently assume + // that gcc is not used for Apple and Wasm targets (#97402). + cmd.arg(format!("--target={}", sess.target.llvm_target)); + } } } } else { diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index dd2b9d59366ea..0d89e0a4f25c9 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -1276,7 +1276,9 @@ impl Step for Assemble { compiler: build_compiler, target: target_compiler.host, }); - builder.copy(&lld_wrapper_exe, &gcc_ld_dir.join(exe("ld", target_compiler.host))); + for name in crate::LLD_FILE_NAMES { + builder.copy(&lld_wrapper_exe, &gcc_ld_dir.join(exe(name, target_compiler.host))); + } } if builder.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) { diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 6291b204e485f..31f71759e249e 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -423,8 +423,11 @@ impl Step for Rustc { let gcc_lld_src_dir = src_dir.join("gcc-ld"); let gcc_lld_dst_dir = dst_dir.join("gcc-ld"); t!(fs::create_dir(&gcc_lld_dst_dir)); - let exe_name = exe("ld", compiler.host); - builder.copy(&gcc_lld_src_dir.join(&exe_name), &gcc_lld_dst_dir.join(&exe_name)); + for name in crate::LLD_FILE_NAMES { + let exe_name = exe(name, compiler.host); + builder + .copy(&gcc_lld_src_dir.join(&exe_name), &gcc_lld_dst_dir.join(&exe_name)); + } } // Man pages diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index f84de73297acb..797e846733176 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -186,6 +186,9 @@ const LLVM_TOOLS: &[&str] = &[ "opt", // used to optimize LLVM bytecode ]; +/// LLD file names for all flavors. +const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"]; + pub const VERSION: usize = 2; /// Extra --check-cfg to add when building diff --git a/src/tools/lld-wrapper/src/main.rs b/src/tools/lld-wrapper/src/main.rs index 90bd24a75e064..1795f3d7fe5bc 100644 --- a/src/tools/lld-wrapper/src/main.rs +++ b/src/tools/lld-wrapper/src/main.rs @@ -8,8 +8,8 @@ //! make gcc/clang pass `-flavor ` as the first two arguments in the linker invocation //! and since Windows does not support symbolic links for files this wrapper is used in place of a //! symbolic link. It execs `../rust-lld -flavor ` by propagating the flavor argument -//! passed to the wrapper as the first two arguments. On Windows it spawns a `..\rust-lld.exe` -//! child process. +//! obtained from the wrapper's name as the first two arguments. +//! On Windows it spawns a `..\rust-lld.exe` child process. use std::fmt::Display; use std::path::{Path, PathBuf}; @@ -53,29 +53,32 @@ fn get_rust_lld_path(current_exe_path: &Path) -> PathBuf { rust_lld_path } +/// Extract LLD flavor name from the lld-wrapper executable name. +fn get_lld_flavor(current_exe_path: &Path) -> Result<&'static str, String> { + let stem = current_exe_path.file_stem(); + Ok(match stem.and_then(|s| s.to_str()) { + Some("ld.lld") => "gnu", + Some("ld64.lld") => "darwin", + Some("lld-link") => "link", + Some("wasm-ld") => "wasm", + _ => return Err(format!("{:?}", stem)), + }) +} + /// Returns the command for invoking rust-lld with the correct flavor. -/// LLD only accepts the flavor argument at the first two arguments, so move it there. +/// LLD only accepts the flavor argument at the first two arguments, so pass it there. /// /// Exits on error. fn get_rust_lld_command(current_exe_path: &Path) -> process::Command { let rust_lld_path = get_rust_lld_path(current_exe_path); let mut command = process::Command::new(rust_lld_path); - let mut flavor = None; - let args = env::args_os() - .skip(1) - .filter(|arg| match arg.to_str().and_then(|s| s.strip_prefix("-rustc-lld-flavor=")) { - Some(suffix) => { - flavor = Some(suffix.to_string()); - false - } - None => true, - }) - .collect::>(); + let flavor = + get_lld_flavor(current_exe_path).unwrap_or_exit_with("executable has unexpected name"); command.arg("-flavor"); - command.arg(flavor.unwrap_or_exit_with("-rustc-lld-flavor= is not passed")); - command.args(args); + command.arg(flavor); + command.args(env::args_os().skip(1)); command } From d8a32ddaac4868d679e6a5d5205baf841f3fe32d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 14 Aug 2022 20:28:34 +0300 Subject: [PATCH 02/18] rustc_target: Add a compatibility layer to separate internal and user-facing linker flavors --- compiler/rustc_codegen_ssa/src/back/link.rs | 3 +- compiler/rustc_session/src/config.rs | 4 +- compiler/rustc_session/src/options.rs | 10 +- compiler/rustc_target/src/spec/mod.rs | 190 +++++++++++++----- .../rustc_target/src/spec/tests/tests_impl.rs | 6 +- 5 files changed, 152 insertions(+), 61 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 7f6947e3c79d8..a97bdb2be70dd 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1236,7 +1236,8 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { // linker and linker flavor specified via command line have precedence over what the target // specification specifies - if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), sess.opts.cg.linker_flavor) { + let linker_flavor = sess.opts.cg.linker_flavor.map(LinkerFlavor::from_cli); + if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), linker_flavor) { return ret; } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 68519c8fa828e..a21fe894b6524 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -12,7 +12,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::ToStableHashKey; use rustc_target::abi::{Align, TargetDataLayout}; -use rustc_target::spec::{LinkerFlavor, SplitDebuginfo, Target, TargetTriple, TargetWarnings}; +use rustc_target::spec::{LinkerFlavorCli, SplitDebuginfo, Target, TargetTriple, TargetWarnings}; use rustc_target::spec::{PanicStrategy, SanitizerSet, TARGETS}; use crate::parse::{CrateCheckConfig, CrateConfig}; @@ -2379,7 +2379,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { } } - if cg.linker_flavor == Some(LinkerFlavor::L4Bender) + if cg.linker_flavor == Some(LinkerFlavorCli::L4Bender) && !nightly_options::is_unstable_enabled(matches) { early_error( diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 63ae91f8e6cee..c3a9823f1d4fc 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -5,7 +5,7 @@ use crate::lint; use crate::search_paths::SearchPath; use crate::utils::NativeLib; use rustc_errors::LanguageIdentifier; -use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy, SanitizerSet}; +use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, SanitizerSet}; use rustc_target::spec::{ RelocModel, RelroLevel, SplitDebuginfo, StackProtector, TargetTriple, TlsModel, }; @@ -382,7 +382,7 @@ mod desc { "either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`"; pub const parse_cfprotection: &str = "`none`|`no`|`n` (default), `branch`, `return`, or `full`|`yes`|`y` (equivalent to `branch` and `return`)"; pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`"; - pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavor::one_of(); + pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of(); pub const parse_optimization_fuel: &str = "crate=integer"; pub const parse_mir_spanview: &str = "`statement` (default), `terminator`, or `block`"; pub const parse_instrument_coverage: &str = @@ -763,8 +763,8 @@ mod parse { true } - pub(crate) fn parse_linker_flavor(slot: &mut Option, v: Option<&str>) -> bool { - match v.and_then(LinkerFlavor::from_str) { + pub(crate) fn parse_linker_flavor(slot: &mut Option, v: Option<&str>) -> bool { + match v.and_then(LinkerFlavorCli::from_str) { Some(lf) => *slot = Some(lf), _ => return false, } @@ -1139,7 +1139,7 @@ options! { on C toolchain installed in the system"), linker: Option = (None, parse_opt_pathbuf, [UNTRACKED], "system linker to link outputs with"), - linker_flavor: Option = (None, parse_linker_flavor, [UNTRACKED], + linker_flavor: Option = (None, parse_linker_flavor, [UNTRACKED], "linker flavor"), linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled, parse_linker_plugin_lto, [TRACKED], diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 0b49edc232c06..51f9edfcabe8e 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -102,6 +102,18 @@ pub enum LinkerFlavor { BpfLinker, } +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum LinkerFlavorCli { + Em, + Gcc, + L4Bender, + Ld, + Msvc, + Lld(LldFlavor), + PtxLinker, + BpfLinker, +} + #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum LldFlavor { Wasm, @@ -137,14 +149,37 @@ impl ToJson for LldFlavor { } } -impl ToJson for LinkerFlavor { - fn to_json(&self) -> Json { - self.desc().to_json() +impl LinkerFlavor { + pub fn from_cli(cli: LinkerFlavorCli) -> LinkerFlavor { + match cli { + LinkerFlavorCli::Em => LinkerFlavor::Em, + LinkerFlavorCli::Gcc => LinkerFlavor::Gcc, + LinkerFlavorCli::L4Bender => LinkerFlavor::L4Bender, + LinkerFlavorCli::Ld => LinkerFlavor::Ld, + LinkerFlavorCli::Msvc => LinkerFlavor::Msvc, + LinkerFlavorCli::Lld(lld_flavor) => LinkerFlavor::Lld(lld_flavor), + LinkerFlavorCli::PtxLinker => LinkerFlavor::PtxLinker, + LinkerFlavorCli::BpfLinker => LinkerFlavor::BpfLinker, + } + } + + fn to_cli(self) -> LinkerFlavorCli { + match self { + LinkerFlavor::Em => LinkerFlavorCli::Em, + LinkerFlavor::Gcc => LinkerFlavorCli::Gcc, + LinkerFlavor::L4Bender => LinkerFlavorCli::L4Bender, + LinkerFlavor::Ld => LinkerFlavorCli::Ld, + LinkerFlavor::Msvc => LinkerFlavorCli::Msvc, + LinkerFlavor::Lld(lld_flavor) => LinkerFlavorCli::Lld(lld_flavor), + LinkerFlavor::PtxLinker => LinkerFlavorCli::PtxLinker, + LinkerFlavor::BpfLinker => LinkerFlavorCli::BpfLinker, + } } } + macro_rules! flavor_mappings { ($((($($flavor:tt)*), $string:expr),)*) => ( - impl LinkerFlavor { + impl LinkerFlavorCli { pub const fn one_of() -> &'static str { concat!("one of: ", $($string, " ",)*) } @@ -166,17 +201,23 @@ macro_rules! flavor_mappings { } flavor_mappings! { - ((LinkerFlavor::Em), "em"), - ((LinkerFlavor::Gcc), "gcc"), - ((LinkerFlavor::L4Bender), "l4-bender"), - ((LinkerFlavor::Ld), "ld"), - ((LinkerFlavor::Msvc), "msvc"), - ((LinkerFlavor::PtxLinker), "ptx-linker"), - ((LinkerFlavor::BpfLinker), "bpf-linker"), - ((LinkerFlavor::Lld(LldFlavor::Wasm)), "wasm-ld"), - ((LinkerFlavor::Lld(LldFlavor::Ld64)), "ld64.lld"), - ((LinkerFlavor::Lld(LldFlavor::Ld)), "ld.lld"), - ((LinkerFlavor::Lld(LldFlavor::Link)), "lld-link"), + ((LinkerFlavorCli::Em), "em"), + ((LinkerFlavorCli::Gcc), "gcc"), + ((LinkerFlavorCli::L4Bender), "l4-bender"), + ((LinkerFlavorCli::Ld), "ld"), + ((LinkerFlavorCli::Msvc), "msvc"), + ((LinkerFlavorCli::PtxLinker), "ptx-linker"), + ((LinkerFlavorCli::BpfLinker), "bpf-linker"), + ((LinkerFlavorCli::Lld(LldFlavor::Wasm)), "wasm-ld"), + ((LinkerFlavorCli::Lld(LldFlavor::Ld64)), "ld64.lld"), + ((LinkerFlavorCli::Lld(LldFlavor::Ld)), "ld.lld"), + ((LinkerFlavorCli::Lld(LldFlavor::Link)), "lld-link"), +} + +impl ToJson for LinkerFlavorCli { + fn to_json(&self) -> Json { + self.desc().to_json() + } } #[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)] @@ -467,6 +508,7 @@ impl fmt::Display for LinkOutputKind { } pub type LinkArgs = BTreeMap>>; +pub type LinkArgsCli = BTreeMap>>; #[derive(Clone, Copy, Hash, Debug, PartialEq, Eq)] pub enum SplitDebuginfo { @@ -1159,6 +1201,7 @@ pub struct TargetOptions { /// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed /// on the command line. Defaults to `LinkerFlavor::Gcc`. pub linker_flavor: LinkerFlavor, + linker_flavor_json: LinkerFlavorCli, /// Linker to invoke pub linker: Option>, @@ -1169,6 +1212,7 @@ pub struct TargetOptions { /// Linker arguments that are passed *before* any user-defined libraries. pub pre_link_args: LinkArgs, + pre_link_args_json: LinkArgsCli, /// Objects to link before and after all other object code. pub pre_link_objects: CrtObjects, pub post_link_objects: CrtObjects, @@ -1181,15 +1225,19 @@ pub struct TargetOptions { /// user-defined but before post-link objects. Standard platform /// libraries that should be always be linked to, usually go here. pub late_link_args: LinkArgs, + late_link_args_json: LinkArgsCli, /// Linker arguments used in addition to `late_link_args` if at least one /// Rust dependency is dynamically linked. pub late_link_args_dynamic: LinkArgs, + late_link_args_dynamic_json: LinkArgsCli, /// Linker arguments used in addition to `late_link_args` if all Rust /// dependencies are statically linked. pub late_link_args_static: LinkArgs, + late_link_args_static_json: LinkArgsCli, /// Linker arguments that are unconditionally passed *after* any /// user-defined libraries. pub post_link_args: LinkArgs, + post_link_args_json: LinkArgsCli, /// Optional link script applied to `dylib` and `executable` crate types. /// This is a string containing the script, not a path. Can only be applied /// to linkers where `linker_is_gnu` is true. @@ -1496,6 +1544,36 @@ impl TargetOptions { fn add_post_link_args(&mut self, flavor: LinkerFlavor, args: &[&'static str]) { add_link_args(&mut self.post_link_args, flavor, args); } + + fn update_from_cli(&mut self) { + self.linker_flavor = LinkerFlavor::from_cli(self.linker_flavor_json); + for (args, args_json) in [ + (&mut self.pre_link_args, &self.pre_link_args_json), + (&mut self.late_link_args, &self.late_link_args_json), + (&mut self.late_link_args_dynamic, &self.late_link_args_dynamic_json), + (&mut self.late_link_args_static, &self.late_link_args_static_json), + (&mut self.post_link_args, &self.post_link_args_json), + ] { + *args = args_json + .iter() + .map(|(flavor, args)| (LinkerFlavor::from_cli(*flavor), args.clone())) + .collect(); + } + } + + fn update_to_cli(&mut self) { + self.linker_flavor_json = self.linker_flavor.to_cli(); + for (args, args_json) in [ + (&self.pre_link_args, &mut self.pre_link_args_json), + (&self.late_link_args, &mut self.late_link_args_json), + (&self.late_link_args_dynamic, &mut self.late_link_args_dynamic_json), + (&self.late_link_args_static, &mut self.late_link_args_static_json), + (&self.post_link_args, &mut self.post_link_args_json), + ] { + *args_json = + args.iter().map(|(flavor, args)| (flavor.to_cli(), args.clone())).collect(); + } + } } impl Default for TargetOptions { @@ -1511,10 +1589,13 @@ impl Default for TargetOptions { abi: "".into(), vendor: "unknown".into(), linker_flavor: LinkerFlavor::Gcc, + linker_flavor_json: LinkerFlavorCli::Gcc, linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.into()), lld_flavor: LldFlavor::Ld, pre_link_args: LinkArgs::new(), + pre_link_args_json: LinkArgsCli::new(), post_link_args: LinkArgs::new(), + post_link_args_json: LinkArgsCli::new(), link_script: None, asm_args: cvs![], cpu: "generic".into(), @@ -1555,8 +1636,11 @@ impl Default for TargetOptions { post_link_objects_self_contained: Default::default(), link_self_contained: LinkSelfContainedDefault::False, late_link_args: LinkArgs::new(), + late_link_args_json: LinkArgsCli::new(), late_link_args_dynamic: LinkArgs::new(), + late_link_args_dynamic_json: LinkArgsCli::new(), late_link_args_static: LinkArgs::new(), + late_link_args_static_json: LinkArgsCli::new(), link_env: cvs![], link_env_remove: cvs![], archive_format: "gnu".into(), @@ -1926,13 +2010,13 @@ impl Target { Some(Ok(())) })).unwrap_or(Ok(())) } ); - ($key_name:ident, LinkerFlavor) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { - match LinkerFlavor::from_str(s) { + ($key_name:ident = $json_name:expr, LinkerFlavor) => ( { + let name = $json_name; + obj.remove(name).and_then(|o| o.as_str().and_then(|s| { + match LinkerFlavorCli::from_str(s) { Some(linker_flavor) => base.$key_name = linker_flavor, _ => return Some(Err(format!("'{}' is not a valid value for linker-flavor. \ - Use {}", s, LinkerFlavor::one_of()))), + Use {}", s, LinkerFlavorCli::one_of()))), } Some(Ok(())) })).unwrap_or(Ok(())) @@ -2013,14 +2097,14 @@ impl Target { base.$key_name = args; } } ); - ($key_name:ident, link_args) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - if let Some(val) = obj.remove(&name) { + ($key_name:ident = $json_name:expr, link_args) => ( { + let name = $json_name; + if let Some(val) = obj.remove(name) { let obj = val.as_object().ok_or_else(|| format!("{}: expected a \ JSON object with fields per linker-flavor.", name))?; - let mut args = LinkArgs::new(); + let mut args = LinkArgsCli::new(); for (k, v) in obj { - let flavor = LinkerFlavor::from_str(&k).ok_or_else(|| { + let flavor = LinkerFlavorCli::from_str(&k).ok_or_else(|| { format!("{}: '{}' is not a valid value for linker-flavor. \ Use 'em', 'gcc', 'ld' or 'msvc'", name, k) })?; @@ -2106,7 +2190,7 @@ impl Target { key!(env); key!(abi); key!(vendor); - key!(linker_flavor, LinkerFlavor)?; + key!(linker_flavor_json = "linker-flavor", LinkerFlavor)?; key!(linker, optional); key!(lld_flavor, LldFlavor)?; key!(pre_link_objects = "pre-link-objects", link_objects); @@ -2114,11 +2198,11 @@ impl Target { key!(pre_link_objects_self_contained = "pre-link-objects-fallback", link_objects); key!(post_link_objects_self_contained = "post-link-objects-fallback", link_objects); key!(link_self_contained = "crt-objects-fallback", link_self_contained)?; - key!(pre_link_args, link_args); - key!(late_link_args, link_args); - key!(late_link_args_dynamic, link_args); - key!(late_link_args_static, link_args); - key!(post_link_args, link_args); + key!(pre_link_args_json = "pre-link-args", link_args); + key!(late_link_args_json = "late-link-args", link_args); + key!(late_link_args_dynamic_json = "late-link-args-dynamic", link_args); + key!(late_link_args_static_json = "late-link-args-static", link_args); + key!(post_link_args_json = "post-link-args", link_args); key!(link_script, optional); key!(link_env, env); key!(link_env_remove, list); @@ -2201,6 +2285,8 @@ impl Target { // This can cause unfortunate ICEs later down the line. return Err("may not set is_builtin for targets not built-in".into()); } + base.update_from_cli(); + // Each field should have been read using `Json::remove` so any keys remaining are unused. let remaining_keys = obj.keys(); Ok(( @@ -2292,42 +2378,44 @@ impl ToJson for Target { fn to_json(&self) -> Json { let mut d = serde_json::Map::new(); let default: TargetOptions = Default::default(); + let mut target = self.clone(); + target.update_to_cli(); macro_rules! target_val { ($attr:ident) => {{ let name = (stringify!($attr)).replace("_", "-"); - d.insert(name, self.$attr.to_json()); + d.insert(name, target.$attr.to_json()); }}; } macro_rules! target_option_val { ($attr:ident) => {{ let name = (stringify!($attr)).replace("_", "-"); - if default.$attr != self.$attr { - d.insert(name, self.$attr.to_json()); + if default.$attr != target.$attr { + d.insert(name, target.$attr.to_json()); } }}; - ($attr:ident, $key_name:expr) => {{ - let name = $key_name; - if default.$attr != self.$attr { - d.insert(name.into(), self.$attr.to_json()); + ($attr:ident, $json_name:expr) => {{ + let name = $json_name; + if default.$attr != target.$attr { + d.insert(name.into(), target.$attr.to_json()); } }}; - (link_args - $attr:ident) => {{ - let name = (stringify!($attr)).replace("_", "-"); - if default.$attr != self.$attr { - let obj = self + (link_args - $attr:ident, $json_name:expr) => {{ + let name = $json_name; + if default.$attr != target.$attr { + let obj = target .$attr .iter() .map(|(k, v)| (k.desc().to_string(), v.clone())) .collect::>(); - d.insert(name, obj.to_json()); + d.insert(name.to_string(), obj.to_json()); } }}; (env - $attr:ident) => {{ let name = (stringify!($attr)).replace("_", "-"); - if default.$attr != self.$attr { - let obj = self + if default.$attr != target.$attr { + let obj = target .$attr .iter() .map(|&(ref k, ref v)| format!("{k}={v}")) @@ -2349,7 +2437,7 @@ impl ToJson for Target { target_option_val!(env); target_option_val!(abi); target_option_val!(vendor); - target_option_val!(linker_flavor); + target_option_val!(linker_flavor_json, "linker-flavor"); target_option_val!(linker); target_option_val!(lld_flavor); target_option_val!(pre_link_objects); @@ -2357,11 +2445,11 @@ impl ToJson for Target { target_option_val!(pre_link_objects_self_contained, "pre-link-objects-fallback"); target_option_val!(post_link_objects_self_contained, "post-link-objects-fallback"); target_option_val!(link_self_contained, "crt-objects-fallback"); - target_option_val!(link_args - pre_link_args); - target_option_val!(link_args - late_link_args); - target_option_val!(link_args - late_link_args_dynamic); - target_option_val!(link_args - late_link_args_static); - target_option_val!(link_args - post_link_args); + target_option_val!(link_args - pre_link_args_json, "pre-link-args"); + target_option_val!(link_args - late_link_args_json, "late-link-args"); + target_option_val!(link_args - late_link_args_dynamic_json, "late-link-args-dynamic"); + target_option_val!(link_args - late_link_args_static_json, "late-link-args-static"); + target_option_val!(link_args - post_link_args_json, "post-link-args"); target_option_val!(link_script); target_option_val!(env - link_env); target_option_val!(link_env_remove); diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs index 03e579aee0a96..5e035f189c49b 100644 --- a/compiler/rustc_target/src/spec/tests/tests_impl.rs +++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs @@ -2,9 +2,11 @@ use super::super::*; use std::assert_matches::assert_matches; // Test target self-consistency and JSON encoding/decoding roundtrip. -pub(super) fn test_target(target: Target) { +pub(super) fn test_target(mut target: Target) { + let recycled_target = Target::from_json(target.to_json()).map(|(j, _)| j); + target.update_to_cli(); target.check_consistency(); - assert_eq!(Target::from_json(target.to_json()).map(|(j, _)| j), Ok(target)); + assert_eq!(recycled_target, Ok(target)); } impl Target { From 667eb184ad7771de148f3fd17aa806bbb7b82d63 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 15 Aug 2022 00:31:31 +0300 Subject: [PATCH 03/18] rustc_target: Refactor internal linker flavors slightly Remove one unstable user-facing linker flavor (l4-bender) --- compiler/rustc_codegen_ssa/src/back/link.rs | 27 +++-- compiler/rustc_codegen_ssa/src/back/linker.rs | 21 ++-- compiler/rustc_interface/src/tests.rs | 8 +- compiler/rustc_session/src/config.rs | 14 +-- .../src/spec/asmjs_unknown_emscripten.rs | 2 +- compiler/rustc_target/src/spec/bpf_base.rs | 2 +- compiler/rustc_target/src/spec/l4re_base.rs | 2 +- compiler/rustc_target/src/spec/mod.rs | 110 ++++++++---------- .../src/spec/nvptx64_nvidia_cuda.rs | 2 +- .../rustc_target/src/spec/tests/tests_impl.rs | 22 ++-- .../src/spec/wasm32_unknown_emscripten.rs | 4 +- 11 files changed, 93 insertions(+), 121 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index a97bdb2be70dd..9528b131c1e1b 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1173,13 +1173,6 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { // only the linker flavor is known; use the default linker for the selected flavor (None, Some(flavor)) => Some(( PathBuf::from(match flavor { - LinkerFlavor::Em => { - if cfg!(windows) { - "emcc.bat" - } else { - "emcc" - } - } LinkerFlavor::Gcc => { if cfg!(any(target_os = "solaris", target_os = "illumos")) { // On historical Solaris systems, "cc" may have @@ -1194,11 +1187,17 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { } } LinkerFlavor::Ld => "ld", - LinkerFlavor::Msvc => "link.exe", LinkerFlavor::Lld(_) => "lld", - LinkerFlavor::PtxLinker => "rust-ptx-linker", - LinkerFlavor::BpfLinker => "bpf-linker", - LinkerFlavor::L4Bender => "l4-bender", + LinkerFlavor::Msvc => "link.exe", + LinkerFlavor::EmCc => { + if cfg!(windows) { + "emcc.bat" + } else { + "emcc" + } + } + LinkerFlavor::Bpf => "bpf-linker", + LinkerFlavor::Ptx => "rust-ptx-linker", }), flavor, )), @@ -1208,7 +1207,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { }); let flavor = if stem == "emcc" { - LinkerFlavor::Em + LinkerFlavor::EmCc } else if stem == "gcc" || stem.ends_with("-gcc") || stem == "clang" @@ -2114,11 +2113,11 @@ fn add_order_independent_options( }); } - if flavor == LinkerFlavor::PtxLinker { + if flavor == LinkerFlavor::Ptx { // Provide the linker with fallback to internal `target-cpu`. cmd.arg("--fallback-arch"); cmd.arg(&codegen_results.crate_info.target_cpu); - } else if flavor == LinkerFlavor::BpfLinker { + } else if flavor == LinkerFlavor::Bpf { cmd.arg("--cpu"); cmd.arg(&codegen_results.crate_info.target_cpu); cmd.arg("--cpu-features"); diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index ce51b2e9531fc..8c6f526b054bc 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -126,29 +126,26 @@ pub fn get_linker<'a>( // to the linker args construction. assert!(cmd.get_args().is_empty() || sess.target.vendor == "uwp"); match flavor { - LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => { - Box::new(MsvcLinker { cmd, sess }) as Box - } - LinkerFlavor::Em => Box::new(EmLinker { cmd, sess }) as Box, LinkerFlavor::Gcc => { Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: false }) as Box } - + LinkerFlavor::Ld if sess.target.os == "l4re" => { + Box::new(L4Bender::new(cmd, sess)) as Box + } LinkerFlavor::Lld(LldFlavor::Ld) | LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Ld => { Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: true }) as Box } - + LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => { + Box::new(MsvcLinker { cmd, sess }) as Box + } LinkerFlavor::Lld(LldFlavor::Wasm) => Box::new(WasmLd::new(cmd, sess)) as Box, - - LinkerFlavor::PtxLinker => Box::new(PtxLinker { cmd, sess }) as Box, - - LinkerFlavor::BpfLinker => Box::new(BpfLinker { cmd, sess }) as Box, - - LinkerFlavor::L4Bender => Box::new(L4Bender::new(cmd, sess)) as Box, + LinkerFlavor::EmCc => Box::new(EmLinker { cmd, sess }) as Box, + LinkerFlavor::Bpf => Box::new(BpfLinker { cmd, sess }) as Box, + LinkerFlavor::Ptx => Box::new(PtxLinker { cmd, sess }) as Box, } } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 9207a0488623c..5df5ab3ddc032 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -21,10 +21,8 @@ use rustc_session::{build_session, getopts, DiagnosticOutput, Session}; use rustc_span::edition::{Edition, DEFAULT_EDITION}; use rustc_span::symbol::sym; use rustc_span::SourceFileHashAlgorithm; -use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy}; -use rustc_target::spec::{ - RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel, -}; +use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel}; +use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel}; use std::collections::{BTreeMap, BTreeSet}; use std::iter::FromIterator; @@ -552,7 +550,7 @@ fn test_codegen_options_tracking_hash() { untracked!(link_args, vec![String::from("abc"), String::from("def")]); untracked!(link_self_contained, Some(true)); untracked!(linker, Some(PathBuf::from("linker"))); - untracked!(linker_flavor, Some(LinkerFlavor::Gcc)); + untracked!(linker_flavor, Some(LinkerFlavorCli::Gcc)); untracked!(no_stack_check, true); untracked!(remark, Passes::Some(vec![String::from("pass1"), String::from("pass2")])); untracked!(rpath, true); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index a21fe894b6524..7005409fc4020 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -12,8 +12,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::ToStableHashKey; use rustc_target::abi::{Align, TargetDataLayout}; -use rustc_target::spec::{LinkerFlavorCli, SplitDebuginfo, Target, TargetTriple, TargetWarnings}; -use rustc_target::spec::{PanicStrategy, SanitizerSet, TARGETS}; +use rustc_target::spec::{PanicStrategy, SanitizerSet, SplitDebuginfo}; +use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS}; use crate::parse::{CrateCheckConfig, CrateConfig}; use rustc_feature::UnstableFeatures; @@ -2379,16 +2379,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { } } - if cg.linker_flavor == Some(LinkerFlavorCli::L4Bender) - && !nightly_options::is_unstable_enabled(matches) - { - early_error( - error_format, - "`l4-bender` linker flavor is unstable, `-Z unstable-options` \ - flag must also be passed to explicitly use it", - ); - } - let prints = collect_print_requests(&mut cg, &mut unstable_opts, matches, error_format); let cg = cg; diff --git a/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs b/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs index b4cf2c5ee2294..f492c3451a418 100644 --- a/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs +++ b/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs @@ -2,6 +2,6 @@ use super::{wasm32_unknown_emscripten, LinkerFlavor, Target}; pub fn target() -> Target { let mut target = wasm32_unknown_emscripten::target(); - target.add_post_link_args(LinkerFlavor::Em, &["-sWASM=0", "--memory-init-file", "0"]); + target.add_post_link_args(LinkerFlavor::EmCc, &["-sWASM=0", "--memory-init-file", "0"]); target } diff --git a/compiler/rustc_target/src/spec/bpf_base.rs b/compiler/rustc_target/src/spec/bpf_base.rs index 3c4da6f883d9d..baf36587147a6 100644 --- a/compiler/rustc_target/src/spec/bpf_base.rs +++ b/compiler/rustc_target/src/spec/bpf_base.rs @@ -5,7 +5,7 @@ pub fn opts(endian: Endian) -> TargetOptions { TargetOptions { allow_asm: true, endian, - linker_flavor: LinkerFlavor::BpfLinker, + linker_flavor: LinkerFlavor::Bpf, atomic_cas: false, dynamic_linking: true, no_builtins: true, diff --git a/compiler/rustc_target/src/spec/l4re_base.rs b/compiler/rustc_target/src/spec/l4re_base.rs index a08756861e5b2..26fce7dcb2b4c 100644 --- a/compiler/rustc_target/src/spec/l4re_base.rs +++ b/compiler/rustc_target/src/spec/l4re_base.rs @@ -4,7 +4,7 @@ pub fn opts() -> TargetOptions { TargetOptions { os: "l4re".into(), env: "uclibc".into(), - linker_flavor: LinkerFlavor::L4Bender, + linker_flavor: LinkerFlavor::Ld, panic_strategy: PanicStrategy::Abort, linker: Some("l4-bender".into()), linker_is_gnu: false, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 51f9edfcabe8e..11f51d267b00d 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -92,26 +92,24 @@ mod windows_uwp_msvc_base; #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum LinkerFlavor { - Em, Gcc, - L4Bender, Ld, - Msvc, Lld(LldFlavor), - PtxLinker, - BpfLinker, + Msvc, + EmCc, + Bpf, + Ptx, } #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum LinkerFlavorCli { - Em, Gcc, - L4Bender, Ld, - Msvc, Lld(LldFlavor), - PtxLinker, + Msvc, + Em, BpfLinker, + PtxLinker, } #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] @@ -152,39 +150,37 @@ impl ToJson for LldFlavor { impl LinkerFlavor { pub fn from_cli(cli: LinkerFlavorCli) -> LinkerFlavor { match cli { - LinkerFlavorCli::Em => LinkerFlavor::Em, LinkerFlavorCli::Gcc => LinkerFlavor::Gcc, - LinkerFlavorCli::L4Bender => LinkerFlavor::L4Bender, LinkerFlavorCli::Ld => LinkerFlavor::Ld, - LinkerFlavorCli::Msvc => LinkerFlavor::Msvc, LinkerFlavorCli::Lld(lld_flavor) => LinkerFlavor::Lld(lld_flavor), - LinkerFlavorCli::PtxLinker => LinkerFlavor::PtxLinker, - LinkerFlavorCli::BpfLinker => LinkerFlavor::BpfLinker, + LinkerFlavorCli::Msvc => LinkerFlavor::Msvc, + LinkerFlavorCli::Em => LinkerFlavor::EmCc, + LinkerFlavorCli::BpfLinker => LinkerFlavor::Bpf, + LinkerFlavorCli::PtxLinker => LinkerFlavor::Ptx, } } fn to_cli(self) -> LinkerFlavorCli { match self { - LinkerFlavor::Em => LinkerFlavorCli::Em, LinkerFlavor::Gcc => LinkerFlavorCli::Gcc, - LinkerFlavor::L4Bender => LinkerFlavorCli::L4Bender, LinkerFlavor::Ld => LinkerFlavorCli::Ld, - LinkerFlavor::Msvc => LinkerFlavorCli::Msvc, LinkerFlavor::Lld(lld_flavor) => LinkerFlavorCli::Lld(lld_flavor), - LinkerFlavor::PtxLinker => LinkerFlavorCli::PtxLinker, - LinkerFlavor::BpfLinker => LinkerFlavorCli::BpfLinker, + LinkerFlavor::Msvc => LinkerFlavorCli::Msvc, + LinkerFlavor::EmCc => LinkerFlavorCli::Em, + LinkerFlavor::Bpf => LinkerFlavorCli::BpfLinker, + LinkerFlavor::Ptx => LinkerFlavorCli::PtxLinker, } } } -macro_rules! flavor_mappings { - ($((($($flavor:tt)*), $string:expr),)*) => ( +macro_rules! linker_flavor_cli_impls { + ($(($($flavor:tt)*) $string:literal)*) => ( impl LinkerFlavorCli { pub const fn one_of() -> &'static str { concat!("one of: ", $($string, " ",)*) } - pub fn from_str(s: &str) -> Option { + pub fn from_str(s: &str) -> Option { Some(match s { $($string => $($flavor)*,)* _ => return None, @@ -200,18 +196,17 @@ macro_rules! flavor_mappings { ) } -flavor_mappings! { - ((LinkerFlavorCli::Em), "em"), - ((LinkerFlavorCli::Gcc), "gcc"), - ((LinkerFlavorCli::L4Bender), "l4-bender"), - ((LinkerFlavorCli::Ld), "ld"), - ((LinkerFlavorCli::Msvc), "msvc"), - ((LinkerFlavorCli::PtxLinker), "ptx-linker"), - ((LinkerFlavorCli::BpfLinker), "bpf-linker"), - ((LinkerFlavorCli::Lld(LldFlavor::Wasm)), "wasm-ld"), - ((LinkerFlavorCli::Lld(LldFlavor::Ld64)), "ld64.lld"), - ((LinkerFlavorCli::Lld(LldFlavor::Ld)), "ld.lld"), - ((LinkerFlavorCli::Lld(LldFlavor::Link)), "lld-link"), +linker_flavor_cli_impls! { + (LinkerFlavorCli::Gcc) "gcc" + (LinkerFlavorCli::Ld) "ld" + (LinkerFlavorCli::Lld(LldFlavor::Ld)) "ld.lld" + (LinkerFlavorCli::Lld(LldFlavor::Ld64)) "ld64.lld" + (LinkerFlavorCli::Lld(LldFlavor::Link)) "lld-link" + (LinkerFlavorCli::Lld(LldFlavor::Wasm)) "wasm-ld" + (LinkerFlavorCli::Msvc) "msvc" + (LinkerFlavorCli::Em) "em" + (LinkerFlavorCli::BpfLinker) "bpf-linker" + (LinkerFlavorCli::PtxLinker) "ptx-linker" } impl ToJson for LinkerFlavorCli { @@ -1198,21 +1193,21 @@ pub struct TargetOptions { pub abi: StaticCow, /// Vendor name to use for conditional compilation (`target_vendor`). Defaults to "unknown". pub vendor: StaticCow, + + /// Linker to invoke + pub linker: Option>, /// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed /// on the command line. Defaults to `LinkerFlavor::Gcc`. pub linker_flavor: LinkerFlavor, linker_flavor_json: LinkerFlavorCli, - - /// Linker to invoke - pub linker: Option>, - /// LLD flavor used if `lld` (or `rust-lld`) is specified as a linker /// without clarifying its flavor in any way. + /// FIXME: Merge this into `LinkerFlavor`. pub lld_flavor: LldFlavor, + /// Whether the linker support GNU-like arguments such as -O. Defaults to true. + /// FIXME: Merge this into `LinkerFlavor`. + pub linker_is_gnu: bool, - /// Linker arguments that are passed *before* any user-defined libraries. - pub pre_link_args: LinkArgs, - pre_link_args_json: LinkArgsCli, /// Objects to link before and after all other object code. pub pre_link_objects: CrtObjects, pub post_link_objects: CrtObjects, @@ -1221,6 +1216,9 @@ pub struct TargetOptions { pub post_link_objects_self_contained: CrtObjects, pub link_self_contained: LinkSelfContainedDefault, + /// Linker arguments that are passed *before* any user-defined libraries. + pub pre_link_args: LinkArgs, + pre_link_args_json: LinkArgsCli, /// Linker arguments that are unconditionally passed after any /// user-defined but before post-link objects. Standard platform /// libraries that should be always be linked to, usually go here. @@ -1238,11 +1236,11 @@ pub struct TargetOptions { /// user-defined libraries. pub post_link_args: LinkArgs, post_link_args_json: LinkArgsCli, + /// Optional link script applied to `dylib` and `executable` crate types. /// This is a string containing the script, not a path. Can only be applied /// to linkers where `linker_is_gnu` is true. pub link_script: Option>, - /// Environment variables to be set for the linker invocation. pub link_env: StaticCow<[(StaticCow, StaticCow)]>, /// Environment variables to be removed for the linker invocation. @@ -1327,8 +1325,6 @@ pub struct TargetOptions { /// Default supported version of DWARF on this platform. /// Useful because some platforms (osx, bsd) only want up to DWARF2. pub default_dwarf_version: u32, - /// Whether the linker support GNU-like arguments such as -O. Defaults to true. - pub linker_is_gnu: bool, /// The MinGW toolchain has a known issue that prevents it from correctly /// handling COFF object files with more than 215 sections. Since each weak /// symbol needs its own COMDAT section, weak linkage implies a large @@ -1522,11 +1518,7 @@ fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'stati LinkerFlavor::Lld(lld_flavor) => { panic!("add_link_args: use non-LLD flavor for {:?}", lld_flavor) } - LinkerFlavor::Gcc - | LinkerFlavor::Em - | LinkerFlavor::L4Bender - | LinkerFlavor::BpfLinker - | LinkerFlavor::PtxLinker => {} + LinkerFlavor::Gcc | LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Ptx => {} } } @@ -1588,14 +1580,11 @@ impl Default for TargetOptions { env: "".into(), abi: "".into(), vendor: "unknown".into(), + linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.into()), linker_flavor: LinkerFlavor::Gcc, linker_flavor_json: LinkerFlavorCli::Gcc, - linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.into()), lld_flavor: LldFlavor::Ld, - pre_link_args: LinkArgs::new(), - pre_link_args_json: LinkArgsCli::new(), - post_link_args: LinkArgs::new(), - post_link_args_json: LinkArgsCli::new(), + linker_is_gnu: true, link_script: None, asm_args: cvs![], cpu: "generic".into(), @@ -1622,7 +1611,6 @@ impl Default for TargetOptions { is_like_msvc: false, is_like_wasm: false, default_dwarf_version: 4, - linker_is_gnu: true, allows_weak_linkage: true, has_rpath: false, no_default_libraries: true, @@ -1635,12 +1623,16 @@ impl Default for TargetOptions { pre_link_objects_self_contained: Default::default(), post_link_objects_self_contained: Default::default(), link_self_contained: LinkSelfContainedDefault::False, + pre_link_args: LinkArgs::new(), + pre_link_args_json: LinkArgsCli::new(), late_link_args: LinkArgs::new(), late_link_args_json: LinkArgsCli::new(), late_link_args_dynamic: LinkArgs::new(), late_link_args_dynamic_json: LinkArgsCli::new(), late_link_args_static: LinkArgs::new(), late_link_args_static_json: LinkArgsCli::new(), + post_link_args: LinkArgs::new(), + post_link_args_json: LinkArgsCli::new(), link_env: cvs![], link_env_remove: cvs![], archive_format: "gnu".into(), @@ -2190,9 +2182,10 @@ impl Target { key!(env); key!(abi); key!(vendor); - key!(linker_flavor_json = "linker-flavor", LinkerFlavor)?; key!(linker, optional); + key!(linker_flavor_json = "linker-flavor", LinkerFlavor)?; key!(lld_flavor, LldFlavor)?; + key!(linker_is_gnu, bool); key!(pre_link_objects = "pre-link-objects", link_objects); key!(post_link_objects = "post-link-objects", link_objects); key!(pre_link_objects_self_contained = "pre-link-objects-fallback", link_objects); @@ -2230,7 +2223,6 @@ impl Target { key!(is_like_msvc, bool); key!(is_like_wasm, bool); key!(default_dwarf_version, u32); - key!(linker_is_gnu, bool); key!(allows_weak_linkage, bool); key!(has_rpath, bool); key!(no_default_libraries, bool); @@ -2437,9 +2429,10 @@ impl ToJson for Target { target_option_val!(env); target_option_val!(abi); target_option_val!(vendor); - target_option_val!(linker_flavor_json, "linker-flavor"); target_option_val!(linker); + target_option_val!(linker_flavor_json, "linker-flavor"); target_option_val!(lld_flavor); + target_option_val!(linker_is_gnu); target_option_val!(pre_link_objects); target_option_val!(post_link_objects); target_option_val!(pre_link_objects_self_contained, "pre-link-objects-fallback"); @@ -2478,7 +2471,6 @@ impl ToJson for Target { target_option_val!(is_like_msvc); target_option_val!(is_like_wasm); target_option_val!(default_dwarf_version); - target_option_val!(linker_is_gnu); target_option_val!(allows_weak_linkage); target_option_val!(has_rpath); target_option_val!(no_default_libraries); diff --git a/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs index 1c5b68001b957..6ab3a8b7eb5a0 100644 --- a/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs +++ b/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs @@ -10,7 +10,7 @@ pub fn target() -> Target { options: TargetOptions { os: "cuda".into(), vendor: "nvidia".into(), - linker_flavor: LinkerFlavor::PtxLinker, + linker_flavor: LinkerFlavor::Ptx, // The linker can be installed from `crates.io`. linker: Some("rust-ptx-linker".into()), linker_is_gnu: false, diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs index 5e035f189c49b..5ec961a672ee8 100644 --- a/compiler/rustc_target/src/spec/tests/tests_impl.rs +++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs @@ -22,10 +22,9 @@ impl Target { assert_eq!(self.is_like_osx, matches!(self.lld_flavor, LldFlavor::Ld64)); assert_eq!(self.is_like_msvc, matches!(self.lld_flavor, LldFlavor::Link)); assert_eq!(self.is_like_wasm, matches!(self.lld_flavor, LldFlavor::Wasm)); - assert_eq!(self.os == "l4re", matches!(self.linker_flavor, LinkerFlavor::L4Bender)); - assert_eq!(self.os == "emscripten", matches!(self.linker_flavor, LinkerFlavor::Em)); - assert_eq!(self.arch == "bpf", matches!(self.linker_flavor, LinkerFlavor::BpfLinker)); - assert_eq!(self.arch == "nvptx64", matches!(self.linker_flavor, LinkerFlavor::PtxLinker)); + assert_eq!(self.os == "emscripten", matches!(self.linker_flavor, LinkerFlavor::EmCc)); + assert_eq!(self.arch == "bpf", matches!(self.linker_flavor, LinkerFlavor::Bpf)); + assert_eq!(self.arch == "nvptx64", matches!(self.linker_flavor, LinkerFlavor::Ptx)); for args in [ &self.pre_link_args, @@ -65,17 +64,14 @@ impl Target { LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc ) } - (LinkerFlavor::L4Bender, LldFlavor::Ld) => { - assert_matches!(flavor, LinkerFlavor::L4Bender) + (LinkerFlavor::EmCc, LldFlavor::Wasm) => { + assert_matches!(flavor, LinkerFlavor::EmCc) } - (LinkerFlavor::Em, LldFlavor::Wasm) => { - assert_matches!(flavor, LinkerFlavor::Em) + (LinkerFlavor::Bpf, LldFlavor::Ld) => { + assert_matches!(flavor, LinkerFlavor::Bpf) } - (LinkerFlavor::BpfLinker, LldFlavor::Ld) => { - assert_matches!(flavor, LinkerFlavor::BpfLinker) - } - (LinkerFlavor::PtxLinker, LldFlavor::Ld) => { - assert_matches!(flavor, LinkerFlavor::PtxLinker) + (LinkerFlavor::Ptx, LldFlavor::Ld) => { + assert_matches!(flavor, LinkerFlavor::Ptx) } flavors => unreachable!("unexpected flavor combination: {:?}", flavors), } diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs index c7e7d22108656..6f77ef98c015d 100644 --- a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs +++ b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs @@ -5,13 +5,13 @@ pub fn target() -> Target { // Reset flags for non-Em flavors back to empty to satisfy sanity checking tests. let pre_link_args = LinkArgs::new(); let post_link_args = TargetOptions::link_args( - LinkerFlavor::Em, + LinkerFlavor::EmCc, &["-sABORTING_MALLOC=0", "-Wl,--fatal-warnings"], ); let opts = TargetOptions { os: "emscripten".into(), - linker_flavor: LinkerFlavor::Em, + linker_flavor: LinkerFlavor::EmCc, // emcc emits two files - a .js file to instantiate the wasm and supply platform // functionality, and a .wasm file. exe_suffix: ".js".into(), From 38de102cffb7692738ec7940794e59452372d395 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Wed, 20 Jul 2022 21:43:37 -0400 Subject: [PATCH 04/18] Support eager and lazy methods for providing references and values There are times where computing a value may be cheap, or where computing a reference may be expensive, so this fills out the possibilities. --- library/core/src/any.rs | 74 +++++++++++++++++++++++++++++++++++---- library/core/tests/any.rs | 2 +- 2 files changed, 69 insertions(+), 7 deletions(-) diff --git a/library/core/src/any.rs b/library/core/src/any.rs index e54f6c912d594..3bfb675531e64 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -796,7 +796,7 @@ pub trait Provider { /// impl Provider for SomeConcreteType { /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) { /// demand.provide_ref::(&self.field) - /// .provide_value::(|| self.num_field); + /// .provide_value::(self.num_field); /// } /// } /// ``` @@ -881,28 +881,55 @@ impl<'a> Demand<'a> { /// /// # Examples /// + /// Provides an `u8`. + /// + /// ```rust + /// #![feature(provide_any)] + /// + /// use std::any::{Provider, Demand}; + /// # struct SomeConcreteType { field: u8 } + /// + /// impl Provider for SomeConcreteType { + /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) { + /// demand.provide_value::(self.field); + /// } + /// } + /// ``` + #[unstable(feature = "provide_any", issue = "96024")] + pub fn provide_value(&mut self, value: T) -> &mut Self + where + T: 'static, + { + self.provide::>(value) + } + + /// Provide a value or other type with only static lifetimes computed using a closure. + /// + /// # Examples + /// /// Provides a `String` by cloning. /// /// ```rust - /// # #![feature(provide_any)] + /// #![feature(provide_any)] + /// /// use std::any::{Provider, Demand}; /// # struct SomeConcreteType { field: String } /// /// impl Provider for SomeConcreteType { /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) { - /// demand.provide_value::(|| self.field.clone()); + /// demand.provide_value_with::(|| self.field.clone()); /// } /// } /// ``` #[unstable(feature = "provide_any", issue = "96024")] - pub fn provide_value(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self + pub fn provide_value_with(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self where T: 'static, { self.provide_with::>(fulfil) } - /// Provide a reference, note that the referee type must be bounded by `'static`, + /// Provide a reference. The referee type must be bounded by `'static`, /// but may be unsized. /// /// # Examples @@ -910,7 +937,8 @@ impl<'a> Demand<'a> { /// Provides a reference to a field as a `&str`. /// /// ```rust - /// # #![feature(provide_any)] + /// #![feature(provide_any)] + /// /// use std::any::{Provider, Demand}; /// # struct SomeConcreteType { field: String } /// @@ -925,6 +953,40 @@ impl<'a> Demand<'a> { self.provide::>>(value) } + /// Provide a reference computed using a closure. The referee type + /// must be bounded by `'static`, but may be unsized. + /// + /// # Examples + /// + /// Provides a reference to a field as a `&str`. + /// + /// ```rust + /// #![feature(provide_any)] + /// + /// use std::any::{Provider, Demand}; + /// # struct SomeConcreteType { business: String, party: String } + /// # fn today_is_a_weekday() -> bool { true } + /// + /// impl Provider for SomeConcreteType { + /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) { + /// demand.provide_ref_with::(|| { + /// if today_is_a_weekday() { + /// &self.business + /// } else { + /// &self.party + /// } + /// }); + /// } + /// } + /// ``` + #[unstable(feature = "provide_any", issue = "96024")] + pub fn provide_ref_with( + &mut self, + fulfil: impl FnOnce() -> &'a T, + ) -> &mut Self { + self.provide_with::>>(fulfil) + } + /// Provide a value with the given `Type` tag. fn provide(&mut self, value: I::Reified) -> &mut Self where diff --git a/library/core/tests/any.rs b/library/core/tests/any.rs index 8ed0c88808fe2..9538b81394957 100644 --- a/library/core/tests/any.rs +++ b/library/core/tests/any.rs @@ -142,7 +142,7 @@ impl Provider for SomeConcreteType { demand .provide_ref::(&self.some_string) .provide_ref::(&self.some_string) - .provide_value::(|| "bye".to_owned()); + .provide_value_with::(|| "bye".to_owned()); } } From 260ec9347838714ad9fa4f7e083bdc0448f4f9be Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Thu, 21 Jul 2022 21:39:20 -0400 Subject: [PATCH 05/18] Add `Provider::{would_be_satisfied_by_value_of,would_be_satisfied_by_ref_of}` While the `provide_*` methods already short-circuit when a value has been provided, there are times where an expensive computation is needed to determine if the `provide_*` method can even be called. --- library/core/src/any.rs | 165 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 3bfb675531e64..1a379ecc11c01 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -1008,6 +1008,156 @@ impl<'a> Demand<'a> { } self } + + /// Check if the `Demand` would be satisfied if provided with a + /// value of the specified type. If the type does not match or has + /// already been provided, returns false. + /// + /// # Examples + /// + /// Check if an `u8` still needs to be provided and then provides + /// it. + /// + /// ```rust + /// #![feature(provide_any)] + /// + /// use std::any::{Provider, Demand}; + /// + /// struct Parent(Option); + /// + /// impl Provider for Parent { + /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) { + /// if let Some(v) = self.0 { + /// demand.provide_value::(v); + /// } + /// } + /// } + /// + /// struct Child { + /// parent: Parent, + /// } + /// + /// impl Child { + /// // Pretend that this takes a lot of resources to evaluate. + /// fn an_expensive_computation(&self) -> Option { + /// Some(99) + /// } + /// } + /// + /// impl Provider for Child { + /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) { + /// // In general, we don't know if this call will provide + /// // an `u8` value or not... + /// self.parent.provide(demand); + /// + /// // ...so we check to see if the `u8` is needed before + /// // we run our expensive computation. + /// if demand.would_be_satisfied_by_value_of::() { + /// if let Some(v) = self.an_expensive_computation() { + /// demand.provide_value::(v); + /// } + /// } + /// + /// // The demand will be satisfied now, regardless of if + /// // the parent provided the value or we did. + /// assert!(!demand.would_be_satisfied_by_value_of::()); + /// } + /// } + /// + /// let parent = Parent(Some(42)); + /// let child = Child { parent }; + /// assert_eq!(Some(42), std::any::request_value::(&child)); + /// + /// let parent = Parent(None); + /// let child = Child { parent }; + /// assert_eq!(Some(99), std::any::request_value::(&child)); + /// ``` + #[unstable(feature = "provide_any", issue = "96024")] + pub fn would_be_satisfied_by_value_of(&self) -> bool + where + T: 'static, + { + self.would_be_satisfied_by::>() + } + + /// Check if the `Demand` would be satisfied if provided with a + /// reference to a value of the specified type. If the type does + /// not match or has already been provided, returns false. + /// + /// # Examples + /// + /// Check if a `&str` still needs to be provided and then provides + /// it. + /// + /// ```rust + /// #![feature(provide_any)] + /// + /// use std::any::{Provider, Demand}; + /// + /// struct Parent(Option); + /// + /// impl Provider for Parent { + /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) { + /// if let Some(v) = &self.0 { + /// demand.provide_ref::(v); + /// } + /// } + /// } + /// + /// struct Child { + /// parent: Parent, + /// name: String, + /// } + /// + /// impl Child { + /// // Pretend that this takes a lot of resources to evaluate. + /// fn an_expensive_computation(&self) -> Option<&str> { + /// Some(&self.name) + /// } + /// } + /// + /// impl Provider for Child { + /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) { + /// // In general, we don't know if this call will provide + /// // a `str` reference or not... + /// self.parent.provide(demand); + /// + /// // ...so we check to see if the `&str` is needed before + /// // we run our expensive computation. + /// if demand.would_be_satisfied_by_ref_of::() { + /// if let Some(v) = self.an_expensive_computation() { + /// demand.provide_ref::(v); + /// } + /// } + /// + /// // The demand will be satisfied now, regardless of if + /// // the parent provided the reference or we did. + /// assert!(!demand.would_be_satisfied_by_ref_of::()); + /// } + /// } + /// + /// let parent = Parent(Some("parent".into())); + /// let child = Child { parent, name: "child".into() }; + /// assert_eq!(Some("parent"), std::any::request_ref::(&child)); + /// + /// let parent = Parent(None); + /// let child = Child { parent, name: "child".into() }; + /// assert_eq!(Some("child"), std::any::request_ref::(&child)); + /// ``` + #[unstable(feature = "provide_any", issue = "96024")] + pub fn would_be_satisfied_by_ref_of(&self) -> bool + where + T: ?Sized + 'static, + { + self.would_be_satisfied_by::>>() + } + + fn would_be_satisfied_by(&self) -> bool + where + I: tags::Type<'a>, + { + matches!(self.0.downcast::(), Some(TaggedOption(None))) + } } #[unstable(feature = "provide_any", issue = "96024")] @@ -1112,6 +1262,21 @@ impl<'a> dyn Erased<'a> + 'a { /// Returns some reference to the dynamic value if it is tagged with `I`, /// or `None` otherwise. #[inline] + fn downcast(&self) -> Option<&TaggedOption<'a, I>> + where + I: tags::Type<'a>, + { + if self.tag_id() == TypeId::of::() { + // SAFETY: Just checked whether we're pointing to an I. + Some(unsafe { &*(self as *const Self).cast::>() }) + } else { + None + } + } + + /// Returns some mutable reference to the dynamic value if it is tagged with `I`, + /// or `None` otherwise. + #[inline] fn downcast_mut(&mut self) -> Option<&mut TaggedOption<'a, I>> where I: tags::Type<'a>, From 81a583c21e74d600ef8c4b45a3d5088382300e17 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Wed, 3 Aug 2022 22:24:47 +0200 Subject: [PATCH 06/18] Try normalizing types without RevealAll in ParamEnv in mir validation Before, the MIR validator used RevealAll in its ParamEnv for type checking. This could cause false negatives in some cases due to RevealAll ParamEnvs not always use all predicates as expected here. Since some MIR passes like inlining use RevealAll as well, keep using it in the MIR validator too, but when it fails usign RevealAll, also try the check without it, to stop false negatives. --- .../src/transform/validate.rs | 28 +++++++++++++------ src/test/ui/mir/issue-99866.rs | 25 +++++++++++++++++ 2 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/mir/issue-99866.rs diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 45a94972c1134..ddde9ff4c0281 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -181,16 +181,28 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if (src, dest).has_opaque_types() { return true; } + + let try_equal_with_param_env = |param_env| { + let src = self.tcx.normalize_erasing_regions(param_env, src); + let dest = self.tcx.normalize_erasing_regions(param_env, dest); + // Type-changing assignments can happen when subtyping is used. While + // all normal lifetimes are erased, higher-ranked types with their + // late-bound lifetimes are still around and can lead to type + // differences. So we compare ignoring lifetimes. + equal_up_to_regions(self.tcx, param_env, src, dest) + }; + // Normalize projections and things like that. + // First, try with reveal_all. This might not work in some cases, as the predicates + // can be cleared in reveal_all mode. We try the reveal first anyways as it is used + // by some other passes like inlining as well. let param_env = self.param_env.with_reveal_all_normalized(self.tcx); - let src = self.tcx.normalize_erasing_regions(param_env, src); - let dest = self.tcx.normalize_erasing_regions(param_env, dest); - - // Type-changing assignments can happen when subtyping is used. While - // all normal lifetimes are erased, higher-ranked types with their - // late-bound lifetimes are still around and can lead to type - // differences. So we compare ignoring lifetimes. - equal_up_to_regions(self.tcx, param_env, src, dest) + if try_equal_with_param_env(param_env) { + true + } else { + // If this fails, we can try it without the reveal. + try_equal_with_param_env(self.param_env) + } } } diff --git a/src/test/ui/mir/issue-99866.rs b/src/test/ui/mir/issue-99866.rs new file mode 100644 index 0000000000000..d39ae6ebf1da2 --- /dev/null +++ b/src/test/ui/mir/issue-99866.rs @@ -0,0 +1,25 @@ +// check-pass +pub trait Backend { + type DescriptorSetLayout; +} + +pub struct Back; + +impl Backend for Back { + type DescriptorSetLayout = u32; +} + +pub struct HalSetLayouts { + vertex_layout: ::DescriptorSetLayout, +} + +impl HalSetLayouts { + pub fn iter(self) -> DSL + where + Back: Backend, + { + self.vertex_layout + } +} + +fn main() {} From 96d4137deed6c52c6db2dd19568c37d1c160f1e7 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 6 Aug 2022 14:22:57 +0200 Subject: [PATCH 07/18] Only normalize once in mir validator typechecker Before, it called `normalize_erasing_regions` twice since `equal_up_to_regions` called it as well for both types. --- .../src/transform/validate.rs | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index ddde9ff4c0281..69113e57bdc5b 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -182,27 +182,22 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return true; } - let try_equal_with_param_env = |param_env| { - let src = self.tcx.normalize_erasing_regions(param_env, src); - let dest = self.tcx.normalize_erasing_regions(param_env, dest); - // Type-changing assignments can happen when subtyping is used. While - // all normal lifetimes are erased, higher-ranked types with their - // late-bound lifetimes are still around and can lead to type - // differences. So we compare ignoring lifetimes. - equal_up_to_regions(self.tcx, param_env, src, dest) - }; - // Normalize projections and things like that. + // Type-changing assignments can happen when subtyping is used. While + // all normal lifetimes are erased, higher-ranked types with their + // late-bound lifetimes are still around and can lead to type + // differences. So we compare ignoring lifetimes. + // First, try with reveal_all. This might not work in some cases, as the predicates // can be cleared in reveal_all mode. We try the reveal first anyways as it is used // by some other passes like inlining as well. let param_env = self.param_env.with_reveal_all_normalized(self.tcx); - if try_equal_with_param_env(param_env) { - true - } else { - // If this fails, we can try it without the reveal. - try_equal_with_param_env(self.param_env) + if equal_up_to_regions(self.tcx, param_env, src, dest) { + return true; } + + // If this fails, we can try it without the reveal. + equal_up_to_regions(self.tcx, self.param_env, src, dest) } } From c846a2af8ddaa14ff2c2da25bc97bbd8d4284df2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 14 Jun 2022 10:44:14 -0700 Subject: [PATCH 08/18] Make `std::os::fd` public. `std::os::fd` defines types like `OwnedFd` and `RawFd` and is common between Unix and non-Unix platforms that share a basic file-descriptor concept. Rust currently uses this internally to simplify its own code, but it would be useful for external users in the same way, so make it public. This means that `OwnedFd` etc. will all appear in three places, for example on unix platforms: - `std::os::fd::OwnedFd` - `std::os::unix::io::OwnedFd` - `std::os::unix::prelude::OwnedFd` --- library/std/src/os/fd/mod.rs | 14 ++++++++++++-- library/std/src/os/fd/owned.rs | 5 +---- library/std/src/os/fd/raw.rs | 15 +++------------ library/std/src/os/mod.rs | 2 +- library/std/src/os/unix/io/fd.rs | 8 -------- library/std/src/os/unix/io/mod.rs | 11 +++++------ library/std/src/os/unix/io/raw.rs | 6 ------ library/std/src/os/unix/io/{fd => }/tests.rs | 0 library/std/src/os/wasi/io/mod.rs | 8 +------- 9 files changed, 23 insertions(+), 46 deletions(-) delete mode 100644 library/std/src/os/unix/io/fd.rs delete mode 100644 library/std/src/os/unix/io/raw.rs rename library/std/src/os/unix/io/{fd => }/tests.rs (100%) diff --git a/library/std/src/os/fd/mod.rs b/library/std/src/os/fd/mod.rs index a456947534a45..8043d1a53d279 100644 --- a/library/std/src/os/fd/mod.rs +++ b/library/std/src/os/fd/mod.rs @@ -1,16 +1,26 @@ //! Owned and borrowed Unix-like file descriptors. +//! +//! This module is supported on Unix platforms, and also some non-Unix +//! platforms which use a similar file descriptor system for referencing OS +//! resources. #![stable(feature = "io_safety", since = "1.63.0")] #![deny(unsafe_op_in_unsafe_fn)] // `RawFd`, `AsRawFd`, etc. -pub mod raw; +mod raw; // `OwnedFd`, `AsFd`, etc. -pub mod owned; +mod owned; // Implementations for `AsRawFd` etc. for network types. mod net; #[cfg(test)] mod tests; + +// Export the types and traits for the public API. +#[stable(feature = "io_safety", since = "1.63.0")] +pub use owned::*; +#[stable(feature = "rust1", since = "1.0.0")] +pub use raw::*; diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index a463bc41db7aa..3a1b04a83fa79 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -205,10 +205,7 @@ pub trait AsFd { /// ```rust,no_run /// use std::fs::File; /// # use std::io; - /// # #[cfg(target_os = "wasi")] - /// # use std::os::wasi::io::{AsFd, BorrowedFd}; - /// # #[cfg(unix)] - /// # use std::os::unix::io::{AsFd, BorrowedFd}; + /// # use std::os::fd::{AsFd, BorrowedFd}; /// /// let mut f = File::open("foo.txt")?; /// # #[cfg(any(unix, target_os = "wasi"))] diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs index 1b3d110426feb..42a9effcf92ab 100644 --- a/library/std/src/os/fd/raw.rs +++ b/library/std/src/os/fd/raw.rs @@ -42,10 +42,7 @@ pub trait AsRawFd { /// ```no_run /// use std::fs::File; /// # use std::io; - /// #[cfg(unix)] - /// use std::os::unix::io::{AsRawFd, RawFd}; - /// #[cfg(target_os = "wasi")] - /// use std::os::wasi::io::{AsRawFd, RawFd}; + /// use std::os::fd::{AsRawFd, RawFd}; /// /// let mut f = File::open("foo.txt")?; /// // Note that `raw_fd` is only valid as long as `f` exists. @@ -83,10 +80,7 @@ pub trait FromRawFd { /// ```no_run /// use std::fs::File; /// # use std::io; - /// #[cfg(unix)] - /// use std::os::unix::io::{FromRawFd, IntoRawFd, RawFd}; - /// #[cfg(target_os = "wasi")] - /// use std::os::wasi::io::{FromRawFd, IntoRawFd, RawFd}; + /// use std::os::fd::{FromRawFd, IntoRawFd, RawFd}; /// /// let f = File::open("foo.txt")?; /// # #[cfg(any(unix, target_os = "wasi"))] @@ -121,10 +115,7 @@ pub trait IntoRawFd { /// ```no_run /// use std::fs::File; /// # use std::io; - /// #[cfg(unix)] - /// use std::os::unix::io::{IntoRawFd, RawFd}; - /// #[cfg(target_os = "wasi")] - /// use std::os::wasi::io::{IntoRawFd, RawFd}; + /// use std::os::fd::{IntoRawFd, RawFd}; /// /// let f = File::open("foo.txt")?; /// #[cfg(any(unix, target_os = "wasi"))] diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 18c64b5100764..f62f5af774f0e 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -147,7 +147,7 @@ pub mod solid; pub mod vxworks; #[cfg(any(unix, target_os = "wasi", doc))] -mod fd; +pub mod fd; #[cfg(any(target_os = "linux", target_os = "android", doc))] mod net; diff --git a/library/std/src/os/unix/io/fd.rs b/library/std/src/os/unix/io/fd.rs deleted file mode 100644 index d4cb696459b7e..0000000000000 --- a/library/std/src/os/unix/io/fd.rs +++ /dev/null @@ -1,8 +0,0 @@ -//! Owned and borrowed file descriptors. - -// Tests for this module -#[cfg(test)] -mod tests; - -#[stable(feature = "io_safety", since = "1.63.0")] -pub use crate::os::fd::owned::*; diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs index 3ab5606f8897d..25b5dbff14f30 100644 --- a/library/std/src/os/unix/io/mod.rs +++ b/library/std/src/os/unix/io/mod.rs @@ -77,10 +77,9 @@ #![stable(feature = "rust1", since = "1.0.0")] -mod fd; -mod raw; - -#[stable(feature = "io_safety", since = "1.63.0")] -pub use fd::*; #[stable(feature = "rust1", since = "1.0.0")] -pub use raw::*; +pub use crate::os::fd::*; + +// Tests for this module +#[cfg(test)] +mod tests; diff --git a/library/std/src/os/unix/io/raw.rs b/library/std/src/os/unix/io/raw.rs deleted file mode 100644 index a4d2ba797d9c4..0000000000000 --- a/library/std/src/os/unix/io/raw.rs +++ /dev/null @@ -1,6 +0,0 @@ -//! Unix-specific extensions to general I/O primitives. - -#![stable(feature = "rust1", since = "1.0.0")] - -#[stable(feature = "rust1", since = "1.0.0")] -pub use crate::os::fd::raw::*; diff --git a/library/std/src/os/unix/io/fd/tests.rs b/library/std/src/os/unix/io/tests.rs similarity index 100% rename from library/std/src/os/unix/io/fd/tests.rs rename to library/std/src/os/unix/io/tests.rs diff --git a/library/std/src/os/wasi/io/mod.rs b/library/std/src/os/wasi/io/mod.rs index 6c884e2eaf471..d528590d75b9a 100644 --- a/library/std/src/os/wasi/io/mod.rs +++ b/library/std/src/os/wasi/io/mod.rs @@ -1,12 +1,6 @@ //! WASI-specific extensions to general I/O primitives. -#![deny(unsafe_op_in_unsafe_fn)] #![unstable(feature = "wasi_ext", issue = "71213")] -mod fd; -mod raw; - -#[unstable(feature = "wasi_ext", issue = "71213")] -pub use fd::*; #[unstable(feature = "wasi_ext", issue = "71213")] -pub use raw::*; +pub use crate::os::fd::*; From 09bbc4224f36e05245e63d1766364ea821c83cd3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 21 Jun 2022 21:09:20 -0700 Subject: [PATCH 09/18] Update asrawfd.js. --- src/test/rustdoc-js-std/asrawfd.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/rustdoc-js-std/asrawfd.js b/src/test/rustdoc-js-std/asrawfd.js index fd228a59099e9..369a34f9c6eb7 100644 --- a/src/test/rustdoc-js-std/asrawfd.js +++ b/src/test/rustdoc-js-std/asrawfd.js @@ -6,9 +6,9 @@ const EXPECTED = { 'others': [ // Reproduction test for https://github.com/rust-lang/rust/issues/78724 // Validate that type alias methods get the correct path. - { 'path': 'std::os::unix::io::AsRawFd', 'name': 'as_raw_fd' }, - { 'path': 'std::os::wasi::io::AsRawFd', 'name': 'as_raw_fd' }, + { 'path': 'std::os::fd::AsRawFd', 'name': 'as_raw_fd' }, + { 'path': 'std::os::fd::AsRawFd', 'name': 'as_raw_fd' }, { 'path': 'std::os::linux::process::PidFd', 'name': 'as_raw_fd' }, - { 'path': 'std::os::unix::io::RawFd', 'name': 'as_raw_fd' }, + { 'path': 'std::os::fd::RawFd', 'name': 'as_raw_fd' }, ], }; From bda12629c3d0926c14b9fbe3f814972f8d50043c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 29 Jun 2022 19:07:43 -0700 Subject: [PATCH 10/18] Clarify that the `fd` module is supported on Unix and WASI. --- library/std/src/os/fd/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/std/src/os/fd/mod.rs b/library/std/src/os/fd/mod.rs index 8043d1a53d279..91dbe44878b1e 100644 --- a/library/std/src/os/fd/mod.rs +++ b/library/std/src/os/fd/mod.rs @@ -1,8 +1,7 @@ //! Owned and borrowed Unix-like file descriptors. //! -//! This module is supported on Unix platforms, and also some non-Unix -//! platforms which use a similar file descriptor system for referencing OS -//! resources. +//! This module is supported on Unix platforms and WASI, which both use a +//! similar file descriptor system for referencing OS resources. #![stable(feature = "io_safety", since = "1.63.0")] #![deny(unsafe_op_in_unsafe_fn)] From 7d80510c16bd2172427aff61e5d929aa695cdfa5 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 23 Aug 2022 11:57:13 -0700 Subject: [PATCH 11/18] Re-introduce `unstable` attributes. Add `#[unstable(feature = "os_fd", issue = "98699")]` to the new `pub use` declarations. --- library/std/src/os/fd/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/os/fd/mod.rs b/library/std/src/os/fd/mod.rs index 91dbe44878b1e..c6aa7c77dbc41 100644 --- a/library/std/src/os/fd/mod.rs +++ b/library/std/src/os/fd/mod.rs @@ -19,7 +19,7 @@ mod net; mod tests; // Export the types and traits for the public API. -#[stable(feature = "io_safety", since = "1.63.0")] +#[unstable(feature = "os_fd", issue = "98699")] pub use owned::*; -#[stable(feature = "rust1", since = "1.0.0")] +#[unstable(feature = "os_fd", issue = "98699")] pub use raw::*; From 803e35abf7c2949fe04d1c403d69605f570d5637 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 31 Aug 2022 17:05:38 +0200 Subject: [PATCH 12/18] Remove unneeded extra whitespace before where clause --- src/librustdoc/html/format.rs | 13 ++++--------- src/librustdoc/html/render/mod.rs | 12 ++++++------ 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index b023792e95a58..05d10f8137fe8 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -349,8 +349,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( let where_preds = comma_sep(where_predicates, false); let clause = if f.alternate() { if ending == Ending::Newline { - // add a space so stripping
tags and breaking spaces still renders properly - format!(" where{where_preds}, ") + format!(" where{where_preds},") } else { format!(" where{where_preds}") } @@ -364,20 +363,16 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( if ending == Ending::Newline { let mut clause = " ".repeat(indent.saturating_sub(1)); - // add a space so stripping
tags and breaking spaces still renders properly - write!( - clause, - " where{where_preds}, " - )?; + write!(clause, "where{where_preds},")?; clause } else { // insert a
tag after a single space but before multiple spaces at the start if indent == 0 { - format!("
where{where_preds}") + format!("
where{where_preds}") } else { let mut clause = br_with_padding; clause.truncate(clause.len() - 5 * " ".len()); - write!(clause, " where{where_preds}")?; + write!(clause, "where{where_preds}")?; clause } } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 6272f47f460ca..bff12e6fee9bd 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1739,8 +1739,8 @@ pub(crate) fn render_impl_summary( // in documentation pages for trait with automatic implementations like "Send" and "Sync". aliases: &[String], ) { - let id = - cx.derive_id(get_id_for_impl(&i.inner_impl().for_, i.inner_impl().trait_.as_ref(), cx)); + let inner_impl = i.inner_impl(); + let id = cx.derive_id(get_id_for_impl(&inner_impl.for_, inner_impl.trait_.as_ref(), cx)); let aliases = if aliases.is_empty() { String::new() } else { @@ -1752,9 +1752,9 @@ pub(crate) fn render_impl_summary( write!(w, "

"); if let Some(use_absolute) = use_absolute { - write!(w, "{}", i.inner_impl().print(use_absolute, cx)); + write!(w, "{}", inner_impl.print(use_absolute, cx)); if show_def_docs { - for it in &i.inner_impl().items { + for it in &inner_impl.items { if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind { w.write_str(" "); assoc_type( @@ -1772,11 +1772,11 @@ pub(crate) fn render_impl_summary( } } } else { - write!(w, "{}", i.inner_impl().print(false, cx)); + write!(w, "{}", inner_impl.print(false, cx)); } write!(w, "

"); - let is_trait = i.inner_impl().trait_.is_some(); + let is_trait = inner_impl.trait_.is_some(); if is_trait { if let Some(portability) = portability(&i.impl_item, Some(parent)) { write!(w, "{}", portability); From 4304d1d1e6ea31ca45b722047f516322af4305c4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 31 Aug 2022 17:05:46 +0200 Subject: [PATCH 13/18] Update rustdoc tests --- src/test/rustdoc-gui/src/lib2/lib.rs | 27 +++++++++++++++++++ .../const-generics/const-generics-docs.rs | 8 +++--- .../rustdoc/generic-associated-types/gats.rs | 4 +-- .../rustdoc/higher-ranked-trait-bounds.rs | 8 +++--- src/test/rustdoc/impl-parts.rs | 4 +-- src/test/rustdoc/issue-20727-4.rs | 4 +-- src/test/rustdoc/issue-21801.rs | 2 +- src/test/rustdoc/issue-29503.rs | 2 +- src/test/rustdoc/issue-34928.rs | 2 +- src/test/rustdoc/issue-50159.rs | 4 +-- src/test/rustdoc/issue-51236.rs | 2 +- src/test/rustdoc/issue-54705.rs | 6 ++--- src/test/rustdoc/issue-98697.rs | 2 +- .../rustdoc/primitive-slice-auto-trait.rs | 4 +-- src/test/rustdoc/synthetic_auto/basic.rs | 4 +-- src/test/rustdoc/synthetic_auto/complex.rs | 2 +- src/test/rustdoc/synthetic_auto/lifetimes.rs | 4 +-- src/test/rustdoc/synthetic_auto/manual.rs | 2 +- src/test/rustdoc/synthetic_auto/nested.rs | 4 +-- .../rustdoc/synthetic_auto/no-redundancy.rs | 2 +- src/test/rustdoc/synthetic_auto/project.rs | 4 +-- .../synthetic_auto/self-referential.rs | 2 +- .../rustdoc/synthetic_auto/static-region.rs | 2 +- src/test/rustdoc/where-clause-order.rs | 2 +- src/test/rustdoc/where.rs | 22 +++++++-------- 25 files changed, 77 insertions(+), 52 deletions(-) diff --git a/src/test/rustdoc-gui/src/lib2/lib.rs b/src/test/rustdoc-gui/src/lib2/lib.rs index 87f91be3ac82c..7f3172878bfb5 100644 --- a/src/test/rustdoc-gui/src/lib2/lib.rs +++ b/src/test/rustdoc-gui/src/lib2/lib.rs @@ -143,3 +143,30 @@ pub struct LongItemInfo2; /// Some docs. #[doc(cfg(any(target_os = "android", target_os = "linux", target_os = "emscripten", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))] impl SimpleTrait for LongItemInfo2 {} + +pub struct WhereWhitespace; + +impl WhereWhitespace { + pub fn new(f: F) -> Self + where + F: FnMut() -> i32, + {} +} + +impl Whitespace<&K> for WhereWhitespace +where + K: std::fmt::Debug, +{ + type Output = WhereWhitespace; + fn index(&self, _key: &K) -> &Self::Output { + self + } +} + +pub trait Whitespace +where + Idx: ?Sized, +{ + type Output; + fn index(&self, index: Idx) -> &Self::Output; +} diff --git a/src/test/rustdoc/const-generics/const-generics-docs.rs b/src/test/rustdoc/const-generics/const-generics-docs.rs index 352a8e646bb49..87d2f29e26055 100644 --- a/src/test/rustdoc/const-generics/const-generics-docs.rs +++ b/src/test/rustdoc/const-generics/const-generics-docs.rs @@ -31,12 +31,12 @@ impl Trait<{1 + 2}> for u8 {} impl Trait for [u8; N] {} // @has foo/struct.Foo.html '//pre[@class="rust struct"]' \ -// 'pub struct Foo where u8: Trait' +// 'pub struct Foowhere u8: Trait' pub struct Foo where u8: Trait; // @has foo/struct.Bar.html '//pre[@class="rust struct"]' 'pub struct Bar(_)' pub struct Bar([T; N]); -// @has foo/struct.Foo.html '//*[@id="impl-Foo%3CM%3E"]/h3[@class="code-header in-band"]' 'impl Foo where u8: Trait' +// @has foo/struct.Foo.html '//*[@id="impl-Foo%3CM%3E"]/h3[@class="code-header in-band"]' 'impl Foowhere u8: Trait' impl Foo where u8: Trait { // @has - '//*[@id="associatedconstant.FOO_ASSOC"]' 'pub const FOO_ASSOC: usize' pub const FOO_ASSOC: usize = M + 13; @@ -50,14 +50,14 @@ impl Foo where u8: Trait { // @has foo/struct.Bar.html '//*[@id="impl-Bar%3Cu8%2C%20M%3E"]/h3[@class="code-header in-band"]' 'impl Bar' impl Bar { // @has - '//*[@id="method.hey"]' \ - // 'pub fn hey(&self) -> Foo where u8: Trait' + // 'pub fn hey(&self) -> Foowhere u8: Trait' pub fn hey(&self) -> Foo where u8: Trait { Foo } } // @has foo/fn.test.html '//pre[@class="rust fn"]' \ -// 'pub fn test() -> impl Trait where u8: Trait' +// 'pub fn test() -> impl Traitwhere u8: Trait' pub fn test() -> impl Trait where u8: Trait { 2u8 } diff --git a/src/test/rustdoc/generic-associated-types/gats.rs b/src/test/rustdoc/generic-associated-types/gats.rs index ae981b9499a67..2b9d4952d04ee 100644 --- a/src/test/rustdoc/generic-associated-types/gats.rs +++ b/src/test/rustdoc/generic-associated-types/gats.rs @@ -3,7 +3,7 @@ // @has foo/trait.LendingIterator.html pub trait LendingIterator { - // @has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' "type Item<'a> where Self: 'a" + // @has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' "type Item<'a>where Self: 'a" type Item<'a> where Self: 'a; // @has - '//*[@id="tymethod.next"]//h4[@class="code-header"]' \ @@ -24,7 +24,7 @@ impl LendingIterator for () { pub struct Infinite(T); // @has foo/trait.LendingIterator.html -// @has - '//*[@id="associatedtype.Item-2"]//h4[@class="code-header"]' "type Item<'a> where Self: 'a = &'a T" +// @has - '//*[@id="associatedtype.Item-2"]//h4[@class="code-header"]' "type Item<'a>where Self: 'a = &'a T" impl LendingIterator for Infinite { type Item<'a> where Self: 'a = &'a T; diff --git a/src/test/rustdoc/higher-ranked-trait-bounds.rs b/src/test/rustdoc/higher-ranked-trait-bounds.rs index b75b8de52f9cb..59b5b6e5797cc 100644 --- a/src/test/rustdoc/higher-ranked-trait-bounds.rs +++ b/src/test/rustdoc/higher-ranked-trait-bounds.rs @@ -4,7 +4,7 @@ pub trait Trait<'x> {} // @has foo/fn.test1.html -// @has - '//pre' "pub fn test1() where for<'a> &'a T: Iterator," +// @has - '//pre' "pub fn test1()where for<'a> &'a T: Iterator," pub fn test1() where for<'a> &'a T: Iterator, @@ -12,7 +12,7 @@ where } // @has foo/fn.test2.html -// @has - '//pre' "pub fn test2() where for<'a, 'b> &'a T: Trait<'b>," +// @has - '//pre' "pub fn test2()where for<'a, 'b> &'a T: Trait<'b>," pub fn test2() where for<'a, 'b> &'a T: Trait<'b>, @@ -20,7 +20,7 @@ where } // @has foo/fn.test3.html -// @has - '//pre' "pub fn test3() where F: for<'a, 'b> Fn(&'a u8, &'b u8)," +// @has - '//pre' "pub fn test3()where F: for<'a, 'b> Fn(&'a u8, &'b u8)," pub fn test3() where F: for<'a, 'b> Fn(&'a u8, &'b u8), @@ -38,7 +38,7 @@ pub struct Foo<'a> { // @has - '//span[@id="structfield.some_trait"]' "some_trait: &'a dyn for<'b> Trait<'b>" impl<'a> Foo<'a> { - // @has - '//h4[@class="code-header"]' "pub fn bar() where T: Trait<'a>," + // @has - '//h4[@class="code-header"]' "pub fn bar()where T: Trait<'a>," pub fn bar() where T: Trait<'a>, diff --git a/src/test/rustdoc/impl-parts.rs b/src/test/rustdoc/impl-parts.rs index 249158c1a1f89..b1481e1f27978 100644 --- a/src/test/rustdoc/impl-parts.rs +++ b/src/test/rustdoc/impl-parts.rs @@ -6,7 +6,7 @@ pub auto trait AnAutoTrait {} pub struct Foo { field: T } // @has impl_parts/struct.Foo.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// "impl !AnAutoTrait for Foo where T: Sync," +// "impl !AnAutoTrait for Foowhere T: Sync," // @has impl_parts/trait.AnAutoTrait.html '//*[@class="item-list"]//h3[@class="code-header in-band"]' \ -// "impl !AnAutoTrait for Foo where T: Sync," +// "impl !AnAutoTrait for Foowhere T: Sync," impl !AnAutoTrait for Foo where T: Sync {} diff --git a/src/test/rustdoc/issue-20727-4.rs b/src/test/rustdoc/issue-20727-4.rs index 84fc6f94a265a..643f938759093 100644 --- a/src/test/rustdoc/issue-20727-4.rs +++ b/src/test/rustdoc/issue-20727-4.rs @@ -25,7 +25,7 @@ pub trait IndexMut: Index { pub mod reexport { // @has issue_20727_4/reexport/trait.Index.html - // @has - '//*[@class="rust trait"]' 'trait Index where Idx: ?Sized, {' + // @has - '//*[@class="rust trait"]' 'trait Indexwhere Idx: ?Sized,{' // @has - '//*[@class="rust trait"]' 'type Output: ?Sized' // @has - '//*[@class="rust trait"]' \ // 'fn index(&self, index: Idx) -> &Self::Output' @@ -33,7 +33,7 @@ pub mod reexport { // @has issue_20727_4/reexport/trait.IndexMut.html // @has - '//*[@class="rust trait"]' \ - // 'trait IndexMut: Index where Idx: ?Sized, {' + // 'trait IndexMut: Indexwhere Idx: ?Sized,{' // @has - '//*[@class="rust trait"]' \ // 'fn index_mut(&mut self, index: Idx) -> &mut Self::Output;' pub use issue_20727::IndexMut; diff --git a/src/test/rustdoc/issue-21801.rs b/src/test/rustdoc/issue-21801.rs index 2a586b6ff6cdc..29d2ec64c206d 100644 --- a/src/test/rustdoc/issue-21801.rs +++ b/src/test/rustdoc/issue-21801.rs @@ -5,5 +5,5 @@ extern crate issue_21801; // @has issue_21801/struct.Foo.html // @has - '//*[@id="method.new"]' \ -// 'fn new(f: F) -> Foo where F: FnMut() -> i32' +// 'fn new(f: F) -> Foowhere F: FnMut() -> i32' pub use issue_21801::Foo; diff --git a/src/test/rustdoc/issue-29503.rs b/src/test/rustdoc/issue-29503.rs index 635c3175f8138..134821e1ef3ea 100644 --- a/src/test/rustdoc/issue-29503.rs +++ b/src/test/rustdoc/issue-29503.rs @@ -5,7 +5,7 @@ pub trait MyTrait { fn my_string(&self) -> String; } -// @has - "//div[@id='implementors-list']//*[@id='impl-MyTrait-for-T']//h3[@class='code-header in-band']" "impl MyTrait for T where T: Debug" +// @has - "//div[@id='implementors-list']//*[@id='impl-MyTrait-for-T']//h3[@class='code-header in-band']" "impl MyTrait for Twhere T: Debug" impl MyTrait for T where T: fmt::Debug, diff --git a/src/test/rustdoc/issue-34928.rs b/src/test/rustdoc/issue-34928.rs index 4184086f622ab..91b67757453d2 100644 --- a/src/test/rustdoc/issue-34928.rs +++ b/src/test/rustdoc/issue-34928.rs @@ -2,5 +2,5 @@ pub trait Bar {} -// @has foo/struct.Foo.html '//pre' 'pub struct Foo(pub T) where T: Bar;' +// @has foo/struct.Foo.html '//pre' 'pub struct Foo(pub T)where T: Bar;' pub struct Foo(pub T) where T: Bar; diff --git a/src/test/rustdoc/issue-50159.rs b/src/test/rustdoc/issue-50159.rs index d88c29217023a..43fb705f58994 100644 --- a/src/test/rustdoc/issue-50159.rs +++ b/src/test/rustdoc/issue-50159.rs @@ -11,8 +11,8 @@ impl Signal2 for B where B: Signal { } // @has issue_50159/struct.Switch.html -// @has - '//h3[@class="code-header in-band"]' 'impl Send for Switch where ::Item: Send' -// @has - '//h3[@class="code-header in-band"]' 'impl Sync for Switch where ::Item: Sync' +// @has - '//h3[@class="code-header in-band"]' 'impl Send for Switchwhere ::Item: Send' +// @has - '//h3[@class="code-header in-band"]' 'impl Sync for Switchwhere ::Item: Sync' // @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0 // @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]' 5 pub struct Switch { diff --git a/src/test/rustdoc/issue-51236.rs b/src/test/rustdoc/issue-51236.rs index ee11ccc681163..aa5890a84514f 100644 --- a/src/test/rustdoc/issue-51236.rs +++ b/src/test/rustdoc/issue-51236.rs @@ -8,7 +8,7 @@ pub mod traits { // @has issue_51236/struct.Owned.html // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// "impl Send for Owned where >::Reader: Send" +// "impl Send for Ownedwhere >::Reader: Send" pub struct Owned where T: for<'a> ::traits::Owned<'a> { marker: PhantomData<>::Reader>, } diff --git a/src/test/rustdoc/issue-54705.rs b/src/test/rustdoc/issue-54705.rs index bedaf5c4ddc36..ce0f85d25da56 100644 --- a/src/test/rustdoc/issue-54705.rs +++ b/src/test/rustdoc/issue-54705.rs @@ -1,13 +1,11 @@ pub trait ScopeHandle<'scope> {} - - // @has issue_54705/struct.ScopeFutureContents.html // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// "impl<'scope, S> Send for ScopeFutureContents<'scope, S> where S: Sync" +// "impl<'scope, S> Send for ScopeFutureContents<'scope, S>where S: Sync" // // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// "impl<'scope, S> Sync for ScopeFutureContents<'scope, S> where S: Sync" +// "impl<'scope, S> Sync for ScopeFutureContents<'scope, S>where S: Sync" pub struct ScopeFutureContents<'scope, S> where S: ScopeHandle<'scope>, { diff --git a/src/test/rustdoc/issue-98697.rs b/src/test/rustdoc/issue-98697.rs index 83e08094c0953..a8841f137fecf 100644 --- a/src/test/rustdoc/issue-98697.rs +++ b/src/test/rustdoc/issue-98697.rs @@ -8,7 +8,7 @@ extern crate issue_98697_reexport_with_anonymous_lifetime; -// @has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'fn repro() where F: Fn(&str)' +// @has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'fn repro()where F: Fn(&str)' // @!has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'for<' pub use issue_98697_reexport_with_anonymous_lifetime::repro; diff --git a/src/test/rustdoc/primitive-slice-auto-trait.rs b/src/test/rustdoc/primitive-slice-auto-trait.rs index b3f511bc1f153..7f8f74ff457a5 100644 --- a/src/test/rustdoc/primitive-slice-auto-trait.rs +++ b/src/test/rustdoc/primitive-slice-auto-trait.rs @@ -7,8 +7,8 @@ // @has - '//span[@class="in-band"]' 'Primitive Type slice' // @has - '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!' // @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations' -// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Send for [T] where T: Send' -// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Sync for [T] where T: Sync' +// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Send for [T]where T: Send' +// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Sync for [T]where T: Sync' #[doc(primitive = "slice")] /// this is a test! mod slice_prim {} diff --git a/src/test/rustdoc/synthetic_auto/basic.rs b/src/test/rustdoc/synthetic_auto/basic.rs index 54c54fdbf68a8..19138fd1aceb2 100644 --- a/src/test/rustdoc/synthetic_auto/basic.rs +++ b/src/test/rustdoc/synthetic_auto/basic.rs @@ -1,6 +1,6 @@ // @has basic/struct.Foo.html -// @has - '//h3[@class="code-header in-band"]' 'impl Send for Foo where T: Send' -// @has - '//h3[@class="code-header in-band"]' 'impl Sync for Foo where T: Sync' +// @has - '//h3[@class="code-header in-band"]' 'impl Send for Foowhere T: Send' +// @has - '//h3[@class="code-header in-band"]' 'impl Sync for Foowhere T: Sync' // @count - '//*[@id="implementations-list"]//*[@class="impl has-srclink"]' 0 // @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]' 5 pub struct Foo { diff --git a/src/test/rustdoc/synthetic_auto/complex.rs b/src/test/rustdoc/synthetic_auto/complex.rs index f9017b90caee7..39f78983da2b0 100644 --- a/src/test/rustdoc/synthetic_auto/complex.rs +++ b/src/test/rustdoc/synthetic_auto/complex.rs @@ -21,7 +21,7 @@ mod foo { // @has complex/struct.NotOuter.html // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// "impl<'a, T, K: ?Sized> Send for Outer<'a, T, K> where K: for<'b> Fn((&'b bool, &'a u8)) \ +// "impl<'a, T, K: ?Sized> Send for Outer<'a, T, K>where K: for<'b> Fn((&'b bool, &'a u8)) \ // -> &'b i8, T: MyTrait<'a>, >::MyItem: Copy, 'a: 'static" pub use foo::{Foo, Inner as NotInner, MyTrait as NotMyTrait, Outer as NotOuter}; diff --git a/src/test/rustdoc/synthetic_auto/lifetimes.rs b/src/test/rustdoc/synthetic_auto/lifetimes.rs index ee1393f9729c1..0c94850e78608 100644 --- a/src/test/rustdoc/synthetic_auto/lifetimes.rs +++ b/src/test/rustdoc/synthetic_auto/lifetimes.rs @@ -10,10 +10,10 @@ where // @has lifetimes/struct.Foo.html // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// "impl<'c, K> Send for Foo<'c, K> where K: for<'b> Fn(&'b bool) -> &'c u8, 'c: 'static" +// "impl<'c, K> Send for Foo<'c, K>where K: for<'b> Fn(&'b bool) -> &'c u8, 'c: 'static" // // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// "impl<'c, K> Sync for Foo<'c, K> where K: Sync" +// "impl<'c, K> Sync for Foo<'c, K>where K: Sync" pub struct Foo<'c, K: 'c> { inner_field: Inner<'c, K>, } diff --git a/src/test/rustdoc/synthetic_auto/manual.rs b/src/test/rustdoc/synthetic_auto/manual.rs index 49bad162211b7..35047e3e8c071 100644 --- a/src/test/rustdoc/synthetic_auto/manual.rs +++ b/src/test/rustdoc/synthetic_auto/manual.rs @@ -1,6 +1,6 @@ // @has manual/struct.Foo.html // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// 'impl Sync for Foo where T: Sync' +// 'impl Sync for Foowhere T: Sync' // // @has - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ // 'impl Send for Foo' diff --git a/src/test/rustdoc/synthetic_auto/nested.rs b/src/test/rustdoc/synthetic_auto/nested.rs index 69edbee619e31..09587bcc30f13 100644 --- a/src/test/rustdoc/synthetic_auto/nested.rs +++ b/src/test/rustdoc/synthetic_auto/nested.rs @@ -10,10 +10,10 @@ where // @has nested/struct.Foo.html // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// 'impl Send for Foo where T: Copy' +// 'impl Send for Foowhere T: Copy' // // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// 'impl Sync for Foo where T: Sync' +// 'impl Sync for Foowhere T: Sync' pub struct Foo { inner_field: Inner, } diff --git a/src/test/rustdoc/synthetic_auto/no-redundancy.rs b/src/test/rustdoc/synthetic_auto/no-redundancy.rs index 16ab876e829ef..41375decc8a4a 100644 --- a/src/test/rustdoc/synthetic_auto/no-redundancy.rs +++ b/src/test/rustdoc/synthetic_auto/no-redundancy.rs @@ -10,7 +10,7 @@ where // @has no_redundancy/struct.Outer.html // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// "impl Send for Outer where T: Send + Copy" +// "impl Send for Outerwhere T: Send + Copy" pub struct Outer { inner_field: Inner, } diff --git a/src/test/rustdoc/synthetic_auto/project.rs b/src/test/rustdoc/synthetic_auto/project.rs index 8b020582563f3..e80b1b1dc9bcf 100644 --- a/src/test/rustdoc/synthetic_auto/project.rs +++ b/src/test/rustdoc/synthetic_auto/project.rs @@ -24,10 +24,10 @@ where // @has project/struct.Foo.html // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// "impl<'c, K> Send for Foo<'c, K> where K: MyTrait, 'c: 'static" +// "impl<'c, K> Send for Foo<'c, K>where K: MyTrait, 'c: 'static" // // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// "impl<'c, K> Sync for Foo<'c, K> where K: MyTrait, ::MyItem: OtherTrait, \ +// "impl<'c, K> Sync for Foo<'c, K>where K: MyTrait, ::MyItem: OtherTrait, \ // 'c: 'static," pub struct Foo<'c, K: 'c> { inner_field: Inner<'c, K>, diff --git a/src/test/rustdoc/synthetic_auto/self-referential.rs b/src/test/rustdoc/synthetic_auto/self-referential.rs index ccef901b18da3..d15a8de7d2fe1 100644 --- a/src/test/rustdoc/synthetic_auto/self-referential.rs +++ b/src/test/rustdoc/synthetic_auto/self-referential.rs @@ -24,6 +24,6 @@ impl Pattern for Wrapper { // @has self_referential/struct.WriteAndThen.html // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// "impl Send for WriteAndThen where ::Value: Send" +// "impl Send for WriteAndThenwhere ::Value: Send" pub struct WriteAndThen(pub P1::Value,pub > as Pattern>::Value) where P1: Pattern; diff --git a/src/test/rustdoc/synthetic_auto/static-region.rs b/src/test/rustdoc/synthetic_auto/static-region.rs index 36e985144b0e0..08e9567313e22 100644 --- a/src/test/rustdoc/synthetic_auto/static-region.rs +++ b/src/test/rustdoc/synthetic_auto/static-region.rs @@ -4,7 +4,7 @@ pub trait OwnedTrait<'a> { // @has static_region/struct.Owned.html // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// "impl Send for Owned where >::Reader: Send" +// "impl Send for Ownedwhere >::Reader: Send" pub struct Owned where T: OwnedTrait<'static> { marker: >::Reader, } diff --git a/src/test/rustdoc/where-clause-order.rs b/src/test/rustdoc/where-clause-order.rs index 3150a8ea05f41..b8502e10a48c4 100644 --- a/src/test/rustdoc/where-clause-order.rs +++ b/src/test/rustdoc/where-clause-order.rs @@ -7,7 +7,7 @@ where } // @has 'foo/trait.SomeTrait.html' -// @has - "//*[@id='impl-SomeTrait%3C(A%2C%20B%2C%20C%2C%20D%2C%20E)%3E-for-(A%2C%20B%2C%20C%2C%20D%2C%20E)']/h3" "impl SomeTrait<(A, B, C, D, E)> for (A, B, C, D, E) where A: PartialOrd + PartialEq, B: PartialOrd + PartialEq, C: PartialOrd + PartialEq, D: PartialOrd + PartialEq, E: PartialOrd + PartialEq + ?Sized, " +// @has - "//*[@id='impl-SomeTrait%3C(A%2C%20B%2C%20C%2C%20D%2C%20E)%3E-for-(A%2C%20B%2C%20C%2C%20D%2C%20E)']/h3" "impl SomeTrait<(A, B, C, D, E)> for (A, B, C, D, E)where A: PartialOrd + PartialEq, B: PartialOrd + PartialEq, C: PartialOrd + PartialEq, D: PartialOrd + PartialEq, E: PartialOrd + PartialEq + ?Sized, " impl SomeTrait<(A, B, C, D, E)> for (A, B, C, D, E) where A: PartialOrd + PartialEq, diff --git a/src/test/rustdoc/where.rs b/src/test/rustdoc/where.rs index 50a5722fbaff6..c1a630e25ba0e 100644 --- a/src/test/rustdoc/where.rs +++ b/src/test/rustdoc/where.rs @@ -3,17 +3,17 @@ pub trait MyTrait { fn dummy(&self) { } } -// @has foo/struct.Alpha.html '//pre' "pub struct Alpha(_) where A: MyTrait" +// @has foo/struct.Alpha.html '//pre' "pub struct Alpha(_)where A: MyTrait" pub struct Alpha(A) where A: MyTrait; -// @has foo/trait.Bravo.html '//pre' "pub trait Bravo where B: MyTrait" +// @has foo/trait.Bravo.html '//pre' "pub trait Bravowhere B: MyTrait" pub trait Bravo where B: MyTrait { fn get(&self, B: B); } -// @has foo/fn.charlie.html '//pre' "pub fn charlie() where C: MyTrait" +// @has foo/fn.charlie.html '//pre' "pub fn charlie()where C: MyTrait" pub fn charlie() where C: MyTrait {} pub struct Delta(D); // @has foo/struct.Delta.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// "impl Delta where D: MyTrait" +// "impl Deltawhere D: MyTrait" impl Delta where D: MyTrait { pub fn delta() {} } @@ -33,19 +33,19 @@ pub trait TraitWhere { } // @has foo/struct.Echo.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// "impl MyTrait for Echo where E: MyTrait" +// "impl MyTrait for Echowhere E: MyTrait" // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header in-band"]' \ -// "impl MyTrait for Echo where E: MyTrait" -impl MyTrait for Echo where E: MyTrait {} +// "impl MyTrait for Echowhere E: MyTrait" +impl MyTrait for Echowhere E: MyTrait {} pub enum Foxtrot { Foxtrot1(F) } // @has foo/enum.Foxtrot.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ -// "impl MyTrait for Foxtrot where F: MyTrait" +// "impl MyTrait for Foxtrotwhere F: MyTrait" // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header in-band"]' \ -// "impl MyTrait for Foxtrot where F: MyTrait" -impl MyTrait for Foxtrot where F: MyTrait {} +// "impl MyTrait for Foxtrotwhere F: MyTrait" +impl MyTrait for Foxtrotwhere F: MyTrait {} // @has foo/type.Golf.html '//pre[@class="rust typedef"]' \ -// "type Golf where T: Clone, = (T, T)" +// "type Golfwhere T: Clone, = (T, T)" pub type Golf where T: Clone = (T, T); From b112bfeda9dba77c6d7e8eef92125e7002c43e68 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 31 Aug 2022 18:13:59 +0200 Subject: [PATCH 14/18] Add rustdoc GUI test --- src/test/rustdoc-gui/where-whitespace.goml | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/test/rustdoc-gui/where-whitespace.goml diff --git a/src/test/rustdoc-gui/where-whitespace.goml b/src/test/rustdoc-gui/where-whitespace.goml new file mode 100644 index 0000000000000..1a3ff1f491cbb --- /dev/null +++ b/src/test/rustdoc-gui/where-whitespace.goml @@ -0,0 +1,27 @@ +// This test ensures that the where conditions are correctly displayed. +goto: file://|DOC_PATH|/lib2/trait.Whitespace.html +show-text: true +// First, we check in the trait definition if the where clause is "on its own" (not on the same +// line than "pub trait Whitespace"). +compare-elements-position-false: (".item-decl code", ".where.fmt-newline", ("y")) +// And that the code following it isn't on the same line either. +compare-elements-position-false: (".item-decl .fnname", ".where.fmt-newline", ("y")) + +goto: file://|DOC_PATH|/lib2/struct.WhereWhitespace.html +// We make the screen a bit wider to ensure that the trait impl is on one line. +size: (915, 915) + +compare-elements-position-false: ("#method\.new .fnname", "#method\.new .where.fmt-newline", ("y")) +// We ensure that both the trait name and the struct name are on the same line in +// "impl Whitespace<&K> for WhereWhitespace". +compare-elements-position: ( + "#trait-implementations-list .impl h3 .trait", + "#trait-implementations-list .impl h3 .struct", + ("y"), +) +// And we now check that the where condition isn't on the same line. +compare-elements-position-false: ( + "#trait-implementations-list .impl h3 .trait", + "#trait-implementations-list .impl h3 .where.fmt-newline", + ("y"), +) From f8af91950c71d7d7269af13253744e068f6cbcd7 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 11 Aug 2022 19:50:48 +0200 Subject: [PATCH 15/18] Add warning against unexpected --cfg with --check-cfg --- .../locales/en-US/lint.ftl | 6 ++++ compiler/rustc_lint/src/builtin.rs | 36 +++++++++++++++++++ compiler/rustc_lint/src/lib.rs | 1 + compiler/rustc_lint_defs/src/builtin.rs | 1 - src/test/ui/check-cfg/allow-at-crate-level.rs | 8 +++++ .../ui/check-cfg/invalid-cfg-value.stderr | 6 +++- src/test/ui/check-cfg/mix.rs | 2 +- src/test/ui/check-cfg/mix.stderr | 10 +++++- 8 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/check-cfg/allow-at-crate-level.rs diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl index 27ad3e4536601..7f9918e4f128f 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl @@ -354,6 +354,12 @@ lint_builtin_unreachable_pub = unreachable `pub` {$what} .suggestion = consider restricting its visibility .help = or consider exporting it for use by other crates +lint_builtin_unexpected_cli_config_name = unexpected `{$name}` as condition name + .help = was set with `--cfg` but isn't in the `--check-cfg` expected names + +lint_builtin_unexpected_cli_config_value = unexpected condition value `{$value}` for condition name `{$name}` + .help = was set with `--cfg` but isn't in the `--check-cfg` expected values + lint_builtin_type_alias_bounds_help = use fully disambiguated paths (i.e., `::Assoc`) to refer to associated types in type aliases lint_builtin_type_alias_where_clause = where clauses are not enforced in type aliases diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 868555a72b0d1..d47fa47f47f5a 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -3173,3 +3173,39 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels { } } } + +pub use rustc_session::lint::builtin::UNEXPECTED_CFGS; + +declare_lint_pass!(UnexpectedCfgs => [UNEXPECTED_CFGS]); + +impl EarlyLintPass for UnexpectedCfgs { + fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) { + let cfg = &cx.sess().parse_sess.config; + let check_cfg = &cx.sess().parse_sess.check_config; + for &(name, value) in cfg { + if let Some(names_valid) = &check_cfg.names_valid { + if !names_valid.contains(&name) { + cx.lookup(UNEXPECTED_CFGS, None::, |diag| { + diag.build(fluent::lint::builtin_unexpected_cli_config_name) + .help(fluent::lint::help) + .set_arg("name", name) + .emit(); + }); + } + } + if let Some(value) = value { + if let Some(values) = &check_cfg.values_valid.get(&name) { + if !values.contains(&value) { + cx.lookup(UNEXPECTED_CFGS, None::, |diag| { + diag.build(fluent::lint::builtin_unexpected_cli_config_value) + .help(fluent::lint::help) + .set_arg("name", name) + .set_arg("value", value) + .emit(); + }); + } + } + } + } + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index c3065e4a2d938..3f0dcb61b3fce 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -141,6 +141,7 @@ macro_rules! early_lint_passes { IncompleteFeatures: IncompleteFeatures, RedundantSemicolons: RedundantSemicolons, UnusedDocComment: UnusedDocComment, + UnexpectedCfgs: UnexpectedCfgs, ] ); }; diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 2dca6acdd6d6f..24f58b753fc09 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3365,7 +3365,6 @@ declare_lint_pass! { DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME, DUPLICATE_MACRO_ATTRIBUTES, SUSPICIOUS_AUTO_TRAIT_IMPLS, - UNEXPECTED_CFGS, DEPRECATED_WHERE_CLAUSE_LOCATION, TEST_UNSTABLE_LINT, FFI_UNWIND_CALLS, diff --git a/src/test/ui/check-cfg/allow-at-crate-level.rs b/src/test/ui/check-cfg/allow-at-crate-level.rs new file mode 100644 index 0000000000000..ce3383a2961aa --- /dev/null +++ b/src/test/ui/check-cfg/allow-at-crate-level.rs @@ -0,0 +1,8 @@ +// This test check that #![allow(unexpected_cfgs)] works with --cfg +// +// check-pass +// compile-flags: --cfg=unexpected --check-cfg=names() -Z unstable-options + +#![allow(unexpected_cfgs)] + +fn main() {} diff --git a/src/test/ui/check-cfg/invalid-cfg-value.stderr b/src/test/ui/check-cfg/invalid-cfg-value.stderr index 6cce31d339286..7db2aadec177b 100644 --- a/src/test/ui/check-cfg/invalid-cfg-value.stderr +++ b/src/test/ui/check-cfg/invalid-cfg-value.stderr @@ -15,5 +15,9 @@ LL | #[cfg(feature = "rand")] | = note: expected values for `feature` are: full, serde -warning: 2 warnings emitted +warning: unexpected condition value `rand` for condition name `feature` + | + = help: was set with `--cfg` but isn't in the `--check-cfg` expected values + +warning: 3 warnings emitted diff --git a/src/test/ui/check-cfg/mix.rs b/src/test/ui/check-cfg/mix.rs index 8e3d20d50458f..4e488fc03ec4b 100644 --- a/src/test/ui/check-cfg/mix.rs +++ b/src/test/ui/check-cfg/mix.rs @@ -3,7 +3,7 @@ // we correctly lint on the `cfg!` macro and `cfg_attr` attribute. // // check-pass -// compile-flags: --check-cfg=names() --check-cfg=values(feature,"foo") --cfg feature="bar" -Z unstable-options +// compile-flags: --check-cfg=names() --check-cfg=values(feature,"foo") --cfg feature="bar" --cfg unknown_name -Z unstable-options #[cfg(windows)] fn do_windows_stuff() {} diff --git a/src/test/ui/check-cfg/mix.stderr b/src/test/ui/check-cfg/mix.stderr index e51b75b3d4358..65603c2130ee3 100644 --- a/src/test/ui/check-cfg/mix.stderr +++ b/src/test/ui/check-cfg/mix.stderr @@ -28,6 +28,14 @@ warning: unexpected `cfg` condition name LL | #[cfg_attr(uu, test)] | ^^ +warning: unexpected `unknown_name` as condition name + | + = help: was set with `--cfg` but isn't in the `--check-cfg` expected names + +warning: unexpected condition value `bar` for condition name `feature` + | + = help: was set with `--cfg` but isn't in the `--check-cfg` expected values + warning: unexpected `cfg` condition name --> $DIR/mix.rs:35:10 | @@ -170,5 +178,5 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | = note: expected values for `feature` are: foo -warning: 25 warnings emitted +warning: 27 warnings emitted From a928255ab1c6a594faa15f93d912c1179ae354ea Mon Sep 17 00:00:00 2001 From: Matt Hamrick Date: Wed, 31 Aug 2022 13:21:47 -0700 Subject: [PATCH 16/18] Fix bad target name in Walkthrough Walkthrough currently say: ``` rustup target add aarch_64-fuchsia ``` but should say ``` rustup target add aarch64-fuchsia ``` --- src/doc/rustc/src/platform-support/fuchsia.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md index c2a1613f288c5..94373b01cc469 100644 --- a/src/doc/rustc/src/platform-support/fuchsia.md +++ b/src/doc/rustc/src/platform-support/fuchsia.md @@ -79,7 +79,7 @@ the following commands: ```sh rustup target add x86_64-fuchsia -rustup target add aarch_64-fuchsia +rustup target add aarch64-fuchsia ``` After installing our Fuchsia targets, we can now compile a Rust binary that targets From 037a911bd8f223a15a500c172e1b8d030c9a05f3 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 31 Aug 2022 10:06:48 -0700 Subject: [PATCH 17/18] rustdoc: remove unused `.docblock .impl-items` CSS The impl-items list stopped being nested inside a docblock since c1b1d6804bfce1aee3a95b3cbff3eaeb15bad9a4 --- src/librustdoc/html/static/css/rustdoc.css | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index c117e3ac40dab..00d2300877284 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -759,14 +759,6 @@ pre, .rustdoc.source .example-wrap { margin-bottom: 15px; } -.content .docblock > .impl-items { - margin-left: 20px; - margin-top: -34px; -} -.content .docblock >.impl-items table td { - padding: 0; -} - .item-info { display: block; } From d8b572b820e2c1b59a26d28fc2c6234e34aedc6d Mon Sep 17 00:00:00 2001 From: Andrew Pollack Date: Wed, 31 Aug 2022 23:49:48 +0000 Subject: [PATCH 18/18] Tweaks to fuchsia doc walkthrough --- src/doc/rustc/src/platform-support/fuchsia.md | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md index c2a1613f288c5..10d12f88454d1 100644 --- a/src/doc/rustc/src/platform-support/fuchsia.md +++ b/src/doc/rustc/src/platform-support/fuchsia.md @@ -125,13 +125,20 @@ during compilation: [target.x86_64-fuchsia] rustflags = [ - "-Lnative", "/arch/x64/sysroot/lib", - "-Lnative", "/arch/x64/lib" + "-Lnative=/arch/x64/lib", + "-Lnative=/arch/x64/sysroot/lib" ] ``` *Note: Make sure to fill out `` with the path to the downloaded [Fuchsia SDK].* +These options configure the following: + +* `-Lnative=${SDK_PATH}/arch/${ARCH}/lib`: Link against Fuchsia libraries from + the SDK +* `-Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib`: Link against Fuchsia kernel + libraries from the SDK + In total, our new project will look like: **Current directory structure** @@ -368,6 +375,7 @@ language called CML. The Fuchsia devsite contains an [overview of CML] and a } ``` +**Current directory structure** ```txt hello_fuchsia/ ┗━ pkg/ @@ -386,6 +394,9 @@ ${SDK_PATH}/tools/${ARCH}/cmc compile \ -o pkg/meta/hello_fuchsia.cm ``` +*Note: `--includepath` tells the compiler where to look for `include`s from our CML. +In our case, we're only using `syslog/client.shard.cml`.* + **Current directory structure** ```txt hello_fuchsia/ @@ -397,19 +408,16 @@ hello_fuchsia/ ┗━ hello_fuchsia.cml ``` -*Note: `--includepath` tells the compiler where to look for `include`s from our CML. -In our case, we're only using `syslog/client.shard.cml`.* - ### Building a Fuchsia package Next, we'll build a package manifest as defined by our manifest: ```sh ${SDK_PATH}/tools/${ARCH}/pm \ - -o hello_fuchsia_manifest \ + -o pkg/hello_fuchsia_manifest \ -m pkg/hello_fuchsia.manifest \ build \ - -output-package-manifest hello_fuchsia_package_manifest + -output-package-manifest pkg/hello_fuchsia_package_manifest ``` This will produce `pkg/hello_fuchsia_manifest/` which is a package manifest we can @@ -469,15 +477,15 @@ We can publish our new package to that repository with: ```sh ${SDK_PATH}/tools/${ARCH}/pm publish \ - -repo repo \ - -lp -f <(echo "hello_fuchsia_package_manifest") + -repo pkg/repo \ + -lp -f <(echo "pkg/hello_fuchsia_package_manifest") ``` Then we can add the repository to `ffx`'s package server as `hello-fuchsia` using: ```sh ${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm \ - repo \ + pkg/repo \ -r hello-fuchsia ```