diff --git a/Cargo.lock b/Cargo.lock index 959c8161e984d..a912eee97dbf2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -175,9 +175,7 @@ dependencies = [ "filetime", "getopts", "ignore", - "lazy_static", "libc", - "merge", "num_cpus", "once_cell", "opener", @@ -2221,28 +2219,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "merge" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10bbef93abb1da61525bbc45eeaff6473a41907d19f8f9aa5168d214e10693e9" -dependencies = [ - "merge_derive", - "num-traits", -] - -[[package]] -name = "merge_derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209d075476da2e63b4b29e72a2ef627b840589588e71400a25e3565c4f849d07" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "minifier" version = "0.0.41" diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 2904b3f5b7071..3804e10030733 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -11,7 +11,7 @@ use rustc_errors::registry::Registry; use rustc_errors::{ErrorReported, Handler}; use rustc_lint::LintStore; use rustc_middle::ty; -use rustc_parse::new_parser_from_source_str; +use rustc_parse::maybe_new_parser_from_source_str; use rustc_query_impl::QueryCtxt; use rustc_session::config::{self, ErrorOutputType, Input, OutputFilenames}; use rustc_session::early_error; @@ -91,7 +91,6 @@ pub fn parse_cfgspecs(cfgspecs: Vec) -> FxHashSet<(String, Option { @@ -102,26 +101,27 @@ pub fn parse_cfgspecs(cfgspecs: Vec) -> FxHashSet<(String, Option { - if meta_item.path.segments.len() != 1 { - error!("argument key must be an identifier"); - } - match &meta_item.kind { - MetaItemKind::List(..) => { - error!(r#"expected `key` or `key="value"`"#); - } - MetaItemKind::NameValue(lit) if !lit.kind.is_str() => { - error!("argument value must be a string"); + match maybe_new_parser_from_source_str(&sess, filename, s.to_string()) { + Ok(mut parser) => match &mut parser.parse_meta_item() { + Ok(meta_item) if parser.token == token::Eof => { + if meta_item.path.segments.len() != 1 { + error!("argument key must be an identifier"); } - MetaItemKind::NameValue(..) | MetaItemKind::Word => { - let ident = meta_item.ident().expect("multi-segment cfg key"); - return (ident.name, meta_item.value_str()); + match &meta_item.kind { + MetaItemKind::List(..) => {} + MetaItemKind::NameValue(lit) if !lit.kind.is_str() => { + error!("argument value must be a string"); + } + MetaItemKind::NameValue(..) | MetaItemKind::Word => { + let ident = meta_item.ident().expect("multi-segment cfg key"); + return (ident.name, meta_item.value_str()); + } } } - } - Ok(..) => {} - Err(err) => err.cancel(), + Ok(..) => {} + Err(err) => err.cancel(), + }, + Err(errs) => errs.into_iter().for_each(|mut err| err.cancel()), } error!(r#"expected `key` or `key="value"`"#); diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index fffdc2c3ac09d..6fdaa8b950aa1 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -148,7 +148,7 @@ use self::spec_extend::SpecExtend; #[cfg(not(no_global_oom_handling))] mod spec_extend; -/// A contiguous growable array type, written as `Vec` and pronounced 'vector'. +/// A contiguous growable array type, written as `Vec`, short for 'vector'. /// /// # Examples /// diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 5ef23871e8b5f..c64377dfbc8ac 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -349,6 +349,33 @@ impl HashMap { Keys { inner: self.iter() } } + /// Creates a consuming iterator visiting all the keys in arbitrary order. + /// The map cannot be used after calling this. + /// The iterator element type is `K`. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let map = HashMap::from([ + /// ("a", 1), + /// ("b", 2), + /// ("c", 3), + /// ]); + /// + /// let mut vec: Vec<&str> = map.into_keys().collect(); + /// // The `IntoKeys` iterator produces keys in arbitrary order, so the + /// // keys must be sorted to test them against a sorted array. + /// vec.sort_unstable(); + /// assert_eq!(vec, ["a", "b", "c"]); + /// ``` + #[inline] + #[stable(feature = "map_into_keys_values", since = "1.54.0")] + pub fn into_keys(self) -> IntoKeys { + IntoKeys { inner: self.into_iter() } + } + /// An iterator visiting all values in arbitrary order. /// The iterator element type is `&'a V`. /// @@ -399,6 +426,33 @@ impl HashMap { ValuesMut { inner: self.iter_mut() } } + /// Creates a consuming iterator visiting all the values in arbitrary order. + /// The map cannot be used after calling this. + /// The iterator element type is `V`. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let map = HashMap::from([ + /// ("a", 1), + /// ("b", 2), + /// ("c", 3), + /// ]); + /// + /// let mut vec: Vec = map.into_values().collect(); + /// // The `IntoValues` iterator produces values in arbitrary order, so + /// // the values must be sorted to test them against a sorted array. + /// vec.sort_unstable(); + /// assert_eq!(vec, [1, 2, 3]); + /// ``` + #[inline] + #[stable(feature = "map_into_keys_values", since = "1.54.0")] + pub fn into_values(self) -> IntoValues { + IntoValues { inner: self.into_iter() } + } + /// An iterator visiting all key-value pairs in arbitrary order. /// The iterator element type is `(&'a K, &'a V)`. /// @@ -555,6 +609,29 @@ impl HashMap { DrainFilter { base: self.base.drain_filter(pred) } } + /// Retains only the elements specified by the predicate. + /// + /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. + /// The elements are visited in unsorted (and unspecified) order. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map: HashMap = (0..8).map(|x| (x, x*10)).collect(); + /// map.retain(|&k, _| k % 2 == 0); + /// assert_eq!(map.len(), 4); + /// ``` + #[inline] + #[stable(feature = "retain_hash_collection", since = "1.18.0")] + pub fn retain(&mut self, f: F) + where + F: FnMut(&K, &mut V) -> bool, + { + self.base.retain(f) + } + /// Clears the map, removing all key-value pairs. Keeps the allocated memory /// for reuse. /// @@ -937,83 +1014,6 @@ where { self.base.remove_entry(k) } - - /// Retains only the elements specified by the predicate. - /// - /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. - /// The elements are visited in unsorted (and unspecified) order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::HashMap; - /// - /// let mut map: HashMap = (0..8).map(|x| (x, x*10)).collect(); - /// map.retain(|&k, _| k % 2 == 0); - /// assert_eq!(map.len(), 4); - /// ``` - #[inline] - #[stable(feature = "retain_hash_collection", since = "1.18.0")] - pub fn retain(&mut self, f: F) - where - F: FnMut(&K, &mut V) -> bool, - { - self.base.retain(f) - } - - /// Creates a consuming iterator visiting all the keys in arbitrary order. - /// The map cannot be used after calling this. - /// The iterator element type is `K`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::HashMap; - /// - /// let map = HashMap::from([ - /// ("a", 1), - /// ("b", 2), - /// ("c", 3), - /// ]); - /// - /// let mut vec: Vec<&str> = map.into_keys().collect(); - /// // The `IntoKeys` iterator produces keys in arbitrary order, so the - /// // keys must be sorted to test them against a sorted array. - /// vec.sort_unstable(); - /// assert_eq!(vec, ["a", "b", "c"]); - /// ``` - #[inline] - #[stable(feature = "map_into_keys_values", since = "1.54.0")] - pub fn into_keys(self) -> IntoKeys { - IntoKeys { inner: self.into_iter() } - } - - /// Creates a consuming iterator visiting all the values in arbitrary order. - /// The map cannot be used after calling this. - /// The iterator element type is `V`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::HashMap; - /// - /// let map = HashMap::from([ - /// ("a", 1), - /// ("b", 2), - /// ("c", 3), - /// ]); - /// - /// let mut vec: Vec = map.into_values().collect(); - /// // The `IntoValues` iterator produces values in arbitrary order, so - /// // the values must be sorted to test them against a sorted array. - /// vec.sort_unstable(); - /// assert_eq!(vec, [1, 2, 3]); - /// ``` - #[inline] - #[stable(feature = "map_into_keys_values", since = "1.54.0")] - pub fn into_values(self) -> IntoValues { - IntoValues { inner: self.into_iter() } - } } impl HashMap diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index a1e28c0b0a695..0d087772bf931 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -290,6 +290,28 @@ impl HashSet { DrainFilter { base: self.base.drain_filter(pred) } } + /// Retains only the elements specified by the predicate. + /// + /// In other words, remove all elements `e` such that `f(&e)` returns `false`. + /// The elements are visited in unsorted (and unspecified) order. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut set = HashSet::from([1, 2, 3, 4, 5, 6]); + /// set.retain(|&k| k % 2 == 0); + /// assert_eq!(set.len(), 3); + /// ``` + #[stable(feature = "retain_hash_collection", since = "1.18.0")] + pub fn retain(&mut self, f: F) + where + F: FnMut(&T) -> bool, + { + self.base.retain(f) + } + /// Clears the set, removing all values. /// /// # Examples @@ -906,28 +928,6 @@ where { self.base.take(value) } - - /// Retains only the elements specified by the predicate. - /// - /// In other words, remove all elements `e` such that `f(&e)` returns `false`. - /// The elements are visited in unsorted (and unspecified) order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::HashSet; - /// - /// let mut set = HashSet::from([1, 2, 3, 4, 5, 6]); - /// set.retain(|&k| k % 2 == 0); - /// assert_eq!(set.len(), 3); - /// ``` - #[stable(feature = "retain_hash_collection", since = "1.18.0")] - pub fn retain(&mut self, f: F) - where - F: FnMut(&T) -> bool, - { - self.base.retain(f) - } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index bcf2ec06022d9..9f7f10d0d0081 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -972,10 +972,13 @@ pub fn park_timeout(dur: Duration) { /// A unique identifier for a running thread. /// -/// A `ThreadId` is an opaque object that has a unique value for each thread -/// that creates one. `ThreadId`s are not guaranteed to correspond to a thread's -/// system-designated identifier. A `ThreadId` can be retrieved from the [`id`] -/// method on a [`Thread`]. +/// A `ThreadId` is an opaque object that uniquely identifies each thread +/// created during the lifetime of a process. `ThreadId`s are guaranteed not to +/// be reused, even when a thread terminates. `ThreadId`s are under the control +/// of Rust's standard library and there may not be any relationship between +/// `ThreadId` and the underlying platform's notion of a thread identifier -- +/// the two concepts cannot, therefore, be used interchangeably. A `ThreadId` +/// can be retrieved from the [`id`] method on a [`Thread`]. /// /// # Examples /// diff --git a/rustfmt.toml b/rustfmt.toml index 265f2194fef8d..aa0d4888f082d 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -19,7 +19,6 @@ ignore = [ "library/backtrace", "library/portable-simd", "library/stdarch", - "compiler/rustc_codegen_cranelift", "compiler/rustc_codegen_gcc", "src/doc/book", "src/doc/edition-guide", @@ -36,4 +35,9 @@ ignore = [ "src/tools/rust-analyzer", "src/tools/rustfmt", "src/tools/rust-installer", + + # these are ignored by a standard cargo fmt run + "compiler/rustc_codegen_cranelift/y.rs", # running rustfmt breaks this file + "compiler/rustc_codegen_cranelift/example", + "compiler/rustc_codegen_cranelift/scripts", ] diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 1ce1f0b26db58..b68b2163f873a 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -44,11 +44,9 @@ libc = "0.2" serde = { version = "1.0.8", features = ["derive"] } serde_json = "1.0.2" toml = "0.5" -lazy_static = "1.3.0" time = "0.1" ignore = "0.4.10" opener = "0.5" -merge = "0.1.0" once_cell = "1.7.2" [target.'cfg(windows)'.dependencies.winapi] diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index ed53a98e9a53f..7105a2457e282 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -15,6 +15,8 @@ //! switching compilers for the bootstrap and for build scripts will probably //! never get replaced. +include!("../dylib_util.rs"); + use std::env; use std::path::PathBuf; use std::process::{Child, Command}; @@ -50,11 +52,11 @@ fn main() { let rustc = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc)); let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir)); - let mut dylib_path = bootstrap::util::dylib_path(); + let mut dylib_path = dylib_path(); dylib_path.insert(0, PathBuf::from(&libdir)); let mut cmd = Command::new(rustc); - cmd.args(&args).env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); + cmd.args(&args).env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); // Get the name of the crate we're compiling, if any. let crate_name = @@ -161,7 +163,7 @@ fn main() { eprintln!( "{} command: {:?}={:?} {:?}", prefix, - bootstrap::util::dylib_path_var(), + dylib_path_var(), env::join_paths(&dylib_path).unwrap(), cmd, ); diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index e4396d53016ea..ad3800834b07c 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -7,6 +7,8 @@ use std::ffi::OsString; use std::path::PathBuf; use std::process::Command; +include!("../dylib_util.rs"); + fn main() { let args = env::args_os().skip(1).collect::>(); let rustdoc = env::var_os("RUSTDOC_REAL").expect("RUSTDOC_REAL was not set"); @@ -20,14 +22,14 @@ fn main() { Err(_) => 0, }; - let mut dylib_path = bootstrap::util::dylib_path(); + let mut dylib_path = dylib_path(); dylib_path.insert(0, PathBuf::from(libdir.clone())); let mut cmd = Command::new(rustdoc); cmd.args(&args) .arg("--sysroot") .arg(&sysroot) - .env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); + .env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); // Force all crates compiled by this compiler to (a) be unstable and (b) // allow the `rustc_private` feature to link to other unstable crates @@ -59,7 +61,7 @@ fn main() { if verbose > 1 { eprintln!( "rustdoc command: {:?}={:?} {:?}", - bootstrap::util::dylib_path_var(), + dylib_path_var(), env::join_paths(&dylib_path).unwrap(), cmd, ); diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index bbd2c087ccabb..917abde9de1ce 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -351,7 +351,6 @@ pub enum Kind { Check, Clippy, Fix, - Format, Test, Bench, Dist, @@ -399,7 +398,7 @@ impl<'a> Builder<'a> { native::Lld, native::CrtBeginEnd ), - Kind::Check | Kind::Clippy { .. } | Kind::Fix | Kind::Format => describe!( + Kind::Check | Kind::Clippy { .. } | Kind::Fix => describe!( check::Std, check::Rustc, check::Rustdoc, diff --git a/src/bootstrap/cache.rs b/src/bootstrap/cache.rs index 0c16fae01bca7..fac5d8db5119d 100644 --- a/src/bootstrap/cache.rs +++ b/src/bootstrap/cache.rs @@ -13,7 +13,8 @@ use std::ops::Deref; use std::path::{Path, PathBuf}; use std::sync::Mutex; -use lazy_static::lazy_static; +// FIXME: replace with std::lazy after it gets stabilized and reaches beta +use once_cell::sync::Lazy; use crate::builder::Step; @@ -222,9 +223,7 @@ impl Interner { } } -lazy_static! { - pub static ref INTERNER: Interner = Interner::default(); -} +pub static INTERNER: Lazy = Lazy::new(Interner::default); /// This is essentially a `HashMap` which allows storing any type in its input and /// any type in its output. It is a write-once cache; values are never evicted, diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 7a4593a75f280..5af9248583cae 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -18,7 +18,6 @@ pub use crate::flags::Subcommand; use crate::flags::{Color, Flags}; use crate::util::exe; use build_helper::t; -use merge::Merge; use serde::Deserialize; macro_rules! check_ci_llvm { @@ -334,6 +333,10 @@ struct TomlConfig { profile: Option, } +trait Merge { + fn merge(&mut self, other: Self); +} + impl Merge for TomlConfig { fn merge( &mut self, @@ -357,105 +360,136 @@ impl Merge for TomlConfig { } } -/// TOML representation of various global build decisions. -#[derive(Deserialize, Default, Clone, Merge)] -#[serde(deny_unknown_fields, rename_all = "kebab-case")] -struct Build { - build: Option, - host: Option>, - target: Option>, - // This is ignored, the rust code always gets the build directory from the `BUILD_DIR` env variable - build_dir: Option, - cargo: Option, - rustc: Option, - rustfmt: Option, - docs: Option, - compiler_docs: Option, - docs_minification: Option, - submodules: Option, - fast_submodules: Option, - gdb: Option, - nodejs: Option, - npm: Option, - python: Option, - locked_deps: Option, - vendor: Option, - full_bootstrap: Option, - extended: Option, - tools: Option>, - verbose: Option, - sanitizers: Option, - profiler: Option, - cargo_native_static: Option, - low_priority: Option, - configure_args: Option>, - local_rebuild: Option, - print_step_timings: Option, - print_step_rusage: Option, - check_stage: Option, - doc_stage: Option, - build_stage: Option, - test_stage: Option, - install_stage: Option, - dist_stage: Option, - bench_stage: Option, - patch_binaries_for_nix: Option, +// We are using a decl macro instead of a derive proc macro here to reduce the compile time of +// rustbuild. +macro_rules! derive_merge { + ($(#[$attr:meta])* struct $name:ident { + $($field:ident: $field_ty:ty,)* + }) => { + $(#[$attr])* + struct $name { + $($field: $field_ty,)* + } + + impl Merge for $name { + fn merge(&mut self, other: Self) { + $( + if !self.$field.is_some() { + self.$field = other.$field; + } + )* + } + } + } } -/// TOML representation of various global install decisions. -#[derive(Deserialize, Default, Clone, Merge)] -#[serde(deny_unknown_fields, rename_all = "kebab-case")] -struct Install { - prefix: Option, - sysconfdir: Option, - docdir: Option, - bindir: Option, - libdir: Option, - mandir: Option, - datadir: Option, +derive_merge! { + /// TOML representation of various global build decisions. + #[derive(Deserialize, Default, Clone)] + #[serde(deny_unknown_fields, rename_all = "kebab-case")] + struct Build { + build: Option, + host: Option>, + target: Option>, + // This is ignored, the rust code always gets the build directory from the `BUILD_DIR` env variable + build_dir: Option, + cargo: Option, + rustc: Option, + rustfmt: Option, + docs: Option, + compiler_docs: Option, + docs_minification: Option, + submodules: Option, + fast_submodules: Option, + gdb: Option, + nodejs: Option, + npm: Option, + python: Option, + locked_deps: Option, + vendor: Option, + full_bootstrap: Option, + extended: Option, + tools: Option>, + verbose: Option, + sanitizers: Option, + profiler: Option, + cargo_native_static: Option, + low_priority: Option, + configure_args: Option>, + local_rebuild: Option, + print_step_timings: Option, + print_step_rusage: Option, + check_stage: Option, + doc_stage: Option, + build_stage: Option, + test_stage: Option, + install_stage: Option, + dist_stage: Option, + bench_stage: Option, + patch_binaries_for_nix: Option, + } } -/// TOML representation of how the LLVM build is configured. -#[derive(Deserialize, Default, Merge)] -#[serde(deny_unknown_fields, rename_all = "kebab-case")] -struct Llvm { - skip_rebuild: Option, - optimize: Option, - thin_lto: Option, - release_debuginfo: Option, - assertions: Option, - tests: Option, - plugins: Option, - ccache: Option, - version_check: Option, - static_libstdcpp: Option, - ninja: Option, - targets: Option, - experimental_targets: Option, - link_jobs: Option, - link_shared: Option, - version_suffix: Option, - clang_cl: Option, - cflags: Option, - cxxflags: Option, - ldflags: Option, - use_libcxx: Option, - use_linker: Option, - allow_old_toolchain: Option, - polly: Option, - clang: Option, - download_ci_llvm: Option, +derive_merge! { + /// TOML representation of various global install decisions. + #[derive(Deserialize, Default, Clone)] + #[serde(deny_unknown_fields, rename_all = "kebab-case")] + struct Install { + prefix: Option, + sysconfdir: Option, + docdir: Option, + bindir: Option, + libdir: Option, + mandir: Option, + datadir: Option, + } } -#[derive(Deserialize, Default, Clone, Merge)] -#[serde(deny_unknown_fields, rename_all = "kebab-case")] -struct Dist { - sign_folder: Option, - gpg_password_file: Option, - upload_addr: Option, - src_tarball: Option, - missing_tools: Option, - compression_formats: Option>, +derive_merge! { + /// TOML representation of how the LLVM build is configured. + #[derive(Deserialize, Default)] + #[serde(deny_unknown_fields, rename_all = "kebab-case")] + struct Llvm { + skip_rebuild: Option, + optimize: Option, + thin_lto: Option, + release_debuginfo: Option, + assertions: Option, + tests: Option, + plugins: Option, + ccache: Option, + version_check: Option, + static_libstdcpp: Option, + ninja: Option, + targets: Option, + experimental_targets: Option, + link_jobs: Option, + link_shared: Option, + version_suffix: Option, + clang_cl: Option, + cflags: Option, + cxxflags: Option, + ldflags: Option, + use_libcxx: Option, + use_linker: Option, + allow_old_toolchain: Option, + polly: Option, + clang: Option, + download_ci_llvm: Option, + } +} + +derive_merge! { + #[derive(Deserialize, Default, Clone)] + #[serde(deny_unknown_fields, rename_all = "kebab-case")] + struct Dist { + sign_folder: Option, + gpg_password_file: Option, + upload_addr: Option, + src_tarball: Option, + missing_tools: Option, + compression_formats: Option>, + } } #[derive(Deserialize)] @@ -471,80 +505,84 @@ impl Default for StringOrBool { } } -/// TOML representation of how the Rust build is configured. -#[derive(Deserialize, Default, Merge)] -#[serde(deny_unknown_fields, rename_all = "kebab-case")] -struct Rust { - optimize: Option, - debug: Option, - codegen_units: Option, - codegen_units_std: Option, - debug_assertions: Option, - debug_assertions_std: Option, - overflow_checks: Option, - overflow_checks_std: Option, - debug_logging: Option, - debuginfo_level: Option, - debuginfo_level_rustc: Option, - debuginfo_level_std: Option, - debuginfo_level_tools: Option, - debuginfo_level_tests: Option, - run_dsymutil: Option, - backtrace: Option, - incremental: Option, - parallel_compiler: Option, - default_linker: Option, - channel: Option, - description: Option, - musl_root: Option, - rpath: Option, - verbose_tests: Option, - optimize_tests: Option, - codegen_tests: Option, - ignore_git: Option, - dist_src: Option, - save_toolstates: Option, - codegen_backends: Option>, - lld: Option, - use_lld: Option, - llvm_tools: Option, - deny_warnings: Option, - backtrace_on_ice: Option, - verify_llvm_ir: Option, - thin_lto_import_instr_limit: Option, - remap_debuginfo: Option, - jemalloc: Option, - test_compare_mode: Option, - llvm_libunwind: Option, - control_flow_guard: Option, - new_symbol_mangling: Option, - profile_generate: Option, - profile_use: Option, - // ignored; this is set from an env var set by bootstrap.py - download_rustc: Option, +derive_merge! { + /// TOML representation of how the Rust build is configured. + #[derive(Deserialize, Default)] + #[serde(deny_unknown_fields, rename_all = "kebab-case")] + struct Rust { + optimize: Option, + debug: Option, + codegen_units: Option, + codegen_units_std: Option, + debug_assertions: Option, + debug_assertions_std: Option, + overflow_checks: Option, + overflow_checks_std: Option, + debug_logging: Option, + debuginfo_level: Option, + debuginfo_level_rustc: Option, + debuginfo_level_std: Option, + debuginfo_level_tools: Option, + debuginfo_level_tests: Option, + run_dsymutil: Option, + backtrace: Option, + incremental: Option, + parallel_compiler: Option, + default_linker: Option, + channel: Option, + description: Option, + musl_root: Option, + rpath: Option, + verbose_tests: Option, + optimize_tests: Option, + codegen_tests: Option, + ignore_git: Option, + dist_src: Option, + save_toolstates: Option, + codegen_backends: Option>, + lld: Option, + use_lld: Option, + llvm_tools: Option, + deny_warnings: Option, + backtrace_on_ice: Option, + verify_llvm_ir: Option, + thin_lto_import_instr_limit: Option, + remap_debuginfo: Option, + jemalloc: Option, + test_compare_mode: Option, + llvm_libunwind: Option, + control_flow_guard: Option, + new_symbol_mangling: Option, + profile_generate: Option, + profile_use: Option, + // ignored; this is set from an env var set by bootstrap.py + download_rustc: Option, + } } -/// TOML representation of how each build target is configured. -#[derive(Deserialize, Default, Merge)] -#[serde(deny_unknown_fields, rename_all = "kebab-case")] -struct TomlTarget { - cc: Option, - cxx: Option, - ar: Option, - ranlib: Option, - default_linker: Option, - linker: Option, - llvm_config: Option, - llvm_filecheck: Option, - android_ndk: Option, - sanitizers: Option, - profiler: Option, - crt_static: Option, - musl_root: Option, - musl_libdir: Option, - wasi_root: Option, - qemu_rootfs: Option, - no_std: Option, +derive_merge! { + /// TOML representation of how each build target is configured. + #[derive(Deserialize, Default)] + #[serde(deny_unknown_fields, rename_all = "kebab-case")] + struct TomlTarget { + cc: Option, + cxx: Option, + ar: Option, + ranlib: Option, + default_linker: Option, + linker: Option, + llvm_config: Option, + llvm_filecheck: Option, + android_ndk: Option, + sanitizers: Option, + profiler: Option, + crt_static: Option, + musl_root: Option, + musl_libdir: Option, + wasi_root: Option, + qemu_rootfs: Option, + no_std: Option, + } } impl Config { @@ -1111,10 +1149,6 @@ impl Config { self.verbose > 0 } - pub fn very_verbose(&self) -> bool { - self.verbose > 1 - } - pub fn sanitizers_enabled(&self, target: TargetSelection) -> bool { self.target_config.get(&target).map(|t| t.sanitizers).flatten().unwrap_or(self.sanitizers) } diff --git a/src/bootstrap/dylib_util.rs b/src/bootstrap/dylib_util.rs new file mode 100644 index 0000000000000..6d75272c50130 --- /dev/null +++ b/src/bootstrap/dylib_util.rs @@ -0,0 +1,28 @@ +// Various utilities for working with dylib paths. +// +// This file is meant to be included directly to avoid a dependency on the bootstrap library from +// the rustc and rustdoc wrappers. This improves compilation time by reducing the linking time. + +/// Returns the environment variable which the dynamic library lookup path +/// resides in for this platform. +pub fn dylib_path_var() -> &'static str { + if cfg!(target_os = "windows") { + "PATH" + } else if cfg!(target_os = "macos") { + "DYLD_LIBRARY_PATH" + } else if cfg!(target_os = "haiku") { + "LIBRARY_PATH" + } else { + "LD_LIBRARY_PATH" + } +} + +/// Parses the `dylib_path_var()` environment variable, returning a list of +/// paths that are members of this lookup path. +pub fn dylib_path() -> Vec { + let var = match env::var_os(dylib_path_var()) { + Some(v) => v, + None => return vec![], + }; + env::split_paths(&var).collect() +} diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 82462f9758e5c..8569089f70128 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -110,7 +110,6 @@ use std::fs::{self, File, OpenOptions}; use std::io::{Read, Seek, SeekFrom, Write}; use std::path::{Path, PathBuf}; use std::process::{self, Command}; -use std::slice; use std::str; #[cfg(unix)] @@ -472,10 +471,6 @@ impl Build { build } - pub fn build_triple(&self) -> &[Interned] { - slice::from_ref(&self.build.triple) - } - // modified from `check_submodule` and `update_submodule` in bootstrap.py /// Given a path to the directory of a submodule, update it. /// diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 57178aa382ffd..ee58bedcc8735 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -16,11 +16,6 @@ use build_helper::t; use crate::builder::Builder; use crate::config::{Config, TargetSelection}; -/// Returns the `name` as the filename of a static library for `target`. -pub fn staticlib(name: &str, target: TargetSelection) -> String { - if target.contains("windows") { format!("{}.lib", name) } else { format!("lib{}.a", name) } -} - /// Given an executable called `name`, return the filename for the /// executable for a particular target. pub fn exe(name: &str, target: TargetSelection) -> String { @@ -54,29 +49,7 @@ pub fn add_dylib_path(path: Vec, cmd: &mut Command) { cmd.env(dylib_path_var(), t!(env::join_paths(list))); } -/// Returns the environment variable which the dynamic library lookup path -/// resides in for this platform. -pub fn dylib_path_var() -> &'static str { - if cfg!(target_os = "windows") { - "PATH" - } else if cfg!(target_os = "macos") { - "DYLD_LIBRARY_PATH" - } else if cfg!(target_os = "haiku") { - "LIBRARY_PATH" - } else { - "LD_LIBRARY_PATH" - } -} - -/// Parses the `dylib_path_var()` environment variable, returning a list of -/// paths that are members of this lookup path. -pub fn dylib_path() -> Vec { - let var = match env::var_os(dylib_path_var()) { - Some(v) => v, - None => return vec![], - }; - env::split_paths(&var).collect() -} +include!("dylib_util.rs"); /// Adds a list of lookup paths to `cmd`'s link library lookup path. pub fn add_link_lib_path(path: Vec, cmd: &mut Command) { @@ -103,21 +76,6 @@ fn link_lib_path() -> Vec { env::split_paths(&var).collect() } -/// `push` all components to `buf`. On windows, append `.exe` to the last component. -pub fn push_exe_path(mut buf: PathBuf, components: &[&str]) -> PathBuf { - let (&file, components) = components.split_last().expect("at least one component required"); - let mut file = file.to_owned(); - - if cfg!(windows) { - file.push_str(".exe"); - } - - buf.extend(components); - buf.push(file); - - buf -} - pub struct TimeIt(bool, Instant); /// Returns an RAII structure that prints out how long it took to drop. diff --git a/src/test/rustdoc/where-clause-order.rs b/src/test/rustdoc/where-clause-order.rs new file mode 100644 index 0000000000000..d0d89cbf126b4 --- /dev/null +++ b/src/test/rustdoc/where-clause-order.rs @@ -0,0 +1,15 @@ +#![crate_name = "foo"] + +pub trait SomeTrait +where Rhs: ?Sized +{} + +// @has 'foo/trait.SomeTrait.html' +// @has - "//div[@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, + B: PartialOrd + PartialEq, + C: PartialOrd + PartialEq, + D: PartialOrd + PartialEq, + E: PartialOrd + PartialEq + ?Sized +{} diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-8.rs b/src/test/ui/conditional-compilation/cfg-arg-invalid-8.rs new file mode 100644 index 0000000000000..1d7fa7885348e --- /dev/null +++ b/src/test/ui/conditional-compilation/cfg-arg-invalid-8.rs @@ -0,0 +1,3 @@ +// compile-flags: --cfg ) +// error-pattern: invalid `--cfg` argument: `)` (expected `key` or `key="value"`) +fn main() {} diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-8.stderr b/src/test/ui/conditional-compilation/cfg-arg-invalid-8.stderr new file mode 100644 index 0000000000000..7bb1814127b29 --- /dev/null +++ b/src/test/ui/conditional-compilation/cfg-arg-invalid-8.stderr @@ -0,0 +1,2 @@ +error: invalid `--cfg` argument: `)` (expected `key` or `key="value"`) +